Compare commits

..

1724 Commits

Author SHA1 Message Date
Benjamin Eberlei 9308afc9a5 Release 2.3.0-RC2 2012-08-29 16:36:26 +02:00
Benjamin Eberlei 1a81444b04 Bump dev version to 2.3.0 2012-08-29 16:35:51 +02:00
Benjamin Eberlei d181fbc98d Release 2.3.0-RC2 2012-08-29 16:35:51 +02:00
Benjamin Eberlei 114e233d87 Revert "Merge remote-tracking branch 'origin/master' into 2.3"
This reverts commit 131d3003a0, reversing
changes made to 9d909cd583.
2012-08-29 15:50:08 +02:00
Benjamin Eberlei bdb36a71c5 Merge branch 'DDC-1918' into 2.3 2012-08-29 15:15:35 +02:00
Benjamin Eberlei 8c1d64372c Merge remote-tracking branch 'origin/2.3' into 2.3 2012-08-29 15:15:27 +02:00
Benjamin Eberlei f4ba58358c [DDC-1918] Fix weird results at the end of paginator when using fetch joins 2012-08-29 15:14:40 +02:00
Benjamin Eberlei 131d3003a0 Merge remote-tracking branch 'origin/master' into 2.3 2012-08-29 14:01:18 +02:00
Benjamin Eberlei 48e94343fd Merge pull request #427 from chEbba/return-exception
Fix ORMInvalidArgumentException factory methods with return instead of throw
2012-08-29 04:57:32 -07:00
FabioBatSilva 9d909cd583 Fix DDC-1977 2012-08-29 13:40:18 +02:00
Kirill chEbba Chebunin 3aaa90e1a8 Fix ORMInvalidArgumentException factory methods with return instead of throw 2012-08-19 22:58:40 +04:00
Guilherme Blanco ece6a005bc Merge pull request #425 from FabioBatSilva/DDC-1977
Fix DDC-1977
2012-08-15 15:29:26 -07:00
FabioBatSilva 641af15280 Fix DDC-1977 2012-08-15 22:57:21 +02:00
Alexander 971865f271 Merge branch 'config' into 2.3 2012-08-14 22:51:23 +02:00
Alexander af08f05164 Fix setCustomHydrationModes + added test 2012-08-14 22:47:35 +02:00
Martin Meredith 2e6b50bb53 Create the setCustomHydrationMode function
This allows multiple hydrators to be set at once, and also allows for
the customHydrationMode options to be set via DoctrineORMModule
2012-08-14 22:47:35 +02:00
Alexander 185b4e0c41 Fix setCustomHydrationModes + added test 2012-08-14 22:43:32 +02:00
Alexander 5c585b4c02 Merge branch 'config' 2012-08-14 22:33:36 +02:00
Martin Meredith 787a208708 Create the setCustomHydrationMode function
This allows multiple hydrators to be set at once, and also allows for
the customHydrationMode options to be set via DoctrineORMModule
2012-08-14 22:33:25 +02:00
Guilherme Blanco f8a582d454 Merge pull request #391 from FabioBatSilva/ns-class
Give FQCN to NamingStrategy#propertyToColumnName
2012-08-12 15:50:20 -07:00
Guilherme Blanco 72ce9a7f37 Merge pull request #417 from jonathaningram/patch-1
Remove unused use statement
2012-08-01 23:38:56 -07:00
Jonathan Ingram 04de52d4c9 Remove unused use statement 2012-08-02 15:33:09 +10:00
Benjamin Eberlei 17862d9a2a Merge branch 'CriteriaExpressionBuilder' into 2.3 2012-08-01 21:40:25 +02:00
Benjamin Eberlei c99c7b6694 Update EntityRepository and PersistentCollection to new Criteria#expr() method instead of having to implement themselves. 2012-08-01 21:39:39 +02:00
Benjamin Eberlei 104a76a6b1 Update EntityRepository and PersistentCollection to new Criteria#expr() method instead of having to implement themselves. 2012-08-01 21:37:22 +02:00
Michael Moravec 79a04b295f [DDC-1961] Fixed parameter type support in Parameter 2012-07-31 21:01:21 +02:00
Guilherme Blanco 3f2ddc60d4 Merge pull request #416 from Majkl578/DDC-1961
[DDC-1961] Fixed parameter type support in Parameter
2012-07-31 07:34:24 -07:00
Michael Moravec 3b3d762277 [DDC-1961] Fixed parameter type support in Parameter 2012-07-31 16:30:27 +02:00
Benjamin Eberlei 992b51eba7 Bump dev version to 2.3.0 2012-07-29 13:03:10 +02:00
Benjamin Eberlei 5527e121ec Release 2.3.0-RC1 2012-07-29 13:03:10 +02:00
Benjamin Eberlei c55394c616 Bump dependencies 2012-07-29 13:02:58 +02:00
Benjamin Eberlei 1676cf23c0 Merge branch 'DDC-1937' into 2.3 2012-07-29 11:56:59 +02:00
Benjamin Eberlei 6dd3078153 [DDC-1937] Fix bug with apc and annotation caching using a workaround. 2012-07-29 11:56:49 +02:00
Benjamin Eberlei 00a5f18544 [DDC-1937] Fix bug with apc and annotation caching using a workaround. 2012-07-29 11:56:41 +02:00
Marco Pivetta 1e2eca1a7e DDC-1933 - Fixing cloning of QueryBuilder and adding related tests 2012-07-29 11:50:24 +02:00
Benjamin Eberlei 7029d3738d Merge branch 'DDC-1964' into 2.3 2012-07-29 11:26:55 +02:00
Benjamin Eberlei 7f68347c1f [DDC-1964] Fix issue with refresh and and object hydrator not setting field to null explicitly to override possible previous values. 2012-07-29 11:26:22 +02:00
Johannes M. Schmitt e63575ea18 added failing test for refresh with eager fetching 2012-07-29 11:26:22 +02:00
Benjamin Eberlei e8d3fc73ff Merge branch 'DDC-1964' 2012-07-29 11:25:54 +02:00
Benjamin Eberlei 7c1235dedb [DDC-1964] Fix issue with refresh and and object hydrator not setting field to null explicitly to override possible previous values. 2012-07-29 11:25:45 +02:00
Benjamin Eberlei d7bdae3bbb Merge branch 'DDC-1939' into 2.3 2012-07-29 09:28:18 +02:00
Benjamin Eberlei e2c40dc365 [DDC-1939] Add test for persistent collection delete with composite key 2012-07-29 09:27:50 +02:00
Marco Pivetta dfa6ff64c4 DDC-1939 - Removing references to non-existing AssociationMapping class 2012-07-29 09:27:50 +02:00
Benjamin Eberlei bcbef5670c Merge branch 'DDC-1939' 2012-07-29 09:27:20 +02:00
Benjamin Eberlei 354fa14df4 [DDC-1939] Add test for persistent collection delete with composite key 2012-07-29 09:27:08 +02:00
Igor Wiedler afd8ea91e3 [2.3] Use HelperSet in cli-config.php 2012-07-29 09:09:17 +02:00
Benjamin Eberlei ef27721db2 Merge remote-tracking branch 'origin/2.3' into 2.3 2012-07-29 09:08:39 +02:00
Benjamin Eberlei 13d32e6de5 Merge remote-tracking branch 'origin/2.3' into 2.3 2012-07-29 09:08:19 +02:00
Benjamin Eberlei bd1e6ac309 Merge pull request #410 from igorw/helper-set
[2.3] Use HelperSet in cli-config.php
2012-07-29 00:05:45 -07:00
Benjamin Eberlei 14bd794960 Merge pull request #411 from stof/new_types
Added the new DBAL 2.3 types in the EntityGenerator typehint map
2012-07-29 00:04:03 -07:00
Christophe Coevoet 369a30ad3d Added the new DBAL 2.3 types in the EntityGenerator typehint map 2012-07-29 09:02:35 +02:00
Christophe Coevoet cebb820030 Added the new DBAL 2.3 types in the EntityGenerator typehint map 2012-07-27 10:34:59 +02:00
Guilherme Blanco ac9df05c92 Fixed is_subclass_of comparing an interface which brought our requirement to 5.3.9. Changed to reflection approach which still keep us at the same dependency as before. 2012-07-26 22:01:37 +02:00
Guilherme Blanco 04e6cc78cd Fixed is_subclass_of comparing an interface which brought our requirement to 5.3.9. Changed to reflection approach which still keep us at the same dependency as before. 2012-07-26 15:50:51 -04:00
Igor Wiedler 2158a0788e [2.3] Use HelperSet in cli-config.php 2012-07-26 19:24:53 +02:00
Johannes M. Schmitt fc4a07c2b3 added failing test for refresh with eager fetching 2012-07-26 12:54:58 +02:00
Guilherme Blanco 2389f77d91 Fixed DefaultRepositoryClassName which should follow the Persistence interface, not ORM class. 2012-07-25 19:54:11 +02:00
Guilherme Blanco 1eaa822d2a Merge branch 'master' of github.com:doctrine/doctrine2 2012-07-25 01:24:33 -04:00
Guilherme Blanco 9dd3b66fe6 Fixed DefaultRepositoryClassName which should follow the Persistence interface, not ORM class. 2012-07-25 01:23:52 -04:00
Fabio B. Silva 1369e3d133 change ticket/group 2012-07-24 14:34:27 +02:00
Fabio B. Silva 50dac4096a give FQCN to NamingStrategy#propertyToColumnName 2012-07-24 14:34:27 +02:00
Marco Pivetta aa0cb0b6d7 DDC-1939 - Removing references to non-existing AssociationMapping class 2012-07-24 11:37:57 +02:00
Guilherme Blanco 5b55739990 Moved implementation from EntityRepository to EntityManager. This decouples ER implementation from EM, as it should be. 2012-07-24 00:23:59 +02:00
Christophe Coevoet 3e53d9d79c Changed commands to use command.name in the help 2012-07-24 00:21:31 +02:00
Guilherme Blanco 619d29adb2 Merge pull request #400 from stof/command_help
Changed commands to use command.name in the help
2012-07-22 22:04:15 -07:00
Guilherme Blanco 68adc7fed3 Merge pull request #403 from Ocramius/DDC-1925
DDC-1925 tests
2012-07-22 22:02:13 -07:00
Guilherme Blanco 98c4833afc Merge pull request #404 from Ocramius/DDC-1933
DDC-1933 - Fixing cloning of QueryBuilder and adding related tests
2012-07-22 22:01:35 -07:00
Guilherme Blanco e5979b5ef2 Moved implementation from EntityRepository to EntityManager. This decouples ER implementation from EM, as it should be. 2012-07-23 00:52:41 -04:00
Marco Pivetta fb3c6f0e8f DDC-1933 - Fixing cloning of QueryBuilder and adding related tests 2012-07-21 20:34:20 +02:00
Marco Pivetta 5b3eee8071 DDC-1925 - squashing ticket tests into a single file 2012-07-20 00:03:39 +02:00
Marco Pivetta 81f97e92d3 Adding tests for DDC-1925 2012-07-19 22:00:56 +02:00
Benjamin Eberlei 93cef61270 Fix DBAL dependency range evaluated as AND, not as OR 2012-07-18 11:23:20 +02:00
Christophe Coevoet a723b73929 Changed commands to use command.name in the help 2012-07-17 00:55:09 +02:00
Benjamin Eberlei 34ac207b3c Bump Version to 2.4.0-DEV 2012-07-16 15:25:20 +02:00
Benjamin Eberlei c8fcd3f8a5 Bump dependencies 2012-07-16 15:24:04 +02:00
Benjamin Eberlei a0ba420969 Bump dev version to 2.3.0 2012-07-16 15:23:33 +02:00
Benjamin Eberlei 816f709950 Release 2.3.0-BETA1 2012-07-16 15:23:33 +02:00
Benjamin Eberlei e0455b5550 Merge pull request #397 from Ocramius/cleanup/removing-deprecated-metadata-drivers
Cleanup/removing deprecated metadata drivers
2012-07-12 00:29:41 -07:00
Guilherme Blanco fcff39571f Merge pull request #399 from Adel-E/patch-1
Fix phpdocs
2012-07-11 15:50:35 -07:00
Adel 51cd553de8 Fix phpdocs 2012-07-11 22:44:07 +00:00
Marco Pivetta 75276e453e Restoring class names extending the Doctrine\Common implementation for BC compatibility 2012-07-10 13:57:33 +02:00
Marco Pivetta a2e00a96cc Reverting change on referenced DBAL commit 2012-07-10 02:59:33 +02:00
Marco Pivetta 915da58fb7 Adding upgrade notes about the BC Break 2012-07-10 02:51:55 +02:00
Marco Pivetta f3aae5de0e Removing tests moved to Doctrine\Common 2012-07-10 02:48:28 +02:00
Marco Pivetta 01f058953b Removing DriverChain and using Doctrine\Common implementation instead 2012-07-10 02:47:08 +02:00
Marco Pivetta e2c1d7c38a Removing deprecated StaticPHPDriver and PHPDriver
modifying tests so that the new implementation in Doctrine\Common is referenced
2012-07-10 02:31:30 +02:00
Benjamin Eberlei 113c6f51c2 Merge pull request #381 from doctrine/DDC-1637
[DDC-1637] Collection Filtering API
2012-07-09 08:16:31 -07:00
Benjamin Eberlei b2385e0afa [DDC-1637] Implementation of Criteria Collections API for
PersistentCollection (OneToMany only) and EntityRepository.
2012-07-09 09:59:48 +02:00
Benjamin Eberlei 4aafeaf7a6 Fix test on PostgreSQL 2012-07-09 09:55:41 +02:00
Benjamin Eberlei fe292cc503 Merge pull request #392 from widop/patch-1
Invalid paginator query cloning
2012-07-08 09:34:09 -07:00
Benjamin Eberlei 3b04cf5b2f Merge pull request #396 from Ocramius/DDC-1893
DDC-1893 - Updating configuration to reflect latest Doctrine Common changes
2012-07-08 09:26:15 -07:00
Benjamin Eberlei f3f1091b44 Merge branch 'DDC-1657' 2012-07-08 18:22:59 +02:00
Benjamin Eberlei 6e924f2a2c [DDC-1657] Prove that DBAL changes also work in ORM, not leading to drop sequence statements on postgresql with SERIAL pks. 2012-07-08 18:22:38 +02:00
Marco Pivetta 346e34adf6 Reverting to default annotation driver with - delayed to 3.0 2012-07-08 17:33:50 +02:00
Marco Pivetta 245d906ebf Adding parameter to allow switching annotation reader implementation 2012-07-08 17:17:32 +02:00
Benjamin Eberlei eaae1f222f Fix PostgreSQL test-failure. UnitOfWork#getEntityState() produced exists() queries because of unmanaged entity passed as parameter to AbstractQuery#setParameter(), thereby skewing the sql count 2012-07-08 16:57:40 +02:00
Marco Pivetta b67140f73c Cleaning up description of the BC Break 2012-07-08 16:49:54 +02:00
Marco Pivetta 7c2e5ae5b2 Adding tests for configuration object (also to ensure defaults for BC break early discovery) 2012-07-08 16:32:27 +02:00
Marco Pivetta fc00d5f39f Updating upgrade docs and fixes suggested by @beberlei 2012-07-08 16:32:27 +02:00
Marco Pivetta 86dbddd596 Updating to reflect latest Doctrine Common changes
Also, changing logic so that the SimpleAnnotationReader is no more the
default one. An additional parameter for the method will allow using it.

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

  2) Changed the language and formatting of the task to be more user-friendly.
2011-06-03 08:02:51 -05:00
Miha Vrhovnik bf0775fbb6 Add extension points into the xml schema 2011-06-03 09:12:32 +02:00
Alexander 7ee8dc4e44 DDC-1179 - Make it possible to specify a namespace when mapping with --from-database 2011-06-02 21:45:03 +02:00
chesteroni 23540c17f1 Added checking for existing indexes in associatation mapping array. 2011-05-28 20:57:19 -07:00
Miha Vrhovnik bb873826ca Fixing Notice: Undefined index: orderBy in ...Doctrine/ORM/Tools/Export/Driver/YamlExporter 2011-05-27 08:43:29 +02:00
Guilherme Blanco 93521217a6 Moved getQuoted* from ClassMetadata to ClassMetadataInfo, since SchemaTool relies on them, making impossible to work with DisconnectedClassMetadataFactory. 2011-05-26 02:18:29 -03:00
Christophe Coevoet 693fc090b5 Updated the EntityGenerator to be compatible with Common 3.0.x 2011-05-25 12:35:54 +02:00
Benjamin Eberlei ca6ea65b1f Merge branch 'NewAnnotations' 2011-05-25 00:36:10 +02:00
Benjamin Eberlei 3adbf0de39 Add forward compatibility with Doctrine Common 3.0 2011-05-25 00:35:57 +02:00
Johannes Schmitt a0d79b03e7 [AnnotationDriver] compatibility with Doctrine Common 3.x 2011-05-25 00:32:55 +02:00
Benjamin Eberlei 2b3d0a209c Merge branch 'NewAnnotations' 2011-05-25 00:26:29 +02:00
Benjamin Eberlei 6d724ad9ff Make ORM forward compatible with new Doctrine Annotations library version 2.1 2011-05-25 00:26:20 +02:00
Benjamin Eberlei 0bb0937372 Started UPGRADE_TO_2_1 document 2011-05-20 21:13:25 +02:00
Benjamin Eberlei bc4e14a99f Prototype for a proxy extension that avoids loads when calling for a getter that is named after an identifier. 2011-05-20 20:50:03 +02:00
Alexander cec62db2d8 Removed _ prefix from private functions. 2011-05-20 16:53:35 +02:00
Alexander 262ae7c942 Implemented tableName -> className and columnName -> fieldName mapping in
DatabaseDriver.
2011-05-20 16:36:43 +02:00
Benjamin Eberlei 85fb1a3ebb Merge branch 'master' of github.com:doctrine/doctrine2 2011-05-18 19:37:32 +02:00
Benjamin Eberlei a979852ee6 Merge branch 'DDC-1080' 2011-05-17 23:42:39 +02:00
Benjamin Eberlei 9ea03de84f DDC-1080 - Fix bug with hydration of derived entities/foreign key as primary key. 2011-05-17 23:42:24 +02:00
Benjamin Eberlei 9f01e9563f Bump Dev Version to 2.1.0BETA2-DEV 2011-05-16 19:35:00 +00:00
Benjamin Eberlei f4021e7469 Update Doctrine Common to latest version and add new methods to ClassMetadataInfo 2011-05-16 20:42:38 +02:00
Benjamin Eberlei 5d81e867be Add some logic to keep backwards compatibility in QueryBuilder 2011-05-15 23:16:44 +02:00
Benjamin Eberlei 85d40847ac Reintroduce QueryBuilder::getRootAlias() for backwards compatibility reasons, mark as @deprecated 2011-05-15 22:11:10 +02:00
Benjamin Eberlei 5e938b3147 Revert "Implemented auto-inference of isCascadeRemove when orphanRemoval is defined (marked as todo)."
This reverts commit 551247d11a.
2011-05-15 20:39:55 +02:00
Benjamin Eberlei 2cfdf2b05d Merge branch 'master' of github.com:doctrine/doctrine2 2011-05-15 20:18:47 +02:00
Benjamin Eberlei d45f7c1302 DDC-694 - Add info command 2011-05-15 20:18:31 +02:00
Benjamin Eberlei 34ad2ccbf1 Merge pull request #23 from kertz/master
LifecycleCallbackMethods Beautification
2011-05-15 10:40:23 -07:00
Benjamin Eberlei 83372bd144 Merge pull request #23 from kertz/master
LifecycleCallbackMethods Beautification
2011-05-15 10:39:44 -07:00
Benjamin Eberlei 1b4f0a5e1f DDC-1080 - Add failing testcase 2011-05-14 13:32:12 +02:00
Benjamin Eberlei 14d630ae1c Merge branch 'DDC-1151' 2011-05-14 08:44:49 +02:00
Benjamin Eberlei cb3615ab47 DDC-1151 - Fix missing table quotes when adding foreign keys in SchemaTool 2011-05-14 08:44:19 +02:00
Benjamin Eberlei e66970b78b Merge branch 'master' of github.com:doctrine/doctrine2 2011-05-14 08:16:21 +02:00
Guilherme Blanco 2a7364bb18 We now support @Id on @ManyToOne fields. Removed TODO and associated code. 2011-05-14 00:53:22 -03:00
Guilherme Blanco f4d62b317e Fixed endless recursion of DDC-719 test. 2011-05-14 00:49:46 -03:00
Guilherme Blanco 551247d11a Implemented auto-inference of isCascadeRemove when orphanRemoval is defined (marked as todo). 2011-05-14 00:43:33 -03:00
Guilherme Blanco 08f2af489e Changed QueryBuilder to allow retrieval of all defined root alises. 2011-05-14 00:40:23 -03:00
Guilherme Blanco e538128645 [DDC-1029] renaming "load()" in proxy to "__load()" 2011-05-13 00:23:27 -03:00
Guilherme Blanco 1e9e2de737 [DDC-1122] Added coverage for bug report. 2011-05-13 00:12:05 -03:00
Guilherme Blanco 8e3fdc5adc [DDC-1148] Implement auto-inference of types in setParameter. 2011-05-12 23:05:45 -03:00
Benjamin Eberlei 814473c27d Merge pull request #35 from brikou/master
[DDC-1136] prevent backup file to be recognized as valid Entity file
2011-05-12 05:41:31 -07:00
Guilherme Blanco a45a02fd64 Merge branch 'master' of github.com:doctrine/doctrine2 2011-05-11 21:40:43 -03:00
Guilherme Blanco 905e05cd36 [DDC-1067][DDC-1145] Fixed bug with multiple froms and inclusion of joins. Added support for index by in QueryBuilder. This break BC only if users are using base support (->add). 2011-05-11 21:40:27 -03:00
Benjamin Eberlei 75b69f946d Merge pull request #57 from stof/DDC-1146
[DDC-1146] Updated the Symfony2 vendors
2011-05-11 16:14:25 -07:00
Christophe Coevoet a112be79ef [DDC-1146] Updated the Symfony2 vendors 2011-05-12 01:10:34 +02:00
Guilherme Blanco 54a0109d5d [DDC-1147] Allowed usage of 0-based input parameters in DQL. 2011-05-11 17:30:42 -03:00
Guilherme Blanco 0d0d61935f Merge pull request #53 from Garfield-fr/master
Fixed typo
2011-05-08 05:18:46 -07:00
Bertrand Zuchuat b959ab37bf Typo 2011-05-08 13:57:08 +02:00
Guilherme Blanco b025b2b343 Fixed where componentes (ie. MEMBER OF) that that are sensitive to parenthesis presence. Made OR and AND expressions smarter. Fixed related unit tests. 2011-05-07 20:14:04 -03:00
Guilherme Blanco bffca232e2 Merge branch 'master' of github.com:doctrine/doctrine2 2011-05-06 01:42:01 -03:00
Guilherme Blanco 19dfe7b891 Added method to allow retrieve all registered entity namespace aliases. 2011-05-06 01:41:34 -03:00
Benjamin Eberlei ce1e446227 Merge branch 'master' of github.com:doctrine/doctrine2 2011-05-03 17:06:42 +02:00
Benjamin Eberlei 5d1905de13 DDC-1120 - Fix comment 2011-05-01 12:17:09 +02:00
Benjamin Eberlei 23131d6860 Merge branch 'DDC-1129' 2011-05-01 11:45:39 +02:00
Benjamin Eberlei d4569baa11 [DDC-1129] Fix bug in version changeset computation aswell as inline ClassMetadata::isCollectionValuedAssociation to increase performance by 2-5% 2011-05-01 11:44:31 +02:00
Benjamin Eberlei b5520aa304 Merge branch 'DDC-1091' 2011-05-01 11:01:39 +02:00
Benjamin Eberlei c53baa9935 [DDC-1091] Fix bug with custom string functions in StringPrimary 2011-05-01 11:01:30 +02:00
Benjamin Eberlei d0b95bb31c Merge branch 'DDC-1043' 2011-05-01 10:21:59 +02:00
Benjamin Eberlei 7a068c206e DDC-1043 - Make computeChangeSet() algorithm more strict, possible leading to more updates to to values that are not exactly the same. However this is necessary to avoid bugs with certain PHP casting rules, i.e. +44 = 44 2011-05-01 10:21:47 +02:00
Benjamin Eberlei 5a6ac2fb56 Merge branch 'DDC-1102' 2011-05-01 10:01:49 +02:00
Benjamin Eberlei 6b3dfaccfc DDC-1102 - Typo in EntityGenerator 2011-05-01 10:01:38 +02:00
Benjamin Eberlei e3d2a0e293 Merge branch 'PR39' 2011-05-01 00:18:22 +02:00
Francis Besset a141aaf663 [PR-39] Throw exception when hydrating joined entity without existing parent alias (NativeQuery problem only) 2011-05-01 00:17:40 +02:00
Benjamin Eberlei 85d6b9fd39 Merge pull request #42 from mridgway/DDC-1059.
DDC-1059: RSM Helper
2011-04-30 15:01:25 -07:00
Benjamin Eberlei e9067eb4a3 Merge branch 'DDC-1149' 2011-04-30 23:52:10 +02:00
Fabien Potencier 0c955fe54f Fix namespace/class parsing in the entity generator 2011-04-30 23:51:22 +02:00
Benjamin Eberlei ea5a623c88 Merge branch 'DDC-1094' 2011-04-30 23:18:48 +02:00
Benjamin Eberlei 73c7605a5c [DDC-1094] Add support for limit, offset and orderby in EntityRepository::findBy(). 2011-04-30 23:18:24 +02:00
Benjamin Eberlei 0b1077a3b3 Merge branch 'DBAL-115' 2011-04-30 17:16:47 +02:00
Benjamin Eberlei 5179ff921b [DBAL-115] REALLY fix issues with SchemaTool::getDropSchemaSQL(). 2011-04-30 17:16:34 +02:00
Benjamin Eberlei abbb3e8656 Merge branch 'DBAL-115' 2011-04-30 16:20:32 +02:00
Benjamin Eberlei 1f665e6ba8 [DBAL-115] Bugfix in SchemaTool not quoting table names when dropping schema. 2011-04-30 16:20:14 +02:00
Benjamin Eberlei d72217a00a Merge branch 'DDC-1133' 2011-04-30 14:23:59 +02:00
Benjamin Eberlei 261d3c892e DDC-1133 - Ducktype AnnotationReader in AnnotationDriver 2011-04-30 14:23:46 +02:00
Benjamin Eberlei 2c50faf5b2 Merge branch 'DDC-1109' 2011-04-30 12:49:52 +02:00
Benjamin Eberlei 7dd0dd273e [DDC-1109] ltrim discriminator map for convenience. 2011-04-30 12:49:37 +02:00
Benjamin Eberlei b462cfbe2b Merge branch 'DDC-1108' 2011-04-30 12:27:35 +02:00
Benjamin Eberlei 67b89eaa4f [DDC-1108] Fix bug with single char named input parameters in DQL lexer. 2011-04-30 12:27:16 +02:00
Benjamin Eberlei ed355d2eb6 Merge branch 'master' of github.com:doctrine/doctrine2 2011-04-30 11:19:58 +02:00
Benjamin Eberlei c6d725d6e8 Merge branch 'DDC-1132' 2011-04-30 11:16:41 +02:00
Benjamin Eberlei 42230a4c51 [DDC-1132] Fix many to many table detection. 2011-04-30 11:16:30 +02:00
Benjamin Eberlei 7929aea45a Merge branch 'DDC-1132' 2011-04-30 11:15:56 +02:00
Benjamin Eberlei f09d299660 [DDC-1132] Fix many to many table detection. 2011-04-30 11:15:45 +02:00
Benjamin Eberlei 41b3a372d3 Add new performance test checking compute changeset performance. 2011-04-30 10:47:56 +02:00
Guilherme Blanco 7aaecacc5b Merged pull request #36 from ajessu/fixTypo.
Fix typos on the help text of the schema commands
2011-04-26 18:12:32 -07:00
Guilherme Blanco 237a05b302 Merged pull request #44 from Chekote/parser_match_phpdoc_fix.
Parser::match phpdoc fix
2011-04-26 18:09:27 -07:00
Guilherme Blanco f73c7f3be0 Merged pull request #48 from rdohms/master.
Fixing docblocks in SchemaTool
2011-04-26 18:05:59 -07:00
Guilherme Blanco fe66d8bc04 Fixed SchemaTool which was failing to dropSchema due to foreignKeyContraint checks. Fixes DDC-1126 2011-04-26 12:32:04 -03:00
Guilherme Blanco 26bd3e3811 Implemented support for closure return on EntityManager::transactional. Fixes DDC-1125 2011-04-25 18:32:43 -03:00
Rafael Dohms 0b7feb359d Fixing outdated docblocks for SchemaTool 2011-04-17 23:39:59 -03:00
Michael Ridgway af4cf0d0ba Replaced prefix parameter with renamedColumns; Added exception when duplicate columns found 2011-04-14 20:55:03 -04:00
Guilherme Blanco 4d561651a1 Merge branch 'master' of github.com:doctrine/doctrine2 2011-04-13 00:11:08 -03:00
Benjamin Eberlei 7e3265e7c7 Merge branch 'DDC-1040' 2011-04-03 23:06:15 +02:00
Benjamin Eberlei 822481d360 [DDC-1040] Add regression tests for entity as multiple named/positional parameters. 2011-04-03 23:06:03 +02:00
Benjamin Eberlei 7905f2a972 [DDC-1040] Bugfix with named parameters and multiple entities passed as parameter. 2011-04-03 23:03:39 +02:00
Benjamin Eberlei 88dc18f88a Merge branch 'DDC-1093' 2011-04-03 20:29:15 +02:00
Benjamin Eberlei e685d59604 [DDC-1093] Fix docblock type hint 2011-04-03 20:29:07 +02:00
Benjamin Eberlei 300df03743 Merge branch 'DDC-1087' 2011-04-03 09:05:20 +02:00
Benjamin Eberlei a329007526 [DDC-1087] Add missing resolution to IS NULL in EntityRepository when passing a null value as a criteria. 2011-04-03 09:03:43 +02:00
Chekote 5784c7bacd Fixed phpdoc on Parser::match incorrectly stating that the token parameter can be a string value 2011-04-01 12:54:12 -05:00
Benjamin Eberlei db82ef3e61 Merge branch 'DDC-991' 2011-03-31 23:35:12 +02:00
Benjamin Eberlei ea52b3cc8f [DDC-991] Rename method to AbstractQuery::getOneOrNullResult(). 2011-03-31 23:35:01 +02:00
Benjamin Eberlei 24a7a72f59 [DDC-991] add AbstractQuery::getOneResult() method that returns null instead of throwing an exception as getSingleResult() does. 2011-03-31 23:32:49 +02:00
Michael Ridgway b1b17376ff Removing left over class import 2011-03-31 17:22:13 -04:00
Michael Ridgway c46d835146 Moved new functions to ResultSetMappingBuilder class 2011-03-30 10:27:31 -04:00
Michael Ridgway 20dc72ef9a First pass on RSM helper functions for adding entities 2011-03-29 20:35:01 -04:00
Benjamin Eberlei e9c4f612cf Merge branch 'DDC-692' 2011-03-29 20:17:56 +02:00
Benjamin Eberlei 34ad308599 [DDC-692] Add respective metadata mapping possiblities for read-only entities and a test. 2011-03-29 20:17:44 +02:00
Benjamin Eberlei 9a75277dd4 [DDC-692] Add ClassMetadataInfo::isReadOnly flag and ignore these entities in Change Tracking. 2011-03-29 20:04:14 +02:00
Benjamin Eberlei 003ab06465 Merge branch 'DDC-696' 2011-03-29 19:43:41 +02:00
Benjamin Eberlei 36985ee704 Merge remote branch 'mridgway/DDC-696' into DDC-696 2011-03-29 19:42:38 +02:00
Benjamin Eberlei 21acb67b01 Merge branch 'DDC-1077' 2011-03-27 21:11:30 +02:00
Benjamin Eberlei bda15231da [DDC-1077] Bugfix in not handling literals in Select Expressions. 2011-03-27 21:10:50 +02:00
Benjamin Eberlei 5022b04ff9 Merge branch 'DDC-1079' 2011-03-27 14:05:08 +02:00
Benjamin Eberlei 6ed0ff0a12 [DDC-1079] Bugfix for shortcut for ArithmeticExpressions in SimpleSelectExpression that lead to literals not being valid. Problem was that ScalarExpression() did not handle AggregateExpressions() at all, which is now fixed. 2011-03-27 14:04:53 +02:00
Benjamin Eberlei 789739f3e4 Merge branch 'DDC-1014' 2011-03-27 12:19:31 +02:00
Benjamin Eberlei 4f1af0114f [DDC-1014] Add DATE_ADD(), DATE_SUB(), DATE_DIFF() functions for DQL. 2011-03-27 12:18:47 +02:00
Benjamin Eberlei 5d1b4f98de [DDC-1014] Update DBAL remote to include date arithmetics related functionality. 2011-03-27 11:34:14 +02:00
Michael Ridgway 706cc838e5 Removed svn variable 2011-03-22 08:54:33 -04:00
Michael Ridgway 17cbb34952 Clean up of test case 2011-03-21 23:30:10 -04:00
Michael Ridgway 1f50dee8a8 DDC-696: Added onClear event 2011-03-21 23:17:08 -04:00
Benjamin Eberlei e126315c1b Bump DBAL dependency to include Security Fix for AbstractPlatform::modifyLimitQuery() 2011-03-21 23:54:40 +01:00
Benjamin Eberlei ccb5c57784 Merge branch 'DDC-992' 2011-03-20 17:07:31 +01:00
Benjamin Eberlei 7a41a205ee [DDC-992] Fix criteria usage of column names clashing with field or associations by prefixing with table names or alias. 2011-03-20 17:07:19 +01:00
Benjamin Eberlei 8430aefe21 Merge branch 'DDC-1053' 2011-03-20 14:07:44 +01:00
Benjamin Eberlei edfdbe10a0 [DDC-1053] Fix bug with usage of identification variables in GroupByItem. 2011-03-20 14:07:33 +01:00
Benjamin Eberlei 108ceae313 Merge branch 'DDC-1052' 2011-03-20 13:07:55 +01:00
Benjamin Eberlei e42a227a7c [DDC-1052] Fix bug with versioning and inheritance 2011-03-20 13:07:47 +01:00
Benjamin Eberlei 7e262dd42c Merge branch 'DDC-1068' 2011-03-20 12:36:03 +01:00
Benjamin Eberlei ac175d2c40 [DDC-1068] Fix case-sensitivity problems of first loading of Metadata. 2011-03-20 12:35:52 +01:00
Benjamin Eberlei c77dbd859b [DDC-1070] Fix global test state problem introduced with test. 2011-03-20 12:25:27 +01:00
Benjamin Eberlei efe26d00a1 Merge branch 'DDC-1070' 2011-03-20 12:19:12 +01:00
Benjamin Eberlei 62755cc647 [DDC-1070] Fix in AbstractQuery::iterate() method not respecting hydrator and parameters. 2011-03-20 12:19:01 +01:00
Guilherme Blanco 8c8a658dfd Merge branch 'master' of github.com:doctrine/doctrine2 2011-03-19 14:36:29 -03:00
Benjamin Eberlei 53ca54ced6 Merge branch 'master' of github.com:doctrine/doctrine2 2011-03-16 23:01:17 +01:00
Benjamin Eberlei e757e3beaf Merge branch 'DDC-952' 2011-03-16 23:00:57 +01:00
Benjamin Eberlei 5192306d39 [DDC-952] One last commit with some refactorings, additional comments and two new tests. Also added convenience method Query::setFetchMode($className, $assocName) 2011-03-16 22:51:32 +01:00
Benjamin Eberlei 4b98e3ea8e DDC-952 - Remove unnecessary instance variable and comment on one feature. 2011-03-16 00:03:43 +01:00
Benjamin Eberlei b7e522d7a7 DDC-952 - This nasty inheritance hydration bug slipped in again, fixed again now. 2011-03-15 23:39:19 +01:00
Benjamin Eberlei 6d27b4760f [DDC-952] Add Persister hydration performance tests. 2011-03-15 23:22:37 +01:00
Benjamin Eberlei 1b46208aa5 [DDC-952] More fixes 2011-03-15 21:34:47 +01:00
Benjamin Eberlei b3c01903b4 DDC-952 - Optimization 2011-03-15 20:03:05 +01:00
Benjamin Eberlei a04ba44874 [DDC-952] Introduced SimpleObjectHydrator again for performance reasons. 2011-03-15 19:48:04 +01:00
brikou 9a8e8ce35d Edited lib/Doctrine/ORM/Tools/EntityGenerator.php via GitHub 2011-03-15 05:39:38 -07:00
Albert Jessurum 234d2e5f0f Fix typo on schema help messages 2011-03-15 12:22:53 +01:00
Guilherme Blanco 180078d0f6 Added namedQueries as optional during serialization of ClassMetadata. 2011-03-14 01:04:50 -03:00
Benjamin Eberlei 38ad25ad4c [DDC-952] Remove all the unnecessary hydration code from all Persisters. 2011-03-13 00:23:46 +01:00
Benjamin Eberlei 1bc4b62805 [DDC-952] Make collection loading work with hydrators also. 2011-03-13 00:15:50 +01:00
Benjamin Eberlei 7c7106b1c1 DDC-952 - Fix bug in inverse one-to-one eager loading sql code. 2011-03-12 19:11:37 +01:00
Benjamin Eberlei 4677883acd [DDC-952] Added modelset and tests for Eager Loading, detected a bug with inverse one-to-one eager fetching that needs to be addressed. 2011-03-12 14:01:51 +01:00
Benjamin Eberlei 8794d35867 DDC-952 - Woah this still needs tons of tests. 2011-03-09 23:30:35 +01:00
Benjamin Eberlei 595c19207c [DDC-914] Always fetch joining inverse side one-to-one associations breaks a ton of DDC-117 tests, investigate why to make this working also. 2011-03-09 23:21:33 +01:00
Benjamin Eberlei 077ae9cee9 [DDC-914] Fetch join many-to-one/one-to-one associations configured as FETCH_EAGER inside the persisters. 2011-03-09 23:14:54 +01:00
Guilherme Blanco 925f1c281c Merge branch 'NamedQueries' 2011-03-09 14:44:56 -03:00
Guilherme Blanco 7d1fca1ca2 Added support to NamedQueries through ClassMetadata. 2011-03-09 14:43:42 -03:00
Benjamin Eberlei fd502631c7 DDC-734 - REname query hint to fetchEager. 2011-03-08 22:28:55 +01:00
Benjamin Eberlei 60eb755fe9 DDC-952, DDC-734 Add DQL query hint to switch associations from lazy to eager for deferred initialization optimizations. 2011-03-08 22:22:54 +01:00
Guilherme Blanco a31289b9d7 Added support to NamedQueries through ClassMetadata. 2011-03-06 18:45:09 -03:00
Benjamin Eberlei 112f9d1480 [DDC-1050] Change refresh of collection back 2011-03-06 21:49:02 +01:00
Benjamin Eberlei 851f44a066 [DDC-952] [DDC-1050] Use ObjectHydrator inside Persisters, removing a bunch of duplicate code (step1, more necessary) 2011-03-06 21:26:54 +01:00
Benjamin Eberlei d9c8a9eecb [DDC-952] Fix merge/rebase mistake. 2011-03-06 15:28:26 +01:00
Benjamin Eberlei 03630df20d Add support for IN(?) queries in repositories using the DBAL support for parameter lists. 2011-03-06 11:15:56 +01:00
Benjamin Eberlei 3d37e436dd DDC-952 - Refactor eager loading entities, it is only allowed for non composite primary key entities. 2011-03-05 11:09:38 +01:00
Benjamin Eberlei 32df9451fd DDC-952 - Implemented first approach for batching eager loads of ToOne associations. 2011-03-05 11:08:41 +01:00
Benjamin Eberlei e0b835178b Bump dependency of ORM master to DBAL 2.0.2 2011-03-05 10:09:16 +01:00
Benjamin Eberlei 78aa893efd Adjust tests to changes in DBAL dependency with regard to automatic foreign key and index naming. 2011-03-05 10:08:30 +01:00
Benjamin Eberlei 8c7261e7c3 Optimize build process even more, now generating PEAR Packages for Symfony YAML and Console. 2011-03-05 00:18:10 +01:00
Benjamin Eberlei ae61272c13 Merge branch 'DDC-1034' 2011-03-04 23:01:02 +01:00
Benjamin Eberlei 67ae22b911 DDC-1034 - Fix bug where callbacks where registered multiple times in inheritance hierachies. 2011-03-04 23:00:54 +01:00
Benjamin Eberlei c0d26f2308 Merge branch 'DDC-1056' 2011-03-04 22:22:19 +01:00
Benjamin Eberlei d58ae2ecda DDC-1056 - Fixed notice in StaticPHPDriver. 2011-03-04 22:22:07 +01:00
Benjamin Eberlei 1d5fef4144 Merge branch 'DDC-1041' 2011-03-03 23:11:24 +01:00
Benjamin Eberlei 49195ebe17 [DDC-1041] You could retrieve instances of the wrong type in inheritance hierachies because the identity map aggregates them by rootEntityName. 2011-03-03 23:11:09 +01:00
Benjamin Eberlei 9a33bd083d Merge branch 'DDC-1050' 2011-03-03 22:52:13 +01:00
Benjamin Eberlei b2c7a9c7fc [DDC-1050] Throw exception when trying to define inheritance information on a mapped superclass. It is not a valid use-case. 2011-03-03 22:51:53 +01:00
Benjamin Eberlei 8b9f12d924 Remove copied code of Symfony Console/Yaml and added submodules. 2011-02-28 21:51:56 +01:00
Benjamin Eberlei 521705a0f2 Merge branch 'DDC-1033' 2011-02-26 12:48:10 +01:00
Benjamin Eberlei c144df9be3 DDC-1033 - Fix cloning of not initialized proxies. 2011-02-26 12:47:59 +01:00
Benjamin Eberlei 1eb7f92956 DDC-1026 - Fix Result Cache Seperate chaining implementation that was wrong since DDC-892 was applied. 2011-02-26 00:39:54 +01:00
Romain Pouclet 9125413786 Fixed typo in AbstractQuery::execute() doc 2011-02-25 10:22:50 -06:00
Benjamin Eberlei afc9495b3f Revert "Merge branch 'DDC-884'"
This reverts commit 3eea19dcfa, reversing
changes made to b13c29944b.
2011-02-21 18:52:49 +01:00
Guilherme Blanco 3eea19dcfa Merge branch 'DDC-884' 2011-02-21 00:51:00 -03:00
Guilherme Blanco 04ab0cd8fc [DDC-884] Allow subclassing EntityManager. 2011-02-21 00:50:51 -03:00
Guilherme Blanco b13c29944b Merge branch 'DDC-1035' 2011-02-21 00:38:03 -03:00
Guilherme Blanco 68bb0c1ae1 [DDC-1035] Fixed orphanRemoval on YAML mapping driver. 2011-02-21 00:37:32 -03:00
Guilherme Blanco a18a7bb678 Merge branch 'DDC-1012' 2011-02-20 01:54:05 -03:00
Guilherme Blanco 834203d868 [DDC-1012] Implemented Expr isNull and isNotNull. 2011-02-20 01:53:55 -03:00
Guilherme Blanco 99c7924292 Merge branch 'DDC-1036' 2011-02-20 01:44:27 -03:00
Guilherme Blanco 505d9e2154 [DDC-1036] Modified the AggregateExpressions to support SimpleArithmeticExpression instead of StateFieldPathExpression. 2011-02-20 01:44:05 -03:00
Guilherme Blanco bca927f861 Merge branch 'DDC-982' 2011-02-20 01:31:12 -03:00
Guilherme Blanco 70d2cbe857 [DDC-982] Implemented more unique sql table alias. 2011-02-20 01:30:58 -03:00
Guilherme Blanco dcf358f154 Fixed some warnings from phpunit. 2011-02-19 19:50:58 -02:00
Guilherme Blanco 2b2d9e7a1d Fixed wrong test. It was failing if you have memcache extension loaded. 2011-02-19 17:20:37 -02:00
Jonathan H. Wage 328a5fe49a Updating to reverted version of common. 2011-02-16 10:25:29 -06:00
Jonathan H. Wage 839b6dd5e4 Revert "Removing old Driver interface in favor of the new one in Common\Persistence. Also changed to use fully qualified class name for interfaces in common to avoid weird aliases."
This reverts commit c988a99d55.
2011-02-16 10:24:42 -06:00
Jonathan H. Wage c988a99d55 Removing old Driver interface in favor of the new one in Common\Persistence. Also changed to use fully qualified class name for interfaces in common to avoid weird aliases. 2011-02-16 10:06:39 -06:00
Jonathan H. Wage a4a184b27c Implementing ClassMetadataFactory interface. 2011-02-15 21:00:48 -06:00
Jonathan H. Wage 68a4099684 Implementing initial Doctrine\Common\Persistence interfaces. 2011-02-15 20:02:45 -06:00
Benjamin Eberlei 64088fce5d Merge branch 'DDC-1030' 2011-02-13 10:02:34 +01:00
Benjamin Eberlei 35a152318e DDC-1030 - Fix Static Reflection with namespace levels deeper than one. 2011-02-13 10:02:18 +01:00
Benjamin Eberlei 3d0d31ddf8 Merge branch 'DDC-1024' 2011-02-12 17:40:16 +01:00
Benjamin Eberlei c456f27f60 DDC-1024 - Do not generate setter/getter for inherited fields. 2011-02-12 17:40:07 +01:00
Benjamin Eberlei 4ecb582c76 Update dependencies to Common 2.0.1 and DBAL 2.0.1 2011-02-05 11:46:35 +01:00
Benjamin Eberlei 7390030854 Merge branch 'DDC-250' 2011-02-05 11:44:00 +01:00
Benjamin Eberlei da2dee03e2 [DDC-250] Small typo fix in xsd 2011-02-05 11:43:50 +01:00
Benjamin Eberlei 9768d08458 [DDC-250] Add tests and fix some glitches and finalized index-by patch. 2011-02-05 11:42:10 +01:00
Benjamin Eberlei a9fe9f43e9 Merge branch 'DDC-1018' into DDC-250 2011-02-05 10:04:36 +01:00
Benjamin Eberlei 61e2cdc6b0 [DDC-1018] Bugfix: INDEX BY was not working in JOIN Declarations, only in FROM. 2011-02-05 10:04:18 +01:00
Benjamin Eberlei 60203af9b2 Merge branch 'DDC-1018' 2011-02-05 10:02:48 +01:00
Benjamin Eberlei 4532c2255a [DDC-1018] Bugfix: INDEX BY was not working in JOIN Declarations, only in FROM. 2011-02-05 10:02:37 +01:00
Benjamin Eberlei 17c1ed948e [DDC-250] Initial untested support for @ManyToMany(indexBy) and @OneToMany(indexBy) option. 2011-02-05 09:31:40 +01:00
Benjamin Eberlei 266d85e917 Merge branch 'DDC-1006' 2011-02-02 23:30:39 +01:00
Benjamin Eberlei 4122abf558 DDC-1008, DDC-1002 - Create constructor and id setter if necessary. 2011-02-02 23:30:16 +01:00
Benjamin Eberlei f9c1464879 DDC-1006, DDC-953 - Fix EntityGenerator creating empty classes 2011-02-02 23:21:42 +01:00
Benjamin Eberlei 277e0aee8c Merge remote branch 'origin/master' 2011-02-02 19:49:23 +01:00
Benjamin Eberlei 957aefe69e Merge branch 'DDC-892' 2011-01-23 20:54:36 +01:00
Benjamin Eberlei 3515df913f DDC-892 - Implement separate chaining approach for result caches to prevent hash colissions. 2011-01-23 20:54:29 +01:00
Benjamin Eberlei 8869678c0f Merge branch 'GenerationTools' 2011-01-23 20:26:37 +01:00
Benjamin Eberlei 05f41278a6 Significantly updated the Help of the ConvertMapping and GenerateEntities Commands to help people using and understanding their scope. Added an additional --force flag to ConvertMapping command. 2011-01-23 20:25:59 +01:00
Benjamin Eberlei 961cb6e9a3 Merge branch 'DDC-958' 2011-01-23 17:26:59 +01:00
Benjamin Eberlei ed53f8aa74 DDC-958 - Fire postLoad event when calling refresh(). 2011-01-23 17:26:11 +01:00
Benjamin Eberlei be2e00c991 Merge branch 'DDC-968' 2011-01-23 16:47:20 +01:00
Benjamin Eberlei f1809ce180 DDC-968 - Add AbstractQuery::getHints() method 2011-01-23 16:47:07 +01:00
Benjamin Eberlei 549965b4b2 Merge branch 'DDC-997' 2011-01-23 16:42:06 +01:00
Benjamin Eberlei f70ee3a038 DDC-997 - Fix bug in hydration that came up with DDC-117 2011-01-23 16:41:40 +01:00
Benjamin Eberlei 975d6ada66 Merge branch 'DDC-969' 2011-01-23 16:12:36 +01:00
Benjamin Eberlei a6e63d2676 DDC-969 - Use of field instead of column when accessing a table leads to error when both differ. 2011-01-23 16:12:26 +01:00
Benjamin Eberlei c5593be7c9 Merge branch 'DDC-978' 2011-01-23 15:40:34 +01:00
Benjamin Eberlei 65bbdc30de DDC-978 - Fix bug where Collection gets cleared (again) when calling flush multiple times and replacing a PersistentCollection with a new one. 2011-01-23 15:40:16 +01:00
Benjamin Eberlei 482ff2d009 Merge branch 'DDC-996' 2011-01-23 14:21:23 +01:00
Benjamin Eberlei fd44894e9a DDC-996 - Throw more useful exception if fieldName is empty in a mapped field or association. 2011-01-23 14:20:15 +01:00
Benjamin Eberlei 92ed05fc84 Merge branch 'DDC-960' 2011-01-23 12:49:20 +01:00
Benjamin Eberlei 5d333045b9 DDC-960 - Bugfix in how Persisters generate Fetch last version of Entity SQL. 2011-01-23 12:48:28 +01:00
Benjamin Eberlei bcafa19386 Merge branch 'DDC-975' 2011-01-13 21:43:47 +01:00
Benjamin Eberlei 03698e4068 DDC-975 - Fix notice in SchemaTool in combination with XML mapping driver. 2011-01-13 21:43:33 +01:00
Benjamin Eberlei fdee7a9ae0 Merge branch 'DDC-980' 2011-01-13 21:16:24 +01:00
Benjamin Eberlei 078e19d1c7 DDC-980 - Fix Update and Delete statements reference of the root table when doing subselects. 2011-01-13 21:16:08 +01:00
Benjamin Eberlei 7a2c99353a Merge branch 'DDC-546' 2011-01-02 15:14:40 +01:00
Benjamin Eberlei 3539b32629 DDC-546 - Found some more code that needs DDC-117 compliance. 2011-01-02 15:14:12 +01:00
Benjamin Eberlei 247fc43cef DDC-546 - Rename ClassMetadataInfo::FETCH_EXTRALAZY to ClassMetadataInfo::FETCH_EXTRA_LAZY 2011-01-02 15:10:47 +01:00
Benjamin Eberlei a3cab174ca DDC-546 - Updated with support for DDC-117. 2011-01-02 14:04:52 +01:00
Benjamin Eberlei 89e7e8623c DDC-546 - Remove dynamic public property approach in PersistentCollection::count() EXTRA_LAZY. 2011-01-02 13:43:49 +01:00
Benjamin Eberlei cbfdf61976 DDC-546 - Bugfix for PersistentCollection::count() in EXTRA LAZY special case. 2011-01-02 13:41:18 +01:00
Benjamin Eberlei 3acc05d953 DDC-546 - Fix bug in inverse many-to-many contains. 2011-01-02 13:37:29 +01:00
Benjamin Eberlei 685e327b43 DDC-546 - Fix some rebasing issues. 2011-01-02 12:54:55 +01:00
Benjamin Eberlei f572be92e2 DDC-546 - Add EXTRALAZY to doctrine-mapping.xsd enumeration of fetch-types. 2011-01-02 12:46:08 +01:00
Benjamin Eberlei 75d59d8695 DDC-546 - Added functionality for extra-lazy PersistentCollection::contains(). 2011-01-02 12:46:08 +01:00
Benjamin Eberlei 7c567b305a Refactor DDC-546 persister approach. 2011-01-02 12:46:08 +01:00
Benjamin Eberlei d3d9957fd4 DDC-546 - Fix some minor glitches in patch. 2011-01-02 12:44:16 +01:00
Benjamin Eberlei c998797c55 DDC-546 - Add Extra Lazy Collection prototype. 2011-01-02 12:44:16 +01:00
Benjamin Eberlei 78d4277e4b Merge branch DDC-117 into master 2011-01-02 12:01:05 +01:00
Benjamin Eberlei f3abf9a30a Merge branch 'DDC-965' 2011-01-02 10:24:38 +01:00
Benjamin Eberlei 9177dc3d52 DDC-965 - Defer ID check after loadMetata event is fired. 2011-01-02 10:24:23 +01:00
Benjamin Eberlei 34b303845f Merge branch 'DDC-966' 2011-01-02 10:18:23 +01:00
Benjamin Eberlei c1edd5848f DDC-966 - Fix NOT NULL constraint SingleTableInheritance Generation using SchemaTool. 2011-01-02 10:18:02 +01:00
Benjamin Eberlei ed7ec261d0 Merge branch 'DDC-949' 2011-01-02 09:42:15 +01:00
Benjamin Eberlei a2cc9f0f6d DDC-949 - Bugfix for BasicEntityPersister not using $types for select clauses. This fixes the issue for PostgreSQL however it still occurs on Oracle. DBAL change is necessary for this. 2011-01-02 09:38:32 +01:00
Benjamin Eberlei 2a005019bf DDC-117 - Add XML and YML Driver support for associated identifier. 2011-01-01 21:47:04 +01:00
Benjamin Eberlei c2bbaa9ead DDC-117 - Slight changes in the patch and fixing inline comments. 2011-01-01 18:53:22 +01:00
Benjamin Eberlei 194a90923d DDC-117 - Finalize patch, fix all the problems of different use-cases by hugely expanding the test-model. 2011-01-01 18:17:19 +01:00
Benjamin Eberlei e1ed0bf52a Merge branch 'DDC-945-2' 2010-12-31 14:39:13 +01:00
Benjamin Eberlei 7112b551e2 DDC-945 - Fix regression, ManyToMany unidirectional owning side assocations should be allowed. 2010-12-31 14:39:01 +01:00
Benjamin Eberlei 3498f4d6ee Merge branch 'DDC-929' 2010-12-30 23:18:14 +01:00
Benjamin Eberlei 8658376713 DDC-929 - Fix bug with DatabaseDriver not detecting indexes that are not called primary. 2010-12-30 23:18:00 +01:00
Benjamin Eberlei 7a40e3f6f2 Merge branch 'DDC-961' 2010-12-30 22:30:59 +01:00
Benjamin Eberlei 58019fbac0 DDC-961 - Bugfix with missing first letter in automatic join table names in global namespace entities. 2010-12-30 22:30:51 +01:00
Benjamin Eberlei 2d27a99a0b DDC-117 - Began to fix some issues surrounding the DDC-881 report and references to composite fk entities. 2010-12-29 01:02:21 +01:00
Benjamin Eberlei 337e2fa043 Fix DDC-795 (subtask of DDC-117) and integrated a test for cascade (that only works with sequence id generators). 2010-12-28 19:05:46 +01:00
Benjamin Eberlei e7b4dca611 Merge master into DDC-117 2010-12-28 17:27:47 +01:00
Benjamin Eberlei 1d5b24ecc5 Merge branch 'DDC-837' 2010-12-28 14:56:24 +01:00
Benjamin Eberlei 2d89ddfb1f DDC-837 - Fix bug with associations of the same name not being possible in inheritance hierachies. 2010-12-28 14:56:13 +01:00
Benjamin Eberlei eeca184836 Merge branch 'DDC-928' 2010-12-28 12:19:16 +01:00
Benjamin Eberlei 1d2b2b2c8b DDC-928 - Fix undefined variable notice. 2010-12-28 12:18:42 +01:00
Benjamin Eberlei 26bb7978b5 Merge branch 'DDC-945' 2010-12-28 12:00:07 +01:00
Benjamin Eberlei aa6ac3d6b0 DDC-945 - Throw exception in ClassMetadataFactory when mapped superclass has to many associations. 2010-12-28 11:59:51 +01:00
Benjamin Eberlei 1720527f81 Merge branch 'DDC-617' 2010-12-28 10:17:53 +01:00
Benjamin Eberlei fe672d2f61 DDC-617 - Throw error if selecting identification variables without picking at least one root entity alias. 2010-12-28 10:17:33 +01:00
Benjamin Eberlei d488e84d8d Merge branch 'DDC-931' 2010-12-22 22:06:02 +01:00
Benjamin Eberlei a4f88407c2 DDC-931 - SchemaTool#dropSchema() should not stop on failure of a single query (as stated in docblocks). 2010-12-22 22:04:11 +01:00
Benjamin Eberlei e46c65db09 Fix for DDC-944 2010-12-22 00:23:22 +01:00
Benjamin Eberlei 6988b55f50 Bump Dev Version to 2.1.0-DEV 2010-12-21 16:45:50 -05:00
Benjamin Eberlei 7def30f283 Update dependencies to Common 2.0 stable and DBAL 2.0 stable. 2010-12-21 22:39:26 +01:00
Benjamin Eberlei 22ffbe7488 Fix tests so that PostgreSQL does not fail anymore on certain test. 2010-12-21 22:33:23 +01:00
Benjamin Eberlei 988d229c07 Fix XSD Schema 2010-12-21 22:04:13 +01:00
Benjamin Eberlei 43c63765db Extend phing build.xml for upcoming release. 2010-12-20 23:34:28 +01:00
Amal Raghav b736c4216c _generateEntityLifecycleCallbackMethods Beautification 2010-12-17 16:51:51 +05:30
Benjamin Eberlei c03fc00f45 DDC-936 - Fix target-entity and repository-class to be string rather than xs:NMTOKEN because of the class backslash. 2010-12-15 22:01:16 +01:00
Benjamin Eberlei 6ddfd06efe Merge branch 'DDC-933' 2010-12-14 23:26:50 +01:00
Benjamin Eberlei d87391e40c DDC-933 - Fix bug in lock sql generation of CTI classes. 2010-12-14 23:26:40 +01:00
Benjamin Eberlei 2648c1a6ca Fix build.xml to generate proper package.xml for Windows PEAR Package. 2010-12-14 23:10:45 +01:00
Benjamin Eberlei 6c9eeb6127 Update Dependency to DBAL RC5 2010-12-12 16:02:46 +01:00
Benjamin Eberlei 6c26af069c DDC-920 - Fix bug in DetachedEntityTest that occours with pre-persist generators (Postgresql, Oracle). Didnt came up when testing against Sqlite. 2010-12-12 15:43:12 +01:00
Benjamin Eberlei 3c0f92f4c7 Remove call to EntityManager#flush() if the unitofwork contains pending insertions. Flush should always be triggered explicitly. 2010-12-11 00:54:54 +01:00
Benjamin Eberlei 4f154b6aa1 DDC-920 - Fix bug when detaching a managed entity that is not yet in the identity map (no id). 2010-12-10 21:55:48 +01:00
Benjamin Eberlei 06326918a5 DDC-915, DDC-925 - Fix Identification Ordering in combination with Tree Walkers. 2010-12-10 21:22:48 +01:00
Benjamin Eberlei 5e788a0b84 DDC-915 - Bugfix in Identification Variable reordering in combination with SQL Walkers. 2010-12-08 23:42:02 +01:00
Benjamin Eberlei 1daf658ec6 DDC-917 - Skip Mapped Superclasses in the Drop Sequence Loop in SchemaTool. 2010-12-08 23:36:15 +01:00
Benjamin Eberlei aa2501eb96 DDC-917 - Bugfix with DriverChain::getAllClassNames() - It was not semantically correct and returning too many metadata. 2010-12-08 23:29:21 +01:00
Benjamin Eberlei ef50d940de CleanUp in SchemaTool. 2010-12-08 21:21:00 +01:00
Benjamin Eberlei ad50327744 Fixed some build.xml problems. 2010-12-04 11:32:12 +01:00
Benjamin Eberlei 9a68015ccf Bump Dev Version to 2.0.0-DEV 2010-12-04 05:29:18 -05:00
Benjamin Eberlei 72ba369dbb Revert Version to 2.0.0RC1-DEV 2010-12-04 05:28:26 -05:00
Benjamin Eberlei 5b20838aec Merge branch 'master' of git@github.com:doctrine/doctrine2 2010-12-04 05:24:41 -05:00
Benjamin Eberlei 8654d060c6 Bump Dev Version to 2.0.0-DEV 2010-12-04 05:24:00 -05:00
Benjamin Eberlei 2ba9d5a597 Update Dependency of DBAL from RC3 to RC4 2010-12-04 11:04:20 +01:00
Benjamin Eberlei 5bd8ffa53c Merge master into DDC-117 2010-08-27 22:27:00 +02:00
Benjamin Eberlei 1496250833 Merge branch 'master' into DDC-117 2010-08-15 20:17:56 +02:00
Benjamin Eberlei 772e592489 Try Assoc-Id Mapping with Id that has its column renamed. 2010-08-15 19:15:34 +02:00
Benjamin Eberlei fb44fa6b5a Fix hydration of Assoc-Id Entities, duplicate the hydration of the foreign key once for for use with the assoc-entity as a meta-column. Added isIdentifier capabilities to meta columns. 2010-08-15 18:58:25 +02:00
Benjamin Eberlei 5799e391c6 Fix bug with updating assoc-id entities 2010-08-15 14:40:06 +02:00
Benjamin Eberlei e45c52b024 Merge Removal of association classes into DDC-117 branch, quite some merge efforts necessary to get it working again 2010-08-13 23:23:11 +02:00
Benjamin Eberlei db936035e0 Added more tests for DQL joining the primary key entity and querying other fields 2010-08-08 19:46:45 +02:00
Benjamin Eberlei 7b07a17886 Merge branch 'master' into DDC-117 2010-08-08 14:07:24 +02:00
Benjamin Eberlei e3a4c8ddeb Refactored TestCase and added several more use-cases 2010-08-08 10:46:01 +02:00
Benjamin Eberlei 013262a9b7 Add support for EntityManager::remove() of full or partial association primary keys 2010-08-07 21:09:19 +02:00
Benjamin Eberlei 10f47389ae Made single identifier One-To-One + Id work also and added a test-case 2010-08-07 20:07:10 +02:00
Benjamin Eberlei c697a2d47f Prototype hack of @ManyToOne + @Id support with two test-scenarios, composite association key only composite key, and a mixed key scenario. I think single foreign association would work also 2010-08-07 19:33:54 +02:00
736 changed files with 51206 additions and 16890 deletions
+3 -1
View File
@@ -1,4 +1,3 @@
build.properties
build/
logs/
reports/
@@ -7,3 +6,6 @@ download/
lib/api/
lib/Doctrine/Common
lib/Doctrine/DBAL
/.settings/
.buildpath
.project
+9
View File
@@ -4,3 +4,12 @@
[submodule "lib/vendor/doctrine-dbal"]
path = lib/vendor/doctrine-dbal
url = git://github.com/doctrine/dbal.git
[submodule "lib/vendor/Symfony/Component/Console"]
path = lib/vendor/Symfony/Component/Console
url = git://github.com/symfony/Console.git
[submodule "lib/vendor/Symfony/Component/Yaml"]
path = lib/vendor/Symfony/Component/Yaml
url = git://github.com/symfony/Yaml.git
[submodule "lib/vendor/doctrine-build-common"]
path = lib/vendor/doctrine-build-common
url = git://github.com/doctrine/doctrine-build-common.git
+19
View File
@@ -0,0 +1,19 @@
language: php
php:
- 5.3
- 5.4
env:
- DB=mysql
- DB=pgsql
- DB=sqlite
before_script:
- sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'DROP DATABASE IF EXISTS doctrine_tests;' -U postgres; fi"
- sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'DROP DATABASE IF EXISTS doctrine_tests_tmp;' -U postgres; fi"
- sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'create database doctrine_tests;' -U postgres; fi"
- sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'create database doctrine_tests_tmp;' -U postgres; fi"
- sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'create database IF NOT EXISTS doctrine_tests_tmp;create database IF NOT EXISTS doctrine_tests;'; fi"
- git submodule update --init
script: phpunit --configuration tests/travis/$DB.travis.xml
+19 -504
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.
+9 -4
View File
@@ -1,14 +1,19 @@
# Doctrine 2 ORM
Doctrine 2 is an object-relational mapper (ORM) for PHP 5.3.0+ that provides transparent persistence
Master: [![Build Status](https://secure.travis-ci.org/doctrine/doctrine2.png?branch=master)](http://travis-ci.org/doctrine/doctrine2)
2.2: [![Build Status](https://secure.travis-ci.org/doctrine/doctrine2.png?branch=2.2)](http://travis-ci.org/doctrine/doctrine2)
2.1: [![Build Status](https://secure.travis-ci.org/doctrine/doctrine2.png?branch=2.1.x)](http://travis-ci.org/doctrine/doctrine2)
Doctrine 2 is an object-relational mapper (ORM) for PHP 5.3.2+ that provides transparent persistence
for PHP objects. It sits on top of a powerful database abstraction layer (DBAL). One of its key features
is the option to write database queries in a proprietary object oriented SQL dialect called Doctrine Query Language (DQL),
inspired by Hibernates HQL. This provides developers with a powerful alternative to SQL that maintains flexibility
without requiring unnecessary code duplication.
More resources:
## More resources:
* [Website](http://www.doctrine-project.org)
* [Documentation](http://www.doctrine-project.org/projects/orm/2.0/docs/reference/introduction/en)
* [Documentation](http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/index.html)
* [Issue Tracker](http://www.doctrine-project.org/jira/browse/DDC)
* [Downloads](http://github.com/doctrine/doctrine2/downloads)
* [Downloads](http://github.com/doctrine/doctrine2/downloads)
+467
View File
@@ -0,0 +1,467 @@
# Upgrade to 2.3
## 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)
-240
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.
-35
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)
-36
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.
Regular → Executable
+1 -1
View File
@@ -1,4 +1,4 @@
#!/usr/bin/env php
<?php
include('doctrine.php');
include('doctrine.php');
+50
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);
Regular → Executable
+1 -8
View File
@@ -17,14 +17,7 @@
* <http://www.doctrine-project.org>.
*/
require_once 'Doctrine/Common/ClassLoader.php';
$classLoader = new \Doctrine\Common\ClassLoader('Doctrine');
$classLoader->register();
$classLoader = new \Doctrine\Common\ClassLoader('Symfony', 'Doctrine');
$classLoader->register();
(@include_once __DIR__ . '/../vendor/autoload.php') || @include_once __DIR__ . '/../../../autoload.php';
$configFile = getcwd() . DIRECTORY_SEPARATOR . 'cli-config.php';
$helperSet = null;
+11
View File
@@ -0,0 +1,11 @@
# Project Name
project.name=DoctrineORM
# Dependency minimum versions
dependencies.common=2.2.0beta1
dependencies.dbal=2.2.0beta1
dependencies.sfconsole=2.0.0
# Version class and file
project.version_class = Doctrine\ORM\Version
project.version_file = lib/Doctrine/ORM/Version.php
+1
View File
@@ -8,6 +8,7 @@ report.dir=reports
log.archive.dir=logs
project.pirum_dir=
project.download_dir=
project.xsd_dir=
test.phpunit_configuration_file=
test.phpunit_generate_coverage=0
test.pmd_reports=0
+24 -118
View File
@@ -1,13 +1,7 @@
<?xml version="1.0"?>
<!--
Doctrine 2 build file.
-->
<project name="Doctrine2" default="build" basedir=".">
<taskdef classname="NativePhpunitTask" classpath="./tests/" name="nativephpunit" />
<project name="DoctrineORM" default="build" basedir=".">
<taskdef classname="phing.tasks.ext.d51PearPkg2Task" name="d51pearpkg2" />
<import file="${project.basedir}/lib/vendor/doctrine-build-common/packaging.xml" />
<property file="build.properties" />
@@ -16,6 +10,8 @@
-->
<fileset id="shared-artifacts" dir=".">
<include name="LICENSE"/>
<include name="UPGRADE*" />
<include name="doctrine-mapping.xsd" />
</fileset>
<!--
@@ -23,7 +19,8 @@
-->
<fileset id="bin-scripts" dir="./bin">
<include name="doctrine"/>
<include name="doctrine.php"/>
<include name="doctrine-pear.php"/>
<include name="doctrine.bat"/>
</fileset>
<!--
@@ -52,97 +49,34 @@
-->
<fileset id="symfony-sources" dir="./lib/vendor">
<include name="Symfony/Component/**"/>
<exclude name="**/.git/**" />
</fileset>
<!--
Clean the directory for the next build.
-->
<target name="clean">
<available file="./build.properties" property="build_properties_exist" value="true"/>
<fail unless="build_properties_exist" message="The build.properties file is missing." />
<delete dir="${build.dir}" includeemptydirs="true" />
<delete dir="${dist.dir}" includeemptydirs="true" />
<delete dir="${report.dir}" includeemptydirs="true" />
</target>
<!--
Prepare the new build directories after cleaning
-->
<target name="prepare" depends="clean">
<echo msg="Creating build directory: ${build.dir}" />
<mkdir dir="${build.dir}" />
<echo msg="Creating distribution directory: ${dist.dir}" />
<mkdir dir="${dist.dir}" />
<echo msg="Creating report directory: ${report.dir}" />
<mkdir dir="${report.dir}" />
<mkdir dir="${build.dir}/logs"/>
<mkdir dir="${report.dir}/tests"/>
</target>
<!--
Builds ORM package, preparing it for distribution.
-->
<target name="build-orm" depends="test">
<copy todir="${build.dir}/doctrine-orm">
<target name="copy-files" depends="prepare">
<copy todir="${build.dir}/${project.name}-${version}">
<fileset refid="shared-artifacts"/>
</copy>
<copy todir="${build.dir}/doctrine-orm">
<copy todir="${build.dir}/${project.name}-${version}">
<fileset refid="common-sources"/>
<fileset refid="dbal-sources"/>
<fileset refid="orm-sources"/>
</copy>
<copy todir="${build.dir}/doctrine-orm/Doctrine">
<copy todir="${build.dir}/${project.name}-${version}/Doctrine">
<fileset refid="symfony-sources"/>
</copy>
<copy todir="${build.dir}/doctrine-orm/bin">
<copy todir="${build.dir}/${project.name}-${version}/bin">
<fileset refid="bin-scripts"/>
</copy>
<exec command="sed 's/${version}-DEV/${version}/' ${build.dir}/doctrine-orm/Doctrine/ORM/Version.php > ${build.dir}/doctrine-orm/Doctrine/ORM/Version2.php" passthru="true" />
<exec command="mv ${build.dir}/doctrine-orm/Doctrine/ORM/Version2.php ${build.dir}/doctrine-orm/Doctrine/ORM/Version.php" passthru="true" />
</target>
<target name="build" depends="test, build-orm"/>
<!--
Runs the full test suite.
-->
<target name="test" depends="prepare">
<if><equals arg1="${test.phpunit_generate_coverage}" arg2="1" />
<then>
<property name="test.phpunit_coverage_file" value="${build.dir}/logs/clover.xml" />
</then>
<else>
<property name="test.phpunit_coverage_file" value="false" />
</else>
</if>
<nativephpunit
testfile="./tests/Doctrine/Tests/AllTests.php" junitlogfile="${build.dir}/logs/testsuites.xml"
testdirectory="./tests" coverageclover="${test.phpunit_coverage_file}" configuration="${test.phpunit_configuration_file}"
/>
<phpunitreport infile="${build.dir}/logs/testsuites.xml" format="frames" todir="${report.dir}/tests" />
<nativephpunit testfile="./tests/Doctrine/Tests/ORM/Performance/AllTests.php" testdirectory="./tests" haltonfailure="false" haltonerror="false" />
<tstamp/>
<copy file="${build.dir}/logs/testsuites.xml" tofile="${log.archive.dir}/latest/log.xml" overwrite="true"/>
<if><equals arg1="${test.pmd_reports}" arg2="1" />
<then>
<exec command="${test.pdepend_exec} --jdepend-xml=${build.dir}/logs/jdepend.xml ./lib/Doctrine" />
<exec command="${test.phpmd_exec} ./lib/Doctrine xml codesize --reportfile ${build.dir}/logs/phpmd.xml" />
<copy file="${build.dir}/logs/jdepend.xml" tofile="${log.archive.dir}/latest/jdepend.xml" overwrite="true"/>
<copy file="${build.dir}/logs/phpmd.xml" tofile="${log.archive.dir}/latest/phpmd.xml" overwrite="true"/>
</then>
</if>
</target>
<!--
Builds distributable PEAR packages.
-->
<target name="build-packages" depends="build-orm">
<d51pearpkg2 baseinstalldir="/" dir="${build.dir}/doctrine-orm">
<target name="define-pear-package" depends="copy-files">
<d51pearpkg2 baseinstalldir="/" dir="${build.dir}/${project.name}-${version}">
<name>DoctrineORM</name>
<summary>Doctrine Object Relational Mapper</summary>
<channel>pear.doctrine-project.org</channel>
@@ -152,57 +86,29 @@
<lead user="romanb" name="Roman Borschel" email="roman@code-factory.org" />
<lead user="beberlei" name="Benjamin Eberlei" email="kontakt@beberlei.de" />
<license>LGPL</license>
<version release="${version}" api="${version}" />
<stability release="${stability}" api="${stability}" />
<version release="${pear.version}" api="${pear.version}" />
<stability release="${pear.stability}" api="${pear.stability}" />
<notes>-</notes>
<dependencies>
<php minimum_version="5.3.0" />
<pear minimum_version="1.6.0" recommended_version="1.6.1" />
<package name="DoctrineCommon" channel="pear.doctrine-project.org" minimum_version="${dependencies.common}" />
<package name="DoctrineDBAL" channel="pear.doctrine-project.org" minimum_version="${dependencies.dbal}" />
<package name="Console" channel="pear.symfony.com" minimum_version="2.0.0" />
<package name="Yaml" channel="pear.symfony.com" minimum_version="2.0.0" />
</dependencies>
<dirroles key="bin">script</dirroles>
<ignore>Doctrine/Common/</ignore>
<ignore>Doctrine/DBAL/</ignore>
<ignore>Symfony/Component/Yaml/</ignore>
<ignore>Symfony/Component/Console/</ignore>
<release>
<install as="doctrine" name="bin/doctrine" />
<install as="doctrine.php" name="bin/doctrine.php" />
<install as="doctrine.php" name="bin/doctrine-pear.php" />
<install as="doctrine.bat" name="bin/doctrine.bat" />
</release>
<replacement path="bin/doctrine" type="pear-config" from="@php_bin@" to="php_bin" />
<replacement path="bin/doctrine.bat" type="pear-config" from="@bin_dir@" to="bin_dir" />
</d51pearpkg2>
<exec command="pear package" dir="${build.dir}/doctrine-orm" passthru="true" />
<exec command="mv DoctrineORM-${version}.tgz ../../dist" dir="${build.dir}/doctrine-orm" passthru="true" />
<tar destfile="dist/DoctrineORM-${version}-full.tar.gz" compression="gzip" basedir="${build.dir}">
<fileset dir="${build.dir}">
<include name="**/**" />
<exclude name="logs/" />
<exclude name="doctrine-orm/package.xml" />
</fileset>
</tar>
</target>
<target name="git-tag">
<exec command="git tag -a ${version}" passthru="true" />
<exec command="git push origin ${version}" passthru="true" />
</target>
<target name="pirum-release">
<exec command="sudo pirum add ${project.pirum_dir} ${project.basedir}/dist/DoctrineDBAL-${version}.tgz" dir="." passthru="true" />
<exec command="sudo pirum build ${project.pirum_dir}" passthru="true" />
</target>
<target name="distribute-download">
<copy file="dist/DoctrineORM-${version}-full.tar.gz" todir="${project.download_dir}" />
</target>
<target name="update-dev-version">
<propertyprompt propertyName="next_version" defaultValue="${version}" promptText="Enter next version string (without -DEV)" />
<exec command="sed 's/${version}-DEV/${next_version}-DEV/' ${project.basedir}/lib/Doctrine/ORM/Version.php > ${project.basedir}/lib/Doctrine/ORM/Version2.php" passthru="true" />
<exec command="mv ${project.basedir}/lib/Doctrine/ORM/Version2.php ${project.basedir}/lib/Doctrine/ORM/Version.php" passthru="true" />
<exec command="git add ${project.basedir}/lib/Doctrine/ORM/Version.php" passthru="true" />
<exec command="git commit -m 'Bump Dev Version to ${next_version}-DEV'" passthru="true" />
<exec command="git push origin master" passthru="true" />
</target>
<target name="release" depends="git-tag,build-packages,distribute-download,pirum-release,update-dev-version" />
</project>
</project>
+32
View File
@@ -0,0 +1,32 @@
{
"name": "doctrine/orm",
"type": "library",
"description": "Object-Relational-Mapper for PHP",
"keywords": ["orm", "database"],
"homepage": "http://www.doctrine-project.org",
"license": "MIT",
"authors": [
{"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"},
{"name": "Roman Borschel", "email": "roman@code-factory.org"},
{"name": "Benjamin Eberlei", "email": "kontakt@beberlei.de"},
{"name": "Jonathan Wage", "email": "jonwage@gmail.com"}
],
"require": {
"php": ">=5.3.2",
"ext-pdo": "*",
"doctrine/dbal": "2.3.*",
"symfony/console": "2.*"
},
"suggest": {
"symfony/yaml": "If you want to use YAML Metadata Mapping Driver"
},
"autoload": {
"psr-0": { "Doctrine\\ORM": "lib/" }
},
"bin": ["bin/doctrine", "bin/doctrine.php"],
"extra": {
"branch-alias": {
"dev-master": "2.3.x-dev"
}
}
}
+230 -16
View File
@@ -17,11 +17,18 @@
<xs:sequence>
<xs:element name="mapped-superclass" type="orm:mapped-superclass" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="entity" type="orm:entity" minOccurs="0" maxOccurs="unbounded" />
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
</xs:element>
<xs:complexType name="emptyType"/>
<xs:complexType name="emptyType">
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="cascade-type">
<xs:sequence>
@@ -30,7 +37,9 @@
<xs:element name="cascade-merge" type="orm:emptyType" minOccurs="0"/>
<xs:element name="cascade-remove" type="orm:emptyType" minOccurs="0"/>
<xs:element name="cascade-refresh" type="orm:emptyType" minOccurs="0"/>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:simpleType name="lifecycle-callback-type">
@@ -46,41 +55,135 @@
</xs:simpleType>
<xs:complexType name="lifecycle-callback">
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="type" type="orm:lifecycle-callback-type" use="required" />
<xs:attribute name="method" type="xs:NMTOKEN" use="required" />
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="lifecycle-callbacks">
<xs:sequence>
<xs:element name="lifecycle-callback" type="orm:lifecycle-callback" minOccurs="1" maxOccurs="unbounded" />
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="named-query">
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="query" type="xs:string" use="required" />
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="named-queries">
<xs:sequence>
<xs:element name="named-query" type="orm:named-query" minOccurs="1" maxOccurs="unbounded" />
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="named-native-query">
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="query" type="xs:string" use="required"/>
<xs:attribute name="result-class" type="xs:string" />
<xs:attribute name="result-set-mapping" type="xs:string" />
</xs:complexType>
<xs:complexType name="named-native-queries">
<xs:sequence>
<xs:element name="named-native-query" type="orm:named-native-query" minOccurs="1" maxOccurs="unbounded" />
<xs:any minOccurs="1" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="column-result">
<xs:attribute name="name" type="xs:string" use="required" />
</xs:complexType>
<xs:complexType name="field-result">
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="column" type="xs:string" />
</xs:complexType>
<xs:complexType name="entity-result">
<xs:sequence>
<xs:element name="field-result" type="orm:field-result" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="entity-class" type="xs:string" use="required" />
</xs:complexType>
<xs:complexType name="sql-result-set-mapping">
<xs:sequence>
<xs:element name="entity-result" type="orm:entity-result" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="column-result" type="orm:column-result" minOccurs="0" maxOccurs="unbounded" />
<xs:any minOccurs="1" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="sql-result-set-mappings">
<xs:sequence>
<xs:element name="sql-result-set-mapping" type="orm:sql-result-set-mapping" minOccurs="1" maxOccurs="unbounded" />
<xs:any minOccurs="1" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="entity">
<xs:sequence>
<xs:element name="options" type="orm:options" minOccurs="0" />
<xs:element name="indexes" type="orm:indexes" minOccurs="0"/>
<xs:element name="unique-constraints" type="orm:unique-constraints" minOccurs="0"/>
<xs:element name="discriminator-column" type="orm:discriminator-column" minOccurs="0"/>
<xs:element name="discriminator-map" type="orm:discriminator-map" minOccurs="0"/>
<xs:element name="lifecycle-callbacks" type="orm:lifecycle-callbacks" minOccurs="0" maxOccurs="1" />
<xs:element name="id" type="orm:id" minOccurs="0" maxOccurs="1" />
<xs:element name="named-queries" type="orm:named-queries" minOccurs="0" maxOccurs="1" />
<xs:element name="named-native-queries" type="orm:named-native-queries" minOccurs="0" maxOccurs="1" />
<xs:element name="id" type="orm:id" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="field" type="orm:field" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="one-to-one" type="orm:one-to-one" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="one-to-many" type="orm:one-to-many" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="many-to-one" type="orm:many-to-one" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="many-to-many" type="orm:many-to-many" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="association-overrides" type="orm:association-overrides" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="attribute-overrides" type="orm:attribute-overrides" minOccurs="0" maxOccurs="unbounded" />
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="table" type="xs:NMTOKEN" />
<xs:attribute name="schema" type="xs:NMTOKEN" />
<xs:attribute name="repository-class" type="xs:NMTOKEN"/>
<xs:attribute name="repository-class" type="xs:string"/>
<xs:attribute name="inheritance-type" type="orm:inheritance-type"/>
<xs:attribute name="change-tracking-policy" type="orm:change-tracking-policy" />
<xs:attribute name="read-only" type="xs:boolean" default="false" />
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="option" mixed="true">
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="option" type="orm:option"/>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="name" type="xs:NMTOKEN" use="required"/>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="options">
<xs:sequence>
<xs:element name="option" type="orm:option" minOccurs="0" maxOccurs="unbounded"/>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="mapped-superclass" >
<xs:complexContent>
<xs:extension base="orm:entity"/>
<xs:extension base="orm:entity">
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:anyAttribute namespace="##other"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
@@ -106,6 +209,8 @@
<xs:enumeration value="SEQUENCE"/>
<xs:enumeration value="IDENTITY"/>
<xs:enumeration value="AUTO"/>
<xs:enumeration value="UUID"/>
<xs:enumeration value="CUSTOM" />
</xs:restriction>
</xs:simpleType>
@@ -113,7 +218,7 @@
<xs:restriction base="xs:token">
<xs:enumeration value="CASCADE"/>
<xs:enumeration value="RESTRICT"/>
<xs:enumeration value="SET_NULL"/>
<xs:enumeration value="SET NULL"/>
</xs:restriction>
</xs:simpleType>
@@ -121,10 +226,15 @@
<xs:restriction base="xs:token">
<xs:enumeration value="EAGER"/>
<xs:enumeration value="LAZY"/>
<xs:enumeration value="EXTRA_LAZY"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="field">
<xs:sequence>
<xs:element name="options" type="orm:options" minOccurs="0" />
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="name" type="xs:NMTOKEN" use="required" />
<xs:attribute name="type" type="xs:NMTOKEN" default="string" />
<xs:attribute name="column" type="xs:NMTOKEN" />
@@ -135,75 +245,124 @@
<xs:attribute name="column-definition" type="xs:string" />
<xs:attribute name="precision" type="xs:integer" use="optional" />
<xs:attribute name="scale" type="xs:integer" use="optional" />
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="discriminator-column">
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="name" type="xs:NMTOKEN" use="required" />
<xs:attribute name="type" type="xs:NMTOKEN" use="required" />
<xs:attribute name="type" type="xs:NMTOKEN"/>
<xs:attribute name="field-name" type="xs:NMTOKEN" />
<xs:attribute name="length" type="xs:NMTOKEN" />
<xs:attribute name="column-definition" type="xs:string" />
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="unique-constraint">
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="name" type="xs:NMTOKEN" use="optional"/>
<xs:attribute name="columns" type="xs:string" use="required"/>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="unique-constraints">
<xs:sequence>
<xs:element name="unique-constraint" type="orm:unique-constraint" minOccurs="1" maxOccurs="unbounded"/>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="index">
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="name" type="xs:NMTOKEN" use="optional"/>
<xs:attribute name="columns" type="xs:NMTOKENS" use="required"/>
<xs:attribute name="columns" type="xs:string" use="required"/>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="indexes">
<xs:sequence>
<xs:element name="index" type="orm:index" minOccurs="1" maxOccurs="unbounded"/>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="discriminator-mapping">
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="value" type="xs:NMTOKEN" use="required"/>
<xs:attribute name="class" type="xs:NMTOKEN" use="required"/>
<xs:attribute name="class" type="xs:string" use="required"/>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="discriminator-map">
<xs:sequence>
<xs:element name="discriminator-mapping" type="orm:discriminator-mapping" minOccurs="1" maxOccurs="unbounded"/>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="generator">
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="strategy" type="orm:generator-strategy" use="optional" default="AUTO" />
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="id">
<xs:sequence>
<xs:element name="generator" type="orm:generator" minOccurs="0" />
<xs:element name="sequence-generator" type="orm:sequence-generator" minOccurs="0" maxOccurs="1" />
<xs:element name="custom-id-generator" type="orm:custom-id-generator" minOccurs="0" maxOccurs="1" />
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="name" type="xs:NMTOKEN" use="required" />
<xs:attribute name="type" type="xs:NMTOKEN" use="required" />
<xs:attribute name="type" type="xs:NMTOKEN" />
<xs:attribute name="column" type="xs:NMTOKEN" />
<xs:attribute name="association-key" type="xs:boolean" default="false" />
<xs:attribute name="column-definition" type="xs:string" />
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="sequence-generator">
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="sequence-name" type="xs:NMTOKEN" use="required" />
<xs:attribute name="allocation-size" type="xs:integer" use="optional" default="1" />
<xs:attribute name="initial-value" type="xs:integer" use="optional" default="1" />
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="custom-id-generator">
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="class" type="xs:NMTOKEN" use="required" />
</xs:complexType>
<xs:complexType name="inverse-join-columns">
<xs:sequence>
<xs:element name="join-column" type="orm:join-column" minOccurs="1" maxOccurs="unbounded" />
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="join-column">
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="name" type="xs:NMTOKEN" use="required" />
<xs:attribute name="referenced-column-name" type="xs:NMTOKEN" use="optional" default="id" />
<xs:attribute name="unique" type="xs:boolean" default="false" />
@@ -211,32 +370,43 @@
<xs:attribute name="on-delete" type="orm:fk-action" />
<xs:attribute name="on-update" type="orm:fk-action" />
<xs:attribute name="column-definition" type="xs:string" />
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="join-columns">
<xs:sequence>
<xs:element name="join-column" type="orm:join-column" minOccurs="1" maxOccurs="unbounded" />
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="join-table">
<xs:sequence>
<xs:element name="join-columns" type="orm:join-columns" />
<xs:element name="inverse-join-columns" type="orm:join-columns" />
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="name" type="xs:NMTOKEN" use="required" />
<xs:attribute name="schema" type="xs:NMTOKEN" />
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="order-by">
<xs:sequence>
<xs:element name="order-by-field" type="orm:order-by-field" minOccurs="1" maxOccurs="unbounded" />
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="order-by-field">
<xs:attribute name="name" type="xs:NMTOKEN" use="required" />
<xs:attribute name="direction" type="orm:order-by-direction" default="ASC" />
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="name" type="xs:NMTOKEN" use="required" />
<xs:attribute name="direction" type="orm:order-by-direction" default="ASC" />
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:simpleType name="order-by-direction">
@@ -251,24 +421,31 @@
<xs:element name="cascade" type="orm:cascade-type" minOccurs="0" />
<xs:element name="join-table" type="orm:join-table" minOccurs="0" />
<xs:element name="order-by" type="orm:order-by" minOccurs="0" />
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="target-entity" type="xs:NMTOKEN" use="required" />
<xs:attribute name="target-entity" type="xs:string" use="required" />
<xs:attribute name="field" type="xs:NMTOKEN" use="required" />
<xs:attribute name="mapped-by" type="xs:NMTOKEN" />
<xs:attribute name="index-by" type="xs:NMTOKEN" />
<xs:attribute name="inversed-by" type="xs:NMTOKEN" />
<xs:attribute name="fetch" type="orm:fetch-type" default="LAZY" />
<xs:attribute name="orphan-removal" type="xs:boolean" default="false" />
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="one-to-many">
<xs:sequence>
<xs:element name="cascade" type="orm:cascade-type" minOccurs="0" />
<xs:element name="order-by" type="orm:order-by" minOccurs="0" />
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="target-entity" type="xs:NMTOKEN" use="required" />
<xs:attribute name="target-entity" type="xs:string" use="required" />
<xs:attribute name="mapped-by" type="xs:NMTOKEN" use="required" />
<xs:attribute name="field" type="xs:NMTOKEN" use="required" />
<xs:attribute name="index-by" type="xs:NMTOKEN" />
<xs:attribute name="orphan-removal" type="xs:boolean" default="false" />
<xs:attribute name="fetch" type="orm:fetch-type" default="LAZY" />
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="many-to-one">
@@ -277,13 +454,16 @@
<xs:choice minOccurs="0" maxOccurs="1">
<xs:element name="join-column" type="orm:join-column"/>
<xs:element name="join-columns" type="orm:join-columns"/>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:choice>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="target-entity" type="xs:NMTOKEN" use="required" />
<xs:attribute name="target-entity" type="xs:string" use="required" />
<xs:attribute name="field" type="xs:NMTOKEN" use="required" />
<xs:attribute name="orphan-removal" type="xs:boolean" default="false" />
<xs:attribute name="fetch" type="orm:fetch-type" default="LAZY" />
<xs:attribute name="inversed-by" type="xs:NMTOKEN" />
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="one-to-one">
@@ -292,14 +472,48 @@
<xs:choice minOccurs="0" maxOccurs="1">
<xs:element name="join-column" type="orm:join-column"/>
<xs:element name="join-columns" type="orm:join-columns"/>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:choice>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:sequence>
<xs:attribute name="field" type="xs:NMTOKEN" use="required" />
<xs:attribute name="target-entity" type="xs:NMTOKEN" use="required" />
<xs:attribute name="target-entity" type="xs:string" use="required" />
<xs:attribute name="mapped-by" type="xs:NMTOKEN" />
<xs:attribute name="inversed-by" type="xs:NMTOKEN" />
<xs:attribute name="orphan-removal" type="xs:boolean" default="false" />
<xs:attribute name="fetch" type="orm:fetch-type" default="LAZY" />
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
</xs:schema>
<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>
+403 -181
View File
@@ -1,7 +1,5 @@
<?php
/*
* $Id: Abstract.php 1393 2008-03-06 17:49:16Z guilhermeblanco $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -15,22 +13,25 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM;
use Doctrine\DBAL\Types\Type,
Doctrine\ORM\Query\QueryException;
use Doctrine\Common\Util\ClassUtils;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Cache\QueryCacheProfile;
use Doctrine\ORM\Query\QueryException;
/**
* Base contract for ORM queries. Base class for Query and NativeQuery.
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 2.0
* @version $Revision$
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
@@ -58,14 +59,14 @@ abstract class AbstractQuery
const HYDRATE_SINGLE_SCALAR = 4;
/**
* @var array The parameter map of this query.
* Very simple object hydrator (optimized for performance).
*/
protected $_params = array();
const HYDRATE_SIMPLEOBJECT = 5;
/**
* @var array The parameter type map of this query.
* @var \Doctrine\Common\Collections\ArrayCollection The parameter map of this query.
*/
protected $_paramTypes = array();
protected $parameters;
/**
* @var ResultSetMapping The user-specified ResultSetMapping to use.
@@ -73,7 +74,7 @@ abstract class AbstractQuery
protected $_resultSetMapping;
/**
* @var Doctrine\ORM\EntityManager The entity manager used by this query object.
* @var \Doctrine\ORM\EntityManager The entity manager used by this query object.
*/
protected $_em;
@@ -88,23 +89,9 @@ abstract class AbstractQuery
protected $_hydrationMode = self::HYDRATE_OBJECT;
/**
* The locally set cache driver used for caching result sets of this query.
*
* @var CacheDriver
* @param \Doctrine\DBAL\Cache\QueryCacheProfile
*/
protected $_resultCacheDriver;
/**
* Boolean flag for whether or not to cache the results of this query.
*
* @var boolean
*/
protected $_useResultCache;
/**
* @var string The id to store the result cache entry under.
*/
protected $_resultCacheId;
protected $_queryCacheProfile;
/**
* @var boolean Boolean value that indicates whether or not expire the result cache.
@@ -112,24 +99,34 @@ abstract class AbstractQuery
protected $_expireResultCache = false;
/**
* @var int Result Cache lifetime.
* @param \Doctrine\DBAL\Cache\QueryCacheProfile
*/
protected $_resultCacheTTL;
protected $_hydrationCacheProfile;
/**
* Initializes a new instance of a class derived from <tt>AbstractQuery</tt>.
*
* @param Doctrine\ORM\EntityManager $entityManager
* @param \Doctrine\ORM\EntityManager $entityManager
*/
public function __construct(EntityManager $em)
{
$this->_em = $em;
$this->parameters = new ArrayCollection();
}
/**
* Gets the SQL query that corresponds to this query object.
* The returned SQL syntax depends on the connection driver that is used
* by this query object at the time of this method call.
*
* @return string SQL query
*/
abstract public function getSQL();
/**
* Retrieves the associated EntityManager of this Query instance.
*
* @return Doctrine\ORM\EntityManager
* @return \Doctrine\ORM\EntityManager
*/
public function getEntityManager()
{
@@ -145,40 +142,67 @@ abstract class AbstractQuery
*/
public function free()
{
$this->_params = array();
$this->_paramTypes = array();
$this->parameters = new ArrayCollection();
$this->_hints = array();
}
/**
* Get all defined parameters.
*
* @return array The defined query parameters.
* @return \Doctrine\Common\Collections\ArrayCollection The defined query parameters.
*/
public function getParameters()
{
return $this->_params;
return $this->parameters;
}
/**
* Gets a query parameter.
*
* @param mixed $key The key (index or name) of the bound parameter.
*
* @return mixed The value of the bound parameter.
*/
public function getParameter($key)
{
return isset($this->_params[$key]) ? $this->_params[$key] : null;
$filteredParameters = $this->parameters->filter(
function ($parameter) use ($key)
{
// Must not be identical because of string to integer conversion
return ($key == $parameter->getName());
}
);
return count($filteredParameters) ? $filteredParameters->first() : null;
}
/**
* Gets the SQL query that corresponds to this query object.
* The returned SQL syntax depends on the connection driver that is used
* by this query object at the time of this method call.
* Sets a collection of query parameters.
*
* @return string SQL query
* @param \Doctrine\Common\Collections\ArrayCollection|array $parameters
*
* @return \Doctrine\ORM\AbstractQuery This query instance.
*/
abstract public function getSQL();
public function setParameters($parameters)
{
// BC compatibility with 2.3-
if (is_array($parameters)) {
$parameterCollection = new ArrayCollection();
foreach ($parameters as $key => $value) {
$parameter = new Query\Parameter($key, $value);
$parameterCollection->add($parameter);
}
$parameters = $parameterCollection;
}
$this->parameters = $parameters;
return $this;
}
/**
* Sets a query parameter.
@@ -188,78 +212,191 @@ abstract class AbstractQuery
* @param string $type The parameter type. If specified, the given value will be run through
* the type conversion of this type. This is usually not needed for
* strings and numeric types.
* @return Doctrine\ORM\AbstractQuery This query instance.
*
* @return \Doctrine\ORM\AbstractQuery This query instance.
*/
public function setParameter($key, $value, $type = null)
{
if ($type !== null) {
$this->_paramTypes[$key] = $type;
$filteredParameters = $this->parameters->filter(
function ($parameter) use ($key)
{
// Must not be identical because of string to integer conversion
return ($key == $parameter->getName());
}
);
if (count($filteredParameters)) {
$parameter = $filteredParameters->first();
$parameter->setValue($value, $type);
return $this;
}
$this->_params[$key] = $value;
$parameter = new Query\Parameter($key, $value, $type);
$this->parameters->add($parameter);
return $this;
}
/**
* Sets a collection of query parameters.
* Process an individual parameter value
*
* @param array $params
* @param array $types
* @return Doctrine\ORM\AbstractQuery This query instance.
* @param mixed $value
* @return array
*/
public function setParameters(array $params, array $types = array())
public function processParameterValue($value)
{
foreach ($params as $key => $value) {
if (isset($types[$key])) {
$this->setParameter($key, $value, $types[$key]);
} else {
$this->setParameter($key, $value);
}
switch (true) {
case is_array($value):
foreach ($value as $key => $paramValue) {
$paramValue = $this->processParameterValue($paramValue);
$value[$key] = is_array($paramValue) ? $paramValue[key($paramValue)] : $paramValue;
}
return $value;
case is_object($value) && $this->_em->getMetadataFactory()->hasMetadataFor(ClassUtils::getClass($value)):
return $this->convertObjectParameterToScalarValue($value);
default:
return $value;
}
return $this;
}
private function convertObjectParameterToScalarValue($value)
{
$class = $this->_em->getClassMetadata(get_class($value));
if ($class->isIdentifierComposite) {
throw new \InvalidArgumentException(
"Binding an entity with a composite primary key to a query is not supported. " .
"You should split the parameter into the explicit fields and bind them seperately."
);
}
$values = ($this->_em->getUnitOfWork()->getEntityState($value) === UnitOfWork::STATE_MANAGED)
? $this->_em->getUnitOfWork()->getEntityIdentifier($value)
: $class->getIdentifierValues($value);
$value = $values[$class->getSingleIdentifierFieldName()];
if ( ! $value) {
throw new \InvalidArgumentException(
"Binding entities to query parameters only allowed for entities that have an identifier."
);
}
return $value;
}
/**
* Sets the ResultSetMapping that should be used for hydration.
*
* @param ResultSetMapping $rsm
* @return Doctrine\ORM\AbstractQuery
* @return \Doctrine\ORM\AbstractQuery
*/
public function setResultSetMapping(Query\ResultSetMapping $rsm)
{
$this->_resultSetMapping = $rsm;
return $this;
}
/**
* Defines a cache driver to be used for caching result sets.
* Set a cache profile for hydration caching.
*
* @param Doctrine\Common\Cache\Cache $driver Cache driver
* @return Doctrine\ORM\AbstractQuery
* If no result cache driver is set in the QueryCacheProfile, the default
* result cache driver is used from the configuration.
*
* Important: Hydration caching does NOT register entities in the
* UnitOfWork when retrieved from the cache. Never use result cached
* entities for requests that also flush the EntityManager. If you want
* some form of caching with UnitOfWork registration you should use
* {@see AbstractQuery::setResultCacheProfile()}.
*
* @example
* $lifetime = 100;
* $resultKey = "abc";
* $query->setHydrationCacheProfile(new QueryCacheProfile());
* $query->setHydrationCacheProfile(new QueryCacheProfile($lifetime, $resultKey));
*
* @param \Doctrine\DBAL\Cache\QueryCacheProfile $profile
* @return \Doctrine\ORM\AbstractQuery
*/
public function setHydrationCacheProfile(QueryCacheProfile $profile = null)
{
if ( ! $profile->getResultCacheDriver()) {
$resultCacheDriver = $this->_em->getConfiguration()->getHydrationCacheImpl();
$profile = $profile->setResultCacheDriver($resultCacheDriver);
}
$this->_hydrationCacheProfile = $profile;
return $this;
}
/**
* @return \Doctrine\DBAL\Cache\QueryCacheProfile
*/
public function getHydrationCacheProfile()
{
return $this->_hydrationCacheProfile;
}
/**
* Set a cache profile for the result cache.
*
* If no result cache driver is set in the QueryCacheProfile, the default
* result cache driver is used from the configuration.
*
* @param \Doctrine\DBAL\Cache\QueryCacheProfile $profile
* @return \Doctrine\ORM\AbstractQuery
*/
public function setResultCacheProfile(QueryCacheProfile $profile = null)
{
if ( ! $profile->getResultCacheDriver()) {
$resultCacheDriver = $this->_em->getConfiguration()->getResultCacheImpl();
$profile = $profile->setResultCacheDriver($resultCacheDriver);
}
$this->_queryCacheProfile = $profile;
return $this;
}
/**
* Defines a cache driver to be used for caching result sets and implictly enables caching.
*
* @param \Doctrine\Common\Cache\Cache $driver Cache driver
* @return \Doctrine\ORM\AbstractQuery
*/
public function setResultCacheDriver($resultCacheDriver = null)
{
if ($resultCacheDriver !== null && ! ($resultCacheDriver instanceof \Doctrine\Common\Cache\Cache)) {
throw ORMException::invalidResultCacheDriver();
}
$this->_resultCacheDriver = $resultCacheDriver;
if ($resultCacheDriver) {
$this->_useResultCache = true;
}
$this->_queryCacheProfile = $this->_queryCacheProfile
? $this->_queryCacheProfile->setResultCacheDriver($resultCacheDriver)
: new QueryCacheProfile(0, null, $resultCacheDriver);
return $this;
}
/**
* Returns the cache driver used for caching result sets.
*
* @return Doctrine\Common\Cache\Cache Cache driver
* @deprecated
* @return \Doctrine\Common\Cache\Cache Cache driver
*/
public function getResultCacheDriver()
{
if ($this->_resultCacheDriver) {
return $this->_resultCacheDriver;
} else {
return $this->_em->getConfiguration()->getResultCacheImpl();
if ($this->_queryCacheProfile && $this->_queryCacheProfile->getResultCacheDriver()) {
return $this->_queryCacheProfile->getResultCacheDriver();
}
return $this->_em->getConfiguration()->getResultCacheImpl();
}
/**
@@ -267,57 +404,62 @@ abstract class AbstractQuery
* how long and which ID to use for the cache entry.
*
* @param boolean $bool
* @param integer $timeToLive
* @param integer $lifetime
* @param string $resultCacheId
* @return This query instance.
* @return \Doctrine\ORM\AbstractQuery This query instance.
*/
public function useResultCache($bool, $timeToLive = null, $resultCacheId = null)
public function useResultCache($bool, $lifetime = null, $resultCacheId = null)
{
$this->_useResultCache = $bool;
if ($timeToLive) {
$this->setResultCacheLifetime($timeToLive);
}
if ($resultCacheId) {
$this->_resultCacheId = $resultCacheId;
if ($bool) {
$this->setResultCacheLifetime($lifetime);
$this->setResultCacheId($resultCacheId);
return $this;
}
$this->_queryCacheProfile = null;
return $this;
}
/**
* Defines how long the result cache will be active before expire.
*
* @param integer $timeToLive How long the cache entry is valid.
* @return Doctrine\ORM\AbstractQuery This query instance.
* @param integer $lifetime How long the cache entry is valid.
* @return \Doctrine\ORM\AbstractQuery This query instance.
*/
public function setResultCacheLifetime($timeToLive)
public function setResultCacheLifetime($lifetime)
{
if ($timeToLive !== null) {
$timeToLive = (int) $timeToLive;
}
$lifetime = ($lifetime !== null) ? (int) $lifetime : 0;
$this->_queryCacheProfile = $this->_queryCacheProfile
? $this->_queryCacheProfile->setLifetime($lifetime)
: new QueryCacheProfile($lifetime, null, $this->_em->getConfiguration()->getResultCacheImpl());
$this->_resultCacheTTL = $timeToLive;
return $this;
}
/**
* Retrieves the lifetime of resultset cache.
*
* @deprecated
* @return integer
*/
public function getResultCacheLifetime()
{
return $this->_resultCacheTTL;
return $this->_queryCacheProfile ? $this->_queryCacheProfile->getLifetime() : 0;
}
/**
* Defines if the result cache is active or not.
*
* @param boolean $expire Whether or not to force resultset cache expiration.
* @return Doctrine\ORM\AbstractQuery This query instance.
* @return \Doctrine\ORM\AbstractQuery This query instance.
*/
public function expireResultCache($expire = true)
{
$this->_expireResultCache = $expire;
return $this;
}
@@ -331,16 +473,46 @@ abstract class AbstractQuery
return $this->_expireResultCache;
}
/**
* @return QueryCacheProfile
*/
public function getQueryCacheProfile()
{
return $this->_queryCacheProfile;
}
/**
* Change the default fetch mode of an association for this query.
*
* $fetchMode can be one of ClassMetadata::FETCH_EAGER or ClassMetadata::FETCH_LAZY
*
* @param string $class
* @param string $assocName
* @param int $fetchMode
* @return AbstractQuery
*/
public function setFetchMode($class, $assocName, $fetchMode)
{
if ($fetchMode !== Mapping\ClassMetadata::FETCH_EAGER) {
$fetchMode = Mapping\ClassMetadata::FETCH_LAZY;
}
$this->_hints['fetchMode'][$class][$assocName] = $fetchMode;
return $this;
}
/**
* Defines the processing mode to be used during hydration / result set transformation.
*
* @param integer $hydrationMode Doctrine processing mode to be used during hydration process.
* One of the Query::HYDRATE_* constants.
* @return Doctrine\ORM\AbstractQuery This query instance.
* @return \Doctrine\ORM\AbstractQuery This query instance.
*/
public function setHydrationMode($hydrationMode)
{
$this->_hydrationMode = $hydrationMode;
return $this;
}
@@ -357,37 +529,63 @@ abstract class AbstractQuery
/**
* Gets the list of results for the query.
*
* Alias for execute(array(), $hydrationMode = HYDRATE_OBJECT).
* Alias for execute(null, $hydrationMode = HYDRATE_OBJECT).
*
* @return array
*/
public function getResult($hydrationMode = self::HYDRATE_OBJECT)
{
return $this->execute(array(), $hydrationMode);
return $this->execute(null, $hydrationMode);
}
/**
* Gets the array of results for the query.
*
* Alias for execute(array(), HYDRATE_ARRAY).
* Alias for execute(null, HYDRATE_ARRAY).
*
* @return array
*/
public function getArrayResult()
{
return $this->execute(array(), self::HYDRATE_ARRAY);
return $this->execute(null, self::HYDRATE_ARRAY);
}
/**
* Gets the scalar results for the query.
*
* Alias for execute(array(), HYDRATE_SCALAR).
* Alias for execute(null, HYDRATE_SCALAR).
*
* @return array
*/
public function getScalarResult()
{
return $this->execute(array(), self::HYDRATE_SCALAR);
return $this->execute(null, self::HYDRATE_SCALAR);
}
/**
* Get exactly one result or null.
*
* @throws NonUniqueResultException
* @param int $hydrationMode
* @return mixed
*/
public function getOneOrNullResult($hydrationMode = null)
{
$result = $this->execute(null, $hydrationMode);
if ($this->_hydrationMode !== self::HYDRATE_SINGLE_SCALAR && ! $result) {
return null;
}
if ( ! is_array($result)) {
return $result;
}
if (count($result) > 1) {
throw new NonUniqueResultException;
}
return array_shift($result);
}
/**
@@ -405,20 +603,21 @@ abstract class AbstractQuery
*/
public function getSingleResult($hydrationMode = null)
{
$result = $this->execute(array(), $hydrationMode);
$result = $this->execute(null, $hydrationMode);
if ($this->_hydrationMode !== self::HYDRATE_SINGLE_SCALAR && ! $result) {
throw new NoResultException;
}
if (is_array($result)) {
if (count($result) > 1) {
throw new NonUniqueResultException;
}
return array_shift($result);
if ( ! is_array($result)) {
return $result;
}
return $result;
if (count($result) > 1) {
throw new NonUniqueResultException;
}
return array_shift($result);
}
/**
@@ -439,11 +638,12 @@ abstract class AbstractQuery
*
* @param string $name The name of the hint.
* @param mixed $value The value of the hint.
* @return Doctrine\ORM\AbstractQuery
* @return \Doctrine\ORM\AbstractQuery
*/
public function setHint($name, $value)
{
$this->_hints[$name] = $value;
return $this;
}
@@ -458,96 +658,97 @@ abstract class AbstractQuery
return isset($this->_hints[$name]) ? $this->_hints[$name] : false;
}
/**
* Return the key value map of query hints that are currently set.
*
* @return array
*/
public function getHints()
{
return $this->_hints;
}
/**
* Executes the query and returns an IterableResult that can be used to incrementally
* iterate over the result.
*
* @param array $params The query parameters.
* @param \Doctrine\Common\Collections\ArrayCollection|array $parameters The query parameters.
* @param integer $hydrationMode The hydration mode to use.
* @return IterableResult
* @return \Doctrine\ORM\Internal\Hydration\IterableResult
*/
public function iterate(array $params = array(), $hydrationMode = self::HYDRATE_OBJECT)
public function iterate($parameters = null, $hydrationMode = null)
{
if ($hydrationMode !== null) {
$this->setHydrationMode($hydrationMode);
}
if ( ! empty($parameters)) {
$this->setParameters($parameters);
}
$stmt = $this->_doExecute();
return $this->_em->newHydrator($this->_hydrationMode)->iterate(
$this->_doExecute($params, $hydrationMode), $this->_resultSetMapping, $this->_hints
$stmt, $this->_resultSetMapping, $this->_hints
);
}
/**
* Executes the query.
*
* @param string $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 there are still pending insertions in the UnitOfWork we need to flush
// in order to guarantee a correct result.
//TODO: Think this over. Its tricky. Not doing this can lead to strange results
// potentially, but doing it could result in endless loops when querying during
// a flush, i.e. inside an event listener.
if ($this->_em->getUnitOfWork()->hasPendingInsertions()) {
$this->_em->flush();
}
if ($hydrationMode !== null) {
$this->setHydrationMode($hydrationMode);
}
if ($params) {
$this->setParameters($params);
if ( ! empty($parameters)) {
$this->setParameters($parameters);
}
if (isset($this->_params[0])) {
throw QueryException::invalidParameterPosition(0);
}
$setCacheEntry = function() {};
// Check result cache
if ($this->_useResultCache && $cacheDriver = $this->getResultCacheDriver()) {
$id = $this->_getResultCacheId();
$cached = $this->_expireResultCache ? false : $cacheDriver->fetch($id);
if ($this->_hydrationCacheProfile !== null) {
list($cacheKey, $realCacheKey) = $this->getHydrationCacheId();
if ($cached === false) {
// Cache miss.
$stmt = $this->_doExecute();
$queryCacheProfile = $this->getHydrationCacheProfile();
$cache = $queryCacheProfile->getResultCacheDriver();
$result = $cache->fetch($cacheKey);
$result = $this->_em->getHydrator($this->_hydrationMode)->hydrateAll(
$stmt, $this->_resultSetMapping, $this->_hints
);
$cacheDriver->save($id, $result, $this->_resultCacheTTL);
return $result;
} else {
// Cache hit.
return $cached;
if (isset($result[$realCacheKey])) {
return $result[$realCacheKey];
}
if ( ! $result) {
$result = array();
}
$setCacheEntry = function($data) use ($cache, $result, $cacheKey, $realCacheKey, $queryCacheProfile) {
$result[$realCacheKey] = $data;
$cache->save($cacheKey, $result, $queryCacheProfile->getLifetime());
};
}
$stmt = $this->_doExecute();
if (is_numeric($stmt)) {
$setCacheEntry($stmt);
return $stmt;
}
return $this->_em->getHydrator($this->_hydrationMode)->hydrateAll(
$stmt, $this->_resultSetMapping, $this->_hints
);
}
$data = $this->_em->getHydrator($this->_hydrationMode)->hydrateAll(
$stmt, $this->_resultSetMapping, $this->_hints
);
/**
* Set the result cache id to use to store the result set cache entry.
* If this is not explicitely set by the developer then a hash is automatically
* generated for you.
*
* @param string $id
* @return Doctrine\ORM\AbstractQuery This query instance.
*/
public function setResultCacheId($id)
{
$this->_resultCacheId = $id;
return $this;
$setCacheEntry($data);
return $data;
}
/**
@@ -555,37 +756,58 @@ abstract class AbstractQuery
* Will return the configured id if it exists otherwise a hash will be
* automatically generated for you.
*
* @return string $id
* @return array ($key, $hash)
*/
protected function _getResultCacheId()
protected function getHydrationCacheId()
{
if ($this->_resultCacheId) {
return $this->_resultCacheId;
} else {
$params = $this->_params;
foreach ($params AS $key => $value) {
if (is_object($value) && $this->_em->getMetadataFactory()->hasMetadataFor(get_class($value))) {
if ($this->_em->getUnitOfWork()->getEntityState($value) == UnitOfWork::STATE_MANAGED) {
$idValues = $this->_em->getUnitOfWork()->getEntityIdentifier($value);
} else {
$class = $this->_em->getClassMetadata(get_class($value));
$idValues = $class->getIdentifierValues($value);
}
$params[$key] = $idValues;
}
}
$parameters = array();
$sql = $this->getSql();
ksort($this->_hints);
return md5(implode(";", (array)$sql) . var_export($params, true) .
var_export($this->_hints, true)."&hydrationMode=".$this->_hydrationMode);
foreach ($this->getParameters() as $parameter) {
$parameters[$parameter->getName()] = $this->processParameterValue($parameter->getValue());
}
$sql = $this->getSQL();
$queryCacheProfile = $this->getHydrationCacheProfile();
$hints = $this->getHints();
$hints['hydrationMode'] = $this->getHydrationMode();
ksort($hints);
return $queryCacheProfile->generateCacheKeys($sql, $parameters, $hints);
}
/**
* Set the result cache id to use to store the result set cache entry.
* If this is not explicitly set by the developer then a hash is automatically
* generated for you.
*
* @param string $id
* @return \Doctrine\ORM\AbstractQuery This query instance.
*/
public function setResultCacheId($id)
{
$this->_queryCacheProfile = $this->_queryCacheProfile
? $this->_queryCacheProfile->setCacheKey($id)
: new QueryCacheProfile(0, $id, $this->_em->getConfiguration()->getResultCacheImpl());
return $this;
}
/**
* Get the result cache id to use to store the result set cache entry if set.
*
* @deprecated
* @return string
*/
public function getResultCacheId()
{
return $this->_queryCacheProfile ? $this->_queryCacheProfile->getCacheKey() : null;
}
/**
* Executes the query and returns a the resulting Statement object.
*
* @return Doctrine\DBAL\Driver\Statement The executed database statement that holds the results.
* @return \Doctrine\DBAL\Driver\Statement The executed database statement that holds the results.
*/
abstract protected function _doExecute();
@@ -596,8 +818,8 @@ abstract class AbstractQuery
*/
public function __clone()
{
$this->_params = array();
$this->_paramTypes = array();
$this->parameters = new ArrayCollection();
$this->_hints = array();
}
}
+275 -78
View File
@@ -13,14 +13,24 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM;
use Doctrine\Common\Cache\Cache,
Doctrine\ORM\Mapping\Driver\Driver;
Doctrine\Common\Cache\ArrayCache,
Doctrine\Common\Annotations\AnnotationRegistry,
Doctrine\Common\Annotations\AnnotationReader,
Doctrine\Common\Persistence\Mapping\Driver\MappingDriver,
Doctrine\ORM\Mapping\Driver\AnnotationDriver,
Doctrine\ORM\Mapping\QuoteStrategy,
Doctrine\ORM\Mapping\DefaultQuoteStrategy,
Doctrine\ORM\Mapping\NamingStrategy,
Doctrine\ORM\Mapping\DefaultNamingStrategy,
Doctrine\Common\Annotations\SimpleAnnotationReader,
Doctrine\Common\Annotations\CachedReader;
/**
* Configuration container for all configuration options of Doctrine.
@@ -52,8 +62,9 @@ class Configuration extends \Doctrine\DBAL\Configuration
*/
public function getProxyDir()
{
return isset($this->_attributes['proxyDir']) ?
$this->_attributes['proxyDir'] : null;
return isset($this->_attributes['proxyDir'])
? $this->_attributes['proxyDir']
: null;
}
/**
@@ -64,8 +75,9 @@ class Configuration extends \Doctrine\DBAL\Configuration
*/
public function getAutoGenerateProxyClasses()
{
return isset($this->_attributes['autoGenerateProxyClasses']) ?
$this->_attributes['autoGenerateProxyClasses'] : true;
return isset($this->_attributes['autoGenerateProxyClasses'])
? $this->_attributes['autoGenerateProxyClasses']
: true;
}
/**
@@ -81,18 +93,19 @@ class Configuration extends \Doctrine\DBAL\Configuration
/**
* Gets the namespace where proxy classes reside.
*
*
* @return string
*/
public function getProxyNamespace()
{
return isset($this->_attributes['proxyNamespace']) ?
$this->_attributes['proxyNamespace'] : null;
return isset($this->_attributes['proxyNamespace'])
? $this->_attributes['proxyNamespace']
: null;
}
/**
* Sets the namespace where proxy classes reside.
*
*
* @param string $ns
*/
public function setProxyNamespace($ns)
@@ -103,27 +116,40 @@ class Configuration extends \Doctrine\DBAL\Configuration
/**
* Sets the cache driver implementation that is used for metadata caching.
*
* @param Driver $driverImpl
* @param MappingDriver $driverImpl
* @todo Force parameter to be a Closure to ensure lazy evaluation
* (as soon as a metadata cache is in effect, the driver never needs to initialize).
*/
public function setMetadataDriverImpl(Driver $driverImpl)
public function setMetadataDriverImpl(MappingDriver $driverImpl)
{
$this->_attributes['metadataDriverImpl'] = $driverImpl;
}
/**
* Add a new default annotation driver with a correctly configured annotation reader.
*
* Add a new default annotation driver with a correctly configured annotation reader. If $useSimpleAnnotationReader
* is true, the notation `@Entity` will work, otherwise, the notation `@ORM\Entity` will be supported.
*
* @param array $paths
* @return Mapping\Driver\AnnotationDriver
* @param bool $useSimpleAnnotationReader
* @return AnnotationDriver
*/
public function newDefaultAnnotationDriver($paths = array())
public function newDefaultAnnotationDriver($paths = array(), $useSimpleAnnotationReader = true)
{
$reader = new \Doctrine\Common\Annotations\AnnotationReader();
$reader->setDefaultAnnotationNamespace('Doctrine\ORM\Mapping\\');
return new \Doctrine\ORM\Mapping\Driver\AnnotationDriver($reader, (array)$paths);
AnnotationRegistry::registerFile(__DIR__ . '/Mapping/Driver/DoctrineAnnotations.php');
if ($useSimpleAnnotationReader) {
// Register the ORM Annotations in the AnnotationRegistry
$reader = new SimpleAnnotationReader();
$reader->addNamespace('Doctrine\ORM\Mapping');
$cachedReader = new CachedReader($reader, new ArrayCache());
return new AnnotationDriver($cachedReader, (array) $paths);
}
return new AnnotationDriver(
new CachedReader(new AnnotationReader(), new ArrayCache()),
(array) $paths
);
}
/**
@@ -140,9 +166,9 @@ class Configuration extends \Doctrine\DBAL\Configuration
/**
* Resolves a registered namespace alias to the full namespace.
*
* @param string $entityNamespaceAlias
* @param string $entityNamespaceAlias
* @throws ORMException
* @return string
* @throws MappingException
*/
public function getEntityNamespace($entityNamespaceAlias)
{
@@ -156,45 +182,34 @@ class Configuration extends \Doctrine\DBAL\Configuration
/**
* Set the entity alias map
*
* @param array $entityAliasMap
* @return void
* @param array $entityNamespaces
*/
public function setEntityNamespaces(array $entityNamespaces)
{
$this->_attributes['entityNamespaces'] = $entityNamespaces;
}
/**
* Retrieves the list of registered entity namespace aliases.
*
* @return array
*/
public function getEntityNamespaces()
{
return $this->_attributes['entityNamespaces'];
}
/**
* Gets the cache driver implementation that is used for the mapping metadata.
*
* @throws ORMException
* @return Mapping\Driver\Driver
* @return MappingDriver
*/
public function getMetadataDriverImpl()
{
return isset($this->_attributes['metadataDriverImpl']) ?
$this->_attributes['metadataDriverImpl'] : null;
}
/**
* Gets the cache driver implementation that is used for query result caching.
*
* @return \Doctrine\Common\Cache\Cache
*/
public function getResultCacheImpl()
{
return isset($this->_attributes['resultCacheImpl']) ?
$this->_attributes['resultCacheImpl'] : null;
}
/**
* Sets the cache driver implementation that is used for query result caching.
*
* @param \Doctrine\Common\Cache\Cache $cacheImpl
*/
public function setResultCacheImpl(Cache $cacheImpl)
{
$this->_attributes['resultCacheImpl'] = $cacheImpl;
return isset($this->_attributes['metadataDriverImpl'])
? $this->_attributes['metadataDriverImpl']
: null;
}
/**
@@ -204,8 +219,9 @@ class Configuration extends \Doctrine\DBAL\Configuration
*/
public function getQueryCacheImpl()
{
return isset($this->_attributes['queryCacheImpl']) ?
$this->_attributes['queryCacheImpl'] : null;
return isset($this->_attributes['queryCacheImpl'])
? $this->_attributes['queryCacheImpl']
: null;
}
/**
@@ -218,6 +234,28 @@ class Configuration extends \Doctrine\DBAL\Configuration
$this->_attributes['queryCacheImpl'] = $cacheImpl;
}
/**
* Gets the cache driver implementation that is used for the hydration cache (SQL cache).
*
* @return \Doctrine\Common\Cache\Cache
*/
public function getHydrationCacheImpl()
{
return isset($this->_attributes['hydrationCacheImpl'])
? $this->_attributes['hydrationCacheImpl']
: null;
}
/**
* Sets the cache driver implementation that is used for the hydration cache (SQL cache).
*
* @param \Doctrine\Common\Cache\Cache $cacheImpl
*/
public function setHydrationCacheImpl(Cache $cacheImpl)
{
$this->_attributes['hydrationCacheImpl'] = $cacheImpl;
}
/**
* Gets the cache driver implementation that is used for metadata caching.
*
@@ -225,8 +263,9 @@ class Configuration extends \Doctrine\DBAL\Configuration
*/
public function getMetadataCacheImpl()
{
return isset($this->_attributes['metadataCacheImpl']) ?
$this->_attributes['metadataCacheImpl'] : null;
return isset($this->_attributes['metadataCacheImpl'])
? $this->_attributes['metadataCacheImpl']
: null;
}
/**
@@ -254,6 +293,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
* Gets a previously registered named DQL query.
*
* @param string $name The name of the query.
* @throws ORMException
* @return string The DQL query.
*/
public function getNamedQuery($name)
@@ -261,15 +301,16 @@ class Configuration extends \Doctrine\DBAL\Configuration
if ( ! isset($this->_attributes['namedQueries'][$name])) {
throw ORMException::namedQueryNotFound($name);
}
return $this->_attributes['namedQueries'][$name];
}
/**
* Adds a named native query to the configuration.
*
* @param string $name The name of the query.
* @param string $sql The native SQL query string.
* @param ResultSetMapping $rsm The ResultSetMapping used for the results of the SQL query.
* @param string $name The name of the query.
* @param string $sql The native SQL query string.
* @param Query\ResultSetMapping $rsm The ResultSetMapping used for the results of the SQL query.
*/
public function addNamedNativeQuery($name, $sql, Query\ResultSetMapping $rsm)
{
@@ -279,15 +320,17 @@ class Configuration extends \Doctrine\DBAL\Configuration
/**
* Gets the components of a previously registered named native query.
*
* @param string $name The name of the query.
* @return array A tuple with the first element being the SQL string and the second
* element being the ResultSetMapping.
* @param string $name The name of the query.
* @throws ORMException
* @return array A tuple with the first element being the SQL string and the second
* element being the ResultSetMapping.
*/
public function getNamedNativeQuery($name)
{
if ( ! isset($this->_attributes['namedNativeQueries'][$name])) {
throw ORMException::namedNativeQueryNotFound($name);
}
return $this->_attributes['namedNativeQueries'][$name];
}
@@ -300,12 +343,14 @@ class Configuration extends \Doctrine\DBAL\Configuration
*/
public function ensureProductionSettings()
{
if ( !$this->getQueryCacheImpl()) {
if ( ! $this->getQueryCacheImpl()) {
throw ORMException::queryCacheNotConfigured();
}
if ( !$this->getMetadataCacheImpl()) {
if ( ! $this->getMetadataCacheImpl()) {
throw ORMException::metadataCacheNotConfigured();
}
if ($this->getAutoGenerateProxyClasses()) {
throw ORMException::proxyClassesAlwaysRegenerating();
}
@@ -320,23 +365,30 @@ class Configuration extends \Doctrine\DBAL\Configuration
*
* @param string $name
* @param string $className
* @throws ORMException
*/
public function addCustomStringFunction($name, $className)
{
if (Query\Parser::isInternalFunction($name)) {
throw ORMException::overwriteInternalDQLFunctionNotAllowed($name);
}
$this->_attributes['customStringFunctions'][strtolower($name)] = $className;
}
/**
* Gets the implementation class name of a registered custom string DQL function.
*
*
* @param string $name
* @return string
*/
public function getCustomStringFunction($name)
{
$name = strtolower($name);
return isset($this->_attributes['customStringFunctions'][$name]) ?
$this->_attributes['customStringFunctions'][$name] : null;
return isset($this->_attributes['customStringFunctions'][$name])
? $this->_attributes['customStringFunctions'][$name]
: null;
}
/**
@@ -351,7 +403,9 @@ class Configuration extends \Doctrine\DBAL\Configuration
*/
public function setCustomStringFunctions(array $functions)
{
$this->_attributes['customStringFunctions'] = array_change_key_case($functions);
foreach ($functions as $name => $className) {
$this->addCustomStringFunction($name, $className);
}
}
/**
@@ -363,23 +417,30 @@ class Configuration extends \Doctrine\DBAL\Configuration
*
* @param string $name
* @param string $className
* @throws ORMException
*/
public function addCustomNumericFunction($name, $className)
{
if (Query\Parser::isInternalFunction($name)) {
throw ORMException::overwriteInternalDQLFunctionNotAllowed($name);
}
$this->_attributes['customNumericFunctions'][strtolower($name)] = $className;
}
/**
* Gets the implementation class name of a registered custom numeric DQL function.
*
*
* @param string $name
* @return string
*/
public function getCustomNumericFunction($name)
{
$name = strtolower($name);
return isset($this->_attributes['customNumericFunctions'][$name]) ?
$this->_attributes['customNumericFunctions'][$name] : null;
return isset($this->_attributes['customNumericFunctions'][$name])
? $this->_attributes['customNumericFunctions'][$name]
: null;
}
/**
@@ -394,7 +455,9 @@ class Configuration extends \Doctrine\DBAL\Configuration
*/
public function setCustomNumericFunctions(array $functions)
{
$this->_attributes['customNumericFunctions'] = array_change_key_case($functions);
foreach ($functions as $name => $className) {
$this->addCustomNumericFunction($name, $className);
}
}
/**
@@ -406,23 +469,30 @@ class Configuration extends \Doctrine\DBAL\Configuration
*
* @param string $name
* @param string $className
* @throws ORMException
*/
public function addCustomDatetimeFunction($name, $className)
{
if (Query\Parser::isInternalFunction($name)) {
throw ORMException::overwriteInternalDQLFunctionNotAllowed($name);
}
$this->_attributes['customDatetimeFunctions'][strtolower($name)] = $className;
}
/**
* Gets the implementation class name of a registered custom date/time DQL function.
*
*
* @param string $name
* @return string
*/
public function getCustomDatetimeFunction($name)
{
$name = strtolower($name);
return isset($this->_attributes['customDatetimeFunctions'][$name]) ?
$this->_attributes['customDatetimeFunctions'][$name] : null;
return isset($this->_attributes['customDatetimeFunctions'][$name])
? $this->_attributes['customDatetimeFunctions'][$name]
: null;
}
/**
@@ -437,7 +507,23 @@ class Configuration extends \Doctrine\DBAL\Configuration
*/
public function setCustomDatetimeFunctions(array $functions)
{
$this->_attributes['customDatetimeFunctions'] = array_change_key_case($functions);
foreach ($functions as $name => $className) {
$this->addCustomDatetimeFunction($name, $className);
}
}
/**
* Set the custom hydrator modes in one pass.
*
* @param array An array of ($modeName => $hydrator)
*/
public function setCustomHydrationModes($modes)
{
$this->_attributes['customHydrationModes'] = array();
foreach ($modes as $modeName => $hydrator) {
$this->addCustomHydrationMode($modeName, $hydrator);
}
}
/**
@@ -448,8 +534,9 @@ class Configuration extends \Doctrine\DBAL\Configuration
*/
public function getCustomHydrationMode($modeName)
{
return isset($this->_attributes['customHydrationModes'][$modeName]) ?
$this->_attributes['customHydrationModes'][$modeName] : null;
return isset($this->_attributes['customHydrationModes'][$modeName])
? $this->_attributes['customHydrationModes'][$modeName]
: null;
}
/**
@@ -465,8 +552,8 @@ class Configuration extends \Doctrine\DBAL\Configuration
/**
* Set a class metadata factory.
*
* @param string $cmf
*
* @param string $cmfName
*/
public function setClassMetadataFactoryName($cmfName)
{
@@ -478,9 +565,119 @@ class Configuration extends \Doctrine\DBAL\Configuration
*/
public function getClassMetadataFactoryName()
{
if (!isset($this->_attributes['classMetadataFactoryName'])) {
if ( ! isset($this->_attributes['classMetadataFactoryName'])) {
$this->_attributes['classMetadataFactoryName'] = 'Doctrine\ORM\Mapping\ClassMetadataFactory';
}
return $this->_attributes['classMetadataFactoryName'];
}
}
/**
* Add a filter to the list of possible filters.
*
* @param string $name The name of the filter.
* @param string $className The class name of the filter.
*/
public function addFilter($name, $className)
{
$this->_attributes['filters'][$name] = $className;
}
/**
* Gets the class name for a given filter name.
*
* @param string $name The name of the filter.
*
* @return string The class name of the filter, or null of it is not
* defined.
*/
public function getFilterClassName($name)
{
return isset($this->_attributes['filters'][$name])
? $this->_attributes['filters'][$name]
: null;
}
/**
* Set default repository class.
*
* @since 2.2
* @param string $className
* @throws ORMException If not is a \Doctrine\Common\Persistence\ObjectRepository
*/
public function setDefaultRepositoryClassName($className)
{
$reflectionClass = new \ReflectionClass($className);
if ( ! $reflectionClass->implementsInterface('Doctrine\Common\Persistence\ObjectRepository')) {
throw ORMException::invalidEntityRepository($className);
}
$this->_attributes['defaultRepositoryClassName'] = $className;
}
/**
* Get default repository class.
*
* @since 2.2
* @return string
*/
public function getDefaultRepositoryClassName()
{
return isset($this->_attributes['defaultRepositoryClassName'])
? $this->_attributes['defaultRepositoryClassName']
: 'Doctrine\ORM\EntityRepository';
}
/**
* Set naming strategy.
*
* @since 2.3
* @param NamingStrategy $namingStrategy
*/
public function setNamingStrategy(NamingStrategy $namingStrategy)
{
$this->_attributes['namingStrategy'] = $namingStrategy;
}
/**
* Get naming strategy..
*
* @since 2.3
* @return NamingStrategy
*/
public function getNamingStrategy()
{
if ( ! isset($this->_attributes['namingStrategy'])) {
$this->_attributes['namingStrategy'] = new DefaultNamingStrategy();
}
return $this->_attributes['namingStrategy'];
}
/**
* Set quote strategy.
*
* @since 2.3
* @param Doctrine\ORM\Mapping\QuoteStrategy $quoteStrategy
*/
public function setQuoteStrategy(QuoteStrategy $quoteStrategy)
{
$this->_attributes['quoteStrategy'] = $quoteStrategy;
}
/**
* Get quote strategy.
*
* @since 2.3
* @return Doctrine\ORM\Mapping\QuoteStrategy
*/
public function getQuoteStrategy()
{
if ( ! isset($this->_attributes['quoteStrategy'])) {
$this->_attributes['quoteStrategy'] = new DefaultQuoteStrategy();
}
return $this->_attributes['quoteStrategy'];
}
}
+287 -114
View File
@@ -13,20 +13,22 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM;
use Closure, Exception,
use Exception,
Doctrine\Common\EventManager,
Doctrine\Common\Persistence\ObjectManager,
Doctrine\DBAL\Connection,
Doctrine\DBAL\LockMode,
Doctrine\ORM\Mapping\ClassMetadata,
Doctrine\ORM\Mapping\ClassMetadataFactory,
Doctrine\ORM\Query\ResultSetMapping,
Doctrine\ORM\Proxy\ProxyFactory;
Doctrine\ORM\Proxy\ProxyFactory,
Doctrine\ORM\Query\FilterCollection;
/**
* The EntityManager is the central access point to ORM functionality.
@@ -37,26 +39,26 @@ use Closure, Exception,
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class EntityManager
class EntityManager implements ObjectManager
{
/**
* The used Configuration.
*
* @var Doctrine\ORM\Configuration
* @var \Doctrine\ORM\Configuration
*/
private $config;
/**
* The database connection used by the EntityManager.
*
* @var Doctrine\DBAL\Connection
* @var \Doctrine\DBAL\Connection
*/
private $conn;
/**
* The metadata factory, used to retrieve the ORM metadata of entity classes.
*
* @var Doctrine\ORM\Mapping\ClassMetadataFactory
* @var \Doctrine\ORM\Mapping\ClassMetadataFactory
*/
private $metadataFactory;
@@ -70,14 +72,14 @@ class EntityManager
/**
* The UnitOfWork used to coordinate object-level transactions.
*
* @var Doctrine\ORM\UnitOfWork
* @var \Doctrine\ORM\UnitOfWork
*/
private $unitOfWork;
/**
* The event manager that is the central point of the event system.
*
* @var Doctrine\Common\EventManager
* @var \Doctrine\Common\EventManager
*/
private $eventManager;
@@ -91,50 +93,64 @@ class EntityManager
/**
* The proxy factory used to create dynamic proxies.
*
* @var Doctrine\ORM\Proxy\ProxyFactory
* @var \Doctrine\ORM\Proxy\ProxyFactory
*/
private $proxyFactory;
/**
* @var ExpressionBuilder The expression builder instance used to generate query expressions.
* The expression builder instance used to generate query expressions.
*
* @var \Doctrine\ORM\Query\Expr
*/
private $expressionBuilder;
/**
* Whether the EntityManager is closed or not.
*
* @var bool
*/
private $closed = false;
/**
* Collection of query filters.
*
* @var Doctrine\ORM\Query\FilterCollection
*/
private $filterCollection;
/**
* Creates a new EntityManager that operates on the given database connection
* and uses the given Configuration and EventManager implementations.
*
* @param Doctrine\DBAL\Connection $conn
* @param Doctrine\ORM\Configuration $config
* @param Doctrine\Common\EventManager $eventManager
* @param \Doctrine\DBAL\Connection $conn
* @param \Doctrine\ORM\Configuration $config
* @param \Doctrine\Common\EventManager $eventManager
*/
protected function __construct(Connection $conn, Configuration $config, EventManager $eventManager)
{
$this->conn = $conn;
$this->config = $config;
$this->conn = $conn;
$this->config = $config;
$this->eventManager = $eventManager;
$metadataFactoryClassName = $config->getClassMetadataFactoryName();
$this->metadataFactory = new $metadataFactoryClassName;
$this->metadataFactory->setEntityManager($this);
$this->metadataFactory->setCacheDriver($this->config->getMetadataCacheImpl());
$this->unitOfWork = new UnitOfWork($this);
$this->proxyFactory = new ProxyFactory($this,
$config->getProxyDir(),
$config->getProxyNamespace(),
$config->getAutoGenerateProxyClasses());
$this->unitOfWork = new UnitOfWork($this);
$this->proxyFactory = new ProxyFactory(
$this,
$config->getProxyDir(),
$config->getProxyNamespace(),
$config->getAutoGenerateProxyClasses()
);
}
/**
* Gets the database connection object used by the EntityManager.
*
* @return Doctrine\DBAL\Connection
* @return \Doctrine\DBAL\Connection
*/
public function getConnection()
{
@@ -144,7 +160,7 @@ class EntityManager
/**
* Gets the metadata factory used to gather the metadata of classes.
*
* @return Doctrine\ORM\Mapping\ClassMetadataFactory
* @return \Doctrine\ORM\Mapping\ClassMetadataFactory
*/
public function getMetadataFactory()
{
@@ -163,20 +179,19 @@ class EntityManager
* ->where($expr->orX($expr->eq('u.id', 1), $expr->eq('u.id', 2)));
* </code>
*
* @return ExpressionBuilder
* @return \Doctrine\ORM\Query\Expr
*/
public function getExpressionBuilder()
{
if ($this->expressionBuilder === null) {
$this->expressionBuilder = new Query\Expr;
}
return $this->expressionBuilder;
}
/**
* Starts a transaction on the underlying database connection.
*
* @deprecated Use {@link getConnection}.beginTransaction().
*/
public function beginTransaction()
{
@@ -193,26 +208,34 @@ class EntityManager
* If an exception occurs during execution of the function or flushing or transaction commit,
* the transaction is rolled back, the EntityManager closed and the exception re-thrown.
*
* @param Closure $func The function to execute transactionally.
* @param callable $func The function to execute transactionally.
* @return mixed Returns the non-empty value returned from the closure or true instead
*/
public function transactional(Closure $func)
public function transactional($func)
{
if (!is_callable($func)) {
throw new \InvalidArgumentException('Expected argument of type "callable", got "' . gettype($func) . '"');
}
$this->conn->beginTransaction();
try {
$func($this);
$return = call_user_func($func, $this);
$this->flush();
$this->conn->commit();
return $return ?: true;
} catch (Exception $e) {
$this->close();
$this->conn->rollback();
throw $e;
}
}
/**
* Commits a transaction on the underlying database connection.
*
* @deprecated Use {@link getConnection}.commit().
*/
public function commit()
{
@@ -221,8 +244,6 @@ class EntityManager
/**
* Performs a rollback on the underlying database connection.
*
* @deprecated Use {@link getConnection}.rollback().
*/
public function rollback()
{
@@ -234,12 +255,12 @@ class EntityManager
*
* The class name must be the fully-qualified class name without a leading backslash
* (as it is returned by get_class($obj)) or an aliased class name.
*
*
* Examples:
* MyProject\Domain\User
* sales:PriceRequest
*
* @return Doctrine\ORM\Mapping\ClassMetadata
* @return \Doctrine\ORM\Mapping\ClassMetadata
* @internal Performance-sensitive method.
*/
public function getClassMetadata($className)
@@ -250,15 +271,17 @@ class EntityManager
/**
* Creates a new Query object.
*
* @param string The DQL string.
* @return Doctrine\ORM\Query
* @param string $dql The DQL string.
* @return \Doctrine\ORM\Query
*/
public function createQuery($dql = "")
{
$query = new Query($this);
if ( ! empty($dql)) {
$query->setDql($dql);
}
return $query;
}
@@ -266,7 +289,7 @@ class EntityManager
* Creates a Query from a named query.
*
* @param string $name
* @return Doctrine\ORM\Query
* @return \Doctrine\ORM\Query
*/
public function createNamedQuery($name)
{
@@ -283,8 +306,10 @@ class EntityManager
public function createNativeQuery($sql, ResultSetMapping $rsm)
{
$query = new NativeQuery($this);
$query->setSql($sql);
$query->setResultSetMapping($rsm);
return $query;
}
@@ -292,11 +317,12 @@ class EntityManager
* Creates a NativeQuery from a named native query.
*
* @param string $name
* @return Doctrine\ORM\NativeQuery
* @return \Doctrine\ORM\NativeQuery
*/
public function createNamedNativeQuery($name)
{
list($sql, $rsm) = $this->config->getNamedNativeQuery($name);
return $this->createNativeQuery($sql, $rsm);
}
@@ -315,29 +341,95 @@ class EntityManager
* This effectively synchronizes the in-memory state of managed objects with the
* database.
*
* @throws Doctrine\ORM\OptimisticLockException If a version check on an entity that
* If an entity is explicitly passed to this method only this entity and
* the cascade-persist semantics + scheduled inserts/removals are synchronized.
*
* @param object $entity
* @throws \Doctrine\ORM\OptimisticLockException If a version check on an entity that
* makes use of optimistic locking fails.
*/
public function flush()
public function flush($entity = null)
{
$this->errorIfClosed();
$this->unitOfWork->commit();
}
$this->unitOfWork->commit($entity);
}
/**
* Finds an Entity by its identifier.
*
* This is just a convenient shortcut for getRepository($entityName)->find($id).
*
* @param string $entityName
* @param mixed $identifier
* @param int $lockMode
* @param int $lockVersion
* @param mixed $id
* @param integer $lockMode
* @param integer $lockVersion
*
* @return object
*/
public function find($entityName, $identifier, $lockMode = LockMode::NONE, $lockVersion = null)
public function find($entityName, $id, $lockMode = LockMode::NONE, $lockVersion = null)
{
return $this->getRepository($entityName)->find($identifier, $lockMode, $lockVersion);
$class = $this->metadataFactory->getMetadataFor(ltrim($entityName, '\\'));
if ( ! is_array($id)) {
$id = array($class->identifier[0] => $id);
}
$sortedId = array();
foreach ($class->identifier as $identifier) {
if ( ! isset($id[$identifier])) {
throw ORMException::missingIdentifierField($class->name, $identifier);
}
$sortedId[$identifier] = $id[$identifier];
}
$unitOfWork = $this->getUnitOfWork();
// Check identity map first
if (($entity = $unitOfWork->tryGetById($sortedId, $class->rootEntityName)) !== false) {
if ( ! ($entity instanceof $class->name)) {
return null;
}
switch ($lockMode) {
case LockMode::OPTIMISTIC:
$this->lock($entity, $lockMode, $lockVersion);
break;
case LockMode::PESSIMISTIC_READ:
case LockMode::PESSIMISTIC_WRITE:
$persister = $unitOfWork->getEntityPersister($class->name);
$persister->refresh($sortedId, $entity, $lockMode);
break;
}
return $entity; // Hit!
}
$persister = $unitOfWork->getEntityPersister($class->name);
switch ($lockMode) {
case LockMode::NONE:
return $persister->load($sortedId);
case LockMode::OPTIMISTIC:
if ( ! $class->isVersioned) {
throw OptimisticLockException::notVersioned($class->name);
}
$entity = $persister->load($sortedId);
$unitOfWork->lock($entity, $lockMode, $lockVersion);
return $entity;
default:
if ( ! $this->getConnection()->isTransactionActive()) {
throw TransactionRequiredException::transactionRequired();
}
return $persister->load($sortedId, null, null, array(), $lockMode);
}
}
/**
@@ -345,27 +437,44 @@ class EntityManager
* without actually loading it, if the entity is not yet loaded.
*
* @param string $entityName The name of the entity type.
* @param mixed $identifier The entity identifier.
* @param mixed $id The entity identifier.
* @return object The entity reference.
*/
public function getReference($entityName, $identifier)
public function getReference($entityName, $id)
{
$class = $this->metadataFactory->getMetadataFor(ltrim($entityName, '\\'));
// Check identity map first, if its already in there just return it.
if ($entity = $this->unitOfWork->tryGetById($identifier, $class->rootEntityName)) {
return $entity;
if ( ! is_array($id)) {
$id = array($class->identifier[0] => $id);
}
if ($class->subClasses) {
$entity = $this->find($entityName, $identifier);
} else {
if ( ! is_array($identifier)) {
$identifier = array($class->identifier[0] => $identifier);
$sortedId = array();
foreach ($class->identifier as $identifier) {
if ( ! isset($id[$identifier])) {
throw ORMException::missingIdentifierField($class->name, $identifier);
}
$entity = $this->proxyFactory->getProxy($class->name, $identifier);
$this->unitOfWork->registerManaged($entity, $identifier, array());
$sortedId[$identifier] = $id[$identifier];
}
// Check identity map first, if its already in there just return it.
if (($entity = $this->unitOfWork->tryGetById($sortedId, $class->rootEntityName)) !== false) {
return ($entity instanceof $class->name) ? $entity : null;
}
if ($class->subClasses) {
return $this->find($entityName, $sortedId);
}
if ( ! is_array($sortedId)) {
$sortedId = array($class->identifier[0] => $sortedId);
}
$entity = $this->proxyFactory->getProxy($class->name, $sortedId);
$this->unitOfWork->registerManaged($entity, $sortedId, array());
return $entity;
}
@@ -393,16 +502,20 @@ class EntityManager
$class = $this->metadataFactory->getMetadataFor(ltrim($entityName, '\\'));
// Check identity map first, if its already in there just return it.
if ($entity = $this->unitOfWork->tryGetById($identifier, $class->rootEntityName)) {
return $entity;
if (($entity = $this->unitOfWork->tryGetById($identifier, $class->rootEntityName)) !== false) {
return ($entity instanceof $class->name) ? $entity : null;
}
if ( ! is_array($identifier)) {
$identifier = array($class->identifier[0] => $identifier);
}
$entity = $class->newInstance();
$class->setIdentifierValues($entity, $identifier);
$this->unitOfWork->registerManaged($entity, $identifier, array());
$this->unitOfWork->markReadOnly($entity);
return $entity;
}
@@ -411,16 +524,11 @@ class EntityManager
* Clears the EntityManager. All entities that are currently managed
* by this EntityManager become detached.
*
* @param string $entityName
* @param string $entityName if given, only entities of this type will get detached
*/
public function clear($entityName = null)
{
if ($entityName === null) {
$this->unitOfWork->clear();
} else {
//TODO
throw new ORMException("EntityManager#clear(\$entityName) not yet implemented.");
}
$this->unitOfWork->clear($entityName);
}
/**
@@ -431,6 +539,7 @@ class EntityManager
public function close()
{
$this->clear();
$this->closed = true;
}
@@ -439,7 +548,7 @@ class EntityManager
*
* The entity will be entered into the database at or before transaction
* commit or as a result of the flush operation.
*
*
* NOTE: The persist operation always considers entities that are not yet known to
* this EntityManager as NEW. Do not pass detached entities to the persist operation.
*
@@ -448,9 +557,11 @@ class EntityManager
public function persist($entity)
{
if ( ! is_object($entity)) {
throw new \InvalidArgumentException(gettype($entity));
throw ORMInvalidArgumentException::invalidObject('EntityManager#persist()' , $entity);
}
$this->errorIfClosed();
$this->unitOfWork->persist($entity);
}
@@ -465,9 +576,11 @@ class EntityManager
public function remove($entity)
{
if ( ! is_object($entity)) {
throw new \InvalidArgumentException(gettype($entity));
throw ORMInvalidArgumentException::invalidObject('EntityManager#remove()' , $entity);
}
$this->errorIfClosed();
$this->unitOfWork->remove($entity);
}
@@ -480,9 +593,11 @@ class EntityManager
public function refresh($entity)
{
if ( ! is_object($entity)) {
throw new \InvalidArgumentException(gettype($entity));
throw ORMInvalidArgumentException::invalidObject('EntityManager#refresh()' , $entity);
}
$this->errorIfClosed();
$this->unitOfWork->refresh($entity);
}
@@ -498,8 +613,9 @@ class EntityManager
public function detach($entity)
{
if ( ! is_object($entity)) {
throw new \InvalidArgumentException(gettype($entity));
throw ORMInvalidArgumentException::invalidObject('EntityManager#detach()' , $entity);
}
$this->unitOfWork->detach($entity);
}
@@ -514,9 +630,11 @@ class EntityManager
public function merge($entity)
{
if ( ! is_object($entity)) {
throw new \InvalidArgumentException(gettype($entity));
throw ORMInvalidArgumentException::invalidObject('EntityManager#merge()' , $entity);
}
$this->errorIfClosed();
return $this->unitOfWork->merge($entity);
}
@@ -556,19 +674,20 @@ class EntityManager
public function getRepository($entityName)
{
$entityName = ltrim($entityName, '\\');
if (isset($this->repositories[$entityName])) {
return $this->repositories[$entityName];
}
$metadata = $this->getClassMetadata($entityName);
$customRepositoryClassName = $metadata->customRepositoryClassName;
$repositoryClassName = $metadata->customRepositoryClassName;
if ($customRepositoryClassName !== null) {
$repository = new $customRepositoryClassName($this, $metadata);
} else {
$repository = new EntityRepository($this, $metadata);
if ($repositoryClassName === null) {
$repositoryClassName = $this->config->getDefaultRepositoryClassName();
}
$repository = new $repositoryClassName($this, $metadata);
$this->repositories[$entityName] = $repository;
return $repository;
@@ -582,15 +701,15 @@ class EntityManager
*/
public function contains($entity)
{
return $this->unitOfWork->isScheduledForInsert($entity) ||
$this->unitOfWork->isInIdentityMap($entity) &&
! $this->unitOfWork->isScheduledForDelete($entity);
return $this->unitOfWork->isScheduledForInsert($entity)
|| $this->unitOfWork->isInIdentityMap($entity)
&& ! $this->unitOfWork->isScheduledForDelete($entity);
}
/**
* Gets the EventManager used by the EntityManager.
*
* @return Doctrine\Common\EventManager
* @return \Doctrine\Common\EventManager
*/
public function getEventManager()
{
@@ -600,7 +719,7 @@ class EntityManager
/**
* Gets the Configuration used by the EntityManager.
*
* @return Doctrine\ORM\Configuration
* @return \Doctrine\ORM\Configuration
*/
public function getConfiguration()
{
@@ -621,7 +740,7 @@ class EntityManager
/**
* Check if the Entity manager is open or closed.
*
*
* @return bool
*/
public function isOpen()
@@ -632,7 +751,7 @@ class EntityManager
/**
* Gets the UnitOfWork used by the EntityManager to coordinate operations.
*
* @return Doctrine\ORM\UnitOfWork
* @return \Doctrine\ORM\UnitOfWork
*/
public function getUnitOfWork()
{
@@ -646,7 +765,7 @@ class EntityManager
* selectively iterate over the result.
*
* @param int $hydrationMode
* @return Doctrine\ORM\Internal\Hydration\AbstractHydrator
* @return \Doctrine\ORM\Internal\Hydration\AbstractHydrator
*/
public function getHydrator($hydrationMode)
{
@@ -661,32 +780,33 @@ class EntityManager
* Create a new instance for the given hydration mode.
*
* @param int $hydrationMode
* @return Doctrine\ORM\Internal\Hydration\AbstractHydrator
* @return \Doctrine\ORM\Internal\Hydration\AbstractHydrator
*/
public function newHydrator($hydrationMode)
{
switch ($hydrationMode) {
case Query::HYDRATE_OBJECT:
$hydrator = new Internal\Hydration\ObjectHydrator($this);
break;
return new Internal\Hydration\ObjectHydrator($this);
case Query::HYDRATE_ARRAY:
$hydrator = new Internal\Hydration\ArrayHydrator($this);
break;
return new Internal\Hydration\ArrayHydrator($this);
case Query::HYDRATE_SCALAR:
$hydrator = new Internal\Hydration\ScalarHydrator($this);
break;
return new Internal\Hydration\ScalarHydrator($this);
case Query::HYDRATE_SINGLE_SCALAR:
$hydrator = new Internal\Hydration\SingleScalarHydrator($this);
break;
return new Internal\Hydration\SingleScalarHydrator($this);
case Query::HYDRATE_SIMPLEOBJECT:
return new Internal\Hydration\SimpleObjectHydrator($this);
default:
if ($class = $this->config->getCustomHydrationMode($hydrationMode)) {
$hydrator = new $class($this);
break;
if (($class = $this->config->getCustomHydrationMode($hydrationMode)) !== null) {
return new $class($this);
}
throw ORMException::invalidHydrationMode($hydrationMode);
}
return $hydrator;
throw ORMException::invalidHydrationMode($hydrationMode);
}
/**
@@ -699,6 +819,18 @@ class EntityManager
return $this->proxyFactory;
}
/**
* Helper method to initialize a lazy loading proxy or persistent collection.
*
* This method is a no-op for other objects
*
* @param object $obj
*/
public function initializeObject($obj)
{
$this->unitOfWork->initializeObject($obj);
}
/**
* Factory method to create EntityManager instances.
*
@@ -710,20 +842,61 @@ class EntityManager
*/
public static function create($conn, Configuration $config, EventManager $eventManager = null)
{
if (!$config->getMetadataDriverImpl()) {
if ( ! $config->getMetadataDriverImpl()) {
throw ORMException::missingMappingDriverImpl();
}
if (is_array($conn)) {
$conn = \Doctrine\DBAL\DriverManager::getConnection($conn, $config, ($eventManager ?: new EventManager()));
} else if ($conn instanceof Connection) {
if ($eventManager !== null && $conn->getEventManager() !== $eventManager) {
throw ORMException::mismatchedEventManager();
}
} else {
throw new \InvalidArgumentException("Invalid argument: " . $conn);
switch (true) {
case (is_array($conn)):
$conn = \Doctrine\DBAL\DriverManager::getConnection(
$conn, $config, ($eventManager ?: new EventManager())
);
break;
case ($conn instanceof Connection):
if ($eventManager !== null && $conn->getEventManager() !== $eventManager) {
throw ORMException::mismatchedEventManager();
}
break;
default:
throw new \InvalidArgumentException("Invalid argument: " . $conn);
}
return new EntityManager($conn, $config, $conn->getEventManager());
}
/**
* Gets the enabled filters.
*
* @return FilterCollection The active filter collection.
*/
public function getFilters()
{
if (null === $this->filterCollection) {
$this->filterCollection = new FilterCollection($this);
}
return $this->filterCollection;
}
/**
* Checks whether the state of the filter collection is clean.
*
* @return boolean True, if the filter collection is clean.
*/
public function isFiltersStateClean()
{
return null === $this->filterCollection || $this->filterCollection->isClean();
}
/**
* Checks whether the Entity Manager has filters.
*
* @return True, if the EM has a filter collection.
*/
public function hasFilters()
{
return null !== $this->filterCollection;
}
}
+2 -2
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.');
}
}
}
+114 -63
View File
@@ -13,13 +13,19 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM;
use Doctrine\DBAL\LockMode;
use Doctrine\Common\Persistence\ObjectRepository;
use Doctrine\Common\Collections\Selectable;
use Doctrine\Common\Collections\Criteria;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\ExpressionBuilder;
/**
* An EntityRepository serves as a repository for entities with generic as well as
@@ -34,7 +40,7 @@ use Doctrine\DBAL\LockMode;
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class EntityRepository
class EntityRepository implements ObjectRepository, Selectable
{
/**
* @var string
@@ -47,7 +53,7 @@ class EntityRepository
protected $_em;
/**
* @var Doctrine\ORM\Mapping\ClassMetadata
* @var \Doctrine\ORM\Mapping\ClassMetadata
*/
protected $_class;
@@ -60,8 +66,8 @@ class EntityRepository
public function __construct($em, Mapping\ClassMetadata $class)
{
$this->_entityName = $class->name;
$this->_em = $em;
$this->_class = $class;
$this->_em = $em;
$this->_class = $class;
}
/**
@@ -77,6 +83,32 @@ class EntityRepository
->from($this->_entityName, $alias);
}
/**
* Create a new Query instance based on a predefined metadata named query.
*
* @param string $queryName
* @return Query
*/
public function createNamedQuery($queryName)
{
return $this->_em->createQuery($this->_class->getNamedQuery($queryName));
}
/**
* Creates a native SQL query.
*
* @param string $queryName
* @return NativeQuery
*/
public function createNativeNamedQuery($queryName)
{
$queryMapping = $this->_class->getNamedNativeQuery($queryName);
$rsm = new Query\ResultSetMappingBuilder($this->_em);
$rsm->addNamedNativeQueryMapping($this->_class, $queryMapping);
return $this->_em->createNativeQuery($queryMapping['query'], $rsm);
}
/**
* Clears the repository, causing all managed entities to become detached.
*/
@@ -88,46 +120,15 @@ class EntityRepository
/**
* Finds an entity by its primary key / identifier.
*
* @param $id The identifier.
* @param int $lockMode
* @param int $lockVersion
* @param mixed $id The identifier.
* @param integer $lockMode
* @param integer $lockVersion
*
* @return object The entity.
*/
public function find($id, $lockMode = LockMode::NONE, $lockVersion = null)
{
// Check identity map first
if ($entity = $this->_em->getUnitOfWork()->tryGetById($id, $this->_class->rootEntityName)) {
if ($lockMode != LockMode::NONE) {
$this->_em->lock($entity, $lockMode, $lockVersion);
}
return $entity; // Hit!
}
if ( ! is_array($id) || count($id) <= 1) {
// @todo FIXME: Not correct. Relies on specific order.
$value = is_array($id) ? array_values($id) : array($id);
$id = array_combine($this->_class->identifier, $value);
}
if ($lockMode == LockMode::NONE) {
return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->load($id);
} else if ($lockMode == LockMode::OPTIMISTIC) {
if (!$this->_class->isVersioned) {
throw OptimisticLockException::notVersioned($this->_entityName);
}
$entity = $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->load($id);
$this->_em->getUnitOfWork()->lock($entity, $lockMode, $lockVersion);
return $entity;
} else {
if (!$this->_em->getConnection()->isTransactionActive()) {
throw TransactionRequiredException::transactionRequired();
}
return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->load($id, null, null, array(), $lockMode);
}
return $this->_em->find($this->_entityName, $id, $lockMode, $lockVersion);
}
/**
@@ -144,11 +145,16 @@ class EntityRepository
* Finds entities by a set of criteria.
*
* @param array $criteria
* @return array
* @param array|null $orderBy
* @param int|null $limit
* @param int|null $offset
* @return array The objects.
*/
public function findBy(array $criteria)
public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
{
return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->loadAll($criteria);
$persister = $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName);
return $persister->loadAll($criteria, $orderBy, $limit, $offset);
}
/**
@@ -159,7 +165,9 @@ class EntityRepository
*/
public function findOneBy(array $criteria)
{
return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->load($criteria);
$persister = $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName);
return $persister->load($criteria, null, null, array(), 0, 1);
}
/**
@@ -172,31 +180,50 @@ class EntityRepository
*/
public function __call($method, $arguments)
{
if (substr($method, 0, 6) == 'findBy') {
$by = substr($method, 6, strlen($method));
$method = 'findBy';
} else if (substr($method, 0, 9) == 'findOneBy') {
$by = substr($method, 9, strlen($method));
$method = 'findOneBy';
} else {
throw new \BadMethodCallException(
"Undefined method '$method'. The method name must start with ".
"either findBy or findOneBy!"
);
switch (true) {
case (0 === strpos($method, 'findBy')):
$by = substr($method, 6);
$method = 'findBy';
break;
case (0 === strpos($method, 'findOneBy')):
$by = substr($method, 9);
$method = 'findOneBy';
break;
default:
throw new \BadMethodCallException(
"Undefined method '$method'. The method name must start with ".
"either findBy or findOneBy!"
);
}
if ( !isset($arguments[0])) {
// we dont even want to allow null at this point, because we cannot (yet) transform it into IS NULL.
throw ORMException::findByRequiresParameter($method.$by);
if (empty($arguments)) {
throw ORMException::findByRequiresParameter($method . $by);
}
$fieldName = lcfirst(\Doctrine\Common\Util\Inflector::classify($by));
if ($this->_class->hasField($fieldName) || $this->_class->hasAssociation($fieldName)) {
return $this->$method(array($fieldName => $arguments[0]));
} else {
throw ORMException::invalidFindByCall($this->_entityName, $fieldName, $method.$by);
switch (count($arguments)) {
case 1:
return $this->$method(array($fieldName => $arguments[0]));
case 2:
return $this->$method(array($fieldName => $arguments[0]), $arguments[1]);
case 3:
return $this->$method(array($fieldName => $arguments[0]), $arguments[1], $arguments[2]);
case 4;
return $this->$method(array($fieldName => $arguments[0]), $arguments[1], $arguments[2], $arguments[3]);
default:
// Do nothing
}
}
throw ORMException::invalidFindByCall($this->_entityName, $fieldName, $method.$by);
}
/**
@@ -207,6 +234,14 @@ class EntityRepository
return $this->_entityName;
}
/**
* @return string
*/
public function getClassName()
{
return $this->getEntityName();
}
/**
* @return EntityManager
*/
@@ -222,4 +257,20 @@ class EntityRepository
{
return $this->_class;
}
}
/**
* Select all elements from a selectable that match the expression and
* return a new collection containing these elements.
*
* @param \Doctrine\Common\Collections\Criteria $criteria
*
* @return \Doctrine\Common\Collections\Collection
*/
public function matching(Criteria $criteria)
{
$persister = $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName);
return new ArrayCollection($persister->loadCriteria($criteria));
}
}
+35 -18
View File
@@ -13,48 +13,65 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Event;
use Doctrine\Common\EventArgs;
use Doctrine\ORM\EntityManager;
/**
* Lifecycle Events are triggered by the UnitOfWork during lifecycle transitions
* of entities.
*
* @since 2.0
* @link www.doctrine-project.org
* @since 2.0
* @author Roman Borschel <roman@code-factory.de>
* @author Benjamin Eberlei <kontakt@beberlei.de>
*/
class LifecycleEventArgs extends \Doctrine\Common\EventArgs
class LifecycleEventArgs extends EventArgs
{
/**
* @var EntityManager
* @var \Doctrine\ORM\EntityManager
*/
private $_em;
private $em;
/**
* @var object
*/
private $_entity;
public function __construct($entity, $em)
private $entity;
/**
* Constructor
*
* @param object $entity
* @param \Doctrine\ORM\EntityManager $em
*/
public function __construct($entity, EntityManager $em)
{
$this->_entity = $entity;
$this->_em = $em;
}
public function getEntity()
{
return $this->_entity;
$this->entity = $entity;
$this->em = $em;
}
/**
* @return EntityManager
* Retrieve associated Entity.
*
* @return object
*/
public function getEntity()
{
return $this->entity;
}
/**
* Retrieve associated EntityManager.
*
* @return \Doctrine\ORM\EntityManager
*/
public function getEntityManager()
{
return $this->_em;
return $this->em;
}
}
}
@@ -1,9 +1,25 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Event;
use Doctrine\Common\EventArgs;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
use Doctrine\ORM\EntityManager;
@@ -11,32 +27,36 @@ use Doctrine\ORM\EntityManager;
* Class that holds event arguments for a loadMetadata event.
*
* @author Jonathan H. Wage <jonwage@gmail.com>
* @since 2.0
* @since 2.0
*/
class LoadClassMetadataEventArgs extends EventArgs
{
/**
* @var ClassMetadata
* @var \Doctrine\ORM\Mapping\ClassMetadata
*/
private $classMetadata;
/**
* @var EntityManager
* @var \Doctrine\ORM\EntityManager
*/
private $em;
/**
* @param ClassMetadataInfo $classMetadata
* @param EntityManager $em
* Constructor.
*
* @param \Doctrine\ORM\Mapping\ClassMetadataInfo $classMetadata
* @param \Doctrine\ORM\EntityManager $em
*/
public function __construct(ClassMetadataInfo $classMetadata, EntityManager $em)
{
$this->classMetadata = $classMetadata;
$this->em = $em;
$this->em = $em;
}
/**
* @return ClassMetadataInfo
* Retrieve associated ClassMetadata.
*
* @return \Doctrine\ORM\Mapping\ClassMetadataInfo
*/
public function getClassMetadata()
{
@@ -44,7 +64,9 @@ class LoadClassMetadataEventArgs extends EventArgs
}
/**
* @return EntityManager
* Retrieve associated EntityManager.
*
* @return \Doctrine\ORM\EntityManager
*/
public function getEntityManager()
{
@@ -0,0 +1,84 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Event;
/**
* Provides event arguments for the onClear event.
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 2.0
* @author Roman Borschel <roman@code-factory.de>
* @author Benjamin Eberlei <kontakt@beberlei.de>
*/
class OnClearEventArgs extends \Doctrine\Common\EventArgs
{
/**
* @var \Doctrine\ORM\EntityManager
*/
private $em;
/**
* @var string
*/
private $entityClass;
/**
* Constructor.
*
* @param \Doctrine\ORM\EntityManager $em
* @param string $entityClass Optional entity class
*/
public function __construct($em, $entityClass = null)
{
$this->em = $em;
$this->entityClass = $entityClass;
}
/**
* Retrieve associated EntityManager.
*
* @return \Doctrine\ORM\EntityManager
*/
public function getEntityManager()
{
return $this->em;
}
/**
* Name of the entity class that is cleared, or empty if all are cleared.
*
* @return string
*/
public function getEntityClass()
{
return $this->entityClass;
}
/**
* Check if event clears all entities.
*
* @return bool
*/
public function clearsAllEntities()
{
return ($this->entityClass === null);
}
}
+30 -24
View File
@@ -1,7 +1,5 @@
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -15,64 +13,72 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
*/
namespace Doctrine\ORM\Event;
use Doctrine\ORM\EntityManager;
/**
* Provides event arguments for the preFlush event.
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.com
* @link www.doctrine-project.org
* @since 2.0
* @version $Revision$
* @author Roman Borschel <roman@code-factory.de>
* @author Benjamin Eberlei <kontakt@beberlei.de>
*/
class OnFlushEventArgs extends \Doctrine\Common\EventArgs
{
/**
* @var EntityManager
* @var Doctirne\ORM\EntityManager
*/
private $_em;
//private $_entitiesToPersist = array();
//private $_entitiesToRemove = array();
public function __construct($em)
private $em;
//private $entitiesToPersist = array();
//private $entitiesToRemove = array();
/**
* Constructor.
*
* @param \Doctrine\ORM\EntityManager $em
*/
public function __construct(EntityManager $em)
{
$this->_em = $em;
$this->em = $em;
}
/**
* @return EntityManager
* Retrieve associated EntityManager.
*
* @return \Doctrine\ORM\EntityManager
*/
public function getEntityManager()
{
return $this->_em;
return $this->em;
}
/*
public function addEntityToPersist($entity)
{
}
public function addEntityToRemove($entity)
{
}
public function addEntityToUpdate($entity)
{
}
public function getEntitiesToPersist()
{
return $this->_entitiesToPersist;
}
*/
}
}
@@ -0,0 +1,58 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Event;
use Doctrine\ORM\EntityManager;
use Doctrine\Common\EventArgs;
/**
* Provides event arguments for the postFlush event.
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 2.0
* @author Daniel Freudenberger <df@rebuy.de>
*/
class PostFlushEventArgs extends EventArgs
{
/**
* @var \Doctrine\ORM\EntityManager
*/
private $em;
/**
* Constructor.
*
* @param \Doctrine\ORM\EntityManager $em
*/
public function __construct(EntityManager $em)
{
$this->em = $em;
}
/**
* Retrieve associated EntityManager.
*
* @return \Doctrine\ORM\EntityManager
*/
public function getEntityManager()
{
return $this->em;
}
}
@@ -0,0 +1,50 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Event;
/**
* Provides event arguments for the preFlush event.
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.com
* @since 2.0
* @author Roman Borschel <roman@code-factory.de>
* @author Benjamin Eberlei <kontakt@beberlei.de>
*/
class PreFlushEventArgs extends \Doctrine\Common\EventArgs
{
/**
* @var EntityManager
*/
private $_em;
public function __construct($em)
{
$this->_em = $em;
}
/**
* @return EntityManager
*/
public function getEntityManager()
{
return $this->_em;
}
}
+57 -26
View File
@@ -1,4 +1,21 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Event;
@@ -8,55 +25,63 @@ use Doctrine\Common\EventArgs,
/**
* Class that holds event arguments for a preInsert/preUpdate event.
*
* @author Guilherme Blanco <guilehrmeblanco@hotmail.com>
* @author Roman Borschel <roman@code-factory.org>
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @since 2.0
* @since 2.0
*/
class PreUpdateEventArgs extends LifecycleEventArgs
{
/**
* @var array
*/
private $_entityChangeSet;
private $entityChangeSet;
/**
* Constructor.
*
* @param object $entity
* @param EntityManager $em
* @param \Doctrine\ORM\EntityManager $em
* @param array $changeSet
*/
public function __construct($entity, $em, array &$changeSet)
public function __construct($entity, EntityManager $em, array &$changeSet)
{
parent::__construct($entity, $em);
$this->_entityChangeSet = &$changeSet;
}
public function getEntityChangeSet()
{
return $this->_entityChangeSet;
$this->entityChangeSet = &$changeSet;
}
/**
* Field has a changeset?
* Retrieve entity changeset.
*
* @return bool
* @return array
*/
public function getEntityChangeSet()
{
return $this->entityChangeSet;
}
/**
* Check if field has a changeset.
*
* @return boolean
*/
public function hasChangedField($field)
{
return isset($this->_entityChangeSet[$field]);
return isset($this->entityChangeSet[$field]);
}
/**
* Get the old value of the changeset of the changed field.
*
*
* @param string $field
* @return mixed
*/
public function getOldValue($field)
{
$this->_assertValidField($field);
$this->assertValidField($field);
return $this->_entityChangeSet[$field][0];
return $this->entityChangeSet[$field][0];
}
/**
@@ -67,31 +92,37 @@ class PreUpdateEventArgs extends LifecycleEventArgs
*/
public function getNewValue($field)
{
$this->_assertValidField($field);
$this->assertValidField($field);
return $this->_entityChangeSet[$field][1];
return $this->entityChangeSet[$field][1];
}
/**
* Set the new value of this field.
*
*
* @param string $field
* @param mixed $value
*/
public function setNewValue($field, $value)
{
$this->_assertValidField($field);
$this->assertValidField($field);
$this->_entityChangeSet[$field][1] = $value;
$this->entityChangeSet[$field][1] = $value;
}
private function _assertValidField($field)
/**
* Assert the field exists in changeset.
*
* @param string $field
*/
private function assertValidField($field)
{
if (!isset($this->_entityChangeSet[$field])) {
throw new \InvalidArgumentException(
"Field '".$field."' is not a valid field of the entity ".
"'".get_class($this->getEntity())."' in PreInsertUpdateEventArgs."
);
if ( ! isset($this->entityChangeSet[$field])) {
throw new \InvalidArgumentException(sprintf(
'Field "%s" is not a valid field of the entity "%s" in PreUpdateEventArgs.',
$field,
get_class($this->getEntity())
));
}
}
}
+52 -28
View File
@@ -1,7 +1,5 @@
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -15,7 +13,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
@@ -35,55 +33,55 @@ final class Events
/**
* The preRemove event occurs for a given entity before the respective
* EntityManager remove operation for that entity is executed.
*
*
* This is an entity lifecycle event.
*
*
* @var string
*/
const preRemove = 'preRemove';
/**
* The postRemove event occurs for an entity after the entity has
* The postRemove event occurs for an entity after the entity has
* been deleted. It will be invoked after the database delete operations.
*
*
* This is an entity lifecycle event.
*
*
* @var string
*/
const postRemove = 'postRemove';
/**
* The prePersist event occurs for a given entity before the respective
* EntityManager persist operation for that entity is executed.
*
*
* This is an entity lifecycle event.
*
*
* @var string
*/
const prePersist = 'prePersist';
/**
* The postPersist event occurs for an entity after the entity has
* The postPersist event occurs for an entity after the entity has
* been made persistent. It will be invoked after the database insert operations.
* Generated primary key values are available in the postPersist event.
*
*
* This is an entity lifecycle event.
*
*
* @var string
*/
const postPersist = 'postPersist';
/**
* The preUpdate event occurs before the database update operations to
* entity data.
*
* The preUpdate event occurs before the database update operations to
* entity data.
*
* This is an entity lifecycle event.
*
*
* @var string
*/
const preUpdate = 'preUpdate';
/**
* The postUpdate event occurs after the database update operations to
* entity data.
*
* The postUpdate event occurs after the database update operations to
* entity data.
*
* This is an entity lifecycle event.
*
*
* @var string
*/
const postUpdate = 'postUpdate';
@@ -91,32 +89,58 @@ final class Events
* The postLoad event occurs for an entity after the entity has been loaded
* into the current EntityManager from the database or after the refresh operation
* has been applied to it.
*
*
* Note that the postLoad event occurs for an entity before any associations have been
* initialized. Therefore it is not safe to access associations in a postLoad callback
* or event handler.
*
*
* This is an entity lifecycle event.
*
*
* @var string
*/
const postLoad = 'postLoad';
/**
* The loadClassMetadata event occurs after the mapping metadata for a class
* has been loaded from a mapping source (annotations/xml/yaml).
*
*
* @var string
*/
const loadClassMetadata = 'loadClassMetadata';
/**
* The preFlush event occurs when the EntityManager#flush() operation is invoked,
* but before any changes to managed entites have been calculated. This event is
* always raised right after EntityManager#flush() call.
*/
const preFlush = 'preFlush';
/**
* The onFlush event occurs when the EntityManager#flush() operation is invoked,
* after any changes to managed entities have been determined but before any
* actual database operations are executed. The event is only raised if there is
* actually something to do for the underlying UnitOfWork. If nothing needs to be done,
* the onFlush event is not raised.
*
*
* @var string
*/
const onFlush = 'onFlush';
}
/**
* The postFlush event occurs when the EntityManager#flush() operation is invoked and
* after all actual database operations are executed successfully. The event is only raised if there is
* actually something to do for the underlying UnitOfWork. If nothing needs to be done,
* the postFlush event is not raised. The event won't be raised if an error occurs during the
* flush operation.
*
* @var string
*/
const postFlush = 'postFlush';
/**
* The onClear event occurs when the EntityManager#clear() operation is invoked,
* after all references to entities have been removed from the unit of work.
*
* @var string
*/
const onClear = 'onClear';
}
+4 -4
View File
@@ -13,7 +13,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
@@ -26,7 +26,7 @@ abstract class AbstractIdGenerator
/**
* Generates an identifier for an entity.
*
* @param Doctrine\ORM\Entity $entity
* @param \Doctrine\ORM\Entity $entity
* @return mixed
*/
abstract public function generate(EntityManager $em, $entity);
@@ -35,7 +35,7 @@ abstract class AbstractIdGenerator
* Gets whether this generator is a post-insert generator which means that
* {@link generate()} must be called after the entity has been inserted
* into the database.
*
*
* By default, this method returns FALSE. Generators that have this requirement
* must override this method and return TRUE.
*
@@ -45,4 +45,4 @@ abstract class AbstractIdGenerator
{
return false;
}
}
}
+21 -20
View File
@@ -13,7 +13,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
@@ -42,28 +42,29 @@ class AssignedGenerator extends AbstractIdGenerator
*/
public function generate(EntityManager $em, $entity)
{
$class = $em->getClassMetadata(get_class($entity));
$class = $em->getClassMetadata(get_class($entity));
$idFields = $class->getIdentifierFieldNames();
$identifier = array();
if ($class->isIdentifierComposite) {
$idFields = $class->getIdentifierFieldNames();
foreach ($idFields as $idField) {
$value = $class->getReflectionProperty($idField)->getValue($entity);
if (isset($value)) {
$identifier[$idField] = $value;
} else {
throw ORMException::entityMissingAssignedId($entity);
}
}
} else {
$idField = $class->identifier[0];
foreach ($idFields as $idField) {
$value = $class->reflFields[$idField]->getValue($entity);
if (isset($value)) {
$identifier[$idField] = $value;
} else {
throw ORMException::entityMissingAssignedId($entity);
if ( ! isset($value)) {
throw ORMException::entityMissingAssignedIdForField($entity, $idField);
}
if (isset($class->associationMappings[$idField])) {
if ( ! $em->getUnitOfWork()->isInIdentityMap($value)) {
throw ORMException::entityMissingForeignAssignedId($entity, $value);
}
// NOTE: Single Columns as associated identifiers only allowed - this constraint it is enforced.
$value = current($em->getUnitOfWork()->getEntityIdentifier($value));
}
$identifier[$idField] = $value;
}
return $identifier;
}
}
}
+3 -3
View File
@@ -13,7 +13,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
@@ -46,7 +46,7 @@ class IdentityGenerator extends AbstractIdGenerator
*/
public function generate(EntityManager $em, $entity)
{
return $em->getConnection()->lastInsertId($this->_seqName);
return (int)$em->getConnection()->lastInsertId($this->_seqName);
}
/**
@@ -56,4 +56,4 @@ class IdentityGenerator extends AbstractIdGenerator
{
return true;
}
}
}
+10 -7
View File
@@ -13,7 +13,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
@@ -37,7 +37,7 @@ class SequenceGenerator extends AbstractIdGenerator implements Serializable
/**
* Initializes a new sequence generator.
*
* @param Doctrine\ORM\EntityManager $em The EntityManager to use.
* @param \Doctrine\ORM\EntityManager $em The EntityManager to use.
* @param string $sequenceName The name of the sequence.
* @param integer $allocationSize The allocation size of the sequence.
*/
@@ -46,7 +46,7 @@ class SequenceGenerator extends AbstractIdGenerator implements Serializable
$this->_sequenceName = $sequenceName;
$this->_allocationSize = $allocationSize;
}
/**
* Generates an ID for the given entity.
*
@@ -59,10 +59,12 @@ class SequenceGenerator extends AbstractIdGenerator implements Serializable
if ($this->_maxValue === null || $this->_nextValue == $this->_maxValue) {
// Allocate new values
$conn = $em->getConnection();
$sql = $conn->getDatabasePlatform()->getSequenceNextValSQL($this->_sequenceName);
$this->_nextValue = $conn->fetchColumn($sql);
$this->_maxValue = $this->_nextValue + $this->_allocationSize;
$sql = $conn->getDatabasePlatform()->getSequenceNextValSQL($this->_sequenceName);
$this->_nextValue = (int)$conn->fetchColumn($sql);
$this->_maxValue = $this->_nextValue + $this->_allocationSize;
}
return $this->_nextValue++;
}
@@ -90,13 +92,14 @@ class SequenceGenerator extends AbstractIdGenerator implements Serializable
{
return serialize(array(
'allocationSize' => $this->_allocationSize,
'sequenceName' => $this->_sequenceName
'sequenceName' => $this->_sequenceName
));
}
public function unserialize($serialized)
{
$array = unserialize($serialized);
$this->_sequenceName = $array['sequenceName'];
$this->_allocationSize = $array['allocationSize'];
}
+7 -5
View File
@@ -13,7 +13,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
@@ -50,11 +50,12 @@ class TableGenerator extends AbstractIdGenerator
if ($this->_maxValue === null || $this->_nextValue == $this->_maxValue) {
// Allocate new values
$conn = $em->getConnection();
if ($conn->getTransactionNestingLevel() == 0) {
if ($conn->getTransactionNestingLevel() === 0) {
// use select for update
$sql = $conn->getDatabasePlatform()->getTableHiLoCurrentValSql($this->_tableName, $this->_sequenceName);
$sql = $conn->getDatabasePlatform()->getTableHiLoCurrentValSql($this->_tableName, $this->_sequenceName);
$currentLevel = $conn->fetchColumn($sql);
if ($currentLevel != null) {
$this->_nextValue = $currentLevel;
$this->_maxValue = $this->_nextValue + $this->_allocationSize;
@@ -62,7 +63,7 @@ class TableGenerator extends AbstractIdGenerator
$updateSql = $conn->getDatabasePlatform()->getTableHiLoUpdateNextValSql(
$this->_tableName, $this->_sequenceName, $this->_allocationSize
);
if ($conn->executeUpdate($updateSql, array(1 => $currentLevel, 2 => $currentLevel+1)) !== 1) {
// no affected rows, concurrency issue, throw exception
}
@@ -74,6 +75,7 @@ class TableGenerator extends AbstractIdGenerator
// or do we want to work with table locks exclusively?
}
}
return $this->_nextValue++;
}
}
}
+48
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);
}
}
@@ -13,7 +13,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
@@ -23,20 +23,21 @@ namespace Doctrine\ORM\Internal;
* The CommitOrderCalculator is used by the UnitOfWork to sort out the
* correct order in which changes to entities need to be persisted.
*
* @since 2.0
* @author Roman Borschel <roman@code-factory.org>
* @since 2.0
* @author Roman Borschel <roman@code-factory.org>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
*/
class CommitOrderCalculator
{
const NOT_VISITED = 1;
const IN_PROGRESS = 2;
const VISITED = 3;
private $_nodeStates = array();
private $_classes = array(); // The nodes to sort
private $_relatedClasses = array();
private $_sorted = array();
/**
* Clears the current graph.
*
@@ -47,10 +48,10 @@ class CommitOrderCalculator
$this->_classes =
$this->_relatedClasses = array();
}
/**
* Gets a valid commit order for all current nodes.
*
*
* Uses a depth-first search (DFS) to traverse the graph.
* The desired topological sorting is the reverse postorder of these searches.
*
@@ -60,17 +61,16 @@ class CommitOrderCalculator
{
// Check whether we need to do anything. 0 or 1 node is easy.
$nodeCount = count($this->_classes);
if ($nodeCount == 0) {
return array();
} else if ($nodeCount == 1) {
return array_values($this->_classes);
if ($nodeCount <= 1) {
return ($nodeCount == 1) ? array_values($this->_classes) : array();
}
// Init
foreach ($this->_classes as $node) {
$this->_nodeStates[$node->name] = self::NOT_VISITED;
}
// Go
foreach ($this->_classes as $node) {
if ($this->_nodeStates[$node->name] == self::NOT_VISITED) {
@@ -100,19 +100,19 @@ class CommitOrderCalculator
$this->_nodeStates[$node->name] = self::VISITED;
$this->_sorted[] = $node;
}
public function addDependency($fromClass, $toClass)
{
$this->_relatedClasses[$fromClass->name][] = $toClass;
}
public function hasClass($className)
{
return isset($this->_classes[$className]);
}
public function addClass($class)
{
$this->_classes[$class->name] = $class;
}
}
}
@@ -13,7 +13,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
@@ -22,34 +22,37 @@ namespace Doctrine\ORM\Internal\Hydration;
use PDO,
Doctrine\DBAL\Connection,
Doctrine\DBAL\Types\Type,
Doctrine\ORM\EntityManager;
Doctrine\ORM\EntityManager,
Doctrine\ORM\Events,
Doctrine\ORM\Mapping\ClassMetadata;
/**
* Base class for all hydrators. A hydrator is a class that provides some form
* of transformation of an SQL result set into another structure.
*
* @since 2.0
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @author Roman Borschel <roman@code-factory.org>
* @since 2.0
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @author Roman Borschel <roman@code-factory.org>
* @author Guilherme Blanco <guilhermeblanoc@hotmail.com>
*/
abstract class AbstractHydrator
{
/** @var ResultSetMapping The ResultSetMapping. */
/** @var \Doctrine\ORM\Query\ResultSetMapping The ResultSetMapping. */
protected $_rsm;
/** @var EntityManager The EntityManager instance. */
protected $_em;
/** @var AbstractPlatform The dbms Platform instance */
/** @var \Doctrine\DBAL\Platforms\AbstractPlatform The dbms Platform instance */
protected $_platform;
/** @var UnitOfWork The UnitOfWork of the associated EntityManager. */
/** @var \Doctrine\ORM\UnitOfWork The UnitOfWork of the associated EntityManager. */
protected $_uow;
/** @var array The cache used during row-by-row hydration. */
protected $_cache = array();
/** @var Statement The statement that provides the data to hydrate. */
/** @var \Doctrine\DBAL\Driver\Statement The statement that provides the data to hydrate. */
protected $_stmt;
/** @var array The query hints. */
@@ -58,13 +61,13 @@ abstract class AbstractHydrator
/**
* Initializes a new instance of a class derived from <tt>AbstractHydrator</tt>.
*
* @param Doctrine\ORM\EntityManager $em The EntityManager to use.
* @param \Doctrine\ORM\EntityManager $em The EntityManager to use.
*/
public function __construct(EntityManager $em)
{
$this->_em = $em;
$this->_em = $em;
$this->_platform = $em->getConnection()->getDatabasePlatform();
$this->_uow = $em->getUnitOfWork();
$this->_uow = $em->getUnitOfWork();
}
/**
@@ -72,14 +75,20 @@ abstract class AbstractHydrator
*
* @param object $stmt
* @param object $resultSetMapping
*
* @return IterableResult
*/
public function iterate($stmt, $resultSetMapping, array $hints = array())
{
$this->_stmt = $stmt;
$this->_rsm = $resultSetMapping;
$this->_stmt = $stmt;
$this->_rsm = $resultSetMapping;
$this->_hints = $hints;
$this->_prepare();
$evm = $this->_em->getEventManager();
$evm->addEventListener(array(Events::onClear), $this);
$this->prepare();
return new IterableResult($this);
}
@@ -88,16 +97,21 @@ abstract class AbstractHydrator
*
* @param object $stmt
* @param object $resultSetMapping
* @param array $hints
* @return mixed
*/
public function hydrateAll($stmt, $resultSetMapping, array $hints = array())
{
$this->_stmt = $stmt;
$this->_rsm = $resultSetMapping;
$this->_stmt = $stmt;
$this->_rsm = $resultSetMapping;
$this->_hints = $hints;
$this->_prepare();
$result = $this->_hydrateAll();
$this->_cleanup();
$this->prepare();
$result = $this->hydrateAllData();
$this->cleanup();
return $result;
}
@@ -110,12 +124,17 @@ abstract class AbstractHydrator
public function hydrateRow()
{
$row = $this->_stmt->fetch(PDO::FETCH_ASSOC);
if ( ! $row) {
$this->_cleanup();
$this->cleanup();
return false;
}
$result = array();
$this->_hydrateRow($row, $this->_cache, $result);
$this->hydrateRowData($row, $this->_cache, $result);
return $result;
}
@@ -123,16 +142,17 @@ abstract class AbstractHydrator
* Excutes one-time preparation tasks, once each time hydration is started
* through {@link hydrateAll} or {@link iterate()}.
*/
protected function _prepare()
protected function prepare()
{}
/**
* Excutes one-time cleanup tasks at the end of a hydration that was initiated
* through {@link hydrateAll} or {@link iterate()}.
*/
protected function _cleanup()
protected function cleanup()
{
$this->_rsm = null;
$this->_stmt->closeCursor();
$this->_stmt = null;
}
@@ -146,70 +166,106 @@ abstract class AbstractHydrator
* @param array $cache The cache to use.
* @param mixed $result The result to fill.
*/
protected function _hydrateRow(array $data, array &$cache, array &$result)
protected function hydrateRowData(array $data, array &$cache, array &$result)
{
throw new HydrationException("_hydrateRow() not implemented by this hydrator.");
throw new HydrationException("hydrateRowData() not implemented by this hydrator.");
}
/**
* Hydrates all rows from the current statement instance at once.
*/
abstract protected function _hydrateAll();
abstract protected function hydrateAllData();
/**
* Processes a row of the result set.
*
* Used for identity-based hydration (HYDRATE_OBJECT and HYDRATE_ARRAY).
* Puts the elements of a result row into a new array, grouped by the class
* Puts the elements of a result row into a new array, grouped by the dql alias
* they belong to. The column names in the result set are mapped to their
* field names during this procedure as well as any necessary conversions on
* the values applied.
* the values applied. Scalar values are kept in a specfic key 'scalars'.
*
* @param array $data SQL Result Row
* @param array &$cache Cache for column to field result information
* @param array &$id Dql-Alias => ID-Hash
* @param array &$nonemptyComponents Does this DQL-Alias has at least one non NULL value?
*
* @return array An array with all the fields (name => value) of the data row,
* grouped by their component alias.
*/
protected function _gatherRowData(array $data, array &$cache, array &$id, array &$nonemptyComponents)
protected function gatherRowData(array $data, array &$cache, array &$id, array &$nonemptyComponents)
{
$rowData = array();
foreach ($data as $key => $value) {
// Parse each column name only once. Cache the results.
if ( ! isset($cache[$key])) {
if (isset($this->_rsm->scalarMappings[$key])) {
$cache[$key]['fieldName'] = $this->_rsm->scalarMappings[$key];
$cache[$key]['isScalar'] = true;
} else if (isset($this->_rsm->fieldMappings[$key])) {
$fieldName = $this->_rsm->fieldMappings[$key];
$classMetadata = $this->_em->getClassMetadata($this->_rsm->declaringClasses[$key]);
$cache[$key]['fieldName'] = $fieldName;
$cache[$key]['type'] = Type::getType($classMetadata->fieldMappings[$fieldName]['type']);
$cache[$key]['isIdentifier'] = $classMetadata->isIdentifier($fieldName);
$cache[$key]['dqlAlias'] = $this->_rsm->columnOwnerMap[$key];
} else if (!isset($this->_rsm->metaMappings[$key])) {
// this column is a left over, maybe from a LIMIT query hack for example in Oracle or DB2
// maybe from an additional column that has not been defined in a NativeQuery ResultSetMapping.
continue;
} else {
// Meta column (has meaning in relational schema only, i.e. foreign keys or discriminator columns).
$cache[$key]['isMetaColumn'] = true;
$cache[$key]['fieldName'] = $this->_rsm->metaMappings[$key];
$cache[$key]['dqlAlias'] = $this->_rsm->columnOwnerMap[$key];
switch (true) {
// NOTE: Most of the times it's a field mapping, so keep it first!!!
case (isset($this->_rsm->fieldMappings[$key])):
$fieldName = $this->_rsm->fieldMappings[$key];
$classMetadata = $this->_em->getClassMetadata($this->_rsm->declaringClasses[$key]);
$cache[$key]['fieldName'] = $fieldName;
$cache[$key]['type'] = Type::getType($classMetadata->fieldMappings[$fieldName]['type']);
$cache[$key]['isIdentifier'] = $classMetadata->isIdentifier($fieldName);
$cache[$key]['dqlAlias'] = $this->_rsm->columnOwnerMap[$key];
break;
case (isset($this->_rsm->scalarMappings[$key])):
$cache[$key]['fieldName'] = $this->_rsm->scalarMappings[$key];
$cache[$key]['type'] = Type::getType($this->_rsm->typeMappings[$key]);
$cache[$key]['isScalar'] = true;
break;
case (isset($this->_rsm->metaMappings[$key])):
// Meta column (has meaning in relational schema only, i.e. foreign keys or discriminator columns).
$fieldName = $this->_rsm->metaMappings[$key];
$classMetadata = $this->_em->getClassMetadata($this->_rsm->aliasMap[$this->_rsm->columnOwnerMap[$key]]);
$cache[$key]['isMetaColumn'] = true;
$cache[$key]['fieldName'] = $fieldName;
$cache[$key]['dqlAlias'] = $this->_rsm->columnOwnerMap[$key];
$cache[$key]['isIdentifier'] = isset($this->_rsm->isIdentifierColumn[$cache[$key]['dqlAlias']][$key]);
break;
default:
// this column is a left over, maybe from a LIMIT query hack for example in Oracle or DB2
// maybe from an additional column that has not been defined in a NativeQuery ResultSetMapping.
continue 2;
}
}
if (isset($cache[$key]['isScalar'])) {
$value = $cache[$key]['type']->convertToPHPValue($value, $this->_platform);
$rowData['scalars'][$cache[$key]['fieldName']] = $value;
continue;
}
$dqlAlias = $cache[$key]['dqlAlias'];
if ($cache[$key]['isIdentifier']) {
$id[$dqlAlias] .= '|' . $value;
}
if (isset($cache[$key]['isMetaColumn'])) {
$rowData[$dqlAlias][$cache[$key]['fieldName']] = $value;
if ( ! isset($rowData[$dqlAlias][$cache[$key]['fieldName']]) && $value !== null) {
$rowData[$dqlAlias][$cache[$key]['fieldName']] = $value;
if ($cache[$key]['isIdentifier']) {
$nonemptyComponents[$dqlAlias] = true;
}
}
continue;
}
if ($cache[$key]['isIdentifier']) {
$id[$dqlAlias] .= '|' . $value;
// in an inheritance hierarchy the same field could be defined several times.
// We overwrite this value so long we dont have a non-null value, that value we keep.
// Per definition it cannot be that a field is defined several times and has several values.
if (isset($rowData[$dqlAlias][$cache[$key]['fieldName']]) && $value === null) {
continue;
}
$rowData[$dqlAlias][$cache[$key]['fieldName']] = $cache[$key]['type']->convertToPHPValue($value, $this->_platform);
@@ -224,6 +280,7 @@ abstract class AbstractHydrator
/**
* Processes a row of the result set.
*
* Used for HYDRATE_SCALAR. This is a variant of _gatherRowData() that
* simply converts column names to field names and properly converts the
* values according to their types. The resulting row has the same number
@@ -231,48 +288,103 @@ abstract class AbstractHydrator
*
* @param array $data
* @param array $cache
*
* @return array The processed row.
*/
protected function _gatherScalarRowData(&$data, &$cache)
protected function gatherScalarRowData(&$data, &$cache)
{
$rowData = array();
foreach ($data as $key => $value) {
// Parse each column name only once. Cache the results.
if ( ! isset($cache[$key])) {
if (isset($this->_rsm->scalarMappings[$key])) {
$cache[$key]['fieldName'] = $this->_rsm->scalarMappings[$key];
$cache[$key]['isScalar'] = true;
} else if (isset($this->_rsm->fieldMappings[$key])) {
$fieldName = $this->_rsm->fieldMappings[$key];
$classMetadata = $this->_em->getClassMetadata($this->_rsm->declaringClasses[$key]);
$cache[$key]['fieldName'] = $fieldName;
$cache[$key]['type'] = Type::getType($classMetadata->fieldMappings[$fieldName]['type']);
$cache[$key]['dqlAlias'] = $this->_rsm->columnOwnerMap[$key];
} else if (!isset($this->_rsm->metaMappings[$key])) {
// this column is a left over, maybe from a LIMIT query hack for example in Oracle or DB2
// maybe from an additional column that has not been defined in a NativeQuery ResultSetMapping.
continue;
} else {
// Meta column (has meaning in relational schema only, i.e. foreign keys or discriminator columns).
$cache[$key]['isMetaColumn'] = true;
$cache[$key]['fieldName'] = $this->_rsm->metaMappings[$key];
$cache[$key]['dqlAlias'] = $this->_rsm->columnOwnerMap[$key];
switch (true) {
// NOTE: During scalar hydration, most of the times it's a scalar mapping, keep it first!!!
case (isset($this->_rsm->scalarMappings[$key])):
$cache[$key]['fieldName'] = $this->_rsm->scalarMappings[$key];
$cache[$key]['isScalar'] = true;
break;
case (isset($this->_rsm->fieldMappings[$key])):
$fieldName = $this->_rsm->fieldMappings[$key];
$classMetadata = $this->_em->getClassMetadata($this->_rsm->declaringClasses[$key]);
$cache[$key]['fieldName'] = $fieldName;
$cache[$key]['type'] = Type::getType($classMetadata->fieldMappings[$fieldName]['type']);
$cache[$key]['dqlAlias'] = $this->_rsm->columnOwnerMap[$key];
break;
case (isset($this->_rsm->metaMappings[$key])):
// Meta column (has meaning in relational schema only, i.e. foreign keys or discriminator columns).
$cache[$key]['isMetaColumn'] = true;
$cache[$key]['fieldName'] = $this->_rsm->metaMappings[$key];
$cache[$key]['dqlAlias'] = $this->_rsm->columnOwnerMap[$key];
break;
default:
// this column is a left over, maybe from a LIMIT query hack for example in Oracle or DB2
// maybe from an additional column that has not been defined in a NativeQuery ResultSetMapping.
continue 2;
}
}
$fieldName = $cache[$key]['fieldName'];
if (isset($cache[$key]['isScalar'])) {
$rowData[$fieldName] = $value;
} else if (isset($cache[$key]['isMetaColumn'])) {
$rowData[$cache[$key]['dqlAlias'] . '_' . $fieldName] = $value;
} else {
$rowData[$cache[$key]['dqlAlias'] . '_' . $fieldName] = $cache[$key]['type']
->convertToPHPValue($value, $this->_platform);
switch (true) {
case (isset($cache[$key]['isScalar'])):
$rowData[$fieldName] = $value;
break;
case (isset($cache[$key]['isMetaColumn'])):
$rowData[$cache[$key]['dqlAlias'] . '_' . $fieldName] = $value;
break;
default:
$value = $cache[$key]['type']->convertToPHPValue($value, $this->_platform);
$rowData[$cache[$key]['dqlAlias'] . '_' . $fieldName] = $value;
}
}
return $rowData;
}
/**
* Register entity as managed in UnitOfWork.
*
* @param \Doctrine\ORM\Mapping\ClassMetadata $class
* @param object $entity
* @param array $data
*
* @todo The "$id" generation is the same of UnitOfWork#createEntity. Remove this duplication somehow
*/
protected function registerManaged(ClassMetadata $class, $entity, array $data)
{
if ($class->isIdentifierComposite) {
$id = array();
foreach ($class->identifier as $fieldName) {
if (isset($class->associationMappings[$fieldName])) {
$id[$fieldName] = $data[$class->associationMappings[$fieldName]['joinColumns'][0]['name']];
} else {
$id[$fieldName] = $data[$fieldName];
}
}
} else {
if (isset($class->associationMappings[$class->identifier[0]])) {
$id = array($class->identifier[0] => $data[$class->associationMappings[$class->identifier[0]]['joinColumns'][0]['name']]);
} else {
$id = array($class->identifier[0] => $data[$class->identifier[0]]);
}
}
$this->_em->getUnitOfWork()->registerManaged($entity, $id, $data);
}
/**
* When executed in a hydrate() loop we have to clear internal state to
* decrease memory consumption.
*/
public function onClear($eventArgs)
{
}
}
@@ -13,7 +13,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
@@ -25,8 +25,9 @@ use PDO, Doctrine\DBAL\Connection, Doctrine\ORM\Mapping\ClassMetadata;
* The ArrayHydrator produces a nested array "graph" that is often (not always)
* interchangeable with the corresponding object graph for read-only access.
*
* @since 2.0
* @author Roman Borschel <roman@code-factory.org>
* @since 1.0
* @author Guilherme Blanco <guilhermeblanoc@hotmail.com>
*/
class ArrayHydrator extends AbstractHydrator
{
@@ -38,45 +39,55 @@ class ArrayHydrator extends AbstractHydrator
private $_idTemplate = array();
private $_resultCounter = 0;
/** @override */
protected function _prepare()
/**
* {@inheritdoc}
*/
protected function prepare()
{
$this->_isSimpleQuery = count($this->_rsm->aliasMap) <= 1;
$this->_identifierMap = array();
$this->_isSimpleQuery = count($this->_rsm->aliasMap) <= 1;
$this->_identifierMap = array();
$this->_resultPointers = array();
$this->_idTemplate = array();
$this->_resultCounter = 0;
$this->_idTemplate = array();
$this->_resultCounter = 0;
foreach ($this->_rsm->aliasMap as $dqlAlias => $className) {
$this->_identifierMap[$dqlAlias] = array();
$this->_identifierMap[$dqlAlias] = array();
$this->_resultPointers[$dqlAlias] = array();
$this->_idTemplate[$dqlAlias] = '';
$this->_idTemplate[$dqlAlias] = '';
}
}
/** @override */
protected function _hydrateAll()
/**
* {@inheritdoc}
*/
protected function hydrateAllData()
{
$result = array();
$cache = array();
$cache = array();
while ($data = $this->_stmt->fetch(PDO::FETCH_ASSOC)) {
$this->_hydrateRow($data, $cache, $result);
$this->hydrateRowData($data, $cache, $result);
}
return $result;
}
/** @override */
protected function _hydrateRow(array $data, array &$cache, array &$result)
/**
* {@inheritdoc}
*/
protected function hydrateRowData(array $row, array &$cache, array &$result)
{
// 1) Initialize
$id = $this->_idTemplate; // initialize the id-memory
$nonemptyComponents = array();
$rowData = $this->_gatherRowData($data, $cache, $id, $nonemptyComponents);
$rowData = $this->gatherRowData($row, $cache, $id, $nonemptyComponents);
// Extract scalar values. They're appended at the end.
if (isset($rowData['scalars'])) {
$scalars = $rowData['scalars'];
unset($rowData['scalars']);
if (empty($rowData)) {
++$this->_resultCounter;
}
@@ -90,12 +101,17 @@ class ArrayHydrator extends AbstractHydrator
// It's a joined result
$parent = $this->_rsm->parentAliasMap[$dqlAlias];
$path = $parent . '.' . $dqlAlias;
$path = $parent . '.' . $dqlAlias;
// missing parent data, skipping as RIGHT JOIN hydration is not supported.
if ( ! isset($nonemptyComponents[$parent]) ) {
continue;
}
// Get a reference to the right element in the result tree.
// This element will get the associated element attached.
if ($this->_rsm->isMixed && isset($this->_rootAliases[$parent])) {
$first = reset($this->_resultPointers);
$first = reset($this->_resultPointers);
// TODO: Exception if $key === null ?
$baseElement =& $this->_resultPointers[$parent][key($first)];
} else if (isset($this->_resultPointers[$parent])) {
@@ -104,39 +120,41 @@ class ArrayHydrator extends AbstractHydrator
unset($this->_resultPointers[$dqlAlias]); // Ticket #1228
continue;
}
$relationAlias = $this->_rsm->relationMap[$dqlAlias];
$relation = $this->_getClassMetadata($this->_rsm->aliasMap[$parent])->associationMappings[$relationAlias];
$relation = $this->getClassMetadata($this->_rsm->aliasMap[$parent])->associationMappings[$relationAlias];
// Check the type of the relation (many or single-valued)
if ( ! ($relation['type'] & ClassMetadata::TO_ONE)) {
$oneToOne = false;
if (isset($nonemptyComponents[$dqlAlias])) {
if ( ! isset($baseElement[$relationAlias])) {
$baseElement[$relationAlias] = array();
}
$indexExists = isset($this->_identifierMap[$path][$id[$parent]][$id[$dqlAlias]]);
$index = $indexExists ? $this->_identifierMap[$path][$id[$parent]][$id[$dqlAlias]] : false;
$indexExists = isset($this->_identifierMap[$path][$id[$parent]][$id[$dqlAlias]]);
$index = $indexExists ? $this->_identifierMap[$path][$id[$parent]][$id[$dqlAlias]] : false;
$indexIsValid = $index !== false ? isset($baseElement[$relationAlias][$index]) : false;
if ( ! $indexExists || ! $indexIsValid) {
$element = $data;
if (isset($this->_rsm->indexByMap[$dqlAlias])) {
$field = $this->_rsm->indexByMap[$dqlAlias];
$baseElement[$relationAlias][$element[$field]] = $element;
$baseElement[$relationAlias][$row[$this->_rsm->indexByMap[$dqlAlias]]] = $element;
} else {
$baseElement[$relationAlias][] = $element;
}
end($baseElement[$relationAlias]);
$this->_identifierMap[$path][$id[$parent]][$id[$dqlAlias]] =
key($baseElement[$relationAlias]);
$this->_identifierMap[$path][$id[$parent]][$id[$dqlAlias]] = key($baseElement[$relationAlias]);
}
} else if ( ! isset($baseElement[$relationAlias])) {
$baseElement[$relationAlias] = array();
}
} else {
$oneToOne = true;
if ( ! isset($nonemptyComponents[$dqlAlias]) && ! isset($baseElement[$relationAlias])) {
$baseElement[$relationAlias] = null;
} else if ( ! isset($baseElement[$relationAlias])) {
@@ -152,32 +170,42 @@ class ArrayHydrator extends AbstractHydrator
} else {
// It's a root result element
$this->_rootAliases[$dqlAlias] = true; // Mark as root
$entityKey = $this->_rsm->entityMappings[$dqlAlias] ?: 0;
// if this row has a NULL value for the root result id then make it a null result.
if ( ! isset($nonemptyComponents[$dqlAlias]) ) {
if ($this->_rsm->isMixed) {
$result[] = array($entityKey => null);
} else {
$result[] = null;
}
$resultKey = $this->_resultCounter;
++$this->_resultCounter;
continue;
}
// Check for an existing element
if ($this->_isSimpleQuery || ! isset($this->_identifierMap[$dqlAlias][$id[$dqlAlias]])) {
$element = $rowData[$dqlAlias];
if (isset($this->_rsm->indexByMap[$dqlAlias])) {
$field = $this->_rsm->indexByMap[$dqlAlias];
if ($this->_rsm->isMixed) {
$result[] = array($element[$field] => $element);
++$this->_resultCounter;
} else {
$result[$element[$field]] = $element;
}
} else {
if ($this->_rsm->isMixed) {
$result[] = array($element);
++$this->_resultCounter;
} else {
$result[] = $element;
}
if ($this->_rsm->isMixed) {
$element = array($entityKey => $element);
}
end($result);
$this->_identifierMap[$dqlAlias][$id[$dqlAlias]] = key($result);
if (isset($this->_rsm->indexByMap[$dqlAlias])) {
$resultKey = $row[$this->_rsm->indexByMap[$dqlAlias]];
$result[$resultKey] = $element;
} else {
$resultKey = $this->_resultCounter;
$result[] = $element;
++$this->_resultCounter;
}
$this->_identifierMap[$dqlAlias][$id[$dqlAlias]] = $resultKey;
} else {
$index = $this->_identifierMap[$dqlAlias][$id[$dqlAlias]];
$resultKey = $index;
/*if ($this->_rsm->isMixed) {
$result[] =& $result[$index];
++$this->_resultCounter;
@@ -189,8 +217,17 @@ class ArrayHydrator extends AbstractHydrator
// Append scalar values to mixed result sets
if (isset($scalars)) {
if ( ! isset($resultKey) ) {
// this only ever happens when no object is fetched (scalar result only)
if (isset($this->_rsm->indexByMap['scalars'])) {
$resultKey = $row[$this->_rsm->indexByMap['scalars']];
} else {
$resultKey = $this->_resultCounter - 1;
}
}
foreach ($scalars as $name => $value) {
$result[$this->_resultCounter - 1][$name] = $value;
$result[$resultKey][$name] = $value;
}
}
}
@@ -208,28 +245,45 @@ class ArrayHydrator extends AbstractHydrator
{
if ($coll === null) {
unset($this->_resultPointers[$dqlAlias]); // Ticket #1228
return;
}
if ($index !== false) {
$this->_resultPointers[$dqlAlias] =& $coll[$index];
return;
} else {
if ($coll) {
if ($oneToOne) {
$this->_resultPointers[$dqlAlias] =& $coll;
} else {
end($coll);
$this->_resultPointers[$dqlAlias] =& $coll[key($coll)];
}
}
}
if ( ! $coll) {
return;
}
if ($oneToOne) {
$this->_resultPointers[$dqlAlias] =& $coll;
return;
}
end($coll);
$this->_resultPointers[$dqlAlias] =& $coll[key($coll)];
return;
}
private function _getClassMetadata($className)
/**
* Retrieve ClassMetadata associated to entity class name.
*
* @param string $className
*
* @return \Doctrine\ORM\Mapping\ClassMetadata
*/
private function getClassMetadata($className)
{
if ( ! isset($this->_ce[$className])) {
$this->_ce[$className] = $this->_em->getClassMetadata($className);
}
return $this->_ce[$className];
}
}
}
@@ -8,10 +8,49 @@ class HydrationException extends \Doctrine\ORM\ORMException
{
return new self("The result returned by the query was not unique.");
}
public static function parentObjectOfRelationNotFound($alias, $parentAlias)
{
return new self("The parent object of entity result with alias '$alias' was not found."
. " The parent alias is '$parentAlias'.");
}
public static function emptyDiscriminatorValue($dqlAlias)
{
return new self("The DQL alias '" . $dqlAlias . "' contains an entity ".
"of an inheritance hierachy with an empty discriminator value. This means " .
"that the database contains inconsistent data with an empty " .
"discriminator value in a table row."
);
}
/**
* @since 2.3
* @param string $entityName
* @param string $discrColumnName
* @param string $dqlAlias
* @return HydrationException
*/
public static function missingDiscriminatorColumn($entityName, $discrColumnName, $dqlAlias)
{
return new self(sprintf(
'The discriminator column "%s" is missing for "%s" using the DQL alias "%s".',
$discrColumnName, $entityName, $dqlAlias
));
}
/**
* @since 2.3
* @param string $entityName
* @param string $discrColumnName
* @param string $dqlAlias
* @return HydrationException
*/
public static function missingDiscriminatorMetaMappingColumn($entityName, $discrColumnName, $dqlAlias)
{
return new self(sprintf(
'The meta mapping for the discriminator column "%s" is missing for "%s" using the DQL alias "%s".',
$discrColumnName, $entityName, $dqlAlias
));
}
}
@@ -13,7 +13,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
@@ -29,7 +29,7 @@ namespace Doctrine\ORM\Internal\Hydration;
class IterableResult implements \Iterator
{
/**
* @var Doctrine\ORM\Internal\Hydration\AbstractHydrator
* @var \Doctrine\ORM\Internal\Hydration\AbstractHydrator
*/
private $_hydrator;
@@ -49,7 +49,7 @@ class IterableResult implements \Iterator
private $_current = null;
/**
* @param Doctrine\ORM\Internal\Hydration\AbstractHydrator $hydrator
* @param \Doctrine\ORM\Internal\Hydration\AbstractHydrator $hydrator
*/
public function __construct($hydrator)
{
@@ -101,4 +101,4 @@ class IterableResult implements \Iterator
{
return ($this->_current!=false);
}
}
}
@@ -13,7 +13,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
@@ -23,14 +23,19 @@ use PDO,
Doctrine\ORM\Mapping\ClassMetadata,
Doctrine\ORM\PersistentCollection,
Doctrine\ORM\Query,
Doctrine\ORM\Event\LifecycleEventArgs,
Doctrine\ORM\Events,
Doctrine\Common\Collections\ArrayCollection,
Doctrine\Common\Collections\Collection;
Doctrine\Common\Collections\Collection,
Doctrine\ORM\Proxy\Proxy;
/**
* The ObjectHydrator constructs an object graph out of an SQL result set.
*
* @since 2.0
* @author Roman Borschel <roman@code-factory.org>
* @since 2.0
* @author Guilherme Blanco <guilhermeblanoc@hotmail.com>
*
* @internal Highly performance-sensitive code.
*/
class ObjectHydrator extends AbstractHydrator
@@ -39,9 +44,9 @@ class ObjectHydrator extends AbstractHydrator
* This local cache is maintained between hydration runs and not cleared.
*/
private $_ce = array();
/* The following parts are reinitialized on every hydration run. */
private $_identifierMap;
private $_resultPointers;
private $_idTemplate;
@@ -49,56 +54,66 @@ class ObjectHydrator extends AbstractHydrator
private $_rootAliases = array();
private $_initializedCollections = array();
private $_existingCollections = array();
//private $_createdEntities;
/** @override */
protected function _prepare()
protected function prepare()
{
$this->_identifierMap =
$this->_resultPointers =
$this->_idTemplate = array();
$this->_resultCounter = 0;
if ( ! isset($this->_hints['deferEagerLoad'])) {
$this->_hints['deferEagerLoad'] = true;
}
foreach ($this->_rsm->aliasMap as $dqlAlias => $className) {
$this->_identifierMap[$dqlAlias] = array();
$this->_idTemplate[$dqlAlias] = '';
$class = $this->_em->getClassMetadata($className);
$this->_idTemplate[$dqlAlias] = '';
if ( ! isset($this->_ce[$className])) {
$this->_ce[$className] = $class;
$this->_ce[$className] = $this->_em->getClassMetadata($className);
}
// Remember which associations are "fetch joined", so that we know where to inject
// collection stubs or proxies and where not.
if (isset($this->_rsm->relationMap[$dqlAlias])) {
$sourceClassName = $this->_rsm->aliasMap[$this->_rsm->parentAliasMap[$dqlAlias]];
$sourceClass = $this->_getClassMetadata($sourceClassName);
$assoc = $sourceClass->associationMappings[$this->_rsm->relationMap[$dqlAlias]];
$this->_hints['fetched'][$sourceClassName][$assoc['fieldName']] = true;
if ($sourceClass->subClasses) {
foreach ($sourceClass->subClasses as $sourceSubclassName) {
$this->_hints['fetched'][$sourceSubclassName][$assoc['fieldName']] = true;
}
}
if ($assoc['type'] != ClassMetadata::MANY_TO_MANY) {
// Mark any non-collection opposite sides as fetched, too.
if ($assoc['mappedBy']) {
$this->_hints['fetched'][$className][$assoc['mappedBy']] = true;
} else {
if ($assoc['inversedBy']) {
$inverseAssoc = $class->associationMappings[$assoc['inversedBy']];
if ($inverseAssoc['type'] & ClassMetadata::TO_ONE) {
$this->_hints['fetched'][$className][$inverseAssoc['fieldName']] = true;
if ($class->subClasses) {
foreach ($class->subClasses as $targetSubclassName) {
$this->_hints['fetched'][$targetSubclassName][$inverseAssoc['fieldName']] = true;
}
}
}
}
}
if ( ! isset($this->_rsm->relationMap[$dqlAlias])) {
continue;
}
if ( ! isset($this->_rsm->aliasMap[$this->_rsm->parentAliasMap[$dqlAlias]])) {
throw HydrationException::parentObjectOfRelationNotFound($dqlAlias, $this->_rsm->parentAliasMap[$dqlAlias]);
}
$sourceClassName = $this->_rsm->aliasMap[$this->_rsm->parentAliasMap[$dqlAlias]];
$sourceClass = $this->_getClassMetadata($sourceClassName);
$assoc = $sourceClass->associationMappings[$this->_rsm->relationMap[$dqlAlias]];
$this->_hints['fetched'][$this->_rsm->parentAliasMap[$dqlAlias]][$assoc['fieldName']] = true;
if ($assoc['type'] === ClassMetadata::MANY_TO_MANY) {
continue;
}
// Mark any non-collection opposite sides as fetched, too.
if ($assoc['mappedBy']) {
$this->_hints['fetched'][$dqlAlias][$assoc['mappedBy']] = true;
continue;
}
// handle fetch-joined owning side bi-directional one-to-one associations
if ($assoc['inversedBy']) {
$class = $this->_ce[$className];
$inverseAssoc = $class->associationMappings[$assoc['inversedBy']];
if ( ! ($inverseAssoc['type'] & ClassMetadata::TO_ONE)) {
continue;
}
$this->_hints['fetched'][$dqlAlias][$inverseAssoc['fieldName']] = true;
}
}
}
@@ -106,25 +121,32 @@ class ObjectHydrator extends AbstractHydrator
/**
* {@inheritdoc}
*/
protected function _cleanup()
protected function cleanup()
{
parent::_cleanup();
$eagerLoad = (isset($this->_hints['deferEagerLoad'])) && $this->_hints['deferEagerLoad'] == true;
parent::cleanup();
$this->_identifierMap =
$this->_initializedCollections =
$this->_existingCollections =
$this->_resultPointers = array();
if ($eagerLoad) {
$this->_em->getUnitOfWork()->triggerEagerLoads();
}
}
/**
* {@inheritdoc}
*/
protected function _hydrateAll()
protected function hydrateAllData()
{
$result = array();
$cache = array();
$cache = array();
while ($row = $this->_stmt->fetch(PDO::FETCH_ASSOC)) {
$this->_hydrateRow($row, $cache, $result);
$this->hydrateRowData($row, $cache, $result);
}
// Take snapshots from all newly initialized collections
@@ -138,36 +160,41 @@ class ObjectHydrator extends AbstractHydrator
/**
* Initializes a related collection.
*
* @param object $entity The entity to which the collection belongs.
* @param string $name The name of the field on the entity that holds the collection.
* @param object $entity The entity to which the collection belongs.
* @param ClassMetadata $class
* @param string $fieldName The name of the field on the entity that holds the collection.
* @param string $parentDqlAlias Alias of the parent fetch joining this collection.
*/
private function _initRelatedCollection($entity, $class, $fieldName)
private function _initRelatedCollection($entity, $class, $fieldName, $parentDqlAlias)
{
$oid = spl_object_hash($entity);
$oid = spl_object_hash($entity);
$relation = $class->associationMappings[$fieldName];
$value = $class->reflFields[$fieldName]->getValue($entity);
$value = $class->reflFields[$fieldName]->getValue($entity);
if ($value === null) {
$value = new ArrayCollection;
}
if ( ! $value instanceof PersistentCollection) {
$value = new PersistentCollection(
$this->_em,
$this->_ce[$relation['targetEntity']],
$value
$this->_em, $this->_ce[$relation['targetEntity']], $value
);
$value->setOwner($entity, $relation);
$class->reflFields[$fieldName]->setValue($entity, $value);
$this->_uow->setOriginalEntityProperty($oid, $fieldName, $value);
$this->_initializedCollections[$oid . $fieldName] = $value;
} else if (isset($this->_hints[Query::HINT_REFRESH]) ||
isset($this->_hints['fetched'][$class->name][$fieldName]) &&
! $value->isInitialized()) {
} else if (
isset($this->_hints[Query::HINT_REFRESH]) ||
isset($this->_hints['fetched'][$parentDqlAlias][$fieldName]) &&
! $value->isInitialized()
) {
// Is already PersistentCollection, but either REFRESH or FETCH-JOIN and UNINITIALIZED!
$value->setDirty(false);
$value->setInitialized(true);
$value->unwrap()->clear();
$this->_initializedCollections[$oid . $fieldName] = $value;
} else {
// Is already PersistentCollection, and DON'T REFRESH or FETCH-JOIN!
@@ -176,44 +203,81 @@ class ObjectHydrator extends AbstractHydrator
return $value;
}
/**
* Gets an entity instance.
*
* @param $data The instance data.
* @param $dqlAlias The DQL alias of the entity's class.
*
* @param array $data The instance data.
* @param string $dqlAlias The DQL alias of the entity's class.
* @return object The entity.
*/
private function _getEntity(array $data, $dqlAlias)
{
$className = $this->_rsm->aliasMap[$dqlAlias];
$className = $this->_rsm->aliasMap[$dqlAlias];
if (isset($this->_rsm->discriminatorColumns[$dqlAlias])) {
if ( ! isset($this->_rsm->metaMappings[$this->_rsm->discriminatorColumns[$dqlAlias]])) {
throw HydrationException::missingDiscriminatorMetaMappingColumn($className, $this->_rsm->discriminatorColumns[$dqlAlias], $dqlAlias);
}
$discrColumn = $this->_rsm->metaMappings[$this->_rsm->discriminatorColumns[$dqlAlias]];
if ( ! isset($data[$discrColumn])) {
throw HydrationException::missingDiscriminatorColumn($className, $discrColumn, $dqlAlias);
}
if ($data[$discrColumn] === "") {
throw HydrationException::emptyDiscriminatorValue($dqlAlias);
}
$className = $this->_ce[$className]->discriminatorMap[$data[$discrColumn]];
unset($data[$discrColumn]);
}
if (isset($this->_hints[Query::HINT_REFRESH_ENTITY]) && isset($this->_rootAliases[$dqlAlias])) {
$this->registerManaged($this->_ce[$className], $this->_hints[Query::HINT_REFRESH_ENTITY], $data);
}
$this->_hints['fetchAlias'] = $dqlAlias;
return $this->_uow->createEntity($className, $data, $this->_hints);
}
/**
* @param string $className
* @param array $data
* @return mixed
*/
private function _getEntityFromIdentityMap($className, array $data)
{
// TODO: Abstract this code and UnitOfWork::createEntity() equivalent?
$class = $this->_ce[$className];
/* @var $class ClassMetadata */
if ($class->isIdentifierComposite) {
$idHash = '';
foreach ($class->identifier as $fieldName) {
$idHash .= $data[$fieldName] . ' ';
if (isset($class->associationMappings[$fieldName])) {
$idHash .= $data[$class->associationMappings[$fieldName]['joinColumns'][0]['name']] . ' ';
} else {
$idHash .= $data[$fieldName] . ' ';
}
}
return $this->_uow->tryGetByIdHash(rtrim($idHash), $class->rootEntityName);
} else if (isset($class->associationMappings[$class->identifier[0]])) {
return $this->_uow->tryGetByIdHash($data[$class->associationMappings[$class->identifier[0]]['joinColumns'][0]['name']], $class->rootEntityName);
} else {
return $this->_uow->tryGetByIdHash($data[$class->identifier[0]], $class->rootEntityName);
}
}
/**
* Gets a ClassMetadata instance from the local cache.
* If the instance is not yet in the local cache, it is loaded into the
* local cache.
*
*
* @param string $className The name of the class.
* @return ClassMetadata
*/
@@ -222,42 +286,45 @@ class ObjectHydrator extends AbstractHydrator
if ( ! isset($this->_ce[$className])) {
$this->_ce[$className] = $this->_em->getClassMetadata($className);
}
return $this->_ce[$className];
}
/**
* Hydrates a single row in an SQL result set.
*
*
* @internal
* First, the data of the row is split into chunks where each chunk contains data
* that belongs to a particular component/class. Afterwards, all these chunks
* are processed, one after the other. For each chunk of class data only one of the
* following code paths is executed:
*
*
* Path A: The data chunk belongs to a joined/associated object and the association
* is collection-valued.
* Path B: The data chunk belongs to a joined/associated object and the association
* is single-valued.
* Path C: The data chunk belongs to a root result element/object that appears in the topmost
* level of the hydrated result. A typical example are the objects of the type
* specified by the FROM clause in a DQL query.
*
* @param array $data The data of the row to process.
* @param array $cache The cache to use.
* specified by the FROM clause in a DQL query.
*
* @param array $row The data of the row to process.
* @param array $cache The cache to use.
* @param array $result The result array to fill.
*/
protected function _hydrateRow(array $data, array &$cache, array &$result)
protected function hydrateRowData(array $row, array &$cache, array &$result)
{
// Initialize
$id = $this->_idTemplate; // initialize the id-memory
$nonemptyComponents = array();
// Split the row data into chunks of class data.
$rowData = $this->_gatherRowData($data, $cache, $id, $nonemptyComponents);
$rowData = $this->gatherRowData($row, $cache, $id, $nonemptyComponents);
// Extract scalar values. They're appended at the end.
if (isset($rowData['scalars'])) {
$scalars = $rowData['scalars'];
unset($rowData['scalars']);
if (empty($rowData)) {
++$this->_resultCounter;
}
@@ -266,7 +333,7 @@ class ObjectHydrator extends AbstractHydrator
// Hydrate the data chunks
foreach ($rowData as $dqlAlias => $data) {
$entityName = $this->_rsm->aliasMap[$dqlAlias];
if (isset($this->_rsm->parentAliasMap[$dqlAlias])) {
// It's a joined result
@@ -275,10 +342,16 @@ class ObjectHydrator extends AbstractHydrator
// seen for this parent-child relationship
$path = $parentAlias . '.' . $dqlAlias;
// We have a RIGHT JOIN result here. Doctrine cannot hydrate RIGHT JOIN Object-Graphs
if ( ! isset($nonemptyComponents[$parentAlias])) {
// TODO: Add special case code where we hydrate the right join objects into identity map at least
continue;
}
// Get a reference to the parent object to which the joined element belongs.
if ($this->_rsm->isMixed && isset($this->_rootAliases[$parentAlias])) {
$first = reset($this->_resultPointers);
$parentObject = $this->_resultPointers[$parentAlias][key($first)];
$first = reset($this->_resultPointers);
$parentObject = $first[key($first)];
} else if (isset($this->_resultPointers[$parentAlias])) {
$parentObject = $this->_resultPointers[$parentAlias];
} else {
@@ -294,19 +367,20 @@ class ObjectHydrator extends AbstractHydrator
// Check the type of the relation (many or single-valued)
if ( ! ($relation['type'] & ClassMetadata::TO_ONE)) {
$reflFieldValue = $reflField->getValue($parentObject);
// PATH A: Collection-valued association
if (isset($nonemptyComponents[$dqlAlias])) {
$collKey = $oid . $relationField;
if (isset($this->_initializedCollections[$collKey])) {
$reflFieldValue = $this->_initializedCollections[$collKey];
} else if ( ! isset($this->_existingCollections[$collKey])) {
$reflFieldValue = $this->_initRelatedCollection($parentObject, $parentClass, $relationField);
$reflFieldValue = $this->_initRelatedCollection($parentObject, $parentClass, $relationField, $parentAlias);
}
$indexExists = isset($this->_identifierMap[$path][$id[$parentAlias]][$id[$dqlAlias]]);
$index = $indexExists ? $this->_identifierMap[$path][$id[$parentAlias]][$id[$dqlAlias]] : false;
$indexIsValid = $index !== false ? isset($reflFieldValue[$index]) : false;
if ( ! $indexExists || ! $indexIsValid) {
if (isset($this->_existingCollections[$collKey])) {
// Collection exists, only look for the element in the identity map.
@@ -319,8 +393,7 @@ class ObjectHydrator extends AbstractHydrator
$element = $this->_getEntity($data, $dqlAlias);
if (isset($this->_rsm->indexByMap[$dqlAlias])) {
$field = $this->_rsm->indexByMap[$dqlAlias];
$indexValue = $this->_ce[$entityName]->reflFields[$field]->getValue($element);
$indexValue = $row[$this->_rsm->indexByMap[$dqlAlias]];
$reflFieldValue->hydrateSet($indexValue, $element);
$this->_identifierMap[$path][$id[$parentAlias]][$id[$dqlAlias]] = $indexValue;
} else {
@@ -335,21 +408,24 @@ class ObjectHydrator extends AbstractHydrator
// Update result pointer
$this->_resultPointers[$dqlAlias] = $reflFieldValue[$index];
}
} else if ( ! $reflField->getValue($parentObject)) {
$coll = new PersistentCollection($this->_em, $this->_ce[$entityName], new ArrayCollection);
$coll->setOwner($parentObject, $relation);
$reflField->setValue($parentObject, $coll);
$this->_uow->setOriginalEntityProperty($oid, $relationField, $coll);
} else if ( ! $reflFieldValue) {
$reflFieldValue = $this->_initRelatedCollection($parentObject, $parentClass, $relationField, $parentAlias);
} else if ($reflFieldValue instanceof PersistentCollection && $reflFieldValue->isInitialized() === false) {
$reflFieldValue->setInitialized(true);
}
} else {
// PATH B: Single-valued association
$reflFieldValue = $reflField->getValue($parentObject);
if ( ! $reflFieldValue || isset($this->_hints[Query::HINT_REFRESH])) {
if ( ! $reflFieldValue || isset($this->_hints[Query::HINT_REFRESH]) || ($reflFieldValue instanceof Proxy && !$reflFieldValue->__isInitialized__)) {
// we only need to take action if this value is null,
// we refresh the entity or its an unitialized proxy.
if (isset($nonemptyComponents[$dqlAlias])) {
$element = $this->_getEntity($data, $dqlAlias);
$reflField->setValue($parentObject, $element);
$this->_uow->setOriginalEntityProperty($oid, $relationField, $element);
$targetClass = $this->_ce[$relation['targetEntity']];
if ($relation['isOwningSide']) {
//TODO: Just check hints['fetched'] here?
// If there is an inverse mapping on the target class its bidirectional
@@ -370,6 +446,9 @@ class ObjectHydrator extends AbstractHydrator
}
// Update result pointer
$this->_resultPointers[$dqlAlias] = $element;
} else {
$this->_uow->setOriginalEntityProperty($oid, $relationField, null);
$reflField->setValue($parentObject, null);
}
// else leave $reflFieldValue null for single-valued associations
} else {
@@ -380,30 +459,48 @@ class ObjectHydrator extends AbstractHydrator
} else {
// PATH C: Its a root result element
$this->_rootAliases[$dqlAlias] = true; // Mark as root alias
$entityKey = $this->_rsm->entityMappings[$dqlAlias] ?: 0;
// if this row has a NULL value for the root result id then make it a null result.
if ( ! isset($nonemptyComponents[$dqlAlias]) ) {
if ($this->_rsm->isMixed) {
$result[] = array($entityKey => null);
} else {
$result[] = null;
}
$resultKey = $this->_resultCounter;
++$this->_resultCounter;
continue;
}
// check for existing result from the iterations before
if ( ! isset($this->_identifierMap[$dqlAlias][$id[$dqlAlias]])) {
$element = $this->_getEntity($rowData[$dqlAlias], $dqlAlias);
if (isset($this->_rsm->indexByMap[$dqlAlias])) {
$field = $this->_rsm->indexByMap[$dqlAlias];
$key = $this->_ce[$entityName]->reflFields[$field]->getValue($element);
if ($this->_rsm->isMixed) {
$element = array($key => $element);
$result[] = $element;
$this->_identifierMap[$dqlAlias][$id[$dqlAlias]] = $this->_resultCounter;
++$this->_resultCounter;
} else {
$result[$key] = $element;
$this->_identifierMap[$dqlAlias][$id[$dqlAlias]] = $key;
}
} else {
if ($this->_rsm->isMixed) {
$element = array(0 => $element);
}
$result[] = $element;
$this->_identifierMap[$dqlAlias][$id[$dqlAlias]] = $this->_resultCounter;
++$this->_resultCounter;
if ($this->_rsm->isMixed) {
$element = array($entityKey => $element);
}
if (isset($this->_rsm->indexByMap[$dqlAlias])) {
$resultKey = $row[$this->_rsm->indexByMap[$dqlAlias]];
if (isset($this->_hints['collection'])) {
$this->_hints['collection']->hydrateSet($resultKey, $element);
}
$result[$resultKey] = $element;
} else {
$resultKey = $this->_resultCounter;
++$this->_resultCounter;
if (isset($this->_hints['collection'])) {
$this->_hints['collection']->hydrateAdd($element);
}
$result[] = $element;
}
$this->_identifierMap[$dqlAlias][$id[$dqlAlias]] = $resultKey;
// Update result pointer
$this->_resultPointers[$dqlAlias] = $element;
@@ -411,6 +508,7 @@ class ObjectHydrator extends AbstractHydrator
// Update result pointer
$index = $this->_identifierMap[$dqlAlias][$id[$dqlAlias]];
$this->_resultPointers[$dqlAlias] = $result[$index];
$resultKey = $index;
/*if ($this->_rsm->isMixed) {
$result[] = $result[$index];
++$this->_resultCounter;
@@ -421,9 +519,33 @@ class ObjectHydrator extends AbstractHydrator
// Append scalar values to mixed result sets
if (isset($scalars)) {
if ( ! isset($resultKey) ) {
if (isset($this->_rsm->indexByMap['scalars'])) {
$resultKey = $row[$this->_rsm->indexByMap['scalars']];
} else {
$resultKey = $this->_resultCounter - 1;
}
}
foreach ($scalars as $name => $value) {
$result[$this->_resultCounter - 1][$name] = $value;
$result[$resultKey][$name] = $value;
}
}
}
/**
* When executed in a hydrate() loop we may have to clear internal state to
* decrease memory consumption.
*/
public function onClear($eventArgs)
{
parent::onClear($eventArgs);
$aliases = array_keys($this->_identifierMap);
$this->_identifierMap = array();
foreach ($aliases as $alias) {
$this->_identifierMap[$alias] = array();
}
}
}
@@ -13,38 +13,43 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Internal\Hydration;
use Doctrine\DBAL\Connection;
/**
* Hydrator that produces flat, rectangular results of scalar data.
* The created result is almost the same as a regular SQL result set, except
* that column names are mapped to field names and data type conversions take place.
*
* @since 2.0
* @author Roman Borschel <roman@code-factory.org>
* @since 2.0
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
*/
class ScalarHydrator extends AbstractHydrator
{
/** @override */
protected function _hydrateAll()
/**
* {@inheritdoc}
*/
protected function hydrateAllData()
{
$result = array();
$cache = array();
$cache = array();
while ($data = $this->_stmt->fetch(\PDO::FETCH_ASSOC)) {
$result[] = $this->_gatherScalarRowData($data, $cache);
$this->hydrateRowData($data, $cache, $result);
}
return $result;
}
/** @override */
protected function _hydrateRow(array $data, array &$cache, array &$result)
/**
* {@inheritdoc}
*/
protected function hydrateRowData(array $data, array &$cache, array &$result)
{
$result[] = $this->_gatherScalarRowData($data, $cache);
$result[] = $this->gatherScalarRowData($data, $cache);
}
}
}
@@ -0,0 +1,187 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Internal\Hydration;
use \PDO,
Doctrine\DBAL\Types\Type,
Doctrine\ORM\Mapping\ClassMetadata,
Doctrine\ORM\Event\LifecycleEventArgs,
Doctrine\ORM\Events,
Doctrine\ORM\Query;
class SimpleObjectHydrator extends AbstractHydrator
{
/**
* @var ClassMetadata
*/
private $class;
/**
* @var array
*/
private $declaringClasses = array();
/**
* {@inheritdoc}
*/
protected function hydrateAllData()
{
$result = array();
$cache = array();
while ($row = $this->_stmt->fetch(PDO::FETCH_ASSOC)) {
$this->hydrateRowData($row, $cache, $result);
}
$this->_em->getUnitOfWork()->triggerEagerLoads();
return $result;
}
/**
* {@inheritdoc}
*/
protected function prepare()
{
if (count($this->_rsm->aliasMap) !== 1) {
throw new \RuntimeException("Cannot use SimpleObjectHydrator with a ResultSetMapping that contains more than one object result.");
}
if ($this->_rsm->scalarMappings) {
throw new \RuntimeException("Cannot use SimpleObjectHydrator with a ResultSetMapping that contains scalar mappings.");
}
$this->class = $this->_em->getClassMetadata(reset($this->_rsm->aliasMap));
// We only need to add declaring classes if we have inheritance.
if ($this->class->inheritanceType === ClassMetadata::INHERITANCE_TYPE_NONE) {
return;
}
foreach ($this->_rsm->declaringClasses as $column => $class) {
$this->declaringClasses[$column] = $this->_em->getClassMetadata($class);
}
}
/**
* {@inheritdoc}
*/
protected function hydrateRowData(array $sqlResult, array &$cache, array &$result)
{
$entityName = $this->class->name;
$data = array();
// We need to find the correct entity class name if we have inheritance in resultset
if ($this->class->inheritanceType !== ClassMetadata::INHERITANCE_TYPE_NONE) {
$discrColumnName = $this->_platform->getSQLResultCasing($this->class->discriminatorColumn['name']);
if ( ! isset($sqlResult[$discrColumnName])) {
throw HydrationException::missingDiscriminatorColumn($entityName, $discrColumnName, key($this->_rsm->aliasMap));
}
if ($sqlResult[$discrColumnName] === '') {
throw HydrationException::emptyDiscriminatorValue(key($this->_rsm->aliasMap));
}
$entityName = $this->class->discriminatorMap[$sqlResult[$discrColumnName]];
unset($sqlResult[$discrColumnName]);
}
foreach ($sqlResult as $column => $value) {
// Hydrate column information if not yet present
if ( ! isset($cache[$column])) {
if (($info = $this->hydrateColumnInfo($entityName, $column)) === null) {
continue;
}
$cache[$column] = $info;
}
// Convert field to a valid PHP value
if (isset($cache[$column]['field'])) {
$type = Type::getType($cache[$column]['class']->fieldMappings[$cache[$column]['name']]['type']);
$value = $type->convertToPHPValue($value, $this->_platform);
}
// Prevent overwrite in case of inherit classes using same property name (See AbstractHydrator)
if (isset($cache[$column]) && ( ! isset($data[$cache[$column]['name']]) || $value !== null)) {
$data[$cache[$column]['name']] = $value;
}
}
if (isset($this->_hints[Query::HINT_REFRESH_ENTITY])) {
$this->registerManaged($this->class, $this->_hints[Query::HINT_REFRESH_ENTITY], $data);
}
$uow = $this->_em->getUnitOfWork();
$entity = $uow->createEntity($entityName, $data, $this->_hints);
$result[] = $entity;
}
/**
* Retrieve column information form ResultSetMapping.
*
* @param string $entityName
* @param string $column
*
* @return array
*/
protected function hydrateColumnInfo($entityName, $column)
{
switch (true) {
case (isset($this->_rsm->fieldMappings[$column])):
$class = isset($this->declaringClasses[$column])
? $this->declaringClasses[$column]
: $this->class;
// If class is not part of the inheritance, ignore
if ( ! ($class->name === $entityName || is_subclass_of($entityName, $class->name))) {
return null;
}
return array(
'class' => $class,
'name' => $this->_rsm->fieldMappings[$column],
'field' => true,
);
case (isset($this->_rsm->relationMap[$column])):
$class = isset($this->_rsm->relationMap[$column])
? $this->_rsm->relationMap[$column]
: $this->class;
// If class is not self referencing, ignore
if ( ! ($class === $entityName || is_subclass_of($entityName, $class))) {
return null;
}
// TODO: Decide what to do with associations. It seems original code is incomplete.
// One solution is to load the association, but it might require extra efforts.
return array('name' => $column);
default:
return array(
'name' => $this->_rsm->metaMappings[$column]
);
}
}
}
@@ -13,37 +13,44 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Internal\Hydration;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Connection,
Doctrine\ORM\NoResultException,
Doctrine\ORM\NonUniqueResultException;
/**
* Hydrator that hydrates a single scalar value from the result set.
*
* @since 2.0
* @author Roman Borschel <roman@code-factory.org>
* @since 2.0
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
*/
class SingleScalarHydrator extends AbstractHydrator
{
/** @override */
protected function _hydrateAll()
/**
* {@inheritdoc}
*/
protected function hydrateAllData()
{
$cache = array();
$result = $this->_stmt->fetchAll(\PDO::FETCH_ASSOC);
$num = count($result);
$data = $this->_stmt->fetchAll(\PDO::FETCH_ASSOC);
$numRows = count($data);
if ($num == 0) {
throw new \Doctrine\ORM\NoResultException;
} else if ($num > 1 || count($result[key($result)]) > 1) {
throw new \Doctrine\ORM\NonUniqueResultException;
if ($numRows === 0) {
throw new NoResultException();
}
$result = $this->_gatherScalarRowData($result[key($result)], $cache);
if ($numRows > 1 || count($data[key($data)]) > 1) {
throw new NonUniqueResultException();
}
$cache = array();
$result = $this->gatherScalarRowData($data[key($data)], $cache);
return array_shift($result);
}
}
}
+24
View File
@@ -0,0 +1,24 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping;
interface Annotation
{
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -0,0 +1,167 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping\Builder;
use Doctrine\ORM\Mapping\ClassMetadata;
class AssociationBuilder
{
/**
* @var ClassMetadataBuilder
*/
protected $builder;
/**
* @var array
*/
protected $mapping;
/**
* @var array
*/
protected $joinColumns;
/**
*
* @var int
*/
protected $type;
/**
* @param ClassMetadataBuilder $builder
* @param array $mapping
*/
public function __construct(ClassMetadataBuilder $builder, array $mapping, $type)
{
$this->builder = $builder;
$this->mapping = $mapping;
$this->type = $type;
}
public function mappedBy($fieldName)
{
$this->mapping['mappedBy'] = $fieldName;
return $this;
}
public function inversedBy($fieldName)
{
$this->mapping['inversedBy'] = $fieldName;
return $this;
}
public function cascadeAll()
{
$this->mapping['cascade'] = array("ALL");
return $this;
}
public function cascadePersist()
{
$this->mapping['cascade'][] = "persist";
return $this;
}
public function cascadeRemove()
{
$this->mapping['cascade'][] = "remove";
return $this;
}
public function cascadeMerge()
{
$this->mapping['cascade'][] = "merge";
return $this;
}
public function cascadeDetach()
{
$this->mapping['cascade'][] = "detach";
return $this;
}
public function cascadeRefresh()
{
$this->mapping['cascade'][] = "refresh";
return $this;
}
public function fetchExtraLazy()
{
$this->mapping['fetch'] = ClassMetadata::FETCH_EXTRA_LAZY;
return $this;
}
public function fetchEager()
{
$this->mapping['fetch'] = ClassMetadata::FETCH_EAGER;
return $this;
}
public function fetchLazy()
{
$this->mapping['fetch'] = ClassMetadata::FETCH_LAZY;
return $this;
}
/**
* Add Join Columns
*
* @param string $columnName
* @param string $referencedColumnName
* @param bool $nullable
* @param bool $unique
* @param string $onDelete
* @param string $columnDef
*/
public function addJoinColumn($columnName, $referencedColumnName, $nullable = true, $unique = false, $onDelete = null, $columnDef = null)
{
$this->joinColumns[] = array(
'name' => $columnName,
'referencedColumnName' => $referencedColumnName,
'nullable' => $nullable,
'unique' => $unique,
'onDelete' => $onDelete,
'columnDefinition' => $columnDef,
);
return $this;
}
/**
* @return ClassMetadataBuilder
*/
public function build()
{
$mapping = $this->mapping;
if ($this->joinColumns) {
$mapping['joinColumns'] = $this->joinColumns;
}
$cm = $this->builder->getClassMetadata();
if ($this->type == ClassMetadata::MANY_TO_ONE) {
$cm->mapManyToOne($mapping);
} else if ($this->type == ClassMetadata::ONE_TO_ONE) {
$cm->mapOneToOne($mapping);
} else {
throw new \InvalidArgumentException("Type should be a ToOne Assocation here");
}
return $this->builder;
}
}
@@ -0,0 +1,470 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping\Builder;
use Doctrine\ORM\Mapping\ClassMetadata,
Doctrine\ORM\Mapping\ClassMetadataInfo;
/**
* Builder Object for ClassMetadata
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.com
* @since 2.2
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
*/
class ClassMetadataBuilder
{
/**
* @var \Doctrine\ORM\Mapping\ClassMetadataInfo
*/
private $cm;
/**
* @param \Doctrine\ORM\Mapping\ClassMetadataInfo $cm
*/
public function __construct(ClassMetadataInfo $cm)
{
$this->cm = $cm;
}
/**
* @return ClassMetadata
*/
public function getClassMetadata()
{
return $this->cm;
}
/**
* Mark the class as mapped superclass.
*
* @return ClassMetadataBuilder
*/
public function setMappedSuperClass()
{
$this->cm->isMappedSuperclass = true;
return $this;
}
/**
* Set custom Repository class name
*
* @param string $repositoryClassName
* @return ClassMetadataBuilder
*/
public function setCustomRepositoryClass($repositoryClassName)
{
$this->cm->setCustomRepositoryClass($repositoryClassName);
return $this;
}
/**
* Mark class read only
*
* @return ClassMetadataBuilder
*/
public function setReadOnly()
{
$this->cm->markReadOnly();
return $this;
}
/**
* Set the table name
*
* @param string $name
* @return ClassMetadataBuilder
*/
public function setTable($name)
{
$this->cm->setPrimaryTable(array('name' => $name));
return $this;
}
/**
* Add Index
*
* @param array $columns
* @param string $name
* @return ClassMetadataBuilder
*/
public function addIndex(array $columns, $name)
{
if (!isset($this->cm->table['indexes'])) {
$this->cm->table['indexes'] = array();
}
$this->cm->table['indexes'][$name] = array('columns' => $columns);
return $this;
}
/**
* Add Unique Constraint
*
* @param array $columns
* @param string $name
* @return ClassMetadataBuilder
*/
public function addUniqueConstraint(array $columns, $name)
{
if ( ! isset($this->cm->table['uniqueConstraints'])) {
$this->cm->table['uniqueConstraints'] = array();
}
$this->cm->table['uniqueConstraints'][$name] = array('columns' => $columns);
return $this;
}
/**
* Add named query
*
* @param string $name
* @param string $dqlQuery
* @return ClassMetadataBuilder
*/
public function addNamedQuery($name, $dqlQuery)
{
$this->cm->addNamedQuery(array(
'name' => $name,
'query' => $dqlQuery,
));
return $this;
}
/**
* Set class as root of a joined table inheritance hierachy.
*
* @return ClassMetadataBuilder
*/
public function setJoinedTableInheritance()
{
$this->cm->setInheritanceType(ClassMetadata::INHERITANCE_TYPE_JOINED);
return $this;
}
/**
* Set class as root of a single table inheritance hierachy.
*
* @return ClassMetadataBuilder
*/
public function setSingleTableInheritance()
{
$this->cm->setInheritanceType(ClassMetadata::INHERITANCE_TYPE_SINGLE_TABLE);
return $this;
}
/**
* Set the discriminator column details.
*
* @param string $name
* @param string $type
*/
public function setDiscriminatorColumn($name, $type = 'string', $length = 255)
{
$this->cm->setDiscriminatorColumn(array(
'name' => $name,
'type' => $type,
'length' => $length,
));
return $this;
}
/**
* Add a subclass to this inheritance hierachy.
*
* @param string $name
* @param string $class
* @return ClassMetadataBuilder
*/
public function addDiscriminatorMapClass($name, $class)
{
$this->cm->addDiscriminatorMapClass($name, $class);
return $this;
}
/**
* Set deferred explicit change tracking policy.
*
* @return ClassMetadataBuilder
*/
public function setChangeTrackingPolicyDeferredExplicit()
{
$this->cm->setChangeTrackingPolicy(ClassMetadata::CHANGETRACKING_DEFERRED_EXPLICIT);
return $this;
}
/**
* Set notify change tracking policy.
*
* @return ClassMetadataBuilder
*/
public function setChangeTrackingPolicyNotify()
{
$this->cm->setChangeTrackingPolicy(ClassMetadata::CHANGETRACKING_NOTIFY);
return $this;
}
/**
* Add lifecycle event
*
* @param string $methodName
* @param string $event
* @return ClassMetadataBuilder
*/
public function addLifecycleEvent($methodName, $event)
{
$this->cm->addLifecycleCallback($methodName, $event);
return $this;
}
/**
* Add Field
*
* @param string $name
* @param string $type
* @param array $mapping
*/
public function addField($name, $type, array $mapping = array())
{
$mapping['fieldName'] = $name;
$mapping['type'] = $type;
$this->cm->mapField($mapping);
return $this;
}
/**
* Create a field builder.
*
* @param string $name
* @param string $type
* @return FieldBuilder
*/
public function createField($name, $type)
{
return new FieldBuilder(
$this,
array(
'fieldName' => $name,
'type' => $type
)
);
}
/**
* Add a simple many to one association, optionally with the inversed by field.
*
* @param string $name
* @param string $targetEntity
* @param string|null $inversedBy
* @return ClassMetadataBuilder
*/
public function addManyToOne($name, $targetEntity, $inversedBy = null)
{
$builder = $this->createManyToOne($name, $targetEntity);
if ($inversedBy) {
$builder->inversedBy($inversedBy);
}
return $builder->build();
}
/**
* Create a ManyToOne Assocation Builder.
*
* Note: This method does not add the association, you have to call build() on the AssociationBuilder.
*
* @param string $name
* @param string $targetEntity
* @return AssociationBuilder
*/
public function createManyToOne($name, $targetEntity)
{
return new AssociationBuilder(
$this,
array(
'fieldName' => $name,
'targetEntity' => $targetEntity
),
ClassMetadata::MANY_TO_ONE
);
}
/**
* Create OneToOne Assocation Builder
*
* @param string $name
* @param string $targetEntity
* @return AssociationBuilder
*/
public function createOneToOne($name, $targetEntity)
{
return new AssociationBuilder(
$this,
array(
'fieldName' => $name,
'targetEntity' => $targetEntity
),
ClassMetadata::ONE_TO_ONE
);
}
/**
* Add simple inverse one-to-one assocation.
*
* @param string $name
* @param string $targetEntity
* @param string $mappedBy
* @return ClassMetadataBuilder
*/
public function addInverseOneToOne($name, $targetEntity, $mappedBy)
{
$builder = $this->createOneToOne($name, $targetEntity);
$builder->mappedBy($mappedBy);
return $builder->build();
}
/**
* Add simple owning one-to-one assocation.
*
* @param string $name
* @param string $targetEntity
* @param string $inversedBy
* @return ClassMetadataBuilder
*/
public function addOwningOneToOne($name, $targetEntity, $inversedBy = null)
{
$builder = $this->createOneToOne($name, $targetEntity);
if ($inversedBy) {
$builder->inversedBy($inversedBy);
}
return $builder->build();
}
/**
* Create ManyToMany Assocation Builder
*
* @param string $name
* @param string $targetEntity
* @return ManyToManyAssociationBuilder
*/
public function createManyToMany($name, $targetEntity)
{
return new ManyToManyAssociationBuilder(
$this,
array(
'fieldName' => $name,
'targetEntity' => $targetEntity
),
ClassMetadata::MANY_TO_MANY
);
}
/**
* Add a simple owning many to many assocation.
*
* @param string $name
* @param string $targetEntity
* @param string|null $inversedBy
* @return ClassMetadataBuilder
*/
public function addOwningManyToMany($name, $targetEntity, $inversedBy = null)
{
$builder = $this->createManyToMany($name, $targetEntity);
if ($inversedBy) {
$builder->inversedBy($inversedBy);
}
return $builder->build();
}
/**
* Add a simple inverse many to many assocation.
*
* @param string $name
* @param string $targetEntity
* @param string $mappedBy
* @return ClassMetadataBuilder
*/
public function addInverseManyToMany($name, $targetEntity, $mappedBy)
{
$builder = $this->createManyToMany($name, $targetEntity);
$builder->mappedBy($mappedBy);
return $builder->build();
}
/**
* Create a one to many assocation builder
*
* @param string $name
* @param string $targetEntity
* @return OneToManyAssociationBuilder
*/
public function createOneToMany($name, $targetEntity)
{
return new OneToManyAssociationBuilder(
$this,
array(
'fieldName' => $name,
'targetEntity' => $targetEntity
),
ClassMetadata::ONE_TO_MANY
);
}
/**
* Add simple OneToMany assocation.
*
* @param string $name
* @param string $targetEntity
* @param string $mappedBy
* @return ClassMetadataBuilder
*/
public function addOneToMany($name, $targetEntity, $mappedBy)
{
$builder = $this->createOneToMany($name, $targetEntity);
$builder->mappedBy($mappedBy);
return $builder->build();
}
}
@@ -0,0 +1,223 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping\Builder;
/**
* Field Builder
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.com
* @since 2.2
* @author Benjamin Eberlei <kontakt@beberlei.de>
*/
class FieldBuilder
{
/**
* @var ClassMetadataBuilder
*/
private $builder;
/**
* @var array
*/
private $mapping;
/**
* @var bool
*/
private $version;
/**
* @var string
*/
private $generatedValue;
/**
* @var array
*/
private $sequenceDef;
/**
*
* @param ClassMetadataBuilder $builder
* @param array $mapping
*/
public function __construct(ClassMetadataBuilder $builder, array $mapping)
{
$this->builder = $builder;
$this->mapping = $mapping;
}
/**
* Set length.
*
* @param int $length
* @return FieldBuilder
*/
public function length($length)
{
$this->mapping['length'] = $length;
return $this;
}
/**
* Set nullable
*
* @param bool
* @return FieldBuilder
*/
public function nullable($flag = true)
{
$this->mapping['nullable'] = (bool)$flag;
return $this;
}
/**
* Set Unique
*
* @param bool
* @return FieldBuilder
*/
public function unique($flag = true)
{
$this->mapping['unique'] = (bool)$flag;
return $this;
}
/**
* Set column name
*
* @param string $name
* @return FieldBuilder
*/
public function columnName($name)
{
$this->mapping['columnName'] = $name;
return $this;
}
/**
* Set Precision
*
* @param int $p
* @return FieldBuilder
*/
public function precision($p)
{
$this->mapping['precision'] = $p;
return $this;
}
/**
* Set scale.
*
* @param int $s
* @return FieldBuilder
*/
public function scale($s)
{
$this->mapping['scale'] = $s;
return $this;
}
/**
* Set field as primary key.
*
* @return FieldBuilder
*/
public function isPrimaryKey()
{
$this->mapping['id'] = true;
return $this;
}
/**
* @param int $strategy
* @return FieldBuilder
*/
public function generatedValue($strategy = 'AUTO')
{
$this->generatedValue = $strategy;
return $this;
}
/**
* Set field versioned
*
* @return FieldBuilder
*/
public function isVersionField()
{
$this->version = true;
return $this;
}
/**
* Set Sequence Generator
*
* @param string $sequenceName
* @param int $allocationSize
* @param int $initialValue
* @return FieldBuilder
*/
public function setSequenceGenerator($sequenceName, $allocationSize = 1, $initialValue = 1)
{
$this->sequenceDef = array(
'sequenceName' => $sequenceName,
'allocationSize' => $allocationSize,
'initialValue' => $initialValue,
);
return $this;
}
/**
* Set column definition.
*
* @param string $def
* @return FieldBuilder
*/
public function columnDefinition($def)
{
$this->mapping['columnDefinition'] = $def;
return $this;
}
/**
* Finalize this field and attach it to the ClassMetadata.
*
* Without this call a FieldBuilder has no effect on the ClassMetadata.
*
* @return ClassMetadataBuilder
*/
public function build()
{
$cm = $this->builder->getClassMetadata();
if ($this->generatedValue) {
$cm->setIdGeneratorType(constant('Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_' . $this->generatedValue));
}
if ($this->version) {
$cm->setVersionMapping($this->mapping);
}
$cm->mapField($this->mapping);
if ($this->sequenceDef) {
$cm->setSequenceGeneratorDefinition($this->sequenceDef);
}
return $this->builder;
}
}
@@ -0,0 +1,86 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping\Builder;
/**
* ManyToMany Association Builder
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.com
* @since 2.0
* @author Benjamin Eberlei <kontakt@beberlei.de>
*/
class ManyToManyAssociationBuilder extends OneToManyAssociationBuilder
{
private $joinTableName;
private $inverseJoinColumns = array();
public function setJoinTable($name)
{
$this->joinTableName = $name;
return $this;
}
/**
* Add Inverse Join Columns
*
* @param string $columnName
* @param string $referencedColumnName
* @param bool $nullable
* @param bool $unique
* @param string $onDelete
* @param string $columnDef
*/
public function addInverseJoinColumn($columnName, $referencedColumnName, $nullable = true, $unique = false, $onDelete = null, $columnDef = null)
{
$this->inverseJoinColumns[] = array(
'name' => $columnName,
'referencedColumnName' => $referencedColumnName,
'nullable' => $nullable,
'unique' => $unique,
'onDelete' => $onDelete,
'columnDefinition' => $columnDef,
);
return $this;
}
/**
* @return ClassMetadataBuilder
*/
public function build()
{
$mapping = $this->mapping;
$mapping['joinTable'] = array();
if ($this->joinColumns) {
$mapping['joinTable']['joinColumns'] = $this->joinColumns;
}
if ($this->inverseJoinColumns) {
$mapping['joinTable']['inverseJoinColumns'] = $this->inverseJoinColumns;
}
if ($this->joinTableName) {
$mapping['joinTable']['name'] = $this->joinTableName;
}
$cm = $this->builder->getClassMetadata();
$cm->mapManyToMany($mapping);
return $this->builder;
}
}
@@ -0,0 +1,62 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping\Builder;
/**
* OneToMany Association Builder
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.com
* @since 2.0
* @author Benjamin Eberlei <kontakt@beberlei.de>
*/
class OneToManyAssociationBuilder extends AssociationBuilder
{
/**
* @param array $fieldNames
* @return OneToManyAssociationBuilder
*/
public function setOrderBy(array $fieldNames)
{
$this->mapping['orderBy'] = $fieldNames;
return $this;
}
public function setIndexBy($fieldName)
{
$this->mapping['indexBy'] = $fieldName;
return $this;
}
/**
* @return ClassMetadataBuilder
*/
public function build()
{
$mapping = $this->mapping;
if ($this->joinColumns) {
$mapping['joinColumns'] = $this->joinColumns;
}
$cm = $this->builder->getClassMetadata();
$cm->mapOneToMany($mapping);
return $this->builder;
}
}
@@ -0,0 +1,30 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping;
/**
* @Annotation
* @Target("CLASS")
*/
final class ChangeTrackingPolicy implements Annotation
{
/** @var string */
public $value;
}
+3 -350
View File
@@ -13,364 +13,17 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping;
use ReflectionClass, ReflectionProperty;
/**
* A <tt>ClassMetadata</tt> instance holds all the object-relational mapping metadata
* of an entity and it's associations.
*
* Once populated, ClassMetadata instances are usually cached in a serialized form.
* {@inheritDoc}
*
* <b>IMPORTANT NOTE:</b>
*
* The fields of this class are only public for 2 reasons:
* 1) To allow fast READ access.
* 2) To drastically reduce the size of a serialized instance (private/protected members
* get the whole class name, namespace inclusive, prepended to every property in
* the serialized representation).
*
* @author Roman Borschel <roman@code-factory.org>
* @author Jonathan H. Wage <jonwage@gmail.com>
* @since 2.0
* @todo remove or rename ClassMetadataInfo to ClassMetadata
*/
class ClassMetadata extends ClassMetadataInfo
{
/**
* The ReflectionProperty instances of the mapped class.
*
* @var array
*/
public $reflFields = array();
/**
* The prototype from which new instances of the mapped class are created.
*
* @var object
*/
private $_prototype;
/**
* Initializes a new ClassMetadata instance that will hold the object-relational mapping
* metadata of the class with the given name.
*
* @param string $entityName The name of the entity class the new instance is used for.
*/
public function __construct($entityName)
{
parent::__construct($entityName);
$this->reflClass = new ReflectionClass($entityName);
$this->namespace = $this->reflClass->getNamespaceName();
$this->table['name'] = $this->reflClass->getShortName();
}
/**
* Gets the ReflectionPropertys of the mapped class.
*
* @return array An array of ReflectionProperty instances.
*/
public function getReflectionProperties()
{
return $this->reflFields;
}
/**
* Gets a ReflectionProperty for a specific field of the mapped class.
*
* @param string $name
* @return ReflectionProperty
*/
public function getReflectionProperty($name)
{
return $this->reflFields[$name];
}
/**
* Gets the ReflectionProperty for the single identifier field.
*
* @return ReflectionProperty
* @throws BadMethodCallException If the class has a composite identifier.
*/
public function getSingleIdReflectionProperty()
{
if ($this->isIdentifierComposite) {
throw new \BadMethodCallException("Class " . $this->name . " has a composite identifier.");
}
return $this->reflFields[$this->identifier[0]];
}
/**
* Validates & completes the given field mapping.
*
* @param array $mapping The field mapping to validated & complete.
* @return array The validated and completed field mapping.
*
* @throws MappingException
*/
protected function _validateAndCompleteFieldMapping(array &$mapping)
{
parent::_validateAndCompleteFieldMapping($mapping);
// Store ReflectionProperty of mapped field
$refProp = $this->reflClass->getProperty($mapping['fieldName']);
$refProp->setAccessible(true);
$this->reflFields[$mapping['fieldName']] = $refProp;
}
/**
* Extracts the identifier values of an entity of this class.
*
* For composite identifiers, the identifier values are returned as an array
* with the same order as the field order in {@link identifier}.
*
* @param object $entity
* @return array
*/
public function getIdentifierValues($entity)
{
if ($this->isIdentifierComposite) {
$id = array();
foreach ($this->identifier as $idField) {
$value = $this->reflFields[$idField]->getValue($entity);
if ($value !== null) {
$id[$idField] = $value;
}
}
return $id;
} else {
$value = $this->reflFields[$this->identifier[0]]->getValue($entity);
if ($value !== null) {
return array($this->identifier[0] => $value);
}
return array();
}
}
/**
* Populates the entity identifier of an entity.
*
* @param object $entity
* @param mixed $id
* @todo Rename to assignIdentifier()
*/
public function setIdentifierValues($entity, array $id)
{
foreach ($id as $idField => $idValue) {
$this->reflFields[$idField]->setValue($entity, $idValue);
}
}
/**
* Sets the specified field to the specified value on the given entity.
*
* @param object $entity
* @param string $field
* @param mixed $value
*/
public function setFieldValue($entity, $field, $value)
{
$this->reflFields[$field]->setValue($entity, $value);
}
/**
* Gets the specified field's value off the given entity.
*
* @param object $entity
* @param string $field
*/
public function getFieldValue($entity, $field)
{
return $this->reflFields[$field]->getValue($entity);
}
/**
* Stores the association mapping.
*
* @param AssociationMapping $assocMapping
*/
protected function _storeAssociationMapping(array $assocMapping)
{
parent::_storeAssociationMapping($assocMapping);
// Store ReflectionProperty of mapped field
$sourceFieldName = $assocMapping['fieldName'];
$refProp = $this->reflClass->getProperty($sourceFieldName);
$refProp->setAccessible(true);
$this->reflFields[$sourceFieldName] = $refProp;
}
/**
* Gets the (possibly quoted) column name of a mapped field for safe use
* in an SQL statement.
*
* @param string $field
* @param AbstractPlatform $platform
* @return string
*/
public function getQuotedColumnName($field, $platform)
{
return isset($this->fieldMappings[$field]['quoted']) ?
$platform->quoteIdentifier($this->fieldMappings[$field]['columnName']) :
$this->fieldMappings[$field]['columnName'];
}
/**
* Gets the (possibly quoted) primary table name of this class for safe use
* in an SQL statement.
*
* @param AbstractPlatform $platform
* @return string
*/
public function getQuotedTableName($platform)
{
return isset($this->table['quoted']) ?
$platform->quoteIdentifier($this->table['name']) :
$this->table['name'];
}
/**
* Gets the (possibly quoted) name of the join table.
*
* @param AbstractPlatform $platform
* @return string
*/
public function getQuotedJoinTableName(array $assoc, $platform)
{
return isset($assoc['joinTable']['quoted'])
? $platform->quoteIdentifier($assoc['joinTable']['name'])
: $assoc['joinTable']['name'];
}
/**
* Creates a string representation of this instance.
*
* @return string The string representation of this instance.
* @todo Construct meaningful string representation.
*/
public function __toString()
{
return __CLASS__ . '@' . spl_object_hash($this);
}
/**
* Determines which fields get serialized.
*
* It is only serialized what is necessary for best unserialization performance.
* That means any metadata properties that are not set or empty or simply have
* their default value are NOT serialized.
*
* Parts that are also NOT serialized because they can not be properly unserialized:
* - reflClass (ReflectionClass)
* - reflFields (ReflectionProperty array)
*
* @return array The names of all the fields that should be serialized.
*/
public function __sleep()
{
// This metadata is always serialized/cached.
$serialized = array(
'associationMappings',
'columnNames', //TODO: Not really needed. Can use fieldMappings[$fieldName]['columnName']
'fieldMappings',
'fieldNames',
'identifier',
'isIdentifierComposite', // TODO: REMOVE
'name',
'namespace', // TODO: REMOVE
'table',
'rootEntityName',
'idGenerator', //TODO: Does not really need to be serialized. Could be moved to runtime.
);
// The rest of the metadata is only serialized if necessary.
if ($this->changeTrackingPolicy != self::CHANGETRACKING_DEFERRED_IMPLICIT) {
$serialized[] = 'changeTrackingPolicy';
}
if ($this->customRepositoryClassName) {
$serialized[] = 'customRepositoryClassName';
}
if ($this->inheritanceType != self::INHERITANCE_TYPE_NONE) {
$serialized[] = 'inheritanceType';
$serialized[] = 'discriminatorColumn';
$serialized[] = 'discriminatorValue';
$serialized[] = 'discriminatorMap';
$serialized[] = 'parentClasses';
$serialized[] = 'subClasses';
}
if ($this->generatorType != self::GENERATOR_TYPE_NONE) {
$serialized[] = 'generatorType';
if ($this->generatorType == self::GENERATOR_TYPE_SEQUENCE) {
$serialized[] = 'sequenceGeneratorDefinition';
}
}
if ($this->isMappedSuperclass) {
$serialized[] = 'isMappedSuperclass';
}
if ($this->isVersioned) {
$serialized[] = 'isVersioned';
$serialized[] = 'versionField';
}
if ($this->lifecycleCallbacks) {
$serialized[] = 'lifecycleCallbacks';
}
return $serialized;
}
/**
* Restores some state that can not be serialized/unserialized.
*
* @return void
*/
public function __wakeup()
{
// Restore ReflectionClass and properties
$this->reflClass = new ReflectionClass($this->name);
foreach ($this->fieldMappings as $field => $mapping) {
if (isset($mapping['declared'])) {
$reflField = new ReflectionProperty($mapping['declared'], $field);
} else {
$reflField = $this->reflClass->getProperty($field);
}
$reflField->setAccessible(true);
$this->reflFields[$field] = $reflField;
}
foreach ($this->associationMappings as $field => $mapping) {
if (isset($mapping['declared'])) {
$reflField = new ReflectionProperty($mapping['declared'], $field);
} else {
$reflField = $this->reflClass->getProperty($field);
}
$reflField->setAccessible(true);
$this->reflFields[$field] = $reflField;
}
}
/**
* Creates a new instance of the mapped class, without invoking the constructor.
*
* @return object
*/
public function newInstance()
{
if ($this->_prototype === null) {
$this->_prototype = unserialize(sprintf('O:%d:"%s":0:{}', strlen($this->name), $this->name));
}
return clone $this->_prototype;
}
}
+345 -263
View File
@@ -13,7 +13,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
@@ -23,11 +23,16 @@ use ReflectionException,
Doctrine\ORM\ORMException,
Doctrine\ORM\EntityManager,
Doctrine\DBAL\Platforms,
Doctrine\ORM\Events;
Doctrine\ORM\Events,
Doctrine\Common\Persistence\Mapping\ReflectionService,
Doctrine\Common\Persistence\Mapping\ClassMetadata as ClassMetadataInterface,
Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory,
Doctrine\ORM\Id\IdentityGenerator,
Doctrine\ORM\Event\LoadClassMetadataEventArgs;
/**
* The ClassMetadataFactory is used to create ClassMetadata objects that contain all the
* metadata mapping informations of a class which describes how a class should be mapped
* metadata mapping information of a class which describes how a class should be mapped
* to a relational database.
*
* @since 2.0
@@ -36,20 +41,20 @@ use ReflectionException,
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class ClassMetadataFactory
class ClassMetadataFactory extends AbstractClassMetadataFactory
{
/**
* @var EntityManager
*/
private $em;
/**
* @var AbstractPlatform
* @var \Doctrine\DBAL\Platforms\AbstractPlatform
*/
private $targetPlatform;
/**
* @var Driver\Driver
* @var \Doctrine\Common\Persistence\Mapping\Driver\MappingDriver
*/
private $driver;
@@ -59,22 +64,7 @@ class ClassMetadataFactory
private $evm;
/**
* @var \Doctrine\Common\Cache\Cache
*/
private $cacheDriver;
/**
* @var array
*/
private $loadedMetadata = array();
/**
* @var bool
*/
private $initialized = false;
/**
* @param EntityManager $$em
* @param EntityManager $em
*/
public function setEntityManager(EntityManager $em)
{
@@ -82,55 +72,9 @@ class ClassMetadataFactory
}
/**
* Sets the cache driver used by the factory to cache ClassMetadata instances.
*
* @param Doctrine\Common\Cache\Cache $cacheDriver
* {@inheritDoc}.
*/
public function setCacheDriver($cacheDriver)
{
$this->cacheDriver = $cacheDriver;
}
/**
* Gets the cache driver used by the factory to cache ClassMetadata instances.
*
* @return Doctrine\Common\Cache\Cache
*/
public function getCacheDriver()
{
return $this->cacheDriver;
}
public function getLoadedMetadata()
{
return $this->loadedMetadata;
}
/**
* Forces the factory to load the metadata of all classes known to the underlying
* mapping driver.
*
* @return array The ClassMetadata instances of all mapped classes.
*/
public function getAllMetadata()
{
if ( ! $this->initialized) {
$this->initialize();
}
$metadata = array();
foreach ($this->driver->getAllClassNames() as $className) {
$metadata[] = $this->getMetadataFor($className);
}
return $metadata;
}
/**
* Lazy initialization of this stuff, especially the metadata driver,
* since these are not needed at all when a metadata cache is active.
*/
private function initialize()
protected function initialize()
{
$this->driver = $this->em->getConfiguration()->getMetadataDriverImpl();
$this->targetPlatform = $this->em->getConnection()->getDatabasePlatform();
@@ -139,226 +83,202 @@ class ClassMetadataFactory
}
/**
* Gets the class metadata descriptor for a class.
*
* @param string $className The name of the class.
* @return Doctrine\ORM\Mapping\ClassMetadata
* {@inheritDoc}
*/
public function getMetadataFor($className)
protected function doLoadMetadata($class, $parent, $rootEntityFound, array $nonSuperclassParents)
{
if ( ! isset($this->loadedMetadata[$className])) {
$realClassName = $className;
/* @var $class ClassMetadata */
/* @var $parent ClassMetadata */
if ($parent) {
$class->setInheritanceType($parent->inheritanceType);
$class->setDiscriminatorColumn($parent->discriminatorColumn);
$class->setIdGeneratorType($parent->generatorType);
$this->addInheritedFields($class, $parent);
$this->addInheritedRelations($class, $parent);
$class->setIdentifier($parent->identifier);
$class->setVersioned($parent->isVersioned);
$class->setVersionField($parent->versionField);
$class->setDiscriminatorMap($parent->discriminatorMap);
$class->setLifecycleCallbacks($parent->lifecycleCallbacks);
$class->setChangeTrackingPolicy($parent->changeTrackingPolicy);
// Check for namespace alias
if (strpos($className, ':') !== false) {
list($namespaceAlias, $simpleClassName) = explode(':', $className);
$realClassName = $this->em->getConfiguration()->getEntityNamespace($namespaceAlias) . '\\' . $simpleClassName;
if (isset($this->loadedMetadata[$realClassName])) {
// We do not have the alias name in the map, include it
$this->loadedMetadata[$className] = $this->loadedMetadata[$realClassName];
return $this->loadedMetadata[$realClassName];
}
}
if ($this->cacheDriver) {
if (($cached = $this->cacheDriver->fetch("$realClassName\$CLASSMETADATA")) !== false) {
$this->loadedMetadata[$realClassName] = $cached;
} else {
foreach ($this->loadMetadata($realClassName) as $loadedClassName) {
$this->cacheDriver->save(
"$loadedClassName\$CLASSMETADATA", $this->loadedMetadata[$loadedClassName], null
);
}
}
} else {
$this->loadMetadata($realClassName);
}
if ($className != $realClassName) {
// We do not have the alias name in the map, include it
$this->loadedMetadata[$className] = $this->loadedMetadata[$realClassName];
if ($parent->isMappedSuperclass) {
$class->setCustomRepositoryClass($parent->customRepositoryClassName);
}
}
return $this->loadedMetadata[$className];
}
/**
* Checks whether the factory has the metadata for a class loaded already.
*
* @param string $className
* @return boolean TRUE if the metadata of the class in question is already loaded, FALSE otherwise.
*/
public function hasMetadataFor($className)
{
return isset($this->loadedMetadata[$className]);
}
/**
* Sets the metadata descriptor for a specific class.
*
* NOTE: This is only useful in very special cases, like when generating proxy classes.
*
* @param string $className
* @param ClassMetadata $class
*/
public function setMetadataFor($className, $class)
{
$this->loadedMetadata[$className] = $class;
}
/**
* Get array of parent classes for the given entity class
*
* @param string $name
* @return array $parentClasses
*/
protected function getParentClasses($name)
{
// Collect parent classes, ignoring transient (not-mapped) classes.
$parentClasses = array();
foreach (array_reverse(class_parents($name)) as $parentClass) {
if ( ! $this->driver->isTransient($parentClass)) {
$parentClasses[] = $parentClass;
}
}
return $parentClasses;
}
/**
* Loads the metadata of the class in question and all it's ancestors whose metadata
* is still not loaded.
*
* @param string $name The name of the class for which the metadata should get loaded.
* @param array $tables The metadata collection to which the loaded metadata is added.
*/
protected function loadMetadata($name)
{
if ( ! $this->initialized) {
$this->initialize();
// Invoke driver
try {
$this->driver->loadMetadataForClass($class->getName(), $class);
} catch (ReflectionException $e) {
throw MappingException::reflectionFailure($class->getName(), $e);
}
$loaded = array();
$parentClasses = $this->getParentClasses($name);
$parentClasses[] = $name;
// Move down the hierarchy of parent classes, starting from the topmost class
$parent = null;
$visited = array();
foreach ($parentClasses as $className) {
if (isset($this->loadedMetadata[$className])) {
$parent = $this->loadedMetadata[$className];
if ( ! $parent->isMappedSuperclass) {
array_unshift($visited, $className);
}
continue;
// If this class has a parent the id generator strategy is inherited.
// However this is only true if the hierarchy of parents contains the root entity,
// if it consists of mapped superclasses these don't necessarily include the id field.
if ($parent && $rootEntityFound) {
if ($parent->isIdGeneratorSequence()) {
$class->setSequenceGeneratorDefinition($parent->sequenceGeneratorDefinition);
} else if ($parent->isIdGeneratorTable()) {
$class->tableGeneratorDefinition = $parent->tableGeneratorDefinition;
}
$class = $this->newClassMetadataInstance($className);
if ($parent) {
if (!$parent->isMappedSuperclass) {
$class->setInheritanceType($parent->inheritanceType);
$class->setDiscriminatorColumn($parent->discriminatorColumn);
}
if ($parent->generatorType) {
$class->setIdGeneratorType($parent->generatorType);
$this->addInheritedFields($class, $parent);
$this->addInheritedRelations($class, $parent);
$class->setIdentifier($parent->identifier);
$class->setVersioned($parent->isVersioned);
$class->setVersionField($parent->versionField);
if (!$parent->isMappedSuperclass) {
$class->setDiscriminatorMap($parent->discriminatorMap);
}
$class->setLifecycleCallbacks($parent->lifecycleCallbacks);
$class->setChangeTrackingPolicy($parent->changeTrackingPolicy);
}
// Invoke driver
try {
$this->driver->loadMetadataForClass($className, $class);
} catch (ReflectionException $e) {
throw MappingException::reflectionFailure($className, $e);
if ($parent->idGenerator) {
$class->setIdGenerator($parent->idGenerator);
}
} else {
$this->completeIdGeneratorMapping($class);
}
// Verify & complete identifier mapping
if ( ! $class->identifier && ! $class->isMappedSuperclass) {
throw MappingException::identifierRequired($className);
}
if ($parent && ! $parent->isMappedSuperclass) {
if ($parent->isIdGeneratorSequence()) {
$class->setSequenceGeneratorDefinition($parent->sequenceGeneratorDefinition);
} else if ($parent->isIdGeneratorTable()) {
$class->getTableGeneratorDefinition($parent->tableGeneratorDefinition);
}
if ($parent->generatorType) {
$class->setIdGeneratorType($parent->generatorType);
}
if ($parent->idGenerator) {
$class->setIdGenerator($parent->idGenerator);
}
} else {
$this->completeIdGeneratorMapping($class);
}
if ($parent && $parent->isInheritanceTypeSingleTable()) {
$class->setPrimaryTable($parent->table);
}
if ($parent && $parent->isInheritanceTypeSingleTable()) {
$class->setPrimaryTable($parent->table);
}
if ($parent && $parent->containsForeignIdentifier) {
$class->containsForeignIdentifier = true;
}
$class->setParentClasses($visited);
if ($parent && !empty($parent->namedQueries)) {
$this->addInheritedNamedQueries($class, $parent);
}
if ($this->evm->hasListeners(Events::loadClassMetadata)) {
$eventArgs = new \Doctrine\ORM\Event\LoadClassMetadataEventArgs($class, $this->em);
$this->evm->dispatchEvent(Events::loadClassMetadata, $eventArgs);
}
if ($parent && !empty($parent->namedNativeQueries)) {
$this->addInheritedNamedNativeQueries($class, $parent);
}
// verify inheritance
if (!$parent && !$class->isMappedSuperclass && !$class->isInheritanceTypeNone()) {
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 $parent
* @throws MappingException
*/
protected function validateRuntimeMetadata($class, $parent)
{
if ( ! $class->reflClass ) {
// only validate if there is a reflection class instance
return;
}
$class->validateIdentifier();
$class->validateAssocations();
$class->validateLifecycleCallbacks($this->getReflectionService());
// verify inheritance
if ( ! $class->isMappedSuperclass && !$class->isInheritanceTypeNone()) {
if ( ! $parent) {
if (count($class->discriminatorMap) == 0) {
throw MappingException::missingDiscriminatorMap($class->name);
}
if (!$class->discriminatorColumn) {
if ( ! $class->discriminatorColumn) {
throw MappingException::missingDiscriminatorColumn($class->name);
}
} else if ($parent && !$class->reflClass->isAbstract() && !in_array($class->name, array_values($class->discriminatorMap))) {
// enforce discriminator map for all entities of an inheritance hierarchy, otherwise problems will occur.
throw MappingException::mappedClassNotPartOfDiscriminatorMap($class->name, $class->rootEntityName);
}
$this->loadedMetadata[$className] = $class;
$parent = $class;
if ( ! $class->isMappedSuperclass) {
array_unshift($visited, $className);
}
$loaded[] = $className;
} else if ($class->isMappedSuperclass && $class->name == $class->rootEntityName && (count($class->discriminatorMap) || $class->discriminatorColumn)) {
// second condition is necessary for mapped superclasses in the middle of an inheritance hierarchy
throw MappingException::noInheritanceOnMappedSuperClass($class->name);
}
return $loaded;
}
/**
* Creates a new ClassMetadata instance for the given class name.
*
* @param string $className
* @return Doctrine\ORM\Mapping\ClassMetadata
* {@inheritDoc}
*/
protected function newClassMetadataInstance($className)
{
return new ClassMetadata($className);
return new ClassMetadata($className, $this->em->getConfiguration()->getNamingStrategy());
}
/**
* Adds a default discriminator map if no one is given
*
* If an entity is of any inheritance type and does not contain a
* discriminator map, then the map is generated automatically. This process
* is expensive computation wise.
*
* The automatically generated discriminator map contains the lowercase short name of
* each class as key.
*
* @param \Doctrine\ORM\Mapping\ClassMetadata $class
* @throws MappingException
*/
private function addDefaultDiscriminatorMap(ClassMetadata $class)
{
$allClasses = $this->driver->getAllClassNames();
$fqcn = $class->getName();
$map = array($this->getShortName($class->name) => $fqcn);
$duplicates = array();
foreach ($allClasses as $subClassCandidate) {
if (is_subclass_of($subClassCandidate, $fqcn)) {
$shortName = $this->getShortName($subClassCandidate);
if (isset($map[$shortName])) {
$duplicates[] = $shortName;
}
$map[$shortName] = $subClassCandidate;
}
}
if ($duplicates) {
throw MappingException::duplicateDiscriminatorEntry($class->name, $duplicates, $map);
}
$class->setDiscriminatorMap($map);
}
/**
* Get the lower-case short name of a class.
*
* @param string $className
* @return string
*/
private function getShortName($className)
{
if (strpos($className, "\\") === false) {
return strtolower($className);
}
$parts = explode("\\", $className);
return strtolower(end($parts));
}
/**
* Adds inherited fields to the subclass mapping.
*
* @param Doctrine\ORM\Mapping\ClassMetadata $subClass
* @param Doctrine\ORM\Mapping\ClassMetadata $parentClass
* @param \Doctrine\ORM\Mapping\ClassMetadata $subClass
* @param \Doctrine\ORM\Mapping\ClassMetadata $parentClass
*/
private function addInheritedFields(ClassMetadata $subClass, ClassMetadata $parentClass)
{
foreach ($parentClass->fieldMappings as $fieldName => $mapping) {
foreach ($parentClass->fieldMappings as $mapping) {
if ( ! isset($mapping['inherited']) && ! $parentClass->isMappedSuperclass) {
$mapping['inherited'] = $parentClass->name;
}
@@ -375,13 +295,17 @@ class ClassMetadataFactory
/**
* Adds inherited association mappings to the subclass mapping.
*
* @param Doctrine\ORM\Mapping\ClassMetadata $subClass
* @param Doctrine\ORM\Mapping\ClassMetadata $parentClass
* @param \Doctrine\ORM\Mapping\ClassMetadata $subClass
* @param \Doctrine\ORM\Mapping\ClassMetadata $parentClass
* @throws MappingException
*/
private function addInheritedRelations(ClassMetadata $subClass, ClassMetadata $parentClass)
{
foreach ($parentClass->associationMappings as $field => $mapping) {
if ($parentClass->isMappedSuperclass) {
if ($mapping['type'] & ClassMetadata::TO_MANY && !$mapping['isOwningSide']) {
throw MappingException::illegalToManyAssocationOnMappedSuperclass($parentClass->name, $field);
}
$mapping['sourceEntity'] = $subClass->name;
}
@@ -396,11 +320,83 @@ class ClassMetadataFactory
}
}
/**
* Adds inherited named queries to the subclass mapping.
*
* @since 2.2
* @param \Doctrine\ORM\Mapping\ClassMetadata $subClass
* @param \Doctrine\ORM\Mapping\ClassMetadata $parentClass
*/
private function addInheritedNamedQueries(ClassMetadata $subClass, ClassMetadata $parentClass)
{
foreach ($parentClass->namedQueries as $name => $query) {
if ( ! isset ($subClass->namedQueries[$name])) {
$subClass->addNamedQuery(array(
'name' => $query['name'],
'query' => $query['query']
));
}
}
}
/**
* Adds inherited named native queries to the subclass mapping.
*
* @since 2.3
* @param \Doctrine\ORM\Mapping\ClassMetadata $subClass
* @param \Doctrine\ORM\Mapping\ClassMetadata $parentClass
*/
private function addInheritedNamedNativeQueries(ClassMetadata $subClass, ClassMetadata $parentClass)
{
foreach ($parentClass->namedNativeQueries as $name => $query) {
if ( ! isset ($subClass->namedNativeQueries[$name])) {
$subClass->addNamedNativeQuery(array(
'name' => $query['name'],
'query' => $query['query'],
'isSelfClass' => $query['isSelfClass'],
'resultSetMapping' => $query['resultSetMapping'],
'resultClass' => $query['isSelfClass'] ? $subClass->name : $query['resultClass'],
));
}
}
}
/**
* Adds inherited sql result set mappings to the subclass mapping.
*
* @since 2.3
* @param \Doctrine\ORM\Mapping\ClassMetadata $subClass
* @param \Doctrine\ORM\Mapping\ClassMetadata $parentClass
*/
private function addInheritedSqlResultSetMappings(ClassMetadata $subClass, ClassMetadata $parentClass)
{
foreach ($parentClass->sqlResultSetMappings as $name => $mapping) {
if ( ! isset ($subClass->sqlResultSetMappings[$name])) {
$entities = array();
foreach ($mapping['entities'] as $entity) {
$entities[] = array(
'fields' => $entity['fields'],
'isSelfClass' => $entity['isSelfClass'],
'discriminatorColumn' => $entity['discriminatorColumn'],
'entityClass' => $entity['isSelfClass'] ? $subClass->name : $entity['entityClass'],
);
}
$subClass->addSqlResultSetMapping(array(
'name' => $mapping['name'],
'columns' => $mapping['columns'],
'entities' => $entities,
));
}
}
}
/**
* Completes the ID generator mapping. If "auto" is specified we choose the generator
* most appropriate for the targeted database platform.
*
* @param Doctrine\ORM\Mapping\ClassMetadata $class
* @param ClassMetadataInfo $class
* @throws ORMException
*/
private function completeIdGeneratorMapping(ClassMetadataInfo $class)
{
@@ -421,35 +417,121 @@ class ClassMetadataFactory
// For PostgreSQL IDENTITY (SERIAL) we need a sequence name. It defaults to
// <table>_<column>_seq in PostgreSQL for SERIAL columns.
// Not pretty but necessary and the simplest solution that currently works.
$seqName = $this->targetPlatform instanceof Platforms\PostgreSQLPlatform ?
$class->table['name'] . '_' . $class->columnNames[$class->identifier[0]] . '_seq' :
null;
$class->setIdGenerator(new \Doctrine\ORM\Id\IdentityGenerator($seqName));
$sequenceName = null;
if ($this->targetPlatform instanceof Platforms\PostgreSQLPlatform) {
$fieldName = $class->getSingleIdentifierFieldName();
$columnName = $class->getSingleIdentifierColumnName();
$quoted = isset($class->fieldMappings[$fieldName]['quoted']) || isset($class->table['quoted']);
$sequenceName = $class->getTableName() . '_' . $columnName . '_seq';
$definition = array(
'sequenceName' => $this->targetPlatform->fixSchemaElementName($sequenceName)
);
if ($quoted) {
$definition['quoted'] = true;
}
$sequenceName = $this->em->getConfiguration()->getQuoteStrategy()->getSequenceName($definition, $class, $this->targetPlatform);
}
$class->setIdGenerator(new \Doctrine\ORM\Id\IdentityGenerator($sequenceName));
break;
case ClassMetadata::GENERATOR_TYPE_SEQUENCE:
// If there is no sequence definition yet, create a default definition
$definition = $class->sequenceGeneratorDefinition;
if ( ! $definition) {
$sequenceName = $class->getTableName() . '_' . $class->getSingleIdentifierColumnName() . '_seq';
$definition['sequenceName'] = $this->targetPlatform->fixSchemaElementName($sequenceName);
$definition['allocationSize'] = 1;
$definition['initialValue'] = 1;
$fieldName = $class->getSingleIdentifierFieldName();
$columnName = $class->getSingleIdentifierColumnName();
$quoted = isset($class->fieldMappings[$fieldName]['quoted']) || isset($class->table['quoted']);
$sequenceName = $class->getTableName() . '_' . $columnName . '_seq';
$definition = array(
'sequenceName' => $this->targetPlatform->fixSchemaElementName($sequenceName),
'allocationSize' => 1,
'initialValue' => 1,
);
if ($quoted) {
$definition['quoted'] = true;
}
$class->setSequenceGeneratorDefinition($definition);
}
$sequenceGenerator = new \Doctrine\ORM\Id\SequenceGenerator(
$definition['sequenceName'],
$this->em->getConfiguration()->getQuoteStrategy()->getSequenceName($definition, $class, $this->targetPlatform),
$definition['allocationSize']
);
$class->setIdGenerator($sequenceGenerator);
break;
case ClassMetadata::GENERATOR_TYPE_NONE:
$class->setIdGenerator(new \Doctrine\ORM\Id\AssignedGenerator());
break;
case ClassMetadata::GENERATOR_TYPE_UUID:
$class->setIdGenerator(new \Doctrine\ORM\Id\UuidGenerator());
break;
case ClassMetadata::GENERATOR_TYPE_TABLE:
throw new ORMException("TableGenerator not yet implemented.");
break;
case ClassMetadata::GENERATOR_TYPE_CUSTOM:
$definition = $class->customGeneratorDefinition;
if ( ! class_exists($definition['class'])) {
throw new ORMException("Can't instantiate custom generator : " .
$definition['class']);
}
$class->setIdGenerator(new $definition['class']);
break;
default:
throw new ORMException("Unknown generator type: " . $class->generatorType);
}
}
/**
* {@inheritDoc}
*/
protected function wakeupReflection(ClassMetadataInterface $class, ReflectionService $reflService)
{
/* @var $class ClassMetadata */
$class->wakeupReflection($reflService);
}
/**
* {@inheritDoc}
*/
protected function initializeReflection(ClassMetadataInterface $class, ReflectionService $reflService)
{
/* @var $class ClassMetadata */
$class->initializeReflection($reflService);
}
/**
* {@inheritDoc}
*/
protected function getFqcnFromAlias($namespaceAlias, $simpleClassName)
{
return $this->em->getConfiguration()->getEntityNamespace($namespaceAlias) . '\\' . $simpleClassName;
}
/**
* {@inheritDoc}
*/
protected function getDriver()
{
return $this->driver;
}
/**
* {@inheritDoc}
*/
protected function isEntity(ClassMetadataInterface $class)
{
return isset($class->isMappedSuperclass) && $class->isMappedSuperclass === false;
}
}
File diff suppressed because it is too large Load Diff
+46
View File
@@ -0,0 +1,46 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping;
/**
* @Annotation
* @Target({"PROPERTY","ANNOTATION"})
*/
final class Column implements Annotation
{
/** @var string */
public $name;
/** @var mixed */
public $type = 'string';
/** @var integer */
public $length;
/** @var integer */
public $precision = 0; // The precision for a decimal (exact numeric) column (Applies only for decimal column)
/** @var integer */
public $scale = 0; // The scale for a decimal (exact numeric) column (Applies only for decimal column)
/** @var boolean */
public $unique = false;
/** @var boolean */
public $nullable = false;
/** @var array */
public $options = array();
/** @var string */
public $columnDefinition;
}
+42
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;
}
@@ -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;
}
@@ -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()));
}
}
@@ -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);
}
}
@@ -0,0 +1,38 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping;
/**
* @Annotation
* @Target("CLASS")
*/
final class DiscriminatorColumn implements Annotation
{
/** @var string */
public $name;
/** @var string */
public $type;
/** @var integer */
public $length;
/** @var mixed */
public $fieldName; // field name used in non-object hydration (array/scalar)
/** @var string */
public $columnDefinition;
}
@@ -0,0 +1,30 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping;
/**
* @Annotation
* @Target("CLASS")
*/
final class DiscriminatorMap implements Annotation
{
/** @var array<string> */
public $value;
}
@@ -1,210 +0,0 @@
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping\Driver;
use Doctrine\ORM\Mapping\MappingException;
/**
* Base driver for file-based metadata drivers.
*
* A file driver operates in a mode where it loads the mapping files of individual
* classes on demand. This requires the user to adhere to the convention of 1 mapping
* file per class and the file names of the mapping files must correspond to the full
* class name, including namespace, with the namespace delimiters '\', replaced by dots '.'.
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.com
* @since 2.0
* @version $Revision$
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan H. Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
abstract class AbstractFileDriver implements Driver
{
/**
* The paths where to look for mapping files.
*
* @var array
*/
protected $_paths = array();
/**
* The file extension of mapping documents.
*
* @var string
*/
protected $_fileExtension;
/**
* Initializes a new FileDriver that looks in the given path(s) for mapping
* documents and operates in the specified operating mode.
*
* @param string|array $paths One or multiple paths where mapping documents can be found.
*/
public function __construct($paths)
{
$this->addPaths((array) $paths);
}
/**
* Append lookup paths to metadata driver.
*
* @param array $paths
*/
public function addPaths(array $paths)
{
$this->_paths = array_unique(array_merge($this->_paths, $paths));
}
/**
* Retrieve the defined metadata lookup paths.
*
* @return array
*/
public function getPaths()
{
return $this->_paths;
}
/**
* Get the file extension used to look for mapping files under
*
* @return void
*/
public function getFileExtension()
{
return $this->_fileExtension;
}
/**
* Set the file extension used to look for mapping files under
*
* @param string $fileExtension The file extension to set
* @return void
*/
public function setFileExtension($fileExtension)
{
$this->_fileExtension = $fileExtension;
}
/**
* Get the element of schema meta data for the class from the mapping file.
* This will lazily load the mapping file if it is not loaded yet
*
* @return array $element The element of schema meta data
*/
public function getElement($className)
{
$result = $this->_loadMappingFile($this->_findMappingFile($className));
return $result[$className];
}
/**
* Whether the class with the specified name should have its metadata loaded.
* This is only the case if it is either mapped as an Entity or a
* MappedSuperclass.
*
* @param string $className
* @return boolean
*/
public function isTransient($className)
{
$fileName = str_replace('\\', '.', $className) . $this->_fileExtension;
// Check whether file exists
foreach ((array) $this->_paths as $path) {
if (file_exists($path . DIRECTORY_SEPARATOR . $fileName)) {
return false;
}
}
return true;
}
/**
* Gets the names of all mapped classes known to this driver.
*
* @return array The names of all mapped classes known to this driver.
*/
public function getAllClassNames()
{
$classes = array();
if ($this->_paths) {
foreach ((array) $this->_paths as $path) {
if ( ! is_dir($path)) {
throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path);
}
$iterator = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($path),
\RecursiveIteratorIterator::LEAVES_ONLY
);
foreach ($iterator as $file) {
if (($fileName = $file->getBasename($this->_fileExtension)) == $file->getBasename()) {
continue;
}
// NOTE: All files found here means classes are not transient!
$classes[] = str_replace('.', '\\', $fileName);
}
}
}
return $classes;
}
/**
* Finds the mapping file for the class with the given name by searching
* through the configured paths.
*
* @param $className
* @return string The (absolute) file name.
* @throws MappingException
*/
protected function _findMappingFile($className)
{
$fileName = str_replace('\\', '.', $className) . $this->_fileExtension;
// Check whether file exists
foreach ((array) $this->_paths as $path) {
if (file_exists($path . DIRECTORY_SEPARATOR . $fileName)) {
return $path . DIRECTORY_SEPARATOR . $fileName;
}
}
throw MappingException::mappingFileNotFound($className, $fileName);
}
/**
* Loads a mapping file with the given name and returns a map
* from class/entity names to their corresponding elements.
*
* @param string $file The mapping file to load.
* @return array
*/
abstract protected function _loadMappingFile($file);
}
@@ -13,18 +13,18 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping\Driver;
use Doctrine\Common\Cache\ArrayCache,
Doctrine\Common\Annotations\AnnotationReader,
Doctrine\ORM\Mapping\ClassMetadataInfo,
Doctrine\ORM\Mapping\MappingException;
require __DIR__ . '/DoctrineAnnotations.php';
use Doctrine\Common\Annotations\AnnotationReader,
Doctrine\ORM\Mapping\MappingException,
Doctrine\ORM\Mapping\JoinColumn,
Doctrine\ORM\Mapping\Column,
Doctrine\Common\Persistence\Mapping\ClassMetadata,
Doctrine\Common\Persistence\Mapping\Driver\AnnotationDriver as AbstractAnnotationDriver;
/**
* The AnnotationDriver reads the mapping metadata from docblock annotations.
@@ -35,104 +35,53 @@ require __DIR__ . '/DoctrineAnnotations.php';
* @author Jonathan H. Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class AnnotationDriver implements Driver
class AnnotationDriver extends AbstractAnnotationDriver
{
/**
* The AnnotationReader.
*
* @var AnnotationReader
* {@inheritDoc}
*/
private $_reader;
protected $entityAnnotationClasses = array(
'Doctrine\ORM\Mapping\Entity' => 1,
'Doctrine\ORM\Mapping\MappedSuperclass' => 2,
);
/**
* The paths where to look for mapping files.
*
* @var array
* {@inheritDoc}
*/
protected $_paths = array();
/**
* The file extension of mapping documents.
*
* @var string
*/
protected $_fileExtension = '.php';
/**
* @param array
*/
protected $_classNames;
/**
* Initializes a new AnnotationDriver that uses the given AnnotationReader for reading
* docblock annotations.
*
* @param $reader The AnnotationReader to use.
* @param string|array $paths One or multiple paths where mapping classes can be found.
*/
public function __construct(AnnotationReader $reader, $paths = null)
{
$this->_reader = $reader;
if ($paths) {
$this->addPaths((array) $paths);
}
}
/**
* Append lookup paths to metadata driver.
*
* @param array $paths
*/
public function addPaths(array $paths)
{
$this->_paths = array_unique(array_merge($this->_paths, $paths));
}
/**
* Retrieve the defined metadata lookup paths.
*
* @return array
*/
public function getPaths()
{
return $this->_paths;
}
/**
* Get the file extension used to look for mapping files under
*
* @return void
*/
public function getFileExtension()
{
return $this->_fileExtension;
}
/**
* Set the file extension used to look for mapping files under
*
* @param string $fileExtension The file extension to set
* @return void
*/
public function setFileExtension($fileExtension)
{
$this->_fileExtension = $fileExtension;
}
/**
* {@inheritdoc}
*/
public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
public function loadMetadataForClass($className, ClassMetadata $metadata)
{
/* @var $metadata \Doctrine\ORM\Mapping\ClassMetadataInfo */
$class = $metadata->getReflectionClass();
if ( ! $class) {
// this happens when running annotation driver in combination with
// static reflection services. This is not the nicest fix
$class = new \ReflectionClass($metadata->name);
}
$classAnnotations = $this->_reader->getClassAnnotations($class);
$classAnnotations = $this->reader->getClassAnnotations($class);
if ($classAnnotations) {
foreach ($classAnnotations as $key => $annot) {
if ( ! is_numeric($key)) {
continue;
}
$classAnnotations[get_class($annot)] = $annot;
}
}
// Evaluate Entity annotation
if (isset($classAnnotations['Doctrine\ORM\Mapping\Entity'])) {
$entityAnnot = $classAnnotations['Doctrine\ORM\Mapping\Entity'];
$metadata->setCustomRepositoryClass($entityAnnot->repositoryClass);
if ($entityAnnot->repositoryClass !== null) {
$metadata->setCustomRepositoryClass($entityAnnot->repositoryClass);
}
if ($entityAnnot->readOnly) {
$metadata->markReadOnly();
}
} else if (isset($classAnnotations['Doctrine\ORM\Mapping\MappedSuperclass'])) {
$mappedSuperclassAnnot = $classAnnotations['Doctrine\ORM\Mapping\MappedSuperclass'];
$metadata->setCustomRepositoryClass($mappedSuperclassAnnot->repositoryClass);
$metadata->isMappedSuperclass = true;
} else {
throw MappingException::classIsNotAValidEntityOrMappedSuperClass($className);
@@ -148,23 +97,143 @@ class AnnotationDriver implements Driver
if ($tableAnnot->indexes !== null) {
foreach ($tableAnnot->indexes as $indexAnnot) {
$primaryTable['indexes'][$indexAnnot->name] = array(
'columns' => $indexAnnot->columns
);
$index = array('columns' => $indexAnnot->columns);
if ( ! empty($indexAnnot->name)) {
$primaryTable['indexes'][$indexAnnot->name] = $index;
} else {
$primaryTable['indexes'][] = $index;
}
}
}
if ($tableAnnot->uniqueConstraints !== null) {
foreach ($tableAnnot->uniqueConstraints as $uniqueConstraint) {
$primaryTable['uniqueConstraints'][$uniqueConstraint->name] = array(
'columns' => $uniqueConstraint->columns
);
foreach ($tableAnnot->uniqueConstraints as $uniqueConstraintAnnot) {
$uniqueConstraint = array('columns' => $uniqueConstraintAnnot->columns);
if ( ! empty($uniqueConstraintAnnot->name)) {
$primaryTable['uniqueConstraints'][$uniqueConstraintAnnot->name] = $uniqueConstraint;
} else {
$primaryTable['uniqueConstraints'][] = $uniqueConstraint;
}
}
}
if ($tableAnnot->options !== null) {
$primaryTable['options'] = $tableAnnot->options;
}
$metadata->setPrimaryTable($primaryTable);
}
// Evaluate NamedNativeQueries annotation
if (isset($classAnnotations['Doctrine\ORM\Mapping\NamedNativeQueries'])) {
$namedNativeQueriesAnnot = $classAnnotations['Doctrine\ORM\Mapping\NamedNativeQueries'];
foreach ($namedNativeQueriesAnnot->value as $namedNativeQuery) {
$metadata->addNamedNativeQuery(array(
'name' => $namedNativeQuery->name,
'query' => $namedNativeQuery->query,
'resultClass' => $namedNativeQuery->resultClass,
'resultSetMapping' => $namedNativeQuery->resultSetMapping,
));
}
}
// Evaluate SqlResultSetMappings annotation
if (isset($classAnnotations['Doctrine\ORM\Mapping\SqlResultSetMappings'])) {
$sqlResultSetMappingsAnnot = $classAnnotations['Doctrine\ORM\Mapping\SqlResultSetMappings'];
foreach ($sqlResultSetMappingsAnnot->value as $resultSetMapping) {
$entities = array();
$columns = array();
foreach ($resultSetMapping->entities as $entityResultAnnot) {
$entityResult = array(
'fields' => array(),
'entityClass' => $entityResultAnnot->entityClass,
'discriminatorColumn' => $entityResultAnnot->discriminatorColumn,
);
foreach ($entityResultAnnot->fields as $fieldResultAnnot) {
$entityResult['fields'][] = array(
'name' => $fieldResultAnnot->name,
'column' => $fieldResultAnnot->column
);
}
$entities[] = $entityResult;
}
foreach ($resultSetMapping->columns as $columnResultAnnot) {
$columns[] = array(
'name' => $columnResultAnnot->name,
);
}
$metadata->addSqlResultSetMapping(array(
'name' => $resultSetMapping->name,
'entities' => $entities,
'columns' => $columns
));
}
}
// Evaluate NamedQueries annotation
if (isset($classAnnotations['Doctrine\ORM\Mapping\NamedQueries'])) {
$namedQueriesAnnot = $classAnnotations['Doctrine\ORM\Mapping\NamedQueries'];
if ( ! is_array($namedQueriesAnnot->value)) {
throw new \UnexpectedValueException("@NamedQueries should contain an array of @NamedQuery annotations.");
}
foreach ($namedQueriesAnnot->value as $namedQuery) {
if ( ! ($namedQuery instanceof \Doctrine\ORM\Mapping\NamedQuery)) {
throw new \UnexpectedValueException("@NamedQueries should contain an array of @NamedQuery annotations.");
}
$metadata->addNamedQuery(array(
'name' => $namedQuery->name,
'query' => $namedQuery->query
));
}
}
$associationOverrides = array();
// Evaluate AssociationOverrides annotation
if (isset($classAnnotations['Doctrine\ORM\Mapping\AssociationOverrides'])) {
$associationOverridesAnnot = $classAnnotations['Doctrine\ORM\Mapping\AssociationOverrides'];
foreach ($associationOverridesAnnot->value as $associationOverride) {
// Check for JoinColummn/JoinColumns annotations
if ($associationOverride->joinColumns) {
$joinColumns = array();
foreach ($associationOverride->joinColumns as $joinColumn) {
$joinColumns[] = $this->joinColumnToArray($joinColumn);
}
$associationOverrides[$associationOverride->name]['joinColumns'] = $joinColumns;
}
// Check for JoinTable annotations
if ($associationOverride->joinTable) {
$joinTable = null;
$joinTableAnnot = $associationOverride->joinTable;
$joinTable = array(
'name' => $joinTableAnnot->name,
'schema' => $joinTableAnnot->schema
);
foreach ($joinTableAnnot->joinColumns as $joinColumn) {
$joinTable['joinColumns'][] = $this->joinColumnToArray($joinColumn);
}
foreach ($joinTableAnnot->inverseJoinColumns as $joinColumn) {
$joinTable['inverseJoinColumns'][] = $this->joinColumnToArray($joinColumn);
}
$associationOverrides[$associationOverride->name]['joinTable'] = $joinTable;
}
}
}
// Evaluate InheritanceType annotation
if (isset($classAnnotations['Doctrine\ORM\Mapping\InheritanceType'])) {
$inheritanceTypeAnnot = $classAnnotations['Doctrine\ORM\Mapping\InheritanceType'];
@@ -177,7 +246,8 @@ class AnnotationDriver implements Driver
$metadata->setDiscriminatorColumn(array(
'name' => $discrColumnAnnot->name,
'type' => $discrColumnAnnot->type,
'length' => $discrColumnAnnot->length
'length' => $discrColumnAnnot->length,
'columnDefinition' => $discrColumnAnnot->columnDefinition
));
} else {
$metadata->setDiscriminatorColumn(array('name' => 'dtype', 'type' => 'string', 'length' => 255));
@@ -199,6 +269,7 @@ class AnnotationDriver implements Driver
}
// Evaluate annotations on properties/fields
/* @var $property \ReflectionProperty */
foreach ($class->getProperties() as $property) {
if ($metadata->isMappedSuperclass && ! $property->isPrivate()
||
@@ -214,138 +285,103 @@ class AnnotationDriver implements Driver
// Check for JoinColummn/JoinColumns annotations
$joinColumns = array();
if ($joinColumnAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\JoinColumn')) {
$joinColumns[] = array(
'name' => $joinColumnAnnot->name,
'referencedColumnName' => $joinColumnAnnot->referencedColumnName,
'unique' => $joinColumnAnnot->unique,
'nullable' => $joinColumnAnnot->nullable,
'onDelete' => $joinColumnAnnot->onDelete,
'onUpdate' => $joinColumnAnnot->onUpdate,
'columnDefinition' => $joinColumnAnnot->columnDefinition,
);
} else if ($joinColumnsAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\JoinColumns')) {
if ($joinColumnAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\JoinColumn')) {
$joinColumns[] = $this->joinColumnToArray($joinColumnAnnot);
} else if ($joinColumnsAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\JoinColumns')) {
foreach ($joinColumnsAnnot->value as $joinColumn) {
$joinColumns[] = array(
'name' => $joinColumn->name,
'referencedColumnName' => $joinColumn->referencedColumnName,
'unique' => $joinColumn->unique,
'nullable' => $joinColumn->nullable,
'onDelete' => $joinColumn->onDelete,
'onUpdate' => $joinColumn->onUpdate,
'columnDefinition' => $joinColumn->columnDefinition,
);
$joinColumns[] = $this->joinColumnToArray($joinColumn);
}
}
// Field can only be annotated with one of:
// @Column, @OneToOne, @OneToMany, @ManyToOne, @ManyToMany
if ($columnAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Column')) {
if ($columnAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Column')) {
if ($columnAnnot->type == null) {
throw MappingException::propertyTypeIsRequired($className, $property->getName());
}
$mapping['type'] = $columnAnnot->type;
$mapping['length'] = $columnAnnot->length;
$mapping['precision'] = $columnAnnot->precision;
$mapping['scale'] = $columnAnnot->scale;
$mapping['nullable'] = $columnAnnot->nullable;
$mapping['unique'] = $columnAnnot->unique;
if ($columnAnnot->options) {
$mapping['options'] = $columnAnnot->options;
}
$mapping = $this->columnToArray($property->getName(), $columnAnnot);
if (isset($columnAnnot->name)) {
$mapping['columnName'] = $columnAnnot->name;
}
if (isset($columnAnnot->columnDefinition)) {
$mapping['columnDefinition'] = $columnAnnot->columnDefinition;
}
if ($idAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Id')) {
if ($idAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Id')) {
$mapping['id'] = true;
}
if ($generatedValueAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\GeneratedValue')) {
if ($generatedValueAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\GeneratedValue')) {
$metadata->setIdGeneratorType(constant('Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_' . $generatedValueAnnot->strategy));
}
if ($versionAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Version')) {
if ($this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Version')) {
$metadata->setVersionMapping($mapping);
}
$metadata->mapField($mapping);
// Check for SequenceGenerator/TableGenerator definition
if ($seqGeneratorAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\SequenceGenerator')) {
if ($seqGeneratorAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\SequenceGenerator')) {
$metadata->setSequenceGeneratorDefinition(array(
'sequenceName' => $seqGeneratorAnnot->sequenceName,
'allocationSize' => $seqGeneratorAnnot->allocationSize,
'initialValue' => $seqGeneratorAnnot->initialValue
));
} else if ($tblGeneratorAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\TableGenerator')) {
} else if ($this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\TableGenerator')) {
throw MappingException::tableIdGeneratorNotImplemented($className);
} else if ($customGeneratorAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\CustomIdGenerator')) {
$metadata->setCustomGeneratorDefinition(array(
'class' => $customGeneratorAnnot->class
));
}
} else if ($oneToOneAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\OneToOne')) {
} else if ($oneToOneAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\OneToOne')) {
if ($idAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Id')) {
$mapping['id'] = true;
}
$mapping['targetEntity'] = $oneToOneAnnot->targetEntity;
$mapping['joinColumns'] = $joinColumns;
$mapping['mappedBy'] = $oneToOneAnnot->mappedBy;
$mapping['inversedBy'] = $oneToOneAnnot->inversedBy;
$mapping['cascade'] = $oneToOneAnnot->cascade;
$mapping['orphanRemoval'] = $oneToOneAnnot->orphanRemoval;
$mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $oneToOneAnnot->fetch);
$mapping['fetch'] = $this->getFetchMode($className, $oneToOneAnnot->fetch);
$metadata->mapOneToOne($mapping);
} else if ($oneToManyAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\OneToMany')) {
} else if ($oneToManyAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\OneToMany')) {
$mapping['mappedBy'] = $oneToManyAnnot->mappedBy;
$mapping['targetEntity'] = $oneToManyAnnot->targetEntity;
$mapping['cascade'] = $oneToManyAnnot->cascade;
$mapping['indexBy'] = $oneToManyAnnot->indexBy;
$mapping['orphanRemoval'] = $oneToManyAnnot->orphanRemoval;
$mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $oneToManyAnnot->fetch);
$mapping['fetch'] = $this->getFetchMode($className, $oneToManyAnnot->fetch);
if ($orderByAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\OrderBy')) {
if ($orderByAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\OrderBy')) {
$mapping['orderBy'] = $orderByAnnot->value;
}
$metadata->mapOneToMany($mapping);
} else if ($manyToOneAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\ManyToOne')) {
} else if ($manyToOneAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\ManyToOne')) {
if ($idAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Id')) {
$mapping['id'] = true;
}
$mapping['joinColumns'] = $joinColumns;
$mapping['cascade'] = $manyToOneAnnot->cascade;
$mapping['inversedBy'] = $manyToOneAnnot->inversedBy;
$mapping['targetEntity'] = $manyToOneAnnot->targetEntity;
$mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $manyToOneAnnot->fetch);
$mapping['fetch'] = $this->getFetchMode($className, $manyToOneAnnot->fetch);
$metadata->mapManyToOne($mapping);
} else if ($manyToManyAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\ManyToMany')) {
} else if ($manyToManyAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\ManyToMany')) {
$joinTable = array();
if ($joinTableAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\JoinTable')) {
if ($joinTableAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\JoinTable')) {
$joinTable = array(
'name' => $joinTableAnnot->name,
'schema' => $joinTableAnnot->schema
);
foreach ($joinTableAnnot->joinColumns as $joinColumn) {
$joinTable['joinColumns'][] = array(
'name' => $joinColumn->name,
'referencedColumnName' => $joinColumn->referencedColumnName,
'unique' => $joinColumn->unique,
'nullable' => $joinColumn->nullable,
'onDelete' => $joinColumn->onDelete,
'onUpdate' => $joinColumn->onUpdate,
'columnDefinition' => $joinColumn->columnDefinition,
);
$joinTable['joinColumns'][] = $this->joinColumnToArray($joinColumn);
}
foreach ($joinTableAnnot->inverseJoinColumns as $joinColumn) {
$joinTable['inverseJoinColumns'][] = array(
'name' => $joinColumn->name,
'referencedColumnName' => $joinColumn->referencedColumnName,
'unique' => $joinColumn->unique,
'nullable' => $joinColumn->nullable,
'onDelete' => $joinColumn->onDelete,
'onUpdate' => $joinColumn->onUpdate,
'columnDefinition' => $joinColumn->columnDefinition,
);
$joinTable['inverseJoinColumns'][] = $this->joinColumnToArray($joinColumn);
}
}
@@ -354,9 +390,11 @@ class AnnotationDriver implements Driver
$mapping['mappedBy'] = $manyToManyAnnot->mappedBy;
$mapping['inversedBy'] = $manyToManyAnnot->inversedBy;
$mapping['cascade'] = $manyToManyAnnot->cascade;
$mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $manyToManyAnnot->fetch);
$mapping['indexBy'] = $manyToManyAnnot->indexBy;
$mapping['orphanRemoval'] = $manyToManyAnnot->orphanRemoval;
$mapping['fetch'] = $this->getFetchMode($className, $manyToManyAnnot->fetch);
if ($orderByAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\OrderBy')) {
if ($orderByAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\OrderBy')) {
$mapping['orderBy'] = $orderByAnnot->value;
}
@@ -364,11 +402,72 @@ class AnnotationDriver implements Driver
}
}
// Evaluate AssociationOverrides annotation
if (isset($classAnnotations['Doctrine\ORM\Mapping\AssociationOverrides'])) {
$associationOverridesAnnot = $classAnnotations['Doctrine\ORM\Mapping\AssociationOverrides'];
foreach ($associationOverridesAnnot->value as $associationOverride) {
$override = array();
$fieldName = $associationOverride->name;
// Check for JoinColummn/JoinColumns annotations
if ($associationOverride->joinColumns) {
$joinColumns = array();
foreach ($associationOverride->joinColumns as $joinColumn) {
$joinColumns[] = $this->joinColumnToArray($joinColumn);
}
$override['joinColumns'] = $joinColumns;
}
// Check for JoinTable annotations
if ($associationOverride->joinTable) {
$joinTable = null;
$joinTableAnnot = $associationOverride->joinTable;
$joinTable = array(
'name' => $joinTableAnnot->name,
'schema' => $joinTableAnnot->schema
);
foreach ($joinTableAnnot->joinColumns as $joinColumn) {
$joinTable['joinColumns'][] = $this->joinColumnToArray($joinColumn);
}
foreach ($joinTableAnnot->inverseJoinColumns as $joinColumn) {
$joinTable['inverseJoinColumns'][] = $this->joinColumnToArray($joinColumn);
}
$override['joinTable'] = $joinTable;
}
$metadata->setAssociationOverride($fieldName, $override);
}
}
// Evaluate AttributeOverrides annotation
if (isset($classAnnotations['Doctrine\ORM\Mapping\AttributeOverrides'])) {
$attributeOverridesAnnot = $classAnnotations['Doctrine\ORM\Mapping\AttributeOverrides'];
foreach ($attributeOverridesAnnot->value as $attributeOverrideAnnot) {
$attributeOverride = $this->columnToArray($attributeOverrideAnnot->name, $attributeOverrideAnnot->column);
$metadata->setAttributeOverride($attributeOverrideAnnot->name, $attributeOverride);
}
}
// Evaluate @HasLifecycleCallbacks annotation
if (isset($classAnnotations['Doctrine\ORM\Mapping\HasLifecycleCallbacks'])) {
/* @var $method \ReflectionMethod */
foreach ($class->getMethods() as $method) {
if ($method->isPublic()) {
$annotations = $this->_reader->getMethodAnnotations($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);
if ($annotations) {
foreach ($annotations as $key => $annot) {
if ( ! is_numeric($key)) {
continue;
}
$annotations[get_class($annot)] = $annot;
}
}
if (isset($annotations['Doctrine\ORM\Mapping\PrePersist'])) {
$metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::prePersist);
@@ -397,83 +496,87 @@ class AnnotationDriver implements Driver
if (isset($annotations['Doctrine\ORM\Mapping\PostLoad'])) {
$metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postLoad);
}
if (isset($annotations['Doctrine\ORM\Mapping\PreFlush'])) {
$metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::preFlush);
}
}
}
}
}
/**
* Whether the class with the specified name is transient. Only non-transient
* classes, that is entities and mapped superclasses, should have their metadata loaded.
* A class is non-transient if it is annotated with either @Entity or
* @MappedSuperclass in the class doc block.
* Attempts to resolve the fetch mode.
*
* @param string $className
* @return boolean
* @param string $className The class name
* @param string $fetchMode The fetch mode
* @return integer The fetch mode as defined in ClassMetadata
* @throws MappingException If the fetch mode is not valid
*/
public function isTransient($className)
private function getFetchMode($className, $fetchMode)
{
$classAnnotations = $this->_reader->getClassAnnotations(new \ReflectionClass($className));
if( ! defined('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $fetchMode)) {
throw MappingException::invalidFetchMode($className, $fetchMode);
}
return ! isset($classAnnotations['Doctrine\ORM\Mapping\Entity']) &&
! isset($classAnnotations['Doctrine\ORM\Mapping\MappedSuperclass']);
return constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $fetchMode);
}
/**
* {@inheritDoc}
* Parse the given JoinColumn as array
*
* @param JoinColumn $joinColumn
* @return array
*/
public function getAllClassNames()
private function joinColumnToArray(JoinColumn $joinColumn)
{
if ($this->_classNames !== null) {
return $this->_classNames;
return array(
'name' => $joinColumn->name,
'unique' => $joinColumn->unique,
'nullable' => $joinColumn->nullable,
'onDelete' => $joinColumn->onDelete,
'columnDefinition' => $joinColumn->columnDefinition,
'referencedColumnName' => $joinColumn->referencedColumnName,
);
}
/**
* Parse the given Column as array
*
* @param string $fieldName
* @param Column $column
* @return array
*/
private function columnToArray($fieldName, Column $column)
{
$mapping = array(
'fieldName' => $fieldName,
'type' => $column->type,
'scale' => $column->scale,
'length' => $column->length,
'unique' => $column->unique,
'nullable' => $column->nullable,
'precision' => $column->precision
);
if ($column->options) {
$mapping['options'] = $column->options;
}
if (!$this->_paths) {
throw MappingException::pathRequired();
if (isset($column->name)) {
$mapping['columnName'] = $column->name;
}
$classes = array();
$includedFiles = array();
foreach ($this->_paths as $path) {
if ( ! is_dir($path)) {
throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path);
}
$iterator = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($path),
\RecursiveIteratorIterator::LEAVES_ONLY
);
foreach ($iterator as $file) {
if (($fileName = $file->getBasename($this->_fileExtension)) == $file->getBasename()) {
continue;
}
$sourceFile = realpath($file->getPathName());
require_once $sourceFile;
$includedFiles[] = $sourceFile;
}
if (isset($column->columnDefinition)) {
$mapping['columnDefinition'] = $column->columnDefinition;
}
$declared = get_declared_classes();
foreach ($declared as $className) {
$rc = new \ReflectionClass($className);
$sourceFile = $rc->getFileName();
if (in_array($sourceFile, $includedFiles) && ! $this->isTransient($className)) {
$classes[] = $className;
}
}
$this->_classNames = $classes;
return $classes;
return $mapping;
}
/**
* Factory method for the Annotation Driver
*
*
* @param array|string $paths
* @param AnnotationReader $reader
* @return AnnotationDriver
@@ -482,8 +585,8 @@ class AnnotationDriver implements Driver
{
if ($reader == null) {
$reader = new AnnotationReader();
$reader->setDefaultAnnotationNamespace('Doctrine\ORM\Mapping\\');
}
return new self($reader, $paths);
}
}
@@ -13,30 +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
@@ -54,31 +55,68 @@ class DatabaseDriver implements Driver
* @var array
*/
private $manyToManyTables = array();
/**
* Initializes a new AnnotationDriver that uses the given AnnotationReader for reading
* docblock annotations.
*
* @param AnnotationReader $reader The AnnotationReader to use.
* @var array
*/
private $classNamesForTables = array();
/**
* @var array
*/
private $fieldNamesForColumns = array();
/**
* The namespace for the generated entities.
*
* @var string
*/
private $namespace;
/**
*
* @param AbstractSchemaManager $schemaManager
*/
public function __construct(AbstractSchemaManager $schemaManager)
{
$this->_sm = $schemaManager;
}
/**
* Set tables manually instead of relying on the reverse engeneering capabilities of SchemaManager.
*
* @param array $entityTables
* @param array $manyToManyTables
* @return void
*/
public function setTables($entityTables, $manyToManyTables)
{
$this->tables = $this->manyToManyTables = $this->classToTableNames = array();
foreach ($entityTables as $table) {
$className = $this->getClassNameForTable($table->getName());
$this->classToTableNames[$className] = $table->getName();
$this->tables[$table->getName()] = $table;
}
foreach ($manyToManyTables as $table) {
$this->manyToManyTables[$table->getName()] = $table;
}
}
private function reverseEngineerMappingFromDatabase()
{
if ($this->tables !== null) {
return;
}
$tables = array();
foreach ($this->_sm->listTableNames() as $tableName) {
$tables[$tableName] = $this->_sm->listTableDetails($tableName);
}
$this->tables = array();
foreach ($tables AS $tableName => $table) {
/* @var $table Table */
$this->tables = $this->manyToManyTables = $this->classToTableNames = array();
foreach ($tables as $tableName => $table) {
/* @var $table \Doctrine\DBAL\Schema\Table */
if ($this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) {
$foreignKeys = $table->getForeignKeys();
} else {
@@ -86,34 +124,37 @@ class DatabaseDriver implements Driver
}
$allForeignKeyColumns = array();
foreach ($foreignKeys AS $foreignKey) {
foreach ($foreignKeys as $foreignKey) {
$allForeignKeyColumns = array_merge($allForeignKeyColumns, $foreignKey->getLocalColumns());
}
if ( ! $table->hasPrimaryKey()) {
throw new MappingException(
"Table " . $table->getName() . " has no primary key. Doctrine does not ".
"support reverse engineering from tables that don't have a primary key."
);
}
$pkColumns = $table->getPrimaryKey()->getColumns();
sort($pkColumns);
sort($allForeignKeyColumns);
if ($pkColumns == $allForeignKeyColumns) {
if (count($table->getForeignKeys()) > 2) {
throw new \InvalidArgumentException("ManyToMany table '" . $tableName . "' with more or less than two foreign keys are not supported by the Database Reverese Engineering Driver.");
}
if ($pkColumns == $allForeignKeyColumns && count($foreignKeys) == 2) {
$this->manyToManyTables[$tableName] = $table;
} else {
// lower-casing is necessary because of Oracle Uppercase Tablenames,
// assumption is lower-case + underscore separated.
$className = Inflector::classify(strtolower($tableName));
$className = $this->getClassNameForTable($tableName);
$this->tables[$tableName] = $table;
$this->classToTableNames[$className] = $tableName;
}
}
}
/**
* {@inheritdoc}
* {@inheritDoc}
*/
public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
public function loadMetadataForClass($className, ClassMetadata $metadata)
{
$this->reverseEngineerMappingFromDatabase();
@@ -128,7 +169,12 @@ class DatabaseDriver implements Driver
$columns = $this->tables[$tableName]->getColumns();
$indexes = $this->tables[$tableName]->getIndexes();
try {
$primaryKeyColumns = $this->tables[$tableName]->getPrimaryKey()->getColumns();
} catch(SchemaException $e) {
$primaryKeyColumns = array();
}
if ($this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) {
$foreignKeys = $this->tables[$tableName]->getForeignKeys();
} else {
@@ -136,7 +182,7 @@ class DatabaseDriver implements Driver
}
$allForeignKeyColumns = array();
foreach ($foreignKeys AS $foreignKey) {
foreach ($foreignKeys as $foreignKey) {
$allForeignKeyColumns = array_merge($allForeignKeyColumns, $foreignKey->getLocalColumns());
}
@@ -144,13 +190,14 @@ class DatabaseDriver implements Driver
$fieldMappings = array();
foreach ($columns as $column) {
$fieldMapping = array();
if (isset($indexes['primary']) && in_array($column->getName(), $indexes['primary']->getColumns())) {
$fieldMapping['id'] = true;
} else if (in_array($column->getName(), $allForeignKeyColumns)) {
if (in_array($column->getName(), $allForeignKeyColumns)) {
continue;
} else if ($primaryKeyColumns && in_array($column->getName(), $primaryKeyColumns)) {
$fieldMapping['id'] = true;
}
$fieldMapping['fieldName'] = Inflector::camelize(strtolower($column->getName()));
$fieldMapping['fieldName'] = $this->getFieldNameForColumn($tableName, $column->getName(), false);
$fieldMapping['columnName'] = $column->getName();
$fieldMapping['type'] = strtolower((string) $column->getType());
@@ -183,23 +230,31 @@ class DatabaseDriver implements Driver
$metadata->mapField($fieldMapping);
}
foreach ($this->manyToManyTables AS $manyTable) {
foreach ($manyTable->getForeignKeys() AS $foreignKey) {
foreach ($this->manyToManyTables as $manyTable) {
foreach ($manyTable->getForeignKeys() as $foreignKey) {
// foreign key maps to the table of the current entity, many to many association probably exists
if (strtolower($tableName) == strtolower($foreignKey->getForeignTableName())) {
$myFk = $foreignKey;
foreach ($manyTable->getForeignKeys() AS $foreignKey) {
$otherFk = null;
foreach ($manyTable->getForeignKeys() as $foreignKey) {
if ($foreignKey != $myFk) {
$otherFk = $foreignKey;
break;
}
}
if (!$otherFk) {
// the definition of this many to many table does not contain
// enough foreign key information to continue reverse engeneering.
continue;
}
$localColumn = current($myFk->getColumns());
$associationMapping = array();
$associationMapping['fieldName'] = Inflector::camelize(str_replace('_id', '', strtolower(current($otherFk->getColumns()))));
$associationMapping['targetEntity'] = Inflector::classify(strtolower($otherFk->getForeignTableName()));
$associationMapping['fieldName'] = $this->getFieldNameForColumn($manyTable->getName(), current($otherFk->getColumns()), true);
$associationMapping['targetEntity'] = $this->getClassNameForTable($otherFk->getForeignTableName());
if (current($manyTable->getColumns())->getName() == $localColumn) {
$associationMapping['inversedBy'] = Inflector::camelize(str_replace('_id', '', strtolower(current($myFk->getColumns()))));
$associationMapping['inversedBy'] = $this->getFieldNameForColumn($manyTable->getName(), current($myFk->getColumns()), true);
$associationMapping['joinTable'] = array(
'name' => strtolower($manyTable->getName()),
'joinColumns' => array(),
@@ -224,7 +279,7 @@ class DatabaseDriver implements Driver
);
}
} else {
$associationMapping['mappedBy'] = Inflector::camelize(str_replace('_id', '', strtolower(current($myFk->getColumns()))));
$associationMapping['mappedBy'] = $this->getFieldNameForColumn($manyTable->getName(), current($myFk->getColumns()), true);
}
$metadata->mapManyToMany($associationMapping);
break;
@@ -239,8 +294,12 @@ class DatabaseDriver implements Driver
$localColumn = current($cols);
$associationMapping = array();
$associationMapping['fieldName'] = Inflector::camelize(str_replace('_id', '', strtolower($localColumn)));
$associationMapping['targetEntity'] = Inflector::classify($foreignTable);
$associationMapping['fieldName'] = $this->getFieldNameForColumn($tableName, $localColumn, true);
$associationMapping['targetEntity'] = $this->getClassNameForTable($foreignTable);
if ($primaryKeyColumns && in_array($localColumn, $primaryKeyColumns)) {
$associationMapping['id'] = true;
}
for ($i = 0; $i < count($cols); $i++) {
$associationMapping['joinColumns'][] = array(
@@ -248,12 +307,18 @@ class DatabaseDriver implements Driver
'referencedColumnName' => $fkCols[$i],
);
}
$metadata->mapManyToOne($associationMapping);
//Here we need to check if $cols are the same as $primaryKeyColums
if (!array_diff($cols,$primaryKeyColumns)) {
$metadata->mapOneToOne($associationMapping);
} else {
$metadata->mapManyToOne($associationMapping);
}
}
}
/**
* {@inheritdoc}
* {@inheritDoc}
*/
public function isTransient($className)
{
@@ -261,11 +326,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()
{
@@ -273,4 +334,78 @@ class DatabaseDriver implements Driver
return array_keys($this->classToTableNames);
}
}
/**
* Set class name for a table.
*
* @param string $tableName
* @param string $className
* @return void
*/
public function setClassNameForTable($tableName, $className)
{
$this->classNamesForTables[$tableName] = $className;
}
/**
* Set field name for a column on a specific table.
*
* @param string $tableName
* @param string $columnName
* @param string $fieldName
* @return void
*/
public function setFieldNameForColumn($tableName, $columnName, $fieldName)
{
$this->fieldNamesForColumns[$tableName][$columnName] = $fieldName;
}
/**
* Return the mapped class name for a table if it exists. Otherwise return "classified" version.
*
* @param string $tableName
* @return string
*/
private function getClassNameForTable($tableName)
{
if (isset($this->classNamesForTables[$tableName])) {
return $this->namespace . $this->classNamesForTables[$tableName];
}
return $this->namespace . Inflector::classify(strtolower($tableName));
}
/**
* Return the mapped field name for a column, if it exists. Otherwise return camelized version.
*
* @param string $tableName
* @param string $columnName
* @param boolean $fk Whether the column is a foreignkey or not.
* @return string
*/
private function getFieldNameForColumn($tableName, $columnName, $fk = false)
{
if (isset($this->fieldNamesForColumns[$tableName]) && isset($this->fieldNamesForColumns[$tableName][$columnName])) {
return $this->fieldNamesForColumns[$tableName][$columnName];
}
$columnName = strtolower($columnName);
// Replace _id if it is a foreignkey column
if ($fk) {
$columnName = str_replace('_id', '', $columnName);
}
return Inflector::camelize($columnName);
}
/**
* Set the namespace for the generated entities.
*
* @param string $namespace
* @return void
*/
public function setNamespace($namespace)
{
$this->namespace = $namespace;
}
}
@@ -1,7 +1,5 @@
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -15,123 +13,54 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping;
use Doctrine\Common\Annotations\Annotation;
/* Annotations */
final class Entity extends Annotation {
public $repositoryClass;
}
final class MappedSuperclass extends Annotation {}
final class InheritanceType extends Annotation {}
final class DiscriminatorColumn extends Annotation {
public $name;
public $fieldName; // field name used in non-object hydration (array/scalar)
public $type;
public $length;
}
final class DiscriminatorMap extends Annotation {}
final class Id extends Annotation {}
final class GeneratedValue extends Annotation {
public $strategy = 'AUTO';
}
final class Version extends Annotation {}
final class JoinColumn extends Annotation {
public $name;
public $fieldName; // field name used in non-object hydration (array/scalar)
public $referencedColumnName = 'id';
public $unique = false;
public $nullable = true;
public $onDelete;
public $onUpdate;
public $columnDefinition;
}
final class JoinColumns extends Annotation {}
final class Column extends Annotation {
public $type = 'string';
public $length;
// The precision for a decimal (exact numeric) column (Applies only for decimal column)
public $precision = 0;
// The scale for a decimal (exact numeric) column (Applies only for decimal column)
public $scale = 0;
public $unique = false;
public $nullable = false;
public $name;
public $options = array();
public $columnDefinition;
}
final class OneToOne extends Annotation {
public $targetEntity;
public $mappedBy;
public $inversedBy;
public $cascade;
public $fetch = 'LAZY';
public $orphanRemoval = false;
}
final class OneToMany extends Annotation {
public $mappedBy;
public $targetEntity;
public $cascade;
public $fetch = 'LAZY';
public $orphanRemoval = false;
}
final class ManyToOne extends Annotation {
public $targetEntity;
public $cascade;
public $fetch = 'LAZY';
public $inversedBy;
}
final class ManyToMany extends Annotation {
public $targetEntity;
public $mappedBy;
public $inversedBy;
public $cascade;
public $fetch = 'LAZY';
}
final class ElementCollection extends Annotation {
public $tableName;
}
final class Table extends Annotation {
public $name;
public $schema;
public $indexes;
public $uniqueConstraints;
}
final class UniqueConstraint extends Annotation {
public $name;
public $columns;
}
final class Index extends Annotation {
public $name;
public $columns;
}
final class JoinTable extends Annotation {
public $name;
public $schema;
public $joinColumns = array();
public $inverseJoinColumns = array();
}
final class SequenceGenerator extends Annotation {
public $sequenceName;
public $allocationSize = 1;
public $initialValue = 1;
}
final class ChangeTrackingPolicy extends Annotation {}
final class OrderBy extends Annotation {}
/* Annotations for lifecycle callbacks */
final class HasLifecycleCallbacks extends Annotation {}
final class PrePersist extends Annotation {}
final class PostPersist extends Annotation {}
final class PreUpdate extends Annotation {}
final class PostUpdate extends Annotation {}
final class PreRemove extends Annotation {}
final class PostRemove extends Annotation {}
final class PostLoad extends Annotation {}
require_once __DIR__.'/../Annotation.php';
require_once __DIR__.'/../Entity.php';
require_once __DIR__.'/../MappedSuperclass.php';
require_once __DIR__.'/../InheritanceType.php';
require_once __DIR__.'/../DiscriminatorColumn.php';
require_once __DIR__.'/../DiscriminatorMap.php';
require_once __DIR__.'/../Id.php';
require_once __DIR__.'/../GeneratedValue.php';
require_once __DIR__.'/../Version.php';
require_once __DIR__.'/../JoinColumn.php';
require_once __DIR__.'/../JoinColumns.php';
require_once __DIR__.'/../Column.php';
require_once __DIR__.'/../OneToOne.php';
require_once __DIR__.'/../OneToMany.php';
require_once __DIR__.'/../ManyToOne.php';
require_once __DIR__.'/../ManyToMany.php';
require_once __DIR__.'/../ElementCollection.php';
require_once __DIR__.'/../Table.php';
require_once __DIR__.'/../UniqueConstraint.php';
require_once __DIR__.'/../Index.php';
require_once __DIR__.'/../JoinTable.php';
require_once __DIR__.'/../SequenceGenerator.php';
require_once __DIR__.'/../CustomIdGenerator.php';
require_once __DIR__.'/../ChangeTrackingPolicy.php';
require_once __DIR__.'/../OrderBy.php';
require_once __DIR__.'/../NamedQueries.php';
require_once __DIR__.'/../NamedQuery.php';
require_once __DIR__.'/../HasLifecycleCallbacks.php';
require_once __DIR__.'/../PrePersist.php';
require_once __DIR__.'/../PostPersist.php';
require_once __DIR__.'/../PreUpdate.php';
require_once __DIR__.'/../PostUpdate.php';
require_once __DIR__.'/../PreRemove.php';
require_once __DIR__.'/../PostRemove.php';
require_once __DIR__.'/../PostLoad.php';
require_once __DIR__.'/../PreFlush.php';
require_once __DIR__.'/../FieldResult.php';
require_once __DIR__.'/../ColumnResult.php';
require_once __DIR__.'/../EntityResult.php';
require_once __DIR__.'/../NamedNativeQuery.php';
require_once __DIR__.'/../NamedNativeQueries.php';
require_once __DIR__.'/../SqlResultSetMapping.php';
require_once __DIR__.'/../SqlResultSetMappings.php';
require_once __DIR__.'/../AssociationOverride.php';
require_once __DIR__.'/../AssociationOverrides.php';
require_once __DIR__.'/../AttributeOverride.php';
require_once __DIR__.'/../AttributeOverrides.php';
@@ -13,104 +13,19 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping\Driver;
use Doctrine\ORM\Mapping\Driver\Driver,
Doctrine\ORM\Mapping\ClassMetadataInfo,
Doctrine\ORM\Mapping\MappingException;
use Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain;
/**
* The DriverChain allows you to add multiple other mapping drivers for
* certain namespaces
* {@inheritDoc}
*
* @since 2.0
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan H. Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
* @todo Rename: MappingDriverChain or MetadataDriverChain
* @deprecated this driver will be removed. Use Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain instead
*/
class DriverChain implements Driver
class DriverChain extends MappingDriverChain
{
/**
* @var array
*/
private $_drivers = array();
/**
* Add a nested driver.
*
* @param Driver $nestedDriver
* @param string $namespace
*/
public function addDriver(Driver $nestedDriver, $namespace)
{
$this->_drivers[$namespace] = $nestedDriver;
}
/**
* Get the array of nested drivers.
*
* @return array $drivers
*/
public function getDrivers()
{
return $this->_drivers;
}
/**
* Loads the metadata for the specified class into the provided container.
*
* @param string $className
* @param ClassMetadataInfo $metadata
*/
public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
{
foreach ($this->_drivers as $namespace => $driver) {
if (strpos($className, $namespace) === 0) {
$driver->loadMetadataForClass($className, $metadata);
return;
}
}
throw MappingException::classIsNotAValidEntityOrMappedSuperClass($className);
}
/**
* Gets the names of all mapped classes known to this driver.
*
* @return array The names of all mapped classes known to this driver.
*/
public function getAllClassNames()
{
$classNames = array();
foreach ($this->_drivers AS $driver) {
$classNames = array_merge($classNames, $driver->getAllClassNames());
}
return $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;
}
}
+5 -43
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;
}
}
@@ -0,0 +1,43 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping\Driver;
use Doctrine\Common\Persistence\Mapping\Driver\SymfonyFileLocator;
/**
* XmlDriver that additionally looks for mapping information in a global file.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @license MIT
*/
class SimplifiedXmlDriver extends XmlDriver
{
const DEFAULT_FILE_EXTENSION = '.orm.xml';
/**
* {@inheritDoc}
*/
public function __construct($prefixes, $fileExtension = self::DEFAULT_FILE_EXTENSION)
{
$locator = new SymfonyFileLocator((array) $prefixes, $fileExtension);
parent::__construct($locator, $fileExtension);
}
}
@@ -0,0 +1,43 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping\Driver;
use Doctrine\Common\Persistence\Mapping\Driver\SymfonyFileLocator;
/**
* YamlDriver that additionally looks for mapping information in a global file.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @license MIT
*/
class SimplifiedYamlDriver extends YamlDriver
{
const DEFAULT_FILE_EXTENSION = '.orm.yml';
/**
* {@inheritDoc}
*/
public function __construct($prefixes, $fileExtension = self::DEFAULT_FILE_EXTENSION)
{
$locator = new SymfonyFileLocator((array) $prefixes, $fileExtension);
parent::__construct($locator, $fileExtension);
}
}
@@ -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,108 +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
* @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>
* @deprecated this driver will be removed. Use Doctrine\Common\Persistence\Mapping\Driver\StaticPHPDriver instead
*/
class StaticPHPDriver implements Driver
class StaticPHPDriver extends CommonStaticPHPDriver
{
private $_paths = array();
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;
}
}
+311 -93
View File
@@ -1,7 +1,5 @@
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -15,14 +13,15 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping\Driver;
use SimpleXMLElement,
Doctrine\ORM\Mapping\ClassMetadataInfo,
Doctrine\Common\Persistence\Mapping\Driver\FileDriver,
Doctrine\Common\Persistence\Mapping\ClassMetadata,
Doctrine\ORM\Mapping\MappingException;
/**
@@ -31,31 +30,43 @@ use SimpleXMLElement,
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 2.0
* @version $Revision$
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan H. Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class XmlDriver extends AbstractFileDriver
class XmlDriver extends FileDriver
{
/**
* {@inheritdoc}
*/
protected $_fileExtension = '.dcm.xml';
const DEFAULT_FILE_EXTENSION = '.dcm.xml';
/**
* {@inheritdoc}
* {@inheritDoc}
*/
public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
public function __construct($locator, $fileExtension = self::DEFAULT_FILE_EXTENSION)
{
parent::__construct($locator, $fileExtension);
}
/**
* {@inheritDoc}
*/
public function loadMetadataForClass($className, ClassMetadata $metadata)
{
/* @var $metadata \Doctrine\ORM\Mapping\ClassMetadataInfo */
/* @var $xmlRoot SimpleXMLElement */
$xmlRoot = $this->getElement($className);
if ($xmlRoot->getName() == 'entity') {
if (isset($xmlRoot['repository-class'])) {
$metadata->setCustomRepositoryClass((string)$xmlRoot['repository-class']);
}
if (isset($xmlRoot['read-only']) && $xmlRoot['read-only'] == "true") {
$metadata->markReadOnly();
}
} else if ($xmlRoot->getName() == 'mapped-superclass') {
$metadata->setCustomRepositoryClass(
isset($xmlRoot['repository-class']) ? (string)$xmlRoot['repository-class'] : null
);
} else if ($xmlRoot->getName() == 'mapped-superclass') {
$metadata->isMappedSuperclass = true;
} else {
throw MappingException::classIsNotAValidEntityOrMappedSuperClass($className);
@@ -69,11 +80,73 @@ class XmlDriver extends AbstractFileDriver
$metadata->setPrimaryTable($table);
// Evaluate named queries
if (isset($xmlRoot->{'named-queries'})) {
foreach ($xmlRoot->{'named-queries'}->{'named-query'} as $namedQueryElement) {
$metadata->addNamedQuery(array(
'name' => (string)$namedQueryElement['name'],
'query' => (string)$namedQueryElement['query']
));
}
}
// Evaluate native named queries
if (isset($xmlRoot->{'named-native-queries'})) {
foreach ($xmlRoot->{'named-native-queries'}->{'named-native-query'} as $nativeQueryElement) {
$metadata->addNamedNativeQuery(array(
'name' => isset($nativeQueryElement['name']) ? (string)$nativeQueryElement['name'] : null,
'query' => isset($nativeQueryElement->query) ? (string)$nativeQueryElement->query : null,
'resultClass' => isset($nativeQueryElement['result-class']) ? (string)$nativeQueryElement['result-class'] : null,
'resultSetMapping' => isset($nativeQueryElement['result-set-mapping']) ? (string)$nativeQueryElement['result-set-mapping'] : null,
));
}
}
// Evaluate sql result set mapping
if (isset($xmlRoot->{'sql-result-set-mappings'})) {
foreach ($xmlRoot->{'sql-result-set-mappings'}->{'sql-result-set-mapping'} as $rsmElement) {
$entities = array();
$columns = array();
foreach ($rsmElement as $entityElement) {
//<entity-result/>
if (isset($entityElement['entity-class'])) {
$entityResult = array(
'fields' => array(),
'entityClass' => (string)$entityElement['entity-class'],
'discriminatorColumn' => isset($entityElement['discriminator-column']) ? (string)$entityElement['discriminator-column'] : null,
);
foreach ($entityElement as $fieldElement) {
$entityResult['fields'][] = array(
'name' => isset($fieldElement['name']) ? (string)$fieldElement['name'] : null,
'column' => isset($fieldElement['column']) ? (string)$fieldElement['column'] : null,
);
}
$entities[] = $entityResult;
}
//<column-result/>
if (isset($entityElement['name'])) {
$columns[] = array(
'name' => (string)$entityElement['name'],
);
}
}
$metadata->addSqlResultSetMapping(array(
'name' => (string)$rsmElement['name'],
'entities' => $entities,
'columns' => $columns
));
}
}
/* not implemented specially anyway. use table = schema.table
if (isset($xmlRoot['schema'])) {
$metadata->table['schema'] = (string)$xmlRoot['schema'];
}*/
if (isset($xmlRoot['inheritance-type'])) {
$inheritanceType = (string)$xmlRoot['inheritance-type'];
$metadata->setInheritanceType(constant('Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_' . $inheritanceType));
@@ -83,9 +156,10 @@ class XmlDriver extends AbstractFileDriver
if (isset($xmlRoot->{'discriminator-column'})) {
$discrColumn = $xmlRoot->{'discriminator-column'};
$metadata->setDiscriminatorColumn(array(
'name' => (string)$discrColumn['name'],
'type' => (string)$discrColumn['type'],
'length' => (string)$discrColumn['length']
'name' => isset($discrColumn['name']) ? (string)$discrColumn['name'] : null,
'type' => isset($discrColumn['type']) ? (string)$discrColumn['type'] : null,
'length' => isset($discrColumn['length']) ? (string)$discrColumn['length'] : null,
'columnDefinition' => isset($discrColumn['column-definition']) ? (string)$discrColumn['column-definition'] : null
));
} else {
$metadata->setDiscriminatorColumn(array('name' => 'dtype', 'type' => 'string', 'length' => 255));
@@ -94,7 +168,7 @@ class XmlDriver extends AbstractFileDriver
// Evaluate <discriminator-map...>
if (isset($xmlRoot->{'discriminator-map'})) {
$map = array();
foreach ($xmlRoot->{'discriminator-map'}->{'discriminator-mapping'} AS $discrMapElement) {
foreach ($xmlRoot->{'discriminator-map'}->{'discriminator-mapping'} as $discrMapElement) {
$map[(string)$discrMapElement['value']] = (string)$discrMapElement['class'];
}
$metadata->setDiscriminatorMap($map);
@@ -145,66 +219,54 @@ class XmlDriver extends AbstractFileDriver
}
}
if (isset($xmlRoot->options)) {
$metadata->table['options'] = $this->_parseOptions($xmlRoot->options->children());
}
// The mapping assignement is done in 2 times as a bug might occurs on some php/xml lib versions
// The internal SimpleXmlIterator get resetted, to this generate a duplicate field exception
$mappings = array();
// Evaluate <field ...> mappings
if (isset($xmlRoot->field)) {
foreach ($xmlRoot->field as $fieldMapping) {
$mapping = array(
'fieldName' => (string)$fieldMapping['name'],
'type' => (string)$fieldMapping['type']
);
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']) {
$metadata->setVersionMapping($mapping);
}
if (isset($fieldMapping['column-definition'])) {
$mapping['columnDefinition'] = (string)$fieldMapping['column-definition'];
}
$mapping = $this->columnToArray($fieldMapping);
$metadata->mapField($mapping);
}
}
foreach ($mappings as $mapping) {
$metadata->mapField($mapping);
}
// Evaluate <id ...> mappings
$associationIds = array();
foreach ($xmlRoot->id as $idElement) {
if ((bool)$idElement['association-key'] == true) {
$associationIds[(string)$idElement['name']] = true;
continue;
}
$mapping = array(
'id' => true,
'fieldName' => (string)$idElement['name'],
'type' => (string)$idElement['type']
'fieldName' => (string)$idElement['name']
);
if (isset($idElement['type'])) {
$mapping['type'] = (string)$idElement['type'];
}
if (isset($idElement['length'])) {
$mapping['length'] = (string)$idElement['length'];
}
if (isset($idElement['column'])) {
$mapping['columnName'] = (string)$idElement['column'];
}
if (isset($idElement['column-definition'])) {
$mapping['columnDefinition'] = (string)$idElement['column-definition'];
}
$metadata->mapField($mapping);
if (isset($idElement->generator)) {
@@ -222,6 +284,11 @@ class XmlDriver extends AbstractFileDriver
'allocationSize' => (string)$seqGenerator['allocation-size'],
'initialValue' => (string)$seqGenerator['initial-value']
));
} else if (isset($idElement->{'custom-id-generator'})) {
$customGenerator = $idElement->{'custom-id-generator'};
$metadata->setCustomGeneratorDefinition(array(
'class' => (string) $customGenerator['class']
));
} else if (isset($idElement->{'table-generator'})) {
throw MappingException::tableIdGeneratorNotImplemented($className);
}
@@ -235,6 +302,10 @@ class XmlDriver extends AbstractFileDriver
'targetEntity' => (string)$oneToOneElement['target-entity']
);
if (isset($associationIds[$mapping['fieldName']])) {
$mapping['id'] = true;
}
if (isset($oneToOneElement['fetch'])) {
$mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . (string)$oneToOneElement['fetch']);
}
@@ -248,10 +319,10 @@ class XmlDriver extends AbstractFileDriver
$joinColumns = array();
if (isset($oneToOneElement->{'join-column'})) {
$joinColumns[] = $this->_getJoinColumnMapping($oneToOneElement->{'join-column'});
$joinColumns[] = $this->joinColumnToArray($oneToOneElement->{'join-column'});
} else if (isset($oneToOneElement->{'join-columns'})) {
foreach ($oneToOneElement->{'join-columns'}->{'join-column'} as $joinColumnElement) {
$joinColumns[] = $this->_getJoinColumnMapping($joinColumnElement);
$joinColumns[] = $this->joinColumnToArray($joinColumnElement);
}
}
@@ -262,8 +333,8 @@ class XmlDriver extends AbstractFileDriver
$mapping['cascade'] = $this->_getCascadeMappings($oneToOneElement->cascade);
}
if (isset($oneToOneElement->{'orphan-removal'})) {
$mapping['orphanRemoval'] = (bool)$oneToOneElement->{'orphan-removal'};
if (isset($oneToOneElement['orphan-removal'])) {
$mapping['orphanRemoval'] = (bool)$oneToOneElement['orphan-removal'];
}
$metadata->mapOneToOne($mapping);
@@ -287,18 +358,24 @@ class XmlDriver extends AbstractFileDriver
$mapping['cascade'] = $this->_getCascadeMappings($oneToManyElement->cascade);
}
if (isset($oneToManyElement->{'orphan-removal'})) {
$mapping['orphanRemoval'] = (bool)$oneToManyElement->{'orphan-removal'};
if (isset($oneToManyElement['orphan-removal'])) {
$mapping['orphanRemoval'] = (bool)$oneToManyElement['orphan-removal'];
}
if (isset($oneToManyElement->{'order-by'})) {
$orderBy = array();
foreach ($oneToManyElement->{'order-by'}->{'order-by-field'} AS $orderByField) {
foreach ($oneToManyElement->{'order-by'}->{'order-by-field'} as $orderByField) {
$orderBy[(string)$orderByField['name']] = (string)$orderByField['direction'];
}
$mapping['orderBy'] = $orderBy;
}
if (isset($oneToManyElement['index-by'])) {
$mapping['indexBy'] = (string)$oneToManyElement['index-by'];
} else if (isset($oneToManyElement->{'index-by'})) {
throw new \InvalidArgumentException("<index-by /> is not a valid tag");
}
$metadata->mapOneToMany($mapping);
}
}
@@ -311,6 +388,10 @@ class XmlDriver extends AbstractFileDriver
'targetEntity' => (string)$manyToOneElement['target-entity']
);
if (isset($associationIds[$mapping['fieldName']])) {
$mapping['id'] = true;
}
if (isset($manyToOneElement['fetch'])) {
$mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . (string)$manyToOneElement['fetch']);
}
@@ -322,13 +403,10 @@ class XmlDriver extends AbstractFileDriver
$joinColumns = array();
if (isset($manyToOneElement->{'join-column'})) {
$joinColumns[] = $this->_getJoinColumnMapping($manyToOneElement->{'join-column'});
$joinColumns[] = $this->joinColumnToArray($manyToOneElement->{'join-column'});
} else if (isset($manyToOneElement->{'join-columns'})) {
foreach ($manyToOneElement->{'join-columns'}->{'join-column'} as $joinColumnElement) {
if (!isset($joinColumnElement['name'])) {
$joinColumnElement['name'] = $name;
}
$joinColumns[] = $this->_getJoinColumnMapping($joinColumnElement);
$joinColumns[] = $this->joinColumnToArray($joinColumnElement);
}
}
@@ -338,10 +416,6 @@ class XmlDriver extends AbstractFileDriver
$mapping['cascade'] = $this->_getCascadeMappings($manyToOneElement->cascade);
}
if (isset($manyToOneElement->{'orphan-removal'})) {
$mapping['orphanRemoval'] = (bool)$manyToOneElement->{'orphan-removal'};
}
$metadata->mapManyToOne($mapping);
}
}
@@ -358,6 +432,10 @@ class XmlDriver extends AbstractFileDriver
$mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . (string)$manyToManyElement['fetch']);
}
if (isset($manyToManyElement['orphan-removal'])) {
$mapping['orphanRemoval'] = (bool)$manyToManyElement['orphan-removal'];
}
if (isset($manyToManyElement['mapped-by'])) {
$mapping['mappedBy'] = (string)$manyToManyElement['mapped-by'];
} else if (isset($manyToManyElement->{'join-table'})) {
@@ -375,11 +453,11 @@ class XmlDriver extends AbstractFileDriver
}
foreach ($joinTableElement->{'join-columns'}->{'join-column'} as $joinColumnElement) {
$joinTable['joinColumns'][] = $this->_getJoinColumnMapping($joinColumnElement);
$joinTable['joinColumns'][] = $this->joinColumnToArray($joinColumnElement);
}
foreach ($joinTableElement->{'inverse-join-columns'}->{'join-column'} as $joinColumnElement) {
$joinTable['inverseJoinColumns'][] = $this->_getJoinColumnMapping($joinColumnElement);
$joinTable['inverseJoinColumns'][] = $this->joinColumnToArray($joinColumnElement);
}
$mapping['joinTable'] = $joinTable;
@@ -389,22 +467,80 @@ class XmlDriver extends AbstractFileDriver
$mapping['cascade'] = $this->_getCascadeMappings($manyToManyElement->cascade);
}
if (isset($manyToManyElement->{'orphan-removal'})) {
$mapping['orphanRemoval'] = (bool)$manyToManyElement->{'orphan-removal'};
}
if (isset($manyToManyElement->{'order-by'})) {
$orderBy = array();
foreach ($manyToManyElement->{'order-by'}->{'order-by-field'} AS $orderByField) {
foreach ($manyToManyElement->{'order-by'}->{'order-by-field'} as $orderByField) {
$orderBy[(string)$orderByField['name']] = (string)$orderByField['direction'];
}
$mapping['orderBy'] = $orderBy;
}
if (isset($manyToManyElement['index-by'])) {
$mapping['indexBy'] = (string)$manyToManyElement['index-by'];
} else if (isset($manyToManyElement->{'index-by'})) {
throw new \InvalidArgumentException("<index-by /> is not a valid tag");
}
$metadata->mapManyToMany($mapping);
}
}
// Evaluate association-overrides
if (isset($xmlRoot->{'attribute-overrides'})) {
foreach ($xmlRoot->{'attribute-overrides'}->{'attribute-override'} as $overrideElement) {
$fieldName = (string) $overrideElement['name'];
foreach ($overrideElement->field as $field) {
$mapping = $this->columnToArray($field);
$mapping['fieldName'] = $fieldName;
$metadata->setAttributeOverride($fieldName, $mapping);
}
}
}
// Evaluate association-overrides
if (isset($xmlRoot->{'association-overrides'})) {
foreach ($xmlRoot->{'association-overrides'}->{'association-override'} as $overrideElement) {
$fieldName = (string) $overrideElement['name'];
$override = array();
// Check for join-columns
if (isset($overrideElement->{'join-columns'})) {
$joinColumns = array();
foreach ($overrideElement->{'join-columns'}->{'join-column'} as $joinColumnElement) {
$joinColumns[] = $this->joinColumnToArray($joinColumnElement);
}
$override['joinColumns'] = $joinColumns;
}
// Check for join-table
if ($overrideElement->{'join-table'}) {
$joinTable = null;
$joinTableElement = $overrideElement->{'join-table'};
$joinTable = array(
'name' => (string) $joinTableElement['name'],
'schema' => (string) $joinTableElement['schema']
);
if (isset($joinTableElement->{'join-columns'})) {
foreach ($joinTableElement->{'join-columns'}->{'join-column'} as $joinColumnElement) {
$joinTable['joinColumns'][] = $this->joinColumnToArray($joinColumnElement);
}
}
if (isset($joinTableElement->{'inverse-join-columns'})) {
foreach ($joinTableElement->{'inverse-join-columns'}->{'join-column'} as $joinColumnElement) {
$joinTable['inverseJoinColumns'][] = $this->joinColumnToArray($joinColumnElement);
}
}
$override['joinTable'] = $joinTable;
}
$metadata->setAssociationOverride($fieldName, $override);
}
}
// Evaluate <lifecycle-callbacks...>
if (isset($xmlRoot->{'lifecycle-callbacks'})) {
foreach ($xmlRoot->{'lifecycle-callbacks'}->{'lifecycle-callback'} as $lifecycleCallback) {
@@ -413,14 +549,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'],
@@ -439,10 +605,6 @@ class XmlDriver extends AbstractFileDriver
$joinColumn['onDelete'] = (string)$joinColumnElement['on-delete'];
}
if (isset($joinColumnElement['on-update'])) {
$joinColumn['onUpdate'] = (string)$joinColumnElement['on-update'];
}
if (isset($joinColumnElement['column-definition'])) {
$joinColumn['columnDefinition'] = (string)$joinColumnElement['column-definition'];
}
@@ -450,15 +612,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'] = ((string) $fieldMapping['unique'] == "false") ? false : true;
}
if (isset($fieldMapping['nullable'])) {
$mapping['nullable'] = ((string) $fieldMapping['nullable'] == "false") ? false : true;
}
if (isset($fieldMapping['version']) && $fieldMapping['version']) {
$mapping['version'] = $fieldMapping['version'];
}
if (isset($fieldMapping['column-definition'])) {
$mapping['columnDefinition'] = (string) $fieldMapping['column-definition'];
}
if (isset($fieldMapping->options)) {
$mapping['options'] = $this->_parseOptions($fieldMapping->options->children());
}
return $mapping;
}
/**
* Gathers a list of cascade options found in the given cascade element.
*
* @param $cascadeElement The cascade element.
* @param SimpleXMLElement $cascadeElement the cascade element.
* @return array The list of cascade options.
*/
private function _getCascadeMappings($cascadeElement)
{
$cascades = array();
/* @var $action SimpleXmlElement */
foreach ($cascadeElement->children() as $action) {
// According to the JPA specifications, XML uses "cascade-persist"
// instead of "persist". Here, both variations
@@ -471,9 +689,9 @@ class XmlDriver extends AbstractFileDriver
}
/**
* {@inheritdoc}
* {@inheritDoc}
*/
protected function _loadMappingFile($file)
protected function loadMappingFile($file)
{
$result = array();
$xmlElement = simplexml_load_file($file);
+317 -91
View File
@@ -13,14 +13,16 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping\Driver;
use Doctrine\ORM\Mapping\ClassMetadataInfo,
Doctrine\ORM\Mapping\MappingException;
use Doctrine\Common\Persistence\Mapping\ClassMetadata,
Doctrine\Common\Persistence\Mapping\Driver\FileDriver,
Doctrine\ORM\Mapping\MappingException,
Symfony\Component\Yaml\Yaml;
/**
* The YamlDriver reads the mapping metadata from yaml schema files.
@@ -31,25 +33,37 @@ use Doctrine\ORM\Mapping\ClassMetadataInfo,
* @author Jonathan H. Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
*/
class YamlDriver extends AbstractFileDriver
class YamlDriver extends FileDriver
{
/**
* {@inheritdoc}
*/
protected $_fileExtension = '.dcm.yml';
const DEFAULT_FILE_EXTENSION = '.dcm.yml';
/**
* {@inheritdoc}
* {@inheritDoc}
*/
public function loadMetadataForClass($className, ClassMetadataInfo $metadata)
public function __construct($locator, $fileExtension = self::DEFAULT_FILE_EXTENSION)
{
parent::__construct($locator, $fileExtension);
}
/**
* {@inheritDoc}
*/
public function loadMetadataForClass($className, ClassMetadata $metadata)
{
/* @var $metadata \Doctrine\ORM\Mapping\ClassMetadataInfo */
$element = $this->getElement($className);
if ($element['type'] == 'entity') {
if (isset($element['repositoryClass'])) {
$metadata->setCustomRepositoryClass($element['repositoryClass']);
}
if (isset($element['readOnly']) && $element['readOnly'] == true) {
$metadata->markReadOnly();
}
} else if ($element['type'] == 'mappedSuperclass') {
$metadata->setCustomRepositoryClass(
isset($element['repositoryClass']) ? $element['repositoryClass'] : null
);
} else if ($element['type'] == 'mappedSuperclass') {
$metadata->isMappedSuperclass = true;
} else {
throw MappingException::classIsNotAValidEntityOrMappedSuperClass($className);
@@ -62,6 +76,83 @@ class YamlDriver extends AbstractFileDriver
}
$metadata->setPrimaryTable($table);
// Evaluate named queries
if (isset($element['namedQueries'])) {
foreach ($element['namedQueries'] as $name => $queryMapping) {
if (is_string($queryMapping)) {
$queryMapping = array('query' => $queryMapping);
}
if ( ! isset($queryMapping['name'])) {
$queryMapping['name'] = $name;
}
$metadata->addNamedQuery($queryMapping);
}
}
// Evaluate named native queries
if (isset($element['namedNativeQueries'])) {
foreach ($element['namedNativeQueries'] as $name => $mappingElement) {
if (!isset($mappingElement['name'])) {
$mappingElement['name'] = $name;
}
$metadata->addNamedNativeQuery(array(
'name' => $mappingElement['name'],
'query' => isset($mappingElement['query']) ? $mappingElement['query'] : null,
'resultClass' => isset($mappingElement['resultClass']) ? $mappingElement['resultClass'] : null,
'resultSetMapping' => isset($mappingElement['resultSetMapping']) ? $mappingElement['resultSetMapping'] : null,
));
}
}
// Evaluate sql result set mappings
if (isset($element['sqlResultSetMappings'])) {
foreach ($element['sqlResultSetMappings'] as $name => $resultSetMapping) {
if (!isset($resultSetMapping['name'])) {
$resultSetMapping['name'] = $name;
}
$entities = array();
$columns = array();
if (isset($resultSetMapping['entityResult'])) {
foreach ($resultSetMapping['entityResult'] as $entityResultElement) {
$entityResult = array(
'fields' => array(),
'entityClass' => isset($entityResultElement['entityClass']) ? $entityResultElement['entityClass'] : null,
'discriminatorColumn' => isset($entityResultElement['discriminatorColumn']) ? $entityResultElement['discriminatorColumn'] : null,
);
if (isset($entityResultElement['fieldResult'])) {
foreach ($entityResultElement['fieldResult'] as $fieldResultElement) {
$entityResult['fields'][] = array(
'name' => isset($fieldResultElement['name']) ? $fieldResultElement['name'] : null,
'column' => isset($fieldResultElement['column']) ? $fieldResultElement['column'] : null,
);
}
}
$entities[] = $entityResult;
}
}
if (isset($resultSetMapping['columnResult'])) {
foreach ($resultSetMapping['columnResult'] as $columnResultAnnot) {
$columns[] = array(
'name' => isset($columnResultAnnot['name']) ? $columnResultAnnot['name'] : null,
);
}
}
$metadata->addSqlResultSetMapping(array(
'name' => $resultSetMapping['name'],
'entities' => $entities,
'columns' => $columns
));
}
}
/* not implemented specially anyway. use table = schema.table
if (isset($element['schema'])) {
$metadata->table['schema'] = $element['schema'];
@@ -75,9 +166,10 @@ class YamlDriver extends AbstractFileDriver
if (isset($element['discriminatorColumn'])) {
$discrColumn = $element['discriminatorColumn'];
$metadata->setDiscriminatorColumn(array(
'name' => $discrColumn['name'],
'type' => $discrColumn['type'],
'length' => $discrColumn['length']
'name' => isset($discrColumn['name']) ? (string)$discrColumn['name'] : null,
'type' => isset($discrColumn['type']) ? (string)$discrColumn['type'] : null,
'length' => isset($discrColumn['length']) ? (string)$discrColumn['length'] : null,
'columnDefinition' => isset($discrColumn['columnDefinition']) ? (string)$discrColumn['columnDefinition'] : null
));
} else {
$metadata->setDiscriminatorColumn(array('name' => 'dtype', 'type' => 'string', 'length' => 255));
@@ -135,19 +227,28 @@ class YamlDriver extends AbstractFileDriver
}
}
if (isset($element['options'])) {
$metadata->table['options'] = $element['options'];
}
$associationIds = array();
if (isset($element['id'])) {
// Evaluate identifier settings
foreach ($element['id'] as $name => $idElement) {
if (!isset($idElement['type'])) {
throw MappingException::propertyTypeIsRequired($className, $name);
if (isset($idElement['associationKey']) && $idElement['associationKey'] == true) {
$associationIds[$name] = true;
continue;
}
$mapping = array(
'id' => true,
'fieldName' => $name,
'type' => $idElement['type']
'fieldName' => $name
);
if (isset($idElement['type'])) {
$mapping['type'] = $idElement['type'];
}
if (isset($idElement['column'])) {
$mapping['columnName'] = $idElement['column'];
}
@@ -156,6 +257,10 @@ class YamlDriver extends AbstractFileDriver
$mapping['length'] = $idElement['length'];
}
if (isset($idElement['columnDefinition'])) {
$mapping['columnDefinition'] = $idElement['columnDefinition'];
}
$metadata->mapField($mapping);
if (isset($idElement['generator'])) {
@@ -165,6 +270,11 @@ class YamlDriver extends AbstractFileDriver
// Check for SequenceGenerator/TableGenerator definition
if (isset($idElement['sequenceGenerator'])) {
$metadata->setSequenceGeneratorDefinition($idElement['sequenceGenerator']);
} else if (isset($idElement['customIdGenerator'])) {
$customGenerator = $idElement['customIdGenerator'];
$metadata->setCustomGeneratorDefinition(array(
'class' => (string) $customGenerator['class']
));
} else if (isset($idElement['tableGenerator'])) {
throw MappingException::tableIdGeneratorNotImplemented($className);
}
@@ -174,19 +284,9 @@ class YamlDriver extends AbstractFileDriver
// Evaluate fields
if (isset($element['fields'])) {
foreach ($element['fields'] as $name => $fieldMapping) {
if (!isset($fieldMapping['type'])) {
throw MappingException::propertyTypeIsRequired($className, $name);
}
$e = explode('(', $fieldMapping['type']);
$fieldMapping['type'] = $e[0];
if (isset($e[1])) {
$fieldMapping['length'] = substr($e[1], 0, strlen($e[1]) - 1);
}
$mapping = array(
'fieldName' => $name,
'type' => $fieldMapping['type']
);
$mapping = $this->columnToArray($name, $fieldMapping);
if (isset($fieldMapping['id'])) {
$mapping['id'] = true;
if (isset($fieldMapping['generator']['strategy'])) {
@@ -194,33 +294,6 @@ 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']) {
$metadata->setVersionMapping($mapping);
}
if (isset($fieldMapping['columnDefinition'])) {
$mapping['columnDefinition'] = $fieldMapping['columnDefinition'];
}
$metadata->mapField($mapping);
}
@@ -234,6 +307,10 @@ class YamlDriver extends AbstractFileDriver
'targetEntity' => $oneToOneElement['targetEntity']
);
if (isset($associationIds[$mapping['fieldName']])) {
$mapping['id'] = true;
}
if (isset($oneToOneElement['fetch'])) {
$mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $oneToOneElement['fetch']);
}
@@ -248,14 +325,14 @@ class YamlDriver extends AbstractFileDriver
$joinColumns = array();
if (isset($oneToOneElement['joinColumn'])) {
$joinColumns[] = $this->_getJoinColumnMapping($oneToOneElement['joinColumn']);
$joinColumns[] = $this->joinColumnToArray($oneToOneElement['joinColumn']);
} else if (isset($oneToOneElement['joinColumns'])) {
foreach ($oneToOneElement['joinColumns'] as $name => $joinColumnElement) {
if (!isset($joinColumnElement['name'])) {
$joinColumnElement['name'] = $name;
foreach ($oneToOneElement['joinColumns'] as $joinColumnName => $joinColumnElement) {
if ( ! isset($joinColumnElement['name'])) {
$joinColumnElement['name'] = $joinColumnName;
}
$joinColumns[] = $this->_getJoinColumnMapping($joinColumnElement);
$joinColumns[] = $this->joinColumnToArray($joinColumnElement);
}
}
@@ -266,6 +343,10 @@ class YamlDriver extends AbstractFileDriver
$mapping['cascade'] = $oneToOneElement['cascade'];
}
if (isset($oneToOneElement['orphanRemoval'])) {
$mapping['orphanRemoval'] = (bool)$oneToOneElement['orphanRemoval'];
}
$metadata->mapOneToOne($mapping);
}
}
@@ -287,10 +368,18 @@ class YamlDriver extends AbstractFileDriver
$mapping['cascade'] = $oneToManyElement['cascade'];
}
if (isset($oneToManyElement['orphanRemoval'])) {
$mapping['orphanRemoval'] = (bool)$oneToManyElement['orphanRemoval'];
}
if (isset($oneToManyElement['orderBy'])) {
$mapping['orderBy'] = $oneToManyElement['orderBy'];
}
if (isset($oneToManyElement['indexBy'])) {
$mapping['indexBy'] = $oneToManyElement['indexBy'];
}
$metadata->mapOneToMany($mapping);
}
}
@@ -303,6 +392,10 @@ class YamlDriver extends AbstractFileDriver
'targetEntity' => $manyToOneElement['targetEntity']
);
if (isset($associationIds[$mapping['fieldName']])) {
$mapping['id'] = true;
}
if (isset($manyToOneElement['fetch'])) {
$mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $manyToOneElement['fetch']);
}
@@ -314,14 +407,14 @@ class YamlDriver extends AbstractFileDriver
$joinColumns = array();
if (isset($manyToOneElement['joinColumn'])) {
$joinColumns[] = $this->_getJoinColumnMapping($manyToOneElement['joinColumn']);
$joinColumns[] = $this->joinColumnToArray($manyToOneElement['joinColumn']);
} else if (isset($manyToOneElement['joinColumns'])) {
foreach ($manyToOneElement['joinColumns'] as $name => $joinColumnElement) {
if (!isset($joinColumnElement['name'])) {
$joinColumnElement['name'] = $name;
foreach ($manyToOneElement['joinColumns'] as $joinColumnName => $joinColumnElement) {
if ( ! isset($joinColumnElement['name'])) {
$joinColumnElement['name'] = $joinColumnName;
}
$joinColumns[] = $this->_getJoinColumnMapping($joinColumnElement);
$joinColumns[] = $this->joinColumnToArray($joinColumnElement);
}
}
@@ -350,9 +443,6 @@ class YamlDriver extends AbstractFileDriver
if (isset($manyToManyElement['mappedBy'])) {
$mapping['mappedBy'] = $manyToManyElement['mappedBy'];
} else if (isset($manyToManyElement['joinTable'])) {
if (isset($manyToManyElement['inversedBy'])) {
$mapping['inversedBy'] = $manyToManyElement['inversedBy'];
}
$joinTableElement = $manyToManyElement['joinTable'];
$joinTable = array(
@@ -363,25 +453,29 @@ class YamlDriver extends AbstractFileDriver
$joinTable['schema'] = $joinTableElement['schema'];
}
foreach ($joinTableElement['joinColumns'] as $name => $joinColumnElement) {
if (!isset($joinColumnElement['name'])) {
$joinColumnElement['name'] = $name;
foreach ($joinTableElement['joinColumns'] as $joinColumnName => $joinColumnElement) {
if ( ! isset($joinColumnElement['name'])) {
$joinColumnElement['name'] = $joinColumnName;
}
$joinTable['joinColumns'][] = $this->_getJoinColumnMapping($joinColumnElement);
$joinTable['joinColumns'][] = $this->joinColumnToArray($joinColumnElement);
}
foreach ($joinTableElement['inverseJoinColumns'] as $name => $joinColumnElement) {
if (!isset($joinColumnElement['name'])) {
$joinColumnElement['name'] = $name;
foreach ($joinTableElement['inverseJoinColumns'] as $joinColumnName => $joinColumnElement) {
if ( ! isset($joinColumnElement['name'])) {
$joinColumnElement['name'] = $joinColumnName;
}
$joinTable['inverseJoinColumns'][] = $this->_getJoinColumnMapping($joinColumnElement);
$joinTable['inverseJoinColumns'][] = $this->joinColumnToArray($joinColumnElement);
}
$mapping['joinTable'] = $joinTable;
}
if (isset($manyToManyElement['inversedBy'])) {
$mapping['inversedBy'] = $manyToManyElement['inversedBy'];
}
if (isset($manyToManyElement['cascade'])) {
$mapping['cascade'] = $manyToManyElement['cascade'];
}
@@ -390,10 +484,80 @@ class YamlDriver extends AbstractFileDriver
$mapping['orderBy'] = $manyToManyElement['orderBy'];
}
if (isset($manyToManyElement['indexBy'])) {
$mapping['indexBy'] = $manyToManyElement['indexBy'];
}
if (isset($manyToManyElement['orphanRemoval'])) {
$mapping['orphanRemoval'] = (bool)$manyToManyElement['orphanRemoval'];
}
$metadata->mapManyToMany($mapping);
}
}
// Evaluate associationOverride
if (isset($element['associationOverride']) && is_array($element['associationOverride'])) {
foreach ($element['associationOverride'] as $fieldName => $associationOverrideElement) {
$override = array();
// Check for joinColumn
if (isset($associationOverrideElement['joinColumn'])) {
$joinColumns = array();
foreach ($associationOverrideElement['joinColumn'] as $name => $joinColumnElement) {
if ( ! isset($joinColumnElement['name'])) {
$joinColumnElement['name'] = $name;
}
$joinColumns[] = $this->joinColumnToArray($joinColumnElement);
}
$override['joinColumns'] = $joinColumns;
}
// Check for joinTable
if (isset($associationOverrideElement['joinTable'])) {
$joinTableElement = $associationOverrideElement['joinTable'];
$joinTable = array(
'name' => $joinTableElement['name']
);
if (isset($joinTableElement['schema'])) {
$joinTable['schema'] = $joinTableElement['schema'];
}
foreach ($joinTableElement['joinColumns'] as $name => $joinColumnElement) {
if ( ! isset($joinColumnElement['name'])) {
$joinColumnElement['name'] = $name;
}
$joinTable['joinColumns'][] = $this->joinColumnToArray($joinColumnElement);
}
foreach ($joinTableElement['inverseJoinColumns'] as $name => $joinColumnElement) {
if ( ! isset($joinColumnElement['name'])) {
$joinColumnElement['name'] = $name;
}
$joinTable['inverseJoinColumns'][] = $this->joinColumnToArray($joinColumnElement);
}
$override['joinTable'] = $joinTable;
}
$metadata->setAssociationOverride($fieldName, $override);
}
}
// Evaluate associationOverride
if (isset($element['attributeOverride']) && is_array($element['attributeOverride'])) {
foreach ($element['attributeOverride'] as $fieldName => $attributeOverrideElement) {
$mapping = $this->columnToArray($fieldName, $attributeOverrideElement);
$metadata->setAttributeOverride($fieldName, $mapping);
}
}
// Evaluate lifeCycleCallbacks
if (isset($element['lifecycleCallbacks'])) {
foreach ($element['lifecycleCallbacks'] as $type => $methods) {
@@ -408,15 +572,19 @@ class YamlDriver extends AbstractFileDriver
* Constructs a joinColumn mapping array based on the information
* found in the given join column element.
*
* @param $joinColumnElement The array join column element
* @param array $joinColumnElement The array join column element
* @return array The mapping array.
*/
private function _getJoinColumnMapping($joinColumnElement)
private function joinColumnToArray($joinColumnElement)
{
$joinColumn = array(
'name' => $joinColumnElement['name'],
'referencedColumnName' => $joinColumnElement['referencedColumnName']
);
$joinColumn = array();
if (isset($joinColumnElement['referencedColumnName'])) {
$joinColumn['referencedColumnName'] = (string) $joinColumnElement['referencedColumnName'];
}
if (isset($joinColumnElement['name'])) {
$joinColumn['name'] = (string) $joinColumnElement['name'];
}
if (isset($joinColumnElement['fieldName'])) {
$joinColumn['fieldName'] = (string) $joinColumnElement['fieldName'];
@@ -434,10 +602,6 @@ class YamlDriver extends AbstractFileDriver
$joinColumn['onDelete'] = $joinColumnElement['onDelete'];
}
if (isset($joinColumnElement['onUpdate'])) {
$joinColumn['onUpdate'] = $joinColumnElement['onUpdate'];
}
if (isset($joinColumnElement['columnDefinition'])) {
$joinColumn['columnDefinition'] = $joinColumnElement['columnDefinition'];
}
@@ -446,10 +610,72 @@ class YamlDriver extends AbstractFileDriver
}
/**
* {@inheritdoc}
* Parse the given column as array
*
* @param string $fieldName
* @param array $column
* @return array
*/
protected function _loadMappingFile($file)
private function columnToArray($fieldName, $column)
{
return \Symfony\Component\Yaml\Yaml::load($file);
$mapping = array(
'fieldName' => $fieldName
);
if (isset($column['type'])) {
$params = explode('(', $column['type']);
$column['type'] = $params[0];
$mapping['type'] = $column['type'];
if (isset($params[1])) {
$column['length'] = 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);
}
}
@@ -0,0 +1,31 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping;
/**
* @Annotation
* @Target("ALL")
* @todo check available targets
*/
final class ElementCollection implements Annotation
{
/** @var string */
public $tableName;
}
+32
View File
@@ -0,0 +1,32 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping;
/**
* @Annotation
* @Target("CLASS")
*/
final class Entity implements Annotation
{
/** @var string */
public $repositoryClass;
/** @var boolean */
public $readOnly = false;
}
+58
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;
}
+48
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;
}
@@ -0,0 +1,30 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping;
/**
* @Annotation
* @Target("PROPERTY")
*/
final class GeneratedValue implements Annotation
{
/** @var string */
public $strategy = 'AUTO';
}
@@ -0,0 +1,28 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping;
/**
* @Annotation
* @Target("CLASS")
*/
final class HasLifecycleCallbacks implements Annotation
{
}
+28
View File
@@ -0,0 +1,28 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping;
/**
* @Annotation
* @Target("PROPERTY")
*/
final class Id implements Annotation
{
}
+32
View File
@@ -0,0 +1,32 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping;
/**
* @Annotation
* @Target("ANNOTATION")
*/
final class Index implements Annotation
{
/** @var string */
public $name;
/** @var array<string> */
public $columns;
}
@@ -0,0 +1,30 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping;
/**
* @Annotation
* @Target("CLASS")
*/
final class InheritanceType implements Annotation
{
/** @var string */
public $value;
}
+42
View File
@@ -0,0 +1,42 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping;
/**
* @Annotation
* @Target({"PROPERTY","ANNOTATION"})
*/
final class JoinColumn implements Annotation
{
/** @var string */
public $name;
/** @var string */
public $referencedColumnName = 'id';
/** @var boolean */
public $unique = false;
/** @var boolean */
public $nullable = true;
/** @var mixed */
public $onDelete;
/** @var string */
public $columnDefinition;
/** @var string */
public $fieldName; // field name used in non-object hydration (array/scalar)
}
+30
View File
@@ -0,0 +1,30 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping;
/**
* @Annotation
* @Target("PROPERTY")
*/
final class JoinColumns implements Annotation
{
/** @var array<\Doctrine\ORM\Mapping\JoinColumn> */
public $value;
}
+36
View File
@@ -0,0 +1,36 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping;
/**
* @Annotation
* @Target({"PROPERTY","ANNOTATION"})
*/
final class JoinTable implements Annotation
{
/** @var string */
public $name;
/** @var string */
public $schema;
/** @var array<\Doctrine\ORM\Mapping\JoinColumn> */
public $joinColumns = array();
/** @var array<\Doctrine\ORM\Mapping\JoinColumn> */
public $inverseJoinColumns = array();
}
+42
View File
@@ -0,0 +1,42 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping;
/**
* @Annotation
* @Target("PROPERTY")
*/
final class ManyToMany implements Annotation
{
/** @var string */
public $targetEntity;
/** @var string */
public $mappedBy;
/** @var string */
public $inversedBy;
/** @var array<string> */
public $cascade;
/** @var string */
public $fetch = 'LAZY';
/** @var boolean */
public $orphanRemoval = false;
/** @var string */
public $indexBy;
}
+36
View File
@@ -0,0 +1,36 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping;
/**
* @Annotation
* @Target("PROPERTY")
*/
final class ManyToOne implements Annotation
{
/** @var string */
public $targetEntity;
/** @var array<string> */
public $cascade;
/** @var string */
public $fetch = 'LAZY';
/** @var string */
public $inversedBy;
}
@@ -0,0 +1,30 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping;
/**
* @Annotation
* @Target("CLASS")
*/
final class MappedSuperclass implements Annotation
{
/** @var string */
public $repositoryClass;
}
+227 -16
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 (null !== ($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)
@@ -48,9 +58,9 @@ class MappingException extends \Doctrine\ORM\ORMException
return new self("Id generators can't be used with a composite id.");
}
public static function missingFieldName()
public static function missingFieldName($entity)
{
return new self("The association mapping misses the 'fieldName' attribute.");
return new self("The field or association mapping misses the 'fieldName' attribute in entity '$entity'.");
}
public static function missingTargetEntity($fieldName)
@@ -68,9 +78,71 @@ class MappingException extends \Doctrine\ORM\ORMException
return new self("No mapping file found named '$fileName' for class '$entityName'.");
}
public static function mappingNotFound($fieldName)
/**
* 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("No mapping found for field '$fieldName'.");
return new self("Invalid field override named '$fieldName' for class '$className'.");
}
/**
* Exception for invalid property type override.
*
* @param string $className The entity's name
* @param string $fieldName
*/
public static function invalidOverrideFieldType($className, $fieldName)
{
return new self("The column type of attribute '$fieldName' on class '$className' could not be changed.");
}
public static function mappingNotFound($className, $fieldName)
{
return new self("No mapping found for field '$fieldName' on class '$className'.");
}
public static function queryNotFound($className, $queryName)
{
return new self("No query found named '$queryName' on class '$className'.");
}
public static function resultMappingNotFound($className, $resultName)
{
return new self("No result set mapping found named '$resultName' on class '$className'.");
}
public static function emptyQueryMapping($entity, $queryName)
{
return new self('Query named "'.$queryName.'" in "'.$entity.'" could not be empty.');
}
public static function nameIsMandatoryForQueryMapping($className)
{
return new self("Query name on entity class '$className' is not defined.");
}
public static function missingQueryMapping($entity, $queryName)
{
return new self('Query named "'.$queryName.'" in "'.$entity.' requires a result class or result set mapping.');
}
public static function missingResultSetMappingEntity($entity, $resultName)
{
return new self('Result set mapping named "'.$resultName.'" in "'.$entity.' requires a entity class name.');
}
public static function missingResultSetMappingFieldName($entity, $resultName)
{
return new self('Result set mapping named "'.$resultName.'" in "'.$entity.' requires a field name.');
}
public static function nameIsMandatoryForSqlResultSetMapping($className)
{
return new self("Result set mapping name on entity class '$className' is not defined.");
}
public static function oneToManyRequiresMappedBy($fieldName)
@@ -134,7 +206,17 @@ class MappingException extends \Doctrine\ORM\ORMException
public static function classIsNotAValidEntityOrMappedSuperClass($className)
{
return new self('Class '.$className.' is not a valid entity or mapped super class.');
if (null !== ($parent = get_parent_class($className))) {
return new self(sprintf(
'Class "%s" sub class of "%s" is not a valid entity or mapped super class.',
$className, $parent
));
}
return new self(sprintf(
'Class "%s" is not a valid entity or mapped super class.',
$className
));
}
public static function propertyTypeIsRequired($className, $propertyName)
@@ -148,23 +230,36 @@ class MappingException extends \Doctrine\ORM\ORMException
}
/**
*
* @param string $entity The entity's name
* @param string $fieldName The name of the field that was already declared
*/
public static function duplicateFieldMapping($entity, $fieldName) {
public static function duplicateFieldMapping($entity, $fieldName)
{
return new self('Property "'.$fieldName.'" in "'.$entity.'" was already declared, but it must be declared only once');
}
public static function duplicateAssociationMapping($entity, $fieldName) {
public static function duplicateAssociationMapping($entity, $fieldName)
{
return new self('Property "'.$fieldName.'" in "'.$entity.'" was already declared, but it must be declared only once');
}
public static function singleIdNotAllowedOnCompositePrimaryKey($entity) {
public static function duplicateQueryMapping($entity, $queryName)
{
return new self('Query named "'.$queryName.'" in "'.$entity.'" was already declared, but it must be declared only once');
}
public static function duplicateResultSetMapping($entity, $resultName)
{
return new self('Result set mapping named "'.$resultName.'" in "'.$entity.'" was already declared, but it must be declared only once');
}
public static function singleIdNotAllowedOnCompositePrimaryKey($entity)
{
return new self('Single id is not allowed on composite primary key in entity '.$entity);
}
public static function unsupportedOptimisticLockingType($entity, $fieldName, $unsupportedType) {
public static function unsupportedOptimisticLockingType($entity, $fieldName, $unsupportedType)
{
return new self('Locking type "'.$unsupportedType.'" (specified in "'.$entity.'", field "'.$fieldName.'") '
.'is not supported by Doctrine.'
);
@@ -175,7 +270,7 @@ class MappingException extends \Doctrine\ORM\ORMException
if ( ! empty($path)) {
$path = '[' . $path . ']';
}
return new self(
'File mapping drivers must have a valid directory path, ' .
'however the given path ' . $path . ' seems to be incorrect!'
@@ -190,13 +285,25 @@ class MappingException extends \Doctrine\ORM\ORMException
* @param string $owningClass The class that declares the discriminator map.
* @return self
*/
public static function invalidClassInDiscriminatorMap($className, $owningClass) {
public static function invalidClassInDiscriminatorMap($className, $owningClass)
{
return new self(
"Entity class '$className' used in the discriminator map of class '$owningClass' ".
"does not exist."
);
}
public static function duplicateDiscriminatorEntry($className, array $entries, array $map)
{
return new self(
"The entries " . implode(', ', $entries) . " in discriminator map of class '" . $className . "' is duplicated. " .
"If the discriminator map is automatically generated you have to convert it to an explicit discriminator map now. " .
"The entries of the current map are: @DiscriminatorMap({" . implode(', ', array_map(
function($a, $b) { return "'$a': '$b'"; }, array_keys($map), array_values($map)
)) . "})"
);
}
public static function missingDiscriminatorMap($className)
{
return new self("Entity class '$className' is using inheritance but no discriminator map was defined.");
@@ -212,11 +319,21 @@ class MappingException extends \Doctrine\ORM\ORMException
return new self("Discriminator column type on entity class '$className' is not allowed to be '$type'. 'string' or 'integer' type variables are suggested!");
}
public static function nameIsMandatoryForDiscriminatorColumns($className)
{
return new self("Discriminator column name on entity class '$className' is not defined.");
}
public static function cannotVersionIdField($className, $fieldName)
{
return new self("Setting Id field '$fieldName' as versionale in entity class '$className' is not supported.");
}
public static function sqlConversionNotAllowedForIdentifiers($className, $fieldName, $type)
{
return new self("It is not possible to set id field '$fieldName' to type '$type' in entity class '$className'. The type '$type' requires conversion SQL which is not allowed for identifiers.");
}
/**
* @param string $className
* @param string $columnName
@@ -227,4 +344,98 @@ class MappingException extends \Doctrine\ORM\ORMException
return new self("Duplicate definition of column '".$columnName."' on entity '".$className."' in a field or discriminator column mapping.");
}
}
public static function illegalToManyAssocationOnMappedSuperclass($className, $field)
{
return new self("It is illegal to put an inverse side one-to-many or many-to-many association on mapped superclass '".$className."#".$field."'.");
}
/**
* @param string $className
* @param string $targetEntity
* @param string $targetField
* @return self
*/
public static function cannotMapCompositePrimaryKeyEntitiesAsForeignId($className, $targetEntity, $targetField)
{
return new self("It is not possible to map entity '".$className."' with a composite primary key ".
"as part of the primary key of another entity '".$targetEntity."#".$targetField."'.");
}
public static function noSingleAssociationJoinColumnFound($className, $field)
{
return new self("'$className#$field' is not an association with a single join column.");
}
public static function noFieldNameFoundForColumn($className, $column)
{
return new self("Cannot find a field on '$className' that is mapped to column '$column'. Either the ".
"field does not exist or an association exists but it has multiple join columns.");
}
public static function illegalOrphanRemovalOnIdentifierAssociation($className, $field)
{
return new self("The orphan removal option is not allowed on an association that is ".
"part of the identifier in '$className#$field'.");
}
public static function illegalOrphanRemoval($className, $field)
{
return new self("Orphan removal is only allowed on one-to-one and one-to-many ".
"associations, but " . $className."#" .$field . " is not.");
}
public static function illegalInverseIdentifierAssocation($className, $field)
{
return new self("An inverse association is not allowed to be identifier in '$className#$field'.");
}
public static function illegalToManyIdentifierAssoaction($className, $field)
{
return new self("Many-to-many or one-to-many associations are not allowed to be identifier in '$className#$field'.");
}
public static function noInheritanceOnMappedSuperClass($className)
{
return new self("Its not supported to define inheritance information on a mapped superclass '" . $className . "'.");
}
public static function mappedClassNotPartOfDiscriminatorMap($className, $rootClassName)
{
return new self(
"Entity '" . $className . "' has to be part of the discriminator map of '" . $rootClassName . "' " .
"to be properly mapped in the inheritance hierachy. Alternatively you can make '".$className."' an abstract class " .
"to avoid this exception from occuring."
);
}
public static function lifecycleCallbackMethodNotFound($className, $methodName)
{
return new self("Entity '" . $className . "' has no method '" . $methodName . "' to be registered as lifecycle callback.");
}
public static function invalidFetchMode($className, $annotation)
{
return new self("Entity '" . $className . "' has a mapping with invalid fetch mode '" . $annotation . "'");
}
public static function compositeKeyAssignedIdGeneratorRequired($className)
{
return new self("Entity '". $className . "' has a composite identifier but uses an ID generator other than manually assigning (Identity, Sequence). This is not supported.");
}
public static function invalidTargetEntityClass($targetEntity, $sourceEntity, $associationName)
{
return new self("The target-entity " . $targetEntity . " cannot be found in '" . $sourceEntity."#".$associationName."'.");
}
public static function invalidCascadeOption(array $cascades, $className, $propertyName)
{
$cascades = implode(", ", array_map(function ($e) { return "'" . $e . "'"; }, $cascades));
return new self(sprintf(
"You have specified invalid cascade options for %s::$%s: %s; available options: 'remove', 'persist', 'refresh', 'merge', and 'detach'",
$className,
$propertyName,
$cascades
));
}
}
@@ -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();
}
@@ -0,0 +1,63 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping;
/**
* Is used to specify a native SQL named query.
* The NamedNativeQuery annotation can be applied to an entity or mapped superclass.
*
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
* @since 2.3
*
* @Annotation
* @Target("ANNOTATION")
*/
final class NamedNativeQuery implements Annotation
{
/**
* The name used to refer to the query with the EntityManager methods that create query objects.
*
* @var string
*/
public $name;
/**
* The SQL query string.
*
* @var string
*/
public $query;
/**
* The class of the result.
*
* @var string
*/
public $resultClass;
/**
* The name of a SqlResultSetMapping, as defined in metadata.
*
* @var string
*/
public $resultSetMapping;
}
+30
View File
@@ -0,0 +1,30 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping;
/**
* @Annotation
* @Target("CLASS")
*/
final class NamedQueries implements Annotation
{
/** @var array<\Doctrine\ORM\Mapping\NamedQuery> */
public $value;
}
+32
View File
@@ -0,0 +1,32 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping;
/**
* @Annotation
* @Target("ANNOTATION")
*/
final class NamedQuery implements Annotation
{
/** @var string */
public $name;
/** @var string */
public $query;
}
@@ -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);
}
+40
View File
@@ -0,0 +1,40 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping;
/**
* @Annotation
* @Target("PROPERTY")
*/
final class OneToMany implements Annotation
{
/** @var string */
public $mappedBy;
/** @var string */
public $targetEntity;
/** @var array<string> */
public $cascade;
/** @var string */
public $fetch = 'LAZY';
/** @var boolean */
public $orphanRemoval = false;
/** @var string */
public $indexBy;
}
+40
View File
@@ -0,0 +1,40 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping;
/**
* @Annotation
* @Target("PROPERTY")
*/
final class OneToOne implements Annotation
{
/** @var string */
public $targetEntity;
/** @var string */
public $mappedBy;
/** @var string */
public $inversedBy;
/** @var array<string> */
public $cascade;
/** @var string */
public $fetch = 'LAZY';
/** @var boolean */
public $orphanRemoval = false;
}

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