-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstmt.go
More file actions
94 lines (75 loc) · 1.88 KB
/
stmt.go
File metadata and controls
94 lines (75 loc) · 1.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package dbw
import (
"context"
"database/sql"
"sync/atomic"
"time"
"github.com/axkit/errors"
"github.com/lib/pq"
_ "github.com/lib/pq"
)
type Stmt struct {
db *DB
// uid holds hash caclucated over SQL statement text.
uid string
// text holds formatted SQL statement text.
text string
sqlStmt *sql.Stmt
logger StmtLogger
err error
// lastInstanceTime holds a time when the statement has been instatiated last time.
lastInstanceTime int64
}
func newStmt(ctx context.Context, db *DB, uid string, qry string) *Stmt {
s := &Stmt{uid: uid, text: qry, db: db}
s.sqlStmt, s.err = db.SQLDB().PrepareContext(ctx, qry)
if s.err == nil {
return s
}
if pe, ok := s.err.(*pq.Error); ok {
s.err = errors.Catch(s.err).
Set("query", qry).
Set("code", pe.Code).
Set("name", pe.Code.Name()).
Severity(errors.Critical).
Msg("prepare sql statement failed")
} else {
s.err = errors.Catch(s.err).Set("query", qry).Severity(errors.Critical).Msg("prepare sql statement failed")
}
return s
}
func (s *Stmt) Instance() *StmtInstance {
if s.err != nil {
return newStmtInstance(s, 0, s.err)
}
si := newStmtInstance(s, s.db.nextStmtNum(), nil)
atomic.StoreInt64(&s.lastInstanceTime, time.Now().Unix())
return si
}
func (s *Stmt) InstanceTx(tx *Tx) *StmtInstance {
if s.err != nil {
return newStmtInstance(s, 0, s.err)
}
si := newStmtInstanceTx(tx, s, s.db.nextStmtNum(), nil)
atomic.StoreInt64(&s.lastInstanceTime, time.Now().Unix())
return si
}
func (s *Stmt) Err() error {
return s.err
}
func (ss *Stmt) Close() error {
ss.db.delStmt(ss.uid)
return errors.Catch(ss.sqlStmt.Close()).Set("query", ss.text).Msg("sql statement close failed")
}
func (s *Stmt) DB() *DB {
return s.db
}
func (s *Stmt) LastInstanceUnixTime() int64 {
return atomic.LoadInt64(&s.lastInstanceTime)
}
func (s *Stmt) UID() string {
return s.uid
}
func (s *Stmt) Text() string {
return s.text
}