Skip to content
File

Blob: kv/sqlite3/sqlutil.go

go54 lines
1package sqlite3
2 
3import (
4 "context"
5 "database/sql"
6 "strings"
7)
8 
9// withWriteTx executes fn within a write transaction.
10func withWriteTx(ctx context.Context, db *sql.DB, fn func(tx *sql.Tx) error) error {
11 tx, err := db.BeginTx(ctx, nil)
12 if err != nil {
13 return err
14 }
15 if err := fn(tx); err != nil {
16 _ = tx.Rollback()
17 return err
18 }
19 return tx.Commit()
20}
21 
22// withReadTx executes fn within a read-only transaction.
23func withReadTx(ctx context.Context, db *sql.DB, fn func(tx *sql.Tx) error) error {
24 tx, err := db.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
25 if err != nil {
26 return err
27 }
28 if err := fn(tx); err != nil {
29 _ = tx.Rollback()
30 return err
31 }
32 return tx.Commit()
33}
34 
35// placeholders returns a comma-separated string of n "?" placeholders.
36func placeholders(n int) string {
37 if n <= 0 {
38 return ""
39 }
40 return strings.Repeat("?,", n-1) + "?"
41}
42 
43// bindUint64AsInt64 converts a uint64 to int64 for SQLite INTEGER binding.
44// SQLite stores all integers as signed 64-bit. Values derived from
45// chord.Hash (48-bit) and lease tokens (positive UnixNano) fit safely.
46func bindUint64AsInt64(v uint64) int64 {
47 return int64(v)
48}
49 
50// scanInt64AsUint64 converts a scanned int64 back to uint64.
51func scanInt64AsUint64(v int64) uint64 {
52 return uint64(v)
53}