carlos / platform Public

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

Plain git — no account needed to clone.

Download

Download this file

1package registry
2
3import (
4 "context"
5 "database/sql"
6 "database/sql/driver"
7 "errors"
8)
9
10type claimTransaction struct {
11 conn *sql.Conn
12 ctx context.Context
13 full bool
14 done bool
15}
16
17func (r *Registry) beginClaimTransaction(ctx context.Context, full bool) (*claimTransaction, error) {
18 conn, err := r.sql.Conn(ctx)
19 if err != nil {
20 return nil, err
21 }
22 tx := &claimTransaction{conn: conn, ctx: ctx, full: full}
23 if full {
24 if _, err = conn.ExecContext(ctx, "PRAGMA synchronous=FULL"); err != nil {
25 return nil, errors.Join(err, tx.close())
26 }
27 }
28 if _, err = conn.ExecContext(ctx, "BEGIN IMMEDIATE"); err != nil {
29 return nil, errors.Join(err, tx.close())
30 }
31 return tx, nil
32}
33func (t *claimTransaction) ExecContext(ctx context.Context, q string, args ...any) (sql.Result, error) {
34 return t.conn.ExecContext(ctx, q, args...)
35}
36func (t *claimTransaction) QueryRowContext(ctx context.Context, q string, args ...any) *sql.Row {
37 return t.conn.QueryRowContext(ctx, q, args...)
38}
39func (t *claimTransaction) Exec(q string, args ...any) (sql.Result, error) {
40 return t.ExecContext(t.ctx, q, args...)
41}
42func (t *claimTransaction) QueryRow(q string, args ...any) *sql.Row {
43 return t.QueryRowContext(t.ctx, q, args...)
44}
45func (t *claimTransaction) close() error {
46 t.done = true
47 var err error
48 if t.full {
49 _, err = t.conn.ExecContext(context.Background(), "PRAGMA synchronous=NORMAL")
50 if err != nil {
51 _ = t.conn.Raw(func(any) error { return driver.ErrBadConn })
52 }
53 }
54 return errors.Join(err, t.conn.Close())
55}
56func (t *claimTransaction) Commit() error {
57 if t.done {
58 return sql.ErrTxDone
59 }
60 if _, err := t.conn.ExecContext(t.ctx, "COMMIT"); err != nil {
61 return errors.Join(err, t.Rollback())
62 }
63 return t.close()
64}
65func (t *claimTransaction) Rollback() error {
66 if t.done {
67 return nil
68 }
69 _, err := t.conn.ExecContext(context.Background(), "ROLLBACK")
70 if err != nil {
71 _ = t.conn.Raw(func(any) error { return driver.ErrBadConn })
72 }
73 return errors.Join(err, t.close())
74}
75