Commit | Line | Data |
---|---|---|
dd4d51af | 1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
2fe49090 | 4 | | CiviCRM version 5 | |
dd4d51af | 5 | +--------------------------------------------------------------------+ |
6b83d5bd | 6 | | Copyright CiviCRM LLC (c) 2004-2019 | |
dd4d51af | 7 | +--------------------------------------------------------------------+ |
8 | | This file is a part of CiviCRM. | | |
9 | | | | |
10 | | CiviCRM is free software; you can copy, modify, and distribute it | | |
11 | | under the terms of the GNU Affero General Public License | | |
12 | | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. | | |
13 | | | | |
14 | | CiviCRM is distributed in the hope that it will be useful, but | | |
15 | | WITHOUT ANY WARRANTY; without even the implied warranty of | | |
16 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | | |
17 | | See the GNU Affero General Public License for more details. | | |
18 | | | | |
19 | | You should have received a copy of the GNU Affero General Public | | |
20 | | License and the CiviCRM Licensing Exception along | | |
21 | | with this program; if not, contact CiviCRM LLC | | |
22 | | at info[AT]civicrm[DOT]org. If you have questions about the | | |
23 | | GNU Affero General Public License or the licensing of CiviCRM, | | |
24 | | see the CiviCRM license FAQ at http://civicrm.org/licensing | | |
25 | +--------------------------------------------------------------------+ | |
26 | */ | |
27 | ||
dd4d51af | 28 | /** |
29 | * Class CRM_Core_BAO_SchemaHandlerTest. | |
7181119b | 30 | * |
31 | * These tests create and drop indexes on the civicrm_uf_join table. The indexes | |
32 | * being added and dropped we assume will never exist. | |
acb109b7 | 33 | * @group headless |
dd4d51af | 34 | */ |
35 | class CRM_Core_BAO_SchemaHandlerTest extends CiviUnitTestCase { | |
36 | ||
37 | /** | |
38 | * Test creating an index. | |
39 | * | |
40 | * We want to be sure it creates an index and exits gracefully if the index | |
41 | * already exists. | |
42 | */ | |
43 | public function testCreateIndex() { | |
44 | $tables = array('civicrm_uf_join' => array('weight')); | |
45 | CRM_Core_BAO_SchemaHandler::createIndexes($tables); | |
46 | CRM_Core_BAO_SchemaHandler::createIndexes($tables); | |
47 | $dao = CRM_Core_DAO::executeQuery("SHOW INDEX FROM civicrm_uf_join"); | |
48 | $count = 0; | |
49 | ||
50 | while ($dao->fetch()) { | |
51 | if ($dao->Column_name == 'weight') { | |
52 | $count++; | |
53 | CRM_Core_DAO::executeQuery("ALTER TABLE civicrm_uf_join DROP INDEX " . $dao->Key_name); | |
54 | } | |
55 | } | |
56 | $this->assertEquals(1, $count); | |
57 | } | |
58 | ||
49186f94 AS |
59 | /** |
60 | * Test CRM_Core_BAO_SchemaHandler::getIndexes() function | |
61 | */ | |
62 | public function testGetIndexes() { | |
63 | $indexes = CRM_Core_BAO_SchemaHandler::getIndexes(array('civicrm_contact')); | |
64 | $this->assertTrue(array_key_exists('index_contact_type', $indexes['civicrm_contact'])); | |
65 | } | |
66 | ||
7181119b | 67 | /** |
68 | * Test creating an index. | |
69 | * | |
70 | * We want to be sure it creates an index and exits gracefully if the index | |
71 | * already exists. | |
72 | */ | |
73 | public function testCombinedIndex() { | |
74 | $tables = array('civicrm_uf_join' => array('weight')); | |
75 | CRM_Core_BAO_SchemaHandler::createIndexes($tables); | |
76 | ||
77 | $tables = array('civicrm_uf_join' => array(array('weight', 'module'))); | |
78 | CRM_Core_BAO_SchemaHandler::createIndexes($tables); | |
79 | $dao = CRM_Core_DAO::executeQuery("SHOW INDEX FROM civicrm_uf_join"); | |
80 | $weightCount = 0; | |
81 | $combinedCount = 0; | |
82 | $indexes = array(); | |
83 | ||
84 | while ($dao->fetch()) { | |
85 | if ($dao->Column_name == 'weight') { | |
86 | $weightCount++; | |
87 | $indexes[$dao->Key_name] = $dao->Key_name; | |
88 | } | |
89 | if ($dao->Column_name == 'module') { | |
90 | $combinedCount++; | |
91 | $this->assertArrayHasKey($dao->Key_name, $indexes); | |
92 | } | |
93 | ||
94 | } | |
95 | foreach (array_keys($indexes) as $index) { | |
96 | CRM_Core_DAO::executeQuery("ALTER TABLE civicrm_uf_join DROP INDEX " . $index); | |
97 | } | |
98 | $this->assertEquals(2, $weightCount); | |
99 | } | |
100 | ||
50969d52 | 101 | /** |
102 | * Test the drop index if exists function for a non-existent index. | |
103 | */ | |
fe891bc6 | 104 | public function testCheckIndexNotExists() { |
50969d52 | 105 | $this->assertFalse(CRM_Core_BAO_SchemaHandler::checkIfIndexExists('civicrm_contact', 'magic_button')); |
106 | } | |
107 | ||
108 | /** | |
109 | * Test the drop index if exists function for a non-existent index. | |
110 | */ | |
fe891bc6 | 111 | public function testCheckIndexExists() { |
50969d52 | 112 | $this->assertTrue(CRM_Core_BAO_SchemaHandler::checkIfIndexExists('civicrm_contact', 'index_hash')); |
113 | } | |
114 | ||
115 | /** | |
116 | * Test the drop index if exists function for a non-existent index. | |
117 | */ | |
118 | public function testDropIndexNoneExists() { | |
119 | CRM_Core_BAO_SchemaHandler::dropIndexIfExists('civicrm_contact', 'magic_button'); | |
120 | } | |
121 | ||
122 | /** | |
123 | * Test the drop index if exists function. | |
124 | */ | |
125 | public function testDropIndexExists() { | |
126 | CRM_Core_BAO_SchemaHandler::dropIndexIfExists('civicrm_contact', 'index_hash'); | |
127 | $this->assertFalse(CRM_Core_BAO_SchemaHandler::checkIfIndexExists('civicrm_contact', 'index_hash')); | |
128 | ||
129 | // Recreate it to clean up after the test. | |
130 | CRM_Core_BAO_SchemaHandler::createIndexes(array('civicrm_contact' => array('hash'))); | |
131 | } | |
132 | ||
82f5a856 SL |
133 | /** |
134 | * @return array | |
135 | */ | |
136 | public function columnTests() { | |
137 | $columns = array(); | |
138 | $columns[] = array('civicrm_contribution', 'total_amount'); | |
79e67687 | 139 | $columns[] = array('civicrm_contact', 'first_name'); |
82f5a856 SL |
140 | $columns[] = array('civicrm_contact', 'xxxx'); |
141 | return $columns; | |
142 | } | |
143 | ||
144 | /** | |
145 | * @param $tableName | |
146 | * @param $columnName | |
147 | * | |
148 | * @dataProvider columnTests | |
149 | */ | |
150 | public function testCheckIfColumnExists($tableName, $columnName) { | |
151 | if ($columnName == 'xxxx') { | |
152 | $this->assertFalse(CRM_Core_BAO_SchemaHandler::checkIfFieldExists($tableName, $columnName)); | |
153 | } | |
154 | else { | |
155 | $this->assertTrue(CRM_Core_BAO_SchemaHandler::checkIfFieldExists($tableName, $columnName)); | |
156 | } | |
157 | } | |
158 | ||
9cd5a579 SL |
159 | /** |
160 | * @return array | |
161 | */ | |
162 | public function foreignKeyTests() { | |
163 | $keys = array(); | |
164 | $keys[] = array('civicrm_mailing_recipients', 'FK_civicrm_mailing_recipients_email_id'); | |
165 | $keys[] = array('civicrm_mailing_recipients', 'FK_civicrm_mailing_recipients_id'); | |
166 | return $keys; | |
167 | } | |
168 | ||
169475b7 SL |
169 | /** |
170 | * Test to see if we can drop foreign key | |
171 | * | |
9cd5a579 | 172 | * @dataProvider foreignKeyTests |
169475b7 | 173 | */ |
9cd5a579 SL |
174 | public function testSafeDropForeignKey($tableName, $key) { |
175 | if ($key == 'FK_civicrm_mailing_recipients_id') { | |
176 | $this->assertFalse(CRM_Core_BAO_SchemaHandler::safeRemoveFK('civicrm_mailing_recipients', $key)); | |
177 | } | |
178 | else { | |
179 | $this->assertTrue(CRM_Core_BAO_SchemaHandler::safeRemoveFK('civicrm_mailing_recipients', $key)); | |
169475b7 SL |
180 | } |
181 | } | |
182 | ||
49186f94 AS |
183 | /** |
184 | * Check there are no missing indices | |
185 | */ | |
186 | public function testGetMissingIndices() { | |
3d4602c3 | 187 | $missingIndices = CRM_Core_BAO_SchemaHandler::getMissingIndices(); |
49186f94 AS |
188 | $this->assertTrue(empty($missingIndices)); |
189 | } | |
190 | ||
191 | /** | |
192 | * Test that missing indices are correctly created | |
193 | */ | |
194 | public function testCreateMissingIndices() { | |
195 | $indices = array( | |
196 | 'test_table' => array( | |
197 | 'test_index1' => array( | |
198 | 'name' => 'test_index1', | |
199 | 'field' => array( | |
200 | 'title', | |
201 | ), | |
202 | 'unique' => FALSE, | |
203 | ), | |
204 | 'test_index2' => array( | |
205 | 'name' => 'test_index2', | |
206 | 'field' => array( | |
207 | 'title', | |
208 | ), | |
209 | 'unique' => TRUE, | |
210 | ), | |
211 | 'test_index3' => array( | |
212 | 'name' => 'test_index3', | |
213 | 'field' => array( | |
214 | 'title(3)', | |
215 | 'name', | |
216 | ), | |
217 | 'unique' => FALSE, | |
218 | ), | |
219 | ), | |
220 | ); | |
221 | CRM_Core_DAO::executeQuery('DROP table if exists `test_table`'); | |
222 | CRM_Core_DAO::executeQuery('CREATE table `test_table` (`title` varchar(255), `name` varchar(255))'); | |
223 | CRM_Core_BAO_SchemaHandler::createMissingIndices($indices); | |
224 | $actualIndices = CRM_Core_BAO_SchemaHandler::getIndexes(array('test_table')); | |
225 | $this->assertEquals($actualIndices, $indices); | |
226 | } | |
227 | ||
228 | /** | |
229 | * Check there are no missing indices | |
230 | */ | |
231 | public function testReconcileMissingIndices() { | |
232 | CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_contact DROP INDEX index_sort_name'); | |
3d4602c3 | 233 | $missingIndices = CRM_Core_BAO_SchemaHandler::getMissingIndices(); |
63809327 | 234 | $this->assertEquals(array( |
235 | 'civicrm_contact' => array( | |
236 | array( | |
237 | 'name' => 'index_sort_name', | |
238 | 'field' => array('sort_name'), | |
239 | 'localizable' => FALSE, | |
240 | 'sig' => 'civicrm_contact::0::sort_name', | |
241 | ), | |
4b540f18 CW |
242 | ), |
243 | ), $missingIndices); | |
49186f94 | 244 | $this->callAPISuccess('System', 'updateindexes', array()); |
3d4602c3 | 245 | $missingIndices = CRM_Core_BAO_SchemaHandler::getMissingIndices(); |
49186f94 AS |
246 | $this->assertTrue(empty($missingIndices)); |
247 | } | |
248 | ||
d7367cef JP |
249 | /** |
250 | * Check for partial indices | |
251 | */ | |
252 | public function testPartialIndices() { | |
3d4602c3 JP |
253 | $tables = array( |
254 | 'index_all' => 'civicrm_prevnext_cache', | |
255 | 'UI_entity_id_entity_table_tag_id' => 'civicrm_entity_tag', | |
256 | ); | |
257 | CRM_Core_BAO_SchemaHandler::dropIndexIfExists('civicrm_prevnext_cache', 'index_all'); | |
d7367cef | 258 | //Missing Column `is_selected`. |
783b4b21 | 259 | CRM_Core_DAO::executeQuery('CREATE INDEX index_all ON civicrm_prevnext_cache (cachekey, entity_id1, entity_id2, entity_table)'); |
3d4602c3 JP |
260 | $missingIndices = CRM_Core_BAO_SchemaHandler::getMissingIndices(); |
261 | $this->assertNotEmpty($missingIndices); | |
d7367cef | 262 | |
3d4602c3 | 263 | CRM_Core_BAO_SchemaHandler::dropIndexIfExists('civicrm_entity_tag', 'UI_entity_id_entity_table_tag_id'); |
d7367cef JP |
264 | //Test incorrect Ordering(correct order defined is entity_id and then entity_table, tag_id). |
265 | CRM_Core_DAO::executeQuery('CREATE INDEX UI_entity_id_entity_table_tag_id ON civicrm_entity_tag (entity_table, entity_id, tag_id)'); | |
3d4602c3 JP |
266 | $missingIndices = CRM_Core_BAO_SchemaHandler::getMissingIndices(TRUE); |
267 | $this->assertNotEmpty($missingIndices); | |
268 | $this->assertEquals(array_values($tables), array_keys($missingIndices)); | |
d7367cef | 269 | |
3d4602c3 JP |
270 | //Check if both indices are deleted. |
271 | $indices = CRM_Core_BAO_SchemaHandler::getIndexes($tables); | |
272 | foreach ($tables as $index => $tableName) { | |
273 | $this->assertFalse(in_array($index, array_keys($indices[$tableName]))); | |
274 | } | |
d7367cef | 275 | //Drop false index and create again. |
d7367cef JP |
276 | CRM_Core_BAO_SchemaHandler::createMissingIndices($missingIndices); |
277 | //Both vars should be empty now. | |
3d4602c3 | 278 | $missingIndices = CRM_Core_BAO_SchemaHandler::getMissingIndices(); |
d7367cef | 279 | $this->assertEmpty($missingIndices); |
d7367cef JP |
280 | } |
281 | ||
49186f94 AS |
282 | /** |
283 | * Test index signatures are added correctly | |
284 | */ | |
285 | public function testAddIndexSignatures() { | |
286 | $indices = array( | |
287 | 'one' => array( | |
288 | 'field' => array('id', 'name(3)'), | |
289 | 'unique' => TRUE, | |
290 | ), | |
291 | 'two' => array( | |
292 | 'field' => array('title'), | |
293 | ), | |
294 | ); | |
295 | CRM_Core_BAO_SchemaHandler::addIndexSignature('my_table', $indices); | |
296 | $this->assertEquals($indices['one']['sig'], 'my_table::1::id::name(3)'); | |
297 | $this->assertEquals($indices['two']['sig'], 'my_table::0::title'); | |
298 | } | |
299 | ||
dfcc817d PF |
300 | /** |
301 | * Test that columns are dropped | |
302 | */ | |
303 | public function testDropColumn() { | |
304 | CRM_Core_DAO::executeQuery('DROP TABLE IF EXISTS `civicrm_test_drop_column`'); | |
305 | CRM_Core_DAO::executeQuery('CREATE TABLE `civicrm_test_drop_column` (`id` int(10), `col1` varchar(255), `col2` varchar(255))'); | |
306 | ||
307 | // test with logging enabled to ensure log triggers don't break anything | |
308 | $schema = new CRM_Logging_Schema(); | |
309 | $schema->enableLogging(); | |
310 | ||
311 | $alterParams = [ | |
312 | 'table_name' => 'civicrm_test_drop_column', | |
313 | 'operation' => 'delete', | |
314 | 'name' => 'col1', | |
315 | 'type' => 'varchar(255)', | |
316 | 'required' => FALSE, | |
317 | 'searchable' => FALSE, | |
318 | ]; | |
319 | ||
320 | // drop col1 | |
321 | CRM_Core_BAO_SchemaHandler::alterFieldSQL($alterParams, FALSE, TRUE); | |
322 | ||
323 | $create_table = CRM_Core_DAO::executeQuery("SHOW CREATE TABLE civicrm_test_drop_column"); | |
324 | while ($create_table->fetch()) { | |
325 | $this->assertNotContains('col1', $create_table->Create_Table); | |
326 | $this->assertContains('col2', $create_table->Create_Table); | |
327 | } | |
328 | ||
329 | // drop col2 | |
330 | $alterParams['name'] = 'col2'; | |
331 | CRM_Core_BAO_SchemaHandler::alterFieldSQL($alterParams, FALSE, TRUE); | |
332 | ||
333 | $create_table = CRM_Core_DAO::executeQuery("SHOW CREATE TABLE civicrm_test_drop_column"); | |
334 | while ($create_table->fetch()) { | |
335 | $this->assertNotContains('col2', $create_table->Create_Table); | |
336 | } | |
337 | } | |
338 | ||
d992b2f5 | 339 | /** |
340 | * Tests the function that generates sql to modify fields. | |
341 | */ | |
342 | public function testBuildFieldChangeSql() { | |
343 | $params = [ | |
344 | 'table_name' => 'big_table', | |
345 | 'operation' => 'add', | |
346 | 'name' => 'big_bob', | |
347 | 'type' => 'text', | |
348 | ]; | |
349 | $sql = CRM_Core_BAO_SchemaHandler::buildFieldChangeSql($params, FALSE); | |
350 | $this->assertEquals("ALTER TABLE big_table | |
351 | ADD COLUMN `big_bob` text", trim($sql)); | |
352 | ||
353 | $params['operation'] = 'modify'; | |
354 | $params['comment'] = 'super big'; | |
355 | $sql = CRM_Core_BAO_SchemaHandler::buildFieldChangeSql($params, FALSE); | |
356 | $this->assertEquals("ALTER TABLE big_table | |
357 | MODIFY `big_bob` text COMMENT 'super big'", trim($sql)); | |
358 | ||
359 | $params['operation'] = 'delete'; | |
360 | $sql = CRM_Core_BAO_SchemaHandler::buildFieldChangeSql($params, FALSE); | |
361 | $this->assertEquals('ALTER TABLE big_table DROP COLUMN `big_bob`', trim($sql)); | |
362 | } | |
363 | ||
dd4d51af | 364 | } |