3 +--------------------------------------------------------------------+
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2019 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
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. |
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. |
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 +--------------------------------------------------------------------+
29 * Class CRM_Core_BAO_SchemaHandlerTest.
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.
35 class CRM_Core_BAO_SchemaHandlerTest
extends CiviUnitTestCase
{
38 * Test creating an index.
40 * We want to be sure it creates an index and exits gracefully if the index
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");
50 while ($dao->fetch()) {
51 if ($dao->Column_name
== 'weight') {
53 CRM_Core_DAO
::executeQuery("ALTER TABLE civicrm_uf_join DROP INDEX " . $dao->Key_name
);
56 $this->assertEquals(1, $count);
60 * Test CRM_Core_BAO_SchemaHandler::getIndexes() function
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']));
68 * Test creating an index.
70 * We want to be sure it creates an index and exits gracefully if the index
73 public function testCombinedIndex() {
74 $tables = array('civicrm_uf_join' => array('weight'));
75 CRM_Core_BAO_SchemaHandler
::createIndexes($tables);
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");
84 while ($dao->fetch()) {
85 if ($dao->Column_name
== 'weight') {
87 $indexes[$dao->Key_name
] = $dao->Key_name
;
89 if ($dao->Column_name
== 'module') {
91 $this->assertArrayHasKey($dao->Key_name
, $indexes);
95 foreach (array_keys($indexes) as $index) {
96 CRM_Core_DAO
::executeQuery("ALTER TABLE civicrm_uf_join DROP INDEX " . $index);
98 $this->assertEquals(2, $weightCount);
102 * Test the drop index if exists function for a non-existent index.
104 public function testCheckIndexNotExists() {
105 $this->assertFalse(CRM_Core_BAO_SchemaHandler
::checkIfIndexExists('civicrm_contact', 'magic_button'));
109 * Test the drop index if exists function for a non-existent index.
111 public function testCheckIndexExists() {
112 $this->assertTrue(CRM_Core_BAO_SchemaHandler
::checkIfIndexExists('civicrm_contact', 'index_hash'));
116 * Test the drop index if exists function for a non-existent index.
118 public function testDropIndexNoneExists() {
119 CRM_Core_BAO_SchemaHandler
::dropIndexIfExists('civicrm_contact', 'magic_button');
123 * Test the drop index if exists function.
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'));
129 // Recreate it to clean up after the test.
130 CRM_Core_BAO_SchemaHandler
::createIndexes(array('civicrm_contact' => array('hash')));
136 public function columnTests() {
138 $columns[] = array('civicrm_contribution', 'total_amount');
139 $columns[] = array('civicrm_contact', 'first_name');
140 $columns[] = array('civicrm_contact', 'xxxx');
148 * @dataProvider columnTests
150 public function testCheckIfColumnExists($tableName, $columnName) {
151 if ($columnName == 'xxxx') {
152 $this->assertFalse(CRM_Core_BAO_SchemaHandler
::checkIfFieldExists($tableName, $columnName));
155 $this->assertTrue(CRM_Core_BAO_SchemaHandler
::checkIfFieldExists($tableName, $columnName));
162 public function foreignKeyTests() {
164 $keys[] = array('civicrm_mailing_recipients', 'FK_civicrm_mailing_recipients_email_id');
165 $keys[] = array('civicrm_mailing_recipients', 'FK_civicrm_mailing_recipients_id');
170 * Test to see if we can drop foreign key
172 * @dataProvider foreignKeyTests
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));
179 $this->assertTrue(CRM_Core_BAO_SchemaHandler
::safeRemoveFK('civicrm_mailing_recipients', $key));
184 * Check there are no missing indices
186 public function testGetMissingIndices() {
187 $missingIndices = CRM_Core_BAO_SchemaHandler
::getMissingIndices();
188 $this->assertTrue(empty($missingIndices));
192 * Test that missing indices are correctly created
194 public function testCreateMissingIndices() {
196 'test_table' => array(
197 'test_index1' => array(
198 'name' => 'test_index1',
204 'test_index2' => array(
205 'name' => 'test_index2',
211 'test_index3' => array(
212 'name' => 'test_index3',
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);
229 * Check there are no missing indices
231 public function testReconcileMissingIndices() {
232 CRM_Core_DAO
::executeQuery('ALTER TABLE civicrm_contact DROP INDEX index_sort_name');
233 $missingIndices = CRM_Core_BAO_SchemaHandler
::getMissingIndices();
234 $this->assertEquals(array(
235 'civicrm_contact' => array(
237 'name' => 'index_sort_name',
238 'field' => array('sort_name'),
239 'localizable' => FALSE,
240 'sig' => 'civicrm_contact::0::sort_name',
244 $this->callAPISuccess('System', 'updateindexes', array());
245 $missingIndices = CRM_Core_BAO_SchemaHandler
::getMissingIndices();
246 $this->assertTrue(empty($missingIndices));
250 * Check for partial indices
252 public function testPartialIndices() {
254 'index_all' => 'civicrm_prevnext_cache',
255 'UI_entity_id_entity_table_tag_id' => 'civicrm_entity_tag',
257 CRM_Core_BAO_SchemaHandler
::dropIndexIfExists('civicrm_prevnext_cache', 'index_all');
258 //Missing Column `is_selected`.
259 CRM_Core_DAO
::executeQuery('CREATE INDEX index_all ON civicrm_prevnext_cache (cachekey, entity_id1, entity_id2, entity_table)');
260 $missingIndices = CRM_Core_BAO_SchemaHandler
::getMissingIndices();
261 $this->assertNotEmpty($missingIndices);
263 CRM_Core_BAO_SchemaHandler
::dropIndexIfExists('civicrm_entity_tag', 'UI_entity_id_entity_table_tag_id');
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)');
266 $missingIndices = CRM_Core_BAO_SchemaHandler
::getMissingIndices(TRUE);
267 $this->assertNotEmpty($missingIndices);
268 $this->assertEquals(array_values($tables), array_keys($missingIndices));
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])));
275 //Drop false index and create again.
276 CRM_Core_BAO_SchemaHandler
::createMissingIndices($missingIndices);
277 //Both vars should be empty now.
278 $missingIndices = CRM_Core_BAO_SchemaHandler
::getMissingIndices();
279 $this->assertEmpty($missingIndices);
283 * Test index signatures are added correctly
285 public function testAddIndexSignatures() {
288 'field' => array('id', 'name(3)'),
292 'field' => array('title'),
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');
301 * Test that columns are dropped
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))');
307 // test with logging enabled to ensure log triggers don't break anything
308 $schema = new CRM_Logging_Schema();
309 $schema->enableLogging();
312 'table_name' => 'civicrm_test_drop_column',
313 'operation' => 'delete',
315 'type' => 'varchar(255)',
317 'searchable' => FALSE,
321 CRM_Core_BAO_SchemaHandler
::alterFieldSQL($alterParams, FALSE, TRUE);
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
);
330 $alterParams['name'] = 'col2';
331 CRM_Core_BAO_SchemaHandler
::alterFieldSQL($alterParams, FALSE, TRUE);
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
);
340 * Tests the function that generates sql to modify fields.
342 public function testBuildFieldChangeSql() {
344 'table_name' => 'big_table',
345 'operation' => 'add',
349 $sql = CRM_Core_BAO_SchemaHandler
::buildFieldChangeSql($params, FALSE);
350 $this->assertEquals("ALTER TABLE big_table
351 ADD COLUMN `big_bob` text", trim($sql));
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));
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));