sqlitetable

package
v0.1.42 Latest Latest
Warning

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

Go to latest
Published: Sep 29, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package sqlitetable writes rows described by query.ColumnDef into SQLite tables that a `sql` profile can read back under the declared column names.

Each column is stored under a safe physical name derived from its declared one when the table is created (see PhysicalNames), and aliased back on the way out, so any string a profile can name a column is a name this package can store, while the table stays readable by name in hand-written SQL. The derived names are the table's own: its owner persists Table.StoredAs and hands it back, because a later build deriving differently must never reinterpret an existing table.

Index

Constants

View Source
const TimeLayout = "2006-01-02T15:04:05.000000000Z07:00"

TimeLayout is how an instant is stored, and how a bound compared against a stored instant must be bound. SQLite has no time type, so instants are TEXT compared as text, and text only orders as time when every value is written to the same width in the same zone: RFC3339Nano drops trailing zeros, so "…05Z" would sort after "…05.5Z", and the driver's rendering of a bound time.Time is Go's String(), which sorts before every stored value of its day.

Variables

This section is empty.

Functions

func Bare added in v0.1.38

func Bare(ctx context.Context, database Execer) func(name string) (bool, error)

Bare reports, by preparing `SELECT 1 AS <name>` on database, whether SQLite's own parser accepts name as an unquoted identifier. Only a parse failure is a "no"; any other failure is returned.

func DecodeStructured

func DecodeStructured(columns []query.ColumnDef, row query.Row) error

DecodeStructured parses the JSON text of every structured column in row in place, so a row read back holds the value that was written.

func FormatTime

func FormatTime(at time.Time) string

FormatTime is at in TimeLayout, in UTC.

func IsStructured

func IsStructured(columnType query.ColumnType) bool

IsStructured reports whether a column type is stored as JSON text.

func PhysicalColumns added in v0.1.38

func PhysicalColumns(ctx context.Context, database Queryer, table string) ([]string, error)

PhysicalColumns are the columns the table named table has, in order.

func PhysicalNames added in v0.1.38

func PhysicalNames(declared, reserved []string, bare func(name string) (bool, error)) ([]string, error)

PhysicalNames derives the column each declared name is stored in: every run of characters outside [A-Za-z0-9_] becomes "_" and the ends are trimmed; an empty result or a leading digit is prefixed "c_"; a name bare rejects gets a trailing "_"; and a name equal, ignoring case, to a reserved name or an earlier column is numbered "_2", "_3", …. Declared order is kept.

func ProfileColumns

func ProfileColumns(columns []query.ColumnDef) []query.ColumnDef

ProfileColumns are the columns a profile over the table declares: each structured column reads its stored JSON text back as the value it encodes.

func QuoteIdentifier

func QuoteIdentifier(value string) string

QuoteIdentifier quotes a SQLite identifier.

func Type

func Type(columnType query.ColumnType) string

Type is the SQLite column type a declared column type is stored as. A boolean is declared BOOLEAN rather than INTEGER: SQLite stores both as 0/1, but the driver reads a BOOLEAN column back as a Go bool, so a profile over the table returns true/false rather than a number.

func Value

func Value(columnType query.ColumnType, value any) (any, error)

Value converts a row value into one the sqlite driver stores: declared structured values as JSON text, other scalars as themselves, and times in TimeLayout.

Types

type Execer

type Execer interface {
	ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error)
	PrepareContext(ctx context.Context, query string) (*sql.Stmt, error)
}

Execer is what writing a table needs from a connection: a *sql.DB or a *sql.Tx.

type Queryer added in v0.1.38

type Queryer interface {
	QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error)
}

Queryer is what reading a table's shape needs from a connection: a *sql.DB or a *sql.Tx.

type Table

type Table struct {
	Name    string
	Columns []query.ColumnDef

	// StoredAs is the physical column each of Columns is stored in, index-aligned
	// with Columns. Create derives it for a table created without it; a table
	// read back from storage carries the names it was created with.
	StoredAs []string

	// Reserved names the declared columns the table's owner addresses by their
	// own names. Each keeps its name, which must already be a safe bare name, and
	// every other column deriving an equal name is numbered instead.
	Reserved []string

	// PrimaryKey names the declared columns that together identify a row.
	PrimaryKey []string

	// Unique names declared columns that each get their own unique index.
	Unique []string
}

Table is one SQLite table and the declared columns it stores.

func Write

func Write(ctx context.Context, database Execer, table Table, rows []query.Row) (Table, error)

Write creates the table, inserts rows into it, and returns it with the physical names it was created with.

func (Table) Create

func (t Table) Create(ctx context.Context, database Execer) (Table, error)

Create creates the table and its unique indexes, and returns it with the physical names it was created with: StoredAs as given, or derived on database when empty. The table must not exist.

func (Table) Declare added in v0.1.38

func (t Table) Declare() (*schema.Table, error)

Declare is the table as Create creates it, declared for Atlas: every column under its stored name by its raw SQLite type, the primary key and the unique indexes. migrate/sqlite.ReconcileTables reconciles an existing table against it. The table must carry its stored names.

func (Table) Derive added in v0.1.38

func (t Table) Derive(ctx context.Context, database Execer) (Table, error)

Derive returns the table with StoredAs derived on database by PhysicalNames: reserved columns keep their names and every other column is derived against them. It is for a table being created, or migrated from positional storage; an existing table's names are its stored ones.

func (Table) Insert

func (t Table) Insert(ctx context.Context, database Execer, rows []query.Row) error

Insert appends rows to the existing table. A row key the table does not declare is not stored; a declared column the row lacks is stored as NULL, as is any column the table has but does not declare — one another build sharing the file added.

func (Table) Physical

func (t Table) Physical(name string) (string, error)

Physical is the quoted column a declared column is stored in, for a clause that has to address the table itself rather than the aliased result.

func (Table) RenamePositional added in v0.1.38

func (t Table) RenamePositional(ctx context.Context, database interface {
	Execer
	Queryer
}) error

RenamePositional renames the columns of a table an older build stored positionally, "c0"…"c<n>", to StoredAs. Renames carry the table's keys and indexes along. Every column first moves aside to a name no derivation produces, since a derived name may be another column's positional one.

func (Table) Select

func (t Table) Select() string

Select reads every declared column under its declared name, aliasing only the columns stored under another name. It panics on a table that carries no stored names: that table was neither created nor read back from storage.

Jump to

Keyboard shortcuts

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