Skip to content
File

Blob: kv/sqlite3/statements.go

go109 lines
1package sqlite3
2 
3import "database/sql"
4 
5// statements holds prepared statements for fixed-shape queries.
6// Reader statements are prepared on s.reader; writer statements on s.writer.
7// For transactional writes, callers use tx.StmtContext to bind a prepared
8// statement into the active transaction.
9type statements struct {
10 // -- reader --
11 simpleGet *sql.Stmt
12 prefixContains *sql.Stmt
13 prefixList *sql.Stmt
14 listKeys *sql.Stmt
15 rangeKeysNorm *sql.Stmt
16 rangeKeysWrap *sql.Stmt
17 
18 // -- writer --
19 simplePut *sql.Stmt
20 simpleDel *sql.Stmt
21 prefixAppend *sql.Stmt
22 prefixRemove *sql.Stmt
23 prefixCount *sql.Stmt
24 
25 leaseAcquire *sql.Stmt
26 leaseRenew *sql.Stmt
27 leaseRelease *sql.Stmt
28 leaseGet *sql.Stmt
29 leaseImport *sql.Stmt
30 
31 trackerLookup *sql.Stmt
32 trackerInsert *sql.Stmt
33 trackerUpdate *sql.Stmt
34 trackerDelete *sql.Stmt
35 
36 // export uses the reader inside a read tx
37 exportSimpleGet *sql.Stmt
38 exportPrefixList *sql.Stmt
39 exportLeaseGet *sql.Stmt
40 
41 all []*sql.Stmt
42}
43 
44func prepareStatements(reader, writer *sql.DB) (_ *statements, err error) {
45 s := &statements{}
46 defer func() {
47 if err != nil {
48 s.close()
49 }
50 }()
51 
52 type preparedStatement struct {
53 db *sql.DB
54 query string
55 target **sql.Stmt
56 }
57 
58 defs := []preparedStatement{
59 {reader, querySimpleGet, &s.simpleGet},
60 {reader, queryPrefixContains, &s.prefixContains},
61 {reader, queryPrefixList, &s.prefixList},
62 {reader, queryListKeys, &s.listKeys},
63 {reader, queryRangeKeysNorm, &s.rangeKeysNorm},
64 {reader, queryRangeKeysWrap, &s.rangeKeysWrap},
65 {writer, querySimplePut, &s.simplePut},
66 {writer, querySimpleDel, &s.simpleDel},
67 {writer, queryPrefixAppend, &s.prefixAppend},
68 {writer, queryPrefixRemove, &s.prefixRemove},
69 {writer, queryPrefixCount, &s.prefixCount},
70 {writer, queryLeaseAcquire, &s.leaseAcquire},
71 {writer, queryLeaseRenew, &s.leaseRenew},
72 {writer, queryLeaseRelease, &s.leaseRelease},
73 {writer, queryLeaseGet, &s.leaseGet},
74 {writer, queryLeaseImport, &s.leaseImport},
75 {writer, queryTrackerLookup, &s.trackerLookup},
76 {writer, queryTrackerInsert, &s.trackerInsert},
77 {writer, queryTrackerUpdate, &s.trackerUpdate},
78 {writer, queryTrackerDelete, &s.trackerDelete},
79 {reader, queryLeaseGet, &s.exportLeaseGet},
80 }
81 
82 for _, def := range defs {
83 st, prepErr := def.db.Prepare(def.query)
84 if prepErr != nil {
85 err = prepErr
86 return nil, err
87 }
88 *def.target = st
89 s.all = append(s.all, st)
90 }
91 
92 s.exportSimpleGet = s.simpleGet
93 s.exportPrefixList = s.prefixList
94 
95 return s, nil
96}
97 
98func (s *statements) close() {
99 if s == nil {
100 return
101 }
102 for _, st := range s.all {
103 if st != nil {
104 _ = st.Close()
105 }
106 }
107 s.all = nil
108}