Compare commits

...

158 Commits
3.5.6 ... 2.3.2

Author SHA1 Message Date
Benjamin Eberlei
c5725dd6bb Release 2.3.2 2013-01-07 21:05:04 +01:00
Benjamin Eberlei
b59cd047ff Bump submodule of DBAL to 2.3.2 2013-01-07 21:04:49 +01:00
Benjamin Eberlei
019094655b Merge branch 'DDC-2175' into 2.3 2012-12-24 11:18:12 +01:00
Benjamin Eberlei
88e817660c [DDC-2175] Fix bug in JoinedSubclassPersister 2012-12-24 11:14:18 +01:00
Benjamin Eberlei
aee75d8f25 Merge branch '2.3' of github.com:doctrine/doctrine2 into 2.3 2012-12-23 20:34:54 +01:00
Benjamin Eberlei
50132ddc18 Merge branch 'DDC-2206' into 2.3 2012-12-23 20:34:14 +01:00
Benjamin Eberlei
f05bcbc17c [DDC-2206] Fix Setup::registerAutoloadPEAR() to work with Symfony namespaces from top PEAR directory 2012-12-23 20:33:21 +01:00
Benjamin Eberlei
f94b6c07c7 Fix MySQL test 2012-12-22 21:50:42 +01:00
Benjamin Eberlei
b68c6b3d2d Merge branch 'DDC-1690' into 2.3 2012-12-22 12:46:06 +01:00
Patrick Schwisow
0425e8452d [DDC-1690] Added an empty line as requested. 2012-12-22 12:37:03 +01:00
Patrick Schwisow
c120700d89 [DDC-1690] Created unit test 2012-12-22 12:37:02 +01:00
Patrick Schwisow
22dc20c320 Fix DDC-1690
Added the lines suggested by the original reporter.
2012-12-22 12:37:02 +01:00
Benjamin Eberlei
6d89875306 Merge remote-tracking branch 'origin/2.3' into 2.3 2012-12-16 13:00:27 +01:00
Benjamin Eberlei
b666a62979 Merge branch 'DDC-2199' into 2.3 2012-12-16 12:58:46 +01:00
Benjamin Eberlei
f2f8c4f2dd DDC-2199 / DDC-2192 - Versioned fields didnt work in XML/YAML mapping 2012-12-16 12:58:17 +01:00
Benjamin Eberlei
59aef2ca95 Bump dev version to 2.3.2 2012-12-04 23:04:25 +01:00
Benjamin Eberlei
173b398b34 Release 2.3.1 2012-12-04 23:04:25 +01:00
Benjamin Eberlei
de22e726a4 Update DBAL dependency 2012-12-04 22:10:45 +01:00
Benjamin Eberlei
dab2b505a4 Merge branch 'DDC-2182' into 2.3 2012-12-04 21:59:56 +01:00
Francis Besset
0672688088 Passed column options to the join column 2012-12-04 21:58:58 +01:00
Francis Besset
660f89f745 Fixed trailing spaces on SchemaTool 2012-12-04 21:57:41 +01:00
Francis Besset
e0aa01ddb6 Fixed typo 2012-12-04 21:55:47 +01:00
Benjamin Eberlei
287b29aeaa Merge branch 'DDC-2156' into 2.3 2012-11-27 22:26:17 +01:00
Benjamin Eberlei
86132283f1 Clarify BC break in DDC-2156 2012-11-27 22:26:09 +01:00
Benjamin Eberlei
f75c3b517d Merge branch 'DDC-2172' into 2.3 2012-11-27 21:57:14 +01:00
Fabio B. Silva
6e7e4dd35a Fix CS 2012-11-27 21:56:32 +01:00
Fabio B. Silva
faedbfc09a refactoring tests 2012-11-27 21:56:32 +01:00
Fabio B. Silva
45269fe4f2 Fix DDC-2172 2012-11-27 21:56:32 +01:00
Benjamin Eberlei
a3fea32e0e Merge branch 'DDC-2074' into 2.3 2012-11-25 20:16:21 +01:00
Jan Kramer
c90ed73b33 [DDC-2074] Fixed bug regarding clearing PC's without owner
When calling clear on a PC that has no owner (e.g. because it was
cloned), it can't be deleted as there is no metadata available.
In these cases, it shouldn't be scheduled for deletion.
2012-11-25 20:15:57 +01:00
Jan Kramer
83943e86a2 [DDC-2074] Added test for PersistentCollection#clear. 2012-11-25 20:15:57 +01:00
Benjamin Eberlei
1aab5feb4a Merge branch 'DDC-2158' into 2.3 2012-11-25 12:34:47 +01:00
Francisco Facioni
469bd02b41 added outer left join 2012-11-25 12:28:38 +01:00
Francisco Facioni
24f74bc935 regression fix for left joins (double ON) 2012-11-25 12:28:38 +01:00
Benjamin Eberlei
77d060ab74 Merge branch 'DDC-2109' into 2.3 2012-11-12 15:49:41 +01:00
Benjamin Eberlei
01148e52f3 [DDC-2109] Fix bug with ResolveTargetEntityListener and ManyToMany associations. 2012-11-12 15:49:31 +01:00
Benjamin Eberlei
5756021571 Merge branch 'DDC-1958' into 2.3 2012-11-12 15:42:38 +01:00
Miha Vrhovnik
006d3833f6 extracted pgsql sql generation into a helper method 2012-11-12 15:04:15 +01:00
Miha Vrhovnik
8865a5b90d The distinct query should replicate the fields in order by clause and the order by clause itself from inner query
This fixes DDC-1958
2012-11-12 15:04:15 +01:00
Benjamin Eberlei
d0698754b2 Merge branch 'DDC-2071' into 2.3 2012-11-12 12:32:57 +01:00
HarmenM
4ea7a5dde4 Modified the WhereInWalkerTest to be compatible with a single InputParameter. 2012-11-12 12:30:48 +01:00
HarmenM
ed11e61812 Update lib/Doctrine/ORM/Tools/Pagination/Paginator.php
Replaced the foreach loop adding all IDs as single parameters with a single parameter which injects the IDs as an array.
2012-11-12 12:30:48 +01:00
HarmenM
e7e69daabe Update lib/Doctrine/ORM/Tools/Pagination/WhereInWalker.php
replaced the for-loop which adds the InputParameters for a single InputParameter for use with an array instead of a set of scalars.
2012-11-12 12:30:47 +01:00
Benjamin Eberlei
c6eb04de14 Merge branch 'DDC-2079' into 2.3 2012-11-09 22:16:44 +01:00
Fabio B. Silva
8c2009c67e Fix typo 2012-11-09 22:15:41 +01:00
Fabio B. Silva
a7ed9e638b Fix DDC-2079 2012-11-09 22:15:41 +01:00
Benjamin Eberlei
643ed0b8f5 Merge branch 'DDC-2069' into 2.3 2012-11-09 22:12:08 +01:00
Fabio B. Silva
57db88b62a Fix DDC-2069 2012-11-09 22:11:27 +01:00
Benjamin Eberlei
3c944b34ca Merge branch 'DDC-2086' into 2.3 2012-11-09 22:09:53 +01:00
Jasper N. Brouwer
1618a3e393 Added testcase for DDC-2086 2012-11-09 22:09:10 +01:00
Jasper N. Brouwer
a1094d352c Prevented "Undefined index" notice when updating
While executing updates on an entity scheduled for update without
a change-set, an "Undefined index" notice is raised.
2012-11-09 22:09:10 +01:00
Benjamin Eberlei
e4ef9e03ae Merge branch 'DDC-2082' into 2.3 2012-11-09 22:02:00 +01:00
justin.randell
a3c98b1087 check for false as a return value from get_parent_class(), not null 2012-11-09 22:01:00 +01:00
Benjamin Eberlei
2ce877bf8a Merge branch 'DDC-2113' into 2.3 2012-11-09 21:56:56 +01:00
Vaughn Clayton
6d35fad70f [DDC-2113] Surround WHERE clause with parens if using SQLFilter 2012-11-09 21:56:12 +01:00
Benjamin Eberlei
612ed2b3a2 Merge branch 'DDC-2116' into 2.3 2012-11-09 21:54:19 +01:00
Markus Lanthaler
95a85d67ea Improve DocBlock annotations of generated entities
Currently, the DocBlock annotations for member variables contain the variable name as description which is redundant and should be removed. Furthermore the class is annotated with the FQN instead of just the name. This makes automatically generated documentation quite ugly.
2012-11-09 21:53:34 +01:00
Benjamin Eberlei
edaab11a86 Merge branch 'DDC-2115' into 2.3 2012-11-09 21:47:42 +01:00
TR
1627c974b9 Update lib/Doctrine/ORM/Persisters/BasicEntityPersister.php
coding standards change
2012-11-09 21:47:01 +01:00
TR
c6118cb045 refactoring getIndividualValue for valid key value
refactoring getIndividualValue
2012-11-09 21:47:01 +01:00
TR
461d201e40 notice is thrown up if no identifier values found
wrapping the setting of value with an array_key_exists to prevent a notice from being thrown
2012-11-09 21:47:00 +01:00
Benjamin Eberlei
653aef2c83 Merge branch 'DDC-2122' into 2.3 2012-11-09 21:41:49 +01:00
Jeremy Marc
045d058cec Compare to null instead of using isset 2012-11-09 21:41:02 +01:00
Jeremy Marc
9dbf4d8480 Allow 0 id for Entity
When using a 0 id, it's throwing InvalidArgumentException (Binding entities to query parameters only allowed for entities that have an identifier.)
2012-11-09 21:41:02 +01:00
Benjamin Eberlei
2229a5e4c6 Merge branch 'DDC-2123' into 2.3 2012-11-09 21:33:51 +01:00
Gordon Stratton
bbf092c6fd Fix for invalid 'double-ON' SQL generation with entity inheritance type JOINED.
In SqlWalker::walkJoin(), SqlWalker::walkRangeVariableDeclaration() can be
called which may produce an 'ON' clause if the entity inheritance type is
JOINED. As walkJoin() may then produce another ON clause, this results in
invalid SQL (e.g. '... ON foo = bar ON (baz = quux) ...' when the inheritance
type is JOINED.

This adds a test and a fix for the problem, by checking for an inheritance type
of JOINED in walkJoin() and using AND instead of ON in the appropriate place.

It seems like this part of the code is begging to be refactored. This is my
first foray into Doctrine internals and can't see a way to do this without
stomping all over the rest of the code, but this section seems ripe for cleanup
by somebody who is familiar.
2012-11-09 21:32:52 +01:00
Benjamin Eberlei
6fee945fda Merge branch 'DDC-1241' into 2.3 2012-11-09 21:30:17 +01:00
nemekzg
974f18da0c Proposed fix for DDC-1241 2012-11-09 21:29:37 +01:00
Benjamin Eberlei
9b198be070 Merge branch 'DDC-2126' into 2.3 2012-11-09 21:03:42 +01:00
Benjamin Morel
b610855248 Fixed errors:
- Typo in variable name in JoinClassPathExpression;
 - Undefined class AST\ArithmeticPrimary (x2);
 - QueryException::invalidPathExpression() expects a PathExpression, not a string.
2012-11-09 21:02:55 +01:00
Benjamin Eberlei
994917aa23 Merge branch 'DDC-2121' into 2.3 2012-11-09 20:56:07 +01:00
Fabio B. Silva
d64be2888e Fix DDC-2121 2012-11-09 20:55:15 +01:00
Benjamin Eberlei
737e47e155 Merge branch 'DDC-2073' into 2.3 2012-11-09 20:45:35 +01:00
Matthieu Napoli
ef4ff8be81 Fix and test for DDC-2073 2012-11-09 20:44:12 +01:00
Matthieu Napoli
b53c81ae8d Fix and test for DDC-2073 2012-11-09 20:44:12 +01:00
Benjamin Eberlei
6bad010959 Merge branch 'DDC-2067' into 2.3 2012-10-12 21:49:45 +02:00
Benjamin Eberlei
26cfbdd08b [DDC-2067] Refactor and fix bug in boolean evaluation inside XML Driver. 2012-10-12 21:49:35 +02:00
Benjamin Eberlei
e8412b85df Merge branch 'DDC-2068' into 2.3 2012-10-12 20:36:29 +02:00
Oleksandr Kovalov
2e5d7416d8 Fixed bug with comment option not being added to column. 2012-10-12 20:36:18 +02:00
jakoch
1988944e7e fix typo 2012-10-12 20:31:16 +02:00
Benjamin Eberlei
564ec1ee2a Merge branch 'DDC-2028' into 2.3 2012-10-05 23:20:05 +02:00
Asmir Mustafic
cb0cddef83 spaces 2012-10-05 23:19:55 +02:00
Asmir Mustafic
8b2c92a6bd typo fix 2012-10-05 23:19:55 +02:00
Benjamin Eberlei
825a68bcba Merge branch 'DDC-2044' into 2.3 2012-10-05 20:25:31 +02:00
Marcin Radziwoński
abd11374ee Fixed unique-constraint name in XML Exporter 2012-10-05 20:24:46 +02:00
Benjamin Eberlei
518357d987 Merge branch 'DDC-2059' into 2.3 2012-10-05 20:06:06 +02:00
Benjamin Eberlei
4109f22000 [DDC-2059] Fix column and foreign key interfering with each other during reverse engineering. 2012-10-05 20:04:42 +02:00
Fabio B. Silva
c60e6523e9 Fix test case 2012-10-04 19:58:30 +02:00
Benjamin Eberlei
04262e2b73 Merge branch 'DDC-2012' into 2.3 2012-10-03 12:48:22 +02:00
Fabio B. Silva
084101e287 Fix DDC-2012 2012-10-03 12:47:38 +02:00
Benjamin Eberlei
ea2b288578 Bump dev version to 2.3.1 2012-09-20 08:03:35 +02:00
Benjamin Eberlei
b5e19dca18 Release 2.3.0 2012-09-20 08:03:34 +02:00
Benjamin Eberlei
585c9fd208 Bump versions 2012-09-20 08:00:34 +02:00
Benjamin Eberlei
c6101317cd Bump dev version to 2.3.0 2012-09-17 14:09:09 +02:00
Benjamin Eberlei
477642a171 Release 2.3.0-RC4 2012-09-17 14:09:09 +02:00
Benjamin Eberlei
75e968b250 Adjust MysqlSchemaToolTest to DBAL changes 2012-09-17 14:08:45 +02:00
Benjamin Eberlei
3294900faa Update dependencies 2012-09-17 13:53:37 +02:00
Benjamin Eberlei
2353736e8f Merge branch 'DDC-2015' into 2.3 2012-09-17 12:46:10 +02:00
Stefano Rodriguez
586aea0236 use of assertCount 2012-09-17 12:45:32 +02:00
Stefano Rodriguez
18a7fc5726 Fixes PersistentCollection::matching() when collection is not initialized and there are NEW entities in the collection 2012-09-17 12:45:32 +02:00
Stefano Rodriguez
44a56e8e49 Added a failing test case on PersistentCollection::matching() when collection is not initialized and there are NEW entities in the collection 2012-09-17 12:45:32 +02:00
Benjamin Eberlei
c2b82fa529 Merge branch 'DDC-2014' into 2.3 2012-09-17 12:43:19 +02:00
Thomas Rothe
d7da012918 added missing use statement 2012-09-17 12:43:09 +02:00
Thomas Rothe
85e5398354 Several fixes for comments
updated @param and @throws annotations
2012-09-17 12:43:09 +02:00
Benjamin Eberlei
3fd8392ccf Merge branch 'DDC-2026' into 2.3 2012-09-17 12:29:59 +02:00
Fabio B. Silva
0da0d02dec remove duplicate code 2012-09-17 12:29:49 +02:00
Benjamin Eberlei
387516f144 Merge branch 'DDC-2027' into 2.3 2012-09-17 12:28:23 +02:00
Cas
53e164ba5d Update lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php
Allow 'nullable' attribute to be exported for fields, something which already worked in YamlExport. This addition saved me a lot of time during development, not having to manually re-factor after each export.

Don't know why this was missing, maybe it's me who is missing something, so let me know ;)
2012-09-17 12:27:47 +02:00
Benjamin Eberlei
4d9f24b2ee Bump dev version to 2.3.0 2012-09-05 20:16:47 +02:00
Benjamin Eberlei
a96bbbbe0a Release 2.3.0-RC3 2012-09-05 20:16:47 +02:00
Benjamin Eberlei
8edecfdcad Bump DBAL dependency 2012-09-05 19:38:05 +02:00
Benjamin Eberlei
741080dc17 Merge branch 'DDC-2003' into 2.3 2012-09-05 19:30:26 +02:00
Benjamin Eberlei
30ad1b0706 [DDC-2003] Remove unused variable 2012-09-05 19:29:19 +02:00
Josiah Truasheim
9cdee12ccf Refactored the SqlValueVisitor to move all type processing to the entity persister. 2012-09-05 19:29:19 +02:00
Josiah Truasheim
c76280be42 Fixed formatting issues identified by Stof 2012-09-05 19:29:19 +02:00
Josiah Truasheim
0dcfabbc4d Removed the closure keyword as it isn't supported in PHP 5.3 2012-09-05 19:29:19 +02:00
Josiah Truasheim
366c6a7dd6 Fixed DDC-2003 using closures to reference the functionality of the calling entity persister from the SQL value visitor. 2012-09-05 19:29:19 +02:00
Josiah Truasheim
2597192f22 Added a failing test for DDC-2003 2012-09-05 19:29:19 +02:00
Benjamin Eberlei
bbf527a273 Bump dev version to 2.3.0 2012-08-29 16:36:26 +02:00
Benjamin Eberlei
9308afc9a5 Release 2.3.0-RC2 2012-08-29 16:36:26 +02:00
Benjamin Eberlei
1a81444b04 Bump dev version to 2.3.0 2012-08-29 16:35:51 +02:00
Benjamin Eberlei
d181fbc98d Release 2.3.0-RC2 2012-08-29 16:35:51 +02:00
Benjamin Eberlei
114e233d87 Revert "Merge remote-tracking branch 'origin/master' into 2.3"
This reverts commit 131d3003a0, reversing
changes made to 9d909cd583.
2012-08-29 15:50:08 +02:00
Benjamin Eberlei
bdb36a71c5 Merge branch 'DDC-1918' into 2.3 2012-08-29 15:15:35 +02:00
Benjamin Eberlei
8c1d64372c Merge remote-tracking branch 'origin/2.3' into 2.3 2012-08-29 15:15:27 +02:00
Benjamin Eberlei
f4ba58358c [DDC-1918] Fix weird results at the end of paginator when using fetch joins 2012-08-29 15:14:40 +02:00
Benjamin Eberlei
131d3003a0 Merge remote-tracking branch 'origin/master' into 2.3 2012-08-29 14:01:18 +02:00
Benjamin Eberlei
48e94343fd Merge pull request #427 from chEbba/return-exception
Fix ORMInvalidArgumentException factory methods with return instead of throw
2012-08-29 04:57:32 -07:00
FabioBatSilva
9d909cd583 Fix DDC-1977 2012-08-29 13:40:18 +02:00
Kirill chEbba Chebunin
3aaa90e1a8 Fix ORMInvalidArgumentException factory methods with return instead of throw 2012-08-19 22:58:40 +04:00
Alexander
971865f271 Merge branch 'config' into 2.3 2012-08-14 22:51:23 +02:00
Alexander
af08f05164 Fix setCustomHydrationModes + added test 2012-08-14 22:47:35 +02:00
Martin Meredith
2e6b50bb53 Create the setCustomHydrationMode function
This allows multiple hydrators to be set at once, and also allows for
the customHydrationMode options to be set via DoctrineORMModule
2012-08-14 22:47:35 +02:00
Benjamin Eberlei
17862d9a2a Merge branch 'CriteriaExpressionBuilder' into 2.3 2012-08-01 21:40:25 +02:00
Benjamin Eberlei
c99c7b6694 Update EntityRepository and PersistentCollection to new Criteria#expr() method instead of having to implement themselves. 2012-08-01 21:39:39 +02:00
Guilherme Blanco
3f2ddc60d4 Merge pull request #416 from Majkl578/DDC-1961
[DDC-1961] Fixed parameter type support in Parameter
2012-07-31 07:34:24 -07:00
Michael Moravec
3b3d762277 [DDC-1961] Fixed parameter type support in Parameter 2012-07-31 16:30:27 +02:00
Benjamin Eberlei
992b51eba7 Bump dev version to 2.3.0 2012-07-29 13:03:10 +02:00
Benjamin Eberlei
5527e121ec Release 2.3.0-RC1 2012-07-29 13:03:10 +02:00
Benjamin Eberlei
c55394c616 Bump dependencies 2012-07-29 13:02:58 +02:00
Benjamin Eberlei
1676cf23c0 Merge branch 'DDC-1937' into 2.3 2012-07-29 11:56:59 +02:00
Benjamin Eberlei
6dd3078153 [DDC-1937] Fix bug with apc and annotation caching using a workaround. 2012-07-29 11:56:49 +02:00
Marco Pivetta
1e2eca1a7e DDC-1933 - Fixing cloning of QueryBuilder and adding related tests 2012-07-29 11:50:24 +02:00
Benjamin Eberlei
7029d3738d Merge branch 'DDC-1964' into 2.3 2012-07-29 11:26:55 +02:00
Benjamin Eberlei
7f68347c1f [DDC-1964] Fix issue with refresh and and object hydrator not setting field to null explicitly to override possible previous values. 2012-07-29 11:26:22 +02:00
Johannes M. Schmitt
e63575ea18 added failing test for refresh with eager fetching 2012-07-29 11:26:22 +02:00
Benjamin Eberlei
d7bdae3bbb Merge branch 'DDC-1939' into 2.3 2012-07-29 09:28:18 +02:00
Benjamin Eberlei
e2c40dc365 [DDC-1939] Add test for persistent collection delete with composite key 2012-07-29 09:27:50 +02:00
Marco Pivetta
dfa6ff64c4 DDC-1939 - Removing references to non-existing AssociationMapping class 2012-07-29 09:27:50 +02:00
Benjamin Eberlei
ef27721db2 Merge remote-tracking branch 'origin/2.3' into 2.3 2012-07-29 09:08:39 +02:00
Benjamin Eberlei
13d32e6de5 Merge remote-tracking branch 'origin/2.3' into 2.3 2012-07-29 09:08:19 +02:00
Benjamin Eberlei
bd1e6ac309 Merge pull request #410 from igorw/helper-set
[2.3] Use HelperSet in cli-config.php
2012-07-29 00:05:45 -07:00
Christophe Coevoet
369a30ad3d Added the new DBAL 2.3 types in the EntityGenerator typehint map 2012-07-29 09:02:35 +02:00
Guilherme Blanco
ac9df05c92 Fixed is_subclass_of comparing an interface which brought our requirement to 5.3.9. Changed to reflection approach which still keep us at the same dependency as before. 2012-07-26 22:01:37 +02:00
Igor Wiedler
2158a0788e [2.3] Use HelperSet in cli-config.php 2012-07-26 19:24:53 +02:00
Guilherme Blanco
2389f77d91 Fixed DefaultRepositoryClassName which should follow the Persistence interface, not ORM class. 2012-07-25 19:54:11 +02:00
Guilherme Blanco
5b55739990 Moved implementation from EntityRepository to EntityManager. This decouples ER implementation from EM, as it should be. 2012-07-24 00:23:59 +02:00
Christophe Coevoet
3e53d9d79c Changed commands to use command.name in the help 2012-07-24 00:21:31 +02:00
64 changed files with 1471 additions and 470 deletions

View File

@@ -1,5 +1,13 @@
# Upgrade to 2.3
## EntityManager#find() not calls EntityRepository#find() anymore
Previous to 2.3, calling ``EntityManager#find()`` would be delegated to
``EntityRepository#find()``. This has lead to some unexpected behavior in the
core of Doctrine when people have overwritten the find method in their
repositories. That is why this behavior has been reversed in 2.3, and
``EntityRepository#find()`` calls ``EntityManager#find()`` instead.
## EntityGenerator add*() method generation
When generating an add*() method for a collection the EntityGenerator will now not

View File

@@ -1,6 +1,6 @@
{
"name": "doctrine/orm",
"type": "library",
"type": "library","version":"2.3.2",
"description": "Object-Relational-Mapper for PHP",
"keywords": ["orm", "database"],
"homepage": "http://www.doctrine-project.org",
@@ -14,7 +14,7 @@
"require": {
"php": ">=5.3.2",
"ext-pdo": "*",
"doctrine/dbal": ">=2.3-dev,<2.5-dev",
"doctrine/dbal": "2.3.*",
"symfony/console": "2.*"
},
"suggest": {
@@ -26,7 +26,7 @@
"bin": ["bin/doctrine", "bin/doctrine.php"],
"extra": {
"branch-alias": {
"dev-master": "2.4.x-dev"
"dev-master": "2.3.x-dev"
}
}
}

View File

@@ -281,7 +281,7 @@ abstract class AbstractQuery
$value = $values[$class->getSingleIdentifierFieldName()];
if ( ! $value) {
if (null === $value) {
throw new \InvalidArgumentException(
"Binding entities to query parameters only allowed for entities that have an identifier."
);

View File

@@ -25,6 +25,7 @@ use Doctrine\Common\Persistence\ObjectRepository;
use Doctrine\Common\Collections\Selectable;
use Doctrine\Common\Collections\Criteria;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\ExpressionBuilder;
/**
* An EntityRepository serves as a repository for entities with generic as well as
@@ -160,13 +161,14 @@ class EntityRepository implements ObjectRepository, Selectable
* Finds a single entity by a set of criteria.
*
* @param array $criteria
* @param array|null $orderBy
* @return object
*/
public function findOneBy(array $criteria)
public function findOneBy(array $criteria, array $orderBy = null)
{
$persister = $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName);
return $persister->load($criteria, null, null, array(), 0, 1);
return $persister->load($criteria, null, null, array(), 0, 1, $orderBy);
}
/**
@@ -214,7 +216,7 @@ class EntityRepository implements ObjectRepository, Selectable
case 3:
return $this->$method(array($fieldName => $arguments[0]), $arguments[1], $arguments[2]);
case 4;
case 4:
return $this->$method(array($fieldName => $arguments[0]), $arguments[1], $arguments[2], $arguments[3]);
default:

View File

@@ -1188,7 +1188,7 @@ class ClassMetadataInfo implements ClassMetadata
// Complete fieldName and columnName mapping
if ( ! isset($mapping['columnName'])) {
$mapping['columnName'] = $this->namingStrategy->propertyToColumnName($mapping['fieldName'], $this->name);
$mapping['columnName'] = $this->namingStrategy->propertyToColumnName($mapping['fieldName']);
}
if ($mapping['columnName'][0] === '`') {
@@ -1465,7 +1465,6 @@ class ClassMetadataInfo implements ClassMetadata
if ( ! isset($mapping['joinTable']['name'])) {
$mapping['joinTable']['name'] = $this->namingStrategy->joinTableName($mapping['sourceEntity'], $mapping['targetEntity'], $mapping['fieldName']);
}
if ( ! isset($mapping['joinTable']['joinColumns'])) {
$mapping['joinTable']['joinColumns'] = array(array(
'name' => $this->namingStrategy->joinKeyColumnName($mapping['sourceEntity']),
@@ -1479,6 +1478,8 @@ class ClassMetadataInfo implements ClassMetadata
'onDelete' => 'CASCADE'));
}
$mapping['joinTableColumns'] = array();
foreach ($mapping['joinTable']['joinColumns'] as &$joinColumn) {
if (empty($joinColumn['name'])) {
$joinColumn['name'] = $this->namingStrategy->joinKeyColumnName($mapping['sourceEntity'], $joinColumn['referencedColumnName']);
@@ -2725,7 +2726,7 @@ class ClassMetadataInfo implements ClassMetadata
// Association defined as Id field
$joinColumns = $this->associationMappings[$idProperty]['joinColumns'];
$assocQuotedColumnNames = array_map(
function ($joinColumn) {
function ($joinColumn) use ($platform) {
return isset($joinColumn['quoted'])
? $platform->quoteIdentifier($joinColumn['name'])
: $joinColumn['name'];

View File

@@ -45,7 +45,7 @@ class DefaultNamingStrategy implements NamingStrategy
/**
* {@inheritdoc}
*/
public function propertyToColumnName($propertyName, $className = null)
public function propertyToColumnName($propertyName)
{
return $propertyName;
}

View File

@@ -197,43 +197,6 @@ class AnnotationDriver extends AbstractAnnotationDriver
}
}
$associationOverrides = array();
// Evaluate AssociationOverrides annotation
if (isset($classAnnotations['Doctrine\ORM\Mapping\AssociationOverrides'])) {
$associationOverridesAnnot = $classAnnotations['Doctrine\ORM\Mapping\AssociationOverrides'];
foreach ($associationOverridesAnnot->value as $associationOverride) {
// Check for JoinColummn/JoinColumns annotations
if ($associationOverride->joinColumns) {
$joinColumns = array();
foreach ($associationOverride->joinColumns as $joinColumn) {
$joinColumns[] = $this->joinColumnToArray($joinColumn);
}
$associationOverrides[$associationOverride->name]['joinColumns'] = $joinColumns;
}
// Check for JoinTable annotations
if ($associationOverride->joinTable) {
$joinTable = null;
$joinTableAnnot = $associationOverride->joinTable;
$joinTable = array(
'name' => $joinTableAnnot->name,
'schema' => $joinTableAnnot->schema
);
foreach ($joinTableAnnot->joinColumns as $joinColumn) {
$joinTable['joinColumns'][] = $this->joinColumnToArray($joinColumn);
}
foreach ($joinTableAnnot->inverseJoinColumns as $joinColumn) {
$joinTable['inverseJoinColumns'][] = $this->joinColumnToArray($joinColumn);
}
$associationOverrides[$associationOverride->name]['joinTable'] = $joinTable;
}
}
}
// Evaluate InheritanceType annotation
if (isset($classAnnotations['Doctrine\ORM\Mapping\InheritanceType'])) {
$inheritanceTypeAnnot = $classAnnotations['Doctrine\ORM\Mapping\InheritanceType'];

View File

@@ -297,6 +297,10 @@ class DatabaseDriver implements MappingDriver
$associationMapping['fieldName'] = $this->getFieldNameForColumn($tableName, $localColumn, true);
$associationMapping['targetEntity'] = $this->getClassNameForTable($foreignTable);
if (isset($metadata->fieldMappings[$associationMapping['fieldName']])) {
$associationMapping['fieldName'] = $associationMapping['fieldName'] . "2";
}
if ($primaryKeyColumns && in_array($localColumn, $primaryKeyColumns)) {
$associationMapping['id'] = true;
}

View File

@@ -60,7 +60,7 @@ class XmlDriver extends FileDriver
if (isset($xmlRoot['repository-class'])) {
$metadata->setCustomRepositoryClass((string)$xmlRoot['repository-class']);
}
if (isset($xmlRoot['read-only']) && $xmlRoot['read-only'] == "true") {
if (isset($xmlRoot['read-only']) && $this->evaluateBoolean($xmlRoot['read-only'])) {
$metadata->markReadOnly();
}
} else if ($xmlRoot->getName() == 'mapped-superclass') {
@@ -230,18 +230,27 @@ class XmlDriver extends FileDriver
if (isset($xmlRoot->field)) {
foreach ($xmlRoot->field as $fieldMapping) {
$mapping = $this->columnToArray($fieldMapping);
if (isset($mapping['version'])) {
$metadata->setVersionMapping($mapping);
}
$metadata->mapField($mapping);
}
}
foreach ($mappings as $mapping) {
$metadata->mapField($mapping);
if (isset($mapping['version'])) {
$metadata->setVersionMapping($mapping);
}
$metadata->mapField($mapping);
}
// Evaluate <id ...> mappings
$associationIds = array();
foreach ($xmlRoot->id as $idElement) {
if ((bool)$idElement['association-key'] == true) {
if (isset($idElement['association-key']) && $this->evaluateBoolean($idElement['association-key'])) {
$associationIds[(string)$idElement['name']] = true;
continue;
}
@@ -334,7 +343,7 @@ class XmlDriver extends FileDriver
}
if (isset($oneToOneElement['orphan-removal'])) {
$mapping['orphanRemoval'] = (bool)$oneToOneElement['orphan-removal'];
$mapping['orphanRemoval'] = $this->evaluateBoolean($oneToOneElement['orphan-removal']);
}
$metadata->mapOneToOne($mapping);
@@ -359,7 +368,7 @@ class XmlDriver extends FileDriver
}
if (isset($oneToManyElement['orphan-removal'])) {
$mapping['orphanRemoval'] = (bool)$oneToManyElement['orphan-removal'];
$mapping['orphanRemoval'] = $this->evaluateBoolean($oneToManyElement['orphan-removal']);
}
if (isset($oneToManyElement->{'order-by'})) {
@@ -433,7 +442,7 @@ class XmlDriver extends FileDriver
}
if (isset($manyToManyElement['orphan-removal'])) {
$mapping['orphanRemoval'] = (bool)$manyToManyElement['orphan-removal'];
$mapping['orphanRemoval'] = $this->evaluateBoolean($manyToManyElement['orphan-removal']);
}
if (isset($manyToManyElement['mapped-by'])) {
@@ -594,11 +603,11 @@ class XmlDriver extends FileDriver
);
if (isset($joinColumnElement['unique'])) {
$joinColumn['unique'] = ((string)$joinColumnElement['unique'] == "false") ? false : true;
$joinColumn['unique'] = $this->evaluateBoolean($joinColumnElement['unique']);
}
if (isset($joinColumnElement['nullable'])) {
$joinColumn['nullable'] = ((string)$joinColumnElement['nullable'] == "false") ? false : true;
$joinColumn['nullable'] = $this->evaluateBoolean($joinColumnElement['nullable']);
}
if (isset($joinColumnElement['on-delete'])) {
@@ -645,11 +654,11 @@ class XmlDriver extends FileDriver
}
if (isset($fieldMapping['unique'])) {
$mapping['unique'] = ((string) $fieldMapping['unique'] == "false") ? false : true;
$mapping['unique'] = $this->evaluateBoolean($fieldMapping['unique']);
}
if (isset($fieldMapping['nullable'])) {
$mapping['nullable'] = ((string) $fieldMapping['nullable'] == "false") ? false : true;
$mapping['nullable'] = $this->evaluateBoolean($fieldMapping['nullable']);
}
if (isset($fieldMapping['version']) && $fieldMapping['version']) {
@@ -710,4 +719,12 @@ class XmlDriver extends FileDriver
return $result;
}
protected function evaluateBoolean($element)
{
$flag = (string)$element;
return ($flag === true || $flag == "true" || $flag == "1");
}
}

View File

@@ -198,6 +198,7 @@ class YamlDriver extends FileDriver
if (is_string($index['columns'])) {
$columns = explode(',', $index['columns']);
$columns = array_map('trim', $columns);
} else {
$columns = $index['columns'];
}
@@ -217,6 +218,7 @@ class YamlDriver extends FileDriver
if (is_string($unique['columns'])) {
$columns = explode(',', $unique['columns']);
$columns = array_map('trim', $columns);
} else {
$columns = $unique['columns'];
}
@@ -295,6 +297,10 @@ class YamlDriver extends FileDriver
}
}
if (isset($mapping['version'])) {
$metadata->setVersionMapping($mapping);
}
$metadata->mapField($mapping);
}
}
@@ -628,7 +634,7 @@ class YamlDriver extends FileDriver
$mapping['type'] = $column['type'];
if (isset($params[1])) {
$column['length'] = substr($params[1], 0, strlen($params[1]) - 1);
$column['length'] = (integer) substr($params[1], 0, strlen($params[1]) - 1);
}
}

View File

@@ -34,7 +34,7 @@ class MappingException extends \Doctrine\ORM\ORMException
public static function identifierRequired($entityName)
{
if (null !== ($parent = get_parent_class($entityName))) {
if (false !== ($parent = get_parent_class($entityName))) {
return new self(sprintf(
'No identifier/primary key specified for Entity "%s" sub class of "%s". Every Entity must have an identifier/primary key.',
$entityName, $parent
@@ -206,7 +206,7 @@ class MappingException extends \Doctrine\ORM\ORMException
public static function classIsNotAValidEntityOrMappedSuperClass($className)
{
if (null !== ($parent = get_parent_class($className))) {
if (false !== ($parent = get_parent_class($className))) {
return new self(sprintf(
'Class "%s" sub class of "%s" is not a valid entity or mapped super class.',
$className, $parent

View File

@@ -42,10 +42,9 @@ interface NamingStrategy
* Return a column name for a property
*
* @param string $propertyName A property
* @param string $className The fully-qualified class name
* @return string A column name
*/
function propertyToColumnName($propertyName, $className = null);
function propertyToColumnName($propertyName);
/**
* Return the default reference column name

View File

@@ -80,7 +80,7 @@ class UnderscoreNamingStrategy implements NamingStrategy
/**
* {@inheritdoc}
*/
public function propertyToColumnName($propertyName, $className = null)
public function propertyToColumnName($propertyName)
{
return $this->underscore($propertyName);
}

View File

@@ -43,7 +43,7 @@ class ORMInvalidArgumentException extends \InvalidArgumentException
static public function entityWithoutIdentity($className, $entity)
{
throw new self(
return new self(
"The given entity of type '" . $className . "' (".self::objToStr($entity).") has no identity/no " .
"id values set. It cannot be added to the identity map."
);
@@ -70,30 +70,30 @@ class ORMInvalidArgumentException extends \InvalidArgumentException
static public function detachedEntityFoundThroughRelationship(array $assoc, $entry)
{
throw new self("A detached entity of type " . $assoc['targetEntity'] . " (" . self::objToStr($entry) . ") "
return new self("A detached entity of type " . $assoc['targetEntity'] . " (" . self::objToStr($entry) . ") "
. " was found through the relationship '" . $assoc['sourceEntity'] . "#" . $assoc['fieldName'] . "' "
. "during cascading a persist operation.");
}
static public function entityNotManaged($entity)
{
throw new self("Entity " . self::objToStr($entity) . " is not managed. An entity is managed if its fetched " .
return new self("Entity " . self::objToStr($entity) . " is not managed. An entity is managed if its fetched " .
"from the database or registered as new through EntityManager#persist");
}
static public function entityHasNoIdentity($entity, $operation)
{
throw new self("Entity has no identity, therefore " . $operation ." cannot be performed. " . self::objToStr($entity));
return new self("Entity has no identity, therefore " . $operation ." cannot be performed. " . self::objToStr($entity));
}
static public function entityIsRemoved($entity, $operation)
{
throw new self("Entity is removed, therefore " . $operation ." cannot be performed. " . self::objToStr($entity));
return new self("Entity is removed, therefore " . $operation ." cannot be performed. " . self::objToStr($entity));
}
static public function detachedEntityCannot($entity, $operation)
{
throw new self("A detached entity was found during " . $operation . " " . self::objToStr($entity));
return new self("A detached entity was found during " . $operation . " " . self::objToStr($entity));
}
public static function invalidObject($context, $given, $parameterIndex = 1)

View File

@@ -42,6 +42,7 @@ use Closure;
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @author Roman Borschel <roman@code-factory.org>
* @author Giorgio Sironi <piccoloprincipeazzurro@gmail.com>
* @author Stefano Rodriguez <stefano.rodriguez@fubles.com>
* @todo Design for inheritance to allow custom implementations?
*/
final class PersistentCollection implements Collection, Selectable
@@ -654,7 +655,7 @@ final class PersistentCollection implements Collection, Selectable
$this->initialized = true; // direct call, {@link initialize()} is too expensive
if ($this->association['isOwningSide']) {
if ($this->association['isOwningSide'] && $this->owner) {
$this->changed();
$uow->scheduleCollectionDeletion($this);
@@ -812,6 +813,13 @@ final class PersistentCollection implements Collection, Selectable
throw new \RuntimeException("Matching Criteria on PersistentCollection only works on OneToMany assocations at the moment.");
}
// If there are NEW objects we have to check if any of them matches the criteria
$newObjects = array();
if ($this->isDirty) {
$newObjects = $this->coll->matching($criteria)->toArray();
}
$targetClass = $this->em->getClassMetadata(get_class($this->owner));
$id = $targetClass->getSingleIdReflectionProperty()->getValue($this->owner);
@@ -824,7 +832,7 @@ final class PersistentCollection implements Collection, Selectable
$persister = $this->em->getUnitOfWork()->getEntityPersister($this->association['targetEntity']);
return new ArrayCollection($persister->loadCriteria($criteria));
return new ArrayCollection(array_merge($persister->loadCriteria($criteria), $newObjects));
}
}

View File

@@ -88,7 +88,7 @@ class BasicEntityPersister
*/
static private $comparisonMap = array(
Comparison::EQ => '= %s',
Comparison::IS => '= %s',
Comparison::IS => 'IS %s',
Comparison::NEQ => '!= %s',
Comparison::GT => '> %s',
Comparison::GTE => '>= %s',
@@ -659,12 +659,13 @@ class BasicEntityPersister
* @param array $hints Hints for entity creation.
* @param int $lockMode
* @param int $limit Limit number of results
* @param array $orderBy Criteria to order by
* @return object The loaded and managed entity instance or NULL if the entity can not be found.
* @todo Check identity map? loadById method? Try to guess whether $criteria is the id?
*/
public function load(array $criteria, $entity = null, $assoc = null, array $hints = array(), $lockMode = 0, $limit = null)
public function load(array $criteria, $entity = null, $assoc = null, array $hints = array(), $lockMode = 0, $limit = null, array $orderBy = null)
{
$sql = $this->_getSelectEntitiesSQL($criteria, $assoc, $lockMode, $limit);
$sql = $this->_getSelectEntitiesSQL($criteria, $assoc, $lockMode, $limit, null, $orderBy);
list($params, $types) = $this->expandParameters($criteria);
$stmt = $this->_conn->executeQuery($sql, $params, $types);
@@ -808,10 +809,23 @@ class BasicEntityPersister
return array(array(), array());
}
$valueVisitor = new SqlValueVisitor($this->_class);
$valueVisitor = new SqlValueVisitor();
$valueVisitor->dispatch($expression);
return $valueVisitor->getParamsAndTypes();
list($values, $types) = $valueVisitor->getParamsAndTypes();
$sqlValues = array();
foreach ($values as $value) {
$sqlValues[] = $this->getValue($value);
}
$sqlTypes = array();
foreach ($types as $type) {
list($field, $value) = $type;
$sqlTypes[] = $this->getType($field, $value);
}
return array($sqlValues, $sqlTypes);
}
/**
@@ -1686,7 +1700,11 @@ class BasicEntityPersister
$idValues = $class->getIdentifierValues($value);
}
$value = $idValues[key($idValues)];
$key = key($idValues);
if (null !== $key){
$value = $idValues[$key];
}
}
return $value;

View File

@@ -227,8 +227,10 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
// Make sure the table with the version column is updated even if no columns on that
// table were affected.
if ($isVersioned && ! isset($updateData[$versionedTable])) {
$this->_updateTable($entity, $this->quoteStrategy->getTableName($versionedClass, $this->_platform), array(), true);
if ($isVersioned) {
if ( ! isset($updateData[$versionedTable])) {
$this->_updateTable($entity, $this->quoteStrategy->getTableName($versionedClass, $this->_platform), array(), true);
}
$id = $this->_em->getUnitOfWork()->getEntityIdentifier($entity);
$this->assignDefaultVersionValue($entity, $id);
@@ -468,7 +470,8 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
}
} else if ($this->_class->name != $this->_class->rootEntityName ||
! $this->_class->isIdGeneratorIdentity() || $this->_class->identifier[0] != $name) {
$columns[] = $this->quoteStrategy->getColumnName($name, $this->_class, $this->_platform);
$columns[] = $this->quoteStrategy->getColumnName($name, $this->_class, $this->_platform);
$this->_columnTypes[$name] = $this->_class->fieldMappings[$name]['type'];
}
}

View File

@@ -46,19 +46,6 @@ class SqlValueVisitor extends ExpressionVisitor
*/
private $types = array();
/**
* @var \Doctrine\ORM\Mapping\ClassMetadata
*/
private $class;
/**
* @param \Doctrine\ORM\Mapping\ClassMetadata
*/
public function __construct(ClassMetadata $class)
{
$this->class = $class;
}
/**
* Convert a comparison expression into the target query language output
*
@@ -70,9 +57,9 @@ class SqlValueVisitor extends ExpressionVisitor
{
$value = $comparison->getValue()->getValue();
$field = $comparison->getField();
$this->values[] = $value;
$this->types[] = $this->getType($field, $value);
$this->types[] = array($field, $value);
}
/**
@@ -110,17 +97,4 @@ class SqlValueVisitor extends ExpressionVisitor
{
return array($this->values, $this->types);
}
private function getType($field, $value)
{
$type = isset($this->class->fieldMappings[$field])
? Type::getType($this->class->fieldMappings[$field]['type'])->getBindingType()
: \PDO::PARAM_STR;
if (is_array($value)) {
$type += Connection::ARRAY_PARAM_OFFSET;
}
return $type;
}
}

View File

@@ -40,6 +40,6 @@ class JoinClassPathExpression extends Node
public function dispatch($walker)
{
return $sqlWalker->walkJoinPathExpression($this);
return $walker->walkJoinPathExpression($this);
}
}

View File

@@ -1007,8 +1007,13 @@ class SqlWalker implements TreeWalker
switch (true) {
case ($joinDeclaration instanceof \Doctrine\ORM\Query\AST\RangeVariableDeclaration):
$class = $this->em->getClassMetadata($joinDeclaration->abstractSchemaName);
$condExprConjunction = $class->isInheritanceTypeJoined() && $joinType != AST\Join::JOIN_TYPE_LEFT && $joinType != AST\Join::JOIN_TYPE_LEFTOUTER
? ' AND '
: ' ON ';
$sql .= $this->walkRangeVariableDeclaration($joinDeclaration)
. ' ON (' . $this->walkConditionalExpression($join->conditionalExpression) . ')';
. $condExprConjunction . '(' . $this->walkConditionalExpression($join->conditionalExpression) . ')';
break;
case ($joinDeclaration instanceof \Doctrine\ORM\Query\AST\JoinAssociationDeclaration):
@@ -1147,7 +1152,7 @@ class SqlWalker implements TreeWalker
switch (true) {
case ($expr instanceof AST\PathExpression):
if ($expr->type !== AST\PathExpression::TYPE_STATE_FIELD) {
throw QueryException::invalidPathExpression($expr->type);
throw QueryException::invalidPathExpression($expr);
}
$fieldName = $expr->field;
@@ -1188,7 +1193,6 @@ class SqlWalker implements TreeWalker
case ($expr instanceof AST\SimpleArithmeticExpression):
case ($expr instanceof AST\ArithmeticTerm):
case ($expr instanceof AST\ArithmeticFactor):
case ($expr instanceof AST\ArithmeticPrimary):
case ($expr instanceof AST\Literal):
case ($expr instanceof AST\NullIfExpression):
case ($expr instanceof AST\CoalesceExpression):
@@ -1422,7 +1426,6 @@ class SqlWalker implements TreeWalker
case ($expr instanceof AST\SimpleArithmeticExpression):
case ($expr instanceof AST\ArithmeticTerm):
case ($expr instanceof AST\ArithmeticFactor):
case ($expr instanceof AST\ArithmeticPrimary):
case ($expr instanceof AST\Literal):
case ($expr instanceof AST\NullIfExpression):
case ($expr instanceof AST\CoalesceExpression):
@@ -1609,7 +1612,7 @@ class SqlWalker implements TreeWalker
if (count($filterClauses)) {
if ($condSql) {
$condSql .= ' AND ';
$condSql = '(' . $condSql . ') AND ';
}
$condSql .= implode(' AND ', $filterClauses);

View File

@@ -157,6 +157,38 @@ class EntityGenerator
Type::SIMPLE_ARRAY => 'array',
);
/**
* @var array Hash-map to handle generator types string.
*/
protected static $generatorStrategyMap = array(
ClassMetadataInfo::GENERATOR_TYPE_AUTO => 'AUTO',
ClassMetadataInfo::GENERATOR_TYPE_SEQUENCE => 'SEQUENCE',
ClassMetadataInfo::GENERATOR_TYPE_TABLE => 'TABLE',
ClassMetadataInfo::GENERATOR_TYPE_IDENTITY => 'IDENTITY',
ClassMetadataInfo::GENERATOR_TYPE_NONE => 'NONE',
ClassMetadataInfo::GENERATOR_TYPE_UUID => 'UUID',
ClassMetadataInfo::GENERATOR_TYPE_CUSTOM => 'CUSTOM'
);
/**
* @var array Hash-map to handle the change tracking policy string.
*/
protected static $changeTrackingPolicyMap = array(
ClassMetadataInfo::CHANGETRACKING_DEFERRED_IMPLICIT => 'DEFERRED_IMPLICIT',
ClassMetadataInfo::CHANGETRACKING_DEFERRED_EXPLICIT => 'DEFERRED_EXPLICIT',
ClassMetadataInfo::CHANGETRACKING_NOTIFY => 'NOTIFY',
);
/**
* @var array Hash-map to handle the inheritance type string.
*/
protected static $inheritanceTypeMap = array(
ClassMetadataInfo::INHERITANCE_TYPE_NONE => 'NONE',
ClassMetadataInfo::INHERITANCE_TYPE_JOINED => 'JOINED',
ClassMetadataInfo::INHERITANCE_TYPE_SINGLE_TABLE => 'SINGLE_TABLE',
ClassMetadataInfo::INHERITANCE_TYPE_TABLE_PER_CLASS => 'TABLE_PER_CLASS',
);
/**
* @var string
*/
@@ -672,7 +704,7 @@ public function __construct()
{
$lines = array();
$lines[] = '/**';
$lines[] = ' * '.$metadata->name;
$lines[] = ' * ' . $this->getClassName($metadata);
if ($this->generateAnnotations) {
$lines[] = ' *';
@@ -909,9 +941,14 @@ public function __construct()
$var = sprintf('%sMethodTemplate', $type);
$template = self::$$var;
$methodTypeHint = null;
$types = Type::getTypesMap();
$variableType = $typeHint ? $this->getType($typeHint) . ' ' : null;
$methodTypeHint = $typeHint && ! isset($types[$typeHint]) ? '\\' . $typeHint . ' ' : null;
if ($typeHint && ! isset($types[$typeHint])) {
$variableType = '\\' . ltrim($variableType, '\\');
$methodTypeHint = '\\' . $typeHint . ' ';
}
$replacements = array(
'<description>' => ucfirst($type) . ' ' . $fieldName,
@@ -991,9 +1028,9 @@ public function __construct()
$lines[] = $this->spaces . '/**';
if ($associationMapping['type'] & ClassMetadataInfo::TO_MANY) {
$lines[] = $this->spaces . ' * @var \Doctrine\Common\Collections\ArrayCollection';
$lines[] = $this->spaces . ' * @var \Doctrine\Common\Collections\Collection';
} else {
$lines[] = $this->spaces . ' * @var ' . $associationMapping['targetEntity'];
$lines[] = $this->spaces . ' * @var \\' . ltrim($associationMapping['targetEntity'], '\\');
}
if ($this->generateAnnotations) {
@@ -1080,17 +1117,23 @@ public function __construct()
$lines[] = $this->spaces . ' * @' . $this->annotationsPrefix . 'JoinTable(' . implode(', ', $joinTable) . ',';
$lines[] = $this->spaces . ' * joinColumns={';
$joinColumnsLines = array();
foreach ($associationMapping['joinTable']['joinColumns'] as $joinColumn) {
$lines[] = $this->spaces . ' * ' . $this->generateJoinColumnAnnotation($joinColumn);
$joinColumnsLines[] = $this->spaces . ' * ' . $this->generateJoinColumnAnnotation($joinColumn);
}
$lines[] = implode(",". PHP_EOL, $joinColumnsLines);
$lines[] = $this->spaces . ' * },';
$lines[] = $this->spaces . ' * inverseJoinColumns={';
$inverseJoinColumnsLines = array();
foreach ($associationMapping['joinTable']['inverseJoinColumns'] as $joinColumn) {
$lines[] = $this->spaces . ' * ' . $this->generateJoinColumnAnnotation($joinColumn);
$inverseJoinColumnsLines[] = $this->spaces . ' * ' . $this->generateJoinColumnAnnotation($joinColumn);
}
$lines[] = implode(",". PHP_EOL, $inverseJoinColumnsLines);
$lines[] = $this->spaces . ' * }';
$lines[] = $this->spaces . ' * )';
}
@@ -1116,7 +1159,7 @@ public function __construct()
{
$lines = array();
$lines[] = $this->spaces . '/**';
$lines[] = $this->spaces . ' * @var ' . $this->getType($fieldMapping['type']) . ' $' . $fieldMapping['fieldName'];
$lines[] = $this->spaces . ' * @var ' . $this->getType($fieldMapping['type']);
if ($this->generateAnnotations) {
$lines[] = $this->spaces . ' *';
@@ -1203,63 +1246,45 @@ public function __construct()
return implode("\n", $lines);
}
private function getInheritanceTypeString($type)
/**
* @param integer $type The inheritance type used by the class and it's subclasses.
* @return string The literal string for the inheritance type.
* @throws \InvalidArgumentException When the inheritance type does not exists.
*/
protected function getInheritanceTypeString($type)
{
switch ($type) {
case ClassMetadataInfo::INHERITANCE_TYPE_NONE:
return 'NONE';
case ClassMetadataInfo::INHERITANCE_TYPE_JOINED:
return 'JOINED';
case ClassMetadataInfo::INHERITANCE_TYPE_SINGLE_TABLE:
return 'SINGLE_TABLE';
case ClassMetadataInfo::INHERITANCE_TYPE_TABLE_PER_CLASS:
return 'PER_CLASS';
default:
throw new \InvalidArgumentException('Invalid provided InheritanceType: ' . $type);
if ( ! isset(self::$inheritanceTypeMap[$type])) {
throw new \InvalidArgumentException(sprintf('Invalid provided InheritanceType: %s', $type));
}
return self::$inheritanceTypeMap[$type];
}
private function getChangeTrackingPolicyString($policy)
/**
* @param integer $type The policy used for change-tracking for the mapped class.
* @return string The literal string for the change-tracking type.
* @throws \InvalidArgumentException When the change-tracking type does not exists.
*/
protected function getChangeTrackingPolicyString($type)
{
switch ($policy) {
case ClassMetadataInfo::CHANGETRACKING_DEFERRED_IMPLICIT:
return 'DEFERRED_IMPLICIT';
case ClassMetadataInfo::CHANGETRACKING_DEFERRED_EXPLICIT:
return 'DEFERRED_EXPLICIT';
case ClassMetadataInfo::CHANGETRACKING_NOTIFY:
return 'NOTIFY';
default:
throw new \InvalidArgumentException('Invalid provided ChangeTrackingPolicy: ' . $policy);
if ( ! isset(self::$changeTrackingPolicyMap[$type])) {
throw new \InvalidArgumentException(sprintf('Invalid provided ChangeTrackingPolicy: %s', $type));
}
return self::$changeTrackingPolicyMap[$type];
}
private function getIdGeneratorTypeString($type)
/**
* @param integer $type The generator to use for the mapped class.
* @return string The literal string for the generetor type.
* @throws \InvalidArgumentException When the generator type does not exists.
*/
protected function getIdGeneratorTypeString($type)
{
switch ($type) {
case ClassMetadataInfo::GENERATOR_TYPE_AUTO:
return 'AUTO';
case ClassMetadataInfo::GENERATOR_TYPE_SEQUENCE:
return 'SEQUENCE';
case ClassMetadataInfo::GENERATOR_TYPE_TABLE:
return 'TABLE';
case ClassMetadataInfo::GENERATOR_TYPE_IDENTITY:
return 'IDENTITY';
case ClassMetadataInfo::GENERATOR_TYPE_NONE:
return 'NONE';
default:
throw new \InvalidArgumentException('Invalid provided IdGeneratorType: ' . $type);
if ( ! isset(self::$generatorStrategyMap[$type])) {
throw new \InvalidArgumentException(sprintf('Invalid provided IdGeneratorType: %s', $type));
}
return self::$generatorStrategyMap[$type];
}
}

View File

@@ -76,10 +76,12 @@ class XmlExporter extends AbstractExporter
}
if ($metadata->discriminatorColumn) {
$discriminatorColumnXml = $root->addChild('discriminiator-column');
$discriminatorColumnXml = $root->addChild('discriminator-column');
$discriminatorColumnXml->addAttribute('name', $metadata->discriminatorColumn['name']);
$discriminatorColumnXml->addAttribute('type', $metadata->discriminatorColumn['type']);
$discriminatorColumnXml->addAttribute('length', $metadata->discriminatorColumn['length']);
if (isset($metadata->discriminatorColumn['length'])) {
$discriminatorColumnXml->addAttribute('length', $metadata->discriminatorColumn['length']);
}
}
if ($metadata->discriminatorMap) {
@@ -109,9 +111,9 @@ class XmlExporter extends AbstractExporter
if (isset($metadata->table['uniqueConstraints'])) {
$uniqueConstraintsXml = $root->addChild('unique-constraints');
foreach ($metadata->table['uniqueConstraints'] as $unique) {
foreach ($metadata->table['uniqueConstraints'] as $name => $unique) {
$uniqueConstraintXml = $uniqueConstraintsXml->addChild('unique-constraint');
$uniqueConstraintXml->addAttribute('name', $unique['name']);
$uniqueConstraintXml->addAttribute('name', $name);
$uniqueConstraintXml->addAttribute('columns', implode(',', $unique['columns']));
}
}
@@ -180,6 +182,9 @@ class XmlExporter extends AbstractExporter
if (isset($field['columnDefinition'])) {
$fieldXml->addAttribute('column-definition', $field['columnDefinition']);
}
if (isset($field['nullable'])) {
$fieldXml->addAttribute('nullable', $field['nullable'] ? 'true' : 'false');
}
}
}
$orderMap = array(

View File

@@ -13,8 +13,9 @@
namespace Doctrine\ORM\Tools\Pagination;
use Doctrine\ORM\Query\SqlWalker,
Doctrine\ORM\Query\AST\SelectStatement;
use Doctrine\ORM\Query\SqlWalker;
use Doctrine\ORM\Query\AST\SelectStatement;
use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
/**
* Wrap the query in order to select root entity IDs for pagination
@@ -85,7 +86,7 @@ class LimitSubqueryOutputWalker extends SqlWalker
*/
public function walkSelectStatement(SelectStatement $AST)
{
$sql = parent::walkSelectStatement($AST);
$innerSql = parent::walkSelectStatement($AST);
// Find out the SQL alias of the identifier column of the root entity
// It may be possible to make this work with multiple root entities but that
@@ -133,7 +134,12 @@ class LimitSubqueryOutputWalker extends SqlWalker
// Build the counter query
$sql = sprintf('SELECT DISTINCT %s FROM (%s) dctrn_result',
implode(', ', $sqlIdentifier), $sql);
implode(', ', $sqlIdentifier), $innerSql);
if ($this->platform instanceof PostgreSqlPlatform) {
//http://www.doctrine-project.org/jira/browse/DDC-1958
$this->getPostgresqlSql($AST, $sqlIdentifier, $innerSql, $sql);
}
// Apply the limit and offset
$sql = $this->platform->modifyLimitQuery(
@@ -150,4 +156,47 @@ class LimitSubqueryOutputWalker extends SqlWalker
return $sql;
}
/**
* Generate new SQL for postgresql if necessary
*
* @param SelectStatement $AST
* @param array sqlIdentifier
* @param string $sql
*/
public function getPostgresqlSql(SelectStatement $AST, array $sqlIdentifier, $innerSql, &$sql)
{
// For every order by, find out the SQL alias by inspecting the ResultSetMapping
$sqlOrderColumns = array();
$orderBy = array();
if (isset($AST->orderByClause)) {
foreach ($AST->orderByClause->orderByItems as $item) {
$possibleAliases = array_keys($this->rsm->fieldMappings, $item->expression->field);
foreach ($possibleAliases as $alias) {
if ($this->rsm->columnOwnerMap[$alias] == $item->expression->identificationVariable) {
$sqlOrderColumns[] = $alias;
$orderBy[] = $alias . ' ' . $item->type;
break;
}
}
}
//remove identifier aliases
$sqlOrderColumns = array_diff($sqlOrderColumns, $sqlIdentifier);
}
//we don't need orderBy in inner query
//However at least on 5.4.6 I'm getting a segmentation fault and thus we don't clear it for now
/*$AST->orderByClause = null;
$innerSql = parent::walkSelectStatement($AST);*/
if (count($orderBy)) {
$sql = sprintf(
'SELECT DISTINCT %s FROM (%s) dctrn_result ORDER BY %s',
implode(', ', array_merge($sqlIdentifier, $sqlOrderColumns)),
$innerSql,
implode(', ', $orderBy)
);
}
}
}

View File

@@ -174,18 +174,15 @@ class Paginator implements \Countable, \IteratorAggregate
$whereInQuery = $this->cloneQuery($this->query);
// don't do this for an empty id array
if (count($ids) > 0) {
$namespace = WhereInWalker::PAGINATOR_ID_ALIAS;
$whereInQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\WhereInWalker'));
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, count($ids));
$whereInQuery->setFirstResult(null)->setMaxResults(null);
foreach ($ids as $i => $id) {
$i++;
$whereInQuery->setParameter("{$namespace}_{$i}", $id);
}
if (count($ids) == 0) {
return new \ArrayIterator(array());
}
$whereInQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\WhereInWalker'));
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, count($ids));
$whereInQuery->setFirstResult(null)->setMaxResults(null);
$whereInQuery->setParameter(WhereInWalker::PAGINATOR_ID_ALIAS, $ids);
$result = $whereInQuery->getResult($this->query->getHydrationMode());
} else {
$result = $this->cloneQuery($this->query)

View File

@@ -102,11 +102,8 @@ class WhereInWalker extends TreeWalkerAdapter
array($pathExpression)
);
$expression = new InExpression($arithmeticExpression);
$ns = self::PAGINATOR_ID_ALIAS;
$expression->literals[] = new InputParameter(":" . self::PAGINATOR_ID_ALIAS);
for ($i = 1; $i <= $count; $i++) {
$expression->literals[] = new InputParameter(":{$ns}_$i");
}
} else {
$expression = new NullComparisonExpression($pathExpression);
$expression->not = false;

View File

@@ -73,6 +73,7 @@ class ResolveTargetEntityListener
$newMapping = $this->resolveTargetEntities[$mapping['targetEntity']];
$newMapping = array_replace_recursive($mapping, $newMapping);
$newMapping['fieldName'] = $mapping['fieldName'];
unset($classMetadata->associationMappings[$mapping['fieldName']]);
switch ($mapping['type']) {

View File

@@ -385,6 +385,24 @@ class SchemaTool
}
if (isset($mapping['options'])) {
if (isset($mapping['options']['comment'])) {
$options['comment'] = $mapping['options']['comment'];
unset($mapping['options']['comment']);
}
if (isset($mapping['options']['unsigned'])) {
$options['unsigned'] = $mapping['options']['unsigned'];
unset($mapping['options']['unsigned']);
}
if (isset($mapping['options']['fixed'])) {
$options['fixed'] = $mapping['options']['fixed'];
unset($mapping['options']['fixed']);
}
$options['customSchemaOptions'] = $mapping['options'];
}
@@ -546,6 +564,11 @@ class SchemaTool
if (isset($joinColumn['nullable'])) {
$columnOptions['notnull'] = !$joinColumn['nullable'];
}
if (isset($fieldMapping['options'])) {
$columnOptions['options'] = $fieldMapping['options'];
}
if ($fieldMapping['type'] == "string" && isset($fieldMapping['length'])) {
$columnOptions['length'] = $fieldMapping['length'];
} else if ($fieldMapping['type'] == "decimal") {

View File

@@ -63,6 +63,9 @@ class Setup
* Use this method to register all autoloaders for a setup where Doctrine is installed
* though {@link http://pear.doctrine-project.org}.
*
* This method registers autoloaders for both Doctrine and Symfony top
* level namespaces.
*
* @return void
*/
static public function registerAutoloadPEAR()
@@ -74,15 +77,8 @@ class Setup
$loader = new ClassLoader("Doctrine");
$loader->register();
$parts = explode(PATH_SEPARATOR, get_include_path());
foreach ($parts as $includePath) {
if ($includePath != "." && file_exists($includePath . "/Doctrine")) {
$loader = new ClassLoader("Symfony\Component", $includePath . "/Doctrine");
$loader->register();
return;
}
}
$loader = new ClassLoader("Symfony");
$loader->register();
}
/**

View File

@@ -206,7 +206,7 @@ class UnitOfWork implements PropertyChangedListener
/**
* The EventManager used for dispatching events.
*
* @var EventManager
* @var \Doctrine\Common\EventManager
*/
private $evm;
@@ -256,6 +256,9 @@ class UnitOfWork implements PropertyChangedListener
* 5) All entity deletions
*
* @param null|object|array $entity
*
* @throws \Exception
*
* @return void
*/
public function commit($entity = null)
@@ -390,6 +393,9 @@ class UnitOfWork implements PropertyChangedListener
* 4. Only if entity is properly managed.
*
* @param object $entity
*
* @throws \InvalidArgumentException
*
* @return void
*/
private function computeSingleEntityChangeSet($entity)
@@ -440,6 +446,8 @@ class UnitOfWork implements PropertyChangedListener
/**
* Gets the changeset for an entity.
*
* @param object $entity
*
* @return array
*/
public function getEntityChangeSet($entity)
@@ -708,8 +716,13 @@ class UnitOfWork implements PropertyChangedListener
/**
* Computes the changes of an association.
*
* @param AssociationMapping $assoc
* @param array $assoc
* @param mixed $value The value of the association.
*
* @throws ORMInvalidArgumentException
* @throws ORMException
*
* @return void
*/
private function computeAssociationChanges($assoc, $value)
{
@@ -779,6 +792,10 @@ class UnitOfWork implements PropertyChangedListener
}
}
/**
* @param ClassMetadata $class
* @param object $entity
*/
private function persistNew($class, $entity)
{
$oid = spl_object_hash($entity);
@@ -822,7 +839,8 @@ class UnitOfWork implements PropertyChangedListener
* @ignore
* @param ClassMetadata $class The class descriptor of the entity.
* @param object $entity The entity for which to (re)calculate the change set.
* @throws InvalidArgumentException If the passed entity is not MANAGED.
*
* @throws ORMInvalidArgumentException If the passed entity is not MANAGED.
*/
public function recomputeSingleEntityChangeSet(ClassMetadata $class, $entity)
{
@@ -962,7 +980,7 @@ class UnitOfWork implements PropertyChangedListener
);
}
if ($this->entityChangeSets[$oid]) {
if (!empty($this->entityChangeSets[$oid])) {
$persister->update($entity);
}
@@ -1025,6 +1043,8 @@ class UnitOfWork implements PropertyChangedListener
/**
* Gets the commit order.
*
* @param array $entityChangeSet
*
* @return array
*/
private function getCommitOrder(array $entityChangeSet = null)
@@ -1099,6 +1119,9 @@ class UnitOfWork implements PropertyChangedListener
* If the entity already has an identifier, it will be added to the identity map.
*
* @param object $entity The entity to schedule for insertion.
*
* @throws ORMInvalidArgumentException
* @throws \InvalidArgumentException
*/
public function scheduleForInsert($entity)
{
@@ -1134,6 +1157,7 @@ class UnitOfWork implements PropertyChangedListener
* Checks whether an entity is scheduled for insertion.
*
* @param object $entity
*
* @return boolean
*/
public function isScheduledForInsert($entity)
@@ -1145,6 +1169,8 @@ class UnitOfWork implements PropertyChangedListener
* Schedules an entity for being updated.
*
* @param object $entity The entity to schedule for being updated.
*
* @throws ORMInvalidArgumentException
*/
public function scheduleForUpdate($entity)
{
@@ -1194,6 +1220,7 @@ class UnitOfWork implements PropertyChangedListener
* at commit time.
*
* @param object $entity
*
* @return boolean
*/
public function isScheduledForUpdate($entity)
@@ -1206,6 +1233,7 @@ class UnitOfWork implements PropertyChangedListener
* Checks whether an entity is registered to be checked in the unit of work.
*
* @param object $entity
*
* @return boolean
*/
public function isScheduledForDirtyCheck($entity)
@@ -1256,6 +1284,7 @@ class UnitOfWork implements PropertyChangedListener
* of work.
*
* @param object $entity
*
* @return boolean
*/
public function isScheduledForDelete($entity)
@@ -1267,6 +1296,7 @@ class UnitOfWork implements PropertyChangedListener
* Checks whether an entity is scheduled for insertion, update or deletion.
*
* @param $entity
*
* @return boolean
*/
public function isEntityScheduled($entity)
@@ -1286,6 +1316,9 @@ class UnitOfWork implements PropertyChangedListener
*
* @ignore
* @param object $entity The entity to register.
*
* @throws ORMInvalidArgumentException
*
* @return boolean TRUE if the registration was successful, FALSE if the identity of
* the entity in question is already managed.
*/
@@ -1317,6 +1350,7 @@ class UnitOfWork implements PropertyChangedListener
* This parameter can be set to improve performance of entity state detection
* by potentially avoiding a database lookup if the distinction between NEW and DETACHED
* is either known or does not matter for the caller of the method.
*
* @return int The entity state.
*/
public function getEntityState($entity, $assume = null)
@@ -1392,6 +1426,9 @@ class UnitOfWork implements PropertyChangedListener
*
* @ignore
* @param object $entity
*
* @throws ORMInvalidArgumentException
*
* @return boolean
*/
public function removeFromIdentityMap($entity)
@@ -1425,6 +1462,7 @@ class UnitOfWork implements PropertyChangedListener
* @ignore
* @param string $idHash
* @param string $rootClassName
*
* @return object
*/
public function getByIdHash($idHash, $rootClassName)
@@ -1440,6 +1478,7 @@ class UnitOfWork implements PropertyChangedListener
* @ignore
* @param string $idHash
* @param string $rootClassName
*
* @return mixed The found entity or FALSE.
*/
public function tryGetByIdHash($idHash, $rootClassName)
@@ -1455,6 +1494,7 @@ class UnitOfWork implements PropertyChangedListener
* Checks whether an entity is registered in the identity map of this UnitOfWork.
*
* @param object $entity
*
* @return boolean
*/
public function isInIdentityMap($entity)
@@ -1482,6 +1522,7 @@ class UnitOfWork implements PropertyChangedListener
* @ignore
* @param string $idHash
* @param string $rootClassName
*
* @return boolean
*/
public function containsIdHash($idHash, $rootClassName)
@@ -1509,6 +1550,9 @@ class UnitOfWork implements PropertyChangedListener
*
* @param object $entity The entity to persist.
* @param array $visited The already visited entities.
*
* @throws ORMInvalidArgumentException
* @throws UnexpectedValueException
*/
private function doPersist($entity, array &$visited)
{
@@ -1578,7 +1622,9 @@ class UnitOfWork implements PropertyChangedListener
*
* @param object $entity The entity to delete.
* @param array $visited The map of the already visited entities.
* @throws InvalidArgumentException If the instance is a detached entity.
*
* @throws ORMInvalidArgumentException If the instance is a detached entity.
* @throws UnexpectedValueException
*/
private function doRemove($entity, array &$visited)
{
@@ -1627,10 +1673,12 @@ class UnitOfWork implements PropertyChangedListener
* Merges the state of the given detached entity into this UnitOfWork.
*
* @param object $entity
* @return object The managed copy of the entity.
*
* @throws OptimisticLockException If the entity uses optimistic locking through a version
* attribute and the version check against the managed copy fails.
*
* @return object The managed copy of the entity.
*
* @todo Require active transaction!? OptimisticLockException may result in undefined state!?
*/
public function merge($entity)
@@ -1645,10 +1693,15 @@ class UnitOfWork implements PropertyChangedListener
*
* @param object $entity
* @param array $visited
* @return object The managed copy of the entity.
* @param object $prevManagedCopy
* @param array $assoc
*
* @throws OptimisticLockException If the entity uses optimistic locking through a version
* attribute and the version check against the managed copy fails.
* @throws InvalidArgumentException If the entity instance is NEW.
* @throws ORMInvalidArgumentException If the entity instance is NEW.
* @throws EntityNotFoundException
*
* @return object The managed copy of the entity.
*/
private function doMerge($entity, array &$visited, $prevManagedCopy = null, $assoc = null)
{
@@ -1895,6 +1948,7 @@ class UnitOfWork implements PropertyChangedListener
* any local, unpersisted changes.
*
* @param object $entity The entity to refresh.
*
* @throws InvalidArgumentException If the entity is not MANAGED.
*/
public function refresh($entity)
@@ -1909,7 +1963,8 @@ class UnitOfWork implements PropertyChangedListener
*
* @param object $entity The entity to refresh.
* @param array $visited The already visited entities during cascades.
* @throws InvalidArgumentException If the entity is not MANAGED.
*
* @throws ORMInvalidArgumentException If the entity is not MANAGED.
*/
private function doRefresh($entity, array &$visited)
{
@@ -2060,7 +2115,8 @@ class UnitOfWork implements PropertyChangedListener
*
* @param object $entity
* @param array $visited
* @param array $insertNow
*
* @return void
*/
private function cascadePersist($entity, array &$visited)
{
@@ -2144,6 +2200,12 @@ class UnitOfWork implements PropertyChangedListener
* @param object $entity
* @param int $lockMode
* @param int $lockVersion
*
* @throws ORMInvalidArgumentException
* @throws TransactionRequiredException
* @throws OptimisticLockException
*
* @return void
*/
public function lock($entity, $lockMode, $lockVersion = null)
{
@@ -2279,13 +2341,20 @@ class UnitOfWork implements PropertyChangedListener
$this->collectionDeletions[$coid] = $coll;
}
/**
* @param PersistentCollection $coll
*
* @return bool
*/
public function isCollectionScheduledForDeletion(PersistentCollection $coll)
{
return isset($this->collectionsDeletions[spl_object_hash($coll)]);
return isset($this->collectionDeletions[spl_object_hash($coll)]);
}
/**
* @param ClassMetadata $class
*
* @return \Doctrine\Common\Persistence\ObjectManagerAware|object
*/
private function newInstance($class)
{
@@ -2306,6 +2375,7 @@ class UnitOfWork implements PropertyChangedListener
* @param string $className The name of the entity class.
* @param array $data The data for the entity.
* @param array $hints Any hints to account for during reconstitution/lookup of the entity.
*
* @return object The managed entity instance.
* @internal Highly performance-sensitive method.
*
@@ -2501,6 +2571,10 @@ class UnitOfWork implements PropertyChangedListener
$newValueOid = spl_object_hash($newValue);
$this->entityIdentifiers[$newValueOid] = $associatedId;
$this->identityMap[$targetClass->rootEntityName][$relatedIdHash] = $newValue;
if ($newValue instanceof NotifyPropertyChanged) {
$newValue->addPropertyChangedListener($this);
}
$this->entityStates[$newValueOid] = self::STATE_MANAGED;
// make sure that when an proxy is then finally loaded, $this->originalEntityData is set also!
break;
@@ -2578,7 +2652,9 @@ class UnitOfWork implements PropertyChangedListener
/**
* Initializes (loads) an uninitialized persistent collection of an entity.
*
* @param PeristentCollection $collection The collection to initialize.
* @param \Doctrine\ORM\PersistentCollection $collection The collection to initialize.
*
* @return void
* @todo Maybe later move to EntityManager#initialize($proxyOrCollection). See DDC-733.
*/
public function loadCollection(PersistentCollection $collection)
@@ -2612,6 +2688,7 @@ class UnitOfWork implements PropertyChangedListener
* present at the time the entity was reconstituted from the database.
*
* @param object $entity
*
* @return array
*/
public function getOriginalEntityData($entity)
@@ -2654,6 +2731,7 @@ class UnitOfWork implements PropertyChangedListener
* order as the identifier field names as returned by ClassMetadata#getIdentifierFieldNames().
*
* @param object $entity
*
* @return array The identifier values.
*/
public function getEntityIdentifier($entity)
@@ -2667,6 +2745,7 @@ class UnitOfWork implements PropertyChangedListener
*
* @param mixed $id The entity identifier to look for.
* @param string $rootClassName The name of the root class of the mapped entity hierarchy.
*
* @return mixed Returns the entity with the specified identifier if it exists in
* this UnitOfWork, FALSE otherwise.
*/
@@ -2757,9 +2836,9 @@ class UnitOfWork implements PropertyChangedListener
/**
* Gets a collection persister for a collection-valued association.
*
* @param AssociationMapping $association
* @param array $association
*
* @return AbstractCollectionPersister
* @return \Doctrine\ORM\Persisters\AbstractCollectionPersister
*/
public function getCollectionPersister(array $association)
{
@@ -2901,6 +2980,7 @@ class UnitOfWork implements PropertyChangedListener
* Helper method to initialize a lazy loading proxy or persistent collection.
*
* @param object
*
* @return void
*/
public function initializeObject($obj)
@@ -2920,6 +3000,7 @@ class UnitOfWork implements PropertyChangedListener
* Helper method to show an object as string.
*
* @param object $obj
*
* @return string
*/
private static function objToStr($obj)
@@ -2931,10 +3012,13 @@ class UnitOfWork implements PropertyChangedListener
* Marks an entity as read-only so that it will not be considered for updates during UnitOfWork#commit().
*
* This operation cannot be undone as some parts of the UnitOfWork now keep gathering information
* on this object that might be necessary to perform a correct udpate.
* on this object that might be necessary to perform a correct update.
*
*
* @param object $object
*
* @throws ORMInvalidArgumentException
*
* @throws \InvalidArgumentException
* @param $object
* @return void
*/
public function markReadOnly($object)
@@ -2949,9 +3033,11 @@ class UnitOfWork implements PropertyChangedListener
/**
* Is this entity read only?
*
* @throws \InvalidArgumentException
* @param $object
* @return void
* @param object $object
*
* @throws ORMInvalidArgumentException
*
* @return bool
*/
public function isReadOnly($object)
{

View File

@@ -36,7 +36,7 @@ class Version
/**
* Current Doctrine Version
*/
const VERSION = '2.4.0-DEV';
const VERSION = '2.3.2';
/**
* Compares a Doctrine version with the current one.

View File

@@ -10,7 +10,7 @@ namespace Doctrine\Tests\Mocks;
class StatementMock implements \IteratorAggregate, \Doctrine\DBAL\Driver\Statement
{
public function bindValue($param, $value, $type = null){}
public function bindParam($column, &$variable, $type = null){}
public function bindParam($column, &$variable, $type = null, $length = null){}
public function errorCode(){}
public function errorInfo(){}
public function execute($params = null){}

View File

@@ -22,6 +22,31 @@ class DatabaseDriverTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->_sm = $this->_em->getConnection()->getSchemaManager();
}
/**
* @group DDC-2059
*/
public function testIssue2059()
{
if (!$this->_em->getConnection()->getDatabasePlatform()->supportsForeignKeyConstraints()) {
$this->markTestSkipped('Platform does not support foreign keys.');
}
$user = new \Doctrine\DBAL\Schema\Table("ddc2059_user");
$user->addColumn('id', 'integer');
$user->setPrimaryKey(array('id'));
$project = new \Doctrine\DBAL\Schema\Table("ddc2059_project");
$project->addColumn('id', 'integer');
$project->addColumn('user_id', 'integer');
$project->addColumn('user', 'string');
$project->setPrimaryKey(array('id'));
$project->addForeignKeyConstraint('ddc2059_user', array('user_id'), array('id'));
$metadata = $this->convertToClassMetadata(array($project, $user), array());
$this->assertTrue(isset($metadata['Ddc2059Project']->fieldMappings['user']));
$this->assertTrue(isset($metadata['Ddc2059Project']->associationMappings['user2']));
}
public function testLoadMetadataFromDatabase()
{
if (!$this->_em->getConnection()->getDatabasePlatform()->supportsForeignKeyConstraints()) {

View File

@@ -0,0 +1,87 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Tests\ORM\Functional;
use Doctrine\Tests\Models\Generic\DateTimeModel;
use Doctrine\Common\Collections\Criteria;
/**
* @author Josiah <josiah@jjs.id.au>
*/
class EntityRepositoryCriteriaTest extends \Doctrine\Tests\OrmFunctionalTestCase
{
protected function setUp()
{
$this->useModelSet('generic');
parent::setUp();
}
public function tearDown()
{
if ($this->_em) {
$this->_em->getConfiguration()->setEntityNamespaces(array());
}
parent::tearDown();
}
public function loadFixture()
{
$today = new DateTimeModel();
$today->datetime =
$today->date =
$today->time =
new \DateTime('today');
$this->_em->persist($today);
$tomorrow = new DateTimeModel();
$tomorrow->datetime =
$tomorrow->date =
$tomorrow->time =
new \DateTime('tomorrow');
$this->_em->persist($tomorrow);
$yesterday = new DateTimeModel();
$yesterday->datetime =
$yesterday->date =
$yesterday->time =
new \DateTime('yesterday');
$this->_em->persist($yesterday);
$this->_em->flush();
unset($today);
unset($tomorrow);
unset($yesterday);
$this->_em->clear();
}
public function testLteDateComparison()
{
$this->loadFixture();
$repository = $this->_em->getRepository('Doctrine\Tests\Models\Generic\DateTimeModel');
$dates = $repository->matching(new Criteria(
Criteria::expr()->lte('datetime', new \DateTime('today'))
));
$this->assertEquals(2, count($dates));
}
}

View File

@@ -344,6 +344,20 @@ class EntityRepositoryTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertEquals($addressId, $address->id);
}
/**
* @group DDC-1241
*/
public function testFindOneByOrderBy()
{
$this->loadFixture();
$repos = $this->_em->getRepository('Doctrine\Tests\Models\CMS\CmsUser');
$userAsc = $repos->findOneBy(array(), array("username" => "ASC"));
$userDesc = $repos->findOneBy(array(), array("username" => "DESC"));
$this->assertNotSame($userAsc, $userDesc);
}
/**
* @group DDC-817
*/

View File

@@ -173,6 +173,30 @@ class OneToManyBidirectionalAssociationTest extends \Doctrine\Tests\OrmFunctiona
$this->assertInstanceOf('Doctrine\Common\Collections\Collection', $results);
$this->assertEquals(2, count($results));
}
public function testMatchingBis()
{
$this->_createFixture();
$product = $this->_em->find('Doctrine\Tests\Models\ECommerce\ECommerceProduct', $this->product->getId());
$features = $product->getFeatures();
$thirdFeature = new ECommerceFeature();
$thirdFeature->setDescription('Third feature');
$product->addFeature($thirdFeature);
$results = $features->matching(new Criteria(
Criteria::expr()->eq('description', 'Third feature')
));
$this->assertInstanceOf('Doctrine\Common\Collections\Collection', $results);
$this->assertCount(1, $results);
$results = $features->matching(new Criteria());
$this->assertInstanceOf('Doctrine\Common\Collections\Collection', $results);
$this->assertCount(3, $results);
}
private function _createFixture()
{

View File

@@ -453,6 +453,22 @@ class SQLFilterTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertEquals(1, count($query->getResult()));
}
public function testWhereOrFilter()
{
$this->loadFixtureData();
$query = $this->_em->createQuery('select ug from Doctrine\Tests\Models\CMS\CmsGroup ug WHERE 1=1 OR 1=1');
// We get two users before enabling the filter
$this->assertEquals(2, count($query->getResult()));
$conf = $this->_em->getConfiguration();
$conf->addFilter("group_prefix", "\Doctrine\Tests\ORM\Functional\CMSGroupPrefixFilter");
$this->_em->getFilters()->enable("group_prefix")->setParameter("prefix", "bar_%", DBALType::STRING);
// We get one user after enabling the filter
$this->assertEquals(1, count($query->getResult()));
}
private function loadLazyFixtureData()
{

View File

@@ -29,12 +29,12 @@ class MySqlSchemaToolTest extends \Doctrine\Tests\OrmFunctionalTestCase
$tool = new SchemaTool($this->_em);
$sql = $tool->getCreateSchemaSql($classes);
$this->assertEquals("CREATE TABLE cms_groups (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(50) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE = InnoDB", $sql[0]);
$this->assertEquals("CREATE TABLE cms_users (id INT AUTO_INCREMENT NOT NULL, email_id INT DEFAULT NULL, status VARCHAR(50) DEFAULT NULL, username VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, UNIQUE INDEX UNIQ_3AF03EC5F85E0677 (username), UNIQUE INDEX UNIQ_3AF03EC5A832C1C9 (email_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE = InnoDB", $sql[1]);
$this->assertEquals("CREATE TABLE cms_users_groups (user_id INT NOT NULL, group_id INT NOT NULL, INDEX IDX_7EA9409AA76ED395 (user_id), INDEX IDX_7EA9409AFE54D947 (group_id), PRIMARY KEY(user_id, group_id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE = InnoDB", $sql[2]);
$this->assertEquals("CREATE TABLE cms_addresses (id INT AUTO_INCREMENT NOT NULL, user_id INT DEFAULT NULL, country VARCHAR(50) NOT NULL, zip VARCHAR(50) NOT NULL, city VARCHAR(50) NOT NULL, UNIQUE INDEX UNIQ_ACAC157BA76ED395 (user_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE = InnoDB", $sql[3]);
$this->assertEquals("CREATE TABLE cms_emails (id INT AUTO_INCREMENT NOT NULL, email VARCHAR(250) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE = InnoDB", $sql[4]);
$this->assertEquals("CREATE TABLE cms_phonenumbers (phonenumber VARCHAR(50) NOT NULL, user_id INT DEFAULT NULL, INDEX IDX_F21F790FA76ED395 (user_id), PRIMARY KEY(phonenumber)) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE = InnoDB", $sql[5]);
$this->assertEquals("CREATE TABLE cms_groups (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(50) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[0]);
$this->assertEquals("CREATE TABLE cms_users (id INT AUTO_INCREMENT NOT NULL, email_id INT DEFAULT NULL, status VARCHAR(50) DEFAULT NULL, username VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, UNIQUE INDEX UNIQ_3AF03EC5F85E0677 (username), UNIQUE INDEX UNIQ_3AF03EC5A832C1C9 (email_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[1]);
$this->assertEquals("CREATE TABLE cms_users_groups (user_id INT NOT NULL, group_id INT NOT NULL, INDEX IDX_7EA9409AA76ED395 (user_id), INDEX IDX_7EA9409AFE54D947 (group_id), PRIMARY KEY(user_id, group_id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[2]);
$this->assertEquals("CREATE TABLE cms_addresses (id INT AUTO_INCREMENT NOT NULL, user_id INT DEFAULT NULL, country VARCHAR(50) NOT NULL, zip VARCHAR(50) NOT NULL, city VARCHAR(50) NOT NULL, UNIQUE INDEX UNIQ_ACAC157BA76ED395 (user_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[3]);
$this->assertEquals("CREATE TABLE cms_emails (id INT AUTO_INCREMENT NOT NULL, email VARCHAR(250) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[4]);
$this->assertEquals("CREATE TABLE cms_phonenumbers (phonenumber VARCHAR(50) NOT NULL, user_id INT DEFAULT NULL, INDEX IDX_F21F790FA76ED395 (user_id), PRIMARY KEY(phonenumber)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[5]);
$this->assertEquals("ALTER TABLE cms_users ADD CONSTRAINT FK_3AF03EC5A832C1C9 FOREIGN KEY (email_id) REFERENCES cms_emails (id)", $sql[6]);
$this->assertEquals("ALTER TABLE cms_users_groups ADD CONSTRAINT FK_7EA9409AA76ED395 FOREIGN KEY (user_id) REFERENCES cms_users (id)", $sql[7]);
$this->assertEquals("ALTER TABLE cms_users_groups ADD CONSTRAINT FK_7EA9409AFE54D947 FOREIGN KEY (group_id) REFERENCES cms_groups (id)", $sql[8]);
@@ -54,7 +54,7 @@ class MySqlSchemaToolTest extends \Doctrine\Tests\OrmFunctionalTestCase
$sql = $tool->getCreateSchemaSql($classes);
$this->assertEquals(1, count($sql));
$this->assertEquals("CREATE TABLE decimal_model (id INT AUTO_INCREMENT NOT NULL, `decimal` NUMERIC(5, 2) NOT NULL, `high_scale` NUMERIC(14, 4) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE = InnoDB", $sql[0]);
$this->assertEquals("CREATE TABLE decimal_model (id INT AUTO_INCREMENT NOT NULL, `decimal` NUMERIC(5, 2) NOT NULL, `high_scale` NUMERIC(14, 4) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[0]);
}
public function testGetCreateSchemaSql3()
@@ -67,7 +67,7 @@ class MySqlSchemaToolTest extends \Doctrine\Tests\OrmFunctionalTestCase
$sql = $tool->getCreateSchemaSql($classes);
$this->assertEquals(1, count($sql));
$this->assertEquals("CREATE TABLE boolean_model (id INT AUTO_INCREMENT NOT NULL, booleanField TINYINT(1) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE = InnoDB", $sql[0]);
$this->assertEquals("CREATE TABLE boolean_model (id INT AUTO_INCREMENT NOT NULL, booleanField TINYINT(1) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[0]);
}
/**

View File

@@ -0,0 +1,153 @@
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\Common\NotifyPropertyChanged,
Doctrine\Common\PropertyChangedListener;
require_once __DIR__ . '/../../../TestInit.php';
class DDC1690Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
protected function setUp() {
parent::setUp();
try {
$this->_schemaTool->createSchema(array(
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC1690Parent'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC1690Child')
));
} catch (\Exception $e) {
// Swallow all exceptions. We do not test the schema tool here.
}
}
public function testChangeTracking()
{
$parent = new DDC1690Parent();
$child = new DDC1690Child();
$parent->setName('parent');
$child->setName('child');
$parent->setChild($child);
$child->setParent($parent);
$this->_em->persist($parent);
$this->_em->persist($child);
$this->assertEquals(1, count($parent->listeners));
$this->assertEquals(1, count($child->listeners));
$this->_em->flush();
$this->_em->clear();
$this->assertEquals(1, count($parent->listeners));
$this->assertEquals(1, count($child->listeners));
$parentId = $parent->getId();
$childId = $child->getId();
unset($parent, $child);
$parent = $this->_em->find(__NAMESPACE__.'\DDC1690Parent', $parentId);
$child = $this->_em->find(__NAMESPACE__.'\DDC1690Child', $childId);
$this->assertEquals(1, count($parent->listeners));
$this->assertEquals(1, count($child->listeners));
unset($parent, $child);
$parent = $this->_em->find(__NAMESPACE__.'\DDC1690Parent', $parentId);
$child = $parent->getChild();
$this->assertEquals(1, count($parent->listeners));
$this->assertEquals(1, count($child->listeners));
unset($parent, $child);
$child = $this->_em->find(__NAMESPACE__.'\DDC1690Child', $childId);
$parent = $child->getParent();
$this->assertEquals(1, count($parent->listeners));
$this->assertEquals(1, count($child->listeners));
}
}
class NotifyBaseEntity implements NotifyPropertyChanged {
public $listeners = array();
public function addPropertyChangedListener(PropertyChangedListener $listener) {
if (!in_array($listener, $this->listeners)) {
$this->listeners[] = $listener;
}
}
protected function onPropertyChanged($propName, $oldValue, $newValue) {
if ($this->listeners) {
foreach ($this->listeners as $listener) {
$listener->propertyChanged($this, $propName, $oldValue, $newValue);
}
}
}
}
/** @Entity @ChangeTrackingPolicy("NOTIFY") */
class DDC1690Parent extends NotifyBaseEntity {
/** @Id @Column(type="integer") @GeneratedValue */
private $id;
/** @Column */
private $name;
/** @OneToOne(targetEntity="DDC1690Child") */
private $child;
function getId() {
return $this->id;
}
function getName() {
return $this->name;
}
function setName($name) {
$this->onPropertyChanged('name', $this->name, $name);
$this->name = $name;
}
function setChild($child) {
$this->child = $child;
}
function getChild() {
return $this->child;
}
}
/** @Entity */
class DDC1690Child extends NotifyBaseEntity {
/** @Id @Column(type="integer") @GeneratedValue */
private $id;
/** @Column */
private $name;
/** @OneToOne(targetEntity="DDC1690Parent", mappedBy="child") */
private $parent;
function getId() {
return $this->id;
}
function getName() {
return $this->name;
}
function setName($name) {
$this->onPropertyChanged('name', $this->name, $name);
$this->name = $name;
}
function setParent($parent) {
$this->parent = $parent;
}
function getParent() {
return $this->parent;
}
}

View File

@@ -5,8 +5,6 @@ namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\Tests\Models\Quote\Group;
use Doctrine\Tests\Models\Quote\User;
require_once __DIR__ . '/../../../TestInit.php';
/**
* @group DDC-1845
* @group DDC-1885
@@ -170,4 +168,4 @@ class DDC1885Test extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertInstanceOf('Doctrine\Tests\Models\Quote\Group', $user->getGroups()->get(0));
$this->assertInstanceOf('Doctrine\Tests\Models\Quote\Group', $user->getGroups()->get(1));
}
}
}

View File

@@ -0,0 +1,62 @@
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\Tests\Models\CMS\CmsUser;
use Doctrine\Tests\Models\CMS\CmsGroup;
use Doctrine\ORM\Tools\Pagination\Paginator;
/**
* @group DDC-1918
*/
class DDC1918Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
protected function setUp()
{
$this->useModelSet('cms');
parent::setUp();
}
public function testLastPageCorrect()
{
$groups = array();
for ($i = 0; $i < 3; $i++) {
$group = new CmsGroup();
$group->name = "test";
$this->_em->persist($group);
$groups[] = $group;
}
for ($i = 0; $i < 10; $i++) {
$user = new CmsUser();
$user->username = "user$i";
$user->name = "user$i";
$user->status = "active";
$user->groups = $groups;
$this->_em->persist($user);
}
$this->_em->flush();
$query = $this->_em->createQuery('SELECT u, g FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.groups g');
$query->setFirstResult(6);
$query->setMaxResults(3);
$paginator = new Paginator($query, true);
$this->assertEquals(3, count(iterator_to_array($paginator)));
$query->setFirstResult(8);
$query->setMaxResults(3);
$paginator = new Paginator($query, true);
$this->assertEquals(2, count(iterator_to_array($paginator)));
$query->setFirstResult(10);
$query->setMaxResults(3);
$paginator = new Paginator($query, true);
$this->assertEquals(0, count(iterator_to_array($paginator)));
}
}

View File

@@ -1,182 +0,0 @@
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\Common\Collections\ArrayCollection;
require_once __DIR__ . '/../../../TestInit.php';
/**
* @group DDC-1925
* @group DDC-1210
*/
class DDC1925Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
public function testIssue()
{
$this->_schemaTool->createSchema(array(
$this->_em->getClassMetadata(__NAMESPACE__ . '\\DDC1925User'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\\DDC1925Product'),
));
$user = new DDC1925User();
$user->setTitle("Test User");
$this->_em->persist($user);
$product = new DDC1925Product();
$product->setTitle("Test product");
$this->_em->persist($product);
$this->_em->flush();
$product->addBuyer($user);
$this->_em->getUnitOfWork()->computeChangeSets();
$this->_em->persist($product);
$this->_em->flush();
}
}
/**
* @Table
* @Entity
*/
class DDC1925Product
{
/**
* @var integer $id
*
* @Column(name="id", type="integer")
* @Id
* @GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string $title
*
* @Column(name="title", type="string", length=255)
*/
private $title;
/**
* @ManyToMany(targetEntity="DDC1925User")
* @JoinTable(
* name="user_purchases",
* joinColumns={@JoinColumn(name="product_id", referencedColumnName="id")},
* inverseJoinColumns={@JoinColumn(name="user_id", referencedColumnName="id")}
* )
*/
private $buyers;
/**
* Default constructor
*/
public function __construct()
{
$this->buyers = new ArrayCollection();
}
/**
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* @param string $title
*/
public function setTitle($title)
{
$this->title = $title;
}
/**
* Get title
*
* @return string
*/
public function getTitle()
{
return $this->title;
}
/**
* @param string $buyers
*/
public function setBuyers($buyers)
{
$this->buyers = $buyers;
}
/**
* @return string
*/
public function getBuyers()
{
return $this->buyers;
}
/**
* @param DDC1925User $buyer
*/
public function addBuyer(DDC1925User $buyer)
{
$this->buyers[] = $buyer;
}
}
/**
* @Table
* @Entity
*/
class DDC1925User
{
/**
* @var integer
*
* @Column(name="id", type="integer")
* @Id
* @GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @Column(name="title", type="string", length=255)
*/
private $title;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set title
*
* @param string $title
*/
public function setTitle($title)
{
$this->title = $title;
}
/**
* Get title
*
* @return string
*/
public function getTitle()
{
return $this->title;
}
}

View File

@@ -0,0 +1,177 @@
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
require_once __DIR__ . '/../../../TestInit.php';
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Platforms\AbstractPlatform;
/**
* @group DDC-2012
*/
class DDC2012Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
protected function setUp()
{
parent::setUp();
Type::addType(DDC2012TsVectorType::MYTYPE, __NAMESPACE__ . '\DDC2012TsVectorType');
DDC2012TsVectorType::$calls = array();
$this->_schemaTool->createSchema(array(
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2012Item'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2012ItemPerson'),
));
}
public function testIssue()
{
$item = new DDC2012ItemPerson();
$item->tsv = array('word1', 'word2', 'word3');
$this->_em->persist($item);
$this->_em->flush();
$this->_em->clear();
$item = $this->_em->find(get_class($item), $item->id);
$this->assertArrayHasKey('convertToDatabaseValueSQL', DDC2012TsVectorType::$calls);
$this->assertArrayHasKey('convertToDatabaseValue', DDC2012TsVectorType::$calls);
$this->assertArrayHasKey('convertToPHPValue', DDC2012TsVectorType::$calls);
$this->assertCount(1, DDC2012TsVectorType::$calls['convertToDatabaseValueSQL']);
$this->assertCount(1, DDC2012TsVectorType::$calls['convertToDatabaseValue']);
$this->assertCount(1, DDC2012TsVectorType::$calls['convertToPHPValue']);
$this->assertInstanceOf(__NAMESPACE__ . '\DDC2012Item', $item);
$this->assertEquals(array('word1', 'word2', 'word3'), $item->tsv);
$item->tsv = array('word1', 'word2');
$this->_em->persist($item);
$this->_em->flush();
$this->_em->clear();
$item = $this->_em->find(get_class($item), $item->id);
$this->assertCount(2, DDC2012TsVectorType::$calls['convertToDatabaseValueSQL']);
$this->assertCount(2, DDC2012TsVectorType::$calls['convertToDatabaseValue']);
$this->assertCount(2, DDC2012TsVectorType::$calls['convertToPHPValue']);
$this->assertInstanceOf(__NAMESPACE__ . '\DDC2012Item', $item);
$this->assertEquals(array('word1', 'word2'), $item->tsv);
}
}
/**
* @Table(name="ddc2010_item")
* @Entity
* @InheritanceType("JOINED")
* @DiscriminatorColumn(name="type_id", type="smallint")
* @DiscriminatorMap({
* 1 = "DDC2012ItemPerson"
* })
*/
class DDC2012Item
{
/**
* @Id
* @GeneratedValue
* @Column(type="integer")
*/
public $id;
/**
* @Column(name="tsv", type="tsvector", nullable=true)
*/
public $tsv;
}
/**
* @Table(name="ddc2010_item_person")
* @Entity
*/
class DDC2012ItemPerson extends DDC2012Item
{
}
class DDC2012TsVectorType extends Type
{
const MYTYPE = 'tsvector';
public static $calls = array();
/**
* {@inheritdoc}
*/
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
{
return $platform->getVarcharTypeDeclarationSQL($fieldDeclaration);
}
/**
* {@inheritdoc}
*/
public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
if (is_array($value)) {
$value = implode(" ", $value);
}
self::$calls[__FUNCTION__][] = array(
'value' => $value,
'platform' => $platform,
);
return $value;
}
/**
* {@inheritdoc}
*/
public function convertToPHPValue($value, AbstractPlatform $platform)
{
self::$calls[__FUNCTION__][] = array(
'value' => $value,
'platform' => $platform,
);
return explode(" ", strtolower($value));
}
/**
* {@inheritdoc}
*/
public function convertToDatabaseValueSQL($sqlExpr, AbstractPlatform $platform)
{
self::$calls[__FUNCTION__][] = array(
'sqlExpr' => $sqlExpr,
'platform' => $platform,
);
// changed to upper expression to keep the test compatible with other Databases
//sprintf('to_tsvector(%s)', $sqlExpr);
return $platform->getUpperExpression($sqlExpr);
}
/**
* {@inheritdoc}
*/
public function canRequireSQLConversion()
{
return true;
}
/**
* {@inheritdoc}
*/
public function getName()
{
return self::MYTYPE;
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\PersistentCollection;
use Doctrine\Tests\Models\ECommerce\ECommerceCategory;
use Doctrine\Tests\Models\ECommerce\ECommerceProduct;
/**
* @group DDC-2074
*/
class DDC2074Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
public function testShouldNotScheduleDeletionOnClonedInstances()
{
$class = $this->_em->getClassMetadata('Doctrine\Tests\Models\ECommerce\ECommerceProduct');
$product = new ECommerceProduct();
$category = new ECommerceCategory();
$collection = new PersistentCollection($this->_em, $class, new ArrayCollection(array($category)));
$collection->setOwner($product, $class->associationMappings['categories']);
$uow = $this->_em->getUnitOfWork();
$clonedCollection = clone $collection;
$clonedCollection->clear();
$this->assertEquals(0, count($uow->getScheduledCollectionDeletions()));
}
}

View File

@@ -0,0 +1,62 @@
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
/**
* @group DDC-2175
*/
class DDC2175Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
protected function setUp()
{
parent::setUp();
$this->_schemaTool->createSchema(array(
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2175Entity'),
));
}
public function testIssue()
{
$entity = new DDC2175Entity();
$entity->field = "foo";
$this->_em->persist($entity);
$this->_em->flush();
$this->assertEquals(1, $entity->version);
$entity->field = "bar";
$this->_em->flush();
$this->assertEquals(2, $entity->version);
$entity->field = "baz";
$this->_em->flush();
$this->assertEquals(3, $entity->version);
}
}
/**
* @Entity
* @InheritanceType("JOINED")
* @DiscriminatorMap({"entity": "DDC2175Entity"})
*/
class DDC2175Entity
{
/**
* @Id @GeneratedValue @Column(type="integer")
*/
public $id;
/**
* @Column(type="string")
*/
public $field;
/**
* @Version
* @Column(type="integer")
*/
public $version;
}

View File

@@ -0,0 +1,52 @@
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\ORM\UnitOfWork;
require_once __DIR__ . '/../../../TestInit.php';
class DDC2182Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
public function testPassColumnOptionsToJoinColumns()
{
if ($this->_em->getConnection()->getDatabasePlatform()->getName() != 'mysql') {
$this->markTestSkipped("This test is useful for all databases, but designed only for mysql.");
}
$sql = $this->_schemaTool->getCreateSchemaSql(array(
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2182OptionParent'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2182OptionChild'),
));
$this->assertEquals("CREATE TABLE DDC2182OptionParent (id INT UNSIGNED NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[0]);
$this->assertEquals("CREATE TABLE DDC2182OptionChild (id VARCHAR(255) NOT NULL, parent_id INT UNSIGNED DEFAULT NULL, INDEX IDX_B314D4AD727ACA70 (parent_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[1]);
$this->assertEquals("ALTER TABLE DDC2182OptionChild ADD CONSTRAINT FK_B314D4AD727ACA70 FOREIGN KEY (parent_id) REFERENCES DDC2182OptionParent (id)", $sql[2]);
}
}
/**
* @Entity
* @Table
*/
class DDC2182OptionParent
{
/** @Id @Column(type="integer", options={"unsigned": true}) */
private $id;
}
/**
* @Entity
* @Table
*/
class DDC2182OptionChild
{
/** @Id @Column */
private $id;
/**
* @ManyToOne(targetEntity="DDC2182OptionParent")
* @JoinColumn(referencedColumnName="id")
*/
private $parent;
}

View File

@@ -139,14 +139,25 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase
*/
public function testFieldMappings($class)
{
$this->assertEquals(3, count($class->fieldMappings));
$this->assertEquals(4, count($class->fieldMappings));
$this->assertTrue(isset($class->fieldMappings['id']));
$this->assertTrue(isset($class->fieldMappings['name']));
$this->assertTrue(isset($class->fieldMappings['email']));
$this->assertTrue(isset($class->fieldMappings['version']));
return $class;
}
/**
* @depends testFieldMappings
* @param ClassMetadata $class
*/
public function testVersionedField($class)
{
$this->assertTrue($class->isVersioned);
$this->assertEquals("version", $class->versionField);
}
/**
* @depends testEntityTableNameAndInheritance
* @param ClassMetadata $class
@@ -793,6 +804,12 @@ class User
*/
public $groups;
/**
* @Column(type="integer")
* @Version
*/
public $version;
/**
* @PrePersist
@@ -847,6 +864,9 @@ class User
'columnName' => 'user_email',
'columnDefinition' => 'CHAR(32) NOT NULL',
));
$mapping = array('fieldName' => 'version', 'type' => 'integer');
$metadata->setVersionMapping($mapping);
$metadata->mapField($mapping);
$metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
$metadata->mapOneToOne(array(
'fieldName' => 'address',

View File

@@ -922,26 +922,6 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
$this->assertEquals('doctrineglobal_article_cms_cmsuser', $articleMetadata->associationMappings['author']['joinTable']['name']);
}
/**
* @group DDC-984
* @group DDC-559
*/
public function testFullyQualifiedClassNameShouldBeGivenToNamingStrategyPropertyToColumnName()
{
$namingStrategy = new MyPrefixNamingStrategy();
$metadata = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress', $namingStrategy);
$metadata->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
$metadata->mapField(array('fieldName'=>'country'));
$metadata->mapField(array('fieldName'=>'city'));
$this->assertEquals($metadata->fieldNames, array(
'cmsaddress_country' => 'country',
'cmsaddress_city' => 'city'
));
}
/**
* @group DDC-1746
*/
@@ -1013,14 +993,3 @@ class MyNamespacedNamingStrategy extends \Doctrine\ORM\Mapping\DefaultNamingStra
return strtolower($className);
}
}
class MyPrefixNamingStrategy extends \Doctrine\ORM\Mapping\DefaultNamingStrategy
{
/**
* {@inheritdoc}
*/
public function propertyToColumnName($propertyName, $className = null)
{
return strtolower($this->classToTableName($className)) . '_' . $propertyName;
}
}

View File

@@ -54,4 +54,35 @@ class YamlMappingDriverTest extends AbstractMappingDriverTest
$this->createClassMetadata('Doctrine\Tests\Models\Generic\SerializationModel');
}
/**
* @group DDC-2069
*/
public function testSpacesShouldBeIgnoredWhenUseExplode()
{
$metadata = $this->createClassMetadata(__NAMESPACE__.'\DDC2069Entity');
$unique = $metadata->table['uniqueConstraints'][0]['columns'];
$indexes = $metadata->table['indexes'][0]['columns'];
$nameField = $metadata->fieldMappings['name'];
$valueField = $metadata->fieldMappings['value'];
$this->assertEquals('name', $unique[0]);
$this->assertEquals('value', $unique[1]);
$this->assertEquals('value', $indexes[0]);
$this->assertEquals('name', $indexes[1]);
$this->assertEquals(255, $nameField['length']);
$this->assertEquals(255, $valueField['length']);
}
}
class DDC2069Entity
{
public $id;
public $name;
public $value;
}

View File

@@ -35,6 +35,9 @@ $metadata->mapField(array(
'columnName' => 'user_email',
'columnDefinition' => 'CHAR(32) NOT NULL',
));
$mapping = array('fieldName' => 'version', 'type' => 'integer');
$metadata->setVersionMapping($mapping);
$metadata->mapField($mapping);
$metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
$metadata->mapOneToOne(array(
'fieldName' => 'address',
@@ -121,4 +124,4 @@ $metadata->setSequenceGeneratorDefinition(array(
'sequenceName' => 'tablename_seq',
'allocationSize' => 100,
'initialValue' => 1,
));
));

View File

@@ -4,7 +4,7 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
http://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="Doctrine\Tests\ORM\Mapping\User" table="cms_users">
<options>
<option name="foo">bar</option>
@@ -36,7 +36,7 @@
<generator strategy="AUTO"/>
<sequence-generator sequence-name="tablename_seq" allocation-size="100" initial-value="1" />
</id>
<field name="name" column="name" type="string" length="50" nullable="true" unique="true">
<options>
<option name="foo">bar</option>
@@ -46,12 +46,14 @@
</options>
</field>
<field name="email" column="user_email" type="string" column-definition="CHAR(32) NOT NULL" />
<field name="version" type="integer" version="true" />
<one-to-one field="address" target-entity="Address" inversed-by="user">
<cascade><cascade-remove /></cascade>
<join-column name="address_id" referenced-column-name="id" on-delete="CASCADE" on-update="CASCADE"/>
</one-to-one>
<one-to-many field="phonenumbers" target-entity="Phonenumber" mapped-by="user" index-by="number" orphan-removal="true">
<cascade>
<cascade-persist/>
@@ -60,7 +62,7 @@
<order-by-field name="number" direction="ASC" />
</order-by>
</one-to-many>
<many-to-many field="groups" target-entity="Group">
<cascade>
<cascade-all/>
@@ -74,7 +76,7 @@
</inverse-join-columns>
</join-table>
</many-to-many>
</entity>
</doctrine-mapping>

View File

@@ -0,0 +1,15 @@
Doctrine\Tests\ORM\Mapping\DDC2069Entity:
type: entity
id:
id:
fields:
name:
type: string ( 255 )
value:
type: string ( 255 )
uniqueConstraints:
0:
columns: name, value
indexes:
0:
columns: value, name

View File

@@ -30,6 +30,9 @@ Doctrine\Tests\ORM\Mapping\User:
type: string
column: user_email
columnDefinition: CHAR(32) NOT NULL
version:
type: integer
version: true
oneToOne:
address:
targetEntity: Address
@@ -73,4 +76,4 @@ Doctrine\Tests\ORM\Mapping\User:
name_idx:
columns: name
0:
columns: user_email
columns: user_email

View File

@@ -7,6 +7,7 @@ use Doctrine\ORM\Persisters\BasicEntityPersister;
use Doctrine\Tests\Models\CustomType\CustomTypeParent;
use Doctrine\Tests\Models\CustomType\CustomTypeChild;
use Doctrine\Tests\Models\CustomType\CustomTypeFriend;
use Doctrine\Common\Collections\Expr\Comparison;
require_once __DIR__ . '/../../TestInit.php';
@@ -88,4 +89,13 @@ class BasicEntityPersisterTypeValueSqlTest extends \Doctrine\Tests\OrmTestCase
$this->assertEquals('t0."simple-entity-id" AS simpleentityid1, t0."simple-entity-value" AS simpleentityvalue2', $method->invoke($persister));
}
/**
* @group DDC-2073
*/
public function testSelectConditionStatementIsNull()
{
$statement = $this->_persister->getSelectConditionStatementSQL('test', null, array(), Comparison::IS);
$this->assertEquals('test IS ?', $statement);
}
}

View File

@@ -143,6 +143,19 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
);
}
public function testSupportsJoinOnMultipleComponentsWithJoinedInheritanceType()
{
$this->assertSqlGeneration(
'SELECT e FROM Doctrine\Tests\Models\Company\CompanyEmployee e JOIN Doctrine\Tests\Models\Company\CompanyManager m WITH e.id = m.id',
'SELECT c0_.id AS id0, c0_.name AS name1, c1_.salary AS salary2, c1_.department AS department3, c1_.startDate AS startDate4, c0_.discr AS discr5 FROM company_employees c1_ INNER JOIN company_persons c0_ ON c1_.id = c0_.id INNER JOIN company_managers c2_ INNER JOIN company_employees c3_ ON c2_.id = c3_.id INNER JOIN company_persons c4_ ON c2_.id = c4_.id AND (c0_.id = c4_.id)'
);
$this->assertSqlGeneration(
'SELECT e FROM Doctrine\Tests\Models\Company\CompanyEmployee e LEFT JOIN Doctrine\Tests\Models\Company\CompanyManager m WITH e.id = m.id',
'SELECT c0_.id AS id0, c0_.name AS name1, c1_.salary AS salary2, c1_.department AS department3, c1_.startDate AS startDate4, c0_.discr AS discr5 FROM company_employees c1_ INNER JOIN company_persons c0_ ON c1_.id = c0_.id LEFT JOIN company_managers c2_ INNER JOIN company_employees c3_ ON c2_.id = c3_.id INNER JOIN company_persons c4_ ON c2_.id = c4_.id ON (c0_.id = c4_.id)'
);
}
public function testSupportsSelectWithCollectionAssociationJoin()
{
$this->assertSqlGeneration(

View File

@@ -167,6 +167,24 @@ class EntityGeneratorTest extends \Doctrine\Tests\OrmTestCase
$this->assertTrue($reflClass->getMethod('getTest')->isPublic(), "Check for public visibility of method 'getTest' failed.");
}
/**
* @group DDC-2121
*/
public function testMethodDocBlockShouldStartWithBackSlash()
{
$metadata = $this->generateBookEntityFixture();
$book = $this->newInstance($metadata);
$this->assertPhpDocVarType('\Doctrine\Common\Collections\Collection', new \ReflectionProperty($book, 'comments'));
$this->assertPhpDocReturnType('\Doctrine\Common\Collections\Collection', new \ReflectionMethod($book, 'getComments'));
$this->assertPhpDocParamType('\Doctrine\Tests\ORM\Tools\EntityGeneratorComment', new \ReflectionMethod($book, 'addComment'));
$this->assertPhpDocParamType('\Doctrine\Tests\ORM\Tools\EntityGeneratorComment', new \ReflectionMethod($book, 'removeComment'));
$this->assertPhpDocVarType('\Doctrine\Tests\ORM\Tools\EntityGeneratorAuthor', new \ReflectionProperty($book, 'author'));
$this->assertPhpDocReturnType('\Doctrine\Tests\ORM\Tools\EntityGeneratorAuthor', new \ReflectionMethod($book, 'getAuthor'));
$this->assertPhpDocParamType('\Doctrine\Tests\ORM\Tools\EntityGeneratorAuthor', new \ReflectionMethod($book, 'setAuthor'));
}
public function testEntityExtendsStdClass()
{
$this->_generator->setClassToExtend('stdClass');
@@ -278,6 +296,131 @@ class EntityGeneratorTest extends \Doctrine\Tests\OrmTestCase
$this->assertContains('@SequenceGenerator(sequenceName="DDC1784_ID_SEQ", allocationSize=1, initialValue=2)', $docComment);
}
/**
* @group DDC-2079
*/
public function testGenerateEntityWithMultipleInverseJoinColumns()
{
$metadata = new ClassMetadataInfo($this->_namespace . '\DDC2079Entity');
$metadata->namespace = $this->_namespace;
$metadata->mapField(array('fieldName' => 'id', 'type' => 'integer', 'id' => true));
$metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_SEQUENCE);
$metadata->mapManyToMany(array(
'fieldName' => 'centroCustos',
'targetEntity' => 'DDC2079CentroCusto',
'joinTable' => array(
'name' => 'unidade_centro_custo',
'joinColumns' => array(
array('name' => 'idorcamento', 'referencedColumnName' => 'idorcamento'),
array('name' => 'idunidade', 'referencedColumnName' => 'idunidade')
),
'inverseJoinColumns' => array(
array('name' => 'idcentrocusto', 'referencedColumnName' => 'idcentrocusto'),
array('name' => 'idpais', 'referencedColumnName' => 'idpais'),
),
),
));
$this->_generator->writeEntityClass($metadata, $this->_tmpDir);
$filename = $this->_tmpDir . DIRECTORY_SEPARATOR
. $this->_namespace . DIRECTORY_SEPARATOR . 'DDC2079Entity.php';
$this->assertFileExists($filename);
require_once $filename;
$property = new \ReflectionProperty($metadata->name, 'centroCustos');
$docComment = $property->getDocComment();
//joinColumns
$this->assertContains('@JoinColumn(name="idorcamento", referencedColumnName="idorcamento"),', $docComment);
$this->assertContains('@JoinColumn(name="idunidade", referencedColumnName="idunidade")', $docComment);
//inverseJoinColumns
$this->assertContains('@JoinColumn(name="idcentrocusto", referencedColumnName="idcentrocusto"),', $docComment);
$this->assertContains('@JoinColumn(name="idpais", referencedColumnName="idpais")', $docComment);
}
/**
* @group DDC-2172
*/
public function testGetInheritanceTypeString()
{
$reflection = new \ReflectionClass('\Doctrine\ORM\Mapping\ClassMetadata');
$method = new \ReflectionMethod($this->_generator, 'getInheritanceTypeString');
$constants = $reflection->getConstants();
$pattern = '/^INHERITANCE_TYPE_/';
$method->setAccessible(true);
foreach ($constants as $name => $value) {
if( ! preg_match($pattern, $name)) {
continue;
}
$expected = preg_replace($pattern, '', $name);
$actual = $method->invoke($this->_generator, $value);
$this->assertEquals($expected, $actual);
}
$this->setExpectedException('\InvalidArgumentException', 'Invalid provided InheritanceType: INVALID');
$method->invoke($this->_generator, 'INVALID');
}
/**
* @group DDC-2172
*/
public function testGetChangeTrackingPolicyString()
{
$reflection = new \ReflectionClass('\Doctrine\ORM\Mapping\ClassMetadata');
$method = new \ReflectionMethod($this->_generator, 'getChangeTrackingPolicyString');
$constants = $reflection->getConstants();
$pattern = '/^CHANGETRACKING_/';
$method->setAccessible(true);
foreach ($constants as $name => $value) {
if( ! preg_match($pattern, $name)) {
continue;
}
$expected = preg_replace($pattern, '', $name);
$actual = $method->invoke($this->_generator, $value);
$this->assertEquals($expected, $actual);
}
$this->setExpectedException('\InvalidArgumentException', 'Invalid provided ChangeTrackingPolicy: INVALID');
$method->invoke($this->_generator, 'INVALID');
}
/**
* @group DDC-2172
*/
public function testGetIdGeneratorTypeString()
{
$reflection = new \ReflectionClass('\Doctrine\ORM\Mapping\ClassMetadata');
$method = new \ReflectionMethod($this->_generator, 'getIdGeneratorTypeString');
$constants = $reflection->getConstants();
$pattern = '/^GENERATOR_TYPE_/';
$method->setAccessible(true);
foreach ($constants as $name => $value) {
if( ! preg_match($pattern, $name)) {
continue;
}
$expected = preg_replace($pattern, '', $name);
$actual = $method->invoke($this->_generator, $value);
$this->assertEquals($expected, $actual);
}
$this->setExpectedException('\InvalidArgumentException', 'Invalid provided IdGeneratorType: INVALID');
$method->invoke($this->_generator, 'INVALID');
}
/**
* @dataProvider getEntityTypeAliasDataProvider
*

View File

@@ -10,14 +10,42 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase
{
$query = $this->entityManager->createQuery(
'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost p JOIN p.category c JOIN p.author a');
$query->expireQueryCache(true);
$limitQuery = clone $query;
$limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\LimitSubqueryOutputWalker');
$this->assertEquals(
"SELECT DISTINCT id0 FROM (SELECT m0_.id AS id0, c1_.id AS id1, a2_.id AS id2, a2_.name AS name3, m0_.author_id AS author_id4, m0_.category_id AS category_id5 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id) dctrn_result", $limitQuery->getSql()
"SELECT DISTINCT id0 FROM (SELECT m0_.id AS id0, m0_.title AS title1, c1_.id AS id2, a2_.id AS id3, a2_.name AS name4, m0_.author_id AS author_id5, m0_.category_id AS category_id6 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id) dctrn_result", $limitQuery->getSql()
);
}
public function testLimitSubqueryWithSortPg()
{
$odp = $this->entityManager->getConnection()->getDatabasePlatform();
$this->entityManager->getConnection()->setDatabasePlatform(new \Doctrine\DBAL\Platforms\PostgreSqlPlatform);
$query = $this->entityManager->createQuery(
'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost p JOIN p.category c JOIN p.author a ORDER BY p.title');
$limitQuery = clone $query;
$limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\LimitSubqueryOutputWalker');
$this->assertEquals(
"SELECT DISTINCT id0, title1 FROM (SELECT m0_.id AS id0, m0_.title AS title1, c1_.id AS id2, a2_.id AS id3, a2_.name AS name4, m0_.author_id AS author_id5, m0_.category_id AS category_id6 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id ORDER BY m0_.title ASC) dctrn_result ORDER BY title1 ASC", $limitQuery->getSql()
);
$this->entityManager->getConnection()->setDatabasePlatform($odp);
}
public function testLimitSubqueryPg()
{
$odp = $this->entityManager->getConnection()->getDatabasePlatform();
$this->entityManager->getConnection()->setDatabasePlatform(new \Doctrine\DBAL\Platforms\PostgreSqlPlatform);
$this->testLimitSubquery();
$this->entityManager->getConnection()->setDatabasePlatform($odp);
}
public function testCountQuery_MixedResultsWithName()
{
$query = $this->entityManager->createQuery(

View File

@@ -21,6 +21,18 @@ class LimitSubqueryWalkerTest extends PaginationTestCase
);
}
public function testLimitSubqueryWithSort()
{
$query = $this->entityManager->createQuery(
'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost p JOIN p.category c JOIN p.author a ORDER BY p.title');
$limitQuery = clone $query;
$limitQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\LimitSubqueryWalker'));
$this->assertEquals(
"SELECT DISTINCT m0_.id AS id0, m0_.title AS title1 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id ORDER BY m0_.title ASC", $limitQuery->getSql()
);
}
public function testCountQuery_MixedResultsWithName()
{
$query = $this->entityManager->createQuery(

View File

@@ -31,6 +31,8 @@ class MyBlogPost
* @ManyToOne(targetEntity="Category")
*/
public $category;
/** @column(type="string") */
public $title;
}
/**

View File

@@ -20,7 +20,7 @@ class WhereInWalkerTest extends PaginationTestCase
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10);
$this->assertEquals(
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql()
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE u0_.id IN (?)", $whereInQuery->getSql()
);
}
@@ -34,7 +34,7 @@ class WhereInWalkerTest extends PaginationTestCase
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10);
$this->assertEquals(
"SELECT a0_.id AS id0, a0_.name AS name1, sum(a0_.name) AS sclr2 FROM Author a0_ WHERE a0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql()
"SELECT a0_.id AS id0, a0_.name AS name1, sum(a0_.name) AS sclr2 FROM Author a0_ WHERE a0_.id IN (?)", $whereInQuery->getSql()
);
}
@@ -48,7 +48,7 @@ class WhereInWalkerTest extends PaginationTestCase
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10);
$this->assertEquals(
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE 1 = 1 AND u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql()
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE 1 = 1 AND u0_.id IN (?)", $whereInQuery->getSql()
);
}
@@ -62,7 +62,7 @@ class WhereInWalkerTest extends PaginationTestCase
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10);
$this->assertEquals(
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE 1 = 1 AND 2 = 2 AND u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql()
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE 1 = 1 AND 2 = 2 AND u0_.id IN (?)", $whereInQuery->getSql()
);
}
@@ -76,7 +76,7 @@ class WhereInWalkerTest extends PaginationTestCase
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10);
$this->assertEquals(
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE (1 = 1 OR 2 = 2) AND u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql()
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE (1 = 1 OR 2 = 2) AND u0_.id IN (?)", $whereInQuery->getSql()
);
}
@@ -90,7 +90,7 @@ class WhereInWalkerTest extends PaginationTestCase
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10);
$this->assertEquals(
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE (1 = 1 OR 2 = 2) AND 3 = 3 AND u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql()
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE (1 = 1 OR 2 = 2) AND 3 = 3 AND u0_.id IN (?)", $whereInQuery->getSql()
);
}
@@ -104,7 +104,7 @@ class WhereInWalkerTest extends PaginationTestCase
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10);
$this->assertEquals(
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE (1 = 1 AND 2 = 2 OR 3 = 3) AND u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql()
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE (1 = 1 AND 2 = 2 OR 3 = 3) AND u0_.id IN (?)", $whereInQuery->getSql()
);
}
@@ -118,7 +118,7 @@ class WhereInWalkerTest extends PaginationTestCase
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10);
$this->assertEquals(
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE (NOT 1 = 2) AND u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql()
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE (NOT 1 = 2) AND u0_.id IN (?)", $whereInQuery->getSql()
);
}
}

View File

@@ -60,6 +60,31 @@ class ResolveTargetEntityListenerTest extends \Doctrine\Tests\OrmTestCase
$this->assertSame('Doctrine\Tests\ORM\Tools\ResolveTargetEntity', $meta['oneToMany']['targetEntity']);
$this->assertSame('Doctrine\Tests\ORM\Tools\TargetEntity', $meta['oneToOne']['targetEntity']);
}
/**
* @group DDC-2109
*/
public function testAssertTableColumnsAreNotAddedInManyToMany()
{
$evm = $this->em->getEventManager();
$this->listener->addResolveTargetEntity(
'Doctrine\Tests\ORM\Tools\ResolveTargetInterface',
'Doctrine\Tests\ORM\Tools\ResolveTargetEntity',
array()
);
$this->listener->addResolveTargetEntity(
'Doctrine\Tests\ORM\Tools\TargetInterface',
'Doctrine\Tests\ORM\Tools\TargetEntity',
array()
);
$evm->addEventListener(Events::loadClassMetadata, $this->listener);
$cm = $this->factory->getMetadataFor('Doctrine\Tests\ORM\Tools\ResolveTargetEntity');
$meta = $cm->associationMappings['manyToMany'];
$this->assertSame('Doctrine\Tests\ORM\Tools\TargetEntity', $meta['targetEntity']);
$this->assertEquals(array('resolvetargetentity_id', 'targetinterface_id'), $meta['joinTableColumns']);
}
}
interface ResolveTargetInterface

View File

@@ -44,8 +44,8 @@ class SchemaToolTest extends \Doctrine\Tests\OrmTestCase
$schema = $schemaTool->getSchemaFromMetadata($classes);
$expected = array('foo' => 'bar', 'baz' => array('key' => 'val'));
$this->assertEquals($expected, $schema->getTable('TestEntityWithAnnotationOptionsAttribute')->getOptions(), "options annotation are passed to the tables optionss");
$this->assertEquals($expected, $schema->getTable('TestEntityWithAnnotationOptionsAttribute')->getOptions(), "options annotation are passed to the tables options");
$this->assertEquals($expected, $schema->getTable('TestEntityWithAnnotationOptionsAttribute')->getColumn('test')->getCustomSchemaOptions(), "options annotation are passed to the columns customSchemaOptions");
}

View File

@@ -204,6 +204,29 @@ class UnitOfWorkTest extends \Doctrine\Tests\OrmTestCase
$this->assertEquals(UnitOfWork::STATE_DETACHED, $this->_unitOfWork->getEntityState($ph2));
$this->assertFalse($persister->isExistsCalled());
}
/**
* DDC-2086 [GH-484] Prevented "Undefined index" notice when updating.
*/
public function testNoUndefinedIndexNoticeOnScheduleForUpdateWithoutChanges()
{
// Setup fake persister and id generator
$userPersister = new EntityPersisterMock($this->_emMock, $this->_emMock->getClassMetadata("Doctrine\Tests\Models\Forum\ForumUser"));
$userPersister->setMockIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_IDENTITY);
$this->_unitOfWork->setEntityPersister('Doctrine\Tests\Models\Forum\ForumUser', $userPersister);
// Create a test user
$user = new ForumUser();
$user->name = 'Jasper';
$this->_unitOfWork->persist($user);
$this->_unitOfWork->commit();
// Schedule user for update without changes
$this->_unitOfWork->scheduleForUpdate($user);
// This commit should not raise an E_NOTICE
$this->_unitOfWork->commit();
}
}
/**
@@ -309,4 +332,4 @@ class VersionedAssignedIdentifierEntity
* @Version @Column(type="integer")
*/
public $version;
}
}