1// Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>. 2// 3// Use of this source code is governed by an MIT-style 4// license that can be found in the LICENSE file. 5 6package sqlite3 7 8/* 9 10#ifndef USE_LIBSQLITE3 11#include <sqlite3-binding.h> 12#else 13#include <sqlite3.h> 14#endif 15#include <stdlib.h> 16// These wrappers are necessary because SQLITE_TRANSIENT 17// is a pointer constant, and cgo doesn't translate them correctly. 18 19static inline void my_result_text(sqlite3_context *ctx, char *p, int np) { 20 sqlite3_result_text(ctx, p, np, SQLITE_TRANSIENT); 21} 22 23static inline void my_result_blob(sqlite3_context *ctx, void *p, int np) { 24 sqlite3_result_blob(ctx, p, np, SQLITE_TRANSIENT); 25} 26*/ 27import "C" 28 29import ( 30 "math" 31 "reflect" 32 "unsafe" 33) 34 35const i64 = unsafe.Sizeof(int(0)) > 4 36 37// SQLiteContext behave sqlite3_context 38type SQLiteContext C.sqlite3_context 39 40// ResultBool sets the result of an SQL function. 41func (c *SQLiteContext) ResultBool(b bool) { 42 if b { 43 c.ResultInt(1) 44 } else { 45 c.ResultInt(0) 46 } 47} 48 49// ResultBlob sets the result of an SQL function. 50// See: sqlite3_result_blob, http://sqlite.org/c3ref/result_blob.html 51func (c *SQLiteContext) ResultBlob(b []byte) { 52 if i64 && len(b) > math.MaxInt32 { 53 C.sqlite3_result_error_toobig((*C.sqlite3_context)(c)) 54 return 55 } 56 var p *byte 57 if len(b) > 0 { 58 p = &b[0] 59 } 60 C.my_result_blob((*C.sqlite3_context)(c), unsafe.Pointer(p), C.int(len(b))) 61} 62 63// ResultDouble sets the result of an SQL function. 64// See: sqlite3_result_double, http://sqlite.org/c3ref/result_blob.html 65func (c *SQLiteContext) ResultDouble(d float64) { 66 C.sqlite3_result_double((*C.sqlite3_context)(c), C.double(d)) 67} 68 69// ResultInt sets the result of an SQL function. 70// See: sqlite3_result_int, http://sqlite.org/c3ref/result_blob.html 71func (c *SQLiteContext) ResultInt(i int) { 72 if i64 && (i > math.MaxInt32 || i < math.MinInt32) { 73 C.sqlite3_result_int64((*C.sqlite3_context)(c), C.sqlite3_int64(i)) 74 } else { 75 C.sqlite3_result_int((*C.sqlite3_context)(c), C.int(i)) 76 } 77} 78 79// ResultInt64 sets the result of an SQL function. 80// See: sqlite3_result_int64, http://sqlite.org/c3ref/result_blob.html 81func (c *SQLiteContext) ResultInt64(i int64) { 82 C.sqlite3_result_int64((*C.sqlite3_context)(c), C.sqlite3_int64(i)) 83} 84 85// ResultNull sets the result of an SQL function. 86// See: sqlite3_result_null, http://sqlite.org/c3ref/result_blob.html 87func (c *SQLiteContext) ResultNull() { 88 C.sqlite3_result_null((*C.sqlite3_context)(c)) 89} 90 91// ResultText sets the result of an SQL function. 92// See: sqlite3_result_text, http://sqlite.org/c3ref/result_blob.html 93func (c *SQLiteContext) ResultText(s string) { 94 h := (*reflect.StringHeader)(unsafe.Pointer(&s)) 95 cs, l := (*C.char)(unsafe.Pointer(h.Data)), C.int(h.Len) 96 C.my_result_text((*C.sqlite3_context)(c), cs, l) 97} 98 99// ResultZeroblob sets the result of an SQL function. 100// See: sqlite3_result_zeroblob, http://sqlite.org/c3ref/result_blob.html 101func (c *SQLiteContext) ResultZeroblob(n int) { 102 C.sqlite3_result_zeroblob((*C.sqlite3_context)(c), C.int(n)) 103} 104