<?php
include_once($INC . "/sql.inc.php");
include_once($INC . "/state.inc.php");
include_once($INC . "/util.inc.php");
define("RG_DROP_TABLES", 1);
define("RG_IGNORE_ERRORS", 1 << 1);
$rg_sql_struct_slaves = array();
$rg_sql_struct = array();
$rg_sql_struct[1] = array();
$rg_sql_struct[1]['tables'] = array(
"repos" => "CREATE TABLE repos"
. " (repo_id SERIAL PRIMARY KEY"
. ", name TEXT UNIQUE NOT NULL"
. ", uid INTEGER NOT NULL"
. ", itime INTEGER NOT NULL"
. ", disk_quota_mb INTEGER DEFAULT 0"
. ", disk_used_mb INTEGER NOT NULL DEFAULT 0"
. ", max_commit_size INTEGER DEFAULT 0"
. ", master INTEGER NOT NULL DEFAULT 0"
. ", description TEXT NOT NULL DEFAULT ''"
. ", git_dir_done INTEGER NOT NULL DEFAULT 0"
. ", default_rights TEXT NOT NULL DEFAULT ''"
. ", deleted INTEGER NOT NULL DEFAULT 0"
. ", max_users INTEGER NOT NULL DEFAULT 0"
. ")",
"rights" => "CREATE TABLE rights"
. " (type TEXT NOT NULL"
. ", obj_id INTEGER NOT NULL"
. ", uid INTEGER NOT NULL"
. ", rights TEXT NOT NULL"
. ", itime INTEGER NOT NULL)",
"state" => "CREATE TABLE state"
. " (var TEXT PRIMARY KEY"
. ", value TEXT NOT NULL)",
"keys" => "CREATE TABLE keys"
. " (key_id SERIAL PRIMARY KEY"
. ", itime INTEGER NOT NULL"
. ", uid INTEGER NOT NULL"
. ", key TEXT UNIQUE NOT NULL)",
"users" => "CREATE TABLE users"
. " (uid SERIAL PRIMARY KEY"
. ", username TEXT UNIQUE NOT NULL"
. ", realname TEXT NOT NULL"
. ", salt TEXT NOT NULL"
. ", pass TEXT NOT NULL"
. ", email TEXT NOT NULL"
. ", itime INTEGER NOT NULL"
. ", suspended INTEGER NOT NULL DEFAULT 0"
. ", session_time INTEGER NOT NULL DEFAULT 3600"
. ", last_seen INTEGER NOT NULL DEFAULT 0"
. ", is_admin INTEGER NOT NULL DEFAULT 0"
. ", disk_quota_mb INTEGER NOT NULL DEFAULT 0"
. ", disk_used_mb INTEGER NOT NULL DEFAULT 0"
. ", rights TEXT NOT NULL"
. ", confirmed INTEGER NOT NULL DEFAULT 0"
. ", confirm_token TEXT NOT NULL DEFAULT ''"
. ")",
"sess" => "CREATE TABLE sess"
. " (sid TEXT PRIMARY KEY"
. ", uid INTEGER NOT NULL"
. ", expire INTEGER NOT NULL"
. ", session_time INTEGER NOT NULL"
. ", ip TEXT NOT NULL)",
"forgot_pass" => "CREATE TABLE forgot_pass"
. " (token TEXT PRIMARY KEY"
. ", uid INTEGER NOT NULL"
. ", expire INTEGER NOT NULL)",
"tokens" => "CREATE TABLE tokens"
. " (token TEXT PRIMARY KEY"
. ", sid TEXT NOT NULL"
. ", expire INTEGER NOT NULL)"
);
$rg_sql_struct[1]['other'] = array();
$rg_sql_struct[2] = array();
$rg_sql_struct[2]['tables'] = array(
"suggestions" => "CREATE TABLE suggestions"
. " (suggestion_id SERIAL PRIMARY KEY"
. ", uid INTEGER NOT NULL"
. ", email TEXT NOT NULL"
. ", suggestion TEXT NOT NULL)"
);
$rg_sql_struct[2]['other'] = array();
$rg_sql_struct[3] = array();
$rg_sql_struct[3]['tables'] = array();
$rg_sql_struct[3]['other'] = array(
"add organization field to user" => "ALTER TABLE users"
. " ADD organization SMALLINT NOT NULL DEFAULT 0"
);
$rg_sql_struct[4] = array();
$rg_sql_struct[4]['tables'] = array(
"merge_requests" => "CREATE TABLE merge_requests ("
. "repo_id INT NOT NULL"
. ", itime INT NOT NULL"
. ", namespace TEXT NOT NULL"
. ", refname TEXT NOT NULL"
. ", old_rev CHAR(40) NOT NULL"
. ", new_rev CHAR(40) NOT NULL"
. ", done INT NOT NULL DEFAULT 0"
. ", ip TEXT NOT NULL"
. ")"
);
$rg_sql_struct[4]['other'] = array(
"merge_request_index_repo_id" => "CREATE INDEX merge_requests_i_repo_id"
. " ON merge_requests (repo_id)"
);
$rg_sql_struct[5] = array();
$rg_sql_struct[5]['tables'] = array(
"history_push" => "CREATE TABLE history_push ("
. "itime INT NOT NULL"
. ", repo_id INT NOT NULL"
. ", ip TEXT NOT NULL"
. ", refname TEXT NOT NULL"
. ", old_rev CHAR(40) NOT NULL"
. ", new_rev CHAR(40) NOT NULL"
. ")"
);
$rg_sql_struct[6] = array();
$rg_sql_struct[6]['tables'] = array(
"bugs_max" => "CREATE TABLE bugs_max ("
. "repo_id INT NOT NULL PRIMARY KEY"
. ", last_bug_id INT NOT NULL"
. ")",
"bugs" => "CREATE TABLE bugs ("
. "repo_id INT NOT NULL"
. ", bug_id INT NOT NULL"
. ", itime INT NOT NULL"
. ", utime INT NOT NULL"
. ", uid INT NOT NULL"
. ", ip TEXT NOT NULL"
. ", title TEXT NOT NULL"
. ", body TEXT NOT NULL"
. ", state SMALLINT NOT NULL"
. ", assigned_uid INT NOT NULL"
. ", deleted INT NOT NULL"
. ")",
"bug_notes" => "CREATE TABLE bug_notes ("
. "repo_id INT NOT NULL"
. ", bug_id INT NOT NULL"
. ", note TEXT NOT NULL"
. ", itime INT NOT NULL"
. ", uid INT NOT NULL"
. ", ip TEXT NOT NULL"
. ")",
"bug_labels" => "CREATE TABLE bug_labels ("
. "repo_id INT NOT NULL"
. ", bug_id INT NOT NULL"
. ", label TEXT NOT NULL"
. ")"
);
$rg_sql_struct[6]['other'] = array(
"bugs_index_repo_id_bug_id" => "CREATE UNIQUE INDEX bugs_i_repo_id_bug_id"
. " ON bugs (repo_id, bug_id)",
"bugs_index_itime" => "CREATE INDEX bugs_i_itime"
. " ON bugs (itime)",
"bug_notes_index_repo_id_bug_id" => "CREATE INDEX bug_notes_i_repo_id_bug_id"
. " ON bug_notes (repo_id, bug_id)",
"bug_labels_index_repo_id_bug_id" => "CREATE INDEX bug_labels_i_repo_id_bug_id"
. " ON bug_labels (repo_id, bug_id)"
);
$rg_sql_struct[7] = array();
$rg_sql_struct[7]['tables'] = array(
"bug_search" => "CREATE TABLE bug_search ("
. "repo_id INT NOT NULL"
. ", uid INT NOT NULL"
. ", name TEXT NOT NULL"
. ", data TEXT NOT NULL"
. ", for_all_users SMALLINT NOT NULL"
. ")"
);
$rg_sql_struct[7]['other'] = array(
"bug_search_repo_id_uid" => "CREATE INDEX bug_search_i_repo_id_uid"
. " ON bug_search(repo_id, uid)"
);
$rg_sql_struct[8] = array();
$rg_sql_struct[8]['tables'] = array();
$rg_sql_struct[8]['other'] = array(
"more info for keys: last_use" => "ALTER TABLE keys"
. " ADD last_use INT NOT NULL DEFAULT 0",
"more info for keys: last_ip" => "ALTER TABLE keys"
. " ADD last_ip TEXT NOT NULL DEFAULT ''"
);
$rg_sql_struct[9] = array();
$rg_sql_struct[9]['tables'] = array();
$rg_sql_struct[9]['other'] = array(
"index on key_id" => "CREATE INDEX keys_i_key_id"
. " ON keys(key_id)",
"index on repos names" => "CREATE INDEX repos_i_name"
. " ON repos(name)"
);
$rg_sql_struct[10] = array();
$rg_sql_struct[10]['tables'] = array(
"repo_history" => "CREATE TABLE repo_history ("
. "itime INT NOT NULL"
. ", repo_id INT NOT NULL"
. ", category SMALLINT NOT NULL"
. ", message TEXT NOT NULL)"
);
$rg_sql_struct[10]['other'] = array();
$rg_sql_struct_slaves['repo_history'] = "repo_history";
$rg_sql_struct[11] = array();
$rg_sql_struct[11]['tables'] = array(
"events" => "CREATE TABLE events ("
. "id BIGSERIAL PRIMARY KEY"
. ", itime INT NOT NULL"
. ", prio SMALLINT NOT NULL"
. ", data TEXT NOT NULL)"
);
$rg_sql_struct[11]['other'] = array();
$rg_sql_struct[12] = array();
$rg_sql_struct[12]['tables'] = array();
$rg_sql_struct[12]['other'] = array(
"index repos-uid" => "CREATE INDEX repos_i_uid ON repos(uid)",
"index on repos-repo_id" => "CREATE INDEX repos_i_repo_id ON repos(repo_id)"
);
$rg_sql_struct[13] = array();
$rg_sql_struct[13]['tables'] = array(
"repos_renames" => "CREATE TABLE repos_renames ("
. "uid INT NOT NULL"
. ", old_name TEXT NOT NULL"
. ", itime INT NOT NULL"
. ", repo_id INT NOT NULL)"
);
$rg_sql_struct[13]['other'] = array(
"repos_renames_index_ui_old_name" => "CREATE INDEX repos_renames_i_uid_old_name"
. " ON repos_renames(uid, old_name)"
);
$rg_sql_struct[14] = array();
$rg_sql_struct[14]['tables'] = array(
"users_renames" => "CREATE TABLE users_renames ("
. "uid INT NOT NULL"
. ", old_name TEXT NOT NULL"
. ", itime INT NOT NULL)"
);
$rg_sql_struct[14]['other'] = array(
"users_renames_index_old_name" =>
"CREATE INDEX users_renames_i_old_name ON repos_renames(old_name)"
);
$rg_sql_struct[15] = array();
$rg_sql_struct[15]['tables'] = array(
"watch_repo" => "CREATE TABLE watch_repo ("
. "uid INT NOT NULL"
. ", repo_id INT NOT NULL)",
"watch_bug" => "CREATE TABLE watch_bug ("
. "uid INT NOT NULL"
. ", repo_id INT NOT NULL"
. ", bug_id INT NOT NULL)"
);
$rg_sql_struct[16] = array();
$rg_sql_struct[16]['other'] = array(
"ssh_usage_count" => "ALTER TABLE keys"
. " ADD count INT NOT NULL DEFAULT 0"
);
$rg_sql_struct[17] = array();
$rg_sql_struct[17]['other'] = array(
"misc_field_for_rights" => "ALTER TABLE rights"
. " ADD misc TEXT NOT NULL DEFAULT ''"
);
$rg_sql_struct[18] = array();
$rg_sql_struct[18]['tables'] = array(
"plans" => "CREATE TABLE plans (id SERIAL PRIMARY KEY"
. ", name TEXT NOT NULL DEFAULT ''"
. ", disk_mb INT NOT NULL DEFAULT 0"
. ", users INT NOT NULL DEFAULT 0"
. ", bw INT NOT NULL DEFAULT 0"
. ", position INT NOT NULL DEFAULT 0"
. ")"
);
$rg_sql_struct[18]['other'] = array(
"plan_id" => "ALTER TABLE users ADD plan_id INT NOT NULL DEFAULT 0",
"commit_size" => "ALTER TABLE plans ADD commit_size INT NOT NULL DEFAULT 0",
"disk_quota" => "ALTER TABLE users DROP disk_quota_mb",
"plan_desc" => "ALTER TABLE plans ADD description TEXT NOT NULL DEFAULT ''",
"plan_speed" => "ALTER TABLE plans ADD speed INT NOT NULL DEFAULT 0",
"standard plan" => "INSERT INTO plans (name, disk_mb, users, bw"
. ", speed, commit_size, description, position)"
. " VALUES ('Standard', 0, 0, 0, 0, 0, 'Standard plan', 1000)",
"key_first" => "ALTER TABLE keys ADD first_use INT NOT NULL DEFAULT 0"
);
$rg_sql_struct[19] = array();
$rg_sql_struct[19]['tables'] = array();
$rg_sql_struct[19]['other'] = array(
"rights_prio" => "ALTER TABLE rights ADD prio INT NOT NULL DEFAULT 0"
);
$rg_sql_struct[20] = array();
$rg_sql_struct[20]['tables'] = array();
$rg_sql_struct[20]['other'] = array(
"repo_drop_max_users" => "ALTER TABLE repos DROP max_users"
);
$rg_sql_struct[21] = array();
$rg_sql_struct[21]['tables'] = array();
$rg_sql_struct[21]['other'] = array(
"plans_max_public_repos" =>
"ALTER TABLE plans ADD max_public_repos INT NOT NULL DEFAULT 0",
"plans_max_private_repos" =>
"ALTER TABLE plans ADD max_private_repos INT NOT NULL DEFAULT 0"
);
$rg_sql_struct[22] = array();
$rg_sql_struct[22]['tables'] = array();
$rg_sql_struct[22]['other'] = array(
"users_last_ip" => "ALTER TABLE users"
. " ADD last_ip TEXT NOT NULL DEFAULT '?'"
);
$rg_sql_struct[23] = array();
$rg_sql_struct[23]['tables'] = array();
$rg_sql_struct[23]['other'] = array(
"repo_public_private" => "ALTER TABLE repos"
. " ADD public INT NOT NULL DEFAULT 0"
);
$rg_sql_struct[24] = array();
$rg_sql_struct[24]['tables'] = array();
$rg_sql_struct[24]['other'] = array(
"default_rights are not used anymore" => "ALTER TABLE repos"
. " DROP default_rights"
);
$rg_sql_struct[25] = array();
$rg_sql_struct[25]['tables'] = array();
$rg_sql_struct[25]['other'] = array(
"we must record who gave rights" => "ALTER TABLE rights"
. " ADD who INTEGER NOT NULL DEFAULT 0",
"we need an int id for rights" => "ALTER TABLE rights"
. " ADD right_id SERIAL"
);
$rg_sql_struct[26] = array();
$rg_sql_struct[26]['tables'] = array();
$rg_sql_struct[26]['other'] = array(
"we implement IP access in generic rights" => "ALTER TABLE rights"
. " ADD ip TEXT NOT NULL DEFAULT ''",
"we need a new misc field for path" => "ALTER TABLE rights"
. " ADD misc2 TEXT NOT NULL DEFAULT ''"
);
$rg_sql_struct[27] = array();
$rg_sql_struct[27]['tables'] = array();
$rg_sql_struct[27]['other'] = array(
"we need to lookup rights fast" =>
"CREATE INDEX rights_i_type_obj_id ON rights(type, obj_id)",
"record who deleted a bug" =>
"ALTER TABLE bugs ADD deleted_who INTEGER NOT NULL DEFAULT 0"
);
$rg_sql_struct[28] = array();
$rg_sql_struct[28]['tables'] = array();
$rg_sql_struct[28]['other'] = array(
"add repos.last_bug_id" =>
"ALTER TABLE repos ADD last_bug_id INTEGER NOT NULL DEFAULT 0"
);
$rg_sql_struct[29] = array();
$rg_sql_struct[29]['tables'] = array();
$rg_sql_struct[29]['other'] = array(
"add rights.description" =>
"ALTER TABLE rights ADD description TEXT NOT NULL DEFAULT ''",
"index users table" =>
"CREATE UNIQUE INDEX users_username ON users(username)"
);
$rg_sql_struct[30] = array();
$rg_sql_struct[30]['tables'] = array();
$rg_sql_struct[30]['other'] = array(
"events.fail" => "ALTER TABLE events ADD fail SMALLINT NOT NULL DEFAULT 0",
"events.tries" => "ALTER TABLE events ADD tries SMALLINT NOT NULL DEFAULT 0",
"events.next_try" => "ALTER TABLE events ADD next_try INTEGER NOT NULL DEFAULT 0"
);
$rg_sql_struct[31] = array();
$rg_sql_struct[31]['tables'] = array();
$rg_sql_struct[31]['other'] = array(
"repo_history" => "ALTER TABLE repo_history ADD uid INTEGER NOT NULL DEFAULT 0"
);
$rg_sql_struct[32] = array();
$rg_sql_struct[32]['tables'] = array();
$rg_sql_struct[32]['other'] = array(
"repo_license" => "ALTER TABLE repos ADD license TEXT NOT NULL DEFAULT ''"
);
$rg_sql_struct[33] = array();
$rg_sql_struct[33]['tables'] = array(
"login_tokens" => "CREATE TABLE login_tokens ("
. "id SERIAL"
. ", uid INT NOT NULL DEFAULT 0"
. ", itime INT NOT NULL DEFAULT 0"
. ", used INT NOT NULL DEFAULT 0"
. ", name TEXT NOT NULL DEFAULT ''"
. ", secret TEXT NOT NULL DEFAULT ''"
. ", ip TEXT NOT NULL DEFAULT ''"
. ", conf BOOLEAN NOT NULL DEFAULT 't'"
. ", last_used_tc INT NOT NULL DEFAULT 0)",
"login_tokens_ip" => "CREATE TABLE login_tokens_ip ("
. "uid INT NOT NULL DEFAULT 0"
. ", ip TEXT NOT NULL DEFAULT ''"
. ", itime INT NOT NULL DEFAULT 0"
. ", expire INT NOT NULL DEFAULT 0"
. ", token_id INT NOT NULL DEFAULT 0)"
);
$rg_sql_struct[33]['other'] = array(
"suggestion_itime" => "ALTER TABLE suggestions ADD itime INTEGER NOT NULL DEFAULT 0",
"suggestion_email" => "ALTER TABLE suggestions DROP email",
"login_tokens_i_uid" =>
"CREATE INDEX login_tokens_i_uid ON login_tokens(uid)",
"login_tokens_ip_i_uid" =>
"CREATE INDEX login_tokens_ip_i_uid ON login_tokens_ip(uid)"
);
$rg_sql_struct[34] = array();
$rg_sql_struct[34]['tables'] = array(
"scratch_codes" =>
"CREATE TABLE scratch_codes (uid INT NOT NULL DEFAULT 0"
. ", itime INT NOT NULL DEFAULT 0"
. ", sc TEXT NOT NULL DEFAULT '')"
);
$rg_sql_struct[34]['other'] = array(
"scratch_codes_i_uid" =>
"CREATE INDEX scratch_codes_i_uid ON scratch_codes(uid)"
);
$rg_sql_struct[35] = array();
$rg_sql_struct[35]['tables'] = array(
"webhooks" =>
"CREATE TABLE webhooks (id SERIAL"
. ", uid INT NOT NULL DEFAULT 0"
. ", repo_id INT NOT NULL DEFAULT 0"
. ", itime INT NOT NULL DEFAULT 0"
. ", events TEXT NOT NULL DEFAULT ''"
. ", url TEXT NOT NULL DEFAULT ''"
. ", type SMALLINT NOT NULL DEFAULT 0"
. ", client_cert TEXT NOT NULL DEFAULT ''"
. ", client_ca_cert TEXT NOT NULL DEFAULT ''"
. ", flags TEXT NOT NULL DEFAULT ''"
. ", add_ip TEXT NOT NULL DEFAULT ''"
. ", description TEXT NOT NULL DEFAULT ''"
. ")"
);
$rg_sql_struct[35]['other'] = array(
"webhooks_i_uid" =>
"CREATE INDEX webhooks_i_uid ON webhooks(uid)",
'history_push not needed' =>
'DROP TABLE history_push',
'add_key_for_webhooks' =>
"ALTER TABLE webhooks ADD key TEXT NOT NULL DEFAULT ''",
'add_opaque_for_webhooks' =>
"ALTER TABLE webhooks ADD opaque TEXT NOT NULL DEFAULT ''"
);
$rg_sql_struct[36]['tables'] = array(
'watch_user' => "CREATE TABLE watch_user ("
. "uid INT NOT NULL"
. ", watch_uid INT NOT NULL)",
'repo_locks' => "CREATE TABLE repo_locks"
. " (repo_id INT PRIMARY KEY, itime INT NOT NULL DEFAULT 0"
. ", uid INT NOT NULL DEFAULT 0)"
);
$rg_sql_struct[36]['other'] = array(
'users drop double unique constriaint' =>
"ALTER TABLE users DROP CONSTRAINT users_username_key",
'last_cmd' =>
"ALTER TABLE keys ADD last_cmd TEXT NOT NULL DEFAULT ''",
'wh_last_output' =>
"ALTER TABLE webhooks ADD last_output TEXT NOT NULL DEFAULT ''",
'wh_htype' =>
"ALTER TABLE webhooks ADD htype TEXT NOT NULL DEFAULT 'http'",
'wh_idata' =>
"ALTER TABLE webhooks ADD idata TEXT NOT NULL DEFAULT ''",
'watch_repo_i_uid' => "CREATE INDEX watch_repo_i_uid on watch_repo(uid)",
'watch_bug_i_uid' => "CREATE INDEX watch_bug_i_uid on watch_repo(uid)",
'watch_user_i_uid' => "CREATE INDEX watch_user_i_uid on watch_repo(uid)"
);
$rg_sql_struct[37]['other'] = array(
'webhooks - add refname match' =>
"ALTER TABLE webhooks ADD refname TEXT NOT NULL DEFAULT ''",
'webhooks - repo_id not needed' =>
"ALTER TABLE webhooks DROP repo_id",
'webhooks - repo' =>
"ALTER TABLE webhooks ADD repo TEXT NOT NULL DEFAULT '';"
);
$rg_sql_struct[38]['other'] = array(
'repo - template' =>
"ALTER TABLE repos ADD template TEXT NOT NULL DEFAULT ''",
'repo - pr id' =>
"ALTER TABLE repos ADD last_mr_id INT NOT NULL DEFAULT 0",
'merge_requests - id' =>
"ALTER TABLE merge_requests ADD id INT NOT NULL DEFAULT 0",
'merge_requests - who' =>
"ALTER TABLE merge_requests ADD who INT NOT NULL DEFAULT 0"
);
$rg_sql_struct[39]['tables'] = array(
'build_jobs' =>
"CREATE TABLE build_jobs (id BIGSERIAL NOT NULL"
. ", repo_id INT NOT NULL"
. ", prio INT NOT NULL"
. ", itime INT NOT NULL"
. ", done INT NOT NULL"
. ", request TEXT NOT NULL"
. ", status TEXT NOT NULL)",
'commit_labels' =>
"CREATE TABLE commit_labels (repo_id INT NOT NULL"
. ", head TEXT NOT NULL"
. ", type TEXT NOT NULL"
. ", misc TEXT NOT NULL"
. ", labels TEXT NOT NULL)"
);
$rg_sql_struct[40]['tables'] = array(
'ak' =>
"CREATE TABLE apikeys"
. " (key_id SERIAL PRIMARY KEY"
. ", itime INTEGER NOT NULL"
. ", uid INTEGER NOT NULL"
. ", name TEXT NOT NULL DEFAULT ''"
. ", key TEXT NOT NULL"
. ", last_use INTEGER NOT NULL DEFAULT 0"
. ", last_ip TEXT NOT NULL DEFAULT ''"
. ", count INTEGER NOT NULL DEFAULT 0"
. ", first_use INTEGER NOT NULL DEFAULT 0"
. ", last_cmd TEXT NOT NULL DEFAULT '')",
'workers' =>
"CREATE TABLE workers"
. " (id SERIAL PRIMARY KEY"
. ", name TEXT NOT NULL"
. ", key TEXT NOT NULL"
. ", itime INTEGER NOT NULL"
. ", uid INTEGER NOT NULL"
. ", last_connect INTEGER DEFAULT 0"
. ", last_ip TEXT DEFAULT ''"
. ", uname TEXT DEFAULT ''"
. ", host TEXT DEFAULT ''"
. ", arch TEXT DEFAULT ''"
. ", env TEXT DEFAULT ''"
. ", ssh_key TEXT DEFAULT ''"
. ", cost INTEGER DEFAULT 0"
. ", workers TEXT DEFAULT 1"
. ", who INTEGER DEFAULT 0)"
);
$rg_sql_struct[40]['other'] = array(
'api_keys_i_uid' => "CREATE INDEX apikeys_i_uid ON apikeys(uid)",
'workers_i_uid' => "CREATE INDEX workers_i_uid ON workers(uid)",
'users_suspended_0' =>
"UPDATE users SET suspended = 0 WHERE suspended IS NULL",
'users_last_seen_0' =>
"UPDATE users SET last_seen = 0 WHERE last_seen IS NULL",
'disk_used_mb_0' =>
"UPDATE users SET disk_used_mb = 0 WHERE disk_used_mb IS NULL"
);
$rg_sql_struct[41]['other'] = array(
'keys_fingerprint' => "ALTER TABLE keys ADD fingerprint_sha256"
. " TEXT NOT NULL DEFAULT ''",
'keys_fingerprint_index' => "CREATE INDEX keys_i_fingerprint_sha256"
. " ON keys(fingerprint_sha256)",
'workers_fingerprint' => "ALTER TABLE workers ADD fingerprint_sha256"
. " TEXT NOT NULL DEFAULT ''",
'workers_fingerprint_index' => "CREATE INDEX workers_i_fingerprint_sha256"
. " ON workers(fingerprint_sha256)"
);
$rg_sql_struct[42]['other'] = array(
'deleted for users' =>
"ALTER TABLE users ADD deleted INTEGER NOT NULL DEFAULT 0"
);
// Do not forget to add the new tables to statistics
// This must be the last line
$rg_sql_schema_ver = count($rg_sql_struct);
/*
* Generate structure
*/
function rg_sql_struct_run($db, $flags, $old_schema_ver)
{
global $rg_sql_struct;
global $rg_sql_schema_ver;
$ignore_errors = ($flags & RG_IGNORE_ERRORS) ? TRUE : FALSE;
$drop_tables = ($flags & RG_DROP_TABLES) ? TRUE : FALSE;
rg_log_enter("sql_struct_run: flags=$flags"
. " ignore_errors=" . ($ignore_errors ? "Yes" : "No")
. " drop_tables=" . ($drop_tables ? "Yes" : "No")
. " old_schema_ver=$old_schema_ver...");
$ret = TRUE;
for ($i = $old_schema_ver + 1; $i <= $rg_sql_schema_ver; $i++) {
foreach ($rg_sql_struct[$i] as $type => $sqls) {
if (count($sqls) == 0)
continue;
foreach ($sqls as $id => $sql) {
rg_log("Applying schema $i, type $type, id $id...");
if ((strcmp($type, "tables") == 0)
&& ($drop_tables === TRUE)) {
rg_log("Dropping table [$id]...");
$sql2 = "DROP TABLE IF EXISTS $id CASCADE";
$res = rg_sql_query($db, $sql2);
if ($res === FALSE) {
rg_log("WARN: Cannot run sql ($sql2) (" . rg_sql_error() . ")!");
if (!$ignore_errors) {
$ret = FALSE;
break;
}
}
rg_sql_free_result($res);
}
rg_log("Running [$sql]...");
$res = rg_sql_query($db, $sql);
if ($res === FALSE) {
rg_log("WARN: Cannot run sql ($sql) (" . rg_sql_error() . ")!");
if (!$ignore_errors) {
$ret = FALSE;
break;
}
}
rg_sql_free_result($res);
}
if (!$ret)
break;
}
if (!$ret)
break;
}
rg_log_exit();
return $ret;
}
/*
* Returns current version of the schema.
*/
function rg_sql_struct_get_current_ver($db)
{
global $rg_sql_schema_ver;
rg_log_enter("sql_struct_get_current_ver");
$ret = FALSE;
while (1) {
$ret = rg_state_get($db, "schema_version");
if ($ret === FALSE)
break;
if (empty($ret))
$ret = 0;
break;
}
rg_log_exit();
return $ret;
}
/*
* Tests if an update of the structure is needed.
* Returns FALSE on error, 0 if update is not needed, else 1.
*/
function rg_sql_struct_update_needed($db)
{
global $rg_sql_schema_ver;
$old = rg_sql_struct_get_current_ver($db);
if ($old === FALSE)
return 1;
if ($rg_sql_schema_ver == $old)
return 0;
return 1;
}
/*
* Update schema if needed
* Returns FALSE in case of error.
* This must _not_ be run by web user because of the owner of the locking file.
*/
function rg_sql_struct_update($db, $flags)
{
global $rg_sql_schema_ver;
rg_log_enter("sql_struct_update: flags=$flags");
$ret = FALSE;
$rollback = 0;
while (1) {
$old = rg_sql_struct_get_current_ver($db);
if ($old === FALSE)
$old = 0;
if ($rg_sql_schema_ver == $old) {
$ret = TRUE;
break;
}
// If we cannot lock, return error
if (rg_lock("schema_update.lock") === FALSE)
break;
if (rg_sql_begin($db) !== TRUE)
break;
$rollback = 1;
$r = rg_sql_struct_run($db, $flags, $old);
if ($r !== TRUE) {
rg_log("Cannot update schema (" . rg_sql_error() . ")");
break;
}
$r = rg_state_set($db, "schema_version", $rg_sql_schema_ver);
if ($r !== TRUE) {
rg_log("Cannot update schema ver (" . rg_state_error() . ")");
break;
}
if (rg_sql_commit($db) !== TRUE)
break;
$rollback = 0;
$ret = TRUE;
break;
}
if ($rollback == 1)
rg_sql_rollback($db);
rg_unlock("schema_update.lock");
rg_log_exit();
return $ret;
}
/*
* Update slaves (postgresql partitions)
* Returns FALSE in case of error
*/
function rg_sql_struct_slaves_update($db)
{
global $rg_sql_struct_slaves;
rg_prof_start("sql_struct_slaves_update");
rg_log_enter("sql_struct_slaves_update");
$ret = FALSE;
$rollback = 0;
$locked = FALSE;
while (1) {
if (empty($rg_sql_struct_slaves)) {
$ret = TRUE;
break;
}
// If we cannot lock, return error
if (rg_lock("slave_create.lock") === FALSE)
break;
$locked = TRUE;
$last_ts = rg_state_get($db, "slaves_create_last_ts");
if ($last_ts === FALSE)
break;
$last_ts = sprintf("%u", $last_ts);
if ($last_ts == 0)
$last_ts = gmmktime(0, 0, 0, gmdate("m") - 1, 1, gmdate("Y"));
rg_log("last_ts=$last_ts (" . gmdate("Y-m-d", $last_ts) . ")");
// First second of current month
$current_month_ts = gmmktime(0, 0, 0, gmdate("m"), 1, gmdate("Y"));
rg_log("current_month_ts=$current_month_ts (" . gmdate("Y-m-d", $current_month_ts) . ")");
// Do we have current month and the next one covered?
if ($current_month_ts < $last_ts) {
rg_log("No update needed!");
$ret = TRUE;
break;
}
if (rg_sql_begin($db) !== TRUE)
break;
$rollback = 1;
$ok = TRUE;
$month = gmdate("m", $last_ts) + 1;
$year = gmdate("Y", $last_ts);
$ts = gmmktime(0, 0, 0, $month, 1, $year);
$stop_ts = gmmktime(0, 0, 0, gmdate("m") + 1, 1, gmdate("Y"));
while ($ts <= $stop_ts) {
$month++;
$next_ts = gmmktime(0, 0, 0, $month, 1, $year);
foreach ($rg_sql_struct_slaves as $table) {
$slave_table = $table . "_" . gmdate("Y_m", $ts);
// First, check if exists. It is possible that
// we did the update but we could not set the cache.
$sql = "SELECT 1 FROM pg_class"
. " WHERE relname = '" . $slave_table . "'";
$res = rg_sql_query($db, $sql);
if ($res === FALSE) {
$ok = FALSE;
break;
}
$rows = rg_sql_num_rows($res);
rg_sql_free_result($res);
if ($rows > 0)
continue;
$sql = "CREATE TABLE " . $slave_table
. " (CHECK(itime >= $ts AND itime <= " . ($next_ts - 1) . "))"
. " INHERITS (" . $table . ")";
$res = rg_sql_query($db, $sql);
if ($res === FALSE) {
$ok = FALSE;
break;
}
rg_sql_free_result($res);
$sql = "CREATE INDEX " . $slave_table . "_i_itime"
. " ON " . $slave_table
. " (itime)";
$res = rg_sql_query($db, $sql);
if ($res === FALSE) {
$ok = FALSE;
break;
}
rg_sql_free_result($res);
}
$ts = $next_ts;
}
if ($ok === FALSE)
break;
if (rg_sql_commit($db) !== TRUE)
break;
$r = rg_state_set($db, "slaves_create_last_ts", $stop_ts);
if ($r !== TRUE) {
rg_log("Cannot create slave (" . rg_state_error() . ")");
break;
}
$rollback = 0;
$ret = TRUE;
break;
}
if ($rollback == 1)
rg_sql_rollback($db);
if ($locked === TRUE)
rg_unlock("slave_create.lock");
rg_log_exit();
rg_prof_end("sql_struct_slaves_update");
return $ret;
}
/*
* Helper that will setup the structure and the fixes if needed
*/
function rg_struct_ok($db)
{
$ret = FALSE;
while (1) {
$restart_cache = FALSE;
if (rg_sql_struct_update_needed($db) == 1) {
$r = rg_sql_struct_update($db, 0);
if ($r !== TRUE)
break;
$restart_cache = TRUE;
}
if (rg_fixes_needed($db) == 1) {
$r = rg_fixes_update($db);
if ($r !== TRUE)
break;
$restart_cache = TRUE;
}
if ($restart_cache)
rg_cache_restart();
$install_id = rg_state_get($db, 'install_id');
if ($install_id === FALSE)
break;
if (empty($install_id))
rg_state_set($db, 'install_id',
sha512(microtime(TRUE)));
$ret = TRUE;
break;
}
return $ret;
}
?>