protocol

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Aug 19, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package protocol defines the wire protocol shared by the lsqlited server and the database/sql driver.

Every message is a single frame: a 4-byte big-endian length header followed by a JSON-encoded body. A client sends a Request and the server answers with exactly one Response.

Index

Constants

View Source
const (
	TypePing     = "ping"
	TypeQuery    = "query"
	TypeExec     = "exec"
	TypeBegin    = "begin"
	TypeCommit   = "commit"
	TypeRollback = "rollback"
	TypeAuthInit = "auth_init"
	TypeAuth     = "auth"
)

Request types. TypeAuthInit starts the challenge-response handshake and TypeAuth completes it with the client proof.

View Source
const (
	CodeTimeout          = "timeout"
	CodeTooManyRows      = "too_many_rows"
	CodeResponseTooLarge = "response_too_large"
	CodeBusy             = "busy"
)

Error codes classifying Response.Error. They let a client act on the reason a request failed without matching on the message, which stays free-form so that SQLite's own wording reaches the user unchanged.

View Source
const (
	TypeTagNull  = "null"
	TypeTagInt   = "int"
	TypeTagFloat = "float"
	TypeTagBool  = "bool"
	TypeTagText  = "text"
	TypeTagBlob  = "blob" // base64 (standard encoding)
	TypeTagTime  = "time" // RFC 3339 with nanoseconds
)

Value type tags. All values are transported as strings to preserve full precision (e.g. int64 values beyond 2^53 would lose precision as JSON numbers).

View Source
const MaxMessageSize = 64 << 20 // 64 MiB

MaxMessageSize is the maximum allowed size of a single frame body.

Variables

View Source
var ErrMessageTooLarge = errors.New("protocol: message too large")

ErrMessageTooLarge reports a body that does not fit in a frame. WriteMessage returns it before writing anything, so the caller may answer with something smaller on the same connection.

Functions

func DecodeValues

func DecodeValues(vals []Value) ([]any, error)

DecodeValues decodes a slice of wire Values into []any suitable for passing to database/sql query methods.

func ReadMessage

func ReadMessage(r io.Reader, msg any) error

ReadMessage reads a single length-prefixed frame and unmarshals it into msg.

func WriteMessage

func WriteMessage(w io.Writer, msg any) error

WriteMessage marshals msg as JSON and writes it as a length-prefixed frame.

Types

type AuthChallenge

type AuthChallenge struct {
	Salt       string `json:"salt"`
	Iterations int    `json:"iterations"`
	Nonce      string `json:"nonce"`
}

AuthChallenge is the server's answer to a TypeAuthInit request: how to derive the salted password, and the nonce to bind the proof to.

type Request

type Request struct {
	Type     string  `json:"type"`
	Database string  `json:"database,omitempty"`
	Query    string  `json:"query,omitempty"`
	Args     []Value `json:"args,omitempty"`
	// User and Nonce identify the client in a TypeAuthInit request; Proof answers the challenge in a TypeAuth request. All
	// are base64.
	User  string `json:"user,omitempty"`
	Nonce string `json:"nonce,omitempty"`
	Proof string `json:"proof,omitempty"`
	// TimeoutMS and MaxRows are what the client asks for; the server enforces the smaller of each and its own limit, so
	// asking for more than the server allows does not raise the bound. Zero asks for no limit.
	TimeoutMS int64 `json:"timeout_ms,omitempty"`
	MaxRows   int64 `json:"max_rows,omitempty"`
	// ReadOnly asks TypeBegin for a deferred transaction that runs alongside other readers and may not write, rather than
	// one that takes the write lock as it begins.
	ReadOnly bool `json:"read_only,omitempty"`
}

Request is a message sent from the driver to the server.

type Response

type Response struct {
	// Error carries the underlying message verbatim, with no prefix, so that a client can show SQLite's own wording. Code
	// classifies it, and is empty for failures that carry no classification.
	Error string `json:"error,omitempty"`
	Code  string `json:"code,omitempty"`
	// ColumnTypes is parallel to Columns and holds each column's declared SQLite type, empty for an expression, a literal
	// or an aggregate. It is sent even for a result with no rows, since the types cannot be recovered from the values.
	Columns      []string  `json:"columns,omitempty"`
	ColumnTypes  []string  `json:"column_types,omitempty"`
	Rows         [][]Value `json:"rows,omitempty"`
	LastInsertID int64     `json:"last_insert_id,omitempty"`
	RowsAffected int64     `json:"rows_affected,omitempty"`
	// Auth answers TypeAuthInit; Signature answers a successful TypeAuth and lets the client authenticate the server in
	// turn.
	Auth      *AuthChallenge `json:"auth,omitempty"`
	Signature string         `json:"signature,omitempty"`
}

Response is a message sent from the server to the driver.

type Value

type Value struct {
	T string `json:"t"`
	V string `json:"v,omitempty"`
}

Value is a typed SQL value that survives a JSON round trip.

func EncodeValue

func EncodeValue(v any) (Value, error)

EncodeValue converts a Go value produced by database/sql or database/sql/driver into a wire Value.

func EncodeValues

func EncodeValues(vals []any) ([]Value, error)

EncodeValues encodes a slice of Go values.

func (Value) Decode

func (v Value) Decode() (driver.Value, error)

Decode converts a wire Value back into a driver.Value.

Jump to

Keyboard shortcuts

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