Documentation
¶
Index ¶
- Constants
- func FormatOffsetSeconds(duration time.Duration) (string, bool)
- func NewAliasedTable(name TableName, alias TableAlias) aliasedTable
- func NewBuilder() *builder
- func NewBuilderWithOffset(pc *int) *builder
- func NewTable(name TableName) aliasedTable
- func WriteInTuple(fields []Serializable, vals []Tuple, sb Builder)
- type Builder
- type CondInterpreter
- type Condition
- type ConditionSerializable
- type Field
- type FieldName
- type JoinType
- type JoinedTable
- type ModifiableQuery
- type OrderBy
- type PagInterpreter
- type Param
- type Serializable
- type Table
- type TableAlias
- type TableName
- type Tuple
Constants ¶
const (
// ZeroLimit is used to signal to AddLimit to include a `LIMIT 0` clause
ZeroLimit = -1
)
Variables ¶
This section is empty.
Functions ¶
func FormatOffsetSeconds ¶ added in v0.24.0
FormatOffsetSeconds renders the absolute value of duration as the seconds literal of a SQL interval expression, keeping the sub-second part when there is one, and reports whether the duration is a whole number of seconds.
The interpreters used to render int(math.Abs(duration.Seconds())), which truncates toward zero: any offset below a second collapsed to 0, turning a 500ms lease expiry into "now" so that every row looked expired, and 1.5 seconds into 1. No caller passes a sub-second duration today, but the truncation was silent.
The second return value exists for SQLite: datetime() truncates its *output* to whole seconds and so cannot carry a fractional offset even though it accepts one in the modifier.
Both the literal and the whole-second flag come from the same integer nanosecond magnitude, so they cannot disagree. Rendering the literal from duration.Seconds() instead would let a float64 lose sub-second precision past ~104 days and emit a fractional literal on the whole-second path - the one SQLite routes to datetime(), which cannot carry a fraction.
func NewAliasedTable ¶
func NewAliasedTable(name TableName, alias TableAlias) aliasedTable
func NewBuilder ¶
func NewBuilder() *builder
func NewBuilderWithOffset ¶
func NewBuilderWithOffset(pc *int) *builder
func NewTable ¶
func NewTable(name TableName) aliasedTable
TODO: Support new alias per table in case a table is selected twice in the same query (for different joins)
func WriteInTuple ¶ added in v0.24.0
func WriteInTuple(fields []Serializable, vals []Tuple, sb Builder)
WriteInTuple renders the tuple membership test `(fields...) IN (vals...)` using the SQL standard row-value form, which both SQLite (>= 3.15) and Postgres support natively. A single field compared against a single value collapses to plain equality.
Callers must have already ruled out empty input (see cond.InTuple, which returns a sentinel in that case); the guard here is defensive only.
Every tuple must hold exactly one value per field, and a tuple of any other width panics before anything is written. Rendering it instead would produce a query that is wrong rather than merely invalid: a single wide tuple would take the equality shortcut and silently drop every value past the first, and a tuple narrower than the field list would emit a row value whose arity does not match the fields it is compared against.
Types ¶
type Builder ¶
type Builder interface {
WriteParam(Param) Builder
BindParams(...Param) Builder
WriteParamRef(int) Builder
WriteValueTuples([][]Serializable) Builder
WriteTuples([]Tuple) Builder
WriteString(string) Builder
WriteRune(rune) Builder
WriteSerializables(...Serializable) Builder
WriteConditionSerializable(ConditionSerializable, CondInterpreter) Builder
Build() (string, []Param)
}
Builder is the string builder
type CondInterpreter ¶
type CondInterpreter interface {
// TimeOffset appends NOW() - '10 seconds'
TimeOffset(duration time.Duration, sb Builder)
// InTuple creates the condition (field1, field2, ...) IN ((val1, val2, ...), (val3, val4, ...))
InTuple(fields []Serializable, vals []Tuple, sb Builder)
}
CondInterpreter is the condition interpreter for the WHERE clauses It specifies the behaviors that differ among different DBs
type Condition ¶
type Condition ConditionSerializable
type ConditionSerializable ¶
type ConditionSerializable interface {
WriteString(CondInterpreter, Builder)
}
ConditionSerializable is any type that can be transformed to a query part but needs condition interpreter support, e.g. condition, join
type Field ¶
type Field Serializable
type FieldName ¶
type FieldName string
FieldName is the name of the DB column
func (FieldName) WriteString ¶
type JoinedTable ¶
type JoinedTable interface {
ConditionSerializable
JoinAs(typ JoinType, other Table, ons ConditionSerializable) JoinedTable
Join(Table, ConditionSerializable) JoinedTable
}
type ModifiableQuery ¶
type ModifiableQuery interface {
AddField(Field)
AddWhere(Condition)
AddOrderBy(OrderBy)
// AddLimit is used to manage the LIMIT clause.
// Any passed value larger than zero will trigger the inclusion of the clause.
// If one wants to explicitly insert a clause as `LIMIT 0`, then oen should use the constant ZeroLimit
AddLimit(int)
AddOffset(int)
}
type OrderBy ¶
type OrderBy Serializable
type PagInterpreter ¶
type PagInterpreter interface {
// PreProcess modifies the SQL query to add pagination support
PreProcess(driver.Pagination, ModifiableQuery)
}
PagInterpreter is the pagination interpreter
type Serializable ¶
type Serializable interface {
WriteString(Builder)
}
Serializable is any type can be transformed to a query part, e.g. field, order-by
func IntervalAfterNow ¶
func IntervalAfterNow(ref int) Serializable
IntervalAfterNow writes NOW() + $<ref>::interval using an existing bound parameter.
func Ref ¶
func Ref(n int) Serializable
Ref references an already-bound parameter by its 1-based index.
func ToSerializables ¶
func ToSerializables[S Serializable](vs []S) []Serializable
type Table ¶
type Table interface {
JoinedTable
Field(name FieldName) Field
}
type TableAlias ¶
type TableAlias string