function augmentDatabase() { $classTable = $this->owner->class; // Build a list of suffixes whose tables need versioning $allSuffixes = array(); foreach (Versioned::$versionableExtensions as $versionableExtension => $suffixes) { if ($this->owner->hasExtension($versionableExtension) && singleton($versionableExtension)->stat('enabled')) { $allSuffixes = array_merge($allSuffixes, (array) $suffixes); foreach ((array) $suffixes as $suffix) { $allSuffixes[$suffix] = $versionableExtension; } } } // Add the default table with an empty suffix to the list (table name = class name) array_push($allSuffixes, ''); foreach ($allSuffixes as $key => $suffix) { // check that this is a valid suffix if (!is_int($key)) { continue; } if ($suffix) { $table = "{$classTable}_{$suffix}"; } else { $table = $classTable; } if ($fields = $this->owner->databaseFields()) { $indexes = $this->owner->databaseIndexes(); if ($this->owner->parentClass() == "DataObject") { $rootTable = true; } if ($suffix && ($ext = $this->owner->extInstance($allSuffixes[$suffix]))) { if (!$ext->isVersionedTable($table)) { continue; } $fields = $ext->fieldsInExtraTables($suffix); $indexes = $fields['indexes']; $fields = $fields['db']; } // Create tables for other stages foreach ($this->stages as $stage) { // Extra tables for _Live, etc. if ($stage != $this->defaultStage) { DB::requireTable("{$table}_{$stage}", $fields, $indexes); /* if(!DB::query("SELECT * FROM {$table}_$stage")->value()) { $fieldList = implode(", ",array_keys($fields)); DB::query("INSERT INTO `{$table}_$stage` (ID,$fieldList) SELECT ID,$fieldList FROM `$table`"); } */ } // Version fields on each root table (including Stage) if (isset($rootTable)) { $stageTable = $stage == $this->defaultStage ? $table : "{$table}_{$stage}"; DB::requireField($stageTable, "Version", "int(11) not null default '0'"); } } // Create table for all versions $versionFields = array_merge(array("RecordID" => "Int", "Version" => "Int", "WasPublished" => "Boolean", "AuthorID" => "Int", "PublisherID" => "Int"), (array) $fields); $versionIndexes = array_merge(array('RecordID_Version' => '(RecordID, Version)', 'RecordID' => true, 'Version' => true, 'AuthorID' => true, 'PublisherID' => true), (array) $indexes); DB::requireTable("{$table}_versions", $versionFields, $versionIndexes); /* if(!DB::query("SELECT * FROM {$table}_versions")->value()) { $fieldList = implode(", ",array_keys($fields)); DB::query("INSERT INTO `{$table}_versions` ($fieldList, RecordID, Version) SELECT $fieldList, ID AS RecordID, 1 AS Version FROM `$table`"); } */ } else { DB::dontRequireTable("{$table}_versions"); foreach ($this->stages as $stage) { if ($stage != $this->defaultStage) { DB::dontrequireTable("{$table}_{$stage}"); } } } } }
function augmentDatabase() { $classTable = $this->owner->class; $isRootClass = $this->owner->class == ClassInfo::baseDataClass($this->owner->class); // Build a list of suffixes whose tables need versioning $allSuffixes = array(); foreach (Versioned::$versionableExtensions as $versionableExtension => $suffixes) { if ($this->owner->hasExtension($versionableExtension)) { $allSuffixes = array_merge($allSuffixes, (array) $suffixes); foreach ((array) $suffixes as $suffix) { $allSuffixes[$suffix] = $versionableExtension; } } } // Add the default table with an empty suffix to the list (table name = class name) array_push($allSuffixes, ''); foreach ($allSuffixes as $key => $suffix) { // check that this is a valid suffix if (!is_int($key)) { continue; } if ($suffix) { $table = "{$classTable}_{$suffix}"; } else { $table = $classTable; } if ($fields = DataObject::database_fields($this->owner->class)) { $indexes = $this->owner->databaseIndexes(); if ($suffix && ($ext = $this->owner->getExtensionInstance($allSuffixes[$suffix]))) { if (!$ext->isVersionedTable($table)) { continue; } $ext->setOwner($this->owner); $fields = $ext->fieldsInExtraTables($suffix); $ext->clearOwner(); $indexes = $fields['indexes']; $fields = $fields['db']; } // Create tables for other stages foreach ($this->stages as $stage) { // Extra tables for _Live, etc. if ($stage != $this->defaultStage) { DB::requireTable("{$table}_{$stage}", $fields, $indexes, false); } // Version fields on each root table (including Stage) /* if($isRootClass) { $stageTable = ($stage == $this->defaultStage) ? $table : "{$table}_$stage"; $parts=Array('datatype'=>'int', 'precision'=>11, 'null'=>'not null', 'default'=>(int)0); $values=Array('type'=>'int', 'parts'=>$parts); DB::requireField($stageTable, 'Version', $values); } */ } if ($isRootClass) { // Create table for all versions $versionFields = array_merge(self::$db_for_versions_table, (array) $fields); $versionIndexes = array_merge(self::$indexes_for_versions_table, (array) $indexes); } else { // Create fields for any tables of subclasses $versionFields = array_merge(array("RecordID" => "Int", "Version" => "Int"), (array) $fields); $versionIndexes = array_merge(array('RecordID_Version' => array('type' => 'unique', 'value' => 'RecordID,Version'), 'RecordID' => true, 'Version' => true), (array) $indexes); } if (DB::getConn()->hasTable("{$table}_versions")) { // Fix data that lacks the uniqueness constraint (since this was added later and // bugs meant that the constraint was validated) $duplications = DB::query("SELECT MIN(\"ID\") AS \"ID\", \"RecordID\", \"Version\" \n\t\t\t\t\t\tFROM \"{$table}_versions\" GROUP BY \"RecordID\", \"Version\" \n\t\t\t\t\t\tHAVING COUNT(*) > 1"); foreach ($duplications as $dup) { DB::alteration_message("Removing {$table}_versions duplicate data for " . "{$dup['RecordID']}/{$dup['Version']}", "deleted"); DB::query("DELETE FROM \"{$table}_versions\" WHERE \"RecordID\" = {$dup['RecordID']}\n\t\t\t\t\t\t\tAND \"Version\" = {$dup['Version']} AND \"ID\" != {$dup['ID']}"); } // Remove junk which has no data in parent classes. Only needs to run the following // when versioned data is spread over multiple tables if (!$isRootClass && ($versionedTables = ClassInfo::dataClassesFor($table))) { foreach ($versionedTables as $child) { if ($table == $child) { break; } // only need subclasses $count = DB::query("\n\t\t\t\t\t\t\t\tSELECT COUNT(*) FROM \"{$table}_versions\"\n\t\t\t\t\t\t\t\tLEFT JOIN \"{$child}_versions\" \n\t\t\t\t\t\t\t\t\tON \"{$child}_versions\".\"RecordID\" = \"{$table}_versions\".\"RecordID\"\n\t\t\t\t\t\t\t\t\tAND \"{$child}_versions\".\"Version\" = \"{$table}_versions\".\"Version\"\n\t\t\t\t\t\t\t\tWHERE \"{$child}_versions\".\"ID\" IS NULL\n\t\t\t\t\t\t\t")->value(); if ($count > 0) { DB::alteration_message("Removing orphaned versioned records", "deleted"); $effectedIDs = DB::query("\n\t\t\t\t\t\t\t\t\tSELECT \"{$table}_versions\".\"ID\" FROM \"{$table}_versions\"\n\t\t\t\t\t\t\t\t\tLEFT JOIN \"{$child}_versions\" \n\t\t\t\t\t\t\t\t\t\tON \"{$child}_versions\".\"RecordID\" = \"{$table}_versions\".\"RecordID\"\n\t\t\t\t\t\t\t\t\t\tAND \"{$child}_versions\".\"Version\" = \"{$table}_versions\".\"Version\"\n\t\t\t\t\t\t\t\t\tWHERE \"{$child}_versions\".\"ID\" IS NULL\n\t\t\t\t\t\t\t\t")->column(); if (is_array($effectedIDs)) { foreach ($effectedIDs as $key => $value) { DB::query("DELETE FROM \"{$table}_versions\" WHERE \"{$table}_versions\".\"ID\" = '{$value}'"); } } } } } } DB::requireTable("{$table}_versions", $versionFields, $versionIndexes); } else { DB::dontRequireTable("{$table}_versions"); foreach ($this->stages as $stage) { if ($stage != $this->defaultStage) { DB::dontrequireTable("{$table}_{$stage}"); } } } } }
function augmentDatabase() { $classTable = $this->owner->class; $isRootClass = $this->owner->class == ClassInfo::baseDataClass($this->owner->class); // Build a list of suffixes whose tables need versioning $allSuffixes = array(); foreach (Versioned::$versionableExtensions as $versionableExtension => $suffixes) { if ($this->owner->hasExtension($versionableExtension) && singleton($versionableExtension)->stat('enabled')) { $allSuffixes = array_merge($allSuffixes, (array) $suffixes); foreach ((array) $suffixes as $suffix) { $allSuffixes[$suffix] = $versionableExtension; } } } // Add the default table with an empty suffix to the list (table name = class name) array_push($allSuffixes, ''); foreach ($allSuffixes as $key => $suffix) { // check that this is a valid suffix if (!is_int($key)) { continue; } if ($suffix) { $table = "{$classTable}_{$suffix}"; } else { $table = $classTable; } if ($fields = $this->owner->databaseFields()) { $indexes = $this->owner->databaseIndexes(); if ($suffix && ($ext = $this->owner->extInstance($allSuffixes[$suffix]))) { if (!$ext->isVersionedTable($table)) { continue; } $fields = $ext->fieldsInExtraTables($suffix); $indexes = $fields['indexes']; $fields = $fields['db']; } // Create tables for other stages foreach ($this->stages as $stage) { // Extra tables for _Live, etc. if ($stage != $this->defaultStage) { DB::requireTable("{$table}_{$stage}", $fields, $indexes); } // Version fields on each root table (including Stage) if ($isRootClass) { $stageTable = $stage == $this->defaultStage ? $table : "{$table}_{$stage}"; DB::requireField($stageTable, "Version", "int(11) not null default '0'"); } } if ($isRootClass) { // Create table for all versions $versionFields = array_merge(array("RecordID" => "Int", "Version" => "Int", "WasPublished" => "Boolean", "AuthorID" => "Int", "PublisherID" => "Int"), (array) $fields); $versionIndexes = array_merge(array('RecordID_Version' => '(RecordID, Version)', 'RecordID' => true, 'Version' => true, 'AuthorID' => true, 'PublisherID' => true), (array) $indexes); } else { // Create fields for any tables of subclasses $versionFields = array_merge(array("RecordID" => "Int", "Version" => "Int"), (array) $fields); $versionIndexes = array_merge(array('RecordID_Version' => '(RecordID, Version)', 'RecordID' => true, 'Version' => true), (array) $indexes); } DB::requireTable("{$table}_versions", $versionFields, $versionIndexes); } else { DB::dontRequireTable("{$table}_versions"); foreach ($this->stages as $stage) { if ($stage != $this->defaultStage) { DB::dontrequireTable("{$table}_{$stage}"); } } } } }