Skip to content

Commit

Permalink
fix long standing FIXME in rebind for named params (oracle) ++ tests,…
Browse files Browse the repository at this point in the history
… rename in -> In
  • Loading branch information
jmoiron committed Apr 7, 2015
1 parent b75bdd6 commit ab1bdb4
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 12 deletions.
21 changes: 12 additions & 9 deletions bind.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,10 @@ func BindType(driverName string) int {
// FIXME: this should be able to be tolerant of escaped ?'s in queries without
// losing much speed, and should be to avoid confusion.

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

// Rebind a query from the default bindtype (QUESTION) to the target bindtype.
func Rebind(bindType int, query string) string {
if bindType != DOLLAR {
switch bindType {
case QUESTION, UNKNOWN:
return query
}

Expand All @@ -47,7 +46,12 @@ func Rebind(bindType int, query string) string {
j := 1
for _, b := range qb {
if b == '?' {
rqb = append(rqb, '$')
switch bindType {
case DOLLAR:
rqb = append(rqb, '$')
case NAMED:
rqb = append(rqb, ':', 'a', 'r', 'g')
}
for _, b := range strconv.Itoa(j) {
rqb = append(rqb, byte(b))
}
Expand All @@ -63,7 +67,6 @@ func Rebind(bindType int, query string) string {
// much simpler and should be more resistant to odd unicode, but it is twice as
// slow. Kept here for benchmarking purposes and to possibly replace Rebind if
// problems arise with its somewhat naive handling of unicode.

func rebindBuff(bindType int, query string) string {
if bindType != DOLLAR {
return query
Expand All @@ -85,10 +88,10 @@ func rebindBuff(bindType int, query string) string {
return rqb.String()
}

// in expands query parms in args, returning the modified query string and
// a new list of args passable to Exec/Query/etc

func in(query string, args ...interface{}) (string, []interface{}, error) {
// In expands slice query params in args, returning the modified query string
// and a new list of args passable to Exec/Query/etc. It requires queries using
// the '?' bindvar and returns queries using the '?' bindvar.
func In(query string, args ...interface{}) (string, []interface{}, error) {
// TODO: validate this short circuit as actually saving any time..
type slice struct {
v reflect.Value
Expand Down
21 changes: 18 additions & 3 deletions sqlx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1078,6 +1078,7 @@ func TestDoNotPanicOnConnect(t *testing.T) {
t.Errorf("Should return error when using bogus driverName")
}
}

func TestRebind(t *testing.T) {
q1 := `INSERT INTO foo (a, b, c, d, e, f, g, h, i) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
q2 := `INSERT INTO foo (a, b, c) VALUES (?, ?, "foo"), ("Hi", ?, ?)`
Expand All @@ -1092,6 +1093,20 @@ func TestRebind(t *testing.T) {
if s2 != `INSERT INTO foo (a, b, c) VALUES ($1, $2, "foo"), ("Hi", $3, $4)` {
t.Errorf("q2 failed")
}

s1 = Rebind(NAMED, q1)
s2 = Rebind(NAMED, q2)

ex1 := `INSERT INTO foo (a, b, c, d, e, f, g, h, i) VALUES ` +
`(:arg1, :arg2, :arg3, :arg4, :arg5, :arg6, :arg7, :arg8, :arg9, :arg10)`
if s1 != ex1 {
t.Error("q1 failed on Named params")
}

ex2 := `INSERT INTO foo (a, b, c) VALUES (:arg1, :arg2, "foo"), ("Hi", :arg3, :arg4)`
if s2 != ex2 {
t.Error("q2 failed on Named params")
}
}

func TestBindMap(t *testing.T) {
Expand Down Expand Up @@ -1212,7 +1227,7 @@ func TestIn(t *testing.T) {
8},
}
for _, test := range tests {
q, a, err := in(test.q, test.args...)
q, a, err := In(test.q, test.args...)
if err != nil {
t.Error(err)
}
Expand All @@ -1229,7 +1244,7 @@ func TestIn(t *testing.T) {
// might not work, but we shouldn't parse if we don't need to
{
orig := "SELECT * FROM foo WHERE x = ? AND y = ?"
q, a, err := in(orig, "foo", "bar", "baz")
q, a, err := In(orig, "foo", "bar", "baz")
if err != nil {
t.Error(err)
}
Expand All @@ -1256,7 +1271,7 @@ func TestIn(t *testing.T) {
0},
}
for _, test := range tests {
_, _, err := in(test.q, test.args...)
_, _, err := In(test.q, test.args...)
if err == nil {
t.Error("Expected an error, but got nil.")
}
Expand Down

0 comments on commit ab1bdb4

Please sign in to comment.