Documentation.

This commit is contained in:
Nuno Cruces
2023-03-01 10:34:08 +00:00
parent e64bffa520
commit c7165a2e56
10 changed files with 49 additions and 30 deletions

View File

@@ -9,6 +9,8 @@ type ZeroBlob int64
// Blob is a handle to an open BLOB.
//
// It implements [io.ReadWriteSeeker] for incremental BLOB I/O.
//
// https://www.sqlite.org/c3ref/blob.html
type Blob struct {
c *Conn
@@ -50,7 +52,7 @@ func (c *Conn) OpenBlob(db, table, column string, row int64, write bool) (*Blob,
// Close closes a BLOB handle.
//
// It is safe to close a nil, zero or closed BLOB handle.
// It is safe to close a nil, zero or closed Blob.
//
// https://www.sqlite.org/c3ref/blob_close.html
func (b *Blob) Close() error {

View File

@@ -13,9 +13,14 @@ import (
"github.com/tetratelabs/wazero/api"
)
// Configure SQLite.
// Configure SQLite WASM.
//
// Importing package embed initializes these
// with an appropriate build of SQLite:
//
// import _ "github.com/ncruces/go-sqlite3/embed"
var (
Binary []byte // Binary to load.
Binary []byte // WASM binary to load.
Path string // Path to load the binary from.
)

20
conn.go
View File

@@ -13,6 +13,7 @@ import (
)
// Conn is a database connection handle.
// A Conn is not safe for concurrent use by multiple goroutines.
//
// https://www.sqlite.org/c3ref/sqlite3.html
type Conn struct {
@@ -92,7 +93,7 @@ func OpenFlags(filename string, flags OpenFlag) (conn *Conn, err error) {
// open blob handles, and/or unfinished backup objects,
// Close will leave the database connection open and return [BUSY].
//
// It is safe to close a nil, zero or closed connection.
// It is safe to close a nil, zero or closed Conn.
//
// https://www.sqlite.org/c3ref/close.html
func (c *Conn) Close() error {
@@ -125,12 +126,15 @@ func (c *Conn) Exec(sql string) error {
}
// MustPrepare calls [Conn.Prepare] and panics on error,
// or a non empty tail.
// a nil Stmt, or a non-empty tail.
func (c *Conn) MustPrepare(sql string) *Stmt {
s, tail, err := c.PrepareFlags(sql, 0)
if err != nil {
panic(err)
}
if s == nil {
panic(emptyErr)
}
if !emptyStatement(tail) {
panic(tailErr)
}
@@ -208,7 +212,7 @@ func (c *Conn) Changes() int64 {
// Subsequent uses of the connection will return [INTERRUPT]
// until the context is reset by another call to SetInterrupt.
//
// For example, a timeout can be associated with a connection:
// To associate a timeout with a connection:
//
// ctx, cancel := context.WithTimeout(context.TODO(), 100*time.Millisecond)
// conn.SetInterrupt(ctx)
@@ -287,7 +291,7 @@ func (c *Conn) sendInterrupt() {
c.call(c.api.interrupt, uint64(c.handle))
}
// Pragma executes a PRAGMA statement and returns any result as a string.
// Pragma executes a PRAGMA statement and returns any results.
//
// https://www.sqlite.org/pragma.html
func (c *Conn) Pragma(str string) []string {
@@ -430,7 +434,13 @@ func (a *arena) string(s string) uint32 {
return ptr
}
// DriverConn is implemented by the SQLite database/sql driver connection.
// DriverConn is implemented by the SQLite [database/sql] driver connection.
//
// It can be used to access advanced SQLite features like
// [savepoints] and [incremental BLOB I/O].
//
// [savepoints]: https://www.sqlite.org/lang_savepoint.html
// [incremental BLOB I/O]: https://www.sqlite.org/c3ref/blob_open.html
type DriverConn interface {
driver.ConnBeginTx
driver.ExecerContext

View File

@@ -5,23 +5,25 @@ import (
"database/sql"
"fmt"
"log"
"os"
"github.com/ncruces/go-sqlite3"
_ "github.com/ncruces/go-sqlite3/driver"
_ "github.com/ncruces/go-sqlite3/embed"
)
const demo = "demo.db"
var db *sql.DB
func ExampleDriverConn() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
db, err := sql.Open("sqlite3", demo)
var err error
db, err = sql.Open("sqlite3", "demo.db")
if err != nil {
log.Fatal(err)
}
defer db.Close()
defer os.Remove("demo.db")
ctx := context.Background()
conn, err := db.Conn(ctx)
if err != nil {
@@ -34,12 +36,12 @@ func ExampleDriverConn() {
log.Fatal(err)
}
r, err := conn.ExecContext(ctx, `INSERT INTO test VALUES (?)`, sqlite3.ZeroBlob(11))
res, err := conn.ExecContext(ctx, `INSERT INTO test VALUES (?)`, sqlite3.ZeroBlob(11))
if err != nil {
log.Fatal(err)
}
id, err := r.LastInsertId()
id, err := res.LastInsertId()
if err != nil {
log.Fatal(err)
}

View File

@@ -52,7 +52,7 @@ func (e *Error) Error() string {
// Is tests whether this error matches a given [ErrorCode] or [ExtendedErrorCode].
//
// This makes it possible to do:
// It makes it possible to do:
//
// if errors.Is(err, sqlite3.BUSY) {
// // ... handle BUSY
@@ -201,6 +201,7 @@ const (
noFuncErr = errorString("sqlite3: could not find function: ")
binaryErr = errorString("sqlite3: no SQLite binary embed/set/loaded")
timeErr = errorString("sqlite3: invalid time value")
emptyErr = errorString("sqlite3: empty statement")
tailErr = errorString("sqlite3: non-empty tail")
notImplErr = errorString("sqlite3: not implemented")
whenceErr = errorString("sqlite3: invalid whence")

View File

@@ -26,10 +26,7 @@ func Example() {
log.Fatal(err)
}
stmt, _, err := db.Prepare(`SELECT id, name FROM users`)
if err != nil {
log.Fatal(err)
}
stmt := db.MustPrepare(`SELECT id, name FROM users`)
for stmt.Step() {
fmt.Println(stmt.ColumnInt(0), stmt.ColumnText(1))

View File

@@ -16,7 +16,7 @@ type Stmt struct {
// Close destroys the prepared statement object.
//
// It is safe to close a nil, zero or closed prepared statement.
// It is safe to close a nil, zero or closed Stmt.
//
// https://www.sqlite.org/c3ref/finalize.html
func (s *Stmt) Close() error {

View File

@@ -213,12 +213,8 @@ func TestConn_MustPrepare_empty(t *testing.T) {
defer db.Close()
defer func() { _ = recover() }()
stmt := db.MustPrepare(``)
defer stmt.Close()
if stmt != nil {
t.Error("want nil")
}
_ = db.MustPrepare(``)
t.Error("want panic")
}
func TestConn_MustPrepare_tail(t *testing.T) {

View File

@@ -68,7 +68,7 @@ const (
//
// Time values encoded with [time.RFC3339Nano] cannot be sorted as strings
// to produce a time-ordered sequence.
// Use [TimeFormat7TZ] for time-ordered encoding.
// Use [TimeFormat7] for time-ordered encoding.
//
// Formats [TimeFormat1] through [TimeFormat10]
// convert time values to UTC before encoding.

10
tx.go
View File

@@ -44,7 +44,7 @@ func (c *Conn) BeginExclusive() (Tx, error) {
return Tx{c}, nil
}
// End calls either [Commit] or [Rollback]
// End calls either [Tx.Commit] or [Tx.Rollback]
// depending on whether *error points to a nil or non-nil error.
//
// This is meant to be deferred:
@@ -56,7 +56,7 @@ func (c *Conn) BeginExclusive() (Tx, error) {
// // ... do work in the transaction
// }
//
// https://www.sqlite.org/lang_savepoint.html
// https://www.sqlite.org/lang_transaction.html
func (tx Tx) End(errp *error) {
recovered := recover()
if recovered != nil {
@@ -84,10 +84,16 @@ func (tx Tx) End(errp *error) {
}
}
// Commit commits the transaction.
//
// https://www.sqlite.org/lang_transaction.html
func (tx Tx) Commit() error {
return tx.c.Exec(`COMMIT`)
}
// Rollback rollsback the transaction.
//
// https://www.sqlite.org/lang_transaction.html
func (tx Tx) Rollback() error {
// ROLLBACK even if the connection has been interrupted.
old := tx.c.SetInterrupt(context.Background())