<?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_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 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" ); $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. // Do not forget to add the new created 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. * 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; } /* * 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; $locked = 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; $locked = TRUE; 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); if ($locked) rg_unlock('schema_update.lock'); 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') === 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; } /* * Helper that will setup the structure and the fixes if needed */ function rg_struct_ok($db) { $ret = FALSE; while (1) { $restart_cache = FALSE; $r = rg_sql_struct_update_needed($db); if ($r === FALSE) break; if ($r == 1) { $r = rg_sql_struct_update($db, 0); if ($r !== TRUE) break; rg_cache_restart(); } $r = rg_fixes_needed($db); if ($r === FALSE) break; if ($r == 1) { $r = rg_fixes_update($db); if ($r !== TRUE) break; rg_cache_restart(); } $r = rg_sql_struct_parts_update($db); if ($r !== TRUE) break; $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; }