public function setSubselect($subselect) { if ($this->_simpleArithmeticExpression) { throw \Doctrine\Common\DoctrineException::updateMe(); } $this->_subselect = $subselect; }
/** * constructor * * @param Doctrine_Connection $conn Doctrine_Connection object, every connection * statement holds an instance of Doctrine_Connection * @param mixed $stmt */ public function __construct(Connection $conn, $stmt) { $this->_conn = $conn; $this->_stmt = $stmt; if ($stmt === false) { throw \Doctrine\Common\DoctrineException::updateMe('Unknown statement object given.'); } }
/** * {@inheritdoc} */ public function __construct($options) { if (!isset($options['connection']) || !$options['connection'] instanceof Doctrine_DBAL_Connection) { throw \Doctrine\Common\DoctrineException::updateMe('Connection option not set.'); } if (!isset($options['tableName']) || !is_string($options['tableName'])) { throw \Doctrine\Common\DoctrineException::updateMe('Table name option not set.'); } $this->_options = $options; }
/** * Factory method to create type instances. * Type instances are implemented as flyweights. * * @param string $name The name of the type (as returned by getName()). * @return Doctrine\DBAL\Types\Type */ public static function getType($name) { if (!isset(self::$_typeObjects[$name])) { if (!isset(self::$_typesMap[$name])) { throw DoctrineException::updateMe("Unknown type: {$name}"); } self::$_typeObjects[$name] = new self::$_typesMap[$name](); } return self::$_typeObjects[$name]; }
/** * Returns the identifier assigned to the given entity. * * @param object $entity * @return mixed * @override */ public function generate(EntityManager $em, $entity) { $class = $em->getClassMetadata(get_class($entity)); $identifier = null; if ($class->isIdentifierComposite()) { $identifier = array(); $idFields = $class->getIdentifierFieldNames(); foreach ($idFields as $idField) { $identifier[] = $value = $class->getReflectionProperty($idField)->getValue($entity); if (isset($value)) { $identifier[] = $value; } } } else { $value = $class->getReflectionProperty($class->getSingleIdentifierFieldName())->getValue($entity); if (isset($value)) { $identifier = array($value); } } if (!$identifier) { throw DoctrineException::updateMe("Entity of type '" . get_class($entity) . "' is missing an assigned ID."); } return $identifier; }
/** * Looks up the field name for a (lowercased) column name. * * This is mostly used during hydration, because we want to make the * conversion to field names while iterating over the result set for best * performance. By doing this at that point, we can avoid re-iterating over * the data just to convert the column names to field names. * * However, when this is happening, we don't know the real * class name to instantiate yet (the row data may target a sub-type), hence * this method looks up the field name in the subclass mappings if it's not * found on this class mapping. * This lookup on subclasses is costly but happens only *once* for a column * during hydration because the hydrator caches effectively. * * @return string The field name. * @throws DoctrineException If the field name could not be found. */ private function _lookupDeclaringClass($class, $fieldName) { if (isset($class->reflFields[$fieldName])) { return $class; } foreach ($class->subClasses as $subClass) { $subClassMetadata = $this->_em->getClassMetadata($subClass); if ($subClassMetadata->hasField($fieldName)) { return $subClassMetadata; } } throw DoctrineException::updateMe("No owner found for field '{$fieldName}' during hydration."); }
/** * Enter description here... * * @param integer $level */ public function getSetTransactionIsolationSql($level) { throw DoctrineException::updateMe('Set transaction isolation not supported by this platform.'); }
/** * Walks down an PathExpression AST node, thereby generating the appropriate SQL. * * @param mixed * @return string The SQL. */ public function walkPathExpression($pathExpr) { $sql = ''; if ($pathExpr->isSimpleStateFieldPathExpression()) { $parts = $pathExpr->getParts(); $numParts = count($parts); $dqlAlias = $parts[0]; $fieldName = $parts[$numParts - 1]; $qComp = $this->_queryComponents[$dqlAlias]; $class = $qComp['metadata']; if ($numParts > 2) { for ($i = 1; $i < $numParts - 1; ++$i) { //TODO } } if ($this->_useSqlTableAliases) { $sql .= $this->getSqlTableAlias($class->getTableName() . $dqlAlias) . '.'; } if (isset($class->associationMappings[$fieldName])) { //FIXME: Inverse side support //FIXME: Throw exception on composite key $sql .= $class->associationMappings[$fieldName]->joinColumns[0]['name']; } else { $sql .= $class->getColumnName($fieldName); } } else { if ($pathExpr->isSimpleStateFieldAssociationPathExpression()) { throw DoctrineException::updateMe("Not yet implemented."); } else { throw DoctrineException::updateMe("Encountered invalid PathExpression during SQL construction."); } } return $sql; }
/** * Factory method to create EntityManager instances. * * @param mixed $conn An array with the connection parameters or an existing * Connection instance. * @param string $name The name of the EntityManager. * @param Configuration $config The Configuration instance to use. * @param EventManager $eventManager The EventManager instance to use. * @return EntityManager The created EntityManager. */ public static function create($conn, Configuration $config = null, EventManager $eventManager = null) { if (is_array($conn)) { $conn = \Doctrine\DBAL\DriverManager::getConnection($conn, $config, $eventManager); } else { if (!$conn instanceof Connection) { throw DoctrineException::updateMe("Invalid parameter '{$conn}'."); } } if ($config === null) { $config = new Configuration(); } if ($eventManager === null) { $eventManager = new EventManager(); } $em = new EntityManager($conn, $config, $eventManager); return $em; }
/** * {@inheritdoc} */ public function __construct() { if (!extension_loaded('apc')) { \Doctrine\Common\DoctrineException::updateMe('The apc extension must be loaded in order to use the ApcCache.'); } }
public function generate(EntityManager $em, $entity) { throw \Doctrine\Common\DoctrineException::updateMe("Not implemented"); }
/** * alter an existing table * * @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 * of change that is intended to be performed. The types of * changes that are currently supported are defined as follows: * * name * * New name for the table. * * add * * Associative array with the names of fields to be added as * indexes of the array. The value of each entry of the array * should be set to another associative array with the properties * of the fields to be added. The properties of the fields should * be the same as defined by the Metabase parser. * * * remove * * Associative array with the names of fields to be removed as indexes * of the array. Currently the values assigned to each entry are ignored. * An empty array should be used for future compatibility. * * rename * * Associative array with the names of fields to be renamed as indexes * of the array. The value of each entry of the array should be set to * another associative array with the entry named name with the new * field name and the entry named Declaration that is expected to contain * the portion of the field declaration already in DBMS specific SQL code * as it is used in the CREATE TABLE statement. * * change * * Associative array with the names of the fields to be changed as indexes * of the array. Keep in mind that if it is intended to change either the * name of a field and any other properties, the change array entries * should have the new names of the fields as array indexes. * * The value of each entry of the array should be set to another associative * array with the properties of the fields to that are meant to be changed as * array entries. These entries should be assigned to the new values of the * respective properties. The properties of the fields should be the same * as defined by the Metabase parser. * * Example * array( * 'name' => 'userlist', * 'add' => array( * 'quota' => array( * 'type' => 'integer', * 'unsigned' => 1 * ) * ), * 'remove' => array( * 'file_limit' => array(), * 'time_limit' => array() * ), * 'change' => array( * 'name' => array( * 'length' => '20', * 'definition' => array( * 'type' => 'text', * 'length' => 20, * ), * ) * ), * 'rename' => array( * 'sex' => array( * 'name' => 'gender', * 'definition' => array( * 'type' => 'text', * 'length' => 1, * 'default' => 'M', * ), * ) * ) * ) * * @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. * @return void */ public function alterTable($name, array $changes, $check = false) { foreach ($changes as $changeName => $change) { switch ($changeName) { case 'add': break; case 'remove': break; case 'name': case 'rename': case 'change': default: throw \Doctrine\Common\DoctrineException::updateMe('alterTable: change type "' . $changeName . '" not yet supported'); } } $query = ''; if (!empty($changes['add']) && is_array($changes['add'])) { foreach ($changes['add'] as $fieldName => $field) { if ($query) { $query .= ', '; } $query .= 'ADD ' . $this->getDeclaration($fieldName, $field); } } if (!empty($changes['remove']) && is_array($changes['remove'])) { foreach ($changes['remove'] as $fieldName => $field) { if ($query) { $query .= ', '; } $field_name = $this->conn->quoteIdentifier($fieldName, true); $query .= 'DROP COLUMN ' . $fieldName; } } if (!$query) { return false; } $name = $this->conn->quoteIdentifier($name, true); return $this->conn->exec('ALTER TABLE ' . $name . ' ' . $query); }
/** * ArithmeticPrimary ::= StateFieldPathExpression | Literal | "(" SimpleArithmeticExpression ")" | Function | AggregateExpression * @todo Implementation incomplete. */ public function _ArithmeticPrimary() { if ($this->_lexer->lookahead['value'] === '(') { $this->match('('); $expr = $this->_SimpleArithmeticExpression(); $this->match(')'); return $expr; } switch ($this->_lexer->lookahead['type']) { case Lexer::T_IDENTIFIER: $peek = $this->_lexer->glimpse(); if ($peek['value'] == '(') { return $this->_FunctionsReturningNumerics(); } return $this->_StateFieldPathExpression(); case Lexer::T_INPUT_PARAMETER: $this->match($this->_lexer->lookahead['value']); return new AST\InputParameter($this->_lexer->token['value']); case Lexer::T_STRING: case Lexer::T_INTEGER: case Lexer::T_FLOAT: $this->match($this->_lexer->lookahead['value']); return $this->_lexer->token['value']; default: $peek = $this->_lexer->glimpse(); if ($peek['value'] == '(') { if ($this->_isAggregateFunction($this->_lexer->lookahead['type'])) { return $this->_AggregateExpression(); } return $this->_FunctionsReturningStrings(); } else { $this->syntaxError(); } } throw DoctrineException::updateMe("Not yet implemented2."); //TODO... }
public function alterTableSql($name, array $changes, $check = false) { if (!$name) { throw \Doctrine\Common\DoctrineException::updateMe('no valid table name specified'); } foreach ($changes as $changeName => $change) { switch ($changeName) { case 'add': case 'change': case 'rename': case 'name': break; default: throw \Doctrine\Common\DoctrineException::updateMe('change type "' . $changeName . '" not yet supported'); } } if ($check) { return true; } $query = ''; if (!empty($changes['name'])) { $change_name = $this->_conn->quoteIdentifier($changes['name']); $query .= 'RENAME TO ' . $change_name; } if (!empty($changes['add']) && is_array($changes['add'])) { foreach ($changes['add'] as $fieldName => $field) { if ($query) { $query .= ', '; } $query .= 'ADD ' . $this->getDeclaration($fieldName, $field); } } $rename = array(); if (!empty($changes['rename']) && is_array($changes['rename'])) { foreach ($changes['rename'] as $fieldName => $field) { $rename[$field['name']] = $fieldName; } } if (!empty($changes['change']) && is_array($changes['change'])) { foreach ($changes['change'] as $fieldName => $field) { if ($query) { $query .= ', '; } if (isset($rename[$fieldName])) { $oldFieldName = $rename[$fieldName]; unset($rename[$fieldName]); } else { $oldFieldName = $fieldName; } $oldFieldName = $this->_conn->quoteIdentifier($oldFieldName, true); $query .= 'CHANGE ' . $oldFieldName . ' ' . $this->getDeclaration($fieldName, $field['definition']); } } if (!empty($rename) && is_array($rename)) { foreach ($rename as $renameName => $renamedField) { if ($query) { $query .= ', '; } $field = $changes['rename'][$renamedField]; $renamedField = $this->_conn->quoteIdentifier($renamedField, true); $query .= 'CHANGE ' . $renamedField . ' ' . $this->getDeclaration($field['name'], $field['definition']); } } if (!$query) { return false; } $name = $this->_conn->quoteIdentifier($name, true); return 'ALTER TABLE ' . $name . ' ' . $query; }
/** * Loads the metadata for the specified class into the provided container. */ public function loadMetadataForClass($className, ClassMetadata $metadata) { $annotClass = new \Addendum\ReflectionAnnotatedClass($className); // Evaluate DoctrineEntity annotation if (($entityAnnot = $annotClass->getAnnotation('DoctrineEntity')) === false) { throw DoctrineException::updateMe("{$className} is no entity."); } $metadata->setCustomRepositoryClass($entityAnnot->repositoryClass); // Evaluate DoctrineTable annotation if ($tableAnnot = $annotClass->getAnnotation('DoctrineTable')) { $metadata->setPrimaryTable(array('name' => $tableAnnot->name, 'schema' => $tableAnnot->schema, 'catalog' => $tableAnnot->catalog)); } // Evaluate DoctrineInheritanceType annotation if ($inheritanceTypeAnnot = $annotClass->getAnnotation('DoctrineInheritanceType')) { $metadata->setInheritanceType($inheritanceTypeAnnot->value); } // Evaluate DoctrineDiscriminatorColumn annotation if ($discrColumnAnnot = $annotClass->getAnnotation('DoctrineDiscriminatorColumn')) { $metadata->setDiscriminatorColumn(array('name' => $discrColumnAnnot->name, 'type' => $discrColumnAnnot->type, 'length' => $discrColumnAnnot->length)); } // Evaluate DoctrineDiscriminatorMap annotation if ($discrValueAnnot = $annotClass->getAnnotation('DoctrineDiscriminatorValue')) { $metadata->setDiscriminatorValue($discrValueAnnot->value); } // Evaluate DoctrineSubClasses annotation if ($subClassesAnnot = $annotClass->getAnnotation('DoctrineSubClasses')) { $metadata->setSubclasses($subClassesAnnot->value); } // Evaluate DoctrineChangeTrackingPolicy annotation if ($changeTrackingAnnot = $annotClass->getAnnotation('DoctrineChangeTrackingPolicy')) { $metadata->setChangeTrackingPolicy($changeTrackingAnnot->value); } // Evaluate annotations on properties/fields foreach ($annotClass->getProperties() as $property) { if ($metadata->hasField($property->getName())) { continue; } $mapping = array(); $mapping['fieldName'] = $property->getName(); // Check for DoctrineJoinColummn/DoctrineJoinColumns annotations $joinColumns = array(); if ($joinColumnAnnot = $property->getAnnotation('DoctrineJoinColumn')) { $joinColumns[] = array('name' => $joinColumnAnnot->name, 'referencedColumnName' => $joinColumnAnnot->referencedColumnName, 'unique' => $joinColumnAnnot->unique, 'nullable' => $joinColumnAnnot->nullable, 'onDelete' => $joinColumnAnnot->onDelete, 'onUpdate' => $joinColumnAnnot->onUpdate); } else { if ($joinColumnsAnnot = $property->getAnnotation('DoctrineJoinColumns')) { $joinColumns = $joinColumnsAnnot->value; } } // Field can only be annotated with one of: DoctrineColumn, // DoctrineOneToOne, DoctrineOneToMany, DoctrineManyToOne, DoctrineManyToMany if ($columnAnnot = $property->getAnnotation('DoctrineColumn')) { if ($columnAnnot->type == null) { throw DoctrineException::updateMe("Missing type on property " . $property->getName()); } $mapping['type'] = $columnAnnot->type; $mapping['length'] = $columnAnnot->length; $mapping['nullable'] = $columnAnnot->nullable; if ($idAnnot = $property->getAnnotation('DoctrineId')) { $mapping['id'] = true; } if ($generatedValueAnnot = $property->getAnnotation('DoctrineGeneratedValue')) { $metadata->setIdGeneratorType($generatedValueAnnot->strategy); } $metadata->mapField($mapping); // Check for SequenceGenerator/TableGenerator definition if ($seqGeneratorAnnot = $property->getAnnotation('DoctrineSequenceGenerator')) { $metadata->setSequenceGeneratorDefinition(array('sequenceName' => $seqGeneratorAnnot->sequenceName, 'allocationSize' => $seqGeneratorAnnot->allocationSize, 'initialValue' => $seqGeneratorAnnot->initialValue)); } else { if ($tblGeneratorAnnot = $property->getAnnotation('DoctrineTableGenerator')) { throw new DoctrineException("DoctrineTableGenerator not yet implemented."); } } } else { if ($oneToOneAnnot = $property->getAnnotation('DoctrineOneToOne')) { $mapping['targetEntity'] = $oneToOneAnnot->targetEntity; $mapping['joinColumns'] = $joinColumns; $mapping['mappedBy'] = $oneToOneAnnot->mappedBy; $mapping['cascade'] = $oneToOneAnnot->cascade; $metadata->mapOneToOne($mapping); } else { if ($oneToManyAnnot = $property->getAnnotation('DoctrineOneToMany')) { $mapping['mappedBy'] = $oneToManyAnnot->mappedBy; $mapping['targetEntity'] = $oneToManyAnnot->targetEntity; $mapping['cascade'] = $oneToManyAnnot->cascade; $metadata->mapOneToMany($mapping); } else { if ($manyToOneAnnot = $property->getAnnotation('DoctrineManyToOne')) { $mapping['joinColumns'] = $joinColumns; $mapping['cascade'] = $manyToOneAnnot->cascade; $mapping['targetEntity'] = $manyToOneAnnot->targetEntity; $metadata->mapManyToOne($mapping); } else { if ($manyToManyAnnot = $property->getAnnotation('DoctrineManyToMany')) { $joinTable = array(); if ($joinTableAnnot = $property->getAnnotation('DoctrineJoinTable')) { $joinTable = array('name' => $joinTableAnnot->name, 'schema' => $joinTableAnnot->schema, 'catalog' => $joinTableAnnot->catalog, 'joinColumns' => $joinTableAnnot->joinColumns, 'inverseJoinColumns' => $joinTableAnnot->inverseJoinColumns); } $mapping['joinTable'] = $joinTable; $mapping['targetEntity'] = $manyToManyAnnot->targetEntity; $mapping['mappedBy'] = $manyToManyAnnot->mappedBy; $mapping['cascade'] = $manyToManyAnnot->cascade; $metadata->mapManyToMany($mapping); } } } } } } }
/** * getIndexFieldDeclarationList * 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 = $this->quoteIdentifier($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::updateMe('Unknown index sorting option given.'); } } } else { $fieldString = $this->quoteIdentifier($field); } $declFields[] = $fieldString; } return implode(', ', $declFields); }
/** * lists all databases * * @return array */ public function listDatabases() { if (!$this->_conn->getAttribute(Doctrine::ATTR_EMULATE_DATABASE)) { throw \Doctrine\Common\DoctrineException::updateMe('database listing is only supported if the "emulate_database" option is enabled'); } /** if ($this->_conn->options['database_name_prefix']) { $query = 'SELECT SUBSTR(username, '; $query.= (strlen($this->_conn->getAttribute(['database_name_prefix'])+1); $query.= ") FROM sys.dba_users WHERE username LIKE '"; $query.= $this->_conn->options['database_name_prefix']."%'"; } else { */ $query = 'SELECT username FROM sys.dba_users'; $result2 = $this->_conn->standaloneQuery($query); $result = $result2->fetchColumn(); return $result; }
/** * Maps a native array description of a field to a Doctrine datatype and length * * @param array $field native field description * @return array containing the various possible types, length, sign, fixed * @override */ public function getPortableDeclaration($field) { $length = isset($field['length']) && $field['length'] > 0 ? $field['length'] : null; $type = array(); $unsigned = $fixed = null; $dbType = strtolower($field['type']); $field['field_sub_type'] = !empty($field['field_sub_type']) ? strtolower($field['field_sub_type']) : null; if (!isset($field['name'])) { $field['name'] = ''; } switch ($dbType) { case 'smallint': case 'integer': case 'int64': //these may be 'numeric' or 'decimal' if (isset($field['field_sub_type'])) { $field['type'] = $field['field_sub_type']; return $this->getPortableDeclaration($field); } case 'bigint': case 'quad': $type[] = 'integer'; if ($length == '1') { $type[] = 'boolean'; if (preg_match('/^(is|has)/', $field['name'])) { $type = array_reverse($type); } } break; case 'varchar': $fixed = false; case 'char': case 'cstring': $type[] = 'string'; if ($length == '1') { $type[] = 'boolean'; if (preg_match('/^(is|has)/', $field['name'])) { $type = array_reverse($type); } } if ($fixed !== false) { $fixed = true; } break; case 'date': $type[] = 'date'; $length = null; break; case 'timestamp': $type[] = 'timestamp'; $length = null; break; case 'time': $type[] = 'time'; $length = null; break; case 'float': case 'double': case 'double precision': case 'd_float': $type[] = 'float'; break; case 'decimal': case 'numeric': $type[] = 'decimal'; break; case 'blob': $type[] = $field['field_sub_type'] == 'text' ? 'clob' : 'blob'; $length = null; break; default: throw \Doctrine\Common\DoctrineException::updateMe('unknown database attribute type: ' . $dbType); } return array('type' => $type, 'length' => $length, 'unsigned' => $unsigned, 'fixed' => $fixed); }
/** * Deletes an entity as part of the current unit of work. * * This method is internally called during delete() cascades as it tracks * the already visited entities to prevent infinite recursions. * * @param object $entity The entity to delete. * @param array $visited The map of the already visited entities. */ private function _doDelete($entity, array &$visited) { $oid = spl_object_hash($entity); if (isset($visited[$oid])) { return; // Prevent infinite recursion } $visited[$oid] = $entity; // mark visited switch ($this->getEntityState($entity)) { case self::STATE_NEW: case self::STATE_DELETED: // nothing to do break; case self::STATE_MANAGED: $this->registerDeleted($entity); break; case self::STATE_DETACHED: throw DoctrineException::updateMe("A detached entity can't be deleted."); default: throw DoctrineException::updateMe("Encountered invalid entity state."); } $this->_cascadeDelete($entity, $visited); }
/** * Obtain DBMS specific SQL code portion needed to declare an text type * field to be used in statements like CREATE TABLE. * * @param array $field associative array with the name of the properties * of the field being declared as array indexes. Currently, the types * of supported field properties are as follows: * * length * Integer value that determines the maximum length of the text * field. If this argument is missing the field should be * declared to have the longest length allowed by the DBMS. * * default * Text value to be used as default for this field. * * notnull * Boolean flag that indicates whether this field is constrained * to not be set to null. * * @return string DBMS specific SQL code portion that should be used to * declare the specified field. * @override */ public function getNativeDeclaration($field) { if (!isset($field['type'])) { throw \Doctrine\Common\DoctrineException::updateMe('Missing column type.'); } switch ($field['type']) { case 'char': case 'varchar': case 'array': case 'object': case 'string': if (empty($field['length']) && array_key_exists('default', $field)) { $field['length'] = $this->conn->varchar_max_length; } $length = !empty($field['length']) ? $field['length'] : false; $fixed = isset($field['fixed']) && $field['fixed'] || $field['type'] == 'char' ? true : false; return $fixed ? $length ? 'CHAR(' . $length . ')' : 'CHAR(255)' : ($length ? 'VARCHAR(' . $length . ')' : 'NVARCHAR'); case 'clob': return 'TEXT'; case 'blob': return 'BLOB'; case 'integer': if (!empty($field['length'])) { $length = $field['length']; if ($length <= 1) { return 'SMALLINT'; } elseif ($length == 2) { return 'SMALLINT'; } elseif ($length == 3 || $length == 4) { return 'INTEGER'; } elseif ($length > 4) { return 'DECIMAL(20)'; } } return 'INT'; case 'boolean': return 'SMALLINT'; case 'date': return 'DATE'; case 'time': return 'DATETIME YEAR TO SECOND'; case 'timestamp': return 'DATETIME'; case 'float': return 'FLOAT'; case 'decimal': return 'DECIMAL'; } throw \Doctrine\Common\DoctrineException::updateMe('Unknown field type \'' . $field['type'] . '\'.'); }
/** * {@inheritdoc} */ public function __construct() { if (!extension_loaded('memcache')) { throw \Doctrine\Common\DoctrineException::updateMe('In order to use Memcache driver, the memcache extension must be loaded.'); } }
/** * create sequence * * @param string $seqName name of the sequence to be created * @param string $start start value of the sequence; default is 1 * @param array $options An associative array of table options: * array( * 'comment' => 'Foo', * 'charset' => 'utf8', * 'collate' => 'utf8_unicode_ci', * ); * @return boolean */ public function createSequence($seqName, $start = 1, array $options = array()) { $sequenceName = $this->_conn->formatter->getSequenceName($seqName); $this->_conn->exec('CREATE GENERATOR ' . $sequenceName); try { $this->_conn->exec('SET GENERATOR ' . $sequenceName . ' TO ' . ($start - 1)); return true; } catch (Doctrine\DBAL\ConnectionException $e) { try { $this->dropSequence($seqName); } catch (Doctrine\DBAL\ConnectionException $e) { throw \Doctrine\Common\DoctrineException::updateMe('Could not drop inconsistent sequence table'); } } throw \Doctrine\Common\DoctrineException::updateMe('could not create sequence table'); }
/** * create sequence * * @param string $sequenceName name of the sequence to be created * @param string $start start value of the sequence; default is 1 * @param array $options An associative array of table options: * array( * 'comment' => 'Foo', * 'charset' => 'utf8', * 'collate' => 'utf8_unicode_ci', * 'type' => 'innodb', * ); * @return boolean * @override */ public function createSequence($sequenceName, $start = 1, array $options = array()) { $sequenceName = $this->_conn->quoteIdentifier($this->_conn->getSequenceName($sequenceName), true); $seqcolName = $this->_conn->quoteIdentifier($this->_conn->getAttribute(Doctrine::ATTR_SEQCOL_NAME), true); $optionsStrings = array(); if (isset($options['comment']) && !empty($options['comment'])) { $optionsStrings['comment'] = 'COMMENT = ' . $this->_conn->quote($options['comment'], 'string'); } if (isset($options['charset']) && !empty($options['charset'])) { $optionsStrings['charset'] = 'DEFAULT CHARACTER SET ' . $options['charset']; if (isset($options['collate'])) { $optionsStrings['collate'] .= ' COLLATE ' . $options['collate']; } } $type = false; if (isset($options['type'])) { $type = $options['type']; } else { $type = $this->_conn->default_table_type; } if ($type) { $optionsStrings[] = 'ENGINE = ' . $type; } try { $query = 'CREATE TABLE ' . $sequenceName . ' (' . $seqcolName . ' INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (' . $seqcolName . '))'; if (!empty($options_strings)) { $query .= ' ' . implode(' ', $options_strings); } $res = $this->_conn->exec($query); } catch (Doctrine\DBAL\ConnectionException $e) { throw \Doctrine\Common\DoctrineException::updateMe('could not create sequence table'); } if ($start == 1) { return true; } $query = 'INSERT INTO ' . $sequenceName . ' (' . $seqcolName . ') VALUES (' . ($start - 1) . ')'; $res = $this->_conn->exec($query); // Handle error try { $res = $this->_conn->exec('DROP TABLE ' . $sequenceName); } catch (Doctrine\DBAL\ConnectionException $e) { throw \Doctrine\Common\DoctrineException::updateMe('could not drop inconsistent sequence table'); } return $res; }
/** * Gets the name of the single id field. Note that this only works on * entity classes that have a single-field pk. * * @return string */ public function getSingleIdentifierFieldName() { if ($this->isIdentifierComposite) { throw DoctrineException::updateMe("Calling getSingleIdentifierFieldName " . "on a class that uses a composite identifier is not allowed."); } return $this->identifier[0]; }
/** * Obtain DBMS specific SQL code portion needed to declare an text type * field to be used in statements like CREATE TABLE. * * @param array $field associative array with the name of the properties * of the field being declared as array indexes. Currently, the types * of supported field properties are as follows: * * length * Integer value that determines the maximum length of the text * field. If this argument is missing the field should be * declared to have the longest length allowed by the DBMS. * * default * Text value to be used as default for this field. * * notnull * Boolean flag that indicates whether this field is constrained * to not be set to null. * @author Lukas Smith (PEAR MDB2 library) * @return string DBMS specific SQL code portion that should be used to * declare the specified field. * @override */ public function getNativeDeclaration(array $field) { /*if ( ! isset($field['type'])) { throw DoctrineException::updateMe('Missing column type.'); } switch ($field['type']) { case 'text': case 'object': case 'array': case 'string': case 'char': case 'gzip': case 'varchar': $length = (isset($field['length']) && $field['length']) ? $field['length'] : null; $fixed = ((isset($field['fixed']) && $field['fixed']) || $field['type'] == 'char') ? true : false; return $fixed ? ($length ? 'CHAR('.$length.')' : 'CHAR('.$this->conn->getAttribute(Doctrine::ATTR_DEFAULT_TEXTFLD_LENGTH).')') : ($length ? 'VARCHAR('.$length.')' : 'TEXT'); case 'clob': if ( ! empty($field['length'])) { $length = $field['length']; if ($length <= 255) { return 'TINYTEXT'; } elseif ($length <= 65535) { return 'TEXT'; } elseif ($length <= 16777215) { return 'MEDIUMTEXT'; } } return 'LONGTEXT'; case 'blob': if ( ! empty($field['length'])) { $length = $field['length']; if ($length <= 255) { return 'TINYBLOB'; } elseif ($length <= 65535) { return 'BLOB'; } elseif ($length <= 16777215) { return 'MEDIUMBLOB'; } } return 'LONGBLOB'; case 'enum': case 'integer': case 'boolean': case 'int': return 'INTEGER'; case 'date': return 'DATE'; case 'time': return 'TIME'; case 'timestamp': return 'DATETIME'; case 'float': case 'double': return 'DOUBLE';//($this->conn->options['fixed_float'] ? '('. //($this->conn->options['fixed_float']+2).','.$this->conn->options['fixed_float'].')' : ''); case 'decimal': $length = !empty($field['length']) ? $field['length'] : 18; $scale = !empty($field['scale']) ? $field['scale'] : $this->conn->getAttribute(Doctrine::ATTR_DECIMAL_PLACES); return 'DECIMAL('.$length.','.$scale.')'; }*/ throw DoctrineException::updateMe('Unknown field type \'' . $field['type'] . '\'.'); }
/** * Maps a native array description of a field to a MDB2 datatype and length * * @param array $field native field description * @return array containing the various possible types, length, sign, fixed * @override */ public function getPortableDeclaration($field) { $db_type = preg_replace('/[\\d\\(\\)]/', '', strtolower($field['type'])); $length = isset($field['length']) && $field['length'] > 0 ? $field['length'] : null; $type = array(); // todo: unsigned handling seems to be missing $unsigned = $fixed = null; if (!isset($field['name'])) { $field['name'] = ''; } switch ($db_type) { case 'bit': $type[0] = 'boolean'; break; case 'tinyint': case 'smallint': case 'int': $type[0] = 'integer'; if ($length == 1) { $type[] = 'boolean'; } break; case 'datetime': $type[0] = 'timestamp'; break; case 'float': case 'real': case 'numeric': $type[0] = 'float'; break; case 'decimal': case 'money': $type[0] = 'decimal'; break; case 'text': case 'varchar': case 'ntext': case 'nvarchar': $fixed = false; case 'char': case 'nchar': $type[0] = 'string'; if ($length == '1') { $type[] = 'boolean'; if (preg_match('/^[is|has]/', $field['name'])) { $type = array_reverse($type); } } elseif (strstr($db_type, 'text')) { $type[] = 'clob'; } if ($fixed !== false) { $fixed = true; } break; case 'image': case 'varbinary': $type[] = 'blob'; $length = null; break; default: throw \Doctrine\Common\DoctrineException::updateMe('unknown database attribute type: ' . $db_type); } return array('type' => $type, 'length' => $length, 'unsigned' => $unsigned, 'fixed' => $fixed); }