$cols = $this->columnsWithDiffSpecs($table, "log_$table");
}
+ // If a column that already exists on logging table is being added, we
+ // should treat it as a modification.
+ $this->resetSchemaCacheForTable("log_$table");
+ $logTableSchema = $this->columnSpecsOf("log_$table");
+ foreach ($cols['ADD'] as $colKey => $col) {
+ if (array_key_exists($col, $logTableSchema)) {
+ $cols['MODIFY'][] = $col;
+ unset($cols['ADD'][$colKey]);
+ }
+ }
+
// use the relevant lines from CREATE TABLE to add colums to the log table
$create = $this->_getCreateQuery($table);
foreach ((['ADD', 'MODIFY']) as $alterType) {
}
}
+ $this->resetSchemaCacheForTable("log_$table");
+
return TRUE;
}
+ /**
+ * Resets schema cache for the given table.
+ *
+ * @param string $table
+ * Name of the table.
+ */
+ private function resetSchemaCacheForTable($table) {
+ unset(\Civi::$statics[__CLASS__]['columnSpecs'][$table]);
+ }
+
/**
* Get query table.
*
*/
public function fixSchemaDifferencesForAll($rebuildTrigger = FALSE) {
$diffs = [];
+ $this->resetTableColumnsCache();
+
foreach ($this->tables as $table) {
if (empty($this->logs[$table])) {
$this->createLogTableFor($table);
}
}
+ /**
+ * Resets columnSpecs.
+ *
+ * Resets columnSpecs static array in Civi's $statics to make sure we use the
+ * real state of the schema to perform sync operations between core and
+ * logging tables.
+ */
+ private function resetTableColumnsCache() {
+ unset(\Civi::$statics[__CLASS__]['columnSpecs']);
+ }
+
/**
* Fix timestamp.
*
}
\Civi::$statics[__CLASS__]['columnsOf'][$table] = [];
while ($dao->fetch()) {
- \Civi::$statics[__CLASS__]['columnsOf'][$table][] = CRM_Utils_type::escape($dao->Field, 'MysqlColumnNameOrAlias');
+ \Civi::$statics[__CLASS__]['columnsOf'][$table][] = CRM_Utils_Type::escape($dao->Field, 'MysqlColumnNameOrAlias');
}
}
return \Civi::$statics[__CLASS__]['columnsOf'][$table];
// logging is enabled, so now lets create the trigger info tables
foreach ($tableNames as $table) {
+ if (!isset($this->logTableSpec[$table])) {
+ // Per testIgnoreCustomTableByHook this would be unset if a hook had
+ // intervened to prevent logging / triggers on this table.
+ // This could go to the extent of blocking the updates to 'modified_date'
+ // which makes sense, in particular, for calculated fields.
+ continue;
+ }
$columns = $this->columnsOf($table, $force);
// only do the change if any data has changed