Compare commits

..

1820 Commits
2.0.4 ... 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
Guilherme Blanco
ece6a005bc Merge pull request #425 from FabioBatSilva/DDC-1977
Fix DDC-1977
2012-08-15 15:29:26 -07:00
FabioBatSilva
641af15280 Fix DDC-1977 2012-08-15 22:57:21 +02: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
Alexander
185b4e0c41 Fix setCustomHydrationModes + added test 2012-08-14 22:43:32 +02:00
Alexander
5c585b4c02 Merge branch 'config' 2012-08-14 22:33:36 +02:00
Martin Meredith
787a208708 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:33:25 +02:00
Guilherme Blanco
f8a582d454 Merge pull request #391 from FabioBatSilva/ns-class
Give FQCN to NamingStrategy#propertyToColumnName
2012-08-12 15:50:20 -07:00
Guilherme Blanco
72ce9a7f37 Merge pull request #417 from jonathaningram/patch-1
Remove unused use statement
2012-08-01 23:38:56 -07:00
Jonathan Ingram
04de52d4c9 Remove unused use statement 2012-08-02 15:33:09 +10: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
Benjamin Eberlei
104a76a6b1 Update EntityRepository and PersistentCollection to new Criteria#expr() method instead of having to implement themselves. 2012-08-01 21:37:22 +02:00
Michael Moravec
79a04b295f [DDC-1961] Fixed parameter type support in Parameter 2012-07-31 21:01:21 +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
Benjamin Eberlei
00a5f18544 [DDC-1937] Fix bug with apc and annotation caching using a workaround. 2012-07-29 11:56:41 +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
e8d3fc73ff Merge branch 'DDC-1964' 2012-07-29 11:25:54 +02:00
Benjamin Eberlei
7c1235dedb [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:25:45 +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
bcbef5670c Merge branch 'DDC-1939' 2012-07-29 09:27:20 +02:00
Benjamin Eberlei
354fa14df4 [DDC-1939] Add test for persistent collection delete with composite key 2012-07-29 09:27:08 +02:00
Igor Wiedler
afd8ea91e3 [2.3] Use HelperSet in cli-config.php 2012-07-29 09:09:17 +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
Benjamin Eberlei
14bd794960 Merge pull request #411 from stof/new_types
Added the new DBAL 2.3 types in the EntityGenerator typehint map
2012-07-29 00:04:03 -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
Christophe Coevoet
cebb820030 Added the new DBAL 2.3 types in the EntityGenerator typehint map 2012-07-27 10:34:59 +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
Guilherme Blanco
04e6cc78cd 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 15:50:51 -04:00
Igor Wiedler
2158a0788e [2.3] Use HelperSet in cli-config.php 2012-07-26 19:24:53 +02:00
Johannes M. Schmitt
fc4a07c2b3 added failing test for refresh with eager fetching 2012-07-26 12:54:58 +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
1eaa822d2a Merge branch 'master' of github.com:doctrine/doctrine2 2012-07-25 01:24:33 -04:00
Guilherme Blanco
9dd3b66fe6 Fixed DefaultRepositoryClassName which should follow the Persistence interface, not ORM class. 2012-07-25 01:23:52 -04:00
Fabio B. Silva
1369e3d133 change ticket/group 2012-07-24 14:34:27 +02:00
Fabio B. Silva
50dac4096a give FQCN to NamingStrategy#propertyToColumnName 2012-07-24 14:34:27 +02:00
Marco Pivetta
aa0cb0b6d7 DDC-1939 - Removing references to non-existing AssociationMapping class 2012-07-24 11:37:57 +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
Guilherme Blanco
619d29adb2 Merge pull request #400 from stof/command_help
Changed commands to use command.name in the help
2012-07-22 22:04:15 -07:00
Guilherme Blanco
68adc7fed3 Merge pull request #403 from Ocramius/DDC-1925
DDC-1925 tests
2012-07-22 22:02:13 -07:00
Guilherme Blanco
98c4833afc Merge pull request #404 from Ocramius/DDC-1933
DDC-1933 - Fixing cloning of QueryBuilder and adding related tests
2012-07-22 22:01:35 -07:00
Guilherme Blanco
e5979b5ef2 Moved implementation from EntityRepository to EntityManager. This decouples ER implementation from EM, as it should be. 2012-07-23 00:52:41 -04:00
Marco Pivetta
fb3c6f0e8f DDC-1933 - Fixing cloning of QueryBuilder and adding related tests 2012-07-21 20:34:20 +02:00
Marco Pivetta
5b3eee8071 DDC-1925 - squashing ticket tests into a single file 2012-07-20 00:03:39 +02:00
Marco Pivetta
81f97e92d3 Adding tests for DDC-1925 2012-07-19 22:00:56 +02:00
Benjamin Eberlei
93cef61270 Fix DBAL dependency range evaluated as AND, not as OR 2012-07-18 11:23:20 +02:00
Christophe Coevoet
a723b73929 Changed commands to use command.name in the help 2012-07-17 00:55:09 +02:00
Benjamin Eberlei
34ac207b3c Bump Version to 2.4.0-DEV 2012-07-16 15:25:20 +02:00
Benjamin Eberlei
c8fcd3f8a5 Bump dependencies 2012-07-16 15:24:04 +02:00
Benjamin Eberlei
a0ba420969 Bump dev version to 2.3.0 2012-07-16 15:23:33 +02:00
Benjamin Eberlei
816f709950 Release 2.3.0-BETA1 2012-07-16 15:23:33 +02:00
Benjamin Eberlei
e0455b5550 Merge pull request #397 from Ocramius/cleanup/removing-deprecated-metadata-drivers
Cleanup/removing deprecated metadata drivers
2012-07-12 00:29:41 -07:00
Guilherme Blanco
fcff39571f Merge pull request #399 from Adel-E/patch-1
Fix phpdocs
2012-07-11 15:50:35 -07:00
Adel
51cd553de8 Fix phpdocs 2012-07-11 22:44:07 +00:00
Marco Pivetta
75276e453e Restoring class names extending the Doctrine\Common implementation for BC compatibility 2012-07-10 13:57:33 +02:00
Marco Pivetta
a2e00a96cc Reverting change on referenced DBAL commit 2012-07-10 02:59:33 +02:00
Marco Pivetta
915da58fb7 Adding upgrade notes about the BC Break 2012-07-10 02:51:55 +02:00
Marco Pivetta
f3aae5de0e Removing tests moved to Doctrine\Common 2012-07-10 02:48:28 +02:00
Marco Pivetta
01f058953b Removing DriverChain and using Doctrine\Common implementation instead 2012-07-10 02:47:08 +02:00
Marco Pivetta
e2c1d7c38a Removing deprecated StaticPHPDriver and PHPDriver
modifying tests so that the new implementation in Doctrine\Common is referenced
2012-07-10 02:31:30 +02:00
Benjamin Eberlei
113c6f51c2 Merge pull request #381 from doctrine/DDC-1637
[DDC-1637] Collection Filtering API
2012-07-09 08:16:31 -07:00
Benjamin Eberlei
b2385e0afa [DDC-1637] Implementation of Criteria Collections API for
PersistentCollection (OneToMany only) and EntityRepository.
2012-07-09 09:59:48 +02:00
Benjamin Eberlei
4aafeaf7a6 Fix test on PostgreSQL 2012-07-09 09:55:41 +02:00
Benjamin Eberlei
fe292cc503 Merge pull request #392 from widop/patch-1
Invalid paginator query cloning
2012-07-08 09:34:09 -07:00
Benjamin Eberlei
3b04cf5b2f Merge pull request #396 from Ocramius/DDC-1893
DDC-1893 - Updating configuration to reflect latest Doctrine Common changes
2012-07-08 09:26:15 -07:00
Benjamin Eberlei
f3f1091b44 Merge branch 'DDC-1657' 2012-07-08 18:22:59 +02:00
Benjamin Eberlei
6e924f2a2c [DDC-1657] Prove that DBAL changes also work in ORM, not leading to drop sequence statements on postgresql with SERIAL pks. 2012-07-08 18:22:38 +02:00
Marco Pivetta
346e34adf6 Reverting to default annotation driver with - delayed to 3.0 2012-07-08 17:33:50 +02:00
Marco Pivetta
245d906ebf Adding parameter to allow switching annotation reader implementation 2012-07-08 17:17:32 +02:00
Benjamin Eberlei
eaae1f222f Fix PostgreSQL test-failure. UnitOfWork#getEntityState() produced exists() queries because of unmanaged entity passed as parameter to AbstractQuery#setParameter(), thereby skewing the sql count 2012-07-08 16:57:40 +02:00
Marco Pivetta
b67140f73c Cleaning up description of the BC Break 2012-07-08 16:49:54 +02:00
Marco Pivetta
7c2e5ae5b2 Adding tests for configuration object (also to ensure defaults for BC break early discovery) 2012-07-08 16:32:27 +02:00
Marco Pivetta
fc00d5f39f Updating upgrade docs and fixes suggested by @beberlei 2012-07-08 16:32:27 +02:00
Marco Pivetta
86dbddd596 Updating to reflect latest Doctrine Common changes
Also, changing logic so that the SimpleAnnotationReader is no more the
default one. An additional parameter for the method will allow using it.

The CS fixes that were additionally implemented (along with other minor changes
that do not affect BC compatibility are caused by a CS sniff via IDE.
2012-07-08 16:30:35 +02:00
Benjamin Eberlei
5adc8bec58 Cleanup UPDATE.md chapter mess a bit 2012-07-08 14:52:16 +02:00
Benjamin Eberlei
baae40c5f4 Concatenate UPGRADE files into new UPGRADE.md 2012-07-08 14:48:32 +02:00
Benjamin Eberlei
7b758eee57 [DDC-1816] Verify XML <discriminator-column /> element works as expected/documented in tests. 2012-07-08 09:06:52 +02:00
Benjamin Eberlei
18d4a2f970 [DDC-1775] Fix NotifyPropertyChanged Listener being attached in addIdentityMap(), which is too late for certain use-cases in the persist lifecycle. 2012-07-07 17:47:29 +02:00
Eric GELOEN
3bdf86922c Add clone query test 2012-07-07 17:35:05 +02:00
Benjamin Eberlei
3783ca6b43 [DDC-1707] Working testcase 2012-07-07 17:15:32 +02:00
Benjamin Eberlei
ff2c5f85c3 [DDC-1846] Fix EntityRepository#find() with pessimistic locking. 2012-07-07 16:49:26 +02:00
Benjamin Eberlei
58a2cba6da Merge pull request #393 from stof/root_entity_found
Updated the classmetadata factory for Common 2.3
2012-07-07 07:21:42 -07:00
Alexander
45df16cdc6 Update DBAL vendor 2012-07-07 15:15:56 +02:00
Alexander
2dd2d694ca Introduce StatementMock to make testsuite ready for upcoming DBAL change 2012-07-07 15:14:51 +02:00
Eric GELOEN
8c24e528ad Clone directly the ArrayCollection instead of looping 2012-07-07 11:38:53 +02:00
Christophe Coevoet
8d0f49f227 Updated the classmetadata factory for Common 2.3
This adds the new method introduced in doctrine/common#162
2012-07-06 22:18:06 +02:00
Eric GELOEN
996e47bf61 Replaced a shallow-copy with a deep-copy to avoid side effects. 2012-07-06 17:49:03 +02:00
Benjamin Eberlei
0a95e42ea8 Merge branch 'DDC-1735' 2012-07-05 22:20:28 +02:00
Benjamin Eberlei
82e1d7fa80 [DDC-1735] Change file_put_contents with LOCK_EX usage to temporary filename + rename, which works on Windows NFS drives. 2012-07-05 22:20:16 +02:00
Benjamin Eberlei
12cddf20e3 [DDC-1900] Throw exception when overwriting internal function. 2012-07-05 21:52:40 +02:00
Benjamin Eberlei
cc4613533b Fix tests after DBAL adjustments 2012-07-04 23:58:41 +02:00
Benjamin Eberlei
4bfdcd32f7 Merge pull request #384 from FabioBatSilva/DDC1885
[DDC-1885] Fix quotes in many to many persisters
2012-07-04 14:43:48 -07:00
Guilherme Blanco
6ba205f561 Merge pull request #314 from Ocramius/dcom-metadata-drivers-reuse
Doctrine\Common metadata drivers reuse
2012-07-04 13:30:54 -07:00
Guilherme Blanco
6093017bc6 Merge pull request #389 from SamsonIT/fix_fetch_relation_by_id_of_association_field_2_3
fixed DDC-1895
2012-07-04 13:27:44 -07:00
Bart van den Burg
64904c77c1 fixed DDC-1895 2012-07-04 22:11:50 +02:00
Fabio B. Silva
632d13ba0c fix extra lazy count 2012-07-04 17:11:43 -03:00
Fabio B. Silva
fe11831bd7 test remove item and clear collection 2012-07-04 17:11:43 -03:00
Fabio B. Silva
63580dfe26 Fix CS 2012-07-04 17:11:43 -03:00
Fabio B. Silva
076663fe3a fix DDC-1885 in persisters 2012-07-04 17:11:42 -03:00
Benjamin Eberlei
1023af6a1f [DDC-1861] Fix UnitOfWork#doMerge() 2012-07-04 21:55:59 +02:00
Benjamin Eberlei
da331cd277 Merge pull request #376 from lstrojny/de-deprecate-transaction-methods
De-deprecate transaction handling methods
2012-07-04 12:42:55 -07:00
Benjamin Eberlei
30e86f442f [DDC-1907] Fix template variable placeholder 2012-07-04 21:30:25 +02:00
Benjamin Eberlei
5cdb0ae8be [DDC-1907] Add generation of remove method for collections 2012-07-04 21:04:47 +02:00
Marco Pivetta
379e69865e Reusing chained driver now available in common, fixing cs/code smells and removing duplicate docs. 2012-07-04 20:59:22 +02:00
Marco Pivetta
97d7cae012 Stoffing and including changes of doctrine/common#138 2012-07-04 20:59:22 +02:00
Marco Pivetta
f6381d7b76 Updating ClassMetadataFactory to comply with new abstract CMF interface as of doctrine/common#150 2012-07-04 20:59:21 +02:00
Marco Pivetta
94714db132 Fixing code sniff issues before continuing refactoring of 2012-07-04 20:59:21 +02:00
Marco Pivetta
e522391ee9 Reusing Doctrine\Common's AbstractClassMetadataFactory 2012-07-04 20:59:21 +02:00
Marco Pivetta
943cff673a Fixing test expecting a ORM\Mapping exception
Those exceptions are now in the Common\Persistence\Mapping namespace
2012-07-04 20:59:21 +02:00
Marco Pivetta
63fbf7c2e5 Fixing broken tests because of wrong method signature and reference to the old Driver interface 2012-07-04 20:59:21 +02:00
Marco Pivetta
737b74e5d5 Rebasing on master 2012-07-04 20:59:21 +02:00
Marco Pivetta
01b1b0b5fb Removing code from the simplified drivers, use SymfonyFileLocator instead 2012-07-04 20:59:21 +02:00
Marco Pivetta
5c05a4356a Adding notes about upgrading to 2.3 (metadata drivers changes) 2012-07-04 20:59:21 +02:00
Marco Pivetta
245718c9eb Removing AbstractFileDriver, using Doctrine\Common\Persistence\Mapping\Driver\FileDriver instead 2012-07-04 20:59:21 +02:00
Marco Pivetta
e9e36dcf32 Removing Doctrine\ORM\Mapping\Driver\Driver interface
Interface has been moved to Doctrine\Common\Persistence\Mapping\Driver\MappingDriver
2012-07-04 20:59:21 +02:00
Marco Pivetta
905acf9176 Removing Doctrine\ORM\Mapping\Driver\Driver interface
Interface has been moved to Doctrine\Common\Persistence\Mapping\Driver\MappingDriver
2012-07-04 20:59:21 +02:00
Marco Pivetta
5b97357402 Removing unused imports 2012-07-04 20:59:21 +02:00
Marco Pivetta
abd3ddc1b1 Removing code duplication, reusing Doctrine\Common\Persistenc\Mapping\Driver\AnnotationDriver 2012-07-04 20:59:20 +02:00
Marco Pivetta
ccace8cb8b Moving exception throwing for invalid file mappings to Doctrine\Common\Persistence\Mapping\Driver\FileDriver 2012-07-04 20:59:20 +02:00
Marco Pivetta
03fb734de8 Removing API that should be moved to common 2012-07-04 20:59:20 +02:00
Marco Pivetta
82cfda3dec Fixing reflection exceptions caused by changes in the AbstractFileDriver interface 2012-07-04 20:59:20 +02:00
Marco Pivetta
bb998d1738 Emulating feature that has to be moved to Doctrine\Common 2012-07-04 20:59:20 +02:00
Marco Pivetta
e9f23d51e0 Removing unused code 2012-07-04 20:59:20 +02:00
Marco Pivetta
34bb0c4943 Reducing code duplication
SimplifiedXmlDriver and SimplifiedYamlDriver are still not valid after this commit
2012-07-04 20:59:20 +02:00
Marco Pivetta
e6a2bae5d7 Updating mapping driver interface to comply with Doctrine\Common\Persistence\Mapping\Driver\MappingDriver 2012-07-04 20:59:20 +02:00
Guilherme Blanco
f20a95fdc0 Merge pull request #388 from fixe/patch-3
Added an empty line feed preceding the return statement
2012-07-03 06:44:51 -07:00
Tiago Ribeiro
bda7310b46 Added an empty line feed preceding the return statement 2012-07-03 12:57:14 +02:00
Guilherme Blanco
dd60cb6645 Merge pull request #387 from shieldo/fix_helptext
fixed typo in command help text
2012-07-02 10:15:35 -07:00
Douglas Greenshields
53e735ffdd fixed typo in command help text 2012-07-02 18:01:57 +01:00
Guilherme Blanco
cc29f85862 Resynced DBAL. 2012-06-24 23:53:05 -04:00
Guilherme Blanco
cb72219b11 Merge pull request #372 from FabioBatSilva/DDC-1845
[DDC-1845] QuoteStrategy
2012-06-24 20:36:54 -07:00
Guilherme Blanco
3dd3ecaff8 Updated dependency libraries with latest versions of related tools. 2012-06-24 23:29:14 -04:00
Fabio B. Silva
ca4862aabc Fix CS 2012-06-23 14:19:47 -03:00
Benjamin Eberlei
9aabdba753 Merge pull request #380 from FabioBatSilva/svn-markers
remove svn markers
2012-06-19 11:45:42 -07:00
Fabio B. Silva
d3d97e7ef8 remove svn markers 2012-06-19 15:27:41 -03:00
Fabio B. Silva
e25987df3a remove svn markers from AST 2012-06-19 15:17:08 -03:00
Guilherme Blanco
921f5c7680 Fixed license. 2012-06-19 11:04:00 -03:00
Guilherme Blanco
2703a2b27c Fixed issue with merge. 2012-06-18 15:23:12 -04:00
Fabio B. Silva
7800a7ef3f wrong indentation 2012-06-18 15:31:20 -03:00
Fabio B. Silva
65efda425f Fix CS 2012-06-18 15:24:52 -03:00
Fabio B. Silva
b9d94e7bf0 add DefaultQuoteStrategy use statement 2012-06-18 14:43:01 -03:00
Fabio B. Silva
49f9d185de Fix CS and test configuration 2012-06-18 14:43:01 -03:00
Fabio B. Silva
ab9ff813fc revert submodule change 2012-06-18 14:43:01 -03:00
Fabio B. Silva
ea690489d7 revert wrong change 2012-06-18 14:43:00 -03:00
Fabio B. Silva
85b6f8dc2f change quote strategy to interface 2012-06-18 14:43:00 -03:00
Fabio B. Silva
b6b35d9482 test quote join variable 2012-06-18 14:43:00 -03:00
Fabio B. Silva
e0a236a9af fix DDC-142 load OneToOne EAGER 2012-06-18 14:43:00 -03:00
Fabio B. Silva
cd806b83db fix DDC-142 persist OneToOne 2012-06-18 14:42:59 -03:00
Fabio B. Silva
51f29cddb9 fix delete join table 2012-06-18 14:42:59 -03:00
Fabio B. Silva
7807d6806c fix delete join table not owning side 2012-06-18 14:42:59 -03:00
Fabio B. Silva
ad380e3ac6 test join column and referenced join columns quote 2012-06-18 14:42:58 -03:00
Fabio B. Silva
debc6e4993 change QuoteStrategy#getJoinColumnName to use join column 2012-06-18 14:42:58 -03:00
Fabio B. Silva
46ec26e745 revert wrong commit 2012-06-18 14:42:58 -03:00
Fabio B. Silva
2afe24f51c start to work in xxToOne quote 2012-06-18 14:42:58 -03:00
Fabio B. Silva
a75c672ee7 fix sequence and join columns 2012-06-18 14:42:57 -03:00
Fabio B. Silva
7215c1a3b1 test join table quote 2012-06-18 14:42:57 -03:00
Fabio B. Silva
2b8e24fb09 revert wrong commit 2012-06-18 14:42:57 -03:00
Fabio B. Silva
0e9c76abf8 revert wrong commit 2012-06-18 14:42:57 -03:00
Fabio B. Silva
f335f23145 tests for quoted columns metadata 2012-06-18 14:42:56 -03:00
Fabio B. Silva
8fec73673d fix DDC-1719 in persiter and query level 2012-06-18 14:42:56 -03:00
Fabio B. Silva
fabfb66293 deprecated metadata quote methods 2012-06-18 14:42:56 -03:00
Fabio B. Silva
4ef3d99770 use quote strategy in SizeFunction, MultiTableDeleteExecutor, MultiTableUpdateExecutor, and SchemaTool 2012-06-18 14:42:56 -03:00
Fabio B. Silva
851d17f940 use quote strategy in SingleTablePersister 2012-06-18 14:42:55 -03:00
Fabio B. Silva
dcd19bba22 use quote strategy in OneToManyPersister 2012-06-18 14:42:55 -03:00
Fabio B. Silva
36296a3906 use quote strategy in JoinedSubclassPersister 2012-06-18 14:42:55 -03:00
Fabio B. Silva
7f64474f3e use quote strategy in persister 2012-06-18 14:42:54 -03:00
Fabio B. Silva
2af7b3fd38 use quote strategy in BasicEntityPersister 2012-06-18 14:42:54 -03:00
Fabio B. Silva
5d665b59a1 remove getQuotedIdentifierColumnNames 2012-06-18 14:42:54 -03:00
Fabio B. Silva
505bdb9c03 missing files 2012-06-18 14:42:54 -03:00
Fabio B. Silva
db53b8651c apply quote strategy at sqlwalker 2012-06-18 14:42:53 -03:00
Fabio B. Silva
d49a968d55 tests for DDC-1719 2012-06-18 14:42:53 -03:00
Fabio B. Silva
1bcda5147a inject quote strategy into sql walker 2012-06-18 14:42:53 -03:00
Fabio B. Silva
2b4c29e4f2 tests for default strategy 2012-06-18 14:42:53 -03:00
Fabio B. Silva
9f297c3140 first tests for DefaultQuoteStrategy 2012-06-18 14:42:52 -03:00
Guilherme Blanco
41d9f612c7 Merge pull request #378 from web-dev/DDC-1880
Fixed DDC-1880 Named Queries not registered in xml mapping
2012-06-18 10:06:15 -07:00
Josiah Truasheim
ff8cc6f4c0 Fixed DDC-1880 Named Queries not registered in xml mapping 2012-06-18 23:41:20 +07:00
Benjamin Eberlei
a3210e78aa Merge pull request #368 from doctrine/join-poc
Join poc
2012-06-18 08:18:13 -07:00
Benjamin Eberlei
e183cc62d9 Merge pull request #377 from Dinduks/fix_doc_link
Fix the documentation link in the README
2012-06-18 08:12:35 -07:00
Dinduks
77edb23291 Fix the documentation link in the README 2012-06-18 17:11:03 +02:00
Benjamin Eberlei
6f13e9543b Fix QueryTest 2012-06-18 17:03:08 +02:00
Guilherme Blanco
cba4e55ac4 Added more coverage tests. Required result confirmation. 2012-06-18 17:02:14 +02:00
Guilherme Blanco
41a650b699 Updated PoC for multiple components DQL support. 2012-06-18 17:01:52 +02:00
Alexander
e7dfa08756 [PoC] Arbitrary join support 2012-06-18 17:00:37 +02:00
Benjamin Eberlei
0c4952447b Merge pull request #369 from greg0ire/master
Show the advice only when relevant.
2012-06-18 07:26:04 -07:00
Benjamin Eberlei
3aee619fc0 Merge pull request #375 from lstrojny/transactional-callable
Allow passing any callable instead of only closures
2012-06-18 07:25:16 -07:00
Lars Strojny
3881e12a2d De-deprecate transaction handling methods 2012-06-16 13:22:53 +02:00
Lars Strojny
164269bff1 Allow passing any callable instead of only closures 2012-06-16 13:20:34 +02:00
Guilherme Blanco
27b4f58b66 Merge pull request #362 from odolbeau/cs
Correct some mistakes (tabs & trailing spaces)
2012-06-14 22:43:18 -07:00
Guilherme Blanco
e8ad82c80f Merge pull request #363 from gajdaw/entities_generator_cs_fix
Entities generator: constructor's template docblock
2012-06-14 22:42:17 -07:00
Guilherme Blanco
8bb4f53447 Merge pull request #370 from Ph3nol/ph3-phpcs-fixes
Some PHP-CS fixes
2012-06-14 22:40:50 -07:00
Guilherme Blanco
1e6508d2dc Merge pull request #371 from instaclick/bin-permissions
set permissions as expected by composer.phar update
2012-06-14 22:40:33 -07:00
Guilherme Blanco
91ffd30f52 Merge pull request #373 from bschaeffer/patch-1
Grammar fix for composer.json file
2012-06-13 07:23:53 -07:00
Braden Schaeffer
05c612f337 Grammar fix for composer.json file 2012-06-12 09:43:38 -05:00
Anthon Pang
c1c046f2dd set permissions as expected by composer.phar update 2012-06-11 11:40:23 -04:00
Ph3nol
2abb459770 Some PHP-CS fixes 2012-06-11 12:39:18 +02:00
Grégoire Paris
111bb52add delimit ternary 2012-06-11 08:23:37 +02:00
Grégoire Paris
190e63a6bb Show the advice only when necessary.
This is indeed a good advice, but people who
already have implemented __toString() might
get confused about it.
2012-06-10 23:59:07 +03:00
Guilherme Blanco
7b758493a3 Merge pull request #365 from Ocramius/DDC-1860
DDC-1860 - Composer arbitrary for CLI and composer/autoload.php in different paths
2012-06-09 05:45:26 -07:00
Marco Pivetta
2f83cf0dbd Cleaning up, removing iteration over parent directories as location of autoload.php can be determined eagerly 2012-06-09 14:41:39 +02:00
Marco Pivetta
8231fb2c68 Adding support for various composer autoload file locations, making composer optional 2012-06-09 10:48:58 +02:00
Włodzimierz Gajda
b263a00eac Entities generator: constructor's template docblock 2012-06-06 08:44:25 +02:00
Olivier Dolbeau
79a9ce5000 Add some corrections 2012-06-05 21:32:53 +02:00
Olivier Dolbeau
7ca0ac289e Remove tabs & trailing spaces 2012-06-05 15:46:10 +02:00
Olivier Dolbeau
c98f9117c2 Remove unused use 2012-06-05 15:39:52 +02:00
Guilherme Blanco
9445502885 Removed un-necessary getIterator(). 2012-05-29 15:14:08 -04:00
Guilherme Blanco
6521e51170 Added missing BC compatibility in QueryBuilder. 2012-05-29 14:52:30 -04:00
Guilherme Blanco
e4935e58f2 Merge pull request #360 from doctrine/DDC-1840
[DDC-1840] Implemented parameters as a collection.
2012-05-29 11:41:00 -07:00
Guilherme Blanco
15f76c62bb Update UPGRADE_TO_2_3 2012-05-29 15:40:27 -03:00
Guilherme Blanco
161ae31a7e Adde more BC compatibility in setParameters. 2012-05-29 14:41:32 -04:00
Guilherme Blanco
b3e7493278 Made setParameters()/excute()/iterate() BC compatible. 2012-05-29 14:25:54 -04:00
Guilherme Blanco
d8e165da8d Added 2.3 BC break information. 2012-05-28 12:28:54 -04:00
Guilherme Blanco
79ff1f10d2 Optimized getParameter. 2012-05-28 12:20:35 -04:00
Guilherme Blanco
1635e0af4b [DDC-1840] Implemented parameters as a collection. 2012-05-28 12:16:42 -04:00
Benjamin Eberlei
1f2ce21b56 [DDC-1497] Change EntityGenerator add method generation for collections. 2012-05-27 20:31:01 +02:00
Benjamin Eberlei
8e644e1303 [DDC-1685] Fix DDC-117 Dataset cleanup 2012-05-27 18:54:35 +02:00
Benjamin Eberlei
958d35a3f3 Merge branch 'DDC-1798' 2012-05-27 18:44:38 +02:00
Benjamin Eberlei
04b23dbf10 [DDC-1798] Exporter generate error when composite primary key is generated. Fixes GH-342 2012-05-27 18:44:31 +02:00
Benjamin Eberlei
47ac61b3e0 Merge branch 'DDC-1685' 2012-05-27 18:33:46 +02:00
Benjamin Eberlei
3398d1e287 [DDC-1685] Fix bug in OutputWalker when used on entities with Foreign Key as Primary Key. 2012-05-27 18:33:35 +02:00
Benjamin Eberlei
2e79637be8 Merge branch 'DDC-1713' 2012-05-27 17:22:25 +02:00
Benjamin Eberlei
03d5922996 [DDC-1713] Verify EntityRepository#findBy() works with fetching array of values. 2012-05-27 17:22:16 +02:00
Benjamin Eberlei
48aba0a3f0 Merge branch 'DDC-1777' 2012-05-27 17:11:29 +02:00
Benjamin Eberlei
6523f7f59e [DDC-1777] Fix bug in BasicEntityPersister#exists() when no primary key is set. 2012-05-27 17:11:21 +02:00
Benjamin Eberlei
c1fd0c479a Merge branch 'DDC-1791' 2012-05-27 13:22:56 +02:00
Benjamin Eberlei
f55b5411c8 [DDC-1791] Fix OutputWalker Pagination on Oracle 2012-05-27 13:22:48 +02:00
Benjamin Eberlei
eb8f524f81 Merge branch 'DDC-1783' 2012-05-27 12:00:54 +02:00
Benjamin Eberlei
44c867827c [DDC-1783] Fix memory leak in ObjectHydrator when using AbstractQuery#iterate() and EntityManager#clear() 2012-05-27 12:00:43 +02:00
Karsten Dambekalns
bcddc47356 [DDC-1835] Fix cloning persistent collections. 2012-05-27 10:17:12 +02:00
Benjamin Eberlei
9ae5b8f442 Merge branch 'DDC-1799' 2012-05-27 09:58:01 +02:00
Benjamin Eberlei
548c997f7b [DDC-1799] Fix bug in YamlExporter using OneToOne instead of ManyToOne 2012-05-27 09:57:46 +02:00
Benjamin Eberlei
0868ec1c19 Update Common and fix cache tests with different assumptions about keys. 2012-05-26 19:29:51 +02:00
Benjamin Eberlei
a5b90fd3c6 Merge pull request #358 from jalliot/patch-1
Update license for Composer
2012-05-26 09:51:19 -07:00
Jordan Alliot
dfae961913 Update license for Composer 2012-05-26 19:15:48 +03:00
Benjamin Eberlei
70458b2f48 LGPL => MIT 2012-05-26 14:37:00 +02:00
Guilherme Blanco
b32bb26a84 Re-added coverage for DDC-369 and DDC-954. 2012-05-23 01:07:29 -04:00
Guilherme Blanco
f54f8f8a95 Fixed anomalous bug of temporary existance table collision in case of any update/delete issue by dropping temp table, no matter what's the result of other executes. 2012-05-23 00:55:05 -04:00
Guilherme Blanco
738bfd8082 Reverted coverage for DDC-369 and DDC-954. 2012-05-23 00:14:50 -04:00
Guilherme Blanco
3e601c3a53 Added coverage for DDC-369 and DDC-954. All passing. 2012-05-23 00:10:25 -04:00
Benjamin Eberlei
a9398e7a74 Autoloaders not needed, composer provides them 2012-05-22 21:54:43 +02:00
Benjamin Eberlei
be6fb617df [DDC-1807] Fix composer bin support and keep BC with PEAR installer. 2012-05-22 20:26:03 +02:00
Benjamin Eberlei
e2d15c3a04 Merge pull request #353 from pscheit/patch-1
prevent the validator to stop with an "undefined array index"-error
2012-05-22 10:09:01 -07:00
Benjamin Eberlei
f686a3ac1b Merge pull request #354 from pscheit/master
ValidateSchemaCommand dont't call exit() in execute()
2012-05-22 10:03:44 -07:00
Philipp Scheit
e9f936c0ba don't call exit() in execute() 2012-05-22 14:25:54 +03:00
Guilherme Blanco
d05ad996c4 Implemented support for internal exception showing DQL that contains syntax or semantical error. 2012-05-21 16:34:27 -04:00
Philipp Scheit
f1571aeac3 prevent the validator to stop with an "undefined array index"-error while validating a wrong inversedBy Attribute 2012-05-21 19:23:22 +03:00
Benjamin Eberlei
93fcb74f9a Merge pull request #350 from stof/branch_alias
Added the branch-alias in the composer.json
2012-05-20 14:21:52 -07:00
Christophe Coevoet
1594831d8a Added the branch-alias in the composer.json 2012-05-20 21:33:56 +02:00
Guilherme Blanco
3d8e46447a Merge pull request #349 from FabioBatSilva/DDC-1822
Fix DDC-1822
2012-05-19 22:10:09 -07:00
Fabio B. Silva
0af5da77f1 fix DDC-1822 2012-05-19 13:40:01 -03:00
Benjamin Eberlei
4ef552e07a Merge pull request #317 from FabioBatSilva/DDC-1694
Fix DDC-1694
2012-05-05 04:39:28 -07:00
Benjamin Eberlei
a038f5edea Merge branch 'DDC-1786' 2012-05-05 09:28:53 +02:00
Benjamin Eberlei
758ffe06d2 [DDC-1786] Add note about BC in EntityManager#find(null) 2012-05-05 09:28:42 +02:00
Fabio B. Silva
e9974911fe fix tests 2012-05-04 21:13:20 -03:00
Fabio B. Silva
67f0722211 change test to uses data provider 2012-05-04 21:13:19 -03:00
Fabio B. Silva
790d98133c fix DDC-1694 2012-05-04 21:11:51 -03:00
Benjamin Eberlei
bd41e69a1f Merge DDC-1542 into master 2012-05-04 23:20:57 +02:00
Benjamin Eberlei
99e303e211 [DDC-1542] Refactored automatic discriminator map detection. 2012-05-04 23:15:12 +02:00
Guilherme Blanco
6103db0d04 Merge pull request #345 from hason/DDC-1802
Fixed DDC-1802
2012-05-04 13:04:08 -07:00
comfortablynumb
f0db9a842d [DDC-1542] - Inheritance: Added default discriminator map (only annotations yet) 2012-05-04 20:36:24 +02:00
Benjamin Eberlei
f566b79c87 Fix coding standards 2012-05-04 19:16:07 +02:00
Benjamin Eberlei
63b2c03a02 Merge pull request #331 from gedrox/DDC-1757
DDC-1757 test and patched query builder
2012-05-04 10:08:59 -07:00
Benjamin Eberlei
e09a9c7deb Merge pull request #315 from Ocramius/getclass-on-proxies-refactoring
Allowing proxies to be passed to ORM public API
2012-05-04 10:04:14 -07:00
Alexander
37ce0f15d6 Update test case for MappingException::invalidCascadeOption() 2012-05-04 18:26:17 +02:00
Alexander
3403305b3d Merge remote-tracking branch 'schmittjoh/betterExMessage' 2012-05-04 18:20:56 +02:00
Guilherme Blanco
5fddd1bee5 Merge pull request #324 from brikou/call_simplified
simplified Doctrine/ORM/EntityRepository::__call
2012-05-03 23:20:13 -07:00
Martin Hasoň
3d852397db DDC-1802 removed unnecessary tokens T_SIZE and T_MOD 2012-05-02 19:10:21 +02:00
Martin Hasoň
3ab6ad23ad DDC-1802 fixed parsing: FunctionDeclaration "NOT" ("LIKE" | "IN" | "BETWEEN") 2012-05-02 19:08:27 +02:00
Guilherme Blanco
0a09a28ec9 Merge pull request #335 from FabioBatSilva/DDC-964
association/attribute override
2012-04-28 20:24:18 -07:00
Fabio B. Silva
fa140d8f59 remove wrong conflit mark 2012-04-21 01:59:25 -03:00
Fabio B. Silva
5c7d7c6f05 remove duplicated 'require_once' 2012-04-21 01:53:34 -03:00
Fabio B. Silva
56fb1035de update docblock 2012-04-21 01:43:18 -03:00
Fabio B. Silva
f63cb95ef3 add annotations 2012-04-21 01:43:18 -03:00
Fabio B. Silva
85790f0752 support for attribute override 2012-04-21 01:43:18 -03:00
Fabio B. Silva
4df3c75321 added missing '\' 2012-04-21 01:41:05 -03:00
Fabio B. Silva
2f67750165 added tags on doctrine-mapping.xsd 2012-04-21 01:41:05 -03:00
Fabio B. Silva
3085c52f95 fix docblock and remove white spaces 2012-04-21 01:41:04 -03:00
Fabio B. Silva
9e010cbd34 added xml/yml drivers 2012-04-21 01:41:04 -03:00
Fabio B. Silva
30fdf8dd1b added support for @AssociationOverride 2012-04-21 01:38:34 -03:00
Aigars Gedroics
c827a98196 Merge branch 'DDC-1757' of github.com:gedrox/doctrine2 into DDC-1757 2012-04-20 16:07:42 +03:00
Aigars Gedroics
5392133beb [DDC-1757] test checks DQL only now, doesn't create schema anymore 2012-04-20 16:06:21 +03:00
Aigars Gedroics
3ddc461d30 [DDC-1757] Fix moved to private method, test improved. 2012-04-20 16:06:21 +03:00
gedrox
29a94f4f52 Parameter PHP documentation for the QueryBuilder::getRootAlias() method 2012-04-20 16:06:21 +03:00
Aigars Gedroics
a1ab3e8cf4 DDC-1757 test and patched query builder 2012-04-20 16:06:21 +03:00
Guilherme Blanco
d5d47222c1 Merge pull request #339 from FabioBatSilva/DDC-1784
Fix DDC-1784
2012-04-18 20:37:09 -07:00
Fabio B. Silva
9b02745cd8 Fix DDC-1784 2012-04-18 20:39:21 -03:00
Benjamin Eberlei
d95e96bd3b Merge pull request #337 from richardmiller/composer_changes
Removed dependency on common as required by dbal anyway
2012-04-17 05:03:40 -07:00
Richard Miller
c008958950 Removed dependency on common as required by dbal anyway 2012-04-17 12:07:22 +01:00
Aigars Gedroics
59e598acc5 [DDC-1757] test checks DQL only now, doesn't create schema anymore 2012-04-17 10:57:31 +03:00
Guilherme Blanco
bad811df6a Merge pull request #293 from FabioBatSilva/DDC-1663
[DDC-1663]Native SQL Query Result Set Mappings
2012-04-16 12:06:26 -07:00
Benjamin Eberlei
4b09712761 Merge pull request #322 from rande/patch-1
In some weird situation the SimpleXmlIterator used to iterate on the ``$...
2012-04-16 09:55:05 -07:00
Benjamin Eberlei
193ac077d6 Merge pull request #316 from fixe/patch-1
Fixes autoloading of generated Annotations
2012-04-16 09:48:50 -07:00
Guilherme Blanco
c02ac6516e Merge pull request #336 from merk/DDC1778
Fixed DDC1778
2012-04-16 07:59:24 -07:00
Tim Nagel
6cbdf53975 Fixed DDC1778 2012-04-16 13:03:19 +10:00
Fabio B. Silva
ad9d590a15 added tags on doctrine-mapping.xsd 2012-04-15 15:40:43 -03:00
Fabio B. Silva
f8b1915efd named native query inheritance 2012-04-15 15:40:43 -03:00
Fabio B. Silva
52c49b444e test multiple entity results 2012-04-15 15:40:43 -03:00
Fabio B. Silva
9c87b5c689 php driver 2012-04-15 15:40:42 -03:00
Fabio B. Silva
4aa67a7598 static driver 2012-04-15 15:40:42 -03:00
Fabio B. Silva
b49180875c yml driver 2012-04-15 15:40:42 -03:00
Fabio B. Silva
531eb68d56 xml driver 2012-04-15 15:40:41 -03:00
Fabio B. Silva
6e93186db4 mapping driver tests 2012-04-15 15:40:41 -03:00
Fabio B. Silva
fdc9fdae3e refactory ResultSetMappingBuilder#addNamedNativeQueryMapping into small submethods 2012-04-15 15:40:41 -03:00
Fabio B. Silva
8c407af1fc fix postgres test 2012-04-15 15:40:41 -03:00
Fabio B. Silva
68665af6e8 test discriminator column 2012-04-15 15:40:41 -03:00
Fabio B. Silva
0cc2583a02 test scalar result 2012-04-15 15:40:40 -03:00
Fabio B. Silva
f813223036 test joined one-to-many and one-to-one 2012-04-15 15:40:40 -03:00
Fabio B. Silva
f018a56d6d test native query with result class 2012-04-15 15:40:40 -03:00
Fabio B. Silva
3b79951824 mapping driver tests 2012-04-15 15:40:40 -03:00
Fabio B. Silva
015ea809b0 added support for resultClass and empty fields 2012-04-15 15:39:22 -03:00
Fabio B. Silva
bfc7986b20 annotation driver and basic support 2012-04-15 15:39:22 -03:00
Fabio B. Silva
2b996128af sql result set mapping metadata 2012-04-15 15:39:22 -03:00
Fabio B. Silva
91e4702772 named native query metadata 2012-04-15 15:39:22 -03:00
Fabio B. Silva
530e4840dd native query annotations 2012-04-15 15:39:21 -03:00
Aigars Gedroics
aa381951cd [DDC-1757] Fix moved to private method, test improved. 2012-04-10 11:47:05 +03:00
Marco Pivetta
cb7a77cc03 Removing usage of ClassUtil where not strictly needed
Optimizing the ClassMetadataFactory API instead and using ClassMetadata to check actual class names as da962f2e and c27b4de0 introduced too much overhead
2012-04-07 18:53:34 +02:00
Marco Pivetta
85ea27dba2 Adding tests for additional usages of the proxy classname in ORM public API
Like Proxy classnames in DQL, EM#getRepository, EM#getReference
2012-04-07 18:53:34 +02:00
Marco Pivetta
d1e868a32a Removing registration of proxy ClassMetadata by the proxyFactory
Ensuring that functionality is kept by checking for the real class name in the ClassMetadataFactory
2012-04-07 18:53:34 +02:00
Marco Pivetta
37279d0753 Adding test to verify validity of changes (fails without them) 2012-04-07 18:53:34 +02:00
Marco Pivetta
c4a2eaea49 Adding additional missing calls to classutils instead of get_class 2012-04-07 18:53:34 +02:00
Marco Pivetta
cbe4987e18 Using Doctrine\Common\Util\ClassUtil for class_name resolutionThis avoids exceptions when passing a Proxy instance to the public API of the EntityManager, ClassMetadataFactory or UnitOfWork when the Proxy itself isn't generated by the EntityManager itself, while discovering the correct ClassMetadata instance for the proxy 2012-04-07 18:53:33 +02:00
Benjamin Eberlei
022d27e4e9 Merge branch 'DDC-1534' 2012-04-07 10:43:05 +02:00
Benjamin Eberlei
de26952e29 [DDC-1534] YamlDriver wrongly used "inversedBy" inside join table condition although its independent. 2012-04-07 10:42:54 +02:00
Benjamin Eberlei
c92393026d Merge branch 'DDC-1771' 2012-04-07 10:30:17 +02:00
Benjamin Eberlei
d54fdf43d0 [DDC-1771] Abstract classes cannot be proxies and should be skipped in complete generation. 2012-04-07 10:30:09 +02:00
Benjamin Eberlei
a1a9f85fda Merge pull request #328 from Netpositive/master
addDiscriminatorMapClass fix
2012-04-07 00:44:29 -07:00
Benjamin Eberlei
d6ccd82cf6 Merge pull request #321 from import/feature/newCacheDriver
Addition for new cache driver
2012-04-07 00:20:55 -07:00
Guilherme Blanco
a5c13a5ef1 Merge pull request #329 from doctrine/DDC-1766
[DDC-1766] Initial implementation of hydration cache.
2012-04-06 06:50:11 -07:00
Benjamin Eberlei
0b3577f2d2 [DDC-1766] Rewrite getHydrationCacheId() to use existing processParameterValue() method. Other code style changes. 2012-04-05 22:40:40 +02:00
gedrox
49016bc156 Parameter PHP documentation for the QueryBuilder::getRootAlias() method 2012-04-05 13:56:08 +03:00
Aigars Gedroics
efebf26cc5 DDC-1757 test and patched query builder 2012-04-05 11:30:00 +03:00
Johannes M. Schmitt
84ec6dc9f5 improved exception message 2012-04-04 21:47:23 -05:00
Benjamin Eberlei
1095fb39cb [DDC-1766] More cleanups 2012-04-05 00:27:23 +02:00
Benjamin Eberlei
f7496b1482 [DDC-1766] Cleaned up code. 2012-04-05 00:26:09 +02:00
Benjamin Eberlei
d31c7f5e2b [DDC-1766] Explain details of Hydration cache, introduce AbstractQuery#setResultCacheProfile method 2012-04-04 23:55:14 +02:00
Benjamin Eberlei
c32a77e6be [DDC-1766] Add usage of default result cache driver, add more docs. 2012-04-04 23:47:32 +02:00
Benjamin Eberlei
fd2a22bd56 [DDC-1766] Add test with explicit cache key. 2012-04-04 23:42:17 +02:00
Benjamin Eberlei
864fbbdaaf [DDC-1766] Remove some testcode 2012-04-04 23:24:51 +02:00
Benjamin Eberlei
306f9e0ca2 [DDC-1766] Rename closure 2012-04-04 23:21:06 +02:00
Benjamin Eberlei
3047c4b955 [DDC-1766] Initial implementation of hydration cache. 2012-04-04 23:10:30 +02:00
Alexander
cc06508bd4 Added test coverage for repository functions when using filters 2012-04-04 22:00:01 +02:00
Somfai Mátyás
a2fd4eca37 Fixing a bug when calling setDiscriminatorMap from multiple sources (ie: from Events::loadClassMetadata and annotation). 2012-04-04 14:49:34 +02:00
Brikou CARRE
029071a144 simplified __call method 2012-04-03 17:33:00 +02:00
Thomas
5005bbe62b In some weird situation the SimpleXmlIterator used to iterate on the `$xmlRoot->field property just get resetted. This solution avoid this situation. This problem occurs when Symfony2 warms up cache with autogenerate proxy to true` 2012-04-02 14:55:35 +03:00
Osman Üngür
e69b022472 Fixed CS 2012-04-02 12:11:38 +03:00
Osman Üngür
4fc7389b1d New cache driver definition for Doctrine running in non-dev mode and cache driver is not set.
This cache driver was added with doctrine/common#109
2012-04-02 11:57:09 +03:00
Benjamin Eberlei
5b18718b92 [DDC-1746] Throw exception on invalid cascade option. 2012-04-01 11:01:58 +02:00
Tiago Ribeiro
975f3c4600 Fixes autoloading of generated Annotations 2012-04-01 02:59:03 +02:00
Benjamin Eberlei
c5c3719e79 Revert GH-311 2012-03-30 22:00:45 +02:00
Benjamin Eberlei
04a4f2fc24 Merge pull request #310 from FabioBatSilva/DDC-889
[DDC-889] Mention parent class for debugging purposes.
2012-03-30 12:55:49 -07:00
Benjamin Eberlei
dd263ce00d Merge pull request #313 from hason/tests
Fixed tests on Windows
2012-03-29 04:41:27 -07:00
Martin Hasoň
f3a9b1efc0 Fixed tests on Windows 2012-03-29 13:26:06 +02:00
Guilherme Blanco
290f8a79e4 Merge pull request #311 from benlumley/patch-1
Proposal: Support for default attribute in yaml mappings.
2012-03-28 18:09:50 -07:00
Ben Lumley
7a5ae3a1a2 Support for default attribute in yaml mappings. 2012-03-28 22:01:57 +02:00
Guilherme Blanco
2811d161bb Merge pull request #309 from FabioBatSilva/DDC-1686
Fix DDC-1686
2012-03-25 21:33:43 -07:00
Fabio B. Silva
6d1209c06d fix typo 2012-03-26 01:03:32 -03:00
Fabio B. Silva
67af9f1853 change comparison 2012-03-26 00:55:57 -03:00
Fabio B. Silva
d6809773db mention parent classes for identifier required exception. 2012-03-25 13:34:52 -03:00
Fabio B. Silva
449d8a66ad changed modifiers 2012-03-25 13:00:50 -03:00
Fabio B. Silva
f591e428c3 mention parent classes when not is a entity or mapped super class. 2012-03-25 12:54:09 -03:00
Fabio B. Silva
0f9afbdf0a Fix DDC-1686 2012-03-25 00:30:58 -03:00
Guilherme Blanco
8a52e3033b Merge pull request #308 from FabioBatSilva/DDC-1697
Fix DDC-1697
2012-03-24 20:29:52 -07:00
Fabio B. Silva
df8626b949 Fix DDC-1697 2012-03-24 22:50:54 -03:00
Benjamin Eberlei
ab15528fde Fix CS: AS => as in foreach loops. 2012-03-24 11:16:32 +01:00
Benjamin Eberlei
08b455b029 Merge branch 'dead_code_cleanup' 2012-03-24 11:08:20 +01:00
Hugo Hamon
16da74d1da [Query] removed unused private _peekBeyond() method from Parser class. 2012-03-24 11:07:44 +01:00
Hugo Hamon
c0620bf857 [Tools] removed unused local variable $assocName in ResolveTargetEntityListener class. 2012-03-24 11:07:41 +01:00
Hugo Hamon
ffa372a76c [Tools] removed unused local variable in YamlExporter class. 2012-03-24 11:07:41 +01:00
Hugo Hamon
505537d4ce [Tools] renamed AS to as in EntityGenerator class. 2012-03-24 11:07:41 +01:00
Hugo Hamon
68806aa8c6 [Tools] removed unused local variable $idHash in DebugUnitOfWorkListener class and renamed AS keywords to as. 2012-03-24 11:07:41 +01:00
Hugo Hamon
aca1470e6b [Tools] removed unused local variable $cm in InfoCommand class. 2012-03-24 11:07:40 +01:00
Hugo Hamon
5a1c1e55ef [Query] removed unused local variables in Parser class. 2012-03-24 11:07:39 +01:00
Hugo Hamon
43eebe1a8b [Query] removed unused local variable $lexer in SizeFunction class. 2012-03-24 11:07:39 +01:00
Hugo Hamon
19602d0a26 [Query] removed unused local variable $platform in IdentityFunction class. 2012-03-24 11:07:39 +01:00
Hugo Hamon
c4dcd39666 [Proxy] renamed AS to as. 2012-03-24 11:07:39 +01:00
Hugo Hamon
d09b733cc3 [Persisters] removed unused local variable in ManyToManyPersister class. 2012-03-24 11:07:39 +01:00
Hugo Hamon
d4bcbd4741 [Persisters] removed unused local variables in BasicEntityPersister class. 2012-03-24 11:07:39 +01:00
Hugo Hamon
74f52a055e [Mapping] removed unused local variable $fileName in StaticPHPDriver class. 2012-03-24 11:07:39 +01:00
Hugo Hamon
155c24772a [Mapping] removed unused local variables $versionAnnot and $tblGeneratorAnnot in AnnotationDriver class. 2012-03-24 11:07:39 +01:00
Hugo Hamon
a3d8207578 [Mapping] removed unused local variable $field in ClassMetadataInfo class. 2012-03-24 11:07:35 +01:00
Hugo Hamon
beae0865db [Mapping] removed unused local variable $fieldName in ClassMetadataFactory class. 2012-03-24 11:07:35 +01:00
Benjamin Eberlei
29318e183c [DDC-1723] Fix missing serialitation for custom generator definition. 2012-03-22 23:07:00 +01:00
Benjamin Eberlei
18e63f9cea Merge branch 'DDC-1723' 2012-03-22 22:30:35 +01:00
Benjamin Eberlei
bc4cf21c9d Merge velovint/SupportCustomIdGenerators 2012-03-22 22:29:15 +01:00
Benjamin Eberlei
7d7edbbd4a Merge pull request #288 from FabioBatSilva/DDC-775
DDC 775
2012-03-22 14:00:48 -07:00
Benjamin Eberlei
3aba23ea35 Merge pull request #304 from doctrine/feature/flush-many-documents
Allow flushing of many entities by passing an array of entities.
2012-03-22 12:34:01 -07:00
Alexander
1b2b831feb Merge pull request #306 from r1pp3rj4ck/patch-1
Fixed fetch mapping in xsd
2012-03-16 09:02:56 -07:00
Attila Bukor
7f3e90e291 Fixed fetch mapping in xsd
It was 'EXTRALAZY' and the constant name in ClassMetadata is 'EXTRA_LAZY'
2012-03-16 17:00:12 +01:00
Guilherme Blanco
6f3ef148a9 Merge pull request #305 from FabioBatSilva/DDC-1470
[DDC-1470] Error messages
2012-03-15 19:36:56 -07:00
Fabio B. Silva
9cee329407 Fix CS 2012-03-15 22:38:54 -03:00
Fabio B. Silva
36dc560533 Fix DDC-1470 2012-03-15 21:29:52 -03:00
Jonathan H. Wage
24e808844b Allow flushing of many entities by passing an array of entities. 2012-03-15 17:45:25 -05:00
Guilherme Blanco
44d7d23e8d Coding style fixes. 2012-03-15 01:26:06 -04:00
Guilherme Blanco
a16ca32981 Coding style fixes. 2012-03-15 01:15:47 -04:00
Guilherme Blanco
c3291f8f24 Coding style fixes. 2012-03-15 01:13:14 -04:00
Guilherme Blanco
c65b22eadf Coding style fixes. 2012-03-15 01:08:28 -04:00
Guilherme Blanco
2a399312f7 Coding style fixes. 2012-03-15 01:03:01 -04:00
Guilherme Blanco
666ae8f1b7 Coding style fixes. 2012-03-15 01:00:29 -04:00
Benjamin Eberlei
e1704402a6 Merge branch 'DDC-1648' 2012-03-14 21:39:29 +01:00
rivaros
9c4e52c136 Convention fix 2012-03-14 21:38:56 +01:00
Rivaros
b346f1901a convention fixes #2 2012-03-14 21:38:50 +01:00
Rivaros
df82b6060b Convention fixes 2012-03-14 21:38:43 +01:00
Rivaros
06eed4cfda Primary Keys as Foreign Keys - reverse engineering 2012-03-14 21:38:33 +01:00
Benjamin Eberlei
de5e4b0fdc [DBAL-1692] Throw exception if table has no primary key instead of fatal error. 2012-03-14 21:09:48 +01:00
Benjamin Eberlei
0e1eff14bc Merge branch 'DDC-1683' 2012-03-14 20:49:34 +01:00
Benjamin Eberlei
18f1d56b60 [DDC-1683] Fix bug with booleans not handled by Expr#literal() in query builder. 2012-03-14 20:49:25 +01:00
Benjamin Eberlei
9b4d60897d [DDC-1698] Add autoloader especially for the non PSR-0 Proxy class names. This is necessary when you want to deserialize your proxy classes from the session. 2012-03-14 20:03:17 +01:00
Alexander
c6ef7a7c03 Merge pull request #303 from sandermarechal/paginate-sql-walkers
Fix GROUP BY clauses for PostgreSQL
2012-03-14 00:16:29 -07:00
Sander Marechal
cb892736eb Fix GROUP BY clauses for PostgreSQL 2012-03-14 07:58:58 +01:00
Benjamin Eberlei
694d0911c9 Merge pull request #301 from sandermarechal/paginate-sql-walkers
Fix HAVING queries for PostgreSQL
2012-03-13 01:15:55 -07:00
Sander Marechal
b2fa2cb195 Fix HAVING queries for PostgreSQL 2012-03-13 07:59:14 +01:00
Fabio B. Silva
84b31714a6 fix indentation 2012-03-12 22:07:43 -03:00
Fabio B. Silva
e46275e80d remove case expressions and functions support 2012-03-12 20:26:40 -03:00
Fabio B. Silva
797c9cf70e supports simple math operator 2012-03-12 20:26:39 -03:00
Fabio B. Silva
df0632258a Order by clause support case expressions 2012-03-12 20:26:38 -03:00
Fabio B. Silva
ce9643bce1 Order by clause support functions 2012-03-12 20:26:38 -03:00
Alexander
73db4e19d2 Merge branch 'merge_non_mapped_properties' 2012-03-12 23:19:16 +01:00
Alexander
e3933e265e Add upgrade file + note about merging entities 2012-03-12 23:18:56 +01:00
Klein Florian
ac1ffaf7e9 make merge copy non persited properties too 2012-03-12 23:18:56 +01:00
Benjamin Eberlei
775936399e Merge branch 'DDC-451' 2012-03-12 12:56:44 +01:00
Benjamin Eberlei
23d004844a [DDC-451] Adjust doctrine-mapping.xsd for new UUID generator 2012-03-12 12:52:36 +01:00
Benjamin Eberlei
d57159ad54 [DDC-451] Add test for UUIDGenerator 2012-03-12 12:48:14 +01:00
Maarten de Keizer
33c5f4f678 Fix comments 2012-03-12 12:32:33 +01:00
Maarten de Keizer
0a835609fa UUID id generator 2012-03-12 12:32:33 +01:00
Benjamin Eberlei
3788d0e815 Merge pull request #298 from sandermarechal/paginate-sql-walkers
Pagination using SQL walkers
2012-03-12 01:04:34 -07:00
Sander Marechal
43f97a9abc CountOutputWalker does not need CountWalker::HINT_DISTINCT 2012-03-12 08:39:28 +01:00
Sander Marechal
53ff312936 Renamed *SqlWalker to *OutputWalker 2012-03-12 08:33:35 +01:00
Guilherme Blanco
7954386705 DDC-1696 Allowed Strings to be used inside of Case expressions. It seems this fixes other misterious use cases not yet identified by us. 2012-03-11 21:14:08 -04:00
Benjamin Eberlei
0a78f7bc11 [DDC-1695] Fix bug in SQL Walker array hydration with escaped fields. 2012-03-11 23:27:51 +01:00
Benjamin Eberlei
4dd296f9ca Merge pull request #299 from patrick-mcdougle/patch-1
Fixed comment for createQuery to include the variable name.
2012-03-11 14:49:43 -07:00
Alexander
3faa1a78c2 [DDC-1426] sizeof() -> count() + added tests 2012-03-11 22:32:30 +01:00
Martin Pöhlmann
39ad87650e findByXXX/findOneByXXX does now also accept orderBy, limit and offset args
Conflicts:

	lib/Doctrine/ORM/EntityRepository.php
2012-03-11 22:32:30 +01:00
Benjamin Eberlei
79d9c07652 [DDC-1693] Fix fatal errors in DQL when using Optimistic or None lock modes. Added tests. 2012-03-11 22:29:20 +01:00
Sander Marechal
47964a1605 Use assertCount for simpler tests 2012-03-08 09:48:41 +01:00
Sander Marechal
ad871e8b26 Cleaned up use statements 2012-03-08 09:41:35 +01:00
Sander Marechal
c9d962b12a Fix indentation 2012-03-07 08:57:51 +01:00
Sander Marechal
2f817b30c3 Use a dataProvider to test both TreeWalker and SqlWalker pagination 2012-03-07 08:52:00 +01:00
Sander Marechal
d2501a9e4a Throw exception when using the CountWalker with a HAVING query 2012-03-07 08:42:09 +01:00
patrick-mcdougle
7798c94a40 Fixed comment for createQuery to include the variable name. 2012-03-06 14:18:18 -06:00
Sander Marechal
edd5d14b06 Pagination using SQL walkers
A CountSqlWalker and LimitSubquerySqlWalker have been implemented. By
default the Paginator will use these SQL walkers. When a query already
uses custom SQL walkers, the Paginator will fall back to the existing
TreeWalker implementations. Improvements:

* Support for more complex DQL queries using named mixed results with
  GROUP BY and HAVING. For example:

  SELECT g, u, COUNT(u.id) AS userCount
      FROM Entity\Group g LEFT JOIN g.users u
      GROUP BY g.id
      HAVING userCount > 0

* Support for entities with composite primary keys in the CountSqlWalker
  and LimitSubquerySqlWalker. Only the WhereInWalker still needs to be
  updated for full composite primary key support. But someone smarter
  than me needs to look at that and figure out how to build a WHERE IN
  query that can select rows based on multiple columns.
2012-03-06 16:24:44 +01:00
Guilherme Blanco
f6a61b133e Fixed roken MySQL test. 2012-03-05 01:54:43 -05:00
Guilherme Blanco
f1fe360788 Merge pull request #296 from brikou/patch-2
According to "Doctrine's implicit CS" and "Symfony's implicit CS" an emp...
2012-03-04 07:36:25 -08:00
Brikou CARRE
e130df4f42 According to "Doctrine's implicit CS" and "Symfony's implicit CS" an empty line added to the end of the file (...same tweaks like the one pushed for the entity generator) 2012-03-04 09:43:52 +01:00
Guilherme Blanco
1a192b6530 Moved SQRT function to Platform. 2012-03-03 23:10:56 -05:00
Benjamin Eberlei
6195d42778 Merge branch 'DDC-1668' 2012-03-03 22:25:00 +01:00
Benjamin Eberlei
794b4ef09c [DDC-1668] Fix problem with the is_int fowards compatibility check. Its not really necesssary anymore, we should remove this code in the future. 2012-03-03 22:24:51 +01:00
Benjamin Eberlei
9cddaf3075 Merge pull request #256 from F5/many_to_many_listeners
When using a ManyToMany relationship no listener is notified about any change to the owning entity
2012-03-03 13:13:09 -08:00
Guilherme Blanco
bf80ee6a30 [DDC-1673] Fixed unused in ProxyFactory. 2012-03-03 13:16:26 -05:00
Guilherme Blanco
a47e566382 [DDC-1667] Removed implicit obligation to define an Index and UniqueConstraint name. It is optional, but Annotations Driver was broken if not defined. 2012-03-03 13:05:11 -05:00
Benjamin Eberlei
1447884fde Merge pull request #295 from brikou/patch-1
According to "Doctrine's implicit CS" and "Symfony's implicit CS" an emp...
2012-03-03 04:23:50 -08:00
Benjamin Eberlei
4a68b90f6f Merge pull request #294 from jmikola/patch-1
Fix typo in LifecycleEventArgs::getEntity() docs
2012-03-03 04:23:18 -08:00
Brikou CARRE
cb2c71b16a According to "Doctrine's implicit CS" and "Symfony's implicit CS" an empty line added to the end of the file 2012-03-02 09:57:24 +01:00
Jeremy Mikola
3d0e87bca9 Fix typo in LifecycleEventArgs::getEntity() docs 2012-03-01 17:03:46 -05:00
Guilherme Blanco
48dcee9d60 [DDC-1616] Removed non-SQL message and improve exportability of SchemaTool CreateCommand. 2012-02-22 01:19:01 -05:00
Vitali Yakavenka
78d3f647ff Merge branch 'master' of git://github.com/doctrine/doctrine2 into SupportCustomIdGenerators 2012-02-21 09:45:16 +03:00
Guilherme Blanco
55a9e1e90c Merge pull request #290 from doctrine/DDC-1652
[DDC-1652] Fix SqlWalker to include foreign key identifiers in SQL SELEC...
2012-02-20 14:34:52 -08:00
Benjamin Eberlei
1bbd52b8ee [DDC-1652] Fix SqlWalker to include foreign key identifiers in SQL SELECT statement no matter what the meta column setting is suggesting. 2012-02-20 17:48:34 +01:00
Benjamin Eberlei
9b9acd6e9e Fix composer.json with regards to latest changes. 2012-02-20 16:03:42 +01:00
Benjamin Eberlei
dbd646b2de [DDC-1649] Fix notice by last commit. 2012-02-20 15:55:19 +01:00
Benjamin Eberlei
502585bf40 [DDC-1649] Add additional check for not allowed mapping of dependent association keys. 2012-02-20 15:55:18 +01:00
Benjamin Eberlei
af07bd7818 Merge pull request #273 from smoya/master
No unique join column fields for Single Table inheritance type.
2012-02-20 06:55:00 -08:00
Benjamin Eberlei
a32948b20f Merge branch 'DDC-1654' 2012-02-20 10:33:26 +01:00
Benjamin Eberlei
68436fee75 [DDC-1654] Add support for orphanRemoval on ManyToMany associations. This only makes sense when ManyToMany is used as uni-directional OneToMany association with join table. The join column has a unique constraint on it to enforce this on the DB level, but we dont validate that this actually happens. Foreign Key constraints help prevent issues and notify developers early if they use it wrong. 2012-02-20 10:33:16 +01:00
Benjamin Eberlei
85d1707a2b Merge branch 'DDC-1659' 2012-02-20 09:36:51 +01:00
Benjamin Eberlei
35764c2402 [DDC-1659] Remove read only marker when clearing entities. 2012-02-20 09:36:35 +01:00
Benjamin Eberlei
5d352389b7 Merge pull request #270 from bmichotte/master
Fluent interface and relations
2012-02-20 00:24:07 -08:00
Benjamin Eberlei
f040ed0cf0 Merge pull request #287 from goetas/nullable
Nullable assocations for entity generator
2012-02-19 15:30:17 -08:00
Benjamin Eberlei
6cd82d77f5 Merge branch 'DDC-1651' 2012-02-18 16:08:09 +01:00
Benjamin Eberlei
bd1bc07270 [DDC-1651] Convert entities as parameters early in setParameter() to avoid them being part of result cache strings, which causes non-uniqueness. 2012-02-18 16:07:55 +01:00
Benjamin Eberlei
93f79d0810 Merge branch 'DDC-1643' 2012-02-18 00:43:04 +01:00
Benjamin Eberlei
9fc1d85e8d [DDC-1643] Fix bugs when cloning PersistentCollection and re-using it. 2012-02-18 00:42:21 +01:00
Benjamin Eberlei
d995c6dbdc [DDC-1655][DDC-1650][DDC-1556] Fix issues with @postLoad Callback being not fired, or fired multiple times. 2012-02-17 23:27:16 +01:00
Asmir Mustafic
d1b2dabc0f nullable assoc 2012-02-15 12:43:55 +01:00
Guilherme Blanco
e6b99c2059 Merge pull request #283 from FabioBatSilva/DDC-807
Fix DDC-807
2012-02-14 10:27:49 -08:00
Guilherme Blanco
2c3c5b34cf Merge pull request #282 from FabioBatSilva/discriminatorColumnName
Mandatory discriminator column name
2012-02-14 10:26:01 -08:00
Guilherme Blanco
e5d1f9e724 Merge pull request #284 from meandmymonkey/docblock-fix
docblock/typehint fix
2012-02-14 10:24:04 -08:00
Andreas Hucks
1d927541e2 added type hint 2012-02-14 19:12:20 +01:00
Andreas Hucks
3419c65efe fixed docblock 2012-02-14 19:08:44 +01:00
Andreas Hucks
2e81fbfd64 added type hint 2012-02-14 19:08:17 +01:00
Fabio B. Silva
da9b2e805e remove unused parameter 2012-02-13 23:43:19 -02:00
Fabio B. Silva
cdde6e8a5c fix required discriminator column name 2012-02-13 23:38:36 -02:00
Fabio B. Silva
5d01123413 Fix DDC-807, DDC-553 2012-02-13 23:22:49 -02:00
Guilherme Blanco
38d725ce32 Merge pull request #279 from FabioBatSilva/DDC-1642
Fix DDC-1642
2012-02-12 16:46:41 -08:00
Fabio B. Silva
86054eb659 fix DDC-1642 2012-02-12 22:24:03 -02:00
Benjamin Eberlei
600d0ba2a2 Merge branch 'DDC-1641' 2012-02-10 21:39:27 +01:00
Benjamin Eberlei
299def4712 DDC-1641 - Fix test producing failure when skipped. 2012-02-10 21:39:17 +01:00
Alexander
19a4d05035 Merge pull request #274 from mvrhov/DDC-1625
Proxy not initialized when parent has get<IDENTIFIER> function.
2012-01-30 07:23:19 -08:00
Miha Vrhovnik
bea78f42e3 Proxy not initialized when parent has get<IDENTIFIER> function. Fixes DDC-1625 2012-01-30 11:44:08 +01:00
Benjamin Eberlei
e774b1d8c0 Fix test for non-mysql like datetimes. 2012-01-29 15:02:40 +01:00
Benjamin Eberlei
3c4d2cd890 Merge pull request #253 from mrmkrs/protectedfields
enable set visibilty of class fields in EntityGenerator
2012-01-28 13:13:37 -08:00
Benjamin Eberlei
120bad8a2c Merge pull request #262 from wrightlabs/patch-1
added optional Command array as parameter for run method
2012-01-28 13:12:50 -08:00
Benjamin Eberlei
6b1ef08a46 Merge pull request #162 from ericclemmons/patch-1
ProxyFactory creates proxy's parent structure if it doesn't exist
2012-01-28 13:12:26 -08:00
Benjamin Eberlei
359a9c015b Merge pull request #196 from goetas/manyidx
Added some improvments for generated XML
2012-01-28 13:11:22 -08:00
Benjamin Eberlei
2ce705ceb3 Merge pull request #272 from jsor/table_options
Implement custom options on table level and complete column options implementation
2012-01-28 12:56:19 -08:00
Benjamin Eberlei
16b22f0f31 Merge pull request #266 from FabioBatSilva/DDC-1412
[DriverChain] Fix DDC-1412 Default Driver
2012-01-28 12:54:47 -08:00
Benjamin Eberlei
585ba534a6 Merge branch 'DDC-1526' 2012-01-28 12:28:23 +01:00
Benjamin Eberlei
3407620bf8 [DDC-1526] Collections are not marked as initialized when they are fetch joined but dont contain any results. This only occurs when using LEFT JOINs on the assocations and causes another query to be fired when the empty collection is accessed again. 2012-01-28 12:28:16 +01:00
Benjamin Eberlei
f9e943fefb Merge branch 'DDC-1617' 2012-01-28 11:16:48 +01:00
Benjamin Eberlei
551df4af52 [DDC-1617] Implement support for Generating Unique Constraints/Indexes in @Table annotation of EntityGenerator. 2012-01-28 11:16:36 +01:00
jsor
fac820f0e2 Complete custom column option implementation
- Support for xml driver
- Tests
2012-01-27 11:05:47 +01:00
Sergio Moya
88bbee127c No unique join column fields for Single Table inheritance type. 2012-01-26 17:37:50 +01:00
Jan Sorgalla
d68fcd8bd2 Implement custom options on table level 2012-01-26 15:05:26 +01:00
Benjamin Eberlei
35fc3c0671 Merge branch 'DDC-1619' 2012-01-25 10:19:18 +01:00
Benjamin Eberlei
7dae89bb02 [DDC-1619] Add QueryBuilder#distinct 2012-01-25 10:19:01 +01:00
Benjamin Eberlei
f0a09a2d52 Merge branch 'DDC-1618' 2012-01-25 00:03:56 +01:00
Thomas Rabaix
8027fca378 Add SqlWalker::HINT_DISTINCT constant 2012-01-25 00:03:40 +01:00
Thomas Rabaix
d9bb861b1f Fix DDC-1618 - add more check before throwing an iterateWithFetchJoinNotAllowed exception 2012-01-25 00:03:40 +01:00
Benjamin Michotte
1d2f46bda7 Add fluent code for relations 2012-01-24 19:08:25 +01:00
Benjamin Eberlei
aca20fc615 Merge pull request #268 from sandermarechal/paginate-where-not
Add support for paginating WHERE NOT ... queries
2012-01-23 11:50:50 -08:00
Sander Marechal
c6c82efe07 Fixed indentation 2012-01-23 16:11:30 +01:00
Sander Marechal
5dc0081f56 Add support for paginating WHERE NOT ... queries
The Pagination tool throws an exception on a DQL query like:

SELECT u FROM User u WHERE NOT (u INSTANCE OF Person)

This is because Paginate does not know about the
Doctrine\ORM\Query\AST\ConditionalFactor which implements the NOT
operator. This patch adds support for that.
2012-01-23 15:42:41 +01:00
Benjamin Eberlei
8bf1c96ae1 Merge branch 'DDC-1613' 2012-01-22 13:35:26 +01:00
Benjamin Eberlei
775071e1ff [DDC-1613] Merge KnpLabs/Pagerfanta Pagination into a Doctrine\ORM\Tools\Pagination namespace. Thanks to @hobodave, pablo and the knplabs team for developing and maintaining this code. 2012-01-22 13:35:06 +01:00
Benjamin Eberlei
358bb2ec33 Merge pull request #267 from webtor/master
Bugfix for crushing when git clone --recursive doctrine2
2012-01-22 01:40:14 -08:00
Alexandr Torosh
9f831f4c98 changed submodule doctrine-build-common url
https://github.com/doctrine/doctrine-build-common.git
to
git://github.com/doctrine/doctrine-build-common.git
with read-only access
2012-01-21 23:38:55 +02:00
Fabio B. Silva
0fce3c8f97 Fix DDC-1412 2012-01-21 12:42:46 -02:00
Benjamin Eberlei
1d46d2b9af Merge branch 'DDC-1610' 2012-01-21 13:58:33 +01:00
Benjamin Eberlei
faf92883b6 [DDC-1610] Add test and fix wakeup reflection in combination with event listener 2012-01-21 13:58:25 +01:00
Benjamin Eberlei
44831f21c1 Merge branch 'DDC-1612' 2012-01-21 13:06:38 +01:00
Benjamin Eberlei
6c24251452 [DDC-1612] Fix bug with EntityManager#flush($entity) on new entities. 2012-01-21 13:06:30 +01:00
Benjamin Eberlei
1d6a21f7fa Merge branch 'DBAL-204' 2012-01-21 11:32:07 +01:00
Benjamin Eberlei
0f3abde413 [DBAL-204] Filter namespaced assets if Schemas/Emulation is not supported. 2012-01-21 11:31:54 +01:00
Guilherme Blanco
febfe35c23 Added coverage for DDC-1529. 2012-01-18 23:51:11 -05:00
Guilherme Blanco
74f3ed7e29 Fixing CS. 2012-01-18 23:27:28 -05:00
Guilherme Blanco
b98280a504 Quick optimizations are always good. 2012-01-18 23:09:23 -05:00
Benjamin Eberlei
e0fc09994c DDC-742 - Flush Memcache, otherwise fail. 2012-01-18 21:32:56 +01:00
Guilherme Blanco
d39760ba49 Fixed DDC-1608. Non-initialized PersistentCollection methods removeElement and contains now deal correctly with managed entities. 2012-01-18 01:04:25 -05:00
John Wright
543c73bc05 added optional command array as parameter for run method 2012-01-16 21:01:44 -08:00
Guilherme Blanco
c1012f7970 Merge pull request #259 from danielholmes/m2m_extra_lazy_contains
Added fix for collection->contains with many-to-many extra lazy fetchMode
2012-01-16 19:51:11 -08:00
Guilherme Blanco
2bb511584e Merge pull request #261 from armetiz/patch-7
Unique key name isn't correctly set - DDC-1603
2012-01-16 19:44:22 -08:00
Guilherme Blanco
0f07044836 Added coverage to DDC-1587. 2012-01-16 22:31:14 -05:00
Guilherme Blanco
fdb2b9c655 Optimized scalar type mapping support. 2012-01-16 14:26:13 -05:00
armetiz
21c9be74c9 Update lib/Doctrine/ORM/Tools/SchemaTool.php 2012-01-16 13:54:04 +01:00
Benjamin Eberlei
28403abe78 Merge branch 'DDC-1604' 2012-01-16 12:51:20 +01:00
Benjamin Eberlei
a029b28423 [DDC-1604] Have ORM Proxy implement new \Doctrine\Common\Persistence\Proxy
* Adjust ProxyFactory to generate proxies according to new naming schema.
* Change proxy naming and file-name generation to be a bit more consistent than previous approach.

[DDC-1598] Additional regexp to check for simple ID methods to make it even more safe.
2012-01-16 12:50:36 +01:00
armetiz
56c49fedd2 Unique key name isn't correctly set - DDC-1603 2012-01-16 10:30:15 +01:00
Daniel Holmes
a12e5ac8a7 Updated some comparisons to strict equality 2012-01-16 08:12:11 +11:00
Benjamin Eberlei
27451a59d4 Merge pull request #254 from jsor/custom_options
Pass options attribute in @Column annotation to Schema\Column's customSchemaOptions
2012-01-15 09:06:46 -08:00
Benjamin Eberlei
47e56de443 Merge branch 'DDC-1594' 2012-01-15 17:42:37 +01:00
Benjamin Eberlei
56ea4872ca DDC-1594 - Fix problem with merge and an existing managed proxy instance. 2012-01-15 15:48:44 +01:00
Benjamin Eberlei
36ce26691d DDC-1585 - Throw exception if setting target entity of the wrong type to an assocation. 2012-01-15 14:59:20 +01:00
Daniel Holmes
5deebc8738 Added fix for collection->contains when many-to-many extra lazy fetchMode 2012-01-15 23:25:57 +11:00
Benjamin Eberlei
3c391f8f37 Merge pull request #258 from danielholmes/patch-1
Fix namespace of BasicEntityPersisterTypeValueSqlTest
2012-01-15 03:33:30 -08:00
Daniel Holmes
cd6b584722 Fix namespace of BasicEntityPersisterTypeValueSqlTest 2012-01-15 22:31:01 +11:00
Benjamin Eberlei
e8e830f10a Merge branch 'DDC-1601' 2012-01-15 12:12:15 +01:00
Benjamin Eberlei
9950af2f58 [DDC-1601] Fix failing test and remove unused code 2012-01-15 12:12:08 +01:00
Benjamin Eberlei
106f10513f [DDC-1601] Fix bugs in SchemaValidator, using all modelsets as testdata for a large test 2012-01-15 11:27:52 +01:00
Benjamin Eberlei
6ffe4d3dda [DDC-1601] Fix bugs in SchemaValidator, using all modelsets as testdata for a large test 2012-01-15 11:27:28 +01:00
Guilherme Blanco
ea14bcff4a Fixed DDC-657. Added type conversion to scalar result. 2012-01-13 20:46:59 -05:00
Marcel
f76d327413 use self:: instead of EntityGenerator:: 2012-01-13 14:43:13 +01:00
Marcel
72d5d0281a use !== to check field visibility
use class constants
2012-01-13 14:34:34 +01:00
Marcel
69f0d70a98 fix if coding standard
fix typo
2012-01-13 14:14:28 +01:00
Francisco Facioni
bab14bfd24 UnitTest for ManyToMany update notification 2012-01-13 09:35:27 -03:00
Marcel
f26d43b3ea remove whitespace
tabs -> spaces
added class constants
updated phpdoc
2012-01-13 11:24:35 +01:00
Guilherme Blanco
52ee848bcb Added coverage to DDC-1595 and DDC-1596. 2012-01-13 00:37:59 -05:00
Guilherme Blanco
bb10211983 Fixes DDC-1596. Added table alias to discriminator column when using STI. 2012-01-12 23:58:08 -05:00
Guilherme Blanco
da7fd2ece7 Merge pull request #250 from FabioBatSilva/DDC-1575
[DDC-1575] Give the FQCN to the naming strategy
2012-01-12 20:45:22 -08:00
Francisco Facioni
e7a6d87990 When using a ManyToMany relationship no listener is notified about any change to the owning entity.
What I'm doing with this patch is marking the entity for update when there is a modification in the ManyToMany relationship so the listeners are notified about it.

The main reason for this is for hooking up services like Solr or other indexers to update the entities even for ManyToMany relationships.
2012-01-12 14:38:07 -03:00
Benjamin Eberlei
c1dae35a24 Fix notice when using regenerate if exists and file is not new. 2012-01-12 11:20:49 +01:00
jsor
615e22073f Pass options attribute in @Column annotation to Schema\Column's customSchemaOptions 2012-01-11 15:58:57 +01:00
Benjamin Eberlei
adec530c13 Merge branch '2.2' 2012-01-09 08:26:33 +01:00
Benjamin Eberlei
41ae873048 DDC-1588 - Improve ResultCache API. The default cache impl is passed to new query cache profiles automatically now. 2012-01-09 08:26:07 +01:00
Benjamin Eberlei
d0b0b0ce59 Merge 2.2 2012-01-09 08:05:15 +01:00
Benjamin Eberlei
773fbd9edb Merge branch '2.2' 2012-01-09 08:04:44 +01:00
Benjamin Eberlei
0014afe746 Fix Typo 2012-01-09 08:04:21 +01:00
Benjamin Eberlei
e16803de61 [doctrine/common-GH-92] Fixing notice when annotation driver is used in combination with static reflection. 2012-01-09 08:02:53 +01:00
Vitali Yakavenka
53ecedf70a Remove support to pass arguments to custom ID generator's constructor 2012-01-08 15:20:35 +03:00
Vitali Yakavenka
b09201ae88 Recover changes in ClassMetadataFactoryTest::_createValidClassMetadata() lost during last merge 2012-01-08 14:55:08 +03:00
Vitali Yakavenka
59e9d55077 Merge doctrine/master 2012-01-06 22:06:59 +03:00
Marcel Raaijmakers
facd64ef2f enable set visibilty of class fields in EntityGenerator 2012-01-06 16:58:27 +01:00
Benjamin Eberlei
d34c39555d Bump dev version to 2.2.0 2012-01-03 22:27:03 +01:00
Benjamin Eberlei
8d3d604ed3 Release 2.2.0-BETA2 2012-01-03 22:27:03 +01:00
Benjamin Eberlei
4deeb23af0 Update dependencies 2012-01-03 21:56:04 +01:00
Fabio B. Silva
781a661704 change naming position 2012-01-03 17:58:20 -02:00
Fabio B. Silva
d8227fcd06 give the FQCN to the naming strategy 2012-01-03 16:59:43 -02:00
Benjamin Eberlei
3fff83cd13 Merge 2.2 into master 2012-01-03 19:20:11 +01:00
Benjamin Eberlei
133232eb6b Merge pull request #249 from doctrine/DCOM-93
[DCOM-93] Remove Reflection dependency from ClassMetadata
2012-01-03 10:12:03 -08:00
Benjamin Eberlei
ef8703e3e9 DCOM-93 - Allow to check testsuite with any constructor-less cache implementation 2012-01-03 19:01:53 +01:00
Benjamin Eberlei
a07fc515c7 DCOM-93 - Fix docblocks 2012-01-03 18:41:48 +01:00
Benjamin Eberlei
76e4f5a80b DCOM-93 - Removed reflection dependency from ClassMetadata completly, moving all the code into ClassMetadataInfo for BC reasons. 2012-01-02 21:32:18 +01:00
Benjamin Eberlei
c7d8c9f34e DCOM-93 - Factor out ClassMetadata constructor into delegate method initializeReflection 2012-01-02 17:06:22 +01:00
Benjamin Eberlei
1cecc9c429 DCOM-93 - Factor out __wakeup into a delegate-method from ClassMetadataFactory#wakeupReflection to ClassMetadataInfo#wakeupReflection 2012-01-02 15:57:32 +01:00
Benjamin Eberlei
ea2d4e4282 DCOM-93 - Add ClassMetadataFactory#wakeupReflection implementation 2012-01-02 15:46:20 +01:00
Benjamin Eberlei
80408ac34f DCOM-93 - Add empty initialize and wakeup methods. 2012-01-02 15:36:36 +01:00
Benjamin Eberlei
9bdf9a9904 DCOM-93 - Adjust ClassMetadataFactory#getClassParents() to use reflection service. 2012-01-02 15:30:25 +01:00
Benjamin Eberlei
9a0d36ae86 Fix Version 2012-01-02 15:13:48 +01:00
Benjamin Eberlei
c6730de3d1 Merge remote-tracking branch 'origin/2.2' 2012-01-02 15:13:26 +01:00
Benjamin Eberlei
239ffe468a Merge pull request #237 from asm89/ddc-551-collections-filters
[DDC-551] Support for inheritance with filters in lazy collections
2012-01-02 06:11:34 -08:00
Benjamin Eberlei
b558ffd694 Merge pull request #244 from kimhemsoe/fix_ddc224_test
Fixed DDC214 test.
2011-12-31 02:27:28 -08:00
Guilherme Blanco
9f3967d65d Merge pull request #245 from milokmet/DDC-1572
[DDC-1572] Allow LIKE pattern to be a function or path expression
2011-12-30 20:17:38 -08:00
Guilherme Blanco
4ae7851a04 Merge pull request #247 from juzna/fix-phpdoc
fixed phpDoc and typos
2011-12-30 13:05:37 -08:00
Jan Dolecek
12c3a42d8c fixed phpDoc and typos 2011-12-30 20:06:20 +01:00
Guilherme Blanco
e43897916a Merge pull request #246 from FabioBatSilva/DDC-1557
[DDC 1557] Support for DQL function on subselect
2011-12-29 11:22:23 -08:00
Fabio B. Silva
ab4482b617 update docblock 2011-12-29 17:05:44 -02:00
Miloslav Kmet
ae4321b4e3 [DDC-1572] Allow LIKE pattern to be a function or path expression 2011-12-29 19:51:48 +01:00
Fabio B. Silva
bf8924df14 some tests 2011-12-29 14:47:23 -02:00
Fabio B. Silva
4cc61bf2ee fix DDC-1557 2011-12-29 14:30:29 -02:00
Kim Hemsø Rasmussen
82bea24426 Fixed DDC214 test. 2011-12-29 02:05:54 +01:00
Benjamin Eberlei
87e0c69381 Merge remote-tracking branch 'origin/2.2' into 2.2 2011-12-28 20:29:53 +01:00
Benjamin Eberlei
a6deb51a05 DDC-1360 - Bugfix in quoting mechanism inside ClassMetadataInfo 2011-12-28 20:29:01 +01:00
Benjamin Eberlei
959a68694e Merge branch 'DDC-1360' 2011-12-28 20:28:45 +01:00
Benjamin Eberlei
9d398afa56 DDC-1360 - Bugfix in quoting mechanism inside ClassMetadataInfo 2011-12-28 20:28:17 +01:00
holtkamp
21cfe4ba9f Allow ExporterDrivers that implement the exportClassMetadata() function to return FALSE when no content is available/needs to be written to a file by the AbstractExporter, preventing empty files to be generated foreach processed ClassMetadataInfo instance. 2011-12-28 09:03:00 +01:00
Benjamin Eberlei
e5cf1da4ee Merge pull request #235 from holtkamp/patch-1
Allow ExporterDrivers that implement the exportClassMetadata() function to return false
2011-12-27 23:54:09 -08:00
Adrien BRAULT
bd49aa5d2c Fix some PHPDoc @return type. 2011-12-28 08:50:17 +01:00
Benjamin Eberlei
3cbb3eab18 Merge pull request #242 from FabioBatSilva/patch-1
[UnderscoreNamingStrategy] fix docblock
2011-12-27 23:46:36 -08:00
Fabio B. Silva
ff4ed93707 fix typo 2011-12-27 09:53:09 -02:00
Guilherme Blanco
abb258c951 Merge pull request #241 from FabioBatSilva/DDC-559
[DDC 559, DDC 852] Naming Strategy
2011-12-24 08:45:38 -08:00
Fabio B. Silva
603f7a1664 fix indentation 2011-12-24 12:34:49 -02:00
Fabio B. Silva
e3acf43dbc move naming classes to Doctrine\ORM\Mapping 2011-12-24 12:01:25 -02:00
Fabio B. Silva
1eddb53d6c fix CS and use php constants 2011-12-24 11:45:51 -02:00
Guilherme Blanco
93df588d87 Merge pull request #240 from FabioBatSilva/testFunctionSubstring
fix QueryDqlFunctionTest#testFunctionSubstring order
2011-12-23 09:17:42 -08:00
Guilherme Blanco
9b1092726d Merge pull request #239 from adrienbrault/master
Fix $qb->expr() PHPDoc @return type.
2011-12-23 09:16:50 -08:00
Fabio B. Silva
223577d8b5 fix QueryDqlFunctionTest#testFunctionSubstring order 2011-12-23 14:57:43 -02:00
Fabio B. Silva
8bdb713073 add support for NamingStrategy 2011-12-23 14:41:03 -02:00
comfortablynumb
6d5f15e708 Merge remote branch 'upstream/master' 2011-12-23 13:30:36 -03:00
Fabio B. Silva
eac34b6d6a test ClassMetadata whit UnderscoreNamingStrategy 2011-12-23 14:13:21 -02:00
Adrien BRAULT
da0a6fc619 Fix some PHPDoc @return type. 2011-12-23 17:05:08 +01:00
Fabio B. Silva
83a9458653 apply naming strategy on ClassMetadata 2011-12-23 12:28:09 -02:00
Fabio B. Silva
8b1f60c9f8 add UnderscoreNamingStrategy 2011-12-23 12:16:36 -02:00
Fabio B. Silva
537821418e apply naming strategy on ClassMetadataInfo 2011-12-23 11:29:50 -02:00
Fabio B. Silva
8368f0e4b9 change default namming strategy 2011-12-23 11:03:28 -02:00
Alexander
4cf5f70bea Update test 2011-12-22 23:21:56 +01:00
Alexander
c3c174512a Added tests for OneToMany associations and lazy collection to CTI entity 2011-12-22 21:10:13 +01:00
Alexander
f49a4e9c40 Added tests for OneToMany associations and lazy collection to STI entity 2011-12-22 20:50:57 +01:00
Alexander
223c47069e Added tests for ManyToMany associations and lazy collection to CTI entity 2011-12-22 17:49:57 +01:00
Fabio B. Silva
a038e6cbad test case 2011-12-22 14:07:58 -02:00
Guilherme Blanco
ec58285b3f Merge pull request #236 from FabioBatSilva/DDC-1065
[DDC-1065] Error messages
2011-12-22 07:31:37 -08:00
Fabio B. Silva
909dbdf29d default NamingStrategy 2011-12-22 12:07:18 -02:00
Fabio B. Silva
c2cee0d6eb error messages 2011-12-22 11:05:11 -02:00
holtkamp
177adbdfc7 Allow ExporterDrivers that implement the exportClassMetadata() function to return FALSE when no content is available/needs to be written to a file by the AbstractExporter, preventing empty files to be generated foreach processed ClassMetadataInfo instance. 2011-12-22 09:38:55 -02:00
Alexander
62be27b295 Added tests for ManyToMany associations and lazy collection to STI entity 2011-12-22 00:25:21 +01:00
Benjamin Eberlei
06de4e62a5 Add 2.2 to travis status icon list 2011-12-22 00:08:53 +01:00
Benjamin Eberlei
b91689fe2f Update common with fix on interface detection 2011-12-21 23:57:33 +01:00
Benjamin Eberlei
f6f2acad4c Merge Improve Error Messages into 2.2 2011-12-21 23:56:25 +01:00
Benjamin Eberlei
ca470d8ba7 Fix glitch in Version produced by build-script 2011-12-21 00:00:43 +01:00
Benjamin Eberlei
0551ccca92 Bump dev version to 2.2.01 2011-12-20 22:39:27 +01:00
Benjamin Eberlei
6136654dad Release 2.2.0-BETA1 2011-12-20 22:39:27 +01:00
Benjamin Eberlei
9d906fa31e Update build common 2011-12-20 22:39:12 +01:00
Benjamin Eberlei
dcaf1b5891 Prepare 2.2 beta 2011-12-20 22:38:38 +01:00
Benjamin Eberlei
9f81d5d077 Fix PEAR path 2011-12-20 21:55:58 +01:00
Alexander
d3e697143f Merge pull request #234 from FabioBatSilva/testJoinQueries
Fix QueryTest#testJoinQueries order
2011-12-20 11:25:04 -08:00
Fabio B. Silva
e90545cef5 ORDER BY CmsArticle#topic 2011-12-20 17:22:14 -02:00
Fabio B. Silva
0a01b14830 fix QueryTest#testJoinQueries order 2011-12-20 16:14:01 -02:00
Guilherme Blanco
4bc014c696 Merge pull request #233 from FabioBatSilva/DDC-1539
[DDC-1539] Fix DDC-1539
2011-12-20 08:36:18 -08:00
Fabio B. Silva
e45ebbac46 remove white spaces 2011-12-20 10:40:29 -02:00
Fabio B. Silva
24dc74a800 Fixed DDC-1539 2011-12-20 10:31:00 -02:00
Guilherme Blanco
772f58a95b Removed test since I'm unable to test now. 2011-12-20 00:48:19 -05:00
Guilherme Blanco
f6eb83705a Added coverage to DDC-1521. Small CS changes. 2011-12-20 00:05:14 -05:00
Vitali Yakavenka
4879c50c5d Merge remote-tracking branch 'doctrine/master' into SupportCustomIdGenerators 2011-12-19 16:47:47 -08:00
Benjamin Eberlei
6c4aaab2d6 Merge branch 'TrailingWhitespaces' 2011-12-19 22:56:52 +01:00
Benjamin Eberlei
cd6131c9b8 Remove all trailing whitespaces 2011-12-19 22:56:19 +01:00
Benjamin Eberlei
f2d8102bbf Fix bug in test, removed an assertion that is not necessary and violates sqlites autoincrement assumptions 2011-12-19 22:32:50 +01:00
Benjamin Eberlei
86f67788c5 Merge pull request #231 from FabioBatSilva/tmp2
[DDC 1213]  bit comparison ( BIT_AND() , BIT_OR() )
2011-12-19 11:08:05 -08:00
Fabio B. Silva
ea5108ea0f rebase upstream/master 2011-12-19 16:25:31 -02:00
Fabio B. Silva
5c89d7ffcb support for bit comparison 2011-12-19 16:24:16 -02:00
Benjamin Eberlei
568698e321 Add dependency to doctrine-build-common and refactor build.xml and build.properties 2011-12-19 19:16:26 +01:00
Benjamin Eberlei
b545525e13 Update ORM to Doctrine Common master 2011-12-19 18:03:53 +01:00
Benjamin Eberlei
bf32125bad DDC-1545 - Fix issue with changing values from null to something new.
This issue was introduced by a side-effect in 2.1.3 with
d9f9228d95. In this commit read-only
objects where prevented to be updated. This lead to an invalid check not
being performed in UnitOfWork#computeChangeSet which was present before
where an association that was null would be injected into the
originalEntityData using the UnitOfWork#setOriginalEntityProperty()
method in the AbstractHydrator.

This commit now explicitly sets this field to null using the same API so
that is present during UnitOfWork#computeChangeSet.
2011-12-19 17:55:19 +01:00
Benjamin Eberlei
a9035e1533 Merge remote-tracking branch 'origin/master' 2011-12-19 17:11:19 +01:00
Guilherme Blanco
68663fac4b Fixed issue when one to one badly populated when containing null values. Fixed DDC-1548. 2011-12-19 10:55:29 -05:00
Benjamin Eberlei
b1b10042d2 Revert "Fixed issue with fetched association not being considered during changeSet calculation. Fixes DDC-1545."
This reverts commit a8478d5766.
2011-12-19 16:31:26 +01:00
comfortablynumb
bf9024b622 Merge remote branch 'upstream/master' 2011-12-19 11:09:09 -03:00
Alexander
108cb53eef Merge pull request #229 from bschussek/DDC-1545
DDC-1545
2011-12-19 03:22:49 -08:00
Bernhard Schussek
e035fe7949 Fixed class name of test for DDC-1545 2011-12-19 11:20:37 +01:00
Benjamin Eberlei
40800bd3cd DDC-1530 - Validate field types in SchemaValidator 2011-12-19 10:11:11 +01:00
Alexander
4f67ea3869 Merge pull request #228 from asm89/ddc-551-parameter-inference
Fixed testsuite
2011-12-19 01:02:30 -08:00
Alexander
8c6c49a6ee Fixed testsuite 2011-12-19 09:55:49 +01:00
Benjamin Eberlei
7f8f39168a Merge pull request #227 from asm89/ddc-551-parameter-inference
[DDC-551] Add type inference to SQLFilter::setParameter() + cleaned tests
2011-12-19 00:47:58 -08:00
Alexander
bd07f8d3dd [DDC-551] Add type inference to SQLFilter::setParameter() + cleaned tests 2011-12-19 08:43:42 +01:00
Guilherme Blanco
a8478d5766 Fixed issue with fetched association not being considered during changeSet calculation. Fixes DDC-1545. 2011-12-19 01:39:48 -05:00
Guilherme Blanco
f6d9344d89 Merge pull request #219 from FabioBatSilva/DDC-1468
Fixed DDC-1468
2011-12-18 19:20:33 -08:00
Benjamin Eberlei
91e700a70e Merge pull request #226 from asm89/ddc-1505
[DDC-1505] joinColumn "nullable" should be handled true by default
2011-12-18 12:59:49 -08:00
Alexander
de769c6c3c [DDC-1505] joinColumn "nullable" should be handled true by default 2011-12-18 21:33:38 +01:00
Benjamin Eberlei
29fabbd81f Merge pull request #225 from asm89/fix-pgsql-testsuite
[DDC-551] Fix testcase on pgsql
2011-12-18 10:59:35 -08:00
Alexander
5160bdc1a8 [DDC-551] Fix testcase on pgsql 2011-12-18 19:58:32 +01:00
Benjamin Eberlei
003d1410b0 Merge pull request #224 from doctrine/DDC-551
DDC-551 - Filter branch
2011-12-18 08:03:23 -08:00
Bernhard Schussek
9b877499c7 Added test case for DDC-1545 2011-12-18 12:13:58 +01:00
Benjamin Eberlei
9cd8f85a8c DDC-1456 - Disallow setting id generators on composite identifiers. 2011-12-18 00:32:35 +01:00
Benjamin Eberlei
072094f722 DDC-1368 - Fix tests 2011-12-17 23:38:39 +01:00
Benjamin Eberlei
170271fd72 DDC-1368 - Improve schema validator 2011-12-17 23:27:39 +01:00
Benjamin Eberlei
bb47e90696 Merge pull request #223 from doctrine/DDC-1544
DDC-1544
2011-12-17 14:04:54 -08:00
Benjamin Eberlei
20c859611a Merge pull request #222 from EvanDotPro/DDC-1544
DDC-1544 Unit test / assertions for ResolveTargetEntityListener
2011-12-17 14:03:33 -08:00
Evan Coury
36a47e391c DDC-1544 - Add unit test and assertions for ResolveTargetEntityListener 2011-12-17 15:00:05 -07:00
Benjamin Eberlei
267ce7df88 DDC-1544 - Add ResolveTargetEntityListener 2011-12-17 19:35:10 +01:00
Benjamin Eberlei
cfe1259400 DDC-1541 - Fix wrong references in ClassMetadataBuilder 2011-12-17 12:39:44 +01:00
Benjamin Eberlei
6015253064 DDC-1524 - Add validation and error messages for annotation named query code. 2011-12-17 12:35:22 +01:00
Benjamin Eberlei
98bd5cae64 Revert "Incorporated setAssociationTargetClass, which solves biggest problem of modular system in ZF. Any questions, pelase forward to @EvanDotPro."
This reverts commit cac9928f28.
2011-12-17 11:36:23 +01:00
comfortablynumb
d7042ab828 Merge branch 'master', remote branch 'upstream/master' 2011-12-16 20:01:10 -03:00
Guilherme Blanco
cac9928f28 Incorporated setAssociationTargetClass, which solves biggest problem of modular system in ZF. Any questions, pelase forward to @EvanDotPro. 2011-12-16 16:16:22 -05:00
Asmir Mustafic
289c186de5 orphanRemoval default is false 2011-12-16 16:16:52 +01:00
Benjamin Eberlei
cd04cbc7c4 Merge branch 'DDC-1514' 2011-12-15 23:00:13 +01:00
Benjamin Eberlei
5b5fb2b732 DDC-1514 - Fix complex self-referencing + proxy hydration problem. 2011-12-15 23:00:01 +01:00
Benjamin Eberlei
e8a47b3921 DDC-1519 - Fix bug in merging of entities that contain foreign identifiers 2011-12-15 20:49:25 +01:00
Fabio B. Silva
017a7d889f Fixed DDC-1468 2011-12-15 17:12:01 -02:00
Guilherme Blanco
41a3d90a57 Merge pull request #214 from yethee/xml_driver
Fixed typo in the XmlDriver
2011-12-13 20:07:43 -08:00
Benjamin Eberlei
99e46a23c6 Bugfix in UnitOfWorklib/Doctrine/ORM/UnitOfWork.phptriggerEagerLoads() 2011-12-13 21:26:04 +01:00
Guilherme Blanco
65c2b498ad Removed broken test. 2011-12-12 23:40:48 -05:00
Benjamin Eberlei
f7ede572e0 DDC-1415 - Remove EntityEventDelegatee, the API sucks and we need another approach. 2011-12-12 16:46:53 +01:00
Benjamin Eberlei
43ef8765fd DDC-1527 - Port bugfix for master branch 2011-12-12 16:39:52 +01:00
Benjamin Eberlei
bda98150c4 Merge pull request #216 from andrewmackrodt/DDC-1025
DDC-1025 - Absolute Namespace Annotations
2011-12-11 14:32:02 -08:00
Andrew Mackrodt
ef12a09ae0 Added remaining absolute namespace paths to phpdoc annotations - issue DDC-1025. 2011-12-11 21:56:27 +00:00
Andrew Mackrodt
2fdb55a878 Added absolute namespace paths to phpdoc annotations - issue DDC-1025. 2011-12-11 21:56:26 +00:00
Benjamin Eberlei
b6d776f75d DDC-551 - rework walker filtering 2011-12-11 21:14:09 +01:00
Benjamin Eberlei
ad6130b02d DDC-551 - Cleanup filters branch, especially inheritance related code and yoda conditions and some inconsistencies 2011-12-11 19:29:36 +01:00
Benjamin Eberlei
ca5dbb182a DDC-551 - Make filters case-sensitive everywhere 2011-12-11 19:27:50 +01:00
Benjamin Eberlei
69b1eb5c64 DDC-551 - Fix locking mess with filters 2011-12-11 18:46:57 +01:00
Benjamin Eberlei
0f501114eb Merge branch 'master' into DDC-551 2011-12-11 18:39:11 +01:00
Benjamin Eberlei
f7175c229e DDC-551 - Fix some ugly yoda conditions and a wrong nesting. 2011-12-11 18:39:04 +01:00
Benjamin Eberlei
853a0ee865 Merge branch 'DDC-1515' 2011-12-11 17:09:11 +01:00
Benjamin Eberlei
40d094fea2 DDC-1515 - Now the real bugfix 2011-12-11 17:08:58 +01:00
Benjamin Eberlei
f6d2b00d5c DDC-1400 - var_dump(), seriously? 2011-12-11 16:42:59 +01:00
Benjamin Eberlei
57970499fd Revert "DDC-1515 - Merge from 2.1.x"
This reverts commit bd0fb574e3.
2011-12-11 16:11:16 +01:00
Benjamin Eberlei
bd0fb574e3 DDC-1515 - Merge from 2.1.x 2011-12-11 16:07:35 +01:00
Deni
2ce9246733 Fixed typo in the XmlDriver 2011-12-11 17:24:38 +04:00
Guilherme Blanco
954b5077e4 Fixed nesting recursion error in some situations. Complement to DDC-1276. 2011-12-09 10:59:53 -05:00
Guilherme Blanco
0febf06114 Made ClassMetadataBuilder support ClassMetadataInfo instead of ClassMetadata. Fixed DDC-1508. 2011-12-09 00:04:47 -05:00
Guilherme Blanco
33c5b639b0 Merge pull request #211 from FabioBatSilva/DDC-1057
DDC-1057
2011-12-07 07:25:45 -08:00
Fabio B. Silva
8e50a31b98 trying remove whitespaces 2011-12-07 12:31:23 -02:00
Fabio B. Silva
c6a89c64f3 put return after comment 2011-12-07 12:16:27 -02:00
Fabio B. Silva
df19e68a86 Fixed DDC-1057 2011-12-07 11:23:15 -02:00
Alexander
5e91f0c1ca [DDC-551] Update SQLWalker to reflect filter requirements for inheritance 2011-12-07 10:02:15 +01:00
Alexander
efe7a01482 [DDC-551] Fixed CS, comments by @stof 2011-12-05 23:00:52 +01:00
Alexander
f4663f4512 [DDC-551] Another batch of small refactorings 2011-12-05 22:19:54 +01:00
Alexander
e8d30068e2 [DDC-551] Various refactorings 2011-12-05 22:05:42 +01:00
Alexander
04635ad4ff Merge remote-tracking branch 'upstream/master' into DDC-551
Conflicts:
	lib/Doctrine/ORM/Persisters/ManyToManyPersister.php
	lib/Doctrine/ORM/Persisters/OneToManyPersister.php
2011-12-05 21:53:34 +01:00
Guilherme Blanco
eaec259186 Merge pull request #209 from FabioBatSilva/DDC1170
DDC-1170
2011-12-05 12:16:39 -08:00
Alexander
3b7d16c60f [DDC-551] General cleanup of the code. 2011-12-05 21:14:31 +01:00
Fabio B. Silva
33c68df3ba Fixed DDC-1170 2011-12-05 17:35:49 -02:00
Alexander
4c842974b4 [DDC-551] Add filters only on root entities in SingleTablePersister 2011-12-05 18:56:44 +01:00
Alexander
752b502326 [DDC-551] Add filters only on root entities in JoinedSubclassPersister 2011-12-05 18:26:56 +01:00
Alexander
e98c775f0d Revert "[DDC-551] Initial support for filters in the JoinedSubclassPersister"
This reverts commit f6d5f0481e.
2011-12-05 16:14:04 +01:00
Guilherme Blanco
0380d5ae58 Implemented multiple enhancements in InExpression support for DQL. Fixed DDC-1472 and DDC-1416. 2011-12-04 02:41:54 -05:00
Guilherme Blanco
a26990c3e8 DDC-1457: Fixed wrong docblock. 2011-12-04 02:14:47 -05:00
Guilherme Blanco
2f6b930a8d Implemented missing support in CollectionMemberComparison. Removed old todo in ArrayHydrator. Finished implementation of IdentificationVariable in ArithmeticPrimary. 2011-12-03 15:19:21 -05:00
Guilherme Blanco
2642daa438 Fixed DDC-1236: GROUP BY now supports ResultVariable and IdentificationVariable. Composite PK is also supported. If you are willing to group by an aggregate function or a function itself, just place it in SELECT expression then refer to it in the GROUP BY clause. If you are not willing to have the function being part of your resultset, just mark the column as HIDDEN and you are done. 2011-12-01 23:52:35 -05:00
Benjamin Eberlei
619a31913a DDC-1517 - Fix EntityRepository#find() and EntityManager#getReference() breaking on invalid or missing identifiers. 2011-12-01 21:18:39 +01:00
Guilherme Blanco
5e3e8b3957 More refactorings and optimizations. 2011-12-01 10:00:26 -05:00
Alexander
bf1cc29a2a [DDC-551] Fixed some comments 2011-12-01 09:46:02 +01:00
Alexander
f6d5f0481e [DDC-551] Initial support for filters in the JoinedSubclassPersister
Still some things to do.
2011-11-30 23:01:10 +01:00
Alexander
4c94a7ccc5 [DDC-551] Various minor fixes after merge and cleanup 2011-11-30 16:40:55 +01:00
Guilherme Blanco
5b73f1bd82 Improved code readability. Improved performance. 2011-11-30 09:57:54 -05:00
Vitali Yakavenka
353ba4dfd1 Remove trailing whitespaces and fix brace locations 2011-11-30 00:20:00 +03:00
Vitali Yakavenka
f13f44a2fc Merge branch 'master' of git://github.com/doctrine/doctrine2 into SupportCustomIdGenerators 2011-11-29 23:42:01 +03:00
Guilherme Blanco
356f5874bf Added support to removeElement remove items without initializing the PersistentCollection. 2011-11-29 11:29:17 -05:00
Guilherme Blanco
24f6b74427 Refactored UnitOfWork::createEntity, improving its performance. 2011-11-29 10:36:32 -05:00
Vitali Yakavenka
c92b78bc06 Cleanup formatting just a little 2011-11-29 00:48:08 +03:00
Vitali Yakavenka
b72d150d33 Rename custom-generator to custom-id-generator in XML mappint to match name in other mapping types 2011-11-28 23:36:23 +03:00
Vitali Yakavenka
a8787be0bf Add missing files from last comming and newly required one after rebase 2011-11-28 23:31:06 +03:00
Vitali Yakavenka
9d1402e4a5 Fix PHPMappingDriver tests 2011-11-28 23:30:32 +03:00
Vitali Yakavenka
84086915e4 Add support for custom ID generator in Yaml driver 2011-11-28 23:30:32 +03:00
Vitali Yakavenka
0a4fbc9770 Remove test for custom ID generator from AnnotationDriverTest as it duplicates one in AbstractMappingDriverTest 2011-11-28 23:30:32 +03:00
Vitali Yakavenka
2b97f79bd3 Add support for custom ID generator in XML 2011-11-28 23:30:32 +03:00
Vitali Yakavenka
6bcfaed640 Remove explicit annotation registration after it was merged into OrmTestCase 2011-11-28 23:30:32 +03:00
Vitali Yakavenka
e2953c8cd4 Rename test accoring to what it tests 2011-11-28 23:29:42 +03:00
Vitali Yakavenka
48b6356e53 Add support for GenerateValue(strategy='CUSTOM') in AnnotationDriver 2011-11-28 23:29:42 +03:00
Vitali Yakavenka
955497e3d5 Remove unnecessary mock 2011-11-28 23:24:19 +03:00
Vitali
82daf651fb Pass specified arguments to generator's constructor 2011-11-28 23:24:19 +03:00
Vitali
cd0915deb5 Introcude ClassMetadataInfo::GENERATOR_TYPE_CUSTOM for custom generators to follow current implementation 2011-11-28 23:24:18 +03:00
Vitali
ffc722a334 Allow loading of custom ID generator class by FQN in @GeneratedValue(type=) 2011-11-28 23:24:18 +03:00
Vitali
3f942e05f3 Register annotations to make ClassMetadataFactoryTest pass alone 2011-11-28 23:22:08 +03:00
Benjamin Eberlei
62ec98a9fc Merge pull request #205 from Seldaek/psr0
PSR-0 compliance
2011-11-28 05:05:50 -08:00
Benjamin Eberlei
f2467dd30e Merge branch 'DDC-1512' 2011-11-28 11:16:35 +01:00
Benjamin Eberlei
0c12d3ed5a DDC-1512 - Make ClassMetadataFactory::isTransient() entity namespace aware. 2011-11-28 11:16:23 +01:00
Benjamin Eberlei
f2f32ca70f DDC-1509 - Fix regression in doMerge() introduced with the DDC-1383 bugfix 2011-11-28 10:04:33 +01:00
Jordi Boggiano
b8ac2fb416 Add requires to new files for BC 2011-11-27 18:16:18 +01:00
Jordi Boggiano
10e74040af PSR-0 compliance 2011-11-27 12:59:17 +01:00
Benjamin Eberlei
2b7360e738 Merge pull request #200 from velovint/StandaloneTestsFailing
Register DoctrineAnnotations on call to OrmTestCase::createAnnotationDri...
2011-11-26 00:17:12 -08:00
Alexander
be48821e86 Merge remote-tracking branch 'origin/master' into DDC-551
Conflicts:
	lib/Doctrine/ORM/Persisters/BasicEntityPersister.php
	lib/Doctrine/ORM/Query.php
2011-11-23 22:43:42 +01:00
Alexander
68027e1b5f Merge remote-tracking branch 'upstream/master' 2011-11-23 22:31:17 +01:00
Guilherme Blanco
ef33454301 Reverted PR which broke suite. Issue is still valid, but it requires more investigation. 2011-11-23 08:40:47 -05:00
Guilherme Blanco
bfcea9460b Merge pull request #202 from realestateconz/master
Fixed array flip breaking discriminator map SQL generation
2011-11-22 18:36:30 -08:00
warezthebeef
b80ef58cab Fixed array_flip breaking discriminator map SQL generation 2011-11-23 12:15:23 +13:00
Benjamin Eberlei
be4eb63c62 Merge branch 'DBAL-15' 2011-11-21 21:38:05 +01:00
jsor
16aa558292 Remove sql conversion from where clauses and update statements 2011-11-21 15:08:36 +01:00
Benjamin Eberlei
135e515e7f DDC-1500 - Fix potential security problem in EntityRepository ORDER BY orientations 2011-11-21 15:04:46 +01:00
Guilherme Blanco
7ca43b72c9 Merge pull request #201 from jonathaningram/patch-1
Fixed typo
2011-11-21 05:16:40 -08:00
Jonathan Ingram
248c9bdeff Fixed typo 2011-11-21 12:34:20 +11:00
Jan Sorgalla
4042bc53ce Fix argument on wrong method call 2011-11-20 19:57:04 +01:00
Jan Sorgalla
841d12e9b6 Move check for conversion SQL to ClassMetadataInfo 2011-11-20 19:50:51 +01:00
Vitali
507c8f45b4 Register DoctrineAnnotations on call to OrmTestCase::createAnnotationDriver() 2011-11-20 17:02:15 +03:00
Benjamin Eberlei
bda593a66d DDC-1448 - Add support for ObjectManagerAware interface and PersistentObject in ORM 2011-11-19 13:06:24 +01:00
Benjamin Eberlei
8eaf160ead Update Doctrine Common Vendor 2011-11-19 09:29:32 +01:00
Benjamin Eberlei
53b3030aa2 Clarify EntityManager#transactional() docblock 2011-11-19 08:58:58 +01:00
Benjamin Eberlei
dc0a03ab30 DDC-1400 working testcase 2011-11-19 08:50:49 +01:00
Jan Sorgalla
6f35679911 Initial implementation of Doctrine\DBAL\Types\Type::convertToDatabaseValueSQL() and Doctrine\DBAL\Types\Type::convertToPHPValueSQL() integration 2011-11-19 00:35:29 +01:00
Benjamin Eberlei
f9a4dcb2d0 Remove code that could allow users of xml and yaml to define orphan removal on the wrong association sides. 2011-11-18 18:33:03 +01:00
Benjamin Eberlei
a0d6d84a4f Merge branch 'DBAL-171' 2011-11-18 17:42:38 +01:00
Benjamin Eberlei
166c05dfaa Fix tests to be more stable 2011-11-18 17:42:32 +01:00
Benjamin Eberlei
ab4d3c3a09 Merge branch 'DBAL-171' 2011-11-18 17:30:26 +01:00
Benjamin Eberlei
9e8a950f2e DBAL-171 - Fix bug where params where resorted but types where not in DQL Query 2011-11-18 17:29:31 +01:00
Benjamin Eberlei
0d4e0626cf Merge pull request #158 from goetas/cascade-all
Collapsed cascade elements, if cascade-all.
2011-11-18 06:49:40 -08:00
Benjamin Eberlei
ef0a901cf5 Merge branch 'DDC-1496' 2011-11-18 15:44:19 +01:00
Benjamin Eberlei
ceadc95439 DDC-1496 - Fix bug with OneToMany collections having orphanRemoval=true and Collection#clear() being called. 2011-11-18 15:44:06 +01:00
Benjamin Eberlei
61e371cbdc DDC-1069 - Fix error in docblocks of query builder 2011-11-18 14:43:47 +01:00
Benjamin Eberlei
b44ff9b849 Merge pull request #194 from FabioBatSilva/DDC-1430-PGSQL-TEST
DDC-1430 - fix broken test on postgres
2011-11-18 05:14:15 -08:00
Benjamin Eberlei
2187f33477 Add test for DDC-1436 and DDC-1452 showing they are the same issues 2011-11-18 13:28:56 +01:00
Asmir Mustafic
24432bd0ab tabs 2011-11-18 11:00:20 +01:00
Asmir Mustafic
82a1626e82 Better generation of exported xml (valid with xsd) 2011-11-18 10:57:27 +01:00
Fabio B. Silva
f4da4591fa fix broken test on postgres 2011-11-16 09:48:11 -02:00
Benjamin Eberlei
43b1e79ec4 Merge pull request #193 from FabioBatSilva/DDC-1430
DDC 1430
2011-11-15 14:47:45 -08:00
Fabio B. Silva
aeb2ab132b group by all fields when entity has foreign keys 2011-11-15 20:27:45 -02:00
Fabio B. Silva
4cbd5eac95 Test Foreign Keys 2011-11-15 18:54:53 -02:00
Benjamin Eberlei
2d14be86f3 Merge pull request #192 from FabioBatSilva/DDC-1474
DDC-1474
2011-11-15 12:10:19 -08:00
Fabio B. Silva
08edf34057 move tests to SelectSqlGenerationTest 2011-11-15 17:27:17 -02:00
Benjamin Eberlei
9916f34262 Merge pull request #191 from FabioBatSilva/DDC1430
DDC-1430
2011-11-15 11:07:30 -08:00
Benjamin Eberlei
a0ee72f264 Fix bug introduced in recent XmlDriver commit 2011-11-15 20:03:56 +01:00
Fabio B. Silva
3f8347a4d9 fixed DDC-1474 2011-11-15 17:00:19 -02:00
Guilherme Blanco
14f20c16bc Changed the RSM to make is behavior as mixed if you alias an entity. 2011-11-15 15:14:57 -02:00
Fabio B. Silva
3dd5d14977 Fixed DDC-1430 2011-11-15 14:28:57 -02:00
Guilherme Blanco
77e076f1fd Fixed DDC-1492. 2011-11-15 01:10:27 -02:00
Guilherme Blanco
45d95ad130 Fixed wrong indentation by my previous commit. 2011-11-15 01:09:48 -02:00
Benjamin Eberlei
9b32a2d87a DDC-1452 - Fix missing fetched parameter in BasicEntityPersister 2011-11-14 23:37:02 +01:00
Benjamin Eberlei
3e95eed76e Merge branch 'DDC-1452' 2011-11-14 23:06:00 +01:00
Benjamin Eberlei
34c94dbd94 DDC-1452 - Fixed bug with multiple fetch joins of the same "propery-path" of Class+field name combinations 2011-11-14 23:05:33 +01:00
Benjamin Eberlei
98033cc878 Merge branch 'master' into DDC-1452 2011-11-14 21:53:36 +01:00
Benjamin Eberlei
909504c074 DDC-1461 - Fix test failures 2011-11-14 21:05:44 +01:00
Benjamin Eberlei
4c7e4296c9 Merge pull request #189 from FabioBatSilva/DDC-1404
DDC-1404
2011-11-14 10:32:31 -08:00
Benjamin Eberlei
1b7eacd9fa Merge pull request #188 from FabioBatSilva/DDC-1476
DDC-1476
2011-11-14 10:31:30 -08:00
Fabio B. Silva
8af0f9d071 added support for Inherited Named Queries 2011-11-14 16:07:37 -02:00
Fabio B. Silva
0632b37492 fix default field type 2011-11-14 13:17:56 -02:00
Guilherme Blanco
81cc6d9da8 Implemented alias support for EntityResult. This addresses DDC-1096 and DDC-1424. Improved DQL Parser, SQL Walker and Hydrators in general. Performance is generally improved by a factor of 20%. There is still more to be done, like remove the isMixed in ResultSetMapping, mainly because this query - SELECT u AS user FROM User u -, it should return an array('user' => [User object]), while currently it doesn't due to this before mentioned 'bug' in RSM. Will open a separate ticket for this. Also, UnitOfWork and Hydrators share code that could be abstracted/improved. 2011-11-14 01:36:39 -02:00
Benjamin Eberlei
e8eda4aeae Merge branch 'DDC-1461' 2011-11-13 23:14:40 +01:00
Benjamin Eberlei
c648981f28 DDC-1461 - Verified deferred explicit works 2011-11-13 23:14:31 +01:00
Benjamin Eberlei
c87d5af243 Specialize build status on versions 2011-11-13 22:40:27 +01:00
Benjamin Eberlei
077d4a0e15 Fix travis configuration files 2011-11-13 22:04:48 +01:00
Benjamin Eberlei
0fdffb9dbc Fix postgresql travis phpunit configuration file 2011-11-13 17:57:54 +01:00
Benjamin Eberlei
c2bb281e80 Merge travis support from @pborreli - thanks! 2011-11-13 17:44:37 +01:00
Benjamin Eberlei
6b0cd7b604 Merge branch 'master' of github.com:doctrine/doctrine2 2011-11-13 17:17:06 +01:00
Benjamin Eberlei
bb853722dc Merge branch 'thiagofesta-master' 2011-11-13 17:16:51 +01:00
Benjamin Eberlei
4571e498b4 DDC-1477 - Adjust patch to really fix bug in Proxy generation 2011-11-13 17:16:43 +01:00
Benjamin Eberlei
4e10a95dca Merge branch 'master' of https://github.com/thiagofesta/doctrine2 into thiagofesta-master 2011-11-13 17:05:23 +01:00
Benjamin Eberlei
e9068a1552 Merge pull request #175 from lsmith77/get_class_name
added EntityRepository::getClassName()
2011-11-13 07:57:58 -08:00
Benjamin Eberlei
64b649ef61 Merge pull request #160 from goetas/generation
Allow to unset one-to-one relation with generated class
2011-11-13 07:53:58 -08:00
Benjamin Eberlei
70f0136c8a Merge branch 'everzet-PreFlush-event' 2011-11-13 16:51:40 +01:00
Benjamin Eberlei
6520211df3 Merge everzet/PreFlush-event 2011-11-13 16:51:23 +01:00
Benjamin Eberlei
056b34d847 Merge branch 'DDC-1491' 2011-11-13 15:45:15 +01:00
Benjamin Eberlei
f7c46c7b33 DDC-1491 - Fix Schema Validator bug 2011-11-13 15:45:06 +01:00
Benjamin Eberlei
146f8f81f7 Merge branch 'DDC-1490' 2011-11-13 15:37:04 +01:00
Benjamin Eberlei
5aeabcb445 DDC-1490 - Fix id generation of sequence and identity to cast values to int 2011-11-13 15:36:48 +01:00
Benjamin Eberlei
01697fee3d Fix failing PostgreSQL tests 2011-11-12 22:16:39 +01:00
Benjamin Eberlei
450d92872a Forward compatibility with DBAL master 2011-11-12 12:56:44 +01:00
Benjamin Eberlei
a14ba1e561 DDC-1237 - Remove dependency to mbstring 2011-11-12 09:43:37 +01:00
Benjamin Eberlei
4d425317b4 Merge pull request #187 from asm89/DDC-1458
Fix DDC-1458
2011-11-10 07:19:46 -08:00
Alexander
1f55351f19 Cleanup 2011-11-10 16:16:55 +01:00
Alexander
9c9f85ed4b Only refresh the given entity if an entity is specified in the query hints 2011-11-09 22:52:48 +01:00
Alexander
3131103801 Failing test case 2011-11-09 22:15:22 +01:00
Benjamin Eberlei
d9ec0a59ec Merge pull request #186 from asm89/fix-tests-phpunit-3.6
Fixed failing tests in PHPUnit 3.6.2 (expecting \Exception was deprecated)
2011-11-09 01:04:38 -08:00
Alexander
2ddfc6af5a Fixed failing tests in PHPUnit 3.6.2 (expecting \Exception was deprecated) 2011-11-09 08:20:35 +01:00
Guilherme Blanco
c391287cc4 More optimizations and increased code readability in Id Generators. 2011-11-08 18:36:18 -02:00
Benjamin Eberlei
d943e67c65 Merge pull request #185 from asm89/indexby-exception
Remove invalid(?) exception for now
2011-11-08 04:17:01 -08:00
Alexander
39ed719c4c Remove invalid(?) exception for now 2011-11-08 13:16:33 +01:00
Benjamin Eberlei
3914e4a5d0 Merge pull request #184 from asm89/InvalidFetchMode-exception
Throw exception on invalid fetch mode in annotations
2011-11-08 01:28:32 -08:00
Benjamin Eberlei
cce3798b4b Merge pull request #183 from asm89/ProxyIdentifier-types
Proxy identifier type casting
2011-11-08 01:27:30 -08:00
Alexander
e99b800406 Throw exception on invalid fetch mode in annotations 2011-11-08 10:01:22 +01:00
Alexander
0cc176aae2 Do not cast BigInt to (int) 2011-11-08 09:47:33 +01:00
Alexander
6707129a3e Added type casts to 'non-lazy' identifiers in proxies. 2011-11-08 09:43:06 +01:00
Guilherme Blanco
32b8d77580 Fixed CS issues. More tiny optimizations in UnitOfWork. 2011-11-07 01:27:20 -02:00
Guilherme Blanco
96aa25fb3e Optimized more pieces of code in UnitOfWork. 2011-11-06 02:03:34 -02:00
Guilherme Blanco
ea69d9ca0c Fixed wrong optimization. Optimized more pieces of code in UnitOfWork. 2011-11-05 19:21:35 -02:00
Guilherme Blanco
c6a3ff4da5 Optimizations in UnitOfWork. 2011-11-05 03:09:14 -02:00
everzet
9c4c06c422 optimized PreFlush (moved into computeChangeSet function) 2011-11-03 16:24:47 +02:00
Benjamin Eberlei
793a1032e6 Merge pull request #182 from asm89/innerjoin-fetch-eager
Eagerly fetched entities should only be inner joined if they are loaded
2011-11-03 03:58:21 -07:00
Alexander
ca438fa110 Eagerly fetched entities should only be inner joined if they are loaded
from the owning side.
2011-11-03 09:20:41 +01:00
Guilherme Blanco
305da5b8ff Added missing indexBy. 2011-11-03 02:49:50 -02:00
Guilherme Blanco
3c31d88810 Major optimizations in SqlWalker code, reducing overhead, reducing lookahead checks. 2011-11-03 02:44:50 -02:00
Guilherme Blanco
058242fa27 Fixed missing changes. 2011-11-03 02:37:54 -02:00
Guilherme Blanco
d1bfd57fd9 Initial code optimization in Hydrators. 2011-11-02 22:08:24 -02:00
Alexander
53055f1fb2 [DDC-551] Fixed a bug in the sql generation for filters 2011-11-02 15:15:22 +01:00
Alexander
9ccce8ed74 [DDC-551] Add filters to eagerly joined entities in the persisters 2011-11-02 15:15:14 +01:00
Benjamin Eberlei
d532de9da3 Fix docblocks ObjectHydratorTest 2011-11-01 17:43:23 +01:00
Benjamin Eberlei
afb8d63fcb Fixed some AbstractHydrator docblocks 2011-11-01 16:42:03 +01:00
Benjamin Eberlei
98e3e04477 Add autoload section to composer.json 2011-11-01 15:05:38 +01:00
Benjamin Eberlei
4b316ec54f DDC-1389 - Add validation for empty discriminator map values 2011-10-31 23:35:41 +01:00
Benjamin Eberlei
c965d231b1 Rename method and refactor code a bit 2011-10-31 23:21:11 +01:00
Benjamin Eberlei
abb129028a Merge branch 'DBAL-1420' 2011-10-31 23:13:33 +01:00
Benjamin Eberlei
e31e164896 DBAL-1420 - Use safe mode for schema validation. Dropping stuff isnt necessary here. 2011-10-31 23:12:52 +01:00
Benjamin Eberlei
c38d273c1f Merge pull request #151 from doctrine/DDC-1385
DDC-1385
2011-10-31 15:10:54 -07:00
Benjamin Eberlei
88bda9b0d5 Merge pull request #180 from asm89/innerjoin-on-fetch-eager
[DDC-1463] Inner join eagerly loaded entities if possible
2011-10-31 14:24:47 -07:00
Alexander
53386e5247 Merge branch 'master' into innerjoin-on-fetch-eager
Conflicts:
	lib/Doctrine/ORM/Persisters/BasicEntityPersister.php
2011-10-31 22:24:16 +01:00
Benjamin Eberlei
231d84b625 Fix xml fix again 2011-10-31 22:15:08 +01:00
Alexander
22b3b46b61 Removed unnecessary spaces in generated SQL 2011-10-31 22:08:40 +01:00
Alexander
0f938b8c1d Added tests for inner join generation with eager loading 2011-10-31 21:53:46 +01:00
Alexander
3994b80aa4 Fix TODO: Inner join when all join columns are NOT nullable. 2011-10-31 21:36:55 +01:00
Benjamin Eberlei
54217bd4c6 Merge branch 'DDC-1462' 2011-10-31 21:34:31 +01:00
Benjamin Eberlei
1dc5b7fba4 DDC-1462 - Fix bug in slice when calling on a dirty collection that is marked extra lazy 2011-10-31 21:34:22 +01:00
Benjamin Eberlei
3b819b52ca Merge branch 'DDC-1399' 2011-10-31 21:17:09 +01:00
Benjamin Eberlei
95193ab5f8 DDC-1399 - Fix extra lazy collections when inner collection contains values but persistent collection is marked not dirty because of flush() 2011-10-31 21:17:01 +01:00
Benjamin Eberlei
11f82bd41f DDC-1439 - Fix validate mapping some more 2011-10-31 20:49:59 +01:00
Guilherme Blanco
d444f0e06b Micro optimization in SqlWalker. 2011-10-30 16:22:45 -02:00
Guilherme Blanco
c246c6b28b AssignedGenerator optimization. 2011-10-30 16:07:43 -02:00
Guilherme Blanco
3cfa479c01 Micro optimization in computeChangeSet when using readOnly entities. 2011-10-30 15:46:07 -02:00
Benjamin Eberlei
67497ed834 Merge branch 'DDC-1384' 2011-10-30 16:48:00 +01:00
Benjamin Eberlei
64d405f7dd Merge origin/master into DDC-1384 2011-10-30 12:12:18 +01:00
Benjamin Eberlei
94c288a6a8 Merge branch 'master' of github.com:doctrine/doctrine2 2011-10-30 08:26:03 +01:00
Benjamin Eberlei
2c036b3185 Fix glitch in testsuites tearDown() 2011-10-30 08:25:19 +01:00
Benjamin Eberlei
1bbec8dd33 Clarify error message 2011-10-30 00:25:49 +02:00
Benjamin Eberlei
30731e0727 DDC-1384 - Fix all tests on Oracle 2011-10-29 23:58:09 +02:00
Benjamin Eberlei
50e028212d DDC-1384 - Fix a bunch of Oracle test failures 2011-10-29 20:42:44 +02:00
Benjamin Eberlei
fb55e8094b DDC-1384 - Made tests case-insenstive to work with latest change regarding column sizes 2011-10-29 18:48:34 +02:00
Guilherme Blanco
96cb3d8004 Merge pull request #178 from adrienbrault/master
Fix Query iterate() doc return type
2011-10-29 06:39:27 -07:00
Adrien BRAULT
e39bfced4a Fix iterate method doc return type 2011-10-29 13:40:01 +02:00
Guilherme Blanco
15562d030e Merge branch 'master' of github.com:doctrine/doctrine2 2011-10-29 02:00:55 -02:00
Guilherme Blanco
0ec2cc557f Implemented support to entities with association marked as @Id support in many situations. Fixed DDC-1435. 2011-10-29 02:00:35 -02:00
Benjamin Eberlei
7d921a8220 DDC-1452 - Attach working testcase 2011-10-29 00:22:45 +02:00
Benjamin Eberlei
f232e45efe Merge branch 'DDC-1410' 2011-10-28 23:45:38 +02:00
Benjamin Eberlei
7be98f475e DDC-1410 - Remove code-inlining that caused problems 2011-10-28 23:45:23 +02:00
Thiago Festa
66d2b9e0fb The ProxyFactory was redeclaring methods serialize and unserialize on the cache file on some OSs. 2011-10-28 17:54:15 -02:00
Guilherme Blanco
3745e948c6 Made SimpleSelectExpression (Literal) be included as a scalar result. More general SQL Walker optimizations. 2011-10-28 14:25:12 -02:00
Guilherme Blanco
1f06e9fca5 Fixed issue with SimpleSelectExpression containing Literals. This issue is related to a previously fixed ticket DDC-1079. 2011-10-28 12:56:14 -02:00
Guilherme Blanco
7841ccb7c0 Merge branch 'master' of github.com:doctrine/doctrine2 2011-10-28 12:49:21 -02:00
Guilherme Blanco
1579c43433 Code beautification and docblocks enhancements. 2011-10-28 12:49:01 -02:00
Benjamin Eberlei
fbfd59afa0 Merge branch 'DDC-1454' 2011-10-28 00:50:30 +02:00
Benjamin Eberlei
f34eb83a7c DDC-1454 - Fix exists() for Joined table inheritance 2011-10-28 00:50:10 +02:00
Benjamin Eberlei
8db1a09001 Merge branch 'master' of github.com:doctrine/doctrine2 2011-10-28 00:26:54 +02:00
Benjamin Eberlei
4a0227e5f2 Revert Expr\Base patch 2011-10-28 00:24:41 +02:00
Benjamin Eberlei
a98c7df2f1 Merge branch 'DDC-217' 2011-10-27 22:36:25 +02:00
Benjamin Eberlei
5918058d86 Merge origin/master 2011-10-27 22:36:06 +02:00
Guilherme Blanco
c5ef21864f Fixed bug with fetch=EAGER associations that have already been hydrated during querying. 2011-10-26 15:04:49 -02:00
Asmir Mustafic
d09285e9d3 Collapse cascade all test (YAML too) 2011-10-26 10:59:15 +02:00
Asmir Mustafic
035ca8e500 Collapse cascade all test 2011-10-26 10:14:59 +02:00
Lukas Kahwe Smith
0a5a23628f added EntityRepository::getClassName() to fullfill the ObjectRepository interface
see https://github.com/doctrine/common/pull/70
2011-10-25 23:21:39 +02:00
Benjamin Eberlei
cfe7ab46f2 Merge branch 'master' of git://github.com/doctrine/doctrine2 2011-10-25 22:55:08 +02:00
Benjamin Eberlei
3b9312e291 Bump DBAL version and make TestUtil more lenient 2011-10-25 22:54:20 +02:00
Eric Clemmons
5b64dbe195 Added error suppression to mkdir in ProxyFactory
See: Symfony\Component\HttpKernel\Kernel#buildContainre
2011-10-25 11:51:09 -07:00
Eric Clemmons
48bf5022e4 ProxyFactory always checks if directory is writable first 2011-10-24 19:45:23 -07:00
Eric Clemmons
99c1383ef5 If proxy directory doesn't exist & cannot be created via mkdir, a ProxyException is thrown 2011-10-24 19:32:38 -07:00
Benjamin Eberlei
a02b0c9269 Merge pull request #165 from armetiz/patch-3
Update lib/Doctrine/ORM/Query/Expr/Base.php
2011-10-24 03:42:04 -07:00
Benjamin Eberlei
0cdf1e042c Merge pull request #173 from jaikdean/master
Fixed a couple of typos of 'discriminator'
2011-10-24 03:41:19 -07:00
Project
1873302ee9 Merge branch 'generation' of https://github.com/goetas/doctrine2 into generation 2011-10-24 12:15:01 +02:00
Asmir Mustafic
7efd615b8c Coding standards 2011-10-24 12:00:11 +02:00
Jaik Dean
cdb452b27b Fixed typos of 'discriminator' 2011-10-24 10:01:27 +01:00
Asmir Mustafic
f5330741ac Coding standards 2011-10-24 10:59:50 +02:00
Asmir Mustafic
5f80b57554 Improoved coding standards 2011-10-24 10:19:01 +02:00
Asmir Mustafic
cb76222e63 Collapse cascade persist, remove, refresh, detach, merge into
cascade-all (implemented currently only for XML annotation)
2011-10-24 09:54:31 +02:00
Asmir Mustafic
1b83fcc46d Coding standards 2011-10-24 09:20:24 +02:00
Benjamin Eberlei
a8052dec37 Added note about result cache changes 2011-10-23 23:35:04 +02:00
Benjamin Eberlei
adc4840cce DDC-217 - Add support for QueryCacheProfiles and remove the old result caching code from ORM. Deprecate a bunch of methods in favor of using the AbstractQuery#getQueryCacheProfile method. 2011-10-23 23:28:23 +02:00
Benjamin Eberlei
993d6f5ac8 Merge pull request #171 from asm89/fix-mysql-tests
Fix mysql testsuite
2011-10-23 13:12:09 -07:00
Alexander
80c9690926 Fix mysql testsuite 2011-10-23 22:06:03 +02:00
Benjamin Eberlei
d9740e2028 Merge pull request #170 from asm89/fix-tests
Fix testsuite
2011-10-23 12:39:00 -07:00
Alexander
f1df4ffca4 Fix testsuite 2011-10-23 21:37:29 +02:00
everzet
91d8829c43 removed non-used code 2011-10-23 18:50:24 +03:00
everzet
20ed8869e4 added test for PreFlush lifetime event 2011-10-23 18:41:41 +03:00
everzet
66e2a9260e added PreFlush lifetime event and lifecycle callback 2011-10-23 18:39:16 +03:00
Benjamin Eberlei
9b8d2d512b Merge pull request #168 from dfreudenberger/master
postFlush event implementation
2011-10-23 01:12:27 -07:00
Benjamin Eberlei
fd00f2d371 Merge pull request #166 from doctrine/DDC-720
DDC-720 - Add support to flush only one entity through EntityManager#flush()
2011-10-23 01:07:14 -07:00
Benjamin Eberlei
5d3298e706 DDC-720 - Correct mentioned issues by @asm89 2011-10-23 10:05:46 +02:00
Daniel Freudenberger
fa8000fa5c dispatch the event after the snapshot was taken 2011-10-23 01:27:09 +02:00
Daniel Freudenberger
5e28273548 fixed typo in docblock 2011-10-22 18:57:48 +02:00
Daniel Freudenberger
46a3fecb4f added the postFlush event 2011-10-22 18:38:51 +02:00
Alexander
079e2b1302 [DDC-1384] Fix for generating sql with aliases not longer than MaxIdentifierLength 2011-10-22 16:27:56 +02:00
Benjamin Eberlei
b910a487c5 DDC-720 - Wait, we should really test it only changes the passed entity. 2011-10-22 14:31:23 +02:00
Benjamin Eberlei
f569a2a389 DDC-720 - Add support to flush only one entity (within cascade rules) through EntityManager#flush() 2011-10-22 13:44:33 +02:00
Benjamin Eberlei
719e05e53e Extract more messages into ORMInvalidArgumentException 2011-10-22 12:57:55 +02:00
Benjamin Eberlei
a8906ce572 Stringify entity in all UnitOfWork exceptions 2011-10-22 12:49:33 +02:00
Benjamin Eberlei
5392737de4 Improved and extracted UnitOfWork error messages 2011-10-22 12:40:12 +02:00
Benjamin Eberlei
3aea203b9c Throw exception if target entity is not found. 2011-10-22 11:28:07 +02:00
Benjamin Eberlei
dba8360166 Merge master into ImproveErrorMessages 2011-10-22 11:06:51 +02:00
Benjamin Eberlei
23560038b4 Merge branch 'master' of github.com:doctrine/doctrine2 2011-10-22 10:37:32 +02:00
Asmir Mustafic
d4059b88ca Nullable relations, fixing join condition 2011-10-21 15:30:21 +02:00
armetiz
baef4f735f Update lib/Doctrine/ORM/Query/Expr/Base.php 2011-10-21 16:30:06 +03:00
Benjamin Eberlei
01f1924a89 Merge pull request #163 from armetiz/patch-2
Update lib/Doctrine/ORM/Query/Expr.php
2011-10-21 05:18:01 -07:00
Alexander
07ce4092cd Merge branch 'master' into DDC-551 2011-10-21 12:04:29 +02:00
armetiz
4a50eb4fa7 Update lib/Doctrine/ORM/Query/Expr.php 2011-10-21 11:55:54 +03:00
Asmir Mustafic
fe84a61d0b Better code generation when association is nullable 2011-10-21 09:38:37 +02:00
Eric Clemmons
fde9d122cc ProxyFactory checks presence of directory with is_dir instead of file_exists 2011-10-20 13:33:20 -07:00
Eric Clemmons
92acd32410 ProxyFactory creates proxy's parent structure if it doesn't exist 2011-10-20 09:35:41 -07:00
Asmir Mustafic
596ba3d5b1 Collection inteface instead of ArrayCollection 2011-10-19 15:04:16 +02:00
Benjamin Eberlei
ca01065c6a Bugfix in short identifier shortcut with association ids 2011-10-19 11:58:59 +02:00
Asmir Mustafic
be3adfb35e With TO_MANY relations, class filed is instanceof ArrayCollection,
instead of targetEntity class type.
2011-10-19 09:25:40 +02:00
Asmir Mustafic
8f092812c4 Spaces 2011-10-19 09:17:30 +02:00
Asmir Mustafic
9c1202a766 Added <variableDefault> on generated class.
This allow to unset many-to-one and one-to-one relations


Example: $user->setGroup(null);
2011-10-19 09:15:41 +02:00
Asmir Mustafic
e19fd756cb Better indentation for generated class 2011-10-19 09:07:18 +02:00
Benjamin Eberlei
7345c795ac Merge pull request #154 from Partugal/master
Fix isTransient call on uninitialized ClassMetadataFactory
2011-10-19 00:04:14 -07:00
Benjamin Eberlei
753f75cfb9 Merge pull request #156 from goetas/xmlassoc
Set association-key attribute in xml mapping
2011-10-19 00:03:55 -07:00
Asmir Mustafic
97321a1ff2 Collapsed cascade elements, if cascade-all.
(better readability for generated xml)
2011-10-18 16:18:25 +02:00
Asmir Mustafic
0d57ffbc3b Set association-key attribute in xml mapping 2011-10-18 15:48:56 +02:00
Sergey Linnik
c3ec6e383c Fix isTransient call on uninitialized ClassMetadataFactory 2011-10-18 01:14:07 +04:00
Benjamin Eberlei
0b1f6e3539 Merge pull request #153 from asm89/shesek-patch-1
Support NULL in EntityRepository's magic findBy and findOneBy methods
2011-10-17 12:05:07 -07:00
Alexander
b8af241504 Added a testcase for findBy(.. => null) and renamed 'old' testcase 2011-10-17 20:53:04 +02:00
Alexander
91bc9c0329 Adjusted test to verify that findBy*(null) is now supported 2011-10-17 18:56:06 +02:00
Alexander
fea855004c Merge remote-tracking branch 'doctrine/master' into shesek-patch-1 2011-10-17 18:55:48 +02:00
Guilherme Blanco
83a8ed01e7 Merge pull request #94 from kwiateusz/findByOnePatch
Now findByOne really retrieve only one entity adding limit to query.
2011-10-17 06:24:37 -07:00
Benjamin Eberlei
2b663ff2bc Merge branch 'master' of github.com:doctrine/doctrine2 2011-10-16 22:47:28 +02:00
Benjamin Eberlei
1a602a8cb3 Merge branch 'DDC-1278' 2011-10-16 22:45:50 +02:00
Benjamin Eberlei
939fbf9c24 DDC-1278 - Clean up event handling of new clear functionality. 2011-10-16 22:45:06 +02:00
Benjamin Eberlei
22a04fd6de Merge dominikl/DDC-1278 into doctrine/DDC-1278 2011-10-16 22:41:16 +02:00
Benjamin Eberlei
8466060797 DDC-1385 - Add INDEX BY scalar variables on the top-level 2011-10-16 19:23:20 +02:00
Benjamin Eberlei
ba5e73213b Merge pull request #150 from stof/initialize_object
Added the initializeObject method in the EntityManager
2011-10-16 08:04:46 -07:00
Christophe Coevoet
a8e6131e3b Added the initializeObject method in the EntityManager 2011-10-16 17:00:33 +02:00
Benjamin Eberlei
ee924ffaba DDC-1385 - Fix scalar handling for array hydrator 2011-10-16 16:27:50 +02:00
Benjamin Eberlei
2730f64d90 DDC-1385 - Refactor ObjectHydrator 2011-10-16 16:13:59 +02:00
Benjamin Eberlei
cb0e5dbff3 DDC-1385 - Fixed Mixed result hydration using INDEX BY to work on the top-level indexes, not some weird result. This is a BC break to those that actually use this crazy logic, sorry for that :-) 2011-10-16 12:46:17 +02:00
Benjamin Eberlei
fc738455b6 Merge branch 'DDC-1358' 2011-10-16 11:17:04 +02:00
Benjamin Eberlei
0252d55c67 DDC-1358 - Fix bug where multiple NULL root entity combined with scalar results will break the object and array hydrator.
This case likeli only occurs when doing native queries. A guard clause that prevents hydration from breaking
when RIGHT JOIN queries with null root entities appear has been added aswell.
2011-10-16 11:15:45 +02:00
Guilherme Blanco
eeba947ea7 Code optimizations. Fixed unused argument in OrmTestCase as referred in DDC-766. 2011-10-16 02:10:59 -02:00
Guilherme Blanco
33bcf7ad6f Added coverage to DDC-1161. 2011-10-16 01:42:36 -02:00
Alexander
58b381bf24 [DDC-551] use isClean to check the filterCollection state.. 2011-10-15 22:31:20 +02:00
Benjamin Eberlei
4474d305cb DDC-1210 - Optimize UnitOfWork collection handling internally. 2011-10-15 21:47:16 +02:00
Benjamin Eberlei
7c244abc1c Merge branch 'master' of github.com:doctrine/doctrine2 2011-10-15 21:09:36 +02:00
Benjamin Eberlei
5c78ecaca1 Fix tests in EntityGenerator due to Annotation prefixes 2011-10-15 20:44:25 +02:00
Benjamin Eberlei
7b71b3284d Fix failing test due to EntityGenerator assuming beginning with 2.2 the AnnotationReader is always used. There is still the simple reader though. 2011-10-15 20:41:07 +02:00
Benjamin Eberlei
7e571212a7 Merge pull request #109 from alOneh/patch-1
Remove trailing spaces
2011-10-15 11:39:56 -07:00
Benjamin Eberlei
75e1d17d18 Merge branch 'ValidateJoinColumnsMatching' 2011-10-15 20:33:46 +02:00
Benjamin Eberlei
a82bffbfc9 Make SchemaValidator catch errors such as very invalid schema using only part of the primary key for join columns 2011-10-15 20:31:56 +02:00
Guilherme Blanco
ba38f3e1e9 Merge pull request #148 from asm89/ProxyIdentifer
Do not load entity on retrieving identifier from a proxy
2011-10-15 11:23:06 -07:00
Benjamin Eberlei
46541755ca Merge pull request #128 from alanbem/xml-schema-on-delete-fix
fixed wrong on-delete XML Schema mapping
2011-10-15 11:09:55 -07:00
Benjamin Eberlei
18fd29613c Merge pull request #137 from docteurklein/fluent_query_expr
added fluent pattern to Query\Expr\Base::add* methods
2011-10-15 11:09:37 -07:00
Benjamin Eberlei
1f59001ff7 Merge pull request #130 from bmichotte/master
Fluent entity (master)
2011-10-15 11:01:19 -07:00
lenar
3dc30dee11 use the correct targetEntity 2011-10-15 20:00:02 +02:00
lenar
cab154b873 identifier referencing foreign entity can be defined in parent class too 2011-10-15 19:59:50 +02:00
Benjamin Eberlei
7f5844c209 Merge pull request #147 from asm89/assignid
Goetas: Better error handling on missing assigned id
2011-10-15 10:41:27 -07:00
Alexander
c5e51e6fa9 Merge branch 'master' into assignid 2011-10-15 19:33:42 +02:00
Alexander
fdb9fb1c2b AssignedGenerator can always tell what field is missing an id 2011-10-15 19:33:29 +02:00
Benjamin Eberlei
b6c49863e8 Merge branch 'master' of github.com:doctrine/doctrine2 2011-10-15 19:14:53 +02:00
Benjamin Eberlei
d0383f93d0 Merge branch 'DDC-1383' 2011-10-15 19:14:40 +02:00
Benjamin Eberlei
08716d9f72 DDC-1383 - Proxy Generation in merge was flawed with inheritance 2011-10-15 19:14:30 +02:00
Benjamin Eberlei
73101be422 Merge pull request #143 from craue/patch-2
added missing type hint
2011-10-15 10:05:53 -07:00
Benjamin Eberlei
6f3667201c Add @ignore and @internal to UnitOfWork#computeChangeSet 2011-10-15 18:11:14 +02:00
Alexander
d46352da01 Fixed tests + added dedicated tests for proxy loading and identifiers 2011-10-15 17:58:00 +02:00
Benjamin Eberlei
30149e48f9 Merge branch 'DDC-1411' 2011-10-15 17:53:11 +02:00
Benjamin Eberlei
52cea01563 DDC-1411 - Fixed onDelete handling in EntityGenerator 2011-10-15 17:53:04 +02:00
Benjamin Eberlei
f54cdf625e Merge branch 'DDC-1414' 2011-10-15 17:47:17 +02:00
Benjamin Eberlei
cb21f3c5ff DDC-1414 - Missing push to $newNodes 2011-10-15 17:47:09 +02:00
Benjamin Eberlei
cb28bfd484 Improve Error Messages in ClassMetadata and UnitOfWork 2011-10-15 17:38:55 +02:00
Alexander
8d1b852aa2 Added tests for not loading the entity + fixed a test 2011-10-15 17:31:09 +02:00
Alexander
f47e1feac6 Merge branch 'master' of git://github.com/doctrine/doctrine2 into ProxyIdentifer
Conflicts:
	lib/Doctrine/ORM/Proxy/ProxyFactory.php
2011-10-15 17:24:13 +02:00
Benjamin Eberlei
84dbb08502 Merge branch 'DDC-1421' 2011-10-15 16:58:05 +02:00
Benjamin Eberlei
e38076c19a DDC-1421 - Fix potential bug and code-smells 2011-10-15 16:57:57 +02:00
Benjamin Eberlei
3b46df68ea Adjust README.markdown 2011-10-15 16:36:20 +02:00
Benjamin Eberlei
dd6f6cb097 Fix notice 2011-10-15 16:03:50 +02:00
Benjamin Eberlei
640facd26a Remove unncessary line 2011-10-15 15:51:11 +02:00
Benjamin Eberlei
291d2fd624 UPGRADE_TO_2_2 2011-10-15 15:49:41 +02:00
Benjamin Eberlei
9ece0fe3c9 Merge branch 'DDC-1386' 2011-10-15 15:45:59 +02:00
Benjamin Eberlei
3801e0c230 Add way to keep track of read only objects in the UnitOfWork which are never updated during flush.
Changed the behavior of EntityManager#getPartialReference to be read-only. No changes are ever
done to this entities. Changed UnitOfWork#computeChangeSet to never create a changeset for
fields that are partially omitted from a DQL or NativeQuery.

To check if an entity is read only use the new API:

    if ($entityManager->getUnitOfWork()->isReadOnly($entity))
2011-10-15 15:42:02 +02:00
Benjamin Eberlei
2166a21511 Merge branch 'master' of github.com:doctrine/doctrine2 2011-10-15 11:36:53 +02:00
Benjamin Eberlei
894bbb020c DDC-1394 - Enhance test to verify 2011-10-15 09:57:35 +02:00
Guilherme Blanco
772b413579 Fixed bug with boolean values being converted to string. 2011-10-15 00:23:55 -03:00
Guilherme Blanco
2518f0687c Removed invalid default argument. 2011-10-15 00:21:11 -03:00
Guilherme Blanco
f86e1ba66c Added tests for DDC-1389. Everything is working in 2.2-DEV. 2011-10-15 00:18:57 -03:00
Alexander
097d573d26 Merge branch 'master' into DDC-551
Conflicts:
	lib/Doctrine/ORM/Configuration.php
	lib/Doctrine/ORM/Persisters/BasicEntityPersister.php
	lib/Doctrine/ORM/Persisters/ManyToManyPersister.php
2011-10-14 12:33:39 +02:00
Benjamin Eberlei
4a920d0aad Merge branch 'DDC-1418' 2011-10-13 23:40:11 +02:00
Fabien Potencier
6a72ba5f97 DDC-1418 - Add simplified XML and YAML drivers ported from the Symfony project, thanks Fabien 2011-10-13 23:39:11 +02:00
Benjamin Eberlei
92b16455c8 Merge branch 'DDC-1415' 2011-10-13 22:58:58 +02:00
Benjamin Eberlei
a36a1624fb [DDC-1415] Add EntityEventDelegatee, allowing to restrict emitting events to certain entity classes only. 2011-10-13 22:58:22 +02:00
Benjamin Eberlei
97a6caf059 Update Common to latest to have the current Persistence Interface 2011-10-11 13:22:26 +02:00
Guilherme Blanco
509e5fb12f Merge pull request #145 from stof/EntityGenerator_versionCheck
Fixed the version check in the entity generator
2011-10-10 12:34:01 -07:00
Christophe Coevoet
c7c875a063 Fixed the version check in the entity generator
The 3.0.x branch of Common has been merged to become the incoming
2.2 release.
2011-10-10 19:20:01 +02:00
Benjamin Eberlei
45308d5f79 Merge branch 'DDC-1402' 2011-10-10 17:52:47 +02:00
Benjamin Eberlei
9058bc3f5c Fix DDC-1402 - No caching for SingleTablePersister::_getSelectColumnList 2011-10-10 17:52:37 +02:00
Benjamin Eberlei
89470787d8 Add composer.json 2011-10-10 16:54:57 +02:00
Benjamin Eberlei
de98f3fb30 Added composer.json 2011-10-10 16:30:49 +02:00
Guilherme Blanco
15877e1443 Merge pull request #144 from craue/patch-3
switched 2nd and 3rd argument for SelectExpression's constructor, making the 3rd one optional to keep its signature compatible to previous versions
2011-10-10 05:21:41 -07:00
Christian Raue
1681d8a893 switched 2nd and 3rd argument for SelectExpression's constructor, making the 3rd one optional to keep its signature compatible to previous versions 2011-10-10 14:04:55 +02:00
Guilherme Blanco
f3b6ed03f3 Merge pull request #142 from craue/patch-1
fixed typo
2011-10-10 03:31:34 -07:00
Christian Raue
689aaef4dc added missing type hint 2011-10-10 09:44:17 +03:00
Christian Raue
bf44be86a9 fixed typo 2011-10-10 03:02:55 +03:00
Guilherme Blanco
24042863ac BasicEntityPersister::exists() was not supporting identifiers that are associations. Fixes DDC-1382. 2011-10-03 02:21:14 -03:00
Guilherme Blanco
ebe933810e Implemented HIDDEN support in DQL. Fixes DDC-1363. 2011-10-03 02:07:07 -03:00
Guilherme Blanco
8efae0b232 Fixes DDC-1396. 2011-10-03 01:30:20 -03:00
Guilherme Blanco
cd28051370 Fixes DDC-1395 2011-10-03 01:26:43 -03:00
Asmir Mustafic
d24f288149 Better error handling on missing assigned id 2011-09-29 09:31:06 +02:00
docteurklein
b28af2e527 added fluent pattern to Query\Expr\Base::add* methods 2011-09-27 10:36:32 +02:00
Guilherme Blanco
80284a273d Merge pull request #133 from FabioBatSilva/DDC-1335
Fixes DDC-1335.

Patch looks perfect to me. @beberlei please merge into 2.1 =)
2011-09-25 14:52:56 -07:00
Benjamin Eberlei
d2cd6560c5 DDC-1337 - Adjust MultiTableUpdateExecutor and MultiTableDeleteExecutor to use AbstractPlatform 2011-09-25 19:01:37 +02:00
Benjamin Eberlei
919f5e5ebc Merge branch 'DDC-1392' 2011-09-25 18:08:50 +02:00
Benjamin Eberlei
9f96d4a31a DDC-1392 - Fix bug with merging unitialized proxies 2011-09-25 18:08:41 +02:00
Fabio B. Silva
5fe996baf9 change tests for DDC-1135 2011-09-25 12:20:48 -03:00
Benjamin Eberlei
43c25ea36d Merge branch 'DDC-1367' 2011-09-25 16:39:50 +02:00
Benjamin Eberlei
cd7029d266 DDC-1367 - Bugfix 2011-09-25 16:39:41 +02:00
Benjamin Eberlei
c02920762b Adjust ClassMetadataFactory to forthcoming interface change 2011-09-25 14:41:56 +02:00
Fabio B. Silva
728724bed5 fix DDC-1135 2011-09-24 16:16:25 -03:00
Fabio B. Silva
e94b902a9b tests for DDC-1335 2011-09-24 16:10:10 -03:00
Fabio B. Silva
f4c5c4ba01 branch for DDC-1335 2011-09-23 18:10:58 -03:00
Guilherme Blanco
9795cb1f0d Subqueries should never add items to ResultSetMapping. Fixing possible broken inclusion. 2011-09-21 17:35:38 -03:00
Guilherme Blanco
a86038b484 Fixed issue with CaseExpression not working in Subselects. 2011-09-21 17:30:45 -03:00
Benjamin
01d900d5d7 tab <-> spaces 2011-09-20 15:50:32 +02:00
Benjamin
944f802d79 Correct indentation 2011-09-20 15:35:16 +02:00
Benjamin
2b334977f5 Add "return $this" to generated methods to get a fluent Enttity class 2011-09-20 14:59:32 +02:00
Alan Bem
90725fa529 fixed wrong on-delete XML Schema mapping 2011-09-20 11:10:59 +02:00
Guilherme Blanco
2ae3bb6e3a Fixed bug in Result cache cleaner. 2011-09-19 01:40:30 -03:00
Guilherme Blanco
1fb213760b Refactored Cache cleaners commands to sync with new Common Cache Providers. 2011-09-15 17:46:13 -03:00
Alexander
63a3fb5ad8 [DDC-551] Moved SQLFilter logic to a separate FilterCollection class 2011-09-15 21:38:47 +02:00
Guilherme Blanco
00321e8f70 Imported DBAL-164 fix to ORM. 2011-09-13 02:03:08 -03:00
Guilherme Blanco
918e2d2018 Fixed remaining Doctrine packages upgrade. 2011-09-13 01:14:36 -03:00
Guilherme Blanco
3bb803fd69 Cherry picked FabioBatSilva upgrade of Common lib. 2011-09-13 00:59:24 -03:00
Guilherme Blanco
f8811c4d21 Merge pull request #121 from FabioBatSilva/DDC-753
DDC-753
2011-09-08 14:30:54 -07:00
Fabio B. Silva
3707b34cbb Change repository type for EntityRepository 2011-09-08 17:21:06 -03:00
Fabio B. Silva
43ccd9ead6 tests for DDC-753 2011-09-08 15:54:49 -03:00
Fabio B. Silva
ee80ec4851 Merge remote-tracking branch 'upstream/master' into DDC-753 2011-09-08 14:36:38 -03:00
Fabio B. Silva
84cd22d7f7 new branch for DDC-753 2011-09-08 14:36:13 -03:00
Guilherme Blanco
7ebfc67d5a Merge pull request #120 from FabioBatSilva/DDC-869
Fixed DDC-869
2011-09-08 10:15:24 -07:00
Fabio B. Silva
19d0887bb0 check if parent class is a mapped superclass 2011-09-08 13:41:16 -03:00
Fabio B. Silva
7f0275155d php mapping 2011-09-08 13:17:53 -03:00
Fabio B. Silva
6a89de51e5 change tests 2011-09-08 12:55:55 -03:00
Fabio B. Silva
54a53b1d03 tests for DDC-869 2011-09-08 11:56:05 -03:00
Fabio B. Silva
f6d34bbb9d Merge remote-tracking branch 'upstream/master' into DDC-869 2011-09-08 11:54:04 -03:00
Guilherme Blanco
2b3bee1fa4 Merge pull request #119 from alOneh/patch-2
Fix documentation for metadata driver
2011-09-08 07:29:55 -07:00
Alain Hippolyte
01c9a4ac1c Fix documentation for metadata driver 2011-09-08 11:41:09 +03:00
Guilherme Blanco
a7f3af8328 Added IDENTITY DQL Function. Fixes DDC-1339. 2011-09-08 02:10:48 -03:00
Fabio B. Silva
b2d98495b1 mapping files 2011-09-07 18:29:43 -03:00
Fabio B. Silva
25ecd45fd1 Merge remote-tracking branch 'upstream/master' into DDC-869 2011-09-07 17:27:59 -03:00
Fabio B. Silva
82f7d6cad2 starts work with mapped superclass repository 2011-09-07 17:27:05 -03:00
Guilherme Blanco
bd5393a318 Added coverage for orphanRemoval in OneToOne when unlinking an entity. 2011-09-07 13:12:02 -03:00
Guilherme Blanco
e3d133af04 Added getQuotedTableName() in missing places of Doctrine ORM. Fixes DDC-1365. 2011-09-07 01:48:19 -03:00
Guilherme Blanco
6ec2ae249b Merge branch 'master' of github.com:doctrine/doctrine2 2011-09-06 01:58:34 -03:00
Guilherme Blanco
2cfc61db84 Fixed bug with orphanRemoval not removing associated Entity on OneToMany and OneToOne relationships. As defined in ClassMatedataInfo, in these situations, when orphanRemoval=true, cascade=remove is implicit. This fixes DDC-1321. 2011-09-06 01:58:16 -03:00
Guilherme Blanco
c30e129390 Merge pull request #118 from bauffman/patch-1
Fixed typo
2011-09-05 06:48:28 -07:00
Davy Hellemans
b333ff95fb Fixed typo 2011-09-05 09:42:09 +03:00
Guilherme Blanco
6bbf2d9da3 Added support for ResultVariable referencing in ArithmeticPrimary. Fixes DDC-1346. 2011-09-05 03:16:01 -03:00
Guilherme Blanco
ddfdb37a58 Merge branch 'master' of github.com:doctrine/doctrine2 2011-09-05 02:27:26 -03:00
Guilherme Blanco
666691f84f Small changes for code readability. Added type binding in JoinedSubclassPersister, which was missing. Fixes DDC-1316. 2011-09-05 02:27:06 -03:00
Benjamin Eberlei
b6a7520c64 Merge branch 'DDC-659' 2011-09-04 14:13:45 +02:00
Benjamin Eberlei
09ac3a9eb2 DDC-659 - Add ClassMetadataBuilder for PHP based metadata management 2011-09-04 14:13:20 +02:00
Benjamin Eberlei
342c3ba941 Initial work on ClassMetdataBuilder 2011-09-04 10:08:33 +02:00
Benjamin Eberlei
88574a0de2 Add note about Common Annotation changes 2011-09-04 01:11:19 +02:00
Benjamin Eberlei
f6f6edbd59 Merge branch 'master' of github.com:doctrine/doctrine2 2011-09-04 01:10:37 +02:00
Guilherme Blanco
f29c907f41 Optimized and refactored code for getParameterValue in Doctrine\ORM\Query. 2011-09-02 13:53:53 -03:00
Guilherme Blanco
3b3186ee98 Added support to user provide an array of Entities as a DQL parameter. Fixes DDC-1356. 2011-09-01 19:11:57 -03:00
Guilherme Blanco
ecc556f687 Fixes DDC-1354. 2011-09-01 03:00:53 -03:00
Benjamin Eberlei
53a153bc15 Merge pull request #111 from Gregwar/yaml_entity_repository
[Tools] Added entityRepository support in yaml exporter
2011-08-30 11:43:25 -07:00
Benjamin Eberlei
800628e3cd Merge branch 'DDC-1350' 2011-08-30 20:40:38 +02:00
Benjamin Eberlei
8b38e68e23 DDC-1350 - Bugfixes in Doctrine\ORM\Tools\Setup 2011-08-30 20:40:26 +02:00
Benjamin Eberlei
7ba656f815 Bump DBAL dependency to 2.1.2 2011-08-29 23:01:05 +02:00
Grégoire Passault
240f0ea34c [Tools] Added entityRepository support in yaml exporter 2011-08-29 17:40:54 +02:00
Guilherme Blanco
12f46e936c Merge branch 'master' of github.com:doctrine/doctrine2 2011-08-28 13:48:24 -03:00
Guilherme Blanco
e7f471ef3e Fixed issue with CTI during DQL update that was incorrectly setting parameter types during multi table execution. Fixes DDC-1341. 2011-08-28 13:48:15 -03:00
Benjamin Eberlei
0a6709acba Fix tests with regard to repositoryClass handling and applying the default namespace 2011-08-28 16:00:21 +02:00
Benjamin Eberlei
c948ad852e Merge branch 'FixPostgresFailures' 2011-08-28 15:58:27 +02:00
Benjamin Eberlei
b145f061c9 DDC-1348 - Fix bug with UnitOfWork::getEntityState() 2011-08-28 15:58:08 +02:00
Benjamin Eberlei
e6a73803a4 Merge branch 'DDC-1306' 2011-08-27 20:44:15 +02:00
Benjamin Eberlei
3b4b38e184 DDC-1306, DDC-1113 - Fix issues with inheritance and commit order 2011-08-27 20:41:52 +02:00
Benjamin Eberlei
7da9beed36 Merge branch 'master' of github.com:doctrine/doctrine2 2011-08-27 17:59:11 +02:00
Benjamin Eberlei
3bee695913 Update dependencies to 2.1.1 respectively 2011-08-27 14:49:49 +02:00
Benjamin Eberlei
d3b27dcb1a DDC-1344 - Fix path displaying to not use realpath()ed variables 2011-08-27 13:36:18 +02:00
Benjamin Eberlei
4f22bbbc76 Add support to distribute the XSD to a given directory during build process 2011-08-27 13:23:17 +02:00
Nadav
2e389e00d4 Removed blank line, used empty() instead of the count() check 2011-08-26 08:15:28 +03:00
Nadav
5fc6277d3f Oops, shouldn't have removed the condition completely... checking a parameter is provided 2011-08-26 07:51:29 +03:00
Nadav
d314386060 we can (now) transform it into IS NULL 2011-08-26 07:42:16 +03:00
Benjamin Eberlei
e69e0fcc71 Merge remote-tracking branch 'origin/master' 2011-08-24 20:45:32 +02:00
Benjamin Eberlei
b560551b1d Merge branch 'DDC-1333' 2011-08-21 15:06:21 +02:00
Benjamin Eberlei
b83945d486 DDC-1333 - Fix bug in xsd 2011-08-21 15:06:14 +02:00
Benjamin Eberlei
3c82b49cd3 Merge branch 'DDC-1340' 2011-08-21 15:02:05 +02:00
Benjamin Eberlei
8c2db89f2b DDC-1340 - Fix bug with merge() and optimistic lock exception 2011-08-21 15:01:57 +02:00
Alain Hippolyte
06d56156dd Remove trailing spaces 2011-08-19 06:11:58 +03:00
Guilherme Blanco
736443f6c2 Merge pull request #108 from lenar/patch-1
short classname support for custom repository class
2011-08-18 11:03:43 -07:00
Lenar Lõhmus
d7fbd2cd14 short classname support for custom repository class 2011-08-19 04:44:24 +03:00
Alexander
ed0fb4ece7 Merge branch 'master' into DDC-551
Conflicts:
	lib/Doctrine/ORM/Persisters/OneToManyPersister.php
2011-08-16 16:59:48 +02:00
Guilherme Blanco
7433148f17 Fixed bug in XMLDriver where relation indexes are treathed as elements but documented as attributes. 2011-08-16 11:36:41 -03:00
Alexander
3800581947 [DDC-551] Altered persisters to make filters work with EXTRA_LAZY associations 2011-08-16 16:24:50 +02:00
Alexander
2653d735e2 [DDC-551] Added state of the complete filter collection to the EM
Previously it was sufficient to use the old parser result for a Query if
the DQL didn't change (Query::STATE_CLEAN), but now there must also be
no changes to the filter collection of the EntityManager.

In the old situation each Query object would create a hash of all the
filter objects on it's own. That was not very efficient.

This commit adds the state of the current filter collection to the
EntityManager. The state will be set to FILTERS_STATE_DIRTY as a filter
is enabled, removed or a parameter is set on a filter. The hash is also
computed by the EntityManager, but only if the filter collection is
dirty. This will prevent recalculation of the hash with each query.
2011-08-16 13:34:42 +02:00
Alexander
3b1ddb0346 [DDC-551] Added filters to SQLWalker 2011-08-16 12:21:43 +02:00
Guilherme Blanco
6857134f36 Fixed issue with duplicated commas if Entity has no fields. 2011-08-15 12:47:17 -03:00
Guilherme Blanco
f148912a28 [DDC-934][DDC-1100][DDC-1331] Implemented support to multi-values in INSTANCE OF expression. 2011-08-15 01:53:56 -03:00
Guilherme Blanco
b9a24b5487 Merge pull request #93 from kwiateusz/UnitTestsUpdate
Last change from assertTrue($a instanceof $b) to assertInstanceOf
2011-08-14 21:05:15 -07:00
Benjamin Eberlei
2ee3cdeb0c Merge pull request #106 from FabioBatSilva/master
[DDC-1325] @Target annotation
2011-08-14 10:22:13 -07:00
Benjamin Eberlei
7782780cda Merge branch 'master' of github.com:doctrine/doctrine2 2011-08-14 19:20:30 +02:00
Dominik Liebler
6e47d7b16d DDC-1278 - EntityManager::clear($entity) support
added test case and modified test data CmsUser to cascade detach address and articles (testing collections and single entites)
2011-08-14 16:12:12 +02:00
Guilherme Blanco
a0ca506db7 Added support to SingleValuePathExpression in ORDER BY. 2011-08-14 00:46:02 -03:00
Guilherme Blanco
63a2f02f4d [DDC-408][DDC-1150][DDC-1277] Implemented support to parameter expanding on associations. 2011-08-13 21:28:54 -03:00
Fabio B. Silva
a04d2933fa @Target annotation and support to common 2.2-DEV 2011-08-13 16:28:05 -03:00
Dominik Liebler
25f5ff0ca1 DDC-1278 - EntityManager::clear($entity) support
cascade detach operation only on entity name entities
2011-08-13 20:22:23 +02:00
Dominik Liebler
745535d269 fixed typo 2011-08-12 20:15:32 +02:00
Dominik Liebler
05fb0b913a DDC-1278 - EntityManager::clear($entity) support
added new parameter $entityName for UnitOfWork::clear()
removed not implemented exception in EntityManager:clear()
2011-08-11 23:03:26 +02:00
Guilherme Blanco
e13720c33d Merge pull request #103 from rdohms/patch-1
Add getReader to AnnotationDriver
2011-08-10 11:11:41 -07:00
Rafael Dohms
07e1c1e2e1 Added method to retrieve currently used Reader. This allows projects that use Doctrine to recycle the reader to use with other annotation-driven packages, like DMS\Filter and Symfony\Validator 2011-08-10 15:10:09 -03:00
Guilherme Blanco
816ce41f63 Added support to CaseExpression. Added support to nest AndX and OrX QueryBuilder composite expressions, since they do not mess with generated queries. 2011-08-08 02:09:25 -03:00
Benjamin Eberlei
1666d59da4 Merge branch 'DDC-1300' 2011-08-06 20:25:52 +02:00
Benjamin Eberlei
bcc7bb1c9c DDC-1300 - Fix bug in fetch join hydration of entities with foreign key identifier 2011-08-06 20:25:45 +02:00
Benjamin Eberlei
15c877b8e8 Merge branch 'master' of github.com:doctrine/doctrine2 2011-08-06 18:15:00 +02:00
Guilherme Blanco
19682bf87a Merge pull request #102 from schmittjoh/configUpdate
updated configuration
2011-08-05 07:56:31 -07:00
Johannes Schmitt
7e47a601b0 updated configuration 2011-08-05 16:48:05 +02:00
Benjamin Eberlei
c85de03b66 Add phar packaging target and distribute phar into download folder 2011-08-01 23:09:03 +02:00
Benjamin Eberlei
d3beb7e23e Merge branch 'DDC-1313' 2011-08-01 21:45:39 +02:00
Benjamin Eberlei
ba882be76b DDC-1313 - Optimize behavior of DriverChain::getAllClassNames() 2011-08-01 21:45:21 +02:00
Benjamin Eberlei
e12a5fb328 Merge branch 'master' of github.com:doctrine/doctrine2 2011-07-31 11:41:30 +02:00
Benjamin Eberlei
d583b149ac Merge pull request #98 from asm89/master
[DDC-1301] Fixed tests teardown for mysql suite
2011-07-31 02:41:19 -07:00
Benjamin Eberlei
4675f65bea Merge branch 'DDC-1302' 2011-07-31 11:34:27 +02:00
Benjamin Eberlei
816039f23f DDC-1302 - Fix bug in XmlDriver not handling orphan removal 2011-07-31 11:32:57 +02:00
Alexander
953a0f6572 [DDC-1301] Fixed tests teardown for mysql suite 2011-07-29 09:35:59 +02:00
Benjamin Eberlei
c34612b8e9 [DDC-1298] DDC117Link file got lost from 2.1.x to master somehow 2011-07-28 23:44:11 +02:00
Benjamin Eberlei
f8558d7740 Merge branch 'master' of github.com:doctrine/doctrine2 2011-07-28 23:26:24 +02:00
Benjamin Eberlei
5c47c07794 Merge pull request #97 from asm89/DDC-1301
[DDC-1301] Fixed count() for fetch="EXTRA_LAZY" on OneToMany association
2011-07-28 14:26:15 -07:00
Benjamin Eberlei
3d788a10cf Merge branch 'master' of github.com:doctrine/doctrine2 2011-07-28 23:19:44 +02:00
Benjamin Eberlei
8f589e5876 Merge pull request #92 from mridgway/DDC-1275
DDC-1275: Added join columns to result set mapping
2011-07-28 14:18:55 -07:00
Michael Ridgway
1250cd7a5a F[DDC-1275] ixed check for owning side of a toOne relationship 2011-07-28 10:50:22 -04:00
Alexander
d439f67df5 [DDC-1301] Prefixed all Legacy models properties with _ 2011-07-28 12:25:23 +02:00
Alexander
d7dbde8f3e [DDC-1301] Fixed count() for fetch="EXTRA_LAZY" on OneToMany association 2011-07-28 11:01:52 +02:00
Alexander
b2951691e2 [DDC-1301] Added tests for fetch="EXTRA_LAZY" count() on a "legacy" database 2011-07-28 11:01:28 +02:00
Benjamin Eberlei
656beb635c Merge branch 'DDC-1298' 2011-07-27 23:26:06 +02:00
Benjamin Eberlei
196632978c DDC-1298 - Fix bug in SQLWalker with derived entities that have no fields of their own. 2011-07-27 23:22:20 +02:00
kwiateusz
d1e9bc6401 Now findByOne really retrieve only one entity adding limit to query. 2011-07-27 15:43:27 +02:00
kwiateusz
a47af43bc1 Last change from assertTrue($a instanceof $b) to assertInstanceOf 2011-07-27 08:54:06 +02:00
Michael Ridgway
7f20a32db3 Removing debug comment 2011-07-26 17:39:57 -04:00
Michael Ridgway
154fd60d85 DDC-1275: Added join columns to result set mapping 2011-07-26 17:35:06 -04:00
Benjamin Eberlei
a0b7c3e76d Add UPGRADE_TO_2_2 file 2011-07-26 23:16:38 +02:00
Benjamin Eberlei
7584ef6ba1 Merge branch 'master' of github.com:doctrine/doctrine2 2011-07-26 23:14:57 +02:00
Benjamin Eberlei
57cfcfd20e Merge pull request #79 from mridgway/DDC-725
[DDC-725] Removed onUpdate property on join columns
2011-07-26 14:14:30 -07:00
Benjamin Eberlei
e73605e177 Merge pull request #90 from mweimerskirch/patch-2
Corrected typo
2011-07-26 14:12:19 -07:00
Benjamin Eberlei
6abe8e412c Merge branch 'master' of github.com:doctrine/doctrine2 2011-07-26 23:03:30 +02:00
Benjamin Eberlei
79d99b11ad Merge pull request #91 from kwiateusz/UnitTestsUpdate
Removed deprecated assertType (thanks @kwiateusz)
2011-07-26 14:03:04 -07:00
Benjamin Eberlei
41a9e9689b Merge branch 'DDC-1215' 2011-07-26 23:00:11 +02:00
Benjamin Eberlei
598ab36968 [DDC-1215] Fix EntityGenerator inheritance regenerating properties and methods 2011-07-26 22:59:55 +02:00
Benjamin Eberlei
2e3d2398d9 Merge branch 'DDC-1280' 2011-07-26 22:30:27 +02:00
Benjamin Eberlei
93d2e1bd0a [DDC-1280] Only generate linefeeds in proxies for consistency. 2011-07-26 22:30:20 +02:00
Benjamin Eberlei
cbf210605a [DDC-1290] Allow smallint and bigint for version fields 2011-07-26 22:24:16 +02:00
Benjamin Eberlei
2a59da1f03 Merge branch 'DDC-1276' 2011-07-26 22:15:37 +02:00
Benjamin Eberlei
a99ffc126f DDC-1276 - Fix bug where merge managed and new entitiy share the same collection that is cascaded, cleared during the process and then empty afterwards. 2011-07-26 22:15:27 +02:00
Benjamin Eberlei
423651e45e Merge branch 'master' of github.com:doctrine/doctrine2 2011-07-26 20:37:37 +02:00
Alexander
6cf7bdc2b7 Merge branch 'master' into DDC-551 2011-07-26 17:26:00 +02:00
Guilherme Blanco
1d9016e48f Merge pull request #88 from asm89/DDC-1294
[DDC-1294] Add discriminator information to subselects
2011-07-26 08:14:36 -07:00
Alexander
97a4dbf2cd [DDC-1294] Added more tests for subselects in subselects 2011-07-26 17:15:21 +02:00
kwiateusz
7261060905 Few more converts from assertTrue($a instance of $b) to assertInstanceOf 2011-07-26 15:22:57 +02:00
kwiateusz
1ea3e543ab Correted indentation and variable name 2011-07-26 12:10:30 +02:00
kwiateusz
49c735109c Change from assertType to assertInstanceOf.
Now PHPUnit doesn't show warning about deprecation of assertType.
Also some refractoring from assertTrue($a instanceof $b) to assertInstanceOf.
Leading \ in namespaces is not required so I removed it from few assertions.
2011-07-26 11:38:09 +02:00
Michel Weimerskirch
6ef4ac62d7 Missed another typo 2011-07-26 11:03:23 +03:00
Michel Weimerskirch
b58f573b31 Corrected typo 2011-07-26 10:59:21 +03:00
Alexander
65f7e897b5 [DDC-1294] Add discriminator information to subselects 2011-07-26 00:19:26 +02:00
Alexander
e3dcfa8702 [DDC-551] Added filters to query hash + tests for hash 2011-07-22 17:01:18 +02:00
Guilherme Blanco
4b85d7a683 Reverted PR #86, which broke our suite. 2011-07-22 11:38:20 -03:00
Alexander
6163d9d932 [DDC-551] Added enabled filters to Query hash 2011-07-22 15:26:03 +02:00
Alexander
afd7a540a7 [DDC-551] Removed 'use ..DBAL\..\Type', causing full testsuite to fail 2011-07-22 15:10:31 +02:00
Alexander
4266ab77b2 [DDC-551] Added __toString() method to SQLFilter 2011-07-22 14:55:00 +02:00
Alexander
4cf63a4e83 [DDC-551] Fixed the escaping of filter parameters 2011-07-22 14:51:30 +02:00
Alexander
d1908f7207 [DDC-551] Keep filter parameters and enabled filters sorted for hashing 2011-07-22 14:36:14 +02:00
Alexander
277fc751b6 [DDC-551] Added tests for SQLFilter 2011-07-22 13:51:26 +02:00
Alexander
b867744f15 [DDC-551] Added tests for SQLFilter functionality + small fixes 2011-07-22 13:08:49 +02:00
Alexander
a85902b08d [DDC-551] Initial code for filter functionality 2011-07-22 12:01:33 +02:00
Guilherme Blanco
4be7c3dac0 Merge pull request #85 from FabienPennequin/fix_ClassMetadataFactory
Fixed php notice in ClassMetadataFactory
2011-07-21 10:02:15 -07:00
Guilherme Blanco
01d6ec35c4 Merge pull request #86 from kwiateusz/findByOne-patch
Now findByOne really retrieve only one entity adding limit to query
2011-07-21 10:01:21 -07:00
kwiateusz
570799b48d Restoring the missing comment 2011-07-21 04:13:15 -07:00
kwiateusz
0e6121e8f5 Now findByOne really retrieve only one entity adding limit to query 2011-07-21 12:40:43 +02:00
Fabien Pennequin
99bdf65c10 Fixed php notice in ClassMetadataFactory 2011-07-17 19:39:55 +02:00
Benjamin Eberlei
180dbbad8b Merge branch 'EntityGenerator' 2011-07-12 23:46:13 +02:00
Benjamin Eberlei
d9b1dbbb09 DDC-1244 - Fix bug with entities without namespace 2011-07-12 23:43:24 +02:00
Benjamin Eberlei
c87dedbec5 DDC-1254 - Dont throw exception about missing id in disconnected metadata factory 2011-07-12 23:39:56 +02:00
Benjamin Eberlei
4796452b07 DDC-1268 - Singular add*() method name through using targetEntity shortname 2011-07-12 23:25:15 +02:00
Benjamin Eberlei
fb11268255 Merge branch 'DDC-1240' 2011-07-12 22:50:31 +02:00
Benjamin Eberlei
98fabd98be DDC-1240 - Fix optimistic lock exception loosing the message 2011-07-12 22:50:21 +02:00
Benjamin Eberlei
5733574867 Merge branch 'master' of github.com:doctrine/doctrine2 2011-07-12 22:47:33 +02:00
Benjamin Eberlei
409c16b898 Merge branch 'DDC-1250' 2011-07-09 22:12:15 +02:00
Benjamin Eberlei
c261315ea7 DDC-1250 - Fix bug with inverse one to one loading and ambigious column names in certain scenarios 2011-07-09 22:11:49 +02:00
Benjamin Eberlei
8b92dc5265 Merge branch 'DDC-1257' 2011-07-09 15:14:31 +02:00
Benjamin Eberlei
442a2b3a51 DDC-1257 - Fix bug where validation callbacks are added multiple times in EntityGenerator 2011-07-09 15:11:16 +02:00
Benjamin Eberlei
305e0345ef Merge branch 'DDC-1251' 2011-07-09 14:53:39 +02:00
Benjamin Eberlei
a8048af65d DDC-1251 - Fix bug in token parsing of EntityGenerator 2011-07-09 14:53:25 +02:00
Benjamin Eberlei
d7da292f60 Merge remote branch 'origin/master' 2011-07-09 14:43:04 +02:00
Benjamin Eberlei
689eaf3172 Merge branch 'DDC-1022' 2011-07-09 12:12:56 +02:00
Benjamin Eberlei
2b207106a3 DDC-1022 - Call __wakeup() with the same semantics then ClassMetadata::newInstance() does inside UnitOfWork 2011-07-09 12:12:44 +02:00
Guilherme Blanco
9d1a647753 Merge branch 'master' of github.com:doctrine/doctrine2 2011-07-08 16:27:20 -03:00
Guilherme Blanco
b6bd46dbed General fix for end point as file extension on Annotation driver. 2011-07-08 16:26:54 -03:00
Benjamin Eberlei
9a68074878 Clarify possible problem 2011-07-08 14:42:15 +02:00
Benjamin Eberlei
ac76dafe62 Add doccomments, refactor into listener and dump method to allow re-use 2011-07-08 14:32:12 +02:00
Benjamin Eberlei
ef663c83f3 DDC-1258 - Add Debug UnitOfWork Listener 2011-07-08 14:27:59 +02:00
Benjamin Eberlei
024b7b7cb6 Bump Dev Version to 2.2.0-DEV 2011-07-04 21:34:59 +00:00
Benjamin Eberlei
dfdb735306 Release 2.1.0 2011-07-04 21:34:47 +00:00
Benjamin Eberlei
cb49648eed Bump Common and DBAL to 2.1 2011-07-04 21:33:36 +00:00
Benjamin Eberlei
5c2a4c0339 Merge branch 'DDC-1238' 2011-07-04 23:19:26 +02:00
Benjamin Eberlei
2858b8290f DDC-1238 - Fixed a bug introduced when refactoring persisters hydration. This occurs when you call $em->clear() and you start accessing a proxy. 2011-07-04 23:19:08 +02:00
Benjamin Eberlei
a638154046 Update tests 2011-07-04 20:59:46 +02:00
Benjamin Eberlei
a947e8a4b0 DDC-1238 - Reproducible case, its correct through 2011-07-04 20:59:46 +02:00
Benjamin Eberlei
8e7c156451 Started trying to reproduce this issue 2011-07-04 20:59:46 +02:00
Benjamin Eberlei
0529efc843 Merge branch 'master' of github.com:doctrine/doctrine2 2011-07-04 19:52:35 +02:00
Guilherme Blanco
438dd9141f Merge branch 'master' of github.com:doctrine/doctrine2 2011-07-04 11:38:45 -03:00
Guilherme Blanco
db37d974c8 Increasing visibility of AnnotationReader inside AnnotationDriver from private to protected. 2011-07-04 11:33:44 -03:00
Benjamin Eberlei
6b54cceed7 Moved AnnotationRegistry::registerFile() call to Configuration#newDefaultAnnotationDriver() and documented the migration in UPGRADE_TO_2_1 2011-07-03 12:21:04 +02:00
Benjamin Eberlei
73f908f25c Merge branch 'master' of github.com:doctrine/doctrine2 2011-07-03 12:07:40 +02:00
Guilherme Blanco
550fcbc17f [DDC-1237] Fixed issue with QueryBuilder where user may have includes nested complex expression in a string format while consuming a composite expression (AND or OR). 2011-07-03 01:48:18 -03:00
Benjamin Eberlei
ffca455788 Bump Dev Version to 2.1.0RC4-DEV 2011-07-02 20:29:02 +00:00
Benjamin Eberlei
e4f2a56277 Release 2.1.0RC3 2011-07-02 20:28:37 +00:00
Benjamin Eberlei
cbe14a694a Update Common dependency to 2.1 RC3 2011-07-02 20:28:04 +00:00
Benjamin Eberlei
f589cd0d9f Update common version 2011-07-02 20:30:35 +02:00
Benjamin Eberlei
43d8466fa9 Update annotation handling in AnnotationDriver to work with AnnotationRegistry and bump common dependency 2011-07-02 19:48:43 +02:00
Benjamin Eberlei
5299bd788f DDC-1239 - Fix missing AND in Eager LEFT JOIN of entity persister when multiple join columns are used 2011-06-30 21:04:46 +02:00
Benjamin Eberlei
a0a81db045 DDC-1204, DDC-1203 - No need to throw this exception for abstract classes anymore 2011-06-30 20:57:29 +02:00
Benjamin Eberlei
5362206297 Revert "Fixed ClassMetadataFactory which was throwing an exception if parent class on inheritance hierarchy is an abstract class and also extends from a mapped superclass (so it contains an inheritance already), but is not in the discriminatorMap."
This reverts commit 4603e94fe9.

Making an exception go away is not a fix for something. :)
2011-06-30 20:12:22 +02:00
Benjamin Eberlei
e32e141012 Merge branch 'master' of github.com:doctrine/doctrine2 2011-06-30 20:10:05 +02:00
Guilherme Blanco
4603e94fe9 Fixed ClassMetadataFactory which was throwing an exception if parent class on inheritance hierarchy is an abstract class and also extends from a mapped superclass (so it contains an inheritance already), but is not in the discriminatorMap. 2011-06-30 15:04:57 -03:00
Benjamin Eberlei
8b7e2a9f32 Merge pull request #81 from schmittjoh/annotation
added @Annotation to annotations
2011-06-30 08:02:08 -07:00
Johannes Schmitt
5701036068 added @Annotation to annotations 2011-06-30 11:03:32 +02:00
Guilherme Blanco
0f68355ce0 Merge pull request #80 from pkruithof/patch-2
Changed order of elements
2011-06-29 06:09:36 -07:00
Peter Kruithof
9395eeed3d Changed order of elements 2011-06-29 03:15:05 -07:00
Benjamin Eberlei
6d035be3e3 Bump Dev Version to 2.1.0-DEV 2011-06-28 21:11:14 +00:00
Benjamin Eberlei
01935e6661 Release 2.1.0RC2 2011-06-28 21:11:02 +00:00
Benjamin Eberlei
379584fb26 Bump dependencies of Common and DBAL to 2.1.0RC2 2011-06-28 21:10:43 +00:00
Benjamin Eberlei
f1c073e080 Merge branch 'master' of github.com:doctrine/doctrine2 2011-06-28 22:30:24 +02:00
Benjamin Eberlei
66e92b147d Minor spelling mistake, thanks Alexandre Mathieu for reporting 2011-06-28 22:30:17 +02:00
Michael Ridgway
c19d7fe2eb Missed one 2011-06-28 15:55:43 -04:00
Michael Ridgway
9ae30421dd Removed onUpdate property on join columns 2011-06-28 15:50:14 -04:00
Benjamin Eberlei
53c799987d Merge pull request #78 from mweimerskirch/patch-1
Removed superfluous variable name in "@return" documentation
2011-06-28 12:49:37 -07:00
Benjamin Eberlei
8850efb0eb Merge branch 'DDC-1230' 2011-06-28 21:38:06 +02:00
Benjamin Eberlei
551f6d05d9 DDC-1230 - Fix bug where UnitOfWork does not set STATE_REMOVE when calling EntityManager#remove() on an entity 2011-06-28 21:37:53 +02:00
Michel Weimerskirch
e899205300 Removed superfluous variable name in "@return" documentation 2011-06-28 12:24:24 -07:00
Benjamin Eberlei
5afc097527 Bump DBAL dependency to latest master 2011-06-26 19:06:52 +02:00
Benjamin Eberlei
ed516edf90 Fix discriminator casing problem in Oracle 2011-06-26 17:49:34 +02:00
Benjamin Eberlei
52431251cb Fix some of the problems with Oracle testsuite 2011-06-26 17:20:03 +02:00
Benjamin Eberlei
69944017d2 Merge branch 'master' of github.com:doctrine/doctrine2 2011-06-26 10:11:29 +02:00
Benjamin Eberlei
ca0bea1d8a Merge branch 'DDC-1224' 2011-06-26 10:11:11 +02:00
Benjamin Eberlei
7efe071ac4 DDC-1224 - Bugfix with temporary table ids and tables in schema (in postgresql) 2011-06-26 10:10:57 +02:00
Guilherme Blanco
ebe95af30c Merge pull request #77 from rubensayshi/master
Fixed wrong keyname
2011-06-25 08:30:30 -07:00
Ruben de Vries
a607e2ec7a fixed wrong keyname 2011-06-25 17:08:56 +02:00
Benjamin Eberlei
a73a1e8437 DDC-1226, DDC-1228 - Bugfix with refereshing proxy references not setting the originalEntityData. 2011-06-25 14:38:44 +02:00
Benjamin Eberlei
07f568e2b4 Add test for DDC-1227 regression 2011-06-25 10:27:06 +02:00
Benjamin Eberlei
0dd1dc20c8 DDC-1227 - Fix regression in QueryBuilder::add() due to Expr\From refactoring. 2011-06-25 10:25:22 +02:00
Benjamin Eberlei
7367e255ae Merge branch 'master' of github.com:doctrine/doctrine2 2011-06-25 10:24:06 +02:00
Benjamin Eberlei
10b70df1af DDC-1218, DDC-1156 - Fixed bugs with mapped superclasses in inheritance hierachies 2011-06-25 10:20:37 +02:00
Benjamin Eberlei
fe8b28a09f Add test for DDC-1156, DDC-1218 2011-06-25 09:57:15 +02:00
Guilherme Blanco
db80b2b135 Fixed phpunit tests which was failing due to a duplicate use declaration. 2011-06-21 12:38:08 -03:00
Benjamin Eberlei
a5cddb0c11 Merge branch 'master' of github.com:doctrine/doctrine2 2011-06-20 21:26:33 +02:00
Benjamin Eberlei
3717ae3c53 strtolower() on cascade information avoids problem with case-sensitivity in YAML and annotations mapping driver. 2011-06-20 21:26:12 +02:00
Guilherme Blanco
2caf0fff60 Merge pull request #75 from joshiausdemwald/DatabaseDriver_Corrections
Suppressed an "undefined variable" notice by adding initialization code
2011-06-20 10:24:37 -07:00
Johannes Heinen
c05fffcc93 Suppressed php undefined variable notice adding initialization code to Doctrine\ORM\Mapping\Driver\DatabaseDriver.php 2011-06-20 19:07:03 +02:00
Benjamin Eberlei
fff0204e6d Merge branch 'DDC-1211' 2011-06-19 10:25:42 +02:00
Benjamin Eberlei
c7c430032c DDC-1211 - Fix bug with empty numeric literal 2011-06-19 10:17:35 +02:00
Benjamin Eberlei
1c2ade61ab DDC-1214 - Fix UpdateCommand::getFullName() 2011-06-19 10:05:30 +02:00
Benjamin Eberlei
c62e27898c Merge branch 'master' of github.com:doctrine/doctrine2 2011-06-19 09:42:45 +02:00
Benjamin Eberlei
6f8ac21273 Merge branch 'DDC-1189' 2011-06-19 09:40:38 +02:00
Benjamin Eberlei
82f0c244e8 DDC-1189 - Bugfix with PersistentCollection#clear() in combination with lazy loading 2011-06-19 09:39:34 +02:00
Benjamin Eberlei
197744a57f Bump Dev Version to 2.1.0RC2-DEV 2011-06-18 22:08:52 +00:00
Benjamin Eberlei
054ac220ac Release 2.1.0RC1 2011-06-18 22:08:37 +00:00
Benjamin Eberlei
c6746d4a4a Merge 2.0.x build.xml changes into master build.xml 2011-06-18 22:07:14 +00:00
Benjamin Eberlei
f0bc3d925d Bump dependencies of Common and DBAL to 2.1.0RC1 2011-06-18 22:02:40 +00:00
Benjamin Eberlei
7810f5fe69 Add convenience helper for running tests against multiple different databases 2011-06-18 23:23:43 +02:00
Benjamin Eberlei
decd1482de Fix bug in ChangeTrackingNotify code 2011-06-18 23:06:07 +02:00
Benjamin Eberlei
fa7574b2ba Removed AllTests files and Suites 2011-06-18 22:49:25 +02:00
Benjamin Eberlei
32b146ea8a Switch testsuite to run with phpunit.ini.dist from main folder, not using AllTests approach. Fixed global state problem in tests that was caused by EventManager being reused. Significantly enhanced error message about cascade persist 2011-06-18 22:47:21 +02:00
Benjamin Eberlei
1aa90dc872 Add UPGRADE note about annotations parser changes 2011-06-18 21:25:29 +02:00
Benjamin Eberlei
989d375be5 Some more tests for the Setup helper 2011-06-18 08:47:10 +02:00
Benjamin Eberlei
ede68ec87b Merge branch 'master' of github.com:doctrine/doctrine2 2011-06-18 01:05:48 +02:00
Benjamin Eberlei
02f06b6d52 Add convenience Setup Tool to register autoloaders and create configuration objects 2011-06-18 01:05:30 +02:00
Guilherme Blanco
699ccfddb6 Implemented COALESCE and NULLIF support in DQL. 2011-06-17 16:16:22 -03:00
Guilherme Blanco
626e467a17 Implemented COALESCE and NULLIF support in DQL. 2011-06-17 16:15:19 -03:00
Guilherme Blanco
1fed340793 Optimized AnnotationDriver to filter found files during getAllClassnames(). 2011-06-16 19:54:50 -03:00
Benjamin Eberlei
0cd0ae49a1 Fix regression introduced with DDC-1203,DDC-1204 patch 2011-06-16 23:00:59 +02:00
Benjamin Eberlei
713f4654fd Merge remote-tracking branch 'origin/master' 2011-06-16 22:49:29 +02:00
Benjamin Eberlei
22bdb1520a Merge branch 'DDC-1172' 2011-06-16 22:34:16 +02:00
Benjamin Eberlei
42c5382a03 DDC-1172 - Handle sequence dropping in SchemaTool. 2011-06-16 22:34:04 +02:00
Guilherme Blanco
98bc3c4e40 Merge pull request #74 from mridgway/DDC-1209
[DDC-1209] Fixed custom object types as @Id
2011-06-16 07:15:40 -07:00
Michael Ridgway
d1106a730b Made DDC-1209 test pass 2011-06-16 08:55:09 -04:00
Michael Ridgway
da2d83fc7d DDC-1209 tests 2011-06-15 17:15:46 -04:00
Benjamin Eberlei
ec748b2a16 Merge branch 'DDC-1203' 2011-06-15 22:27:32 +02:00
Benjamin Eberlei
5ff44b5ec7 DDC-1203, DDC-1204 - Fix problems with mapped superclasses in midth of inheritance hierachy and entities not mapped in discriminator map. 2011-06-15 22:27:24 +02:00
Benjamin Eberlei
dd329c903d Merge branch 'DDC-1208' 2011-06-15 18:32:06 +02:00
Benjamin Eberlei
3be6218341 DDC-1208 - Allow namespace separator in <discriminator-mapping /> 2011-06-15 18:31:59 +02:00
Benjamin Eberlei
71082bdba8 Merge branch 'master' of github.com:doctrine/doctrine2 2011-06-15 18:29:01 +02:00
Benjamin Eberlei
866534334f Merge pull request #71 from fabpot/master
Updated Symfony2 vendors
2011-06-14 08:08:16 -07:00
Fabien Potencier
b37c8f6a23 Update Symfony2 vendors 2011-06-14 17:01:33 +02:00
Benjamin Eberlei
df500033bf Merge pull request #70 from pkruithof/patch-1
Change attribute 'columns' of type 'index' to 'xs:string'
2011-06-14 06:27:07 -07:00
Peter Kruithof
05bf8477a3 The columns attribute of the index type was xs:NMTOKENS, therefore not allowing a comma, which is needed when multiple columns need to be specified. (I've checked the XmlDriver code for this)
It should be the same as the `columns` attribute of the `unique-constraints` type, namely `xs:string`.
2011-06-14 02:36:49 -07:00
Benjamin Eberlei
2b52eff4eb Merge branch 'master' of github.com:doctrine/doctrine2 2011-06-13 08:54:39 +02:00
Benjamin Eberlei
d5daf161c6 Merge pull request #64 from mvrhov/schema_extension
Add extension points into the xml schema
2011-06-12 13:14:19 -07:00
Benjamin Eberlei
12dfb5ee38 Merge pull request #67 from Nico-B/master
joinTable error with DB to YML generator
2011-06-12 13:09:32 -07:00
Benjamin Eberlei
39ee9e5e5b Merge pull request #69 from Garfield-fr/master
Renamed function getFullName with getName
2011-06-12 13:08:43 -07:00
Bertrand Zuchuat
c7eaf77d15 Renamed function getFullName with getName to match with last change on Symfony Console 2011-06-12 14:46:02 +02:00
NicoB
524c799e37 Merge remote-tracking branch 'remotes/upstream/master' 2011-06-11 17:56:50 +07:00
Benjamin Eberlei
fe527fbf1a Merge pull request #59 from asm89/databasedriver-patch
Implemented tableName -> className and columnName -> fieldName mapping in DatabaseDriver.
2011-06-11 03:15:16 -07:00
Benjamin Eberlei
037daff891 Merge pull request #65 from weaverryan/update_command
[Tools][Console] Refactoring the UpdateCommand
2011-06-11 01:16:25 -07:00
Benjamin Eberlei
9945296472 Merge pull request #61 from stof/EntityGenerator_3
Updated the EntityGenerator to be compatible with Common 3.0.x
2011-06-11 01:13:05 -07:00
Guilherme Blanco
fdbc909bde Merge branch 'master' of github.com:doctrine/doctrine2 2011-06-09 15:43:37 -03:00
Guilherme Blanco
1f6b49d236 Added getRootEntities to QueryBuilder. 2011-06-09 15:42:40 -03:00
NicoB
3cdb4e007d joinTable can be undefined because ManyToMAny generation is bidirectional with inverse sides 2011-06-07 18:55:52 +07:00
Benjamin Eberlei
a4cbb23fc8 Slight adjustment to build.xml 2011-06-05 17:21:37 +02:00
Benjamin Eberlei
97573425f9 Merge branch 'DDC-1163' 2011-06-05 16:21:35 +02:00
Benjamin Eberlei
4371e8fab0 DDC-1163 - Fix nasty bug with inheritance in UnitOfWork::executeUpdates() and executeRemovals() 2011-06-05 16:21:23 +02:00
Benjamin Eberlei
22826ac10d DDC-1156 - Do not throw exception for mapped superclass in middle of inheritance hierachy anymore. 2011-06-05 15:00:49 +02:00
Benjamin Eberlei
543432bf53 Merge branch 'DDC-1192' 2011-06-05 14:50:05 +02:00
Benjamin Eberlei
d17d0f5452 DDC-1192 - Fix notice in XmlDriver, removed unnecessary code. 2011-06-05 14:49:54 +02:00
Benjamin Eberlei
d3ab9b51fa DDC-1181 - Add test that verifies cascade remove works for entities with foreign identifiers 2011-06-05 13:57:44 +02:00
Benjamin Eberlei
ddb647f39f DDC-1173 - Fix bug when calling UnitOfWork::clearEntityChangeSet() in listener 2011-06-05 13:34:07 +02:00
Benjamin Eberlei
70d756d59c DDC-1184 - Improve error handling in AssignedIdGenerator 2011-06-05 12:54:29 +02:00
Benjamin Eberlei
f3677554e8 Merge branch 'master' of github.com:doctrine/doctrine2 2011-06-05 12:52:05 +02:00
Benjamin Eberlei
3cdff65761 Merge pull request #63 from chesteroni/master
Added missing checks for associatation indexes
2011-06-05 03:28:52 -07:00
Benjamin Eberlei
ff30f86082 Merge pull request #62 from mvrhov/yml_export_notice_fix
Fixing Notice: Undefined index in yaml export driver
2011-06-05 03:28:31 -07:00
Benjamin Eberlei
1038a866a4 DDC-1194 - Improve error handling for DQL INSTANCE OF 2011-06-05 10:48:21 +02:00
Benjamin Eberlei
2c9a12771b Merge branch 'DDC-1193' 2011-06-05 10:03:04 +02:00
Benjamin Eberlei
bda4165bf8 DDC-1193 - Fix previous commit. 2011-06-05 10:02:57 +02:00
Benjamin Eberlei
84aefd6340 Merge branch 'DDC-1193' 2011-06-05 09:59:57 +02:00
Benjamin Eberlei
acaf08d4b7 DDC-1193 - Fix bug with cascade remove and proxy classes. 2011-06-05 09:59:16 +02:00
Benjamin Eberlei
875912bffd DDC-733 - Add UnitOfWork::initializeObject() method. 2011-06-05 08:44:38 +02:00
Fabien Potencier
86c3744b8c Made orm:convert-mapping command more configurable (allow to change the extension of the generated files for instance) 2011-06-05 08:23:08 +02:00
Benjamin Eberlei
875f5c1fa8 Merge branch 'master' of github.com:doctrine/doctrine2 2011-06-05 08:19:25 +02:00
Ryan Weaver
6468740915 [Tools][Console] Reworking changes to be more backwards compatible
This keeps the --dump-sql and --force options, but adds an exception if you try to use them both (which previously, only dumped the SQL but didn't tell you that it was *not* in fact also executing the queries).

One additional change is the introduction of a `$name` property, which was the only way that a parent task could allow a child task to override the task's name early enough that the task's overridden name is taken to account when the parent class references it for its help message.
2011-06-03 15:09:18 -05:00
Ryan Weaver
79643e32ed [Tools][Console] Refactoring the UpdateCommand
There are two basic changes:

  1) Changed --force and --dump-sql from options to a single argument. Prior, you couldn't pass both options simultaneously anyways, so making them an argument is more accurate.

  2) Changed the language and formatting of the task to be more user-friendly.
2011-06-03 08:02:51 -05:00
Miha Vrhovnik
bf0775fbb6 Add extension points into the xml schema 2011-06-03 09:12:32 +02:00
Alexander
7ee8dc4e44 DDC-1179 - Make it possible to specify a namespace when mapping with --from-database 2011-06-02 21:45:03 +02:00
chesteroni
23540c17f1 Added checking for existing indexes in associatation mapping array. 2011-05-28 20:57:19 -07:00
Miha Vrhovnik
bb873826ca Fixing Notice: Undefined index: orderBy in ...Doctrine/ORM/Tools/Export/Driver/YamlExporter 2011-05-27 08:43:29 +02:00
Guilherme Blanco
93521217a6 Moved getQuoted* from ClassMetadata to ClassMetadataInfo, since SchemaTool relies on them, making impossible to work with DisconnectedClassMetadataFactory. 2011-05-26 02:18:29 -03:00
Christophe Coevoet
693fc090b5 Updated the EntityGenerator to be compatible with Common 3.0.x 2011-05-25 12:35:54 +02:00
Benjamin Eberlei
ca6ea65b1f Merge branch 'NewAnnotations' 2011-05-25 00:36:10 +02:00
Benjamin Eberlei
3adbf0de39 Add forward compatibility with Doctrine Common 3.0 2011-05-25 00:35:57 +02:00
Johannes Schmitt
a0d79b03e7 [AnnotationDriver] compatibility with Doctrine Common 3.x 2011-05-25 00:32:55 +02:00
Benjamin Eberlei
2b3d0a209c Merge branch 'NewAnnotations' 2011-05-25 00:26:29 +02:00
Benjamin Eberlei
6d724ad9ff Make ORM forward compatible with new Doctrine Annotations library version 2.1 2011-05-25 00:26:20 +02:00
Benjamin Eberlei
0bb0937372 Started UPGRADE_TO_2_1 document 2011-05-20 21:13:25 +02:00
Benjamin Eberlei
bc4e14a99f Prototype for a proxy extension that avoids loads when calling for a getter that is named after an identifier. 2011-05-20 20:50:03 +02:00
Alexander
cec62db2d8 Removed _ prefix from private functions. 2011-05-20 16:53:35 +02:00
Alexander
262ae7c942 Implemented tableName -> className and columnName -> fieldName mapping in
DatabaseDriver.
2011-05-20 16:36:43 +02:00
Benjamin Eberlei
85fb1a3ebb Merge branch 'master' of github.com:doctrine/doctrine2 2011-05-18 19:37:32 +02:00
Benjamin Eberlei
a979852ee6 Merge branch 'DDC-1080' 2011-05-17 23:42:39 +02:00
Benjamin Eberlei
9ea03de84f DDC-1080 - Fix bug with hydration of derived entities/foreign key as primary key. 2011-05-17 23:42:24 +02:00
Benjamin Eberlei
9f01e9563f Bump Dev Version to 2.1.0BETA2-DEV 2011-05-16 19:35:00 +00:00
Benjamin Eberlei
f4021e7469 Update Doctrine Common to latest version and add new methods to ClassMetadataInfo 2011-05-16 20:42:38 +02:00
Benjamin Eberlei
5d81e867be Add some logic to keep backwards compatibility in QueryBuilder 2011-05-15 23:16:44 +02:00
Benjamin Eberlei
85d40847ac Reintroduce QueryBuilder::getRootAlias() for backwards compatibility reasons, mark as @deprecated 2011-05-15 22:11:10 +02:00
Benjamin Eberlei
5e938b3147 Revert "Implemented auto-inference of isCascadeRemove when orphanRemoval is defined (marked as todo)."
This reverts commit 551247d11a.
2011-05-15 20:39:55 +02:00
Benjamin Eberlei
2cfdf2b05d Merge branch 'master' of github.com:doctrine/doctrine2 2011-05-15 20:18:47 +02:00
Benjamin Eberlei
d45f7c1302 DDC-694 - Add info command 2011-05-15 20:18:31 +02:00
Benjamin Eberlei
34ad2ccbf1 Merge pull request #23 from kertz/master
LifecycleCallbackMethods Beautification
2011-05-15 10:40:23 -07:00
Benjamin Eberlei
83372bd144 Merge pull request #23 from kertz/master
LifecycleCallbackMethods Beautification
2011-05-15 10:39:44 -07:00
Benjamin Eberlei
1b4f0a5e1f DDC-1080 - Add failing testcase 2011-05-14 13:32:12 +02:00
Benjamin Eberlei
14d630ae1c Merge branch 'DDC-1151' 2011-05-14 08:44:49 +02:00
Benjamin Eberlei
cb3615ab47 DDC-1151 - Fix missing table quotes when adding foreign keys in SchemaTool 2011-05-14 08:44:19 +02:00
Benjamin Eberlei
e66970b78b Merge branch 'master' of github.com:doctrine/doctrine2 2011-05-14 08:16:21 +02:00
Guilherme Blanco
2a7364bb18 We now support @Id on @ManyToOne fields. Removed TODO and associated code. 2011-05-14 00:53:22 -03:00
Guilherme Blanco
f4d62b317e Fixed endless recursion of DDC-719 test. 2011-05-14 00:49:46 -03:00
Guilherme Blanco
551247d11a Implemented auto-inference of isCascadeRemove when orphanRemoval is defined (marked as todo). 2011-05-14 00:43:33 -03:00
Guilherme Blanco
08f2af489e Changed QueryBuilder to allow retrieval of all defined root alises. 2011-05-14 00:40:23 -03:00
Guilherme Blanco
e538128645 [DDC-1029] renaming "load()" in proxy to "__load()" 2011-05-13 00:23:27 -03:00
Guilherme Blanco
1e9e2de737 [DDC-1122] Added coverage for bug report. 2011-05-13 00:12:05 -03:00
Guilherme Blanco
8e3fdc5adc [DDC-1148] Implement auto-inference of types in setParameter. 2011-05-12 23:05:45 -03:00
Benjamin Eberlei
814473c27d Merge pull request #35 from brikou/master
[DDC-1136] prevent backup file to be recognized as valid Entity file
2011-05-12 05:41:31 -07:00
Guilherme Blanco
a45a02fd64 Merge branch 'master' of github.com:doctrine/doctrine2 2011-05-11 21:40:43 -03:00
Guilherme Blanco
905e05cd36 [DDC-1067][DDC-1145] Fixed bug with multiple froms and inclusion of joins. Added support for index by in QueryBuilder. This break BC only if users are using base support (->add). 2011-05-11 21:40:27 -03:00
Benjamin Eberlei
75b69f946d Merge pull request #57 from stof/DDC-1146
[DDC-1146] Updated the Symfony2 vendors
2011-05-11 16:14:25 -07:00
Christophe Coevoet
a112be79ef [DDC-1146] Updated the Symfony2 vendors 2011-05-12 01:10:34 +02:00
Guilherme Blanco
54a0109d5d [DDC-1147] Allowed usage of 0-based input parameters in DQL. 2011-05-11 17:30:42 -03:00
Guilherme Blanco
0d0d61935f Merge pull request #53 from Garfield-fr/master
Fixed typo
2011-05-08 05:18:46 -07:00
Bertrand Zuchuat
b959ab37bf Typo 2011-05-08 13:57:08 +02:00
Guilherme Blanco
b025b2b343 Fixed where componentes (ie. MEMBER OF) that that are sensitive to parenthesis presence. Made OR and AND expressions smarter. Fixed related unit tests. 2011-05-07 20:14:04 -03:00
Guilherme Blanco
bffca232e2 Merge branch 'master' of github.com:doctrine/doctrine2 2011-05-06 01:42:01 -03:00
Guilherme Blanco
19dfe7b891 Added method to allow retrieve all registered entity namespace aliases. 2011-05-06 01:41:34 -03:00
Benjamin Eberlei
ce1e446227 Merge branch 'master' of github.com:doctrine/doctrine2 2011-05-03 17:06:42 +02:00
Benjamin Eberlei
5d1905de13 DDC-1120 - Fix comment 2011-05-01 12:17:09 +02:00
Benjamin Eberlei
23131d6860 Merge branch 'DDC-1129' 2011-05-01 11:45:39 +02:00
Benjamin Eberlei
d4569baa11 [DDC-1129] Fix bug in version changeset computation aswell as inline ClassMetadata::isCollectionValuedAssociation to increase performance by 2-5% 2011-05-01 11:44:31 +02:00
Benjamin Eberlei
b5520aa304 Merge branch 'DDC-1091' 2011-05-01 11:01:39 +02:00
Benjamin Eberlei
c53baa9935 [DDC-1091] Fix bug with custom string functions in StringPrimary 2011-05-01 11:01:30 +02:00
Benjamin Eberlei
d0b95bb31c Merge branch 'DDC-1043' 2011-05-01 10:21:59 +02:00
Benjamin Eberlei
7a068c206e DDC-1043 - Make computeChangeSet() algorithm more strict, possible leading to more updates to to values that are not exactly the same. However this is necessary to avoid bugs with certain PHP casting rules, i.e. +44 = 44 2011-05-01 10:21:47 +02:00
Benjamin Eberlei
5a6ac2fb56 Merge branch 'DDC-1102' 2011-05-01 10:01:49 +02:00
Benjamin Eberlei
6b3dfaccfc DDC-1102 - Typo in EntityGenerator 2011-05-01 10:01:38 +02:00
Benjamin Eberlei
e3d2a0e293 Merge branch 'PR39' 2011-05-01 00:18:22 +02:00
Francis Besset
a141aaf663 [PR-39] Throw exception when hydrating joined entity without existing parent alias (NativeQuery problem only) 2011-05-01 00:17:40 +02:00
Benjamin Eberlei
85d6b9fd39 Merge pull request #42 from mridgway/DDC-1059.
DDC-1059: RSM Helper
2011-04-30 15:01:25 -07:00
Benjamin Eberlei
e9067eb4a3 Merge branch 'DDC-1149' 2011-04-30 23:52:10 +02:00
Fabien Potencier
0c955fe54f Fix namespace/class parsing in the entity generator 2011-04-30 23:51:22 +02:00
Benjamin Eberlei
ea5a623c88 Merge branch 'DDC-1094' 2011-04-30 23:18:48 +02:00
Benjamin Eberlei
73c7605a5c [DDC-1094] Add support for limit, offset and orderby in EntityRepository::findBy(). 2011-04-30 23:18:24 +02:00
Benjamin Eberlei
0b1077a3b3 Merge branch 'DBAL-115' 2011-04-30 17:16:47 +02:00
Benjamin Eberlei
5179ff921b [DBAL-115] REALLY fix issues with SchemaTool::getDropSchemaSQL(). 2011-04-30 17:16:34 +02:00
Benjamin Eberlei
abbb3e8656 Merge branch 'DBAL-115' 2011-04-30 16:20:32 +02:00
Benjamin Eberlei
1f665e6ba8 [DBAL-115] Bugfix in SchemaTool not quoting table names when dropping schema. 2011-04-30 16:20:14 +02:00
Benjamin Eberlei
d72217a00a Merge branch 'DDC-1133' 2011-04-30 14:23:59 +02:00
Benjamin Eberlei
261d3c892e DDC-1133 - Ducktype AnnotationReader in AnnotationDriver 2011-04-30 14:23:46 +02:00
Benjamin Eberlei
2c50faf5b2 Merge branch 'DDC-1109' 2011-04-30 12:49:52 +02:00
Benjamin Eberlei
7dd0dd273e [DDC-1109] ltrim discriminator map for convenience. 2011-04-30 12:49:37 +02:00
Benjamin Eberlei
b462cfbe2b Merge branch 'DDC-1108' 2011-04-30 12:27:35 +02:00
Benjamin Eberlei
67b89eaa4f [DDC-1108] Fix bug with single char named input parameters in DQL lexer. 2011-04-30 12:27:16 +02:00
Benjamin Eberlei
ed355d2eb6 Merge branch 'master' of github.com:doctrine/doctrine2 2011-04-30 11:19:58 +02:00
Benjamin Eberlei
c6d725d6e8 Merge branch 'DDC-1132' 2011-04-30 11:16:41 +02:00
Benjamin Eberlei
42230a4c51 [DDC-1132] Fix many to many table detection. 2011-04-30 11:16:30 +02:00
Benjamin Eberlei
7929aea45a Merge branch 'DDC-1132' 2011-04-30 11:15:56 +02:00
Benjamin Eberlei
f09d299660 [DDC-1132] Fix many to many table detection. 2011-04-30 11:15:45 +02:00
Benjamin Eberlei
41b3a372d3 Add new performance test checking compute changeset performance. 2011-04-30 10:47:56 +02:00
Guilherme Blanco
7aaecacc5b Merged pull request #36 from ajessu/fixTypo.
Fix typos on the help text of the schema commands
2011-04-26 18:12:32 -07:00
Guilherme Blanco
237a05b302 Merged pull request #44 from Chekote/parser_match_phpdoc_fix.
Parser::match phpdoc fix
2011-04-26 18:09:27 -07:00
Guilherme Blanco
f73c7f3be0 Merged pull request #48 from rdohms/master.
Fixing docblocks in SchemaTool
2011-04-26 18:05:59 -07:00
Guilherme Blanco
fe66d8bc04 Fixed SchemaTool which was failing to dropSchema due to foreignKeyContraint checks. Fixes DDC-1126 2011-04-26 12:32:04 -03:00
Guilherme Blanco
26bd3e3811 Implemented support for closure return on EntityManager::transactional. Fixes DDC-1125 2011-04-25 18:32:43 -03:00
Rafael Dohms
0b7feb359d Fixing outdated docblocks for SchemaTool 2011-04-17 23:39:59 -03:00
Michael Ridgway
af4cf0d0ba Replaced prefix parameter with renamedColumns; Added exception when duplicate columns found 2011-04-14 20:55:03 -04:00
Guilherme Blanco
4d561651a1 Merge branch 'master' of github.com:doctrine/doctrine2 2011-04-13 00:11:08 -03:00
Benjamin Eberlei
7e3265e7c7 Merge branch 'DDC-1040' 2011-04-03 23:06:15 +02:00
Benjamin Eberlei
822481d360 [DDC-1040] Add regression tests for entity as multiple named/positional parameters. 2011-04-03 23:06:03 +02:00
Benjamin Eberlei
7905f2a972 [DDC-1040] Bugfix with named parameters and multiple entities passed as parameter. 2011-04-03 23:03:39 +02:00
Benjamin Eberlei
88dc18f88a Merge branch 'DDC-1093' 2011-04-03 20:29:15 +02:00
Benjamin Eberlei
e685d59604 [DDC-1093] Fix docblock type hint 2011-04-03 20:29:07 +02:00
Benjamin Eberlei
300df03743 Merge branch 'DDC-1087' 2011-04-03 09:05:20 +02:00
Benjamin Eberlei
a329007526 [DDC-1087] Add missing resolution to IS NULL in EntityRepository when passing a null value as a criteria. 2011-04-03 09:03:43 +02:00
Chekote
5784c7bacd Fixed phpdoc on Parser::match incorrectly stating that the token parameter can be a string value 2011-04-01 12:54:12 -05:00
Benjamin Eberlei
db82ef3e61 Merge branch 'DDC-991' 2011-03-31 23:35:12 +02:00
Benjamin Eberlei
ea52b3cc8f [DDC-991] Rename method to AbstractQuery::getOneOrNullResult(). 2011-03-31 23:35:01 +02:00
Benjamin Eberlei
24a7a72f59 [DDC-991] add AbstractQuery::getOneResult() method that returns null instead of throwing an exception as getSingleResult() does. 2011-03-31 23:32:49 +02:00
Michael Ridgway
b1b17376ff Removing left over class import 2011-03-31 17:22:13 -04:00
Michael Ridgway
c46d835146 Moved new functions to ResultSetMappingBuilder class 2011-03-30 10:27:31 -04:00
Michael Ridgway
20dc72ef9a First pass on RSM helper functions for adding entities 2011-03-29 20:35:01 -04:00
Benjamin Eberlei
e9c4f612cf Merge branch 'DDC-692' 2011-03-29 20:17:56 +02:00
Benjamin Eberlei
34ad308599 [DDC-692] Add respective metadata mapping possiblities for read-only entities and a test. 2011-03-29 20:17:44 +02:00
Benjamin Eberlei
9a75277dd4 [DDC-692] Add ClassMetadataInfo::isReadOnly flag and ignore these entities in Change Tracking. 2011-03-29 20:04:14 +02:00
Benjamin Eberlei
003ab06465 Merge branch 'DDC-696' 2011-03-29 19:43:41 +02:00
Benjamin Eberlei
36985ee704 Merge remote branch 'mridgway/DDC-696' into DDC-696 2011-03-29 19:42:38 +02:00
Benjamin Eberlei
21acb67b01 Merge branch 'DDC-1077' 2011-03-27 21:11:30 +02:00
Benjamin Eberlei
bda15231da [DDC-1077] Bugfix in not handling literals in Select Expressions. 2011-03-27 21:10:50 +02:00
Benjamin Eberlei
5022b04ff9 Merge branch 'DDC-1079' 2011-03-27 14:05:08 +02:00
Benjamin Eberlei
6ed0ff0a12 [DDC-1079] Bugfix for shortcut for ArithmeticExpressions in SimpleSelectExpression that lead to literals not being valid. Problem was that ScalarExpression() did not handle AggregateExpressions() at all, which is now fixed. 2011-03-27 14:04:53 +02:00
Benjamin Eberlei
789739f3e4 Merge branch 'DDC-1014' 2011-03-27 12:19:31 +02:00
Benjamin Eberlei
4f1af0114f [DDC-1014] Add DATE_ADD(), DATE_SUB(), DATE_DIFF() functions for DQL. 2011-03-27 12:18:47 +02:00
Benjamin Eberlei
5d1b4f98de [DDC-1014] Update DBAL remote to include date arithmetics related functionality. 2011-03-27 11:34:14 +02:00
Michael Ridgway
706cc838e5 Removed svn variable 2011-03-22 08:54:33 -04:00
Michael Ridgway
17cbb34952 Clean up of test case 2011-03-21 23:30:10 -04:00
Michael Ridgway
1f50dee8a8 DDC-696: Added onClear event 2011-03-21 23:17:08 -04:00
Benjamin Eberlei
e126315c1b Bump DBAL dependency to include Security Fix for AbstractPlatform::modifyLimitQuery() 2011-03-21 23:54:40 +01:00
Benjamin Eberlei
ccb5c57784 Merge branch 'DDC-992' 2011-03-20 17:07:31 +01:00
Benjamin Eberlei
7a41a205ee [DDC-992] Fix criteria usage of column names clashing with field or associations by prefixing with table names or alias. 2011-03-20 17:07:19 +01:00
Benjamin Eberlei
8430aefe21 Merge branch 'DDC-1053' 2011-03-20 14:07:44 +01:00
Benjamin Eberlei
edfdbe10a0 [DDC-1053] Fix bug with usage of identification variables in GroupByItem. 2011-03-20 14:07:33 +01:00
Benjamin Eberlei
108ceae313 Merge branch 'DDC-1052' 2011-03-20 13:07:55 +01:00
Benjamin Eberlei
e42a227a7c [DDC-1052] Fix bug with versioning and inheritance 2011-03-20 13:07:47 +01:00
Benjamin Eberlei
7e262dd42c Merge branch 'DDC-1068' 2011-03-20 12:36:03 +01:00
Benjamin Eberlei
ac175d2c40 [DDC-1068] Fix case-sensitivity problems of first loading of Metadata. 2011-03-20 12:35:52 +01:00
Benjamin Eberlei
c77dbd859b [DDC-1070] Fix global test state problem introduced with test. 2011-03-20 12:25:27 +01:00
Benjamin Eberlei
efe26d00a1 Merge branch 'DDC-1070' 2011-03-20 12:19:12 +01:00
Benjamin Eberlei
62755cc647 [DDC-1070] Fix in AbstractQuery::iterate() method not respecting hydrator and parameters. 2011-03-20 12:19:01 +01:00
Guilherme Blanco
8c8a658dfd Merge branch 'master' of github.com:doctrine/doctrine2 2011-03-19 14:36:29 -03:00
Benjamin Eberlei
53ca54ced6 Merge branch 'master' of github.com:doctrine/doctrine2 2011-03-16 23:01:17 +01:00
Benjamin Eberlei
e757e3beaf Merge branch 'DDC-952' 2011-03-16 23:00:57 +01:00
Benjamin Eberlei
5192306d39 [DDC-952] One last commit with some refactorings, additional comments and two new tests. Also added convenience method Query::setFetchMode($className, $assocName) 2011-03-16 22:51:32 +01:00
Benjamin Eberlei
4b98e3ea8e DDC-952 - Remove unnecessary instance variable and comment on one feature. 2011-03-16 00:03:43 +01:00
Benjamin Eberlei
b7e522d7a7 DDC-952 - This nasty inheritance hydration bug slipped in again, fixed again now. 2011-03-15 23:39:19 +01:00
Benjamin Eberlei
6d27b4760f [DDC-952] Add Persister hydration performance tests. 2011-03-15 23:22:37 +01:00
Benjamin Eberlei
1b46208aa5 [DDC-952] More fixes 2011-03-15 21:34:47 +01:00
Benjamin Eberlei
b3c01903b4 DDC-952 - Optimization 2011-03-15 20:03:05 +01:00
Benjamin Eberlei
a04ba44874 [DDC-952] Introduced SimpleObjectHydrator again for performance reasons. 2011-03-15 19:48:04 +01:00
brikou
9a8e8ce35d Edited lib/Doctrine/ORM/Tools/EntityGenerator.php via GitHub 2011-03-15 05:39:38 -07:00
Albert Jessurum
234d2e5f0f Fix typo on schema help messages 2011-03-15 12:22:53 +01:00
Guilherme Blanco
180078d0f6 Added namedQueries as optional during serialization of ClassMetadata. 2011-03-14 01:04:50 -03:00
Benjamin Eberlei
38ad25ad4c [DDC-952] Remove all the unnecessary hydration code from all Persisters. 2011-03-13 00:23:46 +01:00
Benjamin Eberlei
1bc4b62805 [DDC-952] Make collection loading work with hydrators also. 2011-03-13 00:15:50 +01:00
Benjamin Eberlei
7c7106b1c1 DDC-952 - Fix bug in inverse one-to-one eager loading sql code. 2011-03-12 19:11:37 +01:00
Benjamin Eberlei
4677883acd [DDC-952] Added modelset and tests for Eager Loading, detected a bug with inverse one-to-one eager fetching that needs to be addressed. 2011-03-12 14:01:51 +01:00
Benjamin Eberlei
8794d35867 DDC-952 - Woah this still needs tons of tests. 2011-03-09 23:30:35 +01:00
Benjamin Eberlei
595c19207c [DDC-914] Always fetch joining inverse side one-to-one associations breaks a ton of DDC-117 tests, investigate why to make this working also. 2011-03-09 23:21:33 +01:00
Benjamin Eberlei
077ae9cee9 [DDC-914] Fetch join many-to-one/one-to-one associations configured as FETCH_EAGER inside the persisters. 2011-03-09 23:14:54 +01:00
Guilherme Blanco
925f1c281c Merge branch 'NamedQueries' 2011-03-09 14:44:56 -03:00
Guilherme Blanco
7d1fca1ca2 Added support to NamedQueries through ClassMetadata. 2011-03-09 14:43:42 -03:00
Benjamin Eberlei
fd502631c7 DDC-734 - REname query hint to fetchEager. 2011-03-08 22:28:55 +01:00
Benjamin Eberlei
60eb755fe9 DDC-952, DDC-734 Add DQL query hint to switch associations from lazy to eager for deferred initialization optimizations. 2011-03-08 22:22:54 +01:00
Guilherme Blanco
a31289b9d7 Added support to NamedQueries through ClassMetadata. 2011-03-06 18:45:09 -03:00
Benjamin Eberlei
112f9d1480 [DDC-1050] Change refresh of collection back 2011-03-06 21:49:02 +01:00
Benjamin Eberlei
851f44a066 [DDC-952] [DDC-1050] Use ObjectHydrator inside Persisters, removing a bunch of duplicate code (step1, more necessary) 2011-03-06 21:26:54 +01:00
Benjamin Eberlei
d9c8a9eecb [DDC-952] Fix merge/rebase mistake. 2011-03-06 15:28:26 +01:00
Benjamin Eberlei
03630df20d Add support for IN(?) queries in repositories using the DBAL support for parameter lists. 2011-03-06 11:15:56 +01:00
Benjamin Eberlei
3d37e436dd DDC-952 - Refactor eager loading entities, it is only allowed for non composite primary key entities. 2011-03-05 11:09:38 +01:00
Benjamin Eberlei
32df9451fd DDC-952 - Implemented first approach for batching eager loads of ToOne associations. 2011-03-05 11:08:41 +01:00
Benjamin Eberlei
e0b835178b Bump dependency of ORM master to DBAL 2.0.2 2011-03-05 10:09:16 +01:00
Benjamin Eberlei
78aa893efd Adjust tests to changes in DBAL dependency with regard to automatic foreign key and index naming. 2011-03-05 10:08:30 +01:00
Benjamin Eberlei
8c7261e7c3 Optimize build process even more, now generating PEAR Packages for Symfony YAML and Console. 2011-03-05 00:18:10 +01:00
Benjamin Eberlei
ae61272c13 Merge branch 'DDC-1034' 2011-03-04 23:01:02 +01:00
Benjamin Eberlei
67ae22b911 DDC-1034 - Fix bug where callbacks where registered multiple times in inheritance hierachies. 2011-03-04 23:00:54 +01:00
Benjamin Eberlei
c0d26f2308 Merge branch 'DDC-1056' 2011-03-04 22:22:19 +01:00
Benjamin Eberlei
d58ae2ecda DDC-1056 - Fixed notice in StaticPHPDriver. 2011-03-04 22:22:07 +01:00
Benjamin Eberlei
1d5fef4144 Merge branch 'DDC-1041' 2011-03-03 23:11:24 +01:00
Benjamin Eberlei
49195ebe17 [DDC-1041] You could retrieve instances of the wrong type in inheritance hierachies because the identity map aggregates them by rootEntityName. 2011-03-03 23:11:09 +01:00
Benjamin Eberlei
9a33bd083d Merge branch 'DDC-1050' 2011-03-03 22:52:13 +01:00
Benjamin Eberlei
b2c7a9c7fc [DDC-1050] Throw exception when trying to define inheritance information on a mapped superclass. It is not a valid use-case. 2011-03-03 22:51:53 +01:00
Benjamin Eberlei
8b9f12d924 Remove copied code of Symfony Console/Yaml and added submodules. 2011-02-28 21:51:56 +01:00
Benjamin Eberlei
521705a0f2 Merge branch 'DDC-1033' 2011-02-26 12:48:10 +01:00
Benjamin Eberlei
c144df9be3 DDC-1033 - Fix cloning of not initialized proxies. 2011-02-26 12:47:59 +01:00
Benjamin Eberlei
1eb7f92956 DDC-1026 - Fix Result Cache Seperate chaining implementation that was wrong since DDC-892 was applied. 2011-02-26 00:39:54 +01:00
Romain Pouclet
9125413786 Fixed typo in AbstractQuery::execute() doc 2011-02-25 10:22:50 -06:00
Benjamin Eberlei
afc9495b3f Revert "Merge branch 'DDC-884'"
This reverts commit 3eea19dcfa, reversing
changes made to b13c29944b.
2011-02-21 18:52:49 +01:00
Guilherme Blanco
3eea19dcfa Merge branch 'DDC-884' 2011-02-21 00:51:00 -03:00
Guilherme Blanco
04ab0cd8fc [DDC-884] Allow subclassing EntityManager. 2011-02-21 00:50:51 -03:00
Guilherme Blanco
b13c29944b Merge branch 'DDC-1035' 2011-02-21 00:38:03 -03:00
Guilherme Blanco
68bb0c1ae1 [DDC-1035] Fixed orphanRemoval on YAML mapping driver. 2011-02-21 00:37:32 -03:00
Guilherme Blanco
a18a7bb678 Merge branch 'DDC-1012' 2011-02-20 01:54:05 -03:00
Guilherme Blanco
834203d868 [DDC-1012] Implemented Expr isNull and isNotNull. 2011-02-20 01:53:55 -03:00
Guilherme Blanco
99c7924292 Merge branch 'DDC-1036' 2011-02-20 01:44:27 -03:00
Guilherme Blanco
505d9e2154 [DDC-1036] Modified the AggregateExpressions to support SimpleArithmeticExpression instead of StateFieldPathExpression. 2011-02-20 01:44:05 -03:00
Guilherme Blanco
bca927f861 Merge branch 'DDC-982' 2011-02-20 01:31:12 -03:00
Guilherme Blanco
70d2cbe857 [DDC-982] Implemented more unique sql table alias. 2011-02-20 01:30:58 -03:00
Guilherme Blanco
dcf358f154 Fixed some warnings from phpunit. 2011-02-19 19:50:58 -02:00
Guilherme Blanco
2b2d9e7a1d Fixed wrong test. It was failing if you have memcache extension loaded. 2011-02-19 17:20:37 -02:00
Jonathan H. Wage
328a5fe49a Updating to reverted version of common. 2011-02-16 10:25:29 -06:00
Jonathan H. Wage
839b6dd5e4 Revert "Removing old Driver interface in favor of the new one in Common\Persistence. Also changed to use fully qualified class name for interfaces in common to avoid weird aliases."
This reverts commit c988a99d55.
2011-02-16 10:24:42 -06:00
Jonathan H. Wage
c988a99d55 Removing old Driver interface in favor of the new one in Common\Persistence. Also changed to use fully qualified class name for interfaces in common to avoid weird aliases. 2011-02-16 10:06:39 -06:00
Jonathan H. Wage
a4a184b27c Implementing ClassMetadataFactory interface. 2011-02-15 21:00:48 -06:00
Jonathan H. Wage
68a4099684 Implementing initial Doctrine\Common\Persistence interfaces. 2011-02-15 20:02:45 -06:00
Benjamin Eberlei
64088fce5d Merge branch 'DDC-1030' 2011-02-13 10:02:34 +01:00
Benjamin Eberlei
35a152318e DDC-1030 - Fix Static Reflection with namespace levels deeper than one. 2011-02-13 10:02:18 +01:00
Benjamin Eberlei
3d0d31ddf8 Merge branch 'DDC-1024' 2011-02-12 17:40:16 +01:00
Benjamin Eberlei
c456f27f60 DDC-1024 - Do not generate setter/getter for inherited fields. 2011-02-12 17:40:07 +01:00
Benjamin Eberlei
4ecb582c76 Update dependencies to Common 2.0.1 and DBAL 2.0.1 2011-02-05 11:46:35 +01:00
Benjamin Eberlei
7390030854 Merge branch 'DDC-250' 2011-02-05 11:44:00 +01:00
Benjamin Eberlei
da2dee03e2 [DDC-250] Small typo fix in xsd 2011-02-05 11:43:50 +01:00
Benjamin Eberlei
9768d08458 [DDC-250] Add tests and fix some glitches and finalized index-by patch. 2011-02-05 11:42:10 +01:00
Benjamin Eberlei
a9fe9f43e9 Merge branch 'DDC-1018' into DDC-250 2011-02-05 10:04:36 +01:00
Benjamin Eberlei
61e2cdc6b0 [DDC-1018] Bugfix: INDEX BY was not working in JOIN Declarations, only in FROM. 2011-02-05 10:04:18 +01:00
Benjamin Eberlei
60203af9b2 Merge branch 'DDC-1018' 2011-02-05 10:02:48 +01:00
Benjamin Eberlei
4532c2255a [DDC-1018] Bugfix: INDEX BY was not working in JOIN Declarations, only in FROM. 2011-02-05 10:02:37 +01:00
Benjamin Eberlei
17c1ed948e [DDC-250] Initial untested support for @ManyToMany(indexBy) and @OneToMany(indexBy) option. 2011-02-05 09:31:40 +01:00
Benjamin Eberlei
266d85e917 Merge branch 'DDC-1006' 2011-02-02 23:30:39 +01:00
Benjamin Eberlei
4122abf558 DDC-1008, DDC-1002 - Create constructor and id setter if necessary. 2011-02-02 23:30:16 +01:00
Benjamin Eberlei
f9c1464879 DDC-1006, DDC-953 - Fix EntityGenerator creating empty classes 2011-02-02 23:21:42 +01:00
Benjamin Eberlei
277e0aee8c Merge remote branch 'origin/master' 2011-02-02 19:49:23 +01:00
Benjamin Eberlei
957aefe69e Merge branch 'DDC-892' 2011-01-23 20:54:36 +01:00
Benjamin Eberlei
3515df913f DDC-892 - Implement separate chaining approach for result caches to prevent hash colissions. 2011-01-23 20:54:29 +01:00
Benjamin Eberlei
8869678c0f Merge branch 'GenerationTools' 2011-01-23 20:26:37 +01:00
Benjamin Eberlei
05f41278a6 Significantly updated the Help of the ConvertMapping and GenerateEntities Commands to help people using and understanding their scope. Added an additional --force flag to ConvertMapping command. 2011-01-23 20:25:59 +01:00
Benjamin Eberlei
961cb6e9a3 Merge branch 'DDC-958' 2011-01-23 17:26:59 +01:00
Benjamin Eberlei
ed53f8aa74 DDC-958 - Fire postLoad event when calling refresh(). 2011-01-23 17:26:11 +01:00
Benjamin Eberlei
be2e00c991 Merge branch 'DDC-968' 2011-01-23 16:47:20 +01:00
Benjamin Eberlei
f1809ce180 DDC-968 - Add AbstractQuery::getHints() method 2011-01-23 16:47:07 +01:00
Benjamin Eberlei
549965b4b2 Merge branch 'DDC-997' 2011-01-23 16:42:06 +01:00
Benjamin Eberlei
f70ee3a038 DDC-997 - Fix bug in hydration that came up with DDC-117 2011-01-23 16:41:40 +01:00
Benjamin Eberlei
975d6ada66 Merge branch 'DDC-969' 2011-01-23 16:12:36 +01:00
Benjamin Eberlei
a6e63d2676 DDC-969 - Use of field instead of column when accessing a table leads to error when both differ. 2011-01-23 16:12:26 +01:00
Benjamin Eberlei
c5593be7c9 Merge branch 'DDC-978' 2011-01-23 15:40:34 +01:00
Benjamin Eberlei
65bbdc30de DDC-978 - Fix bug where Collection gets cleared (again) when calling flush multiple times and replacing a PersistentCollection with a new one. 2011-01-23 15:40:16 +01:00
Benjamin Eberlei
482ff2d009 Merge branch 'DDC-996' 2011-01-23 14:21:23 +01:00
Benjamin Eberlei
fd44894e9a DDC-996 - Throw more useful exception if fieldName is empty in a mapped field or association. 2011-01-23 14:20:15 +01:00
Benjamin Eberlei
92ed05fc84 Merge branch 'DDC-960' 2011-01-23 12:49:20 +01:00
Benjamin Eberlei
5d333045b9 DDC-960 - Bugfix in how Persisters generate Fetch last version of Entity SQL. 2011-01-23 12:48:28 +01:00
Benjamin Eberlei
bcafa19386 Merge branch 'DDC-975' 2011-01-13 21:43:47 +01:00
Benjamin Eberlei
03698e4068 DDC-975 - Fix notice in SchemaTool in combination with XML mapping driver. 2011-01-13 21:43:33 +01:00
Benjamin Eberlei
fdee7a9ae0 Merge branch 'DDC-980' 2011-01-13 21:16:24 +01:00
Benjamin Eberlei
078e19d1c7 DDC-980 - Fix Update and Delete statements reference of the root table when doing subselects. 2011-01-13 21:16:08 +01:00
Benjamin Eberlei
7a2c99353a Merge branch 'DDC-546' 2011-01-02 15:14:40 +01:00
Benjamin Eberlei
3539b32629 DDC-546 - Found some more code that needs DDC-117 compliance. 2011-01-02 15:14:12 +01:00
Benjamin Eberlei
247fc43cef DDC-546 - Rename ClassMetadataInfo::FETCH_EXTRALAZY to ClassMetadataInfo::FETCH_EXTRA_LAZY 2011-01-02 15:10:47 +01:00
Benjamin Eberlei
a3cab174ca DDC-546 - Updated with support for DDC-117. 2011-01-02 14:04:52 +01:00
Benjamin Eberlei
89e7e8623c DDC-546 - Remove dynamic public property approach in PersistentCollection::count() EXTRA_LAZY. 2011-01-02 13:43:49 +01:00
Benjamin Eberlei
cbfdf61976 DDC-546 - Bugfix for PersistentCollection::count() in EXTRA LAZY special case. 2011-01-02 13:41:18 +01:00
Benjamin Eberlei
3acc05d953 DDC-546 - Fix bug in inverse many-to-many contains. 2011-01-02 13:37:29 +01:00
Benjamin Eberlei
685e327b43 DDC-546 - Fix some rebasing issues. 2011-01-02 12:54:55 +01:00
Benjamin Eberlei
f572be92e2 DDC-546 - Add EXTRALAZY to doctrine-mapping.xsd enumeration of fetch-types. 2011-01-02 12:46:08 +01:00
Benjamin Eberlei
75d59d8695 DDC-546 - Added functionality for extra-lazy PersistentCollection::contains(). 2011-01-02 12:46:08 +01:00
Benjamin Eberlei
7c567b305a Refactor DDC-546 persister approach. 2011-01-02 12:46:08 +01:00
Benjamin Eberlei
d3d9957fd4 DDC-546 - Fix some minor glitches in patch. 2011-01-02 12:44:16 +01:00
Benjamin Eberlei
c998797c55 DDC-546 - Add Extra Lazy Collection prototype. 2011-01-02 12:44:16 +01:00
Benjamin Eberlei
78d4277e4b Merge branch DDC-117 into master 2011-01-02 12:01:05 +01:00
Benjamin Eberlei
f3abf9a30a Merge branch 'DDC-965' 2011-01-02 10:24:38 +01:00
Benjamin Eberlei
9177dc3d52 DDC-965 - Defer ID check after loadMetata event is fired. 2011-01-02 10:24:23 +01:00
Benjamin Eberlei
34b303845f Merge branch 'DDC-966' 2011-01-02 10:18:23 +01:00
Benjamin Eberlei
c1edd5848f DDC-966 - Fix NOT NULL constraint SingleTableInheritance Generation using SchemaTool. 2011-01-02 10:18:02 +01:00
Benjamin Eberlei
ed7ec261d0 Merge branch 'DDC-949' 2011-01-02 09:42:15 +01:00
Benjamin Eberlei
a2cc9f0f6d DDC-949 - Bugfix for BasicEntityPersister not using $types for select clauses. This fixes the issue for PostgreSQL however it still occurs on Oracle. DBAL change is necessary for this. 2011-01-02 09:38:32 +01:00
Benjamin Eberlei
2a005019bf DDC-117 - Add XML and YML Driver support for associated identifier. 2011-01-01 21:47:04 +01:00
Benjamin Eberlei
c2bbaa9ead DDC-117 - Slight changes in the patch and fixing inline comments. 2011-01-01 18:53:22 +01:00
Benjamin Eberlei
194a90923d DDC-117 - Finalize patch, fix all the problems of different use-cases by hugely expanding the test-model. 2011-01-01 18:17:19 +01:00
Benjamin Eberlei
e1ed0bf52a Merge branch 'DDC-945-2' 2010-12-31 14:39:13 +01:00
Benjamin Eberlei
7112b551e2 DDC-945 - Fix regression, ManyToMany unidirectional owning side assocations should be allowed. 2010-12-31 14:39:01 +01:00
Benjamin Eberlei
3498f4d6ee Merge branch 'DDC-929' 2010-12-30 23:18:14 +01:00
Benjamin Eberlei
8658376713 DDC-929 - Fix bug with DatabaseDriver not detecting indexes that are not called primary. 2010-12-30 23:18:00 +01:00
Benjamin Eberlei
7a40e3f6f2 Merge branch 'DDC-961' 2010-12-30 22:30:59 +01:00
Benjamin Eberlei
58019fbac0 DDC-961 - Bugfix with missing first letter in automatic join table names in global namespace entities. 2010-12-30 22:30:51 +01:00
Benjamin Eberlei
2d27a99a0b DDC-117 - Began to fix some issues surrounding the DDC-881 report and references to composite fk entities. 2010-12-29 01:02:21 +01:00
Benjamin Eberlei
337e2fa043 Fix DDC-795 (subtask of DDC-117) and integrated a test for cascade (that only works with sequence id generators). 2010-12-28 19:05:46 +01:00
Benjamin Eberlei
e7b4dca611 Merge master into DDC-117 2010-12-28 17:27:47 +01:00
Benjamin Eberlei
1d5b24ecc5 Merge branch 'DDC-837' 2010-12-28 14:56:24 +01:00
Benjamin Eberlei
2d89ddfb1f DDC-837 - Fix bug with associations of the same name not being possible in inheritance hierachies. 2010-12-28 14:56:13 +01:00
Benjamin Eberlei
eeca184836 Merge branch 'DDC-928' 2010-12-28 12:19:16 +01:00
Benjamin Eberlei
1d2b2b2c8b DDC-928 - Fix undefined variable notice. 2010-12-28 12:18:42 +01:00
Benjamin Eberlei
26bb7978b5 Merge branch 'DDC-945' 2010-12-28 12:00:07 +01:00
Benjamin Eberlei
aa6ac3d6b0 DDC-945 - Throw exception in ClassMetadataFactory when mapped superclass has to many associations. 2010-12-28 11:59:51 +01:00
Benjamin Eberlei
1720527f81 Merge branch 'DDC-617' 2010-12-28 10:17:53 +01:00
Benjamin Eberlei
fe672d2f61 DDC-617 - Throw error if selecting identification variables without picking at least one root entity alias. 2010-12-28 10:17:33 +01:00
Benjamin Eberlei
d488e84d8d Merge branch 'DDC-931' 2010-12-22 22:06:02 +01:00
Benjamin Eberlei
a4f88407c2 DDC-931 - SchemaTool#dropSchema() should not stop on failure of a single query (as stated in docblocks). 2010-12-22 22:04:11 +01:00
Benjamin Eberlei
e46c65db09 Fix for DDC-944 2010-12-22 00:23:22 +01:00
Benjamin Eberlei
6988b55f50 Bump Dev Version to 2.1.0-DEV 2010-12-21 16:45:50 -05:00
Amal Raghav
b736c4216c _generateEntityLifecycleCallbackMethods Beautification 2010-12-17 16:51:51 +05:30
Benjamin Eberlei
5bd8ffa53c Merge master into DDC-117 2010-08-27 22:27:00 +02:00
Benjamin Eberlei
1496250833 Merge branch 'master' into DDC-117 2010-08-15 20:17:56 +02:00
Benjamin Eberlei
772e592489 Try Assoc-Id Mapping with Id that has its column renamed. 2010-08-15 19:15:34 +02:00
Benjamin Eberlei
fb44fa6b5a Fix hydration of Assoc-Id Entities, duplicate the hydration of the foreign key once for for use with the assoc-entity as a meta-column. Added isIdentifier capabilities to meta columns. 2010-08-15 18:58:25 +02:00
Benjamin Eberlei
5799e391c6 Fix bug with updating assoc-id entities 2010-08-15 14:40:06 +02:00
Benjamin Eberlei
e45c52b024 Merge Removal of association classes into DDC-117 branch, quite some merge efforts necessary to get it working again 2010-08-13 23:23:11 +02:00
Benjamin Eberlei
db936035e0 Added more tests for DQL joining the primary key entity and querying other fields 2010-08-08 19:46:45 +02:00
Benjamin Eberlei
7b07a17886 Merge branch 'master' into DDC-117 2010-08-08 14:07:24 +02:00
Benjamin Eberlei
e3a4c8ddeb Refactored TestCase and added several more use-cases 2010-08-08 10:46:01 +02:00
Benjamin Eberlei
013262a9b7 Add support for EntityManager::remove() of full or partial association primary keys 2010-08-07 21:09:19 +02:00
Benjamin Eberlei
10f47389ae Made single identifier One-To-One + Id work also and added a test-case 2010-08-07 20:07:10 +02:00
Benjamin Eberlei
c697a2d47f Prototype hack of @ManyToOne + @Id support with two test-scenarios, composite association key only composite key, and a mixed key scenario. I think single foreign association would work also 2010-08-07 19:33:54 +02:00
707 changed files with 50555 additions and 11649 deletions

4
.gitignore vendored
View File

@@ -1,4 +1,3 @@
build.properties
build/
logs/
reports/
@@ -7,3 +6,6 @@ download/
lib/api/
lib/Doctrine/Common
lib/Doctrine/DBAL
/.settings/
.buildpath
.project

9
.gitmodules vendored
View File

@@ -4,9 +4,12 @@
[submodule "lib/vendor/doctrine-dbal"]
path = lib/vendor/doctrine-dbal
url = git://github.com/doctrine/dbal.git
[submodule "lib/vendor/Symfony/Component/Yaml"]
path = lib/vendor/Symfony/Component/Yaml
url = git://github.com/symfony/Yaml.git
[submodule "lib/vendor/Symfony/Component/Console"]
path = lib/vendor/Symfony/Component/Console
url = git://github.com/symfony/Console.git
[submodule "lib/vendor/Symfony/Component/Yaml"]
path = lib/vendor/Symfony/Component/Yaml
url = git://github.com/symfony/Yaml.git
[submodule "lib/vendor/doctrine-build-common"]
path = lib/vendor/doctrine-build-common
url = git://github.com/doctrine/doctrine-build-common.git

19
.travis.yml Normal file
View File

@@ -0,0 +1,19 @@
language: php
php:
- 5.3
- 5.4
env:
- DB=mysql
- DB=pgsql
- DB=sqlite
before_script:
- sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'DROP DATABASE IF EXISTS doctrine_tests;' -U postgres; fi"
- sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'DROP DATABASE IF EXISTS doctrine_tests_tmp;' -U postgres; fi"
- sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'create database doctrine_tests;' -U postgres; fi"
- sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'create database doctrine_tests_tmp;' -U postgres; fi"
- sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'create database IF NOT EXISTS doctrine_tests_tmp;create database IF NOT EXISTS doctrine_tests;'; fi"
- git submodule update --init
script: phpunit --configuration tests/travis/$DB.travis.xml

523
LICENSE
View File

@@ -1,504 +1,19 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!
Copyright (c) 2006-2012 Doctrine Project
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,14 +1,19 @@
# Doctrine 2 ORM
Doctrine 2 is an object-relational mapper (ORM) for PHP 5.3.0+ that provides transparent persistence
Master: [![Build Status](https://secure.travis-ci.org/doctrine/doctrine2.png?branch=master)](http://travis-ci.org/doctrine/doctrine2)
2.2: [![Build Status](https://secure.travis-ci.org/doctrine/doctrine2.png?branch=2.2)](http://travis-ci.org/doctrine/doctrine2)
2.1: [![Build Status](https://secure.travis-ci.org/doctrine/doctrine2.png?branch=2.1.x)](http://travis-ci.org/doctrine/doctrine2)
Doctrine 2 is an object-relational mapper (ORM) for PHP 5.3.2+ that provides transparent persistence
for PHP objects. It sits on top of a powerful database abstraction layer (DBAL). One of its key features
is the option to write database queries in a proprietary object oriented SQL dialect called Doctrine Query Language (DQL),
inspired by Hibernates HQL. This provides developers with a powerful alternative to SQL that maintains flexibility
without requiring unnecessary code duplication.
More resources:
## More resources:
* [Website](http://www.doctrine-project.org)
* [Documentation](http://www.doctrine-project.org/projects/orm/2.0/docs/reference/introduction/en)
* [Documentation](http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/index.html)
* [Issue Tracker](http://www.doctrine-project.org/jira/browse/DDC)
* [Downloads](http://github.com/doctrine/doctrine2/downloads)
* [Downloads](http://github.com/doctrine/doctrine2/downloads)

475
UPGRADE.md Normal file
View File

@@ -0,0 +1,475 @@
# 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
use the Type-Hint to get the singular for the collection name, but use the field-name
and strip a trailing "s" character if there is one.
## Merge copies non persisted properties too
When merging an entity in UoW not only mapped properties are copied, but also others.
## Query, QueryBuilder and NativeQuery parameters *BC break*
From now on, parameters in queries is an ArrayCollection instead of a simple array.
This affects heavily the usage of setParameters(), because it will not append anymore
parameters to query, but will actually override the already defined ones.
Whenever you are retrieving a parameter (ie. $query->getParameter(1)), you will
receive an instance of Query\Parameter, which contains the methods "getName",
"getValue" and "getType". Parameters are also only converted to when necessary, and
not when they are set.
Also, related functions were affected:
* execute($parameters, $hydrationMode) the argument $parameters can be either an key=>value array or an ArrayCollection instance
* iterate($parameters, $hydrationMode) the argument $parameters can be either an key=>value array or an ArrayCollection instance
* setParameters($parameters) the argument $parameters can be either an key=>value array or an ArrayCollection instance
* getParameters() now returns ArrayCollection instead of array
* getParameter($key) now returns Parameter instance instead of parameter value
## Query TreeWalker method renamed
Internal changes were made to DQL and SQL generation. If you have implemented your own TreeWalker,
you probably need to update it. The method walkJoinVariableDeclaration is now named walkJoin.
## Metadata Drivers
Metadata drivers have been rewritten to reuse code from Doctrine\Common. Anyone who is using the
`Doctrine\ORM\Mapping\Driver\Driver` interface should instead refer to
`Doctrine\Common\Persistence\Mapping\Driver\MappingDriver`. Same applies to
`Doctrine\ORM\Mapping\Driver\AbstractFileDriver`: you should now refer to
`Doctrine\Common\Persistence\Mapping\Driver\FileDriver`.
Also, following mapping drivers have been deprecated, please use their replacements in Doctrine\Common as listed:
* `Doctrine\ORM\Mapping\Driver\DriverChain` => `Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain`
* `Doctrine\ORM\Mapping\Driver\PHPDriver` => `Doctrine\Common\Persistence\Mapping\Driver\PHPDriver`
* `Doctrine\ORM\Mapping\Driver\StaticPHPDriver` => `Doctrine\Common\Persistence\Mapping\Driver\StaticPHPDriver`
# Upgrade to 2.2
## ResultCache implementation rewritten
The result cache is completely rewritten and now works on the database result level, not inside the ORM AbstractQuery
anymore. This means that for result cached queries the hydration will now always be performed again, regardless of
the hydration mode. Affected areas are:
1. Fixes the problem that entities coming from the result cache were not registered in the UnitOfWork
leading to problems during EntityManager#flush. Calls to EntityManager#merge are not necessary anymore.
2. Affects the array hydrator which now includes the overhead of hydration compared to caching the final result.
The API is backwards compatible however most of the getter methods on the `AbstractQuery` object are now
deprecated in favor of calling AbstractQuery#getQueryCacheProfile(). This method returns a `Doctrine\DBAL\Cache\QueryCacheProfile`
instance with access to result cache driver, lifetime and cache key.
## EntityManager#getPartialReference() creates read-only entity
Entities returned from EntityManager#getPartialReference() are now marked as read-only if they
haven't been in the identity map before. This means objects of this kind never lead to changes
in the UnitOfWork.
## Fields omitted in a partial DQL query or a native query are never updated
Fields of an entity that are not returned from a partial DQL Query or native SQL query
will never be updated through an UPDATE statement.
## Removed support for onUpdate in @JoinColumn
The onUpdate foreign key handling makes absolutely no sense in an ORM. Additionally Oracle doesn't even support it. Support for it is removed.
## Changes in Annotation Handling
There have been some changes to the annotation handling in Common 2.2 again, that affect how people with old configurations
from 2.0 have to configure the annotation driver if they don't use `Configuration::newDefaultAnnotationDriver()`:
// Register the ORM Annotations in the AnnotationRegistry
AnnotationRegistry::registerFile('path/to/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php');
$reader = new \Doctrine\Common\Annotations\SimpleAnnotationReader();
$reader->addNamespace('Doctrine\ORM\Mapping');
$reader = new \Doctrine\Common\Annotations\CachedReader($reader, new ArrayCache());
$driver = new AnnotationDriver($reader, (array)$paths);
$config->setMetadataDriverImpl($driver);
## Scalar mappings can now be ommitted from DQL result
You are now allowed to mark scalar SELECT expressions as HIDDEN an they are not hydrated anymore.
Example:
SELECT u, SUM(a.id) AS HIDDEN numArticles FROM User u LEFT JOIN u.Articles a ORDER BY numArticles DESC HAVING numArticles > 10
Your result will be a collection of Users, and not an array with key 0 as User object instance and "numArticles" as the number of articles per user
## Map entities as scalars in DQL result
When hydrating to array or even a mixed result in object hydrator, previously you had the 0 index holding you entity instance.
You are now allowed to alias this, providing more flexibility for you code.
Example:
SELECT u AS user FROM User u
Will now return a collection of arrays with index "user" pointing to the User object instance.
## Performance optimizations
Thousands of lines were completely reviewed and optimized for best performance.
Removed redundancy and improved code readability made now internal Doctrine code easier to understand.
Also, Doctrine 2.2 now is around 10-15% faster than 2.1.
## EntityManager#find(null)
Previously EntityManager#find(null) returned null. It now throws an exception.
# Upgrade to 2.1
## Interface for EntityRepository
The EntityRepository now has an interface Doctrine\Common\Persistence\ObjectRepository. This means that your classes that override EntityRepository and extend find(), findOneBy() or findBy() must be adjusted to follow this interface.
## AnnotationReader changes
The annotation reader was heavily refactored between 2.0 and 2.1-RC1. In theory the operation of the new reader should be backwards compatible, but it has to be setup differently to work that way:
// new call to the AnnotationRegistry
\Doctrine\Common\Annotations\AnnotationRegistry::registerFile('/doctrine-src/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php');
$reader = new \Doctrine\Common\Annotations\AnnotationReader();
$reader->setDefaultAnnotationNamespace('Doctrine\ORM\Mapping\\');
// new code necessary starting here
$reader->setIgnoreNotImportedAnnotations(true);
$reader->setEnableParsePhpImports(false);
$reader = new \Doctrine\Common\Annotations\CachedReader(
new \Doctrine\Common\Annotations\IndexedReader($reader), new ArrayCache()
);
This is already done inside the ``$config->newDefaultAnnotationDriver``, so everything should automatically work if you are using this method. You can verify if everything still works by executing a console command such as schema-validate that loads all metadata into memory.
# Update from 2.0-BETA3 to 2.0-BETA4
## XML Driver <change-tracking-policy /> element demoted to attribute
We changed how the XML Driver allows to define the change-tracking-policy. The working case is now:
<entity change-tracking-policy="DEFERRED_IMPLICT" />
# Update from 2.0-BETA2 to 2.0-BETA3
## Serialization of Uninitialized Proxies
As of Beta3 you can now serialize uninitialized proxies, an exception will only be thrown when
trying to access methods on the unserialized proxy as long as it has not been re-attached to the
EntityManager using `EntityManager#merge()`. See this example:
$proxy = $em->getReference('User', 1);
$serializedProxy = serialize($proxy);
$detachedProxy = unserialized($serializedProxy);
echo $em->contains($detachedProxy); // FALSE
try {
$detachedProxy->getId(); // uninitialized detached proxy
} catch(Exception $e) {
}
$attachedProxy = $em->merge($detachedProxy);
echo $attackedProxy->getId(); // works!
## Changed SQL implementation of Postgres and Oracle DateTime types
The DBAL Type "datetime" included the Timezone Offset in both Postgres and Oracle. As of this version they are now
generated without Timezone (TIMESTAMP WITHOUT TIME ZONE instead of TIMESTAMP WITH TIME ZONE).
See [this comment to Ticket DBAL-22](http://www.doctrine-project.org/jira/browse/DBAL-22?focusedCommentId=13396&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#action_13396)
for more details as well as migration issues for PostgreSQL and Oracle.
Both Postgres and Oracle will throw Exceptions during hydration of Objects with "DateTime" fields unless migration steps are taken!
## Removed multi-dot/deep-path expressions in DQL
The support for implicit joins in DQL through the multi-dot/Deep Path Expressions
was dropped. For example:
SELECT u FROM User u WHERE u.group.name = ?1
See the "u.group.id" here is using multi dots (deep expression) to walk
through the graph of objects and properties. Internally the DQL parser
would rewrite these queries to:
SELECT u FROM User u JOIN u.group g WHERE g.name = ?1
This explicit notation will be the only supported notation as of now. The internal
handling of multi-dots in the DQL Parser was very complex, error prone in edge cases
and required special treatment for several features we added. Additionally
it had edge cases that could not be solved without making the DQL Parser
even much more complex. For this reason we will drop the support for the
deep path expressions to increase maintainability and overall performance
of the DQL parsing process. This will benefit any DQL query being parsed,
even those not using deep path expressions.
Note that the generated SQL of both notations is exactly the same! You
don't loose anything through this.
## Default Allocation Size for Sequences
The default allocation size for sequences has been changed from 10 to 1. This step was made
to not cause confusion with users and also because it is partly some kind of premature optimization.
# Update from 2.0-BETA1 to 2.0-BETA2
There are no backwards incompatible changes in this release.
# Upgrade from 2.0-ALPHA4 to 2.0-BETA1
## EntityRepository deprecates access to protected variables
Instead of accessing protected variables for the EntityManager in
a custom EntityRepository it is now required to use the getter methods
for all the three instance variables:
* `$this->_em` now accessible through `$this->getEntityManager()`
* `$this->_class` now accessible through `$this->getClassMetadata()`
* `$this->_entityName` now accessible through `$this->getEntityName()`
Important: For Beta 2 the protected visibility of these three properties will be
changed to private!
## Console migrated to Symfony Console
The Doctrine CLI has been replaced by Symfony Console Configuration
Instead of having to specify:
[php]
$cliConfig = new CliConfiguration();
$cliConfig->setAttribute('em', $entityManager);
You now have to configure the script like:
[php]
$helperSet = new \Symfony\Components\Console\Helper\HelperSet(array(
'db' => new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($em->getConnection()),
'em' => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($em)
));
## Console: No need for Mapping Paths anymore
In previous versions you had to specify the --from and --from-path options
to show where your mapping paths are from the console. However this information
is already known from the Mapping Driver configuration, so the requirement
for this options were dropped.
Instead for each console command all the entities are loaded and to
restrict the operation to one or more sub-groups you can use the --filter flag.
## AnnotationDriver is not a default mapping driver anymore
In conjunction with the recent changes to Console we realized that the
annotations driver being a default metadata driver lead to lots of glue
code in the console components to detect where entities lie and how to load
them for batch updates like SchemaTool and other commands. However the
annotations driver being a default driver does not really help that much
anyways.
Therefore we decided to break backwards compability in this issue and drop
the support for Annotations as Default Driver and require our users to
specify the driver explicitly (which allows us to ask for the path to all
entities).
If you are using the annotations metadata driver as default driver, you
have to add the following lines to your bootstrap code:
$driverImpl = $config->newDefaultAnnotationDriver(array(__DIR__."/Entities"));
$config->setMetadataDriverImpl($driverImpl);
You have to specify the path to your entities as either string of a single
path or array of multiple paths
to your entities. This information will be used by all console commands to
access all entities.
Xml and Yaml Drivers work as before!
## New inversedBy attribute
It is now *mandatory* that the owning side of a bidirectional association specifies the
'inversedBy' attribute that points to the name of the field on the inverse side that completes
the association. Example:
[php]
// BEFORE (ALPHA4 AND EARLIER)
class User
{
//...
/** @OneToOne(targetEntity="Address", mappedBy="user") */
private $address;
//...
}
class Address
{
//...
/** @OneToOne(targetEntity="User") */
private $user;
//...
}
// SINCE BETA1
// User class DOES NOT CHANGE
class Address
{
//...
/** @OneToOne(targetEntity="User", inversedBy="address") */
private $user;
//...
}
Thus, the inversedBy attribute is the counterpart to the mappedBy attribute. This change
was necessary to enable some simplifications and further performance improvements. We
apologize for the inconvenience.
## Default Property for Field Mappings
The "default" option for database column defaults has been removed. If desired, database column defaults can
be implemented by using the columnDefinition attribute of the @Column annotation (or the approriate XML and YAML equivalents).
Prefer PHP default values, if possible.
## Selecting Partial Objects
Querying for partial objects now has a new syntax. The old syntax to query for partial objects
now has a different meaning. This is best illustrated by an example. If you previously
had a DQL query like this:
[sql]
SELECT u.id, u.name FROM User u
Since BETA1, simple state field path expressions in the select clause are used to select
object fields as plain scalar values (something that was not possible before).
To achieve the same result as previously (that is, a partial object with only id and name populated)
you need to use the following, explicit syntax:
[sql]
SELECT PARTIAL u.{id,name} FROM User u
## XML Mapping Driver
The 'inheritance-type' attribute changed to take last bit of ClassMetadata constant names, i.e.
NONE, SINGLE_TABLE, INHERITANCE_TYPE_JOINED
## YAML Mapping Driver
The way to specify lifecycle callbacks in YAML Mapping driver was changed to allow for multiple callbacks
per event. The Old syntax ways:
[yaml]
lifecycleCallbacks:
doStuffOnPrePersist: prePersist
doStuffOnPostPersist: postPersist
The new syntax is:
[yaml]
lifecycleCallbacks:
prePersist: [ doStuffOnPrePersist, doOtherStuffOnPrePersistToo ]
postPersist: [ doStuffOnPostPersist ]
## PreUpdate Event Listeners
Event Listeners listening to the 'preUpdate' event can only affect the primitive values of entity changesets
by using the API on the `PreUpdateEventArgs` instance passed to the preUpdate listener method. Any changes
to the state of the entitys properties won't affect the database UPDATE statement anymore. This gives drastic
performance benefits for the preUpdate event.
## Collection API
The Collection interface in the Common package has been updated with some missing methods
that were present only on the default implementation, ArrayCollection. Custom collection
implementations need to be updated to adhere to the updated interface.
# Upgrade from 2.0-ALPHA3 to 2.0-ALPHA4
## CLI Controller changes
CLI main object changed its name and namespace. Renamed from Doctrine\ORM\Tools\Cli to Doctrine\Common\Cli\CliController.
Doctrine\Common\Cli\CliController now only deals with namespaces. Ready to go, Core, Dbal and Orm are available and you can subscribe new tasks by retrieving the namespace and including new task. Example:
[php]
$cli->getNamespace('Core')->addTask('my-example', '\MyProject\Tools\Cli\Tasks\MyExampleTask');
## CLI Tasks documentation
Tasks have implemented a new way to build documentation. Although it is still possible to define the help manually by extending the basicHelp and extendedHelp, they are now optional.
With new required method AbstractTask::buildDocumentation, its implementation defines the TaskDocumentation instance (accessible through AbstractTask::getDocumentation()), basicHelp and extendedHelp are now not necessary to be implemented.
## Changes in Method Signatures
* A bunch of Methods on both Doctrine\DBAL\Platforms\AbstractPlatform and Doctrine\DBAL\Schema\AbstractSchemaManager
have changed quite significantly by adopting the new Schema instance objects.
## Renamed Methods
* Doctrine\ORM\AbstractQuery::setExpireResultCache() -> expireResultCache()
* Doctrine\ORM\Query::setExpireQueryCache() -> expireQueryCache()
## SchemaTool Changes
* "doctrine schema-tool --drop" now always drops the complete database instead of
only those tables defined by the current database model. The previous method had
problems when foreign keys of orphaned tables pointed to tables that were schedulded
for deletion.
* Use "doctrine schema-tool --update" to get a save incremental update for your
database schema without deleting any unused tables, sequences or foreign keys.
* Use "doctrine schema-tool --complete-update" to do a full incremental update of
your schema.
# Upgrade from 2.0-ALPHA2 to 2.0-ALPHA3
This section details the changes made to Doctrine 2.0-ALPHA3 to make it easier for you
to upgrade your projects to use this version.
## CLI Changes
The $args variable used in the cli-config.php for configuring the Doctrine CLI has been renamed to $globalArguments.
## Proxy class changes
You are now required to make supply some minimalist configuration with regards to proxy objects. That involves 2 new configuration options. First, the directory where generated proxy classes should be placed needs to be specified. Secondly, you need to configure the namespace used for proxy classes. The following snippet shows an example:
[php]
// step 1: configure directory for proxy classes
// $config instanceof Doctrine\ORM\Configuration
$config->setProxyDir('/path/to/myproject/lib/MyProject/Generated/Proxies');
$config->setProxyNamespace('MyProject\Generated\Proxies');
Note that proxy classes behave exactly like any other classes when it comes to class loading. Therefore you need to make sure the proxy classes can be loaded by some class loader. If you place the generated proxy classes in a namespace and directory under your projects class files, like in the example above, it would be sufficient to register the MyProject namespace on a class loader. Since the proxy classes are contained in that namespace and adhere to the standards for class loading, no additional work is required.
Generating the proxy classes into a namespace within your class library is the recommended setup.
Entities with initialized proxy objects can now be serialized and unserialized properly from within the same application.
For more details refer to the Configuration section of the manual.
## Removed allowPartialObjects configuration option
The allowPartialObjects configuration option together with the `Configuration#getAllowPartialObjects` and `Configuration#setAllowPartialObjects` methods have been removed.
The new behavior is as if the option were set to FALSE all the time, basically disallowing partial objects globally. However, you can still use the `Query::HINT_FORCE_PARTIAL_LOAD` query hint to force a query to return partial objects for optimization purposes.
## Renamed Methods
* Doctrine\ORM\Configuration#getCacheDir() to getProxyDir()
* Doctrine\ORM\Configuration#setCacheDir($dir) to setProxyDir($dir)

View File

@@ -1,240 +0,0 @@
# Update from 2.0-BETA3 to 2.0-BETA4
## XML Driver <change-tracking-policy /> element demoted to attribute
We changed how the XML Driver allows to define the change-tracking-policy. The working case is now:
<entity change-tracking-policy="DEFERRED_IMPLICT" />
# Update from 2.0-BETA2 to 2.0-BETA3
## Serialization of Uninitialized Proxies
As of Beta3 you can now serialize uninitialized proxies, an exception will only be thrown when
trying to access methods on the unserialized proxy as long as it has not been re-attached to the
EntityManager using `EntityManager#merge()`. See this example:
$proxy = $em->getReference('User', 1);
$serializedProxy = serialize($proxy);
$detachedProxy = unserialized($serializedProxy);
echo $em->contains($detachedProxy); // FALSE
try {
$detachedProxy->getId(); // uninitialized detached proxy
} catch(Exception $e) {
}
$attachedProxy = $em->merge($detachedProxy);
echo $attackedProxy->getId(); // works!
## Changed SQL implementation of Postgres and Oracle DateTime types
The DBAL Type "datetime" included the Timezone Offset in both Postgres and Oracle. As of this version they are now
generated without Timezone (TIMESTAMP WITHOUT TIME ZONE instead of TIMESTAMP WITH TIME ZONE).
See [this comment to Ticket DBAL-22](http://www.doctrine-project.org/jira/browse/DBAL-22?focusedCommentId=13396&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#action_13396)
for more details as well as migration issues for PostgreSQL and Oracle.
Both Postgres and Oracle will throw Exceptions during hydration of Objects with "DateTime" fields unless migration steps are taken!
## Removed multi-dot/deep-path expressions in DQL
The support for implicit joins in DQL through the multi-dot/Deep Path Expressions
was dropped. For example:
SELECT u FROM User u WHERE u.group.name = ?1
See the "u.group.id" here is using multi dots (deep expression) to walk
through the graph of objects and properties. Internally the DQL parser
would rewrite these queries to:
SELECT u FROM User u JOIN u.group g WHERE g.name = ?1
This explicit notation will be the only supported notation as of now. The internal
handling of multi-dots in the DQL Parser was very complex, error prone in edge cases
and required special treatment for several features we added. Additionally
it had edge cases that could not be solved without making the DQL Parser
even much more complex. For this reason we will drop the support for the
deep path expressions to increase maintainability and overall performance
of the DQL parsing process. This will benefit any DQL query being parsed,
even those not using deep path expressions.
Note that the generated SQL of both notations is exactly the same! You
don't loose anything through this.
## Default Allocation Size for Sequences
The default allocation size for sequences has been changed from 10 to 1. This step was made
to not cause confusion with users and also because it is partly some kind of premature optimization.
# Update from 2.0-BETA1 to 2.0-BETA2
There are no backwards incompatible changes in this release.
# Upgrade from 2.0-ALPHA4 to 2.0-BETA1
## EntityRepository deprecates access to protected variables
Instead of accessing protected variables for the EntityManager in
a custom EntityRepository it is now required to use the getter methods
for all the three instance variables:
* `$this->_em` now accessible through `$this->getEntityManager()`
* `$this->_class` now accessible through `$this->getClassMetadata()`
* `$this->_entityName` now accessible through `$this->getEntityName()`
Important: For Beta 2 the protected visibility of these three properties will be
changed to private!
## Console migrated to Symfony Console
The Doctrine CLI has been replaced by Symfony Console Configuration
Instead of having to specify:
[php]
$cliConfig = new CliConfiguration();
$cliConfig->setAttribute('em', $entityManager);
You now have to configure the script like:
[php]
$helperSet = new \Symfony\Components\Console\Helper\HelperSet(array(
'db' => new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($em->getConnection()),
'em' => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($em)
));
## Console: No need for Mapping Paths anymore
In previous versions you had to specify the --from and --from-path options
to show where your mapping paths are from the console. However this information
is already known from the Mapping Driver configuration, so the requirement
for this options were dropped.
Instead for each console command all the entities are loaded and to
restrict the operation to one or more sub-groups you can use the --filter flag.
## AnnotationDriver is not a default mapping driver anymore
In conjunction with the recent changes to Console we realized that the
annotations driver being a default metadata driver lead to lots of glue
code in the console components to detect where entities lie and how to load
them for batch updates like SchemaTool and other commands. However the
annotations driver being a default driver does not really help that much
anyways.
Therefore we decided to break backwards compability in this issue and drop
the support for Annotations as Default Driver and require our users to
specify the driver explicitly (which allows us to ask for the path to all
entities).
If you are using the annotations metadata driver as default driver, you
have to add the following lines to your bootstrap code:
$driverImpl = $config->newDefaultAnnotationDriver(array(__DIR__."/Entities"));
$config->setMetadataDriverImpl($driverImpl);
You have to specify the path to your entities as either string of a single
path or array of multiple paths
to your entities. This information will be used by all console commands to
access all entities.
Xml and Yaml Drivers work as before!
## New inversedBy attribute
It is now *mandatory* that the owning side of a bidirectional association specifies the
'inversedBy' attribute that points to the name of the field on the inverse side that completes
the association. Example:
[php]
// BEFORE (ALPHA4 AND EARLIER)
class User
{
//...
/** @OneToOne(targetEntity="Address", mappedBy="user") */
private $address;
//...
}
class Address
{
//...
/** @OneToOne(targetEntity="User") */
private $user;
//...
}
// SINCE BETA1
// User class DOES NOT CHANGE
class Address
{
//...
/** @OneToOne(targetEntity="User", inversedBy="address") */
private $user;
//...
}
Thus, the inversedBy attribute is the counterpart to the mappedBy attribute. This change
was necessary to enable some simplifications and further performance improvements. We
apologize for the inconvenience.
## Default Property for Field Mappings
The "default" option for database column defaults has been removed. If desired, database column defaults can
be implemented by using the columnDefinition attribute of the @Column annotation (or the approriate XML and YAML equivalents).
Prefer PHP default values, if possible.
## Selecting Partial Objects
Querying for partial objects now has a new syntax. The old syntax to query for partial objects
now has a different meaning. This is best illustrated by an example. If you previously
had a DQL query like this:
[sql]
SELECT u.id, u.name FROM User u
Since BETA1, simple state field path expressions in the select clause are used to select
object fields as plain scalar values (something that was not possible before).
To achieve the same result as previously (that is, a partial object with only id and name populated)
you need to use the following, explicit syntax:
[sql]
SELECT PARTIAL u.{id,name} FROM User u
## XML Mapping Driver
The 'inheritance-type' attribute changed to take last bit of ClassMetadata constant names, i.e.
NONE, SINGLE_TABLE, INHERITANCE_TYPE_JOINED
## YAML Mapping Driver
The way to specify lifecycle callbacks in YAML Mapping driver was changed to allow for multiple callbacks
per event. The Old syntax ways:
[yaml]
lifecycleCallbacks:
doStuffOnPrePersist: prePersist
doStuffOnPostPersist: postPersist
The new syntax is:
[yaml]
lifecycleCallbacks:
prePersist: [ doStuffOnPrePersist, doOtherStuffOnPrePersistToo ]
postPersist: [ doStuffOnPostPersist ]
## PreUpdate Event Listeners
Event Listeners listening to the 'preUpdate' event can only affect the primitive values of entity changesets
by using the API on the `PreUpdateEventArgs` instance passed to the preUpdate listener method. Any changes
to the state of the entitys properties won't affect the database UPDATE statement anymore. This gives drastic
performance benefits for the preUpdate event.
## Collection API
The Collection interface in the Common package has been updated with some missing methods
that were present only on the default implementation, ArrayCollection. Custom collection
implementations need to be updated to adhere to the updated interface.

View File

@@ -1,35 +0,0 @@
# Upgrade from 2.0-ALPHA2 to 2.0-ALPHA3
This section details the changes made to Doctrine 2.0-ALPHA3 to make it easier for you
to upgrade your projects to use this version.
## CLI Changes
The $args variable used in the cli-config.php for configuring the Doctrine CLI has been renamed to $globalArguments.
## Proxy class changes
You are now required to make supply some minimalist configuration with regards to proxy objects. That involves 2 new configuration options. First, the directory where generated proxy classes should be placed needs to be specified. Secondly, you need to configure the namespace used for proxy classes. The following snippet shows an example:
[php]
// step 1: configure directory for proxy classes
// $config instanceof Doctrine\ORM\Configuration
$config->setProxyDir('/path/to/myproject/lib/MyProject/Generated/Proxies');
$config->setProxyNamespace('MyProject\Generated\Proxies');
Note that proxy classes behave exactly like any other classes when it comes to class loading. Therefore you need to make sure the proxy classes can be loaded by some class loader. If you place the generated proxy classes in a namespace and directory under your projects class files, like in the example above, it would be sufficient to register the MyProject namespace on a class loader. Since the proxy classes are contained in that namespace and adhere to the standards for class loading, no additional work is required.
Generating the proxy classes into a namespace within your class library is the recommended setup.
Entities with initialized proxy objects can now be serialized and unserialized properly from within the same application.
For more details refer to the Configuration section of the manual.
## Removed allowPartialObjects configuration option
The allowPartialObjects configuration option together with the `Configuration#getAllowPartialObjects` and `Configuration#setAllowPartialObjects` methods have been removed.
The new behavior is as if the option were set to FALSE all the time, basically disallowing partial objects globally. However, you can still use the `Query::HINT_FORCE_PARTIAL_LOAD` query hint to force a query to return partial objects for optimization purposes.
## Renamed Methods
* Doctrine\ORM\Configuration#getCacheDir() to getProxyDir()
* Doctrine\ORM\Configuration#setCacheDir($dir) to setProxyDir($dir)

View File

@@ -1,36 +0,0 @@
# Upgrade from 2.0-ALPHA3 to 2.0-ALPHA4
## CLI Controller changes
CLI main object changed its name and namespace. Renamed from Doctrine\ORM\Tools\Cli to Doctrine\Common\Cli\CliController.
Doctrine\Common\Cli\CliController now only deals with namespaces. Ready to go, Core, Dbal and Orm are available and you can subscribe new tasks by retrieving the namespace and including new task. Example:
[php]
$cli->getNamespace('Core')->addTask('my-example', '\MyProject\Tools\Cli\Tasks\MyExampleTask');
## CLI Tasks documentation
Tasks have implemented a new way to build documentation. Although it is still possible to define the help manually by extending the basicHelp and extendedHelp, they are now optional.
With new required method AbstractTask::buildDocumentation, its implementation defines the TaskDocumentation instance (accessible through AbstractTask::getDocumentation()), basicHelp and extendedHelp are now not necessary to be implemented.
## Changes in Method Signatures
* A bunch of Methods on both Doctrine\DBAL\Platforms\AbstractPlatform and Doctrine\DBAL\Schema\AbstractSchemaManager
have changed quite significantly by adopting the new Schema instance objects.
## Renamed Methods
* Doctrine\ORM\AbstractQuery::setExpireResultCache() -> expireResultCache()
* Doctrine\ORM\Query::setExpireQueryCache() -> expireQueryCache()
## SchemaTool Changes
* "doctrine schema-tool --drop" now always drops the complete database instead of
only those tables defined by the current database model. The previous method had
problems when foreign keys of orphaned tables pointed to tables that were schedulded
for deletion.
* Use "doctrine schema-tool --update" to get a save incremental update for your
database schema without deleting any unused tables, sequences or foreign keys.
* Use "doctrine schema-tool --complete-update" to do a full incremental update of
your schema.

2
bin/doctrine Normal file → Executable file
View File

@@ -1,4 +1,4 @@
#!/usr/bin/env php
<?php
include('doctrine.php');
include('doctrine.php');

50
bin/doctrine-pear.php Normal file
View File

@@ -0,0 +1,50 @@
<?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 LGPL. For more information, see
* <http://www.doctrine-project.org>.
*/
require_once 'Doctrine/Common/ClassLoader.php';
$classLoader = new \Doctrine\Common\ClassLoader('Doctrine');
$classLoader->register();
$classLoader = new \Doctrine\Common\ClassLoader('Symfony');
$classLoader->register();
$configFile = getcwd() . DIRECTORY_SEPARATOR . 'cli-config.php';
$helperSet = null;
if (file_exists($configFile)) {
if ( ! is_readable($configFile)) {
trigger_error(
'Configuration file [' . $configFile . '] does not have read permission.', E_ERROR
);
}
require $configFile;
foreach ($GLOBALS as $helperSetCandidate) {
if ($helperSetCandidate instanceof \Symfony\Component\Console\Helper\HelperSet) {
$helperSet = $helperSetCandidate;
break;
}
}
}
$helperSet = ($helperSet) ?: new \Symfony\Component\Console\Helper\HelperSet();
\Doctrine\ORM\Tools\Console\ConsoleRunner::run($helperSet);

9
bin/doctrine.php Normal file → Executable file
View File

@@ -17,14 +17,7 @@
* <http://www.doctrine-project.org>.
*/
require_once 'Doctrine/Common/ClassLoader.php';
$classLoader = new \Doctrine\Common\ClassLoader('Doctrine');
$classLoader->register();
$classLoader = new \Doctrine\Common\ClassLoader('Symfony', 'Doctrine');
$classLoader->register();
(@include_once __DIR__ . '/../vendor/autoload.php') || @include_once __DIR__ . '/../../../autoload.php';
$configFile = getcwd() . DIRECTORY_SEPARATOR . 'cli-config.php';
$helperSet = null;

11
build.properties Normal file
View File

@@ -0,0 +1,11 @@
# Project Name
project.name=DoctrineORM
# Dependency minimum versions
dependencies.common=2.2.0beta1
dependencies.dbal=2.2.0beta1
dependencies.sfconsole=2.0.0
# Version class and file
project.version_class = Doctrine\ORM\Version
project.version_file = lib/Doctrine/ORM/Version.php

View File

@@ -1,6 +1,6 @@
version=2.0.1
dependencies.common=2.0.1
dependencies.dbal=2.0.1
version=2.0.0BETA2
dependencies.common=2.0.0BETA4
dependencies.dbal=2.0.0BETA4
stability=beta
build.dir=build
dist.dir=dist
@@ -8,6 +8,7 @@ report.dir=reports
log.archive.dir=logs
project.pirum_dir=
project.download_dir=
project.xsd_dir=
test.phpunit_configuration_file=
test.phpunit_generate_coverage=0
test.pmd_reports=0

199
build.xml
View File

@@ -1,11 +1,7 @@
<?xml version="1.0"?>
<!--
Doctrine 2 build file.
-->
<project name="Doctrine2" default="build" basedir=".">
<project name="DoctrineORM" default="build" basedir=".">
<taskdef classname="phing.tasks.ext.d51PearPkg2Task" name="d51pearpkg2" />
<import file="${project.basedir}/lib/vendor/doctrine-build-common/packaging.xml" />
<property file="build.properties" />
@@ -14,6 +10,8 @@
-->
<fileset id="shared-artifacts" dir=".">
<include name="LICENSE"/>
<include name="UPGRADE*" />
<include name="doctrine-mapping.xsd" />
</fileset>
<!--
@@ -21,7 +19,7 @@
-->
<fileset id="bin-scripts" dir="./bin">
<include name="doctrine"/>
<include name="doctrine.php"/>
<include name="doctrine-pear.php"/>
<include name="doctrine.bat"/>
</fileset>
@@ -51,98 +49,34 @@
-->
<fileset id="symfony-sources" dir="./lib/vendor">
<include name="Symfony/Component/**"/>
<exclude name="**/.git/**" />
</fileset>
<!--
Clean the directory for the next build.
-->
<target name="clean">
<available file="./build.properties" property="build_properties_exist" value="true"/>
<fail unless="build_properties_exist" message="The build.properties file is missing." />
<delete dir="${build.dir}" includeemptydirs="true" />
<delete dir="${dist.dir}" includeemptydirs="true" />
<delete dir="${report.dir}" includeemptydirs="true" />
</target>
<!--
Prepare the new build directories after cleaning
-->
<target name="prepare" depends="clean">
<echo msg="Creating build directory: ${build.dir}" />
<mkdir dir="${build.dir}" />
<echo msg="Creating distribution directory: ${dist.dir}" />
<mkdir dir="${dist.dir}" />
<echo msg="Creating report directory: ${report.dir}" />
<mkdir dir="${report.dir}" />
<mkdir dir="${build.dir}/logs"/>
<mkdir dir="${report.dir}/tests"/>
</target>
<!--
Builds ORM package, preparing it for distribution.
-->
<target name="build-orm" depends="prepare">
<exec command="grep '${version}' ${project.basedir}/lib/Doctrine/ORM/Version.php" checkreturn="true"/>
<copy todir="${build.dir}/doctrine-orm">
<target name="copy-files" depends="prepare">
<copy todir="${build.dir}/${project.name}-${version}">
<fileset refid="shared-artifacts"/>
</copy>
<copy todir="${build.dir}/doctrine-orm">
<copy todir="${build.dir}/${project.name}-${version}">
<fileset refid="common-sources"/>
<fileset refid="dbal-sources"/>
<fileset refid="orm-sources"/>
</copy>
<copy todir="${build.dir}/doctrine-orm/Doctrine">
<copy todir="${build.dir}/${project.name}-${version}/Doctrine">
<fileset refid="symfony-sources"/>
</copy>
<copy todir="${build.dir}/doctrine-orm/bin">
<copy todir="${build.dir}/${project.name}-${version}/bin">
<fileset refid="bin-scripts"/>
</copy>
<exec command="sed 's/${version}-DEV/${version}/' ${build.dir}/doctrine-orm/Doctrine/ORM/Version.php > ${build.dir}/doctrine-orm/Doctrine/ORM/Version2.php" passthru="true" />
<exec command="mv ${build.dir}/doctrine-orm/Doctrine/ORM/Version2.php ${build.dir}/doctrine-orm/Doctrine/ORM/Version.php" passthru="true" />
</target>
<target name="build" depends="test, build-orm"/>
<!--
Runs the full test suite.
-->
<target name="test" depends="prepare">
<if><equals arg1="${test.phpunit_generate_coverage}" arg2="1" />
<then>
<property name="test.phpunit_coverage_file" value="${build.dir}/logs/clover.xml" />
</then>
<else>
<property name="test.phpunit_coverage_file" value="false" />
</else>
</if>
<nativephpunit
testfile="./tests/Doctrine/Tests/AllTests.php" junitlogfile="${build.dir}/logs/testsuites.xml"
testdirectory="./tests" coverageclover="${test.phpunit_coverage_file}" configuration="${test.phpunit_configuration_file}"
/>
<phpunitreport infile="${build.dir}/logs/testsuites.xml" format="frames" todir="${report.dir}/tests" />
<nativephpunit testfile="./tests/Doctrine/Tests/ORM/Performance/AllTests.php" testdirectory="./tests" haltonfailure="false" haltonerror="false" />
<tstamp/>
<copy file="${build.dir}/logs/testsuites.xml" tofile="${log.archive.dir}/latest/log.xml" overwrite="true"/>
<if><equals arg1="${test.pmd_reports}" arg2="1" />
<then>
<exec command="${test.pdepend_exec} --jdepend-xml=${build.dir}/logs/jdepend.xml ./lib/Doctrine" />
<exec command="${test.phpmd_exec} ./lib/Doctrine xml codesize --reportfile ${build.dir}/logs/phpmd.xml" />
<copy file="${build.dir}/logs/jdepend.xml" tofile="${log.archive.dir}/latest/jdepend.xml" overwrite="true"/>
<copy file="${build.dir}/logs/phpmd.xml" tofile="${log.archive.dir}/latest/phpmd.xml" overwrite="true"/>
</then>
</if>
</target>
<!--
Builds distributable PEAR packages.
-->
<target name="build-packages" depends="build-orm">
<d51pearpkg2 baseinstalldir="/" dir="${build.dir}/doctrine-orm">
<target name="define-pear-package" depends="copy-files">
<d51pearpkg2 baseinstalldir="/" dir="${build.dir}/${project.name}-${version}">
<name>DoctrineORM</name>
<summary>Doctrine Object Relational Mapper</summary>
<channel>pear.doctrine-project.org</channel>
@@ -152,118 +86,29 @@
<lead user="romanb" name="Roman Borschel" email="roman@code-factory.org" />
<lead user="beberlei" name="Benjamin Eberlei" email="kontakt@beberlei.de" />
<license>LGPL</license>
<version release="${version}" api="${version}" />
<stability release="${stability}" api="${stability}" />
<version release="${pear.version}" api="${pear.version}" />
<stability release="${pear.stability}" api="${pear.stability}" />
<notes>-</notes>
<dependencies>
<php minimum_version="5.3.0" />
<pear minimum_version="1.6.0" recommended_version="1.6.1" />
<package name="DoctrineCommon" channel="pear.doctrine-project.org" minimum_version="${dependencies.common}" />
<package name="DoctrineDBAL" channel="pear.doctrine-project.org" minimum_version="${dependencies.dbal}" />
<package name="DoctrineSymfonyConsole" channel="pear.doctrine-project.org" minimum_version="2.0.0" />
<package name="DoctrineSymfonyYaml" channel="pear.doctrine-project.org" minimum_version="2.0.0" />
<package name="Console" channel="pear.symfony.com" minimum_version="2.0.0" />
<package name="Yaml" channel="pear.symfony.com" minimum_version="2.0.0" />
</dependencies>
<dirroles key="bin">script</dirroles>
<ignore>Doctrine/Common/</ignore>
<ignore>Doctrine/DBAL/</ignore>
<ignore>Symfony/Component/Yaml/</ignore>
<ignore>Symfony/Component/Console/</ignore>
<release>
<install as="doctrine" name="bin/doctrine" />
<install as="doctrine.php" name="bin/doctrine.php" />
<install as="doctrine.php" name="bin/doctrine-pear.php" />
<install as="doctrine.bat" name="bin/doctrine.bat" />
</release>
<replacement path="bin/doctrine.bat" type="pear-config" from="@php_bin@" to="php_bin" />
<replacement path="bin/doctrine" type="pear-config" from="@php_bin@" to="php_bin" />
<replacement path="bin/doctrine.bat" type="pear-config" from="@bin_dir@" to="bin_dir" />
</d51pearpkg2>
<exec command="pear package" dir="${build.dir}/doctrine-orm" passthru="true" />
<exec command="mv DoctrineORM-${version}.tgz ../../dist" dir="${build.dir}/doctrine-orm" passthru="true" />
<tar destfile="dist/DoctrineORM-${version}-full.tar.gz" compression="gzip" basedir="${build.dir}">
<fileset dir="${build.dir}">
<include name="**/**" />
<exclude name="logs/" />
<exclude name="doctrine-orm/package.xml" />
</fileset>
</tar>
</target>
<target name="git-tag">
<exec command="grep '${version}-DEV' ${project.basedir}/lib/Doctrine/ORM/Version.php" checkreturn="true"/>
<exec command="sed 's/${version}-DEV/${version}/' ${project.basedir}/lib/Doctrine/ORM/Version.php > ${project.basedir}/lib/Doctrine/ORM/Version2.php" passthru="true" />
<exec command="mv ${project.basedir}/lib/Doctrine/ORM/Version2.php ${project.basedir}/lib/Doctrine/ORM/Version.php" passthru="true" />
<exec command="git add ${project.basedir}/lib/Doctrine/ORM/Version.php" passthru="true" />
<exec command="git commit -m 'Release ${version}'" />
<exec command="git tag -m 'Tag ${version}' -a ${version}" passthru="true" />
</target>
<target name="pirum-release">
<exec command="sudo pirum add ${project.pirum_dir} ${project.basedir}/dist/DoctrineORM-${version}.tgz" dir="." passthru="true" />
<exec command="sudo pirum build ${project.pirum_dir}" passthru="true" />
</target>
<target name="distribute-download">
<copy file="dist/DoctrineORM-${version}-full.tar.gz" todir="${project.download_dir}" />
</target>
<target name="update-dev-version">
<exec command="grep '${version}' ${project.basedir}/lib/Doctrine/ORM/Version.php" checkreturn="true"/>
<propertyprompt propertyName="next_version" defaultValue="${version}" promptText="Enter next version string (without -DEV)" />
<exec command="sed 's/${version}/${next_version}-DEV/' ${project.basedir}/lib/Doctrine/ORM/Version.php > ${project.basedir}/lib/Doctrine/ORM/Version2.php" passthru="true" />
<exec command="mv ${project.basedir}/lib/Doctrine/ORM/Version2.php ${project.basedir}/lib/Doctrine/ORM/Version.php" passthru="true" />
<exec command="git add ${project.basedir}/lib/Doctrine/ORM/Version.php" passthru="true" />
<exec command="git commit -m 'Bump Dev Version to ${next_version}-DEV'" passthru="true" />
</target>
<target name="release" depends="git-tag,build-packages,distribute-download,pirum-release,update-dev-version" />
<!--
Builds distributable PEAR packages for the Symfony Dependencies
-->
<target name="release-symfony-dependencies" depends="build-orm">
<d51pearpkg2 baseinstalldir="/" dir="${build.dir}/doctrine-orm">
<name>DoctrineSymfonyConsole</name>
<summary>Symfony Console Component</summary>
<channel>pear.doctrine-project.org</channel>
<description>A command line interface tool from the Symfony project. Packaged for shipping with Doctrine projects using ORM version numbers.</description>
<lead user="fabpot" name="Fabien Potencier" email="fabien.potencier@symfony-project.com" />
<license>NewBSD License</license>
<version release="${version}" api="${version}" />
<stability release="${stability}" api="${stability}" />
<notes>-</notes>
<dependencies>
<php minimum_version="5.3.0" />
<pear minimum_version="1.6.0" recommended_version="1.6.1" />
</dependencies>
<ignore>Doctrine/Common/</ignore>
<ignore>Doctrine/DBAL/</ignore>
<ignore>Doctrine/ORM/</ignore>
<ignore>Symfony/Component/Yaml/</ignore>
</d51pearpkg2>
<exec command="pear package" dir="${build.dir}/doctrine-orm" passthru="true" />
<exec command="mv DoctrineSymfonyConsole-${version}.tgz ../../dist" dir="${build.dir}/doctrine-orm" passthru="true" />
<d51pearpkg2 baseinstalldir="/" dir="${build.dir}/doctrine-orm">
<name>DoctrineSymfonyYaml</name>
<summary>Symfony Yaml Component</summary>
<channel>pear.doctrine-project.org</channel>
<description>A YAML Parser from the Symfony project. Packaged for shipping with Doctrine projects using ORM version numbers.</description>
<lead user="fabpot" name="Fabien Potencier" email="fabien.potencier@symfony-project.com" />
<license>NewBSD License</license>
<version release="${version}" api="${version}" />
<stability release="${stability}" api="${stability}" />
<notes>-</notes>
<dependencies>
<php minimum_version="5.3.0" />
<pear minimum_version="1.6.0" recommended_version="1.6.1" />
</dependencies>
<ignore>Doctrine/Common/</ignore>
<ignore>Doctrine/DBAL/</ignore>
<ignore>Doctrine/ORM/</ignore>
<ignore>Symfony/Component/Console/</ignore>
</d51pearpkg2>
<exec command="pear package" dir="${build.dir}/doctrine-orm" passthru="true" />
<exec command="mv DoctrineSymfonyYaml-${version}.tgz ../../dist" dir="${build.dir}/doctrine-orm" passthru="true" />
<exec command="sudo pirum add ${project.pirum_dir} ${project.basedir}/dist/DoctrineSymfonyConsole-${version}.tgz" dir="." passthru="true" />
<exec command="sudo pirum add ${project.pirum_dir} ${project.basedir}/dist/DoctrineSymfonyYaml-${version}.tgz" dir="." passthru="true" />
<exec command="sudo pirum build ${project.pirum_dir}" passthru="true" />
</target>
</project>
</project>

32
composer.json Normal file
View File

@@ -0,0 +1,32 @@
{
"name": "doctrine/orm",
"type": "library","version":"2.3.2",
"description": "Object-Relational-Mapper for PHP",
"keywords": ["orm", "database"],
"homepage": "http://www.doctrine-project.org",
"license": "MIT",
"authors": [
{"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"},
{"name": "Roman Borschel", "email": "roman@code-factory.org"},
{"name": "Benjamin Eberlei", "email": "kontakt@beberlei.de"},
{"name": "Jonathan Wage", "email": "jonwage@gmail.com"}
],
"require": {
"php": ">=5.3.2",
"ext-pdo": "*",
"doctrine/dbal": "2.3.*",
"symfony/console": "2.*"
},
"suggest": {
"symfony/yaml": "If you want to use YAML Metadata Mapping Driver"
},
"autoload": {
"psr-0": { "Doctrine\\ORM": "lib/" }
},
"bin": ["bin/doctrine", "bin/doctrine.php"],
"extra": {
"branch-alias": {
"dev-master": "2.3.x-dev"
}
}
}

View File

@@ -17,11 +17,18 @@
<xs:sequence>
<xs:element name="mapped-superclass" type="orm:mapped-superclass" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="entity" type="orm:entity" minOccurs="0" maxOccurs="unbounded" />
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
</xs:element>
<xs:complexType name="emptyType"/>
<xs:complexType name="emptyType">
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="cascade-type">
<xs:sequence>
@@ -30,7 +37,9 @@
<xs:element name="cascade-merge" type="orm:emptyType" minOccurs="0"/>
<xs:element name="cascade-remove" type="orm:emptyType" minOccurs="0"/>
<xs:element name="cascade-refresh" type="orm:emptyType" minOccurs="0"/>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:simpleType name="lifecycle-callback-type">
@@ -46,29 +55,99 @@
</xs:simpleType>
<xs:complexType name="lifecycle-callback">
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="type" type="orm:lifecycle-callback-type" use="required" />
<xs:attribute name="method" type="xs:NMTOKEN" use="required" />
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="lifecycle-callbacks">
<xs:sequence>
<xs:element name="lifecycle-callback" type="orm:lifecycle-callback" minOccurs="1" maxOccurs="unbounded" />
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="named-query">
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="query" type="xs:string" use="required" />
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="named-queries">
<xs:sequence>
<xs:element name="named-query" type="orm:named-query" minOccurs="1" maxOccurs="unbounded" />
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="named-native-query">
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="query" type="xs:string" use="required"/>
<xs:attribute name="result-class" type="xs:string" />
<xs:attribute name="result-set-mapping" type="xs:string" />
</xs:complexType>
<xs:complexType name="named-native-queries">
<xs:sequence>
<xs:element name="named-native-query" type="orm:named-native-query" minOccurs="1" maxOccurs="unbounded" />
<xs:any minOccurs="1" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="column-result">
<xs:attribute name="name" type="xs:string" use="required" />
</xs:complexType>
<xs:complexType name="field-result">
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="column" type="xs:string" />
</xs:complexType>
<xs:complexType name="entity-result">
<xs:sequence>
<xs:element name="field-result" type="orm:field-result" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="entity-class" type="xs:string" use="required" />
</xs:complexType>
<xs:complexType name="sql-result-set-mapping">
<xs:sequence>
<xs:element name="entity-result" type="orm:entity-result" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="column-result" type="orm:column-result" minOccurs="0" maxOccurs="unbounded" />
<xs:any minOccurs="1" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="sql-result-set-mappings">
<xs:sequence>
<xs:element name="sql-result-set-mapping" type="orm:sql-result-set-mapping" minOccurs="1" maxOccurs="unbounded" />
<xs:any minOccurs="1" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="entity">
<xs:sequence>
<xs:element name="options" type="orm:options" minOccurs="0" />
<xs:element name="indexes" type="orm:indexes" minOccurs="0"/>
<xs:element name="unique-constraints" type="orm:unique-constraints" minOccurs="0"/>
<xs:element name="discriminator-column" type="orm:discriminator-column" minOccurs="0"/>
<xs:element name="discriminator-map" type="orm:discriminator-map" minOccurs="0"/>
<xs:element name="lifecycle-callbacks" type="orm:lifecycle-callbacks" minOccurs="0" maxOccurs="1" />
<xs:element name="id" type="orm:id" minOccurs="0" maxOccurs="1" />
<xs:element name="named-queries" type="orm:named-queries" minOccurs="0" maxOccurs="1" />
<xs:element name="named-native-queries" type="orm:named-native-queries" minOccurs="0" maxOccurs="1" />
<xs:element name="id" type="orm:id" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="field" type="orm:field" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="one-to-one" type="orm:one-to-one" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="one-to-many" type="orm:one-to-many" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="many-to-one" type="orm:many-to-one" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="many-to-many" type="orm:many-to-many" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="association-overrides" type="orm:association-overrides" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="attribute-overrides" type="orm:attribute-overrides" minOccurs="0" maxOccurs="unbounded" />
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="table" type="xs:NMTOKEN" />
@@ -76,11 +155,35 @@
<xs:attribute name="repository-class" type="xs:string"/>
<xs:attribute name="inheritance-type" type="orm:inheritance-type"/>
<xs:attribute name="change-tracking-policy" type="orm:change-tracking-policy" />
<xs:attribute name="read-only" type="xs:boolean" default="false" />
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="option" mixed="true">
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="option" type="orm:option"/>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="name" type="xs:NMTOKEN" use="required"/>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="options">
<xs:sequence>
<xs:element name="option" type="orm:option" minOccurs="0" maxOccurs="unbounded"/>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="mapped-superclass" >
<xs:complexContent>
<xs:extension base="orm:entity"/>
<xs:extension base="orm:entity">
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:anyAttribute namespace="##other"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
@@ -106,6 +209,8 @@
<xs:enumeration value="SEQUENCE"/>
<xs:enumeration value="IDENTITY"/>
<xs:enumeration value="AUTO"/>
<xs:enumeration value="UUID"/>
<xs:enumeration value="CUSTOM" />
</xs:restriction>
</xs:simpleType>
@@ -113,7 +218,7 @@
<xs:restriction base="xs:token">
<xs:enumeration value="CASCADE"/>
<xs:enumeration value="RESTRICT"/>
<xs:enumeration value="SET_NULL"/>
<xs:enumeration value="SET NULL"/>
</xs:restriction>
</xs:simpleType>
@@ -121,10 +226,15 @@
<xs:restriction base="xs:token">
<xs:enumeration value="EAGER"/>
<xs:enumeration value="LAZY"/>
<xs:enumeration value="EXTRA_LAZY"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="field">
<xs:sequence>
<xs:element name="options" type="orm:options" minOccurs="0" />
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="name" type="xs:NMTOKEN" use="required" />
<xs:attribute name="type" type="xs:NMTOKEN" default="string" />
<xs:attribute name="column" type="xs:NMTOKEN" />
@@ -135,75 +245,124 @@
<xs:attribute name="column-definition" type="xs:string" />
<xs:attribute name="precision" type="xs:integer" use="optional" />
<xs:attribute name="scale" type="xs:integer" use="optional" />
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="discriminator-column">
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="name" type="xs:NMTOKEN" use="required" />
<xs:attribute name="type" type="xs:NMTOKEN" use="required" />
<xs:attribute name="type" type="xs:NMTOKEN"/>
<xs:attribute name="field-name" type="xs:NMTOKEN" />
<xs:attribute name="length" type="xs:NMTOKEN" />
<xs:attribute name="column-definition" type="xs:string" />
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="unique-constraint">
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="name" type="xs:NMTOKEN" use="optional"/>
<xs:attribute name="columns" type="xs:string" use="required"/>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="unique-constraints">
<xs:sequence>
<xs:element name="unique-constraint" type="orm:unique-constraint" minOccurs="1" maxOccurs="unbounded"/>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="index">
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="name" type="xs:NMTOKEN" use="optional"/>
<xs:attribute name="columns" type="xs:NMTOKENS" use="required"/>
<xs:attribute name="columns" type="xs:string" use="required"/>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="indexes">
<xs:sequence>
<xs:element name="index" type="orm:index" minOccurs="1" maxOccurs="unbounded"/>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="discriminator-mapping">
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="value" type="xs:NMTOKEN" use="required"/>
<xs:attribute name="class" type="xs:NMTOKEN" use="required"/>
<xs:attribute name="class" type="xs:string" use="required"/>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="discriminator-map">
<xs:sequence>
<xs:element name="discriminator-mapping" type="orm:discriminator-mapping" minOccurs="1" maxOccurs="unbounded"/>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="generator">
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="strategy" type="orm:generator-strategy" use="optional" default="AUTO" />
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="id">
<xs:sequence>
<xs:element name="generator" type="orm:generator" minOccurs="0" />
<xs:element name="sequence-generator" type="orm:sequence-generator" minOccurs="0" maxOccurs="1" />
<xs:element name="custom-id-generator" type="orm:custom-id-generator" minOccurs="0" maxOccurs="1" />
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="name" type="xs:NMTOKEN" use="required" />
<xs:attribute name="type" type="xs:NMTOKEN" use="required" />
<xs:attribute name="type" type="xs:NMTOKEN" />
<xs:attribute name="column" type="xs:NMTOKEN" />
<xs:attribute name="association-key" type="xs:boolean" default="false" />
<xs:attribute name="column-definition" type="xs:string" />
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="sequence-generator">
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="sequence-name" type="xs:NMTOKEN" use="required" />
<xs:attribute name="allocation-size" type="xs:integer" use="optional" default="1" />
<xs:attribute name="initial-value" type="xs:integer" use="optional" default="1" />
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="custom-id-generator">
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="class" type="xs:NMTOKEN" use="required" />
</xs:complexType>
<xs:complexType name="inverse-join-columns">
<xs:sequence>
<xs:element name="join-column" type="orm:join-column" minOccurs="1" maxOccurs="unbounded" />
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="join-column">
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="name" type="xs:NMTOKEN" use="required" />
<xs:attribute name="referenced-column-name" type="xs:NMTOKEN" use="optional" default="id" />
<xs:attribute name="unique" type="xs:boolean" default="false" />
@@ -211,32 +370,43 @@
<xs:attribute name="on-delete" type="orm:fk-action" />
<xs:attribute name="on-update" type="orm:fk-action" />
<xs:attribute name="column-definition" type="xs:string" />
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="join-columns">
<xs:sequence>
<xs:element name="join-column" type="orm:join-column" minOccurs="1" maxOccurs="unbounded" />
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="join-table">
<xs:sequence>
<xs:element name="join-columns" type="orm:join-columns" />
<xs:element name="inverse-join-columns" type="orm:join-columns" />
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="name" type="xs:NMTOKEN" use="required" />
<xs:attribute name="schema" type="xs:NMTOKEN" />
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="order-by">
<xs:sequence>
<xs:element name="order-by-field" type="orm:order-by-field" minOccurs="1" maxOccurs="unbounded" />
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="order-by-field">
<xs:attribute name="name" type="xs:NMTOKEN" use="required" />
<xs:attribute name="direction" type="orm:order-by-direction" default="ASC" />
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="name" type="xs:NMTOKEN" use="required" />
<xs:attribute name="direction" type="orm:order-by-direction" default="ASC" />
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:simpleType name="order-by-direction">
@@ -251,24 +421,31 @@
<xs:element name="cascade" type="orm:cascade-type" minOccurs="0" />
<xs:element name="join-table" type="orm:join-table" minOccurs="0" />
<xs:element name="order-by" type="orm:order-by" minOccurs="0" />
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="target-entity" type="xs:string" use="required" />
<xs:attribute name="field" type="xs:NMTOKEN" use="required" />
<xs:attribute name="mapped-by" type="xs:NMTOKEN" />
<xs:attribute name="index-by" type="xs:NMTOKEN" />
<xs:attribute name="inversed-by" type="xs:NMTOKEN" />
<xs:attribute name="fetch" type="orm:fetch-type" default="LAZY" />
<xs:attribute name="orphan-removal" type="xs:boolean" default="false" />
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="one-to-many">
<xs:sequence>
<xs:element name="cascade" type="orm:cascade-type" minOccurs="0" />
<xs:element name="order-by" type="orm:order-by" minOccurs="0" />
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="target-entity" type="xs:string" use="required" />
<xs:attribute name="mapped-by" type="xs:NMTOKEN" use="required" />
<xs:attribute name="field" type="xs:NMTOKEN" use="required" />
<xs:attribute name="index-by" type="xs:NMTOKEN" />
<xs:attribute name="orphan-removal" type="xs:boolean" default="false" />
<xs:attribute name="fetch" type="orm:fetch-type" default="LAZY" />
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="many-to-one">
@@ -277,13 +454,16 @@
<xs:choice minOccurs="0" maxOccurs="1">
<xs:element name="join-column" type="orm:join-column"/>
<xs:element name="join-columns" type="orm:join-columns"/>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:choice>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="target-entity" type="xs:string" use="required" />
<xs:attribute name="field" type="xs:NMTOKEN" use="required" />
<xs:attribute name="orphan-removal" type="xs:boolean" default="false" />
<xs:attribute name="fetch" type="orm:fetch-type" default="LAZY" />
<xs:attribute name="inversed-by" type="xs:NMTOKEN" />
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="one-to-one">
@@ -292,7 +472,9 @@
<xs:choice minOccurs="0" maxOccurs="1">
<xs:element name="join-column" type="orm:join-column"/>
<xs:element name="join-columns" type="orm:join-columns"/>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:choice>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="field" type="xs:NMTOKEN" use="required" />
<xs:attribute name="target-entity" type="xs:string" use="required" />
@@ -300,6 +482,38 @@
<xs:attribute name="inversed-by" type="xs:NMTOKEN" />
<xs:attribute name="orphan-removal" type="xs:boolean" default="false" />
<xs:attribute name="fetch" type="orm:fetch-type" default="LAZY" />
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="association-overrides">
<xs:sequence>
<xs:element name="association-override" type="orm:association-override" minOccurs="1" maxOccurs="unbounded" />
<xs:any minOccurs="1" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="association-override">
<xs:sequence>
<xs:element name="join-table" type="orm:join-table" minOccurs="0" />
<xs:element name="join-columns" type="orm:join-columns" minOccurs="0" />
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="name" type="xs:NMTOKEN" use="required" />
</xs:complexType>
<xs:complexType name="attribute-overrides">
<xs:sequence>
<xs:element name="attribute-override" type="orm:attribute-override" minOccurs="1" maxOccurs="unbounded" />
<xs:any minOccurs="1" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="attribute-override">
<xs:sequence>
<xs:element name="field" type="orm:field" minOccurs="1" />
<xs:any minOccurs="1" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="name" type="xs:NMTOKEN" use="required" />
</xs:complexType>
</xs:schema>

View File

@@ -1,7 +1,5 @@
<?php
/*
* $Id: Abstract.php 1393 2008-03-06 17:49:16Z guilhermeblanco $
*
* 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
@@ -15,22 +13,25 @@
* 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 LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM;
use Doctrine\DBAL\Types\Type,
Doctrine\ORM\Query\QueryException;
use Doctrine\Common\Util\ClassUtils;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Cache\QueryCacheProfile;
use Doctrine\ORM\Query\QueryException;
/**
* Base contract for ORM queries. Base class for Query and NativeQuery.
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 2.0
* @version $Revision$
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
@@ -58,14 +59,14 @@ abstract class AbstractQuery
const HYDRATE_SINGLE_SCALAR = 4;
/**
* @var array The parameter map of this query.
* Very simple object hydrator (optimized for performance).
*/
protected $_params = array();
const HYDRATE_SIMPLEOBJECT = 5;
/**
* @var array The parameter type map of this query.
* @var \Doctrine\Common\Collections\ArrayCollection The parameter map of this query.
*/
protected $_paramTypes = array();
protected $parameters;
/**
* @var ResultSetMapping The user-specified ResultSetMapping to use.
@@ -73,7 +74,7 @@ abstract class AbstractQuery
protected $_resultSetMapping;
/**
* @var Doctrine\ORM\EntityManager The entity manager used by this query object.
* @var \Doctrine\ORM\EntityManager The entity manager used by this query object.
*/
protected $_em;
@@ -88,23 +89,9 @@ abstract class AbstractQuery
protected $_hydrationMode = self::HYDRATE_OBJECT;
/**
* The locally set cache driver used for caching result sets of this query.
*
* @var CacheDriver
* @param \Doctrine\DBAL\Cache\QueryCacheProfile
*/
protected $_resultCacheDriver;
/**
* Boolean flag for whether or not to cache the results of this query.
*
* @var boolean
*/
protected $_useResultCache;
/**
* @var string The id to store the result cache entry under.
*/
protected $_resultCacheId;
protected $_queryCacheProfile;
/**
* @var boolean Boolean value that indicates whether or not expire the result cache.
@@ -112,24 +99,34 @@ abstract class AbstractQuery
protected $_expireResultCache = false;
/**
* @var int Result Cache lifetime.
* @param \Doctrine\DBAL\Cache\QueryCacheProfile
*/
protected $_resultCacheTTL;
protected $_hydrationCacheProfile;
/**
* Initializes a new instance of a class derived from <tt>AbstractQuery</tt>.
*
* @param Doctrine\ORM\EntityManager $entityManager
* @param \Doctrine\ORM\EntityManager $entityManager
*/
public function __construct(EntityManager $em)
{
$this->_em = $em;
$this->parameters = new ArrayCollection();
}
/**
* Gets the SQL query that corresponds to this query object.
* The returned SQL syntax depends on the connection driver that is used
* by this query object at the time of this method call.
*
* @return string SQL query
*/
abstract public function getSQL();
/**
* Retrieves the associated EntityManager of this Query instance.
*
* @return Doctrine\ORM\EntityManager
* @return \Doctrine\ORM\EntityManager
*/
public function getEntityManager()
{
@@ -145,40 +142,67 @@ abstract class AbstractQuery
*/
public function free()
{
$this->_params = array();
$this->_paramTypes = array();
$this->parameters = new ArrayCollection();
$this->_hints = array();
}
/**
* Get all defined parameters.
*
* @return array The defined query parameters.
* @return \Doctrine\Common\Collections\ArrayCollection The defined query parameters.
*/
public function getParameters()
{
return $this->_params;
return $this->parameters;
}
/**
* Gets a query parameter.
*
* @param mixed $key The key (index or name) of the bound parameter.
*
* @return mixed The value of the bound parameter.
*/
public function getParameter($key)
{
return isset($this->_params[$key]) ? $this->_params[$key] : null;
$filteredParameters = $this->parameters->filter(
function ($parameter) use ($key)
{
// Must not be identical because of string to integer conversion
return ($key == $parameter->getName());
}
);
return count($filteredParameters) ? $filteredParameters->first() : null;
}
/**
* Gets the SQL query that corresponds to this query object.
* The returned SQL syntax depends on the connection driver that is used
* by this query object at the time of this method call.
* Sets a collection of query parameters.
*
* @return string SQL query
* @param \Doctrine\Common\Collections\ArrayCollection|array $parameters
*
* @return \Doctrine\ORM\AbstractQuery This query instance.
*/
abstract public function getSQL();
public function setParameters($parameters)
{
// BC compatibility with 2.3-
if (is_array($parameters)) {
$parameterCollection = new ArrayCollection();
foreach ($parameters as $key => $value) {
$parameter = new Query\Parameter($key, $value);
$parameterCollection->add($parameter);
}
$parameters = $parameterCollection;
}
$this->parameters = $parameters;
return $this;
}
/**
* Sets a query parameter.
@@ -188,78 +212,191 @@ abstract class AbstractQuery
* @param string $type The parameter type. If specified, the given value will be run through
* the type conversion of this type. This is usually not needed for
* strings and numeric types.
* @return Doctrine\ORM\AbstractQuery This query instance.
*
* @return \Doctrine\ORM\AbstractQuery This query instance.
*/
public function setParameter($key, $value, $type = null)
{
if ($type !== null) {
$this->_paramTypes[$key] = $type;
$filteredParameters = $this->parameters->filter(
function ($parameter) use ($key)
{
// Must not be identical because of string to integer conversion
return ($key == $parameter->getName());
}
);
if (count($filteredParameters)) {
$parameter = $filteredParameters->first();
$parameter->setValue($value, $type);
return $this;
}
$this->_params[$key] = $value;
$parameter = new Query\Parameter($key, $value, $type);
$this->parameters->add($parameter);
return $this;
}
/**
* Sets a collection of query parameters.
* Process an individual parameter value
*
* @param array $params
* @param array $types
* @return Doctrine\ORM\AbstractQuery This query instance.
* @param mixed $value
* @return array
*/
public function setParameters(array $params, array $types = array())
public function processParameterValue($value)
{
foreach ($params as $key => $value) {
if (isset($types[$key])) {
$this->setParameter($key, $value, $types[$key]);
} else {
$this->setParameter($key, $value);
}
switch (true) {
case is_array($value):
foreach ($value as $key => $paramValue) {
$paramValue = $this->processParameterValue($paramValue);
$value[$key] = is_array($paramValue) ? $paramValue[key($paramValue)] : $paramValue;
}
return $value;
case is_object($value) && $this->_em->getMetadataFactory()->hasMetadataFor(ClassUtils::getClass($value)):
return $this->convertObjectParameterToScalarValue($value);
default:
return $value;
}
return $this;
}
private function convertObjectParameterToScalarValue($value)
{
$class = $this->_em->getClassMetadata(get_class($value));
if ($class->isIdentifierComposite) {
throw new \InvalidArgumentException(
"Binding an entity with a composite primary key to a query is not supported. " .
"You should split the parameter into the explicit fields and bind them seperately."
);
}
$values = ($this->_em->getUnitOfWork()->getEntityState($value) === UnitOfWork::STATE_MANAGED)
? $this->_em->getUnitOfWork()->getEntityIdentifier($value)
: $class->getIdentifierValues($value);
$value = $values[$class->getSingleIdentifierFieldName()];
if (null === $value) {
throw new \InvalidArgumentException(
"Binding entities to query parameters only allowed for entities that have an identifier."
);
}
return $value;
}
/**
* Sets the ResultSetMapping that should be used for hydration.
*
* @param ResultSetMapping $rsm
* @return Doctrine\ORM\AbstractQuery
* @return \Doctrine\ORM\AbstractQuery
*/
public function setResultSetMapping(Query\ResultSetMapping $rsm)
{
$this->_resultSetMapping = $rsm;
return $this;
}
/**
* Defines a cache driver to be used for caching result sets.
* Set a cache profile for hydration caching.
*
* @param Doctrine\Common\Cache\Cache $driver Cache driver
* @return Doctrine\ORM\AbstractQuery
* If no result cache driver is set in the QueryCacheProfile, the default
* result cache driver is used from the configuration.
*
* Important: Hydration caching does NOT register entities in the
* UnitOfWork when retrieved from the cache. Never use result cached
* entities for requests that also flush the EntityManager. If you want
* some form of caching with UnitOfWork registration you should use
* {@see AbstractQuery::setResultCacheProfile()}.
*
* @example
* $lifetime = 100;
* $resultKey = "abc";
* $query->setHydrationCacheProfile(new QueryCacheProfile());
* $query->setHydrationCacheProfile(new QueryCacheProfile($lifetime, $resultKey));
*
* @param \Doctrine\DBAL\Cache\QueryCacheProfile $profile
* @return \Doctrine\ORM\AbstractQuery
*/
public function setHydrationCacheProfile(QueryCacheProfile $profile = null)
{
if ( ! $profile->getResultCacheDriver()) {
$resultCacheDriver = $this->_em->getConfiguration()->getHydrationCacheImpl();
$profile = $profile->setResultCacheDriver($resultCacheDriver);
}
$this->_hydrationCacheProfile = $profile;
return $this;
}
/**
* @return \Doctrine\DBAL\Cache\QueryCacheProfile
*/
public function getHydrationCacheProfile()
{
return $this->_hydrationCacheProfile;
}
/**
* Set a cache profile for the result cache.
*
* If no result cache driver is set in the QueryCacheProfile, the default
* result cache driver is used from the configuration.
*
* @param \Doctrine\DBAL\Cache\QueryCacheProfile $profile
* @return \Doctrine\ORM\AbstractQuery
*/
public function setResultCacheProfile(QueryCacheProfile $profile = null)
{
if ( ! $profile->getResultCacheDriver()) {
$resultCacheDriver = $this->_em->getConfiguration()->getResultCacheImpl();
$profile = $profile->setResultCacheDriver($resultCacheDriver);
}
$this->_queryCacheProfile = $profile;
return $this;
}
/**
* Defines a cache driver to be used for caching result sets and implictly enables caching.
*
* @param \Doctrine\Common\Cache\Cache $driver Cache driver
* @return \Doctrine\ORM\AbstractQuery
*/
public function setResultCacheDriver($resultCacheDriver = null)
{
if ($resultCacheDriver !== null && ! ($resultCacheDriver instanceof \Doctrine\Common\Cache\Cache)) {
throw ORMException::invalidResultCacheDriver();
}
$this->_resultCacheDriver = $resultCacheDriver;
if ($resultCacheDriver) {
$this->_useResultCache = true;
}
$this->_queryCacheProfile = $this->_queryCacheProfile
? $this->_queryCacheProfile->setResultCacheDriver($resultCacheDriver)
: new QueryCacheProfile(0, null, $resultCacheDriver);
return $this;
}
/**
* Returns the cache driver used for caching result sets.
*
* @return Doctrine\Common\Cache\Cache Cache driver
* @deprecated
* @return \Doctrine\Common\Cache\Cache Cache driver
*/
public function getResultCacheDriver()
{
if ($this->_resultCacheDriver) {
return $this->_resultCacheDriver;
} else {
return $this->_em->getConfiguration()->getResultCacheImpl();
if ($this->_queryCacheProfile && $this->_queryCacheProfile->getResultCacheDriver()) {
return $this->_queryCacheProfile->getResultCacheDriver();
}
return $this->_em->getConfiguration()->getResultCacheImpl();
}
/**
@@ -267,57 +404,62 @@ abstract class AbstractQuery
* how long and which ID to use for the cache entry.
*
* @param boolean $bool
* @param integer $timeToLive
* @param integer $lifetime
* @param string $resultCacheId
* @return This query instance.
* @return \Doctrine\ORM\AbstractQuery This query instance.
*/
public function useResultCache($bool, $timeToLive = null, $resultCacheId = null)
public function useResultCache($bool, $lifetime = null, $resultCacheId = null)
{
$this->_useResultCache = $bool;
if ($timeToLive) {
$this->setResultCacheLifetime($timeToLive);
}
if ($resultCacheId) {
$this->_resultCacheId = $resultCacheId;
if ($bool) {
$this->setResultCacheLifetime($lifetime);
$this->setResultCacheId($resultCacheId);
return $this;
}
$this->_queryCacheProfile = null;
return $this;
}
/**
* Defines how long the result cache will be active before expire.
*
* @param integer $timeToLive How long the cache entry is valid.
* @return Doctrine\ORM\AbstractQuery This query instance.
* @param integer $lifetime How long the cache entry is valid.
* @return \Doctrine\ORM\AbstractQuery This query instance.
*/
public function setResultCacheLifetime($timeToLive)
public function setResultCacheLifetime($lifetime)
{
if ($timeToLive !== null) {
$timeToLive = (int) $timeToLive;
}
$lifetime = ($lifetime !== null) ? (int) $lifetime : 0;
$this->_queryCacheProfile = $this->_queryCacheProfile
? $this->_queryCacheProfile->setLifetime($lifetime)
: new QueryCacheProfile($lifetime, null, $this->_em->getConfiguration()->getResultCacheImpl());
$this->_resultCacheTTL = $timeToLive;
return $this;
}
/**
* Retrieves the lifetime of resultset cache.
*
* @deprecated
* @return integer
*/
public function getResultCacheLifetime()
{
return $this->_resultCacheTTL;
return $this->_queryCacheProfile ? $this->_queryCacheProfile->getLifetime() : 0;
}
/**
* Defines if the result cache is active or not.
*
* @param boolean $expire Whether or not to force resultset cache expiration.
* @return Doctrine\ORM\AbstractQuery This query instance.
* @return \Doctrine\ORM\AbstractQuery This query instance.
*/
public function expireResultCache($expire = true)
{
$this->_expireResultCache = $expire;
return $this;
}
@@ -331,16 +473,46 @@ abstract class AbstractQuery
return $this->_expireResultCache;
}
/**
* @return QueryCacheProfile
*/
public function getQueryCacheProfile()
{
return $this->_queryCacheProfile;
}
/**
* Change the default fetch mode of an association for this query.
*
* $fetchMode can be one of ClassMetadata::FETCH_EAGER or ClassMetadata::FETCH_LAZY
*
* @param string $class
* @param string $assocName
* @param int $fetchMode
* @return AbstractQuery
*/
public function setFetchMode($class, $assocName, $fetchMode)
{
if ($fetchMode !== Mapping\ClassMetadata::FETCH_EAGER) {
$fetchMode = Mapping\ClassMetadata::FETCH_LAZY;
}
$this->_hints['fetchMode'][$class][$assocName] = $fetchMode;
return $this;
}
/**
* Defines the processing mode to be used during hydration / result set transformation.
*
* @param integer $hydrationMode Doctrine processing mode to be used during hydration process.
* One of the Query::HYDRATE_* constants.
* @return Doctrine\ORM\AbstractQuery This query instance.
* @return \Doctrine\ORM\AbstractQuery This query instance.
*/
public function setHydrationMode($hydrationMode)
{
$this->_hydrationMode = $hydrationMode;
return $this;
}
@@ -357,37 +529,63 @@ abstract class AbstractQuery
/**
* Gets the list of results for the query.
*
* Alias for execute(array(), $hydrationMode = HYDRATE_OBJECT).
* Alias for execute(null, $hydrationMode = HYDRATE_OBJECT).
*
* @return array
*/
public function getResult($hydrationMode = self::HYDRATE_OBJECT)
{
return $this->execute(array(), $hydrationMode);
return $this->execute(null, $hydrationMode);
}
/**
* Gets the array of results for the query.
*
* Alias for execute(array(), HYDRATE_ARRAY).
* Alias for execute(null, HYDRATE_ARRAY).
*
* @return array
*/
public function getArrayResult()
{
return $this->execute(array(), self::HYDRATE_ARRAY);
return $this->execute(null, self::HYDRATE_ARRAY);
}
/**
* Gets the scalar results for the query.
*
* Alias for execute(array(), HYDRATE_SCALAR).
* Alias for execute(null, HYDRATE_SCALAR).
*
* @return array
*/
public function getScalarResult()
{
return $this->execute(array(), self::HYDRATE_SCALAR);
return $this->execute(null, self::HYDRATE_SCALAR);
}
/**
* Get exactly one result or null.
*
* @throws NonUniqueResultException
* @param int $hydrationMode
* @return mixed
*/
public function getOneOrNullResult($hydrationMode = null)
{
$result = $this->execute(null, $hydrationMode);
if ($this->_hydrationMode !== self::HYDRATE_SINGLE_SCALAR && ! $result) {
return null;
}
if ( ! is_array($result)) {
return $result;
}
if (count($result) > 1) {
throw new NonUniqueResultException;
}
return array_shift($result);
}
/**
@@ -405,20 +603,21 @@ abstract class AbstractQuery
*/
public function getSingleResult($hydrationMode = null)
{
$result = $this->execute(array(), $hydrationMode);
$result = $this->execute(null, $hydrationMode);
if ($this->_hydrationMode !== self::HYDRATE_SINGLE_SCALAR && ! $result) {
throw new NoResultException;
}
if (is_array($result)) {
if (count($result) > 1) {
throw new NonUniqueResultException;
}
return array_shift($result);
if ( ! is_array($result)) {
return $result;
}
return $result;
if (count($result) > 1) {
throw new NonUniqueResultException;
}
return array_shift($result);
}
/**
@@ -439,11 +638,12 @@ abstract class AbstractQuery
*
* @param string $name The name of the hint.
* @param mixed $value The value of the hint.
* @return Doctrine\ORM\AbstractQuery
* @return \Doctrine\ORM\AbstractQuery
*/
public function setHint($name, $value)
{
$this->_hints[$name] = $value;
return $this;
}
@@ -460,7 +660,7 @@ abstract class AbstractQuery
/**
* Return the key value map of query hints that are currently set.
*
*
* @return array
*/
public function getHints()
@@ -472,18 +672,18 @@ abstract class AbstractQuery
* Executes the query and returns an IterableResult that can be used to incrementally
* iterate over the result.
*
* @param array $params The query parameters.
* @param \Doctrine\Common\Collections\ArrayCollection|array $parameters The query parameters.
* @param integer $hydrationMode The hydration mode to use.
* @return IterableResult
* @return \Doctrine\ORM\Internal\Hydration\IterableResult
*/
public function iterate(array $params = array(), $hydrationMode = null)
public function iterate($parameters = null, $hydrationMode = null)
{
if ($hydrationMode !== null) {
$this->setHydrationMode($hydrationMode);
}
if ($params) {
$this->setParameters($params);
if ( ! empty($parameters)) {
$this->setParameters($parameters);
}
$stmt = $this->_doExecute();
@@ -496,69 +696,59 @@ abstract class AbstractQuery
/**
* Executes the query.
*
* @param array $params Any additional query parameters.
* @param \Doctrine\Common\Collections\ArrayCollection|array $parameters Query parameters.
* @param integer $hydrationMode Processing mode to be used during the hydration process.
* @return mixed
*/
public function execute($params = array(), $hydrationMode = null)
public function execute($parameters = null, $hydrationMode = null)
{
if ($hydrationMode !== null) {
$this->setHydrationMode($hydrationMode);
}
if ($params) {
$this->setParameters($params);
if ( ! empty($parameters)) {
$this->setParameters($parameters);
}
if (isset($this->_params[0])) {
throw QueryException::invalidParameterPosition(0);
}
$setCacheEntry = function() {};
// Check result cache
if ($this->_useResultCache && $cacheDriver = $this->getResultCacheDriver()) {
list($key, $hash) = $this->getResultCacheId();
$cached = $this->_expireResultCache ? false : $cacheDriver->fetch($hash);
if ($this->_hydrationCacheProfile !== null) {
list($cacheKey, $realCacheKey) = $this->getHydrationCacheId();
if ($cached === false || !isset($cached[$key])) {
// Cache miss.
$stmt = $this->_doExecute();
$queryCacheProfile = $this->getHydrationCacheProfile();
$cache = $queryCacheProfile->getResultCacheDriver();
$result = $cache->fetch($cacheKey);
$result = $this->_em->getHydrator($this->_hydrationMode)->hydrateAll(
$stmt, $this->_resultSetMapping, $this->_hints
);
$cacheDriver->save($hash, array($key => $result), $this->_resultCacheTTL);
return $result;
} else {
// Cache hit.
return $cached[$key];
if (isset($result[$realCacheKey])) {
return $result[$realCacheKey];
}
if ( ! $result) {
$result = array();
}
$setCacheEntry = function($data) use ($cache, $result, $cacheKey, $realCacheKey, $queryCacheProfile) {
$result[$realCacheKey] = $data;
$cache->save($cacheKey, $result, $queryCacheProfile->getLifetime());
};
}
$stmt = $this->_doExecute();
if (is_numeric($stmt)) {
$setCacheEntry($stmt);
return $stmt;
}
return $this->_em->getHydrator($this->_hydrationMode)->hydrateAll(
$stmt, $this->_resultSetMapping, $this->_hints
);
}
$data = $this->_em->getHydrator($this->_hydrationMode)->hydrateAll(
$stmt, $this->_resultSetMapping, $this->_hints
);
/**
* Set the result cache id to use to store the result set cache entry.
* If this is not explicitely set by the developer then a hash is automatically
* generated for you.
*
* @param string $id
* @return Doctrine\ORM\AbstractQuery This query instance.
*/
public function setResultCacheId($id)
{
$this->_resultCacheId = $id;
return $this;
$setCacheEntry($data);
return $data;
}
/**
@@ -568,38 +758,56 @@ abstract class AbstractQuery
*
* @return array ($key, $hash)
*/
protected function getResultCacheId()
protected function getHydrationCacheId()
{
if ($this->_resultCacheId) {
return array($this->_resultCacheId, $this->_resultCacheId);
} else {
$params = $this->_params;
foreach ($params AS $key => $value) {
if (is_object($value) && $this->_em->getMetadataFactory()->hasMetadataFor(get_class($value))) {
if ($this->_em->getUnitOfWork()->getEntityState($value) == UnitOfWork::STATE_MANAGED) {
$idValues = $this->_em->getUnitOfWork()->getEntityIdentifier($value);
} else {
$class = $this->_em->getClassMetadata(get_class($value));
$idValues = $class->getIdentifierValues($value);
}
$params[$key] = $idValues;
} else {
$params[$key] = $value;
}
}
$parameters = array();
$sql = $this->getSql();
ksort($this->_hints);
$key = implode(";", (array)$sql) . var_export($params, true) .
var_export($this->_hints, true)."&hydrationMode=".$this->_hydrationMode;
return array($key, md5($key));
foreach ($this->getParameters() as $parameter) {
$parameters[$parameter->getName()] = $this->processParameterValue($parameter->getValue());
}
$sql = $this->getSQL();
$queryCacheProfile = $this->getHydrationCacheProfile();
$hints = $this->getHints();
$hints['hydrationMode'] = $this->getHydrationMode();
ksort($hints);
return $queryCacheProfile->generateCacheKeys($sql, $parameters, $hints);
}
/**
* Set the result cache id to use to store the result set cache entry.
* If this is not explicitly set by the developer then a hash is automatically
* generated for you.
*
* @param string $id
* @return \Doctrine\ORM\AbstractQuery This query instance.
*/
public function setResultCacheId($id)
{
$this->_queryCacheProfile = $this->_queryCacheProfile
? $this->_queryCacheProfile->setCacheKey($id)
: new QueryCacheProfile(0, $id, $this->_em->getConfiguration()->getResultCacheImpl());
return $this;
}
/**
* Get the result cache id to use to store the result set cache entry if set.
*
* @deprecated
* @return string
*/
public function getResultCacheId()
{
return $this->_queryCacheProfile ? $this->_queryCacheProfile->getCacheKey() : null;
}
/**
* Executes the query and returns a the resulting Statement object.
*
* @return Doctrine\DBAL\Driver\Statement The executed database statement that holds the results.
* @return \Doctrine\DBAL\Driver\Statement The executed database statement that holds the results.
*/
abstract protected function _doExecute();
@@ -610,8 +818,8 @@ abstract class AbstractQuery
*/
public function __clone()
{
$this->_params = array();
$this->_paramTypes = array();
$this->parameters = new ArrayCollection();
$this->_hints = array();
}
}

View File

@@ -13,14 +13,24 @@
* 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 LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM;
use Doctrine\Common\Cache\Cache,
Doctrine\ORM\Mapping\Driver\Driver;
Doctrine\Common\Cache\ArrayCache,
Doctrine\Common\Annotations\AnnotationRegistry,
Doctrine\Common\Annotations\AnnotationReader,
Doctrine\Common\Persistence\Mapping\Driver\MappingDriver,
Doctrine\ORM\Mapping\Driver\AnnotationDriver,
Doctrine\ORM\Mapping\QuoteStrategy,
Doctrine\ORM\Mapping\DefaultQuoteStrategy,
Doctrine\ORM\Mapping\NamingStrategy,
Doctrine\ORM\Mapping\DefaultNamingStrategy,
Doctrine\Common\Annotations\SimpleAnnotationReader,
Doctrine\Common\Annotations\CachedReader;
/**
* Configuration container for all configuration options of Doctrine.
@@ -52,8 +62,9 @@ class Configuration extends \Doctrine\DBAL\Configuration
*/
public function getProxyDir()
{
return isset($this->_attributes['proxyDir']) ?
$this->_attributes['proxyDir'] : null;
return isset($this->_attributes['proxyDir'])
? $this->_attributes['proxyDir']
: null;
}
/**
@@ -64,8 +75,9 @@ class Configuration extends \Doctrine\DBAL\Configuration
*/
public function getAutoGenerateProxyClasses()
{
return isset($this->_attributes['autoGenerateProxyClasses']) ?
$this->_attributes['autoGenerateProxyClasses'] : true;
return isset($this->_attributes['autoGenerateProxyClasses'])
? $this->_attributes['autoGenerateProxyClasses']
: true;
}
/**
@@ -81,18 +93,19 @@ class Configuration extends \Doctrine\DBAL\Configuration
/**
* Gets the namespace where proxy classes reside.
*
*
* @return string
*/
public function getProxyNamespace()
{
return isset($this->_attributes['proxyNamespace']) ?
$this->_attributes['proxyNamespace'] : null;
return isset($this->_attributes['proxyNamespace'])
? $this->_attributes['proxyNamespace']
: null;
}
/**
* Sets the namespace where proxy classes reside.
*
*
* @param string $ns
*/
public function setProxyNamespace($ns)
@@ -103,27 +116,40 @@ class Configuration extends \Doctrine\DBAL\Configuration
/**
* Sets the cache driver implementation that is used for metadata caching.
*
* @param Driver $driverImpl
* @param MappingDriver $driverImpl
* @todo Force parameter to be a Closure to ensure lazy evaluation
* (as soon as a metadata cache is in effect, the driver never needs to initialize).
*/
public function setMetadataDriverImpl(Driver $driverImpl)
public function setMetadataDriverImpl(MappingDriver $driverImpl)
{
$this->_attributes['metadataDriverImpl'] = $driverImpl;
}
/**
* Add a new default annotation driver with a correctly configured annotation reader.
*
* Add a new default annotation driver with a correctly configured annotation reader. If $useSimpleAnnotationReader
* is true, the notation `@Entity` will work, otherwise, the notation `@ORM\Entity` will be supported.
*
* @param array $paths
* @return Mapping\Driver\AnnotationDriver
* @param bool $useSimpleAnnotationReader
* @return AnnotationDriver
*/
public function newDefaultAnnotationDriver($paths = array())
public function newDefaultAnnotationDriver($paths = array(), $useSimpleAnnotationReader = true)
{
$reader = new \Doctrine\Common\Annotations\AnnotationReader();
$reader->setDefaultAnnotationNamespace('Doctrine\ORM\Mapping\\');
return new \Doctrine\ORM\Mapping\Driver\AnnotationDriver($reader, (array)$paths);
AnnotationRegistry::registerFile(__DIR__ . '/Mapping/Driver/DoctrineAnnotations.php');
if ($useSimpleAnnotationReader) {
// Register the ORM Annotations in the AnnotationRegistry
$reader = new SimpleAnnotationReader();
$reader->addNamespace('Doctrine\ORM\Mapping');
$cachedReader = new CachedReader($reader, new ArrayCache());
return new AnnotationDriver($cachedReader, (array) $paths);
}
return new AnnotationDriver(
new CachedReader(new AnnotationReader(), new ArrayCache()),
(array) $paths
);
}
/**
@@ -140,9 +166,9 @@ class Configuration extends \Doctrine\DBAL\Configuration
/**
* Resolves a registered namespace alias to the full namespace.
*
* @param string $entityNamespaceAlias
* @param string $entityNamespaceAlias
* @throws ORMException
* @return string
* @throws MappingException
*/
public function getEntityNamespace($entityNamespaceAlias)
{
@@ -156,45 +182,34 @@ class Configuration extends \Doctrine\DBAL\Configuration
/**
* Set the entity alias map
*
* @param array $entityAliasMap
* @return void
* @param array $entityNamespaces
*/
public function setEntityNamespaces(array $entityNamespaces)
{
$this->_attributes['entityNamespaces'] = $entityNamespaces;
}
/**
* Retrieves the list of registered entity namespace aliases.
*
* @return array
*/
public function getEntityNamespaces()
{
return $this->_attributes['entityNamespaces'];
}
/**
* Gets the cache driver implementation that is used for the mapping metadata.
*
* @throws ORMException
* @return Mapping\Driver\Driver
* @return MappingDriver
*/
public function getMetadataDriverImpl()
{
return isset($this->_attributes['metadataDriverImpl']) ?
$this->_attributes['metadataDriverImpl'] : null;
}
/**
* Gets the cache driver implementation that is used for query result caching.
*
* @return \Doctrine\Common\Cache\Cache
*/
public function getResultCacheImpl()
{
return isset($this->_attributes['resultCacheImpl']) ?
$this->_attributes['resultCacheImpl'] : null;
}
/**
* Sets the cache driver implementation that is used for query result caching.
*
* @param \Doctrine\Common\Cache\Cache $cacheImpl
*/
public function setResultCacheImpl(Cache $cacheImpl)
{
$this->_attributes['resultCacheImpl'] = $cacheImpl;
return isset($this->_attributes['metadataDriverImpl'])
? $this->_attributes['metadataDriverImpl']
: null;
}
/**
@@ -204,8 +219,9 @@ class Configuration extends \Doctrine\DBAL\Configuration
*/
public function getQueryCacheImpl()
{
return isset($this->_attributes['queryCacheImpl']) ?
$this->_attributes['queryCacheImpl'] : null;
return isset($this->_attributes['queryCacheImpl'])
? $this->_attributes['queryCacheImpl']
: null;
}
/**
@@ -218,6 +234,28 @@ class Configuration extends \Doctrine\DBAL\Configuration
$this->_attributes['queryCacheImpl'] = $cacheImpl;
}
/**
* Gets the cache driver implementation that is used for the hydration cache (SQL cache).
*
* @return \Doctrine\Common\Cache\Cache
*/
public function getHydrationCacheImpl()
{
return isset($this->_attributes['hydrationCacheImpl'])
? $this->_attributes['hydrationCacheImpl']
: null;
}
/**
* Sets the cache driver implementation that is used for the hydration cache (SQL cache).
*
* @param \Doctrine\Common\Cache\Cache $cacheImpl
*/
public function setHydrationCacheImpl(Cache $cacheImpl)
{
$this->_attributes['hydrationCacheImpl'] = $cacheImpl;
}
/**
* Gets the cache driver implementation that is used for metadata caching.
*
@@ -225,8 +263,9 @@ class Configuration extends \Doctrine\DBAL\Configuration
*/
public function getMetadataCacheImpl()
{
return isset($this->_attributes['metadataCacheImpl']) ?
$this->_attributes['metadataCacheImpl'] : null;
return isset($this->_attributes['metadataCacheImpl'])
? $this->_attributes['metadataCacheImpl']
: null;
}
/**
@@ -254,6 +293,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
* Gets a previously registered named DQL query.
*
* @param string $name The name of the query.
* @throws ORMException
* @return string The DQL query.
*/
public function getNamedQuery($name)
@@ -261,15 +301,16 @@ class Configuration extends \Doctrine\DBAL\Configuration
if ( ! isset($this->_attributes['namedQueries'][$name])) {
throw ORMException::namedQueryNotFound($name);
}
return $this->_attributes['namedQueries'][$name];
}
/**
* Adds a named native query to the configuration.
*
* @param string $name The name of the query.
* @param string $sql The native SQL query string.
* @param ResultSetMapping $rsm The ResultSetMapping used for the results of the SQL query.
* @param string $name The name of the query.
* @param string $sql The native SQL query string.
* @param Query\ResultSetMapping $rsm The ResultSetMapping used for the results of the SQL query.
*/
public function addNamedNativeQuery($name, $sql, Query\ResultSetMapping $rsm)
{
@@ -279,15 +320,17 @@ class Configuration extends \Doctrine\DBAL\Configuration
/**
* Gets the components of a previously registered named native query.
*
* @param string $name The name of the query.
* @return array A tuple with the first element being the SQL string and the second
* element being the ResultSetMapping.
* @param string $name The name of the query.
* @throws ORMException
* @return array A tuple with the first element being the SQL string and the second
* element being the ResultSetMapping.
*/
public function getNamedNativeQuery($name)
{
if ( ! isset($this->_attributes['namedNativeQueries'][$name])) {
throw ORMException::namedNativeQueryNotFound($name);
}
return $this->_attributes['namedNativeQueries'][$name];
}
@@ -300,12 +343,14 @@ class Configuration extends \Doctrine\DBAL\Configuration
*/
public function ensureProductionSettings()
{
if ( !$this->getQueryCacheImpl()) {
if ( ! $this->getQueryCacheImpl()) {
throw ORMException::queryCacheNotConfigured();
}
if ( !$this->getMetadataCacheImpl()) {
if ( ! $this->getMetadataCacheImpl()) {
throw ORMException::metadataCacheNotConfigured();
}
if ($this->getAutoGenerateProxyClasses()) {
throw ORMException::proxyClassesAlwaysRegenerating();
}
@@ -320,23 +365,30 @@ class Configuration extends \Doctrine\DBAL\Configuration
*
* @param string $name
* @param string $className
* @throws ORMException
*/
public function addCustomStringFunction($name, $className)
{
if (Query\Parser::isInternalFunction($name)) {
throw ORMException::overwriteInternalDQLFunctionNotAllowed($name);
}
$this->_attributes['customStringFunctions'][strtolower($name)] = $className;
}
/**
* Gets the implementation class name of a registered custom string DQL function.
*
*
* @param string $name
* @return string
*/
public function getCustomStringFunction($name)
{
$name = strtolower($name);
return isset($this->_attributes['customStringFunctions'][$name]) ?
$this->_attributes['customStringFunctions'][$name] : null;
return isset($this->_attributes['customStringFunctions'][$name])
? $this->_attributes['customStringFunctions'][$name]
: null;
}
/**
@@ -351,7 +403,9 @@ class Configuration extends \Doctrine\DBAL\Configuration
*/
public function setCustomStringFunctions(array $functions)
{
$this->_attributes['customStringFunctions'] = array_change_key_case($functions);
foreach ($functions as $name => $className) {
$this->addCustomStringFunction($name, $className);
}
}
/**
@@ -363,23 +417,30 @@ class Configuration extends \Doctrine\DBAL\Configuration
*
* @param string $name
* @param string $className
* @throws ORMException
*/
public function addCustomNumericFunction($name, $className)
{
if (Query\Parser::isInternalFunction($name)) {
throw ORMException::overwriteInternalDQLFunctionNotAllowed($name);
}
$this->_attributes['customNumericFunctions'][strtolower($name)] = $className;
}
/**
* Gets the implementation class name of a registered custom numeric DQL function.
*
*
* @param string $name
* @return string
*/
public function getCustomNumericFunction($name)
{
$name = strtolower($name);
return isset($this->_attributes['customNumericFunctions'][$name]) ?
$this->_attributes['customNumericFunctions'][$name] : null;
return isset($this->_attributes['customNumericFunctions'][$name])
? $this->_attributes['customNumericFunctions'][$name]
: null;
}
/**
@@ -394,7 +455,9 @@ class Configuration extends \Doctrine\DBAL\Configuration
*/
public function setCustomNumericFunctions(array $functions)
{
$this->_attributes['customNumericFunctions'] = array_change_key_case($functions);
foreach ($functions as $name => $className) {
$this->addCustomNumericFunction($name, $className);
}
}
/**
@@ -406,23 +469,30 @@ class Configuration extends \Doctrine\DBAL\Configuration
*
* @param string $name
* @param string $className
* @throws ORMException
*/
public function addCustomDatetimeFunction($name, $className)
{
if (Query\Parser::isInternalFunction($name)) {
throw ORMException::overwriteInternalDQLFunctionNotAllowed($name);
}
$this->_attributes['customDatetimeFunctions'][strtolower($name)] = $className;
}
/**
* Gets the implementation class name of a registered custom date/time DQL function.
*
*
* @param string $name
* @return string
*/
public function getCustomDatetimeFunction($name)
{
$name = strtolower($name);
return isset($this->_attributes['customDatetimeFunctions'][$name]) ?
$this->_attributes['customDatetimeFunctions'][$name] : null;
return isset($this->_attributes['customDatetimeFunctions'][$name])
? $this->_attributes['customDatetimeFunctions'][$name]
: null;
}
/**
@@ -437,7 +507,23 @@ class Configuration extends \Doctrine\DBAL\Configuration
*/
public function setCustomDatetimeFunctions(array $functions)
{
$this->_attributes['customDatetimeFunctions'] = array_change_key_case($functions);
foreach ($functions as $name => $className) {
$this->addCustomDatetimeFunction($name, $className);
}
}
/**
* Set the custom hydrator modes in one pass.
*
* @param array An array of ($modeName => $hydrator)
*/
public function setCustomHydrationModes($modes)
{
$this->_attributes['customHydrationModes'] = array();
foreach ($modes as $modeName => $hydrator) {
$this->addCustomHydrationMode($modeName, $hydrator);
}
}
/**
@@ -448,8 +534,9 @@ class Configuration extends \Doctrine\DBAL\Configuration
*/
public function getCustomHydrationMode($modeName)
{
return isset($this->_attributes['customHydrationModes'][$modeName]) ?
$this->_attributes['customHydrationModes'][$modeName] : null;
return isset($this->_attributes['customHydrationModes'][$modeName])
? $this->_attributes['customHydrationModes'][$modeName]
: null;
}
/**
@@ -465,8 +552,8 @@ class Configuration extends \Doctrine\DBAL\Configuration
/**
* Set a class metadata factory.
*
* @param string $cmf
*
* @param string $cmfName
*/
public function setClassMetadataFactoryName($cmfName)
{
@@ -478,9 +565,119 @@ class Configuration extends \Doctrine\DBAL\Configuration
*/
public function getClassMetadataFactoryName()
{
if (!isset($this->_attributes['classMetadataFactoryName'])) {
if ( ! isset($this->_attributes['classMetadataFactoryName'])) {
$this->_attributes['classMetadataFactoryName'] = 'Doctrine\ORM\Mapping\ClassMetadataFactory';
}
return $this->_attributes['classMetadataFactoryName'];
}
}
/**
* Add a filter to the list of possible filters.
*
* @param string $name The name of the filter.
* @param string $className The class name of the filter.
*/
public function addFilter($name, $className)
{
$this->_attributes['filters'][$name] = $className;
}
/**
* Gets the class name for a given filter name.
*
* @param string $name The name of the filter.
*
* @return string The class name of the filter, or null of it is not
* defined.
*/
public function getFilterClassName($name)
{
return isset($this->_attributes['filters'][$name])
? $this->_attributes['filters'][$name]
: null;
}
/**
* Set default repository class.
*
* @since 2.2
* @param string $className
* @throws ORMException If not is a \Doctrine\Common\Persistence\ObjectRepository
*/
public function setDefaultRepositoryClassName($className)
{
$reflectionClass = new \ReflectionClass($className);
if ( ! $reflectionClass->implementsInterface('Doctrine\Common\Persistence\ObjectRepository')) {
throw ORMException::invalidEntityRepository($className);
}
$this->_attributes['defaultRepositoryClassName'] = $className;
}
/**
* Get default repository class.
*
* @since 2.2
* @return string
*/
public function getDefaultRepositoryClassName()
{
return isset($this->_attributes['defaultRepositoryClassName'])
? $this->_attributes['defaultRepositoryClassName']
: 'Doctrine\ORM\EntityRepository';
}
/**
* Set naming strategy.
*
* @since 2.3
* @param NamingStrategy $namingStrategy
*/
public function setNamingStrategy(NamingStrategy $namingStrategy)
{
$this->_attributes['namingStrategy'] = $namingStrategy;
}
/**
* Get naming strategy..
*
* @since 2.3
* @return NamingStrategy
*/
public function getNamingStrategy()
{
if ( ! isset($this->_attributes['namingStrategy'])) {
$this->_attributes['namingStrategy'] = new DefaultNamingStrategy();
}
return $this->_attributes['namingStrategy'];
}
/**
* Set quote strategy.
*
* @since 2.3
* @param Doctrine\ORM\Mapping\QuoteStrategy $quoteStrategy
*/
public function setQuoteStrategy(QuoteStrategy $quoteStrategy)
{
$this->_attributes['quoteStrategy'] = $quoteStrategy;
}
/**
* Get quote strategy.
*
* @since 2.3
* @return Doctrine\ORM\Mapping\QuoteStrategy
*/
public function getQuoteStrategy()
{
if ( ! isset($this->_attributes['quoteStrategy'])) {
$this->_attributes['quoteStrategy'] = new DefaultQuoteStrategy();
}
return $this->_attributes['quoteStrategy'];
}
}

View File

@@ -13,20 +13,22 @@
* 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 LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM;
use Closure, Exception,
use Exception,
Doctrine\Common\EventManager,
Doctrine\Common\Persistence\ObjectManager,
Doctrine\DBAL\Connection,
Doctrine\DBAL\LockMode,
Doctrine\ORM\Mapping\ClassMetadata,
Doctrine\ORM\Mapping\ClassMetadataFactory,
Doctrine\ORM\Query\ResultSetMapping,
Doctrine\ORM\Proxy\ProxyFactory;
Doctrine\ORM\Proxy\ProxyFactory,
Doctrine\ORM\Query\FilterCollection;
/**
* The EntityManager is the central access point to ORM functionality.
@@ -37,26 +39,26 @@ use Closure, Exception,
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class EntityManager
class EntityManager implements ObjectManager
{
/**
* The used Configuration.
*
* @var Doctrine\ORM\Configuration
* @var \Doctrine\ORM\Configuration
*/
private $config;
/**
* The database connection used by the EntityManager.
*
* @var Doctrine\DBAL\Connection
* @var \Doctrine\DBAL\Connection
*/
private $conn;
/**
* The metadata factory, used to retrieve the ORM metadata of entity classes.
*
* @var Doctrine\ORM\Mapping\ClassMetadataFactory
* @var \Doctrine\ORM\Mapping\ClassMetadataFactory
*/
private $metadataFactory;
@@ -70,14 +72,14 @@ class EntityManager
/**
* The UnitOfWork used to coordinate object-level transactions.
*
* @var Doctrine\ORM\UnitOfWork
* @var \Doctrine\ORM\UnitOfWork
*/
private $unitOfWork;
/**
* The event manager that is the central point of the event system.
*
* @var Doctrine\Common\EventManager
* @var \Doctrine\Common\EventManager
*/
private $eventManager;
@@ -91,14 +93,14 @@ class EntityManager
/**
* The proxy factory used to create dynamic proxies.
*
* @var Doctrine\ORM\Proxy\ProxyFactory
* @var \Doctrine\ORM\Proxy\ProxyFactory
*/
private $proxyFactory;
/**
* The expression builder instance used to generate query expressions.
*
* @var Doctrine\ORM\Query\Expr
* @var \Doctrine\ORM\Query\Expr
*/
private $expressionBuilder;
@@ -109,36 +111,46 @@ class EntityManager
*/
private $closed = false;
/**
* Collection of query filters.
*
* @var Doctrine\ORM\Query\FilterCollection
*/
private $filterCollection;
/**
* Creates a new EntityManager that operates on the given database connection
* and uses the given Configuration and EventManager implementations.
*
* @param Doctrine\DBAL\Connection $conn
* @param Doctrine\ORM\Configuration $config
* @param Doctrine\Common\EventManager $eventManager
* @param \Doctrine\DBAL\Connection $conn
* @param \Doctrine\ORM\Configuration $config
* @param \Doctrine\Common\EventManager $eventManager
*/
protected function __construct(Connection $conn, Configuration $config, EventManager $eventManager)
{
$this->conn = $conn;
$this->config = $config;
$this->conn = $conn;
$this->config = $config;
$this->eventManager = $eventManager;
$metadataFactoryClassName = $config->getClassMetadataFactoryName();
$this->metadataFactory = new $metadataFactoryClassName;
$this->metadataFactory->setEntityManager($this);
$this->metadataFactory->setCacheDriver($this->config->getMetadataCacheImpl());
$this->unitOfWork = new UnitOfWork($this);
$this->proxyFactory = new ProxyFactory($this,
$config->getProxyDir(),
$config->getProxyNamespace(),
$config->getAutoGenerateProxyClasses());
$this->unitOfWork = new UnitOfWork($this);
$this->proxyFactory = new ProxyFactory(
$this,
$config->getProxyDir(),
$config->getProxyNamespace(),
$config->getAutoGenerateProxyClasses()
);
}
/**
* Gets the database connection object used by the EntityManager.
*
* @return Doctrine\DBAL\Connection
* @return \Doctrine\DBAL\Connection
*/
public function getConnection()
{
@@ -148,7 +160,7 @@ class EntityManager
/**
* Gets the metadata factory used to gather the metadata of classes.
*
* @return Doctrine\ORM\Mapping\ClassMetadataFactory
* @return \Doctrine\ORM\Mapping\ClassMetadataFactory
*/
public function getMetadataFactory()
{
@@ -167,20 +179,19 @@ class EntityManager
* ->where($expr->orX($expr->eq('u.id', 1), $expr->eq('u.id', 2)));
* </code>
*
* @return Doctrine\ORM\Query\Expr
* @return \Doctrine\ORM\Query\Expr
*/
public function getExpressionBuilder()
{
if ($this->expressionBuilder === null) {
$this->expressionBuilder = new Query\Expr;
}
return $this->expressionBuilder;
}
/**
* Starts a transaction on the underlying database connection.
*
* @deprecated Use {@link getConnection}.beginTransaction().
*/
public function beginTransaction()
{
@@ -197,26 +208,34 @@ class EntityManager
* If an exception occurs during execution of the function or flushing or transaction commit,
* the transaction is rolled back, the EntityManager closed and the exception re-thrown.
*
* @param Closure $func The function to execute transactionally.
* @param callable $func The function to execute transactionally.
* @return mixed Returns the non-empty value returned from the closure or true instead
*/
public function transactional(Closure $func)
public function transactional($func)
{
if (!is_callable($func)) {
throw new \InvalidArgumentException('Expected argument of type "callable", got "' . gettype($func) . '"');
}
$this->conn->beginTransaction();
try {
$func($this);
$return = call_user_func($func, $this);
$this->flush();
$this->conn->commit();
return $return ?: true;
} catch (Exception $e) {
$this->close();
$this->conn->rollback();
throw $e;
}
}
/**
* Commits a transaction on the underlying database connection.
*
* @deprecated Use {@link getConnection}.commit().
*/
public function commit()
{
@@ -225,8 +244,6 @@ class EntityManager
/**
* Performs a rollback on the underlying database connection.
*
* @deprecated Use {@link getConnection}.rollback().
*/
public function rollback()
{
@@ -238,12 +255,12 @@ class EntityManager
*
* The class name must be the fully-qualified class name without a leading backslash
* (as it is returned by get_class($obj)) or an aliased class name.
*
*
* Examples:
* MyProject\Domain\User
* sales:PriceRequest
*
* @return Doctrine\ORM\Mapping\ClassMetadata
* @return \Doctrine\ORM\Mapping\ClassMetadata
* @internal Performance-sensitive method.
*/
public function getClassMetadata($className)
@@ -254,15 +271,17 @@ class EntityManager
/**
* Creates a new Query object.
*
* @param string The DQL string.
* @return Doctrine\ORM\Query
* @param string $dql The DQL string.
* @return \Doctrine\ORM\Query
*/
public function createQuery($dql = "")
{
$query = new Query($this);
if ( ! empty($dql)) {
$query->setDql($dql);
}
return $query;
}
@@ -270,7 +289,7 @@ class EntityManager
* Creates a Query from a named query.
*
* @param string $name
* @return Doctrine\ORM\Query
* @return \Doctrine\ORM\Query
*/
public function createNamedQuery($name)
{
@@ -287,8 +306,10 @@ class EntityManager
public function createNativeQuery($sql, ResultSetMapping $rsm)
{
$query = new NativeQuery($this);
$query->setSql($sql);
$query->setResultSetMapping($rsm);
return $query;
}
@@ -296,11 +317,12 @@ class EntityManager
* Creates a NativeQuery from a named native query.
*
* @param string $name
* @return Doctrine\ORM\NativeQuery
* @return \Doctrine\ORM\NativeQuery
*/
public function createNamedNativeQuery($name)
{
list($sql, $rsm) = $this->config->getNamedNativeQuery($name);
return $this->createNativeQuery($sql, $rsm);
}
@@ -319,29 +341,95 @@ class EntityManager
* This effectively synchronizes the in-memory state of managed objects with the
* database.
*
* @throws Doctrine\ORM\OptimisticLockException If a version check on an entity that
* If an entity is explicitly passed to this method only this entity and
* the cascade-persist semantics + scheduled inserts/removals are synchronized.
*
* @param object $entity
* @throws \Doctrine\ORM\OptimisticLockException If a version check on an entity that
* makes use of optimistic locking fails.
*/
public function flush()
public function flush($entity = null)
{
$this->errorIfClosed();
$this->unitOfWork->commit();
}
$this->unitOfWork->commit($entity);
}
/**
* Finds an Entity by its identifier.
*
* This is just a convenient shortcut for getRepository($entityName)->find($id).
*
* @param string $entityName
* @param mixed $identifier
* @param int $lockMode
* @param int $lockVersion
* @param mixed $id
* @param integer $lockMode
* @param integer $lockVersion
*
* @return object
*/
public function find($entityName, $identifier, $lockMode = LockMode::NONE, $lockVersion = null)
public function find($entityName, $id, $lockMode = LockMode::NONE, $lockVersion = null)
{
return $this->getRepository($entityName)->find($identifier, $lockMode, $lockVersion);
$class = $this->metadataFactory->getMetadataFor(ltrim($entityName, '\\'));
if ( ! is_array($id)) {
$id = array($class->identifier[0] => $id);
}
$sortedId = array();
foreach ($class->identifier as $identifier) {
if ( ! isset($id[$identifier])) {
throw ORMException::missingIdentifierField($class->name, $identifier);
}
$sortedId[$identifier] = $id[$identifier];
}
$unitOfWork = $this->getUnitOfWork();
// Check identity map first
if (($entity = $unitOfWork->tryGetById($sortedId, $class->rootEntityName)) !== false) {
if ( ! ($entity instanceof $class->name)) {
return null;
}
switch ($lockMode) {
case LockMode::OPTIMISTIC:
$this->lock($entity, $lockMode, $lockVersion);
break;
case LockMode::PESSIMISTIC_READ:
case LockMode::PESSIMISTIC_WRITE:
$persister = $unitOfWork->getEntityPersister($class->name);
$persister->refresh($sortedId, $entity, $lockMode);
break;
}
return $entity; // Hit!
}
$persister = $unitOfWork->getEntityPersister($class->name);
switch ($lockMode) {
case LockMode::NONE:
return $persister->load($sortedId);
case LockMode::OPTIMISTIC:
if ( ! $class->isVersioned) {
throw OptimisticLockException::notVersioned($class->name);
}
$entity = $persister->load($sortedId);
$unitOfWork->lock($entity, $lockMode, $lockVersion);
return $entity;
default:
if ( ! $this->getConnection()->isTransactionActive()) {
throw TransactionRequiredException::transactionRequired();
}
return $persister->load($sortedId, null, null, array(), $lockMode);
}
}
/**
@@ -349,27 +437,44 @@ class EntityManager
* without actually loading it, if the entity is not yet loaded.
*
* @param string $entityName The name of the entity type.
* @param mixed $identifier The entity identifier.
* @param mixed $id The entity identifier.
* @return object The entity reference.
*/
public function getReference($entityName, $identifier)
public function getReference($entityName, $id)
{
$class = $this->metadataFactory->getMetadataFor(ltrim($entityName, '\\'));
if ( ! is_array($id)) {
$id = array($class->identifier[0] => $id);
}
$sortedId = array();
foreach ($class->identifier as $identifier) {
if ( ! isset($id[$identifier])) {
throw ORMException::missingIdentifierField($class->name, $identifier);
}
$sortedId[$identifier] = $id[$identifier];
}
// Check identity map first, if its already in there just return it.
if ($entity = $this->unitOfWork->tryGetById($identifier, $class->rootEntityName)) {
if (($entity = $this->unitOfWork->tryGetById($sortedId, $class->rootEntityName)) !== false) {
return ($entity instanceof $class->name) ? $entity : null;
}
if ($class->subClasses) {
$entity = $this->find($entityName, $identifier);
} else {
if ( ! is_array($identifier)) {
$identifier = array($class->identifier[0] => $identifier);
}
$entity = $this->proxyFactory->getProxy($class->name, $identifier);
$this->unitOfWork->registerManaged($entity, $identifier, array());
return $this->find($entityName, $sortedId);
}
if ( ! is_array($sortedId)) {
$sortedId = array($class->identifier[0] => $sortedId);
}
$entity = $this->proxyFactory->getProxy($class->name, $sortedId);
$this->unitOfWork->registerManaged($entity, $sortedId, array());
return $entity;
}
@@ -397,16 +502,20 @@ class EntityManager
$class = $this->metadataFactory->getMetadataFor(ltrim($entityName, '\\'));
// Check identity map first, if its already in there just return it.
if ($entity = $this->unitOfWork->tryGetById($identifier, $class->rootEntityName)) {
if (($entity = $this->unitOfWork->tryGetById($identifier, $class->rootEntityName)) !== false) {
return ($entity instanceof $class->name) ? $entity : null;
}
if ( ! is_array($identifier)) {
$identifier = array($class->identifier[0] => $identifier);
}
$entity = $class->newInstance();
$class->setIdentifierValues($entity, $identifier);
$this->unitOfWork->registerManaged($entity, $identifier, array());
$this->unitOfWork->markReadOnly($entity);
return $entity;
}
@@ -415,16 +524,11 @@ class EntityManager
* Clears the EntityManager. All entities that are currently managed
* by this EntityManager become detached.
*
* @param string $entityName
* @param string $entityName if given, only entities of this type will get detached
*/
public function clear($entityName = null)
{
if ($entityName === null) {
$this->unitOfWork->clear();
} else {
//TODO
throw new ORMException("EntityManager#clear(\$entityName) not yet implemented.");
}
$this->unitOfWork->clear($entityName);
}
/**
@@ -435,6 +539,7 @@ class EntityManager
public function close()
{
$this->clear();
$this->closed = true;
}
@@ -443,7 +548,7 @@ class EntityManager
*
* The entity will be entered into the database at or before transaction
* commit or as a result of the flush operation.
*
*
* NOTE: The persist operation always considers entities that are not yet known to
* this EntityManager as NEW. Do not pass detached entities to the persist operation.
*
@@ -452,9 +557,11 @@ class EntityManager
public function persist($entity)
{
if ( ! is_object($entity)) {
throw new \InvalidArgumentException(gettype($entity));
throw ORMInvalidArgumentException::invalidObject('EntityManager#persist()' , $entity);
}
$this->errorIfClosed();
$this->unitOfWork->persist($entity);
}
@@ -469,9 +576,11 @@ class EntityManager
public function remove($entity)
{
if ( ! is_object($entity)) {
throw new \InvalidArgumentException(gettype($entity));
throw ORMInvalidArgumentException::invalidObject('EntityManager#remove()' , $entity);
}
$this->errorIfClosed();
$this->unitOfWork->remove($entity);
}
@@ -484,9 +593,11 @@ class EntityManager
public function refresh($entity)
{
if ( ! is_object($entity)) {
throw new \InvalidArgumentException(gettype($entity));
throw ORMInvalidArgumentException::invalidObject('EntityManager#refresh()' , $entity);
}
$this->errorIfClosed();
$this->unitOfWork->refresh($entity);
}
@@ -502,8 +613,9 @@ class EntityManager
public function detach($entity)
{
if ( ! is_object($entity)) {
throw new \InvalidArgumentException(gettype($entity));
throw ORMInvalidArgumentException::invalidObject('EntityManager#detach()' , $entity);
}
$this->unitOfWork->detach($entity);
}
@@ -518,9 +630,11 @@ class EntityManager
public function merge($entity)
{
if ( ! is_object($entity)) {
throw new \InvalidArgumentException(gettype($entity));
throw ORMInvalidArgumentException::invalidObject('EntityManager#merge()' , $entity);
}
$this->errorIfClosed();
return $this->unitOfWork->merge($entity);
}
@@ -560,19 +674,20 @@ class EntityManager
public function getRepository($entityName)
{
$entityName = ltrim($entityName, '\\');
if (isset($this->repositories[$entityName])) {
return $this->repositories[$entityName];
}
$metadata = $this->getClassMetadata($entityName);
$customRepositoryClassName = $metadata->customRepositoryClassName;
$repositoryClassName = $metadata->customRepositoryClassName;
if ($customRepositoryClassName !== null) {
$repository = new $customRepositoryClassName($this, $metadata);
} else {
$repository = new EntityRepository($this, $metadata);
if ($repositoryClassName === null) {
$repositoryClassName = $this->config->getDefaultRepositoryClassName();
}
$repository = new $repositoryClassName($this, $metadata);
$this->repositories[$entityName] = $repository;
return $repository;
@@ -586,15 +701,15 @@ class EntityManager
*/
public function contains($entity)
{
return $this->unitOfWork->isScheduledForInsert($entity) ||
$this->unitOfWork->isInIdentityMap($entity) &&
! $this->unitOfWork->isScheduledForDelete($entity);
return $this->unitOfWork->isScheduledForInsert($entity)
|| $this->unitOfWork->isInIdentityMap($entity)
&& ! $this->unitOfWork->isScheduledForDelete($entity);
}
/**
* Gets the EventManager used by the EntityManager.
*
* @return Doctrine\Common\EventManager
* @return \Doctrine\Common\EventManager
*/
public function getEventManager()
{
@@ -604,7 +719,7 @@ class EntityManager
/**
* Gets the Configuration used by the EntityManager.
*
* @return Doctrine\ORM\Configuration
* @return \Doctrine\ORM\Configuration
*/
public function getConfiguration()
{
@@ -625,7 +740,7 @@ class EntityManager
/**
* Check if the Entity manager is open or closed.
*
*
* @return bool
*/
public function isOpen()
@@ -636,7 +751,7 @@ class EntityManager
/**
* Gets the UnitOfWork used by the EntityManager to coordinate operations.
*
* @return Doctrine\ORM\UnitOfWork
* @return \Doctrine\ORM\UnitOfWork
*/
public function getUnitOfWork()
{
@@ -650,7 +765,7 @@ class EntityManager
* selectively iterate over the result.
*
* @param int $hydrationMode
* @return Doctrine\ORM\Internal\Hydration\AbstractHydrator
* @return \Doctrine\ORM\Internal\Hydration\AbstractHydrator
*/
public function getHydrator($hydrationMode)
{
@@ -665,32 +780,33 @@ class EntityManager
* Create a new instance for the given hydration mode.
*
* @param int $hydrationMode
* @return Doctrine\ORM\Internal\Hydration\AbstractHydrator
* @return \Doctrine\ORM\Internal\Hydration\AbstractHydrator
*/
public function newHydrator($hydrationMode)
{
switch ($hydrationMode) {
case Query::HYDRATE_OBJECT:
$hydrator = new Internal\Hydration\ObjectHydrator($this);
break;
return new Internal\Hydration\ObjectHydrator($this);
case Query::HYDRATE_ARRAY:
$hydrator = new Internal\Hydration\ArrayHydrator($this);
break;
return new Internal\Hydration\ArrayHydrator($this);
case Query::HYDRATE_SCALAR:
$hydrator = new Internal\Hydration\ScalarHydrator($this);
break;
return new Internal\Hydration\ScalarHydrator($this);
case Query::HYDRATE_SINGLE_SCALAR:
$hydrator = new Internal\Hydration\SingleScalarHydrator($this);
break;
return new Internal\Hydration\SingleScalarHydrator($this);
case Query::HYDRATE_SIMPLEOBJECT:
return new Internal\Hydration\SimpleObjectHydrator($this);
default:
if ($class = $this->config->getCustomHydrationMode($hydrationMode)) {
$hydrator = new $class($this);
break;
if (($class = $this->config->getCustomHydrationMode($hydrationMode)) !== null) {
return new $class($this);
}
throw ORMException::invalidHydrationMode($hydrationMode);
}
return $hydrator;
throw ORMException::invalidHydrationMode($hydrationMode);
}
/**
@@ -703,6 +819,18 @@ class EntityManager
return $this->proxyFactory;
}
/**
* Helper method to initialize a lazy loading proxy or persistent collection.
*
* This method is a no-op for other objects
*
* @param object $obj
*/
public function initializeObject($obj)
{
$this->unitOfWork->initializeObject($obj);
}
/**
* Factory method to create EntityManager instances.
*
@@ -714,20 +842,61 @@ class EntityManager
*/
public static function create($conn, Configuration $config, EventManager $eventManager = null)
{
if (!$config->getMetadataDriverImpl()) {
if ( ! $config->getMetadataDriverImpl()) {
throw ORMException::missingMappingDriverImpl();
}
if (is_array($conn)) {
$conn = \Doctrine\DBAL\DriverManager::getConnection($conn, $config, ($eventManager ?: new EventManager()));
} else if ($conn instanceof Connection) {
if ($eventManager !== null && $conn->getEventManager() !== $eventManager) {
throw ORMException::mismatchedEventManager();
}
} else {
throw new \InvalidArgumentException("Invalid argument: " . $conn);
switch (true) {
case (is_array($conn)):
$conn = \Doctrine\DBAL\DriverManager::getConnection(
$conn, $config, ($eventManager ?: new EventManager())
);
break;
case ($conn instanceof Connection):
if ($eventManager !== null && $conn->getEventManager() !== $eventManager) {
throw ORMException::mismatchedEventManager();
}
break;
default:
throw new \InvalidArgumentException("Invalid argument: " . $conn);
}
return new EntityManager($conn, $config, $conn->getEventManager());
}
/**
* Gets the enabled filters.
*
* @return FilterCollection The active filter collection.
*/
public function getFilters()
{
if (null === $this->filterCollection) {
$this->filterCollection = new FilterCollection($this);
}
return $this->filterCollection;
}
/**
* Checks whether the state of the filter collection is clean.
*
* @return boolean True, if the filter collection is clean.
*/
public function isFiltersStateClean()
{
return null === $this->filterCollection || $this->filterCollection->isClean();
}
/**
* Checks whether the Entity Manager has filters.
*
* @return True, if the EM has a filter collection.
*/
public function hasFilters()
{
return null !== $this->filterCollection;
}
}

View File

@@ -13,7 +13,7 @@
* 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 LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
@@ -31,4 +31,4 @@ class EntityNotFoundException extends ORMException
{
parent::__construct('Entity was not found.');
}
}
}

View File

@@ -13,13 +13,19 @@
* 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 LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM;
use Doctrine\DBAL\LockMode;
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
@@ -34,7 +40,7 @@ use Doctrine\DBAL\LockMode;
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class EntityRepository
class EntityRepository implements ObjectRepository, Selectable
{
/**
* @var string
@@ -47,7 +53,7 @@ class EntityRepository
protected $_em;
/**
* @var Doctrine\ORM\Mapping\ClassMetadata
* @var \Doctrine\ORM\Mapping\ClassMetadata
*/
protected $_class;
@@ -60,8 +66,8 @@ class EntityRepository
public function __construct($em, Mapping\ClassMetadata $class)
{
$this->_entityName = $class->name;
$this->_em = $em;
$this->_class = $class;
$this->_em = $em;
$this->_class = $class;
}
/**
@@ -77,6 +83,32 @@ class EntityRepository
->from($this->_entityName, $alias);
}
/**
* Create a new Query instance based on a predefined metadata named query.
*
* @param string $queryName
* @return Query
*/
public function createNamedQuery($queryName)
{
return $this->_em->createQuery($this->_class->getNamedQuery($queryName));
}
/**
* Creates a native SQL query.
*
* @param string $queryName
* @return NativeQuery
*/
public function createNativeNamedQuery($queryName)
{
$queryMapping = $this->_class->getNamedNativeQuery($queryName);
$rsm = new Query\ResultSetMappingBuilder($this->_em);
$rsm->addNamedNativeQueryMapping($this->_class, $queryMapping);
return $this->_em->createNativeQuery($queryMapping['query'], $rsm);
}
/**
* Clears the repository, causing all managed entities to become detached.
*/
@@ -88,50 +120,15 @@ class EntityRepository
/**
* Finds an entity by its primary key / identifier.
*
* @param $id The identifier.
* @param int $lockMode
* @param int $lockVersion
* @param mixed $id The identifier.
* @param integer $lockMode
* @param integer $lockVersion
*
* @return object The entity.
*/
public function find($id, $lockMode = LockMode::NONE, $lockVersion = null)
{
// Check identity map first
if ($entity = $this->_em->getUnitOfWork()->tryGetById($id, $this->_class->rootEntityName)) {
if (!($entity instanceof $this->_class->name)) {
return null;
}
if ($lockMode != LockMode::NONE) {
$this->_em->lock($entity, $lockMode, $lockVersion);
}
return $entity; // Hit!
}
if ( ! is_array($id) || count($id) <= 1) {
// @todo FIXME: Not correct. Relies on specific order.
$value = is_array($id) ? array_values($id) : array($id);
$id = array_combine($this->_class->identifier, $value);
}
if ($lockMode == LockMode::NONE) {
return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->load($id);
} else if ($lockMode == LockMode::OPTIMISTIC) {
if (!$this->_class->isVersioned) {
throw OptimisticLockException::notVersioned($this->_entityName);
}
$entity = $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->load($id);
$this->_em->getUnitOfWork()->lock($entity, $lockMode, $lockVersion);
return $entity;
} else {
if (!$this->_em->getConnection()->isTransactionActive()) {
throw TransactionRequiredException::transactionRequired();
}
return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->load($id, null, null, array(), $lockMode);
}
return $this->_em->find($this->_entityName, $id, $lockMode, $lockVersion);
}
/**
@@ -148,22 +145,30 @@ class EntityRepository
* Finds entities by a set of criteria.
*
* @param array $criteria
* @return array
* @param array|null $orderBy
* @param int|null $limit
* @param int|null $offset
* @return array The objects.
*/
public function findBy(array $criteria)
public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
{
return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->loadAll($criteria);
$persister = $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName);
return $persister->loadAll($criteria, $orderBy, $limit, $offset);
}
/**
* 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)
{
return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->load($criteria);
$persister = $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName);
return $persister->load($criteria, null, null, array(), 0, 1, $orderBy);
}
/**
@@ -176,31 +181,50 @@ class EntityRepository
*/
public function __call($method, $arguments)
{
if (substr($method, 0, 6) == 'findBy') {
$by = substr($method, 6, strlen($method));
$method = 'findBy';
} else if (substr($method, 0, 9) == 'findOneBy') {
$by = substr($method, 9, strlen($method));
$method = 'findOneBy';
} else {
throw new \BadMethodCallException(
"Undefined method '$method'. The method name must start with ".
"either findBy or findOneBy!"
);
switch (true) {
case (0 === strpos($method, 'findBy')):
$by = substr($method, 6);
$method = 'findBy';
break;
case (0 === strpos($method, 'findOneBy')):
$by = substr($method, 9);
$method = 'findOneBy';
break;
default:
throw new \BadMethodCallException(
"Undefined method '$method'. The method name must start with ".
"either findBy or findOneBy!"
);
}
if ( !isset($arguments[0])) {
// we dont even want to allow null at this point, because we cannot (yet) transform it into IS NULL.
throw ORMException::findByRequiresParameter($method.$by);
if (empty($arguments)) {
throw ORMException::findByRequiresParameter($method . $by);
}
$fieldName = lcfirst(\Doctrine\Common\Util\Inflector::classify($by));
if ($this->_class->hasField($fieldName) || $this->_class->hasAssociation($fieldName)) {
return $this->$method(array($fieldName => $arguments[0]));
} else {
throw ORMException::invalidFindByCall($this->_entityName, $fieldName, $method.$by);
switch (count($arguments)) {
case 1:
return $this->$method(array($fieldName => $arguments[0]));
case 2:
return $this->$method(array($fieldName => $arguments[0]), $arguments[1]);
case 3:
return $this->$method(array($fieldName => $arguments[0]), $arguments[1], $arguments[2]);
case 4:
return $this->$method(array($fieldName => $arguments[0]), $arguments[1], $arguments[2], $arguments[3]);
default:
// Do nothing
}
}
throw ORMException::invalidFindByCall($this->_entityName, $fieldName, $method.$by);
}
/**
@@ -211,6 +235,14 @@ class EntityRepository
return $this->_entityName;
}
/**
* @return string
*/
public function getClassName()
{
return $this->getEntityName();
}
/**
* @return EntityManager
*/
@@ -226,4 +258,20 @@ class EntityRepository
{
return $this->_class;
}
}
/**
* Select all elements from a selectable that match the expression and
* return a new collection containing these elements.
*
* @param \Doctrine\Common\Collections\Criteria $criteria
*
* @return \Doctrine\Common\Collections\Collection
*/
public function matching(Criteria $criteria)
{
$persister = $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName);
return new ArrayCollection($persister->loadCriteria($criteria));
}
}

View File

@@ -13,48 +13,65 @@
* 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 LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Event;
use Doctrine\Common\EventArgs;
use Doctrine\ORM\EntityManager;
/**
* Lifecycle Events are triggered by the UnitOfWork during lifecycle transitions
* of entities.
*
* @since 2.0
* @link www.doctrine-project.org
* @since 2.0
* @author Roman Borschel <roman@code-factory.de>
* @author Benjamin Eberlei <kontakt@beberlei.de>
*/
class LifecycleEventArgs extends \Doctrine\Common\EventArgs
class LifecycleEventArgs extends EventArgs
{
/**
* @var EntityManager
* @var \Doctrine\ORM\EntityManager
*/
private $_em;
private $em;
/**
* @var object
*/
private $_entity;
public function __construct($entity, $em)
private $entity;
/**
* Constructor
*
* @param object $entity
* @param \Doctrine\ORM\EntityManager $em
*/
public function __construct($entity, EntityManager $em)
{
$this->_entity = $entity;
$this->_em = $em;
}
public function getEntity()
{
return $this->_entity;
$this->entity = $entity;
$this->em = $em;
}
/**
* @return EntityManager
* Retrieve associated Entity.
*
* @return object
*/
public function getEntity()
{
return $this->entity;
}
/**
* Retrieve associated EntityManager.
*
* @return \Doctrine\ORM\EntityManager
*/
public function getEntityManager()
{
return $this->_em;
return $this->em;
}
}
}

View File

@@ -1,9 +1,25 @@
<?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\ORM\Event;
use Doctrine\Common\EventArgs;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
use Doctrine\ORM\EntityManager;
@@ -11,32 +27,36 @@ use Doctrine\ORM\EntityManager;
* Class that holds event arguments for a loadMetadata event.
*
* @author Jonathan H. Wage <jonwage@gmail.com>
* @since 2.0
* @since 2.0
*/
class LoadClassMetadataEventArgs extends EventArgs
{
/**
* @var ClassMetadata
* @var \Doctrine\ORM\Mapping\ClassMetadata
*/
private $classMetadata;
/**
* @var EntityManager
* @var \Doctrine\ORM\EntityManager
*/
private $em;
/**
* @param ClassMetadataInfo $classMetadata
* @param EntityManager $em
* Constructor.
*
* @param \Doctrine\ORM\Mapping\ClassMetadataInfo $classMetadata
* @param \Doctrine\ORM\EntityManager $em
*/
public function __construct(ClassMetadataInfo $classMetadata, EntityManager $em)
{
$this->classMetadata = $classMetadata;
$this->em = $em;
$this->em = $em;
}
/**
* @return ClassMetadataInfo
* Retrieve associated ClassMetadata.
*
* @return \Doctrine\ORM\Mapping\ClassMetadataInfo
*/
public function getClassMetadata()
{
@@ -44,7 +64,9 @@ class LoadClassMetadataEventArgs extends EventArgs
}
/**
* @return EntityManager
* Retrieve associated EntityManager.
*
* @return \Doctrine\ORM\EntityManager
*/
public function getEntityManager()
{

View File

@@ -0,0 +1,84 @@
<?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\ORM\Event;
/**
* Provides event arguments for the onClear event.
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 2.0
* @author Roman Borschel <roman@code-factory.de>
* @author Benjamin Eberlei <kontakt@beberlei.de>
*/
class OnClearEventArgs extends \Doctrine\Common\EventArgs
{
/**
* @var \Doctrine\ORM\EntityManager
*/
private $em;
/**
* @var string
*/
private $entityClass;
/**
* Constructor.
*
* @param \Doctrine\ORM\EntityManager $em
* @param string $entityClass Optional entity class
*/
public function __construct($em, $entityClass = null)
{
$this->em = $em;
$this->entityClass = $entityClass;
}
/**
* Retrieve associated EntityManager.
*
* @return \Doctrine\ORM\EntityManager
*/
public function getEntityManager()
{
return $this->em;
}
/**
* Name of the entity class that is cleared, or empty if all are cleared.
*
* @return string
*/
public function getEntityClass()
{
return $this->entityClass;
}
/**
* Check if event clears all entities.
*
* @return bool
*/
public function clearsAllEntities()
{
return ($this->entityClass === null);
}
}

View File

@@ -1,7 +1,5 @@
<?php
/*
* $Id$
*
* 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
@@ -15,64 +13,72 @@
* 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 LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
*/
namespace Doctrine\ORM\Event;
use Doctrine\ORM\EntityManager;
/**
* Provides event arguments for the preFlush event.
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.com
* @link www.doctrine-project.org
* @since 2.0
* @version $Revision$
* @author Roman Borschel <roman@code-factory.de>
* @author Benjamin Eberlei <kontakt@beberlei.de>
*/
class OnFlushEventArgs extends \Doctrine\Common\EventArgs
{
/**
* @var EntityManager
* @var Doctirne\ORM\EntityManager
*/
private $_em;
//private $_entitiesToPersist = array();
//private $_entitiesToRemove = array();
public function __construct($em)
private $em;
//private $entitiesToPersist = array();
//private $entitiesToRemove = array();
/**
* Constructor.
*
* @param \Doctrine\ORM\EntityManager $em
*/
public function __construct(EntityManager $em)
{
$this->_em = $em;
$this->em = $em;
}
/**
* @return EntityManager
* Retrieve associated EntityManager.
*
* @return \Doctrine\ORM\EntityManager
*/
public function getEntityManager()
{
return $this->_em;
return $this->em;
}
/*
public function addEntityToPersist($entity)
{
}
public function addEntityToRemove($entity)
{
}
public function addEntityToUpdate($entity)
{
}
public function getEntitiesToPersist()
{
return $this->_entitiesToPersist;
}
*/
}
}

View File

@@ -0,0 +1,58 @@
<?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\ORM\Event;
use Doctrine\ORM\EntityManager;
use Doctrine\Common\EventArgs;
/**
* Provides event arguments for the postFlush event.
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 2.0
* @author Daniel Freudenberger <df@rebuy.de>
*/
class PostFlushEventArgs extends EventArgs
{
/**
* @var \Doctrine\ORM\EntityManager
*/
private $em;
/**
* Constructor.
*
* @param \Doctrine\ORM\EntityManager $em
*/
public function __construct(EntityManager $em)
{
$this->em = $em;
}
/**
* Retrieve associated EntityManager.
*
* @return \Doctrine\ORM\EntityManager
*/
public function getEntityManager()
{
return $this->em;
}
}

View File

@@ -0,0 +1,50 @@
<?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\ORM\Event;
/**
* Provides event arguments for the preFlush event.
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.com
* @since 2.0
* @author Roman Borschel <roman@code-factory.de>
* @author Benjamin Eberlei <kontakt@beberlei.de>
*/
class PreFlushEventArgs extends \Doctrine\Common\EventArgs
{
/**
* @var EntityManager
*/
private $_em;
public function __construct($em)
{
$this->_em = $em;
}
/**
* @return EntityManager
*/
public function getEntityManager()
{
return $this->_em;
}
}

View File

@@ -1,4 +1,21 @@
<?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\ORM\Event;
@@ -8,55 +25,63 @@ use Doctrine\Common\EventArgs,
/**
* Class that holds event arguments for a preInsert/preUpdate event.
*
* @author Guilherme Blanco <guilehrmeblanco@hotmail.com>
* @author Roman Borschel <roman@code-factory.org>
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @since 2.0
* @since 2.0
*/
class PreUpdateEventArgs extends LifecycleEventArgs
{
/**
* @var array
*/
private $_entityChangeSet;
private $entityChangeSet;
/**
* Constructor.
*
* @param object $entity
* @param EntityManager $em
* @param \Doctrine\ORM\EntityManager $em
* @param array $changeSet
*/
public function __construct($entity, $em, array &$changeSet)
public function __construct($entity, EntityManager $em, array &$changeSet)
{
parent::__construct($entity, $em);
$this->_entityChangeSet = &$changeSet;
}
public function getEntityChangeSet()
{
return $this->_entityChangeSet;
$this->entityChangeSet = &$changeSet;
}
/**
* Field has a changeset?
* Retrieve entity changeset.
*
* @return bool
* @return array
*/
public function getEntityChangeSet()
{
return $this->entityChangeSet;
}
/**
* Check if field has a changeset.
*
* @return boolean
*/
public function hasChangedField($field)
{
return isset($this->_entityChangeSet[$field]);
return isset($this->entityChangeSet[$field]);
}
/**
* Get the old value of the changeset of the changed field.
*
*
* @param string $field
* @return mixed
*/
public function getOldValue($field)
{
$this->_assertValidField($field);
$this->assertValidField($field);
return $this->_entityChangeSet[$field][0];
return $this->entityChangeSet[$field][0];
}
/**
@@ -67,31 +92,37 @@ class PreUpdateEventArgs extends LifecycleEventArgs
*/
public function getNewValue($field)
{
$this->_assertValidField($field);
$this->assertValidField($field);
return $this->_entityChangeSet[$field][1];
return $this->entityChangeSet[$field][1];
}
/**
* Set the new value of this field.
*
*
* @param string $field
* @param mixed $value
*/
public function setNewValue($field, $value)
{
$this->_assertValidField($field);
$this->assertValidField($field);
$this->_entityChangeSet[$field][1] = $value;
$this->entityChangeSet[$field][1] = $value;
}
private function _assertValidField($field)
/**
* Assert the field exists in changeset.
*
* @param string $field
*/
private function assertValidField($field)
{
if (!isset($this->_entityChangeSet[$field])) {
throw new \InvalidArgumentException(
"Field '".$field."' is not a valid field of the entity ".
"'".get_class($this->getEntity())."' in PreInsertUpdateEventArgs."
);
if ( ! isset($this->entityChangeSet[$field])) {
throw new \InvalidArgumentException(sprintf(
'Field "%s" is not a valid field of the entity "%s" in PreUpdateEventArgs.',
$field,
get_class($this->getEntity())
));
}
}
}

View File

@@ -1,7 +1,5 @@
<?php
/*
* $Id$
*
* 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
@@ -15,7 +13,7 @@
* 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 LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
@@ -35,55 +33,55 @@ final class Events
/**
* The preRemove event occurs for a given entity before the respective
* EntityManager remove operation for that entity is executed.
*
*
* This is an entity lifecycle event.
*
*
* @var string
*/
const preRemove = 'preRemove';
/**
* The postRemove event occurs for an entity after the entity has
* The postRemove event occurs for an entity after the entity has
* been deleted. It will be invoked after the database delete operations.
*
*
* This is an entity lifecycle event.
*
*
* @var string
*/
const postRemove = 'postRemove';
/**
* The prePersist event occurs for a given entity before the respective
* EntityManager persist operation for that entity is executed.
*
*
* This is an entity lifecycle event.
*
*
* @var string
*/
const prePersist = 'prePersist';
/**
* The postPersist event occurs for an entity after the entity has
* The postPersist event occurs for an entity after the entity has
* been made persistent. It will be invoked after the database insert operations.
* Generated primary key values are available in the postPersist event.
*
*
* This is an entity lifecycle event.
*
*
* @var string
*/
const postPersist = 'postPersist';
/**
* The preUpdate event occurs before the database update operations to
* entity data.
*
* The preUpdate event occurs before the database update operations to
* entity data.
*
* This is an entity lifecycle event.
*
*
* @var string
*/
const preUpdate = 'preUpdate';
/**
* The postUpdate event occurs after the database update operations to
* entity data.
*
* The postUpdate event occurs after the database update operations to
* entity data.
*
* This is an entity lifecycle event.
*
*
* @var string
*/
const postUpdate = 'postUpdate';
@@ -91,32 +89,58 @@ final class Events
* The postLoad event occurs for an entity after the entity has been loaded
* into the current EntityManager from the database or after the refresh operation
* has been applied to it.
*
*
* Note that the postLoad event occurs for an entity before any associations have been
* initialized. Therefore it is not safe to access associations in a postLoad callback
* or event handler.
*
*
* This is an entity lifecycle event.
*
*
* @var string
*/
const postLoad = 'postLoad';
/**
* The loadClassMetadata event occurs after the mapping metadata for a class
* has been loaded from a mapping source (annotations/xml/yaml).
*
*
* @var string
*/
const loadClassMetadata = 'loadClassMetadata';
/**
* The preFlush event occurs when the EntityManager#flush() operation is invoked,
* but before any changes to managed entites have been calculated. This event is
* always raised right after EntityManager#flush() call.
*/
const preFlush = 'preFlush';
/**
* The onFlush event occurs when the EntityManager#flush() operation is invoked,
* after any changes to managed entities have been determined but before any
* actual database operations are executed. The event is only raised if there is
* actually something to do for the underlying UnitOfWork. If nothing needs to be done,
* the onFlush event is not raised.
*
*
* @var string
*/
const onFlush = 'onFlush';
}
/**
* The postFlush event occurs when the EntityManager#flush() operation is invoked and
* after all actual database operations are executed successfully. The event is only raised if there is
* actually something to do for the underlying UnitOfWork. If nothing needs to be done,
* the postFlush event is not raised. The event won't be raised if an error occurs during the
* flush operation.
*
* @var string
*/
const postFlush = 'postFlush';
/**
* The onClear event occurs when the EntityManager#clear() operation is invoked,
* after all references to entities have been removed from the unit of work.
*
* @var string
*/
const onClear = 'onClear';
}

View File

@@ -13,7 +13,7 @@
* 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 LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
@@ -26,7 +26,7 @@ abstract class AbstractIdGenerator
/**
* Generates an identifier for an entity.
*
* @param Doctrine\ORM\Entity $entity
* @param \Doctrine\ORM\Entity $entity
* @return mixed
*/
abstract public function generate(EntityManager $em, $entity);
@@ -35,7 +35,7 @@ abstract class AbstractIdGenerator
* Gets whether this generator is a post-insert generator which means that
* {@link generate()} must be called after the entity has been inserted
* into the database.
*
*
* By default, this method returns FALSE. Generators that have this requirement
* must override this method and return TRUE.
*
@@ -45,4 +45,4 @@ abstract class AbstractIdGenerator
{
return false;
}
}
}

View File

@@ -13,7 +13,7 @@
* 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 LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
@@ -42,28 +42,29 @@ class AssignedGenerator extends AbstractIdGenerator
*/
public function generate(EntityManager $em, $entity)
{
$class = $em->getClassMetadata(get_class($entity));
$class = $em->getClassMetadata(get_class($entity));
$idFields = $class->getIdentifierFieldNames();
$identifier = array();
if ($class->isIdentifierComposite) {
$idFields = $class->getIdentifierFieldNames();
foreach ($idFields as $idField) {
$value = $class->getReflectionProperty($idField)->getValue($entity);
if (isset($value)) {
$identifier[$idField] = $value;
} else {
throw ORMException::entityMissingAssignedId($entity);
}
}
} else {
$idField = $class->identifier[0];
foreach ($idFields as $idField) {
$value = $class->reflFields[$idField]->getValue($entity);
if (isset($value)) {
$identifier[$idField] = $value;
} else {
throw ORMException::entityMissingAssignedId($entity);
if ( ! isset($value)) {
throw ORMException::entityMissingAssignedIdForField($entity, $idField);
}
if (isset($class->associationMappings[$idField])) {
if ( ! $em->getUnitOfWork()->isInIdentityMap($value)) {
throw ORMException::entityMissingForeignAssignedId($entity, $value);
}
// NOTE: Single Columns as associated identifiers only allowed - this constraint it is enforced.
$value = current($em->getUnitOfWork()->getEntityIdentifier($value));
}
$identifier[$idField] = $value;
}
return $identifier;
}
}
}

View File

@@ -13,7 +13,7 @@
* 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 LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
@@ -46,7 +46,7 @@ class IdentityGenerator extends AbstractIdGenerator
*/
public function generate(EntityManager $em, $entity)
{
return $em->getConnection()->lastInsertId($this->_seqName);
return (int)$em->getConnection()->lastInsertId($this->_seqName);
}
/**
@@ -56,4 +56,4 @@ class IdentityGenerator extends AbstractIdGenerator
{
return true;
}
}
}

View File

@@ -13,7 +13,7 @@
* 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 LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
@@ -37,7 +37,7 @@ class SequenceGenerator extends AbstractIdGenerator implements Serializable
/**
* Initializes a new sequence generator.
*
* @param Doctrine\ORM\EntityManager $em The EntityManager to use.
* @param \Doctrine\ORM\EntityManager $em The EntityManager to use.
* @param string $sequenceName The name of the sequence.
* @param integer $allocationSize The allocation size of the sequence.
*/
@@ -46,7 +46,7 @@ class SequenceGenerator extends AbstractIdGenerator implements Serializable
$this->_sequenceName = $sequenceName;
$this->_allocationSize = $allocationSize;
}
/**
* Generates an ID for the given entity.
*
@@ -59,10 +59,12 @@ class SequenceGenerator extends AbstractIdGenerator implements Serializable
if ($this->_maxValue === null || $this->_nextValue == $this->_maxValue) {
// Allocate new values
$conn = $em->getConnection();
$sql = $conn->getDatabasePlatform()->getSequenceNextValSQL($this->_sequenceName);
$this->_nextValue = $conn->fetchColumn($sql);
$this->_maxValue = $this->_nextValue + $this->_allocationSize;
$sql = $conn->getDatabasePlatform()->getSequenceNextValSQL($this->_sequenceName);
$this->_nextValue = (int)$conn->fetchColumn($sql);
$this->_maxValue = $this->_nextValue + $this->_allocationSize;
}
return $this->_nextValue++;
}
@@ -90,13 +92,14 @@ class SequenceGenerator extends AbstractIdGenerator implements Serializable
{
return serialize(array(
'allocationSize' => $this->_allocationSize,
'sequenceName' => $this->_sequenceName
'sequenceName' => $this->_sequenceName
));
}
public function unserialize($serialized)
{
$array = unserialize($serialized);
$this->_sequenceName = $array['sequenceName'];
$this->_allocationSize = $array['allocationSize'];
}

View File

@@ -13,7 +13,7 @@
* 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 LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
@@ -50,11 +50,12 @@ class TableGenerator extends AbstractIdGenerator
if ($this->_maxValue === null || $this->_nextValue == $this->_maxValue) {
// Allocate new values
$conn = $em->getConnection();
if ($conn->getTransactionNestingLevel() == 0) {
if ($conn->getTransactionNestingLevel() === 0) {
// use select for update
$sql = $conn->getDatabasePlatform()->getTableHiLoCurrentValSql($this->_tableName, $this->_sequenceName);
$sql = $conn->getDatabasePlatform()->getTableHiLoCurrentValSql($this->_tableName, $this->_sequenceName);
$currentLevel = $conn->fetchColumn($sql);
if ($currentLevel != null) {
$this->_nextValue = $currentLevel;
$this->_maxValue = $this->_nextValue + $this->_allocationSize;
@@ -62,7 +63,7 @@ class TableGenerator extends AbstractIdGenerator
$updateSql = $conn->getDatabasePlatform()->getTableHiLoUpdateNextValSql(
$this->_tableName, $this->_sequenceName, $this->_allocationSize
);
if ($conn->executeUpdate($updateSql, array(1 => $currentLevel, 2 => $currentLevel+1)) !== 1) {
// no affected rows, concurrency issue, throw exception
}
@@ -74,6 +75,7 @@ class TableGenerator extends AbstractIdGenerator
// or do we want to work with table locks exclusively?
}
}
return $this->_nextValue++;
}
}
}

View File

@@ -0,0 +1,48 @@
<?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\ORM\Id;
use Serializable, Doctrine\ORM\EntityManager;
/**
* Represents an ID generator that uses the database UUID expression
*
* @since 2.3
* @author Maarten de Keizer <m.de.keizer@markei.nl>
*/
class UuidGenerator extends AbstractIdGenerator
{
/**
* Generates an ID for the given entity.
*
* @param Doctrine\ORM\EntityManager $em The EntityManager to user
* @param object $entity
* @return string The generated value.
* @override
*/
public function generate(EntityManager $em, $entity)
{
$conn = $em->getConnection();
$sql = 'SELECT ' . $conn->getDatabasePlatform()->getGuidExpression();
return $conn->query($sql)->fetchColumn(0);
}
}

View File

@@ -13,7 +13,7 @@
* 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 LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
@@ -23,20 +23,21 @@ namespace Doctrine\ORM\Internal;
* The CommitOrderCalculator is used by the UnitOfWork to sort out the
* correct order in which changes to entities need to be persisted.
*
* @since 2.0
* @author Roman Borschel <roman@code-factory.org>
* @since 2.0
* @author Roman Borschel <roman@code-factory.org>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
*/
class CommitOrderCalculator
{
const NOT_VISITED = 1;
const IN_PROGRESS = 2;
const VISITED = 3;
private $_nodeStates = array();
private $_classes = array(); // The nodes to sort
private $_relatedClasses = array();
private $_sorted = array();
/**
* Clears the current graph.
*
@@ -47,10 +48,10 @@ class CommitOrderCalculator
$this->_classes =
$this->_relatedClasses = array();
}
/**
* Gets a valid commit order for all current nodes.
*
*
* Uses a depth-first search (DFS) to traverse the graph.
* The desired topological sorting is the reverse postorder of these searches.
*
@@ -60,17 +61,16 @@ class CommitOrderCalculator
{
// Check whether we need to do anything. 0 or 1 node is easy.
$nodeCount = count($this->_classes);
if ($nodeCount == 0) {
return array();
} else if ($nodeCount == 1) {
return array_values($this->_classes);
if ($nodeCount <= 1) {
return ($nodeCount == 1) ? array_values($this->_classes) : array();
}
// Init
foreach ($this->_classes as $node) {
$this->_nodeStates[$node->name] = self::NOT_VISITED;
}
// Go
foreach ($this->_classes as $node) {
if ($this->_nodeStates[$node->name] == self::NOT_VISITED) {
@@ -100,19 +100,19 @@ class CommitOrderCalculator
$this->_nodeStates[$node->name] = self::VISITED;
$this->_sorted[] = $node;
}
public function addDependency($fromClass, $toClass)
{
$this->_relatedClasses[$fromClass->name][] = $toClass;
}
public function hasClass($className)
{
return isset($this->_classes[$className]);
}
public function addClass($class)
{
$this->_classes[$class->name] = $class;
}
}
}

View File

@@ -13,7 +13,7 @@
* 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 LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
@@ -22,34 +22,37 @@ namespace Doctrine\ORM\Internal\Hydration;
use PDO,
Doctrine\DBAL\Connection,
Doctrine\DBAL\Types\Type,
Doctrine\ORM\EntityManager;
Doctrine\ORM\EntityManager,
Doctrine\ORM\Events,
Doctrine\ORM\Mapping\ClassMetadata;
/**
* Base class for all hydrators. A hydrator is a class that provides some form
* of transformation of an SQL result set into another structure.
*
* @since 2.0
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @author Roman Borschel <roman@code-factory.org>
* @since 2.0
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @author Roman Borschel <roman@code-factory.org>
* @author Guilherme Blanco <guilhermeblanoc@hotmail.com>
*/
abstract class AbstractHydrator
{
/** @var ResultSetMapping The ResultSetMapping. */
/** @var \Doctrine\ORM\Query\ResultSetMapping The ResultSetMapping. */
protected $_rsm;
/** @var EntityManager The EntityManager instance. */
protected $_em;
/** @var AbstractPlatform The dbms Platform instance */
/** @var \Doctrine\DBAL\Platforms\AbstractPlatform The dbms Platform instance */
protected $_platform;
/** @var UnitOfWork The UnitOfWork of the associated EntityManager. */
/** @var \Doctrine\ORM\UnitOfWork The UnitOfWork of the associated EntityManager. */
protected $_uow;
/** @var array The cache used during row-by-row hydration. */
protected $_cache = array();
/** @var Statement The statement that provides the data to hydrate. */
/** @var \Doctrine\DBAL\Driver\Statement The statement that provides the data to hydrate. */
protected $_stmt;
/** @var array The query hints. */
@@ -58,13 +61,13 @@ abstract class AbstractHydrator
/**
* Initializes a new instance of a class derived from <tt>AbstractHydrator</tt>.
*
* @param Doctrine\ORM\EntityManager $em The EntityManager to use.
* @param \Doctrine\ORM\EntityManager $em The EntityManager to use.
*/
public function __construct(EntityManager $em)
{
$this->_em = $em;
$this->_em = $em;
$this->_platform = $em->getConnection()->getDatabasePlatform();
$this->_uow = $em->getUnitOfWork();
$this->_uow = $em->getUnitOfWork();
}
/**
@@ -72,14 +75,20 @@ abstract class AbstractHydrator
*
* @param object $stmt
* @param object $resultSetMapping
*
* @return IterableResult
*/
public function iterate($stmt, $resultSetMapping, array $hints = array())
{
$this->_stmt = $stmt;
$this->_rsm = $resultSetMapping;
$this->_stmt = $stmt;
$this->_rsm = $resultSetMapping;
$this->_hints = $hints;
$this->_prepare();
$evm = $this->_em->getEventManager();
$evm->addEventListener(array(Events::onClear), $this);
$this->prepare();
return new IterableResult($this);
}
@@ -88,16 +97,21 @@ abstract class AbstractHydrator
*
* @param object $stmt
* @param object $resultSetMapping
* @param array $hints
* @return mixed
*/
public function hydrateAll($stmt, $resultSetMapping, array $hints = array())
{
$this->_stmt = $stmt;
$this->_rsm = $resultSetMapping;
$this->_stmt = $stmt;
$this->_rsm = $resultSetMapping;
$this->_hints = $hints;
$this->_prepare();
$result = $this->_hydrateAll();
$this->_cleanup();
$this->prepare();
$result = $this->hydrateAllData();
$this->cleanup();
return $result;
}
@@ -110,12 +124,17 @@ abstract class AbstractHydrator
public function hydrateRow()
{
$row = $this->_stmt->fetch(PDO::FETCH_ASSOC);
if ( ! $row) {
$this->_cleanup();
$this->cleanup();
return false;
}
$result = array();
$this->_hydrateRow($row, $this->_cache, $result);
$this->hydrateRowData($row, $this->_cache, $result);
return $result;
}
@@ -123,16 +142,17 @@ abstract class AbstractHydrator
* Excutes one-time preparation tasks, once each time hydration is started
* through {@link hydrateAll} or {@link iterate()}.
*/
protected function _prepare()
protected function prepare()
{}
/**
* Excutes one-time cleanup tasks at the end of a hydration that was initiated
* through {@link hydrateAll} or {@link iterate()}.
*/
protected function _cleanup()
protected function cleanup()
{
$this->_rsm = null;
$this->_stmt->closeCursor();
$this->_stmt = null;
}
@@ -146,70 +166,106 @@ abstract class AbstractHydrator
* @param array $cache The cache to use.
* @param mixed $result The result to fill.
*/
protected function _hydrateRow(array $data, array &$cache, array &$result)
protected function hydrateRowData(array $data, array &$cache, array &$result)
{
throw new HydrationException("_hydrateRow() not implemented by this hydrator.");
throw new HydrationException("hydrateRowData() not implemented by this hydrator.");
}
/**
* Hydrates all rows from the current statement instance at once.
*/
abstract protected function _hydrateAll();
abstract protected function hydrateAllData();
/**
* Processes a row of the result set.
*
* Used for identity-based hydration (HYDRATE_OBJECT and HYDRATE_ARRAY).
* Puts the elements of a result row into a new array, grouped by the class
* Puts the elements of a result row into a new array, grouped by the dql alias
* they belong to. The column names in the result set are mapped to their
* field names during this procedure as well as any necessary conversions on
* the values applied.
* the values applied. Scalar values are kept in a specfic key 'scalars'.
*
* @param array $data SQL Result Row
* @param array &$cache Cache for column to field result information
* @param array &$id Dql-Alias => ID-Hash
* @param array &$nonemptyComponents Does this DQL-Alias has at least one non NULL value?
*
* @return array An array with all the fields (name => value) of the data row,
* grouped by their component alias.
*/
protected function _gatherRowData(array $data, array &$cache, array &$id, array &$nonemptyComponents)
protected function gatherRowData(array $data, array &$cache, array &$id, array &$nonemptyComponents)
{
$rowData = array();
foreach ($data as $key => $value) {
// Parse each column name only once. Cache the results.
if ( ! isset($cache[$key])) {
if (isset($this->_rsm->scalarMappings[$key])) {
$cache[$key]['fieldName'] = $this->_rsm->scalarMappings[$key];
$cache[$key]['isScalar'] = true;
} else if (isset($this->_rsm->fieldMappings[$key])) {
$fieldName = $this->_rsm->fieldMappings[$key];
$classMetadata = $this->_em->getClassMetadata($this->_rsm->declaringClasses[$key]);
$cache[$key]['fieldName'] = $fieldName;
$cache[$key]['type'] = Type::getType($classMetadata->fieldMappings[$fieldName]['type']);
$cache[$key]['isIdentifier'] = $classMetadata->isIdentifier($fieldName);
$cache[$key]['dqlAlias'] = $this->_rsm->columnOwnerMap[$key];
} else if (!isset($this->_rsm->metaMappings[$key])) {
// this column is a left over, maybe from a LIMIT query hack for example in Oracle or DB2
// maybe from an additional column that has not been defined in a NativeQuery ResultSetMapping.
continue;
} else {
// Meta column (has meaning in relational schema only, i.e. foreign keys or discriminator columns).
$cache[$key]['isMetaColumn'] = true;
$cache[$key]['fieldName'] = $this->_rsm->metaMappings[$key];
$cache[$key]['dqlAlias'] = $this->_rsm->columnOwnerMap[$key];
switch (true) {
// NOTE: Most of the times it's a field mapping, so keep it first!!!
case (isset($this->_rsm->fieldMappings[$key])):
$fieldName = $this->_rsm->fieldMappings[$key];
$classMetadata = $this->_em->getClassMetadata($this->_rsm->declaringClasses[$key]);
$cache[$key]['fieldName'] = $fieldName;
$cache[$key]['type'] = Type::getType($classMetadata->fieldMappings[$fieldName]['type']);
$cache[$key]['isIdentifier'] = $classMetadata->isIdentifier($fieldName);
$cache[$key]['dqlAlias'] = $this->_rsm->columnOwnerMap[$key];
break;
case (isset($this->_rsm->scalarMappings[$key])):
$cache[$key]['fieldName'] = $this->_rsm->scalarMappings[$key];
$cache[$key]['type'] = Type::getType($this->_rsm->typeMappings[$key]);
$cache[$key]['isScalar'] = true;
break;
case (isset($this->_rsm->metaMappings[$key])):
// Meta column (has meaning in relational schema only, i.e. foreign keys or discriminator columns).
$fieldName = $this->_rsm->metaMappings[$key];
$classMetadata = $this->_em->getClassMetadata($this->_rsm->aliasMap[$this->_rsm->columnOwnerMap[$key]]);
$cache[$key]['isMetaColumn'] = true;
$cache[$key]['fieldName'] = $fieldName;
$cache[$key]['dqlAlias'] = $this->_rsm->columnOwnerMap[$key];
$cache[$key]['isIdentifier'] = isset($this->_rsm->isIdentifierColumn[$cache[$key]['dqlAlias']][$key]);
break;
default:
// this column is a left over, maybe from a LIMIT query hack for example in Oracle or DB2
// maybe from an additional column that has not been defined in a NativeQuery ResultSetMapping.
continue 2;
}
}
if (isset($cache[$key]['isScalar'])) {
$value = $cache[$key]['type']->convertToPHPValue($value, $this->_platform);
$rowData['scalars'][$cache[$key]['fieldName']] = $value;
continue;
}
$dqlAlias = $cache[$key]['dqlAlias'];
if ($cache[$key]['isIdentifier']) {
$id[$dqlAlias] .= '|' . $value;
}
if (isset($cache[$key]['isMetaColumn'])) {
$rowData[$dqlAlias][$cache[$key]['fieldName']] = $value;
if ( ! isset($rowData[$dqlAlias][$cache[$key]['fieldName']]) && $value !== null) {
$rowData[$dqlAlias][$cache[$key]['fieldName']] = $value;
if ($cache[$key]['isIdentifier']) {
$nonemptyComponents[$dqlAlias] = true;
}
}
continue;
}
if ($cache[$key]['isIdentifier']) {
$id[$dqlAlias] .= '|' . $value;
// in an inheritance hierarchy the same field could be defined several times.
// We overwrite this value so long we dont have a non-null value, that value we keep.
// Per definition it cannot be that a field is defined several times and has several values.
if (isset($rowData[$dqlAlias][$cache[$key]['fieldName']]) && $value === null) {
continue;
}
$rowData[$dqlAlias][$cache[$key]['fieldName']] = $cache[$key]['type']->convertToPHPValue($value, $this->_platform);
@@ -224,6 +280,7 @@ abstract class AbstractHydrator
/**
* Processes a row of the result set.
*
* Used for HYDRATE_SCALAR. This is a variant of _gatherRowData() that
* simply converts column names to field names and properly converts the
* values according to their types. The resulting row has the same number
@@ -231,48 +288,103 @@ abstract class AbstractHydrator
*
* @param array $data
* @param array $cache
*
* @return array The processed row.
*/
protected function _gatherScalarRowData(&$data, &$cache)
protected function gatherScalarRowData(&$data, &$cache)
{
$rowData = array();
foreach ($data as $key => $value) {
// Parse each column name only once. Cache the results.
if ( ! isset($cache[$key])) {
if (isset($this->_rsm->scalarMappings[$key])) {
$cache[$key]['fieldName'] = $this->_rsm->scalarMappings[$key];
$cache[$key]['isScalar'] = true;
} else if (isset($this->_rsm->fieldMappings[$key])) {
$fieldName = $this->_rsm->fieldMappings[$key];
$classMetadata = $this->_em->getClassMetadata($this->_rsm->declaringClasses[$key]);
$cache[$key]['fieldName'] = $fieldName;
$cache[$key]['type'] = Type::getType($classMetadata->fieldMappings[$fieldName]['type']);
$cache[$key]['dqlAlias'] = $this->_rsm->columnOwnerMap[$key];
} else if (!isset($this->_rsm->metaMappings[$key])) {
// this column is a left over, maybe from a LIMIT query hack for example in Oracle or DB2
// maybe from an additional column that has not been defined in a NativeQuery ResultSetMapping.
continue;
} else {
// Meta column (has meaning in relational schema only, i.e. foreign keys or discriminator columns).
$cache[$key]['isMetaColumn'] = true;
$cache[$key]['fieldName'] = $this->_rsm->metaMappings[$key];
$cache[$key]['dqlAlias'] = $this->_rsm->columnOwnerMap[$key];
switch (true) {
// NOTE: During scalar hydration, most of the times it's a scalar mapping, keep it first!!!
case (isset($this->_rsm->scalarMappings[$key])):
$cache[$key]['fieldName'] = $this->_rsm->scalarMappings[$key];
$cache[$key]['isScalar'] = true;
break;
case (isset($this->_rsm->fieldMappings[$key])):
$fieldName = $this->_rsm->fieldMappings[$key];
$classMetadata = $this->_em->getClassMetadata($this->_rsm->declaringClasses[$key]);
$cache[$key]['fieldName'] = $fieldName;
$cache[$key]['type'] = Type::getType($classMetadata->fieldMappings[$fieldName]['type']);
$cache[$key]['dqlAlias'] = $this->_rsm->columnOwnerMap[$key];
break;
case (isset($this->_rsm->metaMappings[$key])):
// Meta column (has meaning in relational schema only, i.e. foreign keys or discriminator columns).
$cache[$key]['isMetaColumn'] = true;
$cache[$key]['fieldName'] = $this->_rsm->metaMappings[$key];
$cache[$key]['dqlAlias'] = $this->_rsm->columnOwnerMap[$key];
break;
default:
// this column is a left over, maybe from a LIMIT query hack for example in Oracle or DB2
// maybe from an additional column that has not been defined in a NativeQuery ResultSetMapping.
continue 2;
}
}
$fieldName = $cache[$key]['fieldName'];
if (isset($cache[$key]['isScalar'])) {
$rowData[$fieldName] = $value;
} else if (isset($cache[$key]['isMetaColumn'])) {
$rowData[$cache[$key]['dqlAlias'] . '_' . $fieldName] = $value;
} else {
$rowData[$cache[$key]['dqlAlias'] . '_' . $fieldName] = $cache[$key]['type']
->convertToPHPValue($value, $this->_platform);
switch (true) {
case (isset($cache[$key]['isScalar'])):
$rowData[$fieldName] = $value;
break;
case (isset($cache[$key]['isMetaColumn'])):
$rowData[$cache[$key]['dqlAlias'] . '_' . $fieldName] = $value;
break;
default:
$value = $cache[$key]['type']->convertToPHPValue($value, $this->_platform);
$rowData[$cache[$key]['dqlAlias'] . '_' . $fieldName] = $value;
}
}
return $rowData;
}
/**
* Register entity as managed in UnitOfWork.
*
* @param \Doctrine\ORM\Mapping\ClassMetadata $class
* @param object $entity
* @param array $data
*
* @todo The "$id" generation is the same of UnitOfWork#createEntity. Remove this duplication somehow
*/
protected function registerManaged(ClassMetadata $class, $entity, array $data)
{
if ($class->isIdentifierComposite) {
$id = array();
foreach ($class->identifier as $fieldName) {
if (isset($class->associationMappings[$fieldName])) {
$id[$fieldName] = $data[$class->associationMappings[$fieldName]['joinColumns'][0]['name']];
} else {
$id[$fieldName] = $data[$fieldName];
}
}
} else {
if (isset($class->associationMappings[$class->identifier[0]])) {
$id = array($class->identifier[0] => $data[$class->associationMappings[$class->identifier[0]]['joinColumns'][0]['name']]);
} else {
$id = array($class->identifier[0] => $data[$class->identifier[0]]);
}
}
$this->_em->getUnitOfWork()->registerManaged($entity, $id, $data);
}
/**
* When executed in a hydrate() loop we have to clear internal state to
* decrease memory consumption.
*/
public function onClear($eventArgs)
{
}
}

View File

@@ -13,7 +13,7 @@
* 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 LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
@@ -25,8 +25,9 @@ use PDO, Doctrine\DBAL\Connection, Doctrine\ORM\Mapping\ClassMetadata;
* The ArrayHydrator produces a nested array "graph" that is often (not always)
* interchangeable with the corresponding object graph for read-only access.
*
* @since 2.0
* @author Roman Borschel <roman@code-factory.org>
* @since 1.0
* @author Guilherme Blanco <guilhermeblanoc@hotmail.com>
*/
class ArrayHydrator extends AbstractHydrator
{
@@ -38,45 +39,55 @@ class ArrayHydrator extends AbstractHydrator
private $_idTemplate = array();
private $_resultCounter = 0;
/** @override */
protected function _prepare()
/**
* {@inheritdoc}
*/
protected function prepare()
{
$this->_isSimpleQuery = count($this->_rsm->aliasMap) <= 1;
$this->_identifierMap = array();
$this->_isSimpleQuery = count($this->_rsm->aliasMap) <= 1;
$this->_identifierMap = array();
$this->_resultPointers = array();
$this->_idTemplate = array();
$this->_resultCounter = 0;
$this->_idTemplate = array();
$this->_resultCounter = 0;
foreach ($this->_rsm->aliasMap as $dqlAlias => $className) {
$this->_identifierMap[$dqlAlias] = array();
$this->_identifierMap[$dqlAlias] = array();
$this->_resultPointers[$dqlAlias] = array();
$this->_idTemplate[$dqlAlias] = '';
$this->_idTemplate[$dqlAlias] = '';
}
}
/** @override */
protected function _hydrateAll()
/**
* {@inheritdoc}
*/
protected function hydrateAllData()
{
$result = array();
$cache = array();
$cache = array();
while ($data = $this->_stmt->fetch(PDO::FETCH_ASSOC)) {
$this->_hydrateRow($data, $cache, $result);
$this->hydrateRowData($data, $cache, $result);
}
return $result;
}
/** @override */
protected function _hydrateRow(array $data, array &$cache, array &$result)
/**
* {@inheritdoc}
*/
protected function hydrateRowData(array $row, array &$cache, array &$result)
{
// 1) Initialize
$id = $this->_idTemplate; // initialize the id-memory
$nonemptyComponents = array();
$rowData = $this->_gatherRowData($data, $cache, $id, $nonemptyComponents);
$rowData = $this->gatherRowData($row, $cache, $id, $nonemptyComponents);
// Extract scalar values. They're appended at the end.
if (isset($rowData['scalars'])) {
$scalars = $rowData['scalars'];
unset($rowData['scalars']);
if (empty($rowData)) {
++$this->_resultCounter;
}
@@ -90,12 +101,17 @@ class ArrayHydrator extends AbstractHydrator
// It's a joined result
$parent = $this->_rsm->parentAliasMap[$dqlAlias];
$path = $parent . '.' . $dqlAlias;
$path = $parent . '.' . $dqlAlias;
// missing parent data, skipping as RIGHT JOIN hydration is not supported.
if ( ! isset($nonemptyComponents[$parent]) ) {
continue;
}
// Get a reference to the right element in the result tree.
// This element will get the associated element attached.
if ($this->_rsm->isMixed && isset($this->_rootAliases[$parent])) {
$first = reset($this->_resultPointers);
$first = reset($this->_resultPointers);
// TODO: Exception if $key === null ?
$baseElement =& $this->_resultPointers[$parent][key($first)];
} else if (isset($this->_resultPointers[$parent])) {
@@ -104,39 +120,41 @@ class ArrayHydrator extends AbstractHydrator
unset($this->_resultPointers[$dqlAlias]); // Ticket #1228
continue;
}
$relationAlias = $this->_rsm->relationMap[$dqlAlias];
$relation = $this->_getClassMetadata($this->_rsm->aliasMap[$parent])->associationMappings[$relationAlias];
$relation = $this->getClassMetadata($this->_rsm->aliasMap[$parent])->associationMappings[$relationAlias];
// Check the type of the relation (many or single-valued)
if ( ! ($relation['type'] & ClassMetadata::TO_ONE)) {
$oneToOne = false;
if (isset($nonemptyComponents[$dqlAlias])) {
if ( ! isset($baseElement[$relationAlias])) {
$baseElement[$relationAlias] = array();
}
$indexExists = isset($this->_identifierMap[$path][$id[$parent]][$id[$dqlAlias]]);
$index = $indexExists ? $this->_identifierMap[$path][$id[$parent]][$id[$dqlAlias]] : false;
$indexExists = isset($this->_identifierMap[$path][$id[$parent]][$id[$dqlAlias]]);
$index = $indexExists ? $this->_identifierMap[$path][$id[$parent]][$id[$dqlAlias]] : false;
$indexIsValid = $index !== false ? isset($baseElement[$relationAlias][$index]) : false;
if ( ! $indexExists || ! $indexIsValid) {
$element = $data;
if (isset($this->_rsm->indexByMap[$dqlAlias])) {
$field = $this->_rsm->indexByMap[$dqlAlias];
$baseElement[$relationAlias][$element[$field]] = $element;
$baseElement[$relationAlias][$row[$this->_rsm->indexByMap[$dqlAlias]]] = $element;
} else {
$baseElement[$relationAlias][] = $element;
}
end($baseElement[$relationAlias]);
$this->_identifierMap[$path][$id[$parent]][$id[$dqlAlias]] =
key($baseElement[$relationAlias]);
$this->_identifierMap[$path][$id[$parent]][$id[$dqlAlias]] = key($baseElement[$relationAlias]);
}
} else if ( ! isset($baseElement[$relationAlias])) {
$baseElement[$relationAlias] = array();
}
} else {
$oneToOne = true;
if ( ! isset($nonemptyComponents[$dqlAlias]) && ! isset($baseElement[$relationAlias])) {
$baseElement[$relationAlias] = null;
} else if ( ! isset($baseElement[$relationAlias])) {
@@ -152,32 +170,42 @@ class ArrayHydrator extends AbstractHydrator
} else {
// It's a root result element
$this->_rootAliases[$dqlAlias] = true; // Mark as root
$entityKey = $this->_rsm->entityMappings[$dqlAlias] ?: 0;
// if this row has a NULL value for the root result id then make it a null result.
if ( ! isset($nonemptyComponents[$dqlAlias]) ) {
if ($this->_rsm->isMixed) {
$result[] = array($entityKey => null);
} else {
$result[] = null;
}
$resultKey = $this->_resultCounter;
++$this->_resultCounter;
continue;
}
// Check for an existing element
if ($this->_isSimpleQuery || ! isset($this->_identifierMap[$dqlAlias][$id[$dqlAlias]])) {
$element = $rowData[$dqlAlias];
if (isset($this->_rsm->indexByMap[$dqlAlias])) {
$field = $this->_rsm->indexByMap[$dqlAlias];
if ($this->_rsm->isMixed) {
$result[] = array($element[$field] => $element);
++$this->_resultCounter;
} else {
$result[$element[$field]] = $element;
}
} else {
if ($this->_rsm->isMixed) {
$result[] = array($element);
++$this->_resultCounter;
} else {
$result[] = $element;
}
if ($this->_rsm->isMixed) {
$element = array($entityKey => $element);
}
end($result);
$this->_identifierMap[$dqlAlias][$id[$dqlAlias]] = key($result);
if (isset($this->_rsm->indexByMap[$dqlAlias])) {
$resultKey = $row[$this->_rsm->indexByMap[$dqlAlias]];
$result[$resultKey] = $element;
} else {
$resultKey = $this->_resultCounter;
$result[] = $element;
++$this->_resultCounter;
}
$this->_identifierMap[$dqlAlias][$id[$dqlAlias]] = $resultKey;
} else {
$index = $this->_identifierMap[$dqlAlias][$id[$dqlAlias]];
$resultKey = $index;
/*if ($this->_rsm->isMixed) {
$result[] =& $result[$index];
++$this->_resultCounter;
@@ -189,8 +217,17 @@ class ArrayHydrator extends AbstractHydrator
// Append scalar values to mixed result sets
if (isset($scalars)) {
if ( ! isset($resultKey) ) {
// this only ever happens when no object is fetched (scalar result only)
if (isset($this->_rsm->indexByMap['scalars'])) {
$resultKey = $row[$this->_rsm->indexByMap['scalars']];
} else {
$resultKey = $this->_resultCounter - 1;
}
}
foreach ($scalars as $name => $value) {
$result[$this->_resultCounter - 1][$name] = $value;
$result[$resultKey][$name] = $value;
}
}
}
@@ -208,28 +245,45 @@ class ArrayHydrator extends AbstractHydrator
{
if ($coll === null) {
unset($this->_resultPointers[$dqlAlias]); // Ticket #1228
return;
}
if ($index !== false) {
$this->_resultPointers[$dqlAlias] =& $coll[$index];
return;
} else {
if ($coll) {
if ($oneToOne) {
$this->_resultPointers[$dqlAlias] =& $coll;
} else {
end($coll);
$this->_resultPointers[$dqlAlias] =& $coll[key($coll)];
}
}
}
if ( ! $coll) {
return;
}
if ($oneToOne) {
$this->_resultPointers[$dqlAlias] =& $coll;
return;
}
end($coll);
$this->_resultPointers[$dqlAlias] =& $coll[key($coll)];
return;
}
private function _getClassMetadata($className)
/**
* Retrieve ClassMetadata associated to entity class name.
*
* @param string $className
*
* @return \Doctrine\ORM\Mapping\ClassMetadata
*/
private function getClassMetadata($className)
{
if ( ! isset($this->_ce[$className])) {
$this->_ce[$className] = $this->_em->getClassMetadata($className);
}
return $this->_ce[$className];
}
}
}

View File

@@ -8,10 +8,49 @@ class HydrationException extends \Doctrine\ORM\ORMException
{
return new self("The result returned by the query was not unique.");
}
public static function parentObjectOfRelationNotFound($alias, $parentAlias)
{
return new self("The parent object of entity result with alias '$alias' was not found."
. " The parent alias is '$parentAlias'.");
}
public static function emptyDiscriminatorValue($dqlAlias)
{
return new self("The DQL alias '" . $dqlAlias . "' contains an entity ".
"of an inheritance hierachy with an empty discriminator value. This means " .
"that the database contains inconsistent data with an empty " .
"discriminator value in a table row."
);
}
/**
* @since 2.3
* @param string $entityName
* @param string $discrColumnName
* @param string $dqlAlias
* @return HydrationException
*/
public static function missingDiscriminatorColumn($entityName, $discrColumnName, $dqlAlias)
{
return new self(sprintf(
'The discriminator column "%s" is missing for "%s" using the DQL alias "%s".',
$discrColumnName, $entityName, $dqlAlias
));
}
/**
* @since 2.3
* @param string $entityName
* @param string $discrColumnName
* @param string $dqlAlias
* @return HydrationException
*/
public static function missingDiscriminatorMetaMappingColumn($entityName, $discrColumnName, $dqlAlias)
{
return new self(sprintf(
'The meta mapping for the discriminator column "%s" is missing for "%s" using the DQL alias "%s".',
$discrColumnName, $entityName, $dqlAlias
));
}
}

View File

@@ -13,7 +13,7 @@
* 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 LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
@@ -29,7 +29,7 @@ namespace Doctrine\ORM\Internal\Hydration;
class IterableResult implements \Iterator
{
/**
* @var Doctrine\ORM\Internal\Hydration\AbstractHydrator
* @var \Doctrine\ORM\Internal\Hydration\AbstractHydrator
*/
private $_hydrator;
@@ -49,7 +49,7 @@ class IterableResult implements \Iterator
private $_current = null;
/**
* @param Doctrine\ORM\Internal\Hydration\AbstractHydrator $hydrator
* @param \Doctrine\ORM\Internal\Hydration\AbstractHydrator $hydrator
*/
public function __construct($hydrator)
{
@@ -101,4 +101,4 @@ class IterableResult implements \Iterator
{
return ($this->_current!=false);
}
}
}

View File

@@ -13,7 +13,7 @@
* 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 LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
@@ -23,14 +23,19 @@ use PDO,
Doctrine\ORM\Mapping\ClassMetadata,
Doctrine\ORM\PersistentCollection,
Doctrine\ORM\Query,
Doctrine\ORM\Event\LifecycleEventArgs,
Doctrine\ORM\Events,
Doctrine\Common\Collections\ArrayCollection,
Doctrine\Common\Collections\Collection;
Doctrine\Common\Collections\Collection,
Doctrine\ORM\Proxy\Proxy;
/**
* The ObjectHydrator constructs an object graph out of an SQL result set.
*
* @since 2.0
* @author Roman Borschel <roman@code-factory.org>
* @since 2.0
* @author Guilherme Blanco <guilhermeblanoc@hotmail.com>
*
* @internal Highly performance-sensitive code.
*/
class ObjectHydrator extends AbstractHydrator
@@ -39,9 +44,9 @@ class ObjectHydrator extends AbstractHydrator
* This local cache is maintained between hydration runs and not cleared.
*/
private $_ce = array();
/* The following parts are reinitialized on every hydration run. */
private $_identifierMap;
private $_resultPointers;
private $_idTemplate;
@@ -49,56 +54,66 @@ class ObjectHydrator extends AbstractHydrator
private $_rootAliases = array();
private $_initializedCollections = array();
private $_existingCollections = array();
//private $_createdEntities;
/** @override */
protected function _prepare()
protected function prepare()
{
$this->_identifierMap =
$this->_resultPointers =
$this->_idTemplate = array();
$this->_resultCounter = 0;
if ( ! isset($this->_hints['deferEagerLoad'])) {
$this->_hints['deferEagerLoad'] = true;
}
foreach ($this->_rsm->aliasMap as $dqlAlias => $className) {
$this->_identifierMap[$dqlAlias] = array();
$this->_idTemplate[$dqlAlias] = '';
$class = $this->_em->getClassMetadata($className);
$this->_idTemplate[$dqlAlias] = '';
if ( ! isset($this->_ce[$className])) {
$this->_ce[$className] = $class;
$this->_ce[$className] = $this->_em->getClassMetadata($className);
}
// Remember which associations are "fetch joined", so that we know where to inject
// collection stubs or proxies and where not.
if (isset($this->_rsm->relationMap[$dqlAlias])) {
$sourceClassName = $this->_rsm->aliasMap[$this->_rsm->parentAliasMap[$dqlAlias]];
$sourceClass = $this->_getClassMetadata($sourceClassName);
$assoc = $sourceClass->associationMappings[$this->_rsm->relationMap[$dqlAlias]];
$this->_hints['fetched'][$sourceClassName][$assoc['fieldName']] = true;
if ($sourceClass->subClasses) {
foreach ($sourceClass->subClasses as $sourceSubclassName) {
$this->_hints['fetched'][$sourceSubclassName][$assoc['fieldName']] = true;
}
}
if ($assoc['type'] != ClassMetadata::MANY_TO_MANY) {
// Mark any non-collection opposite sides as fetched, too.
if ($assoc['mappedBy']) {
$this->_hints['fetched'][$className][$assoc['mappedBy']] = true;
} else {
if ($assoc['inversedBy']) {
$inverseAssoc = $class->associationMappings[$assoc['inversedBy']];
if ($inverseAssoc['type'] & ClassMetadata::TO_ONE) {
$this->_hints['fetched'][$className][$inverseAssoc['fieldName']] = true;
if ($class->subClasses) {
foreach ($class->subClasses as $targetSubclassName) {
$this->_hints['fetched'][$targetSubclassName][$inverseAssoc['fieldName']] = true;
}
}
}
}
}
if ( ! isset($this->_rsm->relationMap[$dqlAlias])) {
continue;
}
if ( ! isset($this->_rsm->aliasMap[$this->_rsm->parentAliasMap[$dqlAlias]])) {
throw HydrationException::parentObjectOfRelationNotFound($dqlAlias, $this->_rsm->parentAliasMap[$dqlAlias]);
}
$sourceClassName = $this->_rsm->aliasMap[$this->_rsm->parentAliasMap[$dqlAlias]];
$sourceClass = $this->_getClassMetadata($sourceClassName);
$assoc = $sourceClass->associationMappings[$this->_rsm->relationMap[$dqlAlias]];
$this->_hints['fetched'][$this->_rsm->parentAliasMap[$dqlAlias]][$assoc['fieldName']] = true;
if ($assoc['type'] === ClassMetadata::MANY_TO_MANY) {
continue;
}
// Mark any non-collection opposite sides as fetched, too.
if ($assoc['mappedBy']) {
$this->_hints['fetched'][$dqlAlias][$assoc['mappedBy']] = true;
continue;
}
// handle fetch-joined owning side bi-directional one-to-one associations
if ($assoc['inversedBy']) {
$class = $this->_ce[$className];
$inverseAssoc = $class->associationMappings[$assoc['inversedBy']];
if ( ! ($inverseAssoc['type'] & ClassMetadata::TO_ONE)) {
continue;
}
$this->_hints['fetched'][$dqlAlias][$inverseAssoc['fieldName']] = true;
}
}
}
@@ -106,25 +121,32 @@ class ObjectHydrator extends AbstractHydrator
/**
* {@inheritdoc}
*/
protected function _cleanup()
protected function cleanup()
{
parent::_cleanup();
$eagerLoad = (isset($this->_hints['deferEagerLoad'])) && $this->_hints['deferEagerLoad'] == true;
parent::cleanup();
$this->_identifierMap =
$this->_initializedCollections =
$this->_existingCollections =
$this->_resultPointers = array();
if ($eagerLoad) {
$this->_em->getUnitOfWork()->triggerEagerLoads();
}
}
/**
* {@inheritdoc}
*/
protected function _hydrateAll()
protected function hydrateAllData()
{
$result = array();
$cache = array();
$cache = array();
while ($row = $this->_stmt->fetch(PDO::FETCH_ASSOC)) {
$this->_hydrateRow($row, $cache, $result);
$this->hydrateRowData($row, $cache, $result);
}
// Take snapshots from all newly initialized collections
@@ -138,36 +160,41 @@ class ObjectHydrator extends AbstractHydrator
/**
* Initializes a related collection.
*
* @param object $entity The entity to which the collection belongs.
* @param string $name The name of the field on the entity that holds the collection.
* @param object $entity The entity to which the collection belongs.
* @param ClassMetadata $class
* @param string $fieldName The name of the field on the entity that holds the collection.
* @param string $parentDqlAlias Alias of the parent fetch joining this collection.
*/
private function _initRelatedCollection($entity, $class, $fieldName)
private function _initRelatedCollection($entity, $class, $fieldName, $parentDqlAlias)
{
$oid = spl_object_hash($entity);
$oid = spl_object_hash($entity);
$relation = $class->associationMappings[$fieldName];
$value = $class->reflFields[$fieldName]->getValue($entity);
$value = $class->reflFields[$fieldName]->getValue($entity);
if ($value === null) {
$value = new ArrayCollection;
}
if ( ! $value instanceof PersistentCollection) {
$value = new PersistentCollection(
$this->_em,
$this->_ce[$relation['targetEntity']],
$value
$this->_em, $this->_ce[$relation['targetEntity']], $value
);
$value->setOwner($entity, $relation);
$class->reflFields[$fieldName]->setValue($entity, $value);
$this->_uow->setOriginalEntityProperty($oid, $fieldName, $value);
$this->_initializedCollections[$oid . $fieldName] = $value;
} else if (isset($this->_hints[Query::HINT_REFRESH]) ||
isset($this->_hints['fetched'][$class->name][$fieldName]) &&
! $value->isInitialized()) {
} else if (
isset($this->_hints[Query::HINT_REFRESH]) ||
isset($this->_hints['fetched'][$parentDqlAlias][$fieldName]) &&
! $value->isInitialized()
) {
// Is already PersistentCollection, but either REFRESH or FETCH-JOIN and UNINITIALIZED!
$value->setDirty(false);
$value->setInitialized(true);
$value->unwrap()->clear();
$this->_initializedCollections[$oid . $fieldName] = $value;
} else {
// Is already PersistentCollection, and DON'T REFRESH or FETCH-JOIN!
@@ -176,44 +203,81 @@ class ObjectHydrator extends AbstractHydrator
return $value;
}
/**
* Gets an entity instance.
*
* @param $data The instance data.
* @param $dqlAlias The DQL alias of the entity's class.
*
* @param array $data The instance data.
* @param string $dqlAlias The DQL alias of the entity's class.
* @return object The entity.
*/
private function _getEntity(array $data, $dqlAlias)
{
$className = $this->_rsm->aliasMap[$dqlAlias];
$className = $this->_rsm->aliasMap[$dqlAlias];
if (isset($this->_rsm->discriminatorColumns[$dqlAlias])) {
if ( ! isset($this->_rsm->metaMappings[$this->_rsm->discriminatorColumns[$dqlAlias]])) {
throw HydrationException::missingDiscriminatorMetaMappingColumn($className, $this->_rsm->discriminatorColumns[$dqlAlias], $dqlAlias);
}
$discrColumn = $this->_rsm->metaMappings[$this->_rsm->discriminatorColumns[$dqlAlias]];
if ( ! isset($data[$discrColumn])) {
throw HydrationException::missingDiscriminatorColumn($className, $discrColumn, $dqlAlias);
}
if ($data[$discrColumn] === "") {
throw HydrationException::emptyDiscriminatorValue($dqlAlias);
}
$className = $this->_ce[$className]->discriminatorMap[$data[$discrColumn]];
unset($data[$discrColumn]);
}
if (isset($this->_hints[Query::HINT_REFRESH_ENTITY]) && isset($this->_rootAliases[$dqlAlias])) {
$this->registerManaged($this->_ce[$className], $this->_hints[Query::HINT_REFRESH_ENTITY], $data);
}
$this->_hints['fetchAlias'] = $dqlAlias;
return $this->_uow->createEntity($className, $data, $this->_hints);
}
/**
* @param string $className
* @param array $data
* @return mixed
*/
private function _getEntityFromIdentityMap($className, array $data)
{
// TODO: Abstract this code and UnitOfWork::createEntity() equivalent?
$class = $this->_ce[$className];
/* @var $class ClassMetadata */
if ($class->isIdentifierComposite) {
$idHash = '';
foreach ($class->identifier as $fieldName) {
$idHash .= $data[$fieldName] . ' ';
if (isset($class->associationMappings[$fieldName])) {
$idHash .= $data[$class->associationMappings[$fieldName]['joinColumns'][0]['name']] . ' ';
} else {
$idHash .= $data[$fieldName] . ' ';
}
}
return $this->_uow->tryGetByIdHash(rtrim($idHash), $class->rootEntityName);
} else if (isset($class->associationMappings[$class->identifier[0]])) {
return $this->_uow->tryGetByIdHash($data[$class->associationMappings[$class->identifier[0]]['joinColumns'][0]['name']], $class->rootEntityName);
} else {
return $this->_uow->tryGetByIdHash($data[$class->identifier[0]], $class->rootEntityName);
}
}
/**
* Gets a ClassMetadata instance from the local cache.
* If the instance is not yet in the local cache, it is loaded into the
* local cache.
*
*
* @param string $className The name of the class.
* @return ClassMetadata
*/
@@ -222,42 +286,45 @@ class ObjectHydrator extends AbstractHydrator
if ( ! isset($this->_ce[$className])) {
$this->_ce[$className] = $this->_em->getClassMetadata($className);
}
return $this->_ce[$className];
}
/**
* Hydrates a single row in an SQL result set.
*
*
* @internal
* First, the data of the row is split into chunks where each chunk contains data
* that belongs to a particular component/class. Afterwards, all these chunks
* are processed, one after the other. For each chunk of class data only one of the
* following code paths is executed:
*
*
* Path A: The data chunk belongs to a joined/associated object and the association
* is collection-valued.
* Path B: The data chunk belongs to a joined/associated object and the association
* is single-valued.
* Path C: The data chunk belongs to a root result element/object that appears in the topmost
* level of the hydrated result. A typical example are the objects of the type
* specified by the FROM clause in a DQL query.
*
* @param array $data The data of the row to process.
* @param array $cache The cache to use.
* specified by the FROM clause in a DQL query.
*
* @param array $row The data of the row to process.
* @param array $cache The cache to use.
* @param array $result The result array to fill.
*/
protected function _hydrateRow(array $data, array &$cache, array &$result)
protected function hydrateRowData(array $row, array &$cache, array &$result)
{
// Initialize
$id = $this->_idTemplate; // initialize the id-memory
$nonemptyComponents = array();
// Split the row data into chunks of class data.
$rowData = $this->_gatherRowData($data, $cache, $id, $nonemptyComponents);
$rowData = $this->gatherRowData($row, $cache, $id, $nonemptyComponents);
// Extract scalar values. They're appended at the end.
if (isset($rowData['scalars'])) {
$scalars = $rowData['scalars'];
unset($rowData['scalars']);
if (empty($rowData)) {
++$this->_resultCounter;
}
@@ -266,7 +333,7 @@ class ObjectHydrator extends AbstractHydrator
// Hydrate the data chunks
foreach ($rowData as $dqlAlias => $data) {
$entityName = $this->_rsm->aliasMap[$dqlAlias];
if (isset($this->_rsm->parentAliasMap[$dqlAlias])) {
// It's a joined result
@@ -275,10 +342,16 @@ class ObjectHydrator extends AbstractHydrator
// seen for this parent-child relationship
$path = $parentAlias . '.' . $dqlAlias;
// We have a RIGHT JOIN result here. Doctrine cannot hydrate RIGHT JOIN Object-Graphs
if ( ! isset($nonemptyComponents[$parentAlias])) {
// TODO: Add special case code where we hydrate the right join objects into identity map at least
continue;
}
// Get a reference to the parent object to which the joined element belongs.
if ($this->_rsm->isMixed && isset($this->_rootAliases[$parentAlias])) {
$first = reset($this->_resultPointers);
$parentObject = $this->_resultPointers[$parentAlias][key($first)];
$first = reset($this->_resultPointers);
$parentObject = $first[key($first)];
} else if (isset($this->_resultPointers[$parentAlias])) {
$parentObject = $this->_resultPointers[$parentAlias];
} else {
@@ -294,19 +367,20 @@ class ObjectHydrator extends AbstractHydrator
// Check the type of the relation (many or single-valued)
if ( ! ($relation['type'] & ClassMetadata::TO_ONE)) {
$reflFieldValue = $reflField->getValue($parentObject);
// PATH A: Collection-valued association
if (isset($nonemptyComponents[$dqlAlias])) {
$collKey = $oid . $relationField;
if (isset($this->_initializedCollections[$collKey])) {
$reflFieldValue = $this->_initializedCollections[$collKey];
} else if ( ! isset($this->_existingCollections[$collKey])) {
$reflFieldValue = $this->_initRelatedCollection($parentObject, $parentClass, $relationField);
$reflFieldValue = $this->_initRelatedCollection($parentObject, $parentClass, $relationField, $parentAlias);
}
$indexExists = isset($this->_identifierMap[$path][$id[$parentAlias]][$id[$dqlAlias]]);
$index = $indexExists ? $this->_identifierMap[$path][$id[$parentAlias]][$id[$dqlAlias]] : false;
$indexIsValid = $index !== false ? isset($reflFieldValue[$index]) : false;
if ( ! $indexExists || ! $indexIsValid) {
if (isset($this->_existingCollections[$collKey])) {
// Collection exists, only look for the element in the identity map.
@@ -319,8 +393,7 @@ class ObjectHydrator extends AbstractHydrator
$element = $this->_getEntity($data, $dqlAlias);
if (isset($this->_rsm->indexByMap[$dqlAlias])) {
$field = $this->_rsm->indexByMap[$dqlAlias];
$indexValue = $this->_ce[$entityName]->reflFields[$field]->getValue($element);
$indexValue = $row[$this->_rsm->indexByMap[$dqlAlias]];
$reflFieldValue->hydrateSet($indexValue, $element);
$this->_identifierMap[$path][$id[$parentAlias]][$id[$dqlAlias]] = $indexValue;
} else {
@@ -335,21 +408,24 @@ class ObjectHydrator extends AbstractHydrator
// Update result pointer
$this->_resultPointers[$dqlAlias] = $reflFieldValue[$index];
}
} else if ( ! $reflField->getValue($parentObject)) {
$coll = new PersistentCollection($this->_em, $this->_ce[$entityName], new ArrayCollection);
$coll->setOwner($parentObject, $relation);
$reflField->setValue($parentObject, $coll);
$this->_uow->setOriginalEntityProperty($oid, $relationField, $coll);
} else if ( ! $reflFieldValue) {
$reflFieldValue = $this->_initRelatedCollection($parentObject, $parentClass, $relationField, $parentAlias);
} else if ($reflFieldValue instanceof PersistentCollection && $reflFieldValue->isInitialized() === false) {
$reflFieldValue->setInitialized(true);
}
} else {
// PATH B: Single-valued association
$reflFieldValue = $reflField->getValue($parentObject);
if ( ! $reflFieldValue || isset($this->_hints[Query::HINT_REFRESH])) {
if ( ! $reflFieldValue || isset($this->_hints[Query::HINT_REFRESH]) || ($reflFieldValue instanceof Proxy && !$reflFieldValue->__isInitialized__)) {
// we only need to take action if this value is null,
// we refresh the entity or its an unitialized proxy.
if (isset($nonemptyComponents[$dqlAlias])) {
$element = $this->_getEntity($data, $dqlAlias);
$reflField->setValue($parentObject, $element);
$this->_uow->setOriginalEntityProperty($oid, $relationField, $element);
$targetClass = $this->_ce[$relation['targetEntity']];
if ($relation['isOwningSide']) {
//TODO: Just check hints['fetched'] here?
// If there is an inverse mapping on the target class its bidirectional
@@ -370,6 +446,9 @@ class ObjectHydrator extends AbstractHydrator
}
// Update result pointer
$this->_resultPointers[$dqlAlias] = $element;
} else {
$this->_uow->setOriginalEntityProperty($oid, $relationField, null);
$reflField->setValue($parentObject, null);
}
// else leave $reflFieldValue null for single-valued associations
} else {
@@ -380,30 +459,48 @@ class ObjectHydrator extends AbstractHydrator
} else {
// PATH C: Its a root result element
$this->_rootAliases[$dqlAlias] = true; // Mark as root alias
$entityKey = $this->_rsm->entityMappings[$dqlAlias] ?: 0;
// if this row has a NULL value for the root result id then make it a null result.
if ( ! isset($nonemptyComponents[$dqlAlias]) ) {
if ($this->_rsm->isMixed) {
$result[] = array($entityKey => null);
} else {
$result[] = null;
}
$resultKey = $this->_resultCounter;
++$this->_resultCounter;
continue;
}
// check for existing result from the iterations before
if ( ! isset($this->_identifierMap[$dqlAlias][$id[$dqlAlias]])) {
$element = $this->_getEntity($rowData[$dqlAlias], $dqlAlias);
if (isset($this->_rsm->indexByMap[$dqlAlias])) {
$field = $this->_rsm->indexByMap[$dqlAlias];
$key = $this->_ce[$entityName]->reflFields[$field]->getValue($element);
if ($this->_rsm->isMixed) {
$element = array($key => $element);
$result[] = $element;
$this->_identifierMap[$dqlAlias][$id[$dqlAlias]] = $this->_resultCounter;
++$this->_resultCounter;
} else {
$result[$key] = $element;
$this->_identifierMap[$dqlAlias][$id[$dqlAlias]] = $key;
}
} else {
if ($this->_rsm->isMixed) {
$element = array(0 => $element);
}
$result[] = $element;
$this->_identifierMap[$dqlAlias][$id[$dqlAlias]] = $this->_resultCounter;
++$this->_resultCounter;
if ($this->_rsm->isMixed) {
$element = array($entityKey => $element);
}
if (isset($this->_rsm->indexByMap[$dqlAlias])) {
$resultKey = $row[$this->_rsm->indexByMap[$dqlAlias]];
if (isset($this->_hints['collection'])) {
$this->_hints['collection']->hydrateSet($resultKey, $element);
}
$result[$resultKey] = $element;
} else {
$resultKey = $this->_resultCounter;
++$this->_resultCounter;
if (isset($this->_hints['collection'])) {
$this->_hints['collection']->hydrateAdd($element);
}
$result[] = $element;
}
$this->_identifierMap[$dqlAlias][$id[$dqlAlias]] = $resultKey;
// Update result pointer
$this->_resultPointers[$dqlAlias] = $element;
@@ -411,6 +508,7 @@ class ObjectHydrator extends AbstractHydrator
// Update result pointer
$index = $this->_identifierMap[$dqlAlias][$id[$dqlAlias]];
$this->_resultPointers[$dqlAlias] = $result[$index];
$resultKey = $index;
/*if ($this->_rsm->isMixed) {
$result[] = $result[$index];
++$this->_resultCounter;
@@ -421,9 +519,33 @@ class ObjectHydrator extends AbstractHydrator
// Append scalar values to mixed result sets
if (isset($scalars)) {
if ( ! isset($resultKey) ) {
if (isset($this->_rsm->indexByMap['scalars'])) {
$resultKey = $row[$this->_rsm->indexByMap['scalars']];
} else {
$resultKey = $this->_resultCounter - 1;
}
}
foreach ($scalars as $name => $value) {
$result[$this->_resultCounter - 1][$name] = $value;
$result[$resultKey][$name] = $value;
}
}
}
/**
* When executed in a hydrate() loop we may have to clear internal state to
* decrease memory consumption.
*/
public function onClear($eventArgs)
{
parent::onClear($eventArgs);
$aliases = array_keys($this->_identifierMap);
$this->_identifierMap = array();
foreach ($aliases as $alias) {
$this->_identifierMap[$alias] = array();
}
}
}

View File

@@ -13,38 +13,43 @@
* 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 LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Internal\Hydration;
use Doctrine\DBAL\Connection;
/**
* Hydrator that produces flat, rectangular results of scalar data.
* The created result is almost the same as a regular SQL result set, except
* that column names are mapped to field names and data type conversions take place.
*
* @since 2.0
* @author Roman Borschel <roman@code-factory.org>
* @since 2.0
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
*/
class ScalarHydrator extends AbstractHydrator
{
/** @override */
protected function _hydrateAll()
/**
* {@inheritdoc}
*/
protected function hydrateAllData()
{
$result = array();
$cache = array();
$cache = array();
while ($data = $this->_stmt->fetch(\PDO::FETCH_ASSOC)) {
$result[] = $this->_gatherScalarRowData($data, $cache);
$this->hydrateRowData($data, $cache, $result);
}
return $result;
}
/** @override */
protected function _hydrateRow(array $data, array &$cache, array &$result)
/**
* {@inheritdoc}
*/
protected function hydrateRowData(array $data, array &$cache, array &$result)
{
$result[] = $this->_gatherScalarRowData($data, $cache);
$result[] = $this->gatherScalarRowData($data, $cache);
}
}
}

View File

@@ -0,0 +1,187 @@
<?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\ORM\Internal\Hydration;
use \PDO,
Doctrine\DBAL\Types\Type,
Doctrine\ORM\Mapping\ClassMetadata,
Doctrine\ORM\Event\LifecycleEventArgs,
Doctrine\ORM\Events,
Doctrine\ORM\Query;
class SimpleObjectHydrator extends AbstractHydrator
{
/**
* @var ClassMetadata
*/
private $class;
/**
* @var array
*/
private $declaringClasses = array();
/**
* {@inheritdoc}
*/
protected function hydrateAllData()
{
$result = array();
$cache = array();
while ($row = $this->_stmt->fetch(PDO::FETCH_ASSOC)) {
$this->hydrateRowData($row, $cache, $result);
}
$this->_em->getUnitOfWork()->triggerEagerLoads();
return $result;
}
/**
* {@inheritdoc}
*/
protected function prepare()
{
if (count($this->_rsm->aliasMap) !== 1) {
throw new \RuntimeException("Cannot use SimpleObjectHydrator with a ResultSetMapping that contains more than one object result.");
}
if ($this->_rsm->scalarMappings) {
throw new \RuntimeException("Cannot use SimpleObjectHydrator with a ResultSetMapping that contains scalar mappings.");
}
$this->class = $this->_em->getClassMetadata(reset($this->_rsm->aliasMap));
// We only need to add declaring classes if we have inheritance.
if ($this->class->inheritanceType === ClassMetadata::INHERITANCE_TYPE_NONE) {
return;
}
foreach ($this->_rsm->declaringClasses as $column => $class) {
$this->declaringClasses[$column] = $this->_em->getClassMetadata($class);
}
}
/**
* {@inheritdoc}
*/
protected function hydrateRowData(array $sqlResult, array &$cache, array &$result)
{
$entityName = $this->class->name;
$data = array();
// We need to find the correct entity class name if we have inheritance in resultset
if ($this->class->inheritanceType !== ClassMetadata::INHERITANCE_TYPE_NONE) {
$discrColumnName = $this->_platform->getSQLResultCasing($this->class->discriminatorColumn['name']);
if ( ! isset($sqlResult[$discrColumnName])) {
throw HydrationException::missingDiscriminatorColumn($entityName, $discrColumnName, key($this->_rsm->aliasMap));
}
if ($sqlResult[$discrColumnName] === '') {
throw HydrationException::emptyDiscriminatorValue(key($this->_rsm->aliasMap));
}
$entityName = $this->class->discriminatorMap[$sqlResult[$discrColumnName]];
unset($sqlResult[$discrColumnName]);
}
foreach ($sqlResult as $column => $value) {
// Hydrate column information if not yet present
if ( ! isset($cache[$column])) {
if (($info = $this->hydrateColumnInfo($entityName, $column)) === null) {
continue;
}
$cache[$column] = $info;
}
// Convert field to a valid PHP value
if (isset($cache[$column]['field'])) {
$type = Type::getType($cache[$column]['class']->fieldMappings[$cache[$column]['name']]['type']);
$value = $type->convertToPHPValue($value, $this->_platform);
}
// Prevent overwrite in case of inherit classes using same property name (See AbstractHydrator)
if (isset($cache[$column]) && ( ! isset($data[$cache[$column]['name']]) || $value !== null)) {
$data[$cache[$column]['name']] = $value;
}
}
if (isset($this->_hints[Query::HINT_REFRESH_ENTITY])) {
$this->registerManaged($this->class, $this->_hints[Query::HINT_REFRESH_ENTITY], $data);
}
$uow = $this->_em->getUnitOfWork();
$entity = $uow->createEntity($entityName, $data, $this->_hints);
$result[] = $entity;
}
/**
* Retrieve column information form ResultSetMapping.
*
* @param string $entityName
* @param string $column
*
* @return array
*/
protected function hydrateColumnInfo($entityName, $column)
{
switch (true) {
case (isset($this->_rsm->fieldMappings[$column])):
$class = isset($this->declaringClasses[$column])
? $this->declaringClasses[$column]
: $this->class;
// If class is not part of the inheritance, ignore
if ( ! ($class->name === $entityName || is_subclass_of($entityName, $class->name))) {
return null;
}
return array(
'class' => $class,
'name' => $this->_rsm->fieldMappings[$column],
'field' => true,
);
case (isset($this->_rsm->relationMap[$column])):
$class = isset($this->_rsm->relationMap[$column])
? $this->_rsm->relationMap[$column]
: $this->class;
// If class is not self referencing, ignore
if ( ! ($class === $entityName || is_subclass_of($entityName, $class))) {
return null;
}
// TODO: Decide what to do with associations. It seems original code is incomplete.
// One solution is to load the association, but it might require extra efforts.
return array('name' => $column);
default:
return array(
'name' => $this->_rsm->metaMappings[$column]
);
}
}
}

View File

@@ -13,37 +13,44 @@
* 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 LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Internal\Hydration;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Connection,
Doctrine\ORM\NoResultException,
Doctrine\ORM\NonUniqueResultException;
/**
* Hydrator that hydrates a single scalar value from the result set.
*
* @since 2.0
* @author Roman Borschel <roman@code-factory.org>
* @since 2.0
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
*/
class SingleScalarHydrator extends AbstractHydrator
{
/** @override */
protected function _hydrateAll()
/**
* {@inheritdoc}
*/
protected function hydrateAllData()
{
$cache = array();
$result = $this->_stmt->fetchAll(\PDO::FETCH_ASSOC);
$num = count($result);
$data = $this->_stmt->fetchAll(\PDO::FETCH_ASSOC);
$numRows = count($data);
if ($num == 0) {
throw new \Doctrine\ORM\NoResultException;
} else if ($num > 1 || count($result[key($result)]) > 1) {
throw new \Doctrine\ORM\NonUniqueResultException;
if ($numRows === 0) {
throw new NoResultException();
}
$result = $this->_gatherScalarRowData($result[key($result)], $cache);
if ($numRows > 1 || count($data[key($data)]) > 1) {
throw new NonUniqueResultException();
}
$cache = array();
$result = $this->gatherScalarRowData($data[key($data)], $cache);
return array_shift($result);
}
}
}

View File

@@ -0,0 +1,24 @@
<?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\ORM\Mapping;
interface Annotation
{
}

View File

@@ -0,0 +1,56 @@
<?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\ORM\Mapping;
/**
* This annotation is used to override association mapping of property for an entity relationship.
*
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
* @since 2.3
*
* @Annotation
* @Target("ANNOTATION")
*/
final class AssociationOverride implements Annotation
{
/**
* The name of the relationship property whose mapping is being overridden
*
* @var string
*/
public $name;
/**
* The join column that is being mapped to the persistent attribute.
*
* @var array<\Doctrine\ORM\Mapping\JoinColumn>
*/
public $joinColumns;
/**
* The join table that maps the relationship.
*
* @var \Doctrine\ORM\Mapping\JoinTable
*/
public $joinTable;
}

View File

@@ -0,0 +1,41 @@
<?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\ORM\Mapping;
/**
* This annotation is used to override association mappings of relationship properties.
*
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
* @since 2.3
*
* @Annotation
* @Target("CLASS")
*/
final class AssociationOverrides implements Annotation
{
/**
* Mapping overrides of relationship properties
*
* @var array<\Doctrine\ORM\Mapping\AssociationOverride>
*/
public $value;
}

View File

@@ -0,0 +1,47 @@
<?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\ORM\Mapping;
/**
* This annotation is used to override the mapping of a entity property.
*
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
* @since 2.3
*
* @Annotation
* @Target("ANNOTATION")
*/
final class AttributeOverride implements Annotation
{
/**
* The name of the property whose mapping is being overridden.
*
* @var string
*/
public $name;
/**
* The column definition.
*
* @var \Doctrine\ORM\Mapping\Column
*/
public $column;
}

View File

@@ -0,0 +1,41 @@
<?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\ORM\Mapping;
/**
* This annotation is used to override the mapping of a entity property.
*
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
* @since 2.3
*
* @Annotation
* @Target("CLASS")
*/
final class AttributeOverrides implements Annotation
{
/**
* One or more field or property mapping overrides.
*
* @var array<\Doctrine\ORM\Mapping\AttributeOverride>
*/
public $value;
}

View File

@@ -0,0 +1,167 @@
<?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\ORM\Mapping\Builder;
use Doctrine\ORM\Mapping\ClassMetadata;
class AssociationBuilder
{
/**
* @var ClassMetadataBuilder
*/
protected $builder;
/**
* @var array
*/
protected $mapping;
/**
* @var array
*/
protected $joinColumns;
/**
*
* @var int
*/
protected $type;
/**
* @param ClassMetadataBuilder $builder
* @param array $mapping
*/
public function __construct(ClassMetadataBuilder $builder, array $mapping, $type)
{
$this->builder = $builder;
$this->mapping = $mapping;
$this->type = $type;
}
public function mappedBy($fieldName)
{
$this->mapping['mappedBy'] = $fieldName;
return $this;
}
public function inversedBy($fieldName)
{
$this->mapping['inversedBy'] = $fieldName;
return $this;
}
public function cascadeAll()
{
$this->mapping['cascade'] = array("ALL");
return $this;
}
public function cascadePersist()
{
$this->mapping['cascade'][] = "persist";
return $this;
}
public function cascadeRemove()
{
$this->mapping['cascade'][] = "remove";
return $this;
}
public function cascadeMerge()
{
$this->mapping['cascade'][] = "merge";
return $this;
}
public function cascadeDetach()
{
$this->mapping['cascade'][] = "detach";
return $this;
}
public function cascadeRefresh()
{
$this->mapping['cascade'][] = "refresh";
return $this;
}
public function fetchExtraLazy()
{
$this->mapping['fetch'] = ClassMetadata::FETCH_EXTRA_LAZY;
return $this;
}
public function fetchEager()
{
$this->mapping['fetch'] = ClassMetadata::FETCH_EAGER;
return $this;
}
public function fetchLazy()
{
$this->mapping['fetch'] = ClassMetadata::FETCH_LAZY;
return $this;
}
/**
* Add Join Columns
*
* @param string $columnName
* @param string $referencedColumnName
* @param bool $nullable
* @param bool $unique
* @param string $onDelete
* @param string $columnDef
*/
public function addJoinColumn($columnName, $referencedColumnName, $nullable = true, $unique = false, $onDelete = null, $columnDef = null)
{
$this->joinColumns[] = array(
'name' => $columnName,
'referencedColumnName' => $referencedColumnName,
'nullable' => $nullable,
'unique' => $unique,
'onDelete' => $onDelete,
'columnDefinition' => $columnDef,
);
return $this;
}
/**
* @return ClassMetadataBuilder
*/
public function build()
{
$mapping = $this->mapping;
if ($this->joinColumns) {
$mapping['joinColumns'] = $this->joinColumns;
}
$cm = $this->builder->getClassMetadata();
if ($this->type == ClassMetadata::MANY_TO_ONE) {
$cm->mapManyToOne($mapping);
} else if ($this->type == ClassMetadata::ONE_TO_ONE) {
$cm->mapOneToOne($mapping);
} else {
throw new \InvalidArgumentException("Type should be a ToOne Assocation here");
}
return $this->builder;
}
}

View File

@@ -0,0 +1,470 @@
<?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\ORM\Mapping\Builder;
use Doctrine\ORM\Mapping\ClassMetadata,
Doctrine\ORM\Mapping\ClassMetadataInfo;
/**
* Builder Object for ClassMetadata
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.com
* @since 2.2
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
*/
class ClassMetadataBuilder
{
/**
* @var \Doctrine\ORM\Mapping\ClassMetadataInfo
*/
private $cm;
/**
* @param \Doctrine\ORM\Mapping\ClassMetadataInfo $cm
*/
public function __construct(ClassMetadataInfo $cm)
{
$this->cm = $cm;
}
/**
* @return ClassMetadata
*/
public function getClassMetadata()
{
return $this->cm;
}
/**
* Mark the class as mapped superclass.
*
* @return ClassMetadataBuilder
*/
public function setMappedSuperClass()
{
$this->cm->isMappedSuperclass = true;
return $this;
}
/**
* Set custom Repository class name
*
* @param string $repositoryClassName
* @return ClassMetadataBuilder
*/
public function setCustomRepositoryClass($repositoryClassName)
{
$this->cm->setCustomRepositoryClass($repositoryClassName);
return $this;
}
/**
* Mark class read only
*
* @return ClassMetadataBuilder
*/
public function setReadOnly()
{
$this->cm->markReadOnly();
return $this;
}
/**
* Set the table name
*
* @param string $name
* @return ClassMetadataBuilder
*/
public function setTable($name)
{
$this->cm->setPrimaryTable(array('name' => $name));
return $this;
}
/**
* Add Index
*
* @param array $columns
* @param string $name
* @return ClassMetadataBuilder
*/
public function addIndex(array $columns, $name)
{
if (!isset($this->cm->table['indexes'])) {
$this->cm->table['indexes'] = array();
}
$this->cm->table['indexes'][$name] = array('columns' => $columns);
return $this;
}
/**
* Add Unique Constraint
*
* @param array $columns
* @param string $name
* @return ClassMetadataBuilder
*/
public function addUniqueConstraint(array $columns, $name)
{
if ( ! isset($this->cm->table['uniqueConstraints'])) {
$this->cm->table['uniqueConstraints'] = array();
}
$this->cm->table['uniqueConstraints'][$name] = array('columns' => $columns);
return $this;
}
/**
* Add named query
*
* @param string $name
* @param string $dqlQuery
* @return ClassMetadataBuilder
*/
public function addNamedQuery($name, $dqlQuery)
{
$this->cm->addNamedQuery(array(
'name' => $name,
'query' => $dqlQuery,
));
return $this;
}
/**
* Set class as root of a joined table inheritance hierachy.
*
* @return ClassMetadataBuilder
*/
public function setJoinedTableInheritance()
{
$this->cm->setInheritanceType(ClassMetadata::INHERITANCE_TYPE_JOINED);
return $this;
}
/**
* Set class as root of a single table inheritance hierachy.
*
* @return ClassMetadataBuilder
*/
public function setSingleTableInheritance()
{
$this->cm->setInheritanceType(ClassMetadata::INHERITANCE_TYPE_SINGLE_TABLE);
return $this;
}
/**
* Set the discriminator column details.
*
* @param string $name
* @param string $type
*/
public function setDiscriminatorColumn($name, $type = 'string', $length = 255)
{
$this->cm->setDiscriminatorColumn(array(
'name' => $name,
'type' => $type,
'length' => $length,
));
return $this;
}
/**
* Add a subclass to this inheritance hierachy.
*
* @param string $name
* @param string $class
* @return ClassMetadataBuilder
*/
public function addDiscriminatorMapClass($name, $class)
{
$this->cm->addDiscriminatorMapClass($name, $class);
return $this;
}
/**
* Set deferred explicit change tracking policy.
*
* @return ClassMetadataBuilder
*/
public function setChangeTrackingPolicyDeferredExplicit()
{
$this->cm->setChangeTrackingPolicy(ClassMetadata::CHANGETRACKING_DEFERRED_EXPLICIT);
return $this;
}
/**
* Set notify change tracking policy.
*
* @return ClassMetadataBuilder
*/
public function setChangeTrackingPolicyNotify()
{
$this->cm->setChangeTrackingPolicy(ClassMetadata::CHANGETRACKING_NOTIFY);
return $this;
}
/**
* Add lifecycle event
*
* @param string $methodName
* @param string $event
* @return ClassMetadataBuilder
*/
public function addLifecycleEvent($methodName, $event)
{
$this->cm->addLifecycleCallback($methodName, $event);
return $this;
}
/**
* Add Field
*
* @param string $name
* @param string $type
* @param array $mapping
*/
public function addField($name, $type, array $mapping = array())
{
$mapping['fieldName'] = $name;
$mapping['type'] = $type;
$this->cm->mapField($mapping);
return $this;
}
/**
* Create a field builder.
*
* @param string $name
* @param string $type
* @return FieldBuilder
*/
public function createField($name, $type)
{
return new FieldBuilder(
$this,
array(
'fieldName' => $name,
'type' => $type
)
);
}
/**
* Add a simple many to one association, optionally with the inversed by field.
*
* @param string $name
* @param string $targetEntity
* @param string|null $inversedBy
* @return ClassMetadataBuilder
*/
public function addManyToOne($name, $targetEntity, $inversedBy = null)
{
$builder = $this->createManyToOne($name, $targetEntity);
if ($inversedBy) {
$builder->inversedBy($inversedBy);
}
return $builder->build();
}
/**
* Create a ManyToOne Assocation Builder.
*
* Note: This method does not add the association, you have to call build() on the AssociationBuilder.
*
* @param string $name
* @param string $targetEntity
* @return AssociationBuilder
*/
public function createManyToOne($name, $targetEntity)
{
return new AssociationBuilder(
$this,
array(
'fieldName' => $name,
'targetEntity' => $targetEntity
),
ClassMetadata::MANY_TO_ONE
);
}
/**
* Create OneToOne Assocation Builder
*
* @param string $name
* @param string $targetEntity
* @return AssociationBuilder
*/
public function createOneToOne($name, $targetEntity)
{
return new AssociationBuilder(
$this,
array(
'fieldName' => $name,
'targetEntity' => $targetEntity
),
ClassMetadata::ONE_TO_ONE
);
}
/**
* Add simple inverse one-to-one assocation.
*
* @param string $name
* @param string $targetEntity
* @param string $mappedBy
* @return ClassMetadataBuilder
*/
public function addInverseOneToOne($name, $targetEntity, $mappedBy)
{
$builder = $this->createOneToOne($name, $targetEntity);
$builder->mappedBy($mappedBy);
return $builder->build();
}
/**
* Add simple owning one-to-one assocation.
*
* @param string $name
* @param string $targetEntity
* @param string $inversedBy
* @return ClassMetadataBuilder
*/
public function addOwningOneToOne($name, $targetEntity, $inversedBy = null)
{
$builder = $this->createOneToOne($name, $targetEntity);
if ($inversedBy) {
$builder->inversedBy($inversedBy);
}
return $builder->build();
}
/**
* Create ManyToMany Assocation Builder
*
* @param string $name
* @param string $targetEntity
* @return ManyToManyAssociationBuilder
*/
public function createManyToMany($name, $targetEntity)
{
return new ManyToManyAssociationBuilder(
$this,
array(
'fieldName' => $name,
'targetEntity' => $targetEntity
),
ClassMetadata::MANY_TO_MANY
);
}
/**
* Add a simple owning many to many assocation.
*
* @param string $name
* @param string $targetEntity
* @param string|null $inversedBy
* @return ClassMetadataBuilder
*/
public function addOwningManyToMany($name, $targetEntity, $inversedBy = null)
{
$builder = $this->createManyToMany($name, $targetEntity);
if ($inversedBy) {
$builder->inversedBy($inversedBy);
}
return $builder->build();
}
/**
* Add a simple inverse many to many assocation.
*
* @param string $name
* @param string $targetEntity
* @param string $mappedBy
* @return ClassMetadataBuilder
*/
public function addInverseManyToMany($name, $targetEntity, $mappedBy)
{
$builder = $this->createManyToMany($name, $targetEntity);
$builder->mappedBy($mappedBy);
return $builder->build();
}
/**
* Create a one to many assocation builder
*
* @param string $name
* @param string $targetEntity
* @return OneToManyAssociationBuilder
*/
public function createOneToMany($name, $targetEntity)
{
return new OneToManyAssociationBuilder(
$this,
array(
'fieldName' => $name,
'targetEntity' => $targetEntity
),
ClassMetadata::ONE_TO_MANY
);
}
/**
* Add simple OneToMany assocation.
*
* @param string $name
* @param string $targetEntity
* @param string $mappedBy
* @return ClassMetadataBuilder
*/
public function addOneToMany($name, $targetEntity, $mappedBy)
{
$builder = $this->createOneToMany($name, $targetEntity);
$builder->mappedBy($mappedBy);
return $builder->build();
}
}

View File

@@ -0,0 +1,223 @@
<?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\ORM\Mapping\Builder;
/**
* Field Builder
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.com
* @since 2.2
* @author Benjamin Eberlei <kontakt@beberlei.de>
*/
class FieldBuilder
{
/**
* @var ClassMetadataBuilder
*/
private $builder;
/**
* @var array
*/
private $mapping;
/**
* @var bool
*/
private $version;
/**
* @var string
*/
private $generatedValue;
/**
* @var array
*/
private $sequenceDef;
/**
*
* @param ClassMetadataBuilder $builder
* @param array $mapping
*/
public function __construct(ClassMetadataBuilder $builder, array $mapping)
{
$this->builder = $builder;
$this->mapping = $mapping;
}
/**
* Set length.
*
* @param int $length
* @return FieldBuilder
*/
public function length($length)
{
$this->mapping['length'] = $length;
return $this;
}
/**
* Set nullable
*
* @param bool
* @return FieldBuilder
*/
public function nullable($flag = true)
{
$this->mapping['nullable'] = (bool)$flag;
return $this;
}
/**
* Set Unique
*
* @param bool
* @return FieldBuilder
*/
public function unique($flag = true)
{
$this->mapping['unique'] = (bool)$flag;
return $this;
}
/**
* Set column name
*
* @param string $name
* @return FieldBuilder
*/
public function columnName($name)
{
$this->mapping['columnName'] = $name;
return $this;
}
/**
* Set Precision
*
* @param int $p
* @return FieldBuilder
*/
public function precision($p)
{
$this->mapping['precision'] = $p;
return $this;
}
/**
* Set scale.
*
* @param int $s
* @return FieldBuilder
*/
public function scale($s)
{
$this->mapping['scale'] = $s;
return $this;
}
/**
* Set field as primary key.
*
* @return FieldBuilder
*/
public function isPrimaryKey()
{
$this->mapping['id'] = true;
return $this;
}
/**
* @param int $strategy
* @return FieldBuilder
*/
public function generatedValue($strategy = 'AUTO')
{
$this->generatedValue = $strategy;
return $this;
}
/**
* Set field versioned
*
* @return FieldBuilder
*/
public function isVersionField()
{
$this->version = true;
return $this;
}
/**
* Set Sequence Generator
*
* @param string $sequenceName
* @param int $allocationSize
* @param int $initialValue
* @return FieldBuilder
*/
public function setSequenceGenerator($sequenceName, $allocationSize = 1, $initialValue = 1)
{
$this->sequenceDef = array(
'sequenceName' => $sequenceName,
'allocationSize' => $allocationSize,
'initialValue' => $initialValue,
);
return $this;
}
/**
* Set column definition.
*
* @param string $def
* @return FieldBuilder
*/
public function columnDefinition($def)
{
$this->mapping['columnDefinition'] = $def;
return $this;
}
/**
* Finalize this field and attach it to the ClassMetadata.
*
* Without this call a FieldBuilder has no effect on the ClassMetadata.
*
* @return ClassMetadataBuilder
*/
public function build()
{
$cm = $this->builder->getClassMetadata();
if ($this->generatedValue) {
$cm->setIdGeneratorType(constant('Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_' . $this->generatedValue));
}
if ($this->version) {
$cm->setVersionMapping($this->mapping);
}
$cm->mapField($this->mapping);
if ($this->sequenceDef) {
$cm->setSequenceGeneratorDefinition($this->sequenceDef);
}
return $this->builder;
}
}

View File

@@ -0,0 +1,86 @@
<?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\ORM\Mapping\Builder;
/**
* ManyToMany Association Builder
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.com
* @since 2.0
* @author Benjamin Eberlei <kontakt@beberlei.de>
*/
class ManyToManyAssociationBuilder extends OneToManyAssociationBuilder
{
private $joinTableName;
private $inverseJoinColumns = array();
public function setJoinTable($name)
{
$this->joinTableName = $name;
return $this;
}
/**
* Add Inverse Join Columns
*
* @param string $columnName
* @param string $referencedColumnName
* @param bool $nullable
* @param bool $unique
* @param string $onDelete
* @param string $columnDef
*/
public function addInverseJoinColumn($columnName, $referencedColumnName, $nullable = true, $unique = false, $onDelete = null, $columnDef = null)
{
$this->inverseJoinColumns[] = array(
'name' => $columnName,
'referencedColumnName' => $referencedColumnName,
'nullable' => $nullable,
'unique' => $unique,
'onDelete' => $onDelete,
'columnDefinition' => $columnDef,
);
return $this;
}
/**
* @return ClassMetadataBuilder
*/
public function build()
{
$mapping = $this->mapping;
$mapping['joinTable'] = array();
if ($this->joinColumns) {
$mapping['joinTable']['joinColumns'] = $this->joinColumns;
}
if ($this->inverseJoinColumns) {
$mapping['joinTable']['inverseJoinColumns'] = $this->inverseJoinColumns;
}
if ($this->joinTableName) {
$mapping['joinTable']['name'] = $this->joinTableName;
}
$cm = $this->builder->getClassMetadata();
$cm->mapManyToMany($mapping);
return $this->builder;
}
}

View File

@@ -0,0 +1,62 @@
<?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\ORM\Mapping\Builder;
/**
* OneToMany Association Builder
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.com
* @since 2.0
* @author Benjamin Eberlei <kontakt@beberlei.de>
*/
class OneToManyAssociationBuilder extends AssociationBuilder
{
/**
* @param array $fieldNames
* @return OneToManyAssociationBuilder
*/
public function setOrderBy(array $fieldNames)
{
$this->mapping['orderBy'] = $fieldNames;
return $this;
}
public function setIndexBy($fieldName)
{
$this->mapping['indexBy'] = $fieldName;
return $this;
}
/**
* @return ClassMetadataBuilder
*/
public function build()
{
$mapping = $this->mapping;
if ($this->joinColumns) {
$mapping['joinColumns'] = $this->joinColumns;
}
$cm = $this->builder->getClassMetadata();
$cm->mapOneToMany($mapping);
return $this->builder;
}
}

View File

@@ -0,0 +1,30 @@
<?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\ORM\Mapping;
/**
* @Annotation
* @Target("CLASS")
*/
final class ChangeTrackingPolicy implements Annotation
{
/** @var string */
public $value;
}

View File

@@ -13,364 +13,17 @@
* 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 LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping;
use ReflectionClass, ReflectionProperty;
/**
* A <tt>ClassMetadata</tt> instance holds all the object-relational mapping metadata
* of an entity and it's associations.
*
* Once populated, ClassMetadata instances are usually cached in a serialized form.
* {@inheritDoc}
*
* <b>IMPORTANT NOTE:</b>
*
* The fields of this class are only public for 2 reasons:
* 1) To allow fast READ access.
* 2) To drastically reduce the size of a serialized instance (private/protected members
* get the whole class name, namespace inclusive, prepended to every property in
* the serialized representation).
*
* @author Roman Borschel <roman@code-factory.org>
* @author Jonathan H. Wage <jonwage@gmail.com>
* @since 2.0
* @todo remove or rename ClassMetadataInfo to ClassMetadata
*/
class ClassMetadata extends ClassMetadataInfo
{
/**
* The ReflectionProperty instances of the mapped class.
*
* @var array
*/
public $reflFields = array();
/**
* The prototype from which new instances of the mapped class are created.
*
* @var object
*/
private $_prototype;
/**
* Initializes a new ClassMetadata instance that will hold the object-relational mapping
* metadata of the class with the given name.
*
* @param string $entityName The name of the entity class the new instance is used for.
*/
public function __construct($entityName)
{
parent::__construct($entityName);
$this->reflClass = new ReflectionClass($entityName);
$this->namespace = $this->reflClass->getNamespaceName();
$this->table['name'] = $this->reflClass->getShortName();
}
/**
* Gets the ReflectionPropertys of the mapped class.
*
* @return array An array of ReflectionProperty instances.
*/
public function getReflectionProperties()
{
return $this->reflFields;
}
/**
* Gets a ReflectionProperty for a specific field of the mapped class.
*
* @param string $name
* @return ReflectionProperty
*/
public function getReflectionProperty($name)
{
return $this->reflFields[$name];
}
/**
* Gets the ReflectionProperty for the single identifier field.
*
* @return ReflectionProperty
* @throws BadMethodCallException If the class has a composite identifier.
*/
public function getSingleIdReflectionProperty()
{
if ($this->isIdentifierComposite) {
throw new \BadMethodCallException("Class " . $this->name . " has a composite identifier.");
}
return $this->reflFields[$this->identifier[0]];
}
/**
* Validates & completes the given field mapping.
*
* @param array $mapping The field mapping to validated & complete.
* @return array The validated and completed field mapping.
*
* @throws MappingException
*/
protected function _validateAndCompleteFieldMapping(array &$mapping)
{
parent::_validateAndCompleteFieldMapping($mapping);
// Store ReflectionProperty of mapped field
$refProp = $this->reflClass->getProperty($mapping['fieldName']);
$refProp->setAccessible(true);
$this->reflFields[$mapping['fieldName']] = $refProp;
}
/**
* Extracts the identifier values of an entity of this class.
*
* For composite identifiers, the identifier values are returned as an array
* with the same order as the field order in {@link identifier}.
*
* @param object $entity
* @return array
*/
public function getIdentifierValues($entity)
{
if ($this->isIdentifierComposite) {
$id = array();
foreach ($this->identifier as $idField) {
$value = $this->reflFields[$idField]->getValue($entity);
if ($value !== null) {
$id[$idField] = $value;
}
}
return $id;
} else {
$value = $this->reflFields[$this->identifier[0]]->getValue($entity);
if ($value !== null) {
return array($this->identifier[0] => $value);
}
return array();
}
}
/**
* Populates the entity identifier of an entity.
*
* @param object $entity
* @param mixed $id
* @todo Rename to assignIdentifier()
*/
public function setIdentifierValues($entity, array $id)
{
foreach ($id as $idField => $idValue) {
$this->reflFields[$idField]->setValue($entity, $idValue);
}
}
/**
* Sets the specified field to the specified value on the given entity.
*
* @param object $entity
* @param string $field
* @param mixed $value
*/
public function setFieldValue($entity, $field, $value)
{
$this->reflFields[$field]->setValue($entity, $value);
}
/**
* Gets the specified field's value off the given entity.
*
* @param object $entity
* @param string $field
*/
public function getFieldValue($entity, $field)
{
return $this->reflFields[$field]->getValue($entity);
}
/**
* Stores the association mapping.
*
* @param AssociationMapping $assocMapping
*/
protected function _storeAssociationMapping(array $assocMapping)
{
parent::_storeAssociationMapping($assocMapping);
// Store ReflectionProperty of mapped field
$sourceFieldName = $assocMapping['fieldName'];
$refProp = $this->reflClass->getProperty($sourceFieldName);
$refProp->setAccessible(true);
$this->reflFields[$sourceFieldName] = $refProp;
}
/**
* Gets the (possibly quoted) column name of a mapped field for safe use
* in an SQL statement.
*
* @param string $field
* @param AbstractPlatform $platform
* @return string
*/
public function getQuotedColumnName($field, $platform)
{
return isset($this->fieldMappings[$field]['quoted']) ?
$platform->quoteIdentifier($this->fieldMappings[$field]['columnName']) :
$this->fieldMappings[$field]['columnName'];
}
/**
* Gets the (possibly quoted) primary table name of this class for safe use
* in an SQL statement.
*
* @param AbstractPlatform $platform
* @return string
*/
public function getQuotedTableName($platform)
{
return isset($this->table['quoted']) ?
$platform->quoteIdentifier($this->table['name']) :
$this->table['name'];
}
/**
* Gets the (possibly quoted) name of the join table.
*
* @param AbstractPlatform $platform
* @return string
*/
public function getQuotedJoinTableName(array $assoc, $platform)
{
return isset($assoc['joinTable']['quoted'])
? $platform->quoteIdentifier($assoc['joinTable']['name'])
: $assoc['joinTable']['name'];
}
/**
* Creates a string representation of this instance.
*
* @return string The string representation of this instance.
* @todo Construct meaningful string representation.
*/
public function __toString()
{
return __CLASS__ . '@' . spl_object_hash($this);
}
/**
* Determines which fields get serialized.
*
* It is only serialized what is necessary for best unserialization performance.
* That means any metadata properties that are not set or empty or simply have
* their default value are NOT serialized.
*
* Parts that are also NOT serialized because they can not be properly unserialized:
* - reflClass (ReflectionClass)
* - reflFields (ReflectionProperty array)
*
* @return array The names of all the fields that should be serialized.
*/
public function __sleep()
{
// This metadata is always serialized/cached.
$serialized = array(
'associationMappings',
'columnNames', //TODO: Not really needed. Can use fieldMappings[$fieldName]['columnName']
'fieldMappings',
'fieldNames',
'identifier',
'isIdentifierComposite', // TODO: REMOVE
'name',
'namespace', // TODO: REMOVE
'table',
'rootEntityName',
'idGenerator', //TODO: Does not really need to be serialized. Could be moved to runtime.
);
// The rest of the metadata is only serialized if necessary.
if ($this->changeTrackingPolicy != self::CHANGETRACKING_DEFERRED_IMPLICIT) {
$serialized[] = 'changeTrackingPolicy';
}
if ($this->customRepositoryClassName) {
$serialized[] = 'customRepositoryClassName';
}
if ($this->inheritanceType != self::INHERITANCE_TYPE_NONE) {
$serialized[] = 'inheritanceType';
$serialized[] = 'discriminatorColumn';
$serialized[] = 'discriminatorValue';
$serialized[] = 'discriminatorMap';
$serialized[] = 'parentClasses';
$serialized[] = 'subClasses';
}
if ($this->generatorType != self::GENERATOR_TYPE_NONE) {
$serialized[] = 'generatorType';
if ($this->generatorType == self::GENERATOR_TYPE_SEQUENCE) {
$serialized[] = 'sequenceGeneratorDefinition';
}
}
if ($this->isMappedSuperclass) {
$serialized[] = 'isMappedSuperclass';
}
if ($this->isVersioned) {
$serialized[] = 'isVersioned';
$serialized[] = 'versionField';
}
if ($this->lifecycleCallbacks) {
$serialized[] = 'lifecycleCallbacks';
}
return $serialized;
}
/**
* Restores some state that can not be serialized/unserialized.
*
* @return void
*/
public function __wakeup()
{
// Restore ReflectionClass and properties
$this->reflClass = new ReflectionClass($this->name);
foreach ($this->fieldMappings as $field => $mapping) {
if (isset($mapping['declared'])) {
$reflField = new ReflectionProperty($mapping['declared'], $field);
} else {
$reflField = $this->reflClass->getProperty($field);
}
$reflField->setAccessible(true);
$this->reflFields[$field] = $reflField;
}
foreach ($this->associationMappings as $field => $mapping) {
if (isset($mapping['declared'])) {
$reflField = new ReflectionProperty($mapping['declared'], $field);
} else {
$reflField = $this->reflClass->getProperty($field);
}
$reflField->setAccessible(true);
$this->reflFields[$field] = $reflField;
}
}
/**
* Creates a new instance of the mapped class, without invoking the constructor.
*
* @return object
*/
public function newInstance()
{
if ($this->_prototype === null) {
$this->_prototype = unserialize(sprintf('O:%d:"%s":0:{}', strlen($this->name), $this->name));
}
return clone $this->_prototype;
}
}

View File

@@ -13,7 +13,7 @@
* 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 LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
@@ -23,11 +23,16 @@ use ReflectionException,
Doctrine\ORM\ORMException,
Doctrine\ORM\EntityManager,
Doctrine\DBAL\Platforms,
Doctrine\ORM\Events;
Doctrine\ORM\Events,
Doctrine\Common\Persistence\Mapping\ReflectionService,
Doctrine\Common\Persistence\Mapping\ClassMetadata as ClassMetadataInterface,
Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory,
Doctrine\ORM\Id\IdentityGenerator,
Doctrine\ORM\Event\LoadClassMetadataEventArgs;
/**
* The ClassMetadataFactory is used to create ClassMetadata objects that contain all the
* metadata mapping informations of a class which describes how a class should be mapped
* metadata mapping information of a class which describes how a class should be mapped
* to a relational database.
*
* @since 2.0
@@ -36,20 +41,20 @@ use ReflectionException,
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class ClassMetadataFactory
class ClassMetadataFactory extends AbstractClassMetadataFactory
{
/**
* @var EntityManager
*/
private $em;
/**
* @var AbstractPlatform
* @var \Doctrine\DBAL\Platforms\AbstractPlatform
*/
private $targetPlatform;
/**
* @var Driver\Driver
* @var \Doctrine\Common\Persistence\Mapping\Driver\MappingDriver
*/
private $driver;
@@ -59,22 +64,7 @@ class ClassMetadataFactory
private $evm;
/**
* @var \Doctrine\Common\Cache\Cache
*/
private $cacheDriver;
/**
* @var array
*/
private $loadedMetadata = array();
/**
* @var bool
*/
private $initialized = false;
/**
* @param EntityManager $$em
* @param EntityManager $em
*/
public function setEntityManager(EntityManager $em)
{
@@ -82,55 +72,9 @@ class ClassMetadataFactory
}
/**
* Sets the cache driver used by the factory to cache ClassMetadata instances.
*
* @param Doctrine\Common\Cache\Cache $cacheDriver
* {@inheritDoc}.
*/
public function setCacheDriver($cacheDriver)
{
$this->cacheDriver = $cacheDriver;
}
/**
* Gets the cache driver used by the factory to cache ClassMetadata instances.
*
* @return Doctrine\Common\Cache\Cache
*/
public function getCacheDriver()
{
return $this->cacheDriver;
}
public function getLoadedMetadata()
{
return $this->loadedMetadata;
}
/**
* Forces the factory to load the metadata of all classes known to the underlying
* mapping driver.
*
* @return array The ClassMetadata instances of all mapped classes.
*/
public function getAllMetadata()
{
if ( ! $this->initialized) {
$this->initialize();
}
$metadata = array();
foreach ($this->driver->getAllClassNames() as $className) {
$metadata[] = $this->getMetadataFor($className);
}
return $metadata;
}
/**
* Lazy initialization of this stuff, especially the metadata driver,
* since these are not needed at all when a metadata cache is active.
*/
private function initialize()
protected function initialize()
{
$this->driver = $this->em->getConfiguration()->getMetadataDriverImpl();
$this->targetPlatform = $this->em->getConnection()->getDatabasePlatform();
@@ -139,227 +83,202 @@ class ClassMetadataFactory
}
/**
* Gets the class metadata descriptor for a class.
*
* @param string $className The name of the class.
* @return Doctrine\ORM\Mapping\ClassMetadata
* {@inheritDoc}
*/
public function getMetadataFor($className)
protected function doLoadMetadata($class, $parent, $rootEntityFound, array $nonSuperclassParents)
{
if ( ! isset($this->loadedMetadata[$className])) {
$realClassName = $className;
/* @var $class ClassMetadata */
/* @var $parent ClassMetadata */
if ($parent) {
$class->setInheritanceType($parent->inheritanceType);
$class->setDiscriminatorColumn($parent->discriminatorColumn);
$class->setIdGeneratorType($parent->generatorType);
$this->addInheritedFields($class, $parent);
$this->addInheritedRelations($class, $parent);
$class->setIdentifier($parent->identifier);
$class->setVersioned($parent->isVersioned);
$class->setVersionField($parent->versionField);
$class->setDiscriminatorMap($parent->discriminatorMap);
$class->setLifecycleCallbacks($parent->lifecycleCallbacks);
$class->setChangeTrackingPolicy($parent->changeTrackingPolicy);
// Check for namespace alias
if (strpos($className, ':') !== false) {
list($namespaceAlias, $simpleClassName) = explode(':', $className);
$realClassName = $this->em->getConfiguration()->getEntityNamespace($namespaceAlias) . '\\' . $simpleClassName;
if (isset($this->loadedMetadata[$realClassName])) {
// We do not have the alias name in the map, include it
$this->loadedMetadata[$className] = $this->loadedMetadata[$realClassName];
return $this->loadedMetadata[$realClassName];
}
}
if ($this->cacheDriver) {
if (($cached = $this->cacheDriver->fetch("$realClassName\$CLASSMETADATA")) !== false) {
$this->loadedMetadata[$realClassName] = $cached;
} else {
foreach ($this->loadMetadata($realClassName) as $loadedClassName) {
$this->cacheDriver->save(
"$loadedClassName\$CLASSMETADATA", $this->loadedMetadata[$loadedClassName], null
);
}
}
} else {
$this->loadMetadata($realClassName);
}
if ($className != $realClassName) {
// We do not have the alias name in the map, include it
$this->loadedMetadata[$className] = $this->loadedMetadata[$realClassName];
if ($parent->isMappedSuperclass) {
$class->setCustomRepositoryClass($parent->customRepositoryClassName);
}
}
return $this->loadedMetadata[$className];
}
/**
* Checks whether the factory has the metadata for a class loaded already.
*
* @param string $className
* @return boolean TRUE if the metadata of the class in question is already loaded, FALSE otherwise.
*/
public function hasMetadataFor($className)
{
return isset($this->loadedMetadata[$className]);
}
/**
* Sets the metadata descriptor for a specific class.
*
* NOTE: This is only useful in very special cases, like when generating proxy classes.
*
* @param string $className
* @param ClassMetadata $class
*/
public function setMetadataFor($className, $class)
{
$this->loadedMetadata[$className] = $class;
}
/**
* Get array of parent classes for the given entity class
*
* @param string $name
* @return array $parentClasses
*/
protected function getParentClasses($name)
{
// Collect parent classes, ignoring transient (not-mapped) classes.
$parentClasses = array();
foreach (array_reverse(class_parents($name)) as $parentClass) {
if ( ! $this->driver->isTransient($parentClass)) {
$parentClasses[] = $parentClass;
}
}
return $parentClasses;
}
/**
* Loads the metadata of the class in question and all it's ancestors whose metadata
* is still not loaded.
*
* @param string $name The name of the class for which the metadata should get loaded.
* @param array $tables The metadata collection to which the loaded metadata is added.
*/
protected function loadMetadata($name)
{
if ( ! $this->initialized) {
$this->initialize();
// Invoke driver
try {
$this->driver->loadMetadataForClass($class->getName(), $class);
} catch (ReflectionException $e) {
throw MappingException::reflectionFailure($class->getName(), $e);
}
$loaded = array();
$parentClasses = $this->getParentClasses($name);
$parentClasses[] = $name;
// Move down the hierarchy of parent classes, starting from the topmost class
$parent = null;
$visited = array();
foreach ($parentClasses as $className) {
if (isset($this->loadedMetadata[$className])) {
$parent = $this->loadedMetadata[$className];
if ( ! $parent->isMappedSuperclass) {
array_unshift($visited, $className);
}
continue;
// If this class has a parent the id generator strategy is inherited.
// However this is only true if the hierarchy of parents contains the root entity,
// if it consists of mapped superclasses these don't necessarily include the id field.
if ($parent && $rootEntityFound) {
if ($parent->isIdGeneratorSequence()) {
$class->setSequenceGeneratorDefinition($parent->sequenceGeneratorDefinition);
} else if ($parent->isIdGeneratorTable()) {
$class->tableGeneratorDefinition = $parent->tableGeneratorDefinition;
}
$class = $this->newClassMetadataInstance($className);
if ($parent) {
if (!$parent->isMappedSuperclass) {
$class->setInheritanceType($parent->inheritanceType);
$class->setDiscriminatorColumn($parent->discriminatorColumn);
}
if ($parent->generatorType) {
$class->setIdGeneratorType($parent->generatorType);
$this->addInheritedFields($class, $parent);
$this->addInheritedRelations($class, $parent);
$class->setIdentifier($parent->identifier);
$class->setVersioned($parent->isVersioned);
$class->setVersionField($parent->versionField);
if (!$parent->isMappedSuperclass) {
$class->setDiscriminatorMap($parent->discriminatorMap);
}
$class->setLifecycleCallbacks($parent->lifecycleCallbacks);
$class->setChangeTrackingPolicy($parent->changeTrackingPolicy);
}
// Invoke driver
try {
$this->driver->loadMetadataForClass($className, $class);
} catch (ReflectionException $e) {
throw MappingException::reflectionFailure($className, $e);
if ($parent->idGenerator) {
$class->setIdGenerator($parent->idGenerator);
}
} else {
$this->completeIdGeneratorMapping($class);
}
if ($parent && ! $parent->isMappedSuperclass) {
if ($parent->isIdGeneratorSequence()) {
$class->setSequenceGeneratorDefinition($parent->sequenceGeneratorDefinition);
} else if ($parent->isIdGeneratorTable()) {
$class->getTableGeneratorDefinition($parent->tableGeneratorDefinition);
}
if ($parent->generatorType) {
$class->setIdGeneratorType($parent->generatorType);
}
if ($parent->idGenerator) {
$class->setIdGenerator($parent->idGenerator);
}
} else {
$this->completeIdGeneratorMapping($class);
}
if ($parent && $parent->isInheritanceTypeSingleTable()) {
$class->setPrimaryTable($parent->table);
}
if ($parent && $parent->isInheritanceTypeSingleTable()) {
$class->setPrimaryTable($parent->table);
}
if ($parent && $parent->containsForeignIdentifier) {
$class->containsForeignIdentifier = true;
}
$class->setParentClasses($visited);
if ($parent && !empty($parent->namedQueries)) {
$this->addInheritedNamedQueries($class, $parent);
}
if ($this->evm->hasListeners(Events::loadClassMetadata)) {
$eventArgs = new \Doctrine\ORM\Event\LoadClassMetadataEventArgs($class, $this->em);
$this->evm->dispatchEvent(Events::loadClassMetadata, $eventArgs);
}
if ($parent && !empty($parent->namedNativeQueries)) {
$this->addInheritedNamedNativeQueries($class, $parent);
}
// Verify & complete identifier mapping
if ( ! $class->identifier && ! $class->isMappedSuperclass) {
throw MappingException::identifierRequired($className);
}
if ($parent && !empty($parent->sqlResultSetMappings)) {
$this->addInheritedSqlResultSetMappings($class, $parent);
}
// verify inheritance
if (!$parent && !$class->isMappedSuperclass && !$class->isInheritanceTypeNone()) {
$class->setParentClasses($nonSuperclassParents);
if ( $class->isRootEntity() && ! $class->isInheritanceTypeNone() && ! $class->discriminatorMap) {
$this->addDefaultDiscriminatorMap($class);
}
if ($this->evm->hasListeners(Events::loadClassMetadata)) {
$eventArgs = new LoadClassMetadataEventArgs($class, $this->em);
$this->evm->dispatchEvent(Events::loadClassMetadata, $eventArgs);
}
$this->wakeupReflection($class, $this->getReflectionService());
$this->validateRuntimeMetadata($class, $parent);
}
/**
* Validate runtime metadata is correctly defined.
*
* @param ClassMetadata $class
* @param $parent
* @throws MappingException
*/
protected function validateRuntimeMetadata($class, $parent)
{
if ( ! $class->reflClass ) {
// only validate if there is a reflection class instance
return;
}
$class->validateIdentifier();
$class->validateAssocations();
$class->validateLifecycleCallbacks($this->getReflectionService());
// verify inheritance
if ( ! $class->isMappedSuperclass && !$class->isInheritanceTypeNone()) {
if ( ! $parent) {
if (count($class->discriminatorMap) == 0) {
throw MappingException::missingDiscriminatorMap($class->name);
}
if (!$class->discriminatorColumn) {
if ( ! $class->discriminatorColumn) {
throw MappingException::missingDiscriminatorColumn($class->name);
}
} else if ($parent && !$class->reflClass->isAbstract() && !in_array($class->name, array_values($class->discriminatorMap))) {
// enforce discriminator map for all entities of an inheritance hierarchy, otherwise problems will occur.
throw MappingException::mappedClassNotPartOfDiscriminatorMap($class->name, $class->rootEntityName);
}
$this->loadedMetadata[$className] = $class;
$parent = $class;
if ( ! $class->isMappedSuperclass) {
array_unshift($visited, $className);
}
$loaded[] = $className;
} else if ($class->isMappedSuperclass && $class->name == $class->rootEntityName && (count($class->discriminatorMap) || $class->discriminatorColumn)) {
// second condition is necessary for mapped superclasses in the middle of an inheritance hierarchy
throw MappingException::noInheritanceOnMappedSuperClass($class->name);
}
return $loaded;
}
/**
* Creates a new ClassMetadata instance for the given class name.
*
* @param string $className
* @return Doctrine\ORM\Mapping\ClassMetadata
* {@inheritDoc}
*/
protected function newClassMetadataInstance($className)
{
return new ClassMetadata($className);
return new ClassMetadata($className, $this->em->getConfiguration()->getNamingStrategy());
}
/**
* Adds a default discriminator map if no one is given
*
* If an entity is of any inheritance type and does not contain a
* discriminator map, then the map is generated automatically. This process
* is expensive computation wise.
*
* The automatically generated discriminator map contains the lowercase short name of
* each class as key.
*
* @param \Doctrine\ORM\Mapping\ClassMetadata $class
* @throws MappingException
*/
private function addDefaultDiscriminatorMap(ClassMetadata $class)
{
$allClasses = $this->driver->getAllClassNames();
$fqcn = $class->getName();
$map = array($this->getShortName($class->name) => $fqcn);
$duplicates = array();
foreach ($allClasses as $subClassCandidate) {
if (is_subclass_of($subClassCandidate, $fqcn)) {
$shortName = $this->getShortName($subClassCandidate);
if (isset($map[$shortName])) {
$duplicates[] = $shortName;
}
$map[$shortName] = $subClassCandidate;
}
}
if ($duplicates) {
throw MappingException::duplicateDiscriminatorEntry($class->name, $duplicates, $map);
}
$class->setDiscriminatorMap($map);
}
/**
* Get the lower-case short name of a class.
*
* @param string $className
* @return string
*/
private function getShortName($className)
{
if (strpos($className, "\\") === false) {
return strtolower($className);
}
$parts = explode("\\", $className);
return strtolower(end($parts));
}
/**
* Adds inherited fields to the subclass mapping.
*
* @param Doctrine\ORM\Mapping\ClassMetadata $subClass
* @param Doctrine\ORM\Mapping\ClassMetadata $parentClass
* @param \Doctrine\ORM\Mapping\ClassMetadata $subClass
* @param \Doctrine\ORM\Mapping\ClassMetadata $parentClass
*/
private function addInheritedFields(ClassMetadata $subClass, ClassMetadata $parentClass)
{
foreach ($parentClass->fieldMappings as $fieldName => $mapping) {
foreach ($parentClass->fieldMappings as $mapping) {
if ( ! isset($mapping['inherited']) && ! $parentClass->isMappedSuperclass) {
$mapping['inherited'] = $parentClass->name;
}
@@ -376,8 +295,9 @@ class ClassMetadataFactory
/**
* Adds inherited association mappings to the subclass mapping.
*
* @param Doctrine\ORM\Mapping\ClassMetadata $subClass
* @param Doctrine\ORM\Mapping\ClassMetadata $parentClass
* @param \Doctrine\ORM\Mapping\ClassMetadata $subClass
* @param \Doctrine\ORM\Mapping\ClassMetadata $parentClass
* @throws MappingException
*/
private function addInheritedRelations(ClassMetadata $subClass, ClassMetadata $parentClass)
{
@@ -400,11 +320,83 @@ class ClassMetadataFactory
}
}
/**
* Adds inherited named queries to the subclass mapping.
*
* @since 2.2
* @param \Doctrine\ORM\Mapping\ClassMetadata $subClass
* @param \Doctrine\ORM\Mapping\ClassMetadata $parentClass
*/
private function addInheritedNamedQueries(ClassMetadata $subClass, ClassMetadata $parentClass)
{
foreach ($parentClass->namedQueries as $name => $query) {
if ( ! isset ($subClass->namedQueries[$name])) {
$subClass->addNamedQuery(array(
'name' => $query['name'],
'query' => $query['query']
));
}
}
}
/**
* Adds inherited named native queries to the subclass mapping.
*
* @since 2.3
* @param \Doctrine\ORM\Mapping\ClassMetadata $subClass
* @param \Doctrine\ORM\Mapping\ClassMetadata $parentClass
*/
private function addInheritedNamedNativeQueries(ClassMetadata $subClass, ClassMetadata $parentClass)
{
foreach ($parentClass->namedNativeQueries as $name => $query) {
if ( ! isset ($subClass->namedNativeQueries[$name])) {
$subClass->addNamedNativeQuery(array(
'name' => $query['name'],
'query' => $query['query'],
'isSelfClass' => $query['isSelfClass'],
'resultSetMapping' => $query['resultSetMapping'],
'resultClass' => $query['isSelfClass'] ? $subClass->name : $query['resultClass'],
));
}
}
}
/**
* Adds inherited sql result set mappings to the subclass mapping.
*
* @since 2.3
* @param \Doctrine\ORM\Mapping\ClassMetadata $subClass
* @param \Doctrine\ORM\Mapping\ClassMetadata $parentClass
*/
private function addInheritedSqlResultSetMappings(ClassMetadata $subClass, ClassMetadata $parentClass)
{
foreach ($parentClass->sqlResultSetMappings as $name => $mapping) {
if ( ! isset ($subClass->sqlResultSetMappings[$name])) {
$entities = array();
foreach ($mapping['entities'] as $entity) {
$entities[] = array(
'fields' => $entity['fields'],
'isSelfClass' => $entity['isSelfClass'],
'discriminatorColumn' => $entity['discriminatorColumn'],
'entityClass' => $entity['isSelfClass'] ? $subClass->name : $entity['entityClass'],
);
}
$subClass->addSqlResultSetMapping(array(
'name' => $mapping['name'],
'columns' => $mapping['columns'],
'entities' => $entities,
));
}
}
}
/**
* Completes the ID generator mapping. If "auto" is specified we choose the generator
* most appropriate for the targeted database platform.
*
* @param Doctrine\ORM\Mapping\ClassMetadata $class
* @param ClassMetadataInfo $class
* @throws ORMException
*/
private function completeIdGeneratorMapping(ClassMetadataInfo $class)
{
@@ -425,35 +417,121 @@ class ClassMetadataFactory
// For PostgreSQL IDENTITY (SERIAL) we need a sequence name. It defaults to
// <table>_<column>_seq in PostgreSQL for SERIAL columns.
// Not pretty but necessary and the simplest solution that currently works.
$seqName = $this->targetPlatform instanceof Platforms\PostgreSQLPlatform ?
$class->table['name'] . '_' . $class->columnNames[$class->identifier[0]] . '_seq' :
null;
$class->setIdGenerator(new \Doctrine\ORM\Id\IdentityGenerator($seqName));
$sequenceName = null;
if ($this->targetPlatform instanceof Platforms\PostgreSQLPlatform) {
$fieldName = $class->getSingleIdentifierFieldName();
$columnName = $class->getSingleIdentifierColumnName();
$quoted = isset($class->fieldMappings[$fieldName]['quoted']) || isset($class->table['quoted']);
$sequenceName = $class->getTableName() . '_' . $columnName . '_seq';
$definition = array(
'sequenceName' => $this->targetPlatform->fixSchemaElementName($sequenceName)
);
if ($quoted) {
$definition['quoted'] = true;
}
$sequenceName = $this->em->getConfiguration()->getQuoteStrategy()->getSequenceName($definition, $class, $this->targetPlatform);
}
$class->setIdGenerator(new \Doctrine\ORM\Id\IdentityGenerator($sequenceName));
break;
case ClassMetadata::GENERATOR_TYPE_SEQUENCE:
// If there is no sequence definition yet, create a default definition
$definition = $class->sequenceGeneratorDefinition;
if ( ! $definition) {
$sequenceName = $class->getTableName() . '_' . $class->getSingleIdentifierColumnName() . '_seq';
$definition['sequenceName'] = $this->targetPlatform->fixSchemaElementName($sequenceName);
$definition['allocationSize'] = 1;
$definition['initialValue'] = 1;
$fieldName = $class->getSingleIdentifierFieldName();
$columnName = $class->getSingleIdentifierColumnName();
$quoted = isset($class->fieldMappings[$fieldName]['quoted']) || isset($class->table['quoted']);
$sequenceName = $class->getTableName() . '_' . $columnName . '_seq';
$definition = array(
'sequenceName' => $this->targetPlatform->fixSchemaElementName($sequenceName),
'allocationSize' => 1,
'initialValue' => 1,
);
if ($quoted) {
$definition['quoted'] = true;
}
$class->setSequenceGeneratorDefinition($definition);
}
$sequenceGenerator = new \Doctrine\ORM\Id\SequenceGenerator(
$definition['sequenceName'],
$this->em->getConfiguration()->getQuoteStrategy()->getSequenceName($definition, $class, $this->targetPlatform),
$definition['allocationSize']
);
$class->setIdGenerator($sequenceGenerator);
break;
case ClassMetadata::GENERATOR_TYPE_NONE:
$class->setIdGenerator(new \Doctrine\ORM\Id\AssignedGenerator());
break;
case ClassMetadata::GENERATOR_TYPE_UUID:
$class->setIdGenerator(new \Doctrine\ORM\Id\UuidGenerator());
break;
case ClassMetadata::GENERATOR_TYPE_TABLE:
throw new ORMException("TableGenerator not yet implemented.");
break;
case ClassMetadata::GENERATOR_TYPE_CUSTOM:
$definition = $class->customGeneratorDefinition;
if ( ! class_exists($definition['class'])) {
throw new ORMException("Can't instantiate custom generator : " .
$definition['class']);
}
$class->setIdGenerator(new $definition['class']);
break;
default:
throw new ORMException("Unknown generator type: " . $class->generatorType);
}
}
/**
* {@inheritDoc}
*/
protected function wakeupReflection(ClassMetadataInterface $class, ReflectionService $reflService)
{
/* @var $class ClassMetadata */
$class->wakeupReflection($reflService);
}
/**
* {@inheritDoc}
*/
protected function initializeReflection(ClassMetadataInterface $class, ReflectionService $reflService)
{
/* @var $class ClassMetadata */
$class->initializeReflection($reflService);
}
/**
* {@inheritDoc}
*/
protected function getFqcnFromAlias($namespaceAlias, $simpleClassName)
{
return $this->em->getConfiguration()->getEntityNamespace($namespaceAlias) . '\\' . $simpleClassName;
}
/**
* {@inheritDoc}
*/
protected function getDriver()
{
return $this->driver;
}
/**
* {@inheritDoc}
*/
protected function isEntity(ClassMetadataInterface $class)
{
return isset($class->isMappedSuperclass) && $class->isMappedSuperclass === false;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,46 @@
<?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\ORM\Mapping;
/**
* @Annotation
* @Target({"PROPERTY","ANNOTATION"})
*/
final class Column implements Annotation
{
/** @var string */
public $name;
/** @var mixed */
public $type = 'string';
/** @var integer */
public $length;
/** @var integer */
public $precision = 0; // The precision for a decimal (exact numeric) column (Applies only for decimal column)
/** @var integer */
public $scale = 0; // The scale for a decimal (exact numeric) column (Applies only for decimal column)
/** @var boolean */
public $unique = false;
/** @var boolean */
public $nullable = false;
/** @var array */
public $options = array();
/** @var string */
public $columnDefinition;
}

View File

@@ -0,0 +1,42 @@
<?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\ORM\Mapping;
/**
* References name of a column in the SELECT clause of a SQL query.
* Scalar result types can be included in the query result by specifying this annotation in the metadata.
*
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
* @since 2.3
*
* @Annotation
* @Target("ANNOTATION")
*/
final class ColumnResult implements Annotation
{
/**
* The name of a column in the SELECT clause of a SQL query
*
* @var string
*/
public $name;
}

View File

@@ -0,0 +1,30 @@
<?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\ORM\Mapping;
/**
* @Annotation
* @Target("PROPERTY")
*/
final class CustomIdGenerator implements Annotation
{
/** @var string */
public $class;
}

View File

@@ -0,0 +1,86 @@
<?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\ORM\Mapping;
/**
* The default NamingStrategy
*
*
* @link www.doctrine-project.org
* @since 2.3
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
*/
class DefaultNamingStrategy implements NamingStrategy
{
/**
* {@inheritdoc}
*/
public function classToTableName($className)
{
if (strpos($className, '\\') !== false) {
return substr($className, strrpos($className, '\\') + 1);
}
return $className;
}
/**
* {@inheritdoc}
*/
public function propertyToColumnName($propertyName)
{
return $propertyName;
}
/**
* {@inheritdoc}
*/
public function referenceColumnName()
{
return 'id';
}
/**
* {@inheritdoc}
*/
public function joinColumnName($propertyName)
{
return $propertyName . '_' . $this->referenceColumnName();
}
/**
* {@inheritdoc}
*/
public function joinTableName($sourceEntity, $targetEntity, $propertyName = null)
{
return strtolower($this->classToTableName($sourceEntity) . '_' .
$this->classToTableName($targetEntity));
}
/**
* {@inheritdoc}
*/
public function joinKeyColumnName($entityName, $referencedColumnName = null)
{
return strtolower($this->classToTableName($entityName) . '_' .
($referencedColumnName ?: $this->referenceColumnName()));
}
}

View File

@@ -0,0 +1,140 @@
<?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\ORM\Mapping;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\DBAL\Platforms\AbstractPlatform;
/**
* A set of rules for determining the physical column, alias and table quotes
*
* @since 2.3
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
*/
class DefaultQuoteStrategy implements QuoteStrategy
{
/**
* {@inheritdoc}
*/
public function getColumnName($fieldName, ClassMetadata $class, AbstractPlatform $platform)
{
return isset($class->fieldMappings[$fieldName]['quoted'])
? $platform->quoteIdentifier($class->fieldMappings[$fieldName]['columnName'])
: $class->fieldMappings[$fieldName]['columnName'];
}
/**
* {@inheritdoc}
*/
public function getTableName(ClassMetadata $class, AbstractPlatform $platform)
{
return isset($class->table['quoted'])
? $platform->quoteIdentifier($class->table['name'])
: $class->table['name'];
}
/**
* {@inheritdoc}
*/
public function getSequenceName(array $definition, ClassMetadata $class, AbstractPlatform $platform)
{
return isset($definition['quoted'])
? $platform->quoteIdentifier($definition['sequenceName'])
: $definition['sequenceName'];
}
/**
* {@inheritdoc}
*/
public function getJoinColumnName(array $joinColumn, ClassMetadata $class, AbstractPlatform $platform)
{
return isset($joinColumn['quoted'])
? $platform->quoteIdentifier($joinColumn['name'])
: $joinColumn['name'];
}
/**
* {@inheritdoc}
*/
public function getReferencedJoinColumnName(array $joinColumn, ClassMetadata $class, AbstractPlatform $platform)
{
return isset($joinColumn['quoted'])
? $platform->quoteIdentifier($joinColumn['referencedColumnName'])
: $joinColumn['referencedColumnName'];
}
/**
* {@inheritdoc}
*/
public function getJoinTableName(array $association, ClassMetadata $class, AbstractPlatform $platform)
{
return isset($association['joinTable']['quoted'])
? $platform->quoteIdentifier($association['joinTable']['name'])
: $association['joinTable']['name'];
}
/**
* {@inheritdoc}
*/
public function getIdentifierColumnNames(ClassMetadata $class, AbstractPlatform $platform)
{
$quotedColumnNames = array();
foreach ($class->identifier as $fieldName) {
if (isset($class->fieldMappings[$fieldName])) {
$quotedColumnNames[] = $this->getColumnName($fieldName, $class, $platform);
continue;
}
// Association defined as Id field
$joinColumns = $class->associationMappings[$fieldName]['joinColumns'];
$assocQuotedColumnNames = array_map(
function ($joinColumn) use ($platform)
{
return isset($joinColumn['quoted'])
? $platform->quoteIdentifier($joinColumn['name'])
: $joinColumn['name'];
},
$joinColumns
);
$quotedColumnNames = array_merge($quotedColumnNames, $assocQuotedColumnNames);
}
return $quotedColumnNames;
}
/**
* {@inheritdoc}
*/
public function getColumnAlias($columnName, $counter, AbstractPlatform $platform, ClassMetadata $class = null)
{
// Trim the column alias to the maximum identifier length of the platform.
// If the alias is to long, characters are cut off from the beginning.
// And strip non alphanumeric characters
$columnName = $columnName . $counter;
$columnName = substr($columnName, -$platform->getMaxIdentifierLength());
$columnName = preg_replace('/[^A-Za-z0-9_]/', '', $columnName);
return $platform->getSQLResultCasing($columnName);
}
}

View File

@@ -0,0 +1,38 @@
<?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\ORM\Mapping;
/**
* @Annotation
* @Target("CLASS")
*/
final class DiscriminatorColumn implements Annotation
{
/** @var string */
public $name;
/** @var string */
public $type;
/** @var integer */
public $length;
/** @var mixed */
public $fieldName; // field name used in non-object hydration (array/scalar)
/** @var string */
public $columnDefinition;
}

View File

@@ -0,0 +1,30 @@
<?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\ORM\Mapping;
/**
* @Annotation
* @Target("CLASS")
*/
final class DiscriminatorMap implements Annotation
{
/** @var array<string> */
public $value;
}

View File

@@ -1,210 +0,0 @@
<?php
/*
* $Id$
*
* 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 LGPL. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping\Driver;
use Doctrine\ORM\Mapping\MappingException;
/**
* Base driver for file-based metadata drivers.
*
* A file driver operates in a mode where it loads the mapping files of individual
* classes on demand. This requires the user to adhere to the convention of 1 mapping
* file per class and the file names of the mapping files must correspond to the full
* class name, including namespace, with the namespace delimiters '\', replaced by dots '.'.
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.com
* @since 2.0
* @version $Revision$
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan H. Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
abstract class AbstractFileDriver implements Driver
{
/**
* The paths where to look for mapping files.
*
* @var array
*/
protected $_paths = array();
/**
* The file extension of mapping documents.
*
* @var string
*/
protected $_fileExtension;
/**
* Initializes a new FileDriver that looks in the given path(s) for mapping
* documents and operates in the specified operating mode.
*
* @param string|array $paths One or multiple paths where mapping documents can be found.
*/
public function __construct($paths)
{
$this->addPaths((array) $paths);
}
/**
* Append lookup paths to metadata driver.
*
* @param array $paths
*/
public function addPaths(array $paths)
{
$this->_paths = array_unique(array_merge($this->_paths, $paths));
}
/**
* Retrieve the defined metadata lookup paths.
*
* @return array
*/
public function getPaths()
{
return $this->_paths;
}
/**
* Get the file extension used to look for mapping files under
*
* @return void
*/
public function getFileExtension()
{
return $this->_fileExtension;
}
/**
* Set the file extension used to look for mapping files under
*
* @param string $fileExtension The file extension to set
* @return void
*/
public function setFileExtension($fileExtension)
{
$this->_fileExtension = $fileExtension;
}
/**
* Get the element of schema meta data for the class from the mapping file.
* This will lazily load the mapping file if it is not loaded yet
*
* @return array $element The element of schema meta data
*/
public function getElement($className)
{
$result = $this->_loadMappingFile($this->_findMappingFile($className));
return $result[$className];
}
/**
* Whether the class with the specified name should have its metadata loaded.
* This is only the case if it is either mapped as an Entity or a
* MappedSuperclass.
*
* @param string $className
* @return boolean
*/
public function isTransient($className)
{
$fileName = str_replace('\\', '.', $className) . $this->_fileExtension;
// Check whether file exists
foreach ((array) $this->_paths as $path) {
if (file_exists($path . DIRECTORY_SEPARATOR . $fileName)) {
return false;
}
}
return true;
}
/**
* Gets the names of all mapped classes known to this driver.
*
* @return array The names of all mapped classes known to this driver.
*/
public function getAllClassNames()
{
$classes = array();
if ($this->_paths) {
foreach ((array) $this->_paths as $path) {
if ( ! is_dir($path)) {
throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path);
}
$iterator = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($path),
\RecursiveIteratorIterator::LEAVES_ONLY
);
foreach ($iterator as $file) {
if (($fileName = $file->getBasename($this->_fileExtension)) == $file->getBasename()) {
continue;
}
// NOTE: All files found here means classes are not transient!
$classes[] = str_replace('.', '\\', $fileName);
}
}
}
return $classes;
}
/**
* Finds the mapping file for the class with the given name by searching
* through the configured paths.
*
* @param $className
* @return string The (absolute) file name.
* @throws MappingException
*/
protected function _findMappingFile($className)
{
$fileName = str_replace('\\', '.', $className) . $this->_fileExtension;
// Check whether file exists
foreach ((array) $this->_paths as $path) {
if (file_exists($path . DIRECTORY_SEPARATOR . $fileName)) {
return $path . DIRECTORY_SEPARATOR . $fileName;
}
}
throw MappingException::mappingFileNotFound($className, $fileName);
}
/**
* Loads a mapping file with the given name and returns a map
* from class/entity names to their corresponding elements.
*
* @param string $file The mapping file to load.
* @return array
*/
abstract protected function _loadMappingFile($file);
}

View File

@@ -13,18 +13,18 @@
* 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 LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping\Driver;
use Doctrine\Common\Cache\ArrayCache,
Doctrine\Common\Annotations\AnnotationReader,
Doctrine\ORM\Mapping\ClassMetadataInfo,
Doctrine\ORM\Mapping\MappingException;
require __DIR__ . '/DoctrineAnnotations.php';
use Doctrine\Common\Annotations\AnnotationReader,
Doctrine\ORM\Mapping\MappingException,
Doctrine\ORM\Mapping\JoinColumn,
Doctrine\ORM\Mapping\Column,
Doctrine\Common\Persistence\Mapping\ClassMetadata,
Doctrine\Common\Persistence\Mapping\Driver\AnnotationDriver as AbstractAnnotationDriver;
/**
* The AnnotationDriver reads the mapping metadata from docblock annotations.
@@ -35,104 +35,53 @@ require __DIR__ . '/DoctrineAnnotations.php';
* @author Jonathan H. Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class AnnotationDriver implements Driver
class AnnotationDriver extends AbstractAnnotationDriver
{
/**
* The AnnotationReader.
*
* @var AnnotationReader
* {@inheritDoc}
*/
private $_reader;
protected $entityAnnotationClasses = array(
'Doctrine\ORM\Mapping\Entity' => 1,
'Doctrine\ORM\Mapping\MappedSuperclass' => 2,
);
/**
* The paths where to look for mapping files.
*
* @var array
* {@inheritDoc}
*/
protected $_paths = array();
/**
* The file extension of mapping documents.
*
* @var string
*/
protected $_fileExtension = '.php';
/**
* @param array
*/
protected $_classNames;
/**
* Initializes a new AnnotationDriver that uses the given AnnotationReader for reading
* docblock annotations.
*
* @param $reader The AnnotationReader to use.
* @param string|array $paths One or multiple paths where mapping classes can be found.
*/
public function __construct(AnnotationReader $reader, $paths = null)
{
$this->_reader = $reader;
if ($paths) {
$this->addPaths((array) $paths);
}
}
/**
* Append lookup paths to metadata driver.
*
* @param array $paths
*/
public function addPaths(array $paths)
{
$this->_paths = array_unique(array_merge($this->_paths, $paths));
}
/**
* Retrieve the defined metadata lookup paths.
*
* @return array
*/
public function getPaths()
{
return $this->_paths;
}
/**
* Get the file extension used to look for mapping files under
*
* @return void
*/
public function getFileExtension()
{
return $this->_fileExtension;
}
/**
* Set the file extension used to look for mapping files under
*
* @param string $fileExtension The file extension to set
* @return void
*/
public function setFileExtension($fileExtension)
{
$this->_fileExtension = $fileExtension;
}
/**
* {@inheritdoc}
*/
public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
public function loadMetadataForClass($className, ClassMetadata $metadata)
{
/* @var $metadata \Doctrine\ORM\Mapping\ClassMetadataInfo */
$class = $metadata->getReflectionClass();
if ( ! $class) {
// this happens when running annotation driver in combination with
// static reflection services. This is not the nicest fix
$class = new \ReflectionClass($metadata->name);
}
$classAnnotations = $this->_reader->getClassAnnotations($class);
$classAnnotations = $this->reader->getClassAnnotations($class);
if ($classAnnotations) {
foreach ($classAnnotations as $key => $annot) {
if ( ! is_numeric($key)) {
continue;
}
$classAnnotations[get_class($annot)] = $annot;
}
}
// Evaluate Entity annotation
if (isset($classAnnotations['Doctrine\ORM\Mapping\Entity'])) {
$entityAnnot = $classAnnotations['Doctrine\ORM\Mapping\Entity'];
$metadata->setCustomRepositoryClass($entityAnnot->repositoryClass);
if ($entityAnnot->repositoryClass !== null) {
$metadata->setCustomRepositoryClass($entityAnnot->repositoryClass);
}
if ($entityAnnot->readOnly) {
$metadata->markReadOnly();
}
} else if (isset($classAnnotations['Doctrine\ORM\Mapping\MappedSuperclass'])) {
$mappedSuperclassAnnot = $classAnnotations['Doctrine\ORM\Mapping\MappedSuperclass'];
$metadata->setCustomRepositoryClass($mappedSuperclassAnnot->repositoryClass);
$metadata->isMappedSuperclass = true;
} else {
throw MappingException::classIsNotAValidEntityOrMappedSuperClass($className);
@@ -148,23 +97,106 @@ class AnnotationDriver implements Driver
if ($tableAnnot->indexes !== null) {
foreach ($tableAnnot->indexes as $indexAnnot) {
$primaryTable['indexes'][$indexAnnot->name] = array(
'columns' => $indexAnnot->columns
);
$index = array('columns' => $indexAnnot->columns);
if ( ! empty($indexAnnot->name)) {
$primaryTable['indexes'][$indexAnnot->name] = $index;
} else {
$primaryTable['indexes'][] = $index;
}
}
}
if ($tableAnnot->uniqueConstraints !== null) {
foreach ($tableAnnot->uniqueConstraints as $uniqueConstraint) {
$primaryTable['uniqueConstraints'][$uniqueConstraint->name] = array(
'columns' => $uniqueConstraint->columns
);
foreach ($tableAnnot->uniqueConstraints as $uniqueConstraintAnnot) {
$uniqueConstraint = array('columns' => $uniqueConstraintAnnot->columns);
if ( ! empty($uniqueConstraintAnnot->name)) {
$primaryTable['uniqueConstraints'][$uniqueConstraintAnnot->name] = $uniqueConstraint;
} else {
$primaryTable['uniqueConstraints'][] = $uniqueConstraint;
}
}
}
if ($tableAnnot->options !== null) {
$primaryTable['options'] = $tableAnnot->options;
}
$metadata->setPrimaryTable($primaryTable);
}
// Evaluate NamedNativeQueries annotation
if (isset($classAnnotations['Doctrine\ORM\Mapping\NamedNativeQueries'])) {
$namedNativeQueriesAnnot = $classAnnotations['Doctrine\ORM\Mapping\NamedNativeQueries'];
foreach ($namedNativeQueriesAnnot->value as $namedNativeQuery) {
$metadata->addNamedNativeQuery(array(
'name' => $namedNativeQuery->name,
'query' => $namedNativeQuery->query,
'resultClass' => $namedNativeQuery->resultClass,
'resultSetMapping' => $namedNativeQuery->resultSetMapping,
));
}
}
// Evaluate SqlResultSetMappings annotation
if (isset($classAnnotations['Doctrine\ORM\Mapping\SqlResultSetMappings'])) {
$sqlResultSetMappingsAnnot = $classAnnotations['Doctrine\ORM\Mapping\SqlResultSetMappings'];
foreach ($sqlResultSetMappingsAnnot->value as $resultSetMapping) {
$entities = array();
$columns = array();
foreach ($resultSetMapping->entities as $entityResultAnnot) {
$entityResult = array(
'fields' => array(),
'entityClass' => $entityResultAnnot->entityClass,
'discriminatorColumn' => $entityResultAnnot->discriminatorColumn,
);
foreach ($entityResultAnnot->fields as $fieldResultAnnot) {
$entityResult['fields'][] = array(
'name' => $fieldResultAnnot->name,
'column' => $fieldResultAnnot->column
);
}
$entities[] = $entityResult;
}
foreach ($resultSetMapping->columns as $columnResultAnnot) {
$columns[] = array(
'name' => $columnResultAnnot->name,
);
}
$metadata->addSqlResultSetMapping(array(
'name' => $resultSetMapping->name,
'entities' => $entities,
'columns' => $columns
));
}
}
// Evaluate NamedQueries annotation
if (isset($classAnnotations['Doctrine\ORM\Mapping\NamedQueries'])) {
$namedQueriesAnnot = $classAnnotations['Doctrine\ORM\Mapping\NamedQueries'];
if ( ! is_array($namedQueriesAnnot->value)) {
throw new \UnexpectedValueException("@NamedQueries should contain an array of @NamedQuery annotations.");
}
foreach ($namedQueriesAnnot->value as $namedQuery) {
if ( ! ($namedQuery instanceof \Doctrine\ORM\Mapping\NamedQuery)) {
throw new \UnexpectedValueException("@NamedQueries should contain an array of @NamedQuery annotations.");
}
$metadata->addNamedQuery(array(
'name' => $namedQuery->name,
'query' => $namedQuery->query
));
}
}
// Evaluate InheritanceType annotation
if (isset($classAnnotations['Doctrine\ORM\Mapping\InheritanceType'])) {
$inheritanceTypeAnnot = $classAnnotations['Doctrine\ORM\Mapping\InheritanceType'];
@@ -177,7 +209,8 @@ class AnnotationDriver implements Driver
$metadata->setDiscriminatorColumn(array(
'name' => $discrColumnAnnot->name,
'type' => $discrColumnAnnot->type,
'length' => $discrColumnAnnot->length
'length' => $discrColumnAnnot->length,
'columnDefinition' => $discrColumnAnnot->columnDefinition
));
} else {
$metadata->setDiscriminatorColumn(array('name' => 'dtype', 'type' => 'string', 'length' => 255));
@@ -199,6 +232,7 @@ class AnnotationDriver implements Driver
}
// Evaluate annotations on properties/fields
/* @var $property \ReflectionProperty */
foreach ($class->getProperties() as $property) {
if ($metadata->isMappedSuperclass && ! $property->isPrivate()
||
@@ -214,138 +248,103 @@ class AnnotationDriver implements Driver
// Check for JoinColummn/JoinColumns annotations
$joinColumns = array();
if ($joinColumnAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\JoinColumn')) {
$joinColumns[] = array(
'name' => $joinColumnAnnot->name,
'referencedColumnName' => $joinColumnAnnot->referencedColumnName,
'unique' => $joinColumnAnnot->unique,
'nullable' => $joinColumnAnnot->nullable,
'onDelete' => $joinColumnAnnot->onDelete,
'onUpdate' => $joinColumnAnnot->onUpdate,
'columnDefinition' => $joinColumnAnnot->columnDefinition,
);
} else if ($joinColumnsAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\JoinColumns')) {
if ($joinColumnAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\JoinColumn')) {
$joinColumns[] = $this->joinColumnToArray($joinColumnAnnot);
} else if ($joinColumnsAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\JoinColumns')) {
foreach ($joinColumnsAnnot->value as $joinColumn) {
$joinColumns[] = array(
'name' => $joinColumn->name,
'referencedColumnName' => $joinColumn->referencedColumnName,
'unique' => $joinColumn->unique,
'nullable' => $joinColumn->nullable,
'onDelete' => $joinColumn->onDelete,
'onUpdate' => $joinColumn->onUpdate,
'columnDefinition' => $joinColumn->columnDefinition,
);
$joinColumns[] = $this->joinColumnToArray($joinColumn);
}
}
// Field can only be annotated with one of:
// @Column, @OneToOne, @OneToMany, @ManyToOne, @ManyToMany
if ($columnAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Column')) {
if ($columnAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Column')) {
if ($columnAnnot->type == null) {
throw MappingException::propertyTypeIsRequired($className, $property->getName());
}
$mapping['type'] = $columnAnnot->type;
$mapping['length'] = $columnAnnot->length;
$mapping['precision'] = $columnAnnot->precision;
$mapping['scale'] = $columnAnnot->scale;
$mapping['nullable'] = $columnAnnot->nullable;
$mapping['unique'] = $columnAnnot->unique;
if ($columnAnnot->options) {
$mapping['options'] = $columnAnnot->options;
}
$mapping = $this->columnToArray($property->getName(), $columnAnnot);
if (isset($columnAnnot->name)) {
$mapping['columnName'] = $columnAnnot->name;
}
if (isset($columnAnnot->columnDefinition)) {
$mapping['columnDefinition'] = $columnAnnot->columnDefinition;
}
if ($idAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Id')) {
if ($idAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Id')) {
$mapping['id'] = true;
}
if ($generatedValueAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\GeneratedValue')) {
if ($generatedValueAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\GeneratedValue')) {
$metadata->setIdGeneratorType(constant('Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_' . $generatedValueAnnot->strategy));
}
if ($versionAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Version')) {
if ($this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Version')) {
$metadata->setVersionMapping($mapping);
}
$metadata->mapField($mapping);
// Check for SequenceGenerator/TableGenerator definition
if ($seqGeneratorAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\SequenceGenerator')) {
if ($seqGeneratorAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\SequenceGenerator')) {
$metadata->setSequenceGeneratorDefinition(array(
'sequenceName' => $seqGeneratorAnnot->sequenceName,
'allocationSize' => $seqGeneratorAnnot->allocationSize,
'initialValue' => $seqGeneratorAnnot->initialValue
));
} else if ($tblGeneratorAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\TableGenerator')) {
} else if ($this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\TableGenerator')) {
throw MappingException::tableIdGeneratorNotImplemented($className);
} else if ($customGeneratorAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\CustomIdGenerator')) {
$metadata->setCustomGeneratorDefinition(array(
'class' => $customGeneratorAnnot->class
));
}
} else if ($oneToOneAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\OneToOne')) {
} else if ($oneToOneAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\OneToOne')) {
if ($idAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Id')) {
$mapping['id'] = true;
}
$mapping['targetEntity'] = $oneToOneAnnot->targetEntity;
$mapping['joinColumns'] = $joinColumns;
$mapping['mappedBy'] = $oneToOneAnnot->mappedBy;
$mapping['inversedBy'] = $oneToOneAnnot->inversedBy;
$mapping['cascade'] = $oneToOneAnnot->cascade;
$mapping['orphanRemoval'] = $oneToOneAnnot->orphanRemoval;
$mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $oneToOneAnnot->fetch);
$mapping['fetch'] = $this->getFetchMode($className, $oneToOneAnnot->fetch);
$metadata->mapOneToOne($mapping);
} else if ($oneToManyAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\OneToMany')) {
} else if ($oneToManyAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\OneToMany')) {
$mapping['mappedBy'] = $oneToManyAnnot->mappedBy;
$mapping['targetEntity'] = $oneToManyAnnot->targetEntity;
$mapping['cascade'] = $oneToManyAnnot->cascade;
$mapping['indexBy'] = $oneToManyAnnot->indexBy;
$mapping['orphanRemoval'] = $oneToManyAnnot->orphanRemoval;
$mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $oneToManyAnnot->fetch);
$mapping['fetch'] = $this->getFetchMode($className, $oneToManyAnnot->fetch);
if ($orderByAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\OrderBy')) {
if ($orderByAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\OrderBy')) {
$mapping['orderBy'] = $orderByAnnot->value;
}
$metadata->mapOneToMany($mapping);
} else if ($manyToOneAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\ManyToOne')) {
} else if ($manyToOneAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\ManyToOne')) {
if ($idAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Id')) {
$mapping['id'] = true;
}
$mapping['joinColumns'] = $joinColumns;
$mapping['cascade'] = $manyToOneAnnot->cascade;
$mapping['inversedBy'] = $manyToOneAnnot->inversedBy;
$mapping['targetEntity'] = $manyToOneAnnot->targetEntity;
$mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $manyToOneAnnot->fetch);
$mapping['fetch'] = $this->getFetchMode($className, $manyToOneAnnot->fetch);
$metadata->mapManyToOne($mapping);
} else if ($manyToManyAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\ManyToMany')) {
} else if ($manyToManyAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\ManyToMany')) {
$joinTable = array();
if ($joinTableAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\JoinTable')) {
if ($joinTableAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\JoinTable')) {
$joinTable = array(
'name' => $joinTableAnnot->name,
'schema' => $joinTableAnnot->schema
);
foreach ($joinTableAnnot->joinColumns as $joinColumn) {
$joinTable['joinColumns'][] = array(
'name' => $joinColumn->name,
'referencedColumnName' => $joinColumn->referencedColumnName,
'unique' => $joinColumn->unique,
'nullable' => $joinColumn->nullable,
'onDelete' => $joinColumn->onDelete,
'onUpdate' => $joinColumn->onUpdate,
'columnDefinition' => $joinColumn->columnDefinition,
);
$joinTable['joinColumns'][] = $this->joinColumnToArray($joinColumn);
}
foreach ($joinTableAnnot->inverseJoinColumns as $joinColumn) {
$joinTable['inverseJoinColumns'][] = array(
'name' => $joinColumn->name,
'referencedColumnName' => $joinColumn->referencedColumnName,
'unique' => $joinColumn->unique,
'nullable' => $joinColumn->nullable,
'onDelete' => $joinColumn->onDelete,
'onUpdate' => $joinColumn->onUpdate,
'columnDefinition' => $joinColumn->columnDefinition,
);
$joinTable['inverseJoinColumns'][] = $this->joinColumnToArray($joinColumn);
}
}
@@ -354,9 +353,11 @@ class AnnotationDriver implements Driver
$mapping['mappedBy'] = $manyToManyAnnot->mappedBy;
$mapping['inversedBy'] = $manyToManyAnnot->inversedBy;
$mapping['cascade'] = $manyToManyAnnot->cascade;
$mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $manyToManyAnnot->fetch);
$mapping['indexBy'] = $manyToManyAnnot->indexBy;
$mapping['orphanRemoval'] = $manyToManyAnnot->orphanRemoval;
$mapping['fetch'] = $this->getFetchMode($className, $manyToManyAnnot->fetch);
if ($orderByAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\OrderBy')) {
if ($orderByAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\OrderBy')) {
$mapping['orderBy'] = $orderByAnnot->value;
}
@@ -364,12 +365,72 @@ class AnnotationDriver implements Driver
}
}
// Evaluate AssociationOverrides annotation
if (isset($classAnnotations['Doctrine\ORM\Mapping\AssociationOverrides'])) {
$associationOverridesAnnot = $classAnnotations['Doctrine\ORM\Mapping\AssociationOverrides'];
foreach ($associationOverridesAnnot->value as $associationOverride) {
$override = array();
$fieldName = $associationOverride->name;
// Check for JoinColummn/JoinColumns annotations
if ($associationOverride->joinColumns) {
$joinColumns = array();
foreach ($associationOverride->joinColumns as $joinColumn) {
$joinColumns[] = $this->joinColumnToArray($joinColumn);
}
$override['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);
}
$override['joinTable'] = $joinTable;
}
$metadata->setAssociationOverride($fieldName, $override);
}
}
// Evaluate AttributeOverrides annotation
if (isset($classAnnotations['Doctrine\ORM\Mapping\AttributeOverrides'])) {
$attributeOverridesAnnot = $classAnnotations['Doctrine\ORM\Mapping\AttributeOverrides'];
foreach ($attributeOverridesAnnot->value as $attributeOverrideAnnot) {
$attributeOverride = $this->columnToArray($attributeOverrideAnnot->name, $attributeOverrideAnnot->column);
$metadata->setAttributeOverride($attributeOverrideAnnot->name, $attributeOverride);
}
}
// Evaluate @HasLifecycleCallbacks annotation
if (isset($classAnnotations['Doctrine\ORM\Mapping\HasLifecycleCallbacks'])) {
/* @var $method \ReflectionMethod */
foreach ($class->getMethods() as $method) {
// filter for the declaring class only, callbacks from parents will already be registered.
if ($method->isPublic() && $method->getDeclaringClass()->getName() == $class->name) {
$annotations = $this->_reader->getMethodAnnotations($method);
$annotations = $this->reader->getMethodAnnotations($method);
if ($annotations) {
foreach ($annotations as $key => $annot) {
if ( ! is_numeric($key)) {
continue;
}
$annotations[get_class($annot)] = $annot;
}
}
if (isset($annotations['Doctrine\ORM\Mapping\PrePersist'])) {
$metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::prePersist);
@@ -398,83 +459,87 @@ class AnnotationDriver implements Driver
if (isset($annotations['Doctrine\ORM\Mapping\PostLoad'])) {
$metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postLoad);
}
if (isset($annotations['Doctrine\ORM\Mapping\PreFlush'])) {
$metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::preFlush);
}
}
}
}
}
/**
* Whether the class with the specified name is transient. Only non-transient
* classes, that is entities and mapped superclasses, should have their metadata loaded.
* A class is non-transient if it is annotated with either @Entity or
* @MappedSuperclass in the class doc block.
* Attempts to resolve the fetch mode.
*
* @param string $className
* @return boolean
* @param string $className The class name
* @param string $fetchMode The fetch mode
* @return integer The fetch mode as defined in ClassMetadata
* @throws MappingException If the fetch mode is not valid
*/
public function isTransient($className)
private function getFetchMode($className, $fetchMode)
{
$classAnnotations = $this->_reader->getClassAnnotations(new \ReflectionClass($className));
if( ! defined('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $fetchMode)) {
throw MappingException::invalidFetchMode($className, $fetchMode);
}
return ! isset($classAnnotations['Doctrine\ORM\Mapping\Entity']) &&
! isset($classAnnotations['Doctrine\ORM\Mapping\MappedSuperclass']);
return constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $fetchMode);
}
/**
* {@inheritDoc}
* Parse the given JoinColumn as array
*
* @param JoinColumn $joinColumn
* @return array
*/
public function getAllClassNames()
private function joinColumnToArray(JoinColumn $joinColumn)
{
if ($this->_classNames !== null) {
return $this->_classNames;
return array(
'name' => $joinColumn->name,
'unique' => $joinColumn->unique,
'nullable' => $joinColumn->nullable,
'onDelete' => $joinColumn->onDelete,
'columnDefinition' => $joinColumn->columnDefinition,
'referencedColumnName' => $joinColumn->referencedColumnName,
);
}
/**
* Parse the given Column as array
*
* @param string $fieldName
* @param Column $column
* @return array
*/
private function columnToArray($fieldName, Column $column)
{
$mapping = array(
'fieldName' => $fieldName,
'type' => $column->type,
'scale' => $column->scale,
'length' => $column->length,
'unique' => $column->unique,
'nullable' => $column->nullable,
'precision' => $column->precision
);
if ($column->options) {
$mapping['options'] = $column->options;
}
if (!$this->_paths) {
throw MappingException::pathRequired();
if (isset($column->name)) {
$mapping['columnName'] = $column->name;
}
$classes = array();
$includedFiles = array();
foreach ($this->_paths as $path) {
if ( ! is_dir($path)) {
throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path);
}
$iterator = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($path),
\RecursiveIteratorIterator::LEAVES_ONLY
);
foreach ($iterator as $file) {
if (($fileName = $file->getBasename($this->_fileExtension)) == $file->getBasename()) {
continue;
}
$sourceFile = realpath($file->getPathName());
require_once $sourceFile;
$includedFiles[] = $sourceFile;
}
if (isset($column->columnDefinition)) {
$mapping['columnDefinition'] = $column->columnDefinition;
}
$declared = get_declared_classes();
foreach ($declared as $className) {
$rc = new \ReflectionClass($className);
$sourceFile = $rc->getFileName();
if (in_array($sourceFile, $includedFiles) && ! $this->isTransient($className)) {
$classes[] = $className;
}
}
$this->_classNames = $classes;
return $classes;
return $mapping;
}
/**
* Factory method for the Annotation Driver
*
*
* @param array|string $paths
* @param AnnotationReader $reader
* @return AnnotationDriver
@@ -483,8 +548,8 @@ class AnnotationDriver implements Driver
{
if ($reader == null) {
$reader = new AnnotationReader();
$reader->setDefaultAnnotationNamespace('Doctrine\ORM\Mapping\\');
}
return new self($reader, $paths);
}
}

View File

@@ -13,31 +13,31 @@
* 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 LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping\Driver;
use Doctrine\Common\Cache\ArrayCache,
Doctrine\Common\Annotations\AnnotationReader,
Doctrine\DBAL\Schema\AbstractSchemaManager,
use Doctrine\DBAL\Schema\AbstractSchemaManager,
Doctrine\DBAL\Schema\SchemaException,
Doctrine\Common\Persistence\Mapping\Driver\MappingDriver,
Doctrine\Common\Persistence\Mapping\ClassMetadata,
Doctrine\ORM\Mapping\ClassMetadataInfo,
Doctrine\ORM\Mapping\MappingException,
Doctrine\Common\Util\Inflector;
Doctrine\Common\Util\Inflector,
Doctrine\ORM\Mapping\MappingException;
/**
* The DatabaseDriver reverse engineers the mapping metadata from a database.
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
*
* @link www.doctrine-project.org
* @since 2.0
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Benjamin Eberlei <kontakt@beberlei.de>
*/
class DatabaseDriver implements Driver
class DatabaseDriver implements MappingDriver
{
/**
* @var AbstractSchemaManager
@@ -55,31 +55,68 @@ class DatabaseDriver implements Driver
* @var array
*/
private $manyToManyTables = array();
/**
* Initializes a new AnnotationDriver that uses the given AnnotationReader for reading
* docblock annotations.
*
* @param AnnotationReader $reader The AnnotationReader to use.
* @var array
*/
private $classNamesForTables = array();
/**
* @var array
*/
private $fieldNamesForColumns = array();
/**
* The namespace for the generated entities.
*
* @var string
*/
private $namespace;
/**
*
* @param AbstractSchemaManager $schemaManager
*/
public function __construct(AbstractSchemaManager $schemaManager)
{
$this->_sm = $schemaManager;
}
/**
* Set tables manually instead of relying on the reverse engeneering capabilities of SchemaManager.
*
* @param array $entityTables
* @param array $manyToManyTables
* @return void
*/
public function setTables($entityTables, $manyToManyTables)
{
$this->tables = $this->manyToManyTables = $this->classToTableNames = array();
foreach ($entityTables as $table) {
$className = $this->getClassNameForTable($table->getName());
$this->classToTableNames[$className] = $table->getName();
$this->tables[$table->getName()] = $table;
}
foreach ($manyToManyTables as $table) {
$this->manyToManyTables[$table->getName()] = $table;
}
}
private function reverseEngineerMappingFromDatabase()
{
if ($this->tables !== null) {
return;
}
$tables = array();
foreach ($this->_sm->listTableNames() as $tableName) {
$tables[$tableName] = $this->_sm->listTableDetails($tableName);
}
$this->tables = array();
foreach ($tables AS $tableName => $table) {
/* @var $table Table */
$this->tables = $this->manyToManyTables = $this->classToTableNames = array();
foreach ($tables as $tableName => $table) {
/* @var $table \Doctrine\DBAL\Schema\Table */
if ($this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) {
$foreignKeys = $table->getForeignKeys();
} else {
@@ -87,34 +124,37 @@ class DatabaseDriver implements Driver
}
$allForeignKeyColumns = array();
foreach ($foreignKeys AS $foreignKey) {
foreach ($foreignKeys as $foreignKey) {
$allForeignKeyColumns = array_merge($allForeignKeyColumns, $foreignKey->getLocalColumns());
}
if ( ! $table->hasPrimaryKey()) {
throw new MappingException(
"Table " . $table->getName() . " has no primary key. Doctrine does not ".
"support reverse engineering from tables that don't have a primary key."
);
}
$pkColumns = $table->getPrimaryKey()->getColumns();
sort($pkColumns);
sort($allForeignKeyColumns);
if ($pkColumns == $allForeignKeyColumns) {
if (count($table->getForeignKeys()) > 2) {
throw new \InvalidArgumentException("ManyToMany table '" . $tableName . "' with more or less than two foreign keys are not supported by the Database Reverese Engineering Driver.");
}
if ($pkColumns == $allForeignKeyColumns && count($foreignKeys) == 2) {
$this->manyToManyTables[$tableName] = $table;
} else {
// lower-casing is necessary because of Oracle Uppercase Tablenames,
// assumption is lower-case + underscore separated.
$className = Inflector::classify(strtolower($tableName));
$className = $this->getClassNameForTable($tableName);
$this->tables[$tableName] = $table;
$this->classToTableNames[$className] = $tableName;
}
}
}
/**
* {@inheritdoc}
* {@inheritDoc}
*/
public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
public function loadMetadataForClass($className, ClassMetadata $metadata)
{
$this->reverseEngineerMappingFromDatabase();
@@ -134,7 +174,7 @@ class DatabaseDriver implements Driver
} catch(SchemaException $e) {
$primaryKeyColumns = array();
}
if ($this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) {
$foreignKeys = $this->tables[$tableName]->getForeignKeys();
} else {
@@ -142,7 +182,7 @@ class DatabaseDriver implements Driver
}
$allForeignKeyColumns = array();
foreach ($foreignKeys AS $foreignKey) {
foreach ($foreignKeys as $foreignKey) {
$allForeignKeyColumns = array_merge($allForeignKeyColumns, $foreignKey->getLocalColumns());
}
@@ -150,13 +190,14 @@ class DatabaseDriver implements Driver
$fieldMappings = array();
foreach ($columns as $column) {
$fieldMapping = array();
if ($primaryKeyColumns && in_array($column->getName(), $primaryKeyColumns)) {
$fieldMapping['id'] = true;
} else if (in_array($column->getName(), $allForeignKeyColumns)) {
if (in_array($column->getName(), $allForeignKeyColumns)) {
continue;
} else if ($primaryKeyColumns && in_array($column->getName(), $primaryKeyColumns)) {
$fieldMapping['id'] = true;
}
$fieldMapping['fieldName'] = Inflector::camelize(strtolower($column->getName()));
$fieldMapping['fieldName'] = $this->getFieldNameForColumn($tableName, $column->getName(), false);
$fieldMapping['columnName'] = $column->getName();
$fieldMapping['type'] = strtolower((string) $column->getType());
@@ -189,23 +230,31 @@ class DatabaseDriver implements Driver
$metadata->mapField($fieldMapping);
}
foreach ($this->manyToManyTables AS $manyTable) {
foreach ($manyTable->getForeignKeys() AS $foreignKey) {
foreach ($this->manyToManyTables as $manyTable) {
foreach ($manyTable->getForeignKeys() as $foreignKey) {
// foreign key maps to the table of the current entity, many to many association probably exists
if (strtolower($tableName) == strtolower($foreignKey->getForeignTableName())) {
$myFk = $foreignKey;
foreach ($manyTable->getForeignKeys() AS $foreignKey) {
$otherFk = null;
foreach ($manyTable->getForeignKeys() as $foreignKey) {
if ($foreignKey != $myFk) {
$otherFk = $foreignKey;
break;
}
}
if (!$otherFk) {
// the definition of this many to many table does not contain
// enough foreign key information to continue reverse engeneering.
continue;
}
$localColumn = current($myFk->getColumns());
$associationMapping = array();
$associationMapping['fieldName'] = Inflector::camelize(str_replace('_id', '', strtolower(current($otherFk->getColumns()))));
$associationMapping['targetEntity'] = Inflector::classify(strtolower($otherFk->getForeignTableName()));
$associationMapping['fieldName'] = $this->getFieldNameForColumn($manyTable->getName(), current($otherFk->getColumns()), true);
$associationMapping['targetEntity'] = $this->getClassNameForTable($otherFk->getForeignTableName());
if (current($manyTable->getColumns())->getName() == $localColumn) {
$associationMapping['inversedBy'] = Inflector::camelize(str_replace('_id', '', strtolower(current($myFk->getColumns()))));
$associationMapping['inversedBy'] = $this->getFieldNameForColumn($manyTable->getName(), current($myFk->getColumns()), true);
$associationMapping['joinTable'] = array(
'name' => strtolower($manyTable->getName()),
'joinColumns' => array(),
@@ -230,7 +279,7 @@ class DatabaseDriver implements Driver
);
}
} else {
$associationMapping['mappedBy'] = Inflector::camelize(str_replace('_id', '', strtolower(current($myFk->getColumns()))));
$associationMapping['mappedBy'] = $this->getFieldNameForColumn($manyTable->getName(), current($myFk->getColumns()), true);
}
$metadata->mapManyToMany($associationMapping);
break;
@@ -245,8 +294,16 @@ class DatabaseDriver implements Driver
$localColumn = current($cols);
$associationMapping = array();
$associationMapping['fieldName'] = Inflector::camelize(str_replace('_id', '', strtolower($localColumn)));
$associationMapping['targetEntity'] = Inflector::classify($foreignTable);
$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;
}
for ($i = 0; $i < count($cols); $i++) {
$associationMapping['joinColumns'][] = array(
@@ -254,12 +311,18 @@ class DatabaseDriver implements Driver
'referencedColumnName' => $fkCols[$i],
);
}
$metadata->mapManyToOne($associationMapping);
//Here we need to check if $cols are the same as $primaryKeyColums
if (!array_diff($cols,$primaryKeyColumns)) {
$metadata->mapOneToOne($associationMapping);
} else {
$metadata->mapManyToOne($associationMapping);
}
}
}
/**
* {@inheritdoc}
* {@inheritDoc}
*/
public function isTransient($className)
{
@@ -267,11 +330,7 @@ class DatabaseDriver implements Driver
}
/**
* Return all the class names supported by this driver.
*
* IMPORTANT: This method must return an array of class not tables names.
*
* @return array
* {@inheritDoc}
*/
public function getAllClassNames()
{
@@ -279,4 +338,78 @@ class DatabaseDriver implements Driver
return array_keys($this->classToTableNames);
}
}
/**
* Set class name for a table.
*
* @param string $tableName
* @param string $className
* @return void
*/
public function setClassNameForTable($tableName, $className)
{
$this->classNamesForTables[$tableName] = $className;
}
/**
* Set field name for a column on a specific table.
*
* @param string $tableName
* @param string $columnName
* @param string $fieldName
* @return void
*/
public function setFieldNameForColumn($tableName, $columnName, $fieldName)
{
$this->fieldNamesForColumns[$tableName][$columnName] = $fieldName;
}
/**
* Return the mapped class name for a table if it exists. Otherwise return "classified" version.
*
* @param string $tableName
* @return string
*/
private function getClassNameForTable($tableName)
{
if (isset($this->classNamesForTables[$tableName])) {
return $this->namespace . $this->classNamesForTables[$tableName];
}
return $this->namespace . Inflector::classify(strtolower($tableName));
}
/**
* Return the mapped field name for a column, if it exists. Otherwise return camelized version.
*
* @param string $tableName
* @param string $columnName
* @param boolean $fk Whether the column is a foreignkey or not.
* @return string
*/
private function getFieldNameForColumn($tableName, $columnName, $fk = false)
{
if (isset($this->fieldNamesForColumns[$tableName]) && isset($this->fieldNamesForColumns[$tableName][$columnName])) {
return $this->fieldNamesForColumns[$tableName][$columnName];
}
$columnName = strtolower($columnName);
// Replace _id if it is a foreignkey column
if ($fk) {
$columnName = str_replace('_id', '', $columnName);
}
return Inflector::camelize($columnName);
}
/**
* Set the namespace for the generated entities.
*
* @param string $namespace
* @return void
*/
public function setNamespace($namespace)
{
$this->namespace = $namespace;
}
}

View File

@@ -1,7 +1,5 @@
<?php
/*
* $Id$
*
* 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
@@ -15,123 +13,54 @@
* 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 LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping;
use Doctrine\Common\Annotations\Annotation;
/* Annotations */
final class Entity extends Annotation {
public $repositoryClass;
}
final class MappedSuperclass extends Annotation {}
final class InheritanceType extends Annotation {}
final class DiscriminatorColumn extends Annotation {
public $name;
public $fieldName; // field name used in non-object hydration (array/scalar)
public $type;
public $length;
}
final class DiscriminatorMap extends Annotation {}
final class Id extends Annotation {}
final class GeneratedValue extends Annotation {
public $strategy = 'AUTO';
}
final class Version extends Annotation {}
final class JoinColumn extends Annotation {
public $name;
public $fieldName; // field name used in non-object hydration (array/scalar)
public $referencedColumnName = 'id';
public $unique = false;
public $nullable = true;
public $onDelete;
public $onUpdate;
public $columnDefinition;
}
final class JoinColumns extends Annotation {}
final class Column extends Annotation {
public $type = 'string';
public $length;
// The precision for a decimal (exact numeric) column (Applies only for decimal column)
public $precision = 0;
// The scale for a decimal (exact numeric) column (Applies only for decimal column)
public $scale = 0;
public $unique = false;
public $nullable = false;
public $name;
public $options = array();
public $columnDefinition;
}
final class OneToOne extends Annotation {
public $targetEntity;
public $mappedBy;
public $inversedBy;
public $cascade;
public $fetch = 'LAZY';
public $orphanRemoval = false;
}
final class OneToMany extends Annotation {
public $mappedBy;
public $targetEntity;
public $cascade;
public $fetch = 'LAZY';
public $orphanRemoval = false;
}
final class ManyToOne extends Annotation {
public $targetEntity;
public $cascade;
public $fetch = 'LAZY';
public $inversedBy;
}
final class ManyToMany extends Annotation {
public $targetEntity;
public $mappedBy;
public $inversedBy;
public $cascade;
public $fetch = 'LAZY';
}
final class ElementCollection extends Annotation {
public $tableName;
}
final class Table extends Annotation {
public $name;
public $schema;
public $indexes;
public $uniqueConstraints;
}
final class UniqueConstraint extends Annotation {
public $name;
public $columns;
}
final class Index extends Annotation {
public $name;
public $columns;
}
final class JoinTable extends Annotation {
public $name;
public $schema;
public $joinColumns = array();
public $inverseJoinColumns = array();
}
final class SequenceGenerator extends Annotation {
public $sequenceName;
public $allocationSize = 1;
public $initialValue = 1;
}
final class ChangeTrackingPolicy extends Annotation {}
final class OrderBy extends Annotation {}
/* Annotations for lifecycle callbacks */
final class HasLifecycleCallbacks extends Annotation {}
final class PrePersist extends Annotation {}
final class PostPersist extends Annotation {}
final class PreUpdate extends Annotation {}
final class PostUpdate extends Annotation {}
final class PreRemove extends Annotation {}
final class PostRemove extends Annotation {}
final class PostLoad extends Annotation {}
require_once __DIR__.'/../Annotation.php';
require_once __DIR__.'/../Entity.php';
require_once __DIR__.'/../MappedSuperclass.php';
require_once __DIR__.'/../InheritanceType.php';
require_once __DIR__.'/../DiscriminatorColumn.php';
require_once __DIR__.'/../DiscriminatorMap.php';
require_once __DIR__.'/../Id.php';
require_once __DIR__.'/../GeneratedValue.php';
require_once __DIR__.'/../Version.php';
require_once __DIR__.'/../JoinColumn.php';
require_once __DIR__.'/../JoinColumns.php';
require_once __DIR__.'/../Column.php';
require_once __DIR__.'/../OneToOne.php';
require_once __DIR__.'/../OneToMany.php';
require_once __DIR__.'/../ManyToOne.php';
require_once __DIR__.'/../ManyToMany.php';
require_once __DIR__.'/../ElementCollection.php';
require_once __DIR__.'/../Table.php';
require_once __DIR__.'/../UniqueConstraint.php';
require_once __DIR__.'/../Index.php';
require_once __DIR__.'/../JoinTable.php';
require_once __DIR__.'/../SequenceGenerator.php';
require_once __DIR__.'/../CustomIdGenerator.php';
require_once __DIR__.'/../ChangeTrackingPolicy.php';
require_once __DIR__.'/../OrderBy.php';
require_once __DIR__.'/../NamedQueries.php';
require_once __DIR__.'/../NamedQuery.php';
require_once __DIR__.'/../HasLifecycleCallbacks.php';
require_once __DIR__.'/../PrePersist.php';
require_once __DIR__.'/../PostPersist.php';
require_once __DIR__.'/../PreUpdate.php';
require_once __DIR__.'/../PostUpdate.php';
require_once __DIR__.'/../PreRemove.php';
require_once __DIR__.'/../PostRemove.php';
require_once __DIR__.'/../PostLoad.php';
require_once __DIR__.'/../PreFlush.php';
require_once __DIR__.'/../FieldResult.php';
require_once __DIR__.'/../ColumnResult.php';
require_once __DIR__.'/../EntityResult.php';
require_once __DIR__.'/../NamedNativeQuery.php';
require_once __DIR__.'/../NamedNativeQueries.php';
require_once __DIR__.'/../SqlResultSetMapping.php';
require_once __DIR__.'/../SqlResultSetMappings.php';
require_once __DIR__.'/../AssociationOverride.php';
require_once __DIR__.'/../AssociationOverrides.php';
require_once __DIR__.'/../AttributeOverride.php';
require_once __DIR__.'/../AttributeOverrides.php';

View File

@@ -13,109 +13,19 @@
* 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 LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping\Driver;
use Doctrine\ORM\Mapping\Driver\Driver,
Doctrine\ORM\Mapping\ClassMetadataInfo,
Doctrine\ORM\Mapping\MappingException;
use Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain;
/**
* The DriverChain allows you to add multiple other mapping drivers for
* certain namespaces
* {@inheritDoc}
*
* @since 2.0
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan H. Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
* @todo Rename: MappingDriverChain or MetadataDriverChain
* @deprecated this driver will be removed. Use Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain instead
*/
class DriverChain implements Driver
class DriverChain extends MappingDriverChain
{
/**
* @var array
*/
private $_drivers = array();
/**
* Add a nested driver.
*
* @param Driver $nestedDriver
* @param string $namespace
*/
public function addDriver(Driver $nestedDriver, $namespace)
{
$this->_drivers[$namespace] = $nestedDriver;
}
/**
* Get the array of nested drivers.
*
* @return array $drivers
*/
public function getDrivers()
{
return $this->_drivers;
}
/**
* Loads the metadata for the specified class into the provided container.
*
* @param string $className
* @param ClassMetadataInfo $metadata
*/
public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
{
foreach ($this->_drivers as $namespace => $driver) {
if (strpos($className, $namespace) === 0) {
$driver->loadMetadataForClass($className, $metadata);
return;
}
}
throw MappingException::classIsNotAValidEntityOrMappedSuperClass($className);
}
/**
* Gets the names of all mapped classes known to this driver.
*
* @return array The names of all mapped classes known to this driver.
*/
public function getAllClassNames()
{
$classNames = array();
foreach ($this->_drivers AS $namespace => $driver) {
$driverClasses = $driver->getAllClassNames();
foreach ($driverClasses AS $className) {
if (strpos($className, $namespace) === 0) {
$classNames[] = $className;
}
}
}
return array_unique($classNames);
}
/**
* Whether the class with the specified name should have its metadata loaded.
*
* This is only the case for non-transient classes either mapped as an Entity or MappedSuperclass.
*
* @param string $className
* @return boolean
*/
public function isTransient($className)
{
foreach ($this->_drivers AS $namespace => $driver) {
if (strpos($className, $namespace) === 0) {
return $driver->isTransient($className);
}
}
// class isTransient, i.e. not an entity or mapped superclass
return true;
}
}

View File

@@ -13,57 +13,19 @@
* 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 LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping\Driver;
use Doctrine\Common\Cache\ArrayCache,
Doctrine\Common\Annotations\AnnotationReader,
Doctrine\DBAL\Schema\AbstractSchemaManager,
Doctrine\ORM\Mapping\ClassMetadataInfo,
Doctrine\ORM\Mapping\MappingException,
Doctrine\Common\Util\Inflector,
Doctrine\ORM\Mapping\Driver\AbstractFileDriver;
use Doctrine\Common\Persistence\Mapping\Driver\PHPDriver as CommonPHPDriver;
/**
* The PHPDriver includes php files which just populate ClassMetadataInfo
* instances with plain php code
* {@inheritDoc}
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 2.0
* @version $Revision$
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan H. Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
* @todo Rename: PHPDriver
* @deprecated this driver will be removed. Use Doctrine\Common\Persistence\Mapping\Driver\PHPDriver instead
*/
class PHPDriver extends AbstractFileDriver
class PHPDriver extends CommonPHPDriver
{
/**
* {@inheritdoc}
*/
protected $_fileExtension = '.php';
protected $_metadata;
/**
* {@inheritdoc}
*/
public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
{
$this->_metadata = $metadata;
$this->_loadMappingFile($this->_findMappingFile($className));
}
/**
* {@inheritdoc}
*/
protected function _loadMappingFile($file)
{
$metadata = $this->_metadata;
include $file;
}
}

View File

@@ -0,0 +1,43 @@
<?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\ORM\Mapping\Driver;
use Doctrine\Common\Persistence\Mapping\Driver\SymfonyFileLocator;
/**
* XmlDriver that additionally looks for mapping information in a global file.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @license MIT
*/
class SimplifiedXmlDriver extends XmlDriver
{
const DEFAULT_FILE_EXTENSION = '.orm.xml';
/**
* {@inheritDoc}
*/
public function __construct($prefixes, $fileExtension = self::DEFAULT_FILE_EXTENSION)
{
$locator = new SymfonyFileLocator((array) $prefixes, $fileExtension);
parent::__construct($locator, $fileExtension);
}
}

View File

@@ -0,0 +1,43 @@
<?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\ORM\Mapping\Driver;
use Doctrine\Common\Persistence\Mapping\Driver\SymfonyFileLocator;
/**
* YamlDriver that additionally looks for mapping information in a global file.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @license MIT
*/
class SimplifiedYamlDriver extends YamlDriver
{
const DEFAULT_FILE_EXTENSION = '.orm.yml';
/**
* {@inheritDoc}
*/
public function __construct($prefixes, $fileExtension = self::DEFAULT_FILE_EXTENSION)
{
$locator = new SymfonyFileLocator((array) $prefixes, $fileExtension);
parent::__construct($locator, $fileExtension);
}
}

View File

@@ -13,126 +13,19 @@
* 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 LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping\Driver;
use Doctrine\ORM\Mapping\ClassMetadataInfo,
Doctrine\ORM\Mapping\MappingException;
use Doctrine\Common\Persistence\Mapping\Driver\StaticPHPDriver as CommonStaticPHPDriver;
/**
* The StaticPHPDriver calls a static loadMetadata() method on your entity
* classes where you can manually populate the ClassMetadata instance.
* {@inheritDoc}
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 2.0
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan H. Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
* @deprecated this driver will be removed. Use Doctrine\Common\Persistence\Mapping\Driver\StaticPHPDriver instead
*/
class StaticPHPDriver implements Driver
class StaticPHPDriver extends CommonStaticPHPDriver
{
/**
* Paths of entity directories.
*
* @var array
*/
private $_paths = array();
/**
* Map of all class names.
*
* @var array
*/
private $_classNames;
/**
* The file extension of mapping documents.
*
* @var string
*/
private $_fileExtension = '.php';
public function __construct($paths)
{
$this->addPaths((array) $paths);
}
public function addPaths(array $paths)
{
$this->_paths = array_unique(array_merge($this->_paths, $paths));
}
/**
* {@inheritdoc}
*/
public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
{
call_user_func_array(array($className, 'loadMetadata'), array($metadata));
}
/**
* {@inheritDoc}
* @todo Same code exists in AnnotationDriver, should we re-use it somehow or not worry about it?
*/
public function getAllClassNames()
{
if ($this->_classNames !== null) {
return $this->_classNames;
}
if (!$this->_paths) {
throw MappingException::pathRequired();
}
$classes = array();
$includedFiles = array();
foreach ($this->_paths as $path) {
if (!is_dir($path)) {
throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path);
}
$iterator = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($path),
\RecursiveIteratorIterator::LEAVES_ONLY
);
foreach ($iterator as $file) {
if (($fileName = $file->getBasename($this->_fileExtension)) == $file->getBasename()) {
continue;
}
$sourceFile = realpath($file->getPathName());
require_once $sourceFile;
$includedFiles[] = $sourceFile;
}
}
$declared = get_declared_classes();
foreach ($declared as $className) {
$rc = new \ReflectionClass($className);
$sourceFile = $rc->getFileName();
if (in_array($sourceFile, $includedFiles) && !$this->isTransient($className)) {
$classes[] = $className;
}
}
$this->_classNames = $classes;
return $classes;
}
/**
* {@inheritdoc}
*/
public function isTransient($className)
{
return method_exists($className, 'loadMetadata') ? false : true;
}
}
}

View File

@@ -1,7 +1,5 @@
<?php
/*
* $Id$
*
* 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
@@ -15,14 +13,15 @@
* 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 LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping\Driver;
use SimpleXMLElement,
Doctrine\ORM\Mapping\ClassMetadataInfo,
Doctrine\Common\Persistence\Mapping\Driver\FileDriver,
Doctrine\Common\Persistence\Mapping\ClassMetadata,
Doctrine\ORM\Mapping\MappingException;
/**
@@ -31,31 +30,43 @@ use SimpleXMLElement,
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 2.0
* @version $Revision$
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan H. Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class XmlDriver extends AbstractFileDriver
class XmlDriver extends FileDriver
{
/**
* {@inheritdoc}
*/
protected $_fileExtension = '.dcm.xml';
const DEFAULT_FILE_EXTENSION = '.dcm.xml';
/**
* {@inheritdoc}
* {@inheritDoc}
*/
public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
public function __construct($locator, $fileExtension = self::DEFAULT_FILE_EXTENSION)
{
parent::__construct($locator, $fileExtension);
}
/**
* {@inheritDoc}
*/
public function loadMetadataForClass($className, ClassMetadata $metadata)
{
/* @var $metadata \Doctrine\ORM\Mapping\ClassMetadataInfo */
/* @var $xmlRoot SimpleXMLElement */
$xmlRoot = $this->getElement($className);
if ($xmlRoot->getName() == 'entity') {
if (isset($xmlRoot['repository-class'])) {
$metadata->setCustomRepositoryClass((string)$xmlRoot['repository-class']);
}
if (isset($xmlRoot['read-only']) && $this->evaluateBoolean($xmlRoot['read-only'])) {
$metadata->markReadOnly();
}
} else if ($xmlRoot->getName() == 'mapped-superclass') {
$metadata->setCustomRepositoryClass(
isset($xmlRoot['repository-class']) ? (string)$xmlRoot['repository-class'] : null
);
} else if ($xmlRoot->getName() == 'mapped-superclass') {
$metadata->isMappedSuperclass = true;
} else {
throw MappingException::classIsNotAValidEntityOrMappedSuperClass($className);
@@ -69,11 +80,73 @@ class XmlDriver extends AbstractFileDriver
$metadata->setPrimaryTable($table);
// Evaluate named queries
if (isset($xmlRoot->{'named-queries'})) {
foreach ($xmlRoot->{'named-queries'}->{'named-query'} as $namedQueryElement) {
$metadata->addNamedQuery(array(
'name' => (string)$namedQueryElement['name'],
'query' => (string)$namedQueryElement['query']
));
}
}
// Evaluate native named queries
if (isset($xmlRoot->{'named-native-queries'})) {
foreach ($xmlRoot->{'named-native-queries'}->{'named-native-query'} as $nativeQueryElement) {
$metadata->addNamedNativeQuery(array(
'name' => isset($nativeQueryElement['name']) ? (string)$nativeQueryElement['name'] : null,
'query' => isset($nativeQueryElement->query) ? (string)$nativeQueryElement->query : null,
'resultClass' => isset($nativeQueryElement['result-class']) ? (string)$nativeQueryElement['result-class'] : null,
'resultSetMapping' => isset($nativeQueryElement['result-set-mapping']) ? (string)$nativeQueryElement['result-set-mapping'] : null,
));
}
}
// Evaluate sql result set mapping
if (isset($xmlRoot->{'sql-result-set-mappings'})) {
foreach ($xmlRoot->{'sql-result-set-mappings'}->{'sql-result-set-mapping'} as $rsmElement) {
$entities = array();
$columns = array();
foreach ($rsmElement as $entityElement) {
//<entity-result/>
if (isset($entityElement['entity-class'])) {
$entityResult = array(
'fields' => array(),
'entityClass' => (string)$entityElement['entity-class'],
'discriminatorColumn' => isset($entityElement['discriminator-column']) ? (string)$entityElement['discriminator-column'] : null,
);
foreach ($entityElement as $fieldElement) {
$entityResult['fields'][] = array(
'name' => isset($fieldElement['name']) ? (string)$fieldElement['name'] : null,
'column' => isset($fieldElement['column']) ? (string)$fieldElement['column'] : null,
);
}
$entities[] = $entityResult;
}
//<column-result/>
if (isset($entityElement['name'])) {
$columns[] = array(
'name' => (string)$entityElement['name'],
);
}
}
$metadata->addSqlResultSetMapping(array(
'name' => (string)$rsmElement['name'],
'entities' => $entities,
'columns' => $columns
));
}
}
/* not implemented specially anyway. use table = schema.table
if (isset($xmlRoot['schema'])) {
$metadata->table['schema'] = (string)$xmlRoot['schema'];
}*/
if (isset($xmlRoot['inheritance-type'])) {
$inheritanceType = (string)$xmlRoot['inheritance-type'];
$metadata->setInheritanceType(constant('Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_' . $inheritanceType));
@@ -83,9 +156,10 @@ class XmlDriver extends AbstractFileDriver
if (isset($xmlRoot->{'discriminator-column'})) {
$discrColumn = $xmlRoot->{'discriminator-column'};
$metadata->setDiscriminatorColumn(array(
'name' => (string)$discrColumn['name'],
'type' => (string)$discrColumn['type'],
'length' => (string)$discrColumn['length']
'name' => isset($discrColumn['name']) ? (string)$discrColumn['name'] : null,
'type' => isset($discrColumn['type']) ? (string)$discrColumn['type'] : null,
'length' => isset($discrColumn['length']) ? (string)$discrColumn['length'] : null,
'columnDefinition' => isset($discrColumn['column-definition']) ? (string)$discrColumn['column-definition'] : null
));
} else {
$metadata->setDiscriminatorColumn(array('name' => 'dtype', 'type' => 'string', 'length' => 255));
@@ -94,7 +168,7 @@ class XmlDriver extends AbstractFileDriver
// Evaluate <discriminator-map...>
if (isset($xmlRoot->{'discriminator-map'})) {
$map = array();
foreach ($xmlRoot->{'discriminator-map'}->{'discriminator-mapping'} AS $discrMapElement) {
foreach ($xmlRoot->{'discriminator-map'}->{'discriminator-mapping'} as $discrMapElement) {
$map[(string)$discrMapElement['value']] = (string)$discrMapElement['class'];
}
$metadata->setDiscriminatorMap($map);
@@ -145,66 +219,63 @@ class XmlDriver extends AbstractFileDriver
}
}
if (isset($xmlRoot->options)) {
$metadata->table['options'] = $this->_parseOptions($xmlRoot->options->children());
}
// The mapping assignement is done in 2 times as a bug might occurs on some php/xml lib versions
// The internal SimpleXmlIterator get resetted, to this generate a duplicate field exception
$mappings = array();
// Evaluate <field ...> mappings
if (isset($xmlRoot->field)) {
foreach ($xmlRoot->field as $fieldMapping) {
$mapping = array(
'fieldName' => (string)$fieldMapping['name'],
'type' => (string)$fieldMapping['type']
);
$mapping = $this->columnToArray($fieldMapping);
if (isset($fieldMapping['column'])) {
$mapping['columnName'] = (string)$fieldMapping['column'];
}
if (isset($fieldMapping['length'])) {
$mapping['length'] = (int)$fieldMapping['length'];
}
if (isset($fieldMapping['precision'])) {
$mapping['precision'] = (int)$fieldMapping['precision'];
}
if (isset($fieldMapping['scale'])) {
$mapping['scale'] = (int)$fieldMapping['scale'];
}
if (isset($fieldMapping['unique'])) {
$mapping['unique'] = ((string)$fieldMapping['unique'] == "false") ? false : true;
}
if (isset($fieldMapping['options'])) {
$mapping['options'] = (array)$fieldMapping['options'];
}
if (isset($fieldMapping['nullable'])) {
$mapping['nullable'] = ((string)$fieldMapping['nullable'] == "false") ? false : true;
}
if (isset($fieldMapping['version']) && $fieldMapping['version']) {
if (isset($mapping['version'])) {
$metadata->setVersionMapping($mapping);
}
if (isset($fieldMapping['column-definition'])) {
$mapping['columnDefinition'] = (string)$fieldMapping['column-definition'];
}
$metadata->mapField($mapping);
}
}
foreach ($mappings as $mapping) {
if (isset($mapping['version'])) {
$metadata->setVersionMapping($mapping);
}
$metadata->mapField($mapping);
}
// Evaluate <id ...> mappings
$associationIds = array();
foreach ($xmlRoot->id as $idElement) {
if (isset($idElement['association-key']) && $this->evaluateBoolean($idElement['association-key'])) {
$associationIds[(string)$idElement['name']] = true;
continue;
}
$mapping = array(
'id' => true,
'fieldName' => (string)$idElement['name'],
'type' => (string)$idElement['type']
'fieldName' => (string)$idElement['name']
);
if (isset($idElement['type'])) {
$mapping['type'] = (string)$idElement['type'];
}
if (isset($idElement['length'])) {
$mapping['length'] = (string)$idElement['length'];
}
if (isset($idElement['column'])) {
$mapping['columnName'] = (string)$idElement['column'];
}
if (isset($idElement['column-definition'])) {
$mapping['columnDefinition'] = (string)$idElement['column-definition'];
}
$metadata->mapField($mapping);
if (isset($idElement->generator)) {
@@ -222,6 +293,11 @@ class XmlDriver extends AbstractFileDriver
'allocationSize' => (string)$seqGenerator['allocation-size'],
'initialValue' => (string)$seqGenerator['initial-value']
));
} else if (isset($idElement->{'custom-id-generator'})) {
$customGenerator = $idElement->{'custom-id-generator'};
$metadata->setCustomGeneratorDefinition(array(
'class' => (string) $customGenerator['class']
));
} else if (isset($idElement->{'table-generator'})) {
throw MappingException::tableIdGeneratorNotImplemented($className);
}
@@ -235,6 +311,10 @@ class XmlDriver extends AbstractFileDriver
'targetEntity' => (string)$oneToOneElement['target-entity']
);
if (isset($associationIds[$mapping['fieldName']])) {
$mapping['id'] = true;
}
if (isset($oneToOneElement['fetch'])) {
$mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . (string)$oneToOneElement['fetch']);
}
@@ -248,10 +328,10 @@ class XmlDriver extends AbstractFileDriver
$joinColumns = array();
if (isset($oneToOneElement->{'join-column'})) {
$joinColumns[] = $this->_getJoinColumnMapping($oneToOneElement->{'join-column'});
$joinColumns[] = $this->joinColumnToArray($oneToOneElement->{'join-column'});
} else if (isset($oneToOneElement->{'join-columns'})) {
foreach ($oneToOneElement->{'join-columns'}->{'join-column'} as $joinColumnElement) {
$joinColumns[] = $this->_getJoinColumnMapping($joinColumnElement);
$joinColumns[] = $this->joinColumnToArray($joinColumnElement);
}
}
@@ -262,8 +342,8 @@ class XmlDriver extends AbstractFileDriver
$mapping['cascade'] = $this->_getCascadeMappings($oneToOneElement->cascade);
}
if (isset($oneToOneElement->{'orphan-removal'})) {
$mapping['orphanRemoval'] = (bool)$oneToOneElement->{'orphan-removal'};
if (isset($oneToOneElement['orphan-removal'])) {
$mapping['orphanRemoval'] = $this->evaluateBoolean($oneToOneElement['orphan-removal']);
}
$metadata->mapOneToOne($mapping);
@@ -287,18 +367,24 @@ class XmlDriver extends AbstractFileDriver
$mapping['cascade'] = $this->_getCascadeMappings($oneToManyElement->cascade);
}
if (isset($oneToManyElement->{'orphan-removal'})) {
$mapping['orphanRemoval'] = (bool)$oneToManyElement->{'orphan-removal'};
if (isset($oneToManyElement['orphan-removal'])) {
$mapping['orphanRemoval'] = $this->evaluateBoolean($oneToManyElement['orphan-removal']);
}
if (isset($oneToManyElement->{'order-by'})) {
$orderBy = array();
foreach ($oneToManyElement->{'order-by'}->{'order-by-field'} AS $orderByField) {
foreach ($oneToManyElement->{'order-by'}->{'order-by-field'} as $orderByField) {
$orderBy[(string)$orderByField['name']] = (string)$orderByField['direction'];
}
$mapping['orderBy'] = $orderBy;
}
if (isset($oneToManyElement['index-by'])) {
$mapping['indexBy'] = (string)$oneToManyElement['index-by'];
} else if (isset($oneToManyElement->{'index-by'})) {
throw new \InvalidArgumentException("<index-by /> is not a valid tag");
}
$metadata->mapOneToMany($mapping);
}
}
@@ -311,6 +397,10 @@ class XmlDriver extends AbstractFileDriver
'targetEntity' => (string)$manyToOneElement['target-entity']
);
if (isset($associationIds[$mapping['fieldName']])) {
$mapping['id'] = true;
}
if (isset($manyToOneElement['fetch'])) {
$mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . (string)$manyToOneElement['fetch']);
}
@@ -322,13 +412,10 @@ class XmlDriver extends AbstractFileDriver
$joinColumns = array();
if (isset($manyToOneElement->{'join-column'})) {
$joinColumns[] = $this->_getJoinColumnMapping($manyToOneElement->{'join-column'});
$joinColumns[] = $this->joinColumnToArray($manyToOneElement->{'join-column'});
} else if (isset($manyToOneElement->{'join-columns'})) {
foreach ($manyToOneElement->{'join-columns'}->{'join-column'} as $joinColumnElement) {
if (!isset($joinColumnElement['name'])) {
$joinColumnElement['name'] = $name;
}
$joinColumns[] = $this->_getJoinColumnMapping($joinColumnElement);
$joinColumns[] = $this->joinColumnToArray($joinColumnElement);
}
}
@@ -338,10 +425,6 @@ class XmlDriver extends AbstractFileDriver
$mapping['cascade'] = $this->_getCascadeMappings($manyToOneElement->cascade);
}
if (isset($manyToOneElement->{'orphan-removal'})) {
$mapping['orphanRemoval'] = (bool)$manyToOneElement->{'orphan-removal'};
}
$metadata->mapManyToOne($mapping);
}
}
@@ -358,6 +441,10 @@ class XmlDriver extends AbstractFileDriver
$mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . (string)$manyToManyElement['fetch']);
}
if (isset($manyToManyElement['orphan-removal'])) {
$mapping['orphanRemoval'] = $this->evaluateBoolean($manyToManyElement['orphan-removal']);
}
if (isset($manyToManyElement['mapped-by'])) {
$mapping['mappedBy'] = (string)$manyToManyElement['mapped-by'];
} else if (isset($manyToManyElement->{'join-table'})) {
@@ -375,11 +462,11 @@ class XmlDriver extends AbstractFileDriver
}
foreach ($joinTableElement->{'join-columns'}->{'join-column'} as $joinColumnElement) {
$joinTable['joinColumns'][] = $this->_getJoinColumnMapping($joinColumnElement);
$joinTable['joinColumns'][] = $this->joinColumnToArray($joinColumnElement);
}
foreach ($joinTableElement->{'inverse-join-columns'}->{'join-column'} as $joinColumnElement) {
$joinTable['inverseJoinColumns'][] = $this->_getJoinColumnMapping($joinColumnElement);
$joinTable['inverseJoinColumns'][] = $this->joinColumnToArray($joinColumnElement);
}
$mapping['joinTable'] = $joinTable;
@@ -389,22 +476,80 @@ class XmlDriver extends AbstractFileDriver
$mapping['cascade'] = $this->_getCascadeMappings($manyToManyElement->cascade);
}
if (isset($manyToManyElement->{'orphan-removal'})) {
$mapping['orphanRemoval'] = (bool)$manyToManyElement->{'orphan-removal'};
}
if (isset($manyToManyElement->{'order-by'})) {
$orderBy = array();
foreach ($manyToManyElement->{'order-by'}->{'order-by-field'} AS $orderByField) {
foreach ($manyToManyElement->{'order-by'}->{'order-by-field'} as $orderByField) {
$orderBy[(string)$orderByField['name']] = (string)$orderByField['direction'];
}
$mapping['orderBy'] = $orderBy;
}
if (isset($manyToManyElement['index-by'])) {
$mapping['indexBy'] = (string)$manyToManyElement['index-by'];
} else if (isset($manyToManyElement->{'index-by'})) {
throw new \InvalidArgumentException("<index-by /> is not a valid tag");
}
$metadata->mapManyToMany($mapping);
}
}
// Evaluate association-overrides
if (isset($xmlRoot->{'attribute-overrides'})) {
foreach ($xmlRoot->{'attribute-overrides'}->{'attribute-override'} as $overrideElement) {
$fieldName = (string) $overrideElement['name'];
foreach ($overrideElement->field as $field) {
$mapping = $this->columnToArray($field);
$mapping['fieldName'] = $fieldName;
$metadata->setAttributeOverride($fieldName, $mapping);
}
}
}
// Evaluate association-overrides
if (isset($xmlRoot->{'association-overrides'})) {
foreach ($xmlRoot->{'association-overrides'}->{'association-override'} as $overrideElement) {
$fieldName = (string) $overrideElement['name'];
$override = array();
// Check for join-columns
if (isset($overrideElement->{'join-columns'})) {
$joinColumns = array();
foreach ($overrideElement->{'join-columns'}->{'join-column'} as $joinColumnElement) {
$joinColumns[] = $this->joinColumnToArray($joinColumnElement);
}
$override['joinColumns'] = $joinColumns;
}
// Check for join-table
if ($overrideElement->{'join-table'}) {
$joinTable = null;
$joinTableElement = $overrideElement->{'join-table'};
$joinTable = array(
'name' => (string) $joinTableElement['name'],
'schema' => (string) $joinTableElement['schema']
);
if (isset($joinTableElement->{'join-columns'})) {
foreach ($joinTableElement->{'join-columns'}->{'join-column'} as $joinColumnElement) {
$joinTable['joinColumns'][] = $this->joinColumnToArray($joinColumnElement);
}
}
if (isset($joinTableElement->{'inverse-join-columns'})) {
foreach ($joinTableElement->{'inverse-join-columns'}->{'join-column'} as $joinColumnElement) {
$joinTable['inverseJoinColumns'][] = $this->joinColumnToArray($joinColumnElement);
}
}
$override['joinTable'] = $joinTable;
}
$metadata->setAssociationOverride($fieldName, $override);
}
}
// Evaluate <lifecycle-callbacks...>
if (isset($xmlRoot->{'lifecycle-callbacks'})) {
foreach ($xmlRoot->{'lifecycle-callbacks'}->{'lifecycle-callback'} as $lifecycleCallback) {
@@ -413,14 +558,44 @@ class XmlDriver extends AbstractFileDriver
}
}
/**
* Parses (nested) option elements.
*
* @param SimpleXMLElement $options the XML element.
* @return array The options array.
*/
private function _parseOptions(SimpleXMLElement $options)
{
$array = array();
/* @var $option SimpleXMLElement */
foreach ($options as $option) {
if ($option->count()) {
$value = $this->_parseOptions($option->children());
} else {
$value = (string) $option;
}
$attr = $option->attributes();
if (isset($attr->name)) {
$array[(string) $attr->name] = $value;
} else {
$array[] = $value;
}
}
return $array;
}
/**
* Constructs a joinColumn mapping array based on the information
* found in the given SimpleXMLElement.
*
* @param $joinColumnElement The XML element.
* @param SimpleXMLElement $joinColumnElement the XML element.
* @return array The mapping array.
*/
private function _getJoinColumnMapping(SimpleXMLElement $joinColumnElement)
private function joinColumnToArray(SimpleXMLElement $joinColumnElement)
{
$joinColumn = array(
'name' => (string)$joinColumnElement['name'],
@@ -428,21 +603,17 @@ class XmlDriver extends AbstractFileDriver
);
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'])) {
$joinColumn['onDelete'] = (string)$joinColumnElement['on-delete'];
}
if (isset($joinColumnElement['on-update'])) {
$joinColumn['onUpdate'] = (string)$joinColumnElement['on-update'];
}
if (isset($joinColumnElement['column-definition'])) {
$joinColumn['columnDefinition'] = (string)$joinColumnElement['column-definition'];
}
@@ -450,15 +621,71 @@ class XmlDriver extends AbstractFileDriver
return $joinColumn;
}
/**
* Parse the given field as array
*
* @param SimpleXMLElement $fieldMapping
* @return array
*/
private function columnToArray(SimpleXMLElement $fieldMapping)
{
$mapping = array(
'fieldName' => (string) $fieldMapping['name'],
);
if (isset($fieldMapping['type'])) {
$mapping['type'] = (string) $fieldMapping['type'];
}
if (isset($fieldMapping['column'])) {
$mapping['columnName'] = (string) $fieldMapping['column'];
}
if (isset($fieldMapping['length'])) {
$mapping['length'] = (int) $fieldMapping['length'];
}
if (isset($fieldMapping['precision'])) {
$mapping['precision'] = (int) $fieldMapping['precision'];
}
if (isset($fieldMapping['scale'])) {
$mapping['scale'] = (int) $fieldMapping['scale'];
}
if (isset($fieldMapping['unique'])) {
$mapping['unique'] = $this->evaluateBoolean($fieldMapping['unique']);
}
if (isset($fieldMapping['nullable'])) {
$mapping['nullable'] = $this->evaluateBoolean($fieldMapping['nullable']);
}
if (isset($fieldMapping['version']) && $fieldMapping['version']) {
$mapping['version'] = $fieldMapping['version'];
}
if (isset($fieldMapping['column-definition'])) {
$mapping['columnDefinition'] = (string) $fieldMapping['column-definition'];
}
if (isset($fieldMapping->options)) {
$mapping['options'] = $this->_parseOptions($fieldMapping->options->children());
}
return $mapping;
}
/**
* Gathers a list of cascade options found in the given cascade element.
*
* @param $cascadeElement The cascade element.
* @param SimpleXMLElement $cascadeElement the cascade element.
* @return array The list of cascade options.
*/
private function _getCascadeMappings($cascadeElement)
{
$cascades = array();
/* @var $action SimpleXmlElement */
foreach ($cascadeElement->children() as $action) {
// According to the JPA specifications, XML uses "cascade-persist"
// instead of "persist". Here, both variations
@@ -471,9 +698,9 @@ class XmlDriver extends AbstractFileDriver
}
/**
* {@inheritdoc}
* {@inheritDoc}
*/
protected function _loadMappingFile($file)
protected function loadMappingFile($file)
{
$result = array();
$xmlElement = simplexml_load_file($file);
@@ -492,4 +719,12 @@ class XmlDriver extends AbstractFileDriver
return $result;
}
protected function evaluateBoolean($element)
{
$flag = (string)$element;
return ($flag === true || $flag == "true" || $flag == "1");
}
}

View File

@@ -13,14 +13,16 @@
* 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 LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping\Driver;
use Doctrine\ORM\Mapping\ClassMetadataInfo,
Doctrine\ORM\Mapping\MappingException;
use Doctrine\Common\Persistence\Mapping\ClassMetadata,
Doctrine\Common\Persistence\Mapping\Driver\FileDriver,
Doctrine\ORM\Mapping\MappingException,
Symfony\Component\Yaml\Yaml;
/**
* The YamlDriver reads the mapping metadata from yaml schema files.
@@ -31,25 +33,37 @@ use Doctrine\ORM\Mapping\ClassMetadataInfo,
* @author Jonathan H. Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class YamlDriver extends AbstractFileDriver
class YamlDriver extends FileDriver
{
/**
* {@inheritdoc}
*/
protected $_fileExtension = '.dcm.yml';
const DEFAULT_FILE_EXTENSION = '.dcm.yml';
/**
* {@inheritdoc}
* {@inheritDoc}
*/
public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
public function __construct($locator, $fileExtension = self::DEFAULT_FILE_EXTENSION)
{
parent::__construct($locator, $fileExtension);
}
/**
* {@inheritDoc}
*/
public function loadMetadataForClass($className, ClassMetadata $metadata)
{
/* @var $metadata \Doctrine\ORM\Mapping\ClassMetadataInfo */
$element = $this->getElement($className);
if ($element['type'] == 'entity') {
if (isset($element['repositoryClass'])) {
$metadata->setCustomRepositoryClass($element['repositoryClass']);
}
if (isset($element['readOnly']) && $element['readOnly'] == true) {
$metadata->markReadOnly();
}
} else if ($element['type'] == 'mappedSuperclass') {
$metadata->setCustomRepositoryClass(
isset($element['repositoryClass']) ? $element['repositoryClass'] : null
);
} else if ($element['type'] == 'mappedSuperclass') {
$metadata->isMappedSuperclass = true;
} else {
throw MappingException::classIsNotAValidEntityOrMappedSuperClass($className);
@@ -62,6 +76,83 @@ class YamlDriver extends AbstractFileDriver
}
$metadata->setPrimaryTable($table);
// Evaluate named queries
if (isset($element['namedQueries'])) {
foreach ($element['namedQueries'] as $name => $queryMapping) {
if (is_string($queryMapping)) {
$queryMapping = array('query' => $queryMapping);
}
if ( ! isset($queryMapping['name'])) {
$queryMapping['name'] = $name;
}
$metadata->addNamedQuery($queryMapping);
}
}
// Evaluate named native queries
if (isset($element['namedNativeQueries'])) {
foreach ($element['namedNativeQueries'] as $name => $mappingElement) {
if (!isset($mappingElement['name'])) {
$mappingElement['name'] = $name;
}
$metadata->addNamedNativeQuery(array(
'name' => $mappingElement['name'],
'query' => isset($mappingElement['query']) ? $mappingElement['query'] : null,
'resultClass' => isset($mappingElement['resultClass']) ? $mappingElement['resultClass'] : null,
'resultSetMapping' => isset($mappingElement['resultSetMapping']) ? $mappingElement['resultSetMapping'] : null,
));
}
}
// Evaluate sql result set mappings
if (isset($element['sqlResultSetMappings'])) {
foreach ($element['sqlResultSetMappings'] as $name => $resultSetMapping) {
if (!isset($resultSetMapping['name'])) {
$resultSetMapping['name'] = $name;
}
$entities = array();
$columns = array();
if (isset($resultSetMapping['entityResult'])) {
foreach ($resultSetMapping['entityResult'] as $entityResultElement) {
$entityResult = array(
'fields' => array(),
'entityClass' => isset($entityResultElement['entityClass']) ? $entityResultElement['entityClass'] : null,
'discriminatorColumn' => isset($entityResultElement['discriminatorColumn']) ? $entityResultElement['discriminatorColumn'] : null,
);
if (isset($entityResultElement['fieldResult'])) {
foreach ($entityResultElement['fieldResult'] as $fieldResultElement) {
$entityResult['fields'][] = array(
'name' => isset($fieldResultElement['name']) ? $fieldResultElement['name'] : null,
'column' => isset($fieldResultElement['column']) ? $fieldResultElement['column'] : null,
);
}
}
$entities[] = $entityResult;
}
}
if (isset($resultSetMapping['columnResult'])) {
foreach ($resultSetMapping['columnResult'] as $columnResultAnnot) {
$columns[] = array(
'name' => isset($columnResultAnnot['name']) ? $columnResultAnnot['name'] : null,
);
}
}
$metadata->addSqlResultSetMapping(array(
'name' => $resultSetMapping['name'],
'entities' => $entities,
'columns' => $columns
));
}
}
/* not implemented specially anyway. use table = schema.table
if (isset($element['schema'])) {
$metadata->table['schema'] = $element['schema'];
@@ -75,9 +166,10 @@ class YamlDriver extends AbstractFileDriver
if (isset($element['discriminatorColumn'])) {
$discrColumn = $element['discriminatorColumn'];
$metadata->setDiscriminatorColumn(array(
'name' => $discrColumn['name'],
'type' => $discrColumn['type'],
'length' => $discrColumn['length']
'name' => isset($discrColumn['name']) ? (string)$discrColumn['name'] : null,
'type' => isset($discrColumn['type']) ? (string)$discrColumn['type'] : null,
'length' => isset($discrColumn['length']) ? (string)$discrColumn['length'] : null,
'columnDefinition' => isset($discrColumn['columnDefinition']) ? (string)$discrColumn['columnDefinition'] : null
));
} else {
$metadata->setDiscriminatorColumn(array('name' => 'dtype', 'type' => 'string', 'length' => 255));
@@ -106,6 +198,7 @@ class YamlDriver extends AbstractFileDriver
if (is_string($index['columns'])) {
$columns = explode(',', $index['columns']);
$columns = array_map('trim', $columns);
} else {
$columns = $index['columns'];
}
@@ -125,6 +218,7 @@ class YamlDriver extends AbstractFileDriver
if (is_string($unique['columns'])) {
$columns = explode(',', $unique['columns']);
$columns = array_map('trim', $columns);
} else {
$columns = $unique['columns'];
}
@@ -135,19 +229,28 @@ class YamlDriver extends AbstractFileDriver
}
}
if (isset($element['options'])) {
$metadata->table['options'] = $element['options'];
}
$associationIds = array();
if (isset($element['id'])) {
// Evaluate identifier settings
foreach ($element['id'] as $name => $idElement) {
if (!isset($idElement['type'])) {
throw MappingException::propertyTypeIsRequired($className, $name);
if (isset($idElement['associationKey']) && $idElement['associationKey'] == true) {
$associationIds[$name] = true;
continue;
}
$mapping = array(
'id' => true,
'fieldName' => $name,
'type' => $idElement['type']
'fieldName' => $name
);
if (isset($idElement['type'])) {
$mapping['type'] = $idElement['type'];
}
if (isset($idElement['column'])) {
$mapping['columnName'] = $idElement['column'];
}
@@ -156,6 +259,10 @@ class YamlDriver extends AbstractFileDriver
$mapping['length'] = $idElement['length'];
}
if (isset($idElement['columnDefinition'])) {
$mapping['columnDefinition'] = $idElement['columnDefinition'];
}
$metadata->mapField($mapping);
if (isset($idElement['generator'])) {
@@ -165,6 +272,11 @@ class YamlDriver extends AbstractFileDriver
// Check for SequenceGenerator/TableGenerator definition
if (isset($idElement['sequenceGenerator'])) {
$metadata->setSequenceGeneratorDefinition($idElement['sequenceGenerator']);
} else if (isset($idElement['customIdGenerator'])) {
$customGenerator = $idElement['customIdGenerator'];
$metadata->setCustomGeneratorDefinition(array(
'class' => (string) $customGenerator['class']
));
} else if (isset($idElement['tableGenerator'])) {
throw MappingException::tableIdGeneratorNotImplemented($className);
}
@@ -174,19 +286,9 @@ class YamlDriver extends AbstractFileDriver
// Evaluate fields
if (isset($element['fields'])) {
foreach ($element['fields'] as $name => $fieldMapping) {
if (!isset($fieldMapping['type'])) {
throw MappingException::propertyTypeIsRequired($className, $name);
}
$e = explode('(', $fieldMapping['type']);
$fieldMapping['type'] = $e[0];
if (isset($e[1])) {
$fieldMapping['length'] = substr($e[1], 0, strlen($e[1]) - 1);
}
$mapping = array(
'fieldName' => $name,
'type' => $fieldMapping['type']
);
$mapping = $this->columnToArray($name, $fieldMapping);
if (isset($fieldMapping['id'])) {
$mapping['id'] = true;
if (isset($fieldMapping['generator']['strategy'])) {
@@ -194,33 +296,10 @@ class YamlDriver extends AbstractFileDriver
. strtoupper($fieldMapping['generator']['strategy'])));
}
}
if (isset($fieldMapping['column'])) {
$mapping['columnName'] = $fieldMapping['column'];
}
if (isset($fieldMapping['length'])) {
$mapping['length'] = $fieldMapping['length'];
}
if (isset($fieldMapping['precision'])) {
$mapping['precision'] = $fieldMapping['precision'];
}
if (isset($fieldMapping['scale'])) {
$mapping['scale'] = $fieldMapping['scale'];
}
if (isset($fieldMapping['unique'])) {
$mapping['unique'] = (bool)$fieldMapping['unique'];
}
if (isset($fieldMapping['options'])) {
$mapping['options'] = $fieldMapping['options'];
}
if (isset($fieldMapping['nullable'])) {
$mapping['nullable'] = $fieldMapping['nullable'];
}
if (isset($fieldMapping['version']) && $fieldMapping['version']) {
if (isset($mapping['version'])) {
$metadata->setVersionMapping($mapping);
}
if (isset($fieldMapping['columnDefinition'])) {
$mapping['columnDefinition'] = $fieldMapping['columnDefinition'];
}
$metadata->mapField($mapping);
}
@@ -234,6 +313,10 @@ class YamlDriver extends AbstractFileDriver
'targetEntity' => $oneToOneElement['targetEntity']
);
if (isset($associationIds[$mapping['fieldName']])) {
$mapping['id'] = true;
}
if (isset($oneToOneElement['fetch'])) {
$mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $oneToOneElement['fetch']);
}
@@ -248,14 +331,14 @@ class YamlDriver extends AbstractFileDriver
$joinColumns = array();
if (isset($oneToOneElement['joinColumn'])) {
$joinColumns[] = $this->_getJoinColumnMapping($oneToOneElement['joinColumn']);
$joinColumns[] = $this->joinColumnToArray($oneToOneElement['joinColumn']);
} else if (isset($oneToOneElement['joinColumns'])) {
foreach ($oneToOneElement['joinColumns'] as $name => $joinColumnElement) {
if (!isset($joinColumnElement['name'])) {
$joinColumnElement['name'] = $name;
foreach ($oneToOneElement['joinColumns'] as $joinColumnName => $joinColumnElement) {
if ( ! isset($joinColumnElement['name'])) {
$joinColumnElement['name'] = $joinColumnName;
}
$joinColumns[] = $this->_getJoinColumnMapping($joinColumnElement);
$joinColumns[] = $this->joinColumnToArray($joinColumnElement);
}
}
@@ -266,6 +349,10 @@ class YamlDriver extends AbstractFileDriver
$mapping['cascade'] = $oneToOneElement['cascade'];
}
if (isset($oneToOneElement['orphanRemoval'])) {
$mapping['orphanRemoval'] = (bool)$oneToOneElement['orphanRemoval'];
}
$metadata->mapOneToOne($mapping);
}
}
@@ -287,10 +374,18 @@ class YamlDriver extends AbstractFileDriver
$mapping['cascade'] = $oneToManyElement['cascade'];
}
if (isset($oneToManyElement['orphanRemoval'])) {
$mapping['orphanRemoval'] = (bool)$oneToManyElement['orphanRemoval'];
}
if (isset($oneToManyElement['orderBy'])) {
$mapping['orderBy'] = $oneToManyElement['orderBy'];
}
if (isset($oneToManyElement['indexBy'])) {
$mapping['indexBy'] = $oneToManyElement['indexBy'];
}
$metadata->mapOneToMany($mapping);
}
}
@@ -303,6 +398,10 @@ class YamlDriver extends AbstractFileDriver
'targetEntity' => $manyToOneElement['targetEntity']
);
if (isset($associationIds[$mapping['fieldName']])) {
$mapping['id'] = true;
}
if (isset($manyToOneElement['fetch'])) {
$mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $manyToOneElement['fetch']);
}
@@ -314,14 +413,14 @@ class YamlDriver extends AbstractFileDriver
$joinColumns = array();
if (isset($manyToOneElement['joinColumn'])) {
$joinColumns[] = $this->_getJoinColumnMapping($manyToOneElement['joinColumn']);
$joinColumns[] = $this->joinColumnToArray($manyToOneElement['joinColumn']);
} else if (isset($manyToOneElement['joinColumns'])) {
foreach ($manyToOneElement['joinColumns'] as $name => $joinColumnElement) {
if (!isset($joinColumnElement['name'])) {
$joinColumnElement['name'] = $name;
foreach ($manyToOneElement['joinColumns'] as $joinColumnName => $joinColumnElement) {
if ( ! isset($joinColumnElement['name'])) {
$joinColumnElement['name'] = $joinColumnName;
}
$joinColumns[] = $this->_getJoinColumnMapping($joinColumnElement);
$joinColumns[] = $this->joinColumnToArray($joinColumnElement);
}
}
@@ -350,9 +449,6 @@ class YamlDriver extends AbstractFileDriver
if (isset($manyToManyElement['mappedBy'])) {
$mapping['mappedBy'] = $manyToManyElement['mappedBy'];
} else if (isset($manyToManyElement['joinTable'])) {
if (isset($manyToManyElement['inversedBy'])) {
$mapping['inversedBy'] = $manyToManyElement['inversedBy'];
}
$joinTableElement = $manyToManyElement['joinTable'];
$joinTable = array(
@@ -363,25 +459,29 @@ class YamlDriver extends AbstractFileDriver
$joinTable['schema'] = $joinTableElement['schema'];
}
foreach ($joinTableElement['joinColumns'] as $name => $joinColumnElement) {
if (!isset($joinColumnElement['name'])) {
$joinColumnElement['name'] = $name;
foreach ($joinTableElement['joinColumns'] as $joinColumnName => $joinColumnElement) {
if ( ! isset($joinColumnElement['name'])) {
$joinColumnElement['name'] = $joinColumnName;
}
$joinTable['joinColumns'][] = $this->_getJoinColumnMapping($joinColumnElement);
$joinTable['joinColumns'][] = $this->joinColumnToArray($joinColumnElement);
}
foreach ($joinTableElement['inverseJoinColumns'] as $name => $joinColumnElement) {
if (!isset($joinColumnElement['name'])) {
$joinColumnElement['name'] = $name;
foreach ($joinTableElement['inverseJoinColumns'] as $joinColumnName => $joinColumnElement) {
if ( ! isset($joinColumnElement['name'])) {
$joinColumnElement['name'] = $joinColumnName;
}
$joinTable['inverseJoinColumns'][] = $this->_getJoinColumnMapping($joinColumnElement);
$joinTable['inverseJoinColumns'][] = $this->joinColumnToArray($joinColumnElement);
}
$mapping['joinTable'] = $joinTable;
}
if (isset($manyToManyElement['inversedBy'])) {
$mapping['inversedBy'] = $manyToManyElement['inversedBy'];
}
if (isset($manyToManyElement['cascade'])) {
$mapping['cascade'] = $manyToManyElement['cascade'];
}
@@ -390,10 +490,80 @@ class YamlDriver extends AbstractFileDriver
$mapping['orderBy'] = $manyToManyElement['orderBy'];
}
if (isset($manyToManyElement['indexBy'])) {
$mapping['indexBy'] = $manyToManyElement['indexBy'];
}
if (isset($manyToManyElement['orphanRemoval'])) {
$mapping['orphanRemoval'] = (bool)$manyToManyElement['orphanRemoval'];
}
$metadata->mapManyToMany($mapping);
}
}
// Evaluate associationOverride
if (isset($element['associationOverride']) && is_array($element['associationOverride'])) {
foreach ($element['associationOverride'] as $fieldName => $associationOverrideElement) {
$override = array();
// Check for joinColumn
if (isset($associationOverrideElement['joinColumn'])) {
$joinColumns = array();
foreach ($associationOverrideElement['joinColumn'] as $name => $joinColumnElement) {
if ( ! isset($joinColumnElement['name'])) {
$joinColumnElement['name'] = $name;
}
$joinColumns[] = $this->joinColumnToArray($joinColumnElement);
}
$override['joinColumns'] = $joinColumns;
}
// Check for joinTable
if (isset($associationOverrideElement['joinTable'])) {
$joinTableElement = $associationOverrideElement['joinTable'];
$joinTable = array(
'name' => $joinTableElement['name']
);
if (isset($joinTableElement['schema'])) {
$joinTable['schema'] = $joinTableElement['schema'];
}
foreach ($joinTableElement['joinColumns'] as $name => $joinColumnElement) {
if ( ! isset($joinColumnElement['name'])) {
$joinColumnElement['name'] = $name;
}
$joinTable['joinColumns'][] = $this->joinColumnToArray($joinColumnElement);
}
foreach ($joinTableElement['inverseJoinColumns'] as $name => $joinColumnElement) {
if ( ! isset($joinColumnElement['name'])) {
$joinColumnElement['name'] = $name;
}
$joinTable['inverseJoinColumns'][] = $this->joinColumnToArray($joinColumnElement);
}
$override['joinTable'] = $joinTable;
}
$metadata->setAssociationOverride($fieldName, $override);
}
}
// Evaluate associationOverride
if (isset($element['attributeOverride']) && is_array($element['attributeOverride'])) {
foreach ($element['attributeOverride'] as $fieldName => $attributeOverrideElement) {
$mapping = $this->columnToArray($fieldName, $attributeOverrideElement);
$metadata->setAttributeOverride($fieldName, $mapping);
}
}
// Evaluate lifeCycleCallbacks
if (isset($element['lifecycleCallbacks'])) {
foreach ($element['lifecycleCallbacks'] as $type => $methods) {
@@ -408,15 +578,19 @@ class YamlDriver extends AbstractFileDriver
* Constructs a joinColumn mapping array based on the information
* found in the given join column element.
*
* @param $joinColumnElement The array join column element
* @param array $joinColumnElement The array join column element
* @return array The mapping array.
*/
private function _getJoinColumnMapping($joinColumnElement)
private function joinColumnToArray($joinColumnElement)
{
$joinColumn = array(
'name' => $joinColumnElement['name'],
'referencedColumnName' => $joinColumnElement['referencedColumnName']
);
$joinColumn = array();
if (isset($joinColumnElement['referencedColumnName'])) {
$joinColumn['referencedColumnName'] = (string) $joinColumnElement['referencedColumnName'];
}
if (isset($joinColumnElement['name'])) {
$joinColumn['name'] = (string) $joinColumnElement['name'];
}
if (isset($joinColumnElement['fieldName'])) {
$joinColumn['fieldName'] = (string) $joinColumnElement['fieldName'];
@@ -434,10 +608,6 @@ class YamlDriver extends AbstractFileDriver
$joinColumn['onDelete'] = $joinColumnElement['onDelete'];
}
if (isset($joinColumnElement['onUpdate'])) {
$joinColumn['onUpdate'] = $joinColumnElement['onUpdate'];
}
if (isset($joinColumnElement['columnDefinition'])) {
$joinColumn['columnDefinition'] = $joinColumnElement['columnDefinition'];
}
@@ -446,10 +616,72 @@ class YamlDriver extends AbstractFileDriver
}
/**
* {@inheritdoc}
* Parse the given column as array
*
* @param string $fieldName
* @param array $column
* @return array
*/
protected function _loadMappingFile($file)
private function columnToArray($fieldName, $column)
{
return \Symfony\Component\Yaml\Yaml::load($file);
$mapping = array(
'fieldName' => $fieldName
);
if (isset($column['type'])) {
$params = explode('(', $column['type']);
$column['type'] = $params[0];
$mapping['type'] = $column['type'];
if (isset($params[1])) {
$column['length'] = (integer) substr($params[1], 0, strlen($params[1]) - 1);
}
}
if (isset($column['column'])) {
$mapping['columnName'] = $column['column'];
}
if (isset($column['length'])) {
$mapping['length'] = $column['length'];
}
if (isset($column['precision'])) {
$mapping['precision'] = $column['precision'];
}
if (isset($column['scale'])) {
$mapping['scale'] = $column['scale'];
}
if (isset($column['unique'])) {
$mapping['unique'] = (bool)$column['unique'];
}
if (isset($column['options'])) {
$mapping['options'] = $column['options'];
}
if (isset($column['nullable'])) {
$mapping['nullable'] = $column['nullable'];
}
if (isset($column['version']) && $column['version']) {
$mapping['version'] = $column['version'];
}
if (isset($column['columnDefinition'])) {
$mapping['columnDefinition'] = $column['columnDefinition'];
}
return $mapping;
}
/**
* {@inheritDoc}
*/
protected function loadMappingFile($file)
{
return Yaml::parse($file);
}
}

View File

@@ -0,0 +1,31 @@
<?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\ORM\Mapping;
/**
* @Annotation
* @Target("ALL")
* @todo check available targets
*/
final class ElementCollection implements Annotation
{
/** @var string */
public $tableName;
}

View File

@@ -0,0 +1,32 @@
<?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\ORM\Mapping;
/**
* @Annotation
* @Target("CLASS")
*/
final class Entity implements Annotation
{
/** @var string */
public $repositoryClass;
/** @var boolean */
public $readOnly = false;
}

View File

@@ -0,0 +1,58 @@
<?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\ORM\Mapping;
/**
* References an entity in the SELECT clause of a SQL query.
* If this annotation is used, the SQL statement should select all of the columns that are mapped to the entity object.
* This should include foreign key columns to related entities.
* The results obtained when insufficient data is available are undefined.
*
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
* @since 2.3
*
* @Annotation
* @Target("ANNOTATION")
*/
final class EntityResult implements Annotation
{
/**
* The class of the result
*
* @var string
*/
public $entityClass;
/**
* Maps the columns specified in the SELECT list of the query to the properties or fields of the entity class.
*
* @var array<\Doctrine\ORM\Mapping\FieldResult>
*/
public $fields = array();
/**
* Specifies the column name of the column in the SELECT list that is used to determine the type of the entity instance.
*
* @var string
*/
public $discriminatorColumn;
}

View File

@@ -0,0 +1,48 @@
<?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\ORM\Mapping;
/**
* Is used to map the columns specified in the SELECT list of the query to the properties or fields of the entity class.
*
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
* @since 2.3
*
* @Annotation
* @Target("ANNOTATION")
*/
final class FieldResult implements Annotation
{
/**
* Name of the column in the SELECT clause.
*
* @var string
*/
public $name;
/**
* Name of the persistent field or property of the class.
*
* @var string
*/
public $column;
}

View File

@@ -0,0 +1,30 @@
<?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\ORM\Mapping;
/**
* @Annotation
* @Target("PROPERTY")
*/
final class GeneratedValue implements Annotation
{
/** @var string */
public $strategy = 'AUTO';
}

View File

@@ -0,0 +1,28 @@
<?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\ORM\Mapping;
/**
* @Annotation
* @Target("CLASS")
*/
final class HasLifecycleCallbacks implements Annotation
{
}

View File

@@ -0,0 +1,28 @@
<?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\ORM\Mapping;
/**
* @Annotation
* @Target("PROPERTY")
*/
final class Id implements Annotation
{
}

View File

@@ -0,0 +1,32 @@
<?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\ORM\Mapping;
/**
* @Annotation
* @Target("ANNOTATION")
*/
final class Index implements Annotation
{
/** @var string */
public $name;
/** @var array<string> */
public $columns;
}

View File

@@ -0,0 +1,30 @@
<?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\ORM\Mapping;
/**
* @Annotation
* @Target("CLASS")
*/
final class InheritanceType implements Annotation
{
/** @var string */
public $value;
}

View File

@@ -0,0 +1,42 @@
<?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\ORM\Mapping;
/**
* @Annotation
* @Target({"PROPERTY","ANNOTATION"})
*/
final class JoinColumn implements Annotation
{
/** @var string */
public $name;
/** @var string */
public $referencedColumnName = 'id';
/** @var boolean */
public $unique = false;
/** @var boolean */
public $nullable = true;
/** @var mixed */
public $onDelete;
/** @var string */
public $columnDefinition;
/** @var string */
public $fieldName; // field name used in non-object hydration (array/scalar)
}

View File

@@ -0,0 +1,30 @@
<?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\ORM\Mapping;
/**
* @Annotation
* @Target("PROPERTY")
*/
final class JoinColumns implements Annotation
{
/** @var array<\Doctrine\ORM\Mapping\JoinColumn> */
public $value;
}

View File

@@ -0,0 +1,36 @@
<?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\ORM\Mapping;
/**
* @Annotation
* @Target({"PROPERTY","ANNOTATION"})
*/
final class JoinTable implements Annotation
{
/** @var string */
public $name;
/** @var string */
public $schema;
/** @var array<\Doctrine\ORM\Mapping\JoinColumn> */
public $joinColumns = array();
/** @var array<\Doctrine\ORM\Mapping\JoinColumn> */
public $inverseJoinColumns = array();
}

View File

@@ -0,0 +1,42 @@
<?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\ORM\Mapping;
/**
* @Annotation
* @Target("PROPERTY")
*/
final class ManyToMany implements Annotation
{
/** @var string */
public $targetEntity;
/** @var string */
public $mappedBy;
/** @var string */
public $inversedBy;
/** @var array<string> */
public $cascade;
/** @var string */
public $fetch = 'LAZY';
/** @var boolean */
public $orphanRemoval = false;
/** @var string */
public $indexBy;
}

View File

@@ -0,0 +1,36 @@
<?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\ORM\Mapping;
/**
* @Annotation
* @Target("PROPERTY")
*/
final class ManyToOne implements Annotation
{
/** @var string */
public $targetEntity;
/** @var array<string> */
public $cascade;
/** @var string */
public $fetch = 'LAZY';
/** @var string */
public $inversedBy;
}

View File

@@ -0,0 +1,30 @@
<?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\ORM\Mapping;
/**
* @Annotation
* @Target("CLASS")
*/
final class MappedSuperclass implements Annotation
{
/** @var string */
public $repositoryClass;
}

View File

@@ -13,7 +13,7 @@
* 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 LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.phpdoctrine.org>.
*/
@@ -34,8 +34,18 @@ class MappingException extends \Doctrine\ORM\ORMException
public static function identifierRequired($entityName)
{
return new self("No identifier/primary key specified for Entity '$entityName'."
. " Every Entity must have an identifier/primary key.");
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
));
}
return new self(sprintf(
'No identifier/primary key specified for Entity "%s". Every Entity must have an identifier/primary key.',
$entityName
));
}
public static function invalidInheritanceType($entityName, $type)
@@ -68,11 +78,73 @@ class MappingException extends \Doctrine\ORM\ORMException
return new self("No mapping file found named '$fileName' for class '$entityName'.");
}
/**
* Exception for invalid property name override.
*
* @param string $className The entity's name
* @param string $fieldName
*/
public static function invalidOverrideFieldName($className, $fieldName)
{
return new self("Invalid field override named '$fieldName' for class '$className'.");
}
/**
* Exception for invalid property type override.
*
* @param string $className The entity's name
* @param string $fieldName
*/
public static function invalidOverrideFieldType($className, $fieldName)
{
return new self("The column type of attribute '$fieldName' on class '$className' could not be changed.");
}
public static function mappingNotFound($className, $fieldName)
{
return new self("No mapping found for field '$fieldName' on class '$className'.");
}
public static function queryNotFound($className, $queryName)
{
return new self("No query found named '$queryName' on class '$className'.");
}
public static function resultMappingNotFound($className, $resultName)
{
return new self("No result set mapping found named '$resultName' on class '$className'.");
}
public static function emptyQueryMapping($entity, $queryName)
{
return new self('Query named "'.$queryName.'" in "'.$entity.'" could not be empty.');
}
public static function nameIsMandatoryForQueryMapping($className)
{
return new self("Query name on entity class '$className' is not defined.");
}
public static function missingQueryMapping($entity, $queryName)
{
return new self('Query named "'.$queryName.'" in "'.$entity.' requires a result class or result set mapping.');
}
public static function missingResultSetMappingEntity($entity, $resultName)
{
return new self('Result set mapping named "'.$resultName.'" in "'.$entity.' requires a entity class name.');
}
public static function missingResultSetMappingFieldName($entity, $resultName)
{
return new self('Result set mapping named "'.$resultName.'" in "'.$entity.' requires a field name.');
}
public static function nameIsMandatoryForSqlResultSetMapping($className)
{
return new self("Result set mapping name on entity class '$className' is not defined.");
}
public static function oneToManyRequiresMappedBy($fieldName)
{
return new self("OneToMany mapping on field '$fieldName' requires the 'mappedBy' attribute.");
@@ -134,7 +206,17 @@ class MappingException extends \Doctrine\ORM\ORMException
public static function classIsNotAValidEntityOrMappedSuperClass($className)
{
return new self('Class '.$className.' is not a valid entity or mapped super class.');
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
));
}
return new self(sprintf(
'Class "%s" is not a valid entity or mapped super class.',
$className
));
}
public static function propertyTypeIsRequired($className, $propertyName)
@@ -148,23 +230,36 @@ class MappingException extends \Doctrine\ORM\ORMException
}
/**
*
* @param string $entity The entity's name
* @param string $fieldName The name of the field that was already declared
*/
public static function duplicateFieldMapping($entity, $fieldName) {
public static function duplicateFieldMapping($entity, $fieldName)
{
return new self('Property "'.$fieldName.'" in "'.$entity.'" was already declared, but it must be declared only once');
}
public static function duplicateAssociationMapping($entity, $fieldName) {
public static function duplicateAssociationMapping($entity, $fieldName)
{
return new self('Property "'.$fieldName.'" in "'.$entity.'" was already declared, but it must be declared only once');
}
public static function singleIdNotAllowedOnCompositePrimaryKey($entity) {
public static function duplicateQueryMapping($entity, $queryName)
{
return new self('Query named "'.$queryName.'" in "'.$entity.'" was already declared, but it must be declared only once');
}
public static function duplicateResultSetMapping($entity, $resultName)
{
return new self('Result set mapping named "'.$resultName.'" in "'.$entity.'" was already declared, but it must be declared only once');
}
public static function singleIdNotAllowedOnCompositePrimaryKey($entity)
{
return new self('Single id is not allowed on composite primary key in entity '.$entity);
}
public static function unsupportedOptimisticLockingType($entity, $fieldName, $unsupportedType) {
public static function unsupportedOptimisticLockingType($entity, $fieldName, $unsupportedType)
{
return new self('Locking type "'.$unsupportedType.'" (specified in "'.$entity.'", field "'.$fieldName.'") '
.'is not supported by Doctrine.'
);
@@ -175,7 +270,7 @@ class MappingException extends \Doctrine\ORM\ORMException
if ( ! empty($path)) {
$path = '[' . $path . ']';
}
return new self(
'File mapping drivers must have a valid directory path, ' .
'however the given path ' . $path . ' seems to be incorrect!'
@@ -190,13 +285,25 @@ class MappingException extends \Doctrine\ORM\ORMException
* @param string $owningClass The class that declares the discriminator map.
* @return self
*/
public static function invalidClassInDiscriminatorMap($className, $owningClass) {
public static function invalidClassInDiscriminatorMap($className, $owningClass)
{
return new self(
"Entity class '$className' used in the discriminator map of class '$owningClass' ".
"does not exist."
);
}
public static function duplicateDiscriminatorEntry($className, array $entries, array $map)
{
return new self(
"The entries " . implode(', ', $entries) . " in discriminator map of class '" . $className . "' is duplicated. " .
"If the discriminator map is automatically generated you have to convert it to an explicit discriminator map now. " .
"The entries of the current map are: @DiscriminatorMap({" . implode(', ', array_map(
function($a, $b) { return "'$a': '$b'"; }, array_keys($map), array_values($map)
)) . "})"
);
}
public static function missingDiscriminatorMap($className)
{
return new self("Entity class '$className' is using inheritance but no discriminator map was defined.");
@@ -212,11 +319,21 @@ class MappingException extends \Doctrine\ORM\ORMException
return new self("Discriminator column type on entity class '$className' is not allowed to be '$type'. 'string' or 'integer' type variables are suggested!");
}
public static function nameIsMandatoryForDiscriminatorColumns($className)
{
return new self("Discriminator column name on entity class '$className' is not defined.");
}
public static function cannotVersionIdField($className, $fieldName)
{
return new self("Setting Id field '$fieldName' as versionale in entity class '$className' is not supported.");
}
public static function sqlConversionNotAllowedForIdentifiers($className, $fieldName, $type)
{
return new self("It is not possible to set id field '$fieldName' to type '$type' in entity class '$className'. The type '$type' requires conversion SQL which is not allowed for identifiers.");
}
/**
* @param string $className
* @param string $columnName
@@ -231,4 +348,94 @@ class MappingException extends \Doctrine\ORM\ORMException
{
return new self("It is illegal to put an inverse side one-to-many or many-to-many association on mapped superclass '".$className."#".$field."'.");
}
}
/**
* @param string $className
* @param string $targetEntity
* @param string $targetField
* @return self
*/
public static function cannotMapCompositePrimaryKeyEntitiesAsForeignId($className, $targetEntity, $targetField)
{
return new self("It is not possible to map entity '".$className."' with a composite primary key ".
"as part of the primary key of another entity '".$targetEntity."#".$targetField."'.");
}
public static function noSingleAssociationJoinColumnFound($className, $field)
{
return new self("'$className#$field' is not an association with a single join column.");
}
public static function noFieldNameFoundForColumn($className, $column)
{
return new self("Cannot find a field on '$className' that is mapped to column '$column'. Either the ".
"field does not exist or an association exists but it has multiple join columns.");
}
public static function illegalOrphanRemovalOnIdentifierAssociation($className, $field)
{
return new self("The orphan removal option is not allowed on an association that is ".
"part of the identifier in '$className#$field'.");
}
public static function illegalOrphanRemoval($className, $field)
{
return new self("Orphan removal is only allowed on one-to-one and one-to-many ".
"associations, but " . $className."#" .$field . " is not.");
}
public static function illegalInverseIdentifierAssocation($className, $field)
{
return new self("An inverse association is not allowed to be identifier in '$className#$field'.");
}
public static function illegalToManyIdentifierAssoaction($className, $field)
{
return new self("Many-to-many or one-to-many associations are not allowed to be identifier in '$className#$field'.");
}
public static function noInheritanceOnMappedSuperClass($className)
{
return new self("Its not supported to define inheritance information on a mapped superclass '" . $className . "'.");
}
public static function mappedClassNotPartOfDiscriminatorMap($className, $rootClassName)
{
return new self(
"Entity '" . $className . "' has to be part of the discriminator map of '" . $rootClassName . "' " .
"to be properly mapped in the inheritance hierachy. Alternatively you can make '".$className."' an abstract class " .
"to avoid this exception from occuring."
);
}
public static function lifecycleCallbackMethodNotFound($className, $methodName)
{
return new self("Entity '" . $className . "' has no method '" . $methodName . "' to be registered as lifecycle callback.");
}
public static function invalidFetchMode($className, $annotation)
{
return new self("Entity '" . $className . "' has a mapping with invalid fetch mode '" . $annotation . "'");
}
public static function compositeKeyAssignedIdGeneratorRequired($className)
{
return new self("Entity '". $className . "' has a composite identifier but uses an ID generator other than manually assigning (Identity, Sequence). This is not supported.");
}
public static function invalidTargetEntityClass($targetEntity, $sourceEntity, $associationName)
{
return new self("The target-entity " . $targetEntity . " cannot be found in '" . $sourceEntity."#".$associationName."'.");
}
public static function invalidCascadeOption(array $cascades, $className, $propertyName)
{
$cascades = implode(", ", array_map(function ($e) { return "'" . $e . "'"; }, $cascades));
return new self(sprintf(
"You have specified invalid cascade options for %s::$%s: %s; available options: 'remove', 'persist', 'refresh', 'merge', and 'detach'",
$className,
$propertyName,
$cascades
));
}
}

View File

@@ -0,0 +1,40 @@
<?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\ORM\Mapping;
/**
* Is used to specify an array of native SQL named queries.
* The NamedNativeQueries annotation can be applied to an entity or mapped superclass.
*
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
* @since 2.3
*
* @Annotation
* @Target("CLASS")
*/
final class NamedNativeQueries implements Annotation
{
/**
* One or more NamedNativeQuery annotations.
*
* @var array<\Doctrine\ORM\Mapping\NamedNativeQuery>
*/
public $value = array();
}

View File

@@ -0,0 +1,63 @@
<?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\ORM\Mapping;
/**
* Is used to specify a native SQL named query.
* The NamedNativeQuery annotation can be applied to an entity or mapped superclass.
*
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
* @since 2.3
*
* @Annotation
* @Target("ANNOTATION")
*/
final class NamedNativeQuery implements Annotation
{
/**
* The name used to refer to the query with the EntityManager methods that create query objects.
*
* @var string
*/
public $name;
/**
* The SQL query string.
*
* @var string
*/
public $query;
/**
* The class of the result.
*
* @var string
*/
public $resultClass;
/**
* The name of a SqlResultSetMapping, as defined in metadata.
*
* @var string
*/
public $resultSetMapping;
}

View File

@@ -0,0 +1,30 @@
<?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\ORM\Mapping;
/**
* @Annotation
* @Target("CLASS")
*/
final class NamedQueries implements Annotation
{
/** @var array<\Doctrine\ORM\Mapping\NamedQuery> */
public $value;
}

View File

@@ -0,0 +1,32 @@
<?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\ORM\Mapping;
/**
* @Annotation
* @Target("ANNOTATION")
*/
final class NamedQuery implements Annotation
{
/** @var string */
public $name;
/** @var string */
public $query;
}

View File

@@ -0,0 +1,82 @@
<?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\ORM\Mapping;
/**
* A set of rules for determining the physical column and table names
*
*
* @link www.doctrine-project.org
* @since 2.3
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
*/
interface NamingStrategy
{
/**
* Return a table name for an entity class
*
* @param string $className The fully-qualified class name
* @return string A table name
*/
function classToTableName($className);
/**
* Return a column name for a property
*
* @param string $propertyName A property
* @return string A column name
*/
function propertyToColumnName($propertyName);
/**
* Return the default reference column name
*
* @return string A column name
*/
function referenceColumnName();
/**
* Return a join column name for a property
*
* @param string $propertyName A property
* @return string A join column name
*/
function joinColumnName($propertyName);
/**
* Return a join table name
*
* @param string $sourceEntity The source entity
* @param string $targetEntity The target entity
* @param string $propertyName A property
* @return string A join table name
*/
function joinTableName($sourceEntity, $targetEntity, $propertyName = null);
/**
* Return the foreign key column name for the given parameters
*
* @param string $entityName A entity
* @param string $referencedColumnName A property
* @return string A join column name
*/
function joinKeyColumnName($entityName, $referencedColumnName = null);
}

View File

@@ -0,0 +1,40 @@
<?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\ORM\Mapping;
/**
* @Annotation
* @Target("PROPERTY")
*/
final class OneToMany implements Annotation
{
/** @var string */
public $mappedBy;
/** @var string */
public $targetEntity;
/** @var array<string> */
public $cascade;
/** @var string */
public $fetch = 'LAZY';
/** @var boolean */
public $orphanRemoval = false;
/** @var string */
public $indexBy;
}

View File

@@ -0,0 +1,40 @@
<?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\ORM\Mapping;
/**
* @Annotation
* @Target("PROPERTY")
*/
final class OneToOne implements Annotation
{
/** @var string */
public $targetEntity;
/** @var string */
public $mappedBy;
/** @var string */
public $inversedBy;
/** @var array<string> */
public $cascade;
/** @var string */
public $fetch = 'LAZY';
/** @var boolean */
public $orphanRemoval = false;
}

Some files were not shown because too many files have changed in this diff Show More