types

package
v0.11.0 Latest Latest
Warning

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

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

Documentation

Overview

Package types holds the custom column types Momo understands: each is a Codec, so database/sql can scan it, drivers can bind it and the schema layer can name its SQL type per dialect.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Codec

type Codec interface {
	sql.Scanner
	driver.Valuer
	SQLType(d dialect.Name) string
}

Codec is the custom-type contract: database/sql scanning, driver value encoding and the SQL type per dialect.

type Date

type Date struct {
	Time        time.Time
	Infinity    bool
	NegInfinity bool
}

Date is a calendar date (no time zone): date on PostgreSQL, TEXT 'YYYY-MM-DD' on SQLite and MySQL.

PostgreSQL also has the special dates 'infinity' and '-infinity'. Set Infinity or NegInfinity to write one; Scan sets the flag and leaves Time zero when it reads one. Time is ignored while a flag is set. SQLite and MySQL have no special dates: Momo rejects a Date with a flag set there with ErrValidation. IsFinite reports whether the value is an ordinary date.

func (Date) IsFinite added in v0.8.0

func (d Date) IsFinite() bool

IsFinite reports whether d is an ordinary calendar date, not infinity or -infinity.

func (Date) SQLType

func (Date) SQLType(d dialect.Name) string

SQLType returns the column type for d.

func (*Date) Scan

func (d *Date) Scan(src any) error

Scan accepts 'YYYY-MM-DD', 'infinity' or '-infinity' as string or []byte, or a time.Time (as pgx returns for date columns), whose calendar day in its own location is kept.

func (Date) Value

func (d Date) Value() (driver.Value, error)

Value encodes the date as 'YYYY-MM-DD' using the year, month and day of Time in its own location, or as 'infinity' or '-infinity'. Setting both Infinity and NegInfinity is an error.

type Hstore

type Hstore map[string]*string

Hstore is map[string]*string: hstore on PostgreSQL, TEXT JSON on SQLite. A nil value pointer is an hstore NULL.

func (Hstore) SQLType

func (Hstore) SQLType(d dialect.Name) string

SQLType returns the column type for d.

func (*Hstore) Scan

func (h *Hstore) Scan(src any) error

Scan accepts the PostgreSQL hstore text form or a JSON object (string or []byte). Duplicate keys in hstore text resolve first-wins, as PostgreSQL does. Scan(nil) returns an error: Hstore models a NOT NULL column, so use a *Hstore or a Null wrapper for nullable columns.

func (Hstore) Value

func (h Hstore) Value() (driver.Value, error)

Value returns the hstore text form, e.g. "k"=>"v", "n"=>NULL, with keys sorted, quotes and backslashes escaped and nil values as NULL. SQLite stores the same text in a TEXT column; a dialect-aware JSON encoding for SQLite is not implemented yet.

type JSON

type JSON[T any] struct {
	V T
	// contains filtered or unexported fields
}

JSON[T] stores any JSON-encodable T: jsonb on PostgreSQL, TEXT on SQLite. A nil map, slice or pointer encodes as the JSON literal null, an empty one as {} or []; Scan restores the same distinction.

A scanned JSON literal null also sets a private marker, reported by IsNull, so that writing the value back stores null and not the encoding of the zero T (for a struct T that would be an object). On a nullable column, scan into *JSON[T]: SQL NULL gives a nil pointer and the JSON literal null gives a non-nil pointer whose IsNull is true. Scanning SQL NULL into a plain JSON[T] field stays an error. On SQLite and MySQL, where the column is text, any stored text that is null once white space is trimmed counts as the JSON literal null.

The marker is a private field, so two JSON[T] values compare equal with == only when it matches: a scanned null differs from JSON[T]{}. With go-cmp, pass an option or use an Equal method. JSON[T] has no MarshalJSON, so encoding/json renders any JSON[T] as {"V":...} and JSONNull[T]() as {"V":null}; the null state does not survive an encoding/json round trip.

func JSONNull added in v0.11.0

func JSONNull[T any]() JSON[T]

JSONNull returns a JSON[T] that is the JSON literal null: it writes null, not SQL NULL (a nil *JSON[T] writes SQL NULL) and IsNull reports true.

func (JSON[T]) IsNull added in v0.11.0

func (j JSON[T]) IsNull() bool

IsNull reports whether j is the JSON literal null: it was scanned from null, or built by JSONNull, and it has not been assigned through Set since. It stays true while V is the zero value of T or encodes as null (a json.RawMessage holding null, or a T with its own UnmarshalJSON). Assigning V directly to a non-zero value ends it; assigning the zero value does not, so use Set. A value whose V merely encodes as null (a nil map, slice or pointer) and was not read from null is not reported; its Value is still null.

func (JSON[T]) SQLType

func (JSON[T]) SQLType(d dialect.Name) string

SQLType returns the column type for d.

func (*JSON[T]) Scan

func (j *JSON[T]) Scan(src any) error

Scan decodes JSON text (string or []byte) into V. NULL is an error; the JSON literal null decodes to the zero value of T (or what T's own decoder makes of null) and makes IsNull true.

func (*JSON[T]) Set added in v0.11.0

func (j *JSON[T]) Set(v T)

Set assigns v and clears the JSON null state. After reading a JSON null, assign through Set or a fresh JSON[T]{V: v}: assigning j.V directly to the zero value of T (false, 0, "", an empty struct) leaves j a JSON null, because the zero value cannot be told apart from an untouched V.

func (JSON[T]) Value

func (j JSON[T]) Value() (driver.Value, error)

Value encodes V as JSON text.

type JSONNuller added in v0.11.0

type JSONNuller interface {
	sql.Scanner
	IsNull() bool
	// contains filtered or unexported methods
}

JSONNuller is implemented by JSON[T] and by no other type. It lets another package recognise the family without naming T; it has no method to call.

type Numeric added in v0.8.0

type Numeric struct {
	Decimal     string
	NaN         bool
	Infinity    bool
	NegInfinity bool
}

Numeric is an exact decimal number: numeric on PostgreSQL, TEXT on SQLite and MySQL. The digits live in a string, so no precision is lost to binary floating point and Momo needs no decimal library.

Decimal holds a finite value such as "-12.50" or "0.000000001"; empty means 0. PostgreSQL numeric also holds NaN and the infinities: set NaN, Infinity or NegInfinity (at most one, with Decimal empty) to write one, and Scan sets the flag when it reads one. SQLite and MySQL have no such values: Momo rejects a Numeric with a flag set there with ErrValidation. IsFinite reports whether the value is an ordinary number.

NaN has been a numeric value for a long time, but Infinity and -Infinity need PostgreSQL 14 or later; Momo's CI covers PostgreSQL 16 and 17. An older server rejects them with a database error.

Numeric does no arithmetic. Use a decimal library for that, or let the database do it. Scan does not accept a pgtype.Numeric; read the column as Numeric, or convert with its String form.

func NumericFromFloat64 added in v0.9.0

func NumericFromFloat64(f float64) (Numeric, error)

NumericFromFloat64 returns the Numeric holding f written as the shortest decimal that reads back as the same float64 (strconv.FormatFloat with 'f' and precision -1), without an exponent. A float64 is already binary, so this is the float's shortest representation, not an exact conversion of its bits: 0.1 gives "0.1", not the long expansion of the nearest binary fraction. Use it to bring a float you already have into a numeric column; it cannot repair precision a float already lost. NaN and the infinities return an error; set the NaN, Infinity or NegInfinity flag by hand to store one.

func NumericFromInt64 added in v0.9.0

func NumericFromInt64(n int64) Numeric

NumericFromInt64 returns the Numeric holding n exactly.

func ParseNumeric added in v0.8.0

func ParseNumeric(s string) (Numeric, error)

ParseNumeric parses PostgreSQL numeric text: an optionally signed decimal ("12", "-1.5", ".5", "7."), or NaN, Infinity or -Infinity (also written inf, any case). Surrounding spaces are ignored; an exponent is not accepted.

func (Numeric) IsFinite added in v0.8.0

func (n Numeric) IsFinite() bool

IsFinite reports whether n is an ordinary number: not NaN and not infinite.

func (Numeric) IsInfinite added in v0.8.0

func (n Numeric) IsInfinite() bool

IsInfinite reports whether n is Infinity or -Infinity.

func (Numeric) IsNaN added in v0.8.0

func (n Numeric) IsNaN() bool

IsNaN reports whether n is NaN.

func (Numeric) SQLType added in v0.8.0

func (Numeric) SQLType(d dialect.Name) string

SQLType returns the column type for d.

func (*Numeric) Scan added in v0.8.0

func (n *Numeric) Scan(src any) error

Scan accepts the text form as string or []byte, an int64, or a float64 (what SQLite returns for an aggregate or an expression). A float64 is written in plain decimal form without exponent, with the shortest digits that read back the same; NaN and the infinities set their flags. Scan(nil) returns an error: use a *Numeric for a nullable column.

func (Numeric) Sign added in v0.8.0

func (n Numeric) Sign() int

Sign returns -1, 0 or +1 for a negative, zero or positive n. Infinity is +1, -Infinity is -1 and NaN is 0.

func (Numeric) String added in v0.8.0

func (n Numeric) String() string

String returns the PostgreSQL text form: the digits, or NaN, Infinity or -Infinity.

func (Numeric) Value added in v0.8.0

func (n Numeric) Value() (driver.Value, error)

Value encodes n as its text form. It is an error to set more than one flag, to set a flag together with Decimal, or to leave in Decimal anything that is not a decimal number.

type TSQuery added in v0.4.0

type TSQuery string

TSQuery is a PostgreSQL full-text query: tsquery on PostgreSQL, TEXT on SQLite. It is mostly the result type of the query builders (fts.ToQuery, fts.WebsearchToQuery, ...), but a column can hold one too (stored searches).

func (TSQuery) SQLType added in v0.4.0

func (TSQuery) SQLType(d dialect.Name) string

SQLType returns the column type for d.

func (*TSQuery) Scan added in v0.4.0

func (q *TSQuery) Scan(src any) error

Scan accepts the tsquery text form as string or []byte. Scan(nil) returns an error: use a *TSQuery for a nullable column.

func (TSQuery) Value added in v0.4.0

func (q TSQuery) Value() (driver.Value, error)

Value returns the tsquery text form.

type TSVector added in v0.4.0

type TSVector string

TSVector is a PostgreSQL full-text document: tsvector on PostgreSQL, TEXT on SQLite (which has no full-text search through Momo). Its value is the text form PostgreSQL prints, for example 'cat':3 'fat':2, with the lexemes sorted and normalized by the server.

A column of this type is usually maintained by a trigger declared through MomoConfig and is read-only for the application; the full-text expression builders (fts.Match, fts.ToVector, fts.RankCD, ...) take it as an operand.

func (TSVector) SQLType added in v0.4.0

func (TSVector) SQLType(d dialect.Name) string

SQLType returns the column type for d.

func (*TSVector) Scan added in v0.4.0

func (v *TSVector) Scan(src any) error

Scan accepts the tsvector text form as string or []byte. Scan(nil) returns an error: use a *TSVector for a nullable column.

func (TSVector) Value added in v0.4.0

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

Value returns the tsvector text form.

type TimeOfDay

type TimeOfDay struct{ Nanos int64 }

TimeOfDay is a time of day: time on PostgreSQL, TEXT 'HH:MM:SS.uuuuuu' on SQLite.

func (TimeOfDay) SQLType

func (TimeOfDay) SQLType(d dialect.Name) string

SQLType returns the column type for d.

func (*TimeOfDay) Scan

func (t *TimeOfDay) Scan(src any) error

Scan accepts 'HH:MM:SS' with an optional fraction of 1 to 9 digits (string or []byte). PostgreSQL's 24:00:00 is read as the last nanosecond of the day. Scan(nil) returns an error: use a pointer or a Null wrapper for nullable columns. Integer sources are rejected because drivers disagree on their unit.

func (TimeOfDay) Value

func (t TimeOfDay) Value() (driver.Value, error)

Value encodes the time as 'HH:MM:SS.uuuuuu', truncated to microseconds because PostgreSQL time has microsecond precision (rounding would turn the last microsecond of the day into 24:00:00). Nanos outside one day is an error.

type UUID

type UUID [16]byte

UUID is a 16-byte identifier: uuid on PostgreSQL, TEXT canonical form on SQLite.

func ParseUUID

func ParseUUID(s string) (UUID, error)

ParseUUID parses the canonical 36-character form (dashes at 8, 13, 18, 23) or 32 bare hex digits.

func (UUID) SQLType

func (UUID) SQLType(d dialect.Name) string

SQLType returns the column type for d.

func (*UUID) Scan

func (u *UUID) Scan(src any) error

Scan accepts the canonical 36-character form or 32 bare hex digits (string or []byte), or exactly 16 raw bytes. Any other length or character is an error.

func (UUID) String

func (u UUID) String() string

String returns the canonical 36-character lowercase form.

func (UUID) Value

func (u UUID) Value() (driver.Value, error)

Value returns the canonical string, which PostgreSQL casts to uuid.

Jump to

Keyboard shortcuts

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