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
- func Bare(ctx context.Context, database Execer) func(name string) (bool, error)
- func DecodeStructured(columns []query.ColumnDef, row query.Row) error
- func FormatTime(at time.Time) string
- func IsStructured(columnType query.ColumnType) bool
- func PhysicalColumns(ctx context.Context, database Queryer, table string) ([]string, error)
- func PhysicalNames(declared, reserved []string, bare func(name string) (bool, error)) ([]string, error)
- func ProfileColumns(columns []query.ColumnDef) []query.ColumnDef
- func QuoteIdentifier(value string) string
- func Type(columnType query.ColumnType) string
- func Value(columnType query.ColumnType, value any) (any, error)
- type Execer
- type Queryer
- type Table
- func (t Table) Create(ctx context.Context, database Execer) (Table, error)
- func (t Table) Declare() (*schema.Table, error)
- func (t Table) Derive(ctx context.Context, database Execer) (Table, error)
- func (t Table) Insert(ctx context.Context, database Execer, rows []query.Row) error
- func (t Table) Physical(name string) (string, error)
- func (t Table) RenamePositional(ctx context.Context, database interface{ ... }) error
- func (t Table) Select() string
Constants ¶
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
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 ¶
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 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
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 ¶
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 ¶
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.
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 ¶
Write creates the table, inserts rows into it, and returns it with the physical names it was created with.
func (Table) Create ¶
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
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
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 ¶
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 ¶
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
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.