/**
  * Prepares the data changeset of an entity for database insertion.
  *
  * @param object $entity
  * @param boolean $isInsert Whether the preparation is for an INSERT (or UPDATE, if FALSE).
  * 
  * return The reference to the data array.
  * @access private
  *
  * @author Etienne de Longeaux <*****@*****.**>
  */
 private function _prepareData($entity, $isInsert = false)
 {
     $result = array();
     $platform = $this->_conn->getDatabasePlatform();
     $uow = $this->_em->getUnitOfWork();
     foreach ($this->_reflFields as $field => $ReflectionProperty) {
         $newVal = $this->_class->getFieldValue($entity, $field);
         $columnName = $this->_class->getColumnName($field);
         if (isset($this->_class->associationMappings[$field])) {
             $assocMapping = $this->_class->associationMappings[$field];
             // Only owning side of x-1 associations can have a FK column.
             if (!$assocMapping['isOwningSide']) {
                 continue;
             }
             // Special case: One-one self-referencing of the same class with IDENTITY type key generation.
             if ($this->_class->isIdGeneratorIdentity() && $newVal !== null && $assocMapping['sourceEntity'] == $assocMapping['targetEntity']) {
                 $oid = spl_object_hash($newVal);
                 $isScheduledForInsert = $uow->isScheduledForInsert($newVal);
                 if (isset($this->_queuedInserts[$oid]) || $isScheduledForInsert) {
                     // The associated entity $newVal is not yet persisted, so we must
                     // set $newVal = null, in order to insert a null value and schedule an
                     // extra update on the UnitOfWork.
                     $uow->scheduleExtraUpdate($entity, array($field => array(null, $newVal)));
                     $newVal = null;
                 } else {
                     if ($isInsert && !$isScheduledForInsert && $uow->getEntityState($newVal) == UnitOfWork::STATE_MANAGED) {
                         // $newVal is already fully persisted.
                         // Schedule an extra update for it, so that the foreign key(s) are properly set.
                         $uow->scheduleExtraUpdate($newVal, array($field => array(null, $entity)));
                     }
                 }
             }
             foreach ($assocMapping['sourceToTargetKeyColumns'] as $sourceColumn => $targetColumn) {
                 if ($newVal === null) {
                     $result[$sourceColumn] = null;
                 } else {
                     $otherClass = $this->_em->getClassMetadata($assocMapping['targetEntity']);
                     $result[$sourceColumn] = $otherClass->reflFields[$otherClass->fieldNames[$targetColumn]]->getValue($newVal);
                 }
             }
         } else {
             if ($newVal === null) {
                 $result[$columnName] = null;
             } else {
                 $result[$columnName] = Type::getType($this->_class->fieldMappings[$field]['type'])->convertToDatabaseValue($newVal, $platform);
             }
         }
     }
     return $result;
 }
 /**
  * Creates a column definition as required by the DBAL from an ORM field mapping definition.
  *
  * @param ClassMetadata $class The class that owns the field mapping.
  * @param array $mapping The field mapping.
  * @param Table $table
  * @return array The portable column definition as required by the DBAL.
  */
 private function _gatherColumn($class, array $mapping, $table)
 {
     $columnName = $class->getQuotedColumnName($mapping['fieldName'], $this->_platform);
     $columnType = $mapping['type'];
     $options = array();
     $options['length'] = isset($mapping['length']) ? $mapping['length'] : null;
     $options['notnull'] = isset($mapping['nullable']) ? !$mapping['nullable'] : true;
     if ($class->isInheritanceTypeSingleTable() && count($class->parentClasses) > 0) {
         $options['notnull'] = false;
     }
     $options['platformOptions'] = array();
     $options['platformOptions']['version'] = $class->isVersioned && $class->versionField == $mapping['fieldName'] ? true : false;
     if (strtolower($columnType) == 'string' && $options['length'] === null) {
         $options['length'] = 255;
     }
     if (isset($mapping['precision'])) {
         $options['precision'] = $mapping['precision'];
     }
     if (isset($mapping['scale'])) {
         $options['scale'] = $mapping['scale'];
     }
     if (isset($mapping['default'])) {
         $options['default'] = $mapping['default'];
     }
     if (isset($mapping['columnDefinition'])) {
         $options['columnDefinition'] = $mapping['columnDefinition'];
     }
     if ($class->isIdGeneratorIdentity() && $class->getIdentifierFieldNames() == array($mapping['fieldName'])) {
         $options['autoincrement'] = true;
     }
     if ($class->isInheritanceTypeJoined() && $class->name != $class->rootEntityName) {
         $options['autoincrement'] = false;
     }
     if ($table->hasColumn($columnName)) {
         // required in some inheritance scenarios
         $table->changeColumn($columnName, $options);
     } else {
         $table->addColumn($columnName, $columnType, $options);
     }
     $isUnique = isset($mapping['unique']) ? $mapping['unique'] : false;
     if ($isUnique) {
         $table->addUniqueIndex(array($columnName));
     }
 }
 /**
  * Gets the list of columns to put in the INSERT SQL statement.
  *
  * Subclasses should override this method to alter or change the list of
  * columns placed in the INSERT statements used by the persister.
  *
  * @return array The list of columns.
  */
 protected function getInsertColumnList()
 {
     $columns = [];
     foreach ($this->class->reflFields as $name => $field) {
         if ($this->class->isVersioned && $this->class->versionField == $name) {
             continue;
         }
         if (isset($this->class->embeddedClasses[$name])) {
             continue;
         }
         if (isset($this->class->associationMappings[$name])) {
             $assoc = $this->class->associationMappings[$name];
             if ($assoc['isOwningSide'] && $assoc['type'] & ClassMetadata::TO_ONE) {
                 foreach ($assoc['joinColumns'] as $joinColumn) {
                     $columns[] = $this->quoteStrategy->getJoinColumnName($joinColumn, $this->class, $this->platform);
                 }
             }
             continue;
         }
         if (!$this->class->isIdGeneratorIdentity() || $this->class->identifier[0] != $name) {
             $columns[] = $this->quoteStrategy->getColumnName($name, $this->class, $this->platform);
             $this->columnTypes[$name] = $this->class->fieldMappings[$name]['type'];
         }
     }
     return $columns;
 }
 /**
  * Generates any static SQL strings for a class and stores them in the descriptor.
  *
  * @param ClassMetadata $class
  */
 private function _generateStaticSql($class)
 {
     // Generate INSERT SQL
     $columns = $values = array();
     if ($class->inheritanceType == ClassMetadata::INHERITANCE_TYPE_JOINED) {
         foreach ($class->reflFields as $name => $field) {
             if (isset($class->fieldMappings[$name]['inherited']) && !isset($class->fieldMappings[$name]['id']) || isset($class->inheritedAssociationFields[$name])) {
                 continue;
             }
             if (isset($class->associationMappings[$name])) {
                 $assoc = $class->associationMappings[$name];
                 if ($assoc->isOneToOne() && $assoc->isOwningSide) {
                     foreach ($assoc->targetToSourceKeyColumns as $sourceCol) {
                         $columns[] = $this->_targetPlatform->quoteIdentifier($sourceCol);
                         $values[] = '?';
                     }
                 }
             } else {
                 if ($class->name != $class->rootEntityName || !$class->isIdGeneratorIdentity() || $class->identifier[0] != $name) {
                     $columns[] = $this->_targetPlatform->quoteIdentifier($class->columnNames[$name]);
                     $values[] = '?';
                 }
             }
         }
     } else {
         foreach ($class->reflFields as $name => $field) {
             if (isset($class->associationMappings[$name])) {
                 $assoc = $class->associationMappings[$name];
                 if ($assoc->isOwningSide && $assoc->isOneToOne()) {
                     foreach ($assoc->targetToSourceKeyColumns as $sourceCol) {
                         $columns[] = $this->_targetPlatform->quoteIdentifier($sourceCol);
                         $values[] = '?';
                     }
                 }
             } else {
                 if ($class->generatorType != ClassMetadata::GENERATOR_TYPE_IDENTITY || $class->identifier[0] != $name) {
                     $columns[] = $this->_targetPlatform->quoteIdentifier($class->columnNames[$name]);
                     $values[] = '?';
                 }
             }
         }
     }
     if ($class->isInheritanceTypeSingleTable() || $class->isInheritanceTypeJoined() && $class->name == $class->rootEntityName) {
         $columns[] = $class->discriminatorColumn['name'];
         $values[] = '?';
     }
     $class->insertSql = 'INSERT INTO ' . $this->_targetPlatform->quoteIdentifier($class->primaryTable['name']) . ' (' . implode(', ', $columns) . ') ' . 'VALUES (' . implode(', ', $values) . ')';
 }