Monorepo for Tangled
0

Configure Feed

Select the types of activity you want to include in your feed.

core / appview / db / label_migration_test.go
3.0 kB 92 lines
1package db 2 3import ( 4 "database/sql" 5 "path/filepath" 6 "testing" 7) 8 9func TestDropLabelOpsIndexedColumn(t *testing.T) { 10 path := filepath.Join(t.TempDir(), "legacy.db") 11 conn, err := sql.Open("sqlite3", path+"?_foreign_keys=1") 12 if err != nil { 13 t.Fatalf("open: %v", err) 14 } 15 defer conn.Close() 16 17 legacy := ` 18 create table label_definitions ( 19 id integer primary key autoincrement, 20 did text not null, 21 rkey text not null, 22 at_uri text generated always as ('at://' || did || '/' || 'sh.tangled.label.definition' || '/' || rkey) stored, 23 name text not null, 24 unique (at_uri) 25 ); 26 create table label_ops ( 27 id integer primary key autoincrement, 28 did text not null, 29 rkey text not null, 30 at_uri text generated always as ('at://' || did || '/' || 'sh.tangled.label.op' || '/' || rkey) stored, 31 subject text not null, 32 operation text not null check (operation in ("add", "del")), 33 operand_key text not null, 34 operand_value text not null, 35 performed text not null default (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')), 36 indexed text not null default (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')), 37 foreign key (operand_key) references label_definitions (at_uri) on delete cascade, 38 unique (did, rkey, subject, operand_key, operand_value) 39 ); 40 ` 41 if _, err := conn.Exec(legacy); err != nil { 42 t.Fatalf("legacy schema: %v", err) 43 } 44 45 defUri := "at://did:plc:boltless/sh.tangled.label.definition/prio" 46 if _, err := conn.Exec( 47 `insert into label_definitions (did, rkey, name) values (?, ?, ?)`, 48 "did:plc:boltless", "prio", "priority", 49 ); err != nil { 50 t.Fatalf("seed def: %v", err) 51 } 52 if _, err := conn.Exec( 53 `insert into label_ops (did, rkey, subject, operation, operand_key, operand_value) values (?, ?, ?, ?, ?, ?)`, 54 "did:plc:boltless", "op1", "at://did:plc:boltless/sh.tangled.repo.issue/issue1", "add", defUri, "high", 55 ); err != nil { 56 t.Fatalf("seed op: %v", err) 57 } 58 59 indexedColumns := func() int { 60 var count int 61 if err := conn.QueryRow( 62 `select count(*) from pragma_table_info('label_ops') where name = 'indexed'`, 63 ).Scan(&count); err != nil { 64 t.Fatalf("pragma_table_info: %v", err) 65 } 66 return count 67 } 68 69 if indexedColumns() != 1 { 70 t.Fatalf("legacy table must carry the indexed column before the migration") 71 } 72 if _, err := conn.Exec(`alter table label_ops drop column indexed`); err != nil { 73 t.Fatalf("drop column indexed must succeed against the real table shape: %v", err) 74 } 75 if indexedColumns() != 0 { 76 t.Fatalf("indexed column must be gone after the drop") 77 } 78 79 var gotAtUri, gotVal string 80 if err := conn.QueryRow( 81 `select at_uri, operand_value from label_ops where did = ? and rkey = ?`, 82 "did:plc:boltless", "op1", 83 ).Scan(&gotAtUri, &gotVal); err != nil { 84 t.Fatalf("row must survive the drop: %v", err) 85 } 86 if want := "at://did:plc:boltless/sh.tangled.label.op/op1"; gotAtUri != want { 87 t.Fatalf("generated at_uri must survive the drop: got %q want %q", gotAtUri, want) 88 } 89 if gotVal != "high" { 90 t.Fatalf("operand value must survive the drop: got %q", gotVal) 91 } 92}