Documentation
¶
Overview ¶
Package memeduck provides tools to build Spanner SQL queries.
Supported Types ¶
The following types can be used as a SQL expression:
- If a value implements `ToASTExpr() (*ast.Expr, error)`, memeduck uses this method to convert Go values into SQL expressions.
- If a value is nil (of any type), it is converted into NULL.
- If a value is one of string, *string, or spanner.NullString, it is converted into STRING literal.
- If a value is []byte, it is converted into BYTES literal.
- If a value is one of int, *int, int64, or *int64, spanner.NullInt64, it is converted into INT64 literal.
- If a value is one of bool, *bool, or spanner.NullBool, it is converted into BOOL literal.
- If a value is one of float64, *float64, or spanner.NullFloat64, it is converted into FLOAT64 literal.
- If a value is one of time.Time, *time.Time, or spanner.NullTime, it is converted into TIMESTAMP literal.
- If a value is one of civil.Date, *civil.Date, or spanner.NullDate, it is converted into DATE literal.
- If a value is a slice of the above types, it is converted into ARRAY<T> literal.
Struct Tags ¶
You can add `spanner:"Name"` tag to struct fields to indicate which field in struct corresponds to which column, otherwise memeduck uses field name as column name. See examples section of Insert function for more details.
Index ¶
- type ArraySubQueryStmt
- type BetweenCond
- type BinaryOp
- type DeleteStmt
- type Direction
- type ExprCond
- type IdentExpr
- type InCond
- type InConditionValue
- type InsertStmt
- type LogicalOpCond
- type NullCond
- type OpCond
- func Eq(lhs, rhs interface{}) *OpCond
- func Ge(lhs, rhs interface{}) *OpCond
- func Gt(lhs, rhs interface{}) *OpCond
- func Le(lhs, rhs interface{}) *OpCond
- func Like(lhs, rhs interface{}) *OpCond
- func Lt(lhs, rhs interface{}) *OpCond
- func Ne(lhs, rhs interface{}) *OpCond
- func NotLike(lhs, rhs interface{}) *OpCond
- func Op(lhs interface{}, op BinaryOp, rhs interface{}) *OpCond
- type ParamExpr
- type ScalarSubQueryStmt
- type SelectStmt
- func (s *SelectStmt) AsStruct() *SelectStmt
- func (s *SelectStmt) ForceIndex(idx string) *SelectStmt
- func (s *SelectStmt) Limit(limit int) *SelectStmt
- func (s *SelectStmt) LimitOffset(limit, offset int) *SelectStmt
- func (s *SelectStmt) OrderBy(col string, dir Direction) *SelectStmt
- func (s *SelectStmt) SQL() (string, error)
- func (s *SelectStmt) SubQuery(queries ...SubQuery) *SelectStmt
- func (s *SelectStmt) Where(conds ...WhereCond) *SelectStmt
- type SubQuery
- type UnnestInConditionValue
- type UpdateStmt
- type WhereCond
Examples ¶
- Delete
- Delete (MultipleWhere)
- Delete (QueryParameter)
- Insert
- Insert (QueryParameter)
- Insert (Struct)
- Select
- Select (ForceIndex)
- Select (Limit)
- Select (LimitOffset)
- Select (MultipleWhere)
- Select (OrderBy)
- Select (QueryArraySubquery)
- Select (QueryMultiSubQuery)
- Select (QueryParameter)
- Select (QueryScalarSubquery)
- Update
- Update (MultipleWhere)
- Update (QueryParameter)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type ArraySubQueryStmt ¶ added in v0.2.0
type ArraySubQueryStmt struct {
// contains filtered or unexported fields
}
func ArraySubQuery ¶ added in v0.2.0
func ArraySubQuery(stmt *SelectStmt) *ArraySubQueryStmt
func (*ArraySubQueryStmt) As ¶ added in v0.2.0
func (s *ArraySubQueryStmt) As(as string) *ArraySubQueryStmt
func (*ArraySubQueryStmt) ToAST ¶ added in v0.2.0
func (s *ArraySubQueryStmt) ToAST() (ast.SelectItem, error)
type BetweenCond ¶
type BetweenCond struct {
// contains filtered or unexported fields
}
BetweenCond represents BETWEEN or NOT BETWEEN predicates.
func Between ¶
func Between(x, min, max interface{}) *BetweenCond
Between(x, min, max) creates `x BETWEEN min AND max` predicate.
func NotBetween ¶
func NotBetween(x, min, max interface{}) *BetweenCond
NotBetween(x, min, max) creates `x NOT BETWEEN min AND max` predicate.
func (*BetweenCond) ToASTWhere ¶
func (c *BetweenCond) ToASTWhere() (*ast.Where, error)
type BinaryOp ¶
Op is a binary operator
const ( EQ BinaryOp = BinaryOp(ast.OpEqual) NE BinaryOp = BinaryOp(ast.OpNotEqual) LT BinaryOp = BinaryOp(ast.OpLess) GT BinaryOp = BinaryOp(ast.OpGreater) LE BinaryOp = BinaryOp(ast.OpLessEqual) GE BinaryOp = BinaryOp(ast.OpGreaterEqual) LIKE BinaryOp = BinaryOp(ast.OpLike) NOT_LIKE BinaryOp = BinaryOp(ast.OpNotLike) )
type DeleteStmt ¶
type DeleteStmt struct {
// contains filtered or unexported fields
}
DeleteStmt builds DELETE statements.
func Delete ¶
func Delete(table string) *DeleteStmt
Delete creates a new DeleteStmt with given table name.
Example ¶
package main
import (
"fmt"
"github.com/genkami/memeduck"
)
func main() {
query, _ := memeduck.Delete("user").Where(
memeduck.Eq(memeduck.Ident("id"), 123),
memeduck.Eq(memeduck.Ident("unused"), true),
).SQL()
fmt.Println(query)
}
Output: DELETE FROM user WHERE id = 123 AND unused = TRUE
Example (MultipleWhere) ¶
package main
import (
"fmt"
"github.com/genkami/memeduck"
)
func main() {
query, _ := memeduck.Delete("user").
Where(memeduck.Eq(memeduck.Ident("id"), 123)).
Where(memeduck.Eq(memeduck.Ident("unused"), true)).
SQL()
fmt.Println(query)
}
Output: DELETE FROM user WHERE id = 123 AND unused = TRUE
Example (QueryParameter) ¶
package main
import (
"fmt"
"github.com/genkami/memeduck"
)
func main() {
query, _ := memeduck.Delete("user").
Where(memeduck.Eq(memeduck.Ident("id"), memeduck.Param("id"))).
SQL()
fmt.Println(query)
}
Output: DELETE FROM user WHERE id = @id
func (*DeleteStmt) SQL ¶
func (s *DeleteStmt) SQL() (string, error)
func (*DeleteStmt) Where ¶
func (s *DeleteStmt) Where(conds ...WhereCond) *DeleteStmt
Where appends given conditional expressions to the DELETE statement.
type Direction ¶
Direction is an ordering direction used by ORDER BY clause.
const ( ASC Direction = Direction(ast.DirectionAsc) DESC Direction = Direction(ast.DirectionDesc) )
type ExprCond ¶
type ExprCond struct {
// contains filtered or unexported fields
}
ExprCond is a boolean expression to filter records.
type IdentExpr ¶
type IdentExpr struct {
// contains filtered or unexported fields
}
IdentExpr is an identifier.
type InCond ¶ added in v0.3.0
type InCond struct {
// contains filtered or unexported fields
}
InCond represents IN or NOT IN predicates.
func In ¶ added in v0.3.0
func In(x interface{}, y InConditionValue) *InCond
In(x, y) creates `x IN y` predicate.
func NotIn ¶ added in v0.3.0
func NotIn(x interface{}, y InConditionValue) *InCond
In(x, y) creates `x NOT IN y` predicate.
type InConditionValue ¶ added in v0.3.0
type InConditionValue interface {
ToASTInConditionValue() (ast.InCondition, error)
}
InConditionValue is a value expression in IN clauses.
type InsertStmt ¶
type InsertStmt struct {
// contains filtered or unexported fields
}
InsertStmt builds INSERT statements.
func Insert ¶
func Insert(table string, cols []string) *InsertStmt
Insert creates a new InsertStmt with given table name. and column names.
Example ¶
package main
import (
"fmt"
"github.com/genkami/memeduck"
)
func main() {
query, _ := memeduck.Insert("user", []string{"name", "oshi_mark"}).Values([][]string{
{"Subaru", ":ambulance:"},
{"Watame", ":sheep:"},
}).SQL()
fmt.Println(query)
}
Output: INSERT INTO user (name, oshi_mark) VALUES ("Subaru", ":ambulance:"), ("Watame", ":sheep:")
Example (QueryParameter) ¶
package main
import (
"fmt"
"github.com/genkami/memeduck"
)
func main() {
query, _ := memeduck.Insert("user", []string{"name", "weight", "is_onion"}).Values([][]interface{}{
{memeduck.Param("name"), memeduck.Param("weight"), memeduck.Param("is_onion")},
}).SQL()
fmt.Println(query)
}
Output: INSERT INTO user (name, weight, is_onion) VALUES (@name, @weight, @is_onion)
Example (Struct) ¶
package main
import (
"fmt"
"github.com/genkami/memeduck"
)
type ExampleUserStruct struct {
Name string `spanner:"UserName"`
Papa string `spanner:"PapaName"`
}
func main() {
query, _ := memeduck.Insert("users", []string{"UserName", "PapaName"}).Values([]ExampleUserStruct{
{Name: "Kiara", Papa: "huke"},
}).SQL()
fmt.Println(query)
}
Output: INSERT INTO users (UserName, PapaName) VALUES ("Kiara", "huke")
func (*InsertStmt) SQL ¶
func (is *InsertStmt) SQL() (string, error)
func (*InsertStmt) Values ¶
func (s *InsertStmt) Values(values interface{}) *InsertStmt
Values returns an InsertStmt with its values set to given ones. It replaces existing values.
type LogicalOpCond ¶
type LogicalOpCond struct {
// contains filtered or unexported fields
}
LogicalOpCond represents AND/OR operator.
func And ¶
func And(conds ...WhereCond) *LogicalOpCond
And concatenates more than one WhereConds with AND operator.
func Or ¶
func Or(conds ...WhereCond) *LogicalOpCond
Or concatenates more than one WhereConds with OR operator.
func (*LogicalOpCond) ToASTWhere ¶
func (c *LogicalOpCond) ToASTWhere() (*ast.Where, error)
type NullCond ¶
type NullCond struct {
// contains filtered or unexported fields
}
NullCond represents IS NULL or IS NOT NULL predicate.
type OpCond ¶
type OpCond struct {
// contains filtered or unexported fields
}
OpCond is a binary operator expression.
func NotLike ¶
func NotLike(lhs, rhs interface{}) *OpCond
NotLike(x, y) is a shorthand for Op(x, NOT_LIKE, y)
type ParamExpr ¶
type ParamExpr struct {
// contains filtered or unexported fields
}
ParamExpr is a query parameter.
type ScalarSubQueryStmt ¶ added in v0.2.0
type ScalarSubQueryStmt struct {
// contains filtered or unexported fields
}
func ScalarSubQuery ¶ added in v0.2.0
func ScalarSubQuery(stmt *SelectStmt) *ScalarSubQueryStmt
func (*ScalarSubQueryStmt) As ¶ added in v0.2.0
func (s *ScalarSubQueryStmt) As(as string) *ScalarSubQueryStmt
func (*ScalarSubQueryStmt) ToAST ¶ added in v0.2.0
func (s *ScalarSubQueryStmt) ToAST() (ast.SelectItem, error)
type SelectStmt ¶
type SelectStmt struct {
// contains filtered or unexported fields
}
SelectStmt builds SELECT statements.
func Select ¶
func Select(table string, cols []string) *SelectStmt
Select creates a new SelectStmt with given table name and column names.
Example ¶
package main
import (
"fmt"
"github.com/genkami/memeduck"
)
func main() {
query, _ := memeduck.Select("user", []string{"name", "created_at"}).Where(
memeduck.Eq(memeduck.Ident("race"), "Phoenix"),
memeduck.Eq(memeduck.Ident("work_at"), "KFP"),
).SQL()
fmt.Println(query)
}
Output: SELECT name, created_at FROM user WHERE race = "Phoenix" AND work_at = "KFP"
Example (ForceIndex) ¶
package main
import (
"fmt"
"github.com/genkami/memeduck"
)
func main() {
query, _ := memeduck.Select("user", []string{"name", "age"}).Where(
memeduck.Lt(memeduck.Ident("age"), 18),
).ForceIndex("idx_age").SQL()
fmt.Println(query)
}
Output: SELECT name, age FROM user @{FORCE_INDEX=idx_age} WHERE age < 18
Example (Limit) ¶
package main
import (
"fmt"
"github.com/genkami/memeduck"
)
func main() {
query, _ := memeduck.Select("user", []string{"name", "created_at"}).
Where(memeduck.Eq(memeduck.Ident("likes"), "alcohol")).
Limit(10).
SQL()
fmt.Println(query)
}
Output: SELECT name, created_at FROM user WHERE likes = "alcohol" LIMIT 10
Example (LimitOffset) ¶
package main
import (
"fmt"
"github.com/genkami/memeduck"
)
func main() {
query, _ := memeduck.Select("user", []string{"name", "created_at"}).
Where(memeduck.Eq(memeduck.Ident("good_at"), "cooking")).
LimitOffset(10, 3).
SQL()
fmt.Println(query)
}
Output: SELECT name, created_at FROM user WHERE good_at = "cooking" LIMIT 10 OFFSET 3
Example (MultipleWhere) ¶
package main
import (
"fmt"
"github.com/genkami/memeduck"
)
func main() {
query, _ := memeduck.Select("user", []string{"name", "created_at"}).
Where(memeduck.Eq(memeduck.Ident("job"), "detective")).
Where(memeduck.Eq(memeduck.Ident("defective"), true)).
SQL()
fmt.Println(query)
}
Output: SELECT name, created_at FROM user WHERE job = "detective" AND defective = TRUE
Example (OrderBy) ¶
package main
import (
"fmt"
"github.com/genkami/memeduck"
)
func main() {
query, _ := memeduck.Select("user", []string{"name", "created_at"}).
Where(memeduck.IsNotNull(memeduck.Ident("age"))).
OrderBy("subscribers", memeduck.ASC).
SQL()
fmt.Println(query)
}
Output: SELECT name, created_at FROM user WHERE age IS NOT NULL ORDER BY subscribers ASC
Example (QueryArraySubquery) ¶
package main
import (
"fmt"
"github.com/genkami/memeduck"
)
func main() {
subQueryStmt := memeduck.Select("user_item", []string{"item_id", "count"}).
Where(memeduck.Eq(memeduck.Ident("user_id"), memeduck.Param("id"))).
AsStruct()
query, _ := memeduck.Select("user", []string{"name", "created_at"}).
SubQuery(memeduck.ArraySubQuery(subQueryStmt).As("user_item")).
Where(memeduck.Eq(memeduck.Ident("id"), memeduck.Param("id"))).
SQL()
fmt.Println(query)
}
Output: SELECT name, created_at, ARRAY(SELECT AS STRUCT item_id, count FROM user_item WHERE user_id = @id) AS user_item FROM user WHERE id = @id
Example (QueryMultiSubQuery) ¶
package main
import (
"fmt"
"github.com/genkami/memeduck"
)
func main() {
itemStmt := memeduck.Select("user_item", []string{"item_id", "count"}).
Where(memeduck.Eq(memeduck.Ident("user_id"), "user-id")).
AsStruct()
// user has one status
statusStmt := memeduck.Select("user_status", []string{"state"}).
Where(memeduck.Eq(memeduck.Ident("user_id"), "user-id")).
AsStruct()
query, _ := memeduck.Select("user", []string{"name"}).
SubQuery(
memeduck.ArraySubQuery(itemStmt).As("user_item"),
memeduck.ArraySubQuery(statusStmt).As("user_status"),
).
Where(memeduck.Eq(memeduck.Ident("user_id"), "user-id")).
SQL()
fmt.Println(query)
}
Output: SELECT name, ARRAY(SELECT AS STRUCT item_id, count FROM user_item WHERE user_id = "user-id") AS user_item, ARRAY(SELECT AS STRUCT state FROM user_status WHERE user_id = "user-id") AS user_status FROM user WHERE user_id = "user-id"
Example (QueryParameter) ¶
package main
import (
"fmt"
"github.com/genkami/memeduck"
)
func main() {
query, _ := memeduck.Select("user", []string{"name", "created_at"}).
Where(memeduck.Gt(memeduck.Ident("age"), memeduck.Param("age"))).
SQL()
fmt.Println(query)
}
Output: SELECT name, created_at FROM user WHERE age > @age
Example (QueryScalarSubquery) ¶
package main
import (
"fmt"
"github.com/genkami/memeduck"
)
func main() {
subQueryStmt := memeduck.Select("user_status", []string{"state"}).
Where(memeduck.Eq(memeduck.Ident("user_id"), memeduck.Param("id")))
query, _ := memeduck.Select("user", []string{"name", "created_at"}).
SubQuery(memeduck.ScalarSubQuery(subQueryStmt).As("state")).
Where(memeduck.Eq(memeduck.Ident("id"), memeduck.Param("id"))).
SQL()
fmt.Println(query)
}
Output: SELECT name, created_at, (SELECT state FROM user_status WHERE user_id = @id) AS state FROM user WHERE id = @id
func (*SelectStmt) AsStruct ¶ added in v0.2.0
func (s *SelectStmt) AsStruct() *SelectStmt
func (*SelectStmt) ForceIndex ¶ added in v0.3.0
func (s *SelectStmt) ForceIndex(idx string) *SelectStmt
ForceIndex add a OFRCE_INDEX clause.
func (*SelectStmt) Limit ¶
func (s *SelectStmt) Limit(limit int) *SelectStmt
Limit adds a LIMIT clause to the SELECT statement. It replaces existing LIMIT clauses.
func (*SelectStmt) LimitOffset ¶
func (s *SelectStmt) LimitOffset(limit, offset int) *SelectStmt
LimitOffset adds a LIMIT ... OFFSET ... clause to the SELECT statement. It replaces existing LIMIT clauses.
func (*SelectStmt) OrderBy ¶
func (s *SelectStmt) OrderBy(col string, dir Direction) *SelectStmt
OrderBy appends a column to its ORDER BY clause.
func (*SelectStmt) SQL ¶
func (s *SelectStmt) SQL() (string, error)
func (*SelectStmt) SubQuery ¶ added in v0.2.0
func (s *SelectStmt) SubQuery(queries ...SubQuery) *SelectStmt
func (*SelectStmt) Where ¶
func (s *SelectStmt) Where(conds ...WhereCond) *SelectStmt
Where appends given codintional expressions to the SELECT statement.
type SubQuery ¶ added in v0.2.0
type SubQuery interface {
ToAST() (ast.SelectItem, error)
}
type UnnestInConditionValue ¶ added in v0.3.0
type UnnestInConditionValue struct {
// contains filtered or unexported fields
}
UnnestInConditionValue is a UNNEST operator in IN clauses.
func Unnest ¶ added in v0.3.0
func Unnest(v interface{}) *UnnestInConditionValue
Unnest(v) creates `UNNEST(v)` predicate.
func (*UnnestInConditionValue) ToASTInConditionValue ¶ added in v0.3.0
func (v *UnnestInConditionValue) ToASTInConditionValue() (ast.InCondition, error)
type UpdateStmt ¶
type UpdateStmt struct {
// contains filtered or unexported fields
}
UpdateStmt builds UPDATE statements.
func Update ¶
func Update(table string) *UpdateStmt
Update creates a new UpdateStmt with given table name.
Example ¶
package main
import (
"fmt"
"github.com/genkami/memeduck"
)
func main() {
query, _ := memeduck.Update("user").
Set(memeduck.Ident("position"), "BOTTOM LEFT").
Set(memeduck.Ident("immortal"), true).
Where(
memeduck.Eq(memeduck.Ident("color"), "orange"),
memeduck.Eq(memeduck.Ident("manager"), true),
).
SQL()
fmt.Println(query)
}
Output: UPDATE user SET position = "BOTTOM LEFT", immortal = TRUE WHERE color = "orange" AND manager = TRUE
Example (MultipleWhere) ¶
package main
import (
"fmt"
"github.com/genkami/memeduck"
)
func main() {
query, _ := memeduck.Update("user").
Set(memeduck.Ident("race"), "gorilla").
Where(memeduck.Eq(memeduck.Ident("race"), "angel")).
Where(memeduck.Ge(memeduck.Ident("grip_strength_kg"), 50)).
SQL()
fmt.Println(query)
}
Output: UPDATE user SET race = "gorilla" WHERE race = "angel" AND grip_strength_kg >= 50
Example (QueryParameter) ¶
package main
import (
"fmt"
"github.com/genkami/memeduck"
)
func main() {
query, _ := memeduck.Update("user").
Set(memeduck.Ident("age"), memeduck.Param("age")).
Where(memeduck.Eq(memeduck.Ident("shark"), true)).
SQL()
fmt.Println(query)
}
Output: UPDATE user SET age = @age WHERE shark = TRUE
func (*UpdateStmt) SQL ¶
func (s *UpdateStmt) SQL() (string, error)
func (*UpdateStmt) Set ¶
func (s *UpdateStmt) Set(id *IdentExpr, value interface{}) *UpdateStmt
Set adds a assignment clause to the UPDATE statement.
func (*UpdateStmt) Where ¶
func (s *UpdateStmt) Where(conds ...WhereCond) *UpdateStmt
Where adds a WHERE clause to the UPDATE statement.
