package postgres import ( "database/sql" ) var migrations = []struct { name string stmt []string }{ { name: "001_create_table_users.sql", stmt: []string{ createTableUsers, }, }, { name: "002_create_table_repos.sql", stmt: []string{ createTableRepos, }, }, { name: "003_create_table_builds.sql", stmt: []string{ createTableBuilds, createIndexBuildsRepo, createIndexBuildsAuthor, }, }, { name: "004_create_table_procs.sql", stmt: []string{ createTableProcs, createIndexProcsBuild, }, }, { name: "005_create_table_logs.sql", stmt: []string{ createTableLogs, }, }, { name: "006_create_table_files.sql", stmt: []string{ createTableFiles, createIndexFilesBuilds, createIndexFilesProcs, }, }, { name: "007_create_table_secets.sql", stmt: []string{ createTableSecrets, createIndexSecretsRepo, }, }, { name: "008_create_table_registry.sql", stmt: []string{ createTableRegistry, createIndexRegistryRepo, }, }, { name: "009_create_table_config.sql", stmt: []string{ createTableConfig, }, }, { name: "010_create_table_tasks.sql", stmt: []string{ createTableTasks, }, }, { name: "011_create_table_agents.sql", stmt: []string{ createTableAgents, }, }, { name: "012_create_table_senders.sql", stmt: []string{ createTableSenders, createIndexSenderRepos, }, }, } // Migrate performs the database migration. If the migration fails // and error is returned. func Migrate(db *sql.DB) error { if err := createTable(db); err != nil { return err } completed, err := selectCompleted(db) if err != nil && err != sql.ErrNoRows { return err } for _, migration := range migrations { _, ok := completed[migration.name] if ok { continue } for _, stmt := range migration.stmt { if _, err := db.Exec(stmt); err != nil { return err } } if err := insertMigration(db, migration.name); err != nil { return err } } return nil } func createTable(db *sql.DB) error { _, err := db.Exec(migrationTableCreate) return err } func insertMigration(db *sql.DB, name string) error { _, err := db.Exec(migrationInsert, name) return err } func selectCompleted(db *sql.DB) (map[string]struct{}, error) { migrations := map[string]struct{}{} rows, err := db.Query(migrationSelect) if err != nil { return nil, err } defer rows.Close() for rows.Next() { var name string if err := rows.Scan(&name); err != nil { return nil, err } migrations[name] = struct{}{} } return migrations, nil } // // migration table ddl and sql // var migrationTableCreate = ` CREATE TABLE IF NOT EXISTS migrations ( name VARCHAR(512) ,UNIQUE(name) ) ` var migrationInsert = ` INSERT INTO migrations (name) VALUES ($1) ` var migrationSelect = ` SELECT name FROM migrations ` // // 001_create_table_users.sql // var createTableUsers = ` CREATE TABLE IF NOT EXISTS users ( user_id SERIAL PRIMARY KEY ,user_login VARCHAR(250) ,user_token VARCHAR(500) ,user_secret VARCHAR(500) ,user_expiry INTEGER ,user_email VARCHAR(500) ,user_avatar VARCHAR(500) ,user_active BOOLEAN ,user_admin BOOLEAN ,user_hash VARCHAR(500) ,UNIQUE(user_login) ); ` // // 002_create_table_repos.sql // var createTableRepos = ` CREATE TABLE IF NOT EXISTS repos ( repo_id SERIAL PRIMARY KEY ,repo_user_id INTEGER ,repo_owner VARCHAR(250) ,repo_name VARCHAR(250) ,repo_full_name VARCHAR(250) ,repo_avatar VARCHAR(500) ,repo_link VARCHAR(1000) ,repo_clone VARCHAR(1000) ,repo_branch VARCHAR(500) ,repo_timeout INTEGER ,repo_private BOOLEAN ,repo_trusted BOOLEAN ,repo_allow_pr BOOLEAN ,repo_allow_push BOOLEAN ,repo_allow_deploys BOOLEAN ,repo_allow_tags BOOLEAN ,repo_hash VARCHAR(500) ,repo_scm VARCHAR(50) ,repo_config_path VARCHAR(500) ,repo_gated BOOLEAN ,UNIQUE(repo_full_name) ); ` // // 003_create_table_builds.sql // var createTableBuilds = ` CREATE TABLE IF NOT EXISTS builds ( build_id SERIAL PRIMARY KEY ,build_repo_id INTEGER ,build_number INTEGER ,build_event VARCHAR(500) ,build_status VARCHAR(500) ,build_enqueued INTEGER ,build_created INTEGER ,build_started INTEGER ,build_finished INTEGER ,build_commit VARCHAR(500) ,build_branch VARCHAR(500) ,build_ref VARCHAR(500) ,build_refspec VARCHAR(1000) ,build_remote VARCHAR(500) ,build_title VARCHAR(1000) ,build_message VARCHAR(2000) ,build_timestamp INTEGER ,build_author VARCHAR(500) ,build_avatar VARCHAR(1000) ,build_email VARCHAR(500) ,build_link VARCHAR(1000) ,build_deploy VARCHAR(500) ,build_signed BOOLEAN ,build_verified BOOLEAN ,build_parent INTEGER ,build_error VARCHAR(500) ,build_reviewer VARCHAR(250) ,build_reviewed INTEGER ,build_sender VARCHAR(250) ,build_config_id INTEGER ,UNIQUE(build_number, build_repo_id) ); ` var createIndexBuildsRepo = ` CREATE INDEX IF NOT EXISTS ix_build_repo ON builds (build_repo_id); ` var createIndexBuildsAuthor = ` CREATE INDEX IF NOT EXISTS ix_build_author ON builds (build_author); ` // // 004_create_table_procs.sql // var createTableProcs = ` CREATE TABLE IF NOT EXISTS procs ( proc_id SERIAL PRIMARY KEY ,proc_build_id INTEGER ,proc_pid INTEGER ,proc_ppid INTEGER ,proc_pgid INTEGER ,proc_name VARCHAR(250) ,proc_state VARCHAR(250) ,proc_error VARCHAR(500) ,proc_exit_code INTEGER ,proc_started INTEGER ,proc_stopped INTEGER ,proc_machine VARCHAR(250) ,proc_platform VARCHAR(250) ,proc_environ VARCHAR(2000) ,UNIQUE(proc_build_id, proc_pid) ); ` var createIndexProcsBuild = ` CREATE INDEX IF NOT EXISTS proc_build_ix ON procs (proc_build_id); ` // // 005_create_table_logs.sql // var createTableLogs = ` CREATE TABLE IF NOT EXISTS logs ( log_id SERIAL PRIMARY KEY ,log_job_id INTEGER ,log_data BYTEA ,UNIQUE(log_job_id) ); ` // // 006_create_table_files.sql // var createTableFiles = ` CREATE TABLE IF NOT EXISTS files ( file_id SERIAL PRIMARY KEY ,file_build_id INTEGER ,file_proc_id INTEGER ,file_name VARCHAR(250) ,file_mime VARCHAR(250) ,file_size INTEGER ,file_time INTEGER ,file_data BYTEA ,UNIQUE(file_proc_id,file_name) ); ` var createIndexFilesBuilds = ` CREATE INDEX IF NOT EXISTS file_build_ix ON files (file_build_id); ` var createIndexFilesProcs = ` CREATE INDEX IF NOT EXISTS file_proc_ix ON files (file_proc_id); ` // // 007_create_table_secets.sql // var createTableSecrets = ` CREATE TABLE IF NOT EXISTS secrets ( secret_id SERIAL PRIMARY KEY ,secret_repo_id INTEGER ,secret_name VARCHAR(250) ,secret_value BYTEA ,secret_images VARCHAR(2000) ,secret_events VARCHAR(2000) ,secret_skip_verify BOOLEAN ,secret_conceal BOOLEAN ,UNIQUE(secret_name, secret_repo_id) ); ` var createIndexSecretsRepo = ` CREATE INDEX IF NOT EXISTS ix_secrets_repo ON secrets (secret_repo_id); ` // // 008_create_table_registry.sql // var createTableRegistry = ` CREATE TABLE IF NOT EXISTS registry ( registry_id SERIAL PRIMARY KEY ,registry_repo_id INTEGER ,registry_addr VARCHAR(250) ,registry_email VARCHAR(500) ,registry_username VARCHAR(2000) ,registry_password VARCHAR(2000) ,registry_token VARCHAR(2000) ,UNIQUE(registry_addr, registry_repo_id) ); ` var createIndexRegistryRepo = ` CREATE INDEX IF NOT EXISTS ix_registry_repo ON registry (registry_repo_id); ` // // 009_create_table_config.sql // var createTableConfig = ` CREATE TABLE IF NOT EXISTS config ( config_id SERIAL PRIMARY KEY ,config_repo_id INTEGER ,config_hash VARCHAR(250) ,config_data BYTEA ,UNIQUE(config_hash, config_repo_id) ); ` // // 010_create_table_tasks.sql // var createTableTasks = ` CREATE TABLE IF NOT EXISTS tasks ( task_id VARCHAR(250) PRIMARY KEY ,task_data BYTEA ,task_labels BYTEA ); ` // // 011_create_table_agents.sql // var createTableAgents = ` CREATE TABLE IF NOT EXISTS agents ( agent_id SERIAL PRIMARY KEY ,agent_addr VARCHAR(250) ,agent_platform VARCHAR(500) ,agent_capacity INTEGER ,agent_created INTEGER ,agent_updated INTEGER ,UNIQUE(agent_addr) ); ` // // 012_create_table_senders.sql // var createTableSenders = ` CREATE TABLE IF NOT EXISTS senders ( sender_id SERIAL PRIMARY KEY ,sender_repo_id INTEGER ,sender_login VARCHAR(250) ,sender_allow BOOLEAN ,sender_block BOOLEAN ,UNIQUE(sender_repo_id,sender_login) ); ` var createIndexSenderRepos = ` CREATE INDEX IF NOT EXISTS sender_repo_ix ON senders (sender_repo_id); `