forked from
tangled.org/core
Monorepo for Tangled
1package db
2
3import (
4 "context"
5 "database/sql"
6 "fmt"
7
8 "tangled.org/core/log"
9)
10
11var Migrations = []Migration{
12 {
13 Name: "repos_pk_to_repo_did",
14 Fn: reposPkToRepoDid,
15 },
16}
17
18func reposPkToRepoDid(ctx context.Context, tx *sql.Tx) error {
19 if _, err := tx.ExecContext(ctx,
20 `alter table repos add column if not exists repo_did text`,
21 ); err != nil {
22 return fmt.Errorf("adding repo_did column: %w", err)
23 }
24 var bad int
25 if err := tx.QueryRowContext(ctx,
26 `select count(*) from repos where repo_did is null or repo_did = ''`,
27 ).Scan(&bad); err != nil {
28 return fmt.Errorf("counting rows with null repo_did: %w", err)
29 }
30 if bad > 0 {
31 log.FromContext(ctx).Warn(
32 "dropping repos with null repo_did; their on-disk dirs will be orphaned. re-crawl via tap to restore",
33 "count", bad,
34 )
35 if _, err := tx.ExecContext(ctx,
36 `delete from repos where repo_did is null or repo_did = ''`,
37 ); err != nil {
38 return fmt.Errorf("deleting null repo_did rows: %w", err)
39 }
40 }
41 return execAll(ctx, tx,
42 `alter table repos alter column repo_did set not null`,
43 `alter table repos drop constraint if exists repos_pkey`,
44 `alter table repos add constraint repos_pkey primary key (repo_did)`,
45 )
46}
47
48func execAll(ctx context.Context, tx *sql.Tx, stmts ...string) error {
49 if len(stmts) == 0 {
50 return nil
51 }
52 if _, err := tx.ExecContext(ctx, stmts[0]); err != nil {
53 return err
54 }
55 return execAll(ctx, tx, stmts[1:]...)
56}