Example #1
0
 private function _gatherRelationsSql($class, array &$sql, array &$columns, array &$constraints)
 {
     foreach ($class->associationMappings as $fieldName => $mapping) {
         if (isset($class->inheritedAssociationFields[$fieldName])) {
             continue;
         }
         $foreignClass = $this->_em->getClassMetadata($mapping->targetEntityName);
         if ($mapping->isOneToOne() && $mapping->isOwningSide) {
             $constraint = array();
             $constraint['tableName'] = $class->getTableName();
             $constraint['foreignTable'] = $foreignClass->getTableName();
             $constraint['local'] = array();
             $constraint['foreign'] = array();
             foreach ($mapping->getJoinColumns() as $joinColumn) {
                 $column = array();
                 $column['name'] = $joinColumn['name'];
                 $column['type'] = Type::getType($foreignClass->getTypeOfColumn($joinColumn['referencedColumnName']));
                 $columns[$joinColumn['name']] = $column;
                 $constraint['local'][] = $joinColumn['name'];
                 $constraint['foreign'][] = $joinColumn['referencedColumnName'];
             }
             $constraints[] = $constraint;
         } else {
             if ($mapping->isOneToMany() && $mapping->isOwningSide) {
                 //... create join table, one-many through join table supported later
                 throw DoctrineException::updateMe("Not yet implemented.");
             } else {
                 if ($mapping->isManyToMany() && $mapping->isOwningSide) {
                     // create join table
                     $joinTableColumns = array();
                     $joinTableOptions = array();
                     $joinTable = $mapping->getJoinTable();
                     $constraint1 = array();
                     $constraint1['tableName'] = $joinTable['name'];
                     $constraint1['foreignTable'] = $class->getTableName();
                     $constraint1['local'] = array();
                     $constraint1['foreign'] = array();
                     foreach ($joinTable['joinColumns'] as $joinColumn) {
                         $column = array();
                         $column['primary'] = true;
                         $joinTableOptions['primary'][] = $joinColumn['name'];
                         $column['name'] = $joinColumn['name'];
                         $column['type'] = Type::getType($class->getTypeOfColumn($joinColumn['referencedColumnName']));
                         $joinTableColumns[$joinColumn['name']] = $column;
                         $constraint1['local'][] = $joinColumn['name'];
                         $constraint1['foreign'][] = $joinColumn['referencedColumnName'];
                     }
                     $constraints[] = $constraint1;
                     $constraint2 = array();
                     $constraint2['tableName'] = $joinTable['name'];
                     $constraint2['foreignTable'] = $foreignClass->getTableName();
                     $constraint2['local'] = array();
                     $constraint2['foreign'] = array();
                     foreach ($joinTable['inverseJoinColumns'] as $inverseJoinColumn) {
                         $column = array();
                         $column['primary'] = true;
                         $joinTableOptions['primary'][] = $inverseJoinColumn['name'];
                         $column['name'] = $inverseJoinColumn['name'];
                         $column['type'] = Type::getType($this->_em->getClassMetadata($mapping->getTargetEntityName())->getTypeOfColumn($inverseJoinColumn['referencedColumnName']));
                         $joinTableColumns[$inverseJoinColumn['name']] = $column;
                         $constraint2['local'][] = $inverseJoinColumn['name'];
                         $constraint2['foreign'][] = $inverseJoinColumn['referencedColumnName'];
                     }
                     $constraints[] = $constraint2;
                     $sql = array_merge($sql, $this->_platform->getCreateTableSql($joinTable['name'], $joinTableColumns, $joinTableOptions));
                 }
             }
         }
     }
 }
Example #2
0
 /**
  * Obtain DBMS specific SQL code portion needed to set an index
  * declaration to be used in statements like CREATE TABLE.
  *
  * @return string
  * @override
  */
 public function getIndexFieldDeclarationListSql(array $fields)
 {
     $declFields = array();
     foreach ($fields as $fieldName => $field) {
         $fieldString = '`' . $fieldName . '`';
         if (is_array($field)) {
             if (isset($field['length'])) {
                 $fieldString .= '(' . $field['length'] . ')';
             }
             if (isset($field['sorting'])) {
                 $sort = strtoupper($field['sorting']);
                 switch ($sort) {
                     case 'ASC':
                     case 'DESC':
                         $fieldString .= ' ' . $sort;
                         break;
                     default:
                         throw DoctrineException::unknownIndexSortingOption($sort);
                 }
             }
         } else {
             $fieldString = '`' . $field . '`';
         }
         $declFields[] = $fieldString;
     }
     return implode(', ', $declFields);
 }
Example #3
0
 /**
  * Overrides an already defined type to use a different implementation.
  *
  * @static
  * @param string $name
  * @param string $className
  * @throws DoctrineException
  */
 public static function overrideType($name, $className)
 {
     if (!isset(self::$_typesMap[$name])) {
         throw DoctrineException::typeNotFound($name);
     }
     self::$_typesMap[$name] = $className;
 }
Example #4
0
 /**
  * Defines a cache driver to be used for caching result sets.
  *
  * @param Doctrine\Common\Cache\Cache $driver Cache driver
  * @return Doctrine\ORM\AbstractQuery
  */
 public function setResultCacheDriver($resultCacheDriver = null)
 {
     if ($resultCacheDriver !== null && !$resultCacheDriver instanceof \Doctrine\Common\Cache\Cache) {
         throw DoctrineException::invalidResultCacheObject($resultCacheDriver);
     }
     $this->_resultCacheDriver = $resultCacheDriver;
     if ($resultCacheDriver) {
         $this->_useResultCache = true;
     }
     return $this;
 }
Example #5
0
 /**
  * Gathers the SQL for properly setting up the relations of the given class.
  * This includes the SQL for foreign key constraints and join tables.
  * 
  * @param ClassMetadata $class
  * @param \Doctrine\DBAL\Schema\Table $table
  * @param \Doctrine\DBAL\Schema\Schema $schema
  * @return void
  */
 private function _gatherRelationsSql($class, $table, $schema)
 {
     foreach ($class->associationMappings as $fieldName => $mapping) {
         if (isset($class->inheritedAssociationFields[$fieldName])) {
             continue;
         }
         $foreignClass = $this->_em->getClassMetadata($mapping->targetEntityName);
         if ($mapping->isOneToOne() && $mapping->isOwningSide) {
             $primaryKeyColumns = $uniqueConstraints = array();
             // unnecessary for this relation-type
             $this->_gatherRelationJoinColumns($mapping->getJoinColumns(), $table, $foreignClass, $mapping, $primaryKeyColumns, $uniqueConstraints);
         } else {
             if ($mapping->isOneToMany() && $mapping->isOwningSide) {
                 //... create join table, one-many through join table supported later
                 throw DoctrineException::notSupported();
             } else {
                 if ($mapping->isManyToMany() && $mapping->isOwningSide) {
                     // create join table
                     $joinTable = $mapping->getJoinTable();
                     $theJoinTable = $schema->createTable($mapping->getQuotedJoinTableName($this->_platform));
                     $primaryKeyColumns = $uniqueConstraints = array();
                     // Build first FK constraint (relation table => source table)
                     $this->_gatherRelationJoinColumns($joinTable['joinColumns'], $theJoinTable, $class, $mapping, $primaryKeyColumns, $uniqueConstraints);
                     // Build second FK constraint (relation table => target table)
                     $this->_gatherRelationJoinColumns($joinTable['inverseJoinColumns'], $theJoinTable, $foreignClass, $mapping, $primaryKeyColumns, $uniqueConstraints);
                     foreach ($uniqueConstraints as $indexName => $unique) {
                         $theJoinTable->addUniqueIndex($unique['columns'], is_numeric($indexName) ? null : $indexName);
                     }
                     $theJoinTable->setPrimaryKey($primaryKeyColumns);
                 }
             }
         }
     }
 }
Example #6
0
 /**
  * Retrieves error string given a message key for lookup
  *
  * @static
  * @param string $messageKey
  * @return string|false Returns the error string if found; FALSE otherwise
  */
 public static function getExceptionMessage($messageKey)
 {
     if (!self::$_messages) {
         // Lazy-init messages
         self::$_messages = array('DoctrineException#partialObjectsAreDangerous' => "Loading partial objects is dangerous. Fetch full objects or consider " . "using a different fetch mode. If you really want partial objects, " . "set the doctrine.forcePartialLoad query hint to TRUE.", 'QueryException#nonUniqueResult' => "The query contains more than one result.");
     }
     if (isset(self::$_messages[$messageKey])) {
         return self::$_messages[$messageKey];
     }
     return false;
 }
Example #7
0
 /**
  * Defines a cache driver to be used for caching result sets.
  *
  * @param Doctrine\ORM\Cache\Cache $driver Cache driver
  * @return Doctrine\ORM\Query
  */
 public function setResultCache($resultCache = null)
 {
     if ($resultCache !== null && !$resultCache instanceof \Doctrine\ORM\Cache\Cache) {
         throw DoctrineException::updateMe('Method setResultCache() accepts only an instance of Doctrine_Cache_Interface or null.');
     }
     $this->_resultCache = $resultCache;
     return $this;
 }
 /**
  * Obtain DBMS specific SQL to be used to create time fields in statements
  * like CREATE TABLE.
  *
  * @param array $fieldDeclaration
  * @return string
  */
 public function getTimeTypeDeclarationSql(array $fieldDeclaration)
 {
     throw DoctrineException::getTimeTypeDeclarationNotSupported($this);
 }
Example #9
0
 /**
  * Add a single task to CLI Namespace.
  * Example of inclusion support to a single task:
  *
  *     [php]
  *     $cliOrmNamespace->addTask('my-custom-task', 'MyProject\Cli\Tasks\MyCustomTask');
  *
  * @param string $name CLI Task name
  * @param string $class CLI Task class (FQCN - Fully Qualified Class Name)
  *
  * @return TaskNamespace This object instance
  */
 public function addTask($name, $class)
 {
     $name = self::formatName($name);
     if ($this->hasTask($name)) {
         throw DoctrineException::cannotOverrideTask($name);
     }
     return $this->overrideTask($name, $class);
 }
Example #10
0
 /**
  * Adds support for magic finders.
  *
  * @return array|object The found entity/entities.
  * @throws BadMethodCallException  If the method called is an invalid find* method
  *                                 or no find* method at all and therefore an invalid
  *                                 method call.
  */
 public function __call($method, $arguments)
 {
     if (substr($method, 0, 6) == 'findBy') {
         $by = substr($method, 6, strlen($method));
         $method = 'findBy';
     } else {
         if (substr($method, 0, 9) == 'findOneBy') {
             $by = substr($method, 9, strlen($method));
             $method = 'findOneBy';
         } else {
             throw new \BadMethodCallException("Undefined method '{$method}'.");
         }
     }
     if (!isset($arguments[0])) {
         throw DoctrineException::findByNameRequired();
     }
     $fieldName = lcfirst(\Doctrine\Common\Util\Inflector::classify($by));
     if ($this->_class->hasField($fieldName)) {
         return $this->{$method}(array($fieldName => $arguments[0]));
     } else {
         throw \Doctrine\Common\DoctrineException::invalidFindBy($by);
     }
 }
Example #11
0
 /**
  * generates the sql for altering an existing table on postgresql
  *
  * @param string $name          name of the table that is intended to be changed.
  * @param array $changes        associative array that contains the details of each type      *
  * @param boolean $check        indicates whether the function should just check if the DBMS driver
  *                              can perform the requested table alterations if the value is true or
  *                              actually perform them otherwise.
  * @see Doctrine_Export::alterTable()
  * @return array
  * @override
  */
 public function getAlterTableSql($name, array $changes, $check = false)
 {
     foreach ($changes as $changeName => $change) {
         switch ($changeName) {
             case 'add':
             case 'remove':
             case 'change':
             case 'name':
             case 'rename':
                 break;
             default:
                 throw DoctrineException::updateMe('change type "' . $changeName . '\\" not yet supported');
         }
     }
     if ($check) {
         return true;
     }
     $sql = array();
     if (isset($changes['add']) && is_array($changes['add'])) {
         foreach ($changes['add'] as $fieldName => $field) {
             $query = 'ADD ' . $this->getColumnDeclarationSql($fieldName, $field);
             $sql[] = 'ALTER TABLE ' . $name . ' ' . $query;
         }
     }
     if (isset($changes['remove']) && is_array($changes['remove'])) {
         foreach ($changes['remove'] as $fieldName => $field) {
             $fieldName = $this->quoteIdentifier($fieldName, true);
             $query = 'DROP ' . $fieldName;
             $sql[] = 'ALTER TABLE ' . $name . ' ' . $query;
         }
     }
     if (isset($changes['change']) && is_array($changes['change'])) {
         foreach ($changes['change'] as $fieldName => $field) {
             $fieldName = $this->quoteIdentifier($fieldName, true);
             if (isset($field['type'])) {
                 $serverInfo = $this->getServerVersion();
                 if (is_array($serverInfo) && $serverInfo['major'] < 8) {
                     throw DoctrineException::updateMe('changing column type for "' . $field['type'] . '\\" requires PostgreSQL 8.0 or above');
                 }
                 $query = 'ALTER ' . $fieldName . ' TYPE ' . $this->getTypeDeclarationSql($field['definition']);
                 $sql[] = 'ALTER TABLE ' . $name . ' ' . $query;
             }
             if (array_key_exists('default', $field)) {
                 $query = 'ALTER ' . $fieldName . ' SET DEFAULT ' . $this->quote($field['definition']['default'], $field['definition']['type']);
                 $sql[] = 'ALTER TABLE ' . $name . ' ' . $query;
             }
             if (!empty($field['notnull'])) {
                 $query = 'ALTER ' . $fieldName . ' ' . ($field['definition']['notnull'] ? 'SET' : 'DROP') . ' NOT NULL';
                 $sql[] = 'ALTER TABLE ' . $name . ' ' . $query;
             }
         }
     }
     if (isset($changes['rename']) && is_array($changes['rename'])) {
         foreach ($changes['rename'] as $fieldName => $field) {
             $fieldName = $this->quoteIdentifier($fieldName, true);
             $sql[] = 'ALTER TABLE ' . $name . ' RENAME COLUMN ' . $fieldName . ' TO ' . $this->quoteIdentifier($field['name'], true);
         }
     }
     $name = $this->quoteIdentifier($name, true);
     if (isset($changes['name'])) {
         $changeName = $this->quoteIdentifier($changes['name'], true);
         $sql[] = 'ALTER TABLE ' . $name . ' RENAME TO ' . $changeName;
     }
     return $sql;
 }
Example #12
0
 /**
  * create a new table
  *
  * @param string $name   Name of the database that should be created
  * @param array $fields  Associative array that contains the definition of each field of the new table
  *                       The indexes of the array entries are the names of the fields of the table an
  *                       the array entry values are associative arrays like those that are meant to be
  *                       passed with the field definitions to get[Type]Declaration() functions.
  *                          array(
  *                              'id' => array(
  *                                  'type' => 'integer',
  *                                  'unsigned' => 1
  *                                  'notnull' => 1
  *                                  'default' => 0
  *                              ),
  *                              'name' => array(
  *                                  'type' => 'text',
  *                                  'length' => 12
  *                              ),
  *                              'password' => array(
  *                                  'type' => 'text',
  *                                  'length' => 12
  *                              )
  *                          );
  * @param array $options  An associative array of table options:
  *
  * @return void
  * @override
  */
 public function getCreateTableSql($name, array $fields, array $options = array())
 {
     if (!$name) {
         throw DoctrineException::invalidTableName($name);
     }
     if (empty($fields)) {
         throw DoctrineException::noFieldsSpecifiedForTable($name);
     }
     $queryFields = $this->getColumnDeclarationListSql($fields);
     $autoinc = false;
     foreach ($fields as $field) {
         if (isset($field['autoincrement']) && $field['autoincrement']) {
             $autoinc = true;
             break;
         }
     }
     if (!$autoinc && isset($options['primary']) && !empty($options['primary'])) {
         $keyColumns = array_unique(array_values($options['primary']));
         $keyColumns = array_map(array($this, 'quoteIdentifier'), $keyColumns);
         $queryFields .= ', PRIMARY KEY(' . implode(', ', $keyColumns) . ')';
     }
     $sql = 'CREATE TABLE ' . $name . ' (' . $queryFields;
     /*if ($check = $this->getCheckDeclarationSql($fields)) {
                 $sql .= ', ' . $check;
             }
     
             if (isset($options['checks']) && $check = $this->getCheckDeclarationSql($options['checks'])) {
                 $sql .= ', ' . $check;
             }*/
     $sql .= ')';
     $query[] = $sql;
     if (isset($options['indexes']) && !empty($options['indexes'])) {
         foreach ($options['indexes'] as $index => $definition) {
             $query[] = $this->getCreateIndexSql($name, $index, $definition);
         }
     }
     return $query;
 }
 /**
  * build a pattern matching string
  *
  * EXPERIMENTAL
  *
  * WARNING: this function is experimental and may change signature at
  * any time until labelled as non-experimental
  *
  * @access public
  *
  * @param array $pattern even keys are strings, odd are patterns (% and _)
  * @param string $operator optional pattern operator (LIKE, ILIKE and maybe others in the future)
  * @param string $field optional field name that is being matched against
  *                  (might be required when emulating ILIKE)
  *
  * @return string SQL pattern
  * @override
  */
 public function getMatchPatternExpression($pattern, $operator = null, $field = null)
 {
     $match = '';
     if (!is_null($operator)) {
         $field = is_null($field) ? '' : $field . ' ';
         $operator = strtoupper($operator);
         switch ($operator) {
             // case insensitive
             case 'ILIKE':
                 $match = $field . 'ILIKE ';
                 break;
                 // case sensitive
             // case sensitive
             case 'LIKE':
                 $match = $field . 'LIKE ';
                 break;
             default:
                 throw DoctrineException::operatorNotSupported($operator);
         }
     }
     $match .= "'";
     foreach ($pattern as $key => $value) {
         if ($key % 2) {
             $match .= $value;
         } else {
             $match .= $this->conn->escapePattern($this->conn->escape($value));
         }
     }
     $match .= "'";
     $match .= $this->patternEscapeString();
     return $match;
 }
Example #14
0
 /**
  * Adds support for magic finders.
  * findByColumnName, findByRelationAlias
  * findById, findByContactId, etc.
  *
  * @return void
  * @throws BadMethodCallException  If the method called is an invalid find* method
  *                                    or no find* method at all and therefore an invalid
  *                                    method call.
  */
 public function __call($method, $arguments)
 {
     if (substr($method, 0, 6) == 'findBy') {
         $by = substr($method, 6, strlen($method));
         $method = 'findBy';
     } else {
         if (substr($method, 0, 9) == 'findOneBy') {
             $by = substr($method, 9, strlen($method));
             $method = 'findOneBy';
         } else {
             throw new BadMethodCallException("Undefined method '{$method}'.");
         }
     }
     if (isset($by)) {
         if (!isset($arguments[0])) {
             throw DoctrineException::updateMe('You must specify the value to findBy.');
         }
         $fieldName = Doctrine::tableize($by);
         $hydrationMode = isset($arguments[1]) ? $arguments[1] : null;
         if ($this->_classMetadata->hasField($fieldName)) {
             return $this->{$method}($fieldName, $arguments[0], $hydrationMode);
         } else {
             if ($this->_classMetadata->hasRelation($by)) {
                 $relation = $this->_classMetadata->getRelation($by);
                 if ($relation['type'] === Doctrine_Relation::MANY) {
                     throw DoctrineException::updateMe('Cannot findBy many relationship.');
                 }
                 return $this->{$method}($relation['local'], $arguments[0], $hydrationMode);
             } else {
                 throw DoctrineException::updateMe('Cannot find by: ' . $by . '. Invalid field or relationship alias.');
             }
         }
     }
 }