Skip to content

Commit 16e5f49

Browse files
committed
documentation cleanup, vet and lint fixes, remove BindMap and BindStruct from public interface in favor of a single BindNamed
1 parent 2b1877d commit 16e5f49

File tree

8 files changed

+59
-66
lines changed

8 files changed

+59
-66
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,5 @@ _cgo_export.*
2020
_testmain.go
2121

2222
*.exe
23+
tags
24+
environ

bind.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@ import (
55
"strconv"
66
)
77

8-
// Bindvar types supported by sqlx's Rebind & BindMap/Struct functions.
8+
// Bindvar types supported by Rebind, BindMap and BindStruct.
99
const (
1010
UNKNOWN = iota
1111
QUESTION
1212
DOLLAR
1313
NAMED
1414
)
1515

16-
// BindType returns the bindtype for a given database given a drivername
16+
// BindType returns the bindtype for a given database given a drivername.
1717
func BindType(driverName string) int {
1818
switch driverName {
1919
case "postgres":
@@ -33,7 +33,7 @@ func BindType(driverName string) int {
3333

3434
// FIXME: this is now produces the wrong results for oracle's NAMED bindtype
3535

36-
// Rebind a query from the default bindtype (QUESTION) to the target bindtype
36+
// Rebind a query from the default bindtype (QUESTION) to the target bindtype.
3737
func Rebind(bindType int, query string) string {
3838
if bindType != DOLLAR {
3939
return query

doc.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
// Package sqlx provides general purpose extensions to database/sql.
22
//
3-
// sqlx is intended to seamlessly wrap database/sql and provide convenience
3+
// It is intended to seamlessly wrap database/sql and provide convenience
44
// methods which are useful in the development of database driven applications.
5-
// None of the underlying database/sql methods are changed, instead all extended
5+
// None of the underlying database/sql methods are changed. Instead all extended
66
// behavior is implemented through new methods defined on wrapper types.
77
//
8-
// sqlx adds struct scanning, named queries, query rebinding between drivers,
9-
// convenient shorthand for common error handling, from-file query execution,
8+
// Additions include scanning into structs, named query support, rebinding
9+
// queries for different drivers, convenient shorthands for common error handling
1010
// and more.
1111
//
1212
package sqlx

named.go

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,14 @@ package sqlx
22

33
// Named Query Support
44
//
5-
// * BindStruct, BindMap - bind query bindvars to map/struct args
5+
// * BindMap - bind query bindvars to map/struct args
66
// * NamedExec, NamedQuery - named query w/ struct or map
7-
// * NamedExecMap, NamedQueryMap - named query w/ maps (DEPRECATED)
87
// * NamedStmt - a pre-compiled named query which is a prepared statement
98
//
109
// Internal Interfaces:
1110
//
1211
// * compileNamedQuery - rebind a named query, returning a query and list of names
1312
// * bindArgs, bindMapArgs, bindAnyArgs - given a list of names, return an arglist
14-
// * bindAny - call BindStruct or BindMap depending on the type of the argument
1513
//
1614
import (
1715
"database/sql"
@@ -111,7 +109,7 @@ func (n *NamedStmt) Get(dest interface{}, arg interface{}) error {
111109
// named statements (as the bindtype must be determined).
112110
type namedPreparer interface {
113111
Preparer
114-
Binder
112+
binder
115113
}
116114

117115
func prepareNamed(p namedPreparer, query string) (*NamedStmt, error) {
@@ -177,10 +175,10 @@ func bindMapArgs(names []string, arg map[string]interface{}) ([]interface{}, err
177175
return arglist, nil
178176
}
179177

180-
// BindStruct binds a named parameter query with fields from a struct argument.
178+
// bindStruct binds a named parameter query with fields from a struct argument.
181179
// The rules for binding field names to parameter names follow the same
182180
// conventions as for StructScan, including obeying the `db` struct tags.
183-
func BindStruct(bindType int, query string, arg interface{}) (string, []interface{}, error) {
181+
func bindStruct(bindType int, query string, arg interface{}) (string, []interface{}, error) {
184182
bound, names, err := compileNamedQuery([]byte(query), bindType)
185183
if err != nil {
186184
return "", []interface{}{}, err
@@ -194,8 +192,8 @@ func BindStruct(bindType int, query string, arg interface{}) (string, []interfac
194192
return bound, arglist, nil
195193
}
196194

197-
// BindMap binds a named parameter query with a map of arguments.
198-
func BindMap(bindType int, query string, args map[string]interface{}) (string, []interface{}, error) {
195+
// bindMap binds a named parameter query with a map of arguments.
196+
func bindMap(bindType int, query string, args map[string]interface{}) (string, []interface{}, error) {
199197
bound, names, err := compileNamedQuery([]byte(query), bindType)
200198
if err != nil {
201199
return "", []interface{}{}, err
@@ -285,19 +283,19 @@ func compileNamedQuery(qs []byte, bindType int) (query string, names []string, e
285283
return string(rebound), names, err
286284
}
287285

288-
// bindAny binds a struct or a map by inspecting the arg interface.
289-
func bindAny(e Ext, query string, arg interface{}) (string, []interface{}, error) {
286+
// Bind binds a struct or a map to a query with named parameters.
287+
func BindNamed(bindType int, query string, arg interface{}) (string, []interface{}, error) {
290288
if maparg, ok := arg.(map[string]interface{}); ok {
291-
return e.BindMap(query, maparg)
289+
return bindMap(bindType, query, maparg)
292290
}
293-
return e.BindStruct(query, arg)
291+
return bindStruct(bindType, query, arg)
294292
}
295293

296294
// NamedQuery binds a named query and then runs Query on the result using the
297295
// provided Ext (sqlx.Tx, sqlx.Db). It works with both structs and with
298296
// map[string]interface{} types.
299297
func NamedQuery(e Ext, query string, arg interface{}) (*Rows, error) {
300-
q, args, err := bindAny(e, query, arg)
298+
q, args, err := BindNamed(BindType(e.DriverName()), query, arg)
301299
if err != nil {
302300
return nil, err
303301
}
@@ -308,7 +306,7 @@ func NamedQuery(e Ext, query string, arg interface{}) (*Rows, error) {
308306
// then runs Exec on the result. Returns an error from the binding
309307
// or the query excution itself.
310308
func NamedExec(e Ext, query string, arg interface{}) (sql.Result, error) {
311-
q, args, err := bindAny(e, query, arg)
309+
q, args, err := BindNamed(BindType(e.DriverName()), query, arg)
312310
if err != nil {
313311
return nil, err
314312
}

named_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,13 +123,13 @@ func TestNamedQueries(t *testing.T) {
123123
var p2 Person
124124
rows.StructScan(&p2)
125125
if p.FirstName != p2.FirstName {
126-
t.Error("got %s, expected %s", p.FirstName, p2.FirstName)
126+
t.Errorf("got %s, expected %s", p.FirstName, p2.FirstName)
127127
}
128128
if p.LastName != p2.LastName {
129-
t.Error("got %s, expected %s", p.LastName, p2.LastName)
129+
t.Errorf("got %s, expected %s", p.LastName, p2.LastName)
130130
}
131131
if p.Email != p2.Email {
132-
t.Error("got %s, expected %s", p.Email, p2.Email)
132+
t.Errorf("got %s, expected %s", p.Email, p2.Email)
133133
}
134134
}
135135

@@ -142,13 +142,13 @@ func TestNamedQueries(t *testing.T) {
142142
t.Errorf("got %d results, expected %d", len(people), 1)
143143
}
144144
if p.FirstName != people[0].FirstName {
145-
t.Error("got %s, expected %s", p.FirstName, people[0].FirstName)
145+
t.Errorf("got %s, expected %s", p.FirstName, people[0].FirstName)
146146
}
147147
if p.LastName != people[0].LastName {
148-
t.Error("got %s, expected %s", p.LastName, people[0].LastName)
148+
t.Errorf("got %s, expected %s", p.LastName, people[0].LastName)
149149
}
150150
if p.Email != people[0].Email {
151-
t.Error("got %s, expected %s", p.Email, people[0].Email)
151+
t.Errorf("got %s, expected %s", p.Email, people[0].Email)
152152
}
153153

154154
// test Exec

sqlx.go

Lines changed: 21 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import (
2121
// NameMapper is used to map column names to struct field names. By default,
2222
// it uses strings.ToLower to lowercase struct field names. It can be set
2323
// to whatever you want, but it is encouraged to be set before sqlx is used
24-
// as field-to-name mappings are cached after first use on a type.
24+
// as name-to-field mappings are cached after first use on a type.
2525
var NameMapper = strings.ToLower
2626
var origMapper = reflect.ValueOf(NameMapper)
2727

@@ -33,51 +33,49 @@ var mpr *reflectx.Mapper
3333
func mapper() *reflectx.Mapper {
3434
if mpr == nil {
3535
mpr = reflectx.NewMapperFunc("db", NameMapper)
36-
}
37-
if origMapper != reflect.ValueOf(NameMapper) {
36+
} else if origMapper != reflect.ValueOf(NameMapper) {
37+
// if NameMapper has changed, create a new mapper
3838
mpr = reflectx.NewMapperFunc("db", NameMapper)
3939
origMapper = reflect.ValueOf(NameMapper)
4040
}
4141
return mpr
4242
}
4343

44-
// ColScanner is an interface for something which can Scan and return a list
45-
// of columns (Row, Rows)
44+
// ColScanner is an interface used by MapScan and SliceScan
4645
type ColScanner interface {
4746
Columns() ([]string, error)
4847
Scan(dest ...interface{}) error
4948
Err() error
5049
}
5150

52-
// Queryer is an interface for something which can Query (Tx, DB, Stmt)
51+
// Queryer is an interface used by Get and Select
5352
type Queryer interface {
5453
Query(query string, args ...interface{}) (*sql.Rows, error)
5554
Queryx(query string, args ...interface{}) (*Rows, error)
5655
QueryRowx(query string, args ...interface{}) *Row
5756
}
5857

59-
// Execer is an interface for something which can Exec (Tx, DB, Stmt)
58+
// Execer is an interface used by MustExec and LoadFile
6059
type Execer interface {
6160
Exec(query string, args ...interface{}) (sql.Result, error)
6261
}
6362

6463
// Binder is an interface for something which can bind queries (Tx, DB)
65-
type Binder interface {
64+
type binder interface {
6665
DriverName() string
6766
Rebind(string) string
68-
BindMap(string, map[string]interface{}) (string, []interface{}, error)
69-
BindStruct(string, interface{}) (string, []interface{}, error)
67+
BindNamed(string, interface{}) (string, []interface{}, error)
7068
}
7169

72-
// Ext is a union interface which can bind, query, and exec (Tx, DB), used for
73-
// NamedQuery and NamedExec, which requires exec/query and BindMap/Struct
70+
// Ext is a union interface which can bind, query, and exec, used by
71+
// NamedQuery and NamedExec.
7472
type Ext interface {
75-
Binder
73+
binder
7674
Queryer
7775
Execer
7876
}
7977

80-
// Preparer is an interface for something which can prepare sql statements (Tx, DB)
78+
// Preparer is an interface used by Preparex.
8179
type Preparer interface {
8280
Prepare(query string) (*sql.Stmt, error)
8381
}
@@ -192,7 +190,7 @@ func (db *DB) DriverName() string {
192190
return db.driverName
193191
}
194192

195-
// Open is the same as database/sql's Open, but returns an *sqlx.DB instead.
193+
// Open is the same as sql.Open, but returns an *sqlx.DB instead.
196194
func Open(driverName, dataSourceName string) (*DB, error) {
197195
db, err := sql.Open(driverName, dataSourceName)
198196
if err != nil {
@@ -214,14 +212,9 @@ func (db *DB) Unsafe() *DB {
214212
return &DB{DB: db.DB, driverName: db.driverName, unsafe: true}
215213
}
216214

217-
// BindMap binds a query using the DB driver's bindvar type.
218-
func (db *DB) BindMap(query string, argmap map[string]interface{}) (string, []interface{}, error) {
219-
return BindMap(BindType(db.driverName), query, argmap)
220-
}
221-
222-
// BindStruct binds a query using the DB driver's bindvar type.
223-
func (db *DB) BindStruct(query string, arg interface{}) (string, []interface{}, error) {
224-
return BindStruct(BindType(db.driverName), query, arg)
215+
// BindNamed binds a query using the DB driver's bindvar type.
216+
func (db *DB) BindNamed(query string, arg interface{}) (string, []interface{}, error) {
217+
return BindNamed(BindType(db.driverName), query, arg)
225218
}
226219

227220
// NamedQuery using this DB.
@@ -293,7 +286,7 @@ func (db *DB) PrepareNamed(query string) (*NamedStmt, error) {
293286
return prepareNamed(db, query)
294287
}
295288

296-
// Tx is an sqlx wrapper around database/sql's Tx with extra functionality
289+
// Tx is an sqlx wrapper around sql.Tx with extra functionality
297290
type Tx struct {
298291
*sql.Tx
299292
driverName string
@@ -316,14 +309,9 @@ func (tx *Tx) Unsafe() *Tx {
316309
return &Tx{Tx: tx.Tx, driverName: tx.driverName, unsafe: true}
317310
}
318311

319-
// BindMap binds a query within a transaction's bindvar type.
320-
func (tx *Tx) BindMap(query string, argmap map[string]interface{}) (string, []interface{}, error) {
321-
return BindMap(BindType(tx.driverName), query, argmap)
322-
}
323-
324-
// BindStruct binds a query within a transaction's bindvar type.
325-
func (tx *Tx) BindStruct(query string, arg interface{}) (string, []interface{}, error) {
326-
return BindStruct(BindType(tx.driverName), query, arg)
312+
// BindNamed binds a query within a transaction's bindvar type.
313+
func (tx *Tx) BindNamed(query string, arg interface{}) (string, []interface{}, error) {
314+
return BindNamed(BindType(tx.driverName), query, arg)
327315
}
328316

329317
// NamedQuery within a transaction.
@@ -404,7 +392,7 @@ func (tx *Tx) PrepareNamed(query string) (*NamedStmt, error) {
404392
return prepareNamed(tx, query)
405393
}
406394

407-
// Stmt is an sqlx wrapper around database/sql's Stmt with extra functionality
395+
// Stmt is an sqlx wrapper around sql.Stmt with extra functionality
408396
type Stmt struct {
409397
*sql.Stmt
410398
unsafe bool

sqlx_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -870,7 +870,7 @@ func TestBindMap(t *testing.T) {
870870
"last": "Moiron",
871871
}
872872

873-
bq, args, _ := BindMap(QUESTION, q1, am)
873+
bq, args, _ := bindMap(QUESTION, q1, am)
874874
expect := `INSERT INTO foo (a, b, c, d) VALUES (?, ?, ?, ?)`
875875
if bq != expect {
876876
t.Errorf("Interpolation of query failed: got `%v`, expected `%v`\n", bq, expect)
@@ -917,7 +917,7 @@ func TestBindStruct(t *testing.T) {
917917

918918
am := tt{"Jason Moiron", 30, "Jason", "Moiron"}
919919

920-
bq, args, _ := BindStruct(QUESTION, q1, am)
920+
bq, args, _ := bindStruct(QUESTION, q1, am)
921921
expect := `INSERT INTO foo (a, b, c, d) VALUES (?, ?, ?, ?)`
922922
if bq != expect {
923923
t.Errorf("Interpolation of query failed: got `%v`, expected `%v`\n", bq, expect)
@@ -940,7 +940,7 @@ func TestBindStruct(t *testing.T) {
940940
}
941941

942942
am2 := tt2{"Hello", "World"}
943-
bq, args, _ = BindStruct(QUESTION, "INSERT INTO foo (a, b) VALUES (:field_2, :field_1)", am2)
943+
bq, args, _ = bindStruct(QUESTION, "INSERT INTO foo (a, b) VALUES (:field_2, :field_1)", am2)
944944
expect = `INSERT INTO foo (a, b) VALUES (?, ?)`
945945
if bq != expect {
946946
t.Errorf("Interpolation of query failed: got `%v`, expected `%v`\n", bq, expect)
@@ -957,7 +957,7 @@ func TestBindStruct(t *testing.T) {
957957
am3.Field1 = "Hello"
958958
am3.Field2 = "World"
959959

960-
bq, args, err = BindStruct(QUESTION, "INSERT INTO foo (a, b, c) VALUES (:name, :field_1, :field_2)", am3)
960+
bq, args, err = bindStruct(QUESTION, "INSERT INTO foo (a, b, c) VALUES (:name, :field_1, :field_2)", am3)
961961

962962
if err != nil {
963963
t.Fatal(err)
@@ -991,7 +991,7 @@ func BenchmarkBindStruct(b *testing.B) {
991991
am := t{"Jason Moiron", 30, "Jason", "Moiron"}
992992
b.StartTimer()
993993
for i := 0; i < b.N; i++ {
994-
BindStruct(DOLLAR, q1, am)
994+
bindStruct(DOLLAR, q1, am)
995995
//bindMap(QUESTION, q1, am)
996996
}
997997
}
@@ -1007,7 +1007,7 @@ func BenchmarkBindMap(b *testing.B) {
10071007
}
10081008
b.StartTimer()
10091009
for i := 0; i < b.N; i++ {
1010-
BindMap(DOLLAR, q1, am)
1010+
bindMap(DOLLAR, q1, am)
10111011
//bindMap(QUESTION, q1, am)
10121012
}
10131013
}

types/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# types
2+
3+
The types package provides some useful types which implement the `sql.Scanner`
4+
and `driver.Valuer` interfaces, suitable for use as scan and value targets with
5+
database/sql.

0 commit comments

Comments
 (0)