sqlbuilder

package module
v0.0.0-...-c13208b Latest Latest
Warning

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

Go to latest
Published: Nov 3, 2020 License: MIT Imports: 6 Imported by: 0

README

umisama/go-sqlbuilder

go-sqlbuilder is a SQL-query builder for golang. This supports you using relational database with more readable and flexible code than raw SQL query string.

Build Status Coverage Status

Support

  • Generate SQL query programmatically.
    • fluent flexibility! yeah!!
  • Basic SQL statements
    • SELECT/INSERT/UPDATE/DELETE/DROP/CREATE TABLE/CREATE INDEX
  • Strict error checking
  • Some database server
  • Subquery in SELECT FROM clause

TODO

  • Support UNION clause
  • Support LOCK clause

Quick usage

import (
	sb "github.com/umisama/go-sqlbuilder"
	"github.com/umisama/go-sqlbuilder/dialects"
)

db, err := sql.Open("sqlite3", ":memory:")
if err != nil {
	fmt.Println(err.Error())
	return
}

// Set dialect first
// dialects are in github.com/umisama/go-sqlbuilder/dialects
sb.SetDialect(TestDialect{})

// Define a table
tbl_person := sb.NewTable(
	"PERSON",
	&sb.TableOption{},
	sb.IntColumn("id", &sb.ColumnOption{
		PrimaryKey: true,
	}),
	sb.StringColumn("name", &sb.ColumnOption{
		Unique:  true,
		Size:    255,
		Default: "no_name",
	}),
	sb.DateColumn("birth", nil),
)

// Create Table
query, args, err := sb.CreateTable(tbl_person).ToSql()
if err != nil {
	fmt.Println(err.Error())
	return
}
_, err = db.Exec(query, args...)
if err != nil {
	fmt.Println(err.Error())
	return
}

// Insert data
// (Table).C function returns a column object.
query, args, err = sb.Insert(tbl_person).
	Set(tbl_person.C("name"), "Kurisu Makise").
	Set(tbl_person.C("birth"), time.Date(1992, time.July, 25, 0, 0, 0, 0, time.UTC)).
	ToSql()
_, err = db.Exec(query, args...)
if err != nil {
	fmt.Println(err.Error())
	return
}

// Query
// (Column).Eq returns a condition object for equal(=) operator.  See
var birth time.Time
query, args, err = sb.Select(tbl_person).Columns(
	tbl_person.C("birth"),
).Where(
	tbl_person.C("name").Eq("Kurisu Makise"),
).ToSql()
err = db.QueryRow(query, args...).Scan(&birth)
if err != nil {
	fmt.Println(err.Error())
	return
}

fmt.Printf("Kurisu's birthday is %s,%d %d", birth.Month().String(), birth.Day(), birth.Year())

// Output:
// Kurisu's birthday is July,25 1992

Examples

Initialize

off course, go getable.

$ go get github.com/umisama/go-sqlbuilder

I recomended to set "sb" as sqlbuilder's shorthand.

import sb "github.com/umisama/go-sqlbuilder"

// First, you set dialect for your DB
func init (
	sb.SetDialect(sb.SqliteDialect{})
)
Define a table

Sqlbuilder needs table definition to strict query generating. Any statement checks column type and constraints.

tbl_person := sb.NewTable(
	"PERSON",
	&sb.TableOption{},
	sb.IntColumn("id", &sb.ColumnOption{
		PrimaryKey: true,
	}),
	sb.StringColumn("name", &sb.ColumnOption{
		Unique:  true,
		Size:    255,
		Default: "no_name",
	}),
	sb.DateColumn("birth", nil),
)
Table Options
Unique [][]string

Sets UNIQUE options to table.

example:

&sb.TableOption{
	Unique: [][]string{
		{"hoge", "piyo"},
		{"fuga"},
	}
}
CREATE TABLE PERSON ( "id" integer, ~~~, UNIQUE("hoge", "piyo"), UNIQUE("fuga"))
Column Options
PrimaryKey bool

true for add primary key option.

NotNull bool

true for add UNIQUE option.

Unique bool

true for add UNIQUE option to column.

example:

IntColumn("test", &sb.ColumnOption{
	Unique: true,
})
"test" INTEGER UNIQUE
AutoIncrement bool

true for add AutoIncrement option to column.

Size int

Sets size for string column. example:

StringColumn("test", &sb.ColumnOption{
	Size: 255,
})
"test" VARCHAR(255)
SqlType string

Sets type for column on AnyColumn.

AnyColumn("test", &sb.ColumnOption{
	ColumnType: "BLOB",
})
"test" BLOB
Default interface{}

Sets default value. Default's type need to be same as column.

StringColumn("test", &sb.ColumnOption{
	Size:    255,
	Default: "empty"
})
"test" VARCHAR(255) DEFAILT "empty"
CRATE TABLE statement

Sqlbuilder has a Statement object generating CREATE TABLE statement from table object.
Statement objects have ToSql() method. it returns query(string), placeholder arguments([]interface{}) and error.

query, args, err := sb.CreateTable(tbl_person).ToSql()
if err != nil {
	panic(err)
}
// query == `CREATE TABLE "PERSON" ( "id" INTEGER PRIMARY KEY, "value" INTEGER );`
// args  == []interface{}{}
// err   == nil

You can exec with database/sql package or Table-struct mapper(for example, gorp).
here is example,

db, err := sql.Open("sqlite3", ":memory:")
if err != nil {
	panic(err)
}
_, err = db.Exec(query, args...)
if err != nil {
	panic(err)
}
INSERT statement

Sqlbuilder can generate INSERT statement. You can checkout a column with Table.C([column_name]) method.

query, args, err := sb.Insert(table1).
	Columns(table1.C("id"), table1.C("value")).
	Values(1, 10).
	ToSql()
// query == `INSERT INTO "TABLE_A" ( "id", "value" ) VALUES ( ?, ? );`
// args  == []interface{}{1, 10}
// err   == nil

Or, can use Set() method.

query, args, err := sb.Insert(table1).
	Set(table1.C("id"), 1).
	Set(table1.C("value"), 10).
	ToSql()
// query == `INSERT INTO "TABLE_A" ( "id", "value" ) VALUES ( ?, ? );`
// args  == []interface{}{1, 10}
// err   == nil
SELECT statement

Sqlbuilder can generate SELECT statement with readable interfaces. Condition object is generated from column object.

query, args, err := sb.Select(table1.C("id"), table1.C("value")).
	From(table1).
	Where(
		table1.C("id").Eq(10),
	).
	Limit(1).OrderBy(false, table1.C("id")).
	ToSql()
// query == `SELECT "TABLE_A"."id", "TABLE_A"."value" FROM "TABLE_A" WHERE "TABLE_A"."id"=? ORDER BY "TABLE_A"."id" ASC LIMIT ?;`
// args  == []interface{}{10, 1}
// err   == nil

See godoc.org for more options

Condition

You can define condition with Condition objects. Condition object create from Column's method.

example operation output example
table1.C("id").Eq(10) "TABLE1"."id"=10
table1.C("id").Eq(table2.C("id")) "TABLE1"."id"="TABLE2"."id"

More than one condition can combine with AND & OR operator.

example operation output example
And(table1.C("id").Eq(1), table2.C("id").Eq(2) "TABLE1"."id"=1 AND "TABLE2"."id"=1
Or(table1.C("id").Eq(1), table2.C("id").Eq(2) "TABLE1"."id"=1 OR "TABLE2"."id"=1

Sqlbuilder is supporting most common condition operators.
Here is supporting:

columns method means SQL operator example
Eq(Column or value) EQUAL TO = "TABLE"."id" = 10
NotEq(Column or value) NOT EQUAL TO <> "TABLE"."id" <> 10
Gt(Column or value) GRATER-THAN > "TABLE"."id" > 10
GtEq(Column or value) GRATER-THAN OR EQUAL TO >= "TABLE"."id" >= 10
Lt(Column or value) LESS-THAN < "TABLE"."id" < 10
LtEq(Column or value) LESS-THAN OR EQUAL TO <= "TABLE"."id" <= 10
Like(string) LIKE LIKE "TABLE"."id" LIKE "%hoge%"
In(values array) IN IN "TABLE"."id" IN ( 1, 2, 3 )
NotIn(values array) NOT IN NOT IN "TABLE"."id" NOT IN ( 1, 2, 3 )
Between(loewer, higher int) BETWEEN BETWEEN "TABLE"."id" BETWEEN 10 AND 20)

Document for all: godoc(Column)

More documents

godoc.org

License

under the MIT license

Documentation

Overview

Package sqlbuilder is a SQL-query builder for golang. This supports you using relational database with more readable and flexible code than raw SQL query string.

See https://github.com/umisama/go-sqlbuilder for more infomation.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func SetDialect

func SetDialect(opt Dialect)

SetDialect sets dialect for SQL server. Must set dialect at first.

Types

type AlterTableStatement

type AlterTableStatement struct {
	// contains filtered or unexported fields
}

func AlterTable

func AlterTable(tbl Table) *AlterTableStatement

func (*AlterTableStatement) AddColumn

func (*AlterTableStatement) AddColumnAfter

func (b *AlterTableStatement) AddColumnAfter(col ColumnConfig, after Column) *AlterTableStatement

func (*AlterTableStatement) AddColumnFirst

func (b *AlterTableStatement) AddColumnFirst(col ColumnConfig) *AlterTableStatement

func (*AlterTableStatement) ApplyToTable

func (b *AlterTableStatement) ApplyToTable() error

func (*AlterTableStatement) ChangeColumn

func (b *AlterTableStatement) ChangeColumn(old_column Column, new_column ColumnConfig) *AlterTableStatement

func (*AlterTableStatement) ChangeColumnAfter

func (b *AlterTableStatement) ChangeColumnAfter(old_column Column, new_column ColumnConfig, after Column) *AlterTableStatement

func (*AlterTableStatement) ChangeColumnFirst

func (b *AlterTableStatement) ChangeColumnFirst(old_column Column, new_column ColumnConfig) *AlterTableStatement

func (*AlterTableStatement) DropColumn

func (b *AlterTableStatement) DropColumn(col Column) *AlterTableStatement

func (*AlterTableStatement) RenameTo

func (b *AlterTableStatement) RenameTo(name string) *AlterTableStatement

func (*AlterTableStatement) ToSql

func (b *AlterTableStatement) ToSql() (query string, args []interface{}, err error)

type Column

type Column interface {

	// As creates Column alias.
	As(alias string) Column

	// Eq creates Condition for "column==right".  Type for right is column's one or other Column.
	Eq(right interface{}) Condition

	// NotEq creates Condition for "column<>right".  Type for right is column's one or other Column.
	NotEq(right interface{}) Condition

	// GtEq creates Condition for "column>right".  Type for right is column's one or other Column.
	Gt(right interface{}) Condition

	// GtEq creates Condition for "column>=right".  Type for right is column's one or other Column.
	GtEq(right interface{}) Condition

	// Lt creates Condition for "column<right".  Type for right is column's one or other Column.
	Lt(right interface{}) Condition

	// LtEq creates Condition for "column<=right".  Type for right is column's one or other Column.
	LtEq(right interface{}) Condition

	// Like creates Condition for "column LIKE right".  Type for right is column's one or other Column.
	Like(right string) Condition

	// Between creates Condition for "column BETWEEN lower AND higher".  Type for lower/higher is int or time.Time.
	Between(lower, higher interface{}) Condition

	// In creates Condition for "column IN (values[0], values[1] ...)".  Type for values is column's one or other Column.
	In(values ...interface{}) Condition

	// IntersectJSON creates Condition for "column @> value".  The value is a JSON string.
	IntersectJSON(data string) Condition

	// NotIn creates Condition for "column NOT IN (values[0], values[1] ...)".  Type for values is column's one or other Column.
	NotIn(values ...interface{}) Condition
	// contains filtered or unexported methods
}

Column represents a table column.

var Star Column = &columnImpl{nil, nil}

Star reprecents * column.

type ColumnConfig

type ColumnConfig interface {
	Name() string
	Type() ColumnType
	Option() *ColumnOption
	// contains filtered or unexported methods
}

ColumnConfig represents a config for table's column. This has a name, data type and some options.

func AnyColumn

func AnyColumn(name string, opt *ColumnOption) ColumnConfig

AnyColumn creates config for any types.

func BoolColumn

func BoolColumn(name string, opt *ColumnOption) ColumnConfig

BoolColumn creates config for BOOLEAN type column.

func BytesColumn

func BytesColumn(name string, opt *ColumnOption) ColumnConfig

BytesColumn creates config for BLOB type column.

func DateColumn

func DateColumn(name string, opt *ColumnOption) ColumnConfig

DateColumn creates config for DATETIME type column.

func FloatColumn

func FloatColumn(name string, opt *ColumnOption) ColumnConfig

FloatColumn creates config for REAL or FLOAT type column.

func IntColumn

func IntColumn(name string, opt *ColumnOption) ColumnConfig

IntColumn creates config for INTEGER type column.

func StringColumn

func StringColumn(name string, opt *ColumnOption) ColumnConfig

StringColumn creates config for TEXT or VARCHAR type column.

type ColumnList

type ColumnList []Column

ColumnList represents list of Column.

type ColumnOption

type ColumnOption struct {
	PrimaryKey    bool
	NotNull       bool
	Unique        bool
	AutoIncrement bool
	Size          int
	SqlType       string
	Default       interface{}
}

ColumnOption represents option for a column. ex: primary key.

type ColumnType

type ColumnType int

ColumnType reprecents a type of column. Dialects handle this for know column options.

const (
	ColumnTypeAny ColumnType = iota
	ColumnTypeInt
	ColumnTypeString
	ColumnTypeDate
	ColumnTypeFloat
	ColumnTypeBool
	ColumnTypeBytes
)

func (ColumnType) CapableTypes

func (t ColumnType) CapableTypes() []reflect.Type

func (ColumnType) String

func (t ColumnType) String() string

type Condition

type Condition interface {
	// contains filtered or unexported methods
}

Condition represents a condition for WHERE clause and other.

func And

func And(conds ...Condition) Condition

And creates a combined condition with "AND" operator.

func Or

func Or(conds ...Condition) Condition

And creates a combined condition with "OR" operator.

type CreateIndexStatement

type CreateIndexStatement struct {
	// contains filtered or unexported fields
}

CreateIndexStatement represents a "CREATE INDEX" statement.

func CreateIndex

func CreateIndex(tbl Table) *CreateIndexStatement

CreateIndex returns new "CREATE INDEX" statement. The table is Table object to create index.

func (*CreateIndexStatement) Columns

func (b *CreateIndexStatement) Columns(columns ...Column) *CreateIndexStatement

IfNotExists sets "IF NOT EXISTS" clause. If not set this, returns error on ToSql().

func (*CreateIndexStatement) IfNotExists

func (b *CreateIndexStatement) IfNotExists() *CreateIndexStatement

IfNotExists sets "IF NOT EXISTS" clause.

func (*CreateIndexStatement) Name

Name sets name for index. If not set this, auto generated name will be used.

func (*CreateIndexStatement) ToSql

func (b *CreateIndexStatement) ToSql() (query string, args []interface{}, err error)

ToSql generates query string, placeholder arguments, and returns err on errors.

type CreateTableStatement

type CreateTableStatement struct {
	// contains filtered or unexported fields
}

CreateTableStatement represents a "CREATE TABLE" statement.

func CreateTable

func CreateTable(tbl Table) *CreateTableStatement

CreateTable returns new "CREATE TABLE" statement. The table is Table object to create.

func (*CreateTableStatement) IfNotExists

func (b *CreateTableStatement) IfNotExists() *CreateTableStatement

IfNotExists sets "IF NOT EXISTS" clause.

func (*CreateTableStatement) ToSql

func (b *CreateTableStatement) ToSql() (query string, args []interface{}, err error)

ToSql generates query string, placeholder arguments, and error.

type DeleteStatement

type DeleteStatement struct {
	// contains filtered or unexported fields
}

DeleteStatement represents a DELETE statement.

func Delete

func Delete(from Table) *DeleteStatement

Delete returns new DELETE statement. The table is Table object to delete from.

func (*DeleteStatement) ToSql

func (b *DeleteStatement) ToSql() (query string, args []interface{}, err error)

ToSql generates query string, placeholder arguments, and returns err on errors.

func (*DeleteStatement) Where

func (b *DeleteStatement) Where(cond Condition) *DeleteStatement

Where sets WHERE clause. cond is filter condition.

type Dialect

type Dialect interface {
	QuerySuffix() string
	BindVar(i int) string
	QuoteField(field interface{}) string
	ColumnTypeToString(ColumnConfig) (string, error)
	ColumnOptionToString(*ColumnOption) (string, error)
	TableOptionToString(*TableOption) (string, error)
}

Dialect encapsulates behaviors that differ across SQL database.

type DropTableStatement

type DropTableStatement struct {
	// contains filtered or unexported fields
}

DeleteTableStatement represents a "DROP TABLE" statement.

func DropTable

func DropTable(tbl Table) *DropTableStatement

DropTable returns new "DROP TABLE" statement. The table is Table object to drop.

func (*DropTableStatement) ToSql

func (b *DropTableStatement) ToSql() (query string, args []interface{}, err error)

ToSql generates query string, placeholder arguments, and returns err on errors.

type InsertStatement

type InsertStatement struct {
	// contains filtered or unexported fields
}

InsertStatement represents a INSERT statement.

func Insert

func Insert(into Table) *InsertStatement

Insert returns new INSERT statement. The table is Table object for into.

func (*InsertStatement) Columns

func (b *InsertStatement) Columns(columns ...Column) *InsertStatement

Columns sets columns for insert. This overwrite old results of Columns() or Set(). If not set this, get error on ToSql().

func (*InsertStatement) Returning

func (b *InsertStatement) Returning(column Column) *InsertStatement

func (*InsertStatement) Set

func (b *InsertStatement) Set(column Column, value interface{}) *InsertStatement

Set sets the column and value togeter. Set cannot be called with Columns() or Values() in a statement.

func (*InsertStatement) ToSql

func (b *InsertStatement) ToSql() (query string, args []interface{}, err error)

ToSql generates query string, placeholder arguments, and returns err on errors.

func (*InsertStatement) Values

func (b *InsertStatement) Values(values ...interface{}) *InsertStatement

Values sets VALUES clause. This overwrite old results of Values() or Set().

type SelectStatement

type SelectStatement struct {
	// contains filtered or unexported fields
}

SelectStatement represents a SELECT statement.

func Select

func Select(from Table) *SelectStatement

Select returns new SELECT statement with from as FROM clause.

func (*SelectStatement) Columns

func (b *SelectStatement) Columns(columns ...Column) *SelectStatement

Columns set columns for select. Get all columns (use *) if it is not setted.

func (*SelectStatement) Distinct

func (b *SelectStatement) Distinct() *SelectStatement

Distinct sets DISTINCT clause.

func (*SelectStatement) GroupBy

func (b *SelectStatement) GroupBy(columns ...Column) *SelectStatement

GroupBy sets "GROUP BY" clause by the columns.

func (*SelectStatement) Having

func (b *SelectStatement) Having(cond Condition) *SelectStatement

GroupBy sets "HAVING" clause with the cond.

func (*SelectStatement) Limit

func (b *SelectStatement) Limit(limit int) *SelectStatement

Limit sets LIMIT clause.

func (*SelectStatement) Offset

func (b *SelectStatement) Offset(offset int) *SelectStatement

Offset sets OFFSET clause.

func (*SelectStatement) OrderBy

func (b *SelectStatement) OrderBy(desc bool, columns ...Column) *SelectStatement

OrderBy sets "ORDER BY" clause. Use descending order if the desc is true, by the columns.

func (*SelectStatement) ToSql

func (b *SelectStatement) ToSql() (query string, args []interface{}, err error)

ToSql generates query string, placeholder arguments, and returns err on errors.

func (*SelectStatement) ToSubquery

func (m *SelectStatement) ToSubquery(alias string) Table

func (*SelectStatement) Where

func (b *SelectStatement) Where(cond Condition) *SelectStatement

Where sets WHERE clause. The cond is filter condition.

type SqlFunc

type SqlFunc interface {
	Column
	// contains filtered or unexported methods
}

SqlFunc represents function on SQL(ex:count(*)). This can be use in the same way as Column.

func Func

func Func(name string, args ...Column) SqlFunc

Func returns new SQL function. The name is function name, and the args is arguments of function

type Statement

type Statement interface {
	ToSql() (query string, attrs []interface{}, err error)
}

Statement reprecents a statement(SELECT/INSERT/UPDATE and other)

type Table

type Table interface {

	// As returns a copy of the table with an alias.
	As(alias string) Table

	// C returns table's column by the name.
	C(name string) Column

	// Name returns table' name.
	// returns empty if it is joined table or subquery.
	Name() string

	// Option returns table's option(table constraint).
	// returns nil if it is joined table or subquery.
	Option() *TableOption

	// Columns returns all columns.
	Columns() []Column

	// InnerJoin returns a joined table use with "INNER JOIN" clause.
	// The joined table can be handled in same way as single table.
	InnerJoin(Table, Condition) Table

	// LeftOuterJoin returns a joined table use with "LEFT OUTER JOIN" clause.
	// The joined table can be handled in same way as single table.
	LeftOuterJoin(Table, Condition) Table

	// RightOuterJoin returns a joined table use with "RIGHT OUTER JOIN" clause.
	// The joined table can be handled in same way as single table.
	RightOuterJoin(Table, Condition) Table

	// FullOuterJoin returns a joined table use with "FULL OUTER JOIN" clause.
	// The joined table can be handled in same way as single table.
	FullOuterJoin(Table, Condition) Table
	// contains filtered or unexported methods
}

Table represents a table.

func NewTable

func NewTable(name string, option *TableOption, column_configs ...ColumnConfig) Table

NewTable returns a new table named by the name. Specify table columns by the column_config. Panic if column is empty.

type TableOption

type TableOption struct {
	Unique [][]string
}

TableOption reprecents constraint of a table.

type UpdateStatement

type UpdateStatement struct {
	// contains filtered or unexported fields
}

UpdateStatement represents a UPDATE statement.

func Update

func Update(tbl Table) *UpdateStatement

Update returns new UPDATE statement. The table is Table object to update.

func (*UpdateStatement) Limit

func (b *UpdateStatement) Limit(limit int) *UpdateStatement

Limit sets LIMIT clause.

func (*UpdateStatement) Offset

func (b *UpdateStatement) Offset(offset int) *UpdateStatement

Limit sets OFFSET clause.

func (*UpdateStatement) OrderBy

func (b *UpdateStatement) OrderBy(desc bool, columns ...Column) *UpdateStatement

OrderBy sets "ORDER BY" clause. Use descending order if the desc is true, by the columns.

func (*UpdateStatement) Set

func (b *UpdateStatement) Set(col Column, val interface{}) *UpdateStatement

Set sets SETS clause like col=val. Call many time for update multi columns.

func (*UpdateStatement) ToSql

func (b *UpdateStatement) ToSql() (query string, args []interface{}, err error)

ToSql generates query string, placeholder arguments, and returns err on errors.

func (*UpdateStatement) Where

func (b *UpdateStatement) Where(cond Condition) *UpdateStatement

Where sets WHERE clause. The cond is filter condition.

Directories

Path Synopsis
package for integration test(go-sqlbuilder)
package for integration test(go-sqlbuilder)

Jump to

Keyboard shortcuts

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