diff --git a/framework/db/Connection.php b/framework/db/Connection.php index 797508a..c4bf4b9 100644 --- a/framework/db/Connection.php +++ b/framework/db/Connection.php @@ -242,10 +242,10 @@ class Connection extends Component 'mysql' => 'yii\db\mysql\Schema', // MySQL 'sqlite' => 'yii\db\sqlite\Schema', // sqlite 3 'sqlite2' => 'yii\db\sqlite\Schema', // sqlite 2 - 'mssql' => 'yi\db\dao\mssql\Schema', // Mssql driver on windows hosts - 'sqlsrv' => 'yii\db\mssql\Schema', // Mssql + 'sqlsrv' => 'yii\db\mssql\Schema', // newer MSSQL driver on MS Windows hosts 'oci' => 'yii\db\oci\Schema', // Oracle driver - 'dblib' => 'yii\db\mssql\Schema', // dblib drivers on linux (and maybe others os) hosts + 'mssql' => 'yii\db\mssql\Schema', // older MSSQL driver on MS Windows hosts + 'dblib' => 'yii\db\mssql\Schema', // dblib drivers on GNU/Linux (and maybe other OSes) hosts ); /** * @var Transaction the currently active transaction @@ -351,7 +351,9 @@ class Connection extends Component $pdoClass = '\PDO'; if (($pos = strpos($this->dsn, ':')) !== false) { $driver = strtolower(substr($this->dsn, 0, $pos)); - if ($driver === 'mssql' || $driver === 'dblib' || $driver === 'sqlsrv') { + if ($driver === 'sqlsrv') { + $pdoClass = 'yii\db\mssql\SqlsrvPDO'; + } elseif ($driver === 'mssql' || $driver === 'dblib') { $pdoClass = 'yii\db\mssql\PDO'; } } diff --git a/framework/db/mssql/PDO.php b/framework/db/mssql/PDO.php new file mode 100644 index 0000000..e045d68 --- /dev/null +++ b/framework/db/mssql/PDO.php @@ -0,0 +1,68 @@ + + * @since 2.0 + */ +class PDO extends \PDO +{ + /** + * Returns last inserted ID value. + * + * @param string|null sequence the sequence name. Defaults to null. + * @return integer last inserted ID value. + */ + public function lastInsertId($sequence = null) + { + return $this->query('SELECT CAST(COALESCE(SCOPE_IDENTITY(), @@IDENTITY) AS bigint)')->fetchColumn(); + } + + /** + * Begin a transaction. + * + * Is is necessary to override PDO's method as MSSQL PDO drivers does not support transactions. + * + * @return boolean + */ + public function beginTransaction() + { + $this->exec('BEGIN TRANSACTION'); + return true; + } + + /** + * Commit a transaction. + * + * Is is necessary to override PDO's method as MSSQL PDO drivers does not support transactions. + * + * @return boolean + */ + public function commit() + { + $this->exec('COMMIT TRANSACTION'); + return true; + } + + /** + * Rollback a transaction. + * + * Is is necessary to override PDO's method as MSSQL PDO drivers does not support transaction. + * + * @return boolean + */ + public function rollBack() + { + $this->exec('ROLLBACK TRANSACTION'); + return true; + } +} diff --git a/framework/db/mssql/QueryBuilder.php b/framework/db/mssql/QueryBuilder.php new file mode 100644 index 0000000..988758b --- /dev/null +++ b/framework/db/mssql/QueryBuilder.php @@ -0,0 +1,19 @@ + + * @since 2.0 + */ +class QueryBuilder extends \yii\db\QueryBuilder +{ + // TODO: mssql driver +} diff --git a/framework/db/mssql/Schema.php b/framework/db/mssql/Schema.php new file mode 100644 index 0000000..8fc8aea --- /dev/null +++ b/framework/db/mssql/Schema.php @@ -0,0 +1,93 @@ + + * @since 2.0 + */ +class Schema extends \yii\db\Schema +{ + /** + * Default schema name to be used. + */ + const DEFAULT_SCHEMA = 'dbo'; + + /** + * @var array mapping from physical column types (keys) to abstract column types (values) + */ + public $typeMap = array( + // TODO: mssql driver + ); + + /** + * @param string $name + * @return TableSchema + */ + public function loadTableSchema($name) + { + return null; + } + + /** + * Quotes a table name for use in a query. + * A simple table name has no schema prefix. + * @param string $name table name. + * @return string the properly quoted table name. + */ + public function quoteSimpleTableName($name) + { + return strpos($name, '[') !== false ? $name : '[' . $name . ']'; + } + + /** + * Quotes a column name for use in a query. + * A simple column name has no prefix. + * @param string $name column name. + * @return string the properly quoted column name. + */ + public function quoteSimpleColumnName($name) + { + return strpos($name, '[') !== false || $name === '*' ? $name : '[' . $name . ']'; + } + + /** + * Creates a query builder for the MSSQL database. + * @return QueryBuilder query builder interface. + */ + public function createQueryBuilder() + { + return new QueryBuilder($this->db); + } + + /** + * Returns all table names in the database. + * This method should be overridden by child classes in order to support this feature + * because the default implementation simply throws an exception. + * @param string $schema the schema of the tables. Defaults to empty string, meaning the current or default schema. + * @return array all table names in the database. The names have NO the schema name prefix. + */ + protected function findTableNames($schema = '') + { + if ('' === $schema) { + $schema = self::DEFAULT_SCHEMA; + } + $sql = "SELECT TABLE_NAME FROM [INFORMATION_SCHEMA].[TABLES] WHERE TABLE_SCHEMA = :schema AND TABLE_TYPE = 'BASE TABLE'"; + $names = $this->db->createCommand($sql, array(':schema' => $schema))->queryColumn(); + if (self::DEFAULT_SCHEMA !== $schema) { + foreach ($names as $index => $name) { + $names[$index] = $schema . '.' . $name; + } + } + return $names; + } +} diff --git a/framework/db/mssql/SqlsrvPDO.php b/framework/db/mssql/SqlsrvPDO.php new file mode 100644 index 0000000..607d0e4 --- /dev/null +++ b/framework/db/mssql/SqlsrvPDO.php @@ -0,0 +1,33 @@ + + * @since 2.0 + */ +class SqlsrvPDO extends \PDO +{ + /** + * Returns last inserted ID value. + * + * SQLSRV driver supports PDO::lastInsertId() with one peculiarity: when $sequence value is null + * or empty string it returns empty string. But when parameter is not specified it's working + * as expected and returns actual last inserted ID (like the other PDO drivers). + * + * @param string|null $sequence the sequence name. Defaults to null. + * @return integer last inserted ID value. + */ + public function lastInsertId($sequence = null) + { + return !$sequence ? parent::lastInsertId() : parent::lastInsertId($sequence); + } +}