diff --git a/config.go b/config.go index cf72cbd..474f960 100644 --- a/config.go +++ b/config.go @@ -2,6 +2,7 @@ package sqlite3 import ( "context" + "fmt" "strconv" "github.com/tetratelabs/wazero/api" @@ -70,6 +71,15 @@ func logCallback(ctx context.Context, mod api.Module, _, iCode, zMsg uint32) { } } +// Log writes a message into the error log established by [Conn.ConfigLog]. +// +// https://sqlite.org/c3ref/log.html +func (c *Conn) Log(code ExtendedErrorCode, format string, a ...any) { + if c.log != nil { + c.log(code, fmt.Sprintf(format, a...)) + } +} + // FileControl allows low-level control of database files. // Only a subset of opcodes are supported. // diff --git a/error.go b/error.go index 71238ef..870aa3a 100644 --- a/error.go +++ b/error.go @@ -106,6 +106,11 @@ func (e ErrorCode) Temporary() bool { return e == BUSY } +// ExtendedCode returns the extended error code for this error. +func (e ErrorCode) ExtendedCode() ExtendedErrorCode { + return ExtendedErrorCode(e) +} + // Error implements the error interface. func (e ExtendedErrorCode) Error() string { return util.ErrorCodeString(uint32(e)) @@ -136,6 +141,11 @@ func (e ExtendedErrorCode) Timeout() bool { return e == BUSY_TIMEOUT } +// Code returns the primary error code for this error. +func (e ExtendedErrorCode) Code() ErrorCode { + return ErrorCode(e) +} + func errorCode(err error, def ErrorCode) (msg string, code uint32) { switch code := err.(type) { case nil: diff --git a/tests/config_test.go b/tests/config_test.go index a7ddb92..4272ad3 100644 --- a/tests/config_test.go +++ b/tests/config_test.go @@ -87,9 +87,15 @@ func TestConn_ConfigLog(t *testing.T) { db.Prepare(`SELECT * FRM sqlite_schema`) - if code != sqlite3.ExtendedErrorCode(sqlite3.ERROR) { + if code != sqlite3.ERROR.ExtendedCode() { t.Error("want sqlite3.ERROR") } + + db.Log(sqlite3.NOTICE.ExtendedCode(), "") + + if code.Code() != sqlite3.NOTICE { + t.Error("want sqlite3.NOTICE") + } } func TestConn_FileControl(t *testing.T) {