From 956c6447086df00d5cadb9571a5df91779538e0b Mon Sep 17 00:00:00 2001 From: mark burdett Date: Wed, 13 Mar 2019 22:30:05 -0700 Subject: [PATCH] Use TempTable methods; add TempTable::setName() method. --- CRM/Activity/BAO/Activity.php | 9 ++++----- CRM/Contact/Form/Search/Custom/FullText.php | 15 ++++++-------- CRM/Contact/Import/ImportJob.php | 5 +++-- CRM/Import/DataSource/CSV.php | 6 +++--- CRM/Report/Form.php | 4 +--- CRM/Report/Form/ActivitySummary.php | 20 +++++++++---------- CRM/Report/Form/Contribute/Bookkeeping.php | 8 ++++---- CRM/Report/Form/Contribute/Detail.php | 16 ++++++++------- CRM/Report/Form/Contribute/Repeat.php | 20 +++++++++---------- CRM/Report/Form/Member/ContributionDetail.php | 11 +++++----- CRM/Utils/SQL/TempTable.php | 17 ++++++++++++++++ tests/phpunit/api/v3/ReportTemplateTest.php | 2 +- 12 files changed, 73 insertions(+), 60 deletions(-) diff --git a/CRM/Activity/BAO/Activity.php b/CRM/Activity/BAO/Activity.php index 4645121311e1..183933c59c6e 100644 --- a/CRM/Activity/BAO/Activity.php +++ b/CRM/Activity/BAO/Activity.php @@ -895,7 +895,8 @@ public static function deprecatedGetActivities($input) { $config = CRM_Core_Config::singleton(); - $activityTempTable = CRM_Utils_SQL_TempTable::build()->setCategory('actdetail')->getName(); + $tempTable = CRM_Utils_SQL_TempTable::build()->setCategory('actdetail')->setMemory()->setUtf8(); + $activityTempTable = $tempTable->getName(); $tableFields = array( 'activity_id' => 'int unsigned', @@ -911,12 +912,11 @@ public static function deprecatedGetActivities($input) { 'campaign_id' => 'int unsigned', ); - $sql = "CREATE TEMPORARY TABLE {$activityTempTable} ( "; $insertValueSQL = $selectColumns = array(); // The activityTempTable contains the sorted rows // so in order to maintain the sort order as-is we add an auto_increment // field; we can sort by this later to ensure the sort order stays correct. - $sql .= " fixed_sort_order INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,"; + $sql = " fixed_sort_order INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,"; foreach ($tableFields as $name => $desc) { $sql .= "$name $desc,\n"; $insertValueSQL[] = $name; @@ -933,10 +933,9 @@ public static function deprecatedGetActivities($input) { // fixed_sort_order field $sql .= " UNIQUE KEY ( activity_id ) - ) ENGINE=HEAP DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci "; - CRM_Core_DAO::executeQuery($sql); + $tempTable->createWithColumns($sql); $insertSQL = "INSERT IGNORE INTO {$activityTempTable} (" . implode(',', $insertValueSQL) . " ) "; diff --git a/CRM/Contact/Form/Search/Custom/FullText.php b/CRM/Contact/Form/Search/Custom/FullText.php index 8680dceb0000..2d183d840c57 100644 --- a/CRM/Contact/Form/Search/Custom/FullText.php +++ b/CRM/Contact/Form/Search/Custom/FullText.php @@ -147,8 +147,8 @@ public function initialize() { } public function buildTempTable() { - $randomNum = md5(uniqid()); - $this->_tableName = "civicrm_temp_custom_details_{$randomNum}"; + $table = CRM_Utils_SQL_TempTable::build()->setCategory('custom')->setMemory()->setUtf8(); + $this->_tableName = $table->getName(); $this->_tableFields = array( 'id' => 'int unsigned NOT NULL AUTO_INCREMENT', @@ -200,7 +200,6 @@ public function buildTempTable() { ); $sql = " -CREATE TEMPORARY TABLE {$this->_tableName} ( "; foreach ($this->_tableFields as $name => $desc) { @@ -209,21 +208,19 @@ public function buildTempTable() { $sql .= " PRIMARY KEY ( id ) -) ENGINE=HEAP DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci "; - CRM_Core_DAO::executeQuery($sql); + $table->createWithColumns($sql); - $this->_entityIDTableName = "civicrm_temp_custom_entityID_{$randomNum}"; + $entityIdTable = CRM_Utils_SQL_TempTable::build()->setCategory('entity')->setMemory()->setUtf8(); + $this->_entityIDTableName = $entityIdTable->getName(); $sql = " -CREATE TEMPORARY TABLE {$this->_entityIDTableName} ( id int unsigned NOT NULL AUTO_INCREMENT, entity_id int unsigned NOT NULL, UNIQUE INDEX unique_entity_id ( entity_id ), PRIMARY KEY ( id ) -) ENGINE=HEAP DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci "; - CRM_Core_DAO::executeQuery($sql); + $entityIdTable->createWithColumns($sql); if (!empty($this->_formValues['is_unit_test'])) { $this->_tableNameForTest = $this->_tableName; diff --git a/CRM/Contact/Import/ImportJob.php b/CRM/Contact/Import/ImportJob.php index 565984708154..402ca4cc71be 100644 --- a/CRM/Contact/Import/ImportJob.php +++ b/CRM/Contact/Import/ImportJob.php @@ -81,8 +81,9 @@ public function __construct($tableName = NULL, $createSql = NULL, $createTable = if (!$tableName) { $tableName = 'civicrm_import_job_' . md5(uniqid(rand(), TRUE)); } - $db->query("DROP TABLE IF EXISTS $tableName"); - $db->query("CREATE TABLE $tableName ENGINE=InnoDB DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci $createSql"); + $table = CRM_Utils_SQL_TempTable::build()->setDurable()->setName($tableName)->setUtf8(); + $table->drop(); + $table->createWithQuery($createSql); } if (!$tableName) { diff --git a/CRM/Import/DataSource/CSV.php b/CRM/Import/DataSource/CSV.php index 9d5e460c18c4..ad59c249d55f 100644 --- a/CRM/Import/DataSource/CSV.php +++ b/CRM/Import/DataSource/CSV.php @@ -202,12 +202,12 @@ private static function _CsvToTable( if (!$table) { $table = 'civicrm_import_job_' . md5(uniqid(rand(), TRUE)); } + $tempTable = CRM_Utils_SQL_TempTable::build()->setDurable()->setName($table)->setUtf8(); - $db->query("DROP TABLE IF EXISTS $table"); + $tempTable->drop(); $numColumns = count($columns); - $create = "CREATE TABLE $table (" . implode(' text, ', $columns) . " text) ENGINE=InnoDB DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci"; - $db->query($create); + $tempTable->createWithColumns(implode(' text, ', $columns) . ' text'); // the proper approach, but some MySQL installs do not have this enabled // $load = "LOAD DATA LOCAL INFILE '$file' INTO TABLE $table FIELDS TERMINATED BY '$fieldSeparator' OPTIONALLY ENCLOSED BY '\"'"; diff --git a/CRM/Report/Form.php b/CRM/Report/Form.php index 900a35d4936c..8edb7e28462e 100644 --- a/CRM/Report/Form.php +++ b/CRM/Report/Form.php @@ -1155,9 +1155,7 @@ public function createTemporaryTable($identifier, $sql) { $name = $tempTable->getName(); // Developers may force tables to be durable to assist in debugging so lets check. $isNotTrueTemporary = $tempTable->isDurable(); - // The TempTable build routine adds the next line - we output it to help developers see what has happened. - $sql = 'CREATE ' . ($isNotTrueTemporary ? '' : 'TEMPORARY ') . "TABLE $name DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci " . $sql; - $this->addToDeveloperTab($sql); + $this->addToDeveloperTab($tempTable->getCreateSql()); $this->temporaryTables[$identifier] = ['temporary' => !$isNotTrueTemporary, 'name' => $name]; return $name; } diff --git a/CRM/Report/Form/ActivitySummary.php b/CRM/Report/Form/ActivitySummary.php index af071d83ba11..f0a09864aac6 100644 --- a/CRM/Report/Form/ActivitySummary.php +++ b/CRM/Report/Form/ActivitySummary.php @@ -533,7 +533,8 @@ public function postProcess() { CRM_Utils_Hook::alterReportVar('sql', $this, $this); // store the duration count in temp table - $this->_tempTableName = CRM_Core_DAO::createTempTableName('civicrm_activity'); + $tempTable = CRM_Utils_SQL_TempTable::build()->setCategory('activity')->setUtf8(); + $this->_tempTableName = $tempTable->getName(); // build temporary table column names base on column headers of result $dbColumns = array(); @@ -542,10 +543,9 @@ public function postProcess() { } // create temp table to store main result - $tempQuery = "CREATE TEMPORARY TABLE {$this->_tempTableName} ( - id int unsigned NOT NULL AUTO_INCREMENT, " . implode(', ', $dbColumns) . ' , PRIMARY KEY (id))' - . $this->_databaseAttributes; - CRM_Core_DAO::executeQuery($tempQuery); + $tempTable->createWithColumns(" + id int unsigned NOT NULL AUTO_INCREMENT, " . implode(', ', $dbColumns) . ' , PRIMARY KEY (id)' + ); // build main report query $sql = "{$this->_select} {$this->_from} {$this->_where} {$this->_groupBy} {$this->_having} {$this->_orderBy} {$this->_limit}"; @@ -565,11 +565,11 @@ public function postProcess() { $sql = "SELECT SUM(activity_civireport.duration) as civicrm_activity_duration_total {$this->_from} {$this->_where} {$this->_groupBy} {$this->_having} {$this->_orderBy} {$this->_limit}"; // create temp table to store duration - $this->_tempDurationSumTableName = CRM_Core_DAO::createTempTableName('civicrm_activity'); - $tempQuery = "CREATE TEMPORARY TABLE {$this->_tempDurationSumTableName} ( - id int unsigned NOT NULL AUTO_INCREMENT, civicrm_activity_duration_total VARCHAR(128), PRIMARY KEY (id))" - . $this->_databaseAttributes; - CRM_Core_DAO::executeQuery($tempQuery); + $tempTable = CRM_Utils_SQL_TempTable::build()->setCategory('activity')->setUtf8(); + $this->_tempDurationSumTableName = $tempTable->getName(); + $tempTable->createWithColumns(" + id int unsigned NOT NULL AUTO_INCREMENT, civicrm_activity_duration_total VARCHAR(128), PRIMARY KEY (id)" + ); // store the result in temporary table $insertQuery = "INSERT INTO {$this->_tempDurationSumTableName} (civicrm_activity_duration_total) diff --git a/CRM/Report/Form/Contribute/Bookkeeping.php b/CRM/Report/Form/Contribute/Bookkeeping.php index ee117af7a4b7..85b81ea1a613 100644 --- a/CRM/Report/Form/Contribute/Bookkeeping.php +++ b/CRM/Report/Form/Contribute/Bookkeeping.php @@ -602,7 +602,8 @@ public function groupBy() { */ public function statistics(&$rows) { $statistics = parent::statistics($rows); - $tempTableName = CRM_Core_DAO::createTempTableName('civicrm_contribution'); + $tempTable = CRM_Utils_SQL_TempTable::build()->setCategory('contribution')->setUtf8(); + $tempTableName = $tempTable->getName(); $financialSelect = "CASE WHEN {$this->_aliases['civicrm_entity_financial_trxn']}_item.entity_id IS NOT NULL THEN {$this->_aliases['civicrm_entity_financial_trxn']}_item.amount ELSE {$this->_aliases['civicrm_entity_financial_trxn']}.amount @@ -618,9 +619,8 @@ public function statistics(&$rows) { $this->groupBy(); - $tempQuery = "CREATE TEMPORARY TABLE {$tempTableName} {$this->_databaseAttributes} AS - {$select} {$this->_from} {$this->_where} {$this->_groupBy} "; - CRM_Core_DAO::executeQuery($tempQuery); + $tempTable->createWithQuery(" + {$select} {$this->_from} {$this->_where} {$this->_groupBy} "); $sql = "SELECT COUNT(trxnID) as count, SUM(amount) as amount, currency FROM {$tempTableName} diff --git a/CRM/Report/Form/Contribute/Detail.php b/CRM/Report/Form/Contribute/Detail.php index eccb17c26b43..dd2e3a0115b6 100644 --- a/CRM/Report/Form/Contribute/Detail.php +++ b/CRM/Report/Form/Contribute/Detail.php @@ -544,8 +544,9 @@ public function beginPostProcessCommon() { // we inner join with temp1 to restrict soft contributions to those in temp1 table. // no group by here as we want to display as many soft credit rows as actually exist. $sql = "{$select} {$this->_from} {$this->_where} $this->_groupBy"; - $tempQuery = "CREATE TEMPORARY TABLE civireport_contribution_detail_temp2 {$this->_databaseAttributes} AS {$sql}"; - $this->executeReportQuery($tempQuery); + $tempTable = CRM_Utils_SQL_TempTable::build()->setName('civireport_contribution_detail_temp2')->setUtf8(); + $tempTable->createWithQuery($sql); + $this->addToDeveloperTab($tempTable->getCreateSql()); $this->temporaryTables['civireport_contribution_detail_temp2'] = ['name' => 'civireport_contribution_detail_temp2', 'temporary' => TRUE]; if (CRM_Utils_Array::value('contribution_or_soft_value', $this->_params) == @@ -568,23 +569,24 @@ public function beginPostProcessCommon() { // 3. Decide where to populate temp3 table from if ($this->isContributionBaseMode ) { - $this->executeReportQuery( - "CREATE TEMPORARY TABLE civireport_contribution_detail_temp3 {$this->_databaseAttributes} AS (SELECT * FROM {$this->temporaryTables['civireport_contribution_detail_temp1']['name']})" + $tempTable = CRM_Utils_SQL_TempTable::build()->setName('civireport_contribution_detail_temp3')->setUtf8()->createWithQuery( + "(SELECT * FROM {$this->temporaryTables['civireport_contribution_detail_temp1']['name']})" ); } elseif (CRM_Utils_Array::value('contribution_or_soft_value', $this->_params) == 'soft_credits_only' ) { - $this->executeReportQuery( - "CREATE TEMPORARY TABLE civireport_contribution_detail_temp3 {$this->_databaseAttributes} AS (SELECT * FROM civireport_contribution_detail_temp2)" + $tempTable = CRM_Utils_SQL_TempTable::build()->setName('civireport_contribution_detail_temp3')->setUtf8()->createWithQuery( + "(SELECT * FROM civireport_contribution_detail_temp2)" ); } else { - $this->executeReportQuery("CREATE TEMPORARY TABLE civireport_contribution_detail_temp3 {$this->_databaseAttributes} + $tempTable = CRM_Utils_SQL_TempTable::build()->setName('civireport_contribution_detail_temp3')->setUtf8()->createWithQuery(" (SELECT * FROM {$this->temporaryTables['civireport_contribution_detail_temp1']['name']}) UNION ALL (SELECT * FROM civireport_contribution_detail_temp2)"); } + $this->addToDeveloperTab($tempTable->getCreateSql()); $this->temporaryTables['civireport_contribution_detail_temp3'] = ['name' => 'civireport_contribution_detail_temp3', 'temporary' => TRUE]; $this->isTempTableBuilt = TRUE; } diff --git a/CRM/Report/Form/Contribute/Repeat.php b/CRM/Report/Form/Contribute/Repeat.php index e9f0d418212f..ce2df7e1268e 100644 --- a/CRM/Report/Form/Contribute/Repeat.php +++ b/CRM/Report/Form/Contribute/Repeat.php @@ -1030,31 +1030,31 @@ protected function buildTempTables() { {$from} {$subWhere} GROUP BY contribution2.{$this->contributionJoinTableColumn}, currency"; - $this->tempTableRepeat1 = 'civicrm_temp_civireport_repeat1' . uniqid(); - $sql = " -CREATE TEMPORARY TABLE $this->tempTableRepeat1 ( + $tempTable = CRM_Utils_SQL_TempTable::build()->setCategory('civireport')->setMemory()->setUtf8(); + $this->tempTableRepeat1 = $tempTable->getName(); + $tempTable->createWithColumns(" {$create} {$this->contributionJoinTableColumn} int unsigned, total_amount_sum decimal(20,2), total_amount_count int -) ENGINE=HEAP {$this->_databaseAttributes}"; - $this->executeReportQuery($sql); +"); + $this->addToDeveloperTab($tempTable->getCreateSql()); $this->executeReportQuery("INSERT INTO $this->tempTableRepeat1 {$subContributionQuery1}"); $this->executeReportQuery(" ALTER TABLE $this->tempTableRepeat1 ADD INDEX ({$this->contributionJoinTableColumn}) "); - $this->tempTableRepeat2 = 'civicrm_temp_civireport_repeat2' . uniqid(); - $sql = " -CREATE TEMPORARY TABLE $this->tempTableRepeat2 ( + $tempTable = CRM_Utils_SQL_TempTable::build()->setCategory('civireport')->setMemory()->setUtf8(); + $this->tempTableRepeat2 = $tempTable->getName(); + $tempTable->createWithColumns(" {$create} {$this->contributionJoinTableColumn} int unsigned, total_amount_sum decimal(20,2), total_amount_count int, currency varchar(3) -) ENGINE=HEAP {$this->_databaseAttributes}"; - $this->executeReportQuery($sql); +"); + $this->addToDeveloperTab($tempTable->getCreateSql()); $sql = "INSERT INTO $this->tempTableRepeat2 {$subContributionQuery2}"; $this->executeReportQuery($sql); diff --git a/CRM/Report/Form/Member/ContributionDetail.php b/CRM/Report/Form/Member/ContributionDetail.php index 519c23ef5a50..1f62cd2760f4 100644 --- a/CRM/Report/Form/Member/ContributionDetail.php +++ b/CRM/Report/Form/Member/ContributionDetail.php @@ -505,13 +505,12 @@ public function from() { */ public function tempTable($applyLimit = TRUE) { // create temp table with contact ids,contribtuion id,membership id - $dropTempTable = 'DROP TEMPORARY TABLE IF EXISTS civireport_membership_contribution_detail'; - CRM_Core_DAO::executeQuery($dropTempTable); + $tempTable = CRM_Utils_SQL_TempTable::build()->setMemory()->setName('civireport_membership_contribution_detail')->setUtf8(); + $tempTable->drop(); - $sql = 'CREATE TEMPORARY TABLE civireport_membership_contribution_detail - (contribution_id int, INDEX USING HASH(contribution_id), contact_id int, INDEX USING HASH(contact_id), - membership_id int, INDEX USING HASH(membership_id), payment_id int, INDEX USING HASH(payment_id)) ENGINE=MEMORY' . $this->_databaseAttributes; - CRM_Core_DAO::executeQuery($sql); + $tempTable->createWithColumns(' + contribution_id int, INDEX USING HASH(contribution_id), contact_id int, INDEX USING HASH(contact_id), + membership_id int, INDEX USING HASH(membership_id), payment_id int, INDEX USING HASH(payment_id)'); $fillTemp = " INSERT INTO civireport_membership_contribution_detail (contribution_id, contact_id, membership_id) diff --git a/CRM/Utils/SQL/TempTable.php b/CRM/Utils/SQL/TempTable.php index 444f1ff92b5c..38bc290eaece 100644 --- a/CRM/Utils/SQL/TempTable.php +++ b/CRM/Utils/SQL/TempTable.php @@ -90,6 +90,8 @@ class CRM_Utils_SQL_TempTable { protected $createSql; + protected $name; + /** * @return CRM_Utils_SQL_TempTable */ @@ -119,6 +121,9 @@ public function __destruct() { * Ex: 'civicrm_tmp_d_foo_abcd1234abcd1234' */ public function getName() { + if ($this->name) { + return $this->name; + } $parts = ['civicrm', 'tmp']; $parts[] = ($this->durable ? 'd' : 'e'); $parts[] = $this->category ? $this->category : 'dflt'; @@ -310,6 +315,18 @@ public function setMemory($value = TRUE) { return $this; } + /** + * Set table name. + * + * @param string $name + * + * @return $this + */ + public function setName($name) { + $this->name = $name; + return $this; + } + /** * Set table collation to UTF8. * diff --git a/tests/phpunit/api/v3/ReportTemplateTest.php b/tests/phpunit/api/v3/ReportTemplateTest.php index 2f02b1409a04..d328da7b1232 100644 --- a/tests/phpunit/api/v3/ReportTemplateTest.php +++ b/tests/phpunit/api/v3/ReportTemplateTest.php @@ -473,7 +473,7 @@ public function testLybuntReportWithFYData() { $this->assertEquals(2, $rows['count'], "Report failed - the sql used to generate the results was " . print_r($rows['metadata']['sql'], TRUE)); - $expected = preg_replace('/\s+/', ' ', 'DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci + $expected = preg_replace('/\s+/', ' ', 'DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci AS SELECT SQL_CALC_FOUND_ROWS contact_civireport.id as cid FROM civicrm_contact contact_civireport INNER JOIN civicrm_contribution contribution_civireport USE index (received_date) ON contribution_civireport.contact_id = contact_civireport.id AND contribution_civireport.is_test = 0 AND contribution_civireport.receive_date BETWEEN \'20140701000000\' AND \'20150630235959\'