Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
D
doctrine-dbal
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Tomáš Trávníček
doctrine-dbal
Commits
2eb4a16d
Commit
2eb4a16d
authored
Feb 06, 2009
by
romanb
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[2.0] More progress on the UnitOfWork and collections. First basic functional many-many test.
parent
deb095f2
Changes
14
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
267 additions
and
955 deletions
+267
-955
VirtualPropertyObject.php
lib/Doctrine/Common/VirtualPropertyObject.php
+0
-260
VirtualPropertySystem.php
lib/Doctrine/Common/VirtualPropertySystem.php
+0
-241
Connection.php
lib/Doctrine/DBAL/Connection.php
+2
-1
Frontbase.php
lib/Doctrine/ORM/Export/Frontbase.php
+0
-316
Reporter.php
lib/Doctrine/ORM/Export/Reporter.php
+0
-45
AnnotationDriver.php
lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php
+3
-1
ManyToManyMapping.php
lib/Doctrine/ORM/Mapping/ManyToManyMapping.php
+14
-0
PersistentCollection.php
lib/Doctrine/ORM/PersistentCollection.php
+3
-3
AbstractCollectionPersister.php
lib/Doctrine/ORM/Persisters/AbstractCollectionPersister.php
+27
-25
AbstractEntityPersister.php
lib/Doctrine/ORM/Persisters/AbstractEntityPersister.php
+2
-7
ManyToManyPersister.php
lib/Doctrine/ORM/Persisters/ManyToManyPersister.php
+81
-9
OneToManyPersister.php
lib/Doctrine/ORM/Persisters/OneToManyPersister.php
+4
-13
UnitOfWork.php
lib/Doctrine/ORM/UnitOfWork.php
+68
-29
BasicCRUDTest.php
tests/Doctrine/Tests/ORM/Functional/BasicCRUDTest.php
+63
-5
No files found.
lib/Doctrine/Common/VirtualPropertyObject.php
deleted
100644 → 0
View file @
deb095f2
<?php
#namespace Doctrine\Common;
#use \ArrayAccess;
/**
* Base class for classes that use the virtual property system.
*
* @author robo
*/
class
Doctrine_Common_VirtualPropertyObject
implements
ArrayAccess
{
protected
$_data
=
array
();
protected
$_entityName
;
/**
* Initializes a new instance of a class derived from VirtualPropertyObject.
*/
public
function
__construct
()
{
$this
->
_entityName
=
get_class
(
$this
);
if
(
!
Doctrine_Common_VirtualPropertySystem
::
isInitialized
(
$this
->
_entityName
))
{
Doctrine_Common_VirtualPropertySystem
::
initialize
(
$this
->
_entityName
);
}
}
/**
* Generic getter for virtual properties.
*
* @param string $fieldName Name of the field.
* @return mixed
*/
final
public
function
get
(
$fieldName
)
{
if
(
!
Doctrine_Common_VirtualPropertySystem
::
hasProperty
(
$this
->
_entityName
,
$fieldName
))
{
throw
new
Doctrine_Exception
(
"Access of undefined property '
$fieldName
'."
);
}
$getter
=
$this
->
_getCustomAccessor
(
$fieldName
);
if
(
$getter
)
{
return
$this
->
$getter
();
}
return
$this
->
_get
(
$fieldName
);
}
/**
* Generic setter for virtual properties.
*
* @param string $name The name of the field to set.
* @param mixed $value The value of the field.
*/
final
public
function
set
(
$fieldName
,
$value
)
{
if
(
!
Doctrine_Common_VirtualPropertySystem
::
hasProperty
(
$this
->
_entityName
,
$fieldName
))
{
throw
new
Doctrine_Exception
(
"Access of undefined property '
$fieldName
'."
);
}
if
(
Doctrine_Common_VirtualPropertySystem
::
isTypeCheckEnabled
())
{
$this
->
_checkType
(
$fieldName
,
$value
);
}
$setter
=
$this
->
_getCustomMutator
(
$fieldName
);
if
(
$setter
)
{
return
$this
->
$setter
(
$value
);
}
$this
->
_set
(
$fieldName
,
$value
);
}
/**
* Checks the type of a virtual property.
*
* @param <type> $fieldName
* @param <type> $value
*/
protected
function
_checkType
(
$fieldName
,
$value
)
{
$type
=
Doctrine_Common_VirtualPropertySystem
::
getType
(
$this
->
_entityName
,
$fieldName
);
if
(
Doctrine_Common_VirtualPropertySystem
::
isSimplePHPType
(
$type
))
{
$is_type
=
"is_
$type
"
;
if
(
!
$is_type
(
$value
))
{
throw
new
Doctrine_Exception
(
"'
$value
' is of an invalid type. Expected:
$type
."
);
}
}
else
if
(
$type
==
'array'
)
{
if
(
!
is_array
(
$value
))
{
throw
new
Doctrine_Exception
(
"'
$value
' is of an invalid type. Expected: array."
);
}
}
else
{
if
(
!
$value
instanceof
$type
)
{
throw
new
Doctrine_Exception
(
"'
$value
' is of an invalid type. Expected:
$type
."
);
}
}
}
protected
function
_get
(
$fieldName
)
{
return
isset
(
$this
->
_data
[
$fieldName
])
?
$this
->
_data
[
$fieldName
]
:
null
;
}
protected
function
_set
(
$fieldName
,
$value
)
{
$this
->
_data
[
$fieldName
]
=
$value
;
}
/**
* Gets the custom mutator method for a virtual property, if it exists.
*
* @param string $fieldName The field name.
* @return mixed The name of the custom mutator or FALSE, if the field does
* not have a custom mutator.
*/
private
function
_getCustomMutator
(
$fieldName
)
{
if
(
Doctrine_Common_VirtualPropertySystem
::
getMutator
(
$this
->
_entityName
,
$fieldName
)
===
null
)
{
if
(
Doctrine_Common_VirtualPropertySystem
::
isAutoAccessorOverride
())
{
$setterMethod
=
'set'
.
Doctrine
::
classify
(
$fieldName
);
if
(
!
method_exists
(
$this
,
$setterMethod
))
{
$setterMethod
=
false
;
}
Doctrine_Common_VirtualPropertySystem
::
setMutator
(
$this
->
_entityName
,
$fieldName
,
$setterMethod
);
}
else
{
Doctrine_Common_VirtualPropertySystem
::
setMutator
(
$this
->
_entityName
,
$fieldName
,
false
);
}
}
return
Doctrine_Common_VirtualPropertySystem
::
getMutator
(
$this
->
_entityName
,
$fieldName
);
}
/**
* Gets the custom accessor method of a virtual property, if it exists.
*
* @param string $fieldName The field name.
* @return mixed The name of the custom accessor method, or FALSE if the
* field does not have a custom accessor.
*/
private
function
_getCustomAccessor
(
$fieldName
)
{
if
(
Doctrine_Common_VirtualPropertySystem
::
getAccessor
(
$this
->
_entityName
,
$fieldName
)
===
null
)
{
if
(
Doctrine_Common_VirtualPropertySystem
::
isAutoAccessorOverride
())
{
$getterMethod
=
'get'
.
Doctrine
::
classify
(
$fieldName
);
if
(
!
method_exists
(
$this
,
$getterMethod
))
{
$getterMethod
=
false
;
}
Doctrine_Common_VirtualPropertySystem
::
setAccessor
(
$this
->
_entityName
,
$fieldName
,
$getterMethod
);
}
else
{
Doctrine_Common_VirtualPropertySystem
::
setAccessor
(
$this
->
_entityName
,
$fieldName
,
false
);
}
}
return
Doctrine_Common_VirtualPropertySystem
::
getAccessor
(
$this
->
_entityName
,
$fieldName
);
}
protected
function
_contains
(
$fieldName
)
{
return
isset
(
$this
->
_data
[
$fieldName
]);
}
protected
function
_unset
(
$fieldName
)
{
unset
(
$this
->
_data
[
$fieldName
]);
}
/**
* Intercepts mutating calls for virtual properties.
*
* @see set, offsetSet
* @param $name
* @param $value
* @since 1.0
* @return void
*/
public
function
__set
(
$name
,
$value
)
{
$this
->
set
(
$name
,
$value
);
}
/**
* Intercepts accessing calls for virtual properties.
*
* @see get, offsetGet
* @param mixed $name
* @return mixed
*/
public
function
__get
(
$name
)
{
return
$this
->
get
(
$name
);
}
/**
* Intercepts isset() calls for virtual properties.
*
* @param string $name
* @return boolean whether or not this object contains $name
*/
public
function
__isset
(
$name
)
{
return
$this
->
_contains
(
$name
);
}
/**
* Intercepts unset() calls for virtual properties.
*
* @param string $name
* @return void
*/
public
function
__unset
(
$name
)
{
return
$this
->
_unset
(
$name
);
}
/* ArrayAccess implementation */
/**
* Check if an offsetExists.
*
* @param mixed $offset
* @return boolean whether or not this object contains $offset
*/
public
function
offsetExists
(
$offset
)
{
return
$this
->
_contains
(
$offset
);
}
/**
* offsetGet an alias of get()
*
* @see get, __get
* @param mixed $offset
* @return mixed
*/
public
function
offsetGet
(
$offset
)
{
return
$this
->
get
(
$offset
);
}
/**
* sets $offset to $value
* @see set, __set
* @param mixed $offset
* @param mixed $value
* @return void
*/
public
function
offsetSet
(
$offset
,
$value
)
{
return
$this
->
set
(
$offset
,
$value
);
}
/**
* unset a given offset
* @see set, offsetSet, __set
* @param mixed $offset
*/
public
function
offsetUnset
(
$offset
)
{
return
$this
->
_unset
(
$offset
);
}
/* END of ArrayAccess implementation */
}
?>
lib/Doctrine/Common/VirtualPropertySystem.php
deleted
100644 → 0
View file @
deb095f2
<?php
/**
* The VirtualPropertySystem class is a class consisting solely of static methods and
* serves as a generic virtual property registry system.
* Classes register their (virtual) properties with the property system, optionally specifying
* property features/options. These can then be evaluated by other code.
*
* @author robo
* @since 2.0
*/
class
Doctrine_Common_VirtualPropertySystem
{
private
static
$_properties
=
array
();
private
static
$_callback
=
'construct'
;
private
static
$_checkTypes
=
false
;
private
static
$_useAutoAccessorOverride
=
true
;
private
static
$_simplePHPTypes
=
array
(
'int'
=>
true
,
'string'
=>
true
,
'bool'
=>
true
,
'double'
=>
true
);
/** Private constructor. This class cannot be instantiated. */
private
function
__construct
()
{}
/**
* Gets all properties of a class that are registered with the VirtualPropertySystem.
*
* @param string $class
* @return array
*/
public
static
function
getProperties
(
$class
)
{
if
(
!
self
::
isInitialized
(
$class
))
{
self
::
initialize
(
$class
);
}
return
self
::
$_properties
[
$class
];
}
/**
* Gets whether automatic accessor overrides are enabled.
*
* @return boolean
*/
public
static
function
isAutoAccessorOverride
()
{
return
self
::
$_useAutoAccessorOverride
;
}
/**
* Sets whether automatic accessor overrides are enabled.
*
* @param boolean $bool
*/
public
static
function
setAutoAccessorOverride
(
$bool
)
{
self
::
$_useAutoAccessorOverride
=
(
bool
)
$bool
;
}
/**
* Prepopulates the property system.
*
* @param array $properties
*/
public
static
function
populate
(
array
$properties
)
{
self
::
$_properties
=
$properties
;
}
/**
* Checks whether the given type is a simple PHP type.
* Simple php types are: int, string, bool, double.
*
* @param string $type The type to check.
* @return boolean
*/
public
static
function
isSimplePHPType
(
$type
)
{
return
isset
(
self
::
$_simplePHPTypes
[
$type
]);
}
/**
* Gets whether type checks are enabled.
*
* @return boolean
*/
public
static
function
isTypeCheckEnabled
()
{
return
self
::
$_checkTypes
;
}
/**
* Sets whether type checks are enabled.
*
* @param boolean $bool
*/
public
static
function
setTypeCheckEnabled
(
$bool
)
{
self
::
$_checkTypes
=
(
bool
)
$bool
;
}
/**
* Sets the name of the callback method to use for initializing the virtual
* properties of a class. The callback must be static and public.
*
* @param string $callback
*/
public
static
function
setCallback
(
$callback
)
{
self
::
$_callback
=
$callback
;
}
/**
* Registers a virtual property for a class.
*
* @param string $class
* @param string $propName
* @param string $type
* @param string $accessor
* @param string $mutator
*/
public
static
function
register
(
$class
,
$propName
,
$type
,
$accessor
=
null
,
$mutator
=
null
)
{
self
::
$_properties
[
$class
][
$propName
]
=
array
(
'type'
=>
$type
,
'accessor'
=>
$accessor
,
'mutator'
=>
$mutator
);
}
/**
* Gets whether a class has already been initialized by the virtual property system.
*
* @param string $class
* @return boolean
*/
public
static
function
isInitialized
(
$class
)
{
return
isset
(
self
::
$_properties
[
$class
]);
}
/**
* Initializes a class with the virtual property system.
*
* @param <type> $class
*/
public
static
function
initialize
(
$class
)
{
if
(
method_exists
(
$class
,
self
::
$_callback
))
{
call_user_func
(
array
(
$class
,
self
::
$_callback
));
}
else
{
self
::
$_properties
[
$class
]
=
false
;
}
}
/**
* Gets whether a class has a virtual property with a certain name.
*
* @param string $class
* @param string $propName
* @return boolean
*/
public
static
function
hasProperty
(
$class
,
$propName
)
{
return
isset
(
self
::
$_properties
[
$class
][
$propName
]);
}
/**
* Gets the accessor for a virtual property.
*
* @param string $class
* @param string $propName
* @return string|null
*/
public
static
function
getAccessor
(
$class
,
$propName
)
{
return
isset
(
self
::
$_properties
[
$class
][
$propName
][
'accessor'
])
?
self
::
$_properties
[
$class
][
$propName
][
'accessor'
]
:
null
;
}
/**
* Sets the accessor method for a virtual property.
*
* @param <type> $class
* @param <type> $propName
* @param <type> $accessor
*/
public
static
function
setAccessor
(
$class
,
$propName
,
$accessor
)
{
self
::
$_properties
[
$class
][
$propName
][
'accessor'
]
=
$accessor
;
}
/**
* Gets the mutator method for a virtual property.
*
* @param <type> $class
* @param <type> $propName
* @return <type>
*/
public
static
function
getMutator
(
$class
,
$propName
)
{
return
isset
(
self
::
$_properties
[
$class
][
$propName
][
'mutator'
])
?
self
::
$_properties
[
$class
][
$propName
][
'mutator'
]
:
null
;
}
/**
* Sets the mutator method for a virtual property.
*
* @param <type> $class
* @param <type> $propName
* @param <type> $mutator
*/
public
static
function
setMutator
(
$class
,
$propName
,
$mutator
)
{
self
::
$_properties
[
$class
][
$propName
][
'mutator'
]
=
$mutator
;
}
/**
* Gets the type of a virtual property.
*
* @param <type> $class
* @param <type> $propName
* @return <type>
*/
public
static
function
getType
(
$class
,
$propName
)
{
return
isset
(
self
::
$_properties
[
$class
][
$propName
][
'type'
])
?
self
::
$_properties
[
$class
][
$propName
][
'type'
]
:
null
;
}
/**
* Sets the type of a virtual property.
*
* @param <type> $class
* @param <type> $propName
* @param <type> $type
*/
public
static
function
setType
(
$class
,
$propName
,
$type
)
{
self
::
$_properties
[
$class
][
$propName
][
'type'
]
=
$type
;
}
}
?>
lib/Doctrine/DBAL/Connection.php
View file @
2eb4a16d
...
...
@@ -542,8 +542,9 @@ class Connection
public
function
exec
(
$query
,
array
$params
=
array
())
{
$this
->
connect
();
try
{
echo
$query
.
PHP_EOL
;
if
(
!
empty
(
$params
))
{
//
var_dump($params);
var_dump
(
$params
);
$stmt
=
$this
->
prepare
(
$query
);
$stmt
->
execute
(
$params
);
return
$stmt
->
rowCount
();
...
...
lib/Doctrine/ORM/Export/Frontbase.php
deleted
100644 → 0
View file @
deb095f2
This diff is collapsed.
Click to expand it.
lib/Doctrine/ORM/Export/Reporter.php
deleted
100644 → 0
View file @
deb095f2
<?php
/*
* $Id: Reporter.php 3882 2008-02-22 18:11:35Z jwage $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.org>.
*/
/**
* Doctrine_Export_Reporter
*
* @package Doctrine
* @subpackage Export
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.phpdoctrine.org
* @since 1.0
* @version $Revision: 3882 $
*/
class
Doctrine_Export_Reporter
implements
IteratorAggregate
{
protected
$messages
=
array
();
public
function
add
(
$code
,
$message
)
{
$this
->
messages
[]
=
array
(
$code
,
$message
);
}
public
function
pop
()
{
return
array_pop
(
$this
->
messages
);
}
public
function
getIterator
()
{
return
new
ArrayIterator
(
$this
->
messages
);
}
}
\ No newline at end of file
lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php
View file @
2eb4a16d
...
...
@@ -31,9 +31,11 @@ if ( ! class_exists('\Addendum', false)) {
require
__DIR__
.
'/DoctrineAnnotations.php'
;
/**
* The AnnotationDriver reads the mapping metadata from docblock annotations.
* The AnnotationDriver reads the mapping metadata from docblock annotations
* with the help of the Addendum reflection extensions.
*
* @author robo
* @since 2.0
*/
class
AnnotationDriver
{
...
...
lib/Doctrine/ORM/Mapping/ManyToManyMapping.php
View file @
2eb4a16d
...
...
@@ -51,6 +51,11 @@ class ManyToManyMapping extends AssociationMapping
* Maps the columns in the target table to the columns in the relation table.
*/
private
$_targetToRelationKeyColumns
=
array
();
/**
* The columns on the join table.
*/
private
$_joinTableColumns
=
array
();
/**
* Initializes a new ManyToManyMapping.
...
...
@@ -76,25 +81,34 @@ class ManyToManyMapping extends AssociationMapping
if
(
!
isset
(
$mapping
[
'joinTable'
]))
{
throw
MappingException
::
joinTableRequired
(
$mapping
[
'fieldName'
]);
}
// owning side MUST specify joinColumns
if
(
!
isset
(
$mapping
[
'joinTable'
][
'joinColumns'
]))
{
throw
MappingException
::
invalidMapping
(
$this
->
_sourceFieldName
);
}
foreach
(
$mapping
[
'joinTable'
][
'joinColumns'
]
as
$joinColumn
)
{
$this
->
_sourceToRelationKeyColumns
[
$joinColumn
[
'referencedColumnName'
]]
=
$joinColumn
[
'name'
];
$this
->
_joinTableColumns
[]
=
$joinColumn
[
'name'
];
}
$this
->
_sourceKeyColumns
=
array_keys
(
$this
->
_sourceToRelationKeyColumns
);
// owning side MUST specify inverseJoinColumns
if
(
!
isset
(
$mapping
[
'joinTable'
][
'inverseJoinColumns'
]))
{
throw
MappingException
::
invalidMapping
(
$this
->
_sourceFieldName
);
}
foreach
(
$mapping
[
'joinTable'
][
'inverseJoinColumns'
]
as
$inverseJoinColumn
)
{
$this
->
_targetToRelationKeyColumns
[
$inverseJoinColumn
[
'referencedColumnName'
]]
=
$inverseJoinColumn
[
'name'
];
$this
->
_joinTableColumns
[]
=
$inverseJoinColumn
[
'name'
];
}
$this
->
_targetKeyColumns
=
array_keys
(
$this
->
_targetToRelationKeyColumns
);
}
}
public
function
getJoinTableColumns
()
{
return
$this
->
_joinTableColumns
;
}
public
function
getSourceToRelationKeyColumns
()
{
return
$this
->
_sourceToRelationKeyColumns
;
...
...
lib/Doctrine/ORM/PersistentCollection.php
View file @
2eb4a16d
...
...
@@ -27,11 +27,11 @@ use Doctrine\ORM\Mapping\AssociationMapping;
* A PersistentCollection represents a collection of elements that have persistent state.
* Collections of entities represent only the associations (links) to those entities.
* That means, if the collection is part of a many-many mapping and you remove
* entities from the collection, only the links in the
xref
table are removed (on flush).
* entities from the collection, only the links in the
relation
table are removed (on flush).
* Similarly, if you remove entities from a collection that is part of a one-many
* mapping this will only result in the nulling out of the foreign keys on flush
* (or removal of the links in the
xref table if the one-many is mapped through an
*
xref
table). If you want entities in a one-many collection to be removed when
* (or removal of the links in the
relation table if the one-many is mapped through a
*
relation
table). If you want entities in a one-many collection to be removed when
* they're removed from the collection, use deleteOrphans => true on the one-many
* mapping.
*
...
...
lib/Doctrine/ORM/Persisters/AbstractCollectionPersister.php
View file @
2eb4a16d
...
...
@@ -55,54 +55,54 @@ abstract class AbstractCollectionPersister
}
//...
}
/**
* Deletes the persistent state represented by the given collection.
*
* @param PersistentCollection $coll
*/
public
function
delete
(
PersistentCollection
$coll
)
{
if
(
$coll
->
get
Relation
()
->
isInverseSide
())
{
return
;
if
(
$coll
->
get
Mapping
()
->
isInverseSide
())
{
return
;
// ignore inverse side
}
//...
$sql
=
$this
->
_getDeleteSql
(
$coll
);
$this
->
_conn
->
exec
(
$sql
,
$this
->
_getDeleteSqlParameters
(
$coll
));
}
abstract
protected
function
_getDeleteSql
(
PersistentCollection
$coll
);
abstract
protected
function
_getDeleteSqlParameters
(
PersistentCollection
$coll
);
public
function
update
(
PersistentCollection
$coll
)
{
if
(
$coll
->
getMapping
()
->
isInverseSide
())
{
return
;
// ignore inverse side
}
$this
->
deleteRows
(
$coll
);
$this
->
updateRows
(
$coll
);
//
$this->updateRows($coll);
$this
->
insertRows
(
$coll
);
}
/* collection update actions */
public
function
deleteRows
(
PersistentCollection
$coll
)
{
if
(
$coll
->
getMapping
()
->
isInverseSide
())
{
return
;
// ignore inverse side
}
{
$deleteDiff
=
$coll
->
getDeleteDiff
();
$sql
=
$this
->
_getDeleteRowSql
(
$coll
);
$uow
=
$this
->
_em
->
getUnitOfWork
();
foreach
(
$deleteDiff
as
$element
)
{
$this
->
_conn
->
exec
(
$sql
,
$this
->
_getDeleteRowSqlParameters
(
$element
));
$this
->
_conn
->
exec
(
$sql
,
$this
->
_getDeleteRowSqlParameters
(
$
coll
,
$
element
));
}
}
public
function
updateRows
(
PersistentCollection
$coll
)
{
}
{}
public
function
insertRows
(
PersistentCollection
$coll
)
{
if
(
$coll
->
getMapping
()
->
isInverseSide
())
{
return
;
// ignore inverse side
}
$insertDiff
=
$coll
->
getInsertDiff
();
$sql
=
$this
->
_getInsertRowSql
(
$coll
);
$uow
=
$this
->
_em
->
getUnitOfWork
();
foreach
(
$insertDiff
as
$element
)
{
$this
->
_conn
->
exec
(
$sql
/*, $uow->getEntityIdentifier($element)*/
);
$this
->
_conn
->
exec
(
$sql
,
$this
->
_getInsertRowSqlParameters
(
$coll
,
$element
)
);
}
}
...
...
@@ -120,13 +120,15 @@ abstract class AbstractCollectionPersister
*
* @param PersistentCollection $coll
*/
abstract
protected
function
_getUpdateRowSql
();
abstract
protected
function
_getUpdateRowSql
(
PersistentCollection
$coll
);
/**
* Gets the SQL statement used for inserting a row from to the collection.
*
* @param PersistentCollection $coll
*/
abstract
protected
function
_getInsertRowSql
();
abstract
protected
function
_getInsertRowSql
(
PersistentCollection
$coll
);
abstract
protected
function
_getInsertRowSqlParameters
(
PersistentCollection
$coll
,
$element
);
}
lib/Doctrine/ORM/Persisters/AbstractEntityPersister.php
View file @
2eb4a16d
...
...
@@ -171,13 +171,8 @@ abstract class AbstractEntityPersister
protected
function
_prepareData
(
$entity
,
array
&
$result
,
$isInsert
=
false
)
{
foreach
(
$this
->
_em
->
getUnitOfWork
()
->
getEntityChangeSet
(
$entity
)
as
$field
=>
$change
)
{
if
(
is_array
(
$change
))
{
$oldVal
=
$change
[
0
];
$newVal
=
$change
[
1
];
}
else
{
$oldVal
=
null
;
$newVal
=
$change
;
}
$oldVal
=
$change
[
0
];
$newVal
=
$change
[
1
];
$type
=
$this
->
_classMetadata
->
getTypeOfField
(
$field
);
$columnName
=
$this
->
_classMetadata
->
getColumnName
(
$field
);
...
...
lib/Doctrine/ORM/Persisters/ManyToManyPersister.php
View file @
2eb4a16d
...
...
@@ -21,40 +21,112 @@
namespace
Doctrine\ORM\Persisters
;
use
Doctrine\ORM\PersistentCollection
;
/**
* Persister for many-to-many collections.
*
* @author robo
* @since 2.0
*/
class
ManyToManyPersister
extends
AbstractCollectionPersister
{
/**
* {@inheritdoc}
*
* @param <type> $coll
* @override
* @todo Identifier quoting.
* @see _getDeleteRowSqlParameters()
*/
protected
function
_getDeleteRowSql
(
PersistentCollection
$coll
)
{
$mapping
=
$coll
->
getMapping
();
$joinTable
=
$mapping
->
getJoinTable
();
$columns
=
array_merge
(
$mapping
->
getSourceKeyColumns
(),
$mapping
->
getTargetKeyColumns
()
);
return
"DELETE FROM
$joinTable
WHERE "
.
implode
(
' = ?,
'
,
$columns
)
.
' = ?'
;
$columns
=
$mapping
->
getJoinTableColumns
(
);
return
"DELETE FROM
{
$joinTable
[
'name'
]
}
WHERE "
.
implode
(
' = ? AND
'
,
$columns
)
.
' = ?'
;
}
/**
* {@inheritdoc}
*
* @param <type> $element
* @override
* @see _getDeleteRowSql()
*/
protected
function
_getDeleteRowSqlParameters
(
PersistentCollection
$coll
,
$element
)
{
$owner
=
$coll
->
getOwner
();
$params
=
array_merge
(
$this
->
_uow
->
getEntityIdentifier
(
$coll
->
getOwner
()),
$this
->
_uow
->
getEntityIdentifier
(
$element
)
);
//var_dump($params);
return
$params
;
}
/**
* {@inheritdoc}
*
* @override
*/
protected
function
_getUpdateRowSql
(
PersistentCollection
$coll
)
{
}
/**
* {@inheritdoc}
*
* @override
*/
protected
function
_getInsertRowSql
(
PersistentCollection
$coll
)
{
$mapping
=
$coll
->
getMapping
();
$joinTable
=
$mapping
->
getJoinTable
();
$columns
=
$mapping
->
getJoinTableColumns
();
return
"INSERT INTO
{
$joinTable
[
'name'
]
}
("
.
implode
(
', '
,
$columns
)
.
")"
.
" VALUES ("
.
implode
(
', '
,
array_fill
(
0
,
count
(
$columns
),
'?'
))
.
')'
;
}
/**
* {@inheritdoc}
*
* @override
*/
protected
function
_getInsertRowSqlParameters
(
PersistentCollection
$coll
,
$element
)
{
//FIXME: This is still problematic for composite keys because we silently
// rely on a specific ordering of the columns.
$params
=
array_merge
(
$this
->
_uow
->
getEntityIdentifier
(
$coll
->
getOwner
()),
$this
->
_uow
->
getEntityIdentifier
(
$element
)
);
var_dump
(
$params
);
return
$params
;
}
/**
* {@inheritdoc}
*
* @override
*/
protected
function
_getDeleteSql
(
PersistentCollection
$coll
)
{
$mapping
=
$coll
->
getMapping
();
$joinTable
=
$mapping
->
getJoinTable
();
$whereClause
=
''
;
foreach
(
$mapping
->
getSourceToRelationKeyColumns
()
as
$relationColumn
)
{
if
(
$whereClause
!==
''
)
$whereClause
.=
' AND '
;
$whereClause
.=
"
$relationColumn
= ?"
;
}
return
"DELETE FROM
{
$joinTable
[
'name'
]
}
WHERE
$whereClause
"
;
}
/**
* {@inheritdoc}
*
* @override
*/
protected
function
_getDeleteSqlParameters
(
PersistentCollection
$coll
)
{
//FIXME: This is still problematic for composite keys because we silently
// rely on a specific ordering of the columns.
return
$this
->
_uow
->
getEntityIdentifier
(
$coll
->
getOwner
());
}
}
lib/Doctrine/ORM/Persisters/OneToManyPersister.php
View file @
2eb4a16d
...
...
@@ -25,8 +25,11 @@ use Doctrine\ORM\PersistentCollection;
/**
* Persister for one-to-many collections.
*
* This persister is only used for uni-directional one-to-many mappings.
*
* @since 2.0
* @author Roman Borschel <roman@code-factory.org>
*/
class
OneToManyPersister
extends
AbstractCollectionPersister
{
...
...
@@ -57,19 +60,7 @@ class OneToManyPersister extends AbstractCollectionPersister
$whereClause
.=
"
$idColumn
= ?"
;
}
return
"UPDATE
$table
SET
$setClause
WHERE
$whereClause
"
;
}
/**
* {@inheritdoc}
*
* @param <type> $element
* @return <type>
* @override
*/
protected
function
_getDeleteRowSqlParameters
(
PersistentCollection
$coll
,
$element
)
{
return
$this
->
_uow
->
getEntityIdentifier
(
$element
);
return
array
(
"UPDATE
$table
SET
$setClause
WHERE
$whereClause
"
,
$this
->
_uow
->
getEntityIdentifier
(
$element
));
}
protected
function
_getInsertRowSql
()
...
...
lib/Doctrine/ORM/UnitOfWork.php
View file @
2eb4a16d
This diff is collapsed.
Click to expand it.
tests/Doctrine/Tests/ORM/Functional/BasicCRUDTest.php
View file @
2eb4a16d
...
...
@@ -6,8 +6,7 @@ use Doctrine\ORM\Export\ClassExporter;
use
Doctrine\Tests\Models\CMS\CmsUser
;
use
Doctrine\Tests\Models\CMS\CmsPhonenumber
;
use
Doctrine\Tests\Models\CMS\CmsAddress
;
use
Doctrine\Tests\Models\Forum\ForumUser
;
use
Doctrine\Tests\Models\Forum\ForumAvatar
;
use
Doctrine\Tests\Models\CMS\CmsGroup
;
require_once
__DIR__
.
'/../../TestInit.php'
;
...
...
@@ -25,7 +24,8 @@ class BasicCRUDTest extends \Doctrine\Tests\OrmFunctionalTestCase {
$exporter
->
exportClasses
(
array
(
$this
->
_em
->
getClassMetadata
(
'Doctrine\Tests\Models\CMS\CmsUser'
),
$this
->
_em
->
getClassMetadata
(
'Doctrine\Tests\Models\CMS\CmsPhonenumber'
),
$this
->
_em
->
getClassMetadata
(
'Doctrine\Tests\Models\CMS\CmsAddress'
)
$this
->
_em
->
getClassMetadata
(
'Doctrine\Tests\Models\CMS\CmsAddress'
),
$this
->
_em
->
getClassMetadata
(
'Doctrine\Tests\Models\CMS\CmsGroup'
)
));
// Create
...
...
@@ -48,7 +48,7 @@ class BasicCRUDTest extends \Doctrine\Tests\OrmFunctionalTestCase {
$em
->
flush
();
$this
->
assertTrue
(
$em
->
contains
(
$ph
));
$this
->
assertTrue
(
$em
->
contains
(
$user
));
$this
->
assertTrue
(
$user
->
phonenumbers
instanceof
\Doctrine\ORM\PersistentCollection
);
//
$this->assertTrue($user->phonenumbers instanceof \Doctrine\ORM\PersistentCollection);
// Update name
$user
->
name
=
'guilherme'
;
...
...
@@ -90,7 +90,7 @@ class BasicCRUDTest extends \Doctrine\Tests\OrmFunctionalTestCase {
$this
->
_em
->
save
(
$user
);
$this
->
_em
->
flush
();
$this
->
assertTrue
(
$user
->
phonenumbers
instanceof
\Doctrine\ORM\PersistentCollection
);
//
$this->assertTrue($user->phonenumbers instanceof \Doctrine\ORM\PersistentCollection);
// Remove the first element from the collection
unset
(
$user
->
phonenumbers
[
0
]);
...
...
@@ -125,5 +125,63 @@ class BasicCRUDTest extends \Doctrine\Tests\OrmFunctionalTestCase {
array
(
$address
->
id
))
->
fetchColumn
();
$this
->
assertTrue
(
is_numeric
(
$userId
));
}
public
function
testBasicManyToMany
()
{
$user
=
new
CmsUser
;
$user
->
name
=
'Guilherme'
;
$user
->
username
=
'gblanco'
;
$user
->
status
=
'developer'
;
$group
=
new
CmsGroup
;
$group
->
name
=
'Developers'
;
$user
->
groups
[]
=
$group
;
$group
->
users
[]
=
$user
;
$this
->
_em
->
save
(
$user
);
$this
->
_em
->
save
(
$group
);
$this
->
_em
->
flush
();
unset
(
$group
->
users
[
0
]);
// inverse side
unset
(
$user
->
groups
[
0
]);
// owning side!
$this
->
_em
->
flush
();
// Check that the link in the association table has been deleted
$count
=
$this
->
_em
->
getConnection
()
->
execute
(
"SELECT COUNT(*) FROM cms_users_groups"
,
array
())
->
fetchColumn
();
$this
->
assertEquals
(
0
,
$count
);
}
public
function
testManyToManyCollectionClearing
()
{
$user
=
new
CmsUser
;
$user
->
name
=
'Guilherme'
;
$user
->
username
=
'gblanco'
;
$user
->
status
=
'developer'
;
for
(
$i
=
0
;
$i
<
10
;
++
$i
)
{
$group
=
new
CmsGroup
;
$group
->
name
=
'Developers_'
.
$i
;
$user
->
groups
[]
=
$group
;
$group
->
users
[]
=
$user
;
}
$this
->
_em
->
save
(
$user
);
// Saves the user, cause of post-insert ID
$this
->
_em
->
flush
();
// Saves the groups, cause they're attached to a persistent entity ($user)
//$user->groups->clear();
unset
(
$user
->
groups
);
$this
->
_em
->
flush
();
// Check that the links in the association table have been deleted
$count
=
$this
->
_em
->
getConnection
()
->
execute
(
"SELECT COUNT(*) FROM cms_users_groups"
,
array
())
->
fetchColumn
();
$this
->
assertEquals
(
0
,
$count
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment