OXYGENHUB
◆ v0.7.0 oxygenhub / crates / hub / migrations-pg / 0001_schema.sql
34.6 KiB · SQL · last changed Postgres, step 3: the hub builds and passes its tests on PostgreSQL 19 days ago source blame history raw
1
-- The hub's schema on Postgres: one migration equal to SQLite's 0001-0072.
2
-- Generated from the migrated SQLite schema, then reviewed; later changes
3
-- are written for both engines. citext is made by db::open, in public.
4
5
CREATE TABLE repositories (
6
    id               BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
7
    owner            TEXT NOT NULL,
8
    name             TEXT NOT NULL,
9
    description      TEXT NOT NULL DEFAULT '',
10
    default_bookmark TEXT NOT NULL DEFAULT 'main',
11
    visibility       TEXT NOT NULL DEFAULT 'public' CHECK (visibility IN ('public', 'internal', 'private')),
12
    created_ms       BIGINT NOT NULL,
13
    updated_ms       BIGINT NOT NULL,
14
    required_approvals BIGINT NOT NULL DEFAULT 0,
15
    require_owners BOOLEAN NOT NULL DEFAULT FALSE,
16
    allow_conflicts BOOLEAN NOT NULL DEFAULT FALSE,
17
    required_checks TEXT NOT NULL DEFAULT '',
18
    git_mirror BOOLEAN NOT NULL DEFAULT FALSE,
19
    git_mirror_state TEXT NOT NULL DEFAULT '',
20
    forked_from BIGINT REFERENCES repositories(id) ON DELETE SET NULL,
21
    topics TEXT NOT NULL DEFAULT '',
22
    flow TEXT NOT NULL DEFAULT '',
23
    archived BOOLEAN NOT NULL DEFAULT FALSE,
24
    archived_reason TEXT NOT NULL DEFAULT '',
25
    diffusion TEXT NOT NULL DEFAULT '',
26
    diffusion_land TEXT NOT NULL DEFAULT '',
27
    backup TEXT NOT NULL DEFAULT '',
28
    UNIQUE (owner, name)
29
);
30
CREATE TABLE accounts (
31
    id             BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
32
    username       CITEXT NOT NULL UNIQUE,
33
    display_name   TEXT NOT NULL DEFAULT '',
34
    email          TEXT NOT NULL DEFAULT '',
35
    email_verified BOOLEAN NOT NULL DEFAULT FALSE,
36
    password_hash  TEXT NOT NULL,
37
    session_salt   TEXT NOT NULL,
38
    totp_secret    TEXT,
39
    recovery_codes TEXT NOT NULL DEFAULT '',
40
    is_admin       BOOLEAN NOT NULL DEFAULT FALSE,
41
    banned         BOOLEAN NOT NULL DEFAULT FALSE,
42
    created_ms     BIGINT NOT NULL,
43
    last_seen_ms   BIGINT NOT NULL DEFAULT 0,
44
    email_notifications BOOLEAN NOT NULL DEFAULT FALSE,
45
    unsubscribe_key TEXT NOT NULL DEFAULT '',
46
    bio TEXT NOT NULL DEFAULT '',
47
    website TEXT NOT NULL DEFAULT '',
48
    location TEXT NOT NULL DEFAULT '',
49
    avatar TEXT NOT NULL DEFAULT '',
50
    disabled BOOLEAN NOT NULL DEFAULT FALSE,
51
    bluesky TEXT NOT NULL DEFAULT '',
52
    mastodon TEXT NOT NULL DEFAULT '',
53
    github TEXT NOT NULL DEFAULT ''
54
);
55
CREATE TABLE pushes (
56
    id         BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
57
    repo_id    BIGINT NOT NULL REFERENCES repositories(id) ON DELETE CASCADE,
58
    at_ms      BIGINT NOT NULL,
59
    reference  TEXT NOT NULL,
60
    ok         BOOLEAN NOT NULL,
61
    reason     TEXT NOT NULL DEFAULT '',
62
    old_state TEXT NOT NULL DEFAULT '',
63
    new_state TEXT NOT NULL DEFAULT '',
64
    heads BIGINT NOT NULL DEFAULT 0,
65
    changes BIGINT NOT NULL DEFAULT 0,
66
    account_id BIGINT REFERENCES accounts(id) ON DELETE SET NULL,
67
    pusher TEXT NOT NULL DEFAULT '',
68
    via TEXT NOT NULL DEFAULT ''
69
);
70
CREATE TABLE organisations (
71
    id           BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
72
    name         CITEXT NOT NULL UNIQUE,
73
    display_name TEXT NOT NULL DEFAULT '',
74
    description  TEXT NOT NULL DEFAULT '',
75
    default_role TEXT NOT NULL DEFAULT 'read' CHECK (default_role IN ('none', 'read', 'triage', 'write', 'maintain', 'admin')),
76
    created_ms   BIGINT NOT NULL,
77
    avatar TEXT NOT NULL DEFAULT ''
78
);
79
CREATE TABLE org_members (
80
    org_id     BIGINT NOT NULL REFERENCES organisations(id) ON DELETE CASCADE,
81
    account_id BIGINT NOT NULL REFERENCES accounts(id) ON DELETE CASCADE,
82
    role       TEXT NOT NULL DEFAULT 'member' CHECK (role IN ('owner', 'member')),
83
    PRIMARY KEY (org_id, account_id)
84
);
85
CREATE TABLE teams (
86
    id     BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
87
    org_id BIGINT NOT NULL REFERENCES organisations(id) ON DELETE CASCADE,
88
    name   CITEXT NOT NULL,
89
    UNIQUE (org_id, name)
90
);
91
CREATE TABLE team_members (
92
    team_id    BIGINT NOT NULL REFERENCES teams(id) ON DELETE CASCADE,
93
    account_id BIGINT NOT NULL REFERENCES accounts(id) ON DELETE CASCADE,
94
    PRIMARY KEY (team_id, account_id)
95
);
96
CREATE TABLE collaborators (
97
    repo_id    BIGINT NOT NULL REFERENCES repositories(id) ON DELETE CASCADE,
98
    account_id BIGINT REFERENCES accounts(id) ON DELETE CASCADE,
99
    team_id    BIGINT REFERENCES teams(id) ON DELETE CASCADE,
100
    role       TEXT NOT NULL CHECK (role IN ('read', 'triage', 'write', 'maintain', 'admin')),
101
    CHECK ((account_id IS NULL) <> (team_id IS NULL))
102
);
103
CREATE TABLE tokens (
104
    id           BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
105
    account_id   BIGINT NOT NULL REFERENCES accounts(id) ON DELETE CASCADE,
106
    name         TEXT NOT NULL,
107
    hash         TEXT NOT NULL UNIQUE,
108
    scopes       TEXT NOT NULL,
109
    repos        TEXT NOT NULL DEFAULT '',
110
    created_ms   BIGINT NOT NULL,
111
    expires_ms   BIGINT,
112
    last_used_ms BIGINT,
113
    scopes_note TEXT NOT NULL DEFAULT '',
114
    renew_ms BIGINT,
115
    agent BOOLEAN NOT NULL DEFAULT FALSE
116
);
117
CREATE TABLE identities (
118
    key        TEXT PRIMARY KEY,
119
    account_id BIGINT NOT NULL REFERENCES accounts(id) ON DELETE CASCADE,
120
    name       TEXT NOT NULL,
121
    email      TEXT NOT NULL,
122
    object     BYTEA NOT NULL,
123
    linked_ms  BIGINT NOT NULL
124
);
125
CREATE TABLE challenges (
126
    id         BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
127
    account_id BIGINT NOT NULL REFERENCES accounts(id) ON DELETE CASCADE,
128
    bytes      TEXT NOT NULL,
129
    object     BYTEA NOT NULL DEFAULT ''::bytea,
130
    created_ms BIGINT NOT NULL
131
);
132
CREATE TABLE invitations (
133
    code       TEXT PRIMARY KEY,
134
    created_by BIGINT REFERENCES accounts(id) ON DELETE SET NULL,
135
    used_by    BIGINT REFERENCES accounts(id) ON DELETE SET NULL,
136
    created_ms BIGINT NOT NULL
137
);
138
CREATE TABLE audit (
139
    id         BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
140
    at_ms      BIGINT NOT NULL,
141
    actor_id   BIGINT REFERENCES accounts(id) ON DELETE SET NULL,
142
    actor      TEXT NOT NULL DEFAULT '',
143
    action     TEXT NOT NULL,
144
    target     TEXT NOT NULL DEFAULT '',
145
    detail     TEXT NOT NULL DEFAULT ''
146
);
147
CREATE TABLE settings (
148
    key   TEXT PRIMARY KEY,
149
    value TEXT NOT NULL
150
);
151
CREATE TABLE numbers (
152
    repo_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY REFERENCES repositories(id) ON DELETE CASCADE,
153
    next    BIGINT NOT NULL DEFAULT 1
154
);
155
CREATE TABLE proposals (
156
    id               BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
157
    repo_id          BIGINT NOT NULL REFERENCES repositories(id) ON DELETE CASCADE,
158
    number           BIGINT NOT NULL,
159
    title            TEXT NOT NULL,
160
    body             TEXT NOT NULL DEFAULT '',
161
    author_id        BIGINT REFERENCES accounts(id) ON DELETE SET NULL,
162
    author           TEXT NOT NULL DEFAULT '',
163
    state            TEXT NOT NULL DEFAULT 'open' CHECK (state IN ('draft', 'open', 'landed', 'closed')),
164
    target           TEXT NOT NULL,
165
    source_kind      TEXT NOT NULL CHECK (source_kind IN ('bookmark', 'fork', 'changes')),
166
    source_repo_id   BIGINT REFERENCES repositories(id) ON DELETE SET NULL,
167
    source_bookmark  TEXT NOT NULL DEFAULT '',
168
    source_changes   TEXT NOT NULL DEFAULT '',
169
    projected_state  TEXT NOT NULL DEFAULT '',
170
    projected_heads  TEXT NOT NULL DEFAULT '',
171
    projected_target TEXT NOT NULL DEFAULT '',
172
    projected_changes TEXT NOT NULL DEFAULT '',
173
    conflicted       BOOLEAN NOT NULL DEFAULT FALSE,
174
    landed_state     TEXT NOT NULL DEFAULT '',
175
    created_ms       BIGINT NOT NULL,
176
    updated_ms       BIGINT NOT NULL,
177
    landed_by TEXT NOT NULL DEFAULT '',
178
    landed_via TEXT NOT NULL DEFAULT '',
179
    landed_ms BIGINT NOT NULL DEFAULT 0,
180
    UNIQUE (repo_id, number)
181
);
182
CREATE TABLE proposal_comments (
183
    id          BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
184
    proposal_id BIGINT NOT NULL REFERENCES proposals(id) ON DELETE CASCADE,
185
    author_id   BIGINT REFERENCES accounts(id) ON DELETE SET NULL,
186
    author      TEXT NOT NULL DEFAULT '',
187
    body        TEXT NOT NULL,
188
    path        TEXT NOT NULL DEFAULT '',
189
    anchor_change TEXT NOT NULL DEFAULT '',
190
    anchor_index  BIGINT NOT NULL DEFAULT 0,
191
    resolved    BOOLEAN NOT NULL DEFAULT FALSE,
192
    created_ms  BIGINT NOT NULL,
193
    via TEXT NOT NULL DEFAULT ''
194
);
195
CREATE TABLE proposal_events (
196
    id          BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
197
    proposal_id BIGINT NOT NULL REFERENCES proposals(id) ON DELETE CASCADE,
198
    at_ms       BIGINT NOT NULL,
199
    actor       TEXT NOT NULL DEFAULT '',
200
    event       TEXT NOT NULL,
201
    detail      TEXT NOT NULL DEFAULT ''
202
);
203
CREATE TABLE milestones (
204
    id          BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
205
    repo_id     BIGINT NOT NULL REFERENCES repositories(id) ON DELETE CASCADE,
206
    title       TEXT NOT NULL,
207
    description TEXT NOT NULL DEFAULT '',
208
    due_ms      BIGINT,
209
    state       TEXT NOT NULL DEFAULT 'open' CHECK (state IN ('open', 'closed')),
210
    UNIQUE (repo_id, title)
211
);
212
CREATE TABLE issues (
213
    id           BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
214
    repo_id      BIGINT NOT NULL REFERENCES repositories(id) ON DELETE CASCADE,
215
    number       BIGINT NOT NULL,
216
    title        TEXT NOT NULL,
217
    body         TEXT NOT NULL DEFAULT '',
218
    author_id    BIGINT REFERENCES accounts(id) ON DELETE SET NULL,
219
    author       TEXT NOT NULL DEFAULT '',
220
    state        TEXT NOT NULL DEFAULT 'open' CHECK (state IN ('open', 'closed')),
221
    reason       TEXT NOT NULL DEFAULT '' CHECK (reason IN ('', 'completed', 'not_planned')),
222
    locked       BOOLEAN NOT NULL DEFAULT FALSE,
223
    pinned       BOOLEAN NOT NULL DEFAULT FALSE,
224
    milestone_id BIGINT REFERENCES milestones(id) ON DELETE SET NULL,
225
    created_ms   BIGINT NOT NULL,
226
    updated_ms   BIGINT NOT NULL,
227
    closed_ms    BIGINT,
228
    UNIQUE (repo_id, number)
229
);
230
CREATE TABLE issue_comments (
231
    id         BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
232
    issue_id   BIGINT NOT NULL REFERENCES issues(id) ON DELETE CASCADE,
233
    author_id  BIGINT REFERENCES accounts(id) ON DELETE SET NULL,
234
    author     TEXT NOT NULL DEFAULT '',
235
    body       TEXT NOT NULL,
236
    created_ms BIGINT NOT NULL,
237
    edited_ms  BIGINT
238
);
239
CREATE TABLE issue_events (
240
    id       BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
241
    issue_id BIGINT NOT NULL REFERENCES issues(id) ON DELETE CASCADE,
242
    at_ms    BIGINT NOT NULL,
243
    actor    TEXT NOT NULL DEFAULT '',
244
    event    TEXT NOT NULL,
245
    detail   TEXT NOT NULL DEFAULT ''
246
);
247
CREATE TABLE labels (
248
    id          BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
249
    repo_id     BIGINT NOT NULL REFERENCES repositories(id) ON DELETE CASCADE,
250
    name        CITEXT NOT NULL,
251
    colour      TEXT NOT NULL DEFAULT '#0072ff',
252
    description TEXT NOT NULL DEFAULT '',
253
    UNIQUE (repo_id, name)
254
);
255
CREATE TABLE issue_labels (
256
    issue_id BIGINT NOT NULL REFERENCES issues(id) ON DELETE CASCADE,
257
    label_id BIGINT NOT NULL REFERENCES labels(id) ON DELETE CASCADE,
258
    PRIMARY KEY (issue_id, label_id)
259
);
260
CREATE TABLE issue_assignees (
261
    issue_id   BIGINT NOT NULL REFERENCES issues(id) ON DELETE CASCADE,
262
    account_id BIGINT NOT NULL REFERENCES accounts(id) ON DELETE CASCADE,
263
    PRIMARY KEY (issue_id, account_id)
264
);
265
CREATE TABLE proposal_labels (
266
    proposal_id BIGINT NOT NULL REFERENCES proposals(id) ON DELETE CASCADE,
267
    label_id    BIGINT NOT NULL REFERENCES labels(id) ON DELETE CASCADE,
268
    PRIMARY KEY (proposal_id, label_id)
269
);
270
CREATE TABLE notifications (
271
    id         BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
272
    account_id BIGINT NOT NULL REFERENCES accounts(id) ON DELETE CASCADE,
273
    at_ms      BIGINT NOT NULL,
274
    kind       TEXT NOT NULL,
275
    title      TEXT NOT NULL,
276
    url        TEXT NOT NULL,
277
    actor      TEXT NOT NULL DEFAULT '',
278
    read       BOOLEAN NOT NULL DEFAULT FALSE,
279
    repo_id BIGINT REFERENCES repositories(id) ON DELETE CASCADE,
280
    thread TEXT NOT NULL DEFAULT '',
281
    reason TEXT NOT NULL DEFAULT 'participating' CHECK (reason IN ('participating', 'watching')),
282
    done BOOLEAN NOT NULL DEFAULT FALSE
283
);
284
CREATE TABLE watches (
285
    account_id BIGINT NOT NULL REFERENCES accounts(id) ON DELETE CASCADE,
286
    repo_id    BIGINT NOT NULL REFERENCES repositories(id) ON DELETE CASCADE,
287
    muted BOOLEAN NOT NULL DEFAULT FALSE,
288
    PRIMARY KEY (account_id, repo_id)
289
);
290
CREATE TABLE subscriptions (
291
    account_id BIGINT NOT NULL REFERENCES accounts(id) ON DELETE CASCADE,
292
    kind       TEXT NOT NULL CHECK (kind IN ('issue', 'proposal')),
293
    target_id  BIGINT NOT NULL,
294
    PRIMARY KEY (account_id, kind, target_id)
295
);
296
CREATE TABLE hooks (
297
    id         BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
298
    repo_id    BIGINT REFERENCES repositories(id) ON DELETE CASCADE,
299
    org_id     BIGINT REFERENCES organisations(id) ON DELETE CASCADE,
300
    url        TEXT NOT NULL,
301
    secret     TEXT NOT NULL DEFAULT '',
302
    events     TEXT NOT NULL DEFAULT '*',
303
    active     BOOLEAN NOT NULL DEFAULT TRUE,
304
    created_ms BIGINT NOT NULL,
305
    format TEXT NOT NULL DEFAULT 'oxygenhub' CHECK (format IN ('oxygenhub', 'discord', 'slack')),
306
    CHECK ((repo_id IS NULL) <> (org_id IS NULL))
307
);
308
CREATE TABLE deliveries (
309
    id          BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
310
    hook_id     BIGINT NOT NULL REFERENCES hooks(id) ON DELETE CASCADE,
311
    delivery    TEXT NOT NULL,
312
    event       TEXT NOT NULL,
313
    payload     TEXT NOT NULL,
314
    created_ms  BIGINT NOT NULL,
315
    attempts    BIGINT NOT NULL DEFAULT 0,
316
    next_ms     BIGINT NOT NULL,
317
    status      BIGINT,
318
    response    TEXT NOT NULL DEFAULT '',
319
    delivered_ms BIGINT
320
);
321
CREATE TABLE checks (
322
    id          BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
323
    repo_id     BIGINT NOT NULL REFERENCES repositories(id) ON DELETE CASCADE,
324
    state       TEXT NOT NULL,
325
    name        TEXT NOT NULL,
326
    status      TEXT NOT NULL CHECK (status IN ('queued', 'running', 'passed', 'failed', 'cancelled', 'skipped')),
327
    summary     TEXT NOT NULL DEFAULT '',
328
    url         TEXT NOT NULL DEFAULT '',
329
    reporter_id BIGINT REFERENCES accounts(id) ON DELETE SET NULL,
330
    reporter    TEXT NOT NULL DEFAULT '',
331
    seal        TEXT NOT NULL DEFAULT '',
332
    started_ms  BIGINT NOT NULL,
333
    finished_ms BIGINT,
334
    UNIQUE (repo_id, state, name)
335
);
336
CREATE TABLE releases (
337
    id          BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
338
    repo_id     BIGINT NOT NULL REFERENCES repositories(id) ON DELETE CASCADE,
339
    tag         TEXT NOT NULL,
340
    title       TEXT NOT NULL,
341
    notes       TEXT NOT NULL DEFAULT '',
342
    prerelease  BOOLEAN NOT NULL DEFAULT FALSE,
343
    author_id   BIGINT REFERENCES accounts(id) ON DELETE SET NULL,
344
    author      TEXT NOT NULL DEFAULT '',
345
    created_ms  BIGINT NOT NULL,
346
    UNIQUE (repo_id, tag)
347
);
348
CREATE TABLE release_assets (
349
    id           BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
350
    release_id   BIGINT NOT NULL REFERENCES releases(id) ON DELETE CASCADE,
351
    name         TEXT NOT NULL,
352
    size         BIGINT NOT NULL,
353
    hash         TEXT NOT NULL,
354
    content_type TEXT NOT NULL DEFAULT 'application/octet-stream',
355
    downloads    BIGINT NOT NULL DEFAULT 0,
356
    created_ms   BIGINT NOT NULL,
357
    UNIQUE (release_id, name)
358
);
359
CREATE TABLE stars (
360
    account_id BIGINT NOT NULL REFERENCES accounts(id) ON DELETE CASCADE,
361
    repo_id    BIGINT NOT NULL REFERENCES repositories(id) ON DELETE CASCADE,
362
    at_ms      BIGINT NOT NULL,
363
    PRIMARY KEY (account_id, repo_id)
364
);
365
CREATE TABLE flow_runs (
366
    id            BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
367
    repo_id       BIGINT NOT NULL REFERENCES repositories(id) ON DELETE CASCADE,
368
    bookmark      TEXT NOT NULL,
369
    state         TEXT NOT NULL,
370
    heads         TEXT NOT NULL,
371
    pipeline_hash TEXT NOT NULL DEFAULT '',
372
    status        TEXT NOT NULL CHECK (status IN ('queued', 'running', 'passed', 'failed', 'error', 'cancelled')),
373
    error         TEXT NOT NULL DEFAULT '',
374
    actor         TEXT NOT NULL DEFAULT '',
375
    created_ms    BIGINT NOT NULL,
376
    finished_ms   BIGINT,
377
    number        BIGINT NOT NULL DEFAULT 0,
378
    trigger       TEXT NOT NULL DEFAULT 'push'
379
);
380
CREATE TABLE flow_jobs (
381
    id             BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
382
    run_id         BIGINT NOT NULL REFERENCES flow_runs(id) ON DELETE CASCADE,
383
    name           TEXT NOT NULL,
384
    depth          BIGINT NOT NULL,
385
    depends        TEXT NOT NULL,
386
    spec           TEXT NOT NULL,
387
    sandbox        TEXT NOT NULL,
388
    runtime        TEXT NOT NULL,
389
    status         TEXT NOT NULL CHECK (status IN ('queued', 'running', 'passed', 'failed', 'skipped', 'error', 'cancelled')),
390
    runner         TEXT NOT NULL DEFAULT '',
391
    token_hash     TEXT NOT NULL DEFAULT '',
392
    started_ms     BIGINT,
393
    finished_ms    BIGINT,
394
    exit_code      BIGINT,
395
    error          TEXT NOT NULL DEFAULT '',
396
    receipt        TEXT NOT NULL DEFAULT '',
397
    receipt_hash   TEXT NOT NULL DEFAULT '',
398
    log_count      BIGINT NOT NULL DEFAULT 0,
399
    also_read      TEXT NOT NULL DEFAULT '',
400
    receipt_attest TEXT NOT NULL DEFAULT '',
401
    receipt_signer TEXT NOT NULL DEFAULT '',
402
    receipt_note   TEXT NOT NULL DEFAULT '',
403
    runner_id      BIGINT,
404
    timeout_s      BIGINT NOT NULL DEFAULT 0,
405
    waiting TEXT NOT NULL DEFAULT '',
406
    peak_disk_mib BIGINT,
407
    peak_memory_mib BIGINT,
408
    need_disk_mib BIGINT,
409
    placed TEXT NOT NULL DEFAULT '',
410
    approval TEXT NOT NULL DEFAULT '',
411
    approved_by TEXT NOT NULL DEFAULT '',
412
    approved_ms BIGINT,
413
    environment TEXT NOT NULL DEFAULT '',
414
    approval_seal TEXT NOT NULL DEFAULT '',
415
    UNIQUE (run_id, name)
416
);
417
CREATE TABLE flow_logs (
418
    job_id BIGINT NOT NULL REFERENCES flow_jobs(id) ON DELETE CASCADE,
419
    seq    BIGINT NOT NULL,
420
    t      BIGINT NOT NULL,
421
    stream TEXT NOT NULL,
422
    text   TEXT NOT NULL,
423
    PRIMARY KEY (job_id, seq)
424
);
425
CREATE TABLE account_links (
426
    id         BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
427
    account_id BIGINT NOT NULL REFERENCES accounts(id) ON DELETE CASCADE,
428
    kind       TEXT NOT NULL CHECK (kind IN ('reset', 'verify')),
429
    hash       TEXT NOT NULL UNIQUE,
430
    email      TEXT NOT NULL DEFAULT '',
431
    created_by BIGINT REFERENCES accounts(id) ON DELETE SET NULL,
432
    created_ms BIGINT NOT NULL,
433
    expires_ms BIGINT NOT NULL,
434
    used_ms    BIGINT
435
);
436
CREATE TABLE projects (
437
    id          BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
438
    owner       TEXT NOT NULL,
439
    number      BIGINT NOT NULL,
440
    title       TEXT NOT NULL,
441
    description TEXT NOT NULL DEFAULT '',
442
    public      BOOLEAN NOT NULL DEFAULT TRUE,
443
    closed      BOOLEAN NOT NULL DEFAULT FALSE,
444
    created_ms  BIGINT NOT NULL,
445
    updated_ms  BIGINT NOT NULL,
446
    UNIQUE (owner, number)
447
);
448
CREATE TABLE project_columns (
449
    id         BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
450
    project_id BIGINT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
451
    name       TEXT NOT NULL,
452
    position   BIGINT NOT NULL
453
);
454
CREATE TABLE project_cards (
455
    id         BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
456
    project_id BIGINT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
457
    column_id  BIGINT NOT NULL REFERENCES project_columns(id) ON DELETE CASCADE,
458
    position   BIGINT NOT NULL,
459
    kind       TEXT NOT NULL CHECK (kind IN ('issue', 'proposal', 'note')),
460
    repo_id    BIGINT REFERENCES repositories(id) ON DELETE CASCADE,
461
    number     BIGINT,
462
    note       TEXT NOT NULL DEFAULT '',
463
    added_by   TEXT NOT NULL DEFAULT '',
464
    created_ms BIGINT NOT NULL
465
);
466
CREATE TABLE flow_runner_keys (
467
    token_hash TEXT PRIMARY KEY,
468
    key TEXT NOT NULL,
469
    name TEXT NOT NULL,
470
    first_ms BIGINT NOT NULL
471
);
472
CREATE TABLE flow_artifacts (
473
    job_id BIGINT NOT NULL REFERENCES flow_jobs(id) ON DELETE CASCADE,
474
    name TEXT NOT NULL,
475
    path TEXT NOT NULL,
476
    blob TEXT NOT NULL,
477
    size BIGINT NOT NULL,
478
    content TEXT NOT NULL,
479
    created_ms BIGINT NOT NULL,
480
    PRIMARY KEY (job_id, name)
481
);
482
CREATE TABLE flow_runners (
483
    id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
484
    name TEXT NOT NULL,
485
    token_hash TEXT NOT NULL UNIQUE,
486
    source TEXT NOT NULL,
487
    key TEXT NOT NULL DEFAULT '',
488
    key_name TEXT NOT NULL DEFAULT '',
489
    arch TEXT NOT NULL DEFAULT '',
490
    os TEXT NOT NULL DEFAULT '',
491
    version TEXT NOT NULL DEFAULT '',
492
    labels TEXT NOT NULL DEFAULT '',
493
    max_jobs BIGINT NOT NULL DEFAULT 1,
494
    memory_mib BIGINT,
495
    cpus BIGINT,
496
    state TEXT NOT NULL DEFAULT 'active',
497
    created_ms BIGINT NOT NULL,
498
    created_by TEXT NOT NULL DEFAULT '',
499
    last_seen_ms BIGINT,
500
    scope_owner TEXT NOT NULL DEFAULT '',
501
    scope_repo_id BIGINT,
502
    admin_labels TEXT NOT NULL DEFAULT '',
503
    timeout_minutes BIGINT,
504
    tiers TEXT NOT NULL DEFAULT '',
505
    images TEXT NOT NULL DEFAULT '',
506
    profile TEXT NOT NULL DEFAULT '',
507
    fetches_images BOOLEAN NOT NULL DEFAULT FALSE,
508
    free_disk_mib BIGINT,
509
    load_x100 BIGINT,
510
    speed BIGINT,
511
    speed_class BIGINT,
512
    kernel TEXT NOT NULL DEFAULT '',
513
    state_ms BIGINT NOT NULL DEFAULT 0
514
);
515
CREATE TABLE flow_runner_registrations (
516
    token_hash TEXT PRIMARY KEY,
517
    created_by TEXT NOT NULL,
518
    created_ms BIGINT NOT NULL,
519
    expires_ms BIGINT NOT NULL,
520
    used_ms BIGINT,
521
    runner_id BIGINT,
522
    scope_owner TEXT NOT NULL DEFAULT '',
523
    scope_repo_id BIGINT
524
);
525
CREATE TABLE device_codes (
526
    id              BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
527
    device_hash     TEXT NOT NULL UNIQUE,
528
    user_code       TEXT NOT NULL UNIQUE,
529
    client          TEXT NOT NULL,
530
    scopes          TEXT NOT NULL,
531
    created_ms      BIGINT NOT NULL,
532
    expires_ms      BIGINT NOT NULL,
533
    last_poll_ms    BIGINT NOT NULL DEFAULT 0,
534
    account_id      BIGINT REFERENCES accounts(id) ON DELETE CASCADE,
535
    approved_scopes TEXT NOT NULL DEFAULT '',
536
    denied          BOOLEAN NOT NULL DEFAULT FALSE,
537
    requester TEXT NOT NULL DEFAULT ''
538
);
539
CREATE TABLE proposal_review_requests (
540
    proposal_id  BIGINT NOT NULL REFERENCES proposals(id) ON DELETE CASCADE,
541
    account_id   BIGINT NOT NULL REFERENCES accounts(id) ON DELETE CASCADE,
542
    requested_by TEXT NOT NULL,
543
    requested_ms BIGINT NOT NULL,
544
    PRIMARY KEY (proposal_id, account_id)
545
);
546
CREATE TABLE retired_usernames (
547
    username   CITEXT PRIMARY KEY,
548
    retired_ms BIGINT NOT NULL
549
);
550
CREATE TABLE proposal_reviews (
551
    id          BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
552
    proposal_id BIGINT NOT NULL REFERENCES proposals(id) ON DELETE CASCADE,
553
    author_id   BIGINT REFERENCES accounts(id) ON DELETE SET NULL,
554
    author      TEXT NOT NULL DEFAULT '',
555
    verdict     TEXT NOT NULL CHECK (verdict IN ('comment', 'changes', 'approve')),
556
    body        TEXT NOT NULL DEFAULT '',
557
    created_ms  BIGINT NOT NULL,
558
    via TEXT NOT NULL DEFAULT ''
559
);
560
CREATE TABLE assistants (
561
    id          BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
562
    scope       TEXT NOT NULL CHECK (scope IN ('site', 'org', 'repo')),
563
    scope_id    BIGINT NOT NULL DEFAULT 0,
564
    name        CITEXT NOT NULL,
565
    endpoint    TEXT NOT NULL,
566
    api         TEXT NOT NULL,
567
    model       TEXT NOT NULL,
568
    headers     TEXT NOT NULL DEFAULT '',
569
    token       BYTEA NOT NULL,
570
    enabled     BOOLEAN NOT NULL DEFAULT TRUE,
571
    budget      BIGINT NOT NULL DEFAULT 120000,
572
    created_ms  BIGINT NOT NULL,
573
    updated_ms  BIGINT NOT NULL,
574
    UNIQUE (scope, scope_id, name)
575
);
576
CREATE TABLE assistant_prompts (
577
    scope       TEXT NOT NULL CHECK (scope IN ('site', 'org', 'repo')),
578
    scope_id    BIGINT NOT NULL DEFAULT 0,
579
    prompt      TEXT NOT NULL,
580
    updated_ms  BIGINT NOT NULL,
581
    PRIMARY KEY (scope, scope_id)
582
);
583
CREATE TABLE flow_variables (
584
    scope       TEXT NOT NULL CHECK (scope IN ('site', 'org', 'repo')),
585
    scope_id    BIGINT NOT NULL DEFAULT 0,
586
    name        TEXT NOT NULL,
587
    value       TEXT NOT NULL,
588
    updated_ms  BIGINT NOT NULL,
589
    PRIMARY KEY (scope, scope_id, name)
590
);
591
CREATE TABLE flow_secrets (
592
    scope       TEXT NOT NULL CHECK (scope IN ('site', 'org', 'repo')),
593
    scope_id    BIGINT NOT NULL DEFAULT 0,
594
    name        TEXT NOT NULL,
595
    value       BYTEA NOT NULL,
596
    updated_ms  BIGINT NOT NULL,
597
    PRIMARY KEY (scope, scope_id, name)
598
);
599
CREATE TABLE repo_redirects (
600
    old_owner   TEXT NOT NULL,
601
    old_name    TEXT NOT NULL,
602
    repo_id     BIGINT NOT NULL REFERENCES repositories(id) ON DELETE CASCADE,
603
    moved_ms    BIGINT NOT NULL,
604
    PRIMARY KEY (old_owner, old_name)
605
);
606
CREATE TABLE account_logins (
607
    provider    TEXT NOT NULL,
608
    subject     TEXT NOT NULL,
609
    account_id  BIGINT NOT NULL REFERENCES accounts(id) ON DELETE CASCADE,
610
    login       TEXT NOT NULL DEFAULT '',
611
    linked_ms   BIGINT NOT NULL,
612
    PRIMARY KEY (provider, subject)
613
);
614
CREATE TABLE flow_images (
615
    hash     TEXT PRIMARY KEY,
616
    arch     TEXT NOT NULL,
617
    seen_ms  BIGINT NOT NULL
618
);
619
CREATE TABLE flow_declines (
620
    job_id     BIGINT NOT NULL REFERENCES flow_jobs(id) ON DELETE CASCADE,
621
    runner_id  BIGINT NOT NULL,
622
    runner     TEXT NOT NULL,
623
    profile    TEXT NOT NULL,
624
    reason     TEXT NOT NULL,
625
    ms         BIGINT NOT NULL,
626
    PRIMARY KEY (job_id, runner_id)
627
);
628
CREATE TABLE repo_storage (
629
    repo_id      BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY REFERENCES repositories(id) ON DELETE CASCADE,
630
    url          TEXT NOT NULL,
631
    credentials  BYTEA NOT NULL,
632
    created_ms   BIGINT NOT NULL,
633
    checked_ms   BIGINT,
634
    check_result TEXT NOT NULL DEFAULT ''
635
);
636
CREATE TABLE org_storage_policy (
637
    org_id         BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY REFERENCES organisations(id) ON DELETE CASCADE,
638
    require_bucket BOOLEAN NOT NULL DEFAULT FALSE,
639
    allowed        TEXT NOT NULL DEFAULT ''
640
);
641
CREATE TABLE coverage_settings (
642
    repo_id   BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY REFERENCES repositories(id) ON DELETE CASCADE,
643
    min       DOUBLE PRECISION,
644
    max_drop  DOUBLE PRECISION
645
);
646
CREATE TABLE test_reports (
647
    id          BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
648
    repo_id     BIGINT NOT NULL REFERENCES repositories(id) ON DELETE CASCADE,
649
    run_id      BIGINT NOT NULL REFERENCES flow_runs(id) ON DELETE CASCADE,
650
    job_id      BIGINT NOT NULL UNIQUE,
651
    job         TEXT NOT NULL,
652
    run_number  BIGINT NOT NULL,
653
    bookmark    TEXT NOT NULL,
654
    state       TEXT NOT NULL,
655
    blob        TEXT NOT NULL,
656
    tests       BIGINT NOT NULL,
657
    passed      BIGINT NOT NULL,
658
    failed      BIGINT NOT NULL,
659
    errors      BIGINT NOT NULL,
660
    skipped     BIGINT NOT NULL,
661
    time_ms     BIGINT NOT NULL,
662
    created_ms  BIGINT NOT NULL
663
);
664
CREATE TABLE test_cases (
665
    report_id   BIGINT NOT NULL REFERENCES test_reports(id) ON DELETE CASCADE,
666
    idx         BIGINT NOT NULL,
667
    suite       TEXT NOT NULL,
668
    classname   TEXT NOT NULL,
669
    name        TEXT NOT NULL,
670
    status      TEXT NOT NULL,
671
    time_ms     BIGINT NOT NULL,
672
    message     TEXT NOT NULL,
673
    output      TEXT NOT NULL,
674
    PRIMARY KEY (report_id, idx)
675
);
676
CREATE TABLE project_redirects (
677
    owner      TEXT NOT NULL,
678
    number     BIGINT NOT NULL,
679
    project_id BIGINT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
680
    PRIMARY KEY (owner, number)
681
);
682
CREATE TABLE reports (
683
    id          BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
684
    repo_id     BIGINT NOT NULL REFERENCES repositories(id) ON DELETE CASCADE,
685
    name        TEXT NOT NULL,
686
    kind        TEXT NOT NULL,
687
    title       TEXT NOT NULL,
688
    summary     TEXT NOT NULL,
689
    context     TEXT NOT NULL,
690
    run_id      BIGINT REFERENCES flow_runs(id) ON DELETE CASCADE,
691
    job_id      BIGINT,
692
    run_number  BIGINT,
693
    job         TEXT NOT NULL,
694
    bookmark    TEXT NOT NULL,
695
    state       TEXT NOT NULL,
696
    manifest    TEXT,
697
    files       BIGINT NOT NULL,
698
    bytes       BIGINT NOT NULL,
699
    created_ms  BIGINT NOT NULL,
700
    files_expired_ms BIGINT
701
);
702
CREATE TABLE report_metrics (
703
    report_id   BIGINT NOT NULL REFERENCES reports(id) ON DELETE CASCADE,
704
    key         TEXT NOT NULL,
705
    value       DOUBLE PRECISION NOT NULL,
706
    unit        TEXT NOT NULL,
707
    better      TEXT NOT NULL,
708
    fail_above  DOUBLE PRECISION,
709
    fail_below  DOUBLE PRECISION,
710
    PRIMARY KEY (report_id, key)
711
);
712
CREATE TABLE report_files (
713
    report_id   BIGINT NOT NULL REFERENCES reports(id) ON DELETE CASCADE,
714
    path        TEXT NOT NULL,
715
    blob        TEXT NOT NULL,
716
    size        BIGINT NOT NULL,
717
    PRIMARY KEY (report_id, path)
718
);
719
CREATE TABLE jet_images (
720
    hash        TEXT PRIMARY KEY,
721
    size        BIGINT NOT NULL,
722
    arch        TEXT NOT NULL,
723
    chunks      BIGINT NOT NULL,
724
    uploader    TEXT NOT NULL,
725
    created_ms  BIGINT NOT NULL
726
);
727
CREATE TABLE coverage_reports (
728
    id               BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
729
    repo_id          BIGINT NOT NULL REFERENCES repositories(id) ON DELETE CASCADE,
730
    run_id           BIGINT REFERENCES flow_runs(id) ON DELETE CASCADE,
731
    job_id           BIGINT UNIQUE,
732
    job              TEXT NOT NULL,
733
    run_number       BIGINT NOT NULL,
734
    bookmark         TEXT NOT NULL,
735
    state            TEXT NOT NULL,
736
    heads            TEXT NOT NULL,
737
    blob             TEXT NOT NULL,
738
    format           TEXT NOT NULL,
739
    lines_found      BIGINT NOT NULL,
740
    lines_hit        BIGINT NOT NULL,
741
    functions_found  BIGINT NOT NULL,
742
    functions_hit    BIGINT NOT NULL,
743
    branches_found   BIGINT NOT NULL,
744
    branches_hit     BIGINT NOT NULL,
745
    hits             BIGINT NOT NULL DEFAULT 0,
746
    files            BIGINT NOT NULL,
747
    dropped          BIGINT NOT NULL,
748
    created_ms       BIGINT NOT NULL,
749
    uploader         TEXT NOT NULL DEFAULT ''
750
);
751
CREATE TABLE coverage_files (
752
    report_id        BIGINT NOT NULL REFERENCES "coverage_reports"(id) ON DELETE CASCADE,
753
    path             TEXT NOT NULL,
754
    lines_found      BIGINT NOT NULL,
755
    lines_hit        BIGINT NOT NULL,
756
    functions_found  BIGINT NOT NULL,
757
    functions_hit    BIGINT NOT NULL,
758
    branches_found   BIGINT NOT NULL,
759
    branches_hit     BIGINT NOT NULL,
760
    PRIMARY KEY (report_id, path)
761
);
762
CREATE TABLE diffusion_pins (
763
    consumer_id  BIGINT NOT NULL REFERENCES repositories(id) ON DELETE CASCADE,
764
    bookmark     TEXT NOT NULL,
765
    path         TEXT NOT NULL,
766
    upstream     TEXT NOT NULL,
767
    heads        TEXT NOT NULL,
768
    updated_ms   BIGINT NOT NULL,
769
    upstream_repo_id BIGINT,
770
    PRIMARY KEY (consumer_id, bookmark, path)
771
);
772
CREATE TABLE backup_settings (
773
    owner       TEXT PRIMARY KEY,
774
    kind        TEXT NOT NULL,
775
    every       TEXT NOT NULL DEFAULT 'off',
776
    destination TEXT NOT NULL DEFAULT 'dir',
777
    target      TEXT NOT NULL DEFAULT '',
778
    prefix      TEXT NOT NULL DEFAULT '',
779
    provider    TEXT NOT NULL DEFAULT '',
780
    keep_days   BIGINT NOT NULL DEFAULT 30,
781
    updated_ms  BIGINT NOT NULL,
782
    region TEXT NOT NULL DEFAULT ''
783
);
784
CREATE TABLE backup_runs (
785
    id          BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
786
    owner       TEXT NOT NULL,
787
    started_ms  BIGINT NOT NULL,
788
    finished_ms BIGINT,
789
    status      TEXT NOT NULL,
790
    at          TEXT NOT NULL DEFAULT '',
791
    repos       BIGINT NOT NULL DEFAULT 0,
792
    files       BIGINT NOT NULL DEFAULT 0,
793
    sent        BIGINT NOT NULL DEFAULT 0,
794
    bytes       BIGINT NOT NULL DEFAULT 0,
795
    detail      TEXT NOT NULL DEFAULT '',
796
    trigger     TEXT NOT NULL DEFAULT 'schedule'
797
);
798
CREATE TABLE sessions (
799
    id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
800
    account_id BIGINT NOT NULL REFERENCES accounts(id) ON DELETE CASCADE,
801
    hash TEXT NOT NULL UNIQUE,
802
    salt TEXT NOT NULL,
803
    created_ms BIGINT NOT NULL,
804
    seen_ms BIGINT NOT NULL,
805
    address TEXT NOT NULL DEFAULT '',
806
    agent TEXT NOT NULL DEFAULT ''
807
);
808
CREATE TABLE diffusion_indexed (
809
    consumer_id BIGINT NOT NULL REFERENCES repositories(id) ON DELETE CASCADE,
810
    bookmark TEXT NOT NULL,
811
    heads TEXT NOT NULL,
812
    updated_ms BIGINT NOT NULL,
813
    PRIMARY KEY (consumer_id, bookmark)
814
);
815
CREATE INDEX account_links_by_account ON account_links (account_id, kind, created_ms DESC);
816
CREATE INDEX account_logins_by_account ON account_logins (account_id);
817
CREATE INDEX audit_by_time ON audit (at_ms DESC);
818
CREATE INDEX backup_runs_by_owner ON backup_runs (owner, id DESC);
819
CREATE INDEX checks_by_state ON checks (repo_id, state);
820
CREATE UNIQUE INDEX collaborators_account ON collaborators (repo_id, account_id) WHERE account_id IS NOT NULL;
821
CREATE UNIQUE INDEX collaborators_team ON collaborators (repo_id, team_id) WHERE team_id IS NOT NULL;
822
CREATE INDEX coverage_reports_bookmark ON coverage_reports (repo_id, bookmark, created_ms);
823
CREATE INDEX deliveries_by_hook ON deliveries (hook_id, created_ms DESC);
824
CREATE INDEX deliveries_due ON deliveries (next_ms) WHERE delivered_ms IS NULL;
825
CREATE INDEX diffusion_pins_by_upstream ON diffusion_pins (upstream);
826
CREATE INDEX flow_artifacts_content ON flow_artifacts(content);
827
CREATE INDEX flow_declines_runner ON flow_declines (runner_id, ms);
828
CREATE INDEX flow_jobs_environment ON flow_jobs(environment) WHERE environment != '';
829
CREATE INDEX flow_jobs_queued ON flow_jobs (status, id);
830
CREATE INDEX flow_jobs_runner ON flow_jobs (runner_id);
831
CREATE INDEX flow_jobs_token ON flow_jobs (token_hash) WHERE token_hash <> '';
832
CREATE INDEX flow_runs_by_repo ON flow_runs (repo_id, id DESC);
833
CREATE UNIQUE INDEX flow_runs_number ON flow_runs (repo_id, number);
834
CREATE INDEX issue_comments_by_issue ON issue_comments (issue_id, created_ms);
835
CREATE INDEX notifications_by_account ON notifications (account_id, read, at_ms DESC);
836
CREATE INDEX notifications_by_thread ON notifications (account_id, done, thread, at_ms DESC);
837
CREATE INDEX project_cards_by_column ON project_cards (column_id, position);
838
CREATE UNIQUE INDEX project_cards_once ON project_cards (project_id, repo_id, number) WHERE kind <> 'note';
839
CREATE INDEX project_columns_by_project ON project_columns (project_id, position);
840
CREATE INDEX proposal_comments_by_proposal ON proposal_comments (proposal_id, created_ms);
841
CREATE INDEX proposal_reviews_by_proposal ON proposal_reviews (proposal_id, created_ms);
842
CREATE INDEX pushes_by_repo ON pushes (repo_id, at_ms DESC);
843
CREATE INDEX report_files_blob ON report_files (blob);
844
CREATE INDEX reports_history ON reports (repo_id, name, bookmark, created_ms);
845
CREATE UNIQUE INDEX reports_job ON reports (job_id, name);
846
CREATE INDEX repositories_forks ON repositories (forked_from) WHERE forked_from IS NOT NULL;
847
CREATE INDEX sessions_account ON sessions(account_id);
848
CREATE INDEX stars_by_repo ON stars (repo_id);
849
CREATE INDEX test_cases_name ON test_cases (classname, name);
850
CREATE INDEX test_reports_bookmark ON test_reports (repo_id, bookmark, created_ms);
851
852
-- Full-text search (SQLite: an FTS5 table with the porter tokenizer):
853
-- English stemming, titles weighted above bodies.
854
CREATE TABLE search (
855
    kind      TEXT NOT NULL,
856
    repo_id   BIGINT NOT NULL,
857
    target_id BIGINT NOT NULL,
858
    number    BIGINT NOT NULL,
859
    title     TEXT NOT NULL,
860
    body      TEXT NOT NULL,
861
    doc       tsvector GENERATED ALWAYS AS (setweight(to_tsvector('english', title), 'A') || setweight(to_tsvector('english', body), 'B')) STORED
862
);
863
CREATE INDEX search_doc ON search USING GIN (doc);
864
CREATE INDEX search_target ON search (kind, target_id);