mirror of
https://github.com/silverstripe/silverstripe-mssql
synced 2024-10-22 08:05:53 +02:00
Fixing MSSQLDatabase to conform to dev/build change detection
This involves changing a few things around so that it's closer to how the MySQLDatabase adapter works. indexList() should return an array in the same format instead of using arbitrary "indexname" and "spec". indexNames() has also been introduced to MSSQLDatabase so that we can drop all indexes (except for fulltext and primary key indexes) on a table when altering the table columns, this helps when constraints not directly related to a modified column refuse to allow changes.
This commit is contained in:
parent
91548f76be
commit
d6a075f9c7
@ -613,8 +613,11 @@ class MSSQLDatabase extends SS_Database {
|
||||
|
||||
// drop the index if it exists
|
||||
$alterCol='';
|
||||
$indexName = isset($indexList[$colName]['indexname']) ? $indexList[$colName]['indexname'] : null;
|
||||
if($indexName && $colName != 'ID') {
|
||||
|
||||
// drop *ALL* indexes on a table before proceeding
|
||||
// this won't drop primary keys, though
|
||||
$indexes = $this->indexNames($tableName);
|
||||
foreach($indexes as $indexName) {
|
||||
$alterCol = "\nDROP INDEX \"$indexName\" ON \"$tableName\";";
|
||||
}
|
||||
|
||||
@ -815,10 +818,10 @@ class MSSQLDatabase extends SS_Database {
|
||||
* Some indexes may be arrays, such as fulltext and unique indexes, and this allows database-specific
|
||||
* arrays to be created.
|
||||
*/
|
||||
public function convertIndexSpec($indexSpec){
|
||||
if(is_array($indexSpec)){
|
||||
public function convertIndexSpec($indexSpec) {
|
||||
if(is_array($indexSpec)) {
|
||||
//Here we create a db-specific version of whatever index we need to create.
|
||||
switch($indexSpec['type']){
|
||||
switch($indexSpec['type']) {
|
||||
case 'fulltext':
|
||||
$indexSpec='fulltext (' . str_replace(' ', '', $indexSpec['value']) . ')';
|
||||
break;
|
||||
@ -906,34 +909,50 @@ class MSSQLDatabase extends SS_Database {
|
||||
|
||||
foreach($indexes as $index) {
|
||||
if(strpos($index['index_description'], 'unique') !== false) {
|
||||
$prefix='unique ';
|
||||
$prefix = 'unique ';
|
||||
}
|
||||
|
||||
$key = str_replace(', ', ',', $index['index_keys']);
|
||||
$indexList[$key]['indexname'] = $index['index_name'];
|
||||
$indexList[$key]['spec'] = $prefix . '(' . $key . ')';
|
||||
$name = str_replace(', ', ',', $index['index_keys']);
|
||||
|
||||
// ensure each piece of the index name is quoted, e.g. RecordID,Version
|
||||
// should be "RecordID","Version"
|
||||
$fields = explode(',', $name);
|
||||
if(!$fields) $fields = array($name);
|
||||
ksort($fields);
|
||||
|
||||
$indexList[$name] = $prefix . '("' . implode('","', $fields) . '")';
|
||||
}
|
||||
|
||||
// Now we need to check to see if we have any fulltext indexes attached to this table:
|
||||
// separately build up a list of the fulltext indexes for this table
|
||||
// as MSSQL doesn't return fulltext indexes in sp_helpindex
|
||||
if($this->fullTextEnabled()) {
|
||||
$result = DB::query('EXEC sp_help_fulltext_columns;');
|
||||
$columns = '';
|
||||
$columns = array();
|
||||
|
||||
foreach($result as $row) {
|
||||
if($row['TABLE_NAME'] == $table) {
|
||||
$columns .= $row['FULLTEXT_COLUMN_NAME'] . ',';
|
||||
$columns[] = $row['FULLTEXT_COLUMN_NAME'];
|
||||
}
|
||||
}
|
||||
|
||||
if($columns!=''){
|
||||
$columns=trim($columns, ',');
|
||||
$indexList['SearchFields']['indexname'] = 'SearchFields';
|
||||
$indexList['SearchFields']['spec'] = 'fulltext (' . $columns . ')';
|
||||
}
|
||||
$indexList['SearchFields'] = 'fulltext ("' . implode('","', $columns) . '")';
|
||||
}
|
||||
|
||||
return $indexList;
|
||||
}
|
||||
|
||||
/**
|
||||
* For a given table name, get all the internal index names,
|
||||
* except for those that are primary keys and fulltext indexes.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function indexNames($tableName) {
|
||||
return $this->query(sprintf('SELECT ind.name FROM sys.indexes ind
|
||||
INNER JOIN sys.tables t ON ind.object_id = t.object_id
|
||||
WHERE is_primary_key = 0 AND t.name = \'%s\'', $tableName))->column();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all the tables in the database.
|
||||
* Table names will all be in lowercase.
|
||||
|
Loading…
Reference in New Issue
Block a user