From 7426baf53e042675a84ef25c8ed9376a6f35e972 Mon Sep 17 00:00:00 2001 From: jwage Date: Wed, 27 May 2009 18:54:40 +0000 Subject: [PATCH] [2.0] General work on Platform and SchemaManager classes --- lib/Doctrine/DBAL/Connection.php | 10 +- lib/Doctrine/DBAL/Driver.php | 7 + lib/Doctrine/DBAL/Driver/PDOMsSql/Driver.php | 5 + lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php | 5 + lib/Doctrine/DBAL/Driver/PDOOracle/Driver.php | 5 + lib/Doctrine/DBAL/Driver/PDOPgSql/Driver.php | 5 + lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php | 5 + .../DBAL/Platforms/AbstractPlatform.php | 614 ++++-------------- lib/Doctrine/DBAL/Platforms/Db2Platform.php | 13 +- .../DBAL/Platforms/FirebirdPlatform.php | 165 +---- .../DBAL/Platforms/InformixPlatform.php | 78 +-- lib/Doctrine/DBAL/Platforms/MockPlatform.php | 10 + lib/Doctrine/DBAL/Platforms/MsSqlPlatform.php | 171 +---- lib/Doctrine/DBAL/Platforms/MySqlPlatform.php | 272 +------- .../DBAL/Platforms/OraclePlatform.php | 213 +----- .../DBAL/Platforms/PostgreSqlPlatform.php | 26 +- .../DBAL/Platforms/SqlitePlatform.php | 263 ++------ .../DBAL/Schema/AbstractSchemaManager.php | 356 ++++++---- .../DBAL/Schema/PostgreSqlSchemaManager.php | 123 ---- .../DBAL/Schema/SqliteSchemaManager.php | 560 +--------------- tests/Doctrine/Tests/DBAL/AllTests.php | 3 + .../Tests/DBAL/Functional/AllTests.php | 32 + .../Functional/Schemas/SqliteSchemaTest.php | 47 ++ .../Tests/DbalFunctionalTestSuite.php | 7 + .../Tests/Mocks/DatabasePlatformMock.php | 15 +- tests/Doctrine/Tests/Mocks/DriverMock.php | 5 + 26 files changed, 637 insertions(+), 2378 deletions(-) create mode 100644 tests/Doctrine/Tests/DBAL/Functional/AllTests.php create mode 100644 tests/Doctrine/Tests/DBAL/Functional/Schemas/SqliteSchemaTest.php create mode 100644 tests/Doctrine/Tests/DbalFunctionalTestSuite.php diff --git a/lib/Doctrine/DBAL/Connection.php b/lib/Doctrine/DBAL/Connection.php index b6576c5bc..9edb3edb7 100644 --- a/lib/Doctrine/DBAL/Connection.php +++ b/lib/Doctrine/DBAL/Connection.php @@ -434,7 +434,7 @@ class Connection */ public function fetchRow($statement, array $params = array()) { - return $this->execute($statement, $params)->fetch(PDO::FETCH_ASSOC); + return $this->execute($statement, $params)->fetch(\PDO::FETCH_ASSOC); } /** @@ -446,7 +446,7 @@ class Connection */ public function fetchArray($statement, array $params = array()) { - return $this->execute($statement, $params)->fetch(PDO::FETCH_NUM); + return $this->execute($statement, $params)->fetch(\PDO::FETCH_NUM); } /** @@ -459,7 +459,7 @@ class Connection */ public function fetchColumn($statement, array $params = array(), $colnum = 0) { - return $this->execute($statement, $params)->fetchAll(PDO::FETCH_COLUMN, $colnum); + return $this->execute($statement, $params)->fetchAll(\PDO::FETCH_COLUMN, $colnum); } /** @@ -471,7 +471,7 @@ class Connection */ public function fetchBoth($statement, array $params = array()) { - return $this->execute($statement, $params)->fetchAll(PDO::FETCH_BOTH); + return $this->execute($statement, $params)->fetchAll(\PDO::FETCH_BOTH); } /** @@ -515,7 +515,6 @@ class Connection { $this->connect(); try { - echo "DBAL:" . $query . PHP_EOL; if ( ! empty($params)) { $stmt = $this->prepare($query); $stmt->execute($params); @@ -542,7 +541,6 @@ class Connection public function exec($query, array $params = array()) { $this->connect(); try { - echo "DBAL:" . $query . PHP_EOL; if ( ! empty($params)) { var_dump($params); $stmt = $this->prepare($query); diff --git a/lib/Doctrine/DBAL/Driver.php b/lib/Doctrine/DBAL/Driver.php index 9ba474182..8fa2feb32 100644 --- a/lib/Doctrine/DBAL/Driver.php +++ b/lib/Doctrine/DBAL/Driver.php @@ -36,4 +36,11 @@ interface Driver * @return Doctrine\DBAL\SchemaManager */ public function getSchemaManager(Connection $conn); + + /** + * Get the name of the driver + * + * @return string The name of the driver + */ + public function getName(); } \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Driver/PDOMsSql/Driver.php b/lib/Doctrine/DBAL/Driver/PDOMsSql/Driver.php index 09c43f128..c6edaa06c 100644 --- a/lib/Doctrine/DBAL/Driver/PDOMsSql/Driver.php +++ b/lib/Doctrine/DBAL/Driver/PDOMsSql/Driver.php @@ -57,4 +57,9 @@ class Driver implements \Doctrine\DBAL\Driver { return new \Doctrine\DBAL\Schema\MsSqlSchemaManager($conn); } + + public function getName() + { + return 'pdo_mssql'; + } } \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php b/lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php index 25c4aaaa0..888628387 100644 --- a/lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php +++ b/lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php @@ -82,4 +82,9 @@ class Driver implements \Doctrine\DBAL\Driver { return new \Doctrine\DBAL\Schema\MySqlSchemaManager($conn); } + + public function getName() + { + return 'pdo_mysql'; + } } \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Driver/PDOOracle/Driver.php b/lib/Doctrine/DBAL/Driver/PDOOracle/Driver.php index f07407cdd..0db71e4c9 100644 --- a/lib/Doctrine/DBAL/Driver/PDOOracle/Driver.php +++ b/lib/Doctrine/DBAL/Driver/PDOOracle/Driver.php @@ -74,4 +74,9 @@ class Driver implements \Doctrine\DBAL\Driver { return new \Doctrine\DBAL\Schema\OracleSchemaManager($conn); } + + public function getName() + { + return 'pdo_oracle'; + } } \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Driver/PDOPgSql/Driver.php b/lib/Doctrine/DBAL/Driver/PDOPgSql/Driver.php index 2435bd077..b3f7c44ea 100644 --- a/lib/Doctrine/DBAL/Driver/PDOPgSql/Driver.php +++ b/lib/Doctrine/DBAL/Driver/PDOPgSql/Driver.php @@ -51,4 +51,9 @@ class Driver implements \Doctrine\DBAL\Driver { return new \Doctrine\DBAL\Schema\PostgreSqlSchemaManager($conn); } + + public function getName() + { + return 'pdo_pgsql'; + } } \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php b/lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php index ca897ce8d..f9805dfc9 100644 --- a/lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php +++ b/lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php @@ -83,4 +83,9 @@ class Driver implements \Doctrine\DBAL\Driver { return new \Doctrine\DBAL\Schema\SqliteSchemaManager($conn); } + + public function getName() + { + return 'pdo_sqlite'; + } } \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php b/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php index aba7af53f..eb0a35cc0 100644 --- a/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php @@ -23,6 +23,7 @@ namespace Doctrine\DBAL\Platforms; use Doctrine\Common\DoctrineException; use Doctrine\DBAL\Connection; +use Doctrine\DBAL\Types; /** * Base class for all DatabasePlatforms. The DatabasePlatforms are the central @@ -36,7 +37,7 @@ use Doctrine\DBAL\Connection; abstract class AbstractPlatform { private $_quoteIdentifiers = false; - + /** * Constructor. */ @@ -59,7 +60,7 @@ abstract class AbstractPlatform { return $this->_quoteIdentifiers; } - + /** * Gets the character used for identifier quoting. * @@ -69,7 +70,7 @@ abstract class AbstractPlatform { return '"'; } - + /** * Gets the string portion that starts an SQL comment. * @@ -79,7 +80,7 @@ abstract class AbstractPlatform { return "--"; } - + /** * Gets the string portion that ends an SQL comment. * @@ -89,7 +90,7 @@ abstract class AbstractPlatform { return "\n"; } - + /** * Gets the maximum length of a varchar field. * @@ -99,7 +100,7 @@ abstract class AbstractPlatform { return 255; } - + /** * Gets all SQL wildcard characters of the platform. * @@ -109,7 +110,7 @@ abstract class AbstractPlatform { return array('%', '_'); } - + /** * Returns the regular expression operator. * @@ -129,6 +130,7 @@ abstract class AbstractPlatform public function getAvgExpression($column) { $column = $this->quoteIdentifier($column); + return 'AVG(' . $column . ')'; } @@ -144,6 +146,7 @@ abstract class AbstractPlatform public function getCountExpression($column) { $column = $this->quoteIdentifier($column); + return 'COUNT(' . $column . ')'; } @@ -156,6 +159,7 @@ abstract class AbstractPlatform public function getMaxExpression($column) { $column = $this->quoteIdentifier($column); + return 'MAX(' . $column . ')'; } @@ -168,6 +172,7 @@ abstract class AbstractPlatform public function getMinExpression($column) { $column = $this->quoteIdentifier($column); + return 'MIN(' . $column . ')'; } @@ -180,6 +185,7 @@ abstract class AbstractPlatform public function getSumExpression($column) { $column = $this->quoteIdentifier($column); + return 'SUM(' . $column . ')'; } @@ -195,6 +201,7 @@ abstract class AbstractPlatform public function getMd5Expression($column) { $column = $this->quoteIdentifier($column); + return 'MD5(' . $column . ')'; } @@ -208,6 +215,7 @@ abstract class AbstractPlatform public function getLengthExpression($column) { $column = $this->quoteIdentifier($column); + return 'LENGTH(' . $column . ')'; } @@ -237,6 +245,7 @@ abstract class AbstractPlatform { $expression1 = $this->quoteIdentifier($expression1); $expression2 = $this->quoteIdentifier($expression2); + return 'MOD(' . $expression1 . ', ' . $expression2 . ')'; } @@ -325,21 +334,6 @@ abstract class AbstractPlatform return 'NOW()'; } - /** - * soundex - * Returns a string to call a function to compute the - * soundex encoding of a string - * - * The string "?000" is returned if the argument is NULL. - * - * @param string $value - * @return string SQL soundex function with given parameter - */ - /*public function getSoundexExpression($value) - { - throw DoctrineException::updateMe('SQL soundex function not supported by this driver.'); - }*/ - /** * return string to call a function to get a substring inside an SQL statement * @@ -395,265 +389,6 @@ abstract class AbstractPlatform return 'NOT(' . $this->quoteIdentifier($expression) . ')'; } - /** - * Returns the SQL to perform the same mathematical operation over an array - * of values or expressions. - * - * basicMath() accepts an arbitrary number of parameters. Each parameter - * must contain a value or an expression or an array with values or - * expressions. - * - * @param string $type the type of operation, can be '+', '-', '*' or '/'. - * @param string|array(string) - * @return string an expression - */ - /*private function _getBasicMathExpression($type, array $args) - { - $elements = $this->getIdentifiers($args); - if (count($elements) < 1) { - return ''; - } - if (count($elements) == 1) { - return $elements[0]; - } else { - return '(' . implode(' ' . $type . ' ', $elements) . ')'; - } - }*/ - - /** - * Returns the SQL to add values or expressions together. - * - * add() accepts an arbitrary number of parameters. Each parameter - * must contain a value or an expression or an array with values or - * expressions. - * - * Example: - * - * $q = new Doctrine_Query(); - * $e = $q->expr; - * - * $q->select('u.*') - * ->from('User u') - * ->where($e->eq($e->add('id', 2), 12)); - * - * - * @param string|array(string) - * @return string an expression - */ - /*public function getAddExpression(array $args) - { - return $this->basicMath('+', $args); - }*/ - - /** - * Returns the SQL to subtract values or expressions from eachother. - * - * subtract() accepts an arbitrary number of parameters. Each parameter - * must contain a value or an expression or an array with values or - * expressions. - * - * Example: - * - * $q = new Doctrine_Query(); - * $e = $q->expr; - * - * $q->select('u.*') - * ->from('User u') - * ->where($e->eq($e->sub('id', 2), 12)); - * - * - * @param string|array(string) - * @return string an expression - */ - /*public function getSubExpression(array $args) - { - return $this->basicMath('-', $args ); - }*/ - - /** - * Returns the SQL to multiply values or expressions by eachother. - * - * multiply() accepts an arbitrary number of parameters. Each parameter - * must contain a value or an expression or an array with values or - * expressions. - * - * Example: - * - * $q = new Doctrine_Query(); - * $e = $q->expr; - * - * $q->select('u.*') - * ->from('User u') - * ->where($e->eq($e->mul('id', 2), 12)); - * - * - * @param string|array(string) - * @return string an expression - */ - /*public function getMulExpression(array $args) - { - return $this->basicMath('*', $args); - }*/ - - /** - * Returns the SQL to divide values or expressions by eachother. - * - * divide() accepts an arbitrary number of parameters. Each parameter - * must contain a value or an expression or an array with values or - * expressions. - * - * Example: - * - * $q = new Doctrine_Query(); - * $e = $q->expr; - * - * $q->select('u.*') - * ->from('User u') - * ->where($e->eq($e->div('id', 2), 12)); - * - * - * @param string|array(string) - * @return string an expression - */ - /*public function getDivExpression(array $args) - { - return $this->basicMath('/', $args); - }*/ - - /** - * Returns the SQL to check if two values are equal. - * - * Example: - * - * $q = new Doctrine_Query(); - * $q->select('u.*') - * ->from('User u') - * ->where($q->expr->eq('id', 1)); - * - * - * @param string $value1 logical expression to compare - * @param string $value2 logical expression to compare with - * @return string logical expression - */ - /*public function getEqExpression($value1, $value2) - { - $value1 = $this->quoteIdentifier($value1); - $value2 = $this->quoteIdentifier($value2); - return $value1 . ' = ' . $value2; - }*/ - - /** - * Returns the SQL to check if two values are unequal. - * - * Example: - * - * $q = new Doctrine_Query(); - * $q->select('u.*') - * ->from('User u') - * ->where($q->expr->neq('id', 1)); - * - * - * @param string $value1 logical expression to compare - * @param string $value2 logical expression to compare with - * @return string logical expression - */ - /*public function getNeqExpression($value1, $value2) - { - $value1 = $this->quoteIdentifier($value1); - $value2 = $this->quoteIdentifier($value2); - return $value1 . ' <> ' . $value2; - }*/ - - /** - * Returns the SQL to check if one value is greater than another value. - * - * Example: - * - * $q = new Doctrine_Query(); - * $q->select('u.*') - * ->from('User u') - * ->where($q->expr->gt('id', 1)); - * - * - * @param string $value1 logical expression to compare - * @param string $value2 logical expression to compare with - * @return string logical expression - */ - /*public function getGtExpression($value1, $value2) - { - $value1 = $this->quoteIdentifier($value1); - $value2 = $this->quoteIdentifier($value2); - return $value1 . ' > ' . $value2; - }*/ - - /** - * Returns the SQL to check if one value is greater than or equal to - * another value. - * - * Example: - * - * $q = new Doctrine_Query(); - * $q->select('u.*') - * ->from('User u') - * ->where($q->expr->gte('id', 1)); - * - * - * @param string $value1 logical expression to compare - * @param string $value2 logical expression to compare with - * @return string logical expression - */ - /*public function getGteExpression($value1, $value2) - { - $value1 = $this->quoteIdentifier($value1); - $value2 = $this->quoteIdentifier($value2); - return $value1 . ' >= ' . $value2; - }*/ - - /** - * Returns the SQL to check if one value is less than another value. - * - * Example: - * - * $q = new Doctrine_Query(); - * $q->select('u.*') - * ->from('User u') - * ->where($q->expr->lt('id', 1)); - * - * - * @param string $value1 logical expression to compare - * @param string $value2 logical expression to compare with - * @return string logical expression - */ - /*public function getLtExpression($value1, $value2) - { - $value1 = $this->quoteIdentifier($value1); - $value2 = $this->quoteIdentifier($value2); - return $value1 . ' < ' . $value2; - }*/ - - /** - * Returns the SQL to check if one value is less than or equal to - * another value. - * - * Example: - * - * $q = new Doctrine_Query(); - * $q->select('u.*') - * ->from('User u') - * ->where($q->expr->lte('id', 1)); - * - * - * @param string $value1 logical expression to compare - * @param string $value2 logical expression to compare with - * @return string logical expression - */ - /*public function getLteExpression($value1, $value2) - { - $value1 = $this->quoteIdentifier($value1); - $value2 = $this->quoteIdentifier($value2); - return $value1 . ' <= ' . $value2; - }*/ - /** * Returns the SQL to check if a value is one in a set of * given values. @@ -706,6 +441,7 @@ abstract class AbstractPlatform public function getIsNullExpression($expression) { $expression = $this->quoteIdentifier($expression); + return $expression . ' IS NULL'; } @@ -726,6 +462,7 @@ abstract class AbstractPlatform public function getIsNotNullExpression($expression) { $expression = $this->quoteIdentifier($expression); + return $expression . ' IS NOT NULL'; } @@ -757,220 +494,66 @@ abstract class AbstractPlatform $expression = $this->quoteIdentifier($expression); $value1 = $this->quoteIdentifier($value1); $value2 = $this->quoteIdentifier($value2); + return $expression . ' BETWEEN ' .$value1 . ' AND ' . $value2; } - /** - * Returns global unique identifier - * - * @return string to get global unique identifier - */ - /*public function getGuidExpression() - { - throw DoctrineException::updateMe('method not implemented'); - }*/ - - /** - * returns arcus cosine SQL string - * - * @return string - */ public function getAcosExpression($value) { return 'ACOS(' . $value . ')'; } - /** - * sin - * - * @param string $value - * @return void - */ public function getSinExpression($value) { return 'SIN(' . $value . ')'; } - /** - * pi - * - * @return void - */ public function getPiExpression() { return 'PI()'; } - /** - * cos - * - * @param string $value - * @return void - * @author Jonathan H. Wage - */ public function getCosExpression($value) { return 'COS(' . $value . ')'; } - - /** - * Enter description here... - * - * @return string - */ + public function getForUpdateSql() { return 'FOR UPDATE'; } - - /** - * Enter description here... - * - * @todo Throw exception by default? - */ - public function getListDatabasesSql() - { - throw DoctrineException::updateMe('List databases not supported by this driver.'); - } - - /** - * Enter description here... - * - * @todo Throw exception by default? - */ - public function getListFunctionsSql() - { - throw DoctrineException::updateMe('List functions not supported by this driver.'); - } - - /** - * Enter description here... - * - * @todo Throw exception by default? - */ - public function getListTriggersSql() - { - throw DoctrineException::updateMe('List triggers not supported by this driver.'); - } - - /** - * Enter description here... - * - * @todo Throw exception by default? - */ - public function getListSequencesSql() - { - throw DoctrineException::updateMe('List sequences not supported by this driver.'); - } - - /** - * Enter description here... - * - * @todo Throw exception by default? - */ - public function getListTableConstraintsSql() - { - throw DoctrineException::updateMe('List table constraints not supported by this driver.'); - } - - /** - * Enter description here... - * - * @todo Throw exception by default? - */ - public function getListTableColumnsSql() - { - throw DoctrineException::updateMe('List table columns not supported by this driver.'); - } - - /** - * Enter description here... - * - * @todo Throw exception by default? - */ - public function getListTablesSql() - { - throw DoctrineException::updateMe('List tables not supported by this driver.'); - } - - /** - * Enter description here... - * - * @todo Throw exception by default? - */ - public function getListUsersSql() - { - throw DoctrineException::updateMe('List users not supported by this driver.'); - } - - /** - * Enter description here... - * - * @todo Throw exception by default? - */ - public function getListViewsSql() - { - throw DoctrineException::updateMe('List views not supported by this driver.'); - } - - /** - * Enter description here... - * - * @todo Throw exception by default? - */ + public function getDropDatabaseSql($database) { return 'DROP DATABASE ' . $database; } - - /** - * Enter description here... - * - * @todo Throw exception by default? - */ + public function getDropTableSql($table) { return 'DROP TABLE ' . $table; } - - /** - * Enter description here... - * - * @todo Throw exception by default? - */ + public function getDropIndexSql($index, $name) { return 'DROP INDEX ' . $index; } - - /** - * Enter description here... - * - * @todo Throw exception by default? - */ - public function getDropSequenceSql($sequenceName) + + public function getDropConstraintSql($table, $name, $primary = false) { - throw DoctrineException::updateMe('Drop sequence not supported by this driver.'); + $table = $this->_conn->getDatabasePlatform()->quoteIdentifier($table); + $name = $this->_conn->getDatabasePlatform()->quoteIdentifier($name); + + return 'ALTER TABLE ' . $table . ' DROP CONSTRAINT ' . $name; } - - /** - * Gets the SQL for acquiring the next value from a sequence. - */ - public function getSequenceNextValSql($sequenceName) + + public function getDropForeignKeySql($table, $name) { - throw DoctrineException::updateMe('Sequences not supported by this driver.'); + $table = $this->_conn->getDatabasePlatform()->quoteIdentifier($table); + $name = $this->_conn->getDatabasePlatform()->quoteIdentifier($name); + + return 'ALTER TABLE ' . $table . ' DROP FOREIGN KEY ' . $name; } - - /** - * Enter description here... - * - * @todo Throw exception by default? - */ - public function getCreateDatabaseSql($database) - { - throw DoctrineException::updateMe('Create database not supported by this driver.'); - } - + /** * Gets the SQL statement(s) to create a table with the specified name, columns and options * on this platform. @@ -978,7 +561,7 @@ abstract class AbstractPlatform * @param string $table * @param array $columns * @param array $options - * @return array + * @return array */ public function getCreateTableSql($table, array $columns, array $options = array()) { @@ -995,7 +578,7 @@ abstract class AbstractPlatform } $query = 'CREATE TABLE ' . $this->quoteIdentifier($table, true) . ' (' . $columnListSql; - + $check = $this->getCheckDeclarationSql($columns); if ( ! empty($check)) { $query .= ', ' . $check; @@ -1011,10 +594,10 @@ abstract class AbstractPlatform } } } - + return $sql; } - + /** * Gets the SQL to create a sequence on this platform. * @@ -1028,7 +611,7 @@ abstract class AbstractPlatform { throw DoctrineException::updateMe('Create sequence not supported by this driver.'); } - + /** * Gets the SQL to create a constraint on a table on this platform. * @@ -1068,7 +651,7 @@ abstract class AbstractPlatform return $query; } - + /** * Gets the SQL to create an index on a table on this platform. * @@ -1096,7 +679,7 @@ abstract class AbstractPlatform return $query; } - + /** * Quotes a string so that it can be safely used as a table or column name, * even if it is a reserved word of the platform. @@ -1127,7 +710,7 @@ abstract class AbstractPlatform return $c . $str . $c; } - + /** * createForeignKeySql * @@ -1142,7 +725,7 @@ abstract class AbstractPlatform return $query; } - + /** * Gets the sql for altering an existing table. * (this method is implemented by the drivers) @@ -1158,7 +741,7 @@ abstract class AbstractPlatform { throw DoctrineException::updateMe('Alter table not supported by this driver.'); } - + /** * Get declaration of a number of fields in bulk * @@ -1243,12 +826,12 @@ abstract class AbstractPlatform $unique = (isset($field['unique']) && $field['unique']) ? ' ' . $this->getUniqueFieldDeclarationSql() : ''; - + $check = (isset($field['check']) && $field['check']) ? ' ' . $field['check'] : ''; $typeDecl = $field['type']->getSqlDeclaration($field, $this); - + return $this->quoteIdentifier($name) . ' ' . $typeDecl . $charset . $default . $notnull . $unique . $check . $collation; } @@ -1395,9 +978,9 @@ abstract class AbstractPlatform { return 'TEMPORARY'; } - + /** - * Enter description here... + * Get sql query to show a list of database * * @return unknown */ @@ -1405,7 +988,7 @@ abstract class AbstractPlatform { throw DoctrineException::updateMe('Show databases not supported by this driver.'); } - + /** * getForeignKeyDeclaration * Obtain DBMS specific SQL code portion needed to set the FOREIGN KEY constraint @@ -1576,7 +1159,7 @@ abstract class AbstractPlatform { return ''; } - + /** * build a pattern matching string * @@ -1598,7 +1181,7 @@ abstract class AbstractPlatform { throw DoctrineException::updateMe("Method not implemented."); } - + /** * Whether the platform prefers sequences for ID generation. * Subclasses should override this method to return TRUE if they prefer sequences. @@ -1609,7 +1192,7 @@ abstract class AbstractPlatform { return false; } - + /** * Whether the platform prefers identity columns (eg. autoincrement) for ID generation. * Subclasses should override this method to return TRUE if they prefer identity columns. @@ -1620,12 +1203,12 @@ abstract class AbstractPlatform { return false; } - + /** * Adds a LIMIT/OFFSET clause to the query. * This default implementation writes the syntax "LIMIT x OFFSET y" to the * query which is supported by MySql, PostgreSql and Sqlite. - * Any database platforms that do not support this syntax should override + * Any database platforms that do not support this syntax should override * this implementation and provide their own. * * @param string $query The SQL string to write to / append to. @@ -1636,7 +1219,7 @@ abstract class AbstractPlatform { $limit = (int) $limit; $offset = (int) $offset; - + if ($limit && $offset) { $query .= ' LIMIT ' . $limit . ' OFFSET ' . $offset; } elseif ($limit && ! $offset) { @@ -1647,7 +1230,7 @@ abstract class AbstractPlatform return $query; } - + /** * Some platforms need the boolean values to be converted. * Default conversion defined here converts to integers. @@ -1680,9 +1263,9 @@ abstract class AbstractPlatform { return 'SET NAMES ' . $this->quote($charset); } - + /** - * Enter description here... + * Get sql for transaction isolation level Connection constant * * @param integer $level */ @@ -1699,11 +1282,71 @@ abstract class AbstractPlatform return 'SERIALIZABLE'; default: throw DoctrineException::updateMe('isolation level is not supported: ' . $isolation); - } + } } - + + public function getListDatabasesSql() + { + throw DoctrineException::updateMe('List databases not supported by this driver.'); + } + + public function getListFunctionsSql() + { + throw DoctrineException::updateMe('List functions not supported by this driver.'); + } + + public function getListTriggersSql() + { + throw DoctrineException::updateMe('List triggers not supported by this driver.'); + } + + public function getListSequencesSql() + { + throw DoctrineException::updateMe('List sequences not supported by this driver.'); + } + + public function getListTableConstraintsSql($table) + { + throw DoctrineException::updateMe('List table constraints not supported by this driver.'); + } + + public function getListTableColumnsSql($table) + { + throw DoctrineException::updateMe('List table columns not supported by this driver.'); + } + + public function getListTablesSql() + { + throw DoctrineException::updateMe('List tables not supported by this driver.'); + } + + public function getListUsersSql() + { + throw DoctrineException::updateMe('List users not supported by this driver.'); + } + + public function getListViewsSql() + { + throw DoctrineException::updateMe('List views not supported by this driver.'); + } + + public function getDropSequenceSql($sequenceName) + { + throw DoctrineException::updateMe('Drop sequence not supported by this driver.'); + } + + public function getSequenceNextValSql($sequenceName) + { + throw DoctrineException::updateMe('Sequences not supported by this driver.'); + } + + public function getCreateDatabaseSql($database) + { + throw DoctrineException::updateMe('Create database not supported by this driver.'); + } + /** - * Enter description here... + * Get sql to set the transaction isolation level * * @param integer $level */ @@ -1735,7 +1378,7 @@ abstract class AbstractPlatform { return Connection::TRANSACTION_READ_COMMITTED; } - + /* supports*() metods */ /** @@ -1829,7 +1472,14 @@ abstract class AbstractPlatform /** * Gets the SQL snippet used to declare a VARCHAR column type. * - * @params array $field + * @param array $field */ abstract public function getVarcharTypeDeclarationSql(array $field); + + /** + * Get the platform name for this instance + * + * @return string + */ + abstract public function getName(); } \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Platforms/Db2Platform.php b/lib/Doctrine/DBAL/Platforms/Db2Platform.php index f08870338..037bf66e1 100644 --- a/lib/Doctrine/DBAL/Platforms/Db2Platform.php +++ b/lib/Doctrine/DBAL/Platforms/Db2Platform.php @@ -4,8 +4,19 @@ namespace Doctrine\DBAL\Platforms; class Db2Platform extends AbstractPlatform { - public function getSequenceNextValSql($sequenceName) { + public function getSequenceNextValSql($sequenceName) + { return 'SELECT NEXTVAL FOR ' . $this->quoteIdentifier($sequenceName) . ' FROM SYSIBM.SYSDUMMY1'; } + + /** + * Get the platform name for this instance + * + * @return string + */ + public function getName() + { + return 'db2'; + } } \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Platforms/FirebirdPlatform.php b/lib/Doctrine/DBAL/Platforms/FirebirdPlatform.php index 72ab193d3..41e845898 100644 --- a/lib/Doctrine/DBAL/Platforms/FirebirdPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/FirebirdPlatform.php @@ -58,166 +58,6 @@ class FirebirdPlatform extends AbstractPlatform { return " ESCAPE '". $this->_properties['escape_pattern'] ."'"; } - - /** - * 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 'varchar': - case 'string': - case 'array': - case 'object': - case 'char': - case 'text': - case 'gzip': - $length = !empty($field['length']) - ? $field['length'] : 16777215; // TODO: $this->conn->options['default_text_field_length']; - - $fixed = ((isset($field['fixed']) && $field['fixed']) || $field['type'] == 'char') ? true : false; - - return $fixed ? 'CHAR('.$length.')' : 'VARCHAR('.$length.')'; - case 'clob': - return 'BLOB SUB_TYPE 1'; - case 'blob': - return 'BLOB SUB_TYPE 0'; - case 'integer': - case 'enum': - case 'int': - return 'INT'; - case 'boolean': - return 'SMALLINT'; - case 'date': - return 'DATE'; - case 'time': - return 'TIME'; - case 'timestamp': - return 'TIMESTAMP'; - case 'float': - return 'DOUBLE PRECISION'; - 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 \Doctrine\Common\DoctrineException::updateMe('Unknown field type \'' . $field['type'] . '\'.'); - } - - /** - * 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); - } /** * Obtain DBMS specific SQL code portion needed to set the CHARACTER SET @@ -288,4 +128,9 @@ class FirebirdPlatform extends AbstractPlatform { return 'SET TRANSACTION ISOLATION LEVEL ' . $this->_getTransactionIsolationLevelSql($level); } + + public function getName() + { + return 'firebird'; + } } \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Platforms/InformixPlatform.php b/lib/Doctrine/DBAL/Platforms/InformixPlatform.php index 4a3c99c27..3e0b5a427 100644 --- a/lib/Doctrine/DBAL/Platforms/InformixPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/InformixPlatform.php @@ -13,82 +13,14 @@ class InformixPlatform extends AbstractPlatform { parent::__construct(); } - + /** - * Obtain DBMS specific SQL code portion needed to declare an text type - * field to be used in statements like CREATE TABLE. + * Get the platform name for this instance * - * @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 + * @return string */ - public function getNativeDeclaration($field) + public function getName() { - 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'] . '\'.'); + return 'informix'; } } \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Platforms/MockPlatform.php b/lib/Doctrine/DBAL/Platforms/MockPlatform.php index a0252d7de..38e959e7a 100644 --- a/lib/Doctrine/DBAL/Platforms/MockPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/MockPlatform.php @@ -5,4 +5,14 @@ class MockPlatform extends AbstractPlatform { public function getNativeDeclaration(array $field) {} public function getPortableDeclaration(array $field) {} + + /** + * Get the platform name for this instance + * + * @return string + */ + public function getName() + { + return 'mock'; + } } \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Platforms/MsSqlPlatform.php b/lib/Doctrine/DBAL/Platforms/MsSqlPlatform.php index 4d4fa6b3b..55e425750 100644 --- a/lib/Doctrine/DBAL/Platforms/MsSqlPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/MsSqlPlatform.php @@ -302,167 +302,6 @@ class MsSqlPlatform extends AbstractPlatform return false; } - /** - * 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 'array': - case 'object': - case 'text': - case 'char': - case 'varchar': - case 'string': - case 'gzip': - $length = !empty($field['length']) - ? $field['length'] : false; - - $fixed = ((isset($field['fixed']) && $field['fixed']) || $field['type'] == 'char') ? true : false; - - return $fixed ? ($length ? 'CHAR('.$length.')' : 'CHAR('.$this->conn->options['default_text_field_length'].')') - : ($length ? 'VARCHAR('.$length.')' : 'TEXT'); - case 'clob': - if ( ! empty($field['length'])) { - $length = $field['length']; - if ($length <= 8000) { - return 'VARCHAR('.$length.')'; - } - } - return 'TEXT'; - case 'blob': - if ( ! empty($field['length'])) { - $length = $field['length']; - if ($length <= 8000) { - return "VARBINARY($length)"; - } - } - return 'IMAGE'; - case 'integer': - case 'enum': - case 'int': - return 'INT'; - case 'boolean': - return 'BIT'; - case 'date': - return 'CHAR(' . strlen('YYYY-MM-DD') . ')'; - case 'time': - return 'CHAR(' . strlen('HH:MM:SS') . ')'; - case 'timestamp': - return 'CHAR(' . strlen('YYYY-MM-DD HH:MM:SS') . ')'; - case 'float': - return '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 \Doctrine\Common\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); - } - /** * Enter description here... * @@ -578,4 +417,14 @@ class MsSqlPlatform extends AbstractPlatform { return 'CHARACTER SET ' . $charset; } + + /** + * Get the platform name for this instance + * + * @return string + */ + public function getName() + { + return 'mssql'; + } } \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php b/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php index a6a8102f0..f3694972f 100644 --- a/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php @@ -188,269 +188,7 @@ class MySqlPlatform extends AbstractPlatform } return 'LONGTEXT'; } - - /** - * 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(array $field) - { - /*if ( ! isset($field['type'])) { - throw DoctrineException::updateMe('Missing column type.'); - } - switch ($field['type']) { - case 'char': - $length = ( ! empty($field['length'])) ? $field['length'] : false; - - return $length ? 'CHAR('.$length.')' : 'CHAR(255)'; - case 'varchar': - case 'array': - case 'object': - case 'string': - case 'gzip': - return $this->getVarcharTypeDeclarationSql($field); - case 'clob': - return $this->getClobDeclarationSql($field); - case 'blob': - if ( ! empty($field['length'])) { - $length = $field['length']; - if ($length <= 255) { - return 'TINYBLOB'; - } elseif ($length <= 65532) { - return 'BLOB'; - } elseif ($length <= 16777215) { - return 'MEDIUMBLOB'; - } - } - return 'LONGBLOB'; - case 'enum': - if ($this->conn->getAttribute(Doctrine::ATTR_USE_NATIVE_ENUM)) { - $values = array(); - foreach ($field['values'] as $value) { - $values[] = $this->conn->quote($value, 'varchar'); - } - return 'ENUM('.implode(', ', $values).')'; - } - // fall back to integer - case 'integer': - case 'int': - if ( ! empty($field['length'])) { - $length = $field['length']; - if ($length <= 1) { - return 'TINYINT'; - } elseif ($length == 2) { - return 'SMALLINT'; - } elseif ($length == 3) { - return 'MEDIUMINT'; - } elseif ($length == 4) { - return 'INT'; - } elseif ($length > 4) { - return 'BIGINT'; - } - } - return 'INT'; - case 'boolean': - return 'TINYINT(1)'; - case 'date': - return 'DATE'; - case 'time': - return 'TIME'; - case 'timestamp': - return 'DATETIME'; - case 'float': - case 'double': - return 'DOUBLE'; - 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 Doctrine datatype and length - * - * @param array $field native field description - * @return array containing the various possible types, length, sign, fixed - * @override - */ - public function getPortableDeclaration(array $field) - { - /*$dbType = strtolower($field['type']); - $dbType = strtok($dbType, '(), '); - if ($dbType == 'national') { - $dbType = strtok('(), '); - } - if (isset($field['length'])) { - $length = $field['length']; - $decimal = ''; - } else { - $length = strtok('(), '); - $decimal = strtok('(), '); - } - $type = array(); - $unsigned = $fixed = null; - - if ( ! isset($field['name'])) { - $field['name'] = ''; - } - - $values = null; - - switch ($dbType) { - case 'tinyint': - $type[] = 'integer'; - $type[] = 'boolean'; - if (preg_match('/^(is|has)/', $field['name'])) { - $type = array_reverse($type); - } - $unsigned = preg_match('/ unsigned/i', $field['type']); - $length = 1; - break; - case 'smallint': - $type[] = 'integer'; - $unsigned = preg_match('/ unsigned/i', $field['type']); - $length = 2; - break; - case 'mediumint': - $type[] = 'integer'; - $unsigned = preg_match('/ unsigned/i', $field['type']); - $length = 3; - break; - case 'int': - case 'integer': - $type[] = 'integer'; - $unsigned = preg_match('/ unsigned/i', $field['type']); - $length = 4; - break; - case 'bigint': - $type[] = 'integer'; - $unsigned = preg_match('/ unsigned/i', $field['type']); - $length = 8; - break; - case 'tinytext': - case 'mediumtext': - case 'longtext': - case 'text': - case 'text': - case 'varchar': - $fixed = false; - case 'string': - case 'char': - $type[] = 'string'; - if ($length == '1') { - $type[] = 'boolean'; - if (preg_match('/^(is|has)/', $field['name'])) { - $type = array_reverse($type); - } - } elseif (strstr($dbType, 'text')) { - $type[] = 'clob'; - if ($decimal == 'binary') { - $type[] = 'blob'; - } - } - if ($fixed !== false) { - $fixed = true; - } - break; - case 'enum': - $type[] = 'enum'; - preg_match_all('/\'((?:\'\'|[^\'])*)\'/', $field['type'], $matches); - $length = 0; - $fixed = false; - if (is_array($matches)) { - foreach ($matches[1] as &$value) { - $value = str_replace('\'\'', '\'', $value); - $length = max($length, strlen($value)); - } - if ($length == '1' && count($matches[1]) == 2) { - $type[] = 'boolean'; - if (preg_match('/^(is|has)/', $field['name'])) { - $type = array_reverse($type); - } - } else { - $values = $matches[1]; - } - } - $type[] = 'integer'; - break; - case 'set': - $fixed = false; - $type[] = 'text'; - $type[] = 'integer'; - break; - case 'date': - $type[] = 'date'; - $length = null; - break; - case 'datetime': - case 'timestamp': - $type[] = 'timestamp'; - $length = null; - break; - case 'time': - $type[] = 'time'; - $length = null; - break; - case 'float': - case 'double': - case 'real': - $type[] = 'float'; - $unsigned = preg_match('/ unsigned/i', $field['type']); - break; - case 'unknown': - case 'decimal': - case 'numeric': - $type[] = 'decimal'; - $unsigned = preg_match('/ unsigned/i', $field['type']); - break; - case 'tinyblob': - case 'mediumblob': - case 'longblob': - case 'blob': - $type[] = 'blob'; - $length = null; - break; - case 'year': - $type[] = 'integer'; - $type[] = 'date'; - $length = null; - break; - default: - throw DoctrineException::updateMe('unknown database attribute type: ' . $dbType); - } - - $length = ((int) $length == 0) ? null : (int) $length; - - if ($values === null) { - return array('type' => $type, 'length' => $length, 'unsigned' => $unsigned, 'fixed' => $fixed); - } else { - return array('type' => $type, 'length' => $length, 'unsigned' => $unsigned, 'fixed' => $fixed, 'values' => $values); - }*/ - } - /** * Obtain DBMS specific SQL code portion needed to set the CHARACTER SET * of a field declaration to be used in statements like CREATE TABLE. @@ -1120,4 +858,14 @@ class MySqlPlatform extends AbstractPlatform { return 'SET SESSION TRANSACTION ISOLATION LEVEL ' . $this->_getTransactionIsolationLevelSql($level); } + + /** + * Get the platform name for this instance + * + * @return string + */ + public function getName() + { + return 'mysql'; + } } \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Platforms/OraclePlatform.php b/lib/Doctrine/DBAL/Platforms/OraclePlatform.php index cc0c3823b..b5a13c9b4 100644 --- a/lib/Doctrine/DBAL/Platforms/OraclePlatform.php +++ b/lib/Doctrine/DBAL/Platforms/OraclePlatform.php @@ -37,36 +37,7 @@ class OraclePlatform extends AbstractPlatform { parent::__construct(); } - - /** - * @todo Doc - */ - /*private function _createLimitSubquery($query, $limit, $offset, $column = null) - { - $limit = (int) $limit; - $offset = (int) $offset; - if (preg_match('/^\s*SELECT/i', $query)) { - if ( ! preg_match('/\sFROM\s/i', $query)) { - $query .= " FROM dual"; - } - if ($limit > 0) { - $max = $offset + $limit; - $column = $column === null ? '*' : $column; - if ($offset > 0) { - $min = $offset + 1; - $query = 'SELECT b.'.$column.' FROM ('. - 'SELECT a.*, ROWNUM AS doctrine_rownum FROM (' - . $query . ') a '. - ') b '. - 'WHERE doctrine_rownum BETWEEN ' . $min . ' AND ' . $max; - } else { - $query = 'SELECT a.'.$column.' FROM (' . $query .') a WHERE ROWNUM <= ' . $max; - } - } - } - return $query; - }*/ - + /** * return string to call a function to get a substring inside an SQL statement * @@ -80,8 +51,9 @@ class OraclePlatform extends AbstractPlatform */ public function getSubstringExpression($value, $position, $length = null) { - if ($length !== null) + if ($length !== null) { return "SUBSTR($value, $position, $length)"; + } return "SUBSTR($value, $position)"; } @@ -128,175 +100,6 @@ class OraclePlatform extends AbstractPlatform { return 'SYS_GUID()'; } - - /** - * 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(array $field) - { - if ( ! isset($field['type'])) { - throw \Doctrine\Common\DoctrineException::updateMe('Missing column type.'); - } - switch ($field['type']) { - case 'string': - case 'array': - case 'object': - case 'gzip': - case 'char': - case 'varchar': - $length = !empty($field['length']) - ? $field['length'] : 16777215; // TODO: $this->conn->options['default_text_field_length']; - - $fixed = ((isset($field['fixed']) && $field['fixed']) || $field['type'] == 'char') ? true : false; - - return $fixed ? 'CHAR('.$length.')' : 'VARCHAR2('.$length.')'; - case 'clob': - return 'CLOB'; - case 'blob': - return 'BLOB'; - case 'integer': - case 'enum': - case 'int': - if ( ! empty($field['length'])) { - return 'NUMBER('.$field['length'].')'; - } - return 'INT'; - case 'boolean': - return 'NUMBER(1)'; - case 'date': - case 'time': - case 'timestamp': - return 'DATE'; - case 'float': - case 'double': - return 'NUMBER'; - case 'decimal': - $scale = !empty($field['scale']) ? $field['scale'] : $this->conn->getAttribute(Doctrine::ATTR_DECIMAL_PLACES); - return 'NUMBER(*,'.$scale.')'; - default: - } - throw \Doctrine\Common\DoctrineException::updateMe('Unknown field type \'' . $field['type'] . '\'.'); - }*/ - - /** - * 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 - * @throws Doctrine_DataDict_Oracle_Exception - * @override - */ - /*public function getPortableDeclaration(array $field) - { - if ( ! isset($field['data_type'])) { - throw \Doctrine\Common\DoctrineException::updateMe('Native oracle definition must have a data_type key specified'); - } - - $dbType = strtolower($field['data_type']); - $type = array(); - $length = $unsigned = $fixed = null; - if ( ! empty($field['data_length'])) { - $length = $field['data_length']; - } - - if ( ! isset($field['column_name'])) { - $field['column_name'] = ''; - } - - switch ($dbType) { - case 'integer': - case 'pls_integer': - case 'binary_integer': - $type[] = 'integer'; - if ($length == '1') { - $type[] = 'boolean'; - if (preg_match('/^(is|has)/', $field['column_name'])) { - $type = array_reverse($type); - } - } - break; - case 'varchar': - case 'varchar2': - case 'nvarchar2': - $fixed = false; - case 'char': - case 'nchar': - $type[] = 'string'; - if ($length == '1') { - $type[] = 'boolean'; - if (preg_match('/^(is|has)/', $field['column_name'])) { - $type = array_reverse($type); - } - } - if ($fixed !== false) { - $fixed = true; - } - break; - case 'date': - case 'timestamp': - $type[] = 'timestamp'; - $length = null; - break; - case 'float': - $type[] = 'float'; - break; - case 'number': - if ( ! empty($field['data_scale'])) { - $type[] = 'decimal'; - } else { - $type[] = 'integer'; - if ($length == '1') { - $type[] = 'boolean'; - if (preg_match('/^(is|has)/', $field['column_name'])) { - $type = array_reverse($type); - } - } - } - break; - case 'long': - $type[] = 'string'; - case 'clob': - case 'nclob': - $type[] = 'clob'; - break; - case 'blob': - case 'raw': - case 'long raw': - case 'bfile': - $type[] = 'blob'; - $length = null; - break; - case 'rowid': - case 'urowid': - default: - throw \Doctrine\Common\DoctrineException::updateMe('unknown database attribute type: ' . $dbType); - } - - return array('type' => $type, - 'length' => $length, - 'unsigned' => $unsigned, - 'fixed' => $fixed); - }*/ /** * {@inheritdoc} @@ -416,4 +219,14 @@ class OraclePlatform extends AbstractPlatform { return true; } + + /** + * Get the platform name for this instance + * + * @return string + */ + public function getName() + { + return 'oracle'; + } } \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php b/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php index 7dc0d9c8a..ce6e7b82b 100644 --- a/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php @@ -63,7 +63,7 @@ class PostgreSqlPlatform extends AbstractPlatform * declare the specified field. * @override */ - /*public function getNativeDeclaration(array $field) + public function getNativeDeclaration(array $field) { if ( ! isset($field['type'])) { throw DoctrineException::updateMe('Missing column type.'); @@ -127,7 +127,7 @@ class PostgreSqlPlatform extends AbstractPlatform return 'NUMERIC('.$length.','.$scale.')'; } throw DoctrineException::updateMe('Unknown field type \'' . $field['type'] . '\'.'); - }*/ + } /** * Maps a native array description of a field to a portable Doctrine datatype and length @@ -137,7 +137,7 @@ class PostgreSqlPlatform extends AbstractPlatform * @return array containing the various possible types, length, sign, fixed * @override */ - /*public function getPortableDeclaration(array $field) + public function getPortableDeclaration(array $field) { $length = (isset($field['length'])) ? $field['length'] : null; if ($length == '-1' && isset($field['atttypmod'])) { @@ -264,7 +264,7 @@ class PostgreSqlPlatform extends AbstractPlatform 'length' => $length, 'unsigned' => $unsigned, 'fixed' => $fixed); - }*/ + } /** * Returns the md5 sum of a field. @@ -579,7 +579,7 @@ class PostgreSqlPlatform extends AbstractPlatform * * @override */ - public function getListTableConstraintsSql() + public function getListTableConstraintsSql($table) { return "SELECT relname @@ -588,7 +588,7 @@ class PostgreSqlPlatform extends AbstractPlatform WHERE oid IN ( SELECT indexrelid FROM pg_index, pg_class - WHERE pg_class.relname = %s + WHERE pg_class.relname = '$table' AND pg_class.oid = pg_index.indrelid AND (indisunique = 't' OR indisprimary = 't') )"; @@ -620,7 +620,7 @@ class PostgreSqlPlatform extends AbstractPlatform * * @override */ - public function getListTableColumnsSql() + public function getListTableColumnsSql($table) { return "SELECT a.attnum, @@ -640,7 +640,7 @@ class PostgreSqlPlatform extends AbstractPlatform AND pg_attrdef.adnum=a.attnum ) AS default FROM pg_attribute a, pg_class c, pg_type t - WHERE c.relname = %s + WHERE c.relname = '$table' AND a.attnum > 0 AND a.attrelid = c.oid AND a.atttypid = t.oid @@ -961,4 +961,14 @@ class PostgreSqlPlatform extends AbstractPlatform return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)') : ($length ? 'VARCHAR(' . $length . ')' : 'TEXT'); } + + /** + * Get the platform name for this instance + * + * @return string + */ + public function getName() + { + return 'postgresql'; + } } \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php b/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php index 09f0efe4b..cdb21672c 100644 --- a/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php +++ b/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php @@ -173,220 +173,7 @@ class SqlitePlatform extends AbstractPlatform } return 'SUBSTR(' . $value . ', ' . $position . ', LENGTH(' . $value . '))'; } - - /** - * 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 Doctrine datatype and length - * - * @param array $field native field description - * @return array containing the various possible types, length, sign, fixed - * @override - */ - public function getPortableDeclaration(array $field) - { - /*$dbType = strtolower($field['type']); - $length = (isset($field['length'])) ? $field['length'] : null; - $unsigned = (isset($field['unsigned'])) ? $field['unsigned'] : null; - $fixed = null; - $type = array(); - - if ( ! isset($field['name'])) { - $field['name'] = ''; - } - - switch ($dbType) { - case 'boolean': - $type[] = 'boolean'; - break; - case 'tinyint': - $type[] = 'integer'; - $type[] = 'boolean'; - if (preg_match('/^(is|has)/', $field['name'])) { - $type = array_reverse($type); - } - $unsigned = preg_match('/ unsigned/i', $field['type']); - $length = 1; - break; - case 'smallint': - $type[] = 'integer'; - $unsigned = preg_match('/ unsigned/i', $field['type']); - $length = 2; - break; - case 'mediumint': - $type[] = 'integer'; - $unsigned = preg_match('/ unsigned/i', $field['type']); - $length = 3; - break; - case 'int': - case 'integer': - case 'serial': - $type[] = 'integer'; - $unsigned = preg_match('/ unsigned/i', $field['type']); - $length = 4; - break; - case 'bigint': - case 'bigserial': - $type[] = 'integer'; - $unsigned = preg_match('/ unsigned/i', $field['type']); - $length = 8; - break; - case 'clob': - case 'tinytext': - case 'mediumtext': - case 'longtext': - case 'text': - case 'varchar': - case 'varchar2': - $fixed = false; - case 'char': - $type[] = 'text'; - if ($length == '1') { - $type[] = 'boolean'; - if (preg_match('/^(is|has)/', $field['name'])) { - $type = array_reverse($type); - } - } elseif (strstr($dbType, 'text')) { - $type[] = 'clob'; - } - if ($fixed !== false) { - $fixed = true; - } - break; - case 'date': - $type[] = 'date'; - $length = null; - break; - case 'datetime': - case 'timestamp': - $type[] = 'timestamp'; - $length = null; - break; - case 'time': - $type[] = 'time'; - $length = null; - break; - case 'float': - case 'double': - case 'real': - $type[] = 'float'; - $length = null; - break; - case 'decimal': - case 'numeric': - $type[] = 'decimal'; - $length = null; - break; - case 'tinyblob': - case 'mediumblob': - case 'longblob': - case 'blob': - $type[] = 'blob'; - $length = null; - break; - case 'year': - $type[] = 'integer'; - $type[] = 'date'; - $length = null; - break; - default: - throw DoctrineException::updateMe('unknown database attribute type: '.$dbType); - } - - return array('type' => $type, - 'length' => $length, - 'unsigned' => $unsigned, - 'fixed' => $fixed);*/ - } - /** * Enter description here... * @@ -419,7 +206,8 @@ class SqlitePlatform extends AbstractPlatform } /** @override */ - public function prefersIdentityColumns() { + public function prefersIdentityColumns() + { return true; } @@ -558,6 +346,43 @@ class SqlitePlatform extends AbstractPlatform : ($length ? 'VARCHAR(' . $length . ')' : 'TEXT'); } + public function getListSequencesSql() + { + return "SELECT name FROM sqlite_master WHERE type='table' AND sql NOT NULL ORDER BY name"; + } + + public function getListTableConstraintsSql($table) + { + return "SELECT sql FROM sqlite_master WHERE type='index' AND tbl_name = $table AND sql NOT NULL ORDER BY name"; + } + + public function getListTableColumnsSql($table) + { + return "PRAGMA table_info($table)"; + } + + public function getListTableIndexesSql($table) + { + return "PRAGMA index_list($table)"; + } + + public function getListTablesSql() + { + return "SELECT name FROM sqlite_master WHERE type = 'table' AND name != 'sqlite_sequence' " + . "UNION ALL SELECT name FROM sqlite_temp_master " + . "WHERE type = 'table' ORDER BY name"; + } + + public function getListTableViews() + { + return "SELECT name, sql FROM sqlite_master WHERE type='view' AND sql NOT NULL"; + } + + public function getListViewsSql() + { + return "SELECT name, sql FROM sqlite_master WHERE type='view' AND sql NOT NULL"; + } + /** * SQLite does support foreign key constraints, but only in CREATE TABLE statements... * This really limits their usefulness and requires SQLite specific handling, so @@ -570,4 +395,14 @@ class SqlitePlatform extends AbstractPlatform { return false; } + + /** + * Get the platform name for this instance + * + * @return string + */ + public function getName() + { + return 'sqlite'; + } } \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php b/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php index 760c7dd40..41aa5c904 100644 --- a/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php +++ b/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php @@ -29,235 +29,282 @@ namespace Doctrine\DBAL\Schema; * @author Konsta Vesterinen * @author Lukas Smith (PEAR MDB2 library) * @author Roman Borschel + * @author Jonathan H. Wage * @version $Revision$ * @since 2.0 */ abstract class AbstractSchemaManager { + /** + * Holds instance of the Doctrine connection for this schema manager + * + * @var object \Doctrine\DBAL\Connection + */ protected $_conn; + /** + * Holds instance of the database platform used for this schema manager + * + * @var string + */ + protected $_platform; + + /** + * Constructor. Accepts the Connection instance to manage the schema for + * + * @param \Doctrine\DBAL\Connection $conn + */ public function __construct(\Doctrine\DBAL\Connection $conn) { $this->_conn = $conn; + $this->_platform = $this->_conn->getDatabasePlatform(); } /** - * lists all databases + * List the available databases for this connection * - * @return array + * @return array $databases */ public function listDatabases() { - return $this->_conn->fetchColumn($this->_conn->getDatabasePlatform() - ->getListDatabasesSql()); + $sql = $this->_platform->getListDatabasesSql(); + + $databases = $this->_conn->fetchAll($sql); + + return $this->_getPortableDatabasesList($databases); } /** - * lists all availible database functions + * List the available functions for this connection * - * @return array + * @return array $functions */ public function listFunctions() { - return $this->_conn->fetchColumn($this->_conn->getDatabasePlatform() - ->getListFunctionsSql()); + $sql = $this->_platform->getListFunctionsSql(); + + $functions = $this->_conn->fetchAll($sql); + + return $this->_getPortableFunctionsList($functions); } /** - * Lists all database triggers. + * List the available triggers for this connection * - * @param string|null $database - * @return array + * @return array $triggers */ - public function listTriggers($database = null) + public function listTriggers() { - return $this->_conn->fetchColumn($this->_conn->getDatabasePlatform() - ->getListTriggersSql()); + $sql = $this->_platform->getListTriggersSql(); + + $triggers = $this->_conn->fetchAll($sql); + + return $this->_getPortableTriggersList($triggers); } /** - * lists all database sequences + * List the available sequences for this connection * - * @param string|null $database - * @return array + * @return array $sequences */ - public function listSequences($database = null) + public function listSequences() { - return $this->_conn->fetchColumn($this->_conn->getDatabasePlatform() - ->getListSequencesSql()); + $sql = $this->_platform->getListSequencesSql(); + + $sequences = $this->_conn->fetchAll($sql); + + return $this->_getPortableSequencesList($sequences); } /** - * Lists table constraints. + * List the constraints for a given table * - * @param string $table database table name - * @return array + * @param string $table The name of the table + * @return array $tableConstraints */ public function listTableConstraints($table) { - return $this->_conn->fetchColumn($this->_conn->getDatabasePlatform() - ->getListTableConstraintsSql()); + $sql = $this->_platform->getListTableConstraintsSql($table); + + $tableContraints = $this->_conn->fetchAll($sql); + + return $this->_getPortableTableConstraintsList($tableConstraints); } /** - * Lists table columns. + * List the columns for a given table * - * @param string $table database table name - * @return array + * @param string $table The name of the table + * @return array $tableColumns */ public function listTableColumns($table) { - return $this->_conn->fetchColumn($this->_conn->getDatabasePlatform() - ->getListTableColumnsSql()); + $sql = $this->_platform->getListTableColumnsSql($table); + + $tableColumns = $this->_conn->fetchAll($sql); + + return $this->_getPortableTableColumnList($tableColumns); } /** - * Lists table indexes. + * List the indexes for a given table * - * @param string $table database table name - * @return array + * @param string $table The name of the table + * @return array $tableIndexes */ public function listTableIndexes($table) { - return $this->_conn->fetchColumn($this->_conn->getDatabasePlatform() - ->getListTableIndexesSql()); + $sql = $this->_platform->getListTableIndexesSql($table); + + $tableIndexes = $this->_conn->fetchAll($sql); + + return $this->_getPortableTableIndexesList($tableIndexes); } /** - * Lists tables. + * List the tables for this connection * - * @param string|null $database - * @return array + * @return array $tables */ - public function listTables($database = null) + public function listTables() { - return $this->_conn->fetchColumn($this->_conn->getDatabasePlatform() - ->getListTablesSql()); + $sql = $this->_platform->getListTablesSql(); + + $tables = $this->_conn->fetchAll($sql); + + return $this->_getPortableTablesList($tables); } /** - * Lists database users. + * List the users this connection has * - * @return array + * @return array $users */ public function listUsers() { - return $this->_conn->fetchColumn($this->_conn->getDatabasePlatform() - ->getListUsersSql()); + $sql = $this->_platform->getListUsersSql(); + + $users = $this->_conn->fetchAll($sql); + + return $this->_getPortableUsersList($users); } /** - * Lists database views. + * List the views this connection has * - * @param string|null $database - * @return array + * @return array $views */ - public function listViews($database = null) + public function listViews() { - return $this->_conn->fetchColumn($this->_conn->getDatabasePlatform() - ->getListViewsSql()); + $sql = $this->_platform->getListViewsSql(); + + $views = $this->_conn->fetchAll($sql); + + return $this->_getPortableViewsList($views); } /** - * drop an existing database - * (this method is implemented by the drivers) + * Drop the database for this connection * - * @param string $name name of the database that should be dropped - * @return void + * @return boolean $result */ - public function dropDatabase($database) + public function dropDatabase() { - $this->_conn->execute($this->_conn->getDatabasePlatform() - ->getDropDatabaseSql($database)); + $sql = $this->_platform->getDropDatabaseSql(); + + return $this->_executeSql($sql, 'execute'); } /** - * drop an existing table + * Drop the given table * - * @param string $table name of table that should be dropped from the database - * @return void + * @param string $table The name of the table to drop + * @return boolean $result */ public function dropTable($table) { - $this->_conn->execute($this->_conn->getDatabasePlatform() - ->getDropTableSql($table)); + $sql = $this->_platform->getDropTableSql($table); + + return $this->_executeSql($sql, 'execute'); } /** - * drop existing index + * Drop the index from the given table * - * @param string $table name of table that should be used in method - * @param string $name name of the index to be dropped - * @return void + * @param string $table The name of the table + * @param string $name The name of the index + * @return boolean $result */ public function dropIndex($table, $name) { - return $this->_conn->exec($this->_conn->getDatabasePlatform() - ->getDropIndexSql($table, $name)); + $sql = $this->_platform->getDropIndexSql($table, $name); + + return $this->_executeSql($sql, 'exec'); } /** - * drop existing constraint + * Drop the constraint from the given table * - * @param string $table name of table that should be used in method - * @param string $name name of the constraint to be dropped - * @param string $primary hint if the constraint is primary - * @return void + * @param string $table The name of the table + * @param string $name The name of the constraint + * @param string $primary Whether or not it is a primary constraint + * @return boolean $result */ public function dropConstraint($table, $name, $primary = false) { - $table = $this->_conn->getDatabasePlatform()->quoteIdentifier($table); - $name = $this->_conn->getDatabasePlatform()->quoteIdentifier($name); - - return $this->_conn->exec('ALTER TABLE ' . $table . ' DROP CONSTRAINT ' . $name); + $sql = $this->_platform->getDropConstraintSql($table, $name, $primary); + + return $this->_executeSql($sql, 'exec'); } /** - * drop existing foreign key + * Drop the foreign key from the given table * - * @param string $table name of table that should be used in method - * @param string $name name of the foreign key to be dropped - * @return void + * @param string $table The name of the table + * @param string $name The name of the foreign key + * @return boolean $result */ public function dropForeignKey($table, $name) { - return $this->dropConstraint($table, $name); + $sql = $this->_platform->getDropForeignKeySql($table, $name); + + return $this->_executeSql($sql, 'exec'); } /** - * drop existing sequence - * (this method is implemented by the drivers) + * Drop the given sequence * - * @throws Doctrine\DBAL\ConnectionException if something fails at database level - * @param string $sequenceName name of the sequence to be dropped - * @return void + * @param string $name The name of the sequence + * @return boolean $result */ - public function dropSequence($sequenceName) + public function dropSequence($name) { - $this->_conn->exec($this->_conn->getDatabasePlatform()->getDropSequenceSql($sequenceName)); + $sql = $this->_platform->getDropSequenceSql($name); + + return $this->_executeSql($sql, 'exec'); } /** - * create a new database - * (this method is implemented by the drivers) + * Create the given database on the connection * - * @param string $name name of the database that should be created - * @return void + * @param string $database The name of the database + * @return boolean $result */ public function createDatabase($database) { - $this->_conn->execute($this->_conn->getDatabasePlatform()->getCreateDatabaseSql($database)); + $sql = $this->_platform->getCreateDatabaseSql($database); + + return $this->_executeSql($sql, 'exec'); } /** - * create a new table + * Create a new database 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 * @param array $options An associative array of table options: - * @see Doctrine_Export::createTableSql() * - * @return void + * @return boolean $result */ public function createTable($name, array $columns, array $options = array()) { @@ -274,18 +321,14 @@ abstract class AbstractSchemaManager } } - $sql = (array) $this->_conn->getDatabasePlatform()->getCreateTableSql( - $name, $columns, $options); + $sql = $this->_platform->getCreateTableSql($name, $columns, $options); - foreach ($sql as $query) { - $this->_conn->execute($query); - } + return $this->_executeSql($sql, 'exec'); } /** - * create sequence + * Create a new sequence * - * @throws Doctrine\DBAL\ConnectionException if something fails at database level * @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: @@ -294,16 +337,18 @@ abstract class AbstractSchemaManager * 'charset' => 'utf8', * 'collate' => 'utf8_unicode_ci', * ); - * @return void + * @return boolean $result + * @throws Doctrine\DBAL\ConnectionException if something fails at database level */ public function createSequence($seqName, $start = 1, array $options = array()) { - return $this->_conn->execute($this->_conn->getDatabasePlatform() - ->getCreateSequenceSql($seqName, $start, $options)); + $sql = $this->_platform->getCreateSequenceSql($seqName, $start, $options); + + return $this->_executeSql($sql, 'exec'); } /** - * create a constraint on a table + * 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 @@ -321,16 +366,17 @@ abstract class AbstractSchemaManager * 'last_login' => array() * ) * ) - * @return void + * @return boolean $result */ public function createConstraint($table, $name, $definition) { - $sql = $this->_conn->getDatabasePlatform()->getCreateConstraintSql($table, $name, $definition); - return $this->_conn->exec($sql); + $sql = $this->_platform->getCreateConstraintSql($table, $name, $definition); + + return $this->_executeSql($sql, 'exec'); } /** - * Get the stucture of a field into an array + * Create a new index on a table * * @param string $table name of the table on which the index is to be created * @param string $name name of the index to be created @@ -358,12 +404,13 @@ abstract class AbstractSchemaManager * 'last_login' => array() * ) * ) - * @return void + * @return boolean $result */ public function createIndex($table, $name, array $definition) { - return $this->_conn->execute($this->_conn->getDatabasePlatform() - ->getCreateIndexSql($table, $name, $definition)); + $sql = $this->_platform->getCreateIndexSql($table, $name, $definition); + + return $this->_executeSql($sql, 'exec'); } /** @@ -371,17 +418,17 @@ abstract class AbstractSchemaManager * * @param string $table name of the table on which the foreign key is to be created * @param array $definition associative array that defines properties of the foreign key to be created. - * @return string + * @return boolean $result */ public function createForeignKey($table, array $definition) { - $sql = $this->_conn->getDatabasePlatform()->getCreateForeignKeySql($table, $definition); - return $this->_conn->execute($sql); + $sql = $this->_platform->getCreateForeignKeySql($table, $definition); + + return $this->_executeSql($sql, 'exec'); } /** - * alter an existing table - * (this method is implemented by the drivers) + * Alter an existing tables schema * * @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 @@ -466,14 +513,71 @@ abstract class AbstractSchemaManager * @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 + * @return boolean $result */ public function alterTable($name, array $changes, $check = false) { - $sql = $this->_conn->getDatabasePlatform()->getAlterTableSql($name, $changes, $check); - - if (is_string($sql) && $sql) { - $this->_conn->execute($sql); + $sql = $this->_platform->getAlterTableSql($name, $changes, $check); + + return $this->_executeSql($sql, 'exec'); + } + + protected function _getPortableDatabasesList($databases) + { + return $databases; + } + + protected function _getPortableFunctionsList($functions) + { + return $functions; + } + + protected function _getPortableTriggersList($triggers) + { + return $triggers; + } + + protected function _getPortableSequencesList($sequences) + { + return $sequences; + } + + protected function _getPortableTableConstraintsList($tableConstraints) + { + return $tableConstraints; + } + + protected function _getPortableTableColumnList($tableColumns) + { + return $tableColumns; + } + + protected function _getPortableTableIndexesList($tableIndexes) + { + return $tableIndexes; + } + + protected function _getPortableTablesList($tables) + { + return $tables; + } + + protected function _getPortableUsersList($users) + { + return $users; + } + + protected function _getPortableViewsList($views) + { + return $views; + } + + protected function _executeSql($sql, $method = 'exec') + { + $result = true; + foreach ((array) $sql as $query) { + $result = $this->_conn->$method($query); } + return $result; } } \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php b/lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php index 6e734bf05..08c854753 100644 --- a/lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php +++ b/lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php @@ -32,129 +32,6 @@ namespace Doctrine\DBAL\Schema; */ class PostgreSqlSchemaManager extends AbstractSchemaManager { - /** - * 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. - * @throws Doctrine\DBAL\ConnectionException - * @return boolean - */ - public function alterTable($name, array $changes, $check = false) - { - $sql = $this->alterTableSql($name, $changes, $check); - foreach ($sql as $query) { - $this->_conn->exec($query); - } - return true; - } - - /** - * lists all database triggers - * - * @param string|null $database - * @return array - */ - public function listTriggers($database = null) - { - - } - - /** - * lists table constraints - * - * @param string $table database table name - * @return array - */ - public function listTableConstraints($table) - { - $table = $this->conn->quote($table); - $query = sprintf($this->sql['listTableConstraints'], $table); - - return $this->conn->fetchColumn($query); - } - /** * lists table constraints * diff --git a/lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php b/lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php index f0e952d61..186ee772c 100644 --- a/lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php +++ b/lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php @@ -22,569 +22,15 @@ namespace Doctrine\DBAL\Schema; /** - * xxx + * SqliteSchemaManager * * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @author Konsta Vesterinen * @author Lukas Smith (PEAR MDB2 library) + * @author Jonathan H. Wage * @version $Revision$ * @since 2.0 */ class SqliteSchemaManager extends AbstractSchemaManager -{ - /** - * lists all databases - * - * @return array - */ - public function listDatabases() - { - - } - - /** - * lists all available database functions - * - * @return array - */ - public function listFunctions() - { - - } - - /** - * lists all database triggers - * - * @param string|null $database - * @return array - */ - public function listTriggers($database = null) - { - return $this->listTableTriggers(null); - } - - /** - * lists all database sequences - * - * @param string|null $database - * @return array - */ - public function listSequences($database = null) - { - $query = "SELECT name FROM sqlite_master WHERE type='table' AND sql NOT NULL ORDER BY name"; - $tableNames = $this->_conn->fetchColumn($query); - - $result = array(); - foreach ($tableNames as $tableName) { - if ($sqn = $this->_conn->fixSequenceName($tableName, true)) { - $result[] = $sqn; - } - } - if ($this->_conn->getAttribute(Doctrine::ATTR_PORTABILITY) & Doctrine::PORTABILITY_FIX_CASE) { - $result = array_map(($this->_conn->getAttribute(Doctrine::ATTR_FIELD_CASE) == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result); - } - return $result; - } - - /** - * lists table constraints - * - * @param string $table database table name - * @return array - */ - public function listTableConstraints($table) - { - $table = $this->_conn->quote($table, 'text'); - - $query = "SELECT sql FROM sqlite_master WHERE type='index' AND "; - - if ($this->_conn->getAttribute(Doctrine::ATTR_PORTABILITY) & Doctrine::PORTABILITY_FIX_CASE) { - $query .= 'LOWER(tbl_name) = ' . strtolower($table); - } else { - $query .= 'tbl_name = ' . $table; - } - $query .= ' AND sql NOT NULL ORDER BY name'; - $indexes = $this->_conn->fetchColumn($query); - - $result = array(); - foreach ($indexes as $sql) { - if (preg_match("/^create unique index ([^ ]+) on /i", $sql, $tmp)) { - $index = $this->_conn->formatter->fixIndexName($tmp[1]); - if ( ! empty($index)) { - $result[$index] = true; - } - } - } - - if ($this->_conn->getAttribute(Doctrine::ATTR_PORTABILITY) & Doctrine::PORTABILITY_FIX_CASE) { - $result = array_change_key_case($result, $this->_conn->getAttribute(Doctrine::ATTR_FIELD_CASE)); - } - return array_keys($result); - } - - /** - * lists table constraints - * - * @param string $table database table name - * @return array - */ - public function listTableColumns($table) - { - $sql = 'PRAGMA table_info(' . $table . ')'; - $result = $this->_conn->fetchAll($sql); - - $description = array(); - $columns = array(); - foreach ($result as $key => $val) { - $val = array_change_key_case($val, CASE_LOWER); - $decl = $this->_conn->dataDict->getPortableDeclaration($val); - - $description = array( - 'name' => $val['name'], - 'ntype' => $val['type'], - 'type' => $decl['type'][0], - 'alltypes' => $decl['type'], - 'notnull' => (bool) $val['notnull'], - 'default' => $val['dflt_value'], - 'primary' => (bool) $val['pk'], - 'length' => null, - 'scale' => null, - 'precision' => null, - 'unsigned' => null, - ); - $columns[$val['name']] = $description; - } - return $columns; - } - - /** - * lists table constraints - * - * @param string $table database table name - * @return array - */ - public function listTableIndexes($table) - { - $sql = 'PRAGMA index_list(' . $table . ')'; - return $this->_conn->fetchColumn($sql); - } - /** - * lists tables - * - * @param string|null $database - * @return array - */ - public function listTables($database = null) - { - $sql = "SELECT name FROM sqlite_master WHERE type = 'table' " - . "UNION ALL SELECT name FROM sqlite_temp_master " - . "WHERE type = 'table' ORDER BY name"; - - return $this->_conn->fetchColumn($sql); - } - - /** - * lists table triggers - * - * @param string $table database table name - * @return array - */ - public function listTableTriggers($table) - { - $query = "SELECT name FROM sqlite_master WHERE type='trigger' AND sql NOT NULL"; - if (!is_null($table)) { - if ($this->_conn->getAttribute(Doctrine::ATTR_PORTABILITY) & Doctrine::PORTABILITY_FIX_CASE) { - if ($this->_conn->getAttribute(Doctrine::ATTR_FIELD_CASE) == CASE_LOWER) { - $query.= ' AND LOWER(tbl_name)='.$db->quote(strtolower($table), 'text'); - } else { - $query.= ' AND UPPER(tbl_name)='.$db->quote(strtoupper($table), 'text'); - } - } else { - $query.= ' AND tbl_name='.$db->quote($table, 'text'); - } - } - $result = $this->_conn->fetchColumn($query); - - if ($this->_conn->getAttribute(Doctrine::ATTR_PORTABILITY) & Doctrine::PORTABILITY_FIX_CASE) { - $result = array_map(($this->_conn->getAttribute(Doctrine::ATTR_FIELD_CASE) == CASE_LOWER ? 'strtolower' : 'strtoupper'), $result); - } - return $result; - } - - /** - * lists table views - * - * @param string $table database table name - * @return array - */ - public function listTableViews($table) - { - $query = "SELECT name, sql FROM sqlite_master WHERE type='view' AND sql NOT NULL"; - $views = $db->fetchAll($query); - - $result = array(); - foreach ($views as $row) { - if (preg_match("/^create view .* \bfrom\b\s+\b{$table}\b /i", $row['sql'])) { - if ( ! empty($row['name'])) { - $result[$row['name']] = true; - } - } - } - return $result; - } - - /** - * lists database users - * - * @return array - */ - public function listUsers() - { - - } - - /** - * lists database views - * - * @param string|null $database - * @return array - */ - public function listViews($database = null) - { - $query = "SELECT name FROM sqlite_master WHERE type='view' AND sql NOT NULL"; - - return $this->_conn->fetchColumn($query); - } - - /** - * Drops an existing database - * - * @param string $databaseFile Path of the database that should be dropped - * @throws Doctrine_Export_Exception if the database file does not exist - * @throws Doctrine_Export_Exception if something failed during the removal of the database file - * @return void - */ - public function dropDatabase($databaseFile) - { - if ( ! @file_exists($databaseFile)) { - throw \Doctrine\Common\DoctrineException::updateMe('database does not exist'); - } - - $result = @unlink($databaseFile); - - if ( ! $result) { - throw \Doctrine\Common\DoctrineException::updateMe('could not remove the database file'); - } - } - - /** - * createDatabase - * - * Create sqlite database file - * - * @param string $databaseFile Path of the database that should be dropped - * @return void - */ - public function createDatabase($databaseFile) - { - return new PDO('sqlite:' . $databaseFile); - } - - /** - * Get the stucture of a field into an array - * - * @param string $table name of the table on which the index is to be created - * @param string $name name of the index to be created - * @param array $definition associative array that defines properties of the index to be created. - * Currently, only one property named FIELDS is supported. This property - * is also an associative with the names of the index fields as array - * indexes. Each entry of this array is set to another type of associative - * array that specifies properties of the index that are specific to - * each field. - * - * Currently, only the sorting property is supported. It should be used - * to define the sorting direction of the index. It may be set to either - * ascending or descending. - * - * Not all DBMS support index sorting direction configuration. The DBMS - * drivers of those that do not support it ignore this property. Use the - * function support() to determine whether the DBMS driver can manage indexes. - - * Example - * array( - * 'fields' => array( - * 'user_name' => array( - * 'sorting' => 'ascending' - * ), - * 'last_login' => array() - * ) - * ) - * @throws PDOException - * @return void - */ - public function createIndexSql($table, $name, array $definition) - { - $name = $this->_conn->formatter->getIndexName($name); - $name = $this->_conn->quoteIdentifier($name); - $query = 'CREATE INDEX ' . $name . ' ON ' . $table; - $query .= ' (' . $this->getIndexFieldDeclarationList($definition['fields']) . ')'; - - return $query; - } - - /** - * getIndexFieldDeclarationList - * Obtain DBMS specific SQL code portion needed to set an index - * declaration to be used in statements like CREATE TABLE. - * - * @return string - */ - public function getIndexFieldDeclarationList(array $fields) - { - $declFields = array(); - - foreach ($fields as $fieldName => $field) { - $fieldString = $this->_conn->quoteIdentifier($fieldName); - - if (is_array($field)) { - if (isset($field['sorting'])) { - $sort = strtoupper($field['sorting']); - switch ($sort) { - case 'ASC': - case 'DESC': - $fieldString .= ' ' . $sort; - break; - default: - throw \Doctrine\Common\DoctrineException::updateMe('Unknown index sorting option given.'); - } - } - } else { - $fieldString = $this->_conn->quoteIdentifier($field); - } - $declFields[] = $fieldString; - } - return implode(', ', $declFields); - } - - /** - * getAdvancedForeignKeyOptions - * Return the FOREIGN KEY query section dealing with non-standard options - * as MATCH, INITIALLY DEFERRED, ON UPDATE, ... - * - * @param array $definition foreign key definition - * @return string - * @access protected - */ - public function getAdvancedForeignKeyOptions(array $definition) - { - $query = ''; - if (isset($definition['match'])) { - $query .= ' MATCH ' . $definition['match']; - } - if (isset($definition['onUpdate'])) { - $query .= ' ON UPDATE ' . $definition['onUpdate']; - } - if (isset($definition['onDelete'])) { - $query .= ' ON DELETE ' . $definition['onDelete']; - } - if (isset($definition['deferrable'])) { - $query .= ' DEFERRABLE'; - } else { - $query .= ' NOT DEFERRABLE'; - } - if (isset($definition['feferred'])) { - $query .= ' INITIALLY DEFERRED'; - } else { - $query .= ' INITIALLY IMMEDIATE'; - } - return $query; - } - - /** - * 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->quoteIdentifier($this->_conn->getSequenceName($seqName), true); - $seqcolName = $this->_conn->quoteIdentifier($this->_conn->getAttribute(Doctrine::ATTR_SEQCOL_NAME), true); - $query = 'CREATE TABLE ' . $sequenceName . ' (' . $seqcolName . ' INTEGER PRIMARY KEY DEFAULT 0 NOT NULL)'; - - $this->_conn->exec($query); - - if ($start == 1) { - return true; - } - - try { - $this->_conn->exec('INSERT INTO ' . $sequenceName . ' (' . $seqcolName . ') VALUES (' . ($start-1) . ')'); - return true; - } catch(Doctrine\DBAL\ConnectionException $e) { - // Handle error - - try { - $result = $db->exec('DROP TABLE ' . $sequenceName); - } 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'); - } - - /** - * drop existing sequence - * - * @param string $sequenceName name of the sequence to be dropped - * @return string - */ - public function dropSequenceSql($sequenceName) - { - $sequenceName = $this->_conn->quoteIdentifier($this->_conn->getSequenceName($sequenceName), true); - - return 'DROP TABLE ' . $sequenceName; - } - - 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; - } - - /** - * Obtain DBMS specific SQL code portion needed to declare an integer type - * field to be used in statements like CREATE TABLE. - * - * @param string $name name the field to be declared. - * @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: - * - * unsigned - * Boolean flag that indicates whether the field - * should be declared as unsigned integer if - * possible. - * - * default - * Integer 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. - * @access protected - */ - public function getIntegerDeclaration($name, array $field) - { - $default = $autoinc = ''; - $type = $this->_conn->dataDict->getNativeDeclaration($field); - - $autoincrement = isset($field['autoincrement']) && $field['autoincrement']; - - if ($autoincrement) { - $autoinc = ' PRIMARY KEY AUTOINCREMENT'; - $type = 'INTEGER'; - } elseif (array_key_exists('default', $field)) { - if ($field['default'] === '') { - $field['default'] = empty($field['notnull']) ? null : 0; - } - $default = ' DEFAULT ' . $this->_conn->quote($field['default'], $field['type']); - } elseif (empty($field['notnull'])) { - $default = ' DEFAULT NULL'; - } - - $notnull = (isset($field['notnull']) && $field['notnull']) ? ' NOT NULL' : ''; - - // sqlite does not support unsigned attribute for autoinremented fields - $unsigned = (isset($field['unsigned']) && $field['unsigned'] && !$autoincrement) ? ' UNSIGNED' : ''; - - $name = $this->_conn->quoteIdentifier($name, true); - return $name . ' ' . $type . $unsigned . $default . $notnull . $autoinc; - } +{ } \ No newline at end of file diff --git a/tests/Doctrine/Tests/DBAL/AllTests.php b/tests/Doctrine/Tests/DBAL/AllTests.php index 6f0beb318..66a335791 100644 --- a/tests/Doctrine/Tests/DBAL/AllTests.php +++ b/tests/Doctrine/Tests/DBAL/AllTests.php @@ -4,6 +4,7 @@ namespace Doctrine\Tests\DBAL; use Doctrine\Tests\DBAL\Component; use Doctrine\Tests\DBAL\Ticker; +use Doctrine\Tests\DBAL\Functional; if (!defined('PHPUnit_MAIN_METHOD')) { define('PHPUnit_MAIN_METHOD', 'Dbal_Platforms_AllTests::main'); @@ -27,6 +28,8 @@ class AllTests $suite->addTestSuite('Doctrine\Tests\DBAL\Platforms\PostgreSqlPlatformTest'); $suite->addTestSuite('Doctrine\Tests\DBAL\Platforms\MsSqlPlatformTest'); + $suite->addTest(Functional\AllTests::suite()); + return $suite; } } diff --git a/tests/Doctrine/Tests/DBAL/Functional/AllTests.php b/tests/Doctrine/Tests/DBAL/Functional/AllTests.php new file mode 100644 index 000000000..8f5ee0699 --- /dev/null +++ b/tests/Doctrine/Tests/DBAL/Functional/AllTests.php @@ -0,0 +1,32 @@ +addTestSuite('Doctrine\Tests\DBAL\Functional\Schemas\SqliteSchemaTest'); + + return $suite; + } +} + +if (PHPUnit_MAIN_METHOD == 'Dbal_Functional_AllTests::main') { + AllTests::main(); +} \ No newline at end of file diff --git a/tests/Doctrine/Tests/DBAL/Functional/Schemas/SqliteSchemaTest.php b/tests/Doctrine/Tests/DBAL/Functional/Schemas/SqliteSchemaTest.php new file mode 100644 index 000000000..6a9858e33 --- /dev/null +++ b/tests/Doctrine/Tests/DBAL/Functional/Schemas/SqliteSchemaTest.php @@ -0,0 +1,47 @@ +_conn = TestUtil::getConnection(); + if ($this->_conn->getDatabasePlatform()->getName() !== 'sqlite') + { + $this->markTestSkipped('The SqliteSchemaTest requires the use of the pdo_sqlite'); + } + $this->_sm = new Schema\SqliteSchemaManager($this->_conn); + } + + public function testListTableColumns() + { + $columns = array( + 'id' => array( + 'type' => new \Doctrine\DBAL\Types\IntegerType, + 'autoincrement' => true, + 'primary' => true, + 'notnull' => true + ), + 'test' => array( + 'type' => new \Doctrine\DBAL\Types\StringType, + 'length' => 255 + ) + ); + + $options = array(); + + $this->_sm->createTable('list_tables_test', $columns, $options); + + $columns = $this->_sm->listTableColumns('list_tables_test'); + $this->assertEquals($columns[0]['name'], 'id'); + $this->assertEquals($columns[1]['name'], 'test'); + } +} \ No newline at end of file diff --git a/tests/Doctrine/Tests/DbalFunctionalTestSuite.php b/tests/Doctrine/Tests/DbalFunctionalTestSuite.php new file mode 100644 index 000000000..a03c350be --- /dev/null +++ b/tests/Doctrine/Tests/DbalFunctionalTestSuite.php @@ -0,0 +1,7 @@ +_prefersIdentityColumns = $bool; @@ -71,4 +71,9 @@ class DatabasePlatformMock extends \Doctrine\DBAL\Platforms\AbstractPlatform { $this->_sequenceNextValSql = $sql; } + + public function getName() + { + return 'mock'; + } } \ No newline at end of file diff --git a/tests/Doctrine/Tests/Mocks/DriverMock.php b/tests/Doctrine/Tests/Mocks/DriverMock.php index 379b77b39..9315f3365 100644 --- a/tests/Doctrine/Tests/Mocks/DriverMock.php +++ b/tests/Doctrine/Tests/Mocks/DriverMock.php @@ -48,4 +48,9 @@ class DriverMock implements \Doctrine\DBAL\Driver { $this->_platformMock = $platform; } + + public function getName() + { + return 'mock'; + } } \ No newline at end of file