Skip to content

Commit e8b44fe

Browse files
committed
exec and query funcs
1 parent 0988a93 commit e8b44fe

File tree

5 files changed

+145
-117
lines changed

5 files changed

+145
-117
lines changed

examples/nullvalues/main.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,16 @@ func main() {
2222
defer sq.MustExecSql("DROP TABLE users")
2323

2424
// Insert users, some with NULL values.
25-
sq.MustExecParams("INSERT INTO users (id, name) VALUES (?, ?)", [][]any{
26-
{1, "Alice"},
27-
{2, nil},
28-
{3, nil},
25+
sq.MustExecParams("INSERT INTO users (id, name) VALUES (?, ?)", 3, 2, []sqinn.Value{
26+
sqinn.Int32Value(1), sqinn.StringValue("Alice"),
27+
sqinn.Int32Value(2), sqinn.NullValue(),
28+
sqinn.Int32Value(3), sqinn.NullValue(),
2929
})
3030

3131
// Query users, be aware that name can be NULL.
3232
rows := sq.MustQueryRows(
3333
"SELECT id, name FROM users WHERE id >= ? ORDER BY id",
34-
[]any{0}, // query parameters
34+
[]sqinn.Value{sqinn.Int32Value(0)}, // query parameters
3535
[]byte{sqinn.ValInt32, sqinn.ValString}, // fetch id as int, name as string
3636
)
3737
for _, values := range rows {

examples/simple/main.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,16 @@ func main() {
2121
defer sq.MustExecSql("DROP TABLE users")
2222
//
2323
// Insert users
24-
sq.MustExecParams("INSERT INTO users (id, name) VALUES (?, ?)", [][]any{
25-
{1, "Alice"},
26-
{2, "Bob"},
27-
{3, "Carol"},
24+
sq.MustExecParams("INSERT INTO users (id, name) VALUES (?, ?)", 3, 2, []sqinn.Value{
25+
sqinn.Int32Value(1), sqinn.StringValue("Alice"),
26+
sqinn.Int32Value(2), sqinn.StringValue("Bob"),
27+
sqinn.Int32Value(3), sqinn.StringValue("Carol"),
2828
})
2929
//
3030
// Query users
3131
rows := sq.MustQueryRows(
3232
"SELECT id, name FROM users WHERE id >= ? ORDER BY id",
33-
[]any{0}, // query parameters
33+
[]sqinn.Value{sqinn.Int32Value(0)}, // query parameters
3434
[]byte{sqinn.ValInt32, sqinn.ValString}, // fetch id as int, name as string
3535
)
3636
for _, values := range rows {

go.sum

Whitespace-only changes.

sqinn.go

Lines changed: 65 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,8 @@ func MustLaunch(opt Options) *Sqinn {
162162
// once for each iteration.
163163
// Iteration is the iteration index, starting at 0.
164164
// Params is a slice that holds parameter values for this iteration,
165-
// and should be set by the function body.
166-
type ProduceFunc func(iteration int, params []any)
165+
// and must be set by the function body.
166+
type ProduceFunc func(iteration int, params []Value)
167167

168168
// Exec executes a SQL statement, possibly multiple times.
169169
//
@@ -200,10 +200,10 @@ func (sq *Sqinn) Exec(sql string, niterations, nparams int, produce ProduceFunc)
200200
sq.w.writeInt32(niterations) // int niterations
201201
sq.w.writeInt32(nparams) // int nparams
202202
if nparams > 0 {
203-
params := make([]any, nparams)
203+
params := make([]Value, nparams)
204204
for iteration := range niterations {
205205
produce(iteration, params)
206-
sq.writeParams(params) // []value params
206+
sq.writeParams(params)
207207
if err := sq.w.markFrame(); err != nil {
208208
return err
209209
}
@@ -216,35 +216,36 @@ func (sq *Sqinn) Exec(sql string, niterations, nparams int, produce ProduceFunc)
216216
}
217217

218218
// MustExec is the same as Exec except it panics on error.
219-
func (sq *Sqinn) MustExec(sql string, niterations, nparams int, produce func(iteration int, params []any)) {
219+
func (sq *Sqinn) MustExec(sql string, niterations, nparams int, produce ProduceFunc) {
220220
must(0, sq.Exec(sql, niterations, nparams, produce))
221221
}
222222

223-
// ExecParams calls Exec with the provided paramRows.
224-
func (sq *Sqinn) ExecParams(sql string, paramRows [][]any) error {
225-
niterations := len(paramRows)
223+
// ExecParams calls Exec with the provided params.
224+
// The length of the params slice must be niterations * nparams.
225+
func (sq *Sqinn) ExecParams(sql string, niterations, nparams int, params []Value) error {
226+
// check len(params)
227+
if len(params) != niterations*nparams {
228+
panic(fmt.Sprintf("want %d x %d params but have %d", niterations, nparams, len(params)))
229+
}
230+
// nothing to do if niterations is 0
226231
if niterations == 0 {
227-
// nothing to do
228232
return nil
229233
}
230-
nparams := len(paramRows[0])
231-
// all paramRows must have same length
232-
for _, params := range paramRows {
233-
if len(params) != nparams {
234-
panic("all paramRows must have same length")
234+
return sq.Exec(sql, niterations, nparams, func(iteration int, iterationParams []Value) {
235+
if len(iterationParams) != nparams {
236+
panic(fmt.Sprintf("internal error: want %d iterationParams, but have only %d", nparams, len(iterationParams)))
235237
}
236-
}
237-
return sq.Exec(sql, niterations, nparams, func(iteration int, iterationParams []any) {
238-
n := copy(iterationParams, paramRows[iteration])
238+
offset := iteration * nparams
239+
n := copy(iterationParams, params[offset:offset+nparams])
239240
if n != nparams {
240241
panic(fmt.Sprintf("internal error: want %d params copied, but have only %d", nparams, n))
241242
}
242243
})
243244
}
244245

245246
// MustExecParams is the same as ExecParams except it panics on error.
246-
func (sq *Sqinn) MustExecParams(sql string, paramRows [][]any) {
247-
must(0, sq.ExecParams(sql, paramRows))
247+
func (sq *Sqinn) MustExecParams(sql string, niterations, nparams int, params []Value) {
248+
must(0, sq.ExecParams(sql, niterations, nparams, params))
248249
}
249250

250251
// ExecSql is the same as Exec(sql,1,0,nil).
@@ -269,7 +270,7 @@ type ConsumeFunc func(row int, values []Value)
269270
// Coltypes defines the types of the columns to be fetched.
270271
//
271272
// Consume is called exactly once for each result row.
272-
func (sq *Sqinn) Query(sql string, params []any, coltypes []byte, consume ConsumeFunc) error {
273+
func (sq *Sqinn) Query(sql string, params []Value, coltypes []byte, consume ConsumeFunc) error {
273274
ncols := len(coltypes)
274275
if ncols == 0 {
275276
panic("no coltypes")
@@ -278,7 +279,7 @@ func (sq *Sqinn) Query(sql string, params []any, coltypes []byte, consume Consum
278279
panic("no consume func")
279280
}
280281
for _, param := range params {
281-
if param == nil {
282+
if param.Type == ValNull {
282283
panic("nil param not allowed in Query")
283284
}
284285
}
@@ -343,8 +344,13 @@ func (sq *Sqinn) Query(sql string, params []any, coltypes []byte, consume Consum
343344
return sq.readOk()
344345
}
345346

347+
// MustQuery is the same as Query except it panics on error.
348+
func (sq *Sqinn) MustQuery(sql string, params []Value, coltypes []byte, consume ConsumeFunc) {
349+
must(0, sq.Query(sql, params, coltypes, consume))
350+
}
351+
346352
// QueryRows is like Query but consumes all rows and returns them in a [][]Value array.
347-
func (sq *Sqinn) QueryRows(sql string, params []any, coltypes []byte) ([][]Value, error) {
353+
func (sq *Sqinn) QueryRows(sql string, params []Value, coltypes []byte) ([][]Value, error) {
348354
var rows [][]Value
349355
err := sq.Query(sql, params, coltypes, func(row int, values []Value) {
350356
vals := append(make([]Value, 0, len(values)), values...)
@@ -354,7 +360,7 @@ func (sq *Sqinn) QueryRows(sql string, params []any, coltypes []byte) ([][]Value
354360
}
355361

356362
// MustQueryRows is the same as QueryRows except it panics on error.
357-
func (sq *Sqinn) MustQueryRows(sql string, params []any, coltypes []byte) [][]Value {
363+
func (sq *Sqinn) MustQueryRows(sql string, params []Value, coltypes []byte) [][]Value {
358364
return must(sq.QueryRows(sql, params, coltypes))
359365
}
360366

@@ -391,33 +397,27 @@ func (sq *Sqinn) readOk() error {
391397
if err != nil {
392398
return err
393399
}
394-
return fmt.Errorf("%s", errmsg)
400+
return fmt.Errorf("sqinn: %s", errmsg)
395401
}
396402

397-
func (sq *Sqinn) writeParams(params []any) {
403+
func (sq *Sqinn) writeParams(params []Value) {
398404
for _, p := range params {
399-
if p == nil {
400-
sq.w.writeByte(ValNull)
401-
} else {
402-
switch v := p.(type) {
403-
case int:
404-
sq.w.writeByte(ValInt32)
405-
sq.w.writeInt32(int(v))
406-
case int64:
407-
sq.w.writeByte(ValInt64)
408-
sq.w.writeInt64(v)
409-
case float64:
410-
sq.w.writeByte(ValDouble)
411-
sq.w.writeDouble(float64(v))
412-
case string:
413-
sq.w.writeByte(ValString)
414-
sq.w.writeString(v)
415-
case []byte:
416-
sq.w.writeByte(ValBlob)
417-
sq.w.writeBlob(v)
418-
default:
419-
panic(fmt.Sprintf("unknown param type %T", v))
420-
}
405+
sq.w.writeByte(p.Type)
406+
switch p.Type {
407+
case ValNull:
408+
// no furhter data
409+
case ValInt32:
410+
sq.w.writeInt32(p.Int32)
411+
case ValInt64:
412+
sq.w.writeInt64(p.Int64)
413+
case ValDouble:
414+
sq.w.writeDouble(p.Double)
415+
case ValString:
416+
sq.w.writeString(p.String)
417+
case ValBlob:
418+
sq.w.writeBlob(p.Blob)
419+
default:
420+
panic(fmt.Sprintf("unknown param value type %T", p.Type))
421421
}
422422
}
423423
}
@@ -438,6 +438,24 @@ type Value struct {
438438
Blob []byte // For ValBlob
439439
}
440440

441+
// NullValue creates a Value with type ValNull.
442+
func NullValue() Value { return Value{Type: ValNull} }
443+
444+
// Int32Value creates a Value with type ValInt32.
445+
func Int32Value(v int) Value { return Value{Type: ValInt32, Int32: v} }
446+
447+
// Int64Value creates a Value with type ValInt64.
448+
func Int64Value(v int64) Value { return Value{Type: ValInt64, Int64: v} }
449+
450+
// DoubleValue creates a Value with type ValDouble.
451+
func DoubleValue(v float64) Value { return Value{Type: ValDouble, Double: v} }
452+
453+
// StringValue creates a Value with type ValString.
454+
func StringValue(v string) Value { return Value{Type: ValString, String: v} }
455+
456+
// BlobValue creates a Value with type ValBlob.
457+
func BlobValue(v []byte) Value { return Value{Type: ValBlob, Blob: v} }
458+
441459
// Value types.
442460
const (
443461
ValNull = 0

0 commit comments

Comments
 (0)