From fe0a640c397254990ac76d45b706939130a140f6 Mon Sep 17 00:00:00 2001 From: Geoff Munn Date: Wed, 17 Dec 2008 00:40:24 +0000 Subject: [PATCH] API CHANGE: fulltext and unique indexes are now arrays API CHANGE: db/build now no longer notifies you of changes which haven't actually happened. git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@69303 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- core/model/Database.php | 16 ++++++++++----- core/model/MySQLDatabase.php | 40 ++++++++++++++++++++++++++++++++---- core/model/SiteTree.php | 12 +++++------ filesystem/File.php | 2 +- security/Member.php | 3 ++- 5 files changed, 56 insertions(+), 17 deletions(-) diff --git a/core/model/Database.php b/core/model/Database.php index d76623636..ef2262675 100755 --- a/core/model/Database.php +++ b/core/model/Database.php @@ -278,10 +278,14 @@ abstract class Database extends Object { function requireIndex($table, $index, $spec) { $newTable = false; + //DB Abstraction: remove this ===true option as a possibility? if($spec === true) { $spec = "($index)"; } - $spec = ereg_replace(" *, *",",",$spec); + + //Indexes specified as arrays cannot be checked with this line: (it flattens out the array) + if(!is_array($spec)) + $spec = ereg_replace(" *, *",",",$spec); if(!isset($this->tableList[strtolower($table)])) $newTable = true; @@ -291,9 +295,10 @@ abstract class Database extends Object { if($newTable || !isset($this->indexList[$table][$index])) { $this->transCreateIndex($table, $index, $spec); Database::alteration_message("Index $table.$index: created as $spec","created"); - } else if($this->indexList[$table][$index] != $spec) { + } else if($this->indexList[$table][$index] != DB::getConn()->convertIndexSpec($spec)) { $this->transAlterIndex($table, $index, $spec); - Database::alteration_message("Index $table.$index: changed to $spec (from {$this->indexList[$table][$index]})","changed"); + $spec_msg=DB::getConn()->convertIndexSpec($spec); + Database::alteration_message("Index $table.$index: changed to $spec_msg (from {$this->indexList[$table][$index]})","changed"); } } @@ -329,7 +334,7 @@ abstract class Database extends Object { $this->transCreateField($table, $field, $spec); Profiler::unmark('createField'); Database::alteration_message("Field $table.$field: created as $spec","created"); - } else if($this->fieldList[$table][$field] != $spec) { + } else if($this->fieldList[$table][$field] != DB::getConn()->convertIndexSpec($spec)) { // If enums are being modified, then we need to fix existing data in the table. // Update any records where the enum is set to a legacy value to be set to the default. // One hard-coded exception is SiteTree - the default for this is Page. @@ -363,7 +368,8 @@ abstract class Database extends Object { Profiler::mark('alterField'); $this->transAlterField($table, $field, $spec); Profiler::unmark('alterField'); - Database::alteration_message("Field $table.$field: changed to $spec (from {$this->fieldList[$table][$field]})","changed"); + $spec_msg=DB::getConn()->convertIndexSpec($spec); + Database::alteration_message("Field $table.$field: changed to $spec_msg (from {$this->fieldList[$table][$field]})","changed"); } Profiler::unmark('requireField'); } diff --git a/core/model/MySQLDatabase.php b/core/model/MySQLDatabase.php index 372bfc372..47bc9d9aa 100644 --- a/core/model/MySQLDatabase.php +++ b/core/model/MySQLDatabase.php @@ -285,7 +285,10 @@ class MySQLDatabase extends Database { } if($field['Default'] || $field['Default'] === "0") { - $fieldSpec .= " default '" . addslashes($field['Default']) . "'"; + if(is_numeric($field['Default'])) + $fieldSpec .= " default " . addslashes($field['Default']); + else + $fieldSpec .= " default '" . addslashes($field['Default']) . "'"; } if($field['Extra']) $fieldSpec .= " $field[Extra]"; @@ -304,13 +307,39 @@ class MySQLDatabase extends Database { $this->query("ALTER TABLE \"$tableName\" ADD " . $this->getIndexSqlDefinition($indexName, $indexSpec)); } + /* + * This takes the index spec which has been provided by a class (ie static $indexes = blah blah) + * and turns it into a proper string. + * 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)){ + //Here we create a db-specific version of whatever index we need to create. + switch($indexSpec['type']){ + case 'fulltext': + $indexSpec='fulltext (' . str_replace(' ', '', $indexSpec['value']) . ')'; + break; + case 'unique': + $indexSpec='unique (' . $indexSpec['value'] . ')'; + break; + } + } + + return $indexSpec; + } + protected function getIndexSqlDefinition($indexName, $indexSpec) { - $indexSpec = trim($indexSpec); + + $indexSpec=$this->convertIndexSpec($indexSpec); + + $indexSpec = trim($indexSpec); if($indexSpec[0] != '(') list($indexType, $indexFields) = explode(' ',$indexSpec,2); else $indexFields = $indexSpec; if(!isset($indexType)) { $indexType = "index"; } + return "$indexType \"$indexName\" $indexFields"; } @@ -321,7 +350,10 @@ class MySQLDatabase extends Database { * @param string $indexSpec The specification of the index, see Database::requireIndex() for more details. */ public function alterIndex($tableName, $indexName, $indexSpec) { - $indexSpec = trim($indexSpec); + + $indexSpec=$this->convertIndexSpec($indexSpec); + + $indexSpec = trim($indexSpec); if($indexSpec[0] != '(') { list($indexType, $indexFields) = explode(' ',$indexSpec,2); } else { @@ -450,7 +482,7 @@ class MySQLDatabase extends Database { //$parts=Array('datatype'=>'enum', 'enums'=>$this->enum, 'character set'=>'utf8', 'collate'=> 'utf8_general_ci', 'default'=>$this->default); //DB::requireField($this->tableName, $this->name, "enum('" . implode("','", $this->enum) . "') character set utf8 collate utf8_general_ci default '{$this->default}'"); - return 'enum(\'' . implode('\', \'', $values['enums']) . '\') character set utf8 collate utf8_general_ci default \'' . $values['default'] . '\''; + return 'enum(\'' . implode('\',\'', $values['enums']) . '\') character set utf8 collate utf8_general_ci default \'' . $values['default'] . '\''; } /** diff --git a/core/model/SiteTree.php b/core/model/SiteTree.php index 0df8bae67..bdc5d03ca 100644 --- a/core/model/SiteTree.php +++ b/core/model/SiteTree.php @@ -86,8 +86,8 @@ class SiteTree extends DataObject implements PermissionProvider { ); static $indexes = array( - "SearchFields" => "fulltext (Title, MenuTitle, Content, MetaTitle, MetaDescription, MetaKeywords)", - "TitleSearchFields" => "fulltext (Title)", + "SearchFields" => Array('type'=>'fulltext', 'value'=>'Title, MenuTitle, Content, MetaTitle, MetaDescription, MetaKeywords'), + "TitleSearchFields" => Array('type'=>'fulltext', 'value'=>'Title'), "URLSegment" => true, ); @@ -1202,7 +1202,7 @@ class SiteTree extends DataObject implements PermissionProvider { ) //new NamedLabelField("Status", $message, "pageStatusMessage", true) ); - + if(!Permission::check('SITETREE_GRANT_ACCESS')) { $fields->makeFieldReadonly($viewersOptionsField); $fields->makeFieldReadonly($viewerGroupsField); @@ -1314,12 +1314,12 @@ class SiteTree extends DataObject implements PermissionProvider { $actions->push(new FormAction('save',_t('CMSMain.SAVE','Save'))); } } - + if($this->canPublish()) { // "publish" $actions->push(new FormAction('publish', _t('SiteTree.BUTTONSAVEPUBLISH', 'Save and Publish'))); } - + // getCMSActions() can be extended with updateCMSActions() on a decorator $this->extend('updateCMSActions', $actions); @@ -1692,7 +1692,7 @@ class SiteTree extends DataObject implements PermissionProvider { public static function enableCMSFieldsExtensions() { self::$runCMSFieldsExtensions = true; } - + function providePermissions() { return array( 'SITETREE_GRANT_ACCESS' => _t( diff --git a/filesystem/File.php b/filesystem/File.php index ea34cb618..19583e0fb 100755 --- a/filesystem/File.php +++ b/filesystem/File.php @@ -25,7 +25,7 @@ class File extends DataObject { ); static $indexes = array( - "SearchFields" => "fulltext (Filename,Title,Content)", + "SearchFields" => Array('type'=>'fulltext', 'value'=>'Filename,Title,Content'), ); static $has_one = array( diff --git a/security/Member.php b/security/Member.php index 4b943e0a4..e0255e596 100644 --- a/security/Member.php +++ b/security/Member.php @@ -39,7 +39,8 @@ class Member extends DataObject { static $indexes = array( 'Email' => true, - 'AutoLoginHash' => 'unique (AutoLoginHash)' + //'AutoLoginHash' => 'unique (AutoLoginHash)' + 'AutoLoginHash' => Array('type'=>'unique', 'value'=>'AutoLoginHash') ); static $notify_password_change = false;