From d1930d0577fb58a86e763e555f0df8a0569abdb6 Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Mon, 31 Jul 2017 18:18:00 -0700 Subject: [PATCH 1/2] CRM-21079, CRM-9683 - Display advisories about DATETIME/TIMESTAMP columns --- CRM/Utils/Check/Component/Timestamps.php | 125 +++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 CRM/Utils/Check/Component/Timestamps.php diff --git a/CRM/Utils/Check/Component/Timestamps.php b/CRM/Utils/Check/Component/Timestamps.php new file mode 100644 index 000000000000..4e98293169ef --- /dev/null +++ b/CRM/Utils/Check/Component/Timestamps.php @@ -0,0 +1,125 @@ +%s.%s (New sites default to TIMESTAMP in %s+)', $target['table'], $target['column'], $target['changed']); + } + else { + $problems[] = sprintf('%s.%s (Experimental suggestion)', $target['table'], $target['column']); + } + } + } + + $messages = array(); + if ($problems) { + $messages[] = new CRM_Utils_Check_Message( + __FUNCTION__ . md5(implode(',', $problems)), + '

' . + ts('This system includes some SQL columns with type "DATETIME". These may work better as "TIMESTAMP".') . + '

' . + '' . + '

' . + ts('For further discussion, please visit %1', array( + 1 => sprintf('%s', self::DOCTOR_WHEN, self::DOCTOR_WHEN), + )) . + '

', + ts('Timestamp Schema'), + \Psr\Log\LogLevel::NOTICE, + 'fa-clock-o' + ); + } + return $messages; + } + + /** + * @param string $table + * Ex: 'civicrm_log'. + * @param string $column + * Ex: 'modified_date'. + * @param string $expectType + * Ex: 'datetime' or 'timestamp'. + * @return bool + */ + public static function isFieldType($table, $column, $expectType) { + $result = FALSE; + $dao = CRM_Core_DAO::executeQuery('DESC ' . $table); + while ($dao->fetch()) { + if ($dao->Field === $column && strtolower($dao->Type) === $expectType) { + $result = TRUE; + } + } + $dao->free(); + return $result; + } + + public static function getConvertedTimestamps() { + return array( + array('table' => 'civicrm_cache', 'column' => 'created_date', 'changed' => '4.7.20', 'default' => 'CURRENT_TIMESTAMP', 'jira' => 'CRM-9683'), + array('table' => 'civicrm_cache', 'column' => 'expired_date', 'changed' => '4.7.20', 'jira' => 'CRM-9683'), + array('table' => 'civicrm_job', 'column' => 'last_run', 'changed' => '4.7.20', 'jira' => 'CRM-9683'), + array('table' => 'civicrm_mailing_event_bounce', 'column' => 'time_stamp', 'changed' => '4.7.20', 'default' => 'CURRENT_TIMESTAMP', 'jira' => 'CRM-9683'), + array('table' => 'civicrm_mailing_event_confirm', 'column' => 'time_stamp', 'changed' => '4.7.20', 'default' => 'CURRENT_TIMESTAMP', 'jira' => 'CRM-9683'), + array('table' => 'civicrm_mailing_event_delivered', 'column' => 'time_stamp', 'changed' => '4.7.20', 'default' => 'CURRENT_TIMESTAMP', 'jira' => 'CRM-9683'), + array('table' => 'civicrm_mailing_event_forward', 'column' => 'time_stamp', 'changed' => '4.7.20', 'default' => 'CURRENT_TIMESTAMP', 'jira' => 'CRM-9683'), + array('table' => 'civicrm_mailing_event_opened', 'column' => 'time_stamp', 'changed' => '4.7.20', 'default' => 'CURRENT_TIMESTAMP', 'jira' => 'CRM-9683'), + array('table' => 'civicrm_mailing_event_reply', 'column' => 'time_stamp', 'changed' => '4.7.20', 'default' => 'CURRENT_TIMESTAMP', 'jira' => 'CRM-9683'), + array('table' => 'civicrm_mailing_event_subscribe', 'column' => 'time_stamp', 'changed' => '4.7.20', 'default' => 'CURRENT_TIMESTAMP', 'jira' => 'CRM-9683'), + array('table' => 'civicrm_mailing_event_trackable_url_open', 'column' => 'time_stamp', 'changed' => '4.7.20', 'default' => 'CURRENT_TIMESTAMP', 'jira' => 'CRM-9683'), + array('table' => 'civicrm_mailing_event_unsubscribe', 'column' => 'time_stamp', 'changed' => '4.7.20', 'default' => 'CURRENT_TIMESTAMP', 'jira' => 'CRM-9683'), + array('table' => 'civicrm_mailing', 'column' => 'created_date', 'changed' => '4.7.20', 'default' => 'CURRENT_TIMESTAMP', 'jira' => 'CRM-9683'), + array('table' => 'civicrm_mailing', 'column' => 'scheduled_date', 'changed' => '4.7.20', 'jira' => 'CRM-9683'), + array('table' => 'civicrm_mailing', 'column' => 'approval_date', 'changed' => '4.7.20', 'jira' => 'CRM-9683'), + array('table' => 'civicrm_mailing_abtest', 'column' => 'created_date', 'changed' => '4.7.20', 'default' => 'CURRENT_TIMESTAMP', 'jira' => 'CRM-9683'), + array('table' => 'civicrm_mailing_job', 'column' => 'scheduled_date', 'changed' => '4.7.20', 'jira' => 'CRM-9683'), + array('table' => 'civicrm_mailing_job', 'column' => 'start_date', 'changed' => '4.7.20', 'jira' => 'CRM-9683'), + array('table' => 'civicrm_mailing_job', 'column' => 'end_date', 'changed' => '4.7.20', 'jira' => 'CRM-9683'), + array('table' => 'civicrm_mailing_spool', 'column' => 'added_at', 'changed' => '4.7.20', 'jira' => 'CRM-9683'), + array('table' => 'civicrm_mailing_spool', 'column' => 'removed_at', 'changed' => '4.7.20', 'jira' => 'CRM-9683'), + ); + } + +} From 874ee3860b67499902e7c11bcbc7940147ae483b Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Mon, 28 Aug 2017 19:03:11 -0700 Subject: [PATCH 2/2] CRM-21079, CRM-9683 - CRM_Utils_Check - Expand advice --- CRM/Utils/Check/Component/Timestamps.php | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/CRM/Utils/Check/Component/Timestamps.php b/CRM/Utils/Check/Component/Timestamps.php index 4e98293169ef..00477e1d0bd0 100644 --- a/CRM/Utils/Check/Component/Timestamps.php +++ b/CRM/Utils/Check/Component/Timestamps.php @@ -43,12 +43,21 @@ public function checkSchema() { $problems = array(); foreach (self::getConvertedTimestamps() as $target) { if (self::isFieldType($target['table'], $target['column'], 'datetime')) { + $phrases = array(); + $phrases[] = sprintf('%s.%s', $target['table'], $target['column']); + if ($target['changed']) { - $problems[] = sprintf('%s.%s (New sites default to TIMESTAMP in %s+)', $target['table'], $target['column'], $target['changed']); + $phrases[] = sprintf('(New sites default to TIMESTAMP in v%s+)', $target['changed']); } else { - $problems[] = sprintf('%s.%s (Experimental suggestion)', $target['table'], $target['column']); + $phrases[] = '(Experimental suggestion)'; + } + + if (isset($target['jira'])) { + $phrases[] = sprintf(' [%s]', $target['jira'], $target['jira']); } + + $problems[] = implode(' ', $phrases); } } @@ -57,17 +66,20 @@ public function checkSchema() { $messages[] = new CRM_Utils_Check_Message( __FUNCTION__ . md5(implode(',', $problems)), '

' . - ts('This system includes some SQL columns with type "DATETIME". These may work better as "TIMESTAMP".') . + ts('This MySQL database stores certain fields with data-type "DATETIME". To improve timezone support, you may want to change these from "DATETIME" to "TIMESTAMP".') . '

' . '' . '

' . + ts('Changing should improve data-quality for organizations working in multiple timezones. However, if you do change, then you may need to re-test any customizations or processes that reference these fields. Changing is suggested but not required.') . + '

' . + '

' . ts('For further discussion, please visit %1', array( 1 => sprintf('%s', self::DOCTOR_WHEN, self::DOCTOR_WHEN), )) . '

', - ts('Timestamp Schema'), + ts('Timestamps and Timezones'), \Psr\Log\LogLevel::NOTICE, 'fa-clock-o' );