Completed
Push — php7-fix ( 538bb9...015411 )
by Sam
07:21
created

testTableCaseFixed()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 32
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 18
nc 1
nop 0
dl 0
loc 32
rs 8.8571
c 0
b 0
f 0
1
<?php
2
3
4
use SilverStripe\ORM\Connect\MySQLSchemaManager;
5
use SilverStripe\ORM\DB;
6
use SilverStripe\ORM\FieldType\DBClassName;
7
use SilverStripe\ORM\DataObject;
8
use SilverStripe\Core\Config\Config;
9
use SilverStripe\Dev\SapphireTest;
10
use SilverStripe\Dev\TestOnly;
11
12
13
14
15
class DataObjectSchemaGenerationTest extends SapphireTest {
16
	protected $extraDataObjects = array(
17
		'DataObjectSchemaGenerationTest_DO',
18
		'DataObjectSchemaGenerationTest_IndexDO'
19
	);
20
21
	public function setUpOnce() {
22
23
		// enable fulltext option on this table
24
		Config::inst()->update('DataObjectSchemaGenerationTest_IndexDO', 'create_table_options',
25
			array(MySQLSchemaManager::ID => 'ENGINE=MyISAM'));
26
27
		parent::setUpOnce();
28
	}
29
30
	public function testTableCaseFixed() {
31
		DB::quiet();
32
33
		// Modify table case
34
		DB::get_schema()->renameTable(
35
			'DataObjectSchemaGenerationTest_DO',
36
			'__TEMP__DataOBJECTSchemaGenerationTest_do'
37
		);
38
		DB::get_schema()->renameTable(
39
			'__TEMP__DataOBJECTSchemaGenerationTest_do',
40
			'DataOBJECTSchemaGenerationTest_do'
41
		);
42
43
		// Check table
44
		$tables = DB::table_list();
45
		$this->assertEquals(
46
			'DataOBJECTSchemaGenerationTest_do',
47
			$tables['dataobjectschemagenerationtest_do']
48
		);
49
50
		// Rebuild table
51
		DB::get_schema()->schemaUpdate(function() {
52
			DataObjectSchemaGenerationTest_DO::singleton()->requireTable();
53
		});
54
55
		// Check table
56
		$tables = DB::table_list();
57
		$this->assertEquals(
58
			'DataObjectSchemaGenerationTest_DO',
59
			$tables['dataobjectschemagenerationtest_do']
60
		);
61
	}
62
63
	/**
64
	 * Check that once a schema has been generated, then it doesn't need any more updating
65
	 */
66
	public function testFieldsDontRerequestChanges() {
67
		$schema = DB::get_schema();
68
		$test = $this;
69
		DB::quiet();
70
71
		// Table will have been initially created by the $extraDataObjects setting
72
73
		// Verify that it doesn't need to be recreated
74
		$schema->schemaUpdate(function() use ($test, $schema) {
75
			$obj = new DataObjectSchemaGenerationTest_DO();
76
			$obj->requireTable();
77
			$needsUpdating = $schema->doesSchemaNeedUpdating();
78
			$schema->cancelSchemaUpdate();
79
			$test->assertFalse($needsUpdating);
80
		});
81
	}
82
83
	/**
84
	 * Check that updates to a class fields are reflected in the database
85
	 */
86 View Code Duplication
	public function testFieldsRequestChanges() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
87
		$schema = DB::get_schema();
88
		$test = $this;
89
		DB::quiet();
90
91
		// Table will have been initially created by the $extraDataObjects setting
92
93
		// Let's insert a new field here
94
		Config::inst()->update('DataObjectSchemaGenerationTest_DO', 'db', array(
95
			'SecretField' => 'Varchar(100)'
96
		));
97
98
		// Verify that the above extra field triggered a schema update
99
		$schema->schemaUpdate(function() use ($test, $schema) {
100
			$obj = new DataObjectSchemaGenerationTest_DO();
101
			$obj->requireTable();
102
			$needsUpdating = $schema->doesSchemaNeedUpdating();
103
			$schema->cancelSchemaUpdate();
104
			$test->assertTrue($needsUpdating);
105
		});
106
	}
107
108
	/**
109
	 * Check that indexes on a newly generated class do not subsequently request modification
110
	 */
111
	public function testIndexesDontRerequestChanges() {
112
		$schema = DB::get_schema();
113
		$test = $this;
114
		DB::quiet();
115
116
		// Table will have been initially created by the $extraDataObjects setting
117
118
		// Verify that it doesn't need to be recreated
119
		$schema->schemaUpdate(function() use ($test, $schema) {
120
			$obj = new DataObjectSchemaGenerationTest_IndexDO();
121
			$obj->requireTable();
122
			$needsUpdating = $schema->doesSchemaNeedUpdating();
123
			$schema->cancelSchemaUpdate();
124
			$test->assertFalse($needsUpdating);
125
		});
126
127
		// Test with alternate index format, although these indexes are the same
128
		Config::inst()->remove('DataObjectSchemaGenerationTest_IndexDO', 'indexes');
129
		Config::inst()->update('DataObjectSchemaGenerationTest_IndexDO', 'indexes',
130
			Config::inst()->get('DataObjectSchemaGenerationTest_IndexDO', 'indexes_alt')
131
		);
132
133
		// Verify that it still doesn't need to be recreated
134
		$schema->schemaUpdate(function() use ($test, $schema) {
135
			$obj2 = new DataObjectSchemaGenerationTest_IndexDO();
136
			$obj2->requireTable();
137
			$needsUpdating = $schema->doesSchemaNeedUpdating();
138
			$schema->cancelSchemaUpdate();
139
			$test->assertFalse($needsUpdating);
140
		});
141
	}
142
143
	/**
144
	 * Check that updates to a dataobject's indexes are reflected in DDL
145
	 */
146 View Code Duplication
	public function testIndexesRerequestChanges() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
147
		$schema = DB::get_schema();
148
		$test = $this;
149
		DB::quiet();
150
151
		// Table will have been initially created by the $extraDataObjects setting
152
153
		// Update the SearchFields index here
154
		Config::inst()->update('DataObjectSchemaGenerationTest_IndexDO', 'indexes', array(
155
			'SearchFields' => array(
156
				'value' => 'Title'
157
			)
158
		));
159
160
		// Verify that the above index change triggered a schema update
161
		$schema->schemaUpdate(function() use ($test, $schema) {
162
			$obj = new DataObjectSchemaGenerationTest_IndexDO();
163
			$obj->requireTable();
164
			$needsUpdating = $schema->doesSchemaNeedUpdating();
165
			$schema->cancelSchemaUpdate();
166
			$test->assertTrue($needsUpdating);
167
		});
168
	}
169
170
	/**
171
	 * Tests the generation of the ClassName spec and ensure it's not unnecessarily influenced
172
	 * by the order of classnames of existing records
173
	 */
174
	public function testClassNameSpecGeneration() {
175
		$schema = DataObject::getSchema();
176
177
		// Test with blank entries
178
		DBClassName::clear_classname_cache();
179
		$do1 = new DataObjectSchemaGenerationTest_DO();
180
		$fields = $schema->databaseFields(DataObjectSchemaGenerationTest_DO::class, false);
181
		/** @skipUpgrade */
182
		$this->assertEquals("DBClassName", $fields['ClassName']);
183
		$this->assertEquals(
184
			array(
185
				'DataObjectSchemaGenerationTest_DO' => 'DataObjectSchemaGenerationTest_DO',
186
				'DataObjectSchemaGenerationTest_IndexDO' => 'DataObjectSchemaGenerationTest_IndexDO'
187
			),
188
			$do1->dbObject('ClassName')->getEnum()
189
		);
190
191
192
		// Test with instance of subclass
193
		$item1 = new DataObjectSchemaGenerationTest_IndexDO();
194
		$item1->write();
195
		DBClassName::clear_classname_cache();
196
		$this->assertEquals(
197
			array(
198
				'DataObjectSchemaGenerationTest_DO' => 'DataObjectSchemaGenerationTest_DO',
199
				'DataObjectSchemaGenerationTest_IndexDO' => 'DataObjectSchemaGenerationTest_IndexDO'
200
			),
201
			$item1->dbObject('ClassName')->getEnum()
202
		);
203
		$item1->delete();
204
205
		// Test with instance of main class
206
		$item2 = new DataObjectSchemaGenerationTest_DO();
207
		$item2->write();
208
		DBClassName::clear_classname_cache();
209
		$this->assertEquals(
210
			array(
211
				'DataObjectSchemaGenerationTest_DO' => 'DataObjectSchemaGenerationTest_DO',
212
				'DataObjectSchemaGenerationTest_IndexDO' => 'DataObjectSchemaGenerationTest_IndexDO'
213
			),
214
			$item2->dbObject('ClassName')->getEnum()
215
		);
216
		$item2->delete();
217
218
		// Test with instances of both classes
219
		$item1 = new DataObjectSchemaGenerationTest_IndexDO();
220
		$item1->write();
221
		$item2 = new DataObjectSchemaGenerationTest_DO();
222
		$item2->write();
223
		DBClassName::clear_classname_cache();
224
		$this->assertEquals(
225
			array(
226
				'DataObjectSchemaGenerationTest_DO' => 'DataObjectSchemaGenerationTest_DO',
227
				'DataObjectSchemaGenerationTest_IndexDO' => 'DataObjectSchemaGenerationTest_IndexDO'
228
			),
229
			$item1->dbObject('ClassName')->getEnum()
230
		);
231
		$item1->delete();
232
		$item2->delete();
233
	}
234
}
235
236
class DataObjectSchemaGenerationTest_DO extends DataObject implements TestOnly {
237
	private static $db = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
238
		'Enum1' => 'Enum("A, B, C, D","")',
239
		'Enum2' => 'Enum("A, B, C, D","A")',
240
		'NumberField' => 'Decimal',
241
		'FloatingField' => 'Decimal(10,3,1.1)',
242
		'TextValue' => 'Varchar',
243
		'Date' => 'Datetime',
244
		'MyNumber' => 'Int'
245
	);
246
}
247
248
249
class DataObjectSchemaGenerationTest_IndexDO extends DataObjectSchemaGenerationTest_DO implements TestOnly {
250
	private static $db = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
251
		'Title' => 'Varchar(255)',
252
		'Content' => 'Text'
253
	);
254
255
	private static $indexes = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
256
		'NameIndex' => 'unique ("Title")',
257
		'SearchFields' => array(
258
			'type' => 'fulltext',
259
			'name' => 'SearchFields',
260
			'value' => '"Title","Content"'
261
		)
262
	);
263
264
	/** @config */
265
	private static $indexes_alt = array(
266
		'NameIndex' => array(
267
			'type' => 'unique',
268
			'name' => 'NameIndex',
269
			'value' => '"Title"'
270
		),
271
		'SearchFields' => 'fulltext ("Title","Content")'
272
	);
273
}
274