<?php
include_once(__DIR__ . '/sql.inc.php');
include_once(__DIR__ . '/util2.inc.php');
define("RG_DROP_TABLES", 1);
define("RG_IGNORE_ERRORS", 1 << 1);
$rg_sql_struct_parts = 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_parts['repo_history'] = array();
$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 constraint' =>
"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"
);
$rg_sql_struct[43]['other'] = array(
'itime for commit labels' =>
"ALTER TABLE commit_labels ADD itime INTEGER NOT NULL DEFAULT 0"
);
$rg_sql_struct[44]['table'] = array(
'ldap_servers' =>
"CREATE TABLE ldap_servers"
. " (id SERIAL PRIMARY KEY"
. ", prio INTEGER NOT NULL"
. ", session_time INTEGER NOT NULL"
. ", itime INTEGER NOT NULL"
. ", who INTEGER NOT NULL"
. ", name TEXT NOT NULL"
. ", url TEXT NOT NULL"
. ", bind_dn TEXT NOT NULL"
. ", bind_pass TEXT NOT NULL"
. ", user_base TEXT NOT NULL"
. ", uid_attr TEXT NOT NULL"
. ", filter TEXT NOT NULL"
. ", group_base TEXT NOT NULL"
. ", group_attr TEXT NOT NULL"
. ", group_filter TEXT NOT NULL"
. ", admin_group TEXT NOT NULL"
. ", ca_cert TEXT NOT NULL"
. ", csn TEXT NOT NULL DEFAULT ''"
. ", plan_id INTEGER NOT NULL"
. ", timeout INTEGER NOT NULL"
. ")",
'ldap_cache' =>
"CREATE TABLE ldap_cache"
. " (ldap_uid TEXT NOT NULL"
. ", password TEXT NOT NULL"
. ", sn TEXT NOT NULL"
. ", gn TEXT NOT NULL"
. ", gid INTEGER NOT NULL"
. ", mail TEXT NOT NULL"
. ", server_id INTEGER NOT NULL"
. ", uuid TEXT NOT NULL"
. ", uid INTEGER NOT NULL"
. ", cn TEXT NOT NULL"
. ", shadow_expire INTEGER NOT NULL"
. ", uid_number INTEGER NOT NULL"
. ")"
);
$rg_sql_struct[44]['other'] = array(
'index ldap_cache uuid' =>
"CREATE INDEX ldap_cache_i_uuid on ldap_cache(uuid)",
'invalidate_confirmation_token' =>
"UPDATE users SET confirm_token = '' WHERE confirmed > 1"
);
// Here, 0.71 was released.
$rg_sql_struct[45] = array();
$rg_sql_struct[45]['tables'] = array(
'stats' => 'CREATE TABLE stats ('
. 'itime INT NOT NULL'
. ', load INT NOT NULL'
. ', disk_used_gib INT NOT NULL'
. ', mem_used_mib INT NOT NULL)',
'worker_stats' => 'CREATE TABLE worker_stats'
. ' (worker_id INT NOT NULL, itime INT NOT NULL'
. ', data TEXT NOT NULL)',
'conns' => 'CREATE TABLE conns'
. ' (type TEXT NOT NULL, uid INT NOT NULL'
. ', repo_id INT NOT NULL, itime INT NOT NULL'
. ', ip TEXT NOT NULL, url TEXT NOT NULL'
. ', referer TEXT NOT NULL, elap INT NOT NULL'
. ', ua TEXT NOT NULL, cmd TEXT NOT NULL)'
);
$rg_sql_struct[45]['other'] = array(
'we need to know the subtype of a webhook' =>
'ALTER TABLE webhooks ADD hsubtype TEXT NOT NULL DEFAULT \'\'',
'worker_stats id' =>
'CREATE INDEX worker_stats_i_worker_id on worker_stats(worker_id)'
);
$rg_sql_struct_parts['stats'] = array();
$rg_sql_struct_parts['worker_stats'] = array('extra_index' => array('worker_id'));
$rg_sql_struct_parts['conns'] = array();
// Here, 0.72 was released.
$rg_sql_struct[46] = array();
$rg_sql_struct[46]['other'] = array(
'repo git size' =>
'ALTER TABLE repos ADD git_mb INT NOT NULL DEFAULT 0',
'user git size' =>
'ALTER TABLE users ADD git_mb INT NOT NULL DEFAULT 0',
'repo artifacts size' =>
'ALTER TABLE repos ADD artifacts_mb INT NOT NULL DEFAULT 0',
'user artifacts size' =>
'ALTER TABLE users ADD artifacts_mb INT NOT NULL DEFAULT 0',
'repo main_branch' =>
'ALTER TABLE repos ADD main_branch TEXT NOT NULL DEFAULT \'\''
);
// Here, 0.73 was released.
$rg_sql_struct[47] = array();
$rg_sql_struct[47]['tables'] = array(
'pkg_repos' => 'CREATE TABLE pkg_repos ('
. 'id SERIAL PRIMARY KEY'
. ', uid INT NOT NULL'
. ', itime INT NOT NULL'
. ', name TEXT NOT NULL'
. ', flags TEXT NOT NULL'
. ', rgfs_key TEXT NOT NULL'
. ', gpg_priv_key TEXT NOT NULL'
. ', gpg_pub_key TEXT NOT NULL'
. ', version INT DEFAULT 1)',
'pkg_subrepos' => 'CREATE TABLE pkg_subrepos ('
. 'id SERIAL PRIMARY KEY'
. ', pkg_repo_id INT NOT NULL'
. ', itime INT NOT NULL'
. ', name TEXT NOT NULL'
. ', version INT DEFAULT 1)',
'pkg_maps' => 'CREATE TABLE pkg_maps ('
. 'id SERIAL PRIMARY KEY'
. ', uid INT NOT NULL'
. ', itime INT NOT NULL'
. ', flags TEXT NOT NULL'
. ', prio SMALLINT NOT NULL'
. ', repo TEXT NOT NULL'
. ', ref TEXT NOT NULL'
. ', pkg_subrepo_id INT NOT NULL)'
);
$rg_sql_struct[47]['other'] = array(
'pkg_repos index uid' =>
'CREATE INDEX pkg_repos_i_uid on pkg_repos(uid)',
'pkg_subrepos index pkg_repo_id' =>
'CREATE INDEX pkg_subrepos_i_pkg_repo_id on pkg_subrepos(pkg_repo_id)',
'pkg_maps index uid' =>
'CREATE INDEX pkg_maps_i_uid on pkg_maps(uid)',
'login_uid for conns' =>
'ALTER TABLE conns ADD login_uid INT NOT NULL DEFAULT 0',
'disk_used_pkg_repos' =>
'ALTER TABLE pkg_repos ADD disk_used_mb INT NOT NULL DEFAULT 0',
'disk_used_pkg_subrepos' =>
'ALTER TABLE pkg_subrepos ADD disk_used_mb INT NOT NULL DEFAULT 0',
'pkg_subrepos_distro_info' =>
'ALTER TABLE pkg_subrepos ADD distro_info TEXT NOT NULL DEFAULT \'\'',
'pkg_repo password' =>
'ALTER TABLE pkg_repos ADD password TEXT NOT NULL DEFAULT \'\'',
'conns bytes in' =>
'ALTER TABLE conns ADD bytes_in BIGINT NOT NULL DEFAULT -1',
'conns bytes out' =>
'ALTER TABLE conns ADD bytes_out BIGINT NOT NULL DEFAULT -1',
'keys flags' =>
'ALTER TABLE keys ADD flags TEXT NOT NULL DEFAULT \'\'',
'keys spurious index on id' =>
'DROP INDEX IF EXISTS keys_i_key_id'
);
// Here, 0.74 was released.
$rg_sql_struct[48]['tables'] = array(
'build_stats' => 'CREATE TABLE build_stats ('
. 'itime INT NOT NULL'
. ', job_id INT NOT NULL'
. ', json TEXT NOT NULL)'
);
$rg_sql_struct[48]['other'] = array(
'conns_flags' => 'ALTER TABLE conns ADD flags TEXT DEFAULT \'\''
);
$rg_sql_struct_parts['build_stats'] = array('extra_index' => array('job_id'));
// Here 0.76 was released
$rg_sql_struct[49]['tables'] = array();
$rg_sql_struct[49]['other'] = array(
'repo_hash' => 'ALTER TABLE repos ADD hash TEXT DEFAULT \'sha1\''
);
$rg_sql_struct[50]['tables'] = array(
'payments' => 'CREATE TABLE payments ('
. 'id CHAR(16) PRIMARY KEY'
. ', uid INT NOT NULL'
. ', itime INT NOT NULL'
. ', type TEXT NOT NULL'
. ', type_extra TEXT NOT NULL'
. ', amount INT NOT NULL'
. ', currency TEXT NOT NULL'
. ', operator TEXT NOT NULL'
. ', state TEXT NOT NULL'
. ', order_id TEXT NOT NULL'
. ', next_try INT NOT NULL)',
'payments_history' => 'CREATE TABLE payments_history ('
. 'itime INT NOT NULL'
. ', uid INT NOT NULL'
. ', pay_id CHAR(16) NOT NULL'
. ', text TEXT NOT NULL)'
);
$rg_sql_struct[50]['other'] = array(
'plan_prices' => 'ALTER TABLE plans ADD prices TEXT DEFAULT \'\''
);
$rg_sql_struct_parts['payments_history'] = array();
// Here 0.77 was released
// Here 0.78 was released
// Here 0.79 was released
$rg_sql_struct[51]['tables'] = array();
$rg_sql_struct[51]['other'] = array(
'collate keys.fingerprint_sha256' => 'ALTER TABLE keys ALTER COLUMN fingerprint_sha256 SET DATA TYPE TEXT COLLATE "C"',
'collate keys.fingerprint_sha256 i' => 'REINDEX INDEX keys_i_fingerprint_sha256',
'collate state.var' => 'ALTER TABLE state ALTER COLUMN var SET DATA TYPE TEXT COLLATE "C"',
'collate state.var i' => 'REINDEX INDEX state_pkey',
'collate sess.sid' => 'ALTER TABLE sess ALTER COLUMN sid SET DATA TYPE TEXT COLLATE "C"',
'collate sess.sid i' => 'REINDEX INDEX sess_pkey',
'collate sess.sid' => 'ALTER TABLE sess ALTER COLUMN ip SET DATA TYPE TEXT COLLATE "C"',
'collate forgot_pass.token' => 'ALTER TABLE forgot_pass ALTER COLUMN token SET DATA TYPE TEXT COLLATE "C"',
'collate forgot_pass.token i' => 'REINDEX INDEX forgot_pass_pkey',
'collate tokens.token' => 'ALTER TABLE tokens ALTER COLUMN token SET DATA TYPE TEXT COLLATE "C"',
'collate tokens.token i' => 'REINDEX INDEX tokens_pkey',
'collate merge_requests.namespace' => 'ALTER TABLE merge_requests ALTER COLUMN namespace SET DATA TYPE TEXT COLLATE "C"',
'collate merge_requests.ip' => 'ALTER TABLE merge_requests ALTER COLUMN ip SET DATA TYPE TEXT COLLATE "C"',
'collate bugs.ip' => 'ALTER TABLE bugs ALTER COLUMN ip SET DATA TYPE TEXT COLLATE "C"',
'collate bug_notes.ip' => 'ALTER TABLE bug_notes ALTER COLUMN ip SET DATA TYPE TEXT COLLATE "C"',
'collate rights.ip' => 'ALTER TABLE rights ALTER COLUMN ip SET DATA TYPE TEXT COLLATE "C"',
'collate login_tokens.secret' => 'ALTER TABLE login_tokens ALTER COLUMN secret SET DATA TYPE TEXT COLLATE "C"',
'collate login_tokens.ip' => 'ALTER TABLE login_tokens ALTER COLUMN ip SET DATA TYPE TEXT COLLATE "C"',
'collate login_tokens_ip.ip' => 'ALTER TABLE login_tokens_ip ALTER COLUMN ip SET DATA TYPE TEXT COLLATE "C"',
'collate scratch_codes.sc' => 'ALTER TABLE scratch_codes ALTER COLUMN sc SET DATA TYPE TEXT COLLATE "C"',
'collate webhooks.htype' => 'ALTER TABLE webhooks ALTER COLUMN htype SET DATA TYPE TEXT COLLATE "C"',
'collate webhooks.flags' => 'ALTER TABLE webhooks ALTER COLUMN flags SET DATA TYPE TEXT COLLATE "C"',
'collate webhooks.hsubtype' => 'ALTER TABLE webhooks ALTER COLUMN hsubtype SET DATA TYPE TEXT COLLATE "C"',
'collate apikeys.key' => 'ALTER TABLE apikeys ALTER COLUMN key SET DATA TYPE TEXT COLLATE "C"',
'collate workers.key' => 'ALTER TABLE workers ALTER COLUMN key SET DATA TYPE TEXT COLLATE "C"',
'collate workers.fingerprint_sha256' => 'ALTER TABLE workers ALTER COLUMN fingerprint_sha256 SET DATA TYPE TEXT COLLATE "C"',
'collate workers.fingerprint_sha256 i' => 'REINDEX INDEX workers_i_fingerprint_sha256',
'collate conns.type' => 'ALTER TABLE conns ALTER COLUMN type SET DATA TYPE TEXT COLLATE "C"',
'collate conns.ip' => 'ALTER TABLE conns ALTER COLUMN ip SET DATA TYPE TEXT COLLATE "C"',
'collate conns.flags' => 'ALTER TABLE conns ALTER COLUMN ip SET DATA TYPE TEXT COLLATE "C"',
'collate pkg_repos.flags' => 'ALTER TABLE pkg_repos ALTER COLUMN flags SET DATA TYPE TEXT COLLATE "C"',
'collate pkg_repos.rgfs_key' => 'ALTER TABLE pkg_repos ALTER COLUMN rgfs_key SET DATA TYPE TEXT COLLATE "C"',
'collate pkg_maps.flags' => 'ALTER TABLE pkg_maps ALTER COLUMN flags SET DATA TYPE TEXT COLLATE "C"',
'collate payments.id' => 'ALTER TABLE payments ALTER COLUMN id SET DATA TYPE CHAR(16) COLLATE "C"',
'collate payments.id i' => 'REINDEX INDEX payments_pkey',
'collate payments.state' => 'ALTER TABLE payments ALTER COLUMN state SET DATA TYPE TEXT COLLATE "C"',
'collate payments.type' => 'ALTER TABLE payments ALTER COLUMN type SET DATA TYPE TEXT COLLATE "C"',
'collate payments.type_extra' => 'ALTER TABLE payments ALTER COLUMN type_extra SET DATA TYPE TEXT COLLATE "C"',
'collate payments.operator' => 'ALTER TABLE payments ALTER COLUMN operator SET DATA TYPE TEXT COLLATE "C"',
'collate payments.order_id' => 'ALTER TABLE payments ALTER COLUMN order_id SET DATA TYPE TEXT COLLATE "C"',
'collate payments_history.pay_id' => 'ALTER TABLE payments_history ALTER COLUMN pay_id SET DATA TYPE CHAR(16) COLLATE "C"',
'ff keys table' => 'ALTER TABLE keys SET (FILLFACTOR = 95)',
'ff keys index key_id' => 'ALTER INDEX keys_pkey SET (FILLFACTOR = 95)'
);
// Here 0.80 was released
// Do not forget to add the new created tables to statistics.
// See rg_conns_data etc.
// But also by e-mail.
// The next line must be after all rg_sql_struct* definitions.
$rg_sql_schema_ver = count($rg_sql_struct);
/*
* Returns information about COLLATION
*/
$rg_sql_collation_info = FALSE;
function rg_sql_collation_info($db)
{
global $rg_sql_collation_info;
$ret = FALSE;
$info = array();
do {
if ($rg_sql_collation_info !== FALSE) {
$ret = $rg_sql_collation_info;
break;
}
$r = rg_state_get($db, "schema_version");
$sql = 'SELECT datcollate AS col, datcollversion AS db_ver, pg_database_collation_actual_version(oid) AS db_actual_ver'
. ' FROM pg_database'
. ' WHERE datname = current_database()';
$res = rg_sql_query($db, $sql);
if ($res === FALSE)
break;
$info = rg_sql_fetch_array($res);
rg_sql_free_result($res);
/*
$params = array('name' => $info['col']);
$sql = 'SELECT collversion AS coll_ver, pg_collation_actual_version(oid) AS coll_actual_ver'
. ' FROM pg_collation'
. ' WHERE collname = @@name@@';
$res = rg_sql_query_params($db, $sql, $params);
if ($res === FALSE)
break;
$row = rg_sql_fetch_array($res);
rg_sql_free_result($res);
$info['coll_ver'] = $row['coll_ver'];
$info['coll_actual_ver'] = $row['coll_actual_ver'];
*/
$rg_sql_collation_info = $info;
$ret = $rg_sql_collation_info;
} while (0);
return $ret;
}
/*
* 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) {
if (!$ignore_errors) {
$ret = FALSE;
break;
}
}
rg_sql_free_result($res);
}
rg_log("Running [$sql]...");
$res = rg_sql_query($db, $sql);
if ($res === FALSE) {
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.
* FALSE on error.
*/
function rg_sql_struct_get_current_ver($db)
{
rg_log_enter('sql_struct_get_current_ver');
$ret = rg_state_get_uint($db, "schema_version");
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;
rg_log_enter('sql_struct_update_needed');
$ret = FALSE;
while (1) {
$old = rg_sql_struct_get_current_ver($db);
if ($old === FALSE) {
$ret = FALSE;
break;
}
if ($rg_sql_schema_ver == $old) {
$ret = 0;
break;
}
rg_log_debug('sql_schema_ver=' . $rg_sql_schema_ver
. ' != old=' . $old);
$ret = 1;
break;
}
rg_log_exit();
return $ret;
}
function rg_sql_collation_update_needed($db)
{
rg_log_enter('sql_collation_update_needed');
$ret = array('ok' => 0, 'needed' => 0);
do {
$ci = rg_sql_collation_info($db);
if ($ci === FALSE)
break;
$ret['ok'] = 1;
rg_log('DEBUG: collation info [before]: ' . json_encode($ci));
if (strcmp($ci['db_ver'], $ci['db_actual_ver']) != 0) {
rg_log('collation for db mismatch => rebuild objects');
$ret['needed'] = 1;
}
// TODO: not sure if we need to do something about this
//if (strcmp($ci['coll_ver'], $ci['coll_actual_ver'] != 0)) {
// rg_log('collation mismatch => rebuild objects');
// $rebuild = TRUE;
//}
} while (0);
rg_log_exit('sql_collation_update_needed');
return $ret;
}
/*
* Update schema if needed
* Returns FALSE in case of error.
*/
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 (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_log_exit();
return $ret;
}
/*
* Update partitions table
* Returns FALSE in case of error
*/
function rg_sql_struct_parts_update($db)
{
global $rg_sql_struct_parts;
rg_prof_start('sql_struct_parts_update');
rg_log_enter('sql_struct_parts_update');
$ret = FALSE;
$doit = FALSE;
while (1) {
if (empty($rg_sql_struct_parts)) {
$ret = TRUE;
break;
}
$last_list = rg_state_get($db, 'parts_create_last_list');
if ($last_list === FALSE)
break;
// last_ts - last month created already
$last_ts = rg_state_get_uint($db, 'parts_create_last_ts');
if ($last_ts === FALSE)
break;
if ($last_ts == 0)
$last_ts = gmmktime(0, 0, 0, gmdate('m') - 1, 1, gmdate('Y'));
rg_log_debug('last_ts=' . $last_ts . ' (' . gmdate('Y-m-d', $last_ts) . ')');
// goot_ts = What month should be covered?
$good_ts = gmmktime(0, 0, 0, gmdate('m') + 1, 1, gmdate('Y'));
rg_log_debug('good_ts=' . $good_ts . ' (' . gmdate('Y-m-d', $good_ts) . ')');
$cur_list = sha1(rg_serialize($rg_sql_struct_parts));
rg_log_debug('last_list=[' . $last_list . '] cur_list=[' . $cur_list . ']');
if (strcmp($last_list, $cur_list) != 0) {
// We need to set last_ts to first day of the previous month
$last_ts = gmmktime(0, 0, 0, gmdate('m') - 1, 1, gmdate('Y'));
rg_log_debug('list of the parts changed. Set last_ts to ' . $last_ts);
$doit = TRUE;
break;
}
// Do we have current month and the next one covered?
if ($good_ts > $last_ts) {
rg_log('Update needed because good_ts > $last_ts');
$doit = TRUE;
break;
}
rg_log('No update needed!');
$ret = TRUE;
break;
}
rg_log_debug('doit=' . ($doit ? 1 : 0)
. ' ret=' . ($ret === FALSE ? 'FALSE' : 'TRUE'));
$rollback = 0;
$locked = FALSE;
while ($doit) {
// If we cannot lock, return error
if (rg_lock('parts_create.lock', 0) === FALSE)
break;
$locked = TRUE;
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);
rg_log_debug('ts=' . $ts . ' good_ts=' . $good_ts . ' month=' . $month);
while ($ts <= $good_ts) {
rg_log_debug('ts=' . $ts);
$month++;
$next_ts = gmmktime(0, 0, 0, $month, 1, $year);
foreach ($rg_sql_struct_parts as $table => $ti) {
$part_table = $table . '_' . gmdate('Y_m', $ts);
rg_log('Creating table ' . $part_table);
// First, check if exists. It is possible that
// we did the update but we could not set the cache.
$r = rg_sql_rel_exists($db, $part_table);
if ($r === FALSE) {
$ok = FALSE;
break;
}
if ($r === 1) {
rg_log('Table already exists.');
continue;
}
$sql = 'CREATE TABLE ' . $part_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 ' . $part_table . '_i_itime'
. ' ON ' . $part_table
. ' (itime)';
$res = rg_sql_query($db, $sql);
if ($res === FALSE) {
$ok = FALSE;
break;
}
rg_sql_free_result($res);
if (isset($ti['extra_index'])) {
foreach ($ti['extra_index'] as $i) {
$sql = 'CREATE INDEX ' . $part_table . '_i_' . $i
. ' ON ' . $part_table
. ' (' . $i . ')';
$res = rg_sql_query($db, $sql);
if ($res === FALSE) {
$ok = FALSE;
break;
}
rg_sql_free_result($res);
}
}
if ($ok !== TRUE)
break;
}
if ($ok !== TRUE)
break;
$ts = $next_ts;
}
if ($ok !== TRUE)
break;
$r = rg_state_set($db, 'parts_create_last_ts', $good_ts);
if ($r !== TRUE) {
rg_log('Cannot set parts_create_last_ts (' . rg_state_error() . ')');
break;
}
$r = rg_state_set($db, 'parts_create_last_list', $cur_list);
if ($r !== TRUE) {
rg_log('Cannot set parts_create_last_list (' . rg_state_error() . ')');
break;
}
if (rg_sql_commit($db) !== TRUE)
break;
$rollback = 0;
$ret = TRUE;
break;
}
if ($rollback == 1)
rg_sql_rollback($db);
if ($locked === TRUE)
rg_unlock('parts_create.lock');
rg_log_exit();
rg_prof_end('sql_struct_parts_update');
return $ret;
}
function rg_sql_collation_update($db)
{
global $rg_sql_collation_info;
rg_prof_start('sql_collation_update');
rg_log_enter('sql_collation_update');
$ret = FALSE;
do {
rg_log('Reindexing database...');
$sql = 'REINDEX DATABASE';
$res = rg_sql_query($db, $sql);
if ($res === FALSE)
break;
rg_sql_free_result($res);
$rg_sql_collation_info = FALSE; // invalidate memory cache
$ci = rg_sql_collation_info($db);
if ($ci === FALSE)
break;
rg_log('DEBUG: collation info [after reindex]: ' . json_encode($ci));
$name = rg_sql_escape_identifier($db, rg_sql_dbname($db));
rg_log('DEBUG: name=' . $name);
$sql = 'ALTER DATABASE ' . $name . ' REFRESH COLLATION VERSION';
$res = rg_sql_query($db, $sql);
if ($res === FALSE)
break;
rg_sql_free_result($res);
$rg_sql_collation_info = FALSE; // invalidate memory cache
$ci = rg_sql_collation_info($db);
if ($ci === FALSE)
break;
rg_log('DEBUG: collation info [after]: ' . json_encode($ci));
$ret = TRUE;
} while (0);
rg_log_exit();
rg_prof_end('sql_collation_update');
return $ret;
}
/*
* Helper that will setup the structure and the fixes if needed
*/
function rg_struct_ok($db)
{
rg_log_enter('struct_ok');
$ret = FALSE;
do {
$restart_cache = FALSE;
$r = rg_sql_collation_update_needed($db);
if ($r['ok'] != 1)
break;
$uc = $r['needed'];
$ud = rg_sql_struct_update_needed($db);
if ($ud === FALSE)
break;
$uf = rg_fixes_needed($db);
if ($uf === FALSE)
break;
$err = FALSE;
$locked = FALSE;
while ($ud + $uf > 0) {
$err = TRUE;
if (rg_lock('schema_update.lock', 0) === FALSE)
break;
$locked = TRUE;
while ($uc == 1) {
$r = rg_sql_collation_update($db);
if ($r !== TRUE)
break;
}
if ($ud === 1) {
$r = rg_sql_struct_update($db, 0);
if ($r !== TRUE)
break;
}
if ($uf === 1) {
$r = rg_fixes_update($db);
if ($r !== TRUE)
break;
}
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)));
$err = FALSE;
break;
}
if ($locked)
rg_unlock('schema_update.lock');
if ($err)
break;
$r = rg_sql_struct_parts_update($db);
if ($r !== TRUE)
break;
$ret = TRUE;
} while (0);
rg_log_exit();
return $ret;
}