Skip to content

Commit 25ae413

Browse files
committed
feat(builder): update API
1 parent 839f35e commit 25ae413

File tree

3 files changed

+33
-66
lines changed

3 files changed

+33
-66
lines changed

builder.go

+8-35
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77

88
type Builder struct {
99
query strings.Builder
10-
Args []any
10+
args []any
1111
counter int
1212
placeholder rune
1313
}
@@ -20,49 +20,22 @@ func (b *Builder) Appendf(format string, args ...any) {
2020
fmt.Fprintf(&b.query, format, a...)
2121
}
2222

23-
func (b *Builder) String() string { return b.string() }
24-
25-
func (b *Builder) DebugString() string {
26-
query := b.string()
27-
for i, arg := range b.Args {
28-
var sarg string
29-
switch arg := arg.(type) {
30-
case string:
31-
sarg = fmt.Sprintf("'%s'", arg)
32-
case fmt.Stringer:
33-
sarg = fmt.Sprintf("'%s'", arg.String())
34-
default:
35-
sarg = fmt.Sprintf("%v", arg)
36-
}
37-
38-
switch b.placeholder {
39-
case '?':
40-
query = strings.Replace(query, "?", sarg, 1)
41-
case '$':
42-
query = strings.Replace(query, fmt.Sprintf("$%d", i+1), sarg, 1)
43-
case '@':
44-
query = strings.Replace(query, fmt.Sprintf("@p%d", i+1), sarg, 1)
45-
default:
46-
panic("unreachable")
47-
}
48-
}
49-
return query
50-
}
51-
52-
func (b *Builder) string() string {
23+
func (b *Builder) Query() string {
5324
query := b.query.String()
5425
if strings.Contains(query, "%!") {
5526
// fmt silently recovers panics and writes them to the output.
56-
// we want panics to be loud, so we find and rethrow them.
57-
// see also https://github.com/golang/go/issues/28150.
27+
// We want panics to be loud, so we find and rethrow them.
28+
// See also https://github.com/golang/go/issues/28150.
5829
panic(fmt.Sprintf("queries: bad query: %s", query))
5930
}
6031
if b.placeholder == -1 {
61-
panic("queries: bad query: different placeholders used")
32+
panic("queries: different placeholders used")
6233
}
6334
return query
6435
}
6536

37+
func (b *Builder) Args() []any { return b.args }
38+
6639
type argument struct {
6740
value any
6841
builder *Builder
@@ -72,7 +45,7 @@ type argument struct {
7245
func (a argument) Format(s fmt.State, verb rune) {
7346
switch verb {
7447
case '?', '$', '@':
75-
a.builder.Args = append(a.builder.Args, a.value)
48+
a.builder.args = append(a.builder.args, a.value)
7649
if a.builder.placeholder == 0 {
7750
a.builder.placeholder = verb
7851
}

builder_test.go

+24-30
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package queries_test
22

33
import (
4-
"context"
54
"testing"
65

76
"go-simpler.org/queries"
@@ -13,45 +12,40 @@ import (
1312

1413
func TestBuilder(t *testing.T) {
1514
var qb queries.Builder
16-
qb.Appendf("select %s from tbl where 1=1", "*")
17-
qb.Appendf(" and foo = %$", 1)
18-
qb.Appendf(" and bar = %$", 2)
19-
qb.Appendf(" and baz = %$", 3)
15+
qb.Appendf("SELECT %s FROM tbl WHERE 1=1", "*")
16+
qb.Appendf(" AND foo = %$", 42)
17+
qb.Appendf(" AND bar = %$", "test")
18+
qb.Appendf(" AND baz = %$", false)
2019

21-
assert.Equal[E](t, qb.String(), "select * from tbl where 1=1 and foo = $1 and bar = $2 and baz = $3")
22-
assert.Equal[E](t, qb.Args, []any{1, 2, 3})
20+
assert.Equal[E](t, qb.Query(), "SELECT * FROM tbl WHERE 1=1 AND foo = $1 AND bar = $2 AND baz = $3")
21+
assert.Equal[E](t, qb.Args(), []any{42, "test", false})
2322
}
2423

2524
func TestBuilder_placeholders(t *testing.T) {
2625
tests := map[string]struct {
2726
format string
2827
query string
29-
debug string
3028
}{
3129
"?": {
32-
format: "select * from tbl where foo = %? and bar = %? and baz = %?",
33-
query: "select * from tbl where foo = ? and bar = ? and baz = ?",
34-
debug: "select * from tbl where foo = 42 and bar = 'test' and baz = 'context.Background'",
30+
format: "SELECT * FROM tbl WHERE foo = %? AND bar = %? AND baz = %?",
31+
query: "SELECT * FROM tbl WHERE foo = ? AND bar = ? AND baz = ?",
3532
},
3633
"$": {
37-
format: "select * from tbl where foo = %$ and bar = %$ and baz = %$",
38-
query: "select * from tbl where foo = $1 and bar = $2 and baz = $3",
39-
debug: "select * from tbl where foo = 42 and bar = 'test' and baz = 'context.Background'",
34+
format: "SELECT * FROM tbl WHERE foo = %$ AND bar = %$ AND baz = %$",
35+
query: "SELECT * FROM tbl WHERE foo = $1 AND bar = $2 AND baz = $3",
4036
},
4137
"@": {
42-
format: "select * from tbl where foo = %@ and bar = %@ and baz = %@",
43-
query: "select * from tbl where foo = @p1 and bar = @p2 and baz = @p3",
44-
debug: "select * from tbl where foo = 42 and bar = 'test' and baz = 'context.Background'",
38+
format: "SELECT * FROM tbl WHERE foo = %@ AND bar = %@ AND baz = %@",
39+
query: "SELECT * FROM tbl WHERE foo = @p1 AND bar = @p2 AND baz = @p3",
4540
},
4641
}
4742

4843
for name, tt := range tests {
4944
t.Run(name, func(t *testing.T) {
5045
var qb queries.Builder
51-
qb.Appendf(tt.format, 42, "test", context.Background())
52-
assert.Equal[E](t, qb.String(), tt.query)
53-
assert.Equal[E](t, qb.Args, []any{42, "test", context.Background()})
54-
assert.Equal[E](t, qb.DebugString(), tt.debug)
46+
qb.Appendf(tt.format, 1, 2, 3)
47+
assert.Equal[E](t, qb.Query(), tt.query)
48+
assert.Equal[E](t, qb.Args(), []any{1, 2, 3})
5549
})
5650
}
5751
}
@@ -63,35 +57,35 @@ func TestBuilder_badQuery(t *testing.T) {
6357
}{
6458
"bad verb": {
6559
appends: func(qb *queries.Builder) {
66-
qb.Appendf("select %d from tbl", "foo")
60+
qb.Appendf("SELECT %d FROM tbl", "foo")
6761
},
68-
panicMsg: "queries: bad query: select %!d(string=foo) from tbl",
62+
panicMsg: "queries: bad query: SELECT %!d(string=foo) FROM tbl",
6963
},
7064
"too few arguments": {
7165
appends: func(qb *queries.Builder) {
72-
qb.Appendf("select %s from tbl")
66+
qb.Appendf("SELECT %s FROM tbl")
7367
},
74-
panicMsg: "queries: bad query: select %!s(MISSING) from tbl",
68+
panicMsg: "queries: bad query: SELECT %!s(MISSING) FROM tbl",
7569
},
7670
"too many arguments": {
7771
appends: func(qb *queries.Builder) {
78-
qb.Appendf("select %s from tbl", "foo", "bar")
72+
qb.Appendf("SELECT %s FROM tbl", "foo", "bar")
7973
},
80-
panicMsg: "queries: bad query: select foo from tbl%!(EXTRA queries.argument=bar)",
74+
panicMsg: "queries: bad query: SELECT foo FROM tbl%!(EXTRA queries.argument=bar)",
8175
},
8276
"different placeholders": {
8377
appends: func(qb *queries.Builder) {
84-
qb.Appendf("select * from tbl where foo = %? and bar = %$ and baz = %@", 1, 2, 3)
78+
qb.Appendf("SELECT * FROM tbl WHERE foo = %? AND bar = %$ AND baz = %@", 1, 2, 3)
8579
},
86-
panicMsg: "queries: bad query: different placeholders used",
80+
panicMsg: "queries: different placeholders used",
8781
},
8882
}
8983

9084
for name, tt := range tests {
9185
t.Run(name, func(t *testing.T) {
9286
var qb queries.Builder
9387
tt.appends(&qb)
94-
assert.Panics[E](t, func() { _ = qb.String() }, tt.panicMsg)
88+
assert.Panics[E](t, func() { _ = qb.Query() }, tt.panicMsg)
9589
})
9690
}
9791
}

example_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ func run(ctx context.Context) error {
4242
}
4343

4444
// select first_name, last_name, created_at from users where created_at >= $1
45-
rows, err := db.QueryContext(ctx, qb.String(), qb.Args...)
45+
rows, err := db.QueryContext(ctx, qb.Query(), qb.Args()...)
4646
if err != nil {
4747
return err
4848
}

0 commit comments

Comments
 (0)