Monorepo for Tangled
Something went wrong. Try again.
3.4 kB · 125 lines
Go
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126package db
import ( "context" "database/sql" "fmt" "time"
_ "github.com/jackc/pgx/v5/stdlib" "tangled.org/core/log")
type DBTX interface { ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error) QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error) QueryRowContext(ctx context.Context, query string, args ...any) *sql.Row}
func Make(ctx context.Context, dbUrl string, maxConns int) (*sql.DB, error) { db, err := sql.Open("pgx", dbUrl) if err != nil { return nil, fmt.Errorf("opening db: %w", err) }
db.SetMaxOpenConns(maxConns) db.SetMaxIdleConns(maxConns) db.SetConnMaxIdleTime(time.Hour)
pingCtx, cancel := context.WithTimeout(ctx, 5*time.Second) defer cancel() if err := db.PingContext(pingCtx); err != nil { db.Close() return nil, fmt.Errorf("ping db: %w", err) }
conn, err := db.Conn(ctx) if err != nil { return nil, err } defer conn.Close()
_, err = conn.ExecContext(ctx, ` create table if not exists repos ( did text not null, rkey text not null, at_uri text generated always as ('at://' || did || '/' || 'sh.tangled.repo' || '/' || rkey) stored, cid text,
-- record content name text not null, knot_domain text not null,
-- sync info git_rev text not null, repo_sha text not null, state text not null default 'pending', error_msg text, retry_count integer not null default 0, retry_after integer not null default 0, db_created_at timestamptz not null default now(), db_updated_at timestamptz not null default now(),
constraint repos_pkey primary key (did, rkey) );
-- knot hosts create table if not exists hosts ( hostname text not null, no_ssl boolean not null default false, status text not null default 'active', last_seq bigint not null default -1, db_created_at timestamptz not null default now(), db_updated_at timestamptz not null default now(),
constraint hosts_pkey primary key (hostname) );
-- repo language stats at HEAD create table if not exists repo_head_languages ( repo text not null, -- repo identifier (did) commit text not null, -- commit id (oid) language text not null, size integer not null check (size >= 0),
constraint repo_head_languages_pkey primary key (repo, commit, language) );
create index if not exists idx_repos_aturi on repos (at_uri); create index if not exists idx_repos_db_updated_at on repos (db_updated_at desc); create index if not exists idx_hosts_db_updated_at on hosts (db_updated_at desc);
create index if not exists idx_repo_head_languages_repo_commit on repo_head_languages (repo, commit);
create or replace function set_updated_at() returns trigger as $$ begin new.db_updated_at = now(); return new; end; $$ language plpgsql;
drop trigger if exists repos_set_updated_at on repos; create trigger repos_set_updated_at before update on repos for each row execute function set_updated_at();
drop trigger if exists hosts_set_updated_at on hosts; create trigger hosts_set_updated_at before update on hosts for each row execute function set_updated_at(); `) if err != nil { return nil, fmt.Errorf("initializing db schema: %w", err) }
if err := RunMigrations(ctx, conn, log.FromContext(ctx), Migrations); err != nil { return nil, fmt.Errorf("running migrations: %w", err) }
return db, nil}