From 16c4efccd8d6a07bf0660ddaa36a9c841d73e14c Mon Sep 17 00:00:00 2001 From: romanb Date: Sun, 3 May 2009 18:07:57 +0000 Subject: [PATCH] [2.0] DBAL streamlining and starting to increase test coverage. --- .../DBAL/Platforms/AbstractPlatform.php | 270 ++++++------------ lib/Doctrine/DBAL/Platforms/MySqlPlatform.php | 81 ++---- .../DBAL/Platforms/PostgreSqlPlatform.php | 164 +++-------- .../DBAL/Platforms/SqlitePlatform.php | 25 +- lib/Doctrine/DBAL/Types/VarcharType.php | 2 +- lib/Doctrine/ORM/Configuration.php | 20 +- lib/Doctrine/ORM/PersistentCollection.php | 6 +- lib/Doctrine/ORM/Query/SqlWalker.php | 6 + tests/Doctrine/Tests/DBAL/AllTests.php | 2 + .../DBAL/Platforms/MySqlPlatformTest.php | 170 +++++++++++ .../DBAL/Platforms/PostgreSqlPlatformTest.php | 168 +++++++++++ .../DBAL/Platforms/SqlitePlatformTest.php | 63 +++- .../Tests/Mocks/DatabasePlatformMock.php | 2 +- .../Functional/SingleTableInheritanceTest.php | 2 - 14 files changed, 584 insertions(+), 397 deletions(-) create mode 100644 tests/Doctrine/Tests/DBAL/Platforms/MySqlPlatformTest.php create mode 100644 tests/Doctrine/Tests/DBAL/Platforms/PostgreSqlPlatformTest.php diff --git a/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php b/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php index 2346f1b56..929e5c8d6 100644 --- a/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php @@ -65,9 +65,9 @@ abstract class AbstractPlatform } /** - * Gets whether to quote identifiers. + * Gets whether the platform instance currently quotes identifiers in generated SQL. * - * @return boolean + * @return boolean TRUE */ public function getQuoteIdentifiers() { @@ -95,7 +95,7 @@ abstract class AbstractPlatform } /** - * Gets the string portion that starts an SQL comment. + * Gets the string portion that ends an SQL comment. * * @return string */ @@ -142,7 +142,7 @@ abstract class AbstractPlatform */ public function getAvgExpression($column) { - $column = $this->getIdentifier($column); + $column = $this->quoteIdentifier($column); return 'AVG(' . $column . ')'; } @@ -157,7 +157,7 @@ abstract class AbstractPlatform */ public function getCountExpression($column) { - $column = $this->getIdentifier($column); + $column = $this->quoteIdentifier($column); return 'COUNT(' . $column . ')'; } @@ -169,7 +169,7 @@ abstract class AbstractPlatform */ public function getMaxExpression($column) { - $column = $this->getIdentifier($column); + $column = $this->quoteIdentifier($column); return 'MAX(' . $column . ')'; } @@ -181,7 +181,7 @@ abstract class AbstractPlatform */ public function getMinExpression($column) { - $column = $this->getIdentifier($column); + $column = $this->quoteIdentifier($column); return 'MIN(' . $column . ')'; } @@ -193,7 +193,7 @@ abstract class AbstractPlatform */ public function getSumExpression($column) { - $column = $this->getIdentifier($column); + $column = $this->quoteIdentifier($column); return 'SUM(' . $column . ')'; } @@ -208,7 +208,7 @@ abstract class AbstractPlatform */ public function getMd5Expression($column) { - $column = $this->getIdentifier($column); + $column = $this->quoteIdentifier($column); return 'MD5(' . $column . ')'; } @@ -221,7 +221,7 @@ abstract class AbstractPlatform */ public function getLengthExpression($column) { - $column = $this->getIdentifier($column); + $column = $this->quoteIdentifier($column); return 'LENGTH(' . $column . ')'; } @@ -234,7 +234,7 @@ abstract class AbstractPlatform */ public function getRoundExpression($column, $decimals = 0) { - $column = $this->getIdentifier($column); + $column = $this->quoteIdentifier($column); return 'ROUND(' . $column . ', ' . $decimals . ')'; } @@ -249,8 +249,8 @@ abstract class AbstractPlatform */ public function getModExpression($expression1, $expression2) { - $expression1 = $this->getIdentifier($expression1); - $expression2 = $this->getIdentifier($expression2); + $expression1 = $this->quoteIdentifier($expression1); + $expression2 = $this->quoteIdentifier($expression2); return 'MOD(' . $expression1 . ', ' . $expression2 . ')'; } @@ -349,10 +349,10 @@ abstract class AbstractPlatform * @param string $value * @return string SQL soundex function with given parameter */ - public function getSoundexExpression($value) + /*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 @@ -368,11 +368,11 @@ abstract class AbstractPlatform */ public function getSubstringExpression($value, $from, $len = null) { - $value = $this->getIdentifier($value); + $value = $this->quoteIdentifier($value); if ($len === null) return 'SUBSTRING(' . $value . ' FROM ' . $from . ')'; else { - $len = $this->getIdentifier($len); + $len = $this->quoteIdentifier($len); return 'SUBSTRING(' . $value . ' FROM ' . $from . ' FOR ' . $len . ')'; } } @@ -388,9 +388,7 @@ abstract class AbstractPlatform */ public function getConcatExpression() { - $args = func_get_args(); - - return join(' || ' , $args); + return join(' || ' , func_get_args()); } /** @@ -408,8 +406,7 @@ abstract class AbstractPlatform */ public function getNotExpression($expression) { - $expression = $this->getIdentifier($expression); - return 'NOT(' . $expression . ')'; + return 'NOT(' . $this->quoteIdentifier($expression) . ')'; } /** @@ -424,7 +421,7 @@ abstract class AbstractPlatform * @param string|array(string) * @return string an expression */ - private function getBasicMathExpression($type, array $args) + /*private function _getBasicMathExpression($type, array $args) { $elements = $this->getIdentifiers($args); if (count($elements) < 1) { @@ -435,7 +432,7 @@ abstract class AbstractPlatform } else { return '(' . implode(' ' . $type . ' ', $elements) . ')'; } - } + }*/ /** * Returns the SQL to add values or expressions together. @@ -457,10 +454,10 @@ abstract class AbstractPlatform * @param string|array(string) * @return string an expression */ - public function getAddExpression(array $args) + /*public function getAddExpression(array $args) { return $this->basicMath('+', $args); - } + }*/ /** * Returns the SQL to subtract values or expressions from eachother. @@ -482,10 +479,10 @@ abstract class AbstractPlatform * @param string|array(string) * @return string an expression */ - public function getSubExpression(array $args) + /*public function getSubExpression(array $args) { return $this->basicMath('-', $args ); - } + }*/ /** * Returns the SQL to multiply values or expressions by eachother. @@ -507,10 +504,10 @@ abstract class AbstractPlatform * @param string|array(string) * @return string an expression */ - public function getMulExpression(array $args) + /*public function getMulExpression(array $args) { return $this->basicMath('*', $args); - } + }*/ /** * Returns the SQL to divide values or expressions by eachother. @@ -532,10 +529,10 @@ abstract class AbstractPlatform * @param string|array(string) * @return string an expression */ - public function getDivExpression(array $args) + /*public function getDivExpression(array $args) { return $this->basicMath('/', $args); - } + }*/ /** * Returns the SQL to check if two values are equal. @@ -552,12 +549,12 @@ abstract class AbstractPlatform * @param string $value2 logical expression to compare with * @return string logical expression */ - public function getEqExpression($value1, $value2) + /*public function getEqExpression($value1, $value2) { - $value1 = $this->getIdentifier($value1); - $value2 = $this->getIdentifier($value2); + $value1 = $this->quoteIdentifier($value1); + $value2 = $this->quoteIdentifier($value2); return $value1 . ' = ' . $value2; - } + }*/ /** * Returns the SQL to check if two values are unequal. @@ -574,12 +571,12 @@ abstract class AbstractPlatform * @param string $value2 logical expression to compare with * @return string logical expression */ - public function getNeqExpression($value1, $value2) + /*public function getNeqExpression($value1, $value2) { - $value1 = $this->getIdentifier($value1); - $value2 = $this->getIdentifier($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. @@ -596,12 +593,12 @@ abstract class AbstractPlatform * @param string $value2 logical expression to compare with * @return string logical expression */ - public function getGtExpression($value1, $value2) + /*public function getGtExpression($value1, $value2) { - $value1 = $this->getIdentifier($value1); - $value2 = $this->getIdentifier($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 @@ -619,12 +616,12 @@ abstract class AbstractPlatform * @param string $value2 logical expression to compare with * @return string logical expression */ - public function getGteExpression($value1, $value2) + /*public function getGteExpression($value1, $value2) { - $value1 = $this->getIdentifier($value1); - $value2 = $this->getIdentifier($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. @@ -641,12 +638,12 @@ abstract class AbstractPlatform * @param string $value2 logical expression to compare with * @return string logical expression */ - public function getLtExpression($value1, $value2) + /*public function getLtExpression($value1, $value2) { - $value1 = $this->getIdentifier($value1); - $value2 = $this->getIdentifier($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 @@ -664,16 +661,16 @@ abstract class AbstractPlatform * @param string $value2 logical expression to compare with * @return string logical expression */ - public function getLteExpression($value1, $value2) + /*public function getLteExpression($value1, $value2) { - $value1 = $this->getIdentifier($value1); - $value2 = $this->getIdentifier($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.. + * given values. * * in() accepts an arbitrary number of parameters. The first parameter * must always specify the value that should be matched against. Successive @@ -698,7 +695,7 @@ abstract class AbstractPlatform $values = array($values); } $values = $this->getIdentifiers($values); - $column = $this->getIdentifier($column); + $column = $this->quoteIdentifier($column); if (count($values) == 0) { throw DoctrineException::updateMe('Values array for IN operator should not be empty.'); @@ -722,7 +719,7 @@ abstract class AbstractPlatform */ public function getIsNullExpression($expression) { - $expression = $this->getIdentifier($expression); + $expression = $this->quoteIdentifier($expression); return $expression . ' IS NULL'; } @@ -742,7 +739,7 @@ abstract class AbstractPlatform */ public function getIsNotNullExpression($expression) { - $expression = $this->getIdentifier($expression); + $expression = $this->quoteIdentifier($expression); return $expression . ' IS NOT NULL'; } @@ -771,9 +768,9 @@ abstract class AbstractPlatform */ public function getBetweenExpression($expression, $value1, $value2) { - $expression = $this->getIdentifier($expression); - $value1 = $this->getIdentifier($value1); - $value2 = $this->getIdentifier($value2); + $expression = $this->quoteIdentifier($expression); + $value1 = $this->quoteIdentifier($value1); + $value2 = $this->quoteIdentifier($value2); return $expression . ' BETWEEN ' .$value1 . ' AND ' . $value2; } @@ -782,10 +779,10 @@ abstract class AbstractPlatform * * @return string to get global unique identifier */ - public function getGuidExpression() + /*public function getGuidExpression() { throw DoctrineException::updateMe('method not implemented'); - } + }*/ /** * returns arcus cosine SQL string @@ -1002,7 +999,7 @@ abstract class AbstractPlatform throw DoctrineException::updateMe('no fields specified for table ' . $name); } - $queryFields = $this->getFieldDeclarationListSql($columns); + $queryFields = $this->getColumnDeclarationListSql($columns); if (isset($options['primary']) && ! empty($options['primary'])) { $queryFields .= ', PRIMARY KEY(' . implode(', ', array_unique(array_values($options['primary']))) . ')'; @@ -1041,13 +1038,13 @@ abstract class AbstractPlatform * * @todo Throw exception by default? */ - public function getCreateSequenceSql($sequenceName, $start = 1, array $options) + public function getCreateSequenceSql($sequenceName, $start = 1, $allocationSize = 1) { throw DoctrineException::updateMe('Create sequence not supported by this driver.'); } /** - * create a constraint on a table + * Creates 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 @@ -1065,7 +1062,6 @@ abstract class AbstractPlatform * 'last_login' => array() * ) * ) - * @return void */ public function getCreateConstraintSql($table, $name, $definition) { @@ -1134,21 +1130,8 @@ abstract class AbstractPlatform * + double quote (") -- due to Oracle * + brackets ([ or ]) -- due to Access * - * Delimited identifiers are known to generally work correctly under - * the following drivers: - * + mssql - * + mysql - * + mysqli - * + oci8 - * + pgsql - * + sqlite - * - * InterBase doesn't seem to be able to use delimited identifiers - * via PHP 4. They work fine under PHP 5. - * * @param string $str identifier name to be quoted * @param bool $checkOption check the 'quote_identifier' option - * * @return string quoted identifier string */ public function quoteIdentifier($str) @@ -1187,7 +1170,7 @@ abstract class AbstractPlatform } /** - * generates the sql for altering an existing table + * Gets the sql for altering an existing table. * (this method is implemented by the drivers) * * @param string $name name of the table that is intended to be changed. @@ -1195,7 +1178,6 @@ abstract class AbstractPlatform * @param boolean $check indicates whether the function should just check if the DBMS driver * can perform the requested table alterations if the value is true or * actually perform them otherwise. - * @see Doctrine_Export::alterTable() * @return string */ public function getAlterTableSql($name, array $changes, $check = false) @@ -1232,11 +1214,11 @@ abstract class AbstractPlatform * * @return string */ - public function getFieldDeclarationListSql(array $fields) + public function getColumnDeclarationListSql(array $fields) { $queryFields = array(); foreach ($fields as $fieldName => $field) { - $query = $this->getDeclarationSql($fieldName, $field); + $query = $this->getColumnDeclarationSql($fieldName, $field); $queryFields[] = $query; } return implode(', ', $queryFields); @@ -1271,25 +1253,29 @@ abstract class AbstractPlatform * check * column check constraint * - * @return string DBMS specific SQL code portion that should be used to - * declare the specified field. + * @return string DBMS specific SQL code portion that should be used to declare the column. */ - public function getDeclarationSql($name, array $field) + public function getColumnDeclarationSql($name, array $field) { - $default = $this->getDefaultFieldDeclarationSql($field); + $default = $this->getDefaultValueDeclarationSql($field); + $charset = (isset($field['charset']) && $field['charset']) ? - ' ' . $this->getCharsetFieldDeclarationSql($field['charset']) : ''; + ' ' . $this->getColumnCharsetDeclarationSql($field['charset']) : ''; + $collation = (isset($field['collation']) && $field['collation']) ? - ' ' . $this->getCollationFieldDeclarationSql($field['collation']) : ''; + ' ' . $this->getColumnCollationDeclarationSql($field['collation']) : ''; + $notnull = (isset($field['notnull']) && $field['notnull']) ? ' NOT NULL' : ''; + $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, true) . ' ' . $typeDecl . $charset . $default . $notnull . $unique . $check . $collation; + return $this->quoteIdentifier($name) . ' ' . $typeDecl . $charset . $default . $notnull . $unique . $check . $collation; } /** @@ -1322,30 +1308,17 @@ abstract class AbstractPlatform abstract protected function _getCommonIntegerTypeDeclarationSql(array $columnDef); /** - * getDefaultDeclaration * Obtain DBMS specific SQL code portion needed to set a default value * declaration to be used in statements like CREATE TABLE. * * @param array $field field definition array * @return string DBMS specific SQL code portion needed to set a default value */ - public function getDefaultFieldDeclarationSql($field) + public function getDefaultValueDeclarationSql($field) { - $default = ''; + $default = empty($field['notnull']) ? ' DEFAULT NULL' : ''; + if (isset($field['default'])) { - if ($field['default'] === '') { - $field['default'] = empty($field['notnull']) - ? null : $this->valid_default_values[$field['type']]; - - if ($field['default'] === '' && - ($this->_conn->getAttribute(Doctrine::ATTR_PORTABILITY) & Doctrine::PORTABILITY_EMPTY_TO_NULL)) { - $field['default'] = null; - } - } - - if ($field['type'] === 'boolean') { - $field['default'] = $this->convertBooleans($field['default']); - } $default = ' DEFAULT ' . $this->quote($field['default'], $field['type']); } return $default; @@ -1510,7 +1483,6 @@ abstract class AbstractPlatform } /** - * getAdvancedForeignKeyOptions * Return the FOREIGN KEY query section dealing with non-standard options * as MATCH, INITIALLY DEFERRED, ON UPDATE, ... * @@ -1613,7 +1585,7 @@ abstract class AbstractPlatform * @return string DBMS specific SQL code portion needed to set the CHARACTER SET * of a field declaration. */ - public function getCharsetFieldDeclarationSql($charset) + public function getColumnCharsetDeclarationSql($charset) { return ''; } @@ -1626,7 +1598,7 @@ abstract class AbstractPlatform * @return string DBMS specific SQL code portion needed to set the COLLATION * of a field declaration. */ - public function getCollationFieldDeclarationSql($collation) + public function getColumnCollationDeclarationSql($collation) { return ''; } @@ -1653,39 +1625,6 @@ abstract class AbstractPlatform throw DoctrineException::updateMe("Method not implemented."); } - /** - * 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. - */ - abstract public function getNativeDeclaration(array $field); - - /** - * 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 - */ - abstract public function getPortableDeclaration(array $field); - /** * Whether the platform prefers sequences for ID generation. * Subclasses should override this method to return TRUE if they prefer sequences. @@ -1735,40 +1674,6 @@ abstract class AbstractPlatform return $query; } - /** - * Creates DBMS specific LIMIT/OFFSET SQL for the subqueries that are used in the - * context of the limit-subquery construction. - * This default implementation uses the normal LIMIT/OFFSET creation of the - * platform as provided by {@see modifyLimitQuery()}. This means LIMIT/OFFSET - * in subqueries don't get any special treatment. Most of the time this is not - * sufficient (eg. MySql does not allow LIMIT in subqueries) and the concrete - * platforms should provide their own implementation. - * - * @param string $query The SQL string to write to / append to. - * @return string - * @todo Remove the ORM dependency - */ - public function writeLimitClauseInSubquery(\Doctrine\ORM\Mapping\ClassMetadata $rootClass, - $query, $limit = false, $offset = false) - { - return $this->modifyLimitQuery($query, $limit, $offset); - } - - /** - * Enter description here... - * - * @param unknown_type $name - * @return unknown - * @todo Remove. Move properties to DatabasePlatform. - */ - public function getProperty($name) - { - if ( ! isset($this->_properties[$name])) { - throw DoctrineException::unknownProperty($name); - } - return $this->_properties[$name]; - } - /** * Some platforms need the boolean values to be converted. * Default conversion defined here converts to integers. @@ -1844,7 +1749,6 @@ abstract class AbstractPlatform return Connection::TRANSACTION_READ_COMMITTED; } - /* supports*() metods */ /** @@ -1920,7 +1824,7 @@ abstract class AbstractPlatform } /** - * Whether the platform supports getting the affected rows or a recent + * Whether the platform supports getting the affected rows of a recent * update/delete type query. * * @return boolean @@ -1936,9 +1840,9 @@ abstract class AbstractPlatform } /** - * Gets the SQL snippet used to declare a VARCHAR column on the MySql platform. + * Gets the SQL snippet used to declare a VARCHAR column type. * * @params array $field */ - abstract public function getVarcharDeclarationSql(array $field); + abstract public function getVarcharTypeDeclarationSql(array $field); } \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php b/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php index 6652af58c..a6a8102f0 100644 --- a/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php @@ -152,7 +152,7 @@ class MySqlPlatform extends AbstractPlatform * * @params array $field */ - public function getVarcharDeclarationSql(array $field) + public function getVarcharTypeDeclarationSql(array $field) { if ( ! isset($field['length'])) { if (array_key_exists('default', $field)) { @@ -215,8 +215,8 @@ class MySqlPlatform extends AbstractPlatform */ public function getNativeDeclaration(array $field) { - if ( ! isset($field['type'])) { - throw \Doctrine\Common\DoctrineException::updateMe('Missing column type.'); + /*if ( ! isset($field['type'])) { + throw DoctrineException::updateMe('Missing column type.'); } switch ($field['type']) { @@ -229,7 +229,7 @@ class MySqlPlatform extends AbstractPlatform case 'object': case 'string': case 'gzip': - return $this->getVarcharDeclarationSql($field); + return $this->getVarcharTypeDeclarationSql($field); case 'clob': return $this->getClobDeclarationSql($field); case 'blob': @@ -285,8 +285,8 @@ class MySqlPlatform extends AbstractPlatform $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'] . '\'.'); + }*/ + throw DoctrineException::updateMe('Unknown field type \'' . $field['type'] . '\'.'); } /** @@ -298,7 +298,7 @@ class MySqlPlatform extends AbstractPlatform */ public function getPortableDeclaration(array $field) { - $dbType = strtolower($field['type']); + /*$dbType = strtolower($field['type']); $dbType = strtok($dbType, '(), '); if ($dbType == 'national') { $dbType = strtok('(), '); @@ -448,7 +448,7 @@ class MySqlPlatform extends AbstractPlatform return array('type' => $type, 'length' => $length, 'unsigned' => $unsigned, 'fixed' => $fixed); } else { return array('type' => $type, 'length' => $length, 'unsigned' => $unsigned, 'fixed' => $fixed, 'values' => $values); - } + }*/ } /** @@ -602,7 +602,7 @@ class MySqlPlatform extends AbstractPlatform if (empty($fields)) { throw DoctrineException::updateMe('no fields specified for table "'.$name.'"'); } - $queryFields = $this->getFieldDeclarationListSql($fields); + $queryFields = $this->getColumnDeclarationListSql($fields); // build indexes for all foreign key fields (needed in MySQL!!) if (isset($options['foreignKeys'])) { @@ -694,10 +694,10 @@ class MySqlPlatform extends AbstractPlatform } /** - * alter an existing table + * Gets the SQL to 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 + * @param string $name The 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: * @@ -815,7 +815,7 @@ class MySqlPlatform extends AbstractPlatform if ($query) { $query.= ', '; } - $query.= 'ADD ' . $this->getDeclarationSql($fieldName, $field); + $query.= 'ADD ' . $this->getColumnDeclarationSql($fieldName, $field); } } @@ -849,7 +849,7 @@ class MySqlPlatform extends AbstractPlatform } $oldFieldName = $this->quoteIdentifier($oldFieldName, true); $query .= 'CHANGE ' . $oldFieldName . ' ' - . $this->getDeclarationSql($fieldName, $field['definition']); + . $this->getColumnDeclarationSql($fieldName, $field['definition']); } } @@ -861,7 +861,7 @@ class MySqlPlatform extends AbstractPlatform $field = $changes['rename'][$renamedField]; $renamedField = $this->quoteIdentifier($renamedField, true); $query .= 'CHANGE ' . $renamedField . ' ' - . $this->getDeclarationSql($field['name'], $field['definition']); + . $this->getColumnDeclarationSql($field['name'], $field['definition']); } } @@ -912,7 +912,6 @@ class MySqlPlatform extends AbstractPlatform public function getCreateIndexSql($table, $name, array $definition) { $table = $table; - $name = $this->formatter->getIndexName($name); $name = $this->quoteIdentifier($name); $type = ''; if (isset($definition['type'])) { @@ -968,24 +967,12 @@ class MySqlPlatform extends AbstractPlatform return 'BIGINT' . $this->_getCommonIntegerTypeDeclarationSql($field); } - /** @override */ - /*public function getTinyIntTypeDeclarationSql(array $field) - { - return 'TINYINT' . $this->_getCommonIntegerTypeDeclarationSql($field); - }*/ - /** @override */ public function getSmallIntTypeDeclarationSql(array $field) { return 'SMALLINT' . $this->_getCommonIntegerTypeDeclarationSql($field); } - /** @override */ - /*public function getMediumIntTypeDeclarationSql(array $field) - { - return 'MEDIUMINT' . $this->_getCommonIntegerTypeDeclarationSql($field); - }*/ - /** @override */ protected function _getCommonIntegerTypeDeclarationSql(array $columnDef) { @@ -998,27 +985,6 @@ class MySqlPlatform extends AbstractPlatform return $unsigned . $autoinc; } - /** - * Obtain DBMS specific SQL code portion needed to set a default value - * declaration to be used in statements like CREATE TABLE. - * - * @param array $field field definition array - * @return string DBMS specific SQL code portion needed to set a default value - * @override - */ - public function getDefaultFieldDeclarationSql($field) - { - $default = empty($field['notnull']) ? ' DEFAULT NULL' : ''; - - if (isset($field['default']) && ( ! isset($field['length']) || $field['length'] <= 255)) { - if ($field['default'] === '') { - $field['default'] = null; - } - $default = ' DEFAULT ' . $this->quote($field['default'], $field['type']); - } - return $default; - } - /** * Obtain DBMS specific SQL code portion needed to set an index * declaration to be used in statements like CREATE TABLE. @@ -1097,7 +1063,6 @@ class MySqlPlatform extends AbstractPlatform } /** - * getAdvancedForeignKeyOptions * Return the FOREIGN KEY query section dealing with non-standard options * as MATCH, INITIALLY DEFERRED, ON UPDATE, ... * @@ -1121,32 +1086,28 @@ class MySqlPlatform extends AbstractPlatform } /** - * drop existing index + * Gets the SQL to drop an index of a 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 * @override */ public function getDropIndexSql($table, $name) { - $table = $this->quoteIdentifier($table, true); - $name = $this->quoteIdentifier($this->formatter->getIndexName($name), true); + $table = $this->quoteIdentifier($table); + $name = $this->quoteIdentifier($name); return 'DROP INDEX ' . $name . ' ON ' . $table; } /** - * dropTable + * Gets the SQL to drop a table. * - * @param string $table name of table that should be dropped from the database - * @throws PDOException - * @return void + * @param string $table The name of table to drop. * @override */ public function getDropTableSql($table) { - $table = $this->quoteIdentifier($table, true); - return 'DROP TABLE ' . $table; + return 'DROP TABLE ' . $this->quoteIdentifier($table); } /** diff --git a/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php b/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php index 9fe0c555f..d3f37d11c 100644 --- a/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php @@ -1,63 +1,35 @@ . + */ namespace Doctrine\DBAL\Platforms; +/** + * PostgreSqlPlatform. + * + * @since 2.0 + * @author Roman Borschel + * @author Lukas Smith (PEAR MDB2 library) + */ class PostgreSqlPlatform extends AbstractPlatform { - /** - * The reserved keywords by pgsql. Ordered alphabetically. - * - * @param array - * @todo Nedded? What about lazy initialization? - */ - /*protected static $_reservedKeywords = array( - 'abort', 'absolute', 'access', 'action', 'add', 'after', 'aggregate', - 'all', 'alter', 'analyse', 'analyze', 'and', 'any', 'as', 'asc', - 'assertion', 'assignment', 'at', 'authorization', 'backward', 'before', - 'begin', 'between', 'bigint', 'binary', 'bit', 'boolean', 'both', - 'by', 'cache', 'called', 'cascade', 'case', 'cast', 'chain', 'char', - 'character', 'characteristics', 'check', 'checkpoint', 'class', - 'close', 'cluster', 'coalesce', 'collate', 'column', 'comment', - 'commit', 'committed', 'constraint', 'constraints', 'conversion', - 'convert', 'copy', 'create', 'createdb', 'createuser', 'cross', - 'current_date', 'current_time', 'current_timestamp', 'current_user', - 'cursor', 'cycle', 'database', 'day', 'deallocate', 'dec', 'decimal', - 'declare', 'default', 'deferrable', 'deferred', 'definer', 'delete', - 'delimiter', 'delimiters', 'desc', 'distinct', 'do', 'domain', 'double', - 'drop', 'each', 'else', 'encoding', 'encrypted', 'end', 'escape', - 'except', 'exclusive', 'execute', 'exists', 'explain', 'external', - 'extract', 'false', 'fetch', 'float', 'for', 'force', 'foreign', - 'forward', 'freeze', 'from', 'full', 'function', 'get', 'global', - 'grant', 'group', 'handler', 'having', 'hour', 'ilike', 'immediate', - 'immutable', 'implicit', 'in', 'increment', 'index', 'inherits', - 'initially', 'inner', 'inout', 'input', 'insensitive', 'insert', - 'instead', 'int', 'integer', 'intersect', 'interval', 'into', 'invoker', - 'is', 'isnull', 'isolation', 'join', 'key', 'lancompiler', 'language', - 'leading', 'left', 'level', 'like', 'limit', 'listen', 'load', 'local', - 'localtime', 'localtimestamp', 'location', 'lock', 'match', 'maxvalue', - 'minute', 'minvalue', 'mode', 'month', 'move', 'names', 'national', - 'natural', 'nchar', 'new', 'next', 'no', 'nocreatedb', 'nocreateuser', - 'none', 'not', 'nothing', 'notify', 'notnull', 'null', 'nullif', - 'numeric', 'of', 'off', 'offset', 'oids', 'old', 'on', 'only', 'operator', - 'option', 'or', 'order', 'out', 'outer', 'overlaps', 'overlay', - 'owner', 'partial', 'password', 'path', 'pendant', 'placing', 'position', - 'precision', 'prepare', 'primary', 'prior', 'privileges', 'procedural', - 'procedure', 'read', 'real', 'recheck', 'references', 'reindex', - 'relative', 'rename', 'replace', 'reset', 'restrict', 'returns', - 'revoke', 'right', 'rollback', 'row', 'rule', 'schema', 'scroll', - 'second', 'security', 'select', 'sequence', 'serializable', 'session', - 'session_user', 'set', 'setof', 'share', 'show', 'similar', 'simple', - 'smallint', 'some', 'stable', 'start', 'statement', 'statistics', - 'stdin', 'stdout', 'storage', 'strict', 'substring', 'sysid', 'table', - 'temp', 'template', 'temporary', 'then', 'time', 'timestamp', 'to', - 'toast', 'trailing', 'transaction', 'treat', 'trigger', 'trim', 'true', - 'truncate', 'trusted', 'type', 'unencrypted', 'union', 'unique', - 'unknown', 'unlisten', 'until', 'update', 'usage', 'user', 'using', - 'vacuum', 'valid', 'validator', 'values', 'varchar', 'varying', - 'verbose', 'version', 'view', 'volatile', 'when', 'where', 'with', - 'without', 'work', 'write', 'year','zone');*/ - - /** * Constructor. * Creates a new PostgreSqlPlatform. @@ -65,13 +37,6 @@ class PostgreSqlPlatform extends AbstractPlatform public function __construct() { parent::__construct(); - $this->_properties['string_quoting'] = array('start' => "'", - 'end' => "'", - 'escape' => "'", - 'escape_pattern' => '\\'); - $this->_properties['identifier_quoting'] = array('start' => '"', - 'end' => '"', - 'escape' => '"'); } /** @@ -98,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.'); @@ -162,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 @@ -172,9 +137,8 @@ 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'])) { $length = $field['atttypmod'] - 4; @@ -300,7 +264,7 @@ class PostgreSqlPlatform extends AbstractPlatform 'length' => $length, 'unsigned' => $unsigned, 'fixed' => $fixed); - } + }*/ /** * Returns the md5 sum of a field. @@ -323,7 +287,7 @@ class PostgreSqlPlatform extends AbstractPlatform */ public function getMd5Expression($column) { - $column = $this->getIdentifier($column); + $column = $this->quoteIdentifier($column); if ($this->_version > 7) { return 'MD5(' . $column . ')'; @@ -345,10 +309,10 @@ class PostgreSqlPlatform extends AbstractPlatform */ public function getSubstringExpression($value, $from, $len = null) { - $value = $this->getIdentifier($value); + $value = $this->quoteIdentifier($value); if ($len === null) { - $len = $this->getIdentifier($len); + $len = $this->quoteIdentifier($len); return 'SUBSTR(' . $value . ', ' . $from . ')'; } else { return 'SUBSTR(' . $value . ', ' . $from . ', ' . $len . ')'; @@ -778,7 +742,7 @@ class PostgreSqlPlatform extends AbstractPlatform if (isset($changes['add']) && is_array($changes['add'])) { foreach ($changes['add'] as $fieldName => $field) { - $query = 'ADD ' . $this->getDeclarationSql($fieldName, $field); + $query = 'ADD ' . $this->getColumnDeclarationSql($fieldName, $field); $sql[] = 'ALTER TABLE ' . $name . ' ' . $query; } } @@ -845,11 +809,10 @@ class PostgreSqlPlatform extends AbstractPlatform * @return string * @override */ - public function getCreateSequenceSql($sequenceName, $start = 1, array $options = array()) + public function getCreateSequenceSql($sequenceName, $start = 1, $allocationSize = 1) { - $sequenceName = $this->quoteIdentifier($this->formatter->getSequenceName($sequenceName), true); - return 'CREATE SEQUENCE ' . $sequenceName . ' INCREMENT 1' . - ($start < 1 ? ' MINVALUE ' . $start : '') . ' START ' . $start; + return 'CREATE SEQUENCE ' . $this->quoteIdentifier($sequenceName) + . ' INCREMENT BY ' . $allocationSize . ' START ' . $start; } /** @@ -860,8 +823,7 @@ class PostgreSqlPlatform extends AbstractPlatform */ public function getDropSequenceSql($sequenceName) { - $sequenceName = $this->quoteIdentifier($this->formatter->getSequenceName($sequenceName), true); - return 'DROP SEQUENCE ' . $sequenceName; + return 'DROP SEQUENCE ' . $this->quoteIdentifier($sequenceName); } /** @@ -881,7 +843,7 @@ class PostgreSqlPlatform extends AbstractPlatform throw DoctrineException::updateMe('no fields specified for table ' . $name); } - $queryFields = $this->getFieldDeclarationListSql($fields); + $queryFields = $this->getColumnDeclarationListSql($fields); if (isset($options['primary']) && ! empty($options['primary'])) { $keyColumns = array_values($options['primary']); @@ -911,56 +873,10 @@ class PostgreSqlPlatform extends AbstractPlatform return $sql; } - /** - * 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. - */ - public function getIntegerDeclarationSql($name, $field) - { - if ( ! empty($field['autoincrement'])) { - $name = $this->quoteIdentifier($name, true); - return $name . ' ' . $this->getNativeDeclaration($field); - } - - $default = ''; - if (array_key_exists('default', $field)) { - if ($field['default'] === '') { - $field['default'] = empty($field['notnull']) ? null : 0; - } - $default = ' DEFAULT '.$this->quote($field['default'], $field['type']); - } elseif (empty($field['notnull'])) { - $default = ' DEFAULT NULL'; - } - - $notnull = empty($field['notnull']) ? '' : ' NOT NULL'; - $name = $this->quoteIdentifier($name, true); - - return $name . ' ' . $this->getNativeDeclaration($field) . $default . $notnull; - } - /** * Postgres wants boolean values converted to the strings 'true'/'false'. * * @param array $item - * @return void * @override */ public function convertBooleans($item) @@ -1046,7 +962,7 @@ class PostgreSqlPlatform extends AbstractPlatform * @params array $field * @override */ - public function getVarcharDeclarationSql(array $field) + public function getVarcharTypeDeclarationSql(array $field) { if ( ! isset($field['length'])) { if (array_key_exists('default', $field)) { diff --git a/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php b/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php index f25a8c0f7..87d3c9b20 100644 --- a/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php +++ b/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php @@ -26,6 +26,7 @@ namespace Doctrine\DBAL\Platforms; * database platform. * * @since 2.0 + * @author Roman Borschel */ class SqlitePlatform extends AbstractPlatform { @@ -73,18 +74,22 @@ class SqlitePlatform extends AbstractPlatform { return strpos($str, $substr); } + public static function sha1Impl($str) { return sha1($str); } + public static function ltrimImpl($str) { return ltrim($str); } + public static function rtrimImpl($str) { return rtrim($str); } + public static function trimImpl($str) { return trim($str); @@ -193,7 +198,7 @@ class SqlitePlatform extends AbstractPlatform */ public function getNativeDeclaration(array $field) { - if ( ! isset($field['type'])) { + /*if ( ! isset($field['type'])) { throw DoctrineException::updateMe('Missing column type.'); } switch ($field['type']) { @@ -253,7 +258,7 @@ class SqlitePlatform extends AbstractPlatform $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'] . '\'.'); } @@ -266,7 +271,7 @@ class SqlitePlatform extends AbstractPlatform */ public function getPortableDeclaration(array $field) { - $dbType = strtolower($field['type']); + /*$dbType = strtolower($field['type']); $length = (isset($field['length'])) ? $field['length'] : null; $unsigned = (isset($field['unsigned'])) ? $field['unsigned'] : null; $fixed = null; @@ -377,7 +382,7 @@ class SqlitePlatform extends AbstractPlatform return array('type' => $type, 'length' => $length, 'unsigned' => $unsigned, - 'fixed' => $fixed); + 'fixed' => $fixed);*/ } /** @@ -389,11 +394,11 @@ class SqlitePlatform extends AbstractPlatform protected function _getTransactionIsolationLevelSql($level) { switch ($level) { - case Doctrine_DBAL_Connection::TRANSACTION_READ_UNCOMMITTED: + case \Doctrine\DBAL\Connection::TRANSACTION_READ_UNCOMMITTED: return 0; - case Doctrine_DBAL_Connection::TRANSACTION_READ_COMMITTED: - case Doctrine_DBAL_Connection::TRANSACTION_REPEATABLE_READ: - case Doctrine_DBAL_Connection::TRANSACTION_SERIALIZABLE: + case \Doctrine\DBAL\Connection::TRANSACTION_READ_COMMITTED: + case \Doctrine\DBAL\Connection::TRANSACTION_REPEATABLE_READ: + case \Doctrine\DBAL\Connection::TRANSACTION_SERIALIZABLE: return 1; default: return parent::_getTransactionIsolationLevelSql($level); @@ -493,7 +498,7 @@ class SqlitePlatform extends AbstractPlatform if (empty($fields)) { throw ConnectionException::noFieldsSpecifiedForTable($name); } - $queryFields = $this->getFieldDeclarationListSql($fields); + $queryFields = $this->getColumnDeclarationListSql($fields); $autoinc = false; foreach($fields as $field) { @@ -535,7 +540,7 @@ class SqlitePlatform extends AbstractPlatform /** * {@inheritdoc} */ - public function getVarcharDeclarationSql(array $field) + public function getVarcharTypeDeclarationSql(array $field) { if ( ! isset($field['length'])) { if (array_key_exists('default', $field)) { diff --git a/lib/Doctrine/DBAL/Types/VarcharType.php b/lib/Doctrine/DBAL/Types/VarcharType.php index 0e4c11b24..11f7b3be4 100644 --- a/lib/Doctrine/DBAL/Types/VarcharType.php +++ b/lib/Doctrine/DBAL/Types/VarcharType.php @@ -12,7 +12,7 @@ class VarcharType extends Type /** @override */ public function getSqlDeclaration(array $fieldDeclaration, \Doctrine\DBAL\Platforms\AbstractPlatform $platform) { - return $platform->getVarcharDeclarationSql($fieldDeclaration); + return $platform->getVarcharTypeDeclarationSql($fieldDeclaration); } /** @override */ diff --git a/lib/Doctrine/ORM/Configuration.php b/lib/Doctrine/ORM/Configuration.php index e210f18d4..4d13cebd7 100644 --- a/lib/Doctrine/ORM/Configuration.php +++ b/lib/Doctrine/ORM/Configuration.php @@ -16,7 +16,7 @@ * * This software consists of voluntary contributions made by many individuals * and is licensed under the LGPL. For more information, see - * . + * . */ namespace Doctrine\ORM; @@ -26,12 +26,11 @@ use Doctrine\ORM\Mapping\Driver\AnnotationDriver; /** * Configuration container for all configuration options of Doctrine. * It combines all configuration options from DBAL & ORM. - * - * INTERNAL: When adding a new configuration option just write a getter/setter - * pair and add the option to the _attributes array with a proper default value. * * @author Roman Borschel * @since 2.0 + * @internal When adding a new configuration option just write a getter/setter + * pair and add the option to the _attributes array with a proper default value. */ class Configuration extends \Doctrine\DBAL\Configuration { @@ -44,10 +43,21 @@ class Configuration extends \Doctrine\DBAL\Configuration 'resultCacheImpl' => null, 'queryCacheImpl' => null, 'metadataCacheImpl' => null, - 'metadataDriverImpl' => new AnnotationDriver() + 'metadataDriverImpl' => new AnnotationDriver(), + 'dqlClassAliasMap' => array() )); } + public function getDqlClassAliasMap() + { + return $this->_attributes['dqlClassAliasMap']; + } + + public function setDqlClassAliasMap(array $map) + { + $this->_attributes['dqlClassAliasMap'] = $map; + } + public function setMetadataDriverImpl($driverImpl) { $this->_attributes['metadataDriverImpl'] = $driverImpl; diff --git a/lib/Doctrine/ORM/PersistentCollection.php b/lib/Doctrine/ORM/PersistentCollection.php index 60f0629ee..d4e4834ed 100644 --- a/lib/Doctrine/ORM/PersistentCollection.php +++ b/lib/Doctrine/ORM/PersistentCollection.php @@ -75,7 +75,7 @@ final class PersistentCollection extends \Doctrine\Common\Collections\Collection private $_association; /** - * The name of the field that is used for collection key mapping. + * The name of the field that is used for collection indexing. * * @var string */ @@ -90,7 +90,7 @@ final class PersistentCollection extends \Doctrine\Common\Collections\Collection /** * The name of the field on the target entities that points to the owner - * of the collection. This is only set if the association is bidirectional. + * of the collection. This is only set if the association is bi-directional. * * @var string */ @@ -102,7 +102,7 @@ final class PersistentCollection extends \Doctrine\Common\Collections\Collection * @var boolean * @see setHydrationFlag() */ - private $_hydrationFlag; + private $_hydrationFlag = false; /** * The class descriptor of the owning entity. diff --git a/lib/Doctrine/ORM/Query/SqlWalker.php b/lib/Doctrine/ORM/Query/SqlWalker.php index 3cbc87845..3cabe5f55 100644 --- a/lib/Doctrine/ORM/Query/SqlWalker.php +++ b/lib/Doctrine/ORM/Query/SqlWalker.php @@ -661,6 +661,12 @@ class SqlWalker return $sql; } + /** + * Generates a discriminator column SQL condition for the class with the given DQL alias. + * + * @param string $dqlAlias + * @return string + */ private function _generateDiscriminatorColumnConditionSql($dqlAlias) { $sql = ''; diff --git a/tests/Doctrine/Tests/DBAL/AllTests.php b/tests/Doctrine/Tests/DBAL/AllTests.php index 4a777eeb2..2830aa017 100644 --- a/tests/Doctrine/Tests/DBAL/AllTests.php +++ b/tests/Doctrine/Tests/DBAL/AllTests.php @@ -23,6 +23,8 @@ class AllTests $suite = new \Doctrine\Tests\DbalTestSuite('Doctrine DBAL'); $suite->addTestSuite('Doctrine\Tests\DBAL\Platforms\SqlitePlatformTest'); + $suite->addTestSuite('Doctrine\Tests\DBAL\Platforms\MySqlPlatformTest'); + $suite->addTestSuite('Doctrine\Tests\DBAL\Platforms\PostgreSqlPlatformTest'); return $suite; } diff --git a/tests/Doctrine/Tests/DBAL/Platforms/MySqlPlatformTest.php b/tests/Doctrine/Tests/DBAL/Platforms/MySqlPlatformTest.php new file mode 100644 index 000000000..5b9e7c89a --- /dev/null +++ b/tests/Doctrine/Tests/DBAL/Platforms/MySqlPlatformTest.php @@ -0,0 +1,170 @@ +_platform = new MySqlPlatform; + } + + public function testCreateTableSql() + { + $columns = array( + 'id' => array( + 'type' => Type::getType('integer'), + 'autoincrement' => true, + 'primary' => true, + 'notnull' => true + ), + 'test' => array( + 'type' => Type::getType('varchar'), + 'length' => 255, + 'notnull' => true + ) + ); + + $options = array( + 'primary' => array('id') + ); + + $sql = $this->_platform->getCreateTableSql('test', $columns, $options); + $this->assertEquals('CREATE TABLE test (id INT AUTO_INCREMENT NOT NULL, test VARCHAR(255) NOT NULL, PRIMARY KEY(id))', $sql[0]); + } + + public function testAlterTableSql() + { + $changes = array( + 'name' => 'userlist', + 'add' => array( + 'quota' => array( + 'type' => Type::getType('integer'), + 'unsigned' => 1 + ) + )); + + $this->assertEquals( + 'ALTER TABLE mytable RENAME TO userlist, ADD quota INT UNSIGNED DEFAULT NULL', + $this->_platform->getAlterTableSql('mytable', $changes) + ); + } + + public function testCreateIndexSql() + { + $indexDef = array( + 'fields' => array( + 'user_name' => array( + 'sorting' => 'ASC', + 'length' => 10 + ), + 'last_login' => array() + ) + ); + + $this->assertEquals( + 'CREATE INDEX my_idx ON mytable (user_name(10) ASC, last_login)', + $this->_platform->getCreateIndexSql('mytable', 'my_idx', $indexDef) + ); + } + + public function testSqlSnippets() + { + $this->assertEquals('RLIKE', $this->_platform->getRegexpExpression()); + $this->assertEquals('`', $this->_platform->getIdentifierQuoteCharacter()); + $this->assertEquals('RAND()', $this->_platform->getRandomExpression()); + $this->assertEquals('CONCAT(column1, column2, column3)', $this->_platform->getConcatExpression('column1', 'column2', 'column3')); + $this->assertEquals('CHARACTER SET utf8', $this->_platform->getCharsetFieldDeclaration('utf8')); + $this->assertEquals( + 'SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED', + $this->_platform->getSetTransactionIsolationSql(\Doctrine\DBAL\Connection::TRANSACTION_READ_UNCOMMITTED) + ); + $this->assertEquals( + 'SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED', + $this->_platform->getSetTransactionIsolationSql(\Doctrine\DBAL\Connection::TRANSACTION_READ_COMMITTED) + ); + $this->assertEquals( + 'SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ', + $this->_platform->getSetTransactionIsolationSql(\Doctrine\DBAL\Connection::TRANSACTION_REPEATABLE_READ) + ); + $this->assertEquals( + 'SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE', + $this->_platform->getSetTransactionIsolationSql(\Doctrine\DBAL\Connection::TRANSACTION_SERIALIZABLE) + ); + } + + public function testDDLSnippets() + { + $this->assertEquals('SHOW DATABASES', $this->_platform->getShowDatabasesSql()); + $this->assertEquals('CREATE DATABASE foobar', $this->_platform->getCreateDatabaseSql('foobar')); + $this->assertEquals('DROP DATABASE foobar', $this->_platform->getDropDatabaseSql('foobar')); + $this->assertEquals('DROP TABLE foobar', $this->_platform->getDropTableSql('foobar')); + } + + public function testTypeDeclarationSql() + { + $this->assertEquals( + 'INT', + $this->_platform->getIntegerTypeDeclarationSql(array()) + ); + $this->assertEquals( + 'INT AUTO_INCREMENT', + $this->_platform->getIntegerTypeDeclarationSql(array('autoincrement' => true) + )); + $this->assertEquals( + 'INT AUTO_INCREMENT', + $this->_platform->getIntegerTypeDeclarationSql( + array('autoincrement' => true, 'primary' => true) + )); + $this->assertEquals( + 'CHAR(10)', + $this->_platform->getVarcharTypeDeclarationSql( + array('length' => 10, 'fixed' => true) + )); + $this->assertEquals( + 'VARCHAR(50)', + $this->_platform->getVarcharTypeDeclarationSql(array('length' => 50)) + ); + $this->assertEquals( + 'TEXT', + $this->_platform->getVarcharTypeDeclarationSql(array()) + ); + } + + public function testPreferences() + { + $this->assertTrue($this->_platform->prefersIdentityColumns()); + $this->assertTrue($this->_platform->supportsIdentityColumns()); + $this->assertFalse($this->_platform->supportsSavepoints()); + + } + +/* + public function testGetCreateConstraintSql() + { + $sql = $this->_platform->getCreateConstraintSql('test', 'constraint_name', array('fields' => array('test' => array()))); + $this->assertEquals($sql, 'ALTER TABLE test ADD CONSTRAINT constraint_name (test)'); + } + + public function testGetCreateIndexSql() + { + $sql = $this->_platform->getCreateIndexSql('test', 'index_name', array('type' => 'unique', 'fields' => array('test', 'test2'))); + $this->assertEquals($sql, 'CREATE UNIQUE INDEX index_name ON test (test, test2)'); + } + + public function testGetCreateForeignKeySql() + { + $sql = $this->_platform->getCreateForeignKeySql('test', array('foreignTable' => 'other_table', 'local' => 'fk_name_id', 'foreign' => 'id')); + $this->assertEquals($sql, 'ALTER TABLE test ADD FOREIGN KEY (fk_name_id) REFERENCES other_table(id)'); + } + + + */ +} \ No newline at end of file diff --git a/tests/Doctrine/Tests/DBAL/Platforms/PostgreSqlPlatformTest.php b/tests/Doctrine/Tests/DBAL/Platforms/PostgreSqlPlatformTest.php new file mode 100644 index 000000000..b8662cb51 --- /dev/null +++ b/tests/Doctrine/Tests/DBAL/Platforms/PostgreSqlPlatformTest.php @@ -0,0 +1,168 @@ +_platform = new PostgreSqlPlatform; + } + + public function testCreateTableSql() + { + $columns = array( + 'id' => array( + 'type' => Type::getType('integer'), + 'primary' => true, + 'notnull' => true + ), + 'test' => array( + 'type' => Type::getType('varchar'), + 'length' => 255, + 'notnull' => true + ) + ); + + $options = array( + 'primary' => array('id') + ); + + $sql = $this->_platform->getCreateTableSql('test', $columns, $options); + $this->assertEquals('CREATE TABLE test (id INT NOT NULL, test VARCHAR(255) NOT NULL, PRIMARY KEY(id))', $sql[0]); + + } + + public function testAlterTableSql() + { + $changes = array( + 'name' => 'userlist', + 'add' => array( + 'quota' => array( + 'type' => Type::getType('integer') + ) + )); + + $sql = $this->_platform->getAlterTableSql('mytable', $changes); + + $this->assertEquals( + 'ALTER TABLE mytable ADD quota INT DEFAULT NULL', + $sql[0] + ); + $this->assertEquals( + 'ALTER TABLE mytable RENAME TO userlist', + $sql[1] + ); + } + + public function testCreateIndexSql() + { + $indexDef = array( + 'fields' => array( + 'user_name', + 'last_login' + ) + ); + + $sql = $this->_platform->getCreateIndexSql('mytable', 'my_idx', $indexDef); + + $this->assertEquals( + 'CREATE INDEX my_idx ON mytable (user_name, last_login)', + $sql + ); + } + + public function testSqlSnippets() + { + $this->assertEquals('SIMILAR TO', $this->_platform->getRegexpExpression()); + $this->assertEquals('"', $this->_platform->getIdentifierQuoteCharacter()); + $this->assertEquals('RANDOM()', $this->_platform->getRandomExpression()); + $this->assertEquals('column1 || column2 || column3', $this->_platform->getConcatExpression('column1', 'column2', 'column3')); + $this->assertEquals( + 'SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL READ UNCOMMITTED', + $this->_platform->getSetTransactionIsolationSql(Connection::TRANSACTION_READ_UNCOMMITTED) + ); + $this->assertEquals( + 'SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL READ COMMITTED', + $this->_platform->getSetTransactionIsolationSql(Connection::TRANSACTION_READ_COMMITTED) + ); + $this->assertEquals( + 'SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL REPEATABLE READ', + $this->_platform->getSetTransactionIsolationSql(Connection::TRANSACTION_REPEATABLE_READ) + ); + $this->assertEquals( + 'SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE', + $this->_platform->getSetTransactionIsolationSql(Connection::TRANSACTION_SERIALIZABLE) + ); + } + + public function testDDLSnippets() + { + $this->assertEquals('CREATE DATABASE foobar', $this->_platform->getCreateDatabaseSql('foobar')); + $this->assertEquals('DROP DATABASE foobar', $this->_platform->getDropDatabaseSql('foobar')); + $this->assertEquals('DROP TABLE foobar', $this->_platform->getDropTableSql('foobar')); + } + + public function testTypeDeclarationSql() + { + $this->assertEquals( + 'INT', + $this->_platform->getIntegerTypeDeclarationSql(array()) + ); + $this->assertEquals( + 'SERIAL', + $this->_platform->getIntegerTypeDeclarationSql(array('autoincrement' => true) + )); + $this->assertEquals( + 'SERIAL', + $this->_platform->getIntegerTypeDeclarationSql( + array('autoincrement' => true, 'primary' => true) + )); + $this->assertEquals( + 'CHAR(10)', + $this->_platform->getVarcharTypeDeclarationSql( + array('length' => 10, 'fixed' => true) + )); + $this->assertEquals( + 'VARCHAR(50)', + $this->_platform->getVarcharTypeDeclarationSql(array('length' => 50)) + ); + $this->assertEquals( + 'TEXT', + $this->_platform->getVarcharTypeDeclarationSql(array()) + ); + } + + public function testSequenceSQL() + { + $this->assertEquals( + 'CREATE SEQUENCE myseq INCREMENT BY 20 START 1', + $this->_platform->getCreateSequenceSql('myseq', 1, 20) + ); + $this->assertEquals( + 'DROP SEQUENCE myseq', + $this->_platform->getDropSequenceSql('myseq') + ); + $this->assertEquals( + "SELECT NEXTVAL('myseq')", + $this->_platform->getSequenceNextValSql('myseq') + ); + } + + public function testPreferences() + { + $this->assertFalse($this->_platform->prefersIdentityColumns()); + $this->assertTrue($this->_platform->prefersSequences()); + $this->assertTrue($this->_platform->supportsIdentityColumns()); + $this->assertTrue($this->_platform->supportsSavepoints()); + $this->assertTrue($this->_platform->supportsSequences()); + } +} \ No newline at end of file diff --git a/tests/Doctrine/Tests/DBAL/Platforms/SqlitePlatformTest.php b/tests/Doctrine/Tests/DBAL/Platforms/SqlitePlatformTest.php index 9808bc4a1..2f466c258 100644 --- a/tests/Doctrine/Tests/DBAL/Platforms/SqlitePlatformTest.php +++ b/tests/Doctrine/Tests/DBAL/Platforms/SqlitePlatformTest.php @@ -20,7 +20,9 @@ class SqlitePlatformTest extends \Doctrine\Tests\DbalTestCase $columns = array( 'id' => array( 'type' => new \Doctrine\DBAL\Types\IntegerType, - 'autoincrement' => true + 'autoincrement' => true, + 'primary' => true, + 'notnull' => true ), 'test' => array( 'type' => new \Doctrine\DBAL\Types\VarcharType, @@ -28,29 +30,74 @@ class SqlitePlatformTest extends \Doctrine\Tests\DbalTestCase ) ); - $options = array( - 'primary' => array('id') - ); + $options = array(); $sql = $this->_platform->getCreateTableSql('test', $columns, $options); - $this->assertEquals($sql[0], 'CREATE TABLE test (id INTEGER AUTOINCREMENT, test VARCHAR(255))'); + $this->assertEquals('CREATE TABLE test (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, test VARCHAR(255) DEFAULT NULL)', $sql[0]); } public function testGetCreateConstraintSql() { $sql = $this->_platform->getCreateConstraintSql('test', 'constraint_name', array('fields' => array('test' => array()))); - $this->assertEquals($sql, 'ALTER TABLE test ADD CONSTRAINT constraint_name (test)'); + $this->assertEquals('ALTER TABLE test ADD CONSTRAINT constraint_name (test)', $sql); } public function testGetCreateIndexSql() { $sql = $this->_platform->getCreateIndexSql('test', 'index_name', array('type' => 'unique', 'fields' => array('test', 'test2'))); - $this->assertEquals($sql, 'CREATE UNIQUE INDEX index_name ON test (test, test2)'); + $this->assertEquals('CREATE UNIQUE INDEX index_name ON test (test, test2)', $sql); } public function testGetCreateForeignKeySql() { $sql = $this->_platform->getCreateForeignKeySql('test', array('foreignTable' => 'other_table', 'local' => 'fk_name_id', 'foreign' => 'id')); - $this->assertEquals($sql, 'ALTER TABLE test ADD FOREIGN KEY (fk_name_id) REFERENCES other_table(id)'); + $this->assertEquals('ALTER TABLE test ADD FOREIGN KEY (fk_name_id) REFERENCES other_table(id)', $sql); } + + public function testExpressionsSql() + { + $this->assertEquals('RLIKE', $this->_platform->getRegexpExpression()); + $this->assertEquals('SUBSTR(column, 5, LENGTH(column))', $this->_platform->getSubstringExpression('column', 5)); + $this->assertEquals('SUBSTR(column, 0, 5)', $this->_platform->getSubstringExpression('column', 0, 5)); + $this->assertEquals('PRAGMA read_uncommitted = 0', $this->_platform->getSetTransactionIsolationSql(\Doctrine\DBAL\Connection::TRANSACTION_READ_UNCOMMITTED)); + $this->assertEquals('PRAGMA read_uncommitted = 1', $this->_platform->getSetTransactionIsolationSql(\Doctrine\DBAL\Connection::TRANSACTION_READ_COMMITTED)); + $this->assertEquals('PRAGMA read_uncommitted = 1', $this->_platform->getSetTransactionIsolationSql(\Doctrine\DBAL\Connection::TRANSACTION_REPEATABLE_READ)); + $this->assertEquals('PRAGMA read_uncommitted = 1', $this->_platform->getSetTransactionIsolationSql(\Doctrine\DBAL\Connection::TRANSACTION_SERIALIZABLE)); + } + + public function testPreferences() + { + $this->assertTrue($this->_platform->prefersIdentityColumns()); + } + + public function testTypeDeclarationSql() + { + $this->assertEquals( + 'INTEGER', + $this->_platform->getIntegerTypeDeclarationSql(array()) + ); + $this->assertEquals( + 'INTEGER AUTOINCREMENT', + $this->_platform->getIntegerTypeDeclarationSql(array('autoincrement' => true) + )); + $this->assertEquals( + 'INTEGER PRIMARY KEY AUTOINCREMENT', + $this->_platform->getIntegerTypeDeclarationSql( + array('autoincrement' => true, 'primary' => true) + )); + $this->assertEquals( + 'CHAR(10)', + $this->_platform->getVarcharTypeDeclarationSql( + array('length' => 10, 'fixed' => true) + )); + $this->assertEquals( + 'VARCHAR(50)', + $this->_platform->getVarcharTypeDeclarationSql(array('length' => 50)) + ); + $this->assertEquals( + 'TEXT', + $this->_platform->getVarcharTypeDeclarationSql(array()) + ); + } + } \ No newline at end of file diff --git a/tests/Doctrine/Tests/Mocks/DatabasePlatformMock.php b/tests/Doctrine/Tests/Mocks/DatabasePlatformMock.php index 4f9503f92..56bef12a9 100644 --- a/tests/Doctrine/Tests/Mocks/DatabasePlatformMock.php +++ b/tests/Doctrine/Tests/Mocks/DatabasePlatformMock.php @@ -53,7 +53,7 @@ class DatabasePlatformMock extends \Doctrine\DBAL\Platforms\AbstractPlatform protected function _getCommonIntegerTypeDeclarationSql(array $columnDef) {} /** @override */ - public function getVarcharDeclarationSql(array $field) {} + public function getVarcharTypeDeclarationSql(array $field) {} /* MOCK API */ diff --git a/tests/Doctrine/Tests/ORM/Functional/SingleTableInheritanceTest.php b/tests/Doctrine/Tests/ORM/Functional/SingleTableInheritanceTest.php index c51f7a347..7ab3aaa8e 100644 --- a/tests/Doctrine/Tests/ORM/Functional/SingleTableInheritanceTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/SingleTableInheritanceTest.php @@ -22,7 +22,6 @@ class SingleTableInheritanceTest extends \Doctrine\Tests\OrmFunctionalTestCase public function testCRUD() { - $parent = new ParentEntity; $parent->setData('foobar'); @@ -31,7 +30,6 @@ class SingleTableInheritanceTest extends \Doctrine\Tests\OrmFunctionalTestCase $child = new ChildEntity; $child->setData('thedata'); $child->setNumber(1234); - //$child->setRelatedEntity($relatedEntity); $this->_em->save($child);