assertEquals( 'DataObjectSchemaTest_WithRelation', $schema->tableName(WithRelation::class) ); $this->assertEquals( 'DOSTWithCustomTable', $schema->tableName(WithCustomTable::class) ); // Default table name is FQN $this->assertEquals( 'SilverStripe_ORM_Tests_DataObjectSchemaTest_DefaultTableName', $schema->tableName(DefaultTableName::class) ); } /** * Test that the class name is convertible from the table */ public function testClassNameForTable() { $schema = DataObject::getSchema(); // Tables that aren't classes $this->assertNull($schema->tableClass('NotARealTable')); // Non-namespaced tables $this->assertEquals( WithRelation::class, $schema->tableClass('DataObjectSchemaTest_WithRelation') ); $this->assertEquals( WithCustomTable::class, $schema->tableClass('DOSTWithCustomTable') ); } public function testTableForObjectField() { $schema = DataObject::getSchema(); $this->assertEquals( 'DataObjectSchemaTest_WithRelation', $schema->tableForField(WithRelation::class, 'RelationID') ); $this->assertEquals( 'DataObjectSchemaTest_WithRelation', $schema->tableForField(WithRelation::class, 'RelationID') ); $this->assertEquals( 'DataObjectSchemaTest_BaseDataClass', $schema->tableForField(BaseDataClass::class, 'Title') ); $this->assertEquals( 'DataObjectSchemaTest_BaseDataClass', $schema->tableForField(HasFields::class, 'Title') ); $this->assertEquals( 'DataObjectSchemaTest_BaseDataClass', $schema->tableForField(NoFields::class, 'Title') ); $this->assertEquals( 'DataObjectSchemaTest_BaseDataClass', $schema->tableForField(NoFields::class, 'Title') ); $this->assertEquals( 'DataObjectSchemaTest_HasFields', $schema->tableForField(HasFields::Class, 'Description') ); // Class and table differ for this model $this->assertEquals( 'DOSTWithCustomTable', $schema->tableForField(WithCustomTable::class, 'Description') ); $this->assertEquals( WithCustomTable::class, $schema->classForField(WithCustomTable::class, 'Description') ); $this->assertNull( $schema->tableForField(WithCustomTable::class, 'NotAField') ); $this->assertNull( $schema->classForField(WithCustomTable::class, 'NotAField') ); // Non-existent fields shouldn't match any table $this->assertNull( $schema->tableForField(BaseClass::class, 'Nonexist') ); $this->assertNull( $schema->tableForField(ClassInfo::class, 'Title') ); // Test fixed fields $this->assertEquals( 'DataObjectSchemaTest_BaseDataClass', $schema->tableForField(HasFields::class, 'ID') ); $this->assertEquals( 'DataObjectSchemaTest_BaseDataClass', $schema->tableForField(NoFields::class, 'Created') ); } public function testFieldSpec() { $schema = DataObject::getSchema(); $this->assertEquals( [ 'ID' => 'PrimaryKey', 'ClassName' => 'DBClassName', 'LastEdited' => 'DBDatetime', 'Created' => 'DBDatetime', 'Title' => 'Varchar', 'Description' => 'Varchar', 'MoneyFieldCurrency' => 'Varchar(3)', 'MoneyFieldAmount' => 'Decimal(19,4)', 'MoneyField' => 'Money', ], $schema->fieldSpecs(HasFields::class) ); $this->assertEquals( [ 'ID' => DataObjectSchemaTest\HasFields::class . '.PrimaryKey', 'ClassName' => DataObjectSchemaTest\BaseDataClass::class . '.DBClassName', 'LastEdited' => DataObjectSchemaTest\BaseDataClass::class . '.DBDatetime', 'Created' => DataObjectSchemaTest\BaseDataClass::class . '.DBDatetime', 'Title' => DataObjectSchemaTest\BaseDataClass::class . '.Varchar', 'Description' => DataObjectSchemaTest\HasFields::class . '.Varchar', 'MoneyFieldCurrency' => DataObjectSchemaTest\HasFields::class . '.Varchar(3)', 'MoneyFieldAmount' => DataObjectSchemaTest\HasFields::class . '.Decimal(19,4)', 'MoneyField' => DataObjectSchemaTest\HasFields::class . '.Money', ], $schema->fieldSpecs(HasFields::class, DataObjectSchema::INCLUDE_CLASS) ); // DB_ONLY excludes composite field MoneyField $this->assertEquals( [ 'ID' => DataObjectSchemaTest\HasFields::class . '.PrimaryKey', 'ClassName' => DataObjectSchemaTest\BaseDataClass::class . '.DBClassName', 'LastEdited' => DataObjectSchemaTest\BaseDataClass::class . '.DBDatetime', 'Created' => DataObjectSchemaTest\BaseDataClass::class . '.DBDatetime', 'Title' => DataObjectSchemaTest\BaseDataClass::class . '.Varchar', 'Description' => DataObjectSchemaTest\HasFields::class . '.Varchar', 'MoneyFieldCurrency' => DataObjectSchemaTest\HasFields::class . '.Varchar(3)', 'MoneyFieldAmount' => DataObjectSchemaTest\HasFields::class . '.Decimal(19,4)' ], $schema->fieldSpecs( HasFields::class, DataObjectSchema::INCLUDE_CLASS | DataObjectSchema::DB_ONLY ) ); // Use all options at once $this->assertEquals( [ 'ID' => DataObjectSchemaTest\HasFields::class . '.PrimaryKey', 'Description' => DataObjectSchemaTest\HasFields::class . '.Varchar', 'MoneyFieldCurrency' => DataObjectSchemaTest\HasFields::class . '.Varchar(3)', 'MoneyFieldAmount' => DataObjectSchemaTest\HasFields::class . '.Decimal(19,4)', ], $schema->fieldSpecs( HasFields::class, DataObjectSchema::INCLUDE_CLASS | DataObjectSchema::DB_ONLY | DataObjectSchema::UNINHERITED ) ); } /** * @covers \SilverStripe\ORM\DataObjectSchema::baseDataClass() */ public function testBaseDataClass() { $schema = DataObject::getSchema(); $this->assertEquals(BaseClass::class, $schema->baseDataClass(BaseClass::class)); $this->assertEquals(BaseClass::class, $schema->baseDataClass(strtolower(BaseClass::class))); $this->assertEquals(BaseClass::class, $schema->baseDataClass(ChildClass::class)); $this->assertEquals(BaseClass::class, $schema->baseDataClass(strtoupper(ChildClass::class))); $this->assertEquals(BaseClass::class, $schema->baseDataClass(GrandChildClass::class)); $this->assertEquals(BaseClass::class, $schema->baseDataClass(ucfirst(GrandChildClass::class))); $this->expectException(InvalidArgumentException::class); $schema->baseDataClass(DataObject::class); } public function testDatabaseIndexes() { $indexes = DataObject::getSchema()->databaseIndexes(AllIndexes::class); $this->assertCount(5, $indexes); $this->assertArrayHasKey('ClassName', $indexes); $this->assertEquals([ 'type' => 'index', 'columns' => ['ClassName'], ], $indexes['ClassName']); $this->assertArrayHasKey('Content', $indexes); $this->assertEquals([ 'type' => 'index', 'columns' => ['Content'], ], $indexes['Content']); $this->assertArrayHasKey('IndexCols', $indexes); $this->assertEquals([ 'type' => 'index', 'columns' => ['Title', 'Content'], ], $indexes['IndexCols']); $this->assertArrayHasKey('IndexUnique', $indexes); $this->assertEquals([ 'type' => 'unique', 'columns' => ['Number'], ], $indexes['IndexUnique']); $this->assertArrayHasKey('IndexNormal', $indexes); $this->assertEquals([ 'type' => 'index', 'columns' => ['Title'], ], $indexes['IndexNormal']); } public function testCompositeDatabaseFieldIndexes() { $indexes = DataObject::getSchema()->databaseIndexes(HasComposites::class); $this->assertCount(3, $indexes); $this->assertArrayHasKey('RegularHasOneID', $indexes); $this->assertEquals([ 'type' => 'index', 'columns' => ['RegularHasOneID'] ], $indexes['RegularHasOneID']); $this->assertArrayHasKey('Polymorpheus', $indexes); $this->assertEquals([ 'type' => 'index', 'columns' => ['PolymorpheusID', 'PolymorpheusClass'] ], $indexes['Polymorpheus']); // Check that DBPolymorphicForeignKey's "Class" is not indexed on its own $this->assertArrayNotHasKey('PolymorpheusClass', $indexes); } public function testCompositeFieldsCanBeIndexedByDefaultConfiguration() { Config::modify()->set(DBMoney::class, 'index', true); $indexes = DataObject::getSchema()->databaseIndexes(HasComposites::class); $this->assertCount(4, $indexes); $this->assertArrayHasKey('Amount', $indexes); $this->assertEquals([ 'type' => 'index', 'columns' => ['AmountCurrency', 'AmountAmount'] ], $indexes['Amount']); } public function testIndexTypeIsConfigurable() { Config::modify()->set(DBMoney::class, 'index', 'unique'); $indexes = DataObject::getSchema()->databaseIndexes(HasComposites::class); $this->assertCount(4, $indexes); $this->assertArrayHasKey('Amount', $indexes); $this->assertEquals([ 'type' => 'unique', 'columns' => ['AmountCurrency', 'AmountAmount'] ], $indexes['Amount']); } public function testFieldsCanBeIndexedFromFieldSpecs() { $indexes = DataObject::getSchema()->databaseIndexes(HasIndexesInFieldSpecs::class); $this->assertCount(3, $indexes); $this->assertArrayHasKey('ClassName', $indexes); $this->assertArrayHasKey('IndexedTitle', $indexes); $this->assertEquals([ 'type' => 'fulltext', 'columns' => ['IndexedTitle'] ], $indexes['IndexedTitle']); $this->assertArrayHasKey('IndexedMoney', $indexes); $this->assertEquals([ 'type' => 'index', 'columns' => ['IndexedMoneyCurrency', 'IndexedMoneyAmount'] ], $indexes['IndexedMoney']); } /** * Ensure that records with unique indexes can be written */ public function testWriteUniqueIndexes() { // Create default object $zeroObject = new AllIndexes(); $zeroObject->Number = 0; $zeroObject->write(); $this->assertListEquals( [ ['Number' => 0], ], AllIndexes::get() ); // Test a new record can be created without clashing with default value $validObject = new AllIndexes(); $validObject->Number = 1; $validObject->write(); $this->assertListEquals( [ ['Number' => 0], ['Number' => 1], ], AllIndexes::get() ); } }