diff --git a/bin/dbsv-update.php b/bin/dbsv-update.php index 32e118b7..22c8e3d6 100644 --- a/bin/dbsv-update.php +++ b/bin/dbsv-update.php @@ -18,7 +18,7 @@ $opt['rootpath'] = dirname(__FILE__) . '/../htdocs/'; require_once($opt['rootpath'] . 'lib2/cli.inc.php'); - if (!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 up to commit 467aae4 (March 27, 2013) to enable automatic updates. @@ -44,63 +44,28 @@ } while ($db_version > 0); - // test if a database table exists - function table_exists($table) - { - global $opt; - - return sql_value("SELECT COUNT(*) - FROM `information_schema`.`tables` - WHERE `table_schema`='&1' AND `table_name`='&2'", - 0, $opt['db']['placeholder']['db'], $table) > 0; - } - - // test if a database field exists - function field_exists($table, $field) - { - global $opt; - - return sql_value("SELECT COUNT(*) - FROM `information_schema`.`columns` - WHERE `table_schema`='&1' AND `table_name`='&2' AND `column_name`='&3'", - 0, $opt['db']['placeholder']['db'], $table, $field) > 0; - } - - // get type of a database field - function field_type($table, $field) - { - global $opt; - - return strtoupper( - sql_value("SELECT `data_type` - FROM `information_schema`.`columns` - WHERE `table_schema`='&1' AND `table_name`='&2' AND `column_name`='&3'", - '', $opt['db']['placeholder']['db'], $table, $field) ); - } - - // Database mutations // - must be consecutively numbered // - should behave well if run multiple times function dbv_100() // expands log date to datetime, to enable time logging { - if (field_type('cache_logs','date') != 'DATETIME') + if (sql_field_type('cache_logs','date') != 'DATETIME') sql("ALTER TABLE `cache_logs` CHANGE COLUMN `date` `date` DATETIME NOT NULL"); - if (field_type('cache_logs_archived','date') != 'DATETIME') + if (sql_field_type('cache_logs_archived','date') != 'DATETIME') sql("ALTER TABLE `cache_logs_archived` CHANGE COLUMN `date` `date` DATETIME NOT NULL"); } function dbv_101() // add fields for fixing OKAPI issue #232 { - if (!field_exists('caches','meta_last_modified')) + if (!sql_field_exists('caches','meta_last_modified')) { // initialize with '0000-00-00 00:00:00' for existing data, that's ok sql("ALTER TABLE `caches` ADD COLUMN `meta_last_modified` DATETIME NOT NULL COMMENT 'via Trigger (cache_logs)' AFTER `listing_last_modified`"); } - if (!field_exists('cache_logs','log_last_modified')) + if (!sql_field_exists('cache_logs','log_last_modified')) { - if (field_exists('cache_logs','okapi_syncbase')) + if (sql_field_exists('cache_logs','okapi_syncbase')) $after = 'okapi_syncbase'; else $after = 'last_modified'; @@ -110,9 +75,9 @@ IFNULL((SELECT MAX(`last_modified`) FROM `pictures` WHERE `pictures`.`object_type`=1 AND `pictures`.`object_id` = `cache_logs`.`id`),'0') )"); } - if (!field_exists('cache_logs_archived','log_last_modified')) + if (!sql_field_exists('cache_logs_archived','log_last_modified')) { - if (field_exists('cache_logs_archived','okapi_syncbase')) + if (sql_field_exists('cache_logs_archived','okapi_syncbase')) $after = 'okapi_syncbase'; else $after = 'last_modified'; @@ -130,18 +95,18 @@ function dbv_103() // update comments on static tables { - if (table_exists('geodb_areas')) sql("ALTER TABLE `geodb_areas` COMMENT = 'not in use'"); - if (table_exists('geodb_changelog')) sql("ALTER TABLE `geodb_changelog` COMMENT = 'not in use'"); - if (table_exists('geodb_coordinates')) sql("ALTER TABLE `geodb_coordinates` COMMENT = 'static content'"); - if (table_exists('geodb_floatdata')) sql("ALTER TABLE `geodb_floatdata` COMMENT = 'not in use'"); - if (table_exists('geodb_hierarchies')) sql("ALTER TABLE `geodb_hierarchies` COMMENT = 'static content'"); - if (table_exists('geodb_intdata')) sql("ALTER TABLE `geodb_intdata` COMMENT = 'not in use'"); - if (table_exists('geodb_locations')) sql("ALTER TABLE `geodb_locations` COMMENT = 'static content'"); - if (table_exists('geodb_polygons')) sql("ALTER TABLE `geodb_polygons` COMMENT = 'not in use'"); - if (table_exists('geodb_search')) sql("ALTER TABLE `geodb_search` COMMENT = 'static content, not in use'"); - if (table_exists('geodb_textdata')) sql("ALTER TABLE `geodb_textdata` COMMENT = 'static content'"); - if (table_exists('geodb_type_names')) sql("ALTER TABLE `geodb_type_names` COMMENT = 'not in use'"); - if (table_exists('pw_dict')) sql("ALTER TABLE `pw_dict` COMMENT = 'static content'"); + if (sql_table_exists('geodb_areas')) sql("ALTER TABLE `geodb_areas` COMMENT = 'not in use'"); + if (sql_table_exists('geodb_changelog')) sql("ALTER TABLE `geodb_changelog` COMMENT = 'not in use'"); + if (sql_table_exists('geodb_coordinates')) sql("ALTER TABLE `geodb_coordinates` COMMENT = 'static content'"); + if (sql_table_exists('geodb_floatdata')) sql("ALTER TABLE `geodb_floatdata` COMMENT = 'not in use'"); + if (sql_table_exists('geodb_hierarchies')) sql("ALTER TABLE `geodb_hierarchies` COMMENT = 'static content'"); + if (sql_table_exists('geodb_intdata')) sql("ALTER TABLE `geodb_intdata` COMMENT = 'not in use'"); + if (sql_table_exists('geodb_locations')) sql("ALTER TABLE `geodb_locations` COMMENT = 'static content'"); + if (sql_table_exists('geodb_polygons')) sql("ALTER TABLE `geodb_polygons` COMMENT = 'not in use'"); + if (sql_table_exists('geodb_search')) sql("ALTER TABLE `geodb_search` COMMENT = 'static content, not in use'"); + if (sql_table_exists('geodb_textdata')) sql("ALTER TABLE `geodb_textdata` COMMENT = 'static content'"); + if (sql_table_exists('geodb_type_names')) sql("ALTER TABLE `geodb_type_names` COMMENT = 'not in use'"); + if (sql_table_exists('pw_dict')) sql("ALTER TABLE `pw_dict` COMMENT = 'static content'"); sql("ALTER TABLE `npa_areas` COMMENT = 'static content'"); sql("ALTER TABLE `npa_types` COMMENT = 'static content'"); sql("ALTER TABLE `nuts_codes` COMMENT = 'static content'"); @@ -154,15 +119,15 @@ sql("ALTER TABLE `cache_logtype` COMMENT = 'obsolete'"); sql("ALTER TABLE `log_types` CHANGE COLUMN `cache_status` `cache_status` tinyint(1) NOT NULL default '0'"); sql("ALTER TABLE `log_types` CHANGE COLUMN `en` `en` varchar(60) NOT NULL"); - if (!field_exists('stat_caches','maintenance')) + if (!sql_field_exists('stat_caches','maintenance')) sql("ALTER TABLE `stat_caches` ADD COLUMN `maintenance` smallint(5) unsigned NOT NULL AFTER `will_attend`"); - if (!field_exists('stat_cache_logs','maintenance')) + if (!sql_field_exists('stat_cache_logs','maintenance')) sql("ALTER TABLE `stat_cache_logs` ADD COLUMN `maintenance` smallint(5) unsigned NOT NULL AFTER `will_attend`"); - if (!field_exists('stat_user','maintenance')) + if (!sql_field_exists('stat_user','maintenance')) sql("ALTER TABLE `stat_user` ADD COLUMN `maintenance` smallint(5) unsigned NOT NULL AFTER `will_attend`"); - if (!field_exists('cache_logs','oc_team_comment')) + if (!sql_field_exists('cache_logs','oc_team_comment')) sql("ALTER TABLE `cache_logs` ADD COLUMN `oc_team_comment` tinyint(1) NOT NULL default '0' AFTER `type`"); - if (!field_exists('cache_logs_archived','oc_team_comment')) + if (!sql_field_exists('cache_logs_archived','oc_team_comment')) sql("ALTER TABLE `cache_logs_archived` ADD COLUMN `oc_team_comment` tinyint(1) NOT NULL default '0' AFTER `type`"); // The new fields need not to be initialized, as these are new features and all // values are initally zero. @@ -170,9 +135,9 @@ function dbv_105() // HTML user profile texts { - if (!field_exists('user','desc_htmledit')) + if (!sql_field_exists('user','desc_htmledit')) sql("ALTER TABLE `user` ADD COLUMN `desc_htmledit` tinyint(1) unsigned NOT NULL DEFAULT '1' AFTER `data_license`"); - if (!field_exists('user','description')) + if (!sql_field_exists('user','description')) { sql("ALTER TABLE `user` ADD COLUMN `description` mediumtext NOT NULL AFTER `data_license`"); $rs = sql("SELECT `user`.`user_id`,`user_options`.`option_value` FROM `user`,`user_options` WHERE `user_options`.`user_id`=`user`.`user_id` AND `user_options`.`option_id`=3"); diff --git a/bin/dbupdate.php b/bin/dbupdate.php index ff4ef779..fbed4494 100644 --- a/bin/dbupdate.php +++ b/bin/dbupdate.php @@ -25,11 +25,23 @@ chdir ($rootpath . 'doc/sql/stored-proc'); system('php maintain.php'); - echo "updating OKAPI database\n"; - chdir ($rootpath . '../bin'); - system('php okapi-update.php | grep -i -e mutation'); + // We do *two* tests for OKAPI presence to get some robustness agains internal OKAPI changes. + // This should be replaced by a facade function call. + $okapi_vars = sql_table_exists('okapi_vars'); + $okapi_syncbase = sql_field_exists('caches','okapi_syncbase'); + if ($okapi_vars != $okapi_syncbase) + { + echo "!! unknown OKAPI configuration; either dbupdate.php needs an update or your database configuration is wrong\n"; + } + else if ($okapi_vars) + { + echo "updating OKAPI database\n"; + chdir ($rootpath . '../bin'); + system('php okapi-update.php | grep -i -e mutation'); + } echo "resetting webcache:\n"; + chdir ($rootpath . '../bin'); system('php clear-webcache.php'); ?> \ No newline at end of file diff --git a/htdocs/lib2/db.inc.php b/htdocs/lib2/db.inc.php index 20d39064..4376bbb3 100644 --- a/htdocs/lib2/db.inc.php +++ b/htdocs/lib2/db.inc.php @@ -32,6 +32,10 @@ sql_export_table($f, $table) ... export table to file sql_export_table_to_file($filename, $table) + sql_table_exists ... tests if a table exists + sql_field_exists ... tests if a table and a field in this table exist + sql_field_type ... queries the type of a field (uppercase letters) + // slave query functions sql_slave_exclude() ... do not use slave servers for the current user until the slaves have replicated to this point @@ -1081,4 +1085,39 @@ sql_export_structure($f, $table); fclose($f); } + + // test if a database table exists + function sql_table_exists($table) + { + global $opt; + + return sql_value("SELECT COUNT(*) + FROM `information_schema`.`tables` + WHERE `table_schema`='&1' AND `table_name`='&2'", + 0, $opt['db']['placeholder']['db'], $table) > 0; + } + + // test if a database field exists + function sql_field_exists($table, $field) + { + global $opt; + + return sql_value("SELECT COUNT(*) + FROM `information_schema`.`columns` + WHERE `table_schema`='&1' AND `table_name`='&2' AND `column_name`='&3'", + 0, $opt['db']['placeholder']['db'], $table, $field) > 0; + } + + // get type of a database field + function sql_field_type($table, $field) + { + global $opt; + + return strtoupper( + sql_value("SELECT `data_type` + FROM `information_schema`.`columns` + WHERE `table_schema`='&1' AND `table_name`='&2' AND `column_name`='&3'", + '', $opt['db']['placeholder']['db'], $table, $field) ); + } + ?> \ No newline at end of file