mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
API TableBuilder class reduces inconsistency between temp & prod db
This commit is contained in:
parent
33600c3b73
commit
29fae72211
69
src/ORM/Connect/TableBuilder.php
Normal file
69
src/ORM/Connect/TableBuilder.php
Normal file
@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\ORM\Connect;
|
||||
|
||||
use SilverStripe\Control\Director;
|
||||
use SilverStripe\Core\Injector\Injectable;
|
||||
use SilverStripe\Dev\TestOnly;
|
||||
use SilverStripe\ORM\DataObject;
|
||||
use SilverStripe\ORM\DB;
|
||||
|
||||
class TableBuilder
|
||||
{
|
||||
use Injectable;
|
||||
|
||||
public function buildTables(DBSchemaManager $dbSchema, array $dataClasses, array $extraDataObjects = [], bool $quiet = false, bool $testMode = false, bool $showRecordCounts = false)
|
||||
{
|
||||
$dbSchema->schemaUpdate(function () use ($dataClasses, $extraDataObjects, $testMode, $quiet, $showRecordCounts) {
|
||||
$dataObjectSchema = DataObject::getSchema();
|
||||
|
||||
foreach ($dataClasses as $dataClass) {
|
||||
// Check if class exists before trying to instantiate - this sidesteps any manifest weirdness
|
||||
if (!class_exists($dataClass)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if this class should be excluded as per testing conventions
|
||||
/** @var DataObject $SNG */
|
||||
$SNG = new $dataClass([], DataObject::CREATE_SINGLETON);
|
||||
if (!$testMode && $SNG instanceof TestOnly) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Log data
|
||||
if (!$quiet) {
|
||||
$tableName = $dataObjectSchema->tableName($dataClass);
|
||||
if ($showRecordCounts && DB::get_schema()->hasTable($tableName)) {
|
||||
try {
|
||||
$count = DB::query("SELECT COUNT(*) FROM \"$tableName\"")->value();
|
||||
$countSuffix = " ($count records)";
|
||||
} catch (\Exception $e) {
|
||||
$countSuffix = " (error getting record count)";
|
||||
}
|
||||
} else {
|
||||
$countSuffix = "";
|
||||
}
|
||||
|
||||
if (Director::is_cli()) {
|
||||
echo " * $tableName$countSuffix\n";
|
||||
} else {
|
||||
echo "<li>$tableName$countSuffix</li>\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Instruct the class to apply its schema to the database
|
||||
$SNG->requireTable();
|
||||
}
|
||||
|
||||
// If we have additional dataobjects which need schema (i.e. for tests), do so here:
|
||||
if ($extraDataObjects) {
|
||||
foreach ($extraDataObjects as $dataClass) {
|
||||
$SNG = new $dataClass([], DataObject::CREATE_SINGLETON);
|
||||
if ($SNG instanceof DataObject) {
|
||||
$SNG->requireTable();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -244,29 +244,9 @@ class TempDatabase
|
||||
|
||||
$schema = $this->getConn()->getSchemaManager();
|
||||
$schema->quiet();
|
||||
$schema->schemaUpdate(
|
||||
function () use ($dataClasses, $extraDataObjects) {
|
||||
foreach ($dataClasses as $dataClass) {
|
||||
// Check if class exists before trying to instantiate - this sidesteps any manifest weirdness
|
||||
if (class_exists($dataClass ?? '')) {
|
||||
$SNG = singleton($dataClass);
|
||||
if (!($SNG instanceof TestOnly)) {
|
||||
$SNG->requireTable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we have additional dataobjects which need schema, do so here:
|
||||
if ($extraDataObjects) {
|
||||
foreach ($extraDataObjects as $dataClass) {
|
||||
$SNG = singleton($dataClass);
|
||||
if (singleton($dataClass) instanceof DataObject) {
|
||||
$SNG->requireTable();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
$tableBuilder = TableBuilder::singleton();
|
||||
$tableBuilder->buildTables($schema, $dataClasses, $extraDataObjects, true);
|
||||
|
||||
Config::modify()->set(DBSchemaManager::class, 'check_and_repair_on_build', $oldCheckAndRepairOnBuild);
|
||||
|
||||
|
@ -14,6 +14,7 @@ use SilverStripe\Dev\Deprecation;
|
||||
use SilverStripe\Dev\DevelopmentAdmin;
|
||||
use SilverStripe\Dev\TestOnly;
|
||||
use SilverStripe\ORM\Connect\DatabaseException;
|
||||
use SilverStripe\ORM\Connect\TableBuilder;
|
||||
use SilverStripe\ORM\FieldType\DBClassName;
|
||||
use SilverStripe\Security\Permission;
|
||||
use SilverStripe\Security\Security;
|
||||
@ -304,46 +305,8 @@ class DatabaseAdmin extends Controller
|
||||
|
||||
// Initiate schema update
|
||||
$dbSchema = DB::get_schema();
|
||||
$dbSchema->schemaUpdate(function () use ($dataClasses, $testMode, $quiet, $showRecordCounts) {
|
||||
$dataObjectSchema = DataObject::getSchema();
|
||||
|
||||
foreach ($dataClasses as $dataClass) {
|
||||
// Check if class exists before trying to instantiate - this sidesteps any manifest weirdness
|
||||
if (!class_exists($dataClass ?? '')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if this class should be excluded as per testing conventions
|
||||
$SNG = new $dataClass([], DataObject::CREATE_SINGLETON);
|
||||
if (!$testMode && $SNG instanceof TestOnly) {
|
||||
continue;
|
||||
}
|
||||
$tableName = $dataObjectSchema->tableName($dataClass);
|
||||
|
||||
// Log data
|
||||
if (!$quiet) {
|
||||
if ($showRecordCounts && DB::get_schema()->hasTable($tableName)) {
|
||||
try {
|
||||
$count = DB::query("SELECT COUNT(*) FROM \"$tableName\"")->value();
|
||||
$countSuffix = " ($count records)";
|
||||
} catch (Exception $e) {
|
||||
$countSuffix = " (error getting record count)";
|
||||
}
|
||||
} else {
|
||||
$countSuffix = "";
|
||||
}
|
||||
|
||||
if (Director::is_cli()) {
|
||||
echo " * $tableName$countSuffix\n";
|
||||
} else {
|
||||
echo "<li>$tableName$countSuffix</li>\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Instruct the class to apply its schema to the database
|
||||
$SNG->requireTable();
|
||||
}
|
||||
});
|
||||
$tableBuilder = TableBuilder::singleton();
|
||||
$tableBuilder->buildTables($dbSchema, $dataClasses, [], $quiet, $testMode, $showRecordCounts);
|
||||
ClassInfo::reset_db_cache();
|
||||
|
||||
if (!$quiet && !Director::is_cli()) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user