Compare commits

...

81 Commits
2.1.3 ... 2.1.7

Author SHA1 Message Date
Benjamin Eberlei
03d2b0f30c Release 2.1.7 2012-05-28 00:01:53 +02:00
Benjamin Eberlei
5544895cf9 Fix a bunch of tests for Oracle 2012-05-27 23:59:32 +02:00
Benjamin Eberlei
6af72006e4 Bump DBAL to 2.1.7 2012-05-27 21:19:53 +02:00
Benjamin Eberlei
fd76138a56 [DDC-1770] Fix multiple SingleTableInheritance in FROM clause in 2.1.x, was fixed in 2.2 already. 2012-05-27 19:57:59 +02:00
Karsten Dambekalns
1364f23d8c [DDC-1835] Fix clone side effects in PersistentCollection 2012-05-27 10:18:28 +02:00
Benjamin Eberlei
681d3ef45a Merge branch 'DDC-1799' into 2.1.x 2012-05-27 10:00:59 +02:00
Benjamin Eberlei
53c08b59b5 [DDC-1799] Fix bug in YamlExporter using OneToOne instead of ManyToOne 2012-05-27 10:00:19 +02:00
Benjamin Eberlei
07ee8c5249 Merge remote-tracking branch 'origin/2.1.x' into 2.1.x 2012-04-16 18:51:34 +02:00
Tiago Ribeiro
0c69f4ea9c Fixes autoloading of generated Annotations 2012-04-16 18:51:18 +02:00
Benjamin Eberlei
57acceaff2 Merge pull request #326 from Netpositive/2.1.x
2.1.x setDiscriminatorMap fix
2012-04-07 00:47:23 -07:00
Somfai Mátyás
7d3fee59bc Fixing a bug when calling setDiscriminatorMap from multiple sources (ie: from Events::loadClassMetadata and annotation). 2012-04-04 14:44:28 +02:00
Benjamin Eberlei
cab10eb96d Merge pull request #280 from rivaros/DC-1648
Fix for DDC-1648
2012-03-14 13:35:25 -07:00
Benjamin Eberlei
3f0a148dc2 Merge branch 'DDC-1683' into 2.1.x 2012-03-14 20:51:35 +01:00
Benjamin Eberlei
134ea63849 [DDC-1683] Fix bug with booleans not handled by Expr#literal() in query builder. 2012-03-14 20:50:51 +01:00
Benjamin Eberlei
39d0b14bdb Merge branch 'DDC-1695' into 2.1.x 2012-03-11 23:34:15 +01:00
Benjamin Eberlei
22cebf9880 [DDC-1695] Fix bug in SQL Walker array hydration with escaped fields. 2012-03-11 23:33:54 +01:00
rivaros
015cbc46be Convention fix 2012-03-05 10:29:06 +02:00
Benjamin Eberlei
734629af08 Merge branch 'DDC-1678' into 2.1.x 2012-03-03 22:18:55 +01:00
Benjamin Eberlei
e47b5a2b28 DDC-1678 - Adjust test to run on 2.1.x 2012-03-03 22:18:45 +01:00
Francisco Facioni
5152c48ce3 UnitTest for ManyToMany update notification 2012-03-03 22:17:24 +01:00
Francisco Facioni
92028473f0 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-03-03 22:17:24 +01:00
Benjamin Eberlei
3e7c9a1ff4 Merge branch 'DDC-1659' into 2.1.x 2012-02-20 09:40:30 +01:00
Benjamin Eberlei
e6b994eecc [DDC-1659] Remove test for functionality in the higher versions. 2012-02-20 09:40:16 +01:00
Benjamin Eberlei
e094c93035 [DDC-1659] Remove read only marker when clearing entities. 2012-02-20 09:39:17 +01:00
Benjamin Eberlei
c98cc258e8 Merge branch 'DDC-1643' into 2.1.x 2012-02-18 00:48:13 +01:00
Benjamin Eberlei
53bb7e36e3 [DDC-1643] Fix bugs when cloning PersistentCollection and re-using it. 2012-02-18 00:47:33 +01:00
Rivaros
490bdd23f7 convention fixes #2 2012-02-13 16:39:46 +02:00
Rivaros
0805f69101 Convention fixes 2012-02-13 15:05:28 +02:00
Rivaros
9503cf6ff6 Primary Keys as Foreign Keys - reverse engineering 2012-02-13 11:35:55 +02:00
Benjamin Eberlei
affa6feb8a DDC-1594 - Fix merge error 2012-02-10 20:46:27 +01:00
Benjamin Eberlei
061ea2b337 Bump dev version to 2.1.7 2012-01-29 17:53:01 +01:00
Benjamin Eberlei
e1647229cd Release 2.1.6 2012-01-29 17:53:01 +01:00
Benjamin Eberlei
9111d794d5 Bump build commons 2012-01-29 17:52:52 +01:00
Benjamin Eberlei
34ec1e3248 Bump dev version to 2.1.6 2012-01-29 17:51:45 +01:00
Benjamin Eberlei
3c52fa5ea6 Release 2.1.6 2012-01-29 17:51:45 +01:00
Benjamin Eberlei
b3ed478fb4 Merge remote branch 'origin/2.1.x' into 2.1.x 2012-01-29 16:49:39 +00:00
Benjamin Eberlei
c5973f8019 Bump dependencies 2012-01-29 16:48:50 +00:00
Benjamin Eberlei
6512902eae Maximum version in PEAR packages. 2012-01-29 17:39:28 +01:00
Benjamin Eberlei
798a8bca92 Merge branch 'DDC-1526' into 2.1.x 2012-01-28 12:26:02 +01:00
Benjamin Eberlei
7bca37e827 [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:25:01 +01:00
armetiz
818a5d5904 Update lib/Doctrine/ORM/Tools/SchemaTool.php 2012-01-25 22:40:59 +01:00
Benjamin Eberlei
20ac6f383c Merge branch 'DDC-1619' into 2.1.x 2012-01-25 10:29:13 +01:00
Benjamin Eberlei
60d97e068c [DDC-1619] Add QueryBuilder#distinct 2012-01-25 10:28:24 +01:00
Benjamin Eberlei
94162d1c03 Merge pull request #271 from sonata-project/2.1.x
DDC-1618 - Query::Iterate() with fetch join exception but no associaiton selected
2012-01-24 14:59:31 -08:00
Thomas Rabaix
1c042b5b8d Add SqlWalker::HINT_DISTINCT constant 2012-01-24 23:34:20 +01:00
Thomas Rabaix
b770a6687a Fix DDC-1618 - add more check before throwing an iterateWithFetchJoinNotAllowed exception 2012-01-24 23:16:51 +01:00
Benjamin Eberlei
0abf2484ce Merge branch 'DDC-1603' into 2.1.x 2012-01-21 15:37:48 +01:00
armetiz
7d8aa2213d Unique key name isn't correctly set - DDC-1603 2012-01-21 15:37:20 +01:00
Benjamin Eberlei
12a639d4a2 Merge branch 'DDC-1594' into 2.1.x 2012-01-15 17:46:41 +01:00
Benjamin Eberlei
432a035baa DDC-1594 - Fix problem with merge and an existing managed proxy instance. 2012-01-15 17:46:19 +01:00
Benjamin Eberlei
97df2f8749 Fix notice when using regenerate if exists and file is not new. 2012-01-12 11:21:16 +01:00
Benjamin Eberlei
61aec8fdcd DDC-1589 - Remove mbstring dependency from Composite 2012-01-09 14:34:31 +01:00
Adrien BRAULT
292fbd9756 Fix some PHPDoc @return type. 2011-12-28 08:50:33 +01:00
Benjamin Eberlei
c2112c0584 Fix PEAR Path 2011-12-20 21:56:37 +01:00
Benjamin Eberlei
05c7e0055a Bump dev version to 2.1.6 2011-12-19 19:27:40 +01:00
Benjamin Eberlei
fb7b5c6fb1 Bump dev version to 2.1.5 2011-12-19 19:27:12 +01:00
Benjamin Eberlei
da0e3439ab Release 2.1.5 2011-12-19 19:27:12 +01:00
Benjamin Eberlei
a1df81e18c Merge build-commons back into 2.1.x 2011-12-19 19:19:43 +01:00
Guilherme Blanco
1dea57013c Cherry-pick fix for DDC-1548 2011-12-19 18:49:14 +01:00
Benjamin Eberlei
91b1a25bb2 Add DDC-1545 Test 2011-12-19 18:13:11 +01:00
Benjamin Eberlei
473ba2f04c 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 18:10:33 +01:00
Benjamin Eberlei
e80eae4c98 DDC-1514 - Fix complex self-referencing + proxy hydration problem. 2011-12-15 23:00:34 +01:00
Benjamin Eberlei
68184a3803 DDC-1519 - Merge fix 2011-12-15 20:59:11 +01:00
Deni
3412ef935a Fixed typo in the XmlDriver 2011-12-15 20:16:40 +01:00
Benjamin Eberlei
4215a24969 Merge branch 'DDC-1520' into 2.1.x 2011-12-13 21:34:13 +01:00
Benjamin Eberlei
02d8802570 Bugfix in UnitOfWorklib/Doctrine/ORM/UnitOfWork.phptriggerEagerLoads() 2011-12-13 21:32:10 +01:00
Benjamin Eberlei
0e107880cf DDC-1527 - Fix bug with complex type handling in repositories 2011-12-12 16:20:46 +01:00
Guilherme Blanco
3b259dcb42 Merge pull request #215 from andrewmackrodt/2.1.x
2.1.x
2011-12-11 13:00:41 -08:00
Andrew Mackrodt
d87e90d392 Added absolute namespace paths to phpdoc annotations - issue DDC-1025. 2011-12-11 20:52:29 +00:00
Benjamin Eberlei
c1ad170bed DDC-1515 - Now the real bugfix 2011-12-11 20:22:11 +01:00
Benjamin Eberlei
565962ec8b Revert "DDC-1515 - Bugfix in hydration of dependant entities without additional fields."
This reverts commit d9b39f6fce.
2011-12-11 16:34:34 +01:00
Benjamin Eberlei
eb9812feb5 Merge branch 'DDC-1515' into 2.1.x 2011-12-11 16:02:13 +01:00
Benjamin Eberlei
d9b39f6fce DDC-1515 - Bugfix in hydration of dependant entities without additional fields. 2011-12-11 16:01:36 +01:00
Benjamin Eberlei
b1db2ad0d8 Merge branch 'DDC-1512' into 2.1.x 2011-11-28 11:18:45 +01:00
Benjamin Eberlei
92b3d0a383 DDC-1512 - Adjustment for 2.1.x branch 2011-11-28 11:18:30 +01:00
Benjamin Eberlei
fc8997a935 DDC-1512 - Make ClassMetadataFactory::isTransient() entity namespace aware. 2011-11-28 11:17:30 +01:00
Benjamin Eberlei
88d937cc89 Bump Dev Version to 2.1.5-DEV 2011-11-23 19:44:51 +00:00
Benjamin Eberlei
bff55577cd Release 2.1.4 2011-11-23 19:44:26 +00:00
Benjamin Eberlei
7ff30e273a Merge branch 'DDC-1509' into 2.1.x 2011-11-23 20:38:58 +01:00
Benjamin Eberlei
9c81989349 DDC-1509 - Fix regression in doMerge() introduced with the DDC-1383 bugfix 2011-11-23 20:37:37 +01:00
Benjamin Eberlei
e0bb84e1da Bump Dev Version to 2.1.4-DEV 2011-11-21 15:08:18 +00:00
74 changed files with 1937 additions and 588 deletions

1
.gitignore vendored
View File

@@ -1,4 +1,3 @@
build.properties
build/
logs/
reports/

3
.gitmodules vendored
View File

@@ -10,3 +10,6 @@
[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 = https://github.com/doctrine/doctrine-build-common.git

11
build.properties Normal file
View File

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

View File

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

221
build.xml
View File

@@ -1,11 +1,7 @@
<?xml version="1.0"?>
<!--
Doctrine 2 build file.
-->
<project name="Doctrine2" default="build" basedir=".">
<project name="DoctrineORM" default="build" basedir=".">
<taskdef classname="phing.tasks.ext.d51PearPkg2Task" name="d51pearpkg2" />
<import file="${project.basedir}/lib/vendor/doctrine-build-common/packaging.xml" />
<property file="build.properties" />
@@ -14,6 +10,8 @@
-->
<fileset id="shared-artifacts" dir=".">
<include name="LICENSE"/>
<include name="UPGRADE*" />
<include name="doctrine-mapping.xsd" />
</fileset>
<!--
@@ -51,118 +49,34 @@
-->
<fileset id="symfony-sources" dir="./lib/vendor">
<include name="Symfony/Component/**"/>
<exclude name="**/.git/**" />
</fileset>
<!--
Clean the directory for the next build.
-->
<target name="clean">
<available file="./build.properties" property="build_properties_exist" value="true"/>
<fail unless="build_properties_exist" message="The build.properties file is missing." />
<delete dir="${build.dir}" includeemptydirs="true" />
<delete dir="${dist.dir}" includeemptydirs="true" />
<delete dir="${report.dir}" includeemptydirs="true" />
</target>
<!--
Prepare the new build directories after cleaning
-->
<target name="prepare" depends="clean">
<echo msg="Creating build directory: ${build.dir}" />
<mkdir dir="${build.dir}" />
<echo msg="Creating distribution directory: ${dist.dir}" />
<mkdir dir="${dist.dir}" />
<echo msg="Creating report directory: ${report.dir}" />
<mkdir dir="${report.dir}" />
<mkdir dir="${build.dir}/logs"/>
<mkdir dir="${report.dir}/tests"/>
</target>
<!--
Builds ORM package, preparing it for distribution.
-->
<target name="build-orm" depends="prepare">
<exec command="grep '${version}' ${project.basedir}/lib/Doctrine/ORM/Version.php" checkreturn="true"/>
<copy todir="${build.dir}/doctrine-orm">
<target name="copy-files" depends="prepare">
<copy todir="${build.dir}/${project.name}-${version}">
<fileset refid="shared-artifacts"/>
</copy>
<copy todir="${build.dir}/doctrine-orm">
<copy todir="${build.dir}/${project.name}-${version}">
<fileset refid="common-sources"/>
<fileset refid="dbal-sources"/>
<fileset refid="orm-sources"/>
</copy>
<copy todir="${build.dir}/doctrine-orm/Doctrine">
<copy todir="${build.dir}/${project.name}-${version}/Doctrine">
<fileset refid="symfony-sources"/>
</copy>
<copy todir="${build.dir}/doctrine-orm/bin">
<copy todir="${build.dir}/${project.name}-${version}/bin">
<fileset refid="bin-scripts"/>
</copy>
<exec command="sed 's/${version}-DEV/${version}/' ${build.dir}/doctrine-orm/Doctrine/ORM/Version.php > ${build.dir}/doctrine-orm/Doctrine/ORM/Version2.php" passthru="true" />
<exec command="mv ${build.dir}/doctrine-orm/Doctrine/ORM/Version2.php ${build.dir}/doctrine-orm/Doctrine/ORM/Version.php" passthru="true" />
<delete dir="${build.dir}/doctrine-orm/Doctrine/Symfony/Component/Yaml/.git" includeemptydirs="true"/>
<delete dir="${build.dir}/doctrine-orm/Doctrine/Symfony/Component/Console/.git" includeemptydirs="true"/>
</target>
<target name="build" depends="test, build-orm"/>
<target name="package-phar" depends="build-orm">
<pharpackage basedir="${build.dir}/doctrine-orm/" destfile="${dist.dir}/doctrine-orm-${version}.phar" clistub="${build.dir}/doctrine-orm/bin/doctrine.php" signature="sha512">
<fileset dir="${build.dir}/doctrine-orm">
<include name="**/**" />
</fileset>
<metadata>
<element name="version" value="${version}" />
<element name="authors">
<element name="Guilherme Blanco"><element name="e-mail" value="guilhermeblanco@gmail.com" /></element>
<element name="Benjamin Eberlei"><element name="e-mail" value="kontakt@beberlei.de" /></element>
<element name="Jonathan H. Wage"><element name="e-mail" value="jonwage@gmail.com" /></element>
<element name="Roman Borschel"><element name="e-mail" value="roman@code-factory.org" /></element>
</element>
</metadata>
</pharpackage>
</target>
<!--
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>
@@ -172,124 +86,29 @@
<lead user="romanb" name="Roman Borschel" email="roman@code-factory.org" />
<lead user="beberlei" name="Benjamin Eberlei" email="kontakt@beberlei.de" />
<license>LGPL</license>
<version release="${version}" api="${version}" />
<stability release="${stability}" api="${stability}" />
<version release="${pear.version}" api="${pear.version}" />
<stability release="${pear.stability}" api="${pear.stability}" />
<notes>-</notes>
<dependencies>
<php minimum_version="5.3.0" />
<pear minimum_version="1.6.0" recommended_version="1.6.1" />
<package name="DoctrineCommon" channel="pear.doctrine-project.org" minimum_version="${dependencies.common}" />
<package name="DoctrineDBAL" channel="pear.doctrine-project.org" minimum_version="${dependencies.dbal}" />
<package name="DoctrineSymfonyConsole" channel="pear.doctrine-project.org" minimum_version="2.0.0" />
<package name="DoctrineSymfonyYaml" channel="pear.doctrine-project.org" minimum_version="2.0.0" />
<package name="DoctrineCommon" channel="pear.doctrine-project.org" minimum_version="${dependencies.common}" maximum_version="2.1.99" />
<package name="DoctrineDBAL" channel="pear.doctrine-project.org" minimum_version="${dependencies.dbal}" maximum_version="2.1.99" />
<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/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.bat" name="bin/doctrine.bat" />
</release>
<replacement path="bin/doctrine.bat" type="pear-config" from="@php_bin@" to="php_bin" />
<replacement path="bin/doctrine" type="pear-config" from="@php_bin@" to="php_bin" />
<replacement path="bin/doctrine.bat" type="pear-config" from="@bin_dir@" to="bin_dir" />
</d51pearpkg2>
<exec command="pear package" dir="${build.dir}/doctrine-orm" passthru="true" />
<exec command="mv DoctrineORM-${version}.tgz ../../dist" dir="${build.dir}/doctrine-orm" passthru="true" />
<tar destfile="dist/DoctrineORM-${version}-full.tar.gz" compression="gzip" basedir="${build.dir}">
<fileset dir="${build.dir}">
<include name="**/**" />
<exclude name="logs/" />
<exclude name="doctrine-orm/package.xml" />
</fileset>
</tar>
</target>
<target name="git-tag">
<exec command="grep '${version}-DEV' ${project.basedir}/lib/Doctrine/ORM/Version.php" checkreturn="true"/>
<exec command="sed 's/${version}-DEV/${version}/' ${project.basedir}/lib/Doctrine/ORM/Version.php > ${project.basedir}/lib/Doctrine/ORM/Version2.php" passthru="true" />
<exec command="mv ${project.basedir}/lib/Doctrine/ORM/Version2.php ${project.basedir}/lib/Doctrine/ORM/Version.php" passthru="true" />
<exec command="git add ${project.basedir}/lib/Doctrine/ORM/Version.php" passthru="true" />
<exec command="git commit -m 'Release ${version}'" />
<exec command="git tag -m 'Tag ${version}' -a ${version}" passthru="true" />
</target>
<target name="pirum-release">
<exec command="sudo pirum add ${project.pirum_dir} ${project.basedir}/dist/DoctrineORM-${version}.tgz" dir="." passthru="true" />
<exec command="sudo pirum build ${project.pirum_dir}" passthru="true" />
</target>
<target name="distribute-download">
<copy file="dist/DoctrineORM-${version}-full.tar.gz" todir="${project.download_dir}" />
<copy file="${dist.dir}/doctrine-orm-${version}.phar" todir="${project.download_dir}" />
</target>
<target name="update-dev-version">
<exec command="grep '${version}' ${project.basedir}/lib/Doctrine/ORM/Version.php" checkreturn="true"/>
<propertyprompt propertyName="next_version" defaultValue="${version}" promptText="Enter next version string (without -DEV)" />
<exec command="sed 's/${version}/${next_version}-DEV/' ${project.basedir}/lib/Doctrine/ORM/Version.php > ${project.basedir}/lib/Doctrine/ORM/Version2.php" passthru="true" />
<exec command="mv ${project.basedir}/lib/Doctrine/ORM/Version2.php ${project.basedir}/lib/Doctrine/ORM/Version.php" passthru="true" />
<exec command="git add ${project.basedir}/lib/Doctrine/ORM/Version.php" passthru="true" />
<exec command="git commit -m 'Bump Dev Version to ${next_version}-DEV'" passthru="true" />
</target>
<target name="release" depends="git-tag,build-packages,package-phar,distribute-download,pirum-release,update-dev-version" />
<!--
Builds distributable PEAR packages for the Symfony Dependencies
-->
<target name="release-symfony-dependencies" depends="build-orm">
<d51pearpkg2 baseinstalldir="/" dir="${build.dir}/doctrine-orm">
<name>DoctrineSymfonyConsole</name>
<summary>Symfony Console Component</summary>
<channel>pear.doctrine-project.org</channel>
<description>A command line interface tool from the Symfony project. Packaged for shipping with Doctrine projects using ORM version numbers.</description>
<lead user="fabpot" name="Fabien Potencier" email="fabien.potencier@symfony-project.com" />
<license>NewBSD License</license>
<version release="${version}" api="${version}" />
<stability release="${stability}" api="${stability}" />
<notes>-</notes>
<dependencies>
<php minimum_version="5.3.0" />
<pear minimum_version="1.6.0" recommended_version="1.6.1" />
</dependencies>
<ignore>bin/</ignore>
<ignore>Doctrine/Common/</ignore>
<ignore>Doctrine/DBAL/</ignore>
<ignore>Doctrine/ORM/</ignore>
<ignore>Symfony/Component/Yaml/</ignore>
</d51pearpkg2>
<exec command="pear package" dir="${build.dir}/doctrine-orm" passthru="true" />
<exec command="mv DoctrineSymfonyConsole-${version}.tgz ../../dist" dir="${build.dir}/doctrine-orm" passthru="true" />
<d51pearpkg2 baseinstalldir="/" dir="${build.dir}/doctrine-orm">
<name>DoctrineSymfonyYaml</name>
<summary>Symfony Yaml Component</summary>
<channel>pear.doctrine-project.org</channel>
<description>A YAML Parser from the Symfony project. Packaged for shipping with Doctrine projects using ORM version numbers.</description>
<lead user="fabpot" name="Fabien Potencier" email="fabien.potencier@symfony-project.com" />
<license>NewBSD License</license>
<version release="${version}" api="${version}" />
<stability release="${stability}" api="${stability}" />
<notes>-</notes>
<dependencies>
<php minimum_version="5.3.0" />
<pear minimum_version="1.6.0" recommended_version="1.6.1" />
</dependencies>
<ignore>bin/</ignore>
<ignore>Doctrine/Common/</ignore>
<ignore>Doctrine/DBAL/</ignore>
<ignore>Doctrine/ORM/</ignore>
<ignore>Symfony/Component/Console/</ignore>
</d51pearpkg2>
<exec command="pear package" dir="${build.dir}/doctrine-orm" passthru="true" />
<exec command="mv DoctrineSymfonyYaml-${version}.tgz ../../dist" dir="${build.dir}/doctrine-orm" passthru="true" />
<exec command="sudo pirum add ${project.pirum_dir} ${project.basedir}/dist/DoctrineSymfonyConsole-${version}.tgz" dir="." passthru="true" />
<exec command="sudo pirum add ${project.pirum_dir} ${project.basedir}/dist/DoctrineSymfonyYaml-${version}.tgz" dir="." passthru="true" />
<exec command="sudo pirum build ${project.pirum_dir}" passthru="true" />
</target>
</project>

View File

@@ -1,6 +1,6 @@
{
"name": "doctrine/orm",
"type": "library",
"type": "library","version":"2.1.7",
"description": "Object-Relational-Mapper for PHP",
"keywords": ["orm", "database"],
"homepage": "http://www.doctrine-project.org",

View File

@@ -76,7 +76,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;
@@ -122,7 +122,7 @@ abstract class AbstractQuery
/**
* 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)
{
@@ -132,7 +132,7 @@ abstract class AbstractQuery
/**
* Retrieves the associated EntityManager of this Query instance.
*
* @return Doctrine\ORM\EntityManager
* @return \Doctrine\ORM\EntityManager
*/
public function getEntityManager()
{
@@ -212,7 +212,7 @@ 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)
{
@@ -231,7 +231,7 @@ abstract class AbstractQuery
*
* @param array $params
* @param array $types
* @return Doctrine\ORM\AbstractQuery This query instance.
* @return \Doctrine\ORM\AbstractQuery This query instance.
*/
public function setParameters(array $params, array $types = array())
{
@@ -249,7 +249,7 @@ abstract class AbstractQuery
* 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)
{
@@ -260,8 +260,8 @@ abstract class AbstractQuery
/**
* Defines a cache driver to be used for caching result sets.
*
* @param Doctrine\Common\Cache\Cache $driver Cache driver
* @return Doctrine\ORM\AbstractQuery
* @param \Doctrine\Common\Cache\Cache $driver Cache driver
* @return \Doctrine\ORM\AbstractQuery
*/
public function setResultCacheDriver($resultCacheDriver = null)
{
@@ -278,7 +278,7 @@ abstract class AbstractQuery
/**
* Returns the cache driver used for caching result sets.
*
* @return Doctrine\Common\Cache\Cache Cache driver
* @return \Doctrine\Common\Cache\Cache Cache driver
*/
public function getResultCacheDriver()
{
@@ -296,7 +296,7 @@ abstract class AbstractQuery
* @param boolean $bool
* @param integer $timeToLive
* @param string $resultCacheId
* @return Doctrine\ORM\AbstractQuery This query instance.
* @return \Doctrine\ORM\AbstractQuery This query instance.
*/
public function useResultCache($bool, $timeToLive = null, $resultCacheId = null)
{
@@ -314,7 +314,7 @@ abstract class AbstractQuery
* 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.
* @return \Doctrine\ORM\AbstractQuery This query instance.
*/
public function setResultCacheLifetime($timeToLive)
{
@@ -340,7 +340,7 @@ abstract class AbstractQuery
* 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)
{
@@ -383,7 +383,7 @@ abstract class AbstractQuery
*
* @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)
{
@@ -511,7 +511,7 @@ 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)
{
@@ -621,7 +621,7 @@ abstract class AbstractQuery
* generated for you.
*
* @param string $id
* @return Doctrine\ORM\AbstractQuery This query instance.
* @return \Doctrine\ORM\AbstractQuery This query instance.
*/
public function setResultCacheId($id)
{
@@ -667,7 +667,7 @@ abstract class AbstractQuery
/**
* 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();

View File

@@ -43,21 +43,21 @@ 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;
@@ -71,14 +71,14 @@ class EntityManager implements ObjectManager
/**
* 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;
@@ -92,14 +92,14 @@ class EntityManager implements ObjectManager
/**
* The proxy factory used to create dynamic proxies.
*
* @var Doctrine\ORM\Proxy\ProxyFactory
* @var \Doctrine\ORM\Proxy\ProxyFactory
*/
private $proxyFactory;
/**
* The expression builder instance used to generate query expressions.
*
* @var Doctrine\ORM\Query\Expr
* @var \Doctrine\ORM\Query\Expr
*/
private $expressionBuilder;
@@ -114,9 +114,9 @@ class EntityManager implements ObjectManager
* 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)
{
@@ -139,7 +139,7 @@ class EntityManager implements ObjectManager
/**
* Gets the database connection object used by the EntityManager.
*
* @return Doctrine\DBAL\Connection
* @return \Doctrine\DBAL\Connection
*/
public function getConnection()
{
@@ -149,7 +149,7 @@ class EntityManager implements ObjectManager
/**
* Gets the metadata factory used to gather the metadata of classes.
*
* @return Doctrine\ORM\Mapping\ClassMetadataFactory
* @return \Doctrine\ORM\Mapping\ClassMetadataFactory
*/
public function getMetadataFactory()
{
@@ -168,7 +168,7 @@ class EntityManager implements ObjectManager
* ->where($expr->orX($expr->eq('u.id', 1), $expr->eq('u.id', 2)));
* </code>
*
* @return Doctrine\ORM\Query\Expr
* @return \Doctrine\ORM\Query\Expr
*/
public function getExpressionBuilder()
{
@@ -249,7 +249,7 @@ class EntityManager implements ObjectManager
* MyProject\Domain\User
* sales:PriceRequest
*
* @return Doctrine\ORM\Mapping\ClassMetadata
* @return \Doctrine\ORM\Mapping\ClassMetadata
* @internal Performance-sensitive method.
*/
public function getClassMetadata($className)
@@ -261,7 +261,7 @@ class EntityManager implements ObjectManager
* Creates a new Query object.
*
* @param string The DQL string.
* @return Doctrine\ORM\Query
* @return \Doctrine\ORM\Query
*/
public function createQuery($dql = "")
{
@@ -276,7 +276,7 @@ class EntityManager implements ObjectManager
* Creates a Query from a named query.
*
* @param string $name
* @return Doctrine\ORM\Query
* @return \Doctrine\ORM\Query
*/
public function createNamedQuery($name)
{
@@ -302,7 +302,7 @@ class EntityManager implements ObjectManager
* Creates a NativeQuery from a named native query.
*
* @param string $name
* @return Doctrine\ORM\NativeQuery
* @return \Doctrine\ORM\NativeQuery
*/
public function createNamedNativeQuery($name)
{
@@ -325,7 +325,7 @@ class EntityManager implements ObjectManager
* 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
* @throws \Doctrine\ORM\OptimisticLockException If a version check on an entity that
* makes use of optimistic locking fails.
*/
public function flush()
@@ -601,7 +601,7 @@ class EntityManager implements ObjectManager
/**
* Gets the EventManager used by the EntityManager.
*
* @return Doctrine\Common\EventManager
* @return \Doctrine\Common\EventManager
*/
public function getEventManager()
{
@@ -611,7 +611,7 @@ class EntityManager implements ObjectManager
/**
* Gets the Configuration used by the EntityManager.
*
* @return Doctrine\ORM\Configuration
* @return \Doctrine\ORM\Configuration
*/
public function getConfiguration()
{
@@ -643,7 +643,7 @@ class EntityManager implements ObjectManager
/**
* Gets the UnitOfWork used by the EntityManager to coordinate operations.
*
* @return Doctrine\ORM\UnitOfWork
* @return \Doctrine\ORM\UnitOfWork
*/
public function getUnitOfWork()
{
@@ -657,7 +657,7 @@ class EntityManager implements ObjectManager
* selectively iterate over the result.
*
* @param int $hydrationMode
* @return Doctrine\ORM\Internal\Hydration\AbstractHydrator
* @return \Doctrine\ORM\Internal\Hydration\AbstractHydrator
*/
public function getHydrator($hydrationMode)
{
@@ -672,7 +672,7 @@ class EntityManager implements ObjectManager
* 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)
{

View File

@@ -48,7 +48,7 @@ class EntityRepository implements ObjectRepository
protected $_em;
/**
* @var Doctrine\ORM\Mapping\ClassMetadata
* @var \Doctrine\ORM\Mapping\ClassMetadata
*/
protected $_class;
@@ -112,7 +112,7 @@ class EntityRepository implements ObjectRepository
if (!($entity instanceof $this->_class->name)) {
return null;
}
if ($lockMode != LockMode::NONE) {
$this->_em->lock($entity, $lockMode, $lockVersion);
}
@@ -141,7 +141,7 @@ class EntityRepository implements ObjectRepository
if (!$this->_em->getConnection()->isTransactionActive()) {
throw TransactionRequiredException::transactionRequired();
}
return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->load($id, null, null, array(), $lockMode);
}
}
@@ -241,4 +241,4 @@ class EntityRepository implements ObjectRepository
{
return $this->_class;
}
}
}

View File

@@ -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);

View File

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

View File

@@ -58,7 +58,7 @@ 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)
{
@@ -216,8 +216,11 @@ abstract class AbstractHydrator
}
if (isset($cache[$key]['isMetaColumn'])) {
if (!isset($rowData[$dqlAlias][$cache[$key]['fieldName']]) || $value !== null) {
if ( ! isset($rowData[$dqlAlias][$cache[$key]['fieldName']]) && $value !== null) {
$rowData[$dqlAlias][$cache[$key]['fieldName']] = $value;
if ($cache[$key]['isIdentifier']) {
$nonemptyComponents[$dqlAlias] = true;
}
}
continue;
}

View File

@@ -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)
{

View File

@@ -24,7 +24,8 @@ use PDO,
Doctrine\ORM\PersistentCollection,
Doctrine\ORM\Query,
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.
@@ -320,6 +321,7 @@ 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;
@@ -361,13 +363,18 @@ class ObjectHydrator extends AbstractHydrator
// Update result pointer
$this->_resultPointers[$dqlAlias] = $reflFieldValue[$index];
}
} else if ( ! $reflField->getValue($parentObject)) {
} 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);
@@ -393,6 +400,8 @@ class ObjectHydrator extends AbstractHydrator
}
// Update result pointer
$this->_resultPointers[$dqlAlias] = $element;
} else {
$this->_uow->setOriginalEntityProperty($oid, $relationField, null);
}
// else leave $reflFieldValue null for single-valued associations
} else {

View File

@@ -85,7 +85,7 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
/**
* Sets the cache driver used by the factory to cache ClassMetadata instances.
*
* @param Doctrine\Common\Cache\Cache $cacheDriver
* @param \Doctrine\Common\Cache\Cache $cacheDriver
*/
public function setCacheDriver($cacheDriver)
{
@@ -95,7 +95,7 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
/**
* Gets the cache driver used by the factory to cache ClassMetadata instances.
*
* @return Doctrine\Common\Cache\Cache
* @return \Doctrine\Common\Cache\Cache
*/
public function getCacheDriver()
{
@@ -143,7 +143,7 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
* Gets the class metadata descriptor for a class.
*
* @param string $className The name of the class.
* @return Doctrine\ORM\Mapping\ClassMetadata
* @return \Doctrine\ORM\Mapping\ClassMetadata
*/
public function getMetadataFor($className)
{
@@ -370,7 +370,7 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
* Creates a new ClassMetadata instance for the given class name.
*
* @param string $className
* @return Doctrine\ORM\Mapping\ClassMetadata
* @return \Doctrine\ORM\Mapping\ClassMetadata
*/
protected function newClassMetadataInstance($className)
{
@@ -380,8 +380,8 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
/**
* 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)
{
@@ -402,8 +402,8 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
/**
* 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
*/
private function addInheritedRelations(ClassMetadata $subClass, ClassMetadata $parentClass)
{
@@ -430,7 +430,7 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
* 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 \Doctrine\ORM\Mapping\ClassMetadata $class
*/
private function completeIdGeneratorMapping(ClassMetadataInfo $class)
{
@@ -486,10 +486,18 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
/**
* {@inheritDoc}
*/
public function isTransient($className)
public function isTransient($class)
{
$this->initialize();
return $this->driver->isTransient($className);
if ( ! $this->initialized) {
$this->initialize();
}
// Check for namespace alias
if (strpos($class, ':') !== false) {
list($namespaceAlias, $simpleClassName) = explode(':', $class);
$class = $this->em->getConfiguration()->getEntityNamespace($namespaceAlias) . '\\' . $simpleClassName;
}
return $this->driver->isTransient($class);
}
}

View File

@@ -884,7 +884,9 @@ class ClassMetadataInfo implements ClassMetadata
foreach ($mapping['joinColumns'] as $key => &$joinColumn) {
if ($mapping['type'] === self::ONE_TO_ONE) {
if (count($mapping['joinColumns']) == 1) {
$joinColumn['unique'] = true;
if (! isset($mapping['id']) || ! $mapping['id']) {
$joinColumn['unique'] = true;
}
} else {
$uniqueContraintColumns[] = $joinColumn['name'];
}
@@ -1238,7 +1240,7 @@ class ClassMetadataInfo implements ClassMetadata
* Gets the type of a field.
*
* @param string $fieldName
* @return Doctrine\DBAL\Types\Type
* @return \Doctrine\DBAL\Types\Type
*/
public function getTypeOfField($fieldName)
{
@@ -1249,7 +1251,7 @@ class ClassMetadataInfo implements ClassMetadata
/**
* Gets the type of a column.
*
* @return Doctrine\DBAL\Types\Type
* @return \Doctrine\DBAL\Types\Type
*/
public function getTypeOfColumn($columnName)
{
@@ -1640,7 +1642,7 @@ class ClassMetadataInfo implements ClassMetadata
if ( ! class_exists($className)) {
throw MappingException::invalidClassInDiscriminatorMap($className, $this->name);
}
if (is_subclass_of($className, $this->name)) {
if (is_subclass_of($className, $this->name) && ! in_array($className, $this->subClasses)) {
$this->subClasses[] = $className;
}
}

View File

@@ -185,12 +185,13 @@ class DatabaseDriver implements Driver
$fieldMappings = array();
foreach ($columns as $column) {
$fieldMapping = array();
if ($primaryKeyColumns && in_array($column->getName(), $primaryKeyColumns)) {
$fieldMapping['id'] = true;
} else if (in_array($column->getName(), $allForeignKeyColumns)) {
if (in_array($column->getName(), $allForeignKeyColumns)) {
continue;
} else if ($primaryKeyColumns && in_array($column->getName(), $primaryKeyColumns)) {
$fieldMapping['id'] = true;
}
$fieldMapping['fieldName'] = $this->getFieldNameForColumn($tableName, $column->getName(), false);
$fieldMapping['columnName'] = $column->getName();
$fieldMapping['type'] = strtolower((string) $column->getType());
@@ -291,13 +292,23 @@ class DatabaseDriver implements Driver
$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(
'name' => $cols[$i],
'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);
}
}
}

View File

@@ -210,7 +210,7 @@ class XmlDriver extends AbstractFileDriver
$associationIds = array();
foreach ($xmlRoot->id as $idElement) {
if ((bool)$idElement['association-key'] == true) {
$associationIds[(string)$idElement['fieldName']] = true;
$associationIds[(string)$idElement['name']] = true;
continue;
}

View File

@@ -66,7 +66,7 @@ final class PersistentCollection implements Collection
/**
* The EntityManager that manages the persistence of the collection.
*
* @var Doctrine\ORM\EntityManager
* @var \Doctrine\ORM\EntityManager
*/
private $em;
@@ -265,7 +265,7 @@ final class PersistentCollection implements Collection
/**
* INTERNAL: Gets the association mapping of the collection.
*
* @return Doctrine\ORM\Mapping\AssociationMapping
* @return \Doctrine\ORM\Mapping\AssociationMapping
*/
public function getMapping()
{
@@ -280,7 +280,7 @@ final class PersistentCollection implements Collection
if ( ! $this->isDirty) {
$this->isDirty = true;
if ($this->association !== null && $this->association['isOwningSide'] && $this->association['type'] == ClassMetadata::MANY_TO_MANY &&
$this->em->getClassMetadata(get_class($this->owner))->isChangeTrackingNotify()) {
$this->owner && $this->em->getClassMetadata(get_class($this->owner))->isChangeTrackingNotify()) {
$this->em->getUnitOfWork()->scheduleForDirtyCheck($this->owner);
}
}
@@ -687,4 +687,28 @@ final class PersistentCollection implements Collection
$this->initialize();
return $this->coll->slice($offset, $length);
}
/**
* Cleanup internal state of cloned persistent collection.
*
* The following problems have to be prevented:
* 1. Added entities are added to old PC
* 2. New collection is not dirty, if reused on other entity nothing
* changes.
* 3. Snapshot leads to invalid diffs being generated.
* 4. Lazy loading grabs entities from old owner object.
* 5. New collection is connected to old owner and leads to duplicate keys.
*/
public function __clone()
{
if (is_object($this->coll)) {
$this->coll = clone $this->coll;
}
$this->initialize();
$this->owner = null;
$this->snapshot = array();
$this->changed();
}
}

View File

@@ -36,19 +36,19 @@ abstract class AbstractCollectionPersister
protected $_em;
/**
* @var Doctrine\DBAL\Connection
* @var \Doctrine\DBAL\Connection
*/
protected $_conn;
/**
* @var Doctrine\ORM\UnitOfWork
* @var \Doctrine\ORM\UnitOfWork
*/
protected $_uow;
/**
* Initializes a new instance of a class derived from AbstractCollectionPersister.
*
* @param Doctrine\ORM\EntityManager $em
* @param \Doctrine\ORM\EntityManager $em
*/
public function __construct(EntityManager $em)
{
@@ -194,4 +194,4 @@ abstract class AbstractCollectionPersister
* @param mixed $element
*/
abstract protected function _getInsertRowSQLParameters(PersistentCollection $coll, $element);
}
}

View File

@@ -78,28 +78,28 @@ class BasicEntityPersister
/**
* Metadata object that describes the mapping of the mapped entity class.
*
* @var Doctrine\ORM\Mapping\ClassMetadata
* @var \Doctrine\ORM\Mapping\ClassMetadata
*/
protected $_class;
/**
* The underlying DBAL Connection of the used EntityManager.
*
* @var Doctrine\DBAL\Connection $conn
* @var \Doctrine\DBAL\Connection $conn
*/
protected $_conn;
/**
* The database platform.
*
* @var Doctrine\DBAL\Platforms\AbstractPlatform
* @var \Doctrine\DBAL\Platforms\AbstractPlatform
*/
protected $_platform;
/**
* The EntityManager instance.
*
* @var Doctrine\ORM\EntityManager
* @var \Doctrine\ORM\EntityManager
*/
protected $_em;
@@ -171,8 +171,8 @@ class BasicEntityPersister
* Initializes a new <tt>BasicEntityPersister</tt> that uses the given EntityManager
* and persists instances of the class described by the given ClassMetadata descriptor.
*
* @param Doctrine\ORM\EntityManager $em
* @param Doctrine\ORM\Mapping\ClassMetadata $class
* @param \Doctrine\ORM\EntityManager $em
* @param \Doctrine\ORM\Mapping\ClassMetadata $class
*/
public function __construct(EntityManager $em, ClassMetadata $class)
{
@@ -183,7 +183,7 @@ class BasicEntityPersister
}
/**
* @return Doctrine\ORM\Mapping\ClassMetadata
* @return \Doctrine\ORM\Mapping\ClassMetadata
*/
public function getClassMetadata()
{
@@ -271,7 +271,7 @@ class BasicEntityPersister
/**
* Fetch the current version value of a versioned entity.
*
* @param Doctrine\ORM\Mapping\ClassMetadata $versionedClass
* @param \Doctrine\ORM\Mapping\ClassMetadata $versionedClass
* @param mixed $id
* @return mixed
*/
@@ -724,7 +724,7 @@ class BasicEntityPersister
* Load an array of entities from a given dbal statement.
*
* @param array $assoc
* @param Doctrine\DBAL\Statement $stmt
* @param \Doctrine\DBAL\Statement $stmt
* @return array
*/
private function loadArrayFromStatement($assoc, $stmt)
@@ -746,7 +746,7 @@ class BasicEntityPersister
* Hydrate a collection from a given dbal statement.
*
* @param array $assoc
* @param Doctrine\DBAL\Statement $stmt
* @param \Doctrine\DBAL\Statement $stmt
* @param PersistentCollection $coll
*/
private function loadCollectionFromStatement($assoc, $stmt, $coll)
@@ -1272,7 +1272,7 @@ class BasicEntityPersister
* @param object $sourceEntity
* @param int|null $offset
* @param int|null $limit
* @return Doctrine\DBAL\Statement
* @return \Doctrine\DBAL\Statement
*/
private function getOneToManyStatement(array $assoc, $sourceEntity, $offset = null, $limit = null)
{
@@ -1320,13 +1320,12 @@ class BasicEntityPersister
}
$type = null;
if (isset($this->_class->fieldMappings[$field])) {
$type = Type::getType($this->_class->fieldMappings[$field]['type'])->getBindingType();
}
if (is_array($value)) {
$type = Type::getType( $this->_class->fieldMappings[$field]['type'] )->getBindingType();
$type += Connection::ARRAY_PARAM_OFFSET;
} else if (isset($this->_class->fieldMappings[$field])) {
$type = $this->_class->fieldMappings[$field]['type'];
}
$params[] = $value;
$types[] = $type;
}

View File

@@ -67,7 +67,7 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
* This function finds the ClassMetadata instance in an inheritance hierarchy
* that is responsible for enabling versioning.
*
* @return Doctrine\ORM\Mapping\ClassMetadata
* @return \Doctrine\ORM\Mapping\ClassMetadata
*/
private function _getVersionedClassMetadata()
{

View File

@@ -81,7 +81,7 @@ final class Query extends AbstractQuery
const HINT_INCLUDE_META_COLUMNS = 'doctrine.includeMetaColumns';
/**
* An array of class names that implement Doctrine\ORM\Query\TreeWalker and
* An array of class names that implement \Doctrine\ORM\Query\TreeWalker and
* are iterated and executed after the DQL has been parsed into an AST.
*
* @var string
@@ -89,7 +89,7 @@ final class Query extends AbstractQuery
const HINT_CUSTOM_TREE_WALKERS = 'doctrine.customTreeWalkers';
/**
* A string with a class name that implements Doctrine\ORM\Query\TreeWalker
* A string with a class name that implements \Doctrine\ORM\Query\TreeWalker
* and is used for generating the target SQL from any DQL AST tree.
*
* @var string
@@ -119,7 +119,7 @@ final class Query extends AbstractQuery
private $_dql = null;
/**
* @var Doctrine\ORM\Query\ParserResult The parser result that holds DQL => SQL information.
* @var \Doctrine\ORM\Query\ParserResult The parser result that holds DQL => SQL information.
*/
private $_parserResult;
@@ -158,7 +158,7 @@ final class Query extends AbstractQuery
/**
* Initializes a new Query instance.
*
* @param Doctrine\ORM\EntityManager $entityManager
* @param \Doctrine\ORM\EntityManager $entityManager
*/
/*public function __construct(EntityManager $entityManager)
{
@@ -179,9 +179,9 @@ final class Query extends AbstractQuery
/**
* Returns the corresponding AST for this DQL query.
*
* @return Doctrine\ORM\Query\AST\SelectStatement |
* Doctrine\ORM\Query\AST\UpdateStatement |
* Doctrine\ORM\Query\AST\DeleteStatement
* @return \Doctrine\ORM\Query\AST\SelectStatement |
* \Doctrine\ORM\Query\AST\UpdateStatement |
* \Doctrine\ORM\Query\AST\DeleteStatement
*/
public function getAST()
{
@@ -194,7 +194,7 @@ final class Query extends AbstractQuery
*
* Note: Populates $this->_parserResult as a side-effect.
*
* @return Doctrine\ORM\Query\ParserResult
* @return \Doctrine\ORM\Query\ParserResult
*/
private function _parse()
{
@@ -428,7 +428,7 @@ final class Query extends AbstractQuery
* Sets a DQL query string.
*
* @param string $dqlQuery DQL Query
* @return Doctrine\ORM\AbstractQuery
* @return \Doctrine\ORM\AbstractQuery
*/
public function setDQL($dqlQuery)
{
@@ -558,7 +558,7 @@ final class Query extends AbstractQuery
/**
* Set the lock mode for this Query.
*
* @see Doctrine\DBAL\LockMode
* @see \Doctrine\DBAL\LockMode
* @param int $lockMode
* @return Query
*/

View File

@@ -49,9 +49,9 @@ abstract class AbstractSqlExecutor
/**
* Executes all sql statements.
*
* @param Doctrine\DBAL\Connection $conn The database connection that is used to execute the queries.
* @param \Doctrine\DBAL\Connection $conn The database connection that is used to execute the queries.
* @param array $params The parameters.
* @return Doctrine\DBAL\Driver\Statement
* @return \Doctrine\DBAL\Driver\Statement
*/
abstract public function execute(Connection $conn, array $params, array $types);
}

View File

@@ -104,7 +104,7 @@ class MultiTableDeleteExecutor extends AbstractSqlExecutor
/**
* Executes all SQL statements.
*
* @param Doctrine\DBAL\Connection $conn The database connection that is used to execute the queries.
* @param \Doctrine\DBAL\Connection $conn The database connection that is used to execute the queries.
* @param array $params The parameters.
* @override
*/

View File

@@ -73,7 +73,7 @@ class Expr
* Creates an ASCending order expression.
*
* @param $sort
* @return OrderBy
* @return Expr\OrderBy
*/
public function asc($expr)
{
@@ -84,7 +84,7 @@ class Expr
* Creates a DESCending order expression.
*
* @param $sort
* @return OrderBy
* @return Expr\OrderBy
*/
public function desc($expr)
{
@@ -560,6 +560,8 @@ class Expr
{
if (is_numeric($literal) && !is_string($literal)) {
return (string) $literal;
} else if (is_bool($literal)) {
return $literal ? "true" : "false";
} else {
return "'" . str_replace("'", "''", $literal) . "'";
}

View File

@@ -39,30 +39,30 @@ class Composite extends Base
if ($this->count() === 1) {
return (string) $this->_parts[0];
}
$components = array();
foreach ($this->_parts as $part) {
$components[] = $this->processQueryPart($part);
}
return implode($this->_separator, $components);
}
private function processQueryPart($part)
{
$queryPart = (string) $part;
if (is_object($part) && $part instanceof self && $part->count() > 1) {
return $this->_preSeparator . $queryPart . $this->_postSeparator;
}
// Fixes DDC-1237: User may have added a where item containing nested expression (with "OR" or "AND")
if (mb_stripos($queryPart, ' OR ') !== false || mb_stripos($queryPart, ' AND ') !== false) {
if (stripos($queryPart, ' OR ') !== false || stripos($queryPart, ' AND ') !== false) {
return $this->_preSeparator . $queryPart . $this->_postSeparator;
}
return $queryPart;
}
}
}

View File

@@ -37,8 +37,8 @@ class ParameterTypeInferer
{
/**
* Infer type of a given value, returning a compatible constant:
* - Type (Doctrine\DBAL\Types\Type::*)
* - Connection (Doctrine\DBAL\Connection::PARAM_*)
* - Type (\Doctrine\DBAL\Types\Type::*)
* - Connection (\Doctrine\DBAL\Connection::PARAM_*)
*
* @param mixed $value Parameter value
*

View File

@@ -75,14 +75,14 @@ class Parser
/**
* The lexer.
*
* @var Doctrine\ORM\Query\Lexer
* @var \Doctrine\ORM\Query\Lexer
*/
private $_lexer;
/**
* The parser result.
*
* @var Doctrine\ORM\Query\ParserResult
* @var \Doctrine\ORM\Query\ParserResult
*/
private $_parserResult;
@@ -170,7 +170,7 @@ class Parser
/**
* Gets the lexer used by the parser.
*
* @return Doctrine\ORM\Query\Lexer
* @return \Doctrine\ORM\Query\Lexer
*/
public function getLexer()
{
@@ -180,7 +180,7 @@ class Parser
/**
* Gets the ParserResult that is being filled with information during parsing.
*
* @return Doctrine\ORM\Query\ParserResult
* @return \Doctrine\ORM\Query\ParserResult
*/
public function getParserResult()
{
@@ -1466,7 +1466,7 @@ class Parser
/**
* RangeVariableDeclaration ::= AbstractSchemaName ["AS"] AliasIdentificationVariable
*
* @return Doctrine\ORM\Query\AST\RangeVariableDeclaration
* @return \Doctrine\ORM\Query\AST\RangeVariableDeclaration
*/
public function RangeVariableDeclaration()
{
@@ -1537,7 +1537,7 @@ class Parser
* Join ::= ["LEFT" ["OUTER"] | "INNER"] "JOIN" JoinAssociationPathExpression
* ["AS"] AliasIdentificationVariable ["WITH" ConditionalExpression]
*
* @return Doctrine\ORM\Query\AST\Join
* @return \Doctrine\ORM\Query\AST\Join
*/
public function Join()
{
@@ -1607,7 +1607,7 @@ class Parser
/**
* IndexBy ::= "INDEX" "BY" StateFieldPathExpression
*
* @return Doctrine\ORM\Query\AST\IndexBy
* @return \Doctrine\ORM\Query\AST\IndexBy
*/
public function IndexBy()
{
@@ -1698,7 +1698,7 @@ class Parser
/**
* CoalesceExpression ::= "COALESCE" "(" ScalarExpression {"," ScalarExpression}* ")"
*
* @return Doctrine\ORM\Query\AST\CoalesceExpression
* @return \Doctrine\ORM\Query\AST\CoalesceExpression
*/
public function CoalesceExpression()
{
@@ -1722,7 +1722,7 @@ class Parser
/**
* NullIfExpression ::= "NULLIF" "(" ScalarExpression "," ScalarExpression ")"
*
* @return Doctrine\ORM\Query\AST\ExistsExpression
* @return \Doctrine\ORM\Query\AST\ExistsExpression
*/
public function NullIfExpression()
{
@@ -1743,7 +1743,7 @@ class Parser
* IdentificationVariable | StateFieldPathExpression |
* (AggregateExpression | "(" Subselect ")" | ScalarExpression) [["AS"] AliasResultVariable]
*
* @return Doctrine\ORM\Query\AST\SelectExpression
* @return \Doctrine\ORM\Query\AST\SelectExpression
*/
public function SelectExpression()
{
@@ -1967,7 +1967,7 @@ class Parser
/**
* ConditionalPrimary ::= SimpleConditionalExpression | "(" ConditionalExpression ")"
*
* @return Doctrine\ORM\Query\AST\ConditionalPrimary
* @return \Doctrine\ORM\Query\AST\ConditionalPrimary
*/
public function ConditionalPrimary()
{

View File

@@ -89,7 +89,7 @@ class QueryException extends \Doctrine\ORM\ORMException
}
/**
* @param Doctrine\ORM\Mapping\AssociationMapping $assoc
* @param \Doctrine\ORM\Mapping\AssociationMapping $assoc
*/
public static function iterateWithFetchJoinCollectionNotAllowed($assoc)
{

View File

@@ -35,6 +35,11 @@ use Doctrine\DBAL\LockMode,
*/
class SqlWalker implements TreeWalker
{
/**
* @var string
*/
const HINT_DISTINCT = 'doctrine.distinct';
/**
* @var ResultSetMapping
*/
@@ -57,7 +62,7 @@ class SqlWalker implements TreeWalker
private $_em;
/**
* @var Doctrine\DBAL\Connection
* @var \Doctrine\DBAL\Connection
*/
private $_conn;
@@ -160,18 +165,18 @@ class SqlWalker implements TreeWalker
switch (true) {
case ($AST instanceof AST\DeleteStatement):
$primaryClass = $this->_em->getClassMetadata($AST->deleteClause->abstractSchemaName);
return ($primaryClass->isInheritanceTypeJoined())
? new Exec\MultiTableDeleteExecutor($AST, $this)
: new Exec\SingleTableDeleteUpdateExecutor($AST, $this);
case ($AST instanceof AST\UpdateStatement):
$primaryClass = $this->_em->getClassMetadata($AST->updateClause->abstractSchemaName);
return ($primaryClass->isInheritanceTypeJoined())
return ($primaryClass->isInheritanceTypeJoined())
? new Exec\MultiTableUpdateExecutor($AST, $this)
: new Exec\SingleTableDeleteUpdateExecutor($AST, $this);
default:
return new Exec\SingleSelectExecutor($AST, $this);
}
@@ -262,7 +267,7 @@ class SqlWalker implements TreeWalker
$sql .= ' LEFT JOIN ' . $subClass->getQuotedTableName($this->_platform)
. ' ' . $tableAlias . ' ON ';
$first = true;
foreach ($class->getQuotedIdentifierColumnNames($this->_platform) as $columnName) {
if ($first) $first = false; else $sql .= ' AND ';
@@ -328,8 +333,7 @@ class SqlWalker implements TreeWalker
$encapsulate = true;
}
$sql .= ($sql != '' ? ' AND ' : '')
. (($this->_useSqlTableAliases) ? $this->getSQLTableAlias($class->table['name'], $dqlAlias) . '.' : '')
$sql .= (($this->_useSqlTableAliases) ? $this->getSQLTableAlias($class->table['name'], $dqlAlias) . '.' : '')
. $class->discriminatorColumn['name'] . ' IN (' . implode(', ', $values) . ')';
}
}
@@ -497,7 +501,7 @@ class SqlWalker implements TreeWalker
throw QueryException::associationPathInverseSideNotSupported();
}
break;
default:
throw QueryException::invalidPathExpression($pathExpr);
}
@@ -516,6 +520,10 @@ class SqlWalker implements TreeWalker
$sql = 'SELECT ' . (($selectClause->isDistinct) ? 'DISTINCT ' : '');
$sqlSelectExpressions = array_filter(array_map(array($this, 'walkSelectExpression'), $selectClause->selectExpressions));
if ($this->_query->getHint(Query::HINT_INTERNAL_ITERATION) == true && $selectClause->isDistinct) {
$this->_query->setHint(self::HINT_DISTINCT, true);
}
$addMetaColumns = ! $this->_query->getHint(Query::HINT_FORCE_PARTIAL_LOAD) &&
$this->_query->getHydrationMode() == Query::HYDRATE_OBJECT
||
@@ -540,7 +548,7 @@ class SqlWalker implements TreeWalker
$tblAlias = $this->getSQLTableAlias($rootClass->table['name'], $dqlAlias);
$discrColumn = $rootClass->discriminatorColumn;
$columnAlias = $this->getSQLColumnAlias($discrColumn['name']);
$sqlSelectExpressions[] = $tblAlias . '.' . $discrColumn['name'] . ' AS ' . $columnAlias;
$columnAlias = $this->_platform->getSQLResultCasing($columnAlias);
@@ -558,12 +566,12 @@ class SqlWalker implements TreeWalker
} else {
$sqlTableAlias = $this->getSQLTableAlias($class->table['name'], $dqlAlias);
}
foreach ($assoc['targetToSourceKeyColumns'] as $srcColumn) {
$columnAlias = $this->getSQLColumnAlias($srcColumn);
$sqlSelectExpressions[] = $sqlTableAlias . '.' . $srcColumn . ' AS ' . $columnAlias;
$columnAlias = $this->_platform->getSQLResultCasing($columnAlias);
$this->_rsm->addMetaResult($dqlAlias, $this->_platform->getSQLResultCasing($columnAlias), $srcColumn, (isset($assoc['id']) && $assoc['id'] === true));
}
@@ -578,9 +586,9 @@ class SqlWalker implements TreeWalker
if ($assoc['isOwningSide'] && $assoc['type'] & ClassMetadata::TO_ONE) {
foreach ($assoc['targetToSourceKeyColumns'] as $srcColumn) {
$columnAlias = $this->getSQLColumnAlias($srcColumn);
$sqlSelectExpressions[] = $sqlTableAlias . '.' . $srcColumn . ' AS ' . $columnAlias;
$columnAlias = $this->_platform->getSQLResultCasing($columnAlias);
$this->_rsm->addMetaResult($dqlAlias, $this->_platform->getSQLResultCasing($columnAlias), $srcColumn, (isset($assoc['id']) && $assoc['id'] === true));
}
@@ -589,7 +597,7 @@ class SqlWalker implements TreeWalker
}
}
}
$sql .= implode(', ', $sqlSelectExpressions);
return $sql;
@@ -610,7 +618,7 @@ class SqlWalker implements TreeWalker
$rangeDecl = $identificationVariableDecl->rangeVariableDeclaration;
$dqlAlias = $rangeDecl->aliasIdentificationVariable;
$this->_rootAliases[] = $dqlAlias;
$class = $this->_em->getClassMetadata($rangeDecl->abstractSchemaName);
@@ -736,8 +744,7 @@ class SqlWalker implements TreeWalker
// Ensure we got the owning side, since it has all mapping info
$assoc = ( ! $relation['isOwningSide']) ? $targetClass->associationMappings[$relation['mappedBy']] : $relation;
if ($this->_query->getHint(Query::HINT_INTERNAL_ITERATION) == true) {
if ($this->_query->getHint(Query::HINT_INTERNAL_ITERATION) == true && (!$this->_query->getHint(self::HINT_DISTINCT) || isset($this->_selectedClasses[$joinedDqlAlias]))) {
if ($relation['type'] == ClassMetadata::ONE_TO_MANY || $relation['type'] == ClassMetadata::MANY_TO_MANY) {
throw QueryException::iterateWithFetchJoinNotAllowed($assoc);
}
@@ -866,7 +873,7 @@ class SqlWalker implements TreeWalker
return $sql;
}
/**
* Walks down a CoalesceExpression AST node and generates the corresponding SQL.
*
@@ -876,32 +883,32 @@ class SqlWalker implements TreeWalker
public function walkCoalesceExpression($coalesceExpression)
{
$sql = 'COALESCE(';
$scalarExpressions = array();
foreach ($coalesceExpression->scalarExpressions as $scalarExpression) {
$scalarExpressions[] = $this->walkSimpleArithmeticExpression($scalarExpression);
}
$sql .= implode(', ', $scalarExpressions) . ')';
return $sql;
}
public function walkCaseExpression($expression)
{
switch (true) {
case ($expression instanceof AST\CoalesceExpression):
return $this->walkCoalesceExpression($expression);
case ($expression instanceof AST\NullIfExpression):
return $this->walkNullIfExpression($expression);
default:
return '';
}
}
/**
* Walks down a NullIfExpression AST node and generates the corresponding SQL.
*
@@ -910,14 +917,14 @@ class SqlWalker implements TreeWalker
*/
public function walkNullIfExpression($nullIfExpression)
{
$firstExpression = is_string($nullIfExpression->firstExpression)
$firstExpression = is_string($nullIfExpression->firstExpression)
? $this->_conn->quote($nullIfExpression->firstExpression)
: $this->walkSimpleArithmeticExpression($nullIfExpression->firstExpression);
$secondExpression = is_string($nullIfExpression->secondExpression)
$secondExpression = is_string($nullIfExpression->secondExpression)
? $this->_conn->quote($nullIfExpression->secondExpression)
: $this->walkSimpleArithmeticExpression($nullIfExpression->secondExpression);
return 'NULLIF(' . $firstExpression . ', ' . $secondExpression . ')';
}
@@ -954,7 +961,7 @@ class SqlWalker implements TreeWalker
$sqlTableAlias = $this->getSQLTableAlias($tableName, $dqlAlias);
$columnName = $class->getQuotedColumnName($fieldName, $this->_platform);
$columnAlias = $this->getSQLColumnAlias($columnName);
$columnAlias = $this->getSQLColumnAlias($class->fieldMappings[$fieldName]['columnName']);
$sql .= $sqlTableAlias . '.' . $columnName . ' AS ' . $columnAlias;
$columnAlias = $this->_platform->getSQLResultCasing($columnAlias);
$this->_rsm->addScalarResult($columnAlias, $resultAlias);
@@ -1017,13 +1024,13 @@ class SqlWalker implements TreeWalker
}
$columnAlias = 'sclr' . $this->_aliasCounter++;
if ($expr instanceof AST\Literal) {
$sql .= $this->walkLiteral($expr) . ' AS ' .$columnAlias;
} else {
$sql .= $this->walkSimpleArithmeticExpression($expr) . ' AS ' . $columnAlias;
}
$this->_scalarResultAliasMap[$resultAlias] = $columnAlias;
$columnAlias = $this->_platform->getSQLResultCasing($columnAlias);
@@ -1040,9 +1047,9 @@ class SqlWalker implements TreeWalker
}
$columnAlias = 'sclr' . $this->_aliasCounter++;
$sql .= $this->walkCaseExpression($expr) . ' AS ' . $columnAlias;
$this->_scalarResultAliasMap[$resultAlias] = $columnAlias;
$columnAlias = $this->_platform->getSQLResultCasing($columnAlias);
@@ -1222,61 +1229,61 @@ class SqlWalker implements TreeWalker
{
$expr = $simpleSelectExpression->expression;
$sql = ' ';
switch (true) {
case ($expr instanceof AST\PathExpression):
$sql .= $this->walkPathExpression($expr);
break;
case ($expr instanceof AST\AggregateExpression):
$alias = $simpleSelectExpression->fieldIdentificationVariable ?: $this->_scalarResultCounter++;
$sql .= $this->walkAggregateExpression($expr) . ' AS dctrn__' . $alias;
break;
case ($expr instanceof AST\Subselect):
$alias = $simpleSelectExpression->fieldIdentificationVariable ?: $this->_scalarResultCounter++;
$columnAlias = 'sclr' . $this->_aliasCounter++;
$this->_scalarResultAliasMap[$alias] = $columnAlias;
$sql .= '(' . $this->walkSubselect($expr) . ') AS ' . $columnAlias;
break;
case ($expr instanceof AST\Functions\FunctionNode):
$alias = $simpleSelectExpression->fieldIdentificationVariable ?: $this->_scalarResultCounter++;
$columnAlias = 'sclr' . $this->_aliasCounter++;
$this->_scalarResultAliasMap[$alias] = $columnAlias;
$sql .= $this->walkFunction($expr) . ' AS ' . $columnAlias;
break;
case ($expr instanceof AST\SimpleArithmeticExpression):
case ($expr instanceof AST\ArithmeticTerm):
case ($expr instanceof AST\ArithmeticFactor):
case ($expr instanceof AST\ArithmeticPrimary):
case ($expr instanceof AST\Literal):
$alias = $simpleSelectExpression->fieldIdentificationVariable ?: $this->_scalarResultCounter++;
$columnAlias = 'sclr' . $this->_aliasCounter++;
$this->_scalarResultAliasMap[$alias] = $columnAlias;
$sql .= $this->walkSimpleArithmeticExpression($expr) . ' AS ' . $columnAlias;
break;
case ($expr instanceof AST\NullIfExpression):
case ($expr instanceof AST\CoalesceExpression):
case ($expr instanceof AST\GeneralCaseExpression):
case ($expr instanceof AST\SimpleCaseExpression):
$alias = $simpleSelectExpression->fieldIdentificationVariable ?: $this->_scalarResultCounter++;
$columnAlias = 'sclr' . $this->_aliasCounter++;
$this->_scalarResultAliasMap[$alias] = $columnAlias;
$sql .= $this->walkCaseExpression($expr) . ' AS ' . $columnAlias;
break;
default: // IdentificationVariable
$class = $this->_queryComponents[$expr]['metadata'];
$tableAlias = $this->getSQLTableAlias($class->getTableName(), $expr);
@@ -1285,11 +1292,11 @@ class SqlWalker implements TreeWalker
foreach ($class->getQuotedIdentifierColumnNames($this->_platform) as $columnName) {
$sqlParts[] = $tableAlias . '.' . $columnName;
}
$sql .= implode(', ', $sqlParts);
break;
}
return $sql;
}
@@ -1314,22 +1321,22 @@ class SqlWalker implements TreeWalker
public function walkGroupByClause($groupByClause)
{
$sqlParts = array();
foreach ($groupByClause->groupByItems AS $groupByItem) {
if ( ! is_string($groupByItem)) {
$sqlParts[] = $this->walkGroupByItem($groupByItem);
continue;
}
foreach ($this->_queryComponents[$groupByItem]['metadata']->identifier AS $idField) {
$groupByItem = new AST\PathExpression(AST\PathExpression::TYPE_STATE_FIELD, $groupByItem, $idField);
$groupByItem->type = AST\PathExpression::TYPE_STATE_FIELD;
$sqlParts[] = $this->walkGroupByItem($groupByItem);
}
}
return ' GROUP BY ' . implode(', ', $sqlParts);
}
@@ -1355,7 +1362,7 @@ class SqlWalker implements TreeWalker
$class = $this->_em->getClassMetadata($deleteClause->abstractSchemaName);
$tableName = $class->getTableName();
$sql = 'DELETE FROM ' . $class->getQuotedTableName($this->_platform);
$this->setSQLTableAlias($tableName, $tableName, $deleteClause->aliasIdentificationVariable);
$this->_rootAliases[] = $deleteClause->aliasIdentificationVariable;
@@ -1373,7 +1380,7 @@ class SqlWalker implements TreeWalker
$class = $this->_em->getClassMetadata($updateClause->abstractSchemaName);
$tableName = $class->getTableName();
$sql = 'UPDATE ' . $class->getQuotedTableName($this->_platform);
$this->setSQLTableAlias($tableName, $tableName, $updateClause->aliasIdentificationVariable);
$this->_rootAliases[] = $updateClause->aliasIdentificationVariable;
@@ -1400,11 +1407,11 @@ class SqlWalker implements TreeWalker
case ($newValue instanceof AST\Node):
$sql .= $newValue->dispatch($this);
break;
case ($newValue === null):
$sql .= 'NULL';
break;
default:
$sql .= $this->_conn->quote($newValue);
break;
@@ -1428,8 +1435,8 @@ class SqlWalker implements TreeWalker
if ($condSql) {
return ' WHERE ' . (( ! $discrSql) ? $condSql : '(' . $condSql . ') AND ' . $discrSql);
}
}
if ($discrSql) {
return ' WHERE ' . $discrSql;
}
@@ -1450,7 +1457,7 @@ class SqlWalker implements TreeWalker
if ( ! ($condExpr instanceof AST\ConditionalExpression)) {
return $this->walkConditionalTerm($condExpr);
}
return implode(' OR ', array_map(array($this, 'walkConditionalTerm'), $condExpr->conditionalTerms));
}
@@ -1467,7 +1474,7 @@ class SqlWalker implements TreeWalker
if ( ! ($condTerm instanceof AST\ConditionalTerm)) {
return $this->walkConditionalFactor($condTerm);
}
return implode(' AND ', array_map(array($this, 'walkConditionalFactor'), $condTerm->conditionalFactors));
}
@@ -1496,8 +1503,8 @@ class SqlWalker implements TreeWalker
{
if ($primary->isSimpleConditionalExpression()) {
return $primary->simpleConditionalExpression->dispatch($this);
}
}
if ($primary->isConditionalExpression()) {
$condExpr = $primary->conditionalExpression;
@@ -1532,12 +1539,12 @@ class SqlWalker implements TreeWalker
$sql .= 'EXISTS (SELECT 1 FROM ';
$entityExpr = $collMemberExpr->entityExpression;
$collPathExpr = $collMemberExpr->collectionValuedPathExpression;
$fieldName = $collPathExpr->field;
$dqlAlias = $collPathExpr->identificationVariable;
$class = $this->_queryComponents[$dqlAlias]['metadata'];
if ($entityExpr instanceof AST\InputParameter) {
$dqlParamKey = $entityExpr->name;
$entity = $this->_query->getParameter($dqlParamKey);
@@ -1545,41 +1552,41 @@ class SqlWalker implements TreeWalker
//TODO
throw new \BadMethodCallException("Not implemented");
}
$assoc = $class->associationMappings[$fieldName];
if ($assoc['type'] == ClassMetadata::ONE_TO_MANY) {
$targetClass = $this->_em->getClassMetadata($assoc['targetEntity']);
$targetTableAlias = $this->getSQLTableAlias($targetClass->table['name']);
$sourceTableAlias = $this->getSQLTableAlias($class->table['name'], $dqlAlias);
$sql .= $targetClass->getQuotedTableName($this->_platform)
. ' ' . $targetTableAlias . ' WHERE ';
$owningAssoc = $targetClass->associationMappings[$assoc['mappedBy']];
$first = true;
foreach ($owningAssoc['targetToSourceKeyColumns'] as $targetColumn => $sourceColumn) {
if ($first) $first = false; else $sql .= ' AND ';
$sql .= $sourceTableAlias . '.' . $class->getQuotedColumnName($class->fieldNames[$targetColumn], $this->_platform)
. ' = '
$sql .= $sourceTableAlias . '.' . $class->getQuotedColumnName($class->fieldNames[$targetColumn], $this->_platform)
. ' = '
. $targetTableAlias . '.' . $sourceColumn;
}
$sql .= ' AND ';
$first = true;
foreach ($targetClass->getQuotedIdentifierColumnNames($this->_platform) as $targetColumnName) {
if ($first) $first = false; else $sql .= ' AND ';
$this->_parserResult->addParameterMapping($dqlParamKey, $this->_sqlParamIndex++);
$sql .= $targetTableAlias . '.' . $targetColumnName . ' = ?';
}
} else { // many-to-many
$targetClass = $this->_em->getClassMetadata($assoc['targetEntity']);
$owningAssoc = $assoc['isOwningSide'] ? $assoc : $targetClass->associationMappings[$assoc['mappedBy']];
$joinTable = $owningAssoc['joinTable'];
@@ -1587,13 +1594,13 @@ class SqlWalker implements TreeWalker
$joinTableAlias = $this->getSQLTableAlias($joinTable['name']);
$targetTableAlias = $this->getSQLTableAlias($targetClass->table['name']);
$sourceTableAlias = $this->getSQLTableAlias($class->table['name'], $dqlAlias);
// join to target table
$sql .= $targetClass->getQuotedJoinTableName($owningAssoc, $this->_platform)
. ' ' . $joinTableAlias . ' INNER JOIN '
. $targetClass->getQuotedTableName($this->_platform)
. ' ' . $targetTableAlias . ' ON ';
// join conditions
$joinColumns = $assoc['isOwningSide']
? $joinTable['inverseJoinColumns']
@@ -1619,18 +1626,18 @@ class SqlWalker implements TreeWalker
foreach ($joinColumns as $joinColumn) {
if ($first) $first = false; else $sql .= ' AND ';
$sql .= $joinTableAlias . '.' . $joinColumn['name'] . ' = '
$sql .= $joinTableAlias . '.' . $joinColumn['name'] . ' = '
. $sourceTableAlias . '.' . $class->getQuotedColumnName(
$class->fieldNames[$joinColumn['referencedColumnName']],
$this->_platform);
}
$sql .= ' AND ';
$first = true;
foreach ($targetClass->getQuotedIdentifierColumnNames($this->_platform) as $targetColumnName) {
if ($first) $first = false; else $sql .= ' AND ';
$this->_parserResult->addParameterMapping($dqlParamKey, $this->_sqlParamIndex++);
$sql .= $targetTableAlias . '.' . $targetColumnName . ' = ?';
}
@@ -1638,7 +1645,7 @@ class SqlWalker implements TreeWalker
return $sql . ')';
}
/**
* Walks down an EmptyCollectionComparisonExpression AST node, thereby generating the appropriate SQL.
*
@@ -1685,10 +1692,10 @@ class SqlWalker implements TreeWalker
*/
public function walkInExpression($inExpr)
{
$sql = $this->walkPathExpression($inExpr->pathExpression)
$sql = $this->walkPathExpression($inExpr->pathExpression)
. ($inExpr->not ? ' NOT' : '') . ' IN (';
$sql .= ($inExpr->subselect)
$sql .= ($inExpr->subselect)
? $this->walkSubselect($inExpr->subselect)
: implode(', ', array_map(array($this, 'walkInParameter'), $inExpr->literals));
@@ -1725,11 +1732,11 @@ class SqlWalker implements TreeWalker
// We need to modify the parameter value to be its correspondent mapped value
$dqlParamKey = $instanceOfExpr->value->name;
$paramValue = $this->_query->getParameter($dqlParamKey);
if ( ! ($paramValue instanceof \Doctrine\ORM\Mapping\ClassMetadata)) {
throw QueryException::invalidParameterType('ClassMetadata', get_class($paramValue));
}
$entityClassName = $paramValue->name;
} else {
// Get name from ClassMetadata to resolve aliases.
@@ -1743,7 +1750,7 @@ class SqlWalker implements TreeWalker
if (!isset($discrMap[$entityClassName])) {
throw QueryException::instanceOfUnrelatedClass($entityClassName, $class->rootEntityName);
}
$sql .= $this->_conn->quote($discrMap[$entityClassName]);
}
@@ -1758,8 +1765,8 @@ class SqlWalker implements TreeWalker
*/
public function walkInParameter($inParam)
{
return $inParam instanceof AST\InputParameter
? $this->walkInputParameter($inParam)
return $inParam instanceof AST\InputParameter
? $this->walkInputParameter($inParam)
: $this->walkLiteral($inParam);
}
@@ -1852,14 +1859,14 @@ class SqlWalker implements TreeWalker
$leftExpr = $compExpr->leftExpression;
$rightExpr = $compExpr->rightExpression;
$sql = '';
$sql .= ($leftExpr instanceof AST\Node)
$sql .= ($leftExpr instanceof AST\Node)
? $leftExpr->dispatch($this)
: (is_numeric($leftExpr) ? $leftExpr : $this->_conn->quote($leftExpr));
$sql .= ' ' . $compExpr->operator . ' ';
$sql .= ($rightExpr instanceof AST\Node)
$sql .= ($rightExpr instanceof AST\Node)
? $rightExpr->dispatch($this)
: (is_numeric($rightExpr) ? $rightExpr : $this->_conn->quote($rightExpr));
@@ -1903,7 +1910,7 @@ class SqlWalker implements TreeWalker
if ( ! ($simpleArithmeticExpr instanceof AST\SimpleArithmeticExpression)) {
return $this->walkArithmeticTerm($simpleArithmeticExpr);
}
return implode(' ', array_map(array($this, 'walkArithmeticTerm'), $simpleArithmeticExpr->arithmeticTerms));
}
@@ -1918,10 +1925,10 @@ class SqlWalker implements TreeWalker
if (is_string($term)) {
if (isset($this->_queryComponents[$term])) {
$columnName = $this->_queryComponents[$term]['token']['value'];
return $this->_scalarResultAliasMap[$columnName];
}
return $term;
}
@@ -1930,7 +1937,7 @@ class SqlWalker implements TreeWalker
if ( ! ($term instanceof AST\ArithmeticTerm)) {
return $this->walkArithmeticFactor($term);
}
return implode(' ', array_map(array($this, 'walkArithmeticFactor'), $term->arithmeticFactors));
}
@@ -1945,15 +1952,15 @@ class SqlWalker implements TreeWalker
if (is_string($factor)) {
return $factor;
}
// Phase 2 AST optimization: Skip processment of ArithmeticFactor
// if only one ArithmeticPrimary is defined
if ( ! ($factor instanceof AST\ArithmeticFactor)) {
return $this->walkArithmeticPrimary($factor);
}
$sign = $factor->isNegativeSigned() ? '-' : ($factor->isPositiveSigned() ? '+' : '');
return $sign . $this->walkArithmeticPrimary($factor->arithmeticPrimary);
}
@@ -1967,8 +1974,8 @@ class SqlWalker implements TreeWalker
{
if ($primary instanceof AST\SimpleArithmeticExpression) {
return '(' . $this->walkSimpleArithmeticExpression($primary) . ')';
}
}
if ($primary instanceof AST\Node) {
return $primary->dispatch($this);
}

View File

@@ -55,7 +55,7 @@ abstract class TreeWalkerAdapter implements TreeWalker
/**
* Retrieve Query Instance reponsible for the current walkers execution.
*
* @return Doctrine\ORM\Query
* @return \Doctrine\ORM\Query
*/
protected function _getQuery()
{
@@ -65,7 +65,7 @@ abstract class TreeWalkerAdapter implements TreeWalker
/**
* Retrieve ParserResult
*
* @return Doctrine\ORM\Query\ParserResult
* @return \Doctrine\ORM\Query\ParserResult
*/
protected function _getParserResult()
{

View File

@@ -50,6 +50,7 @@ class QueryBuilder
* @var array The array of DQL parts collected.
*/
private $_dqlParts = array(
'distinct' => false,
'select' => array(),
'from' => array(),
'join' => array(),
@@ -119,7 +120,7 @@ class QueryBuilder
* For more complex expression construction, consider storing the expression
* builder object in a local variable.
*
* @return Expr
* @return Query\Expr
*/
public function expr()
{
@@ -342,8 +343,8 @@ class QueryBuilder
* ->from('User', 'u')
* ->where('u.id = :user_id1 OR u.id = :user_id2')
* ->setParameters(array(
* ':user_id1' => 1,
* ':user_id2' => 2
* 'user_id1' => 1,
* 'user_id2' => 2
* ));
* </code>
*
@@ -502,6 +503,25 @@ class QueryBuilder
return $this->add('select', new Expr\Select($selects), false);
}
/**
* Add a DISTINCT flag to this query.
*
* <code>
* $qb = $em->createQueryBuilder()
* ->select('u')
* ->distinct()
* ->from('User', 'u');
* </code>
*
* @param bool
* @return QueryBuilder
*/
public function distinct($flag = true)
{
$this->_dqlParts['distinct'] = (bool) $flag;
return $this;
}
/**
* Adds an item that is to be returned in the query result.
*
@@ -973,8 +993,10 @@ class QueryBuilder
private function _getDQLForSelect()
{
$dql = 'SELECT' . $this->_getReducedDQLQueryPart('select', array('pre' => ' ', 'separator' => ', '));
$dql = 'SELECT'
. ($this->_dqlParts['distinct']===true ? ' DISTINCT' : '')
. $this->_getReducedDQLQueryPart('select', array('pre' => ' ', 'separator' => ', '));
$fromParts = $this->getDQLPart('from');
$joinParts = $this->getDQLPart('join');
$fromClauses = array();
@@ -1082,4 +1104,4 @@ class QueryBuilder
}
}
}
}
}

View File

@@ -50,7 +50,7 @@ EOT
protected function execute(InputInterface $input, OutputInterface $output)
{
/* @var $entityManager Doctrine\ORM\EntityManager */
/* @var $entityManager \Doctrine\ORM\EntityManager */
$entityManager = $this->getHelper('em')->getEntityManager();
$entityClassNames = $entityManager->getConfiguration()

View File

@@ -189,6 +189,8 @@ public function <methodName>()
if ( ! $this->_isNew) {
$this->_parseTokensInEntityFile(file_get_contents($path));
} else {
$this->_staticReflection[$metadata->name] = array('properties' => array(), 'methods' => array());
}
if ($this->_backupExisting && file_exists($path)) {
@@ -749,7 +751,7 @@ public function <methodName>()
$this->_staticReflection[$metadata->name]['methods'][] = $methodName;
$replacements = array(
'<name>' => $this->_annotationsPrefix . $name,
'<name>' => $this->_annotationsPrefix . ucfirst($name),
'<methodName>' => $methodName,
);
@@ -805,6 +807,14 @@ public function <methodName>()
if ($this->_generateAnnotations) {
$lines[] = $this->_spaces . ' *';
if (isset($associationMapping['id']) && $associationMapping['id']) {
$lines[] = $this->_spaces . ' * @' . $this->_annotationsPrefix . 'Id';
if ($generatorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) {
$lines[] = $this->_spaces . ' * @' . $this->_annotationsPrefix . 'GeneratedValue(strategy="' . $generatorType . '")';
}
}
$type = null;
switch ($associationMapping['type']) {
@@ -1061,4 +1071,4 @@ public function <methodName>()
throw new \InvalidArgumentException('Invalid provided IdGeneratorType: ' . $type);
}
}
}
}

View File

@@ -27,7 +27,7 @@ use Doctrine\ORM\Tools\Export\ExportException;
/**
* Abstract base class which is to be used for the Exporter drivers
* which can be found in Doctrine\ORM\Tools\Export\Driver
* which can be found in \Doctrine\ORM\Tools\Export\Driver
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org

View File

@@ -166,7 +166,13 @@ class YamlExporter extends AbstractExporter
);
$associationMappingArray = array_merge($associationMappingArray, $oneToOneMappingArray);
$array['oneToOne'][$name] = $associationMappingArray;
if ($associationMapping['type'] & ClassMetadataInfo::ONE_TO_ONE) {
$array['oneToOne'][$name] = $associationMappingArray;
} else {
$array['manyToOne'][$name] = $associationMappingArray;
}
} else if ($associationMapping['type'] == ClassMetadataInfo::ONE_TO_MANY) {
$oneToManyMappingArray = array(
'mappedBy' => $associationMapping['mappedBy'],

View File

@@ -56,7 +56,7 @@ class SchemaTool
* Initializes a new SchemaTool instance that uses the connection of the
* provided EntityManager.
*
* @param Doctrine\ORM\EntityManager $em
* @param \Doctrine\ORM\EntityManager $em
*/
public function __construct(EntityManager $em)
{
@@ -174,7 +174,7 @@ class SchemaTool
$discrColumnDef = $this->_getDiscriminatorColumnDefinition($class, $table);
} else {
// Add an ID FK column to child tables
/* @var Doctrine\ORM\Mapping\ClassMetadata $class */
/* @var \Doctrine\ORM\Mapping\ClassMetadata $class */
$idMapping = $class->fieldMappings[$class->identifier[0]];
$this->_gatherColumn($class, $idMapping, $table);
$columnName = $class->getQuotedColumnName($class->identifier[0], $this->_platform);
@@ -217,13 +217,13 @@ class SchemaTool
if (isset($class->table['indexes'])) {
foreach ($class->table['indexes'] AS $indexName => $indexData) {
$table->addIndex($indexData['columns'], $indexName);
$table->addIndex($indexData['columns'], is_numeric($indexName) ? null : $indexName);
}
}
if (isset($class->table['uniqueConstraints'])) {
foreach ($class->table['uniqueConstraints'] AS $indexName => $indexData) {
$table->addUniqueIndex($indexData['columns'], $indexName);
$table->addUniqueIndex($indexData['columns'], is_numeric($indexName) ? null : $indexName);
}
}

View File

@@ -176,7 +176,7 @@ class UnitOfWork implements PropertyChangedListener
/**
* The EntityManager that "owns" this UnitOfWork instance.
*
* @var Doctrine\ORM\EntityManager
* @var \Doctrine\ORM\EntityManager
*/
private $em;
@@ -184,7 +184,7 @@ class UnitOfWork implements PropertyChangedListener
* The calculator used to calculate the order in which changes to
* entities need to be written to the database.
*
* @var Doctrine\ORM\Internal\CommitOrderCalculator
* @var \Doctrine\ORM\Internal\CommitOrderCalculator
*/
private $commitOrderCalculator;
@@ -233,7 +233,7 @@ class UnitOfWork implements PropertyChangedListener
/**
* Initializes a new UnitOfWork instance, bound to the given EntityManager.
*
* @param Doctrine\ORM\EntityManager $em
* @param \Doctrine\ORM\EntityManager $em
*/
public function __construct(EntityManager $em)
{
@@ -492,6 +492,23 @@ class UnitOfWork implements PropertyChangedListener
$this->collectionDeletions[] = $orgValue;
$changeSet[$propName] = $orgValue; // Signal changeset, to-many assocs will be ignored.
}
// Persistent collection was exchanged with the "originally"
// created one. This can only mean it was cloned and replaced
// on another entity.
if ($actualValue instanceof PersistentCollection) {
$owner = $actualValue->getOwner();
if ($owner === null) { // cloned
$actualValue->setOwner($entity, $assoc);
} else if ($owner !== $entity) { // no clone, we have to fix
if (!$actualValue->isInitialized()) {
$actualValue->initialize(); // we have to do this otherwise the cols share state
}
$newValue = clone $actualValue;
$newValue->setOwner($entity, $assoc);
$class->reflFields[$propName]->setValue($entity, $newValue);
}
}
}
} else if ($isChangeTrackingNotify) {
continue;
@@ -511,6 +528,15 @@ class UnitOfWork implements PropertyChangedListener
$val = $class->reflFields[$field]->getValue($entity);
if ($val !== null) {
$this->computeAssociationChanges($assoc, $val);
if (!isset($this->entityChangeSets[$oid]) &&
$assoc['isOwningSide'] &&
$assoc['type'] == ClassMetadata::MANY_TO_MANY &&
$val instanceof PersistentCollection &&
$val->isDirty()) {
$this->entityChangeSets[$oid] = array();
$this->originalEntityData[$oid] = $actualData;
$this->entityUpdates[$oid] = $entity;
}
}
}
}
@@ -700,7 +726,7 @@ class UnitOfWork implements PropertyChangedListener
/**
* Executes all entity insertions for entities of the specified type.
*
* @param Doctrine\ORM\Mapping\ClassMetadata $class
* @param \Doctrine\ORM\Mapping\ClassMetadata $class
*/
private function executeInserts($class)
{
@@ -753,7 +779,7 @@ class UnitOfWork implements PropertyChangedListener
/**
* Executes all entity updates for entities of the specified type.
*
* @param Doctrine\ORM\Mapping\ClassMetadata $class
* @param \Doctrine\ORM\Mapping\ClassMetadata $class
*/
private function executeUpdates($class)
{
@@ -797,7 +823,7 @@ class UnitOfWork implements PropertyChangedListener
/**
* Executes all entity deletions for entities of the specified type.
*
* @param Doctrine\ORM\Mapping\ClassMetadata $class
* @param \Doctrine\ORM\Mapping\ClassMetadata $class
*/
private function executeDeletions($class)
{
@@ -1170,6 +1196,8 @@ class UnitOfWork implements PropertyChangedListener
$className = $classMetadata->rootEntityName;
if (isset($this->identityMap[$className][$idHash])) {
unset($this->identityMap[$className][$idHash]);
unset($this->readOnlyObjects[$oid]);
//$this->entityStates[$oid] = self::STATE_DETACHED;
return true;
}
@@ -1418,7 +1446,20 @@ class UnitOfWork implements PropertyChangedListener
$managedCopy = $class->newInstance();
$this->persistNew($class, $managedCopy);
} else {
$managedCopy = $this->tryGetById($id, $class->rootEntityName);
$flatId = $id;
if ($class->containsForeignIdentifier) {
// convert foreign identifiers into scalar foreign key
// values to avoid object to string conversion failures.
foreach ($id as $idField => $idValue) {
if (isset($class->associationMappings[$idField])) {
$targetClassMetadata = $this->em->getClassMetadata($class->associationMappings[$idField]['targetEntity']);
$associatedId = $this->getEntityIdentifier($idValue);
$flatId[$idField] = $associatedId[$targetClassMetadata->identifier[0]];
}
}
}
$managedCopy = $this->tryGetById($flatId, $class->rootEntityName);
if ($managedCopy) {
// We have the entity in-memory already, just make sure its not removed.
if ($this->getEntityState($managedCopy) == self::STATE_REMOVED) {
@@ -1427,7 +1468,7 @@ class UnitOfWork implements PropertyChangedListener
}
} else {
// We need to fetch the managed copy in order to merge.
$managedCopy = $this->em->find($class->name, $id);
$managedCopy = $this->em->find($class->name, $flatId);
}
if ($managedCopy === null) {
@@ -1440,6 +1481,10 @@ class UnitOfWork implements PropertyChangedListener
} else {
throw new EntityNotFoundException;
}
} else {
if ($managedCopy instanceof Proxy && ! $managedCopy->__isInitialized__) {
$managedCopy->__load();
}
}
}
@@ -1468,21 +1513,18 @@ class UnitOfWork implements PropertyChangedListener
// do not merge fields marked lazy that have not been fetched.
continue;
} else if ( ! $assoc2['isCascadeMerge']) {
if ($this->getEntityState($other, self::STATE_DETACHED) == self::STATE_MANAGED) {
$prop->setValue($managedCopy, $other);
} else {
if ($this->getEntityState($other, self::STATE_DETACHED) !== self::STATE_MANAGED) {
$targetClass = $this->em->getClassMetadata($assoc2['targetEntity']);
$relatedId = $targetClass->getIdentifierValues($other);
if ($targetClass->subClasses) {
$entity = $this->em->find($targetClass->name, $relatedId);
$other = $this->em->find($targetClass->name, $relatedId);
} else {
$proxy = $this->em->getProxyFactory()->getProxy($assoc2['targetEntity'], $relatedId);
$prop->setValue($managedCopy, $proxy);
$this->registerManaged($proxy, $relatedId, array());
$other = $this->em->getProxyFactory()->getProxy($assoc2['targetEntity'], $relatedId);
$this->registerManaged($other, $relatedId, array());
}
}
$prop->setValue($managedCopy, $other);
}
} else {
$mergeCol = $prop->getValue($entity);
@@ -1826,7 +1868,7 @@ class UnitOfWork implements PropertyChangedListener
/**
* Gets the CommitOrderCalculator used by the UnitOfWork to order commits.
*
* @return Doctrine\ORM\Internal\CommitOrderCalculator
* @return \Doctrine\ORM\Internal\CommitOrderCalculator
*/
public function getCommitOrderCalculator()
{
@@ -1853,6 +1895,7 @@ class UnitOfWork implements PropertyChangedListener
$this->collectionDeletions =
$this->collectionUpdates =
$this->extraUpdates =
$this->readOnlyObjects =
$this->orphanRemovals = array();
if ($this->commitOrderCalculator !== null) {
$this->commitOrderCalculator->clear();
@@ -2118,7 +2161,11 @@ class UnitOfWork implements PropertyChangedListener
foreach ($eagerLoadingEntities AS $entityName => $ids) {
$class = $this->em->getClassMetadata($entityName);
$this->getEntityPersister($entityName)->loadAll(array_combine($class->identifier, array(array_values($ids))));
if ($ids) {
$this->getEntityPersister($entityName)->loadAll(
array_combine($class->identifier, array(array_values($ids)))
);
}
}
}
@@ -2264,7 +2311,7 @@ class UnitOfWork implements PropertyChangedListener
* Gets the EntityPersister for an Entity.
*
* @param string $entityName The name of the Entity.
* @return Doctrine\ORM\Persisters\AbstractEntityPersister
* @return \Doctrine\ORM\Persisters\AbstractEntityPersister
*/
public function getEntityPersister($entityName)
{

View File

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

View File

@@ -0,0 +1,77 @@
<?php
namespace Doctrine\Tests\ORM\Functional;
use Doctrine\Tests\Models\CMS\CmsUser;
use Doctrine\Tests\Models\CMS\CmsGroup;
use Doctrine\ORM\Events;
require_once __DIR__ . '/../../TestInit.php';
/**
* ManyToManyEventTest
*
* @author Francisco Facioni <fran6co@gmail.com>
*/
class ManyToManyEventTest extends \Doctrine\Tests\OrmFunctionalTestCase
{
/**
* @var PostUpdateListener
*/
private $listener;
protected function setUp()
{
$this->useModelSet('cms');
parent::setUp();
$this->listener = new PostUpdateListener();
$evm = $this->_em->getEventManager();
$evm->addEventListener(Events::postUpdate, $this->listener);
}
public function testListenerShouldBeNotifiedOnlyWhenUpdating()
{
$user = $this->createNewValidUser();
$this->_em->persist($user);
$this->_em->flush();
$this->assertFalse($this->listener->wasNotified);
$group = new CmsGroup();
$group->name = "admins";
$user->addGroup($group);
$this->_em->persist($user);
$this->_em->flush();
$this->assertTrue($this->listener->wasNotified);
}
/**
* @return CmsUser
*/
private function createNewValidUser()
{
$user = new CmsUser();
$user->username = 'fran6co';
$user->name = 'Francisco Facioni';
$user->status = 'foo';
$group = new CmsGroup();
$group->name = "users";
$user->addGroup($group);
return $user;
}
}
class PostUpdateListener
{
/**
* @var bool
*/
public $wasNotified = false;
/**
* @param $args
*/
public function postUpdate($args)
{
$this->wasNotified = true;
}
}

View File

@@ -0,0 +1,97 @@
<?php
namespace Doctrine\Tests\ORM\Functional;
use Doctrine\Common\Persistence\PersistentObject;
/**
*/
class PersistentCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
{
protected function setUp()
{
parent::setUp();
try {
$this->_schemaTool->createSchema(array(
$this->_em->getClassMetadata(__NAMESPACE__ . '\PersistentCollectionHolder'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\PersistentCollectionContent'),
));
} catch (\Exception $e) {
}
}
public function testPersist()
{
$collectionHolder = new PersistentCollectionHolder();
$content = new PersistentCollectionContent('first element');
$collectionHolder->addElement($content);
$this->_em->persist($collectionHolder);
$this->_em->flush();
$this->_em->clear();
$collectionHolder = $this->_em->find(__NAMESPACE__ . '\PersistentCollectionHolder', $collectionHolder->id);
$collectionHolder->getCollection();
$content = new PersistentCollectionContent('second element');
$collectionHolder->addElement($content);
$this->assertEquals(2, $collectionHolder->getCollection()->count());
}
}
/**
* @Entity
*/
class PersistentCollectionHolder
{
/**
* @Id @Column(type="integer") @GeneratedValue
* @var int
*/
public $id;
/**
* @var \Doctrine\Common\Collections\Collection
* @ManyToMany(targetEntity="PersistentCollectionContent", cascade={"all"})
* @JoinTable(name="pcholder_content_mm")
*/
public $collection;
public function __construct()
{
$this->collection = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* @param PersistentCollectionContent $element
*/
public function addElement(PersistentCollectionContent $element)
{
$this->collection->add($element);
}
/**
* @return \Doctrine\Common\Collections\Collection
*/
public function getCollection()
{
return clone $this->collection;
}
}
/**
* @Entity
*/
class PersistentCollectionContent
{
/**
* @Id @Column(type="integer") @GeneratedValue
* @var int
*/
public $id;
}

View File

@@ -15,9 +15,12 @@ class ReadOnlyTest extends \Doctrine\Tests\OrmFunctionalTestCase
{
parent::setUp();
$this->_schemaTool->createSchema(array(
$this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\ReadOnlyEntity'),
));
try {
$this->_schemaTool->createSchema(array(
$this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\ReadOnlyEntity'),
));
} catch(\Exception $e) {
}
}
public function testReadOnlyEntityNeverChangeTracked()
@@ -36,6 +39,21 @@ class ReadOnlyTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertEquals("Test1", $dbReadOnly->name);
$this->assertEquals(1234, $dbReadOnly->number);
}
/**
* @group DDC-1659
*/
public function testClearReadOnly()
{
$readOnly = new ReadOnlyEntity("Test1", 1234);
$this->_em->persist($readOnly);
$this->_em->flush();
$this->_em->getUnitOfWork()->markReadOnly($readOnly);
$this->_em->clear();
$this->assertFalse($this->_em->getUnitOfWork()->isReadOnly($readOnly));
}
}
/**
@@ -50,7 +68,7 @@ class ReadOnlyEntity
public $id;
/** @column(type="string") */
public $name;
/** @Column(type="integer") */
/** @Column(type="integer", name="number_col") */
public $number;
public function __construct($name, $number)
@@ -58,4 +76,4 @@ class ReadOnlyEntity
$this->name = $name;
$this->number = $number;
}
}
}

View File

@@ -367,4 +367,13 @@ class SingleTableInheritanceTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertNotInstanceOf('Doctrine\ORM\Proxy\Proxy', $contract->getSalesPerson());
}
/**
* @group DDC-1770
*/
public function testTwoSingleTableInheritanceInFromClause()
{
$dql = 'SELECT f1,f2 FROM Doctrine\Tests\Models\Company\CompanyFixContract f1, Doctrine\Tests\Models\Company\CompanyFixContract f2';
$result = $this->_em->createQuery($dql)->getResult();
}
}

View File

@@ -44,11 +44,10 @@ class DDC1040Test extends \Doctrine\Tests\OrmFunctionalTestCase
->setParameter('author', $user)
->getResult();
$dql = "SELECT a FROM Doctrine\Tests\Models\CMS\CmsArticle a WHERE a.topic = :topic AND a.user = :author AND a.user = :author AND a.text = :text";
$dql = "SELECT a FROM Doctrine\Tests\Models\CMS\CmsArticle a WHERE a.topic = :topic AND a.user = :author AND a.user = :author";
$farticle = $this->_em->createQuery($dql)
->setParameter('author', $user)
->setParameter('topic', 'This is John Galt speaking!')
->setParameter('text', 'Yadda Yadda!')
->getSingleResult();
$this->assertSame($article, $farticle);
@@ -70,14 +69,13 @@ class DDC1040Test extends \Doctrine\Tests\OrmFunctionalTestCase
$this->_em->persist($article);
$this->_em->flush();
$dql = "SELECT a FROM Doctrine\Tests\Models\CMS\CmsArticle a WHERE a.topic = ?1 AND a.user = ?2 AND a.user = ?3 AND a.text = ?4";
$dql = "SELECT a FROM Doctrine\Tests\Models\CMS\CmsArticle a WHERE a.topic = ?1 AND a.user = ?2 AND a.user = ?3";
$farticle = $this->_em->createQuery($dql)
->setParameter(1, 'This is John Galt speaking!')
->setParameter(2, $user)
->setParameter(3, $user)
->setParameter(4, 'Yadda Yadda!')
->getSingleResult();
$this->assertSame($article, $farticle);
}
}
}

View File

@@ -417,4 +417,20 @@ class DDC117Test extends \Doctrine\Tests\OrmFunctionalTestCase
return $this->_em->find(get_class($editor), $editor->id);
}
/**
* @group DDC-1519
*/
public function testMergeForeignKeyIdentifierEntity()
{
$idCriteria = array('source' => $this->article1->id(), 'target' => $this->article2->id());
$refRep = $this->_em->find("Doctrine\Tests\Models\DDC117\DDC117Reference", $idCriteria);
$this->_em->detach($refRep);
$refRep = $this->_em->merge($refRep);
$this->assertEquals($this->article1->id(), $refRep->source()->id());
$this->assertEquals($this->article2->id(), $refRep->target()->id());
}
}

View File

@@ -106,7 +106,7 @@ class DDC1209_3
{
/**
* @Id
* @Column(type="datetime")
* @Column(type="datetime", name="ddc1203_date")
*/
private $date;
@@ -122,4 +122,4 @@ class DateTime2 extends \DateTime
{
return $this->format('Y');
}
}
}

View File

@@ -21,58 +21,60 @@ class DDC1228Test extends \Doctrine\Tests\OrmFunctionalTestCase
$this->_em->getClassMetadata(__NAMESPACE__ . '\\DDC1228User'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\\DDC1228Profile'),
));
} catch(\PDOException $e) {
} catch(\Exception $e) {
}
}
public function testOneToOnePersist()
{
$user = new DDC1228User;
$user->name = "Foo";
$profile = new DDC1228Profile();
$profile->name = "Foo";
$user->profile = $profile;
$this->_em->persist($user);
$this->_em->persist($profile);
$this->_em->flush();
$this->_em->clear();
$user = $this->_em->find(__NAMESPACE__ . '\\DDC1228User', $user->id);
$this->assertFalse($user->getProfile()->__isInitialized__, "Proxy is not initialized");
$user->getProfile()->setName("Bar");
$this->assertTrue($user->getProfile()->__isInitialized__, "Proxy is not initialized");
$this->assertEquals("Bar", $user->getProfile()->getName());
$this->assertEquals(array("id" => 1, "name" => "Foo"), $this->_em->getUnitOfWork()->getOriginalEntityData($user->getProfile()));
$this->_em->flush();
$this->_em->clear();
$user = $this->_em->find(__NAMESPACE__ . '\\DDC1228User', $user->id);
$this->assertEquals("Bar", $user->getProfile()->getName());
}
public function testRefresh()
{
$user = new DDC1228User;
$user->name = "Foo";
$profile = new DDC1228Profile();
$profile->name = "Foo";
$user->profile = $profile;
$this->_em->persist($user);
$this->_em->persist($profile);
$this->_em->flush();
$this->_em->clear();
$user = $this->_em->getReference(__NAMESPACE__ . '\\DDC1228User', $user->id);
$this->_em->refresh($user);
$user->name = "Baz";
$this->_em->flush();
$this->_em->clear();
$user = $this->_em->find(__NAMESPACE__ . '\\DDC1228User', $user->id);
$this->assertEquals("Baz", $user->name);
}
@@ -88,20 +90,20 @@ class DDC1228User
* @var int
*/
public $id;
/**
* @column(type="string")
* @var string
*/
public $name = '';
/**
* @OneToOne(targetEntity="DDC1228Profile")
* @var Profile
*/
public $profile;
public function getProfile()
public function getProfile()
{
return $this->profile;
}
@@ -117,13 +119,13 @@ class DDC1228Profile
* @var int
*/
public $id;
/**
* @column(type="string")
* @var string
*/
public $name;
public function getName()
{
return $this->name;
@@ -133,4 +135,4 @@ class DDC1228Profile
{
$this->name = $name;
}
}
}

View File

@@ -19,47 +19,47 @@ class DDC1238Test extends \Doctrine\Tests\OrmFunctionalTestCase
$this->_schemaTool->createSchema(array(
$this->_em->getClassMetadata(__NAMESPACE__ . '\\DDC1238User'),
));
} catch(\PDOException $e) {
} catch(\Exception $e) {
}
}
public function testIssue()
{
$user = new DDC1238User;
$user->setName("test");
$this->_em->persist($user);
$this->_em->flush();
$this->_em->clear();
$userId = $user->getId();
$this->_em->clear();
$user = $this->_em->getReference(__NAMESPACE__ . '\\DDC1238User', $userId);
$this->_em->clear();
$userId2 = $user->getId();
$this->assertEquals($userId, $userId2, "This proxy can still be initialized.");
}
public function testIssueProxyClear()
{
$user = new DDC1238User;
$user->setName("test");
$this->_em->persist($user);
$this->_em->flush();
$this->_em->clear();
$userId = $user->getId();
$this->_em->clear();
$user = $this->_em->getReference(__NAMESPACE__ . '\\DDC1238User', $userId);
$this->_em->clear();
$user2 = $this->_em->getReference(__NAMESPACE__ . '\\DDC1238User', $userId);
$this->assertNull($user->getId(), "Now this is null, we already have a user instance of that type");
}
}
@@ -71,18 +71,18 @@ class DDC1238User
{
/** @Id @GeneratedValue @Column(type="integer") */
private $id;
/**
* @Column
* @var string
*/
private $name;
public function getId()
{
return $this->id;
}
public function getName()
{
return $this->name;

View File

@@ -0,0 +1,146 @@
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\ORM\UnitOfWork;
/**
* @group DDC-1509
*/
class DDC1509Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
protected function setUp()
{
parent::setUp();
try {
$this->_schemaTool->createSchema(array(
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC1509AbstractFile'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC1509File'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC1509Picture'),
));
} catch (\Exception $ignored) {
}
}
public function testFailingCase()
{
$file = new DDC1509File;
$thumbnail = new DDC1509File;
$picture = new DDC1509Picture;
$picture->setFile($file);
$picture->setThumbnail($thumbnail);
/* @var $em \Doctrine\ORM\EntityManager */
$em = $this->_em;
$em->persist($picture);
$em->flush();
$em->clear();
$id = $picture->getPictureId();
$pic = $em->merge($picture);
/* @var $pic DDC1509Picture */
$this->assertNotNull($pic->getThumbnail());
$this->assertNotNull($pic->getFile());
}
}
/**
* @Entity
*/
class DDC1509Picture
{
/**
* @Column(type="integer")
* @Id
* @GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ManyToOne(targetEntity="DDC1509AbstractFile", cascade={"persist", "remove"})
*/
private $thumbnail;
/**
* @ManyToOne(targetEntity="DDC1509AbstractFile", cascade={"persist", "remove"})
*/
private $file;
/**
* Get pictureId
*/
public function getPictureId()
{
return $this->id;
}
/**
* Set file
*/
public function setFile($value = null)
{
$this->file = $value;
}
/**
* Get file
*/
public function getFile()
{
return $this->file;
}
public function getThumbnail()
{
return $this->thumbnail;
}
public function setThumbnail($thumbnail)
{
$this->thumbnail = $thumbnail;
}
}
/**
* @Entity
* @InheritanceType("SINGLE_TABLE")
* @DiscriminatorColumn(name="discr", type="string")
* @DiscriminatorMap({"file" = "DDC1509File"})
*/
class DDC1509AbstractFile
{
/**
* @Column(type="integer")
* @Id
* @GeneratedValue(strategy="AUTO")
*/
public $id;
/**
* Get fileId
*/
public function getFileId()
{
return $this->id;
}
}
/**
* @Entity
*/
class DDC1509File extends DDC1509AbstractFile
{
}

View File

@@ -0,0 +1,113 @@
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\UnitOfWork;
require_once __DIR__ . '/../../../TestInit.php';
/**
* @group DDC-1514
*/
class DDC1514Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
protected function setUp()
{
parent::setUp();
try {
$this->_schemaTool->createSchema(array(
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC1514EntityA'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC1514EntityB'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC1514EntityC'),
));
} catch (\Exception $ignored) {
}
}
public function testIssue()
{
$a1 = new DDC1514EntityA();
$a1->title = "foo";
$a2 = new DDC1514EntityA();
$a2->title = "bar";
$b1 = new DDC1514EntityB();
$b1->entityAFrom = $a1;
$b1->entityATo = $a2;
$b2 = new DDC1514EntityB();
$b2->entityAFrom = $a2;
$b2->entityATo = $a1;
$c = new DDC1514EntityC();
$c->title = "baz";
$a2->entityC = $c;
$this->_em->persist($a1);
$this->_em->persist($a2);
$this->_em->persist($b1);
$this->_em->persist($b2);
$this->_em->persist($c);
$this->_em->flush();
$this->_em->clear();
$dql = "SELECT a, b, ba, c FROM " . __NAMESPACE__ . "\DDC1514EntityA AS a LEFT JOIN a.entitiesB AS b LEFT JOIN b.entityATo AS ba LEFT JOIN a.entityC AS c";
$results = $this->_em->createQuery($dql)->getResult();
$this->assertInstanceOf(__NAMESPACE__ . "\DDC1514EntityA", $results[1]);
$this->assertInstanceOf(__NAMESPACE__ . "\DDC1514EntityC", $results[1]->entityC);
$this->assertEquals($c->title, $results[1]->entityC->title);
}
}
/**
* @Entity
*/
class DDC1514EntityA
{
/** @Id @Column(type="integer") @GeneratedValue */
public $id;
/** @Column */
public $title;
/** @ManyToMany(targetEntity="DDC1514EntityB", mappedBy="entityAFrom") */
public $entitiesB;
/** @ManyToOne(targetEntity="DDC1514EntityC") */
public $entityC;
public function __construct()
{
$this->entitiesB = new ArrayCollection();
}
}
/**
* @Entity
*/
class DDC1514EntityB
{
/** @Id @Column(type="integer") @GeneratedValue */
public $id;
/**
* @ManyToOne(targetEntity="DDC1514EntityA", inversedBy="entitiesB")
*/
public $entityAFrom;
/**
* @ManyToOne(targetEntity="DDC1514EntityA")
*/
public $entityATo;
}
/**
* @Entity
*/
class DDC1514EntityC
{
/** @Id @Column(type="integer") @GeneratedValue */
public $id;
/** @Column */
public $title;
}

View File

@@ -0,0 +1,64 @@
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
/**
* @group DDC-1515
*/
class DDC1515Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
public function setUp()
{
parent::setUp();
$this->_schemaTool->createSchema(array(
$this->_em->getClassMetadata(__NAMESPACE__ . '\\DDC1515Foo'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\\DDC1515Bar'),
));
}
public function testIssue()
{
$bar = new DDC1515Bar();
$this->_em->persist($bar);
$this->_em->flush();
$foo = new DDC1515Foo();
$foo->bar = $bar;
$this->_em->persist($foo);
$this->_em->flush();
$this->_em->clear();
$bar = $this->_em->find(__NAMESPACE__ . '\DDC1515Bar', $bar->id);
$this->assertInstanceOf(__NAMESPACE__.'\DDC1515Foo', $bar->foo);
}
}
/**
* @Entity
*/
class DDC1515Foo
{
/**
* @OneToOne(targetEntity="DDC1515Bar", inversedBy="foo") @Id
*/
public $bar;
}
/**
* @Entity
*/
class DDC1515Bar
{
/**
* @Id @Column(type="integer") @GeneratedValue
*/
public $id;
/**
* @OneToOne(targetEntity="DDC1515Foo", mappedBy="bar")
*/
public $foo;
}

View File

@@ -0,0 +1,67 @@
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
/**
* @group DDC-1526
*/
class DDC1526Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
public function setUp()
{
parent::setUp();
$this->_schemaTool->createSchema(array(
$this->_em->getClassMetadata(__NAMESPACE__ . '\\DDC1526Menu'),
));
}
public function testIssue()
{
$parents = array();
for ($i = 0; $i < 9; $i++) {
$entity = new DDC1526Menu;
if (isset ($parents[($i % 3)])) {
$entity->parent = $parents[($i%3)];
}
$this->_em->persist($entity);
$parents[$i] = $entity;
}
$this->_em->flush();
$this->_em->clear();
$dql = "SELECT m, c
FROM " . __NAMESPACE__ . "\DDC1526Menu m
LEFT JOIN m.children c";
$menus = $this->_em->createQuery($dql)->getResult();
// All Children collection now have to be initiailzed
foreach ($menus as $menu) {
$this->assertTrue($menu->children->isInitialized());
}
}
}
/**
* @Entity
*/
class DDC1526Menu
{
/**
* @Column(type="integer")
* @Id
* @GeneratedValue
*/
public $id;
/**
* @ManyToOne(targetEntity="DDC1526Menu", inversedBy="children")
*/
public $parent;
/**
* @OneToMany(targetEntity="DDC1526Menu", mappedBy="parent")
*/
public $children;
}

View File

@@ -0,0 +1,203 @@
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\Tests\Models\Qelista\User;
use Doctrine\Tests\Models\Qelista\ShoppingList;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Tests\Models\CMS\CmsComment;
use Doctrine\Tests\Models\CMS\CmsArticle;
use Doctrine\Tests\Models\CMS\CmsUser;
require_once __DIR__ . '/../../../TestInit.php';
/**
* @group DDC-1545
*/
class DDC1545Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
private $articleId;
private $userId;
private $user2Id;
public function setUp()
{
$this->useModelSet('cms');
parent::setUp();
}
private function initDb($link)
{
$article = new CmsArticle();
$article->topic = 'foo';
$article->text = 'foo';
$user = new CmsUser();
$user->status = 'foo';
$user->username = 'foo';
$user->name = 'foo';
$user2 = new CmsUser();
$user2->status = 'bar';
$user2->username = 'bar';
$user2->name = 'bar';
if ($link) {
$article->user = $user;
}
$this->_em->persist($article);
$this->_em->persist($user);
$this->_em->persist($user2);
$this->_em->flush();
$this->_em->clear();
$this->articleId = $article->id;
$this->userId = $user->id;
$this->user2Id = $user2->id;
}
public function testLinkObjects()
{
$this->initDb(false);
// don't join association
$article = $this->_em->find('Doctrine\Tests\Models\Cms\CmsArticle', $this->articleId);
$user = $this->_em->find('Doctrine\Tests\Models\Cms\CmsUser', $this->userId);
$article->user = $user;
$this->_em->flush();
$this->_em->clear();
$article = $this->_em
->createQuery('SELECT a, u FROM Doctrine\Tests\Models\Cms\CmsArticle a LEFT JOIN a.user u WHERE a.id = :id')
->setParameter('id', $this->articleId)
->getOneOrNullResult();
$this->assertNotNull($article->user);
$this->assertEquals($user->id, $article->user->id);
}
public function testLinkObjectsWithAssociationLoaded()
{
$this->initDb(false);
// join association
$article = $this->_em
->createQuery('SELECT a, u FROM Doctrine\Tests\Models\Cms\CmsArticle a LEFT JOIN a.user u WHERE a.id = :id')
->setParameter('id', $this->articleId)
->getOneOrNullResult();
$user = $this->_em->find('Doctrine\Tests\Models\Cms\CmsUser', $this->userId);
$article->user = $user;
$this->_em->flush();
$this->_em->clear();
$article = $this->_em
->createQuery('SELECT a, u FROM Doctrine\Tests\Models\Cms\CmsArticle a LEFT JOIN a.user u WHERE a.id = :id')
->setParameter('id', $this->articleId)
->getOneOrNullResult();
$this->assertNotNull($article->user);
$this->assertEquals($user->id, $article->user->id);
}
public function testUnlinkObjects()
{
$this->initDb(true);
// don't join association
$article = $this->_em->find('Doctrine\Tests\Models\Cms\CmsArticle', $this->articleId);
$article->user = null;
$this->_em->flush();
$this->_em->clear();
$article = $this->_em
->createQuery('SELECT a, u FROM Doctrine\Tests\Models\Cms\CmsArticle a LEFT JOIN a.user u WHERE a.id = :id')
->setParameter('id', $this->articleId)
->getOneOrNullResult();
$this->assertNull($article->user);
}
public function testUnlinkObjectsWithAssociationLoaded()
{
$this->initDb(true);
// join association
$article = $this->_em
->createQuery('SELECT a, u FROM Doctrine\Tests\Models\Cms\CmsArticle a LEFT JOIN a.user u WHERE a.id = :id')
->setParameter('id', $this->articleId)
->getOneOrNullResult();
$article->user = null;
$this->_em->flush();
$this->_em->clear();
$article = $this->_em
->createQuery('SELECT a, u FROM Doctrine\Tests\Models\Cms\CmsArticle a LEFT JOIN a.user u WHERE a.id = :id')
->setParameter('id', $this->articleId)
->getOneOrNullResult();
$this->assertNull($article->user);
}
public function testChangeLink()
{
$this->initDb(false);
// don't join association
$article = $this->_em->find('Doctrine\Tests\Models\Cms\CmsArticle', $this->articleId);
$user2 = $this->_em->find('Doctrine\Tests\Models\Cms\CmsUser', $this->user2Id);
$article->user = $user2;
$this->_em->flush();
$this->_em->clear();
$article = $this->_em
->createQuery('SELECT a, u FROM Doctrine\Tests\Models\Cms\CmsArticle a LEFT JOIN a.user u WHERE a.id = :id')
->setParameter('id', $this->articleId)
->getOneOrNullResult();
$this->assertNotNull($article->user);
$this->assertEquals($user2->id, $article->user->id);
}
public function testChangeLinkWithAssociationLoaded()
{
$this->initDb(false);
// join association
$article = $this->_em
->createQuery('SELECT a, u FROM Doctrine\Tests\Models\Cms\CmsArticle a LEFT JOIN a.user u WHERE a.id = :id')
->setParameter('id', $this->articleId)
->getOneOrNullResult();
$user2 = $this->_em->find('Doctrine\Tests\Models\Cms\CmsUser', $this->user2Id);
$article->user = $user2;
$this->_em->flush();
$this->_em->clear();
$article = $this->_em
->createQuery('SELECT a, u FROM Doctrine\Tests\Models\Cms\CmsArticle a LEFT JOIN a.user u WHERE a.id = :id')
->setParameter('id', $this->articleId)
->getOneOrNullResult();
$this->assertNotNull($article->user);
$this->assertEquals($user2->id, $article->user->id);
}
}

View File

@@ -0,0 +1,80 @@
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
/**
* @group DDC-1548
*/
class DDC1548Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
public function setUp()
{
parent::setUp();
$this->_schemaTool->createSchema(array(
$this->_em->getClassMetadata(__NAMESPACE__ . '\\DDC1548E1'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\\DDC1548E2'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\\DDC1548Rel'),
));
}
public function testIssue()
{
$rel = new DDC1548Rel();
$this->_em->persist($rel);
$this->_em->flush();
$e1 = new DDC1548E1();
$e1->rel = $rel;
$this->_em->persist($e1);
$this->_em->flush();
$this->_em->clear();
$obt = $this->_em->find(__NAMESPACE__ . '\DDC1548Rel', $rel->id);
$this->assertNull($obt->e2);
}
}
/**
* @Entity
*/
class DDC1548E1
{
/**
* @Id
* @OneToOne(targetEntity="DDC1548Rel", inversedBy="e1")
*/
public $rel;
}
/**
* @Entity
*/
class DDC1548E2
{
/**
* @Id
* @OneToOne(targetEntity="DDC1548Rel", inversedBy="e2")
*/
public $rel;
}
/**
* @Entity
*/
class DDC1548Rel
{
/**
* @Id @GeneratedValue
* @Column(type="integer")
*/
public $id;
/**
* @OneToOne(targetEntity="DDC1548E1", mappedBy="rel")
*/
public $e1;
/**
* @OneToOne(targetEntity="DDC1548E2", mappedBy="rel")
*/
public $e2;
}

View File

@@ -0,0 +1,45 @@
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Tests\Models\CMS\CmsComment;
use Doctrine\Tests\Models\CMS\CmsArticle;
use Doctrine\Tests\Models\CMS\CmsUser;
/**
* @group DDC-1594
*/
class DDC1594Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
public function setUp()
{
$this->useModelSet('cms');
parent::setUp();
}
public function testIssue()
{
$user = new CmsUser();
$user->status = 'foo';
$user->username = 'foo';
$user->name = 'foo';
$this->_em->persist($user);
$this->_em->flush();
$this->_em->clear();
$detachedUser = clone $user;
$detachedUser->name = 'bar';
$detachedUser->status = 'bar';
$newUser = $this->_em->getReference(get_class($user), $user->id);
$mergedUser = $this->_em->merge($detachedUser);
$this->assertNotSame($mergedUser, $detachedUser);
$this->assertEquals('bar', $detachedUser->getName());
$this->assertEquals('bar', $mergedUser->getName());
}
}

View File

@@ -0,0 +1,121 @@
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\Tests\Models\CMS\CmsUser;
use Doctrine\Tests\Models\CMS\CmsGroup;
/**
* @group DDC-1643
*/
class DDC1643Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
private $user1;
private $user2;
public function setUp()
{
$this->useModelSet('cms');
parent::setUp();
$user1 = new CmsUser();
$user1->username = "beberlei";
$user1->name = "Benjamin";
$user1->status = "active";
$group1 = new CmsGroup();
$group1->name = "test";
$group2 = new CmsGroup();
$group2->name = "test";
$user1->addGroup($group1);
$user1->addGroup($group2);
$user2 = new CmsUser();
$user2->username = "romanb";
$user2->name = "Roman";
$user2->status = "active";
$this->_em->persist($user1);
$this->_em->persist($user2);
$this->_em->persist($group1);
$this->_em->persist($group2);
$this->_em->flush();
$this->_em->clear();
$this->user1 = $this->_em->find(get_class($user1), $user1->id);
$this->user2 = $this->_em->find(get_class($user1), $user2->id);
}
public function testClonePersistentCollectionAndReuse()
{
$user1 = $this->user1;
$user1->groups = clone $user1->groups;
$this->_em->flush();
$this->_em->clear();
$user1 = $this->_em->find(get_class($user1), $user1->id);
$this->assertEquals(2, count($user1->groups));
}
public function testClonePersistentCollectionAndShare()
{
$user1 = $this->user1;
$user2 = $this->user2;
$user2->groups = clone $user1->groups;
$this->_em->flush();
$this->_em->clear();
$user1 = $this->_em->find(get_class($user1), $user1->id);
$user2 = $this->_em->find(get_class($user1), $user2->id);
$this->assertEquals(2, count($user1->groups));
$this->assertEquals(2, count($user2->groups));
}
public function testCloneThenDirtyPersistentCollection()
{
$user1 = $this->user1;
$user2 = $this->user2;
$group3 = new CmsGroup();
$group3->name = "test";
$user2->groups = clone $user1->groups;
$user2->groups->add($group3);
$this->_em->persist($group3);
$this->_em->flush();
$this->_em->clear();
$user1 = $this->_em->find(get_class($user1), $user1->id);
$user2 = $this->_em->find(get_class($user1), $user2->id);
$this->assertEquals(3, count($user2->groups));
$this->assertEquals(2, count($user1->groups));
}
public function testNotCloneAndPassAroundFlush()
{
$user1 = $this->user1;
$user2 = $this->user2;
$group3 = new CmsGroup();
$group3->name = "test";
$user2->groups = $user1->groups;
$user2->groups->add($group3);
$this->assertEQuals(1, count($user1->groups->getInsertDiff()));
$this->_em->persist($group3);
$this->_em->flush();
$this->_em->clear();
$user1 = $this->_em->find(get_class($user1), $user1->id);
$user2 = $this->_em->find(get_class($user1), $user2->id);
$this->assertEquals(3, count($user2->groups));
$this->assertEquals(3, count($user1->groups));
}
}

View File

@@ -0,0 +1,158 @@
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
/**
* @group DDC-1695
*/
class DDC1695Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
public function testIssue()
{
if ($this->_em->getConnection()->getDatabasePlatform()->getName() != "sqlite") {
$this->markTestSkipped("Only with sqlite");
}
$dql = "SELECT n.smallText, n.publishDate FROM " . __NAMESPACE__ . "\\DDC1695News n";
$sql = $this->_em->createQuery($dql)->getSQL();
$this->assertEquals(
'SELECT d0_."SmallText" AS SmallText0, d0_."PublishDate" AS PublishDate1 FROM "DDC1695News" d0_',
$sql
);
}
}
/**
* @Table(name="`DDC1695News`")
* @Entity
*/
class DDC1695News
{
/**
* @var integer $idNews
*
* @Column(name="`IdNews`", type="integer", nullable=false)
* @Id
* @GeneratedValue
*/
private $idNews;
/**
* @var bigint $iduser
*
* @Column(name="`IdUser`", type="bigint", nullable=false)
*/
private $idUser;
/**
* @var integer $idLanguage
*
* @Column(name="`IdLanguage`", type="integer", nullable=false)
*/
private $idLanguage;
/**
* @var integer $idCondition
*
* @Column(name="`IdCondition`", type="integer", nullable=true)
*/
private $idCondition;
/**
* @var integer $idHealthProvider
*
* @Column(name="`IdHealthProvider`", type="integer", nullable=true)
*/
private $idHealthProvider;
/**
* @var integer $idSpeciality
*
* @Column(name="`IdSpeciality`", type="integer", nullable=true)
*/
private $idSpeciality;
/**
* @var integer $idMedicineType
*
* @Column(name="`IdMedicineType`", type="integer", nullable=true)
*/
private $idMedicineType;
/**
* @var integer $idTreatment
*
* @Column(name="`IdTreatment`", type="integer", nullable=true)
*/
private $idTreatment;
/**
* @var string $title
*
* @Column(name="`Title`", type="string", nullable=true)
*/
private $title;
/**
* @var string $smallText
*
* @Column(name="`SmallText`", type="string", nullable=true)
*/
private $smallText;
/**
* @var string $longText
*
* @Column(name="`LongText`", type="string", nullable=true)
*/
private $longText;
/**
* @var datetimetz $publishDate
*
* @Column(name="`PublishDate`", type="datetimetz", nullable=true)
*/
private $publishDate;
/**
* @var tsvector $idxNews
*
* @Column(name="`IdxNews`", type="tsvector", nullable=true)
*/
private $idxNews;
/**
* @var boolean $highlight
*
* @Column(name="`Highlight`", type="boolean", nullable=false)
*/
private $highlight;
/**
* @var integer $order
*
* @Column(name="`Order`", type="integer", nullable=false)
*/
private $order;
/**
* @var boolean $deleted
*
* @Column(name="`Deleted`", type="boolean", nullable=false)
*/
private $deleted;
/**
* @var boolean $active
*
* @Column(name="`Active`", type="boolean", nullable=false)
*/
private $active;
/**
* @var boolean $updateToHighlighted
*
* @Column(name="`UpdateToHighlighted`", type="boolean", nullable=true)
*/
private $updateToHighlighted;
}

View File

@@ -121,6 +121,9 @@ class TypeTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertInstanceOf('DateTime', $dateTimeDb->datetime);
$this->assertEquals('2009-10-02 20:10:52', $dateTimeDb->datetime->format('Y-m-d H:i:s'));
$articles = $this->_em->getRepository( 'Doctrine\Tests\Models\Generic\DateTimeModel' )->findBy( array( 'datetime' => new \DateTime( "now" ) ) );
$this->assertEquals( 0, count( $articles ) );
}
public function testDqlQueryBindDateTimeInstance()
@@ -172,4 +175,4 @@ class TypeTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertInstanceOf('DateTime', $dateTime->time);
$this->assertEquals('19:27:20', $dateTime->time->format('H:i:s'));
}
}
}

View File

@@ -9,6 +9,7 @@ use Doctrine\Tests\Mocks\ConnectionMock;
use Doctrine\Tests\Mocks\DriverMock;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\Common\EventManager;
use Doctrine\ORM\Mapping\ClassMetadataFactory;
require_once __DIR__ . '/../../TestInit.php';
@@ -81,6 +82,51 @@ class ClassMetadataFactoryTest extends \Doctrine\Tests\OrmTestCase
$this->assertFalse($h2);
$this->assertTrue($h1);
}
/**
* @group DDC-1512
*/
public function testIsTransient()
{
$cmf = new ClassMetadataFactory();
$driver = $this->getMock('Doctrine\ORM\Mapping\Driver\Driver');
$driver->expects($this->at(0))
->method('isTransient')
->with($this->equalTo('Doctrine\Tests\Models\CMS\CmsUser'))
->will($this->returnValue(true));
$driver->expects($this->at(1))
->method('isTransient')
->with($this->equalTo('Doctrine\Tests\Models\CMS\CmsArticle'))
->will($this->returnValue(false));
$em = $this->_createEntityManager($driver);
$this->assertTrue($em->getMetadataFactory()->isTransient('Doctrine\Tests\Models\CMS\CmsUser'));
$this->assertFalse($em->getMetadataFactory()->isTransient('Doctrine\Tests\Models\CMS\CmsArticle'));
}
/**
* @group DDC-1512
*/
public function testIsTransientEntityNamespace()
{
$cmf = new ClassMetadataFactory();
$driver = $this->getMock('Doctrine\ORM\Mapping\Driver\Driver');
$driver->expects($this->at(0))
->method('isTransient')
->with($this->equalTo('Doctrine\Tests\Models\CMS\CmsUser'))
->will($this->returnValue(true));
$driver->expects($this->at(1))
->method('isTransient')
->with($this->equalTo('Doctrine\Tests\Models\CMS\CmsArticle'))
->will($this->returnValue(false));
$em = $this->_createEntityManager($driver);
$em->getConfiguration()->addEntityNamespace('CMS', 'Doctrine\Tests\Models\CMS');
$this->assertTrue($em->getMetadataFactory()->isTransient('CMS:CmsUser'));
$this->assertFalse($em->getMetadataFactory()->isTransient('CMS:CmsArticle'));
}
protected function _createEntityManager($metadataDriver)
{

View File

@@ -33,6 +33,24 @@ class XmlMappingDriverTest extends AbstractMappingDriverTest
$this->assertEquals($expectedMap, $class->discriminatorMap);
}
public function testIdentifierWithAssociationKey()
{
$driver = $this->_loadDriver();
$em = $this->_getTestEntityManager();
$factory = new \Doctrine\ORM\Mapping\ClassMetadataFactory();
$em->getConfiguration()->setMetadataDriverImpl($driver);
$factory->setEntityManager($em);
$class = $factory->getMetadataFor('Doctrine\Tests\Models\DDC117\DDC117Translation');
$this->assertEquals(array('language', 'article'), $class->identifier);
$this->assertArrayHasKey('article', $class->associationMappings);
$this->assertArrayHasKey('id', $class->associationMappings['article']);
$this->assertTrue($class->associationMappings['article']['id']);
}
/**
* @param string $xmlMappingFile
* @dataProvider dataValidSchema

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
http://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="Doctrine\Tests\Models\DDC117\DDC117Translation">
<many-to-one field="article" target-entity="DDC117Article">
<join-column name="article_id" referenced-column-name="article_id" />
</many-to-one>
<many-to-many field="reviewedByEditors" target-entity="DDC117Editor" mapped-by="reviewingTranslations" />
<one-to-many field="lastTranslatedBy" target-entity="DDC117Editor" mapped-by="lastTranslation" />
<id name="article" association-key="true" />
<id name="language" type="string" />
<field name="title" type="string" />
</entity>
</doctrine-mapping>

View File

@@ -336,4 +336,13 @@ class ExprTest extends \Doctrine\Tests\OrmTestCase
$orExpr = $this->_expr->orx();
$orExpr->add($this->_expr->quot(5, 2));
}
}
/**
* @group DDC-1683
*/
public function testBooleanLiteral()
{
$this->assertEquals('true', $this->_expr->literal(true));
$this->assertEquals('false', $this->_expr->literal(false));
}
}

View File

@@ -90,4 +90,28 @@ class QueryTest extends \Doctrine\Tests\OrmTestCase
$this->assertEquals('baz', $q->getHint('bar'));
$this->assertEquals(array('foo' => 'bar', 'bar' => 'baz'), $q->getHints());
}
/**
* @expectedException Doctrine\ORM\Query\QueryException
**/
public function testIterateWithNoDistinctAndWrongSelectClause()
{
$q = $this->_em->createQuery("select u, a from Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a");
$q->iterate();
}
/**
* @expectedException Doctrine\ORM\Query\QueryException
**/
public function testIterateWithNoDistinctAndWithValidSelectClause()
{
$q = $this->_em->createQuery("select u from Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a");
$q->iterate();
}
public function testIterateWithDistinct()
{
$q = $this->_em->createQuery("SELECT DISTINCT u from Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a");
$q->iterate();
}
}

View File

@@ -732,4 +732,17 @@ class QueryBuilderTest extends \Doctrine\Tests\OrmTestCase
$this->assertEquals('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u', $qb->getDQL());
}
}
/**
* @group DDC-1619
*/
public function testAddDistinct()
{
$qb = $this->_em->createQueryBuilder()
->select('u')
->distinct()
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u');
$this->assertEquals('SELECT DISTINCT u FROM Doctrine\Tests\Models\CMS\CmsUser u', $qb->getDQL());
}
}

View File

@@ -68,10 +68,10 @@ abstract class AbstractClassMetadataExporterTest extends \Doctrine\Tests\OrmTest
protected function _createMetadataDriver($type, $path)
{
$mappingDriver = array(
'php' => 'PHPDriver',
'php' => 'PHPDriver',
'annotation' => 'AnnotationDriver',
'xml' => 'XmlDriver',
'yaml' => 'YamlDriver',
'xml' => 'XmlDriver',
'yaml' => 'YamlDriver',
);
$this->assertArrayHasKey($type, $mappingDriver, "There is no metadata driver for the type '" . $type . "'.");
$driverName = $mappingDriver[$type];
@@ -185,7 +185,7 @@ abstract class AbstractClassMetadataExporterTest extends \Doctrine\Tests\OrmTest
* @depends testIdentifierIsExported
* @param ClassMetadataInfo $class
*/
public function testFieldsAreExpored($class)
public function testFieldsAreExported($class)
{
$this->assertTrue(isset($class->fieldMappings['id']['id']) && $class->fieldMappings['id']['id'] === true);
$this->assertEquals('id', $class->fieldMappings['id']['fieldName']);
@@ -206,13 +206,12 @@ abstract class AbstractClassMetadataExporterTest extends \Doctrine\Tests\OrmTest
}
/**
* @depends testFieldsAreExpored
* @depends testFieldsAreExported
* @param ClassMetadataInfo $class
*/
public function testOneToOneAssociationsAreExported($class)
{
$this->assertTrue(isset($class->associationMappings['address']));
//$this->assertTrue($class->associationMappings['address'] instanceof \Doctrine\ORM\Mapping\OneToOneMapping);
$this->assertEquals('Doctrine\Tests\ORM\Tools\Export\Address', $class->associationMappings['address']['targetEntity']);
$this->assertEquals('address_id', $class->associationMappings['address']['joinColumns'][0]['name']);
$this->assertEquals('id', $class->associationMappings['address']['joinColumns'][0]['referencedColumnName']);
@@ -228,6 +227,15 @@ abstract class AbstractClassMetadataExporterTest extends \Doctrine\Tests\OrmTest
return $class;
}
/**
* @depends testFieldsAreExported
*/
public function testManyToOneAssociationsAreExported($class)
{
$this->assertTrue(isset($class->associationMappings['mainGroup']));
$this->assertEquals('Doctrine\Tests\ORM\Tools\Export\Group', $class->associationMappings['mainGroup']['targetEntity']);
}
/**
* @depends testOneToOneAssociationsAreExported
* @param ClassMetadataInfo $class
@@ -338,4 +346,4 @@ abstract class AbstractClassMetadataExporterTest extends \Doctrine\Tests\OrmTest
return rmdir($path);
}
}
}
}

View File

@@ -28,6 +28,11 @@ class User
*/
public $address;
/**
* @ManyToOne(targetEntity="Doctrine\Tests\ORM\Tools\Export\Group")
*/
public $mainGroup;
/**
*
* @OneToMany(targetEntity="Doctrine\Tests\ORM\Tools\Export\Phonenumber", mappedBy="user", cascade={"persist", "merge"}, orphanRemoval=true)

View File

@@ -31,6 +31,10 @@ $metadata->mapField(array(
'columnDefinition' => 'CHAR(32) NOT NULL',
));
$metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
$metadata->mapManyToOne(array(
'fieldName' => 'mainGroup',
'targetEntity' => 'Doctrine\\Tests\\ORM\Tools\\Export\\Group',
));
$metadata->mapOneToOne(array(
'fieldName' => 'address',
'targetEntity' => 'Doctrine\\Tests\\ORM\\Tools\\Export\\Address',
@@ -103,4 +107,4 @@ $metadata->mapManyToMany(array(
),
),
'orderBy' => NULL,
));
));

View File

@@ -4,9 +4,9 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
http://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="Doctrine\Tests\ORM\Tools\Export\User" table="cms_users">
<lifecycle-callbacks>
<lifecycle-callback type="prePersist" method="doStuffOnPrePersist"/>
<lifecycle-callback type="prePersist" method="doOtherStuffOnPrePersistToo"/>
@@ -16,15 +16,17 @@
<id name="id" type="integer" column="id">
<generator strategy="AUTO"/>
</id>
<field name="name" column="name" type="string" length="50" nullable="true" unique="true" />
<field name="email" column="user_email" type="string" column-definition="CHAR(32) NOT NULL" />
<one-to-one field="address" target-entity="Doctrine\Tests\ORM\Tools\Export\Address" inversed-by="user" orphan-removal="true">
<cascade><cascade-persist /></cascade>
<join-column name="address_id" referenced-column-name="id" on-delete="CASCADE" on-update="CASCADE"/>
</one-to-one>
<many-to-one field="mainGroup" target-entity="Doctrine\Tests\ORM\Tools\Export\Group" />
<one-to-many field="phonenumbers" target-entity="Doctrine\Tests\ORM\Tools\Export\Phonenumber" mapped-by="user" orphan-removal="true">
<cascade>
<cascade-persist/>
@@ -34,7 +36,17 @@
<order-by-field name="number" direction="ASC" />
</order-by>
</one-to-many>
<one-to-many field="interests" target-entity="Doctrine\Tests\ORM\Tools\Export\Interests" mapped-by="user" orphan-removal="true">
<cascade>
<cascade-refresh/>
<cascade-persist/>
<cascade-merge/>
<cascade-detach/>
<cascade-remove/>
</cascade>
</one-to-many>
<many-to-many field="groups" target-entity="Doctrine\Tests\ORM\Tools\Export\Group">
<cascade>
<cascade-all/>
@@ -48,7 +60,7 @@
</inverse-join-columns>
</join-table>
</many-to-many>
</entity>
</doctrine-mapping>

View File

@@ -27,6 +27,9 @@ Doctrine\Tests\ORM\Tools\Export\User:
cascade: [ remove, persist ]
inversedBy: user
orphanRemoval: true
manyToOne:
mainGroup:
targetEntity: Doctrine\Tests\ORM\Tools\Export\Group
oneToMany:
phonenumbers:
targetEntity: Doctrine\Tests\ORM\Tools\Export\Phonenumber

View File

@@ -16,7 +16,7 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
/* Shared connection when a TestCase is run alone (outside of it's functional suite) */
protected static $_sharedConn;
/**
* @var \Doctrine\ORM\EntityManager
*/
@@ -117,7 +117,7 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
{
$this->_usedModelSets[$setName] = true;
}
/**
* Sweeps the database tables and clears the EntityManager.
*/
@@ -228,10 +228,10 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
protected function setUp()
{
$forceCreateTables = false;
if ( ! isset(static::$_sharedConn)) {
static::$_sharedConn = TestUtil::getConnection();
if (static::$_sharedConn->getDriver() instanceof \Doctrine\DBAL\Driver\PDOSqlite\Driver) {
$forceCreateTables = true;
}
@@ -244,24 +244,24 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
static::$_sharedConn->executeQuery('SELECT 1 /*' . get_class($this) . '*/ FROM dual');
}
}
if ( ! $this->_em) {
$this->_em = $this->_getEntityManager();
$this->_schemaTool = new \Doctrine\ORM\Tools\SchemaTool($this->_em);
}
$classes = array();
foreach ($this->_usedModelSets as $setName => $bool) {
if ( ! isset(static::$_tablesCreated[$setName])/* || $forceCreateTables*/) {
foreach (static::$_modelSets[$setName] as $className) {
$classes[] = $this->_em->getClassMetadata($className);
}
static::$_tablesCreated[$setName] = true;
}
}
if ($classes) {
$this->_schemaTool->createSchema($classes);
}
@@ -290,7 +290,7 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
$this->_sqlLoggerStack = new \Doctrine\DBAL\Logging\DebugStack();
$this->_sqlLoggerStack->enabled = false;
//FIXME: two different configs! $conn and the created entity manager have
// different configs.
$config = new \Doctrine\ORM\Configuration();
@@ -300,7 +300,7 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
$config->setProxyNamespace('Doctrine\Tests\Proxies');
$config->setMetadataDriverImpl($config->newDefaultAnnotationDriver());
$conn = static::$_sharedConn;
$conn->getConfiguration()->setSQLLogger($this->_sqlLoggerStack);
@@ -311,14 +311,14 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
$evm->removeEventListener(array($event), $listener);
}
}
if (isset($GLOBALS['db_event_subscribers'])) {
foreach (explode(",", $GLOBALS['db_event_subscribers']) AS $subscriberClass) {
$subscriberInstance = new $subscriberClass();
$evm->addEventSubscriber($subscriberInstance);
}
}
return \Doctrine\ORM\EntityManager::create($conn, $config);
}
@@ -335,7 +335,7 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
$params = array_map(function($p) { if (is_object($p)) return get_class($p); else return "'".$p."'"; }, $query['params'] ?: array());
$queries .= ($i+1).". SQL: '".$query['sql']."' Params: ".implode(", ", $params).PHP_EOL;
}
$trace = $e->getTrace();
$traceMsg = "";
foreach($trace AS $part) {
@@ -358,7 +358,7 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
/**
* Using the SQL Logger Stack this method retrieves the current query count executed in this test.
*
*
* @return int
*/
protected function getCurrentQueryCount()