Test Failed
Pull Request — master (#36)
by Frank
03:43 queued 02:03
created

sqlx.scanAll   F

Complexity

Conditions 21

Size

Total Lines 94
Code Lines 57

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 21
eloc 57
nop 3
dl 0
loc 94
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like sqlx.scanAll often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
package sqlx
2
3
import (
4
	"database/sql"
5
	"database/sql/driver"
6
	"errors"
7
	"fmt"
8
9
	"io/ioutil"
10
	"path/filepath"
11
	"reflect"
12
	"strings"
13
	"sync"
14
15
	"github.com/jmoiron/sqlx/reflectx"
16
)
17
18
// Although the NameMapper is convenient, in practice it should not
19
// be relied on except for application code.  If you are writing a library
20
// that uses sqlx, you should be aware that the name mappings you expect
21
// can be overridden by your user's application.
22
23
// NameMapper is used to map column names to struct field names.  By default,
24
// it uses strings.ToLower to lowercase struct field names.  It can be set
25
// to whatever you want, but it is encouraged to be set before sqlx is used
26
// as name-to-field mappings are cached after first use on a type.
27
var NameMapper = strings.ToLower
28
var origMapper = reflect.ValueOf(NameMapper)
29
30
// Rather than creating on init, this is created when necessary so that
31
// importers have time to customize the NameMapper.
32
var mpr *reflectx.Mapper
33
34
// mprMu protects mpr.
35
var mprMu sync.Mutex
36
37
// mapper returns a valid mapper using the configured NameMapper func.
38
func mapper() *reflectx.Mapper {
39
	mprMu.Lock()
40
	defer mprMu.Unlock()
41
42
	if mpr == nil {
43
		mpr = reflectx.NewMapperFunc("db", NameMapper)
44
	} else if origMapper != reflect.ValueOf(NameMapper) {
45
		// if NameMapper has changed, create a new mapper
46
		mpr = reflectx.NewMapperFunc("db", NameMapper)
47
		origMapper = reflect.ValueOf(NameMapper)
48
	}
49
	return mpr
50
}
51
52
// isScannable takes the reflect.Type and the actual dest value and returns
53
// whether or not it's Scannable.  Something is scannable if:
54
//   * it is not a struct
55
//   * it implements sql.Scanner
56
//   * it has no exported fields
57
func isScannable(t reflect.Type) bool {
58
	if reflect.PtrTo(t).Implements(_scannerInterface) {
59
		return true
60
	}
61
	if t.Kind() != reflect.Struct {
62
		return true
63
	}
64
65
	// it's not important that we use the right mapper for this particular object,
66
	// we're only concerned on how many exported fields this struct has
67
	return len(mapper().TypeMap(t).Index) == 0
68
}
69
70
// ColScanner is an interface used by MapScan and SliceScan
71
type ColScanner interface {
72
	Columns() ([]string, error)
73
	Scan(dest ...interface{}) error
74
	Err() error
75
}
76
77
// Queryer is an interface used by Get and Select
78
type Queryer interface {
79
	Query(query string, args ...interface{}) (*sql.Rows, error)
80
	Queryx(query string, args ...interface{}) (*Rows, error)
81
	QueryRowx(query string, args ...interface{}) *Row
82
}
83
84
// Execer is an interface used by MustExec and LoadFile
85
type Execer interface {
86
	Exec(query string, args ...interface{}) (sql.Result, error)
87
}
88
89
// Binder is an interface for something which can bind queries (Tx, DB)
90
type binder interface {
91
	DriverName() string
92
	Rebind(string) string
93
	BindNamed(string, interface{}) (string, []interface{}, error)
94
}
95
96
// Ext is a union interface which can bind, query, and exec, used by
97
// NamedQuery and NamedExec.
98
type Ext interface {
99
	binder
100
	Queryer
101
	Execer
102
}
103
104
// Preparer is an interface used by Preparex.
105
type Preparer interface {
106
	Prepare(query string) (*sql.Stmt, error)
107
}
108
109
// determine if any of our extensions are unsafe
110
func isUnsafe(i interface{}) bool {
111
	switch v := i.(type) {
112
	case Row:
113
		return v.unsafe
114
	case *Row:
115
		return v.unsafe
116
	case Rows:
117
		return v.unsafe
118
	case *Rows:
119
		return v.unsafe
120
	case NamedStmt:
121
		return v.Stmt.unsafe
122
	case *NamedStmt:
123
		return v.Stmt.unsafe
124
	case Stmt:
125
		return v.unsafe
126
	case *Stmt:
127
		return v.unsafe
128
	case qStmt:
129
		return v.unsafe
130
	case *qStmt:
131
		return v.unsafe
132
	case DB:
133
		return v.unsafe
134
	case *DB:
135
		return v.unsafe
136
	case Tx:
137
		return v.unsafe
138
	case *Tx:
139
		return v.unsafe
140
	case sql.Rows, *sql.Rows:
141
		return false
142
	default:
143
		return false
144
	}
145
}
146
147
func mapperFor(i interface{}) *reflectx.Mapper {
148
	switch i := i.(type) {
149
	case DB:
150
		return i.Mapper
151
	case *DB:
152
		return i.Mapper
153
	case Tx:
154
		return i.Mapper
155
	case *Tx:
156
		return i.Mapper
157
	default:
158
		return mapper()
159
	}
160
}
161
162
var _scannerInterface = reflect.TypeOf((*sql.Scanner)(nil)).Elem()
163
var _valuerInterface = reflect.TypeOf((*driver.Valuer)(nil)).Elem()
164
165
// Row is a reimplementation of sql.Row in order to gain access to the underlying
166
// sql.Rows.Columns() data, necessary for StructScan.
167
type Row struct {
168
	err    error
169
	unsafe bool
170
	rows   *sql.Rows
171
	Mapper *reflectx.Mapper
172
}
173
174
// Scan is a fixed implementation of sql.Row.Scan, which does not discard the
175
// underlying error from the internal rows object if it exists.
176
func (r *Row) Scan(dest ...interface{}) error {
177
	if r.err != nil {
178
		return r.err
179
	}
180
181
	// TODO(bradfitz): for now we need to defensively clone all
182
	// []byte that the driver returned (not permitting
183
	// *RawBytes in Rows.Scan), since we're about to close
184
	// the Rows in our defer, when we return from this function.
185
	// the contract with the driver.Next(...) interface is that it
186
	// can return slices into read-only temporary memory that's
187
	// only valid until the next Scan/Close.  But the TODO is that
188
	// for a lot of drivers, this copy will be unnecessary.  We
189
	// should provide an optional interface for drivers to
190
	// implement to say, "don't worry, the []bytes that I return
191
	// from Next will not be modified again." (for instance, if
192
	// they were obtained from the network anyway) But for now we
193
	// don't care.
194
	defer r.rows.Close()
195
	for _, dp := range dest {
196
		if _, ok := dp.(*sql.RawBytes); ok {
197
			return errors.New("sql: RawBytes isn't allowed on Row.Scan")
198
		}
199
	}
200
201
	if !r.rows.Next() {
202
		if err := r.rows.Err(); err != nil {
203
			return err
204
		}
205
		return sql.ErrNoRows
206
	}
207
	err := r.rows.Scan(dest...)
208
	if err != nil {
209
		return err
210
	}
211
	// Make sure the query can be processed to completion with no errors.
212
	if err := r.rows.Close(); err != nil {
213
		return err
214
	}
215
	return nil
216
}
217
218
// Columns returns the underlying sql.Rows.Columns(), or the deferred error usually
219
// returned by Row.Scan()
220
func (r *Row) Columns() ([]string, error) {
221
	if r.err != nil {
222
		return []string{}, r.err
223
	}
224
	return r.rows.Columns()
225
}
226
227
// ColumnTypes returns the underlying sql.Rows.ColumnTypes(), or the deferred error
228
func (r *Row) ColumnTypes() ([]*sql.ColumnType, error) {
229
	if r.err != nil {
230
		return []*sql.ColumnType{}, r.err
231
	}
232
	return r.rows.ColumnTypes()
233
}
234
235
// Err returns the error encountered while scanning.
236
func (r *Row) Err() error {
237
	return r.err
238
}
239
240
// DB is a wrapper around sql.DB which keeps track of the driverName upon Open,
241
// used mostly to automatically bind named queries using the right bindvars.
242
type DB struct {
243
	*sql.DB
244
	driverName string
245
	unsafe     bool
246
	Mapper     *reflectx.Mapper
247
}
248
249
// NewDb returns a new sqlx DB wrapper for a pre-existing *sql.DB.  The
250
// driverName of the original database is required for named query support.
251
func NewDb(db *sql.DB, driverName string) *DB {
252
	return &DB{DB: db, driverName: driverName, Mapper: mapper()}
253
}
254
255
// DriverName returns the driverName passed to the Open function for this DB.
256
func (db *DB) DriverName() string {
257
	return db.driverName
258
}
259
260
// Open is the same as sql.Open, but returns an *sqlx.DB instead.
261
func Open(driverName, dataSourceName string) (*DB, error) {
262
	db, err := sql.Open(driverName, dataSourceName)
263
	if err != nil {
264
		return nil, err
265
	}
266
	return &DB{DB: db, driverName: driverName, Mapper: mapper()}, err
267
}
268
269
// MustOpen is the same as sql.Open, but returns an *sqlx.DB instead and panics on error.
270
func MustOpen(driverName, dataSourceName string) *DB {
271
	db, err := Open(driverName, dataSourceName)
272
	if err != nil {
273
		panic(err)
274
	}
275
	return db
276
}
277
278
// MapperFunc sets a new mapper for this db using the default sqlx struct tag
279
// and the provided mapper function.
280
func (db *DB) MapperFunc(mf func(string) string) {
281
	db.Mapper = reflectx.NewMapperFunc("db", mf)
282
}
283
284
// Rebind transforms a query from QUESTION to the DB driver's bindvar type.
285
func (db *DB) Rebind(query string) string {
286
	return Rebind(BindType(db.driverName), query)
287
}
288
289
// Unsafe returns a version of DB which will silently succeed to scan when
290
// columns in the SQL result have no fields in the destination struct.
291
// sqlx.Stmt and sqlx.Tx which are created from this DB will inherit its
292
// safety behavior.
293
func (db *DB) Unsafe() *DB {
294
	return &DB{DB: db.DB, driverName: db.driverName, unsafe: true, Mapper: db.Mapper}
295
}
296
297
// BindNamed binds a query using the DB driver's bindvar type.
298
func (db *DB) BindNamed(query string, arg interface{}) (string, []interface{}, error) {
299
	return bindNamedMapper(BindType(db.driverName), query, arg, db.Mapper)
300
}
301
302
// NamedQuery using this DB.
303
// Any named placeholder parameters are replaced with fields from arg.
304
func (db *DB) NamedQuery(query string, arg interface{}) (*Rows, error) {
305
	return NamedQuery(db, query, arg)
306
}
307
308
// NamedExec using this DB.
309
// Any named placeholder parameters are replaced with fields from arg.
310
func (db *DB) NamedExec(query string, arg interface{}) (sql.Result, error) {
311
	return NamedExec(db, query, arg)
312
}
313
314
// Select using this DB.
315
// Any placeholder parameters are replaced with supplied args.
316
func (db *DB) Select(dest interface{}, query string, args ...interface{}) error {
317
	return Select(db, dest, query, args...)
318
}
319
320
// Get using this DB.
321
// Any placeholder parameters are replaced with supplied args.
322
// An error is returned if the result set is empty.
323
func (db *DB) Get(dest interface{}, query string, args ...interface{}) error {
324
	return Get(db, dest, query, args...)
325
}
326
327
// MustBegin starts a transaction, and panics on error.  Returns an *sqlx.Tx instead
328
// of an *sql.Tx.
329
func (db *DB) MustBegin() *Tx {
330
	tx, err := db.Beginx()
331
	if err != nil {
332
		panic(err)
333
	}
334
	return tx
335
}
336
337
// Beginx begins a transaction and returns an *sqlx.Tx instead of an *sql.Tx.
338
func (db *DB) Beginx() (*Tx, error) {
339
	tx, err := db.DB.Begin()
340
	if err != nil {
341
		return nil, err
342
	}
343
	return &Tx{Tx: tx, driverName: db.driverName, unsafe: db.unsafe, Mapper: db.Mapper}, err
344
}
345
346
// Queryx queries the database and returns an *sqlx.Rows.
347
// Any placeholder parameters are replaced with supplied args.
348
func (db *DB) Queryx(query string, args ...interface{}) (*Rows, error) {
349
	r, err := db.DB.Query(query, args...)
350
	if err != nil {
351
		return nil, err
352
	}
353
	return &Rows{Rows: r, unsafe: db.unsafe, Mapper: db.Mapper}, err
354
}
355
356
// QueryRowx queries the database and returns an *sqlx.Row.
357
// Any placeholder parameters are replaced with supplied args.
358
func (db *DB) QueryRowx(query string, args ...interface{}) *Row {
359
	rows, err := db.DB.Query(query, args...)
360
	return &Row{rows: rows, err: err, unsafe: db.unsafe, Mapper: db.Mapper}
361
}
362
363
// MustExec (panic) runs MustExec using this database.
364
// Any placeholder parameters are replaced with supplied args.
365
func (db *DB) MustExec(query string, args ...interface{}) sql.Result {
366
	return MustExec(db, query, args...)
367
}
368
369
// Preparex returns an sqlx.Stmt instead of a sql.Stmt
370
func (db *DB) Preparex(query string) (*Stmt, error) {
371
	return Preparex(db, query)
372
}
373
374
// PrepareNamed returns an sqlx.NamedStmt
375
func (db *DB) PrepareNamed(query string) (*NamedStmt, error) {
376
	return prepareNamed(db, query)
377
}
378
379
// Conn is a wrapper around sql.Conn with extra functionality
380
type Conn struct {
381
	*sql.Conn
382
	driverName string
383
	unsafe     bool
384
	Mapper     *reflectx.Mapper
385
}
386
387
// Tx is an sqlx wrapper around sql.Tx with extra functionality
388
type Tx struct {
389
	*sql.Tx
390
	driverName string
391
	unsafe     bool
392
	Mapper     *reflectx.Mapper
393
}
394
395
// DriverName returns the driverName used by the DB which began this transaction.
396
func (tx *Tx) DriverName() string {
397
	return tx.driverName
398
}
399
400
// Rebind a query within a transaction's bindvar type.
401
func (tx *Tx) Rebind(query string) string {
402
	return Rebind(BindType(tx.driverName), query)
403
}
404
405
// Unsafe returns a version of Tx which will silently succeed to scan when
406
// columns in the SQL result have no fields in the destination struct.
407
func (tx *Tx) Unsafe() *Tx {
408
	return &Tx{Tx: tx.Tx, driverName: tx.driverName, unsafe: true, Mapper: tx.Mapper}
409
}
410
411
// BindNamed binds a query within a transaction's bindvar type.
412
func (tx *Tx) BindNamed(query string, arg interface{}) (string, []interface{}, error) {
413
	return bindNamedMapper(BindType(tx.driverName), query, arg, tx.Mapper)
414
}
415
416
// NamedQuery within a transaction.
417
// Any named placeholder parameters are replaced with fields from arg.
418
func (tx *Tx) NamedQuery(query string, arg interface{}) (*Rows, error) {
419
	return NamedQuery(tx, query, arg)
420
}
421
422
// NamedExec a named query within a transaction.
423
// Any named placeholder parameters are replaced with fields from arg.
424
func (tx *Tx) NamedExec(query string, arg interface{}) (sql.Result, error) {
425
	return NamedExec(tx, query, arg)
426
}
427
428
// Select within a transaction.
429
// Any placeholder parameters are replaced with supplied args.
430
func (tx *Tx) Select(dest interface{}, query string, args ...interface{}) error {
431
	return Select(tx, dest, query, args...)
432
}
433
434
// Queryx within a transaction.
435
// Any placeholder parameters are replaced with supplied args.
436
func (tx *Tx) Queryx(query string, args ...interface{}) (*Rows, error) {
437
	r, err := tx.Tx.Query(query, args...)
438
	if err != nil {
439
		return nil, err
440
	}
441
	return &Rows{Rows: r, unsafe: tx.unsafe, Mapper: tx.Mapper}, err
442
}
443
444
// QueryRowx within a transaction.
445
// Any placeholder parameters are replaced with supplied args.
446
func (tx *Tx) QueryRowx(query string, args ...interface{}) *Row {
447
	rows, err := tx.Tx.Query(query, args...)
448
	return &Row{rows: rows, err: err, unsafe: tx.unsafe, Mapper: tx.Mapper}
449
}
450
451
// Get within a transaction.
452
// Any placeholder parameters are replaced with supplied args.
453
// An error is returned if the result set is empty.
454
func (tx *Tx) Get(dest interface{}, query string, args ...interface{}) error {
455
	return Get(tx, dest, query, args...)
456
}
457
458
// MustExec runs MustExec within a transaction.
459
// Any placeholder parameters are replaced with supplied args.
460
func (tx *Tx) MustExec(query string, args ...interface{}) sql.Result {
461
	return MustExec(tx, query, args...)
462
}
463
464
// Preparex  a statement within a transaction.
465
func (tx *Tx) Preparex(query string) (*Stmt, error) {
466
	return Preparex(tx, query)
467
}
468
469
// Stmtx returns a version of the prepared statement which runs within a transaction.  Provided
470
// stmt can be either *sql.Stmt or *sqlx.Stmt.
471
func (tx *Tx) Stmtx(stmt interface{}) *Stmt {
472
	var s *sql.Stmt
473
	switch v := stmt.(type) {
474
	case Stmt:
475
		s = v.Stmt
476
	case *Stmt:
477
		s = v.Stmt
478
	case *sql.Stmt:
479
		s = v
480
	default:
481
		panic(fmt.Sprintf("non-statement type %v passed to Stmtx", reflect.ValueOf(stmt).Type()))
482
	}
483
	return &Stmt{Stmt: tx.Stmt(s), Mapper: tx.Mapper}
484
}
485
486
// NamedStmt returns a version of the prepared statement which runs within a transaction.
487
func (tx *Tx) NamedStmt(stmt *NamedStmt) *NamedStmt {
488
	return &NamedStmt{
489
		QueryString: stmt.QueryString,
490
		Params:      stmt.Params,
491
		Stmt:        tx.Stmtx(stmt.Stmt),
492
	}
493
}
494
495
// PrepareNamed returns an sqlx.NamedStmt
496
func (tx *Tx) PrepareNamed(query string) (*NamedStmt, error) {
497
	return prepareNamed(tx, query)
498
}
499
500
// Stmt is an sqlx wrapper around sql.Stmt with extra functionality
501
type Stmt struct {
502
	*sql.Stmt
503
	unsafe bool
504
	Mapper *reflectx.Mapper
505
}
506
507
// Unsafe returns a version of Stmt which will silently succeed to scan when
508
// columns in the SQL result have no fields in the destination struct.
509
func (s *Stmt) Unsafe() *Stmt {
510
	return &Stmt{Stmt: s.Stmt, unsafe: true, Mapper: s.Mapper}
511
}
512
513
// Select using the prepared statement.
514
// Any placeholder parameters are replaced with supplied args.
515
func (s *Stmt) Select(dest interface{}, args ...interface{}) error {
516
	return Select(&qStmt{s}, dest, "", args...)
517
}
518
519
// Get using the prepared statement.
520
// Any placeholder parameters are replaced with supplied args.
521
// An error is returned if the result set is empty.
522
func (s *Stmt) Get(dest interface{}, args ...interface{}) error {
523
	return Get(&qStmt{s}, dest, "", args...)
524
}
525
526
// MustExec (panic) using this statement.  Note that the query portion of the error
527
// output will be blank, as Stmt does not expose its query.
528
// Any placeholder parameters are replaced with supplied args.
529
func (s *Stmt) MustExec(args ...interface{}) sql.Result {
530
	return MustExec(&qStmt{s}, "", args...)
531
}
532
533
// QueryRowx using this statement.
534
// Any placeholder parameters are replaced with supplied args.
535
func (s *Stmt) QueryRowx(args ...interface{}) *Row {
536
	qs := &qStmt{s}
537
	return qs.QueryRowx("", args...)
538
}
539
540
// Queryx using this statement.
541
// Any placeholder parameters are replaced with supplied args.
542
func (s *Stmt) Queryx(args ...interface{}) (*Rows, error) {
543
	qs := &qStmt{s}
544
	return qs.Queryx("", args...)
545
}
546
547
// qStmt is an unexposed wrapper which lets you use a Stmt as a Queryer & Execer by
548
// implementing those interfaces and ignoring the `query` argument.
549
type qStmt struct{ *Stmt }
550
551
func (q *qStmt) Query(query string, args ...interface{}) (*sql.Rows, error) {
552
	return q.Stmt.Query(args...)
553
}
554
555
func (q *qStmt) Queryx(query string, args ...interface{}) (*Rows, error) {
556
	r, err := q.Stmt.Query(args...)
557
	if err != nil {
558
		return nil, err
559
	}
560
	return &Rows{Rows: r, unsafe: q.Stmt.unsafe, Mapper: q.Stmt.Mapper}, err
561
}
562
563
func (q *qStmt) QueryRowx(query string, args ...interface{}) *Row {
564
	rows, err := q.Stmt.Query(args...)
565
	return &Row{rows: rows, err: err, unsafe: q.Stmt.unsafe, Mapper: q.Stmt.Mapper}
566
}
567
568
func (q *qStmt) Exec(query string, args ...interface{}) (sql.Result, error) {
569
	return q.Stmt.Exec(args...)
570
}
571
572
// Rows is a wrapper around sql.Rows which caches costly reflect operations
573
// during a looped StructScan
574
type Rows struct {
575
	*sql.Rows
576
	unsafe bool
577
	Mapper *reflectx.Mapper
578
	// these fields cache memory use for a rows during iteration w/ structScan
579
	started bool
580
	fields  [][]int
581
	values  []interface{}
582
}
583
584
// SliceScan using this Rows.
585
func (r *Rows) SliceScan() ([]interface{}, error) {
586
	return SliceScan(r)
587
}
588
589
// MapScan using this Rows.
590
func (r *Rows) MapScan(dest map[string]interface{}) error {
591
	return MapScan(r, dest)
592
}
593
594
// StructScan is like sql.Rows.Scan, but scans a single Row into a single Struct.
595
// Use this and iterate over Rows manually when the memory load of Select() might be
596
// prohibitive.  *Rows.StructScan caches the reflect work of matching up column
597
// positions to fields to avoid that overhead per scan, which means it is not safe
598
// to run StructScan on the same Rows instance with different struct types.
599
func (r *Rows) StructScan(dest interface{}) error {
600
	v := reflect.ValueOf(dest)
601
602
	if v.Kind() != reflect.Ptr {
603
		return errors.New("must pass a pointer, not a value, to StructScan destination")
604
	}
605
606
	v = v.Elem()
607
608
	if !r.started {
609
		columns, err := r.Columns()
610
		if err != nil {
611
			return err
612
		}
613
		m := r.Mapper
614
615
		r.fields = m.TraversalsByName(v.Type(), columns)
616
		// if we are not unsafe and are missing fields, return an error
617
		if f, err := missingFields(r.fields); err != nil && !r.unsafe {
618
			return fmt.Errorf("missing destination name %s in %T", columns[f], dest)
619
		}
620
		r.values = make([]interface{}, len(columns))
621
		r.started = true
622
	}
623
624
	err := fieldsByTraversal(v, r.fields, r.values, true)
625
	if err != nil {
626
		return err
627
	}
628
	// scan into the struct field pointers and append to our results
629
	err = r.Scan(r.values...)
630
	if err != nil {
631
		return err
632
	}
633
	return r.Err()
634
}
635
636
// Connect to a database and verify with a ping.
637
func Connect(driverName, dataSourceName string) (*DB, error) {
638
	db, err := Open(driverName, dataSourceName)
639
	if err != nil {
640
		return nil, err
641
	}
642
	err = db.Ping()
643
	if err != nil {
644
		db.Close()
645
		return nil, err
646
	}
647
	return db, nil
648
}
649
650
// MustConnect connects to a database and panics on error.
651
func MustConnect(driverName, dataSourceName string) *DB {
652
	db, err := Connect(driverName, dataSourceName)
653
	if err != nil {
654
		panic(err)
655
	}
656
	return db
657
}
658
659
// Preparex prepares a statement.
660
func Preparex(p Preparer, query string) (*Stmt, error) {
661
	s, err := p.Prepare(query)
662
	if err != nil {
663
		return nil, err
664
	}
665
	return &Stmt{Stmt: s, unsafe: isUnsafe(p), Mapper: mapperFor(p)}, err
666
}
667
668
// Select executes a query using the provided Queryer, and StructScans each row
669
// into dest, which must be a slice.  If the slice elements are scannable, then
670
// the result set must have only one column.  Otherwise, StructScan is used.
671
// The *sql.Rows are closed automatically.
672
// Any placeholder parameters are replaced with supplied args.
673
func Select(q Queryer, dest interface{}, query string, args ...interface{}) error {
674
	rows, err := q.Queryx(query, args...)
675
	if err != nil {
676
		return err
677
	}
678
	// if something happens here, we want to make sure the rows are Closed
679
	defer rows.Close()
680
	return scanAll(rows, dest, false)
681
}
682
683
// Get does a QueryRow using the provided Queryer, and scans the resulting row
684
// to dest.  If dest is scannable, the result must only have one column.  Otherwise,
685
// StructScan is used.  Get will return sql.ErrNoRows like row.Scan would.
686
// Any placeholder parameters are replaced with supplied args.
687
// An error is returned if the result set is empty.
688
func Get(q Queryer, dest interface{}, query string, args ...interface{}) error {
689
	r := q.QueryRowx(query, args...)
690
	return r.scanAny(dest, false)
691
}
692
693
// LoadFile exec's every statement in a file (as a single call to Exec).
694
// LoadFile may return a nil *sql.Result if errors are encountered locating or
695
// reading the file at path.  LoadFile reads the entire file into memory, so it
696
// is not suitable for loading large data dumps, but can be useful for initializing
697
// schemas or loading indexes.
698
//
699
// FIXME: this does not really work with multi-statement files for mattn/go-sqlite3
700
// or the go-mysql-driver/mysql drivers;  pq seems to be an exception here.  Detecting
701
// this by requiring something with DriverName() and then attempting to split the
702
// queries will be difficult to get right, and its current driver-specific behavior
703
// is deemed at least not complex in its incorrectness.
704
func LoadFile(e Execer, path string) (*sql.Result, error) {
705
	realpath, err := filepath.Abs(path)
706
	if err != nil {
707
		return nil, err
708
	}
709
	contents, err := ioutil.ReadFile(realpath)
710
	if err != nil {
711
		return nil, err
712
	}
713
	res, err := e.Exec(string(contents))
714
	return &res, err
715
}
716
717
// MustExec execs the query using e and panics if there was an error.
718
// Any placeholder parameters are replaced with supplied args.
719
func MustExec(e Execer, query string, args ...interface{}) sql.Result {
720
	res, err := e.Exec(query, args...)
721
	if err != nil {
722
		panic(err)
723
	}
724
	return res
725
}
726
727
// SliceScan using this Rows.
728
func (r *Row) SliceScan() ([]interface{}, error) {
729
	return SliceScan(r)
730
}
731
732
// MapScan using this Rows.
733
func (r *Row) MapScan(dest map[string]interface{}) error {
734
	return MapScan(r, dest)
735
}
736
737
func (r *Row) scanAny(dest interface{}, structOnly bool) error {
738
	if r.err != nil {
739
		return r.err
740
	}
741
	if r.rows == nil {
742
		r.err = sql.ErrNoRows
743
		return r.err
744
	}
745
	defer r.rows.Close()
746
747
	v := reflect.ValueOf(dest)
748
	if v.Kind() != reflect.Ptr {
749
		return errors.New("must pass a pointer, not a value, to StructScan destination")
750
	}
751
	if v.IsNil() {
752
		return errors.New("nil pointer passed to StructScan destination")
753
	}
754
755
	base := reflectx.Deref(v.Type())
756
	scannable := isScannable(base)
757
758
	if structOnly && scannable {
759
		return structOnlyError(base)
760
	}
761
762
	columns, err := r.Columns()
763
	if err != nil {
764
		return err
765
	}
766
767
	if scannable && len(columns) > 1 {
768
		return fmt.Errorf("scannable dest type %s with >1 columns (%d) in result", base.Kind(), len(columns))
769
	}
770
771
	if scannable {
772
		return r.Scan(dest)
773
	}
774
775
	m := r.Mapper
776
777
	fields := m.TraversalsByName(v.Type(), columns)
778
	// if we are not unsafe and are missing fields, return an error
779
	if f, err := missingFields(fields); err != nil && !r.unsafe {
780
		return fmt.Errorf("missing destination name %s in %T", columns[f], dest)
781
	}
782
	values := make([]interface{}, len(columns))
783
784
	err = fieldsByTraversal(v, fields, values, true)
785
	if err != nil {
786
		return err
787
	}
788
	// scan into the struct field pointers and append to our results
789
	return r.Scan(values...)
790
}
791
792
// StructScan a single Row into dest.
793
func (r *Row) StructScan(dest interface{}) error {
794
	return r.scanAny(dest, true)
795
}
796
797
// SliceScan a row, returning a []interface{} with values similar to MapScan.
798
// This function is primarily intended for use where the number of columns
799
// is not known.  Because you can pass an []interface{} directly to Scan,
800
// it's recommended that you do that as it will not have to allocate new
801
// slices per row.
802
func SliceScan(r ColScanner) ([]interface{}, error) {
803
	// ignore r.started, since we needn't use reflect for anything.
804
	columns, err := r.Columns()
805
	if err != nil {
806
		return []interface{}{}, err
807
	}
808
809
	values := make([]interface{}, len(columns))
810
	for i := range values {
811
		values[i] = new(interface{})
812
	}
813
814
	err = r.Scan(values...)
815
816
	if err != nil {
817
		return values, err
818
	}
819
820
	for i := range columns {
821
		values[i] = *(values[i].(*interface{}))
822
	}
823
824
	return values, r.Err()
825
}
826
827
// MapScan scans a single Row into the dest map[string]interface{}.
828
// Use this to get results for SQL that might not be under your control
829
// (for instance, if you're building an interface for an SQL server that
830
// executes SQL from input).  Please do not use this as a primary interface!
831
// This will modify the map sent to it in place, so reuse the same map with
832
// care.  Columns which occur more than once in the result will overwrite
833
// each other!
834
func MapScan(r ColScanner, dest map[string]interface{}) error {
835
	// ignore r.started, since we needn't use reflect for anything.
836
	columns, err := r.Columns()
837
	if err != nil {
838
		return err
839
	}
840
841
	values := make([]interface{}, len(columns))
842
	for i := range values {
843
		values[i] = new(interface{})
844
	}
845
846
	err = r.Scan(values...)
847
	if err != nil {
848
		return err
849
	}
850
851
	for i, column := range columns {
852
		dest[column] = *(values[i].(*interface{}))
853
	}
854
855
	return r.Err()
856
}
857
858
type rowsi interface {
859
	Close() error
860
	Columns() ([]string, error)
861
	Err() error
862
	Next() bool
863
	Scan(...interface{}) error
864
}
865
866
// structOnlyError returns an error appropriate for type when a non-scannable
867
// struct is expected but something else is given
868
func structOnlyError(t reflect.Type) error {
869
	isStruct := t.Kind() == reflect.Struct
870
	isScanner := reflect.PtrTo(t).Implements(_scannerInterface)
871
	if !isStruct {
872
		return fmt.Errorf("expected %s but got %s", reflect.Struct, t.Kind())
873
	}
874
	if isScanner {
875
		return fmt.Errorf("structscan expects a struct dest but the provided struct type %s implements scanner", t.Name())
876
	}
877
	return fmt.Errorf("expected a struct, but struct %s has no exported fields", t.Name())
878
}
879
880
// scanAll scans all rows into a destination, which must be a slice of any
881
// type.  If the destination slice type is a Struct, then StructScan will be
882
// used on each row.  If the destination is some other kind of base type, then
883
// each row must only have one column which can scan into that type.  This
884
// allows you to do something like:
885
//
886
//    rows, _ := db.Query("select id from people;")
887
//    var ids []int
888
//    scanAll(rows, &ids, false)
889
//
890
// and ids will be a list of the id results.  I realize that this is a desirable
891
// interface to expose to users, but for now it will only be exposed via changes
892
// to `Get` and `Select`.  The reason that this has been implemented like this is
893
// this is the only way to not duplicate reflect work in the new API while
894
// maintaining backwards compatibility.
895
func scanAll(rows rowsi, dest interface{}, structOnly bool) error {
896
	var v, vp reflect.Value
897
898
	value := reflect.ValueOf(dest)
899
900
	// json.Unmarshal returns errors for these
901
	if value.Kind() != reflect.Ptr {
902
		return errors.New("must pass a pointer, not a value, to StructScan destination")
903
	}
904
	if value.IsNil() {
905
		return errors.New("nil pointer passed to StructScan destination")
906
	}
907
	direct := reflect.Indirect(value)
908
909
	slice, err := baseType(value.Type(), reflect.Slice)
910
	if err != nil {
911
		return err
912
	}
913
914
	isPtr := slice.Elem().Kind() == reflect.Ptr
915
	base := reflectx.Deref(slice.Elem())
916
	scannable := isScannable(base)
917
918
	if structOnly && scannable {
919
		return structOnlyError(base)
920
	}
921
922
	columns, err := rows.Columns()
923
	if err != nil {
924
		return err
925
	}
926
927
	// if it's a base type make sure it only has 1 column;  if not return an error
928
	if scannable && len(columns) > 1 {
929
		return fmt.Errorf("non-struct dest type %s with >1 columns (%d)", base.Kind(), len(columns))
930
	}
931
932
	if !scannable {
933
		var values []interface{}
934
		var m *reflectx.Mapper
935
936
		switch rows.(type) {
937
		case *Rows:
938
			m = rows.(*Rows).Mapper
939
		default:
940
			m = mapper()
941
		}
942
943
		fields := m.TraversalsByName(base, columns)
944
		// if we are not unsafe and are missing fields, return an error
945
		if f, err := missingFields(fields); err != nil && !isUnsafe(rows) {
946
			return fmt.Errorf("missing destination name %s in %T", columns[f], dest)
947
		}
948
		values = make([]interface{}, len(columns))
949
950
		for rows.Next() {
951
			// create a new struct type (which returns PtrTo) and indirect it
952
			vp = reflect.New(base)
953
			v = reflect.Indirect(vp)
954
955
			err = fieldsByTraversal(v, fields, values, true)
956
			if err != nil {
957
				return err
958
			}
959
960
			// scan into the struct field pointers and append to our results
961
			err = rows.Scan(values...)
962
			if err != nil {
963
				return err
964
			}
965
966
			if isPtr {
967
				direct.Set(reflect.Append(direct, vp))
968
			} else {
969
				direct.Set(reflect.Append(direct, v))
970
			}
971
		}
972
	} else {
973
		for rows.Next() {
974
			vp = reflect.New(base)
975
			err = rows.Scan(vp.Interface())
976
			if err != nil {
977
				return err
978
			}
979
			// append
980
			if isPtr {
981
				direct.Set(reflect.Append(direct, vp))
982
			} else {
983
				direct.Set(reflect.Append(direct, reflect.Indirect(vp)))
984
			}
985
		}
986
	}
987
988
	return rows.Err()
989
}
990
991
// FIXME: StructScan was the very first bit of API in sqlx, and now unfortunately
992
// it doesn't really feel like it's named properly.  There is an incongruency
993
// between this and the way that StructScan (which might better be ScanStruct
994
// anyway) works on a rows object.
995
996
// StructScan all rows from an sql.Rows or an sqlx.Rows into the dest slice.
997
// StructScan will scan in the entire rows result, so if you do not want to
998
// allocate structs for the entire result, use Queryx and see sqlx.Rows.StructScan.
999
// If rows is sqlx.Rows, it will use its mapper, otherwise it will use the default.
1000
func StructScan(rows rowsi, dest interface{}) error {
1001
	return scanAll(rows, dest, true)
1002
1003
}
1004
1005
// reflect helpers
1006
1007
func baseType(t reflect.Type, expected reflect.Kind) (reflect.Type, error) {
1008
	t = reflectx.Deref(t)
1009
	if t.Kind() != expected {
1010
		return nil, fmt.Errorf("expected %s but got %s", expected, t.Kind())
1011
	}
1012
	return t, nil
1013
}
1014
1015
// fieldsByName fills a values interface with fields from the passed value based
1016
// on the traversals in int.  If ptrs is true, return addresses instead of values.
1017
// We write this instead of using FieldsByName to save allocations and map lookups
1018
// when iterating over many rows.  Empty traversals will get an interface pointer.
1019
// Because of the necessity of requesting ptrs or values, it's considered a bit too
1020
// specialized for inclusion in reflectx itself.
1021
func fieldsByTraversal(v reflect.Value, traversals [][]int, values []interface{}, ptrs bool) error {
1022
	v = reflect.Indirect(v)
1023
	if v.Kind() != reflect.Struct {
1024
		return errors.New("argument not a struct")
1025
	}
1026
1027
	for i, traversal := range traversals {
1028
		if len(traversal) == 0 {
1029
			values[i] = new(interface{})
1030
			continue
1031
		}
1032
		f := reflectx.FieldByIndexes(v, traversal)
1033
		if ptrs {
1034
			values[i] = f.Addr().Interface()
1035
		} else {
1036
			values[i] = f.Interface()
1037
		}
1038
	}
1039
	return nil
1040
}
1041
1042
func missingFields(transversals [][]int) (field int, err error) {
1043
	for i, t := range transversals {
1044
		if len(t) == 0 {
1045
			return i, errors.New("missing field")
1046
		}
1047
	}
1048
	return 0, nil
1049
}
1050