improved trigger/sp handling of database versioning

- skip dbsv-update if triggers/sp are not installed (yet)
- added safeguard against downgrading to old trigger/sp versions
This commit is contained in:
following
2013-06-27 21:59:38 +02:00
parent 6826f3211f
commit 7c007d564a
5 changed files with 131 additions and 29 deletions

View File

@@ -22,10 +22,24 @@
require_once($opt['rootpath'] . 'lib2/cli.inc.php'); require_once($opt['rootpath'] . 'lib2/cli.inc.php');
if (!sql_field_exists('cache_attrib','gc_id')) if (!sql_field_exists('cache_attrib','gc_id'))
die("\n {
ERROR: Database structure too old. You must first do a manual update die(
up to commit 467aae4 (March 27, 2013) to enable automatic updates. " ERROR: Database structure too old. You must first do a manual update\n" .
See htdocs/doc/sql/db-changes.txt.\n"); " up to commit 467aae4 (March 27, 2013) to enable automatic updates.\n" .
" See htdocs/doc/sql/db-changes.txt.\n");
// Do not continue with dbupdate.php, because the current data.sql and
// maintain.php will not fit either.
}
if (!sql_function_exists('distance') || !sql_procedure_exists('sp_touch_cache'))
{
// We need a consistent starting point including triggers & functions, and it's
// safer not to decide HERE which trigger version to install.
echo "Triggers / DB functions are not installed (yet) - skipping DB versioning.\n";
exit;
// continue with dbupdate.php if called from there and let's hope
// maintain.php matches the installed tables' DB version ...
}
$db_version = max(99, sql_value("SELECT `value` FROM `sysconfig` WHERE `name`='db_version'",99)); $db_version = max(99, sql_value("SELECT `value` FROM `sysconfig` WHERE `name`='db_version'",99));
@@ -59,15 +73,27 @@
{ {
global $opt, $db_version; global $opt, $db_version;
$syncfile = $opt['rootpath'] . 'cache2/dbsv-running'; // For the case we re-run an old mutation for some accident, we must make
file_put_contents($syncfile,'dbsv is running'); // sure that we are not downgrading to an old trigger version (which may be
// incompatible with the current database structures.
if (sql_function_exists('dbsvTriggerVersion'))
$trigger_version = sql_value('SELECT dbsvTriggerVersion()',0);
else
$trigger_version = 0;
system('php ' . $opt['rootpath'] . 'doc/sql/stored-proc/maintain.php --dbsv '.$db_version.' --flush'); if ($trigger_version < $db_version)
if (file_exists($syncfile))
{ {
die("\nmaintain.php was not properly executed\n"); $syncfile = $opt['rootpath'] . 'cache2/dbsv-running';
unlink($syncfile); file_put_contents($syncfile,'dbsv is running');
system('php ' . $opt['rootpath'] . 'doc/sql/stored-proc/maintain.php --dbsv '.$db_version.' --flush');
// This will also update dbsvTriggerVersion.
if (file_exists($syncfile))
{
die("\nmaintain.php was not properly executed\n");
unlink($syncfile);
}
} }
} }
@@ -274,8 +300,23 @@
sql("ALTER TABLE `caches` ADD INDEX `wp_gc_maintained` (`wp_gc_maintained`)"); sql("ALTER TABLE `caches` ADD INDEX `wp_gc_maintained` (`wp_gc_maintained`)");
} }
function dbv_113() // preventive trigger update function dbv_113() // preventive, initial trigger update
{ {
// The if-condition ensures that we will not downgrade to an old trigger
// version for the case this function is re-run by some accident.
// For future trigger updates, this will be ensured by the version
// number returned by dbsvTriggerVersion().
if (!sql_function_exists('dbsvTriggerVersion'))
update_triggers();
}
function dbv_114() // add dbsvTriggerVersion
{
// dbsvTriggerVersion was introduced AFTER defining mutation #113 (it was
// inserted there later). So we need to additionally install it on installations
// which already updated to v113:
update_triggers(); update_triggers();
} }

View File

@@ -1745,4 +1745,13 @@
UPDATE caches SET meta_last_modified=NOW() WHERE caches.wp_oc=OLD.wp; UPDATE caches SET meta_last_modified=NOW() WHERE caches.wp_oc=OLD.wp;
END;"); END;");
// Update trigger version.
// Keep this at the end of this file.
sql_dropFunction('dbsvTriggerVersion');
$db_version = sqlValue("SELECT `value` FROM `sysconfig` WHERE `name`='db_version'", 0);
sql("
CREATE FUNCTION `dbsvTriggerVersion` () RETURNS INT
RETURN '&1'",
$db_version);
?> ?>

View File

@@ -0,0 +1,19 @@
<?php
/***************************************************************************
Unicode Reminder メモ
initialize trigger version function
***************************************************************************/
// We run this via maintain.php instead of dbsv-update.php because the
// latter one has no sufficient privileges yet for updating functions
// (should be changed / may have been changed when you are reading this.)
sql_dropFunction('dbsvTriggerVersion');
sql("
CREATE FUNCTION `dbsvTriggerVersion` () RETURNS INT
RETURN 114");
?>

View File

@@ -1739,4 +1739,14 @@
UPDATE caches SET meta_last_modified=NOW() WHERE caches.wp_oc=OLD.wp; UPDATE caches SET meta_last_modified=NOW() WHERE caches.wp_oc=OLD.wp;
END;"); END;");
// Update trigger version function.
// Keep this at the end of this file.
sql_dropFunction('dbsvTriggerVersion');
$db_version = sqlValue("SELECT `value` FROM `sysconfig` WHERE `name`='db_version'", 0);
sql("
CREATE FUNCTION `dbsvTriggerVersion` () RETURNS INT
RETURN '&1'",
$db_version);
?> ?>

View File

@@ -1089,22 +1089,6 @@
fclose($f); fclose($f);
} }
function sql_dropFunction($name)
{
global $dbname;
$rs = sql("SHOW FUNCTION STATUS LIKE '&1'", $name);
while ($r = sql_fetch_assoc($rs))
{
if ($r['Db'] == $dbname && $r['Name'] == $name && $r['Type'] == 'FUNCTION')
{
sql('DROP FUNCTION `&1`', $name);
return;
}
}
sql_free_result($rs);
}
// test if a database table exists // test if a database table exists
function sql_table_exists($table) function sql_table_exists($table)
{ {
@@ -1150,4 +1134,43 @@
0, $opt['db']['placeholder']['db'], $table, $index) > 0; 0, $opt['db']['placeholder']['db'], $table, $index) > 0;
} }
// test if a function or procedure exists
function sql_fp_exists($type, $name)
{
global $opt;
$rs = sql("SHOW $type STATUS LIKE '&1'", $name);
$r = sql_fetch_assoc($rs);
sql_free_result($rs);
return ($r &&
$r['Db'] == $opt['db']['placeholder']['db'] &&
$r['Name'] == $name &&
$r['Type'] == $type);
}
// test if a function exists
function sql_function_exists($name)
{
return sql_fp_exists('FUNCTION',$name);
}
// delete a function
function sql_dropFunction($name)
{
sql('DROP FUNCTION IF EXISTS `&1`', $name);
}
// test if a procedure exists
function sql_procedure_exists($name)
{
return sql_fp_exists('PROCEDURE',$name);
}
// delete a procedure
function sql_dropProcedure($name)
{
sql('DROP PROCEDURE IF EXISTS `&1`', $name);
}
?> ?>