Compare commits

..

883 Commits
2.2.3 ... 2.3.5

Author SHA1 Message Date
Benjamin Eberlei
2c31ec4809 Release 2.3.5 2014-02-08 17:28:24 +01:00
Benjamin Eberlei
47daa48e1f Update UPGRADE.md notes with BC mention. 2014-02-08 15:41:54 +01:00
Benjamin Eberlei
1a30e0a2e0 Merge branch 'DDC-2715' into 2.3 2013-10-29 09:25:52 +01:00
jan brunnert
550f25f0c0 Removed unnecessary is_object() check 2013-10-29 09:25:30 +01:00
jan brunnert
4863e996db When the OptimisticLockingException is generated with the static function lockFailedVersionMismatch and the passed parameters are DateTime instances, the exception could not be thrown because the DateTime object is not implicitly converted to a string. 2013-10-29 09:25:30 +01:00
Benjamin Eberlei
08e6363684 Merge branch 'DDC-2759' into 2.3 2013-10-26 11:18:16 +02:00
Benjamin Eberlei
4fdd1b9c2b [DDC-2759] Fix regression in ArrayHydrator introduced in DDC-1884 at SHA c7b4c9bf0f 2013-10-26 11:17:51 +02:00
Chris Collins
11f4c90d07 Added a failing test case for DDC-2759. 2013-10-26 11:17:50 +02:00
Benjamin Eberlei
66d8b43f69 Merge branch 'DDC-2608' into 2.3 2013-09-08 16:03:26 +02:00
Benjamin Eberlei
5ded61466b Fix merge conflict leftover 2013-09-08 16:03:15 +02:00
Benjamin Eberlei
8d3617a773 [DDC-2608][DDC-2662] Fix SequenceGenerator requiring "sequenceName" and now throw exception. Fix a bug in quoting the sequenceName. 2013-09-08 16:02:29 +02:00
Benjamin Eberlei
71d5f85ce0 Merge branch 'DDC-2660' into 2.3 2013-09-08 14:41:38 +02:00
Benjamin Eberlei
0e3abb4d79 [DDC-2660] Fix error with NativeSQL, ResultSetMappingBuilder and Associations as Primary Key. 2013-09-08 14:41:16 +02:00
Benjamin Eberlei
b1ba11c06f Merge branch 'DDC-2506' into 2.3 2013-08-20 10:02:51 +02:00
Guilherme Blanco
d349e37ce9 Fixed DDC-2506 by manually updating code. Closes PR #708. 2013-08-20 10:02:32 +02:00
Benjamin Eberlei
fd178d0e0d Merge branch 'DDC-2607' into 2.3 2013-08-20 09:53:46 +02:00
Benjamin Eberlei
6f1b8259d8 Fix variable name 2013-08-20 09:53:37 +02:00
Dustin Thomson
9e54ddca31 Modified executeInserts method in JoinedSubclassPersister to only check for the presence of columns in a composite primary key 2013-08-20 09:52:50 +02:00
Benjamin Eberlei
465bf0f411 Merge branch 'DDC-2579' into 2.3 2013-08-10 18:05:40 +02:00
Fabio B. Silva
794a6bea1b fix DDC-2579 2013-08-10 18:05:28 +02:00
Benjamin Eberlei
e4fdfb0b35 Merge branch 'DDC-2582' into 2.3 2013-08-10 17:50:03 +02:00
Guilherme Blanco
cba05708a9 CS fixes. 2013-08-10 17:49:50 +02:00
Guilherme Blanco
f1f5163394 Fixed DDC-1884. 2013-08-10 17:49:50 +02:00
Benjamin Eberlei
7816025077 Merge branch 'DDC-2548' into 2.3 2013-08-10 17:44:08 +02:00
Michaël Gallego
6fd4e8f470 Allow to have non-distinct queries 2013-08-10 17:43:54 +02:00
Benjamin Eberlei
beed62045f Merge branch 'DDC-2565' into 2.3 2013-08-10 17:28:26 +02:00
Austin Morris
f23656e468 convert PersistentCollection functional tests to unit tests 2013-08-10 17:28:07 +02:00
Austin Morris
76694239fa remove redundant require_once for TestInit.php 2013-08-10 17:28:07 +02:00
Austin Morris
6da540ac10 do not initialize coll on add() 2013-08-10 17:28:06 +02:00
Austin Morris
a0a66431ea Initialize coll when using Collection methods inside PersistentCollection 2013-08-10 17:28:06 +02:00
Austin Morris
8956cfcf2a PersistentCollection - initialize coll - create failing tests 2013-08-10 17:28:06 +02:00
Benjamin Eberlei
063280b0bd Merge branch 'DDC-2587' into 2.3 2013-08-10 16:25:54 +02:00
J. Bruni
9e67efa37b Updated EntityGeneratorTest::testEntityTypeAlias 2013-08-10 16:25:35 +02:00
J. Bruni
00f62dd6c3 Updated EntityGeneratorTest::testEntityTypeAlias 2013-08-10 16:25:35 +02:00
J Bruni
b880452ab1 Corrected PHP type for "decimal" mapping type
"Basic Mapping" documentation says:
"decimal: Type that maps a SQL DECIMAL to a PHP string."
2013-08-10 16:25:35 +02:00
Benjamin Eberlei
de59307b8e Merge branch 'DDC-2517' into 2.3 2013-06-30 10:43:27 +02:00
shulcsm
6c74d8ad33 Clear visitedCollections
Visited collections are cleared only in commit(). Commit clears up only if it actually has something to do. Processing large amounts of records without changing them cause visitedCollections to grow without any way of clearing.
2013-06-30 10:43:08 +02:00
Benjamin Eberlei
0633aa54c8 Merge branch 'DDC-2530' into 2.3 2013-06-25 19:36:05 +02:00
Benjamin Eberlei
db0c1fad78 [DDC-2350] Eager Collections are not marked as initialized, leading to multiple queries being executed. 2013-06-25 19:35:48 +02:00
Benjamin Eberlei
9787b27518 Merge branch 'DDC-2471' into 2.3 2013-05-26 09:27:03 +02:00
Alexander
4f83e7e6c4 [DDC-2471] Fix EQ/NEQ null handling of criteria 2013-05-26 09:26:52 +02:00
Benjamin Eberlei
425f375899 Bump dev version to 2.3.5 2013-05-11 09:51:12 +02:00
Benjamin Eberlei
a41b02c080 Release 2.3.4 2013-05-11 09:51:12 +02:00
Benjamin Eberlei
8b3c206bc1 Bump dependency to 2.3.4 2013-05-11 09:47:19 +02:00
Benjamin Eberlei
e0feccc2e4 Merge branch 'DDC-2280' into 2.3 2013-05-09 18:17:03 +02:00
Benjamin Eberlei
818d3d27fe [DDC-2280] length attribute in <id> was not converted. 2013-05-09 18:16:55 +02:00
Benjamin Eberlei
98d3847a11 Merge branch 'DDC-2387' into 2.3 2013-05-09 12:11:23 +02:00
Benjamin Eberlei
63918f214b [DDC-2387] Fix DatabaseDriver not working with combinations of composite/association keys. 2013-05-09 12:11:04 +02:00
Benjamin Eberlei
acf21246c7 Merge branch 'DDC-2437' into 2.3 2013-05-09 11:04:14 +02:00
Vladislav Vlastovskiy
795e4a4b6b Added test complex inner join with indexBy 2013-05-09 11:03:36 +02:00
Vladislav Vlastovskiy
946a22f2c7 Swapped places indexBy and condition in accordance with EBNF 2013-05-09 11:03:36 +02:00
Benjamin Eberlei
bdd7482b3f Merge branch 'DDC-2423' into 2.3 2013-05-09 10:56:00 +02:00
Benjamin Eberlei
8e31107f86 [DDC-2423] Fixed bug with EntityGenerator not generating fetch="" attribute in association annotations. 2013-05-09 10:55:42 +02:00
Benjamin Eberlei
209090d338 Merge branch 'DDC-2267' into 2.3 2013-05-04 13:39:37 +02:00
Benjamin Eberlei
27117bbc98 [DDC-2267] Allow EntityManager#flush($entity) to be called on entities scheduled for removal. 2013-05-04 13:39:23 +02:00
Benjamin Eberlei
0f2be50d8f [DDC-2426] Missing length attribute in doctrine-mapping.xsd for <id> tag. 2013-05-04 12:59:02 +02:00
Benjamin Eberlei
193e74af05 Merge branch 'DDC-1984' into 2.3 2013-05-01 19:40:06 +02:00
Benjamin Eberlei
bb6e4f2074 [DDC-1984] Throw exception if passing null into UnitOfWork#lock() - which can happen when EntityManager#find() tries to lock entity that was just deleted by another process. 2013-05-01 19:39:48 +02:00
Benjamin Eberlei
6063fe4adf Merge branch 'DDC-2409' into 2.3 2013-05-01 11:01:17 +02:00
Benjamin Eberlei
846c6d2c5e Simplify condition of previous commit (5cdc73e) 2013-05-01 11:00:55 +02:00
Fabio B. Silva
1f257622a1 Fix DDC-2409 2013-05-01 11:00:55 +02:00
Benjamin Eberlei
84257c9454 Merge branch 'DBAL-483' into 2.3 2013-05-01 10:45:19 +02:00
Benjamin Eberlei
eedacc9822 [DBAL-483] Add sqlite check again as ALTER TABLE is only supported as of 2.4 2013-05-01 10:44:31 +02:00
Benjamin Eberlei
3d9099e33b [DBAL-483] Pass default values to DBAL mapping layer correctly to fix default comparision bug. 2013-05-01 10:42:53 +02:00
EuKov
ad7b5871bf Fixed typo in SQLFilter (use statement ClassMetadata) 2013-04-23 22:26:59 +02:00
Benjamin Eberlei
803f2740c9 [DDC-2346] Reapply changes lost in rebase onto 2.3 2013-04-14 09:52:39 +02:00
Stefan Kleff
ed3f375ef3 Added constant 2013-04-14 09:49:26 +02:00
Stefan Kleff
a188c88ef2 Added test based on e468ced00b 2013-04-14 09:48:09 +02:00
Benjamin Eberlei
86e40a692b Merge branch 'DDC-2252' into 2.3 2013-04-06 19:56:15 +02:00
Fabio B. Silva
36b79309bd Fix DDC-2252 2013-04-06 19:55:50 +02:00
Benjamin Eberlei
66b6b7169e Merge branch 'DDC-2224-2' into 2.3 2013-04-04 20:35:01 +02:00
Benjamin Eberlei
7c7a8abe40 [DDC-2224] Adjust ClassMetadata processing 2013-04-04 20:34:49 +02:00
Benjamin Eberlei
e5c68ab45c [DDC-2224] Rewrite instanceof feature with parameter needle ClassMetadata breaks caching of queries. 2013-04-04 20:32:04 +02:00
Benjamin Eberlei
868bb68cc8 Bump dev version to 2.3.4 2013-03-24 21:43:58 +01:00
Benjamin Eberlei
b3788c14ee Release 2.3.3 2013-03-24 21:43:58 +01:00
Benjamin Eberlei
3148d8aeac Bump Dbal Dependency to 2.3.3 2013-03-24 20:21:32 +01:00
Benjamin Eberlei
ae1f903080 Merge branch 'DDC-2090' into 2.3 2013-03-17 21:49:24 +01:00
Fabio B. Silva
07482bd624 Fix DDC-2090 2013-03-17 21:48:55 +01:00
Benjamin Eberlei
8d78b90bca Merge branch 'DDC-1666' into 2.3 2013-03-14 23:42:28 +01:00
Benjamin Eberlei
ca93400493 [DDC-1666] Fix bug where orphan removal on one-to-one associations lead to unique constraint errors when replacing an entity with a new one. 2013-03-14 23:42:04 +01:00
Benjamin Eberlei
7152e5f72f Merge branch 'DDC-2300' into 2.3 2013-03-14 23:22:01 +01:00
Benjamin Eberlei
279fcb6c81 [DDC-2300] Fix version xml mapping and serialization of ClassMetadata. 2013-03-14 23:20:46 +01:00
Benjamin Eberlei
7705105c5d Merge branch 'GH-593' into 2.3 2013-03-14 22:59:42 +01:00
Norbert Orzechowicz
cb70a8a8c4 Fix SimpleObjectHydrator behavior when column not exists in fieldMappings, relationMappings and metaMappings 2013-03-14 22:59:20 +01:00
Benjamin Eberlei
8a2d7374b1 Fix bugs in tests 2013-03-14 20:08:37 +01:00
Benjamin Eberlei
563fdb953b Merge branch 'DDC-2340' into 2.3 2013-03-12 22:53:10 +01:00
Benjamin Eberlei
3daf824c9e [DDC-2340] Fix bug with dirty collection matching + ordering. 2013-03-12 22:52:52 +01:00
Jean-Guilhem Rouel
aa4664687f Don't add empty expression to another one 2013-03-12 19:18:07 +01:00
Benjamin Eberlei
550c1cf98c Merge branch 'GH-572' into 2.3 2013-03-12 19:06:02 +01:00
Norbert Orzechowicz
33799d094c [DDC-2282] Fix pagination problem with SQL Server.
ORDER BY removed from all count queries when on SQL Server
Fixed SQLServer ORDER BY problem in paginator CountOutputWalker
Added test to check query with ORDER BY and SQLServerPlatform
2013-03-12 19:05:28 +01:00
Benjamin Eberlei
304acf0a1a Merge branch 'DDC-2310' into 2.3 2013-02-21 19:03:42 +01:00
Benjamin Eberlei
84996e0601 [DDC-2310] Fix regression introduced in SQL Server lock handling. 2013-02-21 19:03:12 +01:00
Benjamin Eberlei
fdd0af34e6 Merge branch 'DDC-2243' into 2.3 2013-01-20 20:35:21 +01:00
Benjamin Eberlei
f0312edb94 [DDC-2243] Fix bug where a bigint identifier would be casted to an integer, causing inconsistency with the string handling. 2013-01-20 20:34:09 +01:00
Benjamin Eberlei
6d25c4e08a Merge remote-tracking branch 'origin/2.3' into 2.3 2013-01-20 20:12:44 +01:00
Benjamin Eberlei
d9f51eb2fa Merge branch 'DDC-2246' into 2.3 2013-01-20 20:12:35 +01:00
Benjamin Eberlei
88cebe1263 [DDC-2246] Fix bug with UnitOfWork#getEntityState() and entities with foreign identifier. 2013-01-20 20:11:40 +01:00
Benjamin Eberlei
6829c464e8 Merge branch 'DDC-2231' into 2.3 2013-01-12 10:32:44 +01:00
Benjamin Eberlei
fc2eebdf75 DDC-2231 - Simplify test 2013-01-12 10:32:24 +01:00
Stefan Kleff
54193e7f82 Added test 2013-01-12 10:32:24 +01:00
Stefan Kleff
8001cad573 fixed indentation
Restored old way of injection to just inject it during a refresh
Added injection for initialized proxies
2013-01-12 10:32:24 +01:00
Stefan Kleff
c4c70d667a The EntityManager was not injected in uninitialized proxys which are ObjectManagerAware.
I ran into that problem while I had two objects in the identitymap while hydrating a collection: one was new a "real" entity and the other one was an uninitialized proxy. For "real" entities the em is injected in line 2427, for new entities it is injected in 2436->2364, but for proxies this is missing. According to the comment "inject ObjectManager into just loaded proxies." the code in line 2427 should do this, but in fact it is just used if it is a "real" entity or an already initialized proxy. Moving the injection to outside of the condition in line 2411 (if the entity is an unitialized proxy) solves this.
2013-01-12 10:32:24 +01:00
Benjamin Eberlei
f5bb8be884 Bump dev version to 2.3.3 2013-01-07 21:05:04 +01:00
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
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
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
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
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
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
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
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
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
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
Benjamin Eberlei
06de4e62a5 Add 2.2 to travis status icon list 2011-12-22 00:08:53 +01:00
Vitali Yakavenka
4879c50c5d Merge remote-tracking branch 'doctrine/master' into SupportCustomIdGenerators 2011-12-19 16:47:47 -08:00
comfortablynumb
bf9024b622 Merge remote branch 'upstream/master' 2011-12-19 11:09:09 -03:00
comfortablynumb
d7042ab828 Merge branch 'master', remote branch 'upstream/master' 2011-12-16 20:01:10 -03:00
Asmir Mustafic
289c186de5 orphanRemoval default is false 2011-12-16 16:16:52 +01: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
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
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
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
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
473 changed files with 19635 additions and 5952 deletions

2
.gitignore vendored
View File

@@ -8,4 +8,4 @@ lib/Doctrine/Common
lib/Doctrine/DBAL
/.settings/
.buildpath
.project
.project

2
.gitmodules vendored
View File

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

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,7 +1,8 @@
# Doctrine 2 ORM
Master: [![Build Status](https://secure.travis-ci.org/doctrine/doctrine2.png?branch=master)](http://travis-ci.org/doctrine/doctrine2)
2.1.x: [![Build Status](https://secure.travis-ci.org/doctrine/doctrine2.png?branch=2.1.x)](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
@@ -12,7 +13,7 @@ without requiring unnecessary code duplication.
## 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)

481
UPGRADE.md Normal file
View File

@@ -0,0 +1,481 @@
# Upgrade to 2.3
## Auto Discriminator Map breaks userland implementations with Listener
The new feature to detect discriminator maps automatically when none
are provided breaks userland implementations doing this with a
listener in ``loadClassMetadata`` event.
## 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,25 +0,0 @@
This document details all the possible changes that you should investigate when updating
your project from Doctrine 2.0.x 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.

View File

@@ -1,81 +0,0 @@
# 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.

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;

View File

@@ -19,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>
@@ -92,8 +92,8 @@
<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}" maximum_version="2.2.99" />
<package name="DoctrineDBAL" channel="pear.doctrine-project.org" minimum_version="${dependencies.dbal}" maximum_version="2.2.99" />
<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="Console" channel="pear.symfony.com" minimum_version="2.0.0" />
<package name="Yaml" channel="pear.symfony.com" minimum_version="2.0.0" />
</dependencies>
@@ -104,7 +104,7 @@
<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" type="pear-config" from="@php_bin@" to="php_bin" />

View File

@@ -1,10 +1,10 @@
{
"name": "doctrine/orm",
"type": "library","version":"2.2.3",
"type": "library","version":"2.3.5",
"description": "Object-Relational-Mapper for PHP",
"keywords": ["orm", "database"],
"homepage": "http://www.doctrine-project.org",
"license": "LGPL",
"license": "MIT",
"authors": [
{"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"},
{"name": "Roman Borschel", "email": "roman@code-factory.org"},
@@ -14,10 +14,19 @@
"require": {
"php": ">=5.3.2",
"ext-pdo": "*",
"doctrine/common": "2.2.*",
"doctrine/dbal": "2.2.*"
"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

@@ -84,20 +84,69 @@
</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="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" />
@@ -110,6 +159,23 @@
<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">
@@ -143,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>
@@ -158,12 +226,13 @@
<xs:restriction base="xs:token">
<xs:enumeration value="EAGER"/>
<xs:enumeration value="LAZY"/>
<xs:enumeration value="EXTRALAZY"/>
<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" />
@@ -184,9 +253,10 @@
<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>
@@ -253,12 +323,15 @@
<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" />
<xs:attribute name="column" type="xs:NMTOKEN" />
<xs:attribute name="length" 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>
@@ -272,6 +345,13 @@
<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" />
@@ -406,4 +486,35 @@
<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

@@ -13,21 +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\DBAL\Types\Type,
Doctrine\DBAL\Cache\QueryCacheProfile,
Doctrine\ORM\Query\QueryException,
Doctrine\ORM\Internal\Hydration\CacheHydrator;
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;
use Doctrine\ORM\Mapping;
/**
* 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
* @author Benjamin Eberlei <kontakt@beberlei.de>
@@ -62,14 +65,9 @@ abstract class AbstractQuery
const HYDRATE_SIMPLEOBJECT = 5;
/**
* @var array The parameter map of this query.
* @var \Doctrine\Common\Collections\ArrayCollection The parameter map of this query.
*/
protected $_params = array();
/**
* @var array The parameter type map of this query.
*/
protected $_paramTypes = array();
protected $parameters;
/**
* @var ResultSetMapping The user-specified ResultSetMapping to use.
@@ -114,8 +112,18 @@ abstract class AbstractQuery
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.
*
@@ -135,69 +143,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;
}
/**
* Get all defined parameter types.
*
* @return array The defined query parameter types.
*/
public function getParameterTypes()
{
return $this->_paramTypes;
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)
{
if (isset($this->_params[$key])) {
return $this->_params[$key];
}
$filteredParameters = $this->parameters->filter(
function ($parameter) use ($key)
{
// Must not be identical because of string to integer conversion
return ($key == $parameter->getName());
}
);
return null;
return count($filteredParameters) ? $filteredParameters->first() : null;
}
/**
* Gets a query parameter type.
* Sets a collection of query parameters.
*
* @param mixed $key The key (index or name) of the bound parameter.
* @return mixed The parameter type of the bound parameter.
* @param \Doctrine\Common\Collections\ArrayCollection|array $parameters
*
* @return \Doctrine\ORM\AbstractQuery This query instance.
*/
public function getParameterType($key)
public function setParameters($parameters)
{
if (isset($this->_paramTypes[$key])) {
return $this->_paramTypes[$key];
// 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;
}
return null;
}
$this->parameters = $parameters;
/**
* 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();
return $this;
}
/**
* Sets a query parameter.
@@ -207,19 +213,29 @@ 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.
*/
public function setParameter($key, $value, $type = null)
{
$key = trim($key, ':');
$filteredParameters = $this->parameters->filter(
function ($parameter) use ($key)
{
// Must not be identical because of string to integer conversion
return ($key == $parameter->getName());
}
);
$value = $this->processParameterValue($value);
if ($type === null) {
$type = Query\ParameterTypeInferer::inferType($value);
if (count($filteredParameters)) {
$parameter = $filteredParameters->first();
$parameter->setValue($value, $type);
return $this;
}
$this->_paramTypes[$key] = $type;
$this->_params[$key] = $value;
$parameter = new Query\Parameter($key, $value, $type);
$this->parameters->add($parameter);
return $this;
}
@@ -230,63 +246,54 @@ abstract class AbstractQuery
* @param mixed $value
* @return array
*/
private function processParameterValue($value)
public function processParameterValue($value)
{
switch (true) {
case is_array($value):
for ($i = 0, $l = count($value); $i < $l; $i++) {
$paramValue = $this->processParameterValue($value[$i]);
$value[$i] = is_array($paramValue) ? $paramValue[key($paramValue)] : $paramValue;
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(get_class($value)):
case is_object($value) && $this->_em->getMetadataFactory()->hasMetadataFor(ClassUtils::getClass($value)):
return $this->convertObjectParameterToScalarValue($value);
case ($value instanceof Mapping\ClassMetadata):
return $value->name;
default:
return $value;
}
}
protected function convertObjectParameterToScalarValue($value)
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.");
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."
);
}
if ($this->_em->getUnitOfWork()->getEntityState($value) === UnitOfWork::STATE_MANAGED) {
$values = $this->_em->getUnitOfWork()->getEntityIdentifier($value);
} else {
$values = $class->getIdentifierValues($value);
}
$values = ($this->_em->getUnitOfWork()->getEntityState($value) === UnitOfWork::STATE_MANAGED)
? $this->_em->getUnitOfWork()->getEntityIdentifier($value)
: $class->getIdentifierValues($value);
$value = $values[$class->getSingleIdentifierFieldName()];
if (!$value) {
throw new \InvalidArgumentException("Binding entities to query parameters only allowed for entities that have an identifier.");
if (null === $value) {
throw new \InvalidArgumentException(
"Binding entities to query parameters only allowed for entities that have an identifier."
);
}
return $value;
}
/**
* Sets a collection of query parameters.
*
* @param array $params
* @param array $types
* @return \Doctrine\ORM\AbstractQuery This query instance.
*/
public function setParameters(array $params, array $types = array())
{
foreach ($params as $key => $value) {
$this->setParameter($key, $value, isset($types[$key]) ? $types[$key] : null);
}
return $this;
}
/**
* Sets the ResultSetMapping that should be used for hydration.
*
@@ -526,37 +533,37 @@ 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);
}
/**
@@ -568,7 +575,7 @@ abstract class AbstractQuery
*/
public function getOneOrNullResult($hydrationMode = null)
{
$result = $this->execute(array(), $hydrationMode);
$result = $this->execute(null, $hydrationMode);
if ($this->_hydrationMode !== self::HYDRATE_SINGLE_SCALAR && ! $result) {
return null;
@@ -600,7 +607,7 @@ 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;
@@ -655,6 +662,18 @@ abstract class AbstractQuery
return isset($this->_hints[$name]) ? $this->_hints[$name] : false;
}
/**
* Check if the query has a hint
*
* @param string $name The name of the hint
*
* @return bool False if the query does not have any hint
*/
public function hasHint($name)
{
return isset($this->_hints[$name]);
}
/**
* Return the key value map of query hints that are currently set.
*
@@ -669,18 +688,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 \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();
@@ -693,18 +712,18 @@ 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);
}
$setCacheEntry = function() {};
@@ -726,6 +745,7 @@ abstract class AbstractQuery
$setCacheEntry = function($data) use ($cache, $result, $cacheKey, $realCacheKey, $queryCacheProfile) {
$result[$realCacheKey] = $data;
$cache->save($cacheKey, $result, $queryCacheProfile->getLifetime());
};
}
@@ -756,24 +776,25 @@ abstract class AbstractQuery
*/
protected function getHydrationCacheId()
{
$params = $this->getParameters();
$parameters = array();
foreach ($params AS $key => $value) {
$params[$key] = $this->processParameterValue($value);
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, $params, $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 explicitely set by the developer then a hash is automatically
* If this is not explicitly set by the developer then a hash is automatically
* generated for you.
*
* @param string $id
@@ -813,8 +834,8 @@ abstract class AbstractQuery
*/
public function __clone()
{
$this->_params = array();
$this->_paramTypes = array();
$this->parameters = new ArrayCollection();
$this->_hints = array();
}
}

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,8 +23,14 @@ use Doctrine\Common\Cache\Cache,
Doctrine\Common\Cache\ArrayCache,
Doctrine\Common\Annotations\AnnotationRegistry,
Doctrine\Common\Annotations\AnnotationReader,
Doctrine\ORM\Mapping\Driver\Driver,
Doctrine\ORM\Mapping\Driver\AnnotationDriver;
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.
@@ -56,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;
}
/**
@@ -68,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;
}
/**
@@ -90,8 +98,9 @@ class Configuration extends \Doctrine\DBAL\Configuration
*/
public function getProxyNamespace()
{
return isset($this->_attributes['proxyNamespace']) ?
$this->_attributes['proxyNamespace'] : null;
return isset($this->_attributes['proxyNamespace'])
? $this->_attributes['proxyNamespace']
: null;
}
/**
@@ -107,46 +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)
{
if (version_compare(\Doctrine\Common\Version::VERSION, '2.2.0-DEV', '>=')) {
// Register the ORM Annotations in the AnnotationRegistry
AnnotationRegistry::registerFile(__DIR__ . '/Mapping/Driver/DoctrineAnnotations.php');
AnnotationRegistry::registerFile(__DIR__ . '/Mapping/Driver/DoctrineAnnotations.php');
$reader = new \Doctrine\Common\Annotations\SimpleAnnotationReader();
if ($useSimpleAnnotationReader) {
// Register the ORM Annotations in the AnnotationRegistry
$reader = new SimpleAnnotationReader();
$reader->addNamespace('Doctrine\ORM\Mapping');
$reader = new \Doctrine\Common\Annotations\CachedReader($reader, new ArrayCache());
} else if (version_compare(\Doctrine\Common\Version::VERSION, '2.1.0-DEV', '>=')) {
// Register the ORM Annotations in the AnnotationRegistry
AnnotationRegistry::registerFile(__DIR__ . '/Mapping/Driver/DoctrineAnnotations.php');
$cachedReader = new CachedReader($reader, new ArrayCache());
$reader = new AnnotationReader();
$reader->setDefaultAnnotationNamespace('Doctrine\ORM\Mapping\\');
$reader->setIgnoreNotImportedAnnotations(true);
$reader->setEnableParsePhpImports(false);
$reader = new \Doctrine\Common\Annotations\CachedReader(
new \Doctrine\Common\Annotations\IndexedReader($reader), new ArrayCache()
);
} else {
$reader = new AnnotationReader();
$reader->setDefaultAnnotationNamespace('Doctrine\ORM\Mapping\\');
return new AnnotationDriver($cachedReader, (array) $paths);
}
return new AnnotationDriver($reader, (array)$paths);
return new AnnotationDriver(
new CachedReader(new AnnotationReader(), new ArrayCache()),
(array) $paths
);
}
/**
@@ -164,8 +167,8 @@ class Configuration extends \Doctrine\DBAL\Configuration
* Resolves a registered namespace alias to the full namespace.
*
* @param string $entityNamespaceAlias
* @throws ORMException
* @return string
* @throws MappingException
*/
public function getEntityNamespace($entityNamespaceAlias)
{
@@ -179,8 +182,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
/**
* Set the entity alias map
*
* @param array $entityAliasMap
* @return void
* @param array $entityNamespaces
*/
public function setEntityNamespaces(array $entityNamespaces)
{
@@ -201,12 +203,13 @@ class Configuration extends \Doctrine\DBAL\Configuration
* 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;
return isset($this->_attributes['metadataDriverImpl'])
? $this->_attributes['metadataDriverImpl']
: null;
}
/**
@@ -216,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;
}
/**
@@ -259,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;
}
/**
@@ -288,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)
@@ -295,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)
{
@@ -313,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];
}
@@ -334,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();
}
@@ -354,9 +365,14 @@ 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;
}
@@ -369,8 +385,10 @@ class Configuration extends \Doctrine\DBAL\Configuration
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;
}
/**
@@ -385,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);
}
}
/**
@@ -397,9 +417,14 @@ 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;
}
@@ -412,8 +437,10 @@ class Configuration extends \Doctrine\DBAL\Configuration
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;
}
/**
@@ -428,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);
}
}
/**
@@ -440,9 +469,14 @@ 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;
}
@@ -455,8 +489,10 @@ class Configuration extends \Doctrine\DBAL\Configuration
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;
}
/**
@@ -471,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);
}
}
/**
@@ -482,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;
}
/**
@@ -500,7 +553,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
/**
* Set a class metadata factory.
*
* @param string $cmf
* @param string $cmfName
*/
public function setClassMetadataFactoryName($cmfName)
{
@@ -512,9 +565,10 @@ 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'];
}
@@ -539,8 +593,9 @@ class Configuration extends \Doctrine\DBAL\Configuration
*/
public function getFilterClassName($name)
{
return isset($this->_attributes['filters'][$name]) ?
$this->_attributes['filters'][$name] : null;
return isset($this->_attributes['filters'][$name])
? $this->_attributes['filters'][$name]
: null;
}
/**
@@ -548,14 +603,16 @@ class Configuration extends \Doctrine\DBAL\Configuration
*
* @since 2.2
* @param string $className
* @throws ORMException If not is a \Doctrine\ORM\EntityRepository
* @throws ORMException If not is a \Doctrine\Common\Persistence\ObjectRepository
*/
public function setDefaultRepositoryClassName($className)
{
if ($className != "Doctrine\ORM\EntityRepository" &&
!is_subclass_of($className, 'Doctrine\ORM\EntityRepository')){
$reflectionClass = new \ReflectionClass($className);
if ( ! $reflectionClass->implementsInterface('Doctrine\Common\Persistence\ObjectRepository')) {
throw ORMException::invalidEntityRepository($className);
}
$this->_attributes['defaultRepositoryClassName'] = $className;
}
@@ -567,7 +624,60 @@ class Configuration extends \Doctrine\DBAL\Configuration
*/
public function getDefaultRepositoryClassName()
{
return isset($this->_attributes['defaultRepositoryClassName']) ?
$this->_attributes['defaultRepositoryClassName'] : 'Doctrine\ORM\EntityRepository';
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,13 +13,13 @@
* 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,
@@ -128,16 +128,17 @@ class EntityManager implements ObjectManager
*/
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->unitOfWork = new UnitOfWork($this);
$this->proxyFactory = new ProxyFactory(
$this,
$config->getProxyDir(),
@@ -191,8 +192,6 @@ class EntityManager implements ObjectManager
/**
* Starts a transaction on the underlying database connection.
*
* @deprecated Use {@link getConnection}.beginTransaction().
*/
public function beginTransaction()
{
@@ -209,15 +208,19 @@ class EntityManager implements ObjectManager
* 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 {
$return = $func($this);
$return = call_user_func($func, $this);
$this->flush();
$this->conn->commit();
@@ -233,8 +236,6 @@ class EntityManager implements ObjectManager
/**
* Commits a transaction on the underlying database connection.
*
* @deprecated Use {@link getConnection}.commit().
*/
public function commit()
{
@@ -243,8 +244,6 @@ class EntityManager implements ObjectManager
/**
* Performs a rollback on the underlying database connection.
*
* @deprecated Use {@link getConnection}.rollback().
*/
public function rollback()
{
@@ -272,7 +271,7 @@ class EntityManager implements ObjectManager
/**
* Creates a new Query object.
*
* @param string The DQL string.
* @param string $dql The DQL string.
* @return \Doctrine\ORM\Query
*/
public function createQuery($dql = "")
@@ -307,6 +306,7 @@ class EntityManager implements ObjectManager
public function createNativeQuery($sql, ResultSetMapping $rsm)
{
$query = new NativeQuery($this);
$query->setSql($sql);
$query->setResultSetMapping($rsm);
@@ -354,21 +354,82 @@ class EntityManager implements ObjectManager
$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);
}
}
/**
@@ -382,19 +443,23 @@ class EntityManager implements ObjectManager
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])) {
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($sortedId, $class->rootEntityName)) {
if (($entity = $this->unitOfWork->tryGetById($sortedId, $class->rootEntityName)) !== false) {
return ($entity instanceof $class->name) ? $entity : null;
}
@@ -407,6 +472,7 @@ class EntityManager implements ObjectManager
}
$entity = $this->proxyFactory->getProxy($class->name, $sortedId);
$this->unitOfWork->registerManaged($entity, $sortedId, array());
return $entity;
@@ -436,7 +502,7 @@ class EntityManager implements ObjectManager
$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;
}
@@ -445,7 +511,9 @@ class EntityManager implements ObjectManager
}
$entity = $class->newInstance();
$class->setIdentifierValues($entity, $identifier);
$this->unitOfWork->registerManaged($entity, $identifier, array());
$this->unitOfWork->markReadOnly($entity);
@@ -471,6 +539,7 @@ class EntityManager implements ObjectManager
public function close()
{
$this->clear();
$this->closed = true;
}
@@ -488,7 +557,7 @@ class EntityManager implements ObjectManager
public function persist($entity)
{
if ( ! is_object($entity)) {
throw new \InvalidArgumentException(gettype($entity));
throw ORMInvalidArgumentException::invalidObject('EntityManager#persist()' , $entity);
}
$this->errorIfClosed();
@@ -507,7 +576,7 @@ class EntityManager implements ObjectManager
public function remove($entity)
{
if ( ! is_object($entity)) {
throw new \InvalidArgumentException(gettype($entity));
throw ORMInvalidArgumentException::invalidObject('EntityManager#remove()' , $entity);
}
$this->errorIfClosed();
@@ -524,7 +593,7 @@ class EntityManager implements ObjectManager
public function refresh($entity)
{
if ( ! is_object($entity)) {
throw new \InvalidArgumentException(gettype($entity));
throw ORMInvalidArgumentException::invalidObject('EntityManager#refresh()' , $entity);
}
$this->errorIfClosed();
@@ -544,7 +613,7 @@ class EntityManager implements ObjectManager
public function detach($entity)
{
if ( ! is_object($entity)) {
throw new \InvalidArgumentException(gettype($entity));
throw ORMInvalidArgumentException::invalidObject('EntityManager#detach()' , $entity);
}
$this->unitOfWork->detach($entity);
@@ -561,7 +630,7 @@ class EntityManager implements ObjectManager
public function merge($entity)
{
if ( ! is_object($entity)) {
throw new \InvalidArgumentException(gettype($entity));
throw ORMInvalidArgumentException::invalidObject('EntityManager#merge()' , $entity);
}
$this->errorIfClosed();
@@ -732,7 +801,7 @@ class EntityManager implements ObjectManager
return new Internal\Hydration\SimpleObjectHydrator($this);
default:
if ($class = $this->config->getCustomHydrationMode($hydrationMode)) {
if (($class = $this->config->getCustomHydrationMode($hydrationMode)) !== null) {
return new $class($this);
}
}
@@ -818,8 +887,7 @@ class EntityManager implements ObjectManager
*/
public function isFiltersStateClean()
{
return null === $this->filterCollection
|| $this->filterCollection->isClean();
return null === $this->filterCollection || $this->filterCollection->isClean();
}
/**

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,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,6 +22,11 @@ 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
* business specific methods for retrieving entities.
@@ -35,7 +40,7 @@ use Doctrine\Common\Persistence\ObjectRepository;
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class EntityRepository implements ObjectRepository
class EntityRepository implements ObjectRepository, Selectable
{
/**
* @var string
@@ -61,8 +66,8 @@ class EntityRepository implements ObjectRepository
public function __construct($em, Mapping\ClassMetadata $class)
{
$this->_entityName = $class->name;
$this->_em = $em;
$this->_class = $class;
$this->_em = $em;
$this->_class = $class;
}
/**
@@ -89,6 +94,21 @@ class EntityRepository implements ObjectRepository
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.
*/
@@ -100,66 +120,15 @@ class EntityRepository implements ObjectRepository
/**
* 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)
{
if ( ! is_array($id)) {
$id = array($this->_class->identifier[0] => $id);
}
$sortedId = array();
foreach ($this->_class->identifier as $identifier) {
if (!isset($id[$identifier])) {
throw ORMException::missingIdentifierField($this->_class->name, $identifier);
}
$sortedId[$identifier] = $id[$identifier];
}
// Check identity map first
if ($entity = $this->_em->getUnitOfWork()->tryGetById($sortedId, $this->_class->rootEntityName)) {
if ( ! ($entity instanceof $this->_class->name)) {
return null;
}
switch ($lockMode) {
case LockMode::OPTIMISTIC:
$this->_em->lock($entity, $lockMode, $lockVersion);
break;
case LockMode::PESSIMISTIC_READ:
case LockMode::PESSIMISTIC_WRITE:
$persister = $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName);
$persister->refresh($sortedId, $entity, $lockMode);
break;
}
return $entity; // Hit!
}
switch ($lockMode) {
case LockMode::NONE:
return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->load($sortedId);
case LockMode::OPTIMISTIC:
if ( ! $this->_class->isVersioned) {
throw OptimisticLockException::notVersioned($this->_entityName);
}
$entity = $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->load($sortedId);
$this->_em->getUnitOfWork()->lock($entity, $lockMode, $lockVersion);
return $entity;
default:
if ( ! $this->_em->getConnection()->isTransactionActive()) {
throw TransactionRequiredException::transactionRequired();
}
return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->load($sortedId, null, null, array(), $lockMode);
}
return $this->_em->find($this->_entityName, $id, $lockMode, $lockVersion);
}
/**
@@ -183,18 +152,23 @@ class EntityRepository implements ObjectRepository
*/
public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
{
return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->loadAll($criteria, $orderBy, $limit, $offset);
$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, null, null, array(), 0, 1);
$persister = $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName);
return $persister->load($criteria, null, null, array(), 0, 1, $orderBy);
}
/**
@@ -208,13 +182,13 @@ class EntityRepository implements ObjectRepository
public function __call($method, $arguments)
{
switch (true) {
case (substr($method, 0, 6) == 'findBy'):
$by = substr($method, 6, strlen($method));
case (0 === strpos($method, 'findBy')):
$by = substr($method, 6);
$method = 'findBy';
break;
case (substr($method, 0, 9) == 'findOneBy'):
$by = substr($method, 9, strlen($method));
case (0 === strpos($method, 'findOneBy')):
$by = substr($method, 9);
$method = 'findOneBy';
break;
@@ -232,7 +206,22 @@ class EntityRepository implements ObjectRepository
$fieldName = lcfirst(\Doctrine\Common\Util\Inflector::classify($by));
if ($this->_class->hasField($fieldName) || $this->_class->hasAssociation($fieldName)) {
return $this->$method(array($fieldName => $arguments[0]));
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);
@@ -269,4 +258,20 @@ class EntityRepository implements ObjectRepository
{
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,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>.
*/
@@ -56,7 +56,7 @@ class LifecycleEventArgs extends EventArgs
}
/**
* Retireve associated Entity.
* Retrieve associated Entity.
*
* @return object
*/
@@ -74,4 +74,4 @@ class LifecycleEventArgs extends EventArgs
{
return $this->em;
}
}
}

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>.
*/

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>.
*/
@@ -81,4 +81,4 @@ class OnClearEventArgs extends \Doctrine\Common\EventArgs
{
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,9 +13,9 @@
* 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;
@@ -83,4 +81,4 @@ class OnFlushEventArgs extends \Doctrine\Common\EventArgs
return $this->_entitiesToPersist;
}
*/
}
}

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,10 +13,9 @@
* 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;
@@ -58,4 +55,4 @@ class PostFlushEventArgs extends EventArgs
{
return $this->em;
}
}
}

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,9 +13,9 @@
* 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;
@@ -27,7 +25,6 @@ namespace Doctrine\ORM\Event;
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.com
* @since 2.0
* @version $Revision$
* @author Roman Borschel <roman@code-factory.de>
* @author Benjamin Eberlei <kontakt@beberlei.de>
*/

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>.
*/
@@ -81,7 +79,7 @@ class PreUpdateEventArgs extends LifecycleEventArgs
*/
public function getOldValue($field)
{
$this->assertValidField($field);
$this->assertValidField($field);
return $this->entityChangeSet[$field][0];
}
@@ -119,7 +117,7 @@ class PreUpdateEventArgs extends LifecycleEventArgs
*/
private function assertValidField($field)
{
if ( ! isset($this->entityChangeSet[$field])) {
if ( ! isset($this->entityChangeSet[$field])) {
throw new \InvalidArgumentException(sprintf(
'Field "%s" is not a valid field of the entity "%s" in PreUpdateEventArgs.',
$field,

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>.
*/
@@ -145,4 +143,4 @@ final class Events
* @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>.
*/
@@ -45,4 +45,4 @@ abstract class AbstractIdGenerator
{
return false;
}
}
}

View File

@@ -13,14 +13,13 @@
* 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\Id;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\ORMException;
/**

View File

@@ -0,0 +1,66 @@
<?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 Doctrine\ORM\EntityManager;
/**
* Id generator that obtains IDs from special "identity" columns. These are columns
* that automatically get a database-generated, auto-incremented identifier on INSERT.
* This generator obtains the last insert id after such an insert.
*/
class BigIntegerIdentityGenerator extends AbstractIdGenerator
{
/**
* The name of the sequence to pass to lastInsertId(), if any.
*
* @var string
*/
private $sequenceName;
/**
* Constructor.
*
* @param string|null $seqName The name of the sequence to pass to lastInsertId()
* to obtain the last generated identifier within the current
* database session/connection, if any.
*/
public function __construct($sequenceName = null)
{
$this->sequenceName = $sequenceName;
}
/**
* {@inheritdoc}
*/
public function generate(EntityManager $em, $entity)
{
return (string)$em->getConnection()->lastInsertId($this->sequenceName);
}
/**
* {@inheritdoc}
*/
public function isPostInsertGenerator()
{
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>.
*/
@@ -28,17 +28,21 @@ use Doctrine\ORM\EntityManager;
*/
class IdentityGenerator extends AbstractIdGenerator
{
/** @var string The name of the sequence to pass to lastInsertId(), if any. */
private $_seqName;
/**
* The name of the sequence to pass to lastInsertId(), if any.
*
* @var string
*/
private $sequenceName;
/**
* @param string $seqName The name of the sequence to pass to lastInsertId()
* to obtain the last generated identifier within the current
* database session/connection, if any.
*/
public function __construct($seqName = null)
public function __construct($sequenceName = null)
{
$this->_seqName = $seqName;
$this->sequenceName = $sequenceName;
}
/**
@@ -46,7 +50,7 @@ class IdentityGenerator extends AbstractIdGenerator
*/
public function generate(EntityManager $em, $entity)
{
return (int)$em->getConnection()->lastInsertId($this->_seqName);
return (int)$em->getConnection()->lastInsertId($this->sequenceName);
}
/**
@@ -56,4 +60,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>.
*/

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>.
*/
@@ -78,4 +78,4 @@ class TableGenerator extends AbstractIdGenerator
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>.
*/
@@ -115,4 +115,4 @@ class CommitOrderCalculator
{
$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>.
*/
@@ -37,22 +37,22 @@ use PDO,
*/
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. */
@@ -97,6 +97,7 @@ abstract class AbstractHydrator
*
* @param object $stmt
* @param object $resultSetMapping
* @param array $hints
* @return mixed
*/
public function hydrateAll($stmt, $resultSetMapping, array $hints = array())

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>.
*/
@@ -111,13 +111,14 @@ class ArrayHydrator extends AbstractHydrator
// 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])) {
$baseElement =& $this->_resultPointers[$parent];
} else {
unset($this->_resultPointers[$dqlAlias]); // Ticket #1228
continue;
}
@@ -139,6 +140,7 @@ class ArrayHydrator extends AbstractHydrator
if ( ! $indexExists || ! $indexIsValid) {
$element = $data;
if (isset($this->_rsm->indexByMap[$dqlAlias])) {
$baseElement[$relationAlias][$row[$this->_rsm->indexByMap[$dqlAlias]]] = $element;
} else {
@@ -155,7 +157,10 @@ class ArrayHydrator extends AbstractHydrator
} else {
$oneToOne = true;
if ( ! isset($nonemptyComponents[$dqlAlias]) && ! isset($baseElement[$relationAlias])) {
if (
( ! isset($nonemptyComponents[$dqlAlias])) &&
( ! isset($baseElement[$relationAlias]))
) {
$baseElement[$relationAlias] = null;
} else if ( ! isset($baseElement[$relationAlias])) {
$baseElement[$relationAlias] = $data;
@@ -164,10 +169,9 @@ class ArrayHydrator extends AbstractHydrator
$coll =& $baseElement[$relationAlias];
if ($coll !== null) {
if (is_array($coll)) {
$this->updateResultPointer($coll, $index, $dqlAlias, $oneToOne);
}
} else {
// It's a root result element
@@ -176,22 +180,21 @@ class ArrayHydrator extends AbstractHydrator
// 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;
}
$result[] = $this->_rsm->isMixed
? array($entityKey => null)
: 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 ($this->_rsm->isMixed) {
$element = array($entityKey => $element);
}
$element = $this->_rsm->isMixed
? array($entityKey => $rowData[$dqlAlias])
: $rowData[$dqlAlias];
if (isset($this->_rsm->indexByMap[$dqlAlias])) {
$resultKey = $row[$this->_rsm->indexByMap[$dqlAlias]];
@@ -199,6 +202,7 @@ class ArrayHydrator extends AbstractHydrator
} else {
$resultKey = $this->_resultCounter;
$result[] = $element;
++$this->_resultCounter;
}
@@ -206,11 +210,13 @@ class ArrayHydrator extends AbstractHydrator
} else {
$index = $this->_identifierMap[$dqlAlias][$id[$dqlAlias]];
$resultKey = $index;
/*if ($this->_rsm->isMixed) {
$result[] =& $result[$index];
++$this->_resultCounter;
}*/
}
$this->updateResultPointer($result, $index, $dqlAlias, false);
}
}
@@ -219,11 +225,9 @@ class ArrayHydrator extends AbstractHydrator
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;
}
$resultKey = isset($this->_rsm->indexByMap['scalars'])
? $row[$this->_rsm->indexByMap['scalars']]
: $this->_resultCounter - 1;
}
foreach ($scalars as $name => $value) {
@@ -249,6 +253,12 @@ class ArrayHydrator extends AbstractHydrator
return;
}
if ($oneToOne) {
$this->_resultPointers[$dqlAlias] =& $coll;
return;
}
if ($index !== false) {
$this->_resultPointers[$dqlAlias] =& $coll[$index];
@@ -259,12 +269,6 @@ class ArrayHydrator extends AbstractHydrator
return;
}
if ($oneToOne) {
$this->_resultPointers[$dqlAlias] =& $coll;
return;
}
end($coll);
$this->_resultPointers[$dqlAlias] =& $coll[key($coll)];

View File

@@ -23,4 +23,34 @@ class HydrationException extends \Doctrine\ORM\ORMException
"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>.
*/
@@ -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>.
*/
@@ -27,6 +27,7 @@ use PDO,
Doctrine\ORM\Events,
Doctrine\Common\Collections\ArrayCollection,
Doctrine\Common\Collections\Collection,
Doctrine\ORM\UnitOfWork,
Doctrine\ORM\Proxy\Proxy;
/**
@@ -65,8 +66,8 @@ class ObjectHydrator extends AbstractHydrator
$this->_resultCounter = 0;
if ( ! isset($this->_hints['deferEagerLoad'])) {
$this->_hints['deferEagerLoad'] = true;
if ( ! isset($this->_hints[UnitOfWork::HINT_DEFEREAGERLOAD])) {
$this->_hints[UnitOfWork::HINT_DEFEREAGERLOAD] = true;
}
foreach ($this->_rsm->aliasMap as $dqlAlias => $className) {
@@ -123,7 +124,7 @@ class ObjectHydrator extends AbstractHydrator
*/
protected function cleanup()
{
$eagerLoad = (isset($this->_hints['deferEagerLoad'])) && $this->_hints['deferEagerLoad'] == true;
$eagerLoad = (isset($this->_hints[UnitOfWork::HINT_DEFEREAGERLOAD])) && $this->_hints[UnitOfWork::HINT_DEFEREAGERLOAD] == true;
parent::cleanup();
@@ -160,10 +161,10 @@ class ObjectHydrator extends AbstractHydrator
/**
* Initializes a related collection.
*
* @param object $entity The entity to which the collection belongs.
* @param object $entity The entity to which the collection belongs.
* @param ClassMetadata $class
* @param string $name The name of the field on the entity that holds the collection.
* @param string $parentDqlAlias Alias of the parent fetch joining this collection.
* @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, $parentDqlAlias)
{
@@ -207,8 +208,8 @@ class ObjectHydrator extends AbstractHydrator
/**
* 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)
@@ -216,8 +217,17 @@ class ObjectHydrator extends AbstractHydrator
$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);
}
@@ -236,6 +246,11 @@ class ObjectHydrator extends AbstractHydrator
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?
@@ -293,8 +308,8 @@ class ObjectHydrator extends AbstractHydrator
* 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.
* @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 hydrateRowData(array $row, array &$cache, array &$result)
@@ -329,7 +344,7 @@ class ObjectHydrator extends AbstractHydrator
$path = $parentAlias . '.' . $dqlAlias;
// We have a RIGHT JOIN result here. Doctrine cannot hydrate RIGHT JOIN Object-Graphs
if (!isset($nonemptyComponents[$parentAlias])) {
if ( ! isset($nonemptyComponents[$parentAlias])) {
// TODO: Add special case code where we hydrate the right join objects into identity map at least
continue;
}
@@ -434,6 +449,7 @@ class ObjectHydrator extends AbstractHydrator
$this->_resultPointers[$dqlAlias] = $element;
} else {
$this->_uow->setOriginalEntityProperty($oid, $relationField, null);
$reflField->setValue($parentObject, null);
}
// else leave $reflFieldValue null for single-valued associations
} else {

View File

@@ -13,14 +13,12 @@
* 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
@@ -54,4 +52,4 @@ class ScalarHydrator extends AbstractHydrator
{
$result[] = $this->gatherScalarRowData($data, $cache);
}
}
}

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>.
*/
@@ -75,7 +75,7 @@ class SimpleObjectHydrator extends AbstractHydrator
return;
}
foreach ($this->_rsm->declaringClasses AS $column => $class) {
foreach ($this->_rsm->declaringClasses as $column => $class) {
$this->declaringClasses[$column] = $this->_em->getClassMetadata($class);
}
}
@@ -92,6 +92,10 @@ class SimpleObjectHydrator extends AbstractHydrator
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));
}
@@ -174,10 +178,13 @@ class SimpleObjectHydrator extends AbstractHydrator
// One solution is to load the association, but it might require extra efforts.
return array('name' => $column);
default:
case (isset($this->_rsm->metaMappings[$column])):
return array(
'name' => $this->_rsm->metaMappings[$column]
);
default:
return null;
}
}
}

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>.
*/
@@ -53,4 +53,4 @@ class SingleScalarHydrator extends AbstractHydrator
return array_shift($result);
}
}
}

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>.
*/

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

@@ -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>.
*/
@@ -164,4 +164,4 @@ class AssociationBuilder
}
return $this->builder;
}
}
}

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>.
*/

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>.
*/
@@ -220,4 +220,4 @@ class FieldBuilder
}
return $this->builder;
}
}
}

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>.
*/
@@ -83,4 +83,4 @@ class ManyToManyAssociationBuilder extends OneToManyAssociationBuilder
$cm->mapManyToMany($mapping);
return $this->builder;
}
}
}

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>.
*/
@@ -59,4 +59,4 @@ class OneToManyAssociationBuilder extends AssociationBuilder
$cm->mapOneToMany($mapping);
return $this->builder;
}
}
}

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>.
*/

View File

@@ -13,31 +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;
use ReflectionClass, ReflectionProperty;
/**
* A <tt>ClassMetadata</tt> instance holds all the object-relational mapping metadata
* of an entity and it's associations.
* {@inheritDoc}
*
* Once populated, ClassMetadata instances are usually cached in a serialized form.
*
* <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
{

View File

@@ -13,24 +13,27 @@
* 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 ReflectionException,
Doctrine\ORM\ORMException,
Doctrine\ORM\EntityManager,
Doctrine\DBAL\Platforms,
Doctrine\ORM\Events,
Doctrine\Common\Persistence\Mapping\RuntimeReflectionService,
Doctrine\Common\Persistence\Mapping\ReflectionService,
Doctrine\Common\Persistence\Mapping\ClassMetadataFactory as ClassMetadataFactoryInterface;
use ReflectionException;
use Doctrine\ORM\ORMException;
use Doctrine\ORM\EntityManager;
use Doctrine\DBAL\Platforms;
use Doctrine\ORM\Events;
use Doctrine\Common\Persistence\Mapping\ReflectionService;
use Doctrine\Common\Persistence\Mapping\ClassMetadata as ClassMetadataInterface;
use Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory;
use Doctrine\ORM\Id\IdentityGenerator;
use Doctrine\ORM\Id\BigIntegerIdentityGenerator;
use 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
@@ -39,7 +42,7 @@ use ReflectionException,
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class ClassMetadataFactory implements ClassMetadataFactoryInterface
class ClassMetadataFactory extends AbstractClassMetadataFactory
{
/**
* @var EntityManager
@@ -47,12 +50,12 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
private $em;
/**
* @var AbstractPlatform
* @var \Doctrine\DBAL\Platforms\AbstractPlatform
*/
private $targetPlatform;
/**
* @var \Doctrine\ORM\Mapping\Driver\Driver
* @var \Doctrine\Common\Persistence\Mapping\Driver\MappingDriver
*/
private $driver;
@@ -62,27 +65,7 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
private $evm;
/**
* @var \Doctrine\Common\Cache\Cache
*/
private $cacheDriver;
/**
* @var array
*/
private $loadedMetadata = array();
/**
* @var bool
*/
private $initialized = false;
/**
* @var ReflectionService
*/
private $reflectionService;
/**
* @param EntityManager $$em
* @param EntityManager $em
*/
public function setEntityManager(EntityManager $em)
{
@@ -90,55 +73,9 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
}
/**
* 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();
@@ -147,215 +84,99 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
}
/**
* 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->wakeupReflection($cached, $this->getReflectionService());
$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($this->getReflectionService()->getParentClasses($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;
$rootEntityFound = false;
$visited = array();
foreach ($parentClasses as $className) {
if (isset($this->loadedMetadata[$className])) {
$parent = $this->loadedMetadata[$className];
if ( ! $parent->isMappedSuperclass) {
$rootEntityFound = true;
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);
$this->initializeReflection($class, $this->getReflectionService());
if ($parent) {
$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);
$class->setDiscriminatorMap($parent->discriminatorMap);
$class->setLifecycleCallbacks($parent->lifecycleCallbacks);
$class->setChangeTrackingPolicy($parent->changeTrackingPolicy);
if ($parent->isMappedSuperclass) {
$class->setCustomRepositoryClass($parent->customRepositoryClassName);
}
}
// Invoke driver
try {
$this->driver->loadMetadataForClass($className, $class);
} catch (ReflectionException $e) {
throw MappingException::reflectionFailure($className, $e);
if ($parent->idGenerator) {
$class->setIdGenerator($parent->idGenerator);
}
// If this class has a parent the id generator strategy is inherited.
// However this is only true if the hierachy of parents contains the root entity,
// if it consinsts 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->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->containsForeignIdentifier) {
$class->containsForeignIdentifier = true;
}
if ($parent && !empty ($parent->namedQueries)) {
$this->addInheritedNamedQueries($class, $parent);
}
$class->setParentClasses($visited);
if ($this->evm->hasListeners(Events::loadClassMetadata)) {
$eventArgs = new \Doctrine\ORM\Event\LoadClassMetadataEventArgs($class, $this->em);
$this->evm->dispatchEvent(Events::loadClassMetadata, $eventArgs);
}
$this->wakeupReflection($class, $this->getReflectionService());
$this->validateRuntimeMetadata($class, $parent);
$this->loadedMetadata[$className] = $class;
$parent = $class;
if ( ! $class->isMappedSuperclass) {
$rootEntityFound = true;
array_unshift($visited, $className);
}
$loaded[] = $className;
} else {
$this->completeIdGeneratorMapping($class);
}
return $loaded;
if ($parent && $parent->isInheritanceTypeSingleTable()) {
$class->setPrimaryTable($parent->table);
}
if ($parent && $parent->containsForeignIdentifier) {
$class->containsForeignIdentifier = true;
}
if ($parent && !empty($parent->namedQueries)) {
$this->addInheritedNamedQueries($class, $parent);
}
if ($parent && !empty($parent->namedNativeQueries)) {
$this->addInheritedNamedNativeQueries($class, $parent);
}
if ($parent && !empty($parent->sqlResultSetMappings)) {
$this->addInheritedSqlResultSetMappings($class, $parent);
}
$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 ClassMetadata $parent
* @param $parent
* @throws MappingException
*/
protected function validateRuntimeMetadata($class, $parent)
{
@@ -369,33 +190,85 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
$class->validateLifecycleCallbacks($this->getReflectionService());
// verify inheritance
if (!$class->isMappedSuperclass && !$class->isInheritanceTypeNone()) {
if (!$parent) {
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 hierachy, otherwise problems will occur.
// enforce discriminator map for all entities of an inheritance hierarchy, otherwise problems will occur.
throw MappingException::mappedClassNotPartOfDiscriminatorMap($class->name, $class->rootEntityName);
}
} 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 hierachy
// second condition is necessary for mapped superclasses in the middle of an inheritance hierarchy
throw MappingException::noInheritanceOnMappedSuperClass($class->name);
}
}
/**
* 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));
}
/**
@@ -406,7 +279,7 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
*/
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;
}
@@ -425,6 +298,7 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
*
* @param \Doctrine\ORM\Mapping\ClassMetadata $subClass
* @param \Doctrine\ORM\Mapping\ClassMetadata $parentClass
* @throws MappingException
*/
private function addInheritedRelations(ClassMetadata $subClass, ClassMetadata $parentClass)
{
@@ -457,7 +331,7 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
private function addInheritedNamedQueries(ClassMetadata $subClass, ClassMetadata $parentClass)
{
foreach ($parentClass->namedQueries as $name => $query) {
if (!isset ($subClass->namedQueries[$name])) {
if ( ! isset ($subClass->namedQueries[$name])) {
$subClass->addNamedQuery(array(
'name' => $query['name'],
'query' => $query['query']
@@ -466,11 +340,64 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
}
}
/**
* 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)
{
@@ -491,103 +418,126 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
// 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->getTableName() . '_' . $class->columnNames[$class->identifier[0]] . '_seq' :
null;
$class->setIdGenerator(new \Doctrine\ORM\Id\IdentityGenerator($seqName));
$sequenceName = null;
$fieldName = $class->identifier ? $class->getSingleIdentifierFieldName() : null;
if ($this->targetPlatform instanceof Platforms\PostgreSQLPlatform) {
$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);
}
$generator = ($fieldName && $class->fieldMappings[$fieldName]['type'] === "bigint")
? new BigIntegerIdentityGenerator($sequenceName)
: new IdentityGenerator($sequenceName);
$class->setIdGenerator($generator);
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);
}
}
/**
* Check if this class is mapped by this EntityManager + ClassMetadata configuration
*
* @param $class
* @return bool
* {@inheritDoc}
*/
public function isTransient($class)
{
if ( ! $this->initialized) {
$this->initialize();
}
// Check for namespace alias
if (strpos($class, ':') !== false) {
list($namespaceAlias, $simpleClassName) = explode(':', $class);
$class = $this->em->getConfiguration()->getEntityNamespace($namespaceAlias) . '\\' . $simpleClassName;
}
return $this->driver->isTransient($class);
}
/**
* Get reflectionService.
*
* @return \Doctrine\Common\Persistence\Mapping\ReflectionService
*/
public function getReflectionService()
{
if ($this->reflectionService === null) {
$this->reflectionService = new RuntimeReflectionService();
}
return $this->reflectionService;
}
/**
* Set reflectionService.
*
* @param reflectionService the value to set.
*/
public function setReflectionService(ReflectionService $reflectionService)
{
$this->reflectionService = $reflectionService;
}
/**
* Wakeup reflection after ClassMetadata gets unserialized from cache.
*
* @param ClassMetadataInfo $class
* @param ReflectionService $reflService
* @return void
*/
protected function wakeupReflection(ClassMetadataInfo $class, ReflectionService $reflService)
protected function wakeupReflection(ClassMetadataInterface $class, ReflectionService $reflService)
{
/* @var $class ClassMetadata */
$class->wakeupReflection($reflService);
}
/**
* Initialize Reflection after ClassMetadata was constructed.
*
* @param ClassMetadataInfo $class
* @param ReflectionService $reflService
* @return void
* {@inheritDoc}
*/
protected function initializeReflection(ClassMetadataInfo $class, ReflectionService $reflService)
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

@@ -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>.
*/
@@ -21,7 +21,7 @@ namespace Doctrine\ORM\Mapping;
/**
* @Annotation
* @Target("PROPERTY")
* @Target({"PROPERTY","ANNOTATION"})
*/
final class Column implements Annotation
{

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

@@ -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>.
*/
@@ -33,4 +33,6 @@ final class DiscriminatorColumn implements Annotation
public $length;
/** @var mixed */
public $fieldName; // field name used in non-object hydration (array/scalar)
/** @var string */
public $columnDefinition;
}

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>.
*/

View File

@@ -1,213 +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));
if(!isset($result[$className])){
throw MappingException::invalidMappingFile($className, str_replace('\\', '.', $className) . $this->_fileExtension);
}
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,17 +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\Common\Annotations\AnnotationRegistry,
Doctrine\ORM\Mapping\ClassMetadataInfo,
Doctrine\ORM\Mapping\MappingException;
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.
@@ -34,113 +35,30 @@ use Doctrine\Common\Cache\ArrayCache,
* @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}
*/
protected $_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 AnnotationReader $reader The AnnotationReader to use, duck-typed.
* @param string|array $paths One or multiple paths where mapping classes can be found.
*/
public function __construct($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;
}
/**
* Retrieve the current annotation reader
*
* @return AnnotationReader
*/
public function getReader()
{
return $this->_reader;
}
/**
* 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) {
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) {
@@ -201,19 +119,75 @@ class AnnotationDriver implements Driver
}
}
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)) {
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)) {
if ( ! ($namedQuery instanceof \Doctrine\ORM\Mapping\NamedQuery)) {
throw new \UnexpectedValueException("@NamedQueries should contain an array of @NamedQuery annotations.");
}
$metadata->addNamedQuery(array(
@@ -235,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));
@@ -257,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()
||
@@ -272,79 +248,53 @@ 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,
'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,
'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')) {
if ($idAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Id')) {
} else if ($oneToOneAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\OneToOne')) {
if ($idAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Id')) {
$mapping['id'] = true;
}
@@ -356,7 +306,7 @@ class AnnotationDriver implements Driver
$mapping['orphanRemoval'] = $oneToOneAnnot->orphanRemoval;
$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;
@@ -364,13 +314,13 @@ class AnnotationDriver implements Driver
$mapping['orphanRemoval'] = $oneToManyAnnot->orphanRemoval;
$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')) {
if ($idAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Id')) {
} else if ($manyToOneAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\ManyToOne')) {
if ($idAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Id')) {
$mapping['id'] = true;
}
@@ -380,35 +330,21 @@ class AnnotationDriver implements Driver
$mapping['targetEntity'] = $manyToOneAnnot->targetEntity;
$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,
'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,
'columnDefinition' => $joinColumn->columnDefinition,
);
$joinTable['inverseJoinColumns'][] = $this->joinColumnToArray($joinColumn);
}
}
@@ -421,7 +357,7 @@ class AnnotationDriver implements Driver
$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;
}
@@ -429,12 +365,63 @@ 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) {
@@ -481,90 +468,6 @@ class AnnotationDriver implements Driver
}
}
/**
* 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.
*
* @param string $className
* @return boolean
*/
public function isTransient($className)
{
$classAnnotations = $this->_reader->getClassAnnotations(new \ReflectionClass($className));
if ($classAnnotations && is_numeric(key($classAnnotations))) {
foreach ($classAnnotations as $annot) {
if ($annot instanceof \Doctrine\ORM\Mapping\Entity) {
return false;
}
if ($annot instanceof \Doctrine\ORM\Mapping\MappedSuperclass) {
return false;
}
}
return true;
}
return ! isset($classAnnotations['Doctrine\ORM\Mapping\Entity']) &&
! isset($classAnnotations['Doctrine\ORM\Mapping\MappedSuperclass']);
}
/**
* {@inheritDoc}
*/
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 \RegexIterator(
new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($path, \FilesystemIterator::SKIP_DOTS),
\RecursiveIteratorIterator::LEAVES_ONLY
),
'/^.+' . str_replace('.', '\.', $this->_fileExtension) . '$/i',
\RecursiveRegexIterator::GET_MATCH
);
foreach ($iterator as $file) {
$sourceFile = realpath($file[0]);
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;
}
/**
* Attempts to resolve the fetch mode.
*
@@ -575,12 +478,65 @@ class AnnotationDriver implements Driver
*/
private function getFetchMode($className, $fetchMode)
{
if(!defined('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $fetchMode)) {
if( ! defined('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $fetchMode)) {
throw MappingException::invalidFetchMode($className, $fetchMode);
}
return constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $fetchMode);
}
/**
* Parse the given JoinColumn as array
*
* @param JoinColumn $joinColumn
* @return array
*/
private function joinColumnToArray(JoinColumn $joinColumn)
{
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 (isset($column->name)) {
$mapping['columnName'] = $column->name;
}
if (isset($column->columnDefinition)) {
$mapping['columnDefinition'] = $column->columnDefinition;
}
return $mapping;
}
/**
* Factory method for the Annotation Driver
*
@@ -592,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
@@ -74,10 +74,8 @@ class DatabaseDriver implements Driver
private $namespace;
/**
* Initializes a new AnnotationDriver that uses the given AnnotationReader for reading
* docblock annotations.
*
* @param AnnotationReader $reader The AnnotationReader to use.
* @param AbstractSchemaManager $schemaManager
*/
public function __construct(AbstractSchemaManager $schemaManager)
{
@@ -94,12 +92,12 @@ class DatabaseDriver implements Driver
public function setTables($entityTables, $manyToManyTables)
{
$this->tables = $this->manyToManyTables = $this->classToTableNames = array();
foreach ($entityTables AS $table) {
foreach ($entityTables as $table) {
$className = $this->getClassNameForTable($table->getName());
$this->classToTableNames[$className] = $table->getName();
$this->tables[$table->getName()] = $table;
}
foreach ($manyToManyTables AS $table) {
foreach ($manyToManyTables as $table) {
$this->manyToManyTables[$table->getName()] = $table;
}
}
@@ -117,8 +115,8 @@ class DatabaseDriver implements Driver
}
$this->tables = $this->manyToManyTables = $this->classToTableNames = array();
foreach ($tables AS $tableName => $table) {
/* @var $table Table */
foreach ($tables as $tableName => $table) {
/* @var $table \Doctrine\DBAL\Schema\Table */
if ($this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) {
$foreignKeys = $table->getForeignKeys();
} else {
@@ -126,7 +124,7 @@ class DatabaseDriver implements Driver
}
$allForeignKeyColumns = array();
foreach ($foreignKeys AS $foreignKey) {
foreach ($foreignKeys as $foreignKey) {
$allForeignKeyColumns = array_merge($allForeignKeyColumns, $foreignKey->getLocalColumns());
}
@@ -154,9 +152,9 @@ class DatabaseDriver implements Driver
}
/**
* {@inheritdoc}
* {@inheritDoc}
*/
public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
public function loadMetadataForClass($className, ClassMetadata $metadata)
{
$this->reverseEngineerMappingFromDatabase();
@@ -184,7 +182,7 @@ class DatabaseDriver implements Driver
}
$allForeignKeyColumns = array();
foreach ($foreignKeys AS $foreignKey) {
foreach ($foreignKeys as $foreignKey) {
$allForeignKeyColumns = array_merge($allForeignKeyColumns, $foreignKey->getLocalColumns());
}
@@ -192,13 +190,13 @@ class DatabaseDriver implements Driver
$fieldMappings = array();
foreach ($columns as $column) {
$fieldMapping = array();
if (in_array($column->getName(), $allForeignKeyColumns)) {
continue;
} else if ($primaryKeyColumns && in_array($column->getName(), $primaryKeyColumns)) {
$fieldMapping['id'] = true;
}
$fieldMapping['fieldName'] = $this->getFieldNameForColumn($tableName, $column->getName(), false);
$fieldMapping['columnName'] = $column->getName();
$fieldMapping['type'] = strtolower((string) $column->getType());
@@ -219,7 +217,8 @@ class DatabaseDriver implements Driver
}
if ($ids) {
if (count($ids) == 1) {
// We need to check for the columns here, because we might have associations as id as well.
if (count($primaryKeyColumns) == 1) {
$metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
}
@@ -232,13 +231,13 @@ 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;
$otherFk = null;
foreach ($manyTable->getForeignKeys() AS $foreignKey) {
foreach ($manyTable->getForeignKeys() as $foreignKey) {
if ($foreignKey != $myFk) {
$otherFk = $foreignKey;
break;
@@ -299,6 +298,10 @@ class DatabaseDriver implements Driver
$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;
}
@@ -309,7 +312,7 @@ class DatabaseDriver implements Driver
'referencedColumnName' => $fkCols[$i],
);
}
//Here we need to check if $cols are the same as $primaryKeyColums
if (!array_diff($cols,$primaryKeyColumns)) {
$metadata->mapOneToOne($associationMapping);
@@ -320,7 +323,7 @@ class DatabaseDriver implements Driver
}
/**
* {@inheritdoc}
* {@inheritDoc}
*/
public function isTransient($className)
{
@@ -328,11 +331,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()
{

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>.
*/
@@ -39,6 +39,7 @@ 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';
@@ -52,3 +53,14 @@ 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,114 +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();
$driverClasses = array();
foreach ($this->_drivers AS $namespace => $driver) {
$oid = spl_object_hash($driver);
if (!isset($driverClasses[$oid])) {
$driverClasses[$oid] = $driver->getAllClassNames();
}
foreach ($driverClasses[$oid] AS $className) {
if (strpos($className, $namespace) === 0) {
$classNames[$className] = true;
}
}
}
return array_keys($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

@@ -13,13 +13,13 @@
* 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\MappingException;
use Doctrine\Common\Persistence\Mapping\Driver\SymfonyFileLocator;
/**
* XmlDriver that additionally looks for mapping information in a global file.
@@ -30,147 +30,14 @@ use Doctrine\ORM\Mapping\MappingException;
*/
class SimplifiedXmlDriver extends XmlDriver
{
protected $_prefixes = array();
protected $_globalBasename;
protected $_classCache;
protected $_fileExtension = '.orm.xml';
const DEFAULT_FILE_EXTENSION = '.orm.xml';
public function __construct($prefixes)
/**
* {@inheritDoc}
*/
public function __construct($prefixes, $fileExtension = self::DEFAULT_FILE_EXTENSION)
{
$this->addNamespacePrefixes($prefixes);
}
public function setGlobalBasename($file)
{
$this->_globalBasename = $file;
}
public function getGlobalBasename()
{
return $this->_globalBasename;
}
public function addNamespacePrefixes($prefixes)
{
$this->_prefixes = array_merge($this->_prefixes, $prefixes);
$this->addPaths(array_flip($prefixes));
}
public function getNamespacePrefixes()
{
return $this->_prefixes;
}
public function isTransient($className)
{
if (null === $this->_classCache) {
$this->initialize();
}
// The mapping is defined in the global mapping file
if (isset($this->_classCache[$className])) {
return false;
}
try {
$this->_findMappingFile($className);
return false;
} catch (MappingException $e) {
return true;
}
}
public function getAllClassNames()
{
if (null === $this->_classCache) {
$this->initialize();
}
$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) {
$fileName = $file->getBasename($this->_fileExtension);
if ($fileName == $file->getBasename() || $fileName == $this->_globalBasename) {
continue;
}
// NOTE: All files found here means classes are not transient!
if (isset($this->_prefixes[$path])) {
$classes[] = $this->_prefixes[$path].'\\'.str_replace('.', '\\', $fileName);
} else {
$classes[] = str_replace('.', '\\', $fileName);
}
}
}
}
return array_merge($classes, array_keys($this->_classCache));
}
public function getElement($className)
{
if (null === $this->_classCache) {
$this->initialize();
}
if (!isset($this->_classCache[$className])) {
$this->_classCache[$className] = parent::getElement($className);
}
return $this->_classCache[$className];
}
protected function initialize()
{
$this->_classCache = array();
if (null !== $this->_globalBasename) {
foreach ($this->_paths as $path) {
if (is_file($file = $path.'/'.$this->_globalBasename.$this->_fileExtension)) {
$this->_classCache = array_merge($this->_classCache, $this->_loadMappingFile($file));
}
}
}
}
protected function _findMappingFile($className)
{
$defaultFileName = str_replace('\\', '.', $className).$this->_fileExtension;
foreach ($this->_paths as $path) {
if (!isset($this->_prefixes[$path])) {
if (is_file($path.DIRECTORY_SEPARATOR.$defaultFileName)) {
return $path.DIRECTORY_SEPARATOR.$defaultFileName;
}
continue;
}
$prefix = $this->_prefixes[$path];
if (0 !== strpos($className, $prefix.'\\')) {
continue;
}
$filename = $path.'/'.strtr(substr($className, strlen($prefix)+1), '\\', '.').$this->_fileExtension;
if (is_file($filename)) {
return $filename;
}
throw MappingException::mappingFileNotFound($className, $filename);
}
throw MappingException::mappingFileNotFound($className, substr($className, strrpos($className, '\\') + 1).$this->_fileExtension);
$locator = new SymfonyFileLocator((array) $prefixes, $fileExtension);
parent::__construct($locator, $fileExtension);
}
}

View File

@@ -13,13 +13,13 @@
* 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\MappingException;
use Doctrine\Common\Persistence\Mapping\Driver\SymfonyFileLocator;
/**
* YamlDriver that additionally looks for mapping information in a global file.
@@ -30,152 +30,14 @@ use Doctrine\ORM\Mapping\MappingException;
*/
class SimplifiedYamlDriver extends YamlDriver
{
protected $_prefixes = array();
protected $_globalBasename;
protected $_classCache;
protected $_fileExtension = '.orm.yml';
const DEFAULT_FILE_EXTENSION = '.orm.yml';
public function __construct($prefixes)
/**
* {@inheritDoc}
*/
public function __construct($prefixes, $fileExtension = self::DEFAULT_FILE_EXTENSION)
{
$this->addNamespacePrefixes($prefixes);
}
public function setGlobalBasename($file)
{
$this->_globalBasename = $file;
}
public function getGlobalBasename()
{
return $this->_globalBasename;
}
public function addNamespacePrefixes($prefixes)
{
$this->_prefixes = array_merge($this->_prefixes, $prefixes);
$this->addPaths(array_flip($prefixes));
}
public function addNamespacePrefix($prefix, $path)
{
$this->_prefixes[$path] = $prefix;
}
public function getNamespacePrefixes()
{
return $this->_prefixes;
}
public function isTransient($className)
{
if (null === $this->_classCache) {
$this->initialize();
}
// The mapping is defined in the global mapping file
if (isset($this->_classCache[$className])) {
return false;
}
try {
$this->_findMappingFile($className);
return false;
} catch (MappingException $e) {
return true;
}
}
public function getAllClassNames()
{
if (null === $this->_classCache) {
$this->initialize();
}
$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) {
$fileName = $file->getBasename($this->_fileExtension);
if ($fileName == $file->getBasename() || $fileName == $this->_globalBasename) {
continue;
}
// NOTE: All files found here means classes are not transient!
if (isset($this->_prefixes[$path])) {
$classes[] = $this->_prefixes[$path].'\\'.str_replace('.', '\\', $fileName);
} else {
$classes[] = str_replace('.', '\\', $fileName);
}
}
}
}
return array_merge($classes, array_keys($this->_classCache));
}
public function getElement($className)
{
if (null === $this->_classCache) {
$this->initialize();
}
if (!isset($this->_classCache[$className])) {
$this->_classCache[$className] = parent::getElement($className);
}
return $this->_classCache[$className];
}
protected function initialize()
{
$this->_classCache = array();
if (null !== $this->_globalBasename) {
foreach ($this->_paths as $path) {
if (is_file($file = $path.'/'.$this->_globalBasename.$this->_fileExtension)) {
$this->_classCache = array_merge($this->_classCache, $this->_loadMappingFile($file));
}
}
}
}
protected function _findMappingFile($className)
{
$defaultFileName = str_replace('\\', '.', $className).$this->_fileExtension;
foreach ($this->_paths as $path) {
if (!isset($this->_prefixes[$path])) {
if (is_file($path.DIRECTORY_SEPARATOR.$defaultFileName)) {
return $path.DIRECTORY_SEPARATOR.$defaultFileName;
}
continue;
}
$prefix = $this->_prefixes[$path];
if (0 !== strpos($className, $prefix.'\\')) {
continue;
}
$filename = $path.'/'.strtr(substr($className, strlen($prefix)+1), '\\', '.').$this->_fileExtension;
if (is_file($filename)) {
return $filename;
}
throw MappingException::mappingFileNotFound($className, $filename);
}
throw MappingException::mappingFileNotFound($className, substr($className, strrpos($className, '\\') + 1).$this->_fileExtension);
$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,37 @@ 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']) && $xmlRoot['read-only'] == "true") {
if (isset($xmlRoot['read-only']) && $this->evaluateBoolean($xmlRoot['read-only'])) {
$metadata->markReadOnly();
}
} else if ($xmlRoot->getName() == 'mapped-superclass') {
@@ -76,7 +81,7 @@ class XmlDriver extends AbstractFileDriver
$metadata->setPrimaryTable($table);
// Evaluate named queries
if (isset($xmlRoot['named-queries'])) {
if (isset($xmlRoot->{'named-queries'})) {
foreach ($xmlRoot->{'named-queries'}->{'named-query'} as $namedQueryElement) {
$metadata->addNamedQuery(array(
'name' => (string)$namedQueryElement['name'],
@@ -85,6 +90,58 @@ class XmlDriver extends AbstractFileDriver
}
}
// 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'];
@@ -99,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));
@@ -110,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);
@@ -161,61 +219,39 @@ 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'],
);
$mapping = $this->columnToArray($fieldMapping);
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'] = ((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'];
unset($mapping['version']);
}
$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 ((bool)$idElement['association-key'] == true) {
if (isset($idElement['association-key']) && $this->evaluateBoolean($idElement['association-key'])) {
$associationIds[(string)$idElement['name']] = true;
continue;
}
@@ -229,6 +265,10 @@ class XmlDriver extends AbstractFileDriver
$mapping['type'] = (string)$idElement['type'];
}
if (isset($idElement['length'])) {
$mapping['length'] = (string)$idElement['length'];
}
if (isset($idElement['column'])) {
$mapping['columnName'] = (string)$idElement['column'];
}
@@ -254,6 +294,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);
}
@@ -284,10 +329,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);
}
}
@@ -299,7 +344,7 @@ class XmlDriver extends AbstractFileDriver
}
if (isset($oneToOneElement['orphan-removal'])) {
$mapping['orphanRemoval'] = (bool)$oneToOneElement['orphan-removal'];
$mapping['orphanRemoval'] = $this->evaluateBoolean($oneToOneElement['orphan-removal']);
}
$metadata->mapOneToOne($mapping);
@@ -324,12 +369,12 @@ class XmlDriver extends AbstractFileDriver
}
if (isset($oneToManyElement['orphan-removal'])) {
$mapping['orphanRemoval'] = (bool)$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;
@@ -368,10 +413,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) {
$joinColumns[] = $this->_getJoinColumnMapping($joinColumnElement);
$joinColumns[] = $this->joinColumnToArray($joinColumnElement);
}
}
@@ -398,7 +443,7 @@ class XmlDriver extends AbstractFileDriver
}
if (isset($manyToManyElement['orphan-removal'])) {
$mapping['orphanRemoval'] = (bool)$manyToManyElement['orphan-removal'];
$mapping['orphanRemoval'] = $this->evaluateBoolean($manyToManyElement['orphan-removal']);
}
if (isset($manyToManyElement['mapped-by'])) {
@@ -418,11 +463,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;
@@ -434,7 +479,7 @@ class XmlDriver extends AbstractFileDriver
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;
@@ -450,6 +495,62 @@ class XmlDriver extends AbstractFileDriver
}
}
// 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) {
@@ -458,14 +559,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'],
@@ -473,11 +604,11 @@ 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'])) {
@@ -491,15 +622,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'] = $this->evaluateBoolean($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
@@ -512,9 +699,9 @@ class XmlDriver extends AbstractFileDriver
}
/**
* {@inheritdoc}
* {@inheritDoc}
*/
protected function _loadMappingFile($file)
protected function loadMappingFile($file)
{
$result = array();
$xmlElement = simplexml_load_file($file);
@@ -533,4 +720,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,18 +33,24 @@ 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') {
@@ -83,6 +91,68 @@ class YamlDriver extends AbstractFileDriver
}
}
// 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'];
@@ -96,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));
@@ -127,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'];
}
@@ -146,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'];
}
@@ -156,6 +229,10 @@ class YamlDriver extends AbstractFileDriver
}
}
if (isset($element['options'])) {
$metadata->table['options'] = $element['options'];
}
$associationIds = array();
if (isset($element['id'])) {
// Evaluate identifier settings
@@ -195,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);
}
@@ -205,19 +287,7 @@ class YamlDriver extends AbstractFileDriver
if (isset($element['fields'])) {
foreach ($element['fields'] as $name => $fieldMapping) {
$mapping = array(
'fieldName' => $name
);
if (isset($fieldMapping['type'])) {
$e = explode('(', $fieldMapping['type']);
$fieldMapping['type'] = $e[0];
$mapping['type'] = $fieldMapping['type'];
if (isset($e[1])) {
$fieldMapping['length'] = substr($e[1], 0, strlen($e[1]) - 1);
}
}
$mapping = $this->columnToArray($name, $fieldMapping);
if (isset($fieldMapping['id'])) {
$mapping['id'] = true;
@@ -226,32 +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'];
unset($mapping['version']);
}
$metadata->mapField($mapping);
@@ -284,14 +332,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);
}
}
@@ -366,14 +414,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);
}
}
@@ -412,20 +460,20 @@ 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;
@@ -455,6 +503,68 @@ class YamlDriver extends AbstractFileDriver
}
}
// 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) {
@@ -469,15 +579,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'];
@@ -503,10 +617,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::parse($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

@@ -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>.
*/

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>.
*/

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

@@ -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>.
*/

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>.
*/

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>.
*/

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>.
*/

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>.
*/

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>.
*/

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>.
*/

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>.
*/
@@ -21,7 +21,7 @@ namespace Doctrine\ORM\Mapping;
/**
* @Annotation
* @Target("PROPERTY")
* @Target({"PROPERTY","ANNOTATION"})
*/
final class JoinTable implements Annotation
{

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>.
*/

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>.
*/

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>.
*/

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,9 +78,26 @@ class MappingException extends \Doctrine\ORM\ORMException
return new self("No mapping file found named '$fileName' for class '$entityName'.");
}
public static function invalidMappingFile($entityName, $fileName)
/**
* 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 mapping file '$fileName' for class '$entityName'.");
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)
@@ -83,6 +110,41 @@ class MappingException extends \Doctrine\ORM\ORMException
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.");
@@ -144,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)
@@ -158,27 +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 duplicateQueryMapping($entity, $queryName) {
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 singleIdNotAllowedOnCompositePrimaryKey($entity) {
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.'
);
@@ -204,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.");
@@ -226,6 +319,11 @@ 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.");
@@ -329,4 +427,27 @@ class MappingException extends \Doctrine\ORM\ORMException
{
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
));
}
/**
* @param string $className
*
* @return MappingException
*/
public static function missingSequenceName($className)
{
return new self(
sprintf('Missing "sequenceName" attribute for sequence id generator definition on class "%s".', $className)
);
}
}

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

@@ -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,45 +13,51 @@
* 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;
namespace Doctrine\ORM\Mapping;
/**
* Contract for metadata drivers.
* Is used to specify a native SQL named query.
* The NamedNativeQuery annotation can be applied to an entity or mapped superclass.
*
* @since 2.0
* @author Jonathan H. Wage <jonwage@gmail.com>
* @todo Rename: MetadataDriver or MappingDriver
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
* @since 2.3
*
* @Annotation
* @Target("ANNOTATION")
*/
interface Driver
final class NamedNativeQuery implements Annotation
{
/**
* Loads the metadata for the specified class into the provided container.
*
* @param string $className
* @param ClassMetadataInfo $metadata
*/
function loadMetadataForClass($className, ClassMetadataInfo $metadata);
/**
* Gets the names of all mapped classes known to this driver.
* The name used to refer to the query with the EntityManager methods that create query objects.
*
* @return array The names of all mapped classes known to this driver.
* @var string
*/
function getAllClassNames();
public $name;
/**
* 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.
* The SQL query string.
*
* @param string $className
* @return boolean
* @var string
*/
function isTransient($className);
}
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

@@ -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>.
*/

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>.
*/

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

@@ -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>.
*/

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>.
*/

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