mirror of
https://github.com/ncruces/go-sqlite3.git
synced 2026-01-11 21:49:13 +00:00
Error logging.
This commit is contained in:
32
config.go
32
config.go
@@ -1,9 +1,14 @@
|
|||||||
package sqlite3
|
package sqlite3
|
||||||
|
|
||||||
import "github.com/ncruces/go-sqlite3/internal/util"
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/ncruces/go-sqlite3/internal/util"
|
||||||
|
"github.com/tetratelabs/wazero/api"
|
||||||
|
)
|
||||||
|
|
||||||
// Config makes configuration changes to a database connection.
|
// Config makes configuration changes to a database connection.
|
||||||
// Only bool configuratiton options are supported.
|
// Only boolean configuration options are supported.
|
||||||
// Called with no arg reads the current configuration value,
|
// Called with no arg reads the current configuration value,
|
||||||
// called with one arg sets and returns the new value.
|
// called with one arg sets and returns the new value.
|
||||||
//
|
//
|
||||||
@@ -27,3 +32,26 @@ func (c *Conn) Config(op DBConfig, arg ...bool) (bool, error) {
|
|||||||
uint64(op), uint64(argsPtr))
|
uint64(op), uint64(argsPtr))
|
||||||
return util.ReadUint32(c.mod, argsPtr) != 0, c.error(r)
|
return util.ReadUint32(c.mod, argsPtr) != 0, c.error(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ConfigLog sets up the error logging callback for the connection.
|
||||||
|
//
|
||||||
|
// https://www.sqlite.org/errlog.html
|
||||||
|
func (c *Conn) ConfigLog(cb func(code ExtendedErrorCode, msg string)) error {
|
||||||
|
var enable uint64
|
||||||
|
if cb != nil {
|
||||||
|
enable = 1
|
||||||
|
}
|
||||||
|
r := c.call("sqlite3_config_log_go", enable)
|
||||||
|
if err := c.error(r); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
c.log = cb
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func logCallback(ctx context.Context, mod api.Module, _, iCode, zMsg uint32) {
|
||||||
|
if c, ok := ctx.Value(connKey{}).(*Conn); ok && c.log != nil {
|
||||||
|
msg := util.ReadString(mod, zMsg, _MAX_LENGTH)
|
||||||
|
c.log(xErrorCode(iCode), msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
13
conn.go
13
conn.go
@@ -20,6 +20,7 @@ type Conn struct {
|
|||||||
|
|
||||||
interrupt context.Context
|
interrupt context.Context
|
||||||
pending *Stmt
|
pending *Stmt
|
||||||
|
log func(code xErrorCode, msg string)
|
||||||
arena arena
|
arena arena
|
||||||
|
|
||||||
handle uint32
|
handle uint32
|
||||||
@@ -258,6 +259,12 @@ func (c *Conn) SetInterrupt(ctx context.Context) (old context.Context) {
|
|||||||
return old
|
return old
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Conn) checkInterrupt() {
|
||||||
|
if c.interrupt != nil && c.interrupt.Err() != nil {
|
||||||
|
c.call("sqlite3_interrupt", uint64(c.handle))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func progressCallback(ctx context.Context, mod api.Module, _ uint32) uint32 {
|
func progressCallback(ctx context.Context, mod api.Module, _ uint32) uint32 {
|
||||||
if c, ok := ctx.Value(connKey{}).(*Conn); ok {
|
if c, ok := ctx.Value(connKey{}).(*Conn); ok {
|
||||||
if c.interrupt != nil && c.interrupt.Err() != nil {
|
if c.interrupt != nil && c.interrupt.Err() != nil {
|
||||||
@@ -267,12 +274,6 @@ func progressCallback(ctx context.Context, mod api.Module, _ uint32) uint32 {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Conn) checkInterrupt() {
|
|
||||||
if c.interrupt != nil && c.interrupt.Err() != nil {
|
|
||||||
c.call("sqlite3_interrupt", uint64(c.handle))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pragma executes a PRAGMA statement and returns any results.
|
// Pragma executes a PRAGMA statement and returns any results.
|
||||||
//
|
//
|
||||||
// https://sqlite.org/pragma.html
|
// https://sqlite.org/pragma.html
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ sqlite3_column_name
|
|||||||
sqlite3_column_text
|
sqlite3_column_text
|
||||||
sqlite3_column_type
|
sqlite3_column_type
|
||||||
sqlite3_column_value
|
sqlite3_column_value
|
||||||
|
sqlite3_config_log_go
|
||||||
sqlite3_create_aggregate_function_go
|
sqlite3_create_aggregate_function_go
|
||||||
sqlite3_create_collation_go
|
sqlite3_create_collation_go
|
||||||
sqlite3_create_function_go
|
sqlite3_create_function_go
|
||||||
|
|||||||
Binary file not shown.
@@ -53,18 +53,18 @@ func (d fsdir) Open() (sqlite3.VTabCursor, error) {
|
|||||||
|
|
||||||
type cursor struct {
|
type cursor struct {
|
||||||
fsys fs.FS
|
fsys fs.FS
|
||||||
base string
|
|
||||||
rowID int64
|
|
||||||
eof bool
|
|
||||||
curr entry
|
curr entry
|
||||||
next chan entry
|
next chan entry
|
||||||
done chan struct{}
|
done chan struct{}
|
||||||
|
base string
|
||||||
|
rowID int64
|
||||||
|
eof bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type entry struct {
|
type entry struct {
|
||||||
path string
|
|
||||||
fs.DirEntry
|
fs.DirEntry
|
||||||
err error
|
err error
|
||||||
|
path string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cursor) Close() error {
|
func (c *cursor) Close() error {
|
||||||
@@ -180,7 +180,7 @@ func (c *cursor) WalkDirFunc(path string, d fs.DirEntry, err error) error {
|
|||||||
select {
|
select {
|
||||||
case <-c.done:
|
case <-c.done:
|
||||||
return fs.SkipAll
|
return fs.SkipAll
|
||||||
case c.next <- entry{path, d, err}:
|
case c.next <- entry{d, err, path}:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -282,6 +282,7 @@ func (a *arena) string(s string) uint32 {
|
|||||||
|
|
||||||
func exportCallbacks(env wazero.HostModuleBuilder) wazero.HostModuleBuilder {
|
func exportCallbacks(env wazero.HostModuleBuilder) wazero.HostModuleBuilder {
|
||||||
util.ExportFuncII(env, "go_progress", progressCallback)
|
util.ExportFuncII(env, "go_progress", progressCallback)
|
||||||
|
util.ExportFuncVIII(env, "go_log", logCallback)
|
||||||
util.ExportFuncVI(env, "go_destroy", destroyCallback)
|
util.ExportFuncVI(env, "go_destroy", destroyCallback)
|
||||||
util.ExportFuncVIII(env, "go_func", funcCallback)
|
util.ExportFuncVIII(env, "go_func", funcCallback)
|
||||||
util.ExportFuncVIII(env, "go_step", stepCallback)
|
util.ExportFuncVIII(env, "go_step", stepCallback)
|
||||||
|
|||||||
9
sqlite3/log.c
Normal file
9
sqlite3/log.c
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "sqlite3.h"
|
||||||
|
|
||||||
|
void go_log(void*, int, const char*);
|
||||||
|
|
||||||
|
int sqlite3_config_log_go(bool enable) {
|
||||||
|
return sqlite3_config(SQLITE_CONFIG_LOG, enable ? go_log : NULL, NULL);
|
||||||
|
}
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
#include "ext/uuid.c"
|
#include "ext/uuid.c"
|
||||||
// Bindings
|
// Bindings
|
||||||
#include "func.c"
|
#include "func.c"
|
||||||
|
#include "log.c"
|
||||||
#include "pointer.c"
|
#include "pointer.c"
|
||||||
#include "progress.c"
|
#include "progress.c"
|
||||||
#include "time.c"
|
#include "time.c"
|
||||||
|
|||||||
@@ -339,3 +339,28 @@ func TestConn_Config(t *testing.T) {
|
|||||||
t.Error("want false")
|
t.Error("want false")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestConn_ConfigLog(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
db, err := sqlite3.Open(":memory:")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
var code sqlite3.ExtendedErrorCode
|
||||||
|
err = db.ConfigLog(func(c sqlite3.ExtendedErrorCode, msg string) {
|
||||||
|
t.Log(msg)
|
||||||
|
code = c
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
db.Prepare(`SELECT * FRM sqlite_schema`)
|
||||||
|
|
||||||
|
if code != sqlite3.ExtendedErrorCode(sqlite3.ERROR) {
|
||||||
|
t.Error("want sqlite3.ERROR")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user