From 90628ab8aa4e2d2919edd27afcd74ddfcf530e22 Mon Sep 17 00:00:00 2001 From: Nuno Cruces Date: Fri, 10 Nov 2023 13:42:11 +0000 Subject: [PATCH] Text as byte slices. --- context.go | 17 ++++++++++++----- ext/unicode/unicode.go | 8 ++++---- func_test.go | 2 +- stmt.go | 20 ++++++++++++++------ 4 files changed, 31 insertions(+), 16 deletions(-) diff --git a/context.go b/context.go index 5eaabf2..601c37e 100644 --- a/context.go +++ b/context.go @@ -89,6 +89,16 @@ func (ctx Context) ResultText(value string) { uint64(ctx.c.api.destructor), _UTF8) } +// ResultRawText sets the text result of the function to a []byte. +// +// https://sqlite.org/c3ref/result_blob.html +func (ctx Context) ResultRawText(value []byte) { + ptr := ctx.c.newBytes(value) + ctx.c.call(ctx.c.api.resultText, + uint64(ctx.handle), uint64(ptr), uint64(len(value)), + uint64(ctx.c.api.destructor), _UTF8) +} + // ResultBlob sets the result of the function to a []byte. // Returning a nil slice is the same as calling [Context.ResultNull]. // @@ -100,7 +110,7 @@ func (ctx Context) ResultBlob(value []byte) { uint64(ctx.c.api.destructor)) } -// BindZeroBlob sets the result of the function to a zero-filled, length n BLOB. +// ResultZeroBlob sets the result of the function to a zero-filled, length n BLOB. // // https://sqlite.org/c3ref/result_blob.html func (ctx Context) ResultZeroBlob(n int64) { @@ -166,10 +176,7 @@ func (ctx Context) ResultJSON(value any) { if err != nil { ctx.ResultError(err) } - ptr := ctx.c.newBytes(data) - ctx.c.call(ctx.c.api.resultText, - uint64(ctx.handle), uint64(ptr), uint64(len(data)), - uint64(ctx.c.api.destructor)) + ctx.ResultRawText(data) } // ResultValue sets the result of the function a copy of [Value]. diff --git a/ext/unicode/unicode.go b/ext/unicode/unicode.go index 809031b..778e8f5 100644 --- a/ext/unicode/unicode.go +++ b/ext/unicode/unicode.go @@ -66,7 +66,7 @@ func RegisterCollation(db *sqlite3.Conn, locale, name string) error { func upper(ctx sqlite3.Context, arg ...sqlite3.Value) { if len(arg) == 1 { - ctx.ResultBlob(bytes.ToUpper(arg[0].RawBlob())) + ctx.ResultRawText(bytes.ToUpper(arg[0].RawText())) return } cs, ok := ctx.GetAuxData(1).(cases.Caser) @@ -80,12 +80,12 @@ func upper(ctx sqlite3.Context, arg ...sqlite3.Value) { ctx.SetAuxData(1, c) cs = c } - ctx.ResultBlob(cs.Bytes(arg[0].RawBlob())) + ctx.ResultRawText(cs.Bytes(arg[0].RawText())) } func lower(ctx sqlite3.Context, arg ...sqlite3.Value) { if len(arg) == 1 { - ctx.ResultBlob(bytes.ToLower(arg[0].RawBlob())) + ctx.ResultRawText(bytes.ToLower(arg[0].RawText())) return } cs, ok := ctx.GetAuxData(1).(cases.Caser) @@ -99,7 +99,7 @@ func lower(ctx sqlite3.Context, arg ...sqlite3.Value) { ctx.SetAuxData(1, c) cs = c } - ctx.ResultBlob(cs.Bytes(arg[0].RawBlob())) + ctx.ResultRawText(cs.Bytes(arg[0].RawText())) } func regex(ctx sqlite3.Context, arg ...sqlite3.Value) { diff --git a/func_test.go b/func_test.go index 581e090..f2b4cf2 100644 --- a/func_test.go +++ b/func_test.go @@ -74,7 +74,7 @@ func ExampleConn_CreateFunction() { } err = db.CreateFunction("upper", 1, sqlite3.DETERMINISTIC|sqlite3.INNOCUOUS, func(ctx sqlite3.Context, arg ...sqlite3.Value) { - ctx.ResultBlob(bytes.ToUpper(arg[0].RawBlob())) + ctx.ResultRawText(bytes.ToUpper(arg[0].RawText())) }) if err != nil { log.Fatal(err) diff --git a/stmt.go b/stmt.go index d449669..f59cbfc 100644 --- a/stmt.go +++ b/stmt.go @@ -181,6 +181,19 @@ func (s *Stmt) BindText(param int, value string) error { return s.c.error(r) } +// BindRawText binds a []byte to the prepared statement as text. +// The leftmost SQL parameter has an index of 1. +// +// https://sqlite.org/c3ref/bind_blob.html +func (s *Stmt) BindRawText(param int, value []byte) error { + ptr := s.c.newBytes(value) + r := s.c.call(s.c.api.bindText, + uint64(s.handle), uint64(param), + uint64(ptr), uint64(len(value)), + uint64(s.c.api.destructor), _UTF8) + return s.c.error(r) +} + // BindBlob binds a []byte to the prepared statement. // The leftmost SQL parameter has an index of 1. // Binding a nil slice is the same as calling [Stmt.BindNull]. @@ -271,12 +284,7 @@ func (s *Stmt) BindJSON(param int, value any) error { if err != nil { return err } - ptr := s.c.newBytes(data) - r := s.c.call(s.c.api.bindText, - uint64(s.handle), uint64(param), - uint64(ptr), uint64(len(data)), - uint64(s.c.api.destructor), _UTF8) - return s.c.error(r) + return s.BindRawText(param, data) } // ColumnCount returns the number of columns in a result set.