From 2e64e44087a0a7e6a49924591d753bfd5df8532f Mon Sep 17 00:00:00 2001 From: Will Rossiter Date: Wed, 13 Jul 2016 14:47:38 +1200 Subject: [PATCH] FIX: Check index exists before dropping --- code/MSSQLSchemaManager.php | 51 +++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/code/MSSQLSchemaManager.php b/code/MSSQLSchemaManager.php index da1b13f..eb00d81 100644 --- a/code/MSSQLSchemaManager.php +++ b/code/MSSQLSchemaManager.php @@ -2,7 +2,7 @@ /** * Represents and handles all schema management for a MS SQL database - * + * * @package mssql */ class MSSQLSchemaManager extends DBSchemaManager @@ -10,16 +10,16 @@ class MSSQLSchemaManager extends DBSchemaManager /** * Stores per-request cached constraint checks that come from the database. - * + * * @var array */ protected static $cached_checks = array(); - + /** * Builds the internal MS SQL Server index name given the silverstripe table and index name - * + * * @param string $tableName - * @param string $indexName + * @param string $indexName * @param string $prefix The optional prefix for the index. Defaults to "ix" for indexes. * @return string The name of the index */ @@ -36,7 +36,7 @@ class MSSQLSchemaManager extends DBSchemaManager /** * This will set up the full text search capabilities. - * + * * @param string $name Name of full text catalog to use */ public function createFullTextCatalog($name = 'ftCatalog') @@ -49,7 +49,7 @@ class MSSQLSchemaManager extends DBSchemaManager /** * Check that a fulltext catalog has been created yet. - * + * * @param string $name Name of full text catalog to use * @return boolean */ @@ -75,7 +75,7 @@ class MSSQLSchemaManager extends DBSchemaManager if (!$this->database->fullTextEnabled()) { return; } - + $this->query("EXEC sp_fulltext_catalog 'ftCatalog', 'Rebuild';"); // Busy wait until it's done updating, but no longer than 15 seconds. @@ -93,7 +93,7 @@ class MSSQLSchemaManager extends DBSchemaManager /** * Check if a fulltext index exists on a particular table name. - * + * * @param string $tableName * @return boolean TRUE index exists | FALSE index does not exist | NULL no support */ @@ -115,7 +115,7 @@ class MSSQLSchemaManager extends DBSchemaManager /** * MSSQL stores the primary key column with an internal identifier, * so a lookup needs to be done to determine it. - * + * * @param string $tableName Name of table with primary key column "ID" * @return string Internal identifier for primary key */ @@ -135,7 +135,7 @@ class MSSQLSchemaManager extends DBSchemaManager /** * Gets the identity column of a table - * + * * @param string $tableName * @return string|null */ @@ -158,7 +158,7 @@ class MSSQLSchemaManager extends DBSchemaManager { $this->query("CREATE DATABASE \"$name\""); } - + public function dropDatabase($name) { $this->query("DROP DATABASE \"$name\""); @@ -174,7 +174,7 @@ class MSSQLSchemaManager extends DBSchemaManager } return false; } - + public function databaseList() { return $this->query('SELECT NAME FROM sys.sysdatabases')->column(); @@ -276,7 +276,7 @@ class MSSQLSchemaManager extends DBSchemaManager /** * Given the table and column name, retrieve the constraint name for that column * in the table. - * + * * @param string $tableName Table name column resides in * @param string $columnName Column name the constraint is for * @return string|null @@ -294,11 +294,11 @@ class MSSQLSchemaManager extends DBSchemaManager /** * Given a table and column name, return a check constraint clause for that column in * the table. - * + * * This is an expensive query, so it is cached per-request and stored by table. The initial * call for a table that has not been cached will query all columns and store that * so subsequent calls are fast. - * + * * @param string $tableName Table name column resides in * @param string $columnName Column name the constraint is for * @return string The check string @@ -325,7 +325,7 @@ class MSSQLSchemaManager extends DBSchemaManager $checks[$record['COLUMN_NAME']] = $record['CHECK_CLAUSE']; } self::$cached_checks[$tableName] = $checks; - + // Return via cached records return $this->getConstraintCheckClause($tableName, $columnName); } @@ -333,7 +333,7 @@ class MSSQLSchemaManager extends DBSchemaManager /** * Return the name of the default constraint applied to $tableName.$colName. * Will return null if no such constraint exists - * + * * @param string $tableName Name of the table * @param string $colName Name of the column * @return string|null @@ -354,7 +354,7 @@ class MSSQLSchemaManager extends DBSchemaManager /** * Get enum values from a constraint check clause. - * + * * @param string $clause Check clause to parse values from * @return array Enum values */ @@ -395,8 +395,9 @@ class MSSQLSchemaManager extends DBSchemaManager // drop *ALL* indexes on a table before proceeding // this won't drop primary keys, though $indexes = $this->indexNames($tableName); + foreach ($indexes as $indexName) { - $alterQueries[] = "DROP INDEX \"$indexName\" ON \"$tableName\";"; + $alterQueries[] = "\nIF EXISTS (SELECT name FROM sys.indexes WHERE name = '$indexName' AND object_id = object_id('schema.$tableName')) DROP INDEX \"$indexName\" ON \"$tableName\";"; } $prefix = "ALTER TABLE \"$tableName\" "; @@ -413,7 +414,7 @@ class MSSQLSchemaManager extends DBSchemaManager // SET null / not null $nullFragment = empty($matches['null']) ? '' : " {$matches['null']}"; $alterQueries[] = "$prefix ALTER COLUMN \"$colName\" {$matches['definition']}$nullFragment;"; - + // Add a default back if (!empty($matches['default'])) { $alterQueries[] = "$prefix ADD {$matches['default']} FOR \"$colName\";"; @@ -583,10 +584,10 @@ class MSSQLSchemaManager extends DBSchemaManager { $this->query($this->getIndexSqlDefinition($tableName, $indexName, $indexSpec)); } - + /** * Return SQL for dropping and recreating an index - * + * * @param string $tableName Name of table to create this index against * @param string $indexName Name of this index * @param array|string $indexSpec Index specification, either as a raw string @@ -698,7 +699,7 @@ class MSSQLSchemaManager extends DBSchemaManager array($tableName) )->column(); } - + public function tableList() { $tables = array(); @@ -930,7 +931,7 @@ class MSSQLSchemaManager extends DBSchemaManager return ''; } } - + protected function indexKey($table, $index, $spec) { return $index;