sqlite

package module
v0.7.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 21, 2025 License: BSD-2-Clause Imports: 19 Imported by: 0

README

sqlite

Another take at persistence for Go Programs

Documentation

Overview

Package sqlite implements a driver over the SQLite database engine.

To get started, the Open and Conn.Exec methods should be sufficient, but do note that OpenPool is used throughout the server code.

The package API is designed to expose as possible of the underlying engine as possible, including the option to expose Gofunctions via RegisterFunc.

Example

A quick tour of the most important functions in the library

ctn, err := Open(MemoryPath)
if err != nil {
	log.Fatal("cannot open a temporary database", err)
}

ctx := context.Background()

sts := []string{
	"create table tbl1 (a primary key, b)",
	"insert into tbl1 (a, b) values ('hello','world'), ('bonjour','monde'), ('hola','mundo')",
}
for _, st := range sts {
	// Exec can be used for direct statements
	if err := ctn.Exec(ctx, st).Err(); err != nil {
		log.Fatal("cannot create table", err)
	}
}

// Scan to iterate over all results
rows := ctn.Exec(ctx, "select a, b from tbl1")
for rows.Next() {
	var a, b string
	rows.Scan(&a, &b)
	fmt.Println(a, b)
}
if rows.Err() != nil {
	log.Fatal("cannot query tbl1", rows.Err())
}

// ScanOne is a handy shortcut
var b string
if err := ctn.Exec(ctx, "select b from tbl1 where a = ?", "bonjour").ScanOne(&b); err != nil {
	log.Fatal("cannot find value matching \"bonjour\"")
}
fmt.Println(b)
Output:

hello world
bonjour monde
hola mundo
monde

Index

Examples

Constants

View Source
const MemoryPath = "file::memory:?mode=memory"

Variables

View Source
var BusyTransaction = errText[C.SQLITE_BUSY]
View Source
var DBName = "main"

DBName is the name of the database used in the application (main by default).

It can be changed before a back-up is started to reflect the application specificities.

View Source
var DuplicateRecords = errors.New("duplicate records in scanone")
View Source
var ErrNull = errors.New("null SQL value")

ErrNull is a sentinel value that can be returned by functions that want to return (or otherwise handle) null values

View Source
var NumThreads int
View Source
var ZombieTimeout = 30 * time.Second

ZombieTimeout is the time after which a transaction is considered leaked

Functions

func Backup added in v0.5.14

func Backup(ctn *Conn, dest string) error

Backup performs an [online backup] to dest

[online backup] https://www.sqlite.org/backup.html

func BackupDB

func BackupDB(pool *Connections, dest string) error

BackupDB performs an [online backup] to dest

[online backup] https://www.sqlite.org/backup.html

func GetBuffer

func GetBuffer() *bytes.Buffer

GetBuffer returns a bytes buffer from a system-wide pool. It is useful to avoid too much allocation when serializing. The buffer must be release with ReturnBuffer.

func IsComplete

func IsComplete(st string) bool

IsComplete returns true iff the statement is complete

func LoadExtensions

func LoadExtensions(db SQLITE3)

LoadExtensions loads all registered extensions against the database db. This function is automatically called when Open is, and is made available only for modules compiled as a shared library.

func Register

func Register(f ...func(SQLITE3))

Register adds a new statically compiled extension to register when a new SQLite connection is opened. It should be called in a sub-package init function.

Most of the time, f is going to be returned from RegisterFunc.

If not, due to the way CGO handles names bug-13467, callers need to wrap this in an unsafe pointer:

(*C.sqlite3)(unsafe.Pointer(db))

func RegisterFunc

func RegisterFunc(name string, t any) func(SQLITE3)

RegisterFunc binds a Go function as an application-defined SQL function. Functions can only be exposed if:

  1. Their inputs arguments are integer, text, bytes or a pointer to an arbitrary type
  2. Their name is not a registered SQL keyword
  3. They return either (1) no argument, (2) a single argument of type integer, text, bytes, error or PointerValue or (3) 2 arguments of which the first argument must be of type integer, text, bytes or PointerValue the second argument must be of type erorr.

func ReturnBuffer

func ReturnBuffer(b *bytes.Buffer)

ReturnBuffer returns the buffer to the pool. The buffer must not be used afterwards (this also mean the bytes returned from [bytes.buffer.Bytes]).

Types

type ColStrings

type ColStrings map[string]*string

ColStrings augments MultiString with the name of the columns. the pointer type is required to comply with Go’s addressability constraints on maps.

type Conn

type Conn struct {
	// contains filtered or unexported fields
}

Conn is a connection to a given database. Conn is safe for concurrent use.

Internally, Conn maps to an sqlite3 object, and present the same characteristics when not documented otherwise.

func Open

func Open(name string, exts ...func(SQLITE3)) (*Conn, error)

Open creates a new database connection stored at name, and load exts.

func ReadOnly added in v0.5.13

func ReadOnly(name string, exts ...func(SQLITE3)) (*Conn, error)

ReadOnly opens the database at name in read-only mode.

func (*Conn) AsPointer added in v0.7.0

func (ctn *Conn) AsPointer(v any) PointerValue

AsPointer is used to pass the value using the SQLite pointer passing interface. This interface is only useful for reading the value in virtual functions. The “pointer type” parameter will be derived from the underlying data type name.

func (*Conn) Close

func (c *Conn) Close() error

func (*Conn) CreateBLOB

func (cn *Conn) CreateBLOB(database, table, column string, size int) (*DirectBLOB, error)

CreateBLOB creates a new incremental I/O buffer. The database, table, and column are only quoted, and therefore should not be from untrusted inputs.

func (*Conn) EndTx added in v0.5.18

func (ctn *Conn) EndTx(ctx context.Context) error

End terminates (commits) the current transaction. If the transaction is terminated (whether by commit or rollback), it is a no-op

func (*Conn) Exec

func (c *Conn) Exec(ctx context.Context, cmd string, args ...any) *Rows

Exec executes cmd, optionally binding args to parameters in the query. Rows are a a cursor over the results, and the first row is already executed: commands needs not call Rows.Next afterwards. Arguments are matched by position.

This function will panic if the command is invalid SQL. This is intented for static SQL statements (written in your code), not for untrusted SQL.

func (*Conn) OpenBLOB

func (cn *Conn) OpenBLOB(database, table, column string, rownum int) (*DirectBLOB, error)

func (*Conn) RollbackTx added in v0.5.18

func (ctn *Conn) RollbackTx(ctx context.Context) error

Rollback undoes changes to the current transaction. If the transaction is terminated (whether by commit or rollback), it is a no-op.

type Connections

type Connections struct {
	// contains filtered or unexported fields
}

Connections is a pool of connections to a single SQLite database.

func OpenPool

func OpenPool(name string, exts ...func(SQLITE3)) (*Connections, error)

OpenPool ceates a new connection pool

func (*Connections) BeginTx added in v0.5.18

func (p *Connections) BeginTx(ctx context.Context) (context.Context, *Conn, func())

BeginTx starts a new deferred [transaction]. All queries in the connection before calling EndTx / RollbackTx are within the same transaction. The connection must not be used after the cleanup function was called.

ctx, tx, clean := p.BeginTx(ctx)
defer clean()

tx.Exec(ctx, …)
tx.EndTx(ctx)

[transaction] https://www.sqlite.org/lang_transaction.html

func (*Connections) Close

func (p *Connections) Close() error

Close closes all connections in the pool. It can be safely called concurrently [Connections.Savepoint], Connections.Exec and [Connections.Release] but note that calls to [Connections.Savepoint] or Connections.Exec that happen after Close might block forever. The mechanism to terminate other connections has to be done out of band.

func (*Connections) Exec

func (p *Connections) Exec(ctx context.Context, cmd string, args ...any) *Rows

func (*Connections) FreeCount added in v0.5.6

func (c *Connections) FreeCount() int

FreeCount returns the number of free connections in the pool

type DirectBLOB

type DirectBLOB struct {
	RowNumber int
	// contains filtered or unexported fields
}

ReadWriterAt is an incremental I/O buffer. It is mostly useful to work directly with binary formats in SQLite – so akin to mmap.

func (*DirectBLOB) Close

func (r *DirectBLOB) Close() error

func (*DirectBLOB) ReadAt

func (r *DirectBLOB) ReadAt(p []byte, off int64) (n int, err error)

func (*DirectBLOB) Size

func (r *DirectBLOB) Size() int

func (*DirectBLOB) WriteAt

func (r *DirectBLOB) WriteAt(p []byte, off int64) (n int, err error)

type MultiString

type MultiString []string

MultiString is used to read all values of a statement as string. This is useful if you don’t know ahead of time the values returned.

type NullString

type NullString string

NullString as a marker type: strings of length 0 will be set as null instead

type PointerValue

type PointerValue cgo.Handle

Marker type for values that should be passed as pointer. Most users will prefer [AsPointer].

type Rows

type Rows struct {
	// contains filtered or unexported fields
}

Rows are iterator structure over the underlying database statement results.

Rows are lightweigth object, and should not be reused after Rows.Err or Rows.ScanOne calls.

func NewErroredRows added in v0.5.12

func NewErroredRows(c *Conn, err error) *Rows

NewErroredRows create a collection of rows that will error on the first call. This is useful to pipeline call and only handle error at the end, e.g.:

ctn, err := sqlite.Open("/doesnotexist")
if err != nil {
  return NewErroredRows(c, err)
}
return ctn.Exec(ctx, "select * from table")

func (*Rows) Bytecode

func (r *Rows) Bytecode() string

Bytecodes outputs the detailed query plan through the SQLite bytecode operands. This is a fairly low-level operation, and is only really useful for troubleshooting. Even then, Rows.ExplainQueryPlan is usually a much better option.

func (*Rows) ColumnName

func (rows *Rows) ColumnName(i int) string

ColumnName return the ith (zero-based) column name. This is mostly convenient in a loop:

for i := 0; i < st.NumColumn(); i++ {
	buf.WriteString(st.ColumnName(i) + "\t")
}

func (*Rows) Err

func (r *Rows) Err() error

Err finalizes the statement, and return an error if any. Rows should not be used after this.

func (*Rows) ExplainQueryPlan

func (r *Rows) ExplainQueryPlan() string

QueryPlan returns the query plan of the existing statement under a graphical form.

func (*Rows) IsExplain

func (r *Rows) IsExplain() bool

IsExplain returns true iff the statement is an explain query plan command. This is the most important interface for debugging.

func (*Rows) Next

func (rows *Rows) Next() bool

Next advances the cursor to the next result in the set. It returns false if there are no more results, or if an error, or a timeout occur. Use Rows.Err to disambiguate between those cases.

func (*Rows) NumColumn

func (rows *Rows) NumColumn() int

NumColumn returns the count of columns returned by the current statement. Use Rows.ColumnName if the name is useful.

func (*Rows) Scan

func (rows *Rows) Scan(dst ...any)

Scan unmarshals the underlying SQLite value into a Go value. Values in dst are matched by position against the columns in the query, e.g.

 rows := ctn.Exec(ctx, "select a, b from t")
 for rows.Next() {
	var c, d string
	rows.Scan(&c, &d)
	// c -> column a
	// d -> column b
}

Scan defers errors to the Rows.Err method (but note that Rows.Next will stop at the first error).

Conversion is done depending on the SQLite type affinity and the type in Go. Richer Go types (e.g. bytes.Buffer, or time.Time) are automatically read too. Read the code for the full map – but if you’re relying on this, you are probably already doing something too smart.

func (*Rows) ScanOne

func (r *Rows) ScanOne(dst ...any) error

ScanOne is a convenient shortcut over Rows.Scan, returning the first value. DuplicateRecords will be returned if more than one record match.

type SQLITE3

type SQLITE3 *C.sqlite3

SQLITE3 wraps a C pointer type for export. See Register for information about use.

Directories

Path Synopsis
cmd
constrainer command
Constrainer is a tool to generate acces methods from virtual tables types definitions.
Constrainer is a tool to generate acces methods from virtual tables types definitions.
stability command
Package stability provides an API to validate the stability of persisted data structures.
Package stability provides an API to validate the stability of persisted data structures.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL