-
Notifications
You must be signed in to change notification settings - Fork 73
/
querier.go
153 lines (133 loc) · 4.57 KB
/
querier.go
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package reform
import (
"context"
"database/sql"
"fmt"
"time"
)
// Querier performs queries and commands.
type Querier struct {
ctx context.Context
dbtxCtx DBTXContext
tag string
Dialect
Logger Logger
}
func newQuerier(ctx context.Context, dbtxCtx DBTXContext, tag string, dialect Dialect, logger Logger) *Querier {
return &Querier{
ctx: ctx,
dbtxCtx: dbtxCtx,
tag: tag,
Dialect: dialect,
Logger: logger,
}
}
func (q *Querier) clone() *Querier {
return newQuerier(q.ctx, q.dbtxCtx, q.tag, q.Dialect, q.Logger)
}
func (q *Querier) logBefore(query string, args []interface{}) {
if q.Logger != nil {
q.Logger.Before(query, args)
}
}
func (q *Querier) logAfter(query string, args []interface{}, d time.Duration, err error) {
if q.Logger != nil {
q.Logger.After(query, args, d, err)
}
}
func (q *Querier) startQuery(command string) string {
if q.tag == "" {
return command
}
return command + " /* " + q.tag + " */"
}
// Tag returns Querier's tag. Default tag is empty.
func (q *Querier) Tag() string {
return q.tag
}
// WithTag returns a copy of Querier with set tag. Returned Querier is tied to the same DB or TX.
// See Tagging section in documentation for details.
func (q *Querier) WithTag(format string, args ...interface{}) *Querier {
newQ := q.clone()
if len(args) == 0 {
newQ.tag = format
} else {
newQ.tag = fmt.Sprintf(format, args...)
}
return newQ
}
// QualifiedView returns quoted qualified view name.
func (q *Querier) QualifiedView(view View) string {
v := q.QuoteIdentifier(view.Name())
if view.Schema() != "" {
v = q.QuoteIdentifier(view.Schema()) + "." + v
}
return v
}
// Context returns Querier's context. Default context is context.Background().
func (q *Querier) Context() context.Context {
return q.ctx
}
// WithContext returns a copy of Querier with set context. Returned Querier is tied to the same DB or TX.
// See Context section in documentation for details.
func (q *Querier) WithContext(ctx context.Context) *Querier {
newQ := q.clone()
newQ.ctx = ctx
return newQ
}
// QualifiedColumns returns a slice of quoted qualified column names for given view.
func (q *Querier) QualifiedColumns(view View) []string {
v := q.QualifiedView(view)
res := view.Columns()
for i := 0; i < len(res); i++ {
res[i] = v + "." + q.QuoteIdentifier(res[i])
}
return res
}
// Exec executes a query without returning any rows.
// The args are for any placeholder parameters in the query.
func (q *Querier) Exec(query string, args ...interface{}) (sql.Result, error) {
q.logBefore(query, args)
start := time.Now()
res, err := q.dbtxCtx.ExecContext(q.ctx, query, args...)
q.logAfter(query, args, time.Since(start), err)
return res, err
}
// ExecContext just calls q.WithContext(ctx).Exec(query, args...), and that form should be used instead.
// This method exists to satisfy various standard interfaces for advanced use-cases.
func (q *Querier) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error) {
return q.WithContext(ctx).Exec(query, args...)
}
// Query executes a query that returns rows, typically a SELECT.
// The args are for any placeholder parameters in the query.
func (q *Querier) Query(query string, args ...interface{}) (*sql.Rows, error) {
q.logBefore(query, args)
start := time.Now()
rows, err := q.dbtxCtx.QueryContext(q.ctx, query, args...)
q.logAfter(query, args, time.Since(start), err)
return rows, err
}
// QueryContext just calls q.WithContext(ctx).Query(query, args...), and that form should be used instead.
// This method exists to satisfy various standard interfaces for advanced use-cases.
func (q *Querier) QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) {
return q.WithContext(ctx).Query(query, args...)
}
// QueryRow executes a query that is expected to return at most one row.
// QueryRow always returns a non-nil value. Errors are deferred until Row's Scan method is called.
func (q *Querier) QueryRow(query string, args ...interface{}) *sql.Row {
q.logBefore(query, args)
start := time.Now()
row := q.dbtxCtx.QueryRowContext(q.ctx, query, args...)
q.logAfter(query, args, time.Since(start), nil)
return row
}
// QueryRowContext just calls q.WithContext(ctx).QueryRow(query, args...), and that form should be used instead.
// This method exists to satisfy various standard interfaces for advanced use-cases.
func (q *Querier) QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row {
return q.WithContext(ctx).QueryRow(query, args...)
}
// check interfaces
var (
_ DBTX = (*Querier)(nil)
_ DBTXContext = (*Querier)(nil)
)