mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
ENH Exclude a list of models for checking and repairs (#10746)
This commit is contained in:
parent
c1427ff9c4
commit
2c874a1e94
@ -4,8 +4,10 @@ namespace SilverStripe\ORM\Connect;
|
|||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use SilverStripe\Control\Director;
|
use SilverStripe\Control\Director;
|
||||||
|
use SilverStripe\Core\ClassInfo;
|
||||||
use SilverStripe\Core\Config\Config;
|
use SilverStripe\Core\Config\Config;
|
||||||
use SilverStripe\Core\Injector\Injector;
|
use SilverStripe\Core\Injector\Injector;
|
||||||
|
use SilverStripe\ORM\DataObject;
|
||||||
use SilverStripe\ORM\DB;
|
use SilverStripe\ORM\DB;
|
||||||
use SilverStripe\ORM\FieldType\DBField;
|
use SilverStripe\ORM\FieldType\DBField;
|
||||||
use SilverStripe\ORM\FieldType\DBPrimaryKey;
|
use SilverStripe\ORM\FieldType\DBPrimaryKey;
|
||||||
@ -28,6 +30,16 @@ abstract class DBSchemaManager
|
|||||||
*/
|
*/
|
||||||
private static $check_and_repair_on_build = true;
|
private static $check_and_repair_on_build = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For large databases you can declare a list of DataObject classes which will be excluded from
|
||||||
|
* CHECK TABLE and REPAIR TABLE queries during dev/build. Note that the entire inheritance chain
|
||||||
|
* for that class will be excluded, including both ancestors and descendants.
|
||||||
|
*
|
||||||
|
* Only use this configuration if you know what you are doing and have identified specific models
|
||||||
|
* as being problematic during your dev/build process.
|
||||||
|
*/
|
||||||
|
private static array $exclude_models_from_db_checks = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if tables should be renamed in a case-sensitive fashion.
|
* Check if tables should be renamed in a case-sensitive fashion.
|
||||||
* Note: This should still work even on case-insensitive databases.
|
* Note: This should still work even on case-insensitive databases.
|
||||||
@ -366,7 +378,7 @@ abstract class DBSchemaManager
|
|||||||
if (Config::inst()->get(static::class, 'fix_table_case_on_build')) {
|
if (Config::inst()->get(static::class, 'fix_table_case_on_build')) {
|
||||||
$this->fixTableCase($table);
|
$this->fixTableCase($table);
|
||||||
}
|
}
|
||||||
if (Config::inst()->get(static::class, 'check_and_repair_on_build')) {
|
if ($this->canCheckAndRepairTable($table)) {
|
||||||
$this->checkAndRepairTable($table);
|
$this->checkAndRepairTable($table);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -849,6 +861,29 @@ abstract class DBSchemaManager
|
|||||||
*/
|
*/
|
||||||
abstract public function checkAndRepairTable($tableName);
|
abstract public function checkAndRepairTable($tableName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if we should be checking and repairing tables generally, and whether the passed in table
|
||||||
|
* is on the ignore list.
|
||||||
|
*/
|
||||||
|
private function canCheckAndRepairTable(string $tableName): bool
|
||||||
|
{
|
||||||
|
if (!Config::inst()->get(static::class, 'check_and_repair_on_build')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return false if $tableName belongs to any model in the data hierarchy of any class in the ignore list
|
||||||
|
$ignoreModels = Config::inst()->get(static::class, 'exclude_models_from_db_checks');
|
||||||
|
if (!empty($ignoreModels)) {
|
||||||
|
$modelForTable = ClassInfo::class_name(DataObject::getSchema()->tableClass($tableName));
|
||||||
|
foreach ($ignoreModels as $ignoreModel) {
|
||||||
|
if (in_array($modelForTable, ClassInfo::dataClassesFor($ignoreModel))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensure the given table has the correct case
|
* Ensure the given table has the correct case
|
||||||
|
77
tests/php/ORM/DBSchemaManagerTest.php
Normal file
77
tests/php/ORM/DBSchemaManagerTest.php
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\ORM\Tests;
|
||||||
|
|
||||||
|
use ReflectionMethod;
|
||||||
|
use SilverStripe\Core\Config\Config;
|
||||||
|
use SilverStripe\Dev\SapphireTest;
|
||||||
|
use SilverStripe\ORM\Connect\DBSchemaManager;
|
||||||
|
use SilverStripe\ORM\Tests\DBSchemaManagerTest\ChildClass;
|
||||||
|
|
||||||
|
class DBSchemaManagerTest extends SapphireTest
|
||||||
|
{
|
||||||
|
protected $usesDatabase = false;
|
||||||
|
|
||||||
|
public function provideCanCheckAndRepairTable()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
// not ignored, but globally not allowed
|
||||||
|
[
|
||||||
|
'tableName' => 'DBSchemaManagerTest_SomeModel',
|
||||||
|
'checkAndRepairOnBuild' => false,
|
||||||
|
'expected' => false,
|
||||||
|
],
|
||||||
|
// allowed because it's not in the ignore list
|
||||||
|
[
|
||||||
|
'tableName' => 'DBSchemaManagerTest_SomeModel',
|
||||||
|
'checkAndRepairOnBuild' => true,
|
||||||
|
'expected' => true,
|
||||||
|
],
|
||||||
|
// not allowed because it's the base class for an ignored class
|
||||||
|
[
|
||||||
|
'tableName' => 'DBSchemaManagerTest_BaseClass',
|
||||||
|
'checkAndRepairOnBuild' => true,
|
||||||
|
'expected' => false,
|
||||||
|
],
|
||||||
|
// not allowed because it's explicitly in the ignore list
|
||||||
|
[
|
||||||
|
'tableName' => 'DBSchemaManagerTest_ChildClass',
|
||||||
|
'checkAndRepairOnBuild' => true,
|
||||||
|
'expected' => false,
|
||||||
|
],
|
||||||
|
// not allowed because it's a subclass of an ignored class
|
||||||
|
[
|
||||||
|
'tableName' => 'DBSchemaManagerTest_GrandChildClass',
|
||||||
|
'checkAndRepairOnBuild' => true,
|
||||||
|
'expected' => false,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider provideCanCheckAndRepairTable
|
||||||
|
*/
|
||||||
|
public function testCanCheckAndRepairTable(string $tableName, bool $checkAndRepairOnBuild, bool $expected)
|
||||||
|
{
|
||||||
|
// set config
|
||||||
|
Config::modify()->set(DBSchemaManager::class, 'check_and_repair_on_build', $checkAndRepairOnBuild);
|
||||||
|
Config::modify()->set(DBSchemaManager::class, 'exclude_models_from_db_checks', [ChildClass::class]);
|
||||||
|
|
||||||
|
$manager = $this->getConcreteSchemaManager();
|
||||||
|
$reflectionCanCheck = new ReflectionMethod($manager, 'canCheckAndRepairTable');
|
||||||
|
$reflectionCanCheck->setAccessible(true);
|
||||||
|
$result = $reflectionCanCheck->invoke($manager, $tableName);
|
||||||
|
|
||||||
|
$this->assertSame($expected, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DBSchemaManager is an abstract class - this gives us an instance of a concrete subclass.
|
||||||
|
* This allows us to test the original abstract implementations of methods without risking accidentally
|
||||||
|
* testing overridden methods on something like MySQLSchemaManager
|
||||||
|
*/
|
||||||
|
private function getConcreteSchemaManager(): DBSchemaManager
|
||||||
|
{
|
||||||
|
return $this->getMockBuilder(DBSchemaManager::class)->getMockForAbstractClass();
|
||||||
|
}
|
||||||
|
}
|
15
tests/php/ORM/DBSchemaManagerTest/BaseClass.php
Normal file
15
tests/php/ORM/DBSchemaManagerTest/BaseClass.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\ORM\Tests\DBSchemaManagerTest;
|
||||||
|
|
||||||
|
use SilverStripe\Dev\TestOnly;
|
||||||
|
use SilverStripe\ORM\DataObject;
|
||||||
|
|
||||||
|
class BaseClass extends DataObject implements TestOnly
|
||||||
|
{
|
||||||
|
private static $table_name = 'DBSchemaManagerTest_BaseClass';
|
||||||
|
|
||||||
|
private static $db = [
|
||||||
|
'BaseClassField' => 'Varchar',
|
||||||
|
];
|
||||||
|
}
|
12
tests/php/ORM/DBSchemaManagerTest/ChildClass.php
Normal file
12
tests/php/ORM/DBSchemaManagerTest/ChildClass.php
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\ORM\Tests\DBSchemaManagerTest;
|
||||||
|
|
||||||
|
class ChildClass extends BaseClass
|
||||||
|
{
|
||||||
|
private static $table_name = 'DBSchemaManagerTest_ChildClass';
|
||||||
|
|
||||||
|
private static $db = [
|
||||||
|
'ChildField' => 'Varchar',
|
||||||
|
];
|
||||||
|
}
|
12
tests/php/ORM/DBSchemaManagerTest/GrandChildClass.php
Normal file
12
tests/php/ORM/DBSchemaManagerTest/GrandChildClass.php
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\ORM\Tests\DBSchemaManagerTest;
|
||||||
|
|
||||||
|
class GrandChildClass extends ChildClass
|
||||||
|
{
|
||||||
|
private static $table_name = 'DBSchemaManagerTest_GrandChildClass';
|
||||||
|
|
||||||
|
private static $db = [
|
||||||
|
'GrandChildField' => 'Varchar',
|
||||||
|
];
|
||||||
|
}
|
15
tests/php/ORM/DBSchemaManagerTest/SomeModel.php
Normal file
15
tests/php/ORM/DBSchemaManagerTest/SomeModel.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\ORM\Tests\DBSchemaManagerTest;
|
||||||
|
|
||||||
|
use SilverStripe\Dev\TestOnly;
|
||||||
|
use SilverStripe\ORM\DataObject;
|
||||||
|
|
||||||
|
class SomeModel extends DataObject implements TestOnly
|
||||||
|
{
|
||||||
|
private static $table_name = 'DBSchemaManagerTest_SomeModel';
|
||||||
|
|
||||||
|
private static $db = [
|
||||||
|
'SomeField' => 'Varchar',
|
||||||
|
];
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user