|
5 | 5 | "database/sql" |
6 | 6 | "errors" |
7 | 7 | "fmt" |
| 8 | + "reflect" |
8 | 9 | "regexp" |
9 | 10 |
|
10 | 11 | "github.com/go-sql-driver/mysql" |
@@ -60,106 +61,134 @@ func IsDuplicate(err error) bool { |
60 | 61 | // WrappedMap wraps a *borp.DbMap such that its major functions wrap error |
61 | 62 | // results in ErrDatabaseOp instances before returning them to the caller. |
62 | 63 | type WrappedMap struct { |
63 | | - *borp.DbMap |
| 64 | + dbMap *borp.DbMap |
| 65 | +} |
| 66 | + |
| 67 | +func NewWrappedMap(dbMap *borp.DbMap) *WrappedMap { |
| 68 | + return &WrappedMap{dbMap: dbMap} |
| 69 | +} |
| 70 | + |
| 71 | +func (m *WrappedMap) SQLDb() *sql.DB { |
| 72 | + return m.dbMap.Db |
| 73 | +} |
| 74 | + |
| 75 | +func (m *WrappedMap) BorpDB() *borp.DbMap { |
| 76 | + return m.dbMap |
| 77 | +} |
| 78 | + |
| 79 | +func (m *WrappedMap) TableFor(t reflect.Type, checkPK bool) (*borp.TableMap, error) { |
| 80 | + return m.dbMap.TableFor(t, checkPK) |
64 | 81 | } |
65 | 82 |
|
66 | 83 | func (m *WrappedMap) Get(ctx context.Context, holder interface{}, keys ...interface{}) (interface{}, error) { |
67 | | - return WrappedExecutor{SqlExecutor: m.DbMap}.Get(ctx, holder, keys...) |
| 84 | + return WrappedExecutor{sqlExecutor: m.dbMap}.Get(ctx, holder, keys...) |
68 | 85 | } |
69 | 86 |
|
70 | 87 | func (m *WrappedMap) Insert(ctx context.Context, list ...interface{}) error { |
71 | | - return WrappedExecutor{SqlExecutor: m.DbMap}.Insert(ctx, list...) |
| 88 | + return WrappedExecutor{sqlExecutor: m.dbMap}.Insert(ctx, list...) |
72 | 89 | } |
73 | 90 |
|
74 | 91 | func (m *WrappedMap) Update(ctx context.Context, list ...interface{}) (int64, error) { |
75 | | - return WrappedExecutor{SqlExecutor: m.DbMap}.Update(ctx, list...) |
| 92 | + return WrappedExecutor{sqlExecutor: m.dbMap}.Update(ctx, list...) |
76 | 93 | } |
77 | 94 |
|
78 | 95 | func (m *WrappedMap) Delete(ctx context.Context, list ...interface{}) (int64, error) { |
79 | | - return WrappedExecutor{SqlExecutor: m.DbMap}.Delete(ctx, list...) |
| 96 | + return WrappedExecutor{sqlExecutor: m.dbMap}.Delete(ctx, list...) |
80 | 97 | } |
81 | 98 |
|
82 | 99 | func (m *WrappedMap) Select(ctx context.Context, holder interface{}, query string, args ...interface{}) ([]interface{}, error) { |
83 | | - return WrappedExecutor{SqlExecutor: m.DbMap}.Select(ctx, holder, query, args...) |
| 100 | + return WrappedExecutor{sqlExecutor: m.dbMap}.Select(ctx, holder, query, args...) |
84 | 101 | } |
85 | 102 |
|
86 | 103 | func (m *WrappedMap) SelectOne(ctx context.Context, holder interface{}, query string, args ...interface{}) error { |
87 | | - return WrappedExecutor{SqlExecutor: m.DbMap}.SelectOne(ctx, holder, query, args...) |
| 104 | + return WrappedExecutor{sqlExecutor: m.dbMap}.SelectOne(ctx, holder, query, args...) |
| 105 | +} |
| 106 | + |
| 107 | +func (m *WrappedMap) SelectNullInt(ctx context.Context, query string, args ...interface{}) (sql.NullInt64, error) { |
| 108 | + return WrappedExecutor{sqlExecutor: m.dbMap}.SelectNullInt(ctx, query, args...) |
88 | 109 | } |
89 | 110 |
|
90 | 111 | func (m *WrappedMap) QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) { |
91 | | - return WrappedExecutor{SqlExecutor: m.DbMap}.QueryContext(ctx, query, args...) |
| 112 | + return WrappedExecutor{sqlExecutor: m.dbMap}.QueryContext(ctx, query, args...) |
| 113 | +} |
| 114 | + |
| 115 | +func (m *WrappedMap) QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row { |
| 116 | + return WrappedExecutor{sqlExecutor: m.dbMap}.QueryRowContext(ctx, query, args...) |
| 117 | +} |
| 118 | + |
| 119 | +func (m *WrappedMap) SelectStr(ctx context.Context, query string, args ...interface{}) (string, error) { |
| 120 | + return WrappedExecutor{sqlExecutor: m.dbMap}.SelectStr(ctx, query, args...) |
92 | 121 | } |
93 | 122 |
|
94 | 123 | func (m *WrappedMap) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error) { |
95 | | - return WrappedExecutor{SqlExecutor: m.DbMap}.ExecContext(ctx, query, args...) |
| 124 | + return WrappedExecutor{sqlExecutor: m.dbMap}.ExecContext(ctx, query, args...) |
96 | 125 | } |
97 | 126 |
|
98 | 127 | func (m *WrappedMap) BeginTx(ctx context.Context) (Transaction, error) { |
99 | | - tx, err := m.DbMap.BeginTx(ctx) |
| 128 | + tx, err := m.dbMap.BeginTx(ctx) |
100 | 129 | if err != nil { |
101 | 130 | return tx, ErrDatabaseOp{ |
102 | 131 | Op: "begin transaction", |
103 | 132 | Err: err, |
104 | 133 | } |
105 | 134 | } |
106 | 135 | return WrappedTransaction{ |
107 | | - Transaction: tx, |
| 136 | + transaction: tx, |
108 | 137 | }, err |
109 | 138 | } |
110 | 139 |
|
111 | 140 | // WrappedTransaction wraps a *borp.Transaction such that its major functions |
112 | 141 | // wrap error results in ErrDatabaseOp instances before returning them to the |
113 | 142 | // caller. |
114 | 143 | type WrappedTransaction struct { |
115 | | - *borp.Transaction |
| 144 | + transaction *borp.Transaction |
116 | 145 | } |
117 | 146 |
|
118 | 147 | func (tx WrappedTransaction) Commit() error { |
119 | | - return tx.Transaction.Commit() |
| 148 | + return tx.transaction.Commit() |
120 | 149 | } |
121 | 150 |
|
122 | 151 | func (tx WrappedTransaction) Rollback() error { |
123 | | - return tx.Transaction.Rollback() |
| 152 | + return tx.transaction.Rollback() |
124 | 153 | } |
125 | 154 |
|
126 | 155 | func (tx WrappedTransaction) Get(ctx context.Context, holder interface{}, keys ...interface{}) (interface{}, error) { |
127 | | - return (WrappedExecutor{SqlExecutor: tx.Transaction}).Get(ctx, holder, keys...) |
| 156 | + return (WrappedExecutor{sqlExecutor: tx.transaction}).Get(ctx, holder, keys...) |
128 | 157 | } |
129 | 158 |
|
130 | 159 | func (tx WrappedTransaction) Insert(ctx context.Context, list ...interface{}) error { |
131 | | - return (WrappedExecutor{SqlExecutor: tx.Transaction}).Insert(ctx, list...) |
| 160 | + return (WrappedExecutor{sqlExecutor: tx.transaction}).Insert(ctx, list...) |
132 | 161 | } |
133 | 162 |
|
134 | 163 | func (tx WrappedTransaction) Update(ctx context.Context, list ...interface{}) (int64, error) { |
135 | | - return (WrappedExecutor{SqlExecutor: tx.Transaction}).Update(ctx, list...) |
| 164 | + return (WrappedExecutor{sqlExecutor: tx.transaction}).Update(ctx, list...) |
136 | 165 | } |
137 | 166 |
|
138 | 167 | func (tx WrappedTransaction) Delete(ctx context.Context, list ...interface{}) (int64, error) { |
139 | | - return (WrappedExecutor{SqlExecutor: tx.Transaction}).Delete(ctx, list...) |
| 168 | + return (WrappedExecutor{sqlExecutor: tx.transaction}).Delete(ctx, list...) |
140 | 169 | } |
141 | 170 |
|
142 | 171 | func (tx WrappedTransaction) Select(ctx context.Context, holder interface{}, query string, args ...interface{}) ([]interface{}, error) { |
143 | | - return (WrappedExecutor{SqlExecutor: tx.Transaction}).Select(ctx, holder, query, args...) |
| 172 | + return (WrappedExecutor{sqlExecutor: tx.transaction}).Select(ctx, holder, query, args...) |
144 | 173 | } |
145 | 174 |
|
146 | 175 | func (tx WrappedTransaction) SelectOne(ctx context.Context, holder interface{}, query string, args ...interface{}) error { |
147 | | - return (WrappedExecutor{SqlExecutor: tx.Transaction}).SelectOne(ctx, holder, query, args...) |
| 176 | + return (WrappedExecutor{sqlExecutor: tx.transaction}).SelectOne(ctx, holder, query, args...) |
148 | 177 | } |
149 | 178 |
|
150 | 179 | func (tx WrappedTransaction) QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) { |
151 | | - return (WrappedExecutor{SqlExecutor: tx.Transaction}).QueryContext(ctx, query, args...) |
| 180 | + return (WrappedExecutor{sqlExecutor: tx.transaction}).QueryContext(ctx, query, args...) |
152 | 181 | } |
153 | 182 |
|
154 | 183 | func (tx WrappedTransaction) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error) { |
155 | | - return (WrappedExecutor{SqlExecutor: tx.Transaction}).ExecContext(ctx, query, args...) |
| 184 | + return (WrappedExecutor{sqlExecutor: tx.transaction}).ExecContext(ctx, query, args...) |
156 | 185 | } |
157 | 186 |
|
158 | 187 | // WrappedExecutor wraps a borp.SqlExecutor such that its major functions |
159 | 188 | // wrap error results in ErrDatabaseOp instances before returning them to the |
160 | 189 | // caller. |
161 | 190 | type WrappedExecutor struct { |
162 | | - borp.SqlExecutor |
| 191 | + sqlExecutor borp.SqlExecutor |
163 | 192 | } |
164 | 193 |
|
165 | 194 | func errForOp(operation string, err error, list []interface{}) ErrDatabaseOp { |
@@ -196,55 +225,77 @@ func errForQuery(query, operation string, err error, list []interface{}) ErrData |
196 | 225 | } |
197 | 226 |
|
198 | 227 | func (we WrappedExecutor) Get(ctx context.Context, holder interface{}, keys ...interface{}) (interface{}, error) { |
199 | | - res, err := we.SqlExecutor.Get(ctx, holder, keys...) |
| 228 | + res, err := we.sqlExecutor.Get(ctx, holder, keys...) |
200 | 229 | if err != nil { |
201 | 230 | return res, errForOp("get", err, []interface{}{holder}) |
202 | 231 | } |
203 | 232 | return res, err |
204 | 233 | } |
205 | 234 |
|
206 | 235 | func (we WrappedExecutor) Insert(ctx context.Context, list ...interface{}) error { |
207 | | - err := we.SqlExecutor.Insert(ctx, list...) |
| 236 | + err := we.sqlExecutor.Insert(ctx, list...) |
208 | 237 | if err != nil { |
209 | 238 | return errForOp("insert", err, list) |
210 | 239 | } |
211 | 240 | return nil |
212 | 241 | } |
213 | 242 |
|
214 | 243 | func (we WrappedExecutor) Update(ctx context.Context, list ...interface{}) (int64, error) { |
215 | | - updatedRows, err := we.SqlExecutor.Update(ctx, list...) |
| 244 | + updatedRows, err := we.sqlExecutor.Update(ctx, list...) |
216 | 245 | if err != nil { |
217 | 246 | return updatedRows, errForOp("update", err, list) |
218 | 247 | } |
219 | 248 | return updatedRows, err |
220 | 249 | } |
221 | 250 |
|
222 | 251 | func (we WrappedExecutor) Delete(ctx context.Context, list ...interface{}) (int64, error) { |
223 | | - deletedRows, err := we.SqlExecutor.Delete(ctx, list...) |
| 252 | + deletedRows, err := we.sqlExecutor.Delete(ctx, list...) |
224 | 253 | if err != nil { |
225 | 254 | return deletedRows, errForOp("delete", err, list) |
226 | 255 | } |
227 | 256 | return deletedRows, err |
228 | 257 | } |
229 | 258 |
|
230 | 259 | func (we WrappedExecutor) Select(ctx context.Context, holder interface{}, query string, args ...interface{}) ([]interface{}, error) { |
231 | | - result, err := we.SqlExecutor.Select(ctx, holder, query, args...) |
| 260 | + result, err := we.sqlExecutor.Select(ctx, holder, query, args...) |
232 | 261 | if err != nil { |
233 | 262 | return result, errForQuery(query, "select", err, []interface{}{holder}) |
234 | 263 | } |
235 | 264 | return result, err |
236 | 265 | } |
237 | 266 |
|
238 | 267 | func (we WrappedExecutor) SelectOne(ctx context.Context, holder interface{}, query string, args ...interface{}) error { |
239 | | - err := we.SqlExecutor.SelectOne(ctx, holder, query, args...) |
| 268 | + err := we.sqlExecutor.SelectOne(ctx, holder, query, args...) |
240 | 269 | if err != nil { |
241 | 270 | return errForQuery(query, "select one", err, []interface{}{holder}) |
242 | 271 | } |
243 | 272 | return nil |
244 | 273 | } |
245 | 274 |
|
| 275 | +func (we WrappedExecutor) SelectNullInt(ctx context.Context, query string, args ...interface{}) (sql.NullInt64, error) { |
| 276 | + rows, err := we.sqlExecutor.SelectNullInt(ctx, query, args...) |
| 277 | + if err != nil { |
| 278 | + return sql.NullInt64{}, errForQuery(query, "select", err, nil) |
| 279 | + } |
| 280 | + return rows, nil |
| 281 | +} |
| 282 | + |
| 283 | +func (we WrappedExecutor) QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row { |
| 284 | + // Note: we can't do error wrapping here because the error is passed via the `*sql.Row` |
| 285 | + // object, and we can't produce a `*sql.Row` object with a custom error because it is unexported. |
| 286 | + return we.sqlExecutor.QueryRowContext(ctx, query, args...) |
| 287 | +} |
| 288 | + |
| 289 | +func (we WrappedExecutor) SelectStr(ctx context.Context, query string, args ...interface{}) (string, error) { |
| 290 | + str, err := we.sqlExecutor.SelectStr(ctx, query, args...) |
| 291 | + if err != nil { |
| 292 | + return "", errForQuery(query, "select", err, nil) |
| 293 | + } |
| 294 | + return str, nil |
| 295 | +} |
| 296 | + |
246 | 297 | func (we WrappedExecutor) QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) { |
247 | | - rows, err := we.SqlExecutor.QueryContext(ctx, query, args...) |
| 298 | + rows, err := we.sqlExecutor.QueryContext(ctx, query, args...) |
248 | 299 | if err != nil { |
249 | 300 | return nil, errForQuery(query, "select", err, nil) |
250 | 301 | } |
@@ -288,7 +339,7 @@ func tableFromQuery(query string) string { |
288 | 339 | } |
289 | 340 |
|
290 | 341 | func (we WrappedExecutor) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error) { |
291 | | - res, err := we.SqlExecutor.ExecContext(ctx, query, args...) |
| 342 | + res, err := we.sqlExecutor.ExecContext(ctx, query, args...) |
292 | 343 | if err != nil { |
293 | 344 | return res, errForQuery(query, "exec", err, args) |
294 | 345 | } |
|
0 commit comments