/** * @internal * * @return void */ protected function saveManagedObject(MManagedObject $object) { if ($object->hasChanges()) { // Inform the object that it is about to be saved $object->_willStartSaving(); // Save object's updated data if ($object->_hasUpdatedData()) { $data = $this->unpackData($object->_updatedData(), $object->entity()); if ($object->objectID() == MManagedObject::UNKNOWN_ID) { $statements = A(array_fill(0, $data->count(), S("?"))); $query = Sf("INSERT INTO `%s` (`%s`) VALUES (%s);", $object->entity()->plural(), $data->allKeys()->componentsJoinedByString(S("`, `")), $statements->componentsJoinedByString(S(", "))); $statement = $this->connection()->prepare($query->stringValue()); if (!$statement->execute($data->allObjects()->toArray())) { throw new MPersistentStoreException(Sf("Could not save entity [%s]", $object->entity()->name())); } $object->_setObjectID((int) $this->connection()->lastInsertId()); } else { $statements = new MMutableArray(); foreach ($data->allKeys()->toArray() as $field) { $statements->addObject(Sf("`%s` = ?", $field)); } $query = Sf("UPDATE `%s` SET %s WHERE `objectID` = %s;", $object->entity()->plural(), $statements->componentsJoinedByString(S(", ")), $object->objectID()); $statement = $this->connection()->prepare($query->stringValue()); if (!$statement->execute($data->allObjects()->toArray())) { throw new MPersistentStoreException(Sf("Could not save entity [%s]", $object->entity()->name())); } } } // Save object's inserted relationships if ($object->_hasInsertedRelationships()) { foreach ($object->_insertedRelationships()->allKeys()->toArray() as $relationshipName) { if (!$object->_isSavingInsertedObjectsForRelationshipName($relationshipName)) { $relationshipObjects = $object->_insertedRelationships()->objectForKey($relationshipName); $relationship = $object->entity()->attributeWithName($relationshipName); foreach ($relationshipObjects->toArray() as $relationshipObject) { $relationshipObject->_willSaveInsertedObjectsForRelationshipName($relationship->inverseRelationship()->name()); $this->saveManagedObject($relationshipObject); $query = Sf("INSERT INTO `%s` (`%s`, `%s`) VALUES (%s);", $relationship->tableName(), $relationship->columnName(), $relationship->inverseColumnName(), S("?, ?")); $statement = $this->connection()->prepare($query->stringValue()); if (!$statement->execute(array($object->objectID(), $relationshipObject->objectID()))) { throw new MPersistentStoreException(Sf("Could not save relationship [%s] on entity [%s]", $relationshipName, $object->entity()->name())); } $relationshipObject->_didSaveInsertedObjectsForRelationshipName($relationship->inverseRelationship()->name()); } } } } // Delete object's removed relationships if ($object->_hasRemovedRelationships()) { foreach ($object->_removedRelationships()->allKeys()->toArray() as $relationshipName) { if (!$object->_isSavingRemovedObjectsForRelationshipName($relationshipName)) { $relationshipObjects = $object->_removedRelationships()->objectForKey($relationshipName); $relationship = $object->entity()->attributeWithName($relationshipName); foreach ($relationshipObjects->toArray() as $relationshipObject) { $relationshipObject->_willSaveRemovedObjectsForRelationshipName($relationship->inverseRelationship()->name()); $this->saveManagedObject($relationshipObject); $query = Sf("DELETE FROM `%s` WHERE `%s` = ?;", $relationship->tableName(), $relationship->inverseColumnName()); $statement = $this->connection()->prepare($query->stringValue()); if (!$statement->execute(array($relationshipObject->objectID()))) { throw new MPersistentStoreException(Sf("Could not remove relationship [%s] on entity [%s]", $relationshipName, $object->entity()->name())); } $relationshipObject->_didSaveRemovedObjectsForRelationshipName($relationship->inverseRelationship()->name()); } } } } // Tell the object to persit it's changes $object->persistChanges(); // Inform the object that it has finished being saved $object->_didFinishSaving(); } }