Skip to content

Commit fb9af31

Browse files
committed
support sqlserver parameters syntax
1 parent cf35089 commit fb9af31

File tree

4 files changed

+33
-2
lines changed

4 files changed

+33
-2
lines changed

bind.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const (
1616
QUESTION
1717
DOLLAR
1818
NAMED
19+
AT
1920
)
2021

2122
// BindType returns the bindtype for a given database given a drivername.
@@ -29,6 +30,8 @@ func BindType(driverName string) int {
2930
return QUESTION
3031
case "oci8", "ora", "goracle":
3132
return NAMED
33+
case "sqlserver":
34+
return AT
3235
}
3336
return UNKNOWN
3437
}
@@ -56,6 +59,8 @@ func Rebind(bindType int, query string) string {
5659
rqb = append(rqb, '$')
5760
case NAMED:
5861
rqb = append(rqb, ':', 'a', 'r', 'g')
62+
case AT:
63+
rqb = append(rqb, '@', 'p')
5964
}
6065

6166
j++

named.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,12 @@ func compileNamedQuery(qs []byte, bindType int) (query string, names []string, e
287287
rebound = append(rebound, byte(b))
288288
}
289289
currentVar++
290+
case AT:
291+
rebound = append(rebound, '@', 'p')
292+
for _, b := range strconv.Itoa(currentVar) {
293+
rebound = append(rebound, byte(b))
294+
}
295+
currentVar++
290296
}
291297
// add this byte to string unless it was not part of the name
292298
if i != last {

named_test.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@ import (
77

88
func TestCompileQuery(t *testing.T) {
99
table := []struct {
10-
Q, R, D, N string
11-
V []string
10+
Q, R, D, T, N string
11+
V []string
1212
}{
1313
// basic test for named parameters, invalid char ',' terminating
1414
{
1515
Q: `INSERT INTO foo (a,b,c,d) VALUES (:name, :age, :first, :last)`,
1616
R: `INSERT INTO foo (a,b,c,d) VALUES (?, ?, ?, ?)`,
1717
D: `INSERT INTO foo (a,b,c,d) VALUES ($1, $2, $3, $4)`,
18+
T: `INSERT INTO foo (a,b,c,d) VALUES (@p1, @p2, @p3, @p4)`,
1819
N: `INSERT INTO foo (a,b,c,d) VALUES (:name, :age, :first, :last)`,
1920
V: []string{"name", "age", "first", "last"},
2021
},
@@ -23,20 +24,23 @@ func TestCompileQuery(t *testing.T) {
2324
Q: `SELECT * FROM a WHERE first_name=:name1 AND last_name=:name2`,
2425
R: `SELECT * FROM a WHERE first_name=? AND last_name=?`,
2526
D: `SELECT * FROM a WHERE first_name=$1 AND last_name=$2`,
27+
T: `SELECT * FROM a WHERE first_name=@p1 AND last_name=@p2`,
2628
N: `SELECT * FROM a WHERE first_name=:name1 AND last_name=:name2`,
2729
V: []string{"name1", "name2"},
2830
},
2931
{
3032
Q: `SELECT "::foo" FROM a WHERE first_name=:name1 AND last_name=:name2`,
3133
R: `SELECT ":foo" FROM a WHERE first_name=? AND last_name=?`,
3234
D: `SELECT ":foo" FROM a WHERE first_name=$1 AND last_name=$2`,
35+
T: `SELECT ":foo" FROM a WHERE first_name=@p1 AND last_name=@p2`,
3336
N: `SELECT ":foo" FROM a WHERE first_name=:name1 AND last_name=:name2`,
3437
V: []string{"name1", "name2"},
3538
},
3639
{
3740
Q: `SELECT 'a::b::c' || first_name, '::::ABC::_::' FROM person WHERE first_name=:first_name AND last_name=:last_name`,
3841
R: `SELECT 'a:b:c' || first_name, '::ABC:_:' FROM person WHERE first_name=? AND last_name=?`,
3942
D: `SELECT 'a:b:c' || first_name, '::ABC:_:' FROM person WHERE first_name=$1 AND last_name=$2`,
43+
T: `SELECT 'a:b:c' || first_name, '::ABC:_:' FROM person WHERE first_name=@p1 AND last_name=@p2`,
4044
N: `SELECT 'a:b:c' || first_name, '::ABC:_:' FROM person WHERE first_name=:first_name AND last_name=:last_name`,
4145
V: []string{"first_name", "last_name"},
4246
},
@@ -74,6 +78,11 @@ func TestCompileQuery(t *testing.T) {
7478
t.Errorf("\nexpected: `%s`\ngot: `%s`", test.D, qd)
7579
}
7680

81+
qt, _, _ := compileNamedQuery([]byte(test.Q), AT)
82+
if qt != test.T {
83+
t.Errorf("\nexpected: `%s`\ngot: `%s`", test.T, qt)
84+
}
85+
7786
qq, _, _ := compileNamedQuery([]byte(test.Q), NAMED)
7887
if qq != test.N {
7988
t.Errorf("\nexpected: `%s`\ngot: `%s`\n(len: %d vs %d)", test.N, qq, len(test.N), len(qq))

sqlx_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1320,6 +1320,17 @@ func TestRebind(t *testing.T) {
13201320
t.Errorf("q2 failed")
13211321
}
13221322

1323+
s1 = Rebind(AT, q1)
1324+
s2 = Rebind(AT, q2)
1325+
1326+
if s1 != `INSERT INTO foo (a, b, c, d, e, f, g, h, i) VALUES (@p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10)` {
1327+
t.Errorf("q1 failed")
1328+
}
1329+
1330+
if s2 != `INSERT INTO foo (a, b, c) VALUES (@p1, @p2, "foo"), ("Hi", @p3, @p4)` {
1331+
t.Errorf("q2 failed")
1332+
}
1333+
13231334
s1 = Rebind(NAMED, q1)
13241335
s2 = Rebind(NAMED, q2)
13251336

0 commit comments

Comments
 (0)