Author: ts
Date: Fri Jan 11 15:21:55 2008
New Revision: 7127
Log:
- Code cleanups and restructuring.
- Finished task #12287: ezcPersistentSession refactoring.
Modified:
trunk/PersistentObject/src/handlers/delete_handler.php
trunk/PersistentObject/src/handlers/load_handler.php
trunk/PersistentObject/src/handlers/save_handler.php
Modified: trunk/PersistentObject/src/handlers/delete_handler.php
==============================================================================
--- trunk/PersistentObject/src/handlers/delete_handler.php [iso-8859-1]
(original)
+++ trunk/PersistentObject/src/handlers/delete_handler.php [iso-8859-1] Fri Jan
11 15:21:55 2008
@@ -49,24 +49,24 @@
*/
public function delete( $object )
{
- $class = get_class( $object );
- $def = $this->definitionManager->fetchDefinition( $class ); //
propagate exception
- $state = $this->session->getObjectState( $object );
+ $class = get_class( $object );
+ $def = $this->definitionManager->fetchDefinition( $class );
+ $state = $this->session->getObjectState( $object );
$idValue = $state[$def->idProperty->propertyName];
- // check that the object is persistent already
+ // Check that the object is persistent already.
+ // The < 0 check results from the times where only numeric IDs were
allowed.
if ( $idValue == null || $idValue < 0 )
{
- $class = get_class( $object );
throw new ezcPersistentObjectNotPersistentException( $class );
}
- // Transaction savety for exceptions thrown while cascading
+ // Transaction safety for exceptions thrown while cascading.
$this->database->beginTransaction();
try
{
- // check for cascading relations to follow
+ // Check for cascading relations to follow.
foreach ( $def->relations as $relatedClass => $relation )
{
$this->cascadeDelete( $object, $relatedClass, $relation );
@@ -74,20 +74,26 @@
}
catch ( Exception $e )
{
- // Roll back the current transaction on any exception
+ // Roll back the current transaction on any exception.
$this->database->rollback();
throw $e;
}
- // create and execute query
+ // Create and execute query.
$q = $this->database->createDeleteQuery();
- $q->deleteFrom( $this->database->quoteIdentifier( $def->table ) )
- ->where( $q->expr->eq( $this->database->quoteIdentifier(
$def->idProperty->columnName ),
- $q->bindValue( $idValue ) ) );
+ $q->deleteFrom(
+ $this->database->quoteIdentifier( $def->table )
+ )
+ ->where(
+ $q->expr->eq(
+ $this->database->quoteIdentifier( $def->idProperty->columnName
),
+ $q->bindValue( $idValue )
+ )
+ );
try
{
- $this->session->performQuery( $q, true );
+ $this->session->performQuery( $q );
}
catch ( Exception $e )
{
@@ -119,11 +125,12 @@
*/
public function removeRelatedObject( $object, $relatedObject )
{
- $class = get_class( $object );
- $def = $this->definitionManager->fetchDefinition( ( $class =
get_class( $object ) ) );
-
+ $class = get_class( $object );
$relatedClass = get_class( $relatedObject );
-
+ $def = $this->definitionManager->fetchDefinition( $class );
+ $relatedDef = $this->definitionManager->fetchDefinition( get_class(
$relatedObject ) );
+
+ // Sanity checks.
if ( !isset( $def->relations[$relatedClass] ) )
{
throw new ezcPersistentRelationNotFoundException( $class,
$relatedClass );
@@ -138,32 +145,47 @@
);
}
- $objectState = $this->session->getObjectState( $object );
+ $objectState = $this->session->getObjectState( $object );
$relatedObjectState = $this->session->getObjectState( $relatedObject );
- $relatedDef = $this->definitionManager->fetchDefinition( get_class(
$relatedObject ) );
switch ( get_class( ( $relation = $def->relations[get_class(
$relatedObject )] ) ) )
{
case "ezcPersistentOneToManyRelation":
case "ezcPersistentOneToOneRelation":
foreach ( $relation->columnMap as $map )
{
-
$relatedObjectState[$relatedDef->columns[$map->destinationColumn]->propertyName]
= null;
+ $relatedObjectState[
+
$relatedDef->columns[$map->destinationColumn]->propertyName
+ ] = null;
}
break;
case "ezcPersistentManyToManyRelation":
$q = $this->database->createDeleteQuery();
- $q->deleteFrom( $this->database->quoteIdentifier(
$relation->relationTable ) );
+ $q->deleteFrom(
+ $this->database->quoteIdentifier( $relation->relationTable
)
+ );
foreach ( $relation->columnMap as $map )
{
$q->where(
$q->expr->eq(
- $this->database->quoteIdentifier(
$map->relationSourceColumn ),
- $q->bindValue(
$objectState[$def->columns[$map->sourceColumn]->propertyName] )
+ $this->database->quoteIdentifier(
+ $map->relationSourceColumn
+ ),
+ $q->bindValue(
+ $objectState[
+
$def->columns[$map->sourceColumn]->propertyName
+ ]
+ )
),
$q->expr->eq(
- $this->database->quoteIdentifier(
$map->relationDestinationColumn ),
- $q->bindValue(
$relatedObjectState[$relatedDef->columns[$map->destinationColumn]->propertyName]
)
+ $this->database->quoteIdentifier(
+ $map->relationDestinationColumn
+ ),
+ $q->bindValue(
+ $relatedObjectState[
+
$relatedDef->columns[$map->destinationColumn]->propertyName
+ ]
+ )
)
);
}
@@ -218,9 +240,8 @@
*/
public function createDeleteQuery( $class )
{
- $def = $this->definitionManager->fetchDefinition( $class ); //
propagate exception
-
- // init query
+ $def = $this->definitionManager->fetchDefinition( $class );
+
$q = $this->database->createDeleteQuery();
$q->setAliases( $this->session->generateAliasMap( $def, false ) );
$q->deleteFrom( $this->database->quoteIdentifier( $def->table ) );
@@ -248,9 +269,13 @@
// Remove relation records for ManyToMany relations
if ( $relation instanceof ezcPersistentManyToManyRelation )
{
- foreach ( $this->session->loadHandler->getRelatedObjects( $object,
$relatedClass ) as $relatedObject )
+ $relatedObjects = $this->session->loadHandler->getRelatedObjects(
+ $object,
+ $relatedClass
+ );
+ foreach ( $relatedObjects as $relatedObject )
{
- // Need to determine the correct direction for removal
+ // Determine the correct direction for removal.
if ( $relation->reverse === true )
{
$this->removeRelatedObject( $relatedObject, $object );
@@ -261,8 +286,12 @@
}
}
}
+
+ // Actually remove related objects
if ( isset( $relation->cascade ) && $relation->cascade === true )
{
+ // Reverse relations never cascade
+ // @todo: Is this correct? Or do we need to cascade reverse here?
if ( isset( $relation->reverse ) && $relation->reverse === true )
{
throw new ezcPersistentRelationOperationNotSupported(
@@ -272,7 +301,11 @@
"Reverse relations do not support cascading."
);
}
- foreach ( $this->session->loadHandler->getRelatedObjects( $object,
$relatedClass ) as $relatedObject )
+ $relatedObjects = $this->session->loadHandler->getRelatedObjects(
+ $object,
+ $relatedClass
+ );
+ foreach ( $relatedObjects as $relatedObject )
{
$this->delete( $relatedObject );
}
Modified: trunk/PersistentObject/src/handlers/load_handler.php
==============================================================================
--- trunk/PersistentObject/src/handlers/load_handler.php [iso-8859-1] (original)
+++ trunk/PersistentObject/src/handlers/load_handler.php [iso-8859-1] Fri Jan
11 15:21:55 2008
@@ -35,9 +35,11 @@
*/
public function load( $class, $id )
{
- $def = $this->definitionManager->fetchDefinition( $class ); //
propagate exception
+ $def = $this->definitionManager->fetchDefinition( $class );
$object = new $def->class;
+
$this->loadIntoObject( $object, $id );
+
return $object;
}
@@ -61,7 +63,7 @@
}
catch ( Exception $e )
{
- // eat, we return null on error
+ // Eat, we return null on error.
}
return $result;
}
@@ -84,19 +86,32 @@
*/
public function loadIntoObject( $object, $id )
{
- $def = $this->definitionManager->fetchDefinition( get_class( $object )
); // propagate exception
+ $def = $this->definitionManager->fetchDefinition(
+ get_class( $object )
+ );
+
+ // Prepare query.
$q = $this->database->createSelectQuery();
- $q->select( $this->session->getColumnsFromDefinition( $def ) )
- ->from( $this->database->quoteIdentifier( $def->table ) )
- ->where( $q->expr->eq( $this->database->quoteIdentifier(
$def->idProperty->columnName ),
- $q->bindValue( $id ) ) );
-
+ $q->select(
+ $this->session->getColumnsFromDefinition( $def )
+ )->from(
+ $this->database->quoteIdentifier( $def->table )
+ )->where(
+ $q->expr->eq(
+ $this->database->quoteIdentifier( $def->idProperty->columnName
),
+ $q->bindValue( $id )
+ )
+ );
+
+ // Execute and fetch rows.
$stmt = $this->session->performQuery( $q );
$row = $stmt->fetch( PDO::FETCH_ASSOC );
$stmt->closeCursor();
- if ( $row !== false ) // we got a result
- {
- // we could check if there was more than one result here
+
+ // Convert result into object.
+ if ( $row !== false )
+ {
+ // We could check if there was more than one result here
// but we don't because of the overhead and since the Persistent
// Object would be faulty by design in that case and the user
would have
// to execute custom code to get into an invalid state.
@@ -119,7 +134,9 @@
else
{
$class = get_class( $object );
- throw new ezcPersistentQueryException( "No object of class
'$class' with id '$id'." );
+ throw new ezcPersistentQueryException(
+ "No object of class '$class' with id '$id'."
+ );
}
}
@@ -141,16 +158,17 @@
*/
public function refresh( $object )
{
- $def = $this->definitionManager->fetchDefinition( get_class( $object )
); // propagate exception
- $state = $this->session->getObjectState( $object );
+ $class = get_class( $object );
+ $def = $this->definitionManager->fetchDefinition( $class );
+ $state = $this->session->getObjectState( $object );
$idValue = $state[$def->idProperty->propertyName];
+
if ( $idValue !== null )
{
$this->loadIntoObject( $object, $idValue );
}
else
{
- $class = get_class( $object );
throw new ezcPersistentObjectNotPersistentException( $class );
}
}
@@ -194,11 +212,12 @@
*/
public function find( ezcQuerySelect $query, $class )
{
- $def = $this->definitionManager->fetchDefinition( $class ); //
propagate exception
-
- $rows = $this->session->performQuery( $query )->fetchAll(
PDO::FETCH_ASSOC );
-
- // convert all the rows states and then objects
+ $def = $this->definitionManager->fetchDefinition( $class );
+
+ $rows = $this->session->performQuery( $query )
+ ->fetchAll( PDO::FETCH_ASSOC );
+
+ // Convert all the rows to states and then to objects.
$result = array();
foreach ( $rows as $row )
{
@@ -238,7 +257,7 @@
*/
public function findIterator( ezcQuerySelect $query, $class )
{
- $def = $this->definitionManager->fetchDefinition( $class ); //
propagate exception
+ $def = $this->definitionManager->fetchDefinition( $class );
$stmt = $this->session->performQuery( $query );
return new ezcPersistentFindIterator( $stmt, $def );
}
@@ -321,7 +340,10 @@
$resArr = $this->find( $query, $relatedClass );
if ( sizeof( $resArr ) < 1 )
{
- throw new ezcPersistentRelatedObjectNotFoundException( $object,
$relatedClass );
+ throw new ezcPersistentRelatedObjectNotFoundException(
+ $object,
+ $relatedClass
+ );
}
return $resArr[0];
}
@@ -348,13 +370,17 @@
*/
public function createFindQuery( $class )
{
- $def = $this->definitionManager->fetchDefinition( $class ); //
propagate exception
-
- // init query
+ $def = $this->definitionManager->fetchDefinition( $class );
+
+ // Init query
$q = $this->database->createSelectQuery();
$q->setAliases( $this->session->generateAliasMap( $def ) );
- $q->select( $this->session->getColumnsFromDefinition( $def ) )
- ->from( $this->database->quoteIdentifier( $def->table ) );
+
+ $q->select(
+ $this->session->getColumnsFromDefinition( $def )
+ )->from(
+ $this->database->quoteIdentifier( $def->table )
+ );
return $q;
}
@@ -377,15 +403,18 @@
*/
public function createRelationFindQuery( $object, $relatedClass )
{
- $def = $this->definitionManager->fetchDefinition( ( $class =
get_class( $object ) ) );
+ $class = get_class( $object );
+ $def = $this->definitionManager->fetchDefinition( $class );
+
if ( !isset( $def->relations[$relatedClass] ) )
{
- throw new ezcPersistentRelationNotFoundException( $class,
$relatedClass );
- }
- $relation = $def->relations[$relatedClass];
-
- $query = $this->createFindQuery( $relatedClass );
-
+ throw new ezcPersistentRelationNotFoundException(
+ $class,
+ $relatedClass
+ );
+ }
+ $relation = $def->relations[$relatedClass];
+ $query = $this->createFindQuery( $relatedClass );
$objectState = $this->session->getObjectState( $object );
switch ( ( $relationClass = get_class( $relation ) ) )
@@ -393,37 +422,100 @@
case "ezcPersistentOneToManyRelation":
case "ezcPersistentManyToOneRelation":
case "ezcPersistentOneToOneRelation":
- foreach ( $relation->columnMap as $map )
- {
- $query->where(
- $query->expr->eq(
- $this->database->quoteIdentifier(
"{$map->destinationColumn}" ),
- $query->bindValue(
$objectState[$def->columns[$map->sourceColumn]->propertyName] )
- )
- );
- }
+ $this->createSimpleRelationFindQuery( $query, $def, $relation,
$objectState );
break;
case "ezcPersistentManyToManyRelation":
- $query->from( $this->database->quoteIdentifier(
$relation->relationTable ) );
- foreach ( $relation->columnMap as $map )
- {
- $query->where(
- $query->expr->eq(
- $this->database->quoteIdentifier(
$relation->relationTable ) . "." . $this->database->quoteIdentifier(
$map->relationSourceColumn ),
- $query->bindValue(
$objectState[$def->columns[$map->sourceColumn]->propertyName] )
- ),
- $query->expr->eq(
- $this->database->quoteIdentifier(
$relation->relationTable ) . "." . $this->database->quoteIdentifier(
$map->relationDestinationColumn ),
- $this->database->quoteIdentifier(
$relation->destinationTable ) . "." . $this->database->quoteIdentifier(
$map->destinationColumn )
- )
- );
- }
+ $this->createComplexRelationFindQuery( $query, $def,
$relation, $objectState );
break;
default:
throw new ezcPersistentRelationInvalidException(
$relationClass );
}
return $query;
}
+
+ /**
+ * Sets find query value for simple related objects.
+ *
+ * Manipulates the find $query for objects related to the object defined in
+ * $objectState, defined my the relation $relation. This method is
+ * responsile for
+ * <ul>
+ * <li>[EMAIL PROTECTED] ezcPersistentOneToManyRelation}</li>
+ * <li>[EMAIL PROTECTED] ezcPersistentOneToOneRelation}</li>
+ * <li>[EMAIL PROTECTED] ezcPersistentManyToOneRelatio}n</li>
+ * </ul>
+ * for [EMAIL PROTECTED] ezcPersistentManyToManyRelation} see [EMAIL
PROTECTED]
+ * createComplexRelationFindQuery()}.
+ *
+ * @param ezcQuery $query
+ * @param ezcPersistentRelation $relation
+ * @param array $objectState
+ */
+ private function createSimpleRelationFindQuery(
+ ezcQuery $query,
+ ezcPersistentObjectDefinition $def,
+ ezcPersistentRelation $relation,
+ array $objectState
+ )
+ {
+ foreach ( $relation->columnMap as $map )
+ {
+ $query->where(
+ $query->expr->eq(
+ $this->database->quoteIdentifier(
+ $map->destinationColumn
+ ),
+ $query->bindValue(
+
$objectState[$def->columns[$map->sourceColumn]->propertyName]
+ )
+ )
+ );
+ }
+ }
+
+ /**
+ * Sets find query value for many-to-many related objects.
+ *
+ * Manipulates the find $query for objects related to the object defined in
+ * $objectState, defined my the relation $relation.
+ *
+ * @param ezcQuery $query
+ * @param ezcPersistentManyToManyRelation $relation
+ * @param array $objectState
+ */
+ private function createComplexRelationFindQuery(
+ ezcQuery $query,
+ ezcPersistentObjectDefinition $def,
+ ezcPersistentManyToManyRelation $relation,
+ array $objectState
+ )
+ {
+ // Join with relation table.
+ $query->from(
+ $this->database->quoteIdentifier( $relation->relationTable )
+ );
+ foreach ( $relation->columnMap as $map )
+ {
+ $query->where(
+ $query->expr->eq(
+ $this->database->quoteIdentifier( $relation->relationTable
)
+ . "."
+ . $this->database->quoteIdentifier(
$map->relationSourceColumn ),
+ $query->bindValue(
+
$objectState[$def->columns[$map->sourceColumn]->propertyName]
+ )
+ ),
+ $query->expr->eq(
+ $this->database->quoteIdentifier( $relation->relationTable
)
+ . "."
+ . $this->database->quoteIdentifier(
$map->relationDestinationColumn ),
+ $this->database->quoteIdentifier(
$relation->destinationTable )
+ . "."
+ . $this->database->quoteIdentifier(
$map->destinationColumn )
+ )
+ );
+ }
+ }
}
?>
Modified: trunk/PersistentObject/src/handlers/save_handler.php
==============================================================================
--- trunk/PersistentObject/src/handlers/save_handler.php [iso-8859-1] (original)
+++ trunk/PersistentObject/src/handlers/save_handler.php [iso-8859-1] Fri Jan
11 15:21:55 2008
@@ -21,9 +21,10 @@
class ezcPersistentSaveHandler extends ezcPersistentSessionHandler
{
/**
- * Saves the new persistent object $object to the database using an INSERT
INTO query.
- *
- * The correct ID is set to $object.
+ * Saves a new persistent $object to the database using an INSERT query.
+ *
+ * The correct ID is set to $object after it has been saved, as described
+ * in its [EMAIL PROTECTED] ezcPersistentObjectDefinition}.
*
* @throws ezcPersistentObjectException if $object
* is not of a valid persistent object type.
@@ -33,7 +34,7 @@
* if it was not possible to generate a unique identifier for the
* new object.
* @throws ezcPersistentObjectException
- * if the insert query failed.
+ * if the INSERT query failed.
*
* @param object $object
*/
@@ -43,13 +44,19 @@
}
/**
- * Saves the new persistent object $object to the database using an UPDATE
query.
- *
- * @throws ezcPersistentDefinitionNotFoundException if $object is not of a
valid persistent object type.
- * @throws ezcPersistentObjectNotPersistentException if $object is not
stored in the database already.
+ * Saves the persistent $object to the database using an UPDATE query.
+ *
+ * The object needs to have already a valid ID als described in its [EMAIL
PROTECTED]
+ * ezcPersistentObjectDefinition}.
+ *
+ * @throws ezcPersistentDefinitionNotFoundException
+ * if $object is not of a valid persistent object type.
+ * @throws ezcPersistentObjectNotPersistentException
+ * if $object is not stored in the database already.
* @throws ezcPersistentQueryException
+ * if the UPDATE query fails.
+ *
* @param object $object
- * @return void
*/
public function update( $object )
{
@@ -76,18 +83,22 @@
*/
public function saveOrUpdate( $object )
{
- $def = $this->definitionManager->fetchDefinition( get_class( $object )
);// propagate exception
+ $class = get_class( $object );
+ $def = $this->definitionManager->fetchDefinition( $class );
$state = $this->session->getObjectState( $object );
- // fetch the id generator
+ // Fetch the id generator
$idGenerator = null;
+ // @todo: Missing else part! Should throw exception!
if ( ezcBaseFeatures::classExists( $def->idProperty->generator->class
) )
{
$idGenerator = new $def->idProperty->generator->class;
if ( !( $idGenerator instanceof ezcPersistentIdentifierGenerator )
)
{
- throw new ezcPersistentIdentifierGenerationException(
get_class( $object ),
- "Could
not initialize identifier generator: ". "{$def->idProperty->generator->class}
." );
+ throw new ezcPersistentIdentifierGenerationException(
+ $class,
+ "Could not initialize identifier generator:
{$def->idProperty->generator->class}."
+ );
}
}
@@ -122,67 +133,63 @@
*/
public function addRelatedObject( $object, $relatedObject )
{
- $class = get_class( $object );
- $def = $this->definitionManager->fetchDefinition( ( $class =
get_class( $object ) ) );
-
+ $class = get_class( $object );
$relatedClass = get_class( $relatedObject );
-
- $objectState = $this->session->getObjectState( $object );
+ $def = $this->definitionManager->fetchDefinition( $class );
+
+ $objectState = $this->session->getObjectState( $object );
$relatedObjectState = $this->session->getObjectState( $relatedObject );
+ // Sanity checks.
if ( !isset( $def->relations[$relatedClass] ) )
{
- throw new ezcPersistentRelationNotFoundException( $class,
$relatedClass );
- }
- if ( isset( $def->relations[$relatedClass]->reverse ) &&
$def->relations[$relatedClass]->reverse === true )
+ throw new ezcPersistentRelationNotFoundException(
+ $class,
+ $relatedClass
+ );
+ }
+ if (
+ isset( $def->relations[$relatedClass]->reverse )
+ && $def->relations[$relatedClass]->reverse === true
+ )
{
throw new ezcPersistentRelationOperationNotSupportedException(
$class,
$relatedClass,
- "addRelatedObject",
+ __FUNCTION__,
"Relation is a reverse relation."
);
}
- $relatedDef = $this->definitionManager->fetchDefinition( get_class(
$relatedObject ) );
- switch ( get_class( ( $relation = $def->relations[get_class(
$relatedObject )] ) ) )
+ $relatedDef = $this->definitionManager->fetchDefinition( $relatedClass
);
+ $relation = $def->relations[$relatedClass];
+
+ switch ( get_class( $relation ) )
{
case "ezcPersistentOneToManyRelation":
+ // Not needed, already caught by sanity checks:
+ // case "ezcPersistentManyToOneRelation":
case "ezcPersistentOneToOneRelation":
foreach ( $relation->columnMap as $map )
{
-
$relatedObjectState[$relatedDef->columns[$map->destinationColumn]->propertyName]
=
-
$objectState[$def->columns[$map->sourceColumn]->propertyName];
+ $relatedObjectState[
+
$relatedDef->columns[$map->destinationColumn]->propertyName
+ ] = $objectState[
+ $def->columns[$map->sourceColumn]->propertyName
+ ];
}
+ $relatedObject->setState( $relatedObjectState );
break;
case "ezcPersistentManyToManyRelation":
- $q = $this->database->createInsertQuery();
- $q->insertInto( $this->database->quoteIdentifier(
$relation->relationTable ) );
- $insertColumns = array();
- foreach ( $relation->columnMap as $map )
- {
- if ( in_array( $map->relationSourceColumn, $insertColumns
) === false )
- {
- $q->set(
- $this->database->quoteIdentifier(
$map->relationSourceColumn ),
- $q->bindValue(
$objectState[$def->columns[$map->sourceColumn]->propertyName] )
- );
- $insertColumns[] = $map->relationSourceColumn;
- }
- if ( in_array( $map->relationDestinationColumn,
$insertColumns ) === false )
- {
- $q->set(
- $this->database->quoteIdentifier(
$map->relationDestinationColumn ),
- $q->bindValue(
$relatedObjectState[$relatedDef->columns[$map->destinationColumn]->propertyName]
)
- );
- $insertColumns[] = $map->relationDestinationColumn;
- }
- }
- $this->session->performQuery( $q );
+ $this->insertRelationRecord(
+ $relation,
+ $def,
+ $relatedDef,
+ $objectState,
+ $relatedObjectState
+ );
break;
}
-
- $relatedObject->setState( $relatedObjectState );
}
/**
@@ -200,9 +207,8 @@
*/
public function createUpdateQuery( $class )
{
- $def = $this->definitionManager->fetchDefinition( $class ); //
propagate exception
-
- // init query
+ $def = $this->definitionManager->fetchDefinition( $class );
+
$q = $this->database->createUpdateQuery();
$q->setAliases( $this->session->generateAliasMap( $def, false ) );
$q->update( $this->database->quoteIdentifier( $def->table ) );
@@ -246,54 +252,73 @@
* if it was not possible to generate a unique identifier for the
* new object.
* @throws ezcPersistentObjectException
- * if the insert query failed.
+ * if the INSERT query failed.
*
* @param object $object
* @param bool $doPersistenceCheck
* @param ezcPersistentIdentifierGenerator $idGenerator
*/
- private function saveInternal( $object, $doPersistenceCheck = true,
- ezcPersistentIdentifierGenerator
$idGenerator = null )
- {
- $def = $this->definitionManager->fetchDefinition( get_class( $object )
);// propagate exception
- $state = $this->filterAndCastState( $this->session->getObjectState(
$object ), $def );
+ private function saveInternal(
+ $object,
+ $doPersistenceCheck = true,
+ ezcPersistentIdentifierGenerator $idGenerator = null
+ )
+ {
+ $class = get_class( $object );
+ $def = $this->definitionManager->fetchDefinition( $class );
+ $state = $this->filterAndCastState(
+ $this->session->getObjectState( $object ),
+ $def
+ );
$idValue = $state[$def->idProperty->propertyName];
- // fetch the id generator
- if ( $idGenerator == null && ezcBaseFeatures::classExists(
$def->idProperty->generator->class ) )
+ // Fetch the id generator.
+ if ( $idGenerator === null
+ && ezcBaseFeatures::classExists(
$def->idProperty->generator->class )
+ )
+ // @todo: Missing else part, should throw an exception!
{
$idGenerator = new $def->idProperty->generator->class;
if ( !( $idGenerator instanceof ezcPersistentIdentifierGenerator )
)
{
- throw new ezcPersistentIdentifierGenerationException(
get_class( $object ),
- "Could
not initialize identifier generator: ". "{$def->idProperty->generator->class}
." );
- }
- }
-
- if ( $doPersistenceCheck == true && $idGenerator->checkPersistence(
$def, $this->database, $state ) )
- {
- $class = get_class( $object );
+ throw new ezcPersistentIdentifierGenerationException(
+ $class,
+ "Could not initialize identifier generator:
{$def->idProperty->generator->class}."
+ );
+ }
+ }
+
+ if ( $doPersistenceCheck == true
+ && $idGenerator->checkPersistence( $def, $this->database, $state )
+ )
+ {
throw new ezcPersistentObjectAlreadyPersistentException( $class );
}
-
- // set up and execute the query
+ // Set up and execute the query.
$q = $this->database->createInsertQuery();
$q->insertInto( $this->database->quoteIdentifier( $def->table ) );
foreach ( $state as $name => $value )
{
- if ( $name != $def->idProperty->propertyName ) // skip the id field
- {
- // set each of the properties
- $q->set( $this->database->quoteIdentifier(
$def->properties[$name]->columnName ), $q->bindValue( $value ) );
- }
- }
-
+ if ( $name !== $def->idProperty->propertyName )
+ {
+ // Set each of the properties.
+ $q->set(
+ $this->database->quoteIdentifier(
+ $def->properties[$name]->columnName
+ ),
+ $q->bindValue( $value )
+ );
+ }
+ }
+
+ // Atomic operation
$this->database->beginTransaction();
- // let presave id generator do its work
+
+ // Let presave id generator do its work.
$idGenerator->preSave( $def, $this->database, $q );
- // execute the insert query
+ // Execute the insert query
try
{
$this->session->performQuery( $q );
@@ -304,72 +329,94 @@
throw $e;
}
- // fetch the newly created id, and set it to the object
+ // Fetch the newly created ID, and set it to the objects ID property.
$id = $idGenerator->postSave( $def, $this->database );
if ( $id === null )
{
+ // Something must have went wrong, no ID generated.
$this->database->rollback();
- throw new ezcPersistentIdentifierGenerationException( $def->class
);
- }
-
- // everything seems to be fine, lets commit the queries to the database
- // and update the object with its newly created id.
+ throw new ezcPersistentIdentifierGenerationException( $class );
+ }
+
+ // Everything seems to be fine, lets commit the queries to the database
+ // and update the object with its newly created ID.
$this->database->commit();
-
+
$state[$def->idProperty->propertyName] = $id;
$object->setState( $state );
}
/**
- * Saves the new persistent object $object to the database using an UPDATE
query.
- *
- * If $doPersistenceCheck is set this function will check if the object is
persistent before
- * saving. If not, the check is omitted.
- *
- * @throws ezcPersistentDefinitionNotFoundException if $object is not of a
valid persistent object type.
- * @throws ezcPersistentObjectNotPersistentException if $object is not
stored in the database already.
+ * Saves the new persistent $object to the database using an UPDATE query.
+ *
+ * If $doPersistenceCheck is set this function will check if the object is
+ * persistent before saving. If not, the check is omitted.
+ *
+ * @throws ezcPersistentDefinitionNotFoundException
+ * if $object is not of a valid persistent object type.
+ * @throws ezcPersistentObjectNotPersistentException
+ * if $object is not stored in the database already.
* @throws ezcPersistentQueryException
+ * if the UPDATE query failed.
+ *
* @param object $object
* @param bool $doPersistenceCheck
- * @return void
*/
private function updateInternal( $object, $doPersistenceCheck = true )
{
- $def = $this->definitionManager->fetchDefinition( get_class( $object )
); // propagate exception
- $state = $this->filterAndCastState( $this->session->getObjectState(
$object ), $def );
+ $class = get_class( $object );
+ $def = $this->definitionManager->fetchDefinition( $class );
+ $state = $this->filterAndCastState(
+ $this->session->getObjectState( $object ),
+ $def
+ );
$idValue = $state[$def->idProperty->propertyName];
- // fetch the id generator
+ // Fetch the id generator
$idGenerator = null;
if ( ezcBaseFeatures::classExists( $def->idProperty->generator->class
) )
{
$idGenerator = new $def->idProperty->generator->class;
if ( !( $idGenerator instanceof ezcPersistentIdentifierGenerator )
)
{
- throw new ezcPersistentIdentifierGenerationException(
get_class( $object ),
- "Could
not initialize identifier generator: ". "{$def->idProperty->generator->class}
." );
- }
- }
-
- if ( $doPersistenceCheck == true && !$idGenerator->checkPersistence(
$def, $this->database, $state ) )
- {
- $class = get_class( $object );
- throw new ezcPersistentObjectNotPersistentException( get_class(
$object ) );
- }
-
- // set up and execute the query
+ throw new ezcPersistentIdentifierGenerationException(
+ $class,
+ "Could not initialize identifier generator:
{$def->idProperty->generator->class}."
+ );
+ }
+ }
+
+ if ( $doPersistenceCheck == true
+ && !$idGenerator->checkPersistence( $def, $this->database, $state
)
+ )
+ {
+ throw new ezcPersistentObjectNotPersistentException( $class );
+ }
+
+ // Set up and execute the query
$q = $this->database->createUpdateQuery();
$q->update( $this->database->quoteIdentifier( $def->table ) );
foreach ( $state as $name => $value )
{
- if ( $name != $def->idProperty->propertyName ) // skip the id field
- {
- // set each of the properties
- $q->set( $this->database->quoteIdentifier(
$def->properties[$name]->columnName ), $q->bindValue( $value ) );
- }
- }
- $q->where( $q->expr->eq( $this->database->quoteIdentifier(
$def->idProperty->columnName ),
- $q->bindValue( $idValue ) ) );
+ // Skip the id field.
+ if ( $name != $def->idProperty->propertyName )
+ {
+ // Set each of the properties.
+ $q->set(
+ $this->database->quoteIdentifier(
+ $def->properties[$name]->columnName ),
+ $q->bindValue( $value )
+ );
+ }
+ }
+ $q->where(
+ $q->expr->eq(
+ $this->database->quoteIdentifier(
+ $def->idProperty->columnName
+ ),
+ $q->bindValue( $idValue )
+ )
+ );
$this->session->performQuery( $q );
}
@@ -388,15 +435,17 @@
foreach ( $state as $name => $value )
{
$type = null;
- if ( $name == $def->idProperty->propertyName )
+ if ( $name === $def->idProperty->propertyName )
{
$type = $def->idProperty->propertyType;
+ // ID property has no conversion.
$conv = null;
}
else
{
if ( !isset( $def->properties[$name] ) )
{
+ // Unknown property
continue;
}
$type = $def->properties[$name]->propertyType;
@@ -405,10 +454,12 @@
if ( !is_null( $value ) )
{
+ // First convert back from complex type.
if ( !is_null( $conv ) )
{
$value = $conv->toDatabase( $value );
}
+ // Then cast simple type.
switch ( $type )
{
case ezcPersistentObjectProperty::PHP_TYPE_INT:
@@ -427,6 +478,60 @@
}
return $typedState;
}
+
+ /**
+ * Inserts the relation record for a many-to-many relation.
+ *
+ * @param ezcPersistentManyToManyRelation $relation
+ * @param array $objectState
+ * @param array $relatedObjectState
+ */
+ private function insertRelationRecord(
+ ezcPersistentManyToManyRelation $relation,
+ ezcPersistentObjectDefinition $def,
+ ezcPersistentObjectDefinition $relatedDef,
+ array $objectState,
+ array $relatedObjectState
+ )
+ {
+ $q = $this->database->createInsertQuery();
+ $q->insertInto(
+ $this->database->quoteIdentifier( $relation->relationTable )
+ );
+ $insertColumns = array();
+ foreach ( $relation->columnMap as $map )
+ {
+ if ( !in_array( $map->relationSourceColumn, $insertColumns ) )
+ {
+ $q->set(
+ $this->database->quoteIdentifier(
+ $map->relationSourceColumn
+ ),
+ $q->bindValue(
+ $objectState[
+ $def->columns[$map->sourceColumn]->propertyName
+ ]
+ )
+ );
+ $insertColumns[] = $map->relationSourceColumn;
+ }
+ if ( !in_array( $map->relationDestinationColumn, $insertColumns ) )
+ {
+ $q->set(
+ $this->database->quoteIdentifier(
+ $map->relationDestinationColumn
+ ),
+ $q->bindValue(
+ $relatedObjectState[
+
$relatedDef->columns[$map->destinationColumn]->propertyName
+ ]
+ )
+ );
+ $insertColumns[] = $map->relationDestinationColumn;
+ }
+ }
+ $this->session->performQuery( $q );
+ }
}
?>
--
svn-components mailing list
[email protected]
http://lists.ez.no/mailman/listinfo/svn-components