<?php
/*
+--------------------------------------------------------------------+
- | CiviCRM version 4.4 |
+ | CiviCRM version 4.5 |
+--------------------------------------------------------------------+
- | Copyright CiviCRM LLC (c) 2004-2013 |
+ | Copyright CiviCRM LLC (c) 2004-2014 |
+--------------------------------------------------------------------+
| This file is a part of CiviCRM. |
| |
/**
*
* @package CRM
- * @copyright CiviCRM LLC (c) 2004-2013
+ * @copyright CiviCRM LLC (c) 2004-2014
* $Id$
*
*/
$this->tables[] = $dao->TABLE_NAME;
}
- // do not log temp import, cache and log tables
+ // do not log temp import, cache, menu and log tables
$this->tables = preg_grep('/^civicrm_import_job_/', $this->tables, PREG_GREP_INVERT);
$this->tables = preg_grep('/_cache$/', $this->tables, PREG_GREP_INVERT);
$this->tables = preg_grep('/_log/', $this->tables, PREG_GREP_INVERT);
$this->tables = preg_grep('/^civicrm_task_action_temp_/', $this->tables, PREG_GREP_INVERT);
$this->tables = preg_grep('/^civicrm_export_temp_/', $this->tables, PREG_GREP_INVERT);
$this->tables = preg_grep('/^civicrm_queue_/', $this->tables, PREG_GREP_INVERT);
+ $this->tables = preg_grep('/^civicrm_menu/', $this->tables, PREG_GREP_INVERT); //CRM-14672
// do not log civicrm_mailing_event* tables, CRM-12300
$this->tables = preg_grep('/^civicrm_mailing_event_/', $this->tables, PREG_GREP_INVERT);
$this->fixSchemaDifferencesForALL();
}
// invoke the meta trigger creation call
- CRM_Core_DAO::triggerRebuild();
+ CRM_Core_DAO::triggerRebuild(NULL, TRUE);
}
/**
// for any obsolete columns (not null) we just make the column nullable.
if (!empty($cols['OBSOLETE'])) {
- $create = $this->_getCreateQuery("log_{$table}");
+ $create = $this->_getCreateQuery("`{$this->db}`.log_{$table}");
foreach ($cols['OBSOLETE'] as $col) {
$line = $this->_getColumnQuery($col, $create);
// This is just going to make a not null column to nullable
return TRUE;
}
+ /**
+ * @param $table
+ *
+ * @return array
+ */
private function _getCreateQuery($table) {
$dao = CRM_Core_DAO::executeQuery("SHOW CREATE TABLE {$table}");
$dao->fetch();
return $create;
}
+ /**
+ * @param $col
+ * @param $createQuery
+ *
+ * @return array|mixed|string
+ */
private function _getColumnQuery($col, $createQuery) {
$line = preg_grep("/^ `$col` /", $createQuery);
$line = rtrim(array_pop($line), ',');
return $line;
}
+ /**
+ * @param bool $rebuildTrigger
+ */
function fixSchemaDifferencesForAll($rebuildTrigger = FALSE) {
$diffs = array();
foreach ($this->tables as $table) {
if (empty($this->logs[$table])) {
$this->createLogTableFor($table);
- } else {
+ }
+ else {
$diffs[$table] = $this->columnsWithDiffSpecs($table, "log_$table");
}
}
* so there's no need for a default timestamp and therefore we remove such default timestamps
* also eliminate the NOT NULL constraint, since we always copy and schema can change down the road)
*/
+ /**
+ * @param $query
+ *
+ * @return mixed
+ */
function fixTimeStampAndNotNullSQL($query) {
$query = str_ireplace("TIMESTAMP NOT NULL", "TIMESTAMP NULL", $query);
$query = str_ireplace("DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP", '', $query);
/**
* Get an array of column names of the given table.
*/
- private function columnsOf($table) {
+ private function columnsOf($table, $force = FALSE) {
static $columnsOf = array();
$from = (substr($table, 0, 4) == 'log_') ? "`{$this->db}`.$table" : $table;
- if (!isset($columnsOf[$table])) {
- CRM_Core_Error::ignoreException();
+ if (!isset($columnsOf[$table]) || $force) {
+ $errorScope = CRM_Core_TemporaryErrorScope::ignoreException();
$dao = CRM_Core_DAO::executeQuery("SHOW COLUMNS FROM $from");
- CRM_Core_Error::setCallback();
if (is_a($dao, 'DB_Error')) {
return array();
}
$dao = new CRM_Contact_DAO_Contact();
$civiDB = $dao->_database;
}
- CRM_Core_Error::ignoreException();
+ $errorScope = CRM_Core_TemporaryErrorScope::ignoreException();
// NOTE: W.r.t Performance using one query to find all details and storing in static array is much faster
// than firing query for every given table.
$query = "
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_schema IN ('{$this->db}', '{$civiDB}')";
$dao = CRM_Core_DAO::executeQuery($query);
- CRM_Core_Error::setCallback();
if (is_a($dao, 'DB_Error')) {
return array();
}
return $columnSpecs[$table];
}
+ /**
+ * @param $civiTable
+ * @param $logTable
+ *
+ * @return array
+ */
function columnsWithDiffSpecs($civiTable, $logTable) {
$civiTableSpecs = $this->columnSpecsOf($civiTable);
$logTableSpecs = $this->columnSpecsOf($logTable);
// NOTE: we consider only those columns for modifications where there is a spec change, and that the column definition
// wasn't deliberately modified by fixTimeStampAndNotNullSQL() method.
foreach ($civiTableSpecs as $col => $colSpecs) {
+ if (!isset($logTableSpecs[$col]) || !is_array($logTableSpecs[$col]) ) {
+ $logTableSpecs[$col] = array();
+ }
+
$specDiff = array_diff($civiTableSpecs[$col], $logTableSpecs[$col]);
if (!empty($specDiff) && $col != 'id' && !array_key_exists($col, $diff['ADD'])) {
// ignore 'id' column for any spec changes, to avoid any auto-increment mysql errors
- if ($civiTableSpecs[$col]['DATA_TYPE'] != $logTableSpecs[$col]['DATA_TYPE']) {
+ if ($civiTableSpecs[$col]['DATA_TYPE'] != CRM_Utils_Array::value('DATA_TYPE', $logTableSpecs[$col])) {
// if data-type is different, surely consider the column
$diff['MODIFY'][] = $col;
- } else if ($civiTableSpecs[$col]['IS_NULLABLE'] != $logTableSpecs[$col]['IS_NULLABLE'] &&
+ } else if ($civiTableSpecs[$col]['IS_NULLABLE'] != CRM_Utils_Array::value('IS_NULLABLE', $logTableSpecs[$col]) &&
$logTableSpecs[$col]['IS_NULLABLE'] == 'NO') {
// if is-null property is different, and log table's column is NOT-NULL, surely consider the column
$diff['MODIFY'][] = $col;
- } else if ($civiTableSpecs[$col]['COLUMN_DEFAULT'] != $logTableSpecs[$col]['COLUMN_DEFAULT'] &&
+ } else if ($civiTableSpecs[$col]['COLUMN_DEFAULT'] != CRM_Utils_Array::value('COLUMN_DEFAULT', $logTableSpecs[$col]) &&
!strstr($civiTableSpecs[$col]['COLUMN_DEFAULT'], 'TIMESTAMP')) {
// if default property is different, and its not about a timestamp column, consider it
$diff['MODIFY'][] = $col;
return (bool) CRM_Core_DAO::singleValueQuery("SHOW TRIGGERS LIKE 'civicrm_contact'");
}
- function triggerInfo(&$info, $tableName = NULL) {
+ /**
+ * @param $info
+ * @param null $tableName
+ * @param bool $force
+ */
+ function triggerInfo(&$info, $tableName = NULL, $force = FALSE) {
// check if we have logging enabled
$config =& CRM_Core_Config::singleton();
if (!$config->logging) {
// logging is enabled, so now lets create the trigger info tables
foreach ($tableNames as $table) {
- $columns = $this->columnsOf($table);
+ $columns = $this->columnsOf($table, $force);
// only do the change if any data has changed
$cond = array( );