server/database/db.go

201 lines
4.1 KiB
Go
Raw Normal View History

2023-01-14 06:25:41 +00:00
package database
import (
"time"
"git.ohea.xyz/cursorius/server/config"
"context"
"fmt"
"github.com/jackc/pgx/v5/pgxpool"
2023-01-14 06:25:41 +00:00
"github.com/op/go-logging"
)
var log = logging.MustGetLogger("cursorius-server")
type Database struct {
Conn *pgxpool.Pool
}
2023-01-14 13:02:17 +00:00
func LaunchDB(conf config.DBConfig) (Database, error) {
2023-01-14 06:25:41 +00:00
dbURL := fmt.Sprintf(
"postgres://%v:%v@%v:%v/%v",
conf.Username,
conf.Password,
conf.Address,
conf.Port,
conf.Name,
)
dbURLNoPasswd := fmt.Sprintf(
"postgres://%v:********@%v:%v/%v",
conf.Username,
conf.Address,
conf.Port,
conf.Name,
)
db := Database{}
2023-01-14 06:25:41 +00:00
var err error
log.Infof("Connecting to database with URL \"%v\"", dbURLNoPasswd)
db.Conn, err = pgxpool.New(context.Background(), dbURL)
if err != nil {
return db, fmt.Errorf("could not create database pool: %w", err)
}
// sleep until we can sucessfully acquire a connection
2023-01-14 06:25:41 +00:00
for i := 0; i < 10; i++ {
_, err = db.Conn.Acquire(context.Background())
2023-01-14 06:25:41 +00:00
if err == nil {
break
}
time.Sleep(2 * time.Second)
}
if err != nil {
2023-01-14 13:02:17 +00:00
return db, fmt.Errorf("Could not open database: %w", err)
2023-01-14 06:25:41 +00:00
}
2023-01-14 06:28:46 +00:00
log.Infof("Database connected sucessfully!")
2023-01-14 06:25:41 +00:00
versionTableExistsQuery := `
SELECT EXISTS (
SELECT FROM pg_tables
WHERE tablename = 'version'
);`
var versionTableExists bool
err = db.Conn.QueryRow(context.Background(), versionTableExistsQuery).Scan(&versionTableExists)
2023-01-14 06:25:41 +00:00
if err != nil {
2023-01-14 13:02:17 +00:00
return db, fmt.Errorf("Could not check if database was initalized: %w", err)
2023-01-14 06:25:41 +00:00
}
if versionTableExists {
// TODO: migrations
} else {
2023-01-14 06:28:46 +00:00
log.Info("New database found, initializing....")
err = initDB(db.Conn)
2023-01-14 06:25:41 +00:00
if err != nil {
2023-01-14 13:02:17 +00:00
return db, fmt.Errorf("Could not initalize database: %w", err)
2023-01-14 06:25:41 +00:00
}
}
2023-01-14 13:02:17 +00:00
return db, nil
2023-01-14 06:25:41 +00:00
}
func initDB(conn *pgxpool.Pool) error {
2023-01-14 06:25:41 +00:00
createTablesQuery := `
2023-01-14 13:02:17 +00:00
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
2023-01-14 06:25:41 +00:00
CREATE TABLE version (
version INT NOT NULL
2023-01-14 06:25:41 +00:00
);
2023-02-15 03:18:41 +00:00
CREATE TABLE clone_credentials (
id UUID PRIMARY KEY,
name TEXT NOT NULL,
type TEXT NOT NULL,
username TEXT NOT NULL,
secret TEXT NOT NULL
);
2023-01-14 06:25:41 +00:00
CREATE TABLE pipelines (
2023-02-15 03:18:41 +00:00
id UUID PRIMARY KEY,
name TEXT NOT NULL,
url TEXT NOT NULL,
poll_interval INTEGER,
clone_credential UUID DEFAULT NULL,
CONSTRAINT fk_clone_credential
FOREIGN KEY(clone_credential)
REFERENCES clone_credentials(id)
);
CREATE TABLE secrets (
id UUID PRIMARY KEY,
name TEXT NOT NULL UNIQUE,
secret TEXT NOT NULL
);
CREATE TABLE pipeline_secret_mappings (
pipeline UUID NOT NULL,
secret UUID NOT NULL,
CONSTRAINT fk_pipeline
FOREIGN KEY(pipeline)
REFERENCES pipelines(id),
CONSTRAINT fk_secret
FOREIGN KEY(secret)
REFERENCES secrets(id)
2023-01-14 06:25:41 +00:00
);
CREATE TABLE webhooks (
2023-01-14 13:02:17 +00:00
id UUID PRIMARY KEY,
server_type TEXT,
secret TEXT,
pipeline UUID,
2023-01-14 06:25:41 +00:00
CONSTRAINT fk_pipeline
FOREIGN KEY(pipeline)
REFERENCES pipelines(id)
);
CREATE TABLE runs (
2023-01-14 13:02:17 +00:00
id UUID PRIMARY KEY,
pipeline UUID,
in_progress BOOLEAN DEFAULT NULL,
2023-02-25 06:00:10 +00:00
build_output TEXT DEFAULT NULL,
result BIGINT DEFAULT NULL,
stdout TEXT DEFAULT NULL,
stderr TEXT DEFAULT NULL,
CONSTRAINT fk_pipeline
FOREIGN KEY(pipeline)
REFERENCES pipelines(id)
);
CREATE TABLE command_executions (
2023-01-14 13:02:17 +00:00
id UUID PRIMARY KEY,
run_id UUID,
command TEXT,
2023-01-14 13:02:17 +00:00
return_code INT,
stdout TEXT,
stderr TEXT,
start_time TIMESTAMP,
end_time TIMESTAMP,
CONSTRAINT fk_run_id
FOREIGN KEY(run_id)
REFERENCES runs(id)
);
CREATE TABLE runners (
id UUID PRIMARY KEY,
2023-02-25 05:28:07 +00:00
name TEXT NOT NULL UNIQUE,
token TEXT NOT NULL
);
2023-02-09 01:44:54 +00:00
CREATE TABLE pipeline_refs (
name TEXT PRIMARY KEY NOT NULL,
pipeline_id UUID NOT NULL,
hash TEXT NOT NULL,
CONSTRAINT fk_pipeline_id
FOREIGN KEY(pipeline_id)
REFERENCES pipelines(id)
);
`
2023-01-14 06:25:41 +00:00
_, err := conn.Exec(context.Background(), createTablesQuery)
if err != nil {
return err
}
return nil
}