Merge pull request #33 from silverstripe/fixes/ifindexexists

FIX: Check index exists before dropping
This commit is contained in:
Daniel Hensby 2016-07-13 10:02:34 +01:00 committed by GitHub
commit f3574a616b

View File

@ -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;