Commit ce5b0569 authored by beberlei's avatar beberlei

Merge remote branch 'juokaz/sqlsrv-driver' into DBAL-8

parents 3caada2b e2dd9536
<?php <?php
/* /*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
...@@ -19,17 +21,17 @@ ...@@ -19,17 +21,17 @@
namespace Doctrine\DBAL\Driver\PDOMsSql; namespace Doctrine\DBAL\Driver\PDOMsSql;
use PDO, Doctrine\DBAL\Driver\Connection as DriverConnection;
/** /**
* MsSql Connection implementation. * MsSql Connection implementation.
* *
* @since 2.0 * @since 2.0
*/ */
class Connection extends PDO implements DriverConnection class Connection extends \PDO implements \Doctrine\DBAL\Driver\Connection
{ {
/** /**
* {@inheritdoc} * Performs the rollback.
*
* @override
*/ */
public function rollback() public function rollback()
{ {
...@@ -37,7 +39,9 @@ class Connection extends PDO implements DriverConnection ...@@ -37,7 +39,9 @@ class Connection extends PDO implements DriverConnection
} }
/** /**
* {@inheritdoc} * Performs the commit.
*
* @override
*/ */
public function commit() public function commit()
{ {
...@@ -45,21 +49,12 @@ class Connection extends PDO implements DriverConnection ...@@ -45,21 +49,12 @@ class Connection extends PDO implements DriverConnection
} }
/** /**
* {@inheritdoc} * Begins a database transaction.
*
* @override
*/ */
public function beginTransaction() public function beginTransaction()
{ {
$this->exec('BEGIN TRANSACTION'); $this->exec('BEGIN TRANSACTION');
} }
/**
* {@inheritdoc}
*/
public function lastInsertId($name = null)
{
$stmt = $this->query('SELECT SCOPE_IDENTITY()');
$id = $stmt->fetchColumn();
$stmt->closeCursor();
return $id;
}
} }
\ No newline at end of file
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\DBAL\Driver\PDOSqlsrv;
/**
* The PDO-based Sqlsrv driver.
*
* @since 2.0
*/
class Driver implements \Doctrine\DBAL\Driver
{
public function connect(array $params, $username = null, $password = null, array $driverOptions = array())
{
if (isset($params['dbname'])) {
$driverOptions['Database'] = $params['dbname'];
}
return new \Doctrine\DBAL\Driver\PDOConnection(
$this->_constructPdoDsn($params),
$username,
$password,
$driverOptions
);
}
/**
* Constructs the Sqlsrv PDO DSN.
*
* @return string The DSN.
*/
private function _constructPdoDsn(array $params)
{
// TODO: This might need to be revisted once we have access to a sql server
$dsn = 'sqlsrv:(';
if (isset($params['host'])) {
$dsn .= $params['host'];
}
$dsn .= ')';
if (stripos($dsn, '\sqlexpress') !== false)
{
$dsn = str_ireplace('\sqlexpress', '', $dsn);
$dsn .= '\sqlexpress';
}
$dsn = str_ireplace('localhost', 'local', $dsn);
if (isset($params['port']) && !empty($params['port'])) {
$dsn .= ',' . $params['port'];
}
return $dsn;
}
public function getDatabasePlatform()
{
return new \Doctrine\DBAL\Platforms\SqlsrvPlatform();
}
public function getSchemaManager(\Doctrine\DBAL\Connection $conn)
{
return new \Doctrine\DBAL\Schema\SqlsrvSchemaManager($conn);
}
public function getName()
{
return 'pdo_sqlsrv';
}
public function getDatabase(\Doctrine\DBAL\Connection $conn)
{
$params = $conn->getParams();
return $params['dbname'];
}
}
\ No newline at end of file
...@@ -44,6 +44,7 @@ final class DriverManager ...@@ -44,6 +44,7 @@ final class DriverManager
'oci8' => 'Doctrine\DBAL\Driver\OCI8\Driver', 'oci8' => 'Doctrine\DBAL\Driver\OCI8\Driver',
'ibm_db2' => 'Doctrine\DBAL\Driver\IBMDB2\DB2Driver', 'ibm_db2' => 'Doctrine\DBAL\Driver\IBMDB2\DB2Driver',
'pdo_ibm' => 'Doctrine\DBAL\Driver\PDOIbm\Driver', 'pdo_ibm' => 'Doctrine\DBAL\Driver\PDOIbm\Driver',
'pdo_sqlsrv' => 'Doctrine\DBAL\Driver\PDOSqlsrv\Driver',
); );
/** Private constructor. This class cannot be instantiated. */ /** Private constructor. This class cannot be instantiated. */
......
<?php <?php
/* /*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
...@@ -42,6 +40,7 @@ use Doctrine\DBAL\DBALException, ...@@ -42,6 +40,7 @@ use Doctrine\DBAL\DBALException,
* @author Jonathan Wage <jonwage@gmail.com> * @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org> * @author Roman Borschel <roman@code-factory.org>
* @author Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library) * @author Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @todo Remove any unnecessary methods. * @todo Remove any unnecessary methods.
*/ */
abstract class AbstractPlatform abstract class AbstractPlatform
...@@ -76,11 +75,63 @@ abstract class AbstractPlatform ...@@ -76,11 +75,63 @@ abstract class AbstractPlatform
*/ */
const TRIM_BOTH = 3; const TRIM_BOTH = 3;
/**
* @var array
*/
protected $doctrineTypeMapping = null;
/** /**
* Constructor. * Constructor.
*/ */
public function __construct() {} public function __construct() {}
/**
* Register a doctrine type to be used in conjunction with a column type of this platform.
*
* @param string $dbType
* @param string $doctrineType
*/
public function registerDoctrineTypeMapping($dbType, $doctrineType)
{
if ($this->doctrineTypeMapping === null) {
$this->initializeDoctrineTypeMappings();
}
if (!Types\Type::hasType($doctrineType)) {
throw DBALException::typeNotFound($doctrineType);
}
$dbType = strtolower($dbType);
$this->doctrineTypeMapping[$dbType] = $doctrineType;
}
/**
* Get the Doctrine type that is mapped for the given database column type.
*
* @param string $dbType
* @return string
*/
public function getDoctrineTypeMapping($dbType)
{
if ($this->doctrineTypeMapping === null) {
$this->initializeDoctrineTypeMappings();
}
$dbType = strtolower($dbType);
if (isset($this->doctrineTypeMapping[$dbType])) {
return $this->doctrineTypeMapping[$dbType];
} else {
throw new \Doctrine\DBAL\DBALException("Unknown database type ".$dbType." requested, " . get_class($this) . " may not support it.");
}
}
/**
* Lazy load Doctrine Type Mappings
*
* @return void
*/
abstract protected function initializeDoctrineTypeMappings();
/** /**
* Gets the character used for identifier quoting. * Gets the character used for identifier quoting.
* *
...@@ -1901,4 +1952,14 @@ abstract class AbstractPlatform ...@@ -1901,4 +1952,14 @@ abstract class AbstractPlatform
{ {
return 'TRUNCATE '.$tableName; return 'TRUNCATE '.$tableName;
} }
/**
* This is for test reasons, many vendors have special requirements for dummy statements.
*
* @return string
*/
public function getDummySelectSQL()
{
return 'SELECT 1';
}
} }
\ No newline at end of file
<?php <?php
/* /*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
...@@ -27,6 +25,24 @@ use Doctrine\DBAL\Schema\TableDiff; ...@@ -27,6 +25,24 @@ use Doctrine\DBAL\Schema\TableDiff;
class DB2Platform extends AbstractPlatform class DB2Platform extends AbstractPlatform
{ {
public function initializeDoctrineTypeMappings()
{
$this->doctrineTypeMapping = array(
'smallint' => 'smallint',
'bigint' => 'bigint',
'integer' => 'integer',
'time' => 'time',
'date' => 'date',
'varchar' => 'string',
'character' => 'string',
'clob' => 'text',
'decimal' => 'decimal',
'double' => 'decimal',
'real' => 'decimal',
'timestamp' => 'datetime',
);
}
/** /**
* Gets the SQL snippet used to declare a VARCHAR column type. * Gets the SQL snippet used to declare a VARCHAR column type.
* *
...@@ -518,4 +534,9 @@ class DB2Platform extends AbstractPlatform ...@@ -518,4 +534,9 @@ class DB2Platform extends AbstractPlatform
{ {
return ' WITH RR USE AND KEEP UPDATE LOCKS'; return ' WITH RR USE AND KEEP UPDATE LOCKS';
} }
public function getDummySelectSQL()
{
return 'SELECT 1 FROM sysibm.sysdummy1';
}
} }
\ No newline at end of file
<?php <?php
/* /*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
...@@ -23,6 +21,7 @@ namespace Doctrine\DBAL\Platforms; ...@@ -23,6 +21,7 @@ namespace Doctrine\DBAL\Platforms;
use Doctrine\DBAL\Schema\TableDiff; use Doctrine\DBAL\Schema\TableDiff;
use Doctrine\DBAL\DBALException; use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Schema\Index;
/** /**
* The MsSqlPlatform provides the behavior, features and SQL dialect of the * The MsSqlPlatform provides the behavior, features and SQL dialect of the
...@@ -37,50 +36,87 @@ use Doctrine\DBAL\DBALException; ...@@ -37,50 +36,87 @@ use Doctrine\DBAL\DBALException;
class MsSqlPlatform extends AbstractPlatform class MsSqlPlatform extends AbstractPlatform
{ {
/** /**
* Adds an adapter-specific LIMIT clause to the SELECT statement. * Whether the platform prefers identity columns for ID generation.
* [ borrowed from Zend Framework ] * MsSql prefers "autoincrement" identity columns since sequences can only
* be emulated with a table.
* *
* @param string $query * @return boolean
* @param mixed $limit * @override
* @param mixed $offset */
* @link http://lists.bestpractical.com/pipermail/rt-devel/2005-June/007339.html public function prefersIdentityColumns()
{
return true;
}
/**
* Whether the platform supports identity columns.
* MsSql supports this through AUTO_INCREMENT columns.
*
* @return boolean
* @override
*/
public function supportsIdentityColumns()
{
return true;
}
/**
* Whether the platform supports savepoints. MsSql does not.
*
* @return boolean
* @override
*/
public function supportsSavepoints()
{
return false;
}
/**
* create a new database
*
* @param string $name name of the database that should be created
* @return string * @return string
* @override * @override
*/ */
public function writeLimitClause($query, $limit = false, $offset = false) public function getCreateDatabaseSQL($name)
{ {
if ($limit > 0) { return 'CREATE DATABASE ' . $name;
$count = intval($limit); }
$offset = intval($offset); /**
if ($offset < 0) { * drop an existing database
throw DBALException::limitOffsetInvalid($offset); *
} * @param string $name name of the database that should be dropped
* @return string
$orderby = stristr($query, 'ORDER BY'); * @override
if ($orderby !== false) { */
$sort = (stripos($orderby, 'desc') !== false) ? 'desc' : 'asc'; public function getDropDatabaseSQL($name)
$order = str_ireplace('ORDER BY', '', $orderby); {
$order = trim(preg_replace('/ASC|DESC/i', '', $order)); return 'DROP DATABASE ' . $name;
} }
$query = preg_replace('/^SELECT\s/i', 'SELECT TOP ' . ($count+$offset) . ' ', $query);
$query = 'SELECT * FROM (SELECT TOP ' . $count . ' * FROM (' . $query . ') AS inner_tbl';
if ($orderby !== false) {
$query .= ' ORDER BY ' . $order . ' ';
$query .= (stripos($sort, 'asc') !== false) ? 'DESC' : 'ASC';
}
$query .= ') AS outer_tbl';
if ($orderby !== false) {
$query .= ' ORDER BY ' . $order . ' ' . $sort;
}
return $query;
/**
* @override
*/
public function quoteIdentifier($str)
{
return '[' . $str . ']';
}
/**
* @override
*/
public function getDropForeignKeySQL($foreignKey, $table)
{
if ($foreignKey instanceof \Doctrine\DBAL\Schema\ForeignKeyConstraint) {
$foreignKey = $foreignKey->getName();
} }
return $query; if ($table instanceof \Doctrine\DBAL\Schema\Table) {
$table = $table->getName();
}
return 'ALTER TABLE ' . $table . ' DROP CONSTRAINT ' . $foreignKey;
} }
/** /**
...@@ -125,66 +161,77 @@ class MsSqlPlatform extends AbstractPlatform ...@@ -125,66 +161,77 @@ class MsSqlPlatform extends AbstractPlatform
$sql = array_merge($sql, $this->_getAlterTableIndexForeignKeySQL($diff)); $sql = array_merge($sql, $this->_getAlterTableIndexForeignKeySQL($diff));
return $sql; return $sql;
} }
/** /**
* Returns the regular expression operator.
*
* @return string
* @override * @override
*/ */
public function getRegexpExpression() public function getEmptyIdentityInsertSQL($quotedTableName, $quotedIdentifierColumnName)
{ {
return 'RLIKE'; return 'INSERT INTO ' . $quotedTableName . ' DEFAULT VALUES';
} }
/** /**
* Return string to call a variable with the current timestamp inside an SQL statement
* There are three special variables for current date and time:
* - CURRENT_TIMESTAMP (date and time, TIMESTAMP type)
* - CURRENT_DATE (date, DATE type)
* - CURRENT_TIME (time, TIME type)
*
* @return string to call a variable with the current timestamp
* @override * @override
*/ */
public function getNowExpression($type = 'timestamp') public function getShowDatabasesSQL()
{ {
switch ($type) { return 'SHOW DATABASES';
case 'time':
case 'date':
case 'timestamp':
default:
return 'GETDATE()';
}
} }
/** /**
* return string to call a function to get a substring inside an SQL statement
*
* @return string to call a function to get a substring
* @override * @override
*/ */
public function getSubstringExpression($value, $position, $length = null) public function getListTablesSQL()
{ {
if ( ! is_null($length)) { return "SELECT name FROM sysobjects WHERE type = 'U' ORDER BY name";
return 'SUBSTRING(' . $value . ', ' . $position . ', ' . $length . ')';
}
return 'SUBSTRING(' . $value . ', ' . $position . ', LEN(' . $value . ') - ' . $position . ' + 1)';
} }
/** /**
* Returns string to concatenate two or more string parameters * @override
*/
public function getListTableColumnsSQL($table)
{
return 'exec sp_columns @table_name = ' . $table;
}
/**
* @override
*/
public function getListTableForeignKeysSQL($table, $database = null)
{
return "SELECT f.name AS ForeignKey,
SCHEMA_NAME (f.SCHEMA_ID) AS SchemaName,
OBJECT_NAME (f.parent_object_id) AS TableName,
COL_NAME (fc.parent_object_id,fc.parent_column_id) AS ColumnName,
SCHEMA_NAME (o.SCHEMA_ID) ReferenceSchemaName,
OBJECT_NAME (f.referenced_object_id) AS ReferenceTableName,
COL_NAME(fc.referenced_object_id,fc.referenced_column_id) AS ReferenceColumnName,
f.delete_referential_action_desc,
f.update_referential_action_desc
FROM sys.foreign_keys AS f
INNER JOIN sys.foreign_key_columns AS fc
INNER JOIN sys.objects AS o ON o.OBJECT_ID = fc.referenced_object_id
ON f.OBJECT_ID = fc.constraint_object_id
WHERE OBJECT_NAME (f.parent_object_id) = '" . $table . "'";
}
/**
* @override
*/
public function getListTableIndexesSQL($table)
{
return "exec sp_helpindex '" . $table . "'";
}
/**
* Returns the regular expression operator.
* *
* @param string $arg1 * @return string
* @param string $arg2
* @param string $values...
* @return string to concatenate two strings
* @override * @override
*/ */
public function getConcatExpression() public function getRegexpExpression()
{ {
$args = func_get_args(); return 'RLIKE';
return '(' . implode(' + ', $args) . ')';
} }
/** /**
...@@ -195,86 +242,87 @@ class MsSqlPlatform extends AbstractPlatform ...@@ -195,86 +242,87 @@ class MsSqlPlatform extends AbstractPlatform
*/ */
public function getGuidExpression() public function getGuidExpression()
{ {
return 'NEWID()'; return 'UUID()';
} }
/** /**
* Whether the platform prefers identity columns for ID generation.
* MsSql prefers "autoincrement" identity columns since sequences can only
* be emulated with a table.
*
* @return boolean
* @override * @override
*/ */
public function prefersIdentityColumns() public function getLocateExpression($str, $substr, $startPos = false)
{ {
return true; if ($startPos == false) {
return 'CHARINDEX(' . $substr . ', ' . $str . ')';
} else {
return 'CHARINDEX(' . $substr . ', ' . $str . ', '.$startPos.')';
}
} }
/** /**
* Whether the platform supports identity columns.
* MsSql supports this through AUTO_INCREMENT columns.
*
* @return boolean
* @override * @override
*/ */
public function supportsIdentityColumns() public function getModExpression($expression1, $expression2)
{ {
return true; return $expression1 . ' % ' . $expression2;
} }
/** /**
* Whether the platform supports savepoints. MsSql does not.
*
* @return boolean
* @override * @override
*/ */
public function supportsSavepoints() public function getTrimExpression($str, $pos = self::TRIM_UNSPECIFIED, $char = false)
{ {
return false; // @todo
} $trimFn = '';
$trimChar = ($char != false) ? (', ' . $char) : '';
if ($pos == self::TRIM_LEADING) {
$trimFn = 'LTRIM';
} else if($pos == self::TRIM_TRAILING) {
$trimFn = 'RTRIM';
} else {
return 'LTRIM(RTRIM(' . $str . '))';
}
public function getShowDatabasesSQL() return $trimFn . '(' . $str . ')';
{
return 'SHOW DATABASES';
} }
public function getListTablesSQL() /**
* @override
*/
public function getConcatExpression()
{ {
return 'SHOW TABLES'; $args = func_get_args();
return '(' . implode(' + ', $args) . ')';
} }
/** /**
* create a new database
*
* @param string $name name of the database that should be created
* @return string
* @override * @override
*/ */
public function getCreateDatabaseSQL($name) public function getSubstringExpression($value, $from, $len = null)
{ {
return 'CREATE DATABASE ' . $name; if ( ! is_null($len)) {
return 'SUBSTRING(' . $value . ', ' . $from . ', ' . $len . ')';
}
return 'SUBSTRING(' . $value . ', ' . $from . ', LEN(' . $value . ') - ' . $from . ' + 1)';
} }
/** /**
* drop an existing database
*
* @param string $name name of the database that should be dropped
* @return string
* @override * @override
*/ */
public function getDropDatabaseSQL($name) public function getLengthExpression($column)
{ {
return 'DROP DATABASE ' . $name; return 'LEN(' . $column . ')';
} }
/**
* @override
*/
public function getSetTransactionIsolationSQL($level) public function getSetTransactionIsolationSQL($level)
{ {
return 'SET TRANSACTION ISOLATION LEVEL ' . $this->_getTransactionIsolationLevelSQL($level); return 'SET TRANSACTION ISOLATION LEVEL ' . $this->_getTransactionIsolationLevelSQL($level);
} }
/** /**
* @override * @override
*/ */
public function getIntegerTypeDeclarationSQL(array $field) public function getIntegerTypeDeclarationSQL(array $field)
{ {
...@@ -282,21 +330,22 @@ class MsSqlPlatform extends AbstractPlatform ...@@ -282,21 +330,22 @@ class MsSqlPlatform extends AbstractPlatform
} }
/** /**
* @override * @override
*/ */
public function getBigIntTypeDeclarationSQL(array $field) public function getBigIntTypeDeclarationSQL(array $field)
{ {
return 'BIGINT' . $this->_getCommonIntegerTypeDeclarationSQL($field); return 'BIGINT' . $this->_getCommonIntegerTypeDeclarationSQL($field);
} }
/** /**
* @override * @override
*/ */
public function getSmallIntTypeDeclarationSQL(array $field) public function getSmallIntTypeDeclarationSQL(array $field)
{ {
return 'SMALLINT' . $this->_getCommonIntegerTypeDeclarationSQL($field); return 'SMALLINT' . $this->_getCommonIntegerTypeDeclarationSQL($field);
} }
/** @override */
public function getVarcharTypeDeclarationSQL(array $field) public function getVarcharTypeDeclarationSQL(array $field)
{ {
if ( ! isset($field['length'])) { if ( ! isset($field['length'])) {
...@@ -313,21 +362,21 @@ class MsSqlPlatform extends AbstractPlatform ...@@ -313,21 +362,21 @@ class MsSqlPlatform extends AbstractPlatform
return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)') return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)')
: ($length ? 'VARCHAR(' . $length . ')' : 'TEXT'); : ($length ? 'VARCHAR(' . $length . ')' : 'TEXT');
} }
/** @override */ /** @override */
public function getClobTypeDeclarationSQL(array $field) public function getClobTypeDeclarationSQL(array $field)
{ {
return 'TEXT'; return 'TEXT';
} }
/** /**
* @override * @override
*/ */
protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef) protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef)
{ {
$autoinc = ''; $autoinc = '';
if ( ! empty($columnDef['autoincrement'])) { if ( ! empty($columnDef['autoincrement'])) {
$autoinc = ' AUTO_INCREMENT'; $autoinc = ' IDENTITY';
} }
$unsigned = (isset($columnDef['unsigned']) && $columnDef['unsigned']) ? ' UNSIGNED' : ''; $unsigned = (isset($columnDef['unsigned']) && $columnDef['unsigned']) ? ' UNSIGNED' : '';
...@@ -339,7 +388,8 @@ class MsSqlPlatform extends AbstractPlatform ...@@ -339,7 +388,8 @@ class MsSqlPlatform extends AbstractPlatform
*/ */
public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration) public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration)
{ {
return 'CHAR(' . strlen('YYYY-MM-DD HH:MM:SS') . ')'; // 6 - microseconds precision length
return 'DATETIME2(6)';
} }
/** /**
...@@ -347,15 +397,15 @@ class MsSqlPlatform extends AbstractPlatform ...@@ -347,15 +397,15 @@ class MsSqlPlatform extends AbstractPlatform
*/ */
public function getDateTypeDeclarationSQL(array $fieldDeclaration) public function getDateTypeDeclarationSQL(array $fieldDeclaration)
{ {
return 'CHAR(' . strlen('YYYY-MM-DD') . ')'; return 'DATE';
} }
/** /**
* @override * @override
*/ */
public function getTimeTypeDeclarationSQL(array $fieldDeclaration) public function getTimeTypeDeclarationSQL(array $fieldDeclaration)
{ {
return 'CHAR(' . strlen('HH:MM:SS') . ')'; return 'TIME';
} }
/** /**
...@@ -366,16 +416,6 @@ class MsSqlPlatform extends AbstractPlatform ...@@ -366,16 +416,6 @@ class MsSqlPlatform extends AbstractPlatform
return 'BIT'; return 'BIT';
} }
/**
* Get the platform name for this instance
*
* @return string
*/
public function getName()
{
return 'mssql';
}
/** /**
* Adds an adapter-specific LIMIT clause to the SELECT statement. * Adds an adapter-specific LIMIT clause to the SELECT statement.
* *
...@@ -434,14 +474,14 @@ class MsSqlPlatform extends AbstractPlatform ...@@ -434,14 +474,14 @@ class MsSqlPlatform extends AbstractPlatform
$query = 'SELECT * FROM (SELECT TOP ' . $count . ' * FROM (' . $query . ') AS ' . 'inner_tbl'; $query = 'SELECT * FROM (SELECT TOP ' . $count . ' * FROM (' . $query . ') AS ' . 'inner_tbl';
if ($orderby !== false) { if ($orderby !== false) {
$query .= ' ORDER BY '; $query .= ' ORDER BY ';
for ($i = 0, $l = count($orders); $i < $l; $i++) { for ($i = 0, $l = count($orders); $i < $l; $i++) {
if ($i > 0) { // not first order clause if ($i > 0) { // not first order clause
$query .= ', '; $query .= ', ';
} }
$query .= 'inner_tbl' . '.' . $aliases[$i] . ' '; $query .= 'inner_tbl' . '.' . $aliases[$i] . ' ';
$query .= (stripos($sorts[$i], 'ASC') !== false) ? 'DESC' : 'ASC'; $query .= (stripos($sorts[$i], 'ASC') !== false) ? 'DESC' : 'ASC';
} }
} }
...@@ -449,12 +489,12 @@ class MsSqlPlatform extends AbstractPlatform ...@@ -449,12 +489,12 @@ class MsSqlPlatform extends AbstractPlatform
$query .= ') AS ' . 'outer_tbl'; $query .= ') AS ' . 'outer_tbl';
if ($orderby !== false) { if ($orderby !== false) {
$query .= ' ORDER BY '; $query .= ' ORDER BY ';
for ($i = 0, $l = count($orders); $i < $l; $i++) { for ($i = 0, $l = count($orders); $i < $l; $i++) {
if ($i > 0) { // not first order clause if ($i > 0) { // not first order clause
$query .= ', '; $query .= ', ';
} }
$query .= 'outer_tbl' . '.' . $aliases[$i] . ' ' . $sorts[$i]; $query .= 'outer_tbl' . '.' . $aliases[$i] . ' ' . $sorts[$i];
} }
...@@ -465,50 +505,69 @@ class MsSqlPlatform extends AbstractPlatform ...@@ -465,50 +505,69 @@ class MsSqlPlatform extends AbstractPlatform
} }
/** /**
* Get the insert sql for an empty insert statement * @override
*
* @param string $tableName
* @param string $identifierColumnName
* @return string $sql
*/ */
public function getEmptyIdentityInsertSQL($quotedTableName, $quotedIdentifierColumnName) public function convertBooleans($item)
{ {
return 'INSERT INTO ' . $quotedTableName . ' DEFAULT VALUES'; if (is_array($item)) {
foreach ($item as $key => $value) {
if (is_bool($value) || is_numeric($item)) {
$item[$key] = ($value) ? 'TRUE' : 'FALSE';
}
}
} else {
if (is_bool($item) || is_numeric($item)) {
$item = ($item) ? 'TRUE' : 'FALSE';
}
}
return $item;
} }
/** /**
* @inheritdoc * @override
*/ */
public function getTruncateTableSQL($tableName, $cascade = false) public function getCreateTemporaryTableSnippetSQL()
{ {
return 'TRUNCATE TABLE '.$tableName; return "CREATE TABLE";
} }
/** /**
* MsSql uses Table Hints for locking strategies instead of the ANSI SQL FOR UPDATE like hints. * @override
* */
* @return string public function getTemporaryTableName($tableName)
{
return '#' . $tableName;
}
/**
* @override
*/
public function getDateTimeFormatString()
{
return 'Y-m-d H:i:s.u';
}
/**
* @override
*/ */
public function getForUpdateSQL() public function getIndexDeclarationSQL($name, Index $index)
{ {
return ''; // @todo
return $this->getUniqueConstraintDeclarationSQL($name, $index);
} }
/** /**
* @license LGPL * Get the platform name for this instance
* @author Hibernate *
* @param string $fromClause
* @param int $lockMode
* @return string * @return string
*/ */
public function appendLockHint($fromClause, $lockMode) public function getName()
{ {
if ($lockMode == \Doctrine\DBAL\LockMode::PESSIMISTIC_WRITE) { return 'mssql';
return $fromClause . " WITH (UPDLOCK, ROWLOCK)"; }
} else if ( $lockMode == \Doctrine\DBAL\LockMode::PESSIMISTIC_READ ) {
return $fromClause . " WITH (HOLDLOCK, ROWLOCK)"; protected function initializeDoctrineTypeMappings()
} else { {
return $fromClause;
}
} }
} }
<?php <?php
/* /*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
...@@ -588,4 +586,33 @@ class MySqlPlatform extends AbstractPlatform ...@@ -588,4 +586,33 @@ class MySqlPlatform extends AbstractPlatform
{ {
return 'LOCK IN SHARE MODE'; return 'LOCK IN SHARE MODE';
} }
protected function initializeDoctrineTypeMappings()
{
$this->doctrineTypeMapping = array(
'tinyint' => 'boolean',
'smallint' => 'smallint',
'mediumint' => 'integer',
'int' => 'integer',
'integer' => 'integer',
'bigint' => 'bigint',
'tinytext' => 'text',
'mediumtext' => 'text',
'longtext' => 'text',
'text' => 'text',
'varchar' => 'string',
'string' => 'string',
'char' => 'string',
'date' => 'date',
'datetime' => 'datetime',
'timestamp' => 'datetime',
'time' => 'time',
'float' => 'decimal',
'double' => 'decimal',
'real' => 'decimal',
'decimal' => 'decimal',
'numeric' => 'decimal',
'year' => 'date',
);
}
} }
<?php <?php
/* /*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
...@@ -650,4 +648,37 @@ LEFT JOIN all_cons_columns r_cols ...@@ -650,4 +648,37 @@ LEFT JOIN all_cons_columns r_cols
{ {
return 'TRUNCATE TABLE '.$tableName; return 'TRUNCATE TABLE '.$tableName;
} }
/**
* This is for test reasons, many vendors have special requirements for dummy statements.
*
* @return string
*/
public function getDummySelectSQL()
{
return 'SELECT 1 FROM DUAL';
}
protected function initializeDoctrineTypeMappings()
{
$this->doctrineTypeMapping = array(
'integer' => 'integer',
'number' => 'integer',
'pls_integer' => 'boolean',
'binary_integer' => 'boolean',
'varchar' => 'string',
'varchar2' => 'string',
'nvarchar2' => 'string',
'char' => 'string',
'nchar' => 'string',
'date' => 'datetime',
'timestamp' => 'datetime',
'float' => 'decimal',
'long' => 'string',
'clob' => 'text',
'nclob' => 'text',
'rowid' => 'string',
'urowid' => 'string'
);
}
} }
<?php <?php
/* /*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
...@@ -642,4 +640,45 @@ class PostgreSqlPlatform extends AbstractPlatform ...@@ -642,4 +640,45 @@ class PostgreSqlPlatform extends AbstractPlatform
{ {
return 'FOR SHARE'; return 'FOR SHARE';
} }
protected function initializeDoctrineTypeMappings()
{
$this->doctrineTypeMapping = array(
'smallint' => 'smallint',
'int2' => 'smallint',
'serial' => 'integer',
'serial4' => 'integer',
'int' => 'integer',
'int4' => 'integer',
'integer' => 'integer',
'bigserial' => 'bigint',
'serial8' => 'bigint',
'bigint' => 'bigint',
'int8' => 'bigint',
'bool' => 'boolean',
'boolean' => 'boolean',
'text' => 'text',
'varchar' => 'string',
'interval' => 'string',
'_varchar' => 'string',
'char' => 'string',
'bpchar' => 'string',
'date' => 'date',
'datetime' => 'datetime',
'timestamp' => 'datetime',
'timestamptz' => 'datetime',
'time' => 'time',
'timetz' => 'time',
'float' => 'decimal',
'float4' => 'decimal',
'float8' => 'decimal',
'double' => 'decimal',
'double precision' => 'decimal',
'real' => 'decimal',
'decimal' => 'decimal',
'money' => 'decimal',
'numeric' => 'decimal',
'year' => 'date',
);
}
} }
<?php <?php
/* /*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
...@@ -433,4 +431,39 @@ class SqlitePlatform extends AbstractPlatform ...@@ -433,4 +431,39 @@ class SqlitePlatform extends AbstractPlatform
{ {
return ''; return '';
} }
protected function initializeDoctrineTypeMappings()
{
$this->doctrineTypeMapping = array(
'boolean' => 'boolean',
'tinyint' => 'boolean',
'smallint' => 'smallint',
'mediumint' => 'integer',
'int' => 'integer',
'integer' => 'integer',
'serial' => 'integer',
'bigint' => 'bigint',
'bigserial' => 'bigint',
'clob' => 'text',
'tinytext' => 'text',
'mediumtext' => 'text',
'longtext' => 'text',
'text' => 'text',
'varchar' => 'string',
'varchar2' => 'string',
'nvarchar' => 'string',
'image' => 'string',
'ntext' => 'string',
'char' => 'string',
'date' => 'date',
'datetime' => 'datetime',
'timestamp' => 'datetime',
'time' => 'time',
'float' => 'decimal',
'double' => 'decimal',
'real' => 'decimal',
'decimal' => 'decimal',
'numeric' => 'decimal',
);
}
} }
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\DBAL\Platforms;
use Doctrine\DBAL\Schema\TableDiff;
use Doctrine\DBAL\DBALException;
/**
* The SqlsrvPlatform provides the behavior, features and SQL dialect of the
* Microsoft SQL database platform.
*
* @since 2.0
* @author Juozas Kaziukenas <juozas@juokaz.com>
*/
class SqlsrvPlatform extends MsSqlPlatform
{
/**
* Get the platform name for this instance
*
* @return string
*/
public function getName()
{
return 'sqlsrv';
}
}
...@@ -66,41 +66,27 @@ class DB2SchemaManager extends AbstractSchemaManager ...@@ -66,41 +66,27 @@ class DB2SchemaManager extends AbstractSchemaManager
$unsigned = false; $unsigned = false;
$scale = false; $scale = false;
$precision = false; $precision = false;
$type = $this->_platform->getDoctrineTypeMapping($tableColumn['typename']);
switch (strtolower($tableColumn['typename'])) { switch (strtolower($tableColumn['typename'])) {
case 'smallint':
case 'bigint':
case 'integer':
case 'time':
case 'date':
$type = strtolower($tableColumn['typename']);
break;
case 'varchar': case 'varchar':
$type = 'string';
$length = $tableColumn['length']; $length = $tableColumn['length'];
$fixed = false; $fixed = false;
break; break;
case 'character': case 'character':
$type = 'string';
$length = $tableColumn['length']; $length = $tableColumn['length'];
$fixed = true; $fixed = true;
break; break;
case 'clob': case 'clob':
$type = 'text';
$length = $tableColumn['length']; $length = $tableColumn['length'];
break; break;
case 'decimal': case 'decimal':
case 'double': case 'double':
case 'real': case 'real':
$type = 'decimal';
$scale = $tableColumn['scale']; $scale = $tableColumn['scale'];
$precision = $tableColumn['length']; $precision = $tableColumn['length'];
break; break;
case 'timestamp':
$type = 'datetime';
break;
default:
throw new \Doctrine\DBAL\DBALException("Unknown Type: ".$tableColumn['typename']);
} }
$options = array( $options = array(
......
...@@ -27,373 +27,207 @@ namespace Doctrine\DBAL\Schema; ...@@ -27,373 +27,207 @@ namespace Doctrine\DBAL\Schema;
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @author Konsta Vesterinen <kvesteri@cc.hut.fi> * @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @author Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library) * @author Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
* @author Juozas Kaziukenas <juozas@juokaz.com>
* @version $Revision$ * @version $Revision$
* @since 2.0 * @since 2.0
*/ */
class MsSqlSchemaManager extends AbstractSchemaManager class MsSqlSchemaManager extends AbstractSchemaManager
{ {
/** /**
* create a new database * @override
*
* @param string $name name of the database that should be created
* @return void
*/ */
public function createDatabase($name) protected function _getPortableTableColumnDefinition($tableColumn)
{ {
$query = "CREATE DATABASE $name"; $dbType = strtolower($tableColumn['TYPE_NAME']);
if ($this->conn->options['database_device']) {
$query.= ' ON '.$this->conn->options['database_device']; if (stripos($dbType, 'identity')) {
$query.= $this->conn->options['database_size'] ? '=' . $dbType = trim(str_ireplace('identity', '', $dbType));
$this->conn->options['database_size'] : '';
} }
return $this->conn->standaloneQuery($query, null, true);
}
/** $type = array();
* drop an existing database $unsigned = $fixed = null;
*
* @param string $name name of the database that should be dropped
* @return void
*/
public function dropDatabase($name)
{
return $this->conn->standaloneQuery('DROP DATABASE ' . $name, null, true);
}
/** if ( ! isset($tableColumn['name'])) {
* alter an existing table $tableColumn['name'] = '';
*
* @param string $name name of the table that is intended to be changed.
* @param array $changes associative array that contains the details of each type
* of change that is intended to be performed. The types of
* changes that are currently supported are defined as follows:
*
* name
*
* New name for the table.
*
* add
*
* Associative array with the names of fields to be added as
* indexes of the array. The value of each entry of the array
* should be set to another associative array with the properties
* of the fields to be added. The properties of the fields should
* be the same as defined by the Metabase parser.
*
*
* remove
*
* Associative array with the names of fields to be removed as indexes
* of the array. Currently the values assigned to each entry are ignored.
* An empty array should be used for future compatibility.
*
* rename
*
* Associative array with the names of fields to be renamed as indexes
* of the array. The value of each entry of the array should be set to
* another associative array with the entry named name with the new
* field name and the entry named Declaration that is expected to contain
* the portion of the field declaration already in DBMS specific SQL code
* as it is used in the CREATE TABLE statement.
*
* change
*
* Associative array with the names of the fields to be changed as indexes
* of the array. Keep in mind that if it is intended to change either the
* name of a field and any other properties, the change array entries
* should have the new names of the fields as array indexes.
*
* The value of each entry of the array should be set to another associative
* array with the properties of the fields to that are meant to be changed as
* array entries. These entries should be assigned to the new values of the
* respective properties. The properties of the fields should be the same
* as defined by the Metabase parser.
*
* Example
* array(
* 'name' => 'userlist',
* 'add' => array(
* 'quota' => array(
* 'type' => 'integer',
* 'unsigned' => 1
* )
* ),
* 'remove' => array(
* 'file_limit' => array(),
* 'time_limit' => array()
* ),
* 'change' => array(
* 'name' => array(
* 'length' => '20',
* 'definition' => array(
* 'type' => 'text',
* 'length' => 20,
* ),
* )
* ),
* 'rename' => array(
* 'sex' => array(
* 'name' => 'gender',
* 'definition' => array(
* 'type' => 'text',
* 'length' => 1,
* 'default' => 'M',
* ),
* )
* )
* )
*
* @param boolean $check indicates whether the function should just check if the DBMS driver
* can perform the requested table alterations if the value is true or
* actually perform them otherwise.
* @return void
*/
public function alterTable($name, array $changes, $check = false)
{
foreach ($changes as $changeName => $change) {
switch ($changeName) {
case 'add':
break;
case 'remove':
break;
case 'name':
case 'rename':
case 'change':
default:
throw SchemaException::alterTableChangeNotSupported($changeName);
}
} }
$query = ''; // Map db type to Doctrine mapping type
if ( ! empty($changes['add']) && is_array($changes['add'])) { switch ($dbType) {
foreach ($changes['add'] as $fieldName => $field) { case 'tinyint':
if ($query) { $type = 'boolean';
$query .= ', '; break;
case 'smallint':
$type = 'smallint';
break;
case 'mediumint':
$type = 'integer';
break;
case 'int':
case 'integer':
$type = 'integer';
break;
case 'bigint':
$type = 'bigint';
break;
case 'tinytext':
case 'mediumtext':
case 'longtext':
case 'text':
$type = 'text';
$fixed = false;
break;
case 'varchar':
$fixed = false;
case 'string':
case 'char':
$type = 'string';
if ($tableColumn['LENGTH'] == '1') {
$type = 'boolean';
if (preg_match('/^(is|has)/', $tableColumn['name'])) {
$type = array_reverse($type);
}
} else if (strstr($dbType, 'text')) {
$type = 'text';
if ($decimal == 'binary') {
$type = 'blob';
}
} }
$query .= 'ADD ' . $this->getDeclaration($fieldName, $field); if ($fixed !== false) {
} $fixed = true;
}
if ( ! empty($changes['remove']) && is_array($changes['remove'])) {
foreach ($changes['remove'] as $fieldName => $field) {
if ($query) {
$query .= ', ';
} }
$query .= 'DROP COLUMN ' . $fieldName; break;
} case 'set':
$fixed = false;
$type = 'text';
$type = 'integer'; //FIXME:???
break;
case 'date':
$type = 'date';
break;
case 'datetime':
case 'timestamp':
$type = 'datetime';
break;
case 'time':
$type = 'time';
break;
case 'float':
case 'double':
case 'real':
case 'numeric':
case 'decimal':
$type = 'decimal';
break;
case 'tinyblob':
case 'mediumblob':
case 'longblob':
case 'blob':
case 'binary':
case 'varbinary':
$type = 'blob';
break;
case 'year':
$type = 'integer';
$type = 'date';
break;
case 'geometry':
case 'geometrycollection':
case 'point':
case 'multipoint':
case 'linestring':
case 'multilinestring':
case 'polygon':
case 'multipolygon':
$type = 'blob';
break;
default:
$type = 'string';
} }
$def = array(
'type' => $type,
'length' => ((int) $tableColumn['LENGTH'] == 0) ? null : (int) $tableColumn['LENGTH'],
'unsigned' => (bool) $unsigned,
'fixed' => (bool) $fixed
);
if ( ! $query) {
return false;
}
return $this->conn->exec('ALTER TABLE ' . $name . ' ' . $query); $default = $tableColumn['COLUMN_DEF'];
}
/** while($default != ($default2 = preg_replace("/^\((.*)\)$/", '$1', $default))) {
* {@inheritdoc} $default = $default2;
*/
public function createSequence($seqName, $start = 1, $allocationSize = 1)
{
$seqcolName = 'seq_col';
$query = 'CREATE TABLE ' . $seqName . ' (' . $seqcolName .
' INT PRIMARY KEY CLUSTERED IDENTITY(' . $start . ', 1) NOT NULL)';
$res = $this->conn->exec($query);
if ($start == 1) {
return true;
} }
try { $options = array(
$query = 'SET IDENTITY_INSERT ' . $sequenceName . ' ON ' . 'length' => ((int) $tableColumn['LENGTH'] == 0) ? null : (int) $tableColumn['LENGTH'],
'INSERT INTO ' . $sequenceName . ' (' . $seqcolName . ') VALUES ( ' . $start . ')'; 'unsigned' => (bool)$unsigned,
$res = $this->conn->exec($query); 'fixed' => (bool)$fixed,
} catch (Exception $e) { 'default' => $default !== 'NULL' ? $default : null,
$result = $this->conn->exec('DROP TABLE ' . $sequenceName); 'notnull' => (bool) ($tableColumn['IS_NULLABLE'] != 'YES'),
} 'scale' => $tableColumn['SCALE'],
return true; 'precision' => $tableColumn['PRECISION'],
} 'platformOptions' => array(
// @todo
/** 'primary' => false,
* This function drops an existing sequence 'unique' => false,
* 'autoincrement' => false,
* @param string $seqName name of the sequence to be dropped ),
* @return void );
*/
public function dropSequenceSql($seqName) return new Column($tableColumn['COLUMN_NAME'], \Doctrine\DBAL\Types\Type::getType($type), $options);
{
return 'DROP TABLE ' . $seqName;
}
/**
* lists all database sequences
*
* @param string|null $database
* @return array
*/
public function listSequences($database = null)
{
$query = "SELECT name FROM sysobjects WHERE xtype = 'U'";
$tableNames = $this->conn->fetchColumn($query);
return array_map(array($this->conn->formatter, 'fixSequenceName'), $tableNames);
} }
/** /**
* lists table constraints * @override
*
* @param string $table database table name
* @return array
*/ */
public function listTableColumns($table) protected function _getPortableTableIndexesList($tableIndexRows, $tableName=null)
{ {
$sql = 'EXEC sp_columns @table_name = ' . $table; $result = array();
$result = $this->conn->fetchAssoc($sql); foreach($tableIndexRows AS $tableIndex) {
$columns = array(); $indexName = $keyName = $tableIndex['index_name'];
if(strpos($tableIndex['index_description'], 'primary key') !== false) {
foreach ($result as $key => $val) { $keyName = 'primary';
$val = array_change_key_case($val, CASE_LOWER);
if (strstr($val['type_name'], ' ')) {
list($type, $identity) = explode(' ', $val['type_name']);
} else {
$type = $val['type_name'];
$identity = '';
}
if ($type == 'varchar') {
$type .= '(' . $val['length'] . ')';
} }
$keyName = strtolower($keyName);
$val['type'] = $type; $result[$keyName] = array(
$val['identity'] = $identity; 'name' => $indexName,
$decl = $this->conn->getDatabasePlatform()->getPortableDeclaration($val); 'columns' => explode(', ', $tableIndex['index_keys']),
'unique' => strpos($tableIndex['index_description'], 'unique') !== false,
$description = array( 'primary' => strpos($tableIndex['index_description'], 'primary key') !== false,
'name' => $val['column_name'],
'ntype' => $type,
'type' => $decl['type'][0],
'alltypes' => $decl['type'],
'length' => $decl['length'],
'fixed' => $decl['fixed'],
'unsigned' => $decl['unsigned'],
'notnull' => (bool) (trim($val['is_nullable']) === 'NO'),
'default' => $val['column_def'],
'primary' => (strtolower($identity) == 'identity'),
); );
$columns[$val['column_name']] = $description;
} }
return $columns; $indexes = array();
} foreach($result AS $indexKey => $data) {
$indexes[$indexKey] = new Index($data['name'], $data['columns'], $data['unique'], $data['primary']);
/** }
* lists table constraints
*
* @param string $table database table name
* @return array
*/
public function listTableIndexes($table)
{
}
/**
* lists tables
*
* @param string|null $database
* @return array
*/
public function listTables($database = null)
{
$sql = "SELECT name FROM sysobjects WHERE type = 'U' AND name <> 'dtproperties' ORDER BY name";
return $this->conn->fetchColumn($sql);
}
/**
* lists all triggers
*
* @return array
*/
public function listTriggers($database = null)
{
$query = "SELECT name FROM sysobjects WHERE xtype = 'TR'";
$result = $this->conn->fetchColumn($query);
return $result;
}
/**
* lists table triggers
*
* @param string $table database table name
* @return array
*/
public function listTableTriggers($table)
{
$table = $this->conn->quote($table, 'text');
$query = "SELECT name FROM sysobjects WHERE xtype = 'TR' AND object_name(parent_obj) = " . $table;
$result = $this->conn->fetchColumn($query);
return $result; return $indexes;
} }
/** /**
* lists table views * @override
*
* @param string $table database table name
* @return array
*/ */
public function listTableViews($table) public function _getPortableTableForeignKeyDefinition($tableForeignKey)
{ {
$keyName = 'INDEX_NAME'; return new ForeignKeyConstraint(
$pkName = 'PK_NAME'; (array)$tableForeignKey['ColumnName'],
if ($this->conn->getAttribute(Doctrine::ATTR_PORTABILITY) & Doctrine::PORTABILITY_FIX_CASE) { $tableForeignKey['ReferenceTableName'],
if ($this->conn->getAttribute(Doctrine::ATTR_FIELD_CASE) == CASE_LOWER) { (array)$tableForeignKey['ReferenceColumnName'],
$keyName = strtolower($keyName); $tableForeignKey['ForeignKey'],
$pkName = strtolower($pkName); array(
} else { 'onUpdate' => str_replace('_', ' ', $tableForeignKey['update_referential_action_desc']),
$keyName = strtoupper($keyName); 'onDelete' => str_replace('_', ' ', $tableForeignKey['delete_referential_action_desc']),
$pkName = strtoupper($pkName); )
} );
}
$table = $this->conn->quote($table, 'text');
$query = 'EXEC sp_statistics @table_name = ' . $table;
$indexes = $this->conn->fetchColumn($query, $keyName);
$query = 'EXEC sp_pkeys @table_name = ' . $table;
$pkAll = $this->conn->fetchColumn($query, $pkName);
$result = array();
foreach ($indexes as $index) {
if ( ! in_array($index, $pkAll) && $index != null) {
$result[] = $this->conn->formatter->fixIndexName($index);
}
}
return $result;
} }
/** /**
* lists database views * @override
*
* @param string|null $database
* @return array
*/ */
public function listViews($database = null) protected function _getPortableTableDefinition($table)
{
$query = "SELECT name FROM sysobjects WHERE xtype = 'V'";
return $this->conn->fetchColumn($query);
}
protected function _getPortableTableColumnDefinition($tableColumn)
{ {
return $column; return $table['name'];
} }
} }
\ No newline at end of file
<?php <?php
/* /*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
...@@ -89,9 +87,6 @@ class MySqlSchemaManager extends AbstractSchemaManager ...@@ -89,9 +87,6 @@ class MySqlSchemaManager extends AbstractSchemaManager
{ {
$dbType = strtolower($tableColumn['Type']); $dbType = strtolower($tableColumn['Type']);
$dbType = strtok($dbType, '(), '); $dbType = strtok($dbType, '(), ');
if ($dbType == 'national') {
$dbType = strtok('(), ');
}
if (isset($tableColumn['length'])) { if (isset($tableColumn['length'])) {
$length = $tableColumn['length']; $length = $tableColumn['length'];
$decimal = ''; $decimal = '';
...@@ -109,70 +104,10 @@ class MySqlSchemaManager extends AbstractSchemaManager ...@@ -109,70 +104,10 @@ class MySqlSchemaManager extends AbstractSchemaManager
$scale = null; $scale = null;
$precision = null; $precision = null;
// Map db type to Doctrine mapping type $type = $this->_platform->getDoctrineTypeMapping($dbType);
switch ($dbType) { switch ($dbType) {
case 'tinyint':
$type = 'boolean';
$length = null;
break;
case 'smallint':
$type = 'smallint';
$length = null;
break;
case 'mediumint':
$type = 'integer';
$length = null;
break;
case 'int':
case 'integer':
$type = 'integer';
$length = null;
break;
case 'bigint':
$type = 'bigint';
$length = null;
break;
case 'tinytext':
case 'mediumtext':
case 'longtext':
case 'text':
$type = 'text';
$fixed = false;
break;
case 'varchar':
$fixed = false;
case 'string':
case 'char': case 'char':
$type = 'string'; $fixed = true;
if ($length == '1') {
$type = 'boolean';
if (preg_match('/^(is|has)/', $tableColumn['name'])) {
$type = array_reverse($type);
}
} else if (strstr($dbType, 'text')) {
$type = 'text';
if ($decimal == 'binary') {
$type = 'blob';
}
}
if ($fixed !== false) {
$fixed = true;
}
break;
case 'set':
$fixed = false;
$type = 'text';
$type = 'integer'; //FIXME:???
break;
case 'date':
$type = 'date';
break;
case 'datetime':
case 'timestamp':
$type = 'datetime';
break;
case 'time':
$type = 'time';
break; break;
case 'float': case 'float':
case 'double': case 'double':
...@@ -184,36 +119,22 @@ class MySqlSchemaManager extends AbstractSchemaManager ...@@ -184,36 +119,22 @@ class MySqlSchemaManager extends AbstractSchemaManager
$scale = $match[2]; $scale = $match[2];
$length = null; $length = null;
} }
$type = 'decimal';
break; break;
case 'tinyint':
case 'smallint':
case 'mediumint':
case 'int':
case 'integer':
case 'bigint':
case 'tinyblob': case 'tinyblob':
case 'mediumblob': case 'mediumblob':
case 'longblob': case 'longblob':
case 'blob': case 'blob':
case 'binary': case 'binary':
case 'varbinary': case 'varbinary':
$type = 'blob';
$length = null;
break;
case 'year': case 'year':
$type = 'integer';
$type = 'date';
$length = null;
break;
case 'geometry':
case 'geometrycollection':
case 'point':
case 'multipoint':
case 'linestring':
case 'multilinestring':
case 'polygon':
case 'multipolygon':
$type = 'blob';
$length = null; $length = null;
break; break;
default:
$type = 'string';
$length = null;
} }
$length = ((int) $length == 0) ? null : (int) $length; $length = ((int) $length == 0) ? null : (int) $length;
......
...@@ -111,68 +111,57 @@ class OracleSchemaManager extends AbstractSchemaManager ...@@ -111,68 +111,57 @@ class OracleSchemaManager extends AbstractSchemaManager
$precision = null; $precision = null;
$scale = null; $scale = null;
$type = $this->_platform->getDoctrineTypeMapping($dbType);
switch ($dbType) { switch ($dbType) {
case 'integer':
case 'number': case 'number':
// @todo this sucks for the mapping stuff, is this deterministic maybe?
if($tableColumn['data_scale'] > 0) { if($tableColumn['data_scale'] > 0) {
$type = 'decimal';
$precision = $tableColumn['data_precision']; $precision = $tableColumn['data_precision'];
$scale = $tableColumn['data_scale']; $scale = $tableColumn['data_scale'];
} else { if ($precision == 0 && $scale == 1) {
$type = 'integer'; $type = 'boolean';
} else {
$type = 'decimal';
}
} }
$length = null; $length = null;
break; break;
case 'pls_integer': case 'pls_integer':
case 'binary_integer': case 'binary_integer':
$type = 'boolean';
$length = null; $length = null;
break; break;
case 'varchar': case 'varchar':
case 'varchar2': case 'varchar2':
case 'nvarchar2': case 'nvarchar2':
$fixed = false; $fixed = false;
break;
case 'char': case 'char':
case 'nchar': case 'nchar':
if ($length == '1' && preg_match('/^(is|has)/', $tableColumn['column_name'])) { $fixed = true;
$type = 'boolean';
} else {
$type = 'string';
}
if ($fixed !== false) {
$fixed = true;
}
break; break;
case 'date': case 'date':
case 'timestamp': case 'timestamp':
$type = 'datetime';
$length = null; $length = null;
break; break;
case 'float': case 'float':
$precision = $tableColumn['data_precision']; $precision = $tableColumn['data_precision'];
$scale = $tableColumn['data_scale']; $scale = $tableColumn['data_scale'];
$type = 'decimal';
$length = null; $length = null;
break; break;
case 'long':
$type = 'string';
case 'clob': case 'clob':
case 'nclob': case 'nclob':
$length = null; $length = null;
$type = 'text';
break; break;
case 'blob': case 'blob':
case 'raw': case 'raw':
case 'long raw': case 'long raw':
case 'bfile': case 'bfile':
$type = 'blob';
$length = null; $length = null;
break; break;
case 'rowid': case 'rowid':
case 'urowid': case 'urowid':
default: default:
$type = 'string';
$length = null; $length = null;
} }
......
...@@ -199,11 +199,11 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager ...@@ -199,11 +199,11 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager
$dbType = strtolower($tableColumn['type']); $dbType = strtolower($tableColumn['type']);
$type = $this->_platform->getDoctrineTypeMapping($dbType);
$autoincrement = false; $autoincrement = false;
switch ($dbType) { switch ($dbType) {
case 'smallint': case 'smallint':
case 'int2': case 'int2':
$type = 'smallint';
$length = null; $length = null;
break; break;
case 'serial': case 'serial':
...@@ -213,7 +213,6 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager ...@@ -213,7 +213,6 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager
case 'int': case 'int':
case 'int4': case 'int4':
case 'integer': case 'integer':
$type = 'integer';
$length = null; $length = null;
break; break;
case 'bigserial': case 'bigserial':
...@@ -222,52 +221,23 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager ...@@ -222,52 +221,23 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager
// break missing intentionally // break missing intentionally
case 'bigint': case 'bigint':
case 'int8': case 'int8':
$type = 'bigint';
$length = null; $length = null;
break; break;
case 'bool': case 'bool':
case 'boolean': case 'boolean':
$type = 'boolean';
$length = null; $length = null;
break; break;
case 'text': case 'text':
$fixed = false; $fixed = false;
$type = 'text';
break; break;
case 'varchar': case 'varchar':
case 'interval': case 'interval':
case '_varchar': case '_varchar':
$fixed = false; $fixed = false;
case 'tsvector': break;
case 'unknown':
case 'char': case 'char':
case 'bpchar': case 'bpchar':
$type = 'string'; $fixed = true;
if ($length == '1') {
if (preg_match('/^(is|has)/', $tableColumn['name'])) {
$type = 'boolean';
}
} elseif (strstr($dbType, 'text')) {
$type = 'text';
}
if ($fixed !== false) {
$fixed = true;
}
break;
case 'date':
$type = 'date';
$length = null;
break;
case 'datetime':
case 'timestamp':
case 'timetz':
case 'timestamptz':
$type = 'datetime';
$length = null;
break;
case 'time':
$type = 'time';
$length = null;
break; break;
case 'float': case 'float':
case 'float4': case 'float4':
...@@ -283,34 +253,10 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager ...@@ -283,34 +253,10 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager
$scale = $match[2]; $scale = $match[2];
$length = null; $length = null;
} }
$type = 'decimal';
break;
case 'tinyblob':
case 'mediumblob':
case 'longblob':
case 'blob':
case 'bytea':
case 'geometry':
case 'geometrycollection':
case 'point':
case 'multipoint':
case 'linestring':
case 'multilinestring':
case 'polygon':
case 'multipolygon':
$type = 'blob';
$length = null;
break;
case 'oid':
$type = 'blob';
$length = null;
break; break;
case 'year': case 'year':
$type = 'date';
$length = null; $length = null;
break; break;
default:
$type = 'string';
} }
$options = array( $options = array(
......
<?php <?php
/* /*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
...@@ -131,11 +129,10 @@ class SqliteSchemaManager extends AbstractSchemaManager ...@@ -131,11 +129,10 @@ class SqliteSchemaManager extends AbstractSchemaManager
} }
$dbType = strtolower($tableColumn['type']); $dbType = strtolower($tableColumn['type']);
$length = isset($tableColumn['length']) ? $tableColumn['length'] : null; $length = isset($tableColumn['length']) ? $tableColumn['length'] : null;
$unsigned = (boolean) isset($tableColumn['unsigned']) ? $tableColumn['unsigned'] : false; $unsigned = (boolean) isset($tableColumn['unsigned']) ? $tableColumn['unsigned'] : false;
$fixed = false; $fixed = false;
$type = null; $type = $this->_platform->getDoctrineTypeMapping($dbType);
$default = $tableColumn['dflt_value']; $default = $tableColumn['dflt_value'];
if ($default == 'NULL') { if ($default == 'NULL') {
$default = null; $default = null;
...@@ -150,72 +147,8 @@ class SqliteSchemaManager extends AbstractSchemaManager ...@@ -150,72 +147,8 @@ class SqliteSchemaManager extends AbstractSchemaManager
$scale = null; $scale = null;
switch ($dbType) { switch ($dbType) {
case 'boolean':
$type = 'boolean';
break;
case 'tinyint':
$type = 'boolean';
$length = null;
break;
case 'smallint':
$type = 'smallint';
$length = null;
break;
case 'mediumint':
case 'int':
case 'integer':
case 'serial':
$type = 'integer';
$length = null;
break;
case 'bigint':
case 'bigserial':
$type = 'bigint';
$length = null;
break;
case 'clob':
$fixed = false;
$type = 'text';
break;
case 'tinytext':
case 'mediumtext':
case 'longtext':
case 'text':
$type = 'text';
break;
case 'varchar':
case 'varchar2':
case 'nvarchar':
case 'ntext':
case 'image':
case 'nchar':
$fixed = false;
case 'char': case 'char':
$type = 'string'; $fixed = true;
if ($length == '1') {
$type = 'boolean';
if (preg_match('/^(is|has)/', $tableColumn['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 = 'datetime';
$length = null;
break;
case 'time':
$type = 'time';
$length = null;
break; break;
case 'float': case 'float':
case 'double': case 'double':
...@@ -223,23 +156,8 @@ class SqliteSchemaManager extends AbstractSchemaManager ...@@ -223,23 +156,8 @@ class SqliteSchemaManager extends AbstractSchemaManager
case 'decimal': case 'decimal':
case 'numeric': case 'numeric':
list($precision, $scale) = array_map('trim', explode(', ', $tableColumn['length'])); list($precision, $scale) = array_map('trim', explode(', ', $tableColumn['length']));
$type = 'decimal';
$length = null;
break;
case 'tinyblob':
case 'mediumblob':
case 'longblob':
case 'blob':
$type = 'blob';
$length = null; $length = null;
break; break;
case 'year':
$type = 'date';
$length = null;
break;
default:
$type = 'string';
$length = null;
} }
$options = array( $options = array(
......
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.org>.
*/
namespace Doctrine\DBAL\Schema;
/**
* xxx
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @author Juozas Kaziukenas <juozas@juokaz.com>
* @version $Revision$
* @since 2.0
*/
class SqlsrvSchemaManager extends MsSqlSchemaManager
{
}
\ No newline at end of file
...@@ -88,7 +88,7 @@ class ConnectionTest extends \Doctrine\Tests\DbalFunctionalTestCase ...@@ -88,7 +88,7 @@ class ConnectionTest extends \Doctrine\Tests\DbalFunctionalTestCase
{ {
try { try {
$this->_conn->transactional(function($conn) { $this->_conn->transactional(function($conn) {
$conn->executeQuery("select 1"); $conn->executeQuery($conn->getDatabasePlatform()->getDummySelectSQL());
throw new \RuntimeException("Ooops!"); throw new \RuntimeException("Ooops!");
}); });
} catch (\RuntimeException $expected) { } catch (\RuntimeException $expected) {
...@@ -99,7 +99,8 @@ class ConnectionTest extends \Doctrine\Tests\DbalFunctionalTestCase ...@@ -99,7 +99,8 @@ class ConnectionTest extends \Doctrine\Tests\DbalFunctionalTestCase
public function testTransactional() public function testTransactional()
{ {
$this->_conn->transactional(function($conn) { $this->_conn->transactional(function($conn) {
$conn->executeQuery("select 1"); /* @var $conn Connection */
$conn->executeQuery($conn->getDatabasePlatform()->getDummySelectSQL());
}); });
} }
} }
\ No newline at end of file
...@@ -27,8 +27,7 @@ class WriteTest extends \Doctrine\Tests\DbalFunctionalTestCase ...@@ -27,8 +27,7 @@ class WriteTest extends \Doctrine\Tests\DbalFunctionalTestCase
public function testExecuteUpdate() public function testExecuteUpdate()
{ {
$sql = "INSERT INTO " . $this->_conn->quoteIdentifier('write_table') . " ( " . $sql = "INSERT INTO write_table (test_int) VALUES ( " . $this->_conn->quote(1) . ")";
$this->_conn->quoteIdentifier('test_int') . " ) VALUES ( " . $this->_conn->quote(1) . ")";
$affected = $this->_conn->executeUpdate($sql); $affected = $this->_conn->executeUpdate($sql);
$this->assertEquals(1, $affected, "executeUpdate() should return the number of affected rows!"); $this->assertEquals(1, $affected, "executeUpdate() should return the number of affected rows!");
......
...@@ -32,4 +32,6 @@ class MockPlatform extends \Doctrine\DBAL\Platforms\AbstractPlatform ...@@ -32,4 +32,6 @@ class MockPlatform extends \Doctrine\DBAL\Platforms\AbstractPlatform
{ {
return 'mock'; return 'mock';
} }
protected function initializeDoctrineTypeMappings() {
}
} }
...@@ -16,6 +16,24 @@ abstract class AbstractPlatformTestCase extends \Doctrine\Tests\DbalTestCase ...@@ -16,6 +16,24 @@ abstract class AbstractPlatformTestCase extends \Doctrine\Tests\DbalTestCase
$this->_platform = $this->createPlatform(); $this->_platform = $this->createPlatform();
} }
public function testGetUnknownDoctrineMappingType()
{
$this->setExpectedException('Doctrine\DBAL\DBALException');
$this->_platform->getDoctrineTypeMapping('foobar');
}
public function testRegisterDoctrineMappingType()
{
$this->_platform->registerDoctrineTypeMapping('foo', 'integer');
$this->assertEquals('integer', $this->_platform->getDoctrineTypeMapping('foo'));
}
public function testRegisterUnknownDoctrineMappingType()
{
$this->setExpectedException('Doctrine\DBAL\DBALException');
$this->_platform->registerDoctrineTypeMapping('foo', 'bar');
}
public function testCreateWithNoColumns() public function testCreateWithNoColumns()
{ {
$table = new \Doctrine\DBAL\Schema\Table('test'); $table = new \Doctrine\DBAL\Schema\Table('test');
......
...@@ -16,13 +16,13 @@ class MsSqlPlatformTest extends AbstractPlatformTestCase ...@@ -16,13 +16,13 @@ class MsSqlPlatformTest extends AbstractPlatformTestCase
public function getGenerateTableSql() public function getGenerateTableSql()
{ {
return 'CREATE TABLE test (id INT AUTO_INCREMENT NOT NULL, test VARCHAR(255) DEFAULT NULL, PRIMARY KEY(id))'; return 'CREATE TABLE test (id INT IDENTITY NOT NULL, test VARCHAR(255) DEFAULT NULL, PRIMARY KEY(id))';
} }
public function getGenerateTableWithMultiColumnUniqueIndexSql() public function getGenerateTableWithMultiColumnUniqueIndexSql()
{ {
return array( return array(
'CREATE TABLE test (foo VARCHAR(255) DEFAULT NULL, bar VARCHAR(255) DEFAULT NULL, UNIQUE INDEX test_foo_bar_uniq (foo, bar))' 'CREATE TABLE test (foo VARCHAR(255) DEFAULT NULL, bar VARCHAR(255) DEFAULT NULL, CONSTRAINT test_foo_bar_uniq UNIQUE (foo, bar))'
); );
} }
...@@ -75,11 +75,11 @@ class MsSqlPlatformTest extends AbstractPlatformTestCase ...@@ -75,11 +75,11 @@ class MsSqlPlatformTest extends AbstractPlatformTestCase
$this->_platform->getIntegerTypeDeclarationSQL(array()) $this->_platform->getIntegerTypeDeclarationSQL(array())
); );
$this->assertEquals( $this->assertEquals(
'INT AUTO_INCREMENT', 'INT IDENTITY',
$this->_platform->getIntegerTypeDeclarationSQL(array('autoincrement' => true) $this->_platform->getIntegerTypeDeclarationSQL(array('autoincrement' => true)
)); ));
$this->assertEquals( $this->assertEquals(
'INT AUTO_INCREMENT', 'INT IDENTITY',
$this->_platform->getIntegerTypeDeclarationSQL( $this->_platform->getIntegerTypeDeclarationSQL(
array('autoincrement' => true, 'primary' => true) array('autoincrement' => true, 'primary' => true)
)); ));
......
...@@ -4,7 +4,11 @@ namespace Doctrine\Tests; ...@@ -4,7 +4,11 @@ namespace Doctrine\Tests;
class DbalFunctionalTestCase extends DbalTestCase class DbalFunctionalTestCase extends DbalTestCase
{ {
/* Shared connection when a TestCase is run alone (outside of it's functional suite) */ /**
* Shared connection when a TestCase is run alone (outside of it's functional suite)
*
* @var Doctrine\DBAL\Connection
*/
private static $_sharedConn; private static $_sharedConn;
/** /**
...@@ -14,8 +18,14 @@ class DbalFunctionalTestCase extends DbalTestCase ...@@ -14,8 +18,14 @@ class DbalFunctionalTestCase extends DbalTestCase
protected function resetSharedConn() protected function resetSharedConn()
{ {
$this->sharedFixture['conn'] = null; if ($this->sharedFixture['conn']) {
self::$_sharedConn = null; $this->sharedFixture['conn']->close();
$this->sharedFixture['conn'] = null;
}
if (self::$_sharedConn) {
self::$_sharedConn->close();
self::$_sharedConn = null;
}
} }
protected function setUp() protected function setUp()
...@@ -29,4 +39,4 @@ class DbalFunctionalTestCase extends DbalTestCase ...@@ -29,4 +39,4 @@ class DbalFunctionalTestCase extends DbalTestCase
$this->_conn = self::$_sharedConn; $this->_conn = self::$_sharedConn;
} }
} }
} }
\ No newline at end of file
...@@ -82,4 +82,6 @@ class DatabasePlatformMock extends \Doctrine\DBAL\Platforms\AbstractPlatform ...@@ -82,4 +82,6 @@ class DatabasePlatformMock extends \Doctrine\DBAL\Platforms\AbstractPlatform
{ {
return 'mock'; return 'mock';
} }
protected function initializeDoctrineTypeMappings() {
}
} }
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment