forked from elgris/sqrl
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sqrl.go
174 lines (148 loc) · 5.19 KB
/
sqrl.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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
// package sqrl provides a fluent SQL generator.
//
// See https://github.com/elgris/sqrl for examples.
package sqrl
import (
"context"
"database/sql"
"fmt"
)
// Sqlizer is the interface that wraps the ToSql method.
//
// ToSql returns a SQL representation of the Sqlizer, along with a slice of args
// as passed to e.g. database/sql.Exec. It can also return an error.
type Sqlizer interface {
ToSql() (string, []interface{}, error)
}
// Execer is the interface that wraps the Exec method.
//
// Exec executes the given query as implemented by database/sql.Exec.
type Execer interface {
Exec(query string, args ...interface{}) (sql.Result, error)
}
// ExecerContext is the interface that wraps the Exec method.
//
// ExecContext executes the given query using given context as implemented by database/sql.ExecContext.
type ExecerContext interface {
ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error)
}
// Queryer is the interface that wraps the Query method.
//
// Query executes the given query as implemented by database/sql.Query.
type Queryer interface {
Query(query string, args ...interface{}) (*sql.Rows, error)
}
// QueryerContext is the interface that wraps the Query method.
//
// QueryerContext executes the given query using given context as implemented by database/sql.QueryContext.
type QueryerContext interface {
QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)
}
// QueryRower is the interface that wraps the QueryRow method.
//
// QueryRow executes the given query as implemented by database/sql.QueryRow.
type QueryRower interface {
QueryRow(query string, args ...interface{}) RowScanner
}
// QueryRowerContext is the interface that wraps the QueryRow method.
//
// QueryRowContext executes the given query using given context as implemented by database/sql.QueryRowContext.
type QueryRowerContext interface {
QueryRowContext(ctx context.Context, query string, args ...interface{}) RowScanner
}
// BaseRunner groups the Execer and Queryer interfaces.
type BaseRunner interface {
Execer
ExecerContext
Queryer
QueryerContext
}
// Runner groups the Execer, Queryer, and QueryRower interfaces.
type Runner interface {
Execer
ExecerContext
Queryer
QueryerContext
QueryRower
QueryRowerContext
}
// ErrRunnerNotSet is returned by methods that need a Runner if it isn't set.
var ErrRunnerNotSet = fmt.Errorf("cannot run; no Runner set (RunWith)")
// ErrRunnerNotQueryRunner is returned by QueryRow if the RunWith value doesn't implement QueryRower.
var ErrRunnerNotQueryRunner = fmt.Errorf("cannot QueryRow; Runner is not a QueryRower")
// ErrRunnerNotQueryRunnerContext is returned by QueryRowContext if the RunWith value doesn't implement QueryRowerContext.
var ErrRunnerNotQueryRunnerContext = fmt.Errorf("cannot QueryRow; Runner is not a QueryRowerContext")
// ExecWith Execs the SQL returned by s with db.
func ExecWith(db Execer, s Sqlizer) (res sql.Result, err error) {
query, args, err := s.ToSql()
if err != nil {
return
}
return db.Exec(query, args...)
}
// ExecWithContext Execs the SQL returned by s with db.
func ExecWithContext(ctx context.Context, db ExecerContext, s Sqlizer) (res sql.Result, err error) {
query, args, err := s.ToSql()
if err != nil {
return
}
return db.ExecContext(ctx, query, args...)
}
// QueryWith Querys the SQL returned by s with db.
func QueryWith(db Queryer, s Sqlizer) (rows *sql.Rows, err error) {
query, args, err := s.ToSql()
if err != nil {
return
}
return db.Query(query, args...)
}
// QueryWithContext Querys the SQL returned by s with db.
func QueryWithContext(ctx context.Context, db QueryerContext, s Sqlizer) (rows *sql.Rows, err error) {
query, args, err := s.ToSql()
if err != nil {
return
}
return db.QueryContext(ctx, query, args...)
}
// QueryRowWith QueryRows the SQL returned by s with db.
func QueryRowWith(db QueryRower, s Sqlizer) RowScanner {
query, args, err := s.ToSql()
return &Row{RowScanner: db.QueryRow(query, args...), err: err}
}
// QueryRowWithContext QueryRows the SQL returned by s with db.
func QueryRowWithContext(ctx context.Context, db QueryRowerContext, s Sqlizer) RowScanner {
query, args, err := s.ToSql()
return &Row{RowScanner: db.QueryRowContext(ctx, query, args...), err: err}
}
// DBRunner wraps sql.DB to implement Runner.
type dbRunner struct {
*sql.DB
}
func (r *dbRunner) QueryRow(query string, args ...interface{}) RowScanner {
return r.DB.QueryRow(query, args...)
}
func (r *dbRunner) QueryRowContext(ctx context.Context, query string, args ...interface{}) RowScanner {
return r.DB.QueryRowContext(ctx, query, args...)
}
// TxRunner wraps sql.Tx to implement Runner.
type txRunner struct {
*sql.Tx
}
func (r *txRunner) QueryRow(query string, args ...interface{}) RowScanner {
return r.Tx.QueryRow(query, args...)
}
func (r *txRunner) QueryRowContext(ctx context.Context, query string, args ...interface{}) RowScanner {
return r.Tx.QueryRowContext(ctx, query, args...)
}
// WrapRunner returns Runner for sql.DB and sql.Tx, or BaseRunner otherwise.
func wrapRunner(baseRunner BaseRunner) (runner BaseRunner) {
switch r := baseRunner.(type) {
case *sql.DB:
runner = &dbRunner{r}
case *sql.Tx:
runner = &txRunner{r}
default:
runner = r
}
return
}