carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package dbreads
2
3import (
4 "fmt"
5 "time"
6
7 "github.com/carlosframework/platform/internal/dbdoor"
8)
9
10// How a read ended (result.json's state, spec §5.6).
11const (
12 StateDone = "done"
13 StateFailed = "failed"
14 StateRefused = "refused"
15 StateCancelled = "cancelled"
16)
17
18// The fixed code vocabulary the console may read.
19const (
20 CodeNothingReplicated = "nothing-replicated"
21 CodeHistoryGone = "history-gone"
22 CodeCheckFailed = "check-failed"
23 CodeChangedTwice = "changed-twice"
24 CodeTooLarge = "too-large"
25 CodeNoRoom = "no-room"
26 CodeSQLError = "sql-error"
27 CodeTimeout = "timeout"
28 CodeOutputCap = "output-cap"
29 CodeRecordChanged = "record-changed"
30 CodeMoving = "moving"
31 CodeInterrupted = "interrupted"
32)
33
34var codesByState = map[string]map[string]bool{
35 StateDone: {"": true, CodeOutputCap: true},
36 StateFailed: {CodeNothingReplicated: true, CodeHistoryGone: true, CodeCheckFailed: true, CodeChangedTwice: true, CodeTooLarge: true, CodeNoRoom: true, CodeSQLError: true, CodeTimeout: true, CodeInterrupted: true},
37 StateRefused: {CodeRecordChanged: true, CodeMoving: true},
38 StateCancelled: {"": true},
39}
40
41// Result is db-reads/<id>/result.json, written only after every chunk is
42// confirmed. LastSeq is the last chunk's sequence number; a done read has at
43// least one chunk, the last of which is sealed as last.
44type Result struct {
45 State string `json:"state"`
46 Code string `json:"code"`
47 Box string `json:"box"`
48 LastSeq int64 `json:"last_seq"`
49 Started time.Time `json:"started"`
50 Ended time.Time `json:"ended"`
51 Sealed string `json:"sealed"`
52}
53
54// Valid is the shape the console checks before it relays a result.
55func (r Result) Valid() error {
56 codes, ok := codesByState[r.State]
57 switch {
58 case !ok:
59 return fmt.Errorf("dbreads: unknown state %q", r.State)
60 case !codes[r.Code]:
61 return fmt.Errorf("dbreads: code %q is not one of state %s's", r.Code, r.State)
62 case r.LastSeq < 0, r.State == StateDone && r.LastSeq < 1:
63 return fmt.Errorf("dbreads: last_seq %d for state %s", r.LastSeq, r.State)
64 }
65 return nil
66}
67
68// Picked is db-reads/<id>/picked: the owner (J3).
69type Picked struct {
70 Box string `json:"box"`
71 Boot string `json:"boot"`
72 Nonce string `json:"nonce"`
73 Deadline time.Time `json:"deadline"`
74}
75
76// Summary is the result's sealed half, which only the CLI can open (§5.6).
77type Summary struct {
78 TXID uint64 `json:"txid"` // the copy's newest transaction
79 At time.Time `json:"at"` // that transaction's time, from its LTX header
80 Oldest time.Time `json:"oldest"` // history-gone: the earliest --at that works
81 Restored int64 `json:"restored"` // too-large: the restored size
82 Cap int64 `json:"cap"` // too-large: the box's cap
83 Error string `json:"error"` // sql-error: SQLite's text; check-failed: the detail
84 Bytes int64 `json:"bytes"` // the output's plaintext byte count
85 SHA256 string `json:"sha256"` // the output's plaintext SHA-256, hex
86 // Files is a pull's planned files in order (plan 3); empty for a query.
87 Files []dbdoor.LTXFile `json:"files,omitempty"`
88}
89