X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=CRM%2FUpgrade%2FSnapshot.php;h=9f5a493844f298b7c47ddcb8229fb0743a772df1;hb=ee58635b82ac5c92bdfc9fbb5c7f9b670ee86a31;hp=442aed6de1bed80d0ae55aa4844ba62551438a94;hpb=1564970e27330002832e16414e6951085ca76284;p=civicrm-core.git diff --git a/CRM/Upgrade/Snapshot.php b/CRM/Upgrade/Snapshot.php index 442aed6de1..9f5a493844 100644 --- a/CRM/Upgrade/Snapshot.php +++ b/CRM/Upgrade/Snapshot.php @@ -40,7 +40,10 @@ class CRM_Upgrade_Snapshot { */ public static function getActivationIssues(): array { if (static::$activationIssues === NULL) { - // TODO This policy should probably be more configurable, eg via `setting` or `define()`. + $policy = CRM_Utils_Constant::value('CIVICRM_UPGRADE_SNAPSHOT', 'auto'); + if ($policy === TRUE) { + return []; + } $limits = [ 'civicrm_contact' => 200 * 1000, @@ -71,6 +74,10 @@ class CRM_Upgrade_Snapshot { if (CRM_Core_I18n::isMultilingual()) { static::$activationIssues['multilingual'] = ts('Multilingual snapshots have not been implemented.'); } + + if ($policy === FALSE) { + static::$activationIssues['override'] = ts('Snapshots disabled by override (CIVICRM_UPGRADE_SNAPSHOT).'); + } } return static::$activationIssues; @@ -79,28 +86,53 @@ class CRM_Upgrade_Snapshot { /** * Create the name of a MySQL snapshot table. * + * @param string $owner + * Name of the component/module/extension that owns the snapshot. + * Ex: 'civicrm', 'sequentialcreditnotes', 'oauth_client' * @param string $version * Ex: '5.50' * @param string $name * Ex: 'dates' * @return string - * Ex: 'civicrm_snap_v5_50_dates' + * Ex: 'snap_civicrm_v5_50_dates' + * @throws \CRM_Core_Exception + * If the resulting table name would be invalid, then this throws an exception. */ - public static function createTableName(string $version, string $name): string { - [$major, $minor] = explode('.', $version); - return sprintf('civicrm_snap_v%s_%s_%s', $major, $minor, $name); + public static function createTableName(string $owner, string $version, string $name): string { + $versionParts = explode('.', $version); + if (count($versionParts) !== 2) { + throw new \CRM_Core_Exception("Snapshot support is currently only defined for two-part version (MAJOR.MINOR). Found ($version)."); + // If you change this, be sure to consider `cleanupTask()` as well. + // One reason you might change it -- if you were going to track with the internal schema-numbers from an extension. + // Of course, you could get similar effect with "0.{$schemaNumber}" eg "5002" ==> "0.5002" + } + $versionExpr = ($versionParts[0] . '_' . $versionParts[1]); + + $table = sprintf('snap_%s_v%s_%s', $owner, $versionExpr, $name); + if (!preg_match(';^[a-z0-9_]+$;', $table)) { + throw new CRM_Core_Exception("Malformed snapshot name ($table)"); + } + if (strlen($table) > 64) { + throw new CRM_Core_Exception("Snapshot name is too long ($table)"); + } + + return $table; } /** * Build a set of queueable tasks which will store a snapshot. * + * @param string $owner + * Name of the component/module/extension that owns the snapshot. + * Ex: 'civicrm', 'sequentialcreditnotes', 'oauth_client' * @param string $version + * Ex: '5.50' * @param string $name * @param \CRM_Utils_SQL_Select $select * @throws \CRM_Core_Exception */ - public static function createTasks(string $version, string $name, CRM_Utils_SQL_Select $select): iterable { - $destTable = static::createTableName($version, $name); + public static function createTasks(string $owner, string $version, string $name, CRM_Utils_SQL_Select $select): iterable { + $destTable = static::createTableName($owner, $version, $name); $srcTable = \Civi\Test\Invasive::get([$select, 'from']); // Sometimes, backups fail and people rollback and try again. Reset prior snapshots. @@ -144,14 +176,17 @@ class CRM_Upgrade_Snapshot { * Cleanup any old snapshot tables. * * @param CRM_Queue_TaskContext|null $ctx + * @param string $owner + * Ex: 'civicrm', 'sequentialcreditnotes', 'oauth_client' * @param string|null $version * The current version of CiviCRM. * @param int|null $cleanupAfter * How long should we retain old snapshots? * Time is measured in terms of MINOR versions - eg "4" means "retain for 4 MINOR versions". * Thus, on v5.60, you could delete any snapshots predating 5.56. + * @return bool */ - public static function cleanupTask(?CRM_Queue_TaskContext $ctx = NULL, ?string $version = NULL, ?int $cleanupAfter = NULL): void { + public static function cleanupTask(?CRM_Queue_TaskContext $ctx = NULL, string $owner = 'civicrm', ?string $version = NULL, ?int $cleanupAfter = NULL): bool { $version = $version ?: CRM_Core_BAO_Domain::version(); $cleanupAfter = $cleanupAfter ?: static::$cleanupAfter; @@ -163,13 +198,15 @@ class CRM_Upgrade_Snapshot { SELECT TABLE_NAME as tableName FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = %1 - AND TABLE_NAME LIKE 'civicrm_snap_v%' + AND TABLE_NAME LIKE %2 "; - $tables = CRM_Core_DAO::executeQuery($query, [1 => [$dao->database(), 'String']]) - ->fetchMap('tableName', 'tableName'); + $tables = CRM_Core_DAO::executeQuery($query, [ + 1 => [$dao->database(), 'String'], + 2 => ["snap_{$owner}_v%", 'String'], + ])->fetchMap('tableName', 'tableName'); - $oldTables = array_filter($tables, function($table) use ($cutoff) { - if (preg_match(';^civicrm_snap_v(\d+)_(\d+)_;', $table, $m)) { + $oldTables = array_filter($tables, function($table) use ($owner, $cutoff) { + if (preg_match(";^snap_{$owner}_v(\d+)_(\d+)_;", $table, $m)) { $generatedVer = $m[1] . '.' . $m[2]; return (bool) version_compare($generatedVer, $cutoff, '<'); } @@ -177,6 +214,7 @@ class CRM_Upgrade_Snapshot { }); array_map(['CRM_Core_BAO_SchemaHandler', 'dropTable'], $oldTables); + return TRUE; } }