Documentation ¶
Overview ¶
Example (Composition) ¶
Copy of `ExampleStrQ_nested` for package-level docs.
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { inner := s.StrQ{ `select * from some_table where col0 = :val`, s.Dict{`val`: 10}, } outer := s.StrQ{ `select * from (:inner) as _ where col1 = :val`, s.Dict{`inner`: inner, `val`: 20}, } fmt.Println(s.Reify(outer)) }
Output: select * from (select * from some_table where col0 = $1) as _ where col1 = $2 [10 20]
Index ¶
- Constants
- Variables
- func AppendTo(buf []byte, src any) ([]byte, error)
- func AppendWith(buf *[]byte, delim string, val any) (bool, error)
- func AppenderString(val AppenderTo) string
- func FieldDbName(field r.StructField) string
- func FieldJsonName(field r.StructField) string
- func Reify(vals ...Expr) (string, []any)
- func String(src any) (string, error)
- func TryAppend(buf []byte, src any) []byte
- func TryAppendWith(buf *[]byte, delim string, val any) bool
- func TryString(val any) string
- func TypeCols(typ r.Type) string
- func TypeColsDeep(typ r.Type) string
- type AliasedPath
- type And
- type Ands
- type Any
- type AppenderTo
- type ArgDict
- type ArrayAppender
- type Assign
- type Bui
- func (self *Bui) Any(val any)
- func (self *Bui) Arg(val any)
- func (self *Bui) CatchExprs(vals ...Expr) (err error)
- func (self *Bui) Expr(val Expr)
- func (self *Bui) Exprs(vals ...Expr)
- func (self Bui) Get() ([]byte, []any)
- func (self *Bui) Grow(textLen, argsLen int)
- func (self *Bui) OrphanArg(val any) OrdinalParam
- func (self *Bui) OrphanParam(val OrdinalParam)
- func (self Bui) Reify() (string, []any)
- func (self *Bui) Set(text []byte, args []any)
- func (self *Bui) Space()
- func (self *Bui) Str(val string)
- func (self Bui) String() string
- func (self *Bui) SubAny(val any)
- func (self *Bui) SubExpr(val Expr)
- type Call
- type Cols
- type ColsDeep
- type Comma
- type CommaAppender
- type Cond
- type Delete
- type DeleteVoid
- type Dict
- type Dir
- type Eq
- type EqAny
- type Err
- type ErrEmptyExpr
- type ErrInternal
- type ErrInvalidInput
- type ErrMissingArgument
- type ErrOrdinalOutOfBounds
- type ErrStr
- type ErrUnexpectedEOF
- type ErrUnexpectedParameter
- type ErrUnknownField
- type ErrUnusedArgument
- type Expr
- type Exprs
- type Filter
- type Haser
- type Ident
- type Identifier
- type Insert
- type InsertVoid
- type Jel
- func (self Jel) AppendExpr(text []byte, args []any) ([]byte, []any)
- func (self Jel) AppendTo(text []byte) []byte
- func (self *Jel) OrType(typ any)
- func (self *Jel) Parse(val string) error
- func (self Jel) String() string
- func (self *Jel) UnmarshalJSON(val []byte) error
- func (self *Jel) UnmarshalText(val []byte) error
- type LaxDict
- type Limit
- type LimitUint
- type List
- type NamedParam
- type NamedRanger
- type Neq
- type NeqAny
- type Not
- type Nullable
- type Nulls
- type Offset
- type OffsetUint
- type Op
- type Or
- type Ord
- type OrdAsc
- type OrdAscNullsFirst
- type OrdAscNullsLast
- type OrdDesc
- type OrdDescNullsFirst
- type OrdDescNullsLast
- type OrdNullsFirst
- type OrdNullsLast
- type OrderBy
- type Ordering
- type OrdinalParam
- type OrdinalRanger
- type Ords
- func (self *Ords) Add(vals ...Expr)
- func (self Ords) AppendExpr(text []byte, args []any) ([]byte, []any)
- func (self Ords) AppendTo(text []byte) []byte
- func (self *Ords) Grow(size int)
- func (self Ords) IsEmpty() bool
- func (self Ords) Len() (count int)
- func (self Ords) MarshalJSON() ([]byte, error)
- func (self *Ords) Or(vals ...Expr)
- func (self *Ords) OrdsParser(typ any) (out OrdsParser)
- func (self *Ords) OrdsPtr() *Ords
- func (self Ords) RowNumberOver() RowNumberOver
- func (self Ords) String() string
- func (self *Ords) Zero()
- type OrdsParser
- type Ors
- type ParamExpr
- type ParseOpt
- type ParserOrds
- type Partial
- type Path
- type Prefix
- type Prep
- type PseudoPath
- type ReturningAll
- type RowNumberOver
- type Select
- type SelectCols
- type SelectColsDeep
- type SelectCount
- type SelectString
- type Seq
- type SliceCommaAppender
- type Sparse
- type Str
- type StrQ
- type StructAssign
- type StructDict
- type StructInsert
- type StructValues
- type StructsInsert
- type Table
- type TagFilter
- type Token
- type TokenType
- type Tokenizer
- type Update
- type UpdateVoid
- type Upsert
- type UpsertConflict
- type UpsertConflictVoid
- type UpsertVoid
- type Wrap
Examples ¶
- Package (Composition)
- AliasedPath
- And (Slice)
- And (Struct)
- Ands
- Any
- Assign
- Bui
- Bui.CatchExprs
- Call (Arguments)
- Call (Empty)
- Call (SubExpression)
- Call (SubExpressions)
- Cols (NonStruct)
- Cols (Struct)
- ColsDeep (NonStruct)
- ColsDeep (Struct)
- Delete (Filtered)
- Delete (Unfiltered)
- DictQ
- Eq
- EqAny
- Exprs
- Ident
- Ident (Interpolation)
- Identifier
- Insert (Empty)
- Insert (NonEmpty)
- Jel
- LimitUint
- ListQ
- Neq
- NeqAny
- Not
- OffsetUint
- Or (Slice)
- Or (Struct)
- Ords (Empty)
- Ords (Manual)
- Ords.OrdsParser
- Ors
- ParserOrds.ParseSlice
- ParserOrds.UnmarshalJSON
- Path
- PseudoPath
- RowNumberOver (Empty)
- RowNumberOver (NonEmpty)
- Select (Filtered)
- Select (Unfiltered)
- SelectCols (AsIs)
- SelectCols (Cols)
- SelectColsDeep (AsIs)
- SelectColsDeep (Cols)
- SelectCount
- Str (StringInterpolation)
- StrQ (Empty)
- StrQ (Nested)
- StrQ (Simple)
- StrQ (StructInput)
- StrQ (Structs)
- StructAssign
- StructInsert (Empty)
- StructInsert (NonEmpty)
- StructValues
- StructsInsert (Empty)
- StructsInsert (NonEmpty)
- Update
Constants ¶
const ( TagNameDb = `db` TagNameJson = `json` )
Variables ¶
var ErrEmptyAssign = error(ErrEmptyExpr{Err{ `building SQL assignment expression`, ErrStr(`assignment must have at least one field`), }})
Used by `StructAssign` to indicate that no fields were provided, and therefore it was unable to generate valid SQL for an "update set" clause. This can happen because the input struct was missing or empty, or because all fields were excluded through the use of `Sparse`. User code should detect this error to skip the DB request altogether.
var Ops = map[string]Op{ `and`: OpInfix, `or`: OpInfix, `not`: OpPrefix, `is null`: OpPostfix, `is not null`: OpPostfix, `is true`: OpPostfix, `is not true`: OpPostfix, `is false`: OpPostfix, `is not false`: OpPostfix, `is unknown`: OpPostfix, `is not unknown`: OpPostfix, `is distinct from`: OpInfix, `is not distinct from`: OpInfix, `=`: OpInfix, `~`: OpInfix, `~*`: OpInfix, `~=`: OpInfix, `<>`: OpInfix, `<`: OpInfix, `>`: OpInfix, `>=`: OpInfix, `<=`: OpInfix, `@@`: OpInfix, `any`: OpAny, `between`: OpBetween, }
Known SQL operations used in JEL. Serves as a whitelist, allowing us to differentiate them from casts, and describes how to transform JEL Lisp-style calls into SQL expressions (prefix, infix, etc.). This is case-sensitive and whitespace-sensitive.
var ValidateUnusedArguments = true
Enables validation of unused arguments in parametrized queries generated via `ListQ` / `DictQ` / `StructQ` / `StrQ` / `Preparse` / `Prep`. By default, validation is enabled. It can be disabled in two ways: globally by changing this variable to `false`, or by using an argument dictionary without support for argument validation, such as `LaxDict`.
Functions ¶
func AppendTo ¶ added in v0.7.0
Missing feature of the standard library: append the text representation of an arbitrary value to the buffer, prioritizing "append"-style encoding functions over "string"-style functions for efficiency, using only "intentional" representations, and without swallowing errors.
Supports ONLY the following types, in this order of priority. For other types, returns an error.
- `AppenderTo`
- `encoding.TextMarshaler`
- `fmt.Stringer`
- Built-in primitive types.
- Aliases of `[]byte`.
Special cases:
- Nil: append nothing, return buffer as-is.
- Integers: use `strconv.AppendInt` in base 10.
- Floats: use `strconv.AppendFloat` without scientific notation.
Used internally by `CommaAppender`, exported for advanced users.
func AppendWith ¶ added in v0.4.0
Attempts to append the given delimiter and the text representation of the given value, via `AppendTo`. If after delimiter non-zero amount of bytes was appended, returns true. Otherwise reverts the buffer to the original length and returns false. If the buffer got reallocated with increased capacity, preserves the new capacity.
func AppenderString ¶ added in v0.4.0
func AppenderString(val AppenderTo) string
Tiny shortcut for encoding an `AppenderTo` implementation to a string by using its `.AppendTo` method, without paying for a string-to-byte conversion. Used internally by many `Expr` implementations. Exported because it's handy for defining new types.
func FieldDbName ¶ added in v0.2.0
func FieldDbName(field r.StructField) string
Returns the field's DB column name from the "db" tag, following the JSON convention of eliding anything after a comma and treating "-" as a non-name.
func FieldJsonName ¶ added in v0.2.0
func FieldJsonName(field r.StructField) string
Returns the field's JSON column name from the "json" tag, following the same conventions as the `encoding/json` package.
func Reify ¶ added in v0.2.0
Encodes the provided expressions and returns the resulting text and args. Shortcut for using `(*Bui).Exprs` and `Bui.Reify`. Provided mostly for examples. Actual code may want to use `Bui`:
bui := MakeBui(4096, 64) panic(bui.CatchExprs(someExprs...)) text, args := bui.Reify()
func String ¶ added in v0.4.0
Missing feature of the standard library: return a string representation of an arbitrary value intended only for machine use, only for "intentionally" encodable types, without swallowing errors. Differences from `fmt.Sprint`:
Nil input = "" output.
Returns errors separately, without encoding them into the output. This is important when the output is intended to be passed to another system rather than read by humans.
Supports ONLY the following types, in this order of priority. For other types, returns an error.
`fmt.Stringer`
`AppenderTo`
`encoding.TextMarshaler`
Built-in primitive types.
Encodes floats without the scientific notation.
Aliases of `[]byte`.
func TryAppendWith ¶ added in v0.4.0
Variant of `AppendWith` that panics on error.
func TypeCols ¶ added in v0.2.0
Returns the output of `Cols` for the given type, but takes `reflect.Type` as input, rather than a type-carrying `any`. Used internally by `Cols`. The result is cached and reused. Subsequent calls for the same type are nearly free.
func TypeColsDeep ¶ added in v0.2.0
Returns the output of `ColsDeep` for the given type, but takes `reflect.Type` as input, rather than a type-carrying `any`. Used internally by `ColsDeep`. The result is cached and reused. Subsequent calls for the same type are nearly free.
Types ¶
type AliasedPath ¶ added in v0.2.0
type AliasedPath []string
Represents an arbitrarily-nested SQL path that gets encoded as `Path` followed by `PseudoPath` alias. Useful for building "select" clauses. Used internally by `ColsDeep`.
Example ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.AliasedPath{`one`}) fmt.Println(s.AliasedPath{`one`, `two`}) fmt.Println(s.AliasedPath{`one`, `two`, `three`}) }
Output: "one" ("one")."two" as "one.two" ("one")."two"."three" as "one.two.three"
func (AliasedPath) AppendExpr ¶ added in v0.2.0
func (self AliasedPath) AppendExpr(text []byte, args []any) ([]byte, []any)
Implement the `Expr` interface, making this a sub-expression.
func (AliasedPath) AppendTo ¶ added in v0.7.0
func (self AliasedPath) AppendTo(text []byte) []byte
Implement the `AppenderTo` interface, sometimes allowing more efficient text encoding.
func (AliasedPath) Norm ¶ added in v0.2.0
func (self AliasedPath) Norm() Expr
Normalizes the expression, returning nil or a single `Ident` if the length allows this. Otherwise returns self as-is.
func (AliasedPath) String ¶ added in v0.2.0
func (self AliasedPath) String() string
Implement the `fmt.Stringer` interface for debug purposes.
type And ¶ added in v0.2.0
type And [1]any
Represents a sequence of arbitrary sub-expressions or arguments joined by the SQL `and` operator. Rules for the inner value:
- nil or empty -> fallback to `true`
- single `Expr` -> render it as-is
- non-empty slice -> render its individual elements joined by `and`
- non-empty struct -> render column equality conditions joined by `and`
Example (Slice) ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { type list = []any fmt.Println(s.Reify(s.And{nil})) fmt.Println(s.Reify(s.And{list{}})) fmt.Println(s.Reify(s.And{list{true, false, s.Ident(`some_col`)}})) }
Output: true [] true [] $1 and $2 and ("some_col") [true false]
Example (Struct) ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.Reify(s.And{struct{}{}})) fmt.Println(s.Reify(s.And{struct { Col0 bool `db:"col0"` Col1 any `db:"col1"` Col2 any `db:"col2"` }{ true, nil, s.Call{`some_func`, []int{10}}, }})) }
Output: true [] "col0" = $1 and "col1" is null and "col2" = (some_func ($2)) [true 10]
func (And) AppendExpr ¶ added in v0.2.0
Implement the `Expr` interface, making this a sub-expression.
type Ands ¶ added in v0.2.0
type Ands []any
Syntactic shortcut, same as `And` with a slice of sub-expressions or arguments.
Example ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.Reify(s.Ands{})) fmt.Println(s.Reify(s.Ands{true, false, s.Ident(`some_col`)})) }
Output: true [] $1 and $2 and ("some_col") [true false]
func (Ands) AppendExpr ¶ added in v0.2.0
Implement the `Expr` interface, making this a sub-expression.
type Any ¶ added in v0.2.0
type Any [1]any
Represents an SQL "any()" expression. The inner value may be an instance of `Expr`, or an arbitrary argument.
Example ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.Reify(s.Any{})) fmt.Println(s.Reify(s.Any{[]int{10, 20}})) fmt.Println(s.Reify(s.Any{s.Table{`some_table`}})) }
Output: any ($1) [<nil>] any ($1) [[10 20]] any (table "some_table") []
func (Any) AppendExpr ¶ added in v0.2.0
Implement the `Expr` interface, making this a sub-expression.
type AppenderTo ¶ added in v0.7.0
Appends a text repesentation. Sometimes allows better efficiency than `fmt.Stringer`. Implemented by all `Expr` types in this package.
type ArgDict ¶ added in v0.2.0
type ArgDict interface { IsEmpty() bool Len() int GotOrdinal(int) (any, bool) GotNamed(string) (any, bool) }
Dictionary of arbitrary arguments, ordinal and/or named. Used as input to `ParamExpr` (parametrized expressions). This package provides multiple implementations: slice-based `List`, map-based `Dict`, and struct-based `StructDict`. May optionally implement `OrdinalRanger` and `NamedRanger` to validate used/unused arguments.
type ArrayAppender ¶ added in v0.4.0
type ArrayAppender[A AppenderTo] []A
Intermediary tool for implementing SQL array encoding. Has the same behavior as `CommaAppender`, but the text output is always enclosed in `{}`.
func (ArrayAppender[A]) AppendTo ¶ added in v0.7.0
func (self ArrayAppender[A]) AppendTo(buf []byte) []byte
Implement `AppenderTo`. Same as `CommaAppender.AppendTo`, but the output is always enclosed in `{}`.
func (ArrayAppender[_]) Get ¶ added in v0.4.0
func (self ArrayAppender[_]) Get() any
func (ArrayAppender[_]) String ¶ added in v0.4.0
func (self ArrayAppender[_]) String() string
Implement `fmt.Stringer`. Same as `CommaAppender.String`, but the output is always enclosed in `{}`.
type Assign ¶ added in v0.2.0
Represents an SQL assignment such as `"some_col" = arbitrary_expression`. The LHS must be a column name, while the RHS can be an `Expr` instance or an arbitrary argument.
Example ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.Reify(s.Assign{ `some_col`, `arbitrary_value`, })) fmt.Println(s.Reify(s.Assign{ `some_col`, s.Path{`some_table`, `another_col`}, })) }
Output: "some_col" = $1 [arbitrary_value] "some_col" = (("some_table")."another_col") []
func (Assign) AppendExpr ¶ added in v0.2.0
Implement the `Expr` interface, making this a sub-expression.
type Bui ¶ added in v0.2.0
Short for "builder". Tiny shortcut for building SQL expressions. Significantly simplifies the code and avoids various common mistakes. Used internally by most `Expr` implementations in this package. Careful use of `Bui` incurs very litte overhead compared to writing the corresponding code inline. The design may allow future Go versions to optimize it away completely.
Example ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.Reify(SomeExpr{})) } type SomeExpr struct{} func (self SomeExpr) AppendExpr(text []byte, args []any) ([]byte, []any) { bui := s.Bui{text, args} bui.Str(`select`) bui.Any(`some_value`) return bui.Get() }
Output: select $1 [some_value]
func MakeBui ¶ added in v0.2.0
Prealloc tool. Makes a `Bui` with the specified capacity of the text and args buffers.
func (*Bui) Any ¶ added in v0.2.0
Appends an arbitrary value. If the value implements `Expr`, this calls `(*Bui).Expr`, which may append to the text and args in arbitrary ways. Otherwise, appends an argument to the inner slice of args, and the corresponding ordinal parameter such as "$1"/"$2"/.../"$N" to the text.
func (*Bui) Arg ¶ added in v0.2.0
Appends an argument to `.Args` and a corresponding ordinal parameter to `.Text`.
func (*Bui) CatchExprs ¶ added in v0.4.0
Same as `(*Bui).Exprs` but catches panics. Since many functions in this package use panics, this should be used for final reification by apps that insist on errors-as-values.
Example ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { bui := s.MakeBui(1024, 16) err := bui.CatchExprs( s.Select{`some_table`, s.Ands{true, false}}, ) if err != nil { panic(err) } text, args := bui.Reify() fmt.Println(text) fmt.Println(args) }
Output: select * from "some_table" where $1 and $2 [true false]
func (*Bui) Expr ¶ added in v0.2.0
Appends an expression, delimited from the preceding text by a space, if necessary. Nil input is a nop: nothing will be appended.
Should be used only if you already have an `Expr` value. If you have a concrete value that implements the interface, call `bui.Set(val.AppendExpr(bui.Get())` instead, to avoid a heap allocation and a minor slowdown.
func (*Bui) Exprs ¶ added in v0.2.0
Appends each expr by calling `(*Bui).Expr`. They will be space-separated as necessary.
func (Bui) Get ¶ added in v0.2.0
Returns text and args as-is. Useful shortcut for passing them to `AppendExpr`.
func (*Bui) Grow ¶ added in v0.2.0
Increases the capacity (not length) of the text and args buffers by the specified amounts. If there's already enough capacity, avoids allocation.
func (*Bui) OrphanArg ¶ added in v0.6.3
func (self *Bui) OrphanArg(val any) OrdinalParam
Appends an arg to the inner slice of args, returning the corresponding ordinal parameter that should be appended to the text. Requires caution: does not append the corresponding ordinal parameter.
func (*Bui) OrphanParam ¶ added in v0.6.3
func (self *Bui) OrphanParam(val OrdinalParam)
Appends an ordinal parameter such as "$1", space-separated from previous text if necessary. Requires caution: does not verify the existence of the corresponding argument.
func (Bui) Reify ¶ added in v0.2.0
Shortcut for `self.String(), self.Args`. Go database drivers tend to require `string, []any` as inputs for queries and statements.
func (*Bui) Set ¶ added in v0.2.0
Replaces text and args with the inputs. The following idiom is equivalent to `bui.Expr` but more efficient if the expression type is concrete, avoiding an interface-induced allocation:
bui.Set(SomeExpr{}.AppendExpr(bui.Get()))
func (*Bui) Space ¶ added in v0.2.0
func (self *Bui) Space()
Adds a space if the preceding text doesn't already end with a terminator.
func (*Bui) Str ¶ added in v0.2.0
Appends the provided string, delimiting it from the previous text with a space if necessary.
func (*Bui) SubAny ¶ added in v0.2.0
Appends an arbitrary value or sub-expression. Like `(*Bui).Any`, but if the value implements `Expr`, this uses `(*Bui).SubExpr` in order to parenthesize the sub-expression.
func (*Bui) SubExpr ¶ added in v0.2.0
Appends a sub-expression wrapped in parens. Nil input is a nop: nothing will be appended.
Performance note: if you have a concrete value rather than an `Expr`, calling this method will allocate, so you may want to avoid it. If you already have an `Expr`, calling this is fine.
type Call ¶ added in v0.2.0
Represents an SQL function call expression. The text prefix is optional and usually represents a function name. The args must be either nil, a single `Expr`, or a slice of arbitrary sub-expressions or arguments.
Example (Arguments) ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.Reify(s.Call{`some_func`, []int{10, 20, 30}})) }
Output: some_func ($1, $2, $3) [10 20 30]
Example (Empty) ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.Call{`some_func`, nil}) }
Output: some_func ()
Example (SubExpression) ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.Call{`exists`, s.Table{`some_table`}}) }
Output: exists (table "some_table")
Example (SubExpressions) ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.Call{`some_func`, []s.Ident{`one`, `two`}}) }
Output: some_func (("one"), ("two"))
func (Call) AppendExpr ¶ added in v0.2.0
Implement the `Expr` interface, making this a sub-expression.
type Cols ¶
type Cols [1]any
Represents a column list for a "select" expression. The inner value may be of any type, and is used as a type carrier; its actual value is ignored. If the inner value is a struct or struct slice, the resulting expression is a list of column names corresponding to its fields, using a "db" tag. Otherwise the expression is `*`.
Unlike many other struct-scanning expressions, this doesn't support filtering via `Sparse`. It operates at the level of a struct type, not an individual struct value.
TODO actually support `Sparse` because it's used for insert.
Example (NonStruct) ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.Cols{}) fmt.Println(s.Cols{(*int)(nil)}) fmt.Println(s.Cols{(*[]string)(nil)}) }
Output: * * *
Example (Struct) ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { type Internal struct { Id string `db:"id"` Name string `db:"name"` } type External struct { Id string `db:"id"` Name string `db:"name"` Internal Internal `db:"internal"` } fmt.Println(s.Cols{(*External)(nil)}) }
Output: "id", "name", "internal"
func (Cols) AppendExpr ¶ added in v0.2.0
Implement the `Expr` interface, making this a sub-expression.
type ColsDeep ¶ added in v0.2.0
type ColsDeep [1]any
Represents a column list for a "select" expression. The inner value may be of any type, and is used as a type carrier; its actual value is ignored. If the inner value is a struct or struct slice, the resulting expression is a list of column names corresponding to its fields, using a "db" tag. Otherwise the expression is `*`.
Unlike `Cols`, this has special support for nested structs and nested column paths. See the examples.
Unlike many other struct-scanning expressions, this doesn't support filtering via `Sparse`. It operates at the level of a struct type, not an individual struct value.
Example (NonStruct) ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.ColsDeep{}) fmt.Println(s.ColsDeep{(*int)(nil)}) fmt.Println(s.ColsDeep{(*[]string)(nil)}) }
Output: * * *
Example (Struct) ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { type Internal struct { Id string `db:"id"` Name string `db:"name"` } type External struct { Id string `db:"id"` Name string `db:"name"` Internal Internal `db:"internal"` } fmt.Println(s.ColsDeep{(*External)(nil)}) }
Output: "id", "name", ("internal")."id" as "internal.id", ("internal")."name" as "internal.name"
func (ColsDeep) AppendExpr ¶ added in v0.2.0
Implement the `Expr` interface, making this a sub-expression.
type Comma ¶ added in v0.2.0
type Comma [1]any
Represents a comma-separated list of arbitrary sub-expressions. The inner value may be nil or a single `Expr`, otherwise it must be a slice.
func (Comma) AppendExpr ¶ added in v0.2.0
Implement the `Expr` interface, making this a sub-expression.
type CommaAppender ¶ added in v0.4.0
type CommaAppender[A AppenderTo] []A
Intermediary tool for implementing SQL array encoding. Combines multiple arbitrary text encoders. On demand (on a call to `.AppendTo` or `.String`), combines their text representations, separating them with a comma, while skipping any empty representations. The output will never contain a dangling leading comma, double comma, or leading trailing comma, unless they were explicitly generated by the inner encoders. Compare `SliceCommaAppender` which takes an arbitrary slice.
func (CommaAppender[_]) AppendTo ¶ added in v0.7.0
func (self CommaAppender[_]) AppendTo(buf []byte) []byte
Implement `AppenderTo`. Appends comma-separated text representations of the inner encoders to the output buffer, skipping any empty representations.
func (CommaAppender[_]) String ¶ added in v0.4.0
func (self CommaAppender[_]) String() string
Implement `fmt.Stringer` by calling `.AppendTo`.
type Cond ¶ added in v0.2.0
type Cond Seq
Superset of `Seq` with additional support for structs. When the inner value is a struct, this generates a sequence of equality expressions, comparing the struct's column names against the corresponding field values. Field values may be arbitrary sub-expressions or arguments.
This is mostly an internal tool for building other expression types. Used internally by `And` and `Or`.
func (Cond) AppendExpr ¶ added in v0.2.0
Implement the `Expr` interface, making this a sub-expression.
type Delete ¶ added in v0.3.0
type Delete DeleteVoid
Shortcut for simple `delete from A where B returning *` expressions. See the examples. Also see `DeleteVoid` which doesn't have `returning *`.
Example (Filtered) ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { type Filter struct { Col0 int64 `db:"col0"` Col1 int64 `db:"col1"` } fmt.Println(s.Reify(s.Delete{`some_table`, Filter{10, 20}})) }
Output: delete from "some_table" where "col0" = $1 and "col1" = $2 returning * [10 20]
Example (Unfiltered) ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.Reify(s.Delete{`some_table`, nil})) }
Output: delete from "some_table" where null returning * []
func (Delete) AppendExpr ¶ added in v0.3.0
Implement the `Expr` interface, making this a sub-expression.
type DeleteVoid ¶ added in v0.7.1
Shortcut for simple `delete from A where B` expressions. Also see `Delete` which appends `returning *`.
func (DeleteVoid) AppendExpr ¶ added in v0.7.1
func (self DeleteVoid) AppendExpr(text []byte, args []any) ([]byte, []any)
Implement the `Expr` interface, making this a sub-expression.
func (DeleteVoid) AppendTo ¶ added in v0.7.1
func (self DeleteVoid) AppendTo(text []byte) []byte
Implement the `AppenderTo` interface, sometimes allowing more efficient text encoding.
func (DeleteVoid) String ¶ added in v0.7.1
func (self DeleteVoid) String() string
Implement the `fmt.Stringer` interface for debug purposes.
type Dict ¶ added in v0.2.0
Variant of `map[string]any` conforming to the `ArgDict` interface. Supports only named parameters, not ordinal parameters. Used for `StrQ`. See the `DictQ` shortcut.
func (Dict) GotOrdinal ¶ added in v0.2.0
Implement part of the `ArgDict` interface. Always returns `nil, false`.
func (Dict) RangeNamed ¶ added in v0.2.0
Implement `NamedRanger` to automatically validate used/unused arguments.
type Dir ¶ added in v0.2.0
type Dir byte
Short for "direction". Enum for ordering direction: none, "asc", "desc".
func (Dir) AppendTo ¶ added in v0.7.0
Implement the `AppenderTo` interface, sometimes allowing more efficient text encoding.
func (Dir) GoString ¶ added in v0.2.0
Implement `fmt.GoStringer` for debug purposes. Returns valid Go code representing this value.
func (Dir) MarshalJSON ¶ added in v0.6.3
Implement `json.Marshaler`.
func (Dir) MarshalText ¶ added in v0.6.3
Implement `encoding.TextUnmarshaler`.
func (*Dir) Parse ¶ added in v0.6.3
Parses from a string, which must be either empty, "asc" or "desc".
func (*Dir) UnmarshalText ¶ added in v0.6.3
Implement `encoding.TextMarshaler`.
type Eq ¶ added in v0.2.0
type Eq [2]any
Short for "equal". Represents SQL equality such as `A = B` or `A is null`. Counterpart to `Neq`.
Example ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.Reify(s.Eq{10, 20})) fmt.Println(s.Reify(s.Eq{ s.Ident(`some_col`), nil, })) fmt.Println(s.Reify(s.Eq{ s.Ident(`some_col`), s.Ident(`another_col`), })) fmt.Println(s.Reify(s.Eq{ s.Ident(`some_col`), s.Path{`some_table`, `another_col`}, })) }
Output: $1 = $2 [10 20] ("some_col") is null [] ("some_col") = ("another_col") [] ("some_col") = (("some_table")."another_col") []
func (Eq) AppendExpr ¶ added in v0.2.0
Implement the `Expr` interface, making this a sub-expression.
func (Eq) AppendLhs ¶ added in v0.2.0
Note: LHS and RHS are encoded differently because some SQL equality expressions are asymmetric. For example, `any` allows an array only on the RHS, and there's no way to invert it (AFAIK).
type EqAny ¶ added in v0.2.0
type EqAny [2]any
Represents an SQL expression `A = any(B)`. Counterpart to `NeqAny`.
Example ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.Reify(s.EqAny{ 10, []int{20, 30}, })) fmt.Println(s.Reify(s.EqAny{ s.Ident(`some_col`), []int{20, 30}, })) fmt.Println(s.Reify(s.EqAny{ s.Ident(`some_col`), s.Table{`some_table`}, })) }
Output: $1 = any ($2) [10 [20 30]] ("some_col") = any ($1) [[20 30]] ("some_col") = any (table "some_table") []
func (EqAny) AppendExpr ¶ added in v0.2.0
Implement the `Expr` interface, making this a sub-expression.
type Err ¶
All errors generated by this package have this type, usually wrapped into a more specialized one: `ErrInvalidInput{Err{...}}`.
type ErrEmptyExpr ¶ added in v0.2.1
type ErrEmptyExpr struct{ Err }
Specialized type for errors reported by some functions.
func (ErrEmptyExpr) Error ¶ added in v0.2.1
func (self ErrEmptyExpr) Error() string
Implement the `error` interface.
type ErrInternal ¶ added in v0.1.11
type ErrInternal struct{ Err }
Specialized type for errors reported by some functions.
func (ErrInternal) Error ¶ added in v0.2.0
func (self ErrInternal) Error() string
Implement the `error` interface.
type ErrInvalidInput ¶
type ErrInvalidInput struct{ Err }
Specialized type for errors reported by some functions.
func (ErrInvalidInput) Error ¶ added in v0.2.0
func (self ErrInvalidInput) Error() string
Implement the `error` interface.
type ErrMissingArgument ¶
type ErrMissingArgument struct{ Err }
Specialized type for errors reported by some functions.
func (ErrMissingArgument) Error ¶ added in v0.2.0
func (self ErrMissingArgument) Error() string
Implement the `error` interface.
type ErrOrdinalOutOfBounds ¶ added in v0.1.6
type ErrOrdinalOutOfBounds struct{ Err }
Specialized type for errors reported by some functions.
func (ErrOrdinalOutOfBounds) Error ¶ added in v0.2.0
func (self ErrOrdinalOutOfBounds) Error() string
Implement the `error` interface.
type ErrStr ¶ added in v0.7.2
type ErrStr string
String typedef that implements `error`. Errors of this type can be defined as constants.
type ErrUnexpectedEOF ¶ added in v0.2.0
type ErrUnexpectedEOF struct{ Err }
Specialized type for errors reported by some functions.
func (ErrUnexpectedEOF) Error ¶ added in v0.2.0
func (self ErrUnexpectedEOF) Error() string
Implement the `error` interface.
type ErrUnexpectedParameter ¶
type ErrUnexpectedParameter struct{ Err }
Specialized type for errors reported by some functions.
func (ErrUnexpectedParameter) Error ¶ added in v0.2.0
func (self ErrUnexpectedParameter) Error() string
Implement the `error` interface.
type ErrUnknownField ¶ added in v0.1.11
type ErrUnknownField struct{ Err }
Specialized type for errors reported by some functions.
func (ErrUnknownField) Error ¶ added in v0.2.0
func (self ErrUnknownField) Error() string
Implement the `error` interface.
type ErrUnusedArgument ¶
type ErrUnusedArgument struct{ Err }
Specialized type for errors reported by some functions.
func (ErrUnusedArgument) Error ¶ added in v0.2.0
func (self ErrUnusedArgument) Error() string
Implement the `error` interface.
type Expr ¶ added in v0.2.0
Short for "expression". Defines an arbitrary SQL expression. The method appends arbitrary SQL text. In both the input and output, the arguments must correspond to the parameters in the SQL text. Different databases support different styles of ordinal parameters. This package always generates Postgres-style ordinal parameters such as "$1", renumerating them as necessary.
This method is allowed to panic. Use `(*Bui).CatchExprs` to catch expression-encoding panics and convert them to errors.
All `Expr` types in this package also implement `AppenderTo` and `fmt.Stringer`.
type Exprs ¶ added in v0.2.0
type Exprs []Expr
Variable-sized sequence of expressions. When encoding, expressions will be space-separated if necessary.
Example ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { type Filter struct { Slug string `db:"slug"` } fmt.Println(s.Reify( s.Select{`some_table`, Filter{`some_slug`}}, )) }
Output: select * from "some_table" where "slug" = $1 [some_slug]
func (Exprs) AppendExpr ¶ added in v0.2.0
Implement the `Expr` interface, making this a sub-expression.
type Filter ¶ added in v0.5.0
type Filter interface{ AllowField(r.StructField) bool }
Filters struct fields. Used by `Sparse` and `ParseOpt`. Implemented by `TagFilter`.
type Haser ¶ added in v0.2.1
Used by `Partial` for filtering struct fields. See `Sparse` and `Partial` for explanations.
type Ident ¶ added in v0.2.0
type Ident string
Represents an SQL identifier, always quoted.
Example ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.Ident(``)) fmt.Println(s.Ident(`one`)) }
Output: "" "one"
Example (Interpolation) ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.Reify( s.StrQ{ `select :col from some_table where :col <> :val`, s.Dict{ `col`: s.Ident(`some_col`), `val`: `some_val`, }, }, )) }
Output: select "some_col" from some_table where "some_col" <> $1 [some_val]
func (Ident) AppendExpr ¶ added in v0.2.0
Implement the `Expr` interface, making this a sub-expression.
func (Ident) AppendTo ¶ added in v0.7.0
Implement the `AppenderTo` interface, sometimes allowing more efficient text encoding.
type Identifier ¶ added in v0.2.0
type Identifier []string
Represents a nested SQL identifier where all elements are quoted but not parenthesized. Useful for schema-qualified paths. For nested paths that don't begin with a schema, use `Path` instead.
Example ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.Identifier{`one`}) fmt.Println(s.Identifier{`one`, `two`}) fmt.Println(s.Identifier{`one`, `two`, `three`}) }
Output: "one" "one"."two" "one"."two"."three"
func (Identifier) AppendExpr ¶ added in v0.2.0
func (self Identifier) AppendExpr(text []byte, args []any) ([]byte, []any)
Implement the `Expr` interface, making this a sub-expression.
func (Identifier) AppendTo ¶ added in v0.7.0
func (self Identifier) AppendTo(text []byte) []byte
Implement the `AppenderTo` interface, sometimes allowing more efficient text encoding.
func (Identifier) Norm ¶ added in v0.2.0
func (self Identifier) Norm() Expr
Normalizes the expression, returning nil or a single `Ident` if the length allows this. Otherwise returns self as-is.
func (Identifier) String ¶ added in v0.2.0
func (self Identifier) String() string
Implement the `fmt.Stringer` interface for debug purposes.
type Insert ¶ added in v0.3.0
type Insert InsertVoid
Shortcut for simple `insert into A (B) values (C) returning *` expressions. See the examples. Also see `InsertVoid` which doesn't have `returning *`.
Example (Empty) ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.Reify(s.Insert{`some_table`, nil})) }
Output: insert into "some_table" default values returning * []
Example (NonEmpty) ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { type Fields struct { Col0 int64 `db:"col0"` Col1 int64 `db:"col1"` } fmt.Println(s.Reify(s.Insert{`some_table`, Fields{10, 20}})) }
Output: insert into "some_table" ("col0", "col1") values ($1, $2) returning * [10 20]
func (Insert) AppendExpr ¶ added in v0.3.0
Implement the `Expr` interface, making this a sub-expression.
type InsertVoid ¶ added in v0.7.1
Shortcut for simple `insert into A (B) values (C)` expressions. Also see `Insert` which appends `returning *`.
func (InsertVoid) AppendExpr ¶ added in v0.7.1
func (self InsertVoid) AppendExpr(text []byte, args []any) ([]byte, []any)
Implement the `Expr` interface, making this a sub-expression.
func (InsertVoid) AppendTo ¶ added in v0.7.1
func (self InsertVoid) AppendTo(text []byte) []byte
Implement the `AppenderTo` interface, sometimes allowing more efficient text encoding.
func (InsertVoid) String ¶ added in v0.7.1
func (self InsertVoid) String() string
Implement the `fmt.Stringer` interface for debug purposes.
type Jel ¶ added in v0.2.0
Short for "JSON Expression Language". Provides support for expressing a whitelisted subset of SQL with JSON, as Lisp-style nested lists. Transcodes JSON to SQL on the fly. Implements `Expr`. Can be transparently used as a sub-expression in other `sqlb` expressions. See the provided example.
Expressions are Lisp-style, using nested lists to express "calls". This syntax is used for all SQL operations. Binary infix operators are considered variadic.
Lists are used for calls and casts. The first element must be a string. It may be one of the whitelisted operators or functions, listed in `Ops`. If not, it must be a field name or a dot-separated field path. Calls are arbitrarily nestable.
["and", true, ["or", true, ["and", true, false]]] ["<=", 10, 20] ["=", "someField", "otherField"] ["and", ["=", "someField", "otherField"], ["<=", "dateField", ["dateField", "9999-01-01T00:00:00Z"]] ]
Transcoding from JSON to SQL is done by consulting two things: the built-in whitelist of SQL operations (`Ops`, shared), and a struct type provided to that particular decoder. The struct serves as a whitelist of available identifiers, and allows to determine value types via casting.
Casting allows to decode arbitrary JSON directly into the corresponding Go type:
["someDateField", "9999-01-01T00:00:00Z"] ["someGeoField", {"lng": 10, "lat": 20}]
Such decoded values are substituted with ordinal parameters such as $1, and appended to the slice of arguments (see below).
A string not in a call position and not inside a cast is interpreted as an identifier: field name or nested field path, dot-separated. It must be found on the reference struct, otherwise transcoding fails with an error.
"someField" "outerField.innerField"
Literal numbers, booleans, and nulls that occur outside of casts are decoded into their Go equivalents. Like casts, they're substituted with ordinal parameters and appended to the slice of arguments.
JSON queries are transcoded against a struct, by matching fields tagged with `json` against fields tagged with `db`. Literal values are JSON-decoded into the types of the corresponding struct fields.
type Input struct { FieldOne string `json:"fieldOne" db:"field_one"` FieldTwo struct { FieldThree *time.Time `json:"fieldThree" db:"field_three"` } `json:"fieldTwo" db:"field_two"` } const src = ` ["and", ["=", "fieldOne", ["fieldOne", "literal string"]], ["<", "fieldTwo.fieldThree", ["fieldTwo.fieldThree", "9999-01-01T00:00:00Z"]] ] ` expr := Jel{Type: reflect.TypeOf((*Input)(nil)).Elem(), Text: src} text, args := Reify(expr)
The result is roughly equivalent to the following (formatted for clarity):
text := ` "field_one" = 'literal string' and ("field_two")."field_three" < '9999-01-01T00:00:00Z' ` args := []any{"literal string", time.Time("9999-01-01T00:00:00Z")}
Example ¶
package main import ( "fmt" r "reflect" "time" "github.com/mitranim/sqlb" ) func main() { type Internal struct { InternalTime *time.Time `json:"internalTime" db:"internal_time"` } type External struct { ExternalName string `json:"externalName" db:"external_name"` Internal Internal `json:"internal" db:"internal"` } const src = ` ["and", ["or", false, ["=", "externalName", ["externalName", "literal string"]] ], ["and", true, ["<", "internal.internalTime", ["internal.internalTime", "9999-01-01T00:00:00Z"]] ] ] ` expr := sqlb.Jel{ Type: r.TypeOf((*External)(nil)).Elem(), Text: src, } text, args := sqlb.Reify(expr) fmt.Println(string(text)) fmt.Printf("%#v\n", args) }
Output: (($1 or ("external_name" = $2)) and ($3 and (("internal")."internal_time" < $4))) []interface {}{false, "literal string", true, time.Date(9999, time.January, 1, 0, 0, 0, 0, time.UTC)}
func JelFor ¶ added in v0.2.0
Shortcut for instantiating `Jel` with the type of the given value. The input is used only as a type carrier.
func (Jel) AppendExpr ¶ added in v0.2.0
Implement `Expr`, allowing this to be used as a sub-expression in queries built with "github.com/mitranim/sqlb". Always generates a valid boolean expression, falling back on "true" if empty.
func (Jel) AppendTo ¶ added in v0.7.0
Implement the `AppenderTo` interface, sometimes allowing more efficient text encoding.
func (*Jel) OrType ¶ added in v0.2.0
If `.Type` is empty, sets the type of the provided value. Otherwise this is a nop. The input is used only as a type carrier; its actual value is ignored.
func (*Jel) Parse ¶ added in v0.2.0
Stores the input for future use in `.AppendExpr`. Input must be valid JSON.
func (*Jel) UnmarshalJSON ¶ added in v0.2.0
Stores the input for future use in `.AppendExpr`. Input must be valid JSON.
func (*Jel) UnmarshalText ¶ added in v0.2.0
Stores the input for future use in `.AppendExpr`. Input must be valid JSON.
type LaxDict ¶ added in v0.6.8
type LaxDict Dict
Variant of `Dict` without support for validating unused arguments. Note that missing arguments are still detected and cause errors. Useful when generating the dictionary dynamically, rather than hardcoding the set of keys. Must be used with `StrQ` or `Prep`, rather than with `DictQ`, because the latter always converts the given dictionary to `Dict`.
func (LaxDict) GotOrdinal ¶ added in v0.6.8
Implement part of the `ArgDict` interface. Always returns `nil, false`.
type Limit ¶ added in v0.4.2
type Limit [1]any
Represents SQL expression "limit N" with an arbitrary argument or sub-expression. Implements `Expr`:
- If nil -> append nothing.
- If expr -> append "limit (<sub-expression>)".
- If val -> append "limit $N" with the corresponding argument.
func (Limit) AppendExpr ¶ added in v0.4.2
Implement the `Expr` interface, making this a sub-expression.
type LimitUint ¶ added in v0.4.2
type LimitUint uint64
Represents SQL expression "limit N" with a number. Implements `Expr`:
- If 0 -> append nothing.
- Otherwise -> append literal "limit <N>" such as "limit 1".
Because this is uint64, you can safely and correctly decode arbitrary user input into this value, for example into a struct field of this type.
Example ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.Reify( s.Exprs{s.Select{`some_table`, nil}, s.LimitUint(10)}, )) }
Output: select * from "some_table" limit 10 []
func (LimitUint) AppendExpr ¶ added in v0.4.2
Implement the `Expr` interface, making this a sub-expression.
type List ¶ added in v0.2.0
type List []any
Variant of `[]any` conforming to the `ArgDict` interface. Supports only ordinal parameters, not named parameters. Used for `StrQ`. See the `ListQ` shortcut.
func (List) GotNamed ¶ added in v0.2.0
Implement part of the `ArgDict` interface. Always returns `nil, false`.
func (List) GotOrdinal ¶ added in v0.2.0
Implement part of the `ArgDict` interface.
func (List) RangeOrdinal ¶ added in v0.2.0
Implement `OrdinalRanger` to automatically validate used/unused arguments.
type NamedParam ¶ added in v0.2.0
type NamedParam string
Represents a named parameter such as ":blah". Mostly for internal use.
func (NamedParam) AppendExpr ¶ added in v0.2.0
func (self NamedParam) AppendExpr(text []byte, args []any) ([]byte, []any)
Implement the `Expr` interface, making this a sub-expression.
func (NamedParam) AppendTo ¶ added in v0.7.0
func (self NamedParam) AppendTo(text []byte) []byte
Implement the `AppenderTo` interface, sometimes allowing more efficient text encoding.
func (NamedParam) Key ¶ added in v0.2.0
func (self NamedParam) Key() string
Converts to the corresponding dictionary key, which is a plain string. This is a free cast, used to increase code clarity.
func (NamedParam) String ¶ added in v0.2.0
func (self NamedParam) String() string
Implement the `fmt.Stringer` interface for debug purposes.
type NamedRanger ¶ added in v0.2.0
type NamedRanger interface { /** Must iterate over known argument names, calling the function for each name. The func is provided by this package, and will panic for each unused argument. */ RangeNamed(func(string)) }
Optional extension for `ArgDict`. If implemented, this is used to validate used/unused named arguments after building a parametrized SQL expression such as `StrQ`/`Prep`.
type Neq ¶ added in v0.2.0
type Neq [2]any
Short for "not equal". Represents SQL non-equality such as `A <> B` or `A is not null`. Counterpart to `Eq`.
Example ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.Reify(s.Neq{10, 20})) fmt.Println(s.Reify(s.Neq{ s.Ident(`some_col`), nil, })) fmt.Println(s.Reify(s.Neq{ s.Ident(`some_col`), s.Ident(`another_col`), })) fmt.Println(s.Reify(s.Neq{ s.Ident(`some_col`), s.Path{`some_table`, `another_col`}, })) }
Output: $1 <> $2 [10 20] ("some_col") is not null [] ("some_col") <> ("another_col") [] ("some_col") <> (("some_table")."another_col") []
func (Neq) AppendExpr ¶ added in v0.2.0
Implement the `Expr` interface, making this a sub-expression.
type NeqAny ¶ added in v0.2.0
type NeqAny [2]any
Represents an SQL expression `A <> any(B)`. Counterpart to `EqAny`.
Example ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.Reify(s.NeqAny{ 10, []int{20, 30}, })) fmt.Println(s.Reify(s.NeqAny{ s.Ident(`some_col`), []int{20, 30}, })) fmt.Println(s.Reify(s.NeqAny{ s.Ident(`some_col`), s.Table{`some_table`}, })) }
Output: $1 <> any ($2) [10 [20 30]] ("some_col") <> any ($1) [[20 30]] ("some_col") <> any (table "some_table") []
func (NeqAny) AppendExpr ¶ added in v0.2.0
Implement the `Expr` interface, making this a sub-expression.
type Not ¶ added in v0.2.0
type Not [1]any
Represents SQL logical negation such as `not A`. The inner value can be an instance of `Expr` or an arbitrary argument.
Example ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.Reify(s.Not{})) fmt.Println(s.Reify(s.Not{true})) fmt.Println(s.Reify(s.Not{s.Ident(`some_col`)})) }
Output: not $1 [<nil>] not $1 [true] not ("some_col") []
func (Not) AppendExpr ¶ added in v0.2.0
Implement the `Expr` interface, making this a sub-expression.
type Nullable ¶ added in v0.5.1
type Nullable interface{ IsNull() bool }
Optional interface that allows `sqlb` to determine if a given value is null, allowing some expressions to generate `is null` / `is not null` clauses. Not actually required; nils of Go nilable types are automatically considered null, and `sqlb` falls back on encoding the value via `driver.Valuer`. This interface is supported for additional flexibility and efficiency.
type Nulls ¶ added in v0.2.0
type Nulls byte
Enum for nulls handling in ordering: none, "nulls first", "nulls last".
func (Nulls) AppendTo ¶ added in v0.7.0
Implement the `AppenderTo` interface, sometimes allowing more efficient text encoding.
type Offset ¶ added in v0.4.2
type Offset [1]any
Represents SQL expression "offset N" with an arbitrary sub-expression. Implements `Expr`:
- If nil -> append nothing.
- If expr -> append "offset (<sub-expression>)".
- If val -> append "offset $N" with the corresponding argument.
func (Offset) AppendExpr ¶ added in v0.4.2
Implement the `Expr` interface, making this a sub-expression.
type OffsetUint ¶ added in v0.4.2
type OffsetUint uint64
Represents SQL expression "offset N" with a number. Implements `Expr`:
- If 0 -> append nothing.
- Otherwise -> append literal "offset <N>" such as "offset 1".
Because this is uint64, you can safely and correctly decode arbitrary user input into this value, for example into a struct field of this type.
Example ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.Reify( s.Exprs{s.Select{`some_table`, nil}, s.OffsetUint(10)}, )) }
Output: select * from "some_table" offset 10 []
func (OffsetUint) AppendExpr ¶ added in v0.4.2
func (self OffsetUint) AppendExpr(text []byte, args []any) ([]byte, []any)
Implement the `Expr` interface, making this a sub-expression.
func (OffsetUint) AppendTo ¶ added in v0.7.0
func (self OffsetUint) AppendTo(text []byte) []byte
Implement the `AppenderTo` interface, sometimes allowing more efficient text encoding.
func (OffsetUint) String ¶ added in v0.4.2
func (self OffsetUint) String() string
Implement the `fmt.Stringer` interface for debug purposes.
type Op ¶ added in v0.2.0
type Op byte
Syntax type of SQL operator expressions used in JEL. Allows us to convert JEL Lisp-style "calls" into SQL-style operations that use prefix, infix, etc.
type Or ¶ added in v0.2.0
type Or [1]any
Represents a sequence of arbitrary sub-expressions or arguments joined by the SQL `or` operator. Rules for the inner value:
- nil or empty -> fallback to `false`
- single `Expr` -> render it as-is
- non-empty slice -> render its individual elements joined by `or`
- non-empty struct -> render column equality conditions joined by `or`
Example (Slice) ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { type list = []any fmt.Println(s.Reify(s.Or{nil})) fmt.Println(s.Reify(s.Or{list{}})) fmt.Println(s.Reify(s.Or{list{true, false, s.Ident(`some_col`)}})) }
Output: false [] false [] $1 or $2 or ("some_col") [true false]
Example (Struct) ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.Reify(s.Or{struct{}{}})) fmt.Println(s.Reify(s.Or{struct { Col0 bool `db:"col0"` Col1 any `db:"col1"` Col2 any `db:"col2"` }{ true, nil, s.Call{`some_func`, []int{10}}, }})) }
Output: false [] "col0" = $1 or "col1" is null or "col2" = (some_func ($2)) [true 10]
func (Or) AppendExpr ¶ added in v0.2.0
Implement the `Expr` interface, making this a sub-expression.
type Ord ¶ added in v0.1.10
Structured representation of an arbitrary SQL ordering expression. This is not the entire "order by" clause (see `Ords`), but rather just one element in that clause. Also see `Ords`, `OrdsParser`, and the various provided examples.
func (Ord) AppendExpr ¶ added in v0.2.0
Implement the `Expr` interface, making this a sub-expression.
type OrdAsc ¶ added in v0.1.10
type OrdAsc []string
Same as `Ord{Path: path, Dir: DirAsc}` but more syntactically convenient and uses less memory.
func (OrdAsc) AppendExpr ¶ added in v0.2.0
Implement the `Expr` interface, making this a sub-expression.
type OrdAscNullsFirst ¶ added in v0.2.0
type OrdAscNullsFirst []string
Same as `Ord{Path: path, Dir: DirAsc, Nulls: NullsFirst}` but more syntactically convenient and uses less memory.
func (OrdAscNullsFirst) AppendExpr ¶ added in v0.2.0
func (self OrdAscNullsFirst) AppendExpr(text []byte, args []any) ([]byte, []any)
Implement the `Expr` interface, making this a sub-expression.
func (OrdAscNullsFirst) AppendTo ¶ added in v0.7.0
func (self OrdAscNullsFirst) AppendTo(text []byte) []byte
Implement the `AppenderTo` interface, sometimes allowing more efficient text encoding.
func (OrdAscNullsFirst) String ¶ added in v0.2.0
func (self OrdAscNullsFirst) String() string
Implement the `fmt.Stringer` interface for debug purposes.
type OrdAscNullsLast ¶ added in v0.2.0
type OrdAscNullsLast []string
Same as `Ord{Path: path, Dir: DirAsc, Nulls: NullsLast}` but more syntactically convenient and uses less memory.
func (OrdAscNullsLast) AppendExpr ¶ added in v0.2.0
func (self OrdAscNullsLast) AppendExpr(text []byte, args []any) ([]byte, []any)
Implement the `Expr` interface, making this a sub-expression.
func (OrdAscNullsLast) AppendTo ¶ added in v0.7.0
func (self OrdAscNullsLast) AppendTo(text []byte) []byte
Implement the `AppenderTo` interface, sometimes allowing more efficient text encoding.
func (OrdAscNullsLast) String ¶ added in v0.2.0
func (self OrdAscNullsLast) String() string
Implement the `fmt.Stringer` interface for debug purposes.
type OrdDesc ¶ added in v0.1.10
type OrdDesc []string
Same as `Ord{Path: path, Dir: DirDesc}` but more syntactically convenient and uses less memory.
func (OrdDesc) AppendExpr ¶ added in v0.2.0
Implement the `Expr` interface, making this a sub-expression.
type OrdDescNullsFirst ¶ added in v0.2.0
type OrdDescNullsFirst []string
Same as `Ord{Path: path, Dir: DirDesc, Nulls: NullsFirst}` but more syntactically convenient and uses less memory.
func (OrdDescNullsFirst) AppendExpr ¶ added in v0.2.0
func (self OrdDescNullsFirst) AppendExpr(text []byte, args []any) ([]byte, []any)
Implement the `Expr` interface, making this a sub-expression.
func (OrdDescNullsFirst) AppendTo ¶ added in v0.7.0
func (self OrdDescNullsFirst) AppendTo(text []byte) []byte
Implement the `AppenderTo` interface, sometimes allowing more efficient text encoding.
func (OrdDescNullsFirst) String ¶ added in v0.2.0
func (self OrdDescNullsFirst) String() string
Implement the `fmt.Stringer` interface for debug purposes.
type OrdDescNullsLast ¶ added in v0.2.0
type OrdDescNullsLast []string
Same as `Ord{Path: path, Dir: DirDesc, Nulls: NullsLast}` but more syntactically convenient and uses less memory.
func (OrdDescNullsLast) AppendExpr ¶ added in v0.2.0
func (self OrdDescNullsLast) AppendExpr(text []byte, args []any) ([]byte, []any)
Implement the `Expr` interface, making this a sub-expression.
func (OrdDescNullsLast) AppendTo ¶ added in v0.7.0
func (self OrdDescNullsLast) AppendTo(text []byte) []byte
Implement the `AppenderTo` interface, sometimes allowing more efficient text encoding.
func (OrdDescNullsLast) String ¶ added in v0.2.0
func (self OrdDescNullsLast) String() string
Implement the `fmt.Stringer` interface for debug purposes.
type OrdNullsFirst ¶ added in v0.2.0
type OrdNullsFirst []string
Same as `Ord{Path: path, Nulls: NullsFirst}` but more syntactically convenient and uses less memory.
func (OrdNullsFirst) AppendExpr ¶ added in v0.2.0
func (self OrdNullsFirst) AppendExpr(text []byte, args []any) ([]byte, []any)
Implement the `Expr` interface, making this a sub-expression.
func (OrdNullsFirst) AppendTo ¶ added in v0.7.0
func (self OrdNullsFirst) AppendTo(text []byte) []byte
Implement the `AppenderTo` interface, sometimes allowing more efficient text encoding.
func (OrdNullsFirst) String ¶ added in v0.2.0
func (self OrdNullsFirst) String() string
Implement the `fmt.Stringer` interface for debug purposes.
type OrdNullsLast ¶ added in v0.2.0
type OrdNullsLast []string
Same as `Ord{Path: path, Nulls: NullsLast}` but more syntactically convenient and uses less memory.
func (OrdNullsLast) AppendExpr ¶ added in v0.2.0
func (self OrdNullsLast) AppendExpr(text []byte, args []any) ([]byte, []any)
Implement the `Expr` interface, making this a sub-expression.
func (OrdNullsLast) AppendTo ¶ added in v0.7.0
func (self OrdNullsLast) AppendTo(text []byte) []byte
Implement the `AppenderTo` interface, sometimes allowing more efficient text encoding.
func (OrdNullsLast) String ¶ added in v0.2.0
func (self OrdNullsLast) String() string
Implement the `fmt.Stringer` interface for debug purposes.
type OrderBy ¶ added in v0.2.0
type OrderBy [1]Expr
If the provided expression is not nil, prepends the keywords "order by" to it. If the provided expression is nil, this is a nop.
func (OrderBy) AppendExpr ¶ added in v0.2.0
Implement the `Expr` interface, making this a sub-expression.
type Ordering ¶ added in v0.2.0
Structured representation of an arbitrary SQL ordering expression. This is not the entire "order by" clause (see `Ords`), but rather just one element in that clause. This is the general-case representation, but because most ordering expressions use only column names and direction, a more specialized representation is preferred: `Ord`. This is provided just-in-case.
func (Ordering) AppendExpr ¶ added in v0.2.0
Implement the `Expr` interface, making this a sub-expression.
type OrdinalParam ¶ added in v0.2.0
type OrdinalParam int
Represents an ordinal parameter such as "$1". Mostly for internal use.
func (OrdinalParam) AppendExpr ¶ added in v0.2.0
func (self OrdinalParam) AppendExpr(text []byte, args []any) ([]byte, []any)
Implement the `Expr` interface, making this a sub-expression.
func (OrdinalParam) AppendTo ¶ added in v0.7.0
func (self OrdinalParam) AppendTo(text []byte) []byte
Implement the `AppenderTo` interface, sometimes allowing more efficient text encoding.
func (OrdinalParam) FromIndex ¶ added in v0.2.0
func (self OrdinalParam) FromIndex() OrdinalParam
Inverse of `OrdinalParam.Index`: increments by 1, converting index to param.
func (OrdinalParam) Index ¶ added in v0.2.0
func (self OrdinalParam) Index() int
Returns the corresponding Go index (starts at zero).
func (OrdinalParam) String ¶ added in v0.2.0
func (self OrdinalParam) String() string
Implement the `fmt.Stringer` interface for debug purposes.
type OrdinalRanger ¶ added in v0.2.0
type OrdinalRanger interface { /** Must iterate over argument indexes from 0 to N, calling the function for each index. The func is provided by this package, and will panic for each unused argument. */ RangeOrdinal(func(int)) }
Optional extension for `ArgDict`. If implemented, this is used to validate used/unused ordinal arguments after building a parametrized SQL expression such as `StrQ`/`Prep`.
type Ords ¶ added in v0.1.10
type Ords []Expr
Short for "orderings". Sequence of arbitrary expressions used for an SQL "order by" clause. Nil elements are treated as non-existent. If there are no non-nil elements, the resulting expression is empty. Otherwise, the resulting expression is "order by" followed by comma-separated sub-expressions. You can construct `Ords` manually, or parse client inputs via `OrdsParser`. See the examples.
Example (Empty) ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.Ords{}) }
Output:
Example (Manual) ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.Ords{ s.OrdDesc{`col0`}, s.Str(`random() asc`), }) }
Output: order by "col0" desc, random() asc
func (Ords) AppendExpr ¶ added in v0.2.0
Implement the `Expr` interface, making this a sub-expression.
func (Ords) AppendTo ¶ added in v0.7.0
Implement the `AppenderTo` interface, sometimes allowing more efficient text encoding.
func (Ords) MarshalJSON ¶ added in v0.5.0
Allows types that embed `Ords` to behave like a slice in JSON encoding, avoiding some edge issues. For example, this allows an empty `ParserOrds` to be encoded as JSON `null` rather than a struct, allowing types that include it as a field to be used for encoding JSON, not just decoding it. However, this doesn't make ords encoding/decoding actually reversible. Decoding "consults" a struct type to convert JSON field names to DB column names. Ideally, JSON marshaling would perform the same process in reverse, which is not currently implemented.
func (*Ords) OrdsParser ¶ added in v0.5.0
func (self *Ords) OrdsParser(typ any) (out OrdsParser)
Returns an `OrdsParser` that can decode arbitrary JSON or a string slice into the given `*Ords` pointer. Initializes the parser to the provided type, using `typ` only as a type carrier.
Example ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { type SomeStruct struct { Col0 string `json:"jsonField0" db:"dbCol0"` Col1 string `json:"jsonField1" db:"dbCol1"` } var ords s.Ords err := ords.OrdsParser((*SomeStruct)(nil)).ParseSlice([]string{ `jsonField0 asc`, `jsonField1 desc nulls last`, }) if err != nil { panic(err) } fmt.Printf("%#v\n\n", ords) fmt.Println(ords) }
Output: sqlb.Ords{sqlb.OrdAsc{"dbCol0"}, sqlb.OrdDescNullsLast{"dbCol1"}} order by "dbCol0" asc, "dbCol1" desc nulls last
func (Ords) RowNumberOver ¶ added in v0.2.0
func (self Ords) RowNumberOver() RowNumberOver
Returns an expression for the Postgres window function `row_number`:
Ords{}.RowNumber() -> `0` Ords{OrdAsc(`col`)}.RowNumber() -> `row_number() over (order by "col" asc)`
As shown above, empty `Ords` generates `0`. The Postgres query planner should optimize away any ordering by this constant column.
type OrdsParser ¶ added in v0.2.0
Similar to `ParserOrds`, but intended to be transient and stackframe-local, rather than included into other types. Usually obtained by calling `(*Ords).OrdsParser`.
func (OrdsParser) ParseSlice ¶ added in v0.2.0
func (self OrdsParser) ParseSlice(src []string) (err error)
See `(*ParserOrds).ParseSlice` for docs.
func (OrdsParser) UnmarshalJSON ¶ added in v0.2.0
func (self OrdsParser) UnmarshalJSON(src []byte) (err error)
Implement `json.Unmarshaler`. See `(*ParserOrds).UnmarshalJSON` for docs.
type Ors ¶ added in v0.2.0
type Ors []any
Syntactic shortcut, same as `Or` with a slice of sub-expressions or arguments.
Example ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.Reify(s.Ors{})) fmt.Println(s.Reify(s.Ors{true, false, s.Ident(`some_col`)})) }
Output: false [] $1 or $2 or ("some_col") [true false]
func (Ors) AppendExpr ¶ added in v0.2.0
Implement the `Expr` interface, making this a sub-expression.
type ParamExpr ¶ added in v0.2.0
Short for "parametrized expression". Similar to `Expr`, but requires an external input in order to be a valid expression. Implemented by preparsed query types, namely by `Prep`.
type ParseOpt ¶ added in v0.5.0
type ParseOpt struct { /** Must be a struct type. Ords parsing uses this to detect which fields are allowed, and to convert JSON field names to DB column names. */ Type r.Type /** Optional filter. When non-nil, this is invoked for each struct field during ords parsing. If this returns false, the field is "unknown" and may generate a parse error depending on `.Lax`. */ Filter Filter /** When true, unknown JSON fields are skipped/ignored durung parsing. When false, unknown JSON fields cause ords parsing to fail with a descriptive error. */ Lax bool }
Options related to parsing text into `Ords`. Used by `ParserOrds` and `OrdsParser`.
type ParserOrds ¶ added in v0.5.0
Contains `Ords` and parsing options, and implements decoder interfaces such as `json.Unmarshaler`. Intended to be included into other structs. Unmarshals text into inner `Ords` in accordance with the parsing options.
func (*ParserOrds) ParseSlice ¶ added in v0.5.0
func (self *ParserOrds) ParseSlice(src []string) error
Parses a string slice which must consist of individual ordering strings such as "one.two.three desc". Ignores empty strings. Used internally for parsing JSON. String slices may also come from URL queries, form-encoded data, and so on. Supported input format:
<path> <asc|desc>? <nulls first | nulls last>?
Each path can be a single identifier or dot-separated:
one one.two one.two.three
The path MUST correspond to JSON-tagged fields in the reference struct type, which MUST have corresponding DB column names. The parsed ordering uses DB column names, rather than the original JSON names.
Example ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { type SomeStruct struct { Col0 string `json:"jsonField0" db:"dbCol0"` Col1 string `json:"jsonField1" db:"dbCol1"` } var par s.ParserOrds par.OrType((*SomeStruct)(nil)) err := par.ParseSlice([]string{`jsonField0 asc`, `jsonField1 desc nulls last`}) if err != nil { panic(err) } fmt.Printf("%#v\n\n", par.Ords) fmt.Println(par.Ords) }
Output: sqlb.Ords{sqlb.OrdAsc{"dbCol0"}, sqlb.OrdDescNullsLast{"dbCol1"}} order by "dbCol0" asc, "dbCol1" desc nulls last
func (*ParserOrds) UnmarshalJSON ¶ added in v0.5.0
func (self *ParserOrds) UnmarshalJSON(src []byte) error
Implement `json.Unmarshaler`. Consults `.Type` to determine known field paths, and converts them to DB column paths, rejecting unknown identifiers. The JSON input must represent an array of strings. See the method `.ParseSlice` for more docs.
Example ¶
package main import ( "encoding/json" "fmt" s "github.com/mitranim/sqlb" ) func main() { type SomeStruct struct { Col0 string `json:"jsonField0" db:"dbCol0"` Col1 string `json:"jsonField1" db:"dbCol1"` } var par s.ParserOrds par.OrType((*SomeStruct)(nil)) err := json.Unmarshal( []byte(`["jsonField0 asc", "jsonField1 desc nulls last"]`), &par, ) if err != nil { panic(err) } fmt.Printf("%#v\n\n", par.Ords) fmt.Println(par.Ords) }
Output: sqlb.Ords{sqlb.OrdAsc{"dbCol0"}, sqlb.OrdDescNullsLast{"dbCol1"}} order by "dbCol0" asc, "dbCol1" desc nulls last
type Partial ¶ added in v0.2.1
Implements `Sparse` by filtering fields on their JSON names, using only explicit "json" tags. Fields without explicit "json" names are automatically considered missing. Fields with "json" tags must be present in the provided string set represented by `.Fil`.
Designed for compatibility with HTTP request decoders provided by "github.com/mitranim/rd", which either implement `Haser` or can easily generate one. Example PATCH endpoint using "rd":
import "github.com/mitranim/rd" import "github.com/mitranim/try" import s "github.com/mitranim/sqlb" dec := rd.TryDownload(req) var input SomeStructType try.To(dec.Decode(&input)) expr := s.Exprs{ s.Update{s.Ident(`some_table`)}, s.Set{s.StructAssign{s.Partial{input, dec.Haser()}}}, }
func (Partial) AllowField ¶ added in v0.5.0
func (self Partial) AllowField(field r.StructField) bool
Implement `Sparse`, using the underlying filter.
type Path ¶ added in v0.2.0
type Path []string
Represents a nested SQL identifier where the first outer element is parenthesized, and every element is quoted. Useful for nested paths that begin with a table or view name. For schema-qualified paths, use `Identifier` instead.
Example ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.Path{`one`}) fmt.Println(s.Path{`one`, `two`}) fmt.Println(s.Path{`one`, `two`, `three`}) }
Output: "one" ("one")."two" ("one")."two"."three"
func (Path) AppendExpr ¶ added in v0.2.0
Implement the `Expr` interface, making this a sub-expression.
func (Path) AppendTo ¶ added in v0.7.0
Implement the `AppenderTo` interface, sometimes allowing more efficient text encoding.
type Prefix ¶ added in v0.2.0
Combines an expression with a string prefix. If the expr is nil, this is a nop, and the prefix is ignored. Mostly an internal tool for building other expression types.
func (Prefix) AppendExpr ¶ added in v0.2.0
Implement the `Expr` interface, making this a sub-expression.
type Prep ¶ added in v0.2.0
Short for "preparsed" or "prepared". Partially parsed representation of parametrized SQL expressions, suited for efficiently building SQL queries by providing arguments. Supports both ordinal and named parameters/arguments. To avoid redundant work, this should be parsed and cached only once for each SQL query; this deduplication is done by `Preparse` which is also used internally by `StrQ`. User code doesn't need to construct this.
func Preparse ¶ added in v0.2.0
Returns a parsed `Prep` for the given source string. Panics if parsing fails. Caches the result for each source string, reusing it for future calls. Used internally by `StrQ`. User code shouldn't have to call this, but it's exported just in case.
func (Prep) AppendParamExpr ¶ added in v0.2.0
Implement the `ParamExpr` interface. Builds the expression by using the provided named args. Used internally by `StrQ`.
func (Prep) AppendTo ¶ added in v0.7.0
Implement the `AppenderTo` interface, sometimes allowing more efficient text encoding.
type PseudoPath ¶ added in v0.2.0
type PseudoPath []string
Represents an arbitrarily-nested SQL path that gets encoded as a SINGLE quoted identifier, where elements are dot-separated. This is a common convention for nested structs, supported by SQL-scanning libraries such as https://github.com/mitranim/gos.
Example ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.PseudoPath{`one`}) fmt.Println(s.PseudoPath{`one`, `two`}) fmt.Println(s.PseudoPath{`one`, `two`, `three`}) }
Output: "one" "one.two" "one.two.three"
func (PseudoPath) AppendExpr ¶ added in v0.2.0
func (self PseudoPath) AppendExpr(text []byte, args []any) ([]byte, []any)
Implement the `Expr` interface, making this a sub-expression.
func (PseudoPath) AppendTo ¶ added in v0.7.0
func (self PseudoPath) AppendTo(text []byte) []byte
Implement the `AppenderTo` interface, sometimes allowing more efficient text encoding.
func (PseudoPath) Norm ¶ added in v0.2.0
func (self PseudoPath) Norm() Expr
Normalizes the expression, returning nil or a single `Ident` if the length allows this. Otherwise returns self as-is.
func (PseudoPath) String ¶ added in v0.2.0
func (self PseudoPath) String() string
Implement the `fmt.Stringer` interface for debug purposes.
type ReturningAll ¶ added in v0.7.1
type ReturningAll struct{}
Represents the Postgres `returning *` clause.
func (ReturningAll) AppendExpr ¶ added in v0.7.1
func (self ReturningAll) AppendExpr(text []byte, args []any) ([]byte, []any)
Implement the `Expr` interface, making this a sub-expression.
func (ReturningAll) AppendTo ¶ added in v0.7.1
func (self ReturningAll) AppendTo(text []byte) []byte
Implement the `AppenderTo` interface, sometimes allowing more efficient text encoding.
func (ReturningAll) String ¶ added in v0.7.1
func (ReturningAll) String() string
Implement the `fmt.Stringer` interface for debug purposes.
type RowNumberOver ¶ added in v0.2.0
type RowNumberOver [1]Expr
Represents the Postgres window function `row_number`:
RowNumberOver{} -> `0` RowNumberOver{Ords{OrdDesc{Ident(`some_col`)}}} -> `row_number() over (order by "col" desc)`
When the inner expression is nil and the output is `0`, the Postgres query planner should be able to optimize it away.
Example (Empty) ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.RowNumberOver{}) }
Output: 0
Example (NonEmpty) ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.RowNumberOver{s.Ords{s.OrdDesc{`some_col`}}}) }
Output: row_number() over (order by "some_col" desc)
func (RowNumberOver) AppendExpr ¶ added in v0.2.0
func (self RowNumberOver) AppendExpr(text []byte, args []any) ([]byte, []any)
Implement the `Expr` interface, making this a sub-expression.
func (RowNumberOver) AppendTo ¶ added in v0.7.0
func (self RowNumberOver) AppendTo(text []byte) []byte
Implement the `AppenderTo` interface, sometimes allowing more efficient text encoding.
func (RowNumberOver) String ¶ added in v0.2.0
func (self RowNumberOver) String() string
Implement the `fmt.Stringer` interface for debug purposes.
type Select ¶ added in v0.2.0
Shortcut for simple "select * from A where B" expressions. See the examples.
Example (Filtered) ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { type Filter struct { Col0 int64 `db:"col0"` Col1 int64 `db:"col1"` } fmt.Println(s.Reify(s.Select{`some_table`, Filter{10, 20}})) }
Output: select * from "some_table" where "col0" = $1 and "col1" = $2 [10 20]
Example (Unfiltered) ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.Reify(s.Select{`some_table`, nil})) }
Output: select * from "some_table" []
func (Select) AppendExpr ¶ added in v0.2.0
Implement the `Expr` interface, making this a sub-expression.
type SelectCols ¶ added in v0.2.0
Wraps an arbitrary sub-expression, using `Cols{.Type}` to select specific columns from it. If `.Type` doesn't specify a set of columns, for example because it's not a struct type, then this uses the sub-expression as-is without wrapping. Counterpart to `SelectColsDeep`.
Example (AsIs) ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.SelectCols{s.Table{`some_table`}, nil}) }
Output: table "some_table"
Example (Cols) ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { type SomeStruct struct { Col0 string `db:"col0"` Col1 string `db:"col1"` Col2 string `db:"-"` } fmt.Println(s.SelectCols{s.Table{`some_table`}, (*SomeStruct)(nil)}) }
Output: with _ as (table "some_table") select "col0", "col1" from _
func (SelectCols) AppendExpr ¶ added in v0.2.0
func (self SelectCols) AppendExpr(text []byte, args []any) ([]byte, []any)
Implement the `Expr` interface, making this a sub-expression.
func (SelectCols) AppendTo ¶ added in v0.7.0
func (self SelectCols) AppendTo(text []byte) []byte
Implement the `AppenderTo` interface, sometimes allowing more efficient text encoding.
func (SelectCols) String ¶ added in v0.2.0
func (self SelectCols) String() string
Implement the `fmt.Stringer` interface for debug purposes.
type SelectColsDeep ¶ added in v0.2.0
Wraps an arbitrary sub-expression, using `ColsDeep{.Type}` to select specific columns from it. If `.Type` doesn't specify a set of columns, for example because it's not a struct type, then this uses the sub-expression as-is without wrapping. Counterpart to `SelectCols`.
Example (AsIs) ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.SelectColsDeep{s.Table{`some_table`}, nil}) }
Output: table "some_table"
Example (Cols) ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { type SomeStruct struct { Outer string `db:"outer"` Inner struct { Name string `db:"name"` } `db:"inner"` } fmt.Println(s.SelectColsDeep{s.Table{`some_table`}, (*SomeStruct)(nil)}) }
Output: with _ as (table "some_table") select "outer", ("inner")."name" as "inner.name" from _
func (SelectColsDeep) AppendExpr ¶ added in v0.2.0
func (self SelectColsDeep) AppendExpr(text []byte, args []any) ([]byte, []any)
Implement the `Expr` interface, making this a sub-expression.
func (SelectColsDeep) AppendTo ¶ added in v0.7.0
func (self SelectColsDeep) AppendTo(text []byte) []byte
Implement the `AppenderTo` interface, sometimes allowing more efficient text encoding.
func (SelectColsDeep) String ¶ added in v0.2.0
func (self SelectColsDeep) String() string
Implement the `fmt.Stringer` interface for debug purposes.
type SelectCount ¶ added in v0.4.3
type SelectCount [1]Expr
Shortcut for selecting `count(*)` from an arbitrary sub-expression. Equivalent to `s.SelectString{expr, "count(*)"}`.
Example ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println( s.SelectCount{s.Table{`some_table`}}, ) }
Output: with _ as (table "some_table") select count(*) from _
func (SelectCount) AppendExpr ¶ added in v0.4.3
func (self SelectCount) AppendExpr(text []byte, args []any) ([]byte, []any)
Implement the `Expr` interface, making this a sub-expression.
func (SelectCount) AppendTo ¶ added in v0.7.0
func (self SelectCount) AppendTo(text []byte) []byte
Implement the `AppenderTo` interface, sometimes allowing more efficient text encoding.
func (SelectCount) String ¶ added in v0.4.3
func (self SelectCount) String() string
Implement the `fmt.Stringer` interface for debug purposes.
type SelectString ¶ added in v0.2.0
Represents an SQL expression "select .What from (.From) as _". Mostly an internal tool for building other expression types. Used internally by `Cols` and `ColsDeep`; see their docs and examples.
func (SelectString) AppendExpr ¶ added in v0.2.0
func (self SelectString) AppendExpr(text []byte, args []any) ([]byte, []any)
Implement the `Expr` interface, making this a sub-expression.
func (SelectString) AppendTo ¶ added in v0.7.0
func (self SelectString) AppendTo(text []byte) []byte
Implement the `AppenderTo` interface, sometimes allowing more efficient text encoding.
func (SelectString) String ¶ added in v0.2.0
func (self SelectString) String() string
Implement the `fmt.Stringer` interface for debug purposes.
type Seq ¶ added in v0.2.0
Represents a sequence of arbitrary sub-expressions or arguments, joined with a customizable delimiter, with a customizable fallback in case of empty list. This is mostly an internal tool for building other sequences, such as `And` and `Or`. The inner value may be nil or a single `Expr`, otherwise it must be a slice.
func (Seq) AppendExpr ¶ added in v0.2.0
Implement the `Expr` interface, making this a sub-expression.
type SliceCommaAppender ¶ added in v0.5.3
type SliceCommaAppender [1]any
Intermediary tool for implementing SQL array encoding. The inner value must be either nil, a slice/array, or a pointer to a slice/array, where each element must implement `AppenderTo`. When `.AppendTo` or `.String` is called, this combines the text representations of the elements, separating them with a comma, while skipping any empty representations. The output will never contain a dangling leading comma, double comma, or leading trailing comma, unless they were explicitly generated by the inner encoders. Compare `CommaAppender` which itself is a slice.
func (SliceCommaAppender) AppendTo ¶ added in v0.7.0
func (self SliceCommaAppender) AppendTo(buf []byte) []byte
Implement `AppenderTo`. Appends comma-separated text representations of the inner encoders to the output buffer, skipping any empty representations.
func (SliceCommaAppender) String ¶ added in v0.5.3
func (self SliceCommaAppender) String() string
Implement `fmt.Stringer` by calling `.AppendTo`.
type Sparse ¶ added in v0.2.1
Represents an arbitrary struct where not all fields are "present". Calling `.Get` returns the underlying struct value. Calling `.AllowField` answers the question "is this field present?".
Secretly supported by struct-scanning expressions such as `StructInsert`, `StructAssign`, `StructValues`, `Cond`, and more. These types attempt to upcast the inner value to `Sparse`, falling back on using the inner value as-is. This allows to correctly implement REST "PATCH" semantics by using only the fields that were present in a particular HTTP request, while keeping this functionality optional.
Concrete implementation: `Partial`.
type Str ¶ added in v0.2.0
type Str string
Shortcut for interpolating strings into queries. Because this implements `Expr`, when used as an argument in another expression, this will be directly interpolated into the resulting query string. See the examples.
Example (StringInterpolation) ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.Reify( s.StrQ{ `select :col from some_table where :col <> :val`, s.Dict{ `col`: s.Str(`some_col`), `val`: `some_val`, }, }, )) }
Output: select some_col from some_table where some_col <> $1 [some_val]
func (Str) AppendExpr ¶ added in v0.2.0
Implement the `Expr` interface, making this a sub-expression.
type StrQ ¶ added in v0.2.0
Short for "string query". Represents an SQL query with parameters such as "$1" or ":param_name". Args may be a list of ordinal args (via `List`), a dictionary (via `Dict`), a struct (via `StructDict`), or an arbitrary user-defined implementation conforming to the interface. When generating the final expression, parameters are converted to Postgres-style ordinal parameters such as "$1".
Expressions/queries are composable. Named arguments that implement the `Expr` interface do not become ordinal parameters/arguments. Instead, they're treated as sub-expressions, and may include arbitrary text with their own arguments. Parameter collisions between outer and inner queries are completely avoided.
Uses `Preparse` to avoid redundant parsing. Each source string is parsed only once, and the resulting `Prep` is cached. As a result, `StrQ` has little measurable overhead.
Example (Empty) ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.Reify(s.StrQ{})) }
Output: []
Example (Nested) ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { inner := s.StrQ{ `select * from some_table where col0 = :val`, s.Dict{`val`: 10}, } outer := s.StrQ{ `select * from (:inner) as _ where col1 = :val`, s.Dict{`inner`: inner, `val`: 20}, } fmt.Println(s.Reify(outer)) }
Output: select * from (select * from some_table where col0 = $1) as _ where col1 = $2 [10 20]
Example (Simple) ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.Reify( s.StrQ{ `select * from some_table where col_one = :one and col_two = :two`, s.Dict{ `one`: 10, `two`: 20, }, }, )) }
Output: select * from some_table where col_one = $1 and col_two = $2 [10 20]
Example (StructInput) ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { type Output struct { Col0 string `db:"col0"` Col1 string `db:"col1"` } type Filter struct { Col2 int64 `db:"col2"` Col3 int64 `db:"col3"` } type Input struct { Cols s.Cols Filter s.And } fmt.Println(s.Reify( s.StructQ(` select :Cols from some_table where :Filter `, Input{ s.Cols{(*Output)(nil)}, s.And{Filter{10, 20}}, }), )) }
Output: select "col0", "col1" from some_table where "col2" = $1 and "col3" = $2 [10 20]
Example (Structs) ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { type Output struct { Col0 string `db:"col0"` Col1 string `db:"col1"` } type Filter struct { Col2 int64 `db:"col2"` Col3 int64 `db:"col3"` } fmt.Println(s.Reify( s.StrQ{ `select :cols from some_table where :filter`, s.Dict{ `cols`: s.Cols{(*Output)(nil)}, `filter`: s.And{Filter{10, 20}}, }, }, )) }
Output: select "col0", "col1" from some_table where "col2" = $1 and "col3" = $2 [10 20]
func DictQ ¶ added in v0.2.0
Shortcut for `StrQ{text, Dict(args)}`.
Example ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.Reify( s.DictQ(` select * from some_table where col_one = :one and col_two = :two `, map[string]any{ `one`: 10, `two`: 20, }), )) }
Output: select * from some_table where col_one = $1 and col_two = $2 [10 20]
func ListQ ¶ added in v0.2.0
Shortcut for `StrQ{text, List(args)}`.
Example ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.Reify( s.ListQ(` select * from some_table where col_one = $1 and col_two = $2 `, 10, 20), )) }
Output: select * from some_table where col_one = $1 and col_two = $2 [10 20]
func (StrQ) AppendExpr ¶ added in v0.2.0
Implement the `Expr` interface, making this a sub-expression.
type StructAssign ¶ added in v0.2.0
type StructAssign [1]any
Represents an SQL assignment clause suitable for "update set" operations. The inner value must be a struct. The resulting expression consists of comma-separated assignments with column names and values derived from the provided struct. See the example.
Supports filtering. If the inner value implements `Sparse`, then not all fields are considered to be "present", which is useful for PATCH semantics. See the docs on `Sparse` and `Part`. If there are NO fields, panics with `ErrEmptyAssign`, which can be detected by user code via `errors.Is`.
Example ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.Reify(s.StructAssign{struct { Col0 bool `db:"col0"` Col1 any `db:"col1"` Col2 any `db:"col2"` }{ true, nil, s.Call{`some_func`, []int{10}}, }})) }
Output: "col0" = $1, "col1" = $2, "col2" = (some_func ($3)) [true <nil> 10]
func (StructAssign) AppendExpr ¶ added in v0.2.0
func (self StructAssign) AppendExpr(text []byte, args []any) ([]byte, []any)
Implement the `Expr` interface, making this a sub-expression.
func (StructAssign) AppendTo ¶ added in v0.7.0
func (self StructAssign) AppendTo(text []byte) []byte
Implement the `AppenderTo` interface, sometimes allowing more efficient text encoding.
func (StructAssign) String ¶ added in v0.2.0
func (self StructAssign) String() string
Implement the `fmt.Stringer` interface for debug purposes.
type StructDict ¶ added in v0.2.0
Implements `ArgDict` by reading struct fields and methods by name. Supports only named parameters, not ordinal parameters. The inner value must be either invalid or a struct. Compared to `Dict`, a struct is way faster to construct, but reading fields by name is way slower. Used for `StrQ`. See the `StructQ` shortcut.
func (StructDict) GotNamed ¶ added in v0.2.0
func (self StructDict) GotNamed(key string) (any, bool)
Implement part of the `ArgDict` interface.
func (StructDict) GotOrdinal ¶ added in v0.2.0
func (self StructDict) GotOrdinal(int) (any, bool)
Implement part of the `ArgDict` interface. Always returns `nil, false`.
func (StructDict) IsEmpty ¶ added in v0.2.0
func (self StructDict) IsEmpty() bool
Implement part of the `ArgDict` interface.
func (StructDict) Len ¶ added in v0.2.0
func (self StructDict) Len() int
Implement part of the `ArgDict` interface. Always returns 0.
type StructInsert ¶ added in v0.2.0
type StructInsert [1]any
Represents a names-and-values clause suitable for insertion. The inner value must be nil or a struct. Nil or empty struct generates a "default values" clause. Otherwise the resulting expression has SQL column names and values generated by scanning the input struct. See the examples.
Supports filtering. If the inner value implements `Sparse`, then not all fields are considered to be "present", which is useful for PATCH semantics. See the docs on `Sparse` and `Part`.
Example (Empty) ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.StructInsert{}) }
Output: default values
Example (NonEmpty) ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.Reify(s.StructInsert{struct { Col0 bool `db:"col0"` Col1 any `db:"col1"` Col2 any `db:"col2"` }{ true, nil, s.Call{`some_func`, []int{10}}, }})) }
Output: ("col0", "col1", "col2") values ($1, $2, (some_func ($3))) [true <nil> 10]
func (StructInsert) AppendExpr ¶ added in v0.2.0
func (self StructInsert) AppendExpr(text []byte, args []any) ([]byte, []any)
Implement the `Expr` interface, making this a sub-expression.
func (StructInsert) AppendTo ¶ added in v0.7.0
func (self StructInsert) AppendTo(text []byte) []byte
Implement the `AppenderTo` interface, sometimes allowing more efficient text encoding.
func (StructInsert) String ¶ added in v0.2.0
func (self StructInsert) String() string
Implement the `fmt.Stringer` interface for debug purposes.
type StructValues ¶ added in v0.2.0
type StructValues [1]any
Represents comma-separated values from the "db"-tagged fields of an arbitrary struct. Field/column names are ignored. Values may be arbitrary sub-expressions or arguments. The value passed to `StructValues` may be nil, which is equivalent to an empty struct. It may also be an arbitrarily-nested struct pointer, which is automatically dereferenced.
Supports filtering. If the inner value implements `Sparse`, then not all fields are considered to be "present", which is useful for PATCH semantics. See the docs on `Sparse` and `Part`.
Example ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.Reify(s.StructValues{struct { Col0 bool `db:"col0"` Col1 any `db:"col1"` Col2 any `db:"col2"` }{ true, nil, s.Call{`some_func`, []int{10}}, }})) }
Output: $1, $2, (some_func ($3)) [true <nil> 10]
func (StructValues) AppendExpr ¶ added in v0.2.0
func (self StructValues) AppendExpr(text []byte, args []any) ([]byte, []any)
Implement the `Expr` interface, making this a sub-expression.
func (StructValues) AppendTo ¶ added in v0.7.0
func (self StructValues) AppendTo(text []byte) []byte
Implement the `AppenderTo` interface, sometimes allowing more efficient text encoding.
func (StructValues) String ¶ added in v0.2.0
func (self StructValues) String() string
Implement the `fmt.Stringer` interface for debug purposes.
type StructsInsert ¶ added in v0.6.1
type StructsInsert[A any] []A
Variant of `StructInsert` that supports multiple structs. Generates a names-and-values clause suitable for bulk insertion. The inner type must be a struct. An empty slice generates an empty expression. See the examples.
Example (Empty) ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { fmt.Println(s.StructsInsertOf[any]()) }
Output:
Example (NonEmpty) ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { type Row struct { Col0 bool `db:"col0"` Col1 int64 `db:"col1"` Col2 string `db:"col2"` } fmt.Println(s.Reify(s.StructsInsertOf( Row{true, 10, `one`}, Row{false, 20, `two`}, ))) }
Output: ("col0", "col1", "col2") values ($1, $2, $3), ($4, $5, $6) [true 10 one false 20 two]
func StructsInsertOf ¶ added in v0.6.1
func StructsInsertOf[A any](val ...A) StructsInsert[A]
Shortcut for creating `StructsInsert` from the given values. Workaround for lack of type inference in type literals.
func (StructsInsert[A]) AppendExpr ¶ added in v0.6.1
func (self StructsInsert[A]) AppendExpr(text []byte, args []any) ([]byte, []any)
Implement the `Expr` interface, making this a sub-expression.
func (StructsInsert[_]) AppendTo ¶ added in v0.7.0
func (self StructsInsert[_]) AppendTo(text []byte) []byte
Implement the `AppenderTo` interface, sometimes allowing more efficient text encoding.
func (StructsInsert[_]) String ¶ added in v0.6.1
func (self StructsInsert[_]) String() string
Implement the `fmt.Stringer` interface for debug purposes.
type Table ¶ added in v0.2.0
type Table Identifier
Same as `Identifier`, but preceded by the word "table". The SQL clause "table some_name" is equivalent to "select * from some_name".
func (Table) AppendExpr ¶ added in v0.2.0
Implement the `Expr` interface, making this a sub-expression.
type TagFilter ¶ added in v0.5.0
type TagFilter string
Implements `Filter` by requiring that the struct field has this specific tag. The tag's value for any given field is ignored, only its existence is checked.
func (TagFilter) AllowField ¶ added in v0.5.0
func (self TagFilter) AllowField(field r.StructField) bool
type Token ¶ added in v0.2.0
Represents an arbitrary chunk of SQL text parsed by `Tokenizer`.
func (Token) IsInvalid ¶ added in v0.2.0
True if the token's type is `TokenTypeInvalid`. This is used to detect end of iteration when calling `(*Tokenizer).Next`.
func (Token) ParseNamedParam ¶ added in v0.2.0
func (self Token) ParseNamedParam() NamedParam
Assumes that the token has `TokenTypeNamedParam` and looks like a Postgres-style named param: ":one", ":two" and so on. Parses and returns the parameter's name without the leading ":". Panics if the text had the wrong structure.
func (Token) ParseOrdinalParam ¶ added in v0.2.0
func (self Token) ParseOrdinalParam() OrdinalParam
Assumes that the token has `TokenTypeOrdinalParam` and looks like a Postgres-style ordinal param: "$1", "$2" and so on. Parses and returns the number. Panics if the text had the wrong structure.
type Tokenizer ¶ added in v0.2.0
type Tokenizer struct { Source string Transform func(Token) Token // contains filtered or unexported fields }
Partial SQL tokenizer used internally by `(*Prep).Parse` to parse queries, in particular to convert named parameters into other expressions.
Goals:
Correctly parse whitespace, comments, quoted strings and identifiers, ordinal parameters, named parameters.
Decently fast and allocation-free tokenization.
Non-goals:
- Full SQL parser.
Notable limitations:
- No special support for dollar-quoted strings, which are rarely if ever used in dynamically-generated queries.
type Update ¶ added in v0.2.0
type Update UpdateVoid
Shortcut for simple `update A set B where C returning *` expressions. See the examples. Also see `UpdateVoid` which doesn't have `returning *`.
Example ¶
package main import ( "fmt" s "github.com/mitranim/sqlb" ) func main() { type Filter struct { Col0 int64 `db:"col0"` Col1 int64 `db:"col1"` } type Fields struct { Col2 int64 `db:"col2"` Col3 int64 `db:"col3"` } fmt.Println(s.Reify( s.Update{`some_table`, Filter{10, 20}, Fields{30, 40}}, )) }
Output: update "some_table" set "col2" = $1, "col3" = $2 where "col0" = $3 and "col1" = $4 returning * [30 40 10 20]
func (Update) AppendExpr ¶ added in v0.2.0
Implement the `Expr` interface, making this a sub-expression.
type UpdateVoid ¶ added in v0.7.1
Shortcut for simple `update A set B where C` expressions. Also see `Update` which appends `returning *`.
func (UpdateVoid) AppendExpr ¶ added in v0.7.1
func (self UpdateVoid) AppendExpr(text []byte, args []any) ([]byte, []any)
Implement the `Expr` interface, making this a sub-expression.
func (UpdateVoid) AppendTo ¶ added in v0.7.1
func (self UpdateVoid) AppendTo(text []byte) []byte
Implement the `AppenderTo` interface, sometimes allowing more efficient text encoding.
func (UpdateVoid) String ¶ added in v0.7.1
func (self UpdateVoid) String() string
Implement the `fmt.Stringer` interface for debug purposes.
type Upsert ¶ added in v0.6.5
type Upsert UpsertVoid
Same as `UpsertVoid` but also appends `returning *`.
func (Upsert) AppendExpr ¶ added in v0.6.5
Implement the `Expr` interface, making this a sub-expression.
type UpsertConflict ¶ added in v0.7.3
type UpsertConflict UpsertConflictVoid
Same as `UpsertConflictVoid` but also appends `returning *`.
func (UpsertConflict) AppendExpr ¶ added in v0.7.3
func (self UpsertConflict) AppendExpr(text []byte, args []any) ([]byte, []any)
Implement the `Expr` interface, making this a sub-expression.
func (UpsertConflict) AppendTo ¶ added in v0.7.3
func (self UpsertConflict) AppendTo(text []byte) []byte
Implement the `AppenderTo` interface, sometimes allowing more efficient text encoding.
func (UpsertConflict) String ¶ added in v0.7.3
func (self UpsertConflict) String() string
Implement the `fmt.Stringer` interface for debug purposes.
type UpsertConflictVoid ¶ added in v0.7.3
Represents an SQL upsert query. Similar to `UpsertVoid` (see its comment / doc), but instead of generating the conflict clause from the provided "key" fields, requires the caller to provide a hardcoded conflict target string (the `.Conf` field). Useful for conflicts that involve partial indexes. Also see `UpsertConflict` which appends the `returning *` clause.
func (UpsertConflictVoid) AppendExpr ¶ added in v0.7.3
func (self UpsertConflictVoid) AppendExpr(text []byte, args []any) ([]byte, []any)
Implement the `Expr` interface, making this a sub-expression.
func (UpsertConflictVoid) AppendTo ¶ added in v0.7.3
func (self UpsertConflictVoid) AppendTo(text []byte) []byte
Implement the `AppenderTo` interface, sometimes allowing more efficient text encoding.
func (UpsertConflictVoid) String ¶ added in v0.7.3
func (self UpsertConflictVoid) String() string
Implement the `fmt.Stringer` interface for debug purposes.
type UpsertVoid ¶ added in v0.7.1
Represents an SQL upsert query like this:
insert into some_table (key_0, key_1, col_2, col_3) values ($1, $2, $3, $4) on conflict (key_0, key_1) do update set key_0 = excluded.key_0, key_1 = excluded.key_1, col_2 = excluded.col_2, col_3 = excluded.col_3
Notes:
- `.Keys` must be a struct.
- `.Keys` supports `Sparse` and may be empty.
- When `.Keys` is empty, this is equivalent to the `Insert` type.
- `.Cols` must be a struct.
- `.Cols` supports `Sparse` and may be empty.
- `.Keys` provides names and values for key columns which participate in the `on conflict` clause.
- `.Cols` provides names and values for other columns.
Also see `Upsert` which appends the `returning *` clause.
func (UpsertVoid) AppendExpr ¶ added in v0.7.1
func (self UpsertVoid) AppendExpr(text []byte, args []any) ([]byte, []any)
Implement the `Expr` interface, making this a sub-expression.
func (UpsertVoid) AppendTo ¶ added in v0.7.1
func (self UpsertVoid) AppendTo(text []byte) []byte
Implement the `AppenderTo` interface, sometimes allowing more efficient text encoding.
func (UpsertVoid) String ¶ added in v0.7.1
func (self UpsertVoid) String() string
Implement the `fmt.Stringer` interface for debug purposes.
type Wrap ¶ added in v0.2.0
Combines an expression with a string prefix and suffix. If the expr is nil, this is a nop, and the prefix and suffix are ignored. Mostly an internal tool for building other expression types.
func (Wrap) AppendExpr ¶ added in v0.2.0
Difference from `Trio`: if the expr is nil, nothing is appended. Implement the `Expr` interface, making this a sub-expression.