From 45ceb8b03b39a46e98afe577068f5e39fdfc924c Mon Sep 17 00:00:00 2001 From: zYne Date: Mon, 18 Jun 2007 19:58:53 +0000 Subject: [PATCH] --- lib/Doctrine/Export.php | 61 ++++++++++++++++++++++--- lib/Doctrine/Export/Oracle.php | 82 +++++++++++++++++++++++++--------- 2 files changed, 115 insertions(+), 28 deletions(-) diff --git a/lib/Doctrine/Export.php b/lib/Doctrine/Export.php index f6c9a6f05..51103c23b 100644 --- a/lib/Doctrine/Export.php +++ b/lib/Doctrine/Export.php @@ -207,7 +207,20 @@ class Doctrine_Export extends Doctrine_Connection_Module $name = $this->conn->quoteIdentifier($name, true); $query = 'CREATE TABLE ' . $name . ' (' . $queryFields . ')'; - return $query; + $sql[] = $query; + + if (isset($options['foreignKeys'])) { + + foreach ((array) $options['foreignKeys'] as $k => $definition) { + if (is_array($definition)) { + if ( ! isset($definition['table'])) { + $definition['table'] = $name; + } + $sql[] = $this->createForeignKeySql($definition['table'], $definition); + } + } + } + return $sql; } /** * create a new table @@ -221,7 +234,11 @@ class Doctrine_Export extends Doctrine_Connection_Module */ public function createTable($name, array $fields, array $options = array()) { - return $this->conn->execute($this->createTableSql($name, $fields, $options)); + $sql = (array) $this->createTableSql($name, $fields, $options); + + foreach ($sql as $query) { + $this->conn->execute($query); + } } /** * create sequence @@ -282,6 +299,31 @@ class Doctrine_Export extends Doctrine_Connection_Module * @return void */ public function createConstraint($table, $name, $definition) + { + return $this->conn->exec($this->createConstraintSql($table, $name, $definition)); + } + /** + * create a constraint on a table + * + * @param string $table name of the table on which the constraint is to be created + * @param string $name name of the constraint to be created + * @param array $definition associative array that defines properties of the constraint to be created. + * Currently, only one property named FIELDS is supported. This property + * is also an associative with the names of the constraint fields as array + * constraints. Each entry of this array is set to another type of associative + * array that specifies properties of the constraint that are specific to + * each field. + * + * Example + * array( + * 'fields' => array( + * 'user_name' => array(), + * 'last_login' => array() + * ) + * ) + * @return void + */ + public function createConstraintSql($table, $name, $definition) { $table = $this->conn->quoteIdentifier($table); $name = $this->conn->quoteIdentifier($this->conn->formatter->getIndexName($name)); @@ -299,7 +341,7 @@ class Doctrine_Export extends Doctrine_Connection_Module } $query .= ' ('. implode(', ', $fields) . ')'; - return $this->conn->exec($query); + return $query; } /** * Get the stucture of a field into an array @@ -877,16 +919,20 @@ class Doctrine_Export extends Doctrine_Connection_Module { $sql = $this->exportSql($directory); + $this->conn->beginTransaction(); + foreach ($sql as $query) { try { $this->conn->exec($query); } catch (Doctrine_Connection_Exception $e) { // we only want to silence table already exists errors if($e->getPortableCode() !== Doctrine::ERR_ALREADY_EXISTS) { + $this->conn->rollback(); throw $e; } } } + $this->conn->commit(); } /** * exportClasses @@ -901,17 +947,20 @@ class Doctrine_Export extends Doctrine_Connection_Module { $sql = $this->exportClassesSql($classes); + $this->conn->beginTransaction(); + foreach ($sql as $query) { - try { + try { $this->conn->exec($query); } catch (Doctrine_Connection_Exception $e) { // we only want to silence table already exists errors if($e->getPortableCode() !== Doctrine::ERR_ALREADY_EXISTS) { - print $query."
"; + $this->conn->rollback(); throw $e; - } + } } } + $this->conn->commit(); } /** * exportClassesSql diff --git a/lib/Doctrine/Export/Oracle.php b/lib/Doctrine/Export/Oracle.php index 867d869a5..8b596484c 100644 --- a/lib/Doctrine/Export/Oracle.php +++ b/lib/Doctrine/Export/Oracle.php @@ -93,31 +93,30 @@ class Doctrine_Export_Oracle extends Doctrine_Export */ public function _makeAutoincrement($name, $table, $start = 1) { + $sql = array(); $table = strtoupper($table); - $index_name = $table . '_AI_PK'; + $indexName = $table . '_AI_PK'; $definition = array( 'primary' => true, 'fields' => array($name => true), ); - $result = $this->createConstraint($table, $index_name, $definition); + + $sql[] = $this->createConstraintSql($table, $indexName, $definition); if (is_null($start)) { - $this->conn->beginTransaction(); $query = 'SELECT MAX(' . $this->conn->quoteIdentifier($name, true) . ') FROM ' . $this->conn->quoteIdentifier($table, true); $start = $this->conn->fetchOne($query); ++$start; - $result = $this->createSequence($table, $start); - $this->conn->commit(); - } else { - $result = $this->createSequence($table, $start); } - $sequence_name = $this->conn->formatter->getSequenceName($table); - $trigger_name = $this->conn->quoteIdentifier($table . '_AI_PK', true); + $sql[] = $this->createSequenceSql($table, $start); + + $sequenceName = $this->conn->formatter->getSequenceName($table); + $triggerName = $this->conn->quoteIdentifier($table . '_AI_PK', true); $table = $this->conn->quoteIdentifier($table, true); $name = $this->conn->quoteIdentifier($name, true); - $trigger_sql = 'CREATE TRIGGER '.$trigger_name.' + $sql[] = 'CREATE TRIGGER ' . $triggerName . ' BEFORE INSERT ON '.$table.' FOR EACH ROW @@ -125,21 +124,21 @@ DECLARE last_Sequence NUMBER; last_InsertID NUMBER; BEGIN - SELECT '.$sequence_name.'.NEXTVAL INTO :NEW.'.$name.' FROM DUAL; + SELECT '.$sequenceName.'.NEXTVAL INTO :NEW.'.$name.' FROM DUAL; IF (:NEW.'.$name.' IS NULL OR :NEW.'.$name.' = 0) THEN - SELECT '.$sequence_name.'.NEXTVAL INTO :NEW.'.$name.' FROM DUAL; + SELECT '.$sequenceName.'.NEXTVAL INTO :NEW.'.$name.' FROM DUAL; ELSE SELECT NVL(Last_Number, 0) INTO last_Sequence FROM User_Sequences - WHERE UPPER(Sequence_Name) = UPPER(\''.$sequence_name.'\'); + WHERE UPPER(Sequence_Name) = UPPER(\''.$sequenceName.'\'); SELECT :NEW.id INTO last_InsertID FROM DUAL; WHILE (last_InsertID > last_Sequence) LOOP - SELECT '.$sequence_name.'.NEXTVAL INTO last_Sequence FROM DUAL; + SELECT ' . $sequenceName . '.NEXTVAL INTO last_Sequence FROM DUAL; END LOOP; END IF; END; '; - return $this->conn->exec($trigger_sql); + return $sql; } /** * drop an existing autoincrement sequence + trigger @@ -246,17 +245,56 @@ END; { $this->conn->beginTransaction(); - $result = parent::createTable($name, $fields, $options); - - foreach ($fields as $field_name => $field) { - if (isset($field['autoincrement']) && $field['autoincrement']) { - $result = $this->_makeAutoincrement($field_name, $name); - } + foreach ($this->createTableSql($name, $fields, $options) as $sql) { + $this->conn->exec($sql); } $this->conn->commit(); + } - return $result; + /** + * 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. + * + * Example + * 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 + */ + public function createTableSql($name, array $fields, array $options = array()) + { + $sql = parent::createTableSql($name, $fields, $options); + + foreach ($fields as $fieldName => $field) { + if (isset($field['autoincrement']) && $field['autoincrement'] || + (isset($field['autoinc']) && $fields['autoinc'])) { + $sql = array_merge($sql, $this->_makeAutoincrement($fieldName, $name)); + } + } + + return $sql; } /** * drop an existing table