Documentation
¶
Overview ¶
sqlquery is a simple programmatically sql query builder. The idea was to create a unique Builder which can be used with any database driver in go.
Features: Unique Placeholder for all database drivers, Batching function for large Inserts, Whitelist, Quote Identifiers, SQL queries and durations log debugging
Example ¶
Example of the basic usage of the builder. For more details please see the Examples in the methods.
package main import ( "fmt" "github.com/patrickascher/gofw/sqlquery" ) func main() { cfg := sqlquery.Config{ Driver: "mysql", Host: "127.0.0.1", Port: 3319, Username: "root", Password: "root", Database: "gofw", } // Builder from config builder, err := sqlquery.New(cfg, nil) if err != nil { //... } // Select stmt row, err := builder.Select("users").First() if err != nil { //... } fmt.Println(row) // Insert stmt rows, err := builder.Insert("users").Values([]map[string]interface{}{{"id:": 1, "name": "John", "surname": "Doe"}}).Exec() if err != nil { //... } fmt.Println(rows) // Update stmt res, err := builder.Update("users").Set(map[string]interface{}{"name": "John", "surname": "Doe"}).Where("id = ?", 1).Exec() if err != nil { //... } fmt.Println(res) // Delete stmt res, err = builder.Delete("users").Where("id = ?", 1).Exec() if err != nil { //... } fmt.Println(res) // Describe stmt cols, err := builder.Information("users").Describe() if err != nil { //... } fmt.Println(cols) // ForeignKey stmt fks, err := builder.Information("users").ForeignKeys() if err != nil { //... } fmt.Println(fks) }
Output:
Index ¶
- Constants
- Variables
- func Raw(c string) string
- func Register(name string, driver driver) error
- type Builder
- func (b *Builder) Commit() error
- func (b Builder) Config() Config
- func (b *Builder) Delete(from string) *Delete
- func (b *Builder) Driver() DriverI
- func (b *Builder) HasTx() bool
- func (b *Builder) Information(table string) *Information
- func (b *Builder) Insert(into string) *Insert
- func (b Builder) QuoteIdentifier(col string) string
- func (b *Builder) Rollback() error
- func (b *Builder) Select(from string) *Select
- func (b *Builder) SetLogger(l *logger.Logger)
- func (b *Builder) Tx() error
- func (b *Builder) Update(table string) *Update
- type Column
- type Condition
- func (c *Condition) Config(values bool, condition ...int) string
- func (c *Condition) Group(group ...string) *Condition
- func (c *Condition) Having(stmt string, args ...interface{}) *Condition
- func (c *Condition) Limit(l int) *Condition
- func (c *Condition) Offset(o int) *Condition
- func (c *Condition) On(stmt string, args ...interface{}) *Condition
- func (c *Condition) Order(order ...string) *Condition
- func (c *Condition) Reset(reset ...int)
- func (c *Condition) SetWhere(w string)
- func (c *Condition) Where(stmt string, args ...interface{}) *Condition
- type Config
- type Delete
- type DriverI
- type ForeignKey
- type Information
- type Insert
- func (s *Insert) Batch(b int) *Insert
- func (s *Insert) Columns(c ...string) *Insert
- func (s *Insert) Exec() ([]sql.Result, error)
- func (s *Insert) LastInsertedID(column string, ID interface{}) *Insert
- func (s *Insert) String() (stmt string, args [][]interface{}, err error)
- func (s *Insert) Values(values []map[string]interface{}) *Insert
- type Placeholder
- type Relation
- type Select
- func (s Select) All() (*sql.Rows, error)
- func (s *Select) Columns(cols ...string) *Select
- func (s *Select) Condition(c *Condition) *Select
- func (s Select) First() (*sql.Row, error)
- func (s *Select) Group(group ...string) *Select
- func (s *Select) Having(stmt string, args ...interface{}) *Select
- func (s *Select) Join(joinType int, table string, condition *Condition) *Select
- func (s *Select) Limit(l int) *Select
- func (s *Select) Offset(l int) *Select
- func (s *Select) Order(order ...string) *Select
- func (s Select) String() (string, []interface{}, error)
- func (s *Select) Where(stmt string, args ...interface{}) *Select
- type Update
- func (s *Update) Columns(c ...string) *Update
- func (s *Update) Condition(c *Condition) *Update
- func (s *Update) Exec() (sql.Result, error)
- func (s *Update) Set(values map[string]interface{}) *Update
- func (s *Update) String() (stmt string, args []interface{}, err error)
- func (s *Update) Where(stmt string, args ...interface{}) *Update
- Bugs
Examples ¶
Constants ¶
const ( WHERE = iota + 1 HAVING LIMIT ORDER OFFSET GROUP ON )
Allowed conditions
const ( LEFT = iota + 1 RIGHT INNER )
Allowed join types.
const BATCH = 200
BATCH - default value for batching the insert stmt. TODO bug when batching only working if it exactly matches the value otherwise sql expected 300 arguments, got 18 error TODO to fix this, we have to add a stmt as slice.
const PLACEHOLDER = "?"
const PLACEHOLDER_APPEND = "§§"
PLACEHOLDER character.
Variables ¶
var ( ErrArgumentType = errors.New("sqlquery: this argument type %v is not allowed") ErrPlaceholderMismatch = errors.New("sqlquery: %v placeholder(%v) and arguments(%v) does not fit") )
Error messages.
var ( ErrUnknownProvider = errors.New("sqlquery/driver: unknown driver %q") ErrNoProvider = errors.New("sqlquery/driver: empty driver-name or driver is nil") ErrProviderAlreadyExists = errors.New("sqlquery/driver: driver %#v is already registered") )
Error messages.
var ( ErrValueMissing = errors.New("sqlquery: No value is set") ErrColumn = errors.New("sqlquery: Column %v does not exist") )
Error messages.
var (
ErrJoinType = errors.New("sqlquery: wrong join type %#v is used")
)
Error messages.
var (
ErrNoTx = errors.New("sqlquery: no tx exists")
)
Error messages.
Functions ¶
Types ¶
type Builder ¶
type Builder struct {
// contains filtered or unexported fields
}
Builder type.
func New ¶
New Builder instance with the given configuration. If the db argument is nil, a new db connection will be created. It is highly recommended to use one open connection to avoid overhead. TODO: Idea: only one interface argument, in a type select we can figure out if it was a config or *sql.DB.
Example ¶
package main import ( "database/sql" "fmt" "github.com/patrickascher/gofw/sqlquery" ) func main() { cfg := sqlquery.Config{ Driver: "mysql", Host: "127.0.0.1", Port: 3319, Username: "root", Password: "root", Database: "gofw", } // Builder from config. builder, err := sqlquery.New(cfg, nil) if err != nil { //... } fmt.Println(builder) // Builder from adapter - like this a global open pool could be provided. db, err := sql.Open("mysql", "dns") if err != nil { //... } builder, err = sqlquery.New(cfg, db) if err != nil { //... } fmt.Println(builder) }
Output:
func (*Builder) Commit ¶
Commit the builder transaction. Error will return if no transaction was created or there is a commit error.
func (*Builder) Delete ¶
Delete - please see the Delete type documentation.
Example ¶
package main import ( "fmt" "github.com/patrickascher/gofw/sqlquery" ) func main() { // Builder from config. b, err := sqlquery.New(sqlquery.Config{}, nil) if err != nil { //... } res, err := b.Delete("users"). Where("id = ?", 2). Exec() //execute if err != nil { //... } fmt.Println(res) }
Output:
func (*Builder) Information ¶
func (b *Builder) Information(table string) *Information
Information - please see the Information type documentation.
Example ¶
package main import ( "fmt" "github.com/patrickascher/gofw/sqlquery" ) func main() { // Builder from config. b, err := sqlquery.New(sqlquery.Config{}, nil) if err != nil { //... } // Describe table columns. cols, err := b.Information("users").Describe("id", "name") if err != nil { //... } fmt.Println(cols) // FKs of the table. fks, err := b.Information("users").ForeignKeys() if err != nil { //... } fmt.Println(fks) }
Output:
func (*Builder) Insert ¶
Insert - please see the Select type documentation.
Example ¶
package main import ( "fmt" "github.com/patrickascher/gofw/sqlquery" ) func main() { // Builder from config. b, err := sqlquery.New(sqlquery.Config{}, nil) if err != nil { //... } lastID := 0 res, err := b.Insert("users"). Batch(1). //if more than 1 values are set, a batching would be executed. Columns("id", "name"). // set specific columns order Values([]map[string]interface{}{{"id": 1, "name": "John"}}). // values LastInsertedID("id", &lastID). // set last inserted id Exec() //execute if err != nil { //... } fmt.Println(res) }
Output:
func (Builder) QuoteIdentifier ¶
QuoteIdentifier by the driver quote character.
func (*Builder) Rollback ¶
Rollback the builder transaction. Error will return if no transaction was created or there is a rollback error.
func (*Builder) Select ¶
Select - please see the Select type documentation.
Example ¶
// Builder from config. b, err := sqlquery.New(sqlquery.Config{}, nil) if err != nil { //... } // select a single row row, err := b.Select("users"). Columns("id", "name"). Where("id = ?", 1). First() if err != nil { //... } fmt.Println(row) // select all rows jc := sqlquery.Condition{} rows, err := b.Select("users"). Columns("id", "name"). Where("id > ?", 10). Limit(10). Offset(5). Order("surname"). Group("age"). Join(sqlquery.LEFT, "company", jc.On("user.company = company.id AND company.branches > ?", 2)). All() if err != nil { //... } _ = rows.Close() fmt.Println(rows)
Output:
func (*Builder) Tx ¶
Tx creates a new transaction for the builder. If a tx exists, all requests (select, update, insert, delete) will be handled in that transaction.
Example ¶
// Builder from config. b, err := sqlquery.New(sqlquery.Config{}, nil) if err != nil { //... } // start tx err = b.Tx() if err != nil { //... } // some bundled stmts _, err = b.Update("users").Set(map[string]interface{}{"id": 1, "name": "John"}).Where("id = ?", 1).Exec() if err != nil { err = b.Rollback() //... } _, err = b.Delete("users").Where("id = ?", 10).Exec() if err != nil { err = b.Rollback() //... } // commit tx err = b.Commit() if err != nil { //... }
Output:
func (*Builder) Update ¶
Update - please see the Update type documentation.
Example ¶
package main import ( "fmt" "github.com/patrickascher/gofw/sqlquery" ) func main() { // Builder from config. b, err := sqlquery.New(sqlquery.Config{}, nil) if err != nil { //... } res, err := b.Update("users"). Columns("id", "name"). Set(map[string]interface{}{"name": "Bar"}). Where("id = ?", 2). Exec() //execute if err != nil { //... } fmt.Println(res) }
Output:
type Column ¶
type Column struct { Table string Name string Position int NullAble bool PrimaryKey bool Unique bool Type types.Interface DefaultValue sql.NullString Length sql.NullInt64 Autoincrement bool }
Column represents a database table column.
type Condition ¶
type Condition struct {
// contains filtered or unexported fields
}
Condition type.
func NewCondition ¶
func NewCondition() *Condition
func (*Condition) Config ¶
Config returns the requested condition. The first argument defines if the result should include the values or not. Caution, the values are not escaped and should only be used for test or debugging. On database level these are placeholders and getting escaped by the driver.
c.Config(false,WHERE,ORDER) // WHERE and ORDER are being rendered.
func (*Condition) Group ¶
Group condition. Group should only be called once. If its called more often, the last values count. Column names are not quoted TODO?.
c.Group("id","name") // GROUP BY id, name
func (*Condition) Having ¶
Having condition. Having can be called multiple times on a sql statement and gets chained by AND. If you need an OR Condition, be aware to set the right brackets or write the whole condition in one HAVING call. Arrays and slices can be passed as argument.
c.Having("amount > ?",100) c.Having("id IN (?)",[]int{10,11,12})
func (*Condition) Limit ¶
Limit condition. Limit should be called once. If its called more often, the last values count.
c.Limit(10)
func (*Condition) Offset ¶
Offset condition. Offset should be called once. If its called more often, the last values count.
c.Offset(5)
func (*Condition) On ¶
On condition for sql joins. On should only be called once. If its called more often, the last values count. Arrays and slices can be passed as argument.
c.On("user.company = company.id AND user.id > ?",100)
func (*Condition) Order ¶
Order condition. If a column has a `-` prefix, DESC order will get set. Order should only be called once. If its called more often, the last values count. Column names are not quoted TODO?.
c.Order("id","-name") // ORDER BY id ASC, name DESC
func (*Condition) Reset ¶
Reset the condition by one or more conditions. If the argument is empty, all conditions are reset.
c.Reset() // all will be reset c.Reset(WHERE,HAVING) // only WHERE and HAVING are reset.
func (*Condition) SetWhere ¶
DEPRECATED - this is just a quick fix. the wholde sqlquery.condition has to get rewritten because of the where string. not enough manipulation chances.
func (*Condition) Where ¶
Where condition. Where can be called multiple times on a sql statement and gets chained by AND. If you need an OR Condition, be aware to set the right brackets or write the whole condition in one WHERE call. Arrays and slices can be passed as argument.
c.Where("id = ?",1) c.Where("id IN (?)",[]int{10,11,12})
type Config ¶
type Config struct { Name string `json:"name"` Driver string `json:"driver"` Host string `json:"host"` Port int `json:"port"` Username string `json:"username"` Password string `json:"password"` Database string `json:"database"` Schema string `json:"schema"` MaxOpenConnections int `json:"maxOpenConnections"` MaxIdleConnections int `json:"maxIdleConnections"` MaxConnLifetime int `json:"maxConnLifetime"` // in Minutes Debug bool `json:"debug"` PreQuery string `json:"preQuery"` }
Config stores all information about the database.
type Delete ¶
type Delete struct {
// contains filtered or unexported fields
}
Delete type.
func (*Delete) Condition ¶
Condition adds your own condition to the stmt. Only WHERE conditions are allowed.
func (*Delete) Exec ¶
Exec the sql query through the Builder. An error will return if the arguments and placeholders mismatch or the sql.Exec creates with an error.
type DriverI ¶
type DriverI interface { // Connection should return an open connection. The implementation depends on the driver. // As proposal, a connection should be unique to avoid overhead. Store it in on package level if its created. Connection() *sql.DB // The character which will be used for quoting columns. QuoteCharacterColumn() string // Describe the columns of the given table. Describe(b *Builder, db string, table string, cols []string) ([]Column, error) // ForeignKeys of the given table. ForeignKeys(b *Builder, db string, table string) ([]*ForeignKey, error) // Placeholder for the go driver. Placeholder() *Placeholder // Config returns the given configuration of the driver. Config() Config // TypeMapping should unify the different column types of different database types. TypeMapping(string, Column) types.Interface }
Driver interface.
type ForeignKey ¶
ForeignKey represents a table relation. TODO: already define the relation type? 1:1,1:n,n:n?
type Information ¶
type Information struct {
// contains filtered or unexported fields
}
Information struct.
func (Information) Describe ¶
func (i Information) Describe(columns ...string) ([]Column, error)
Describe the table columns. Specific columns can be set, if empty every column will be described. By default the configure database is used, except the table name has a dot notation.
func (Information) ForeignKeys ¶
func (i Information) ForeignKeys() ([]*ForeignKey, error)
ForeignKeys of table. By default the configure database is used, except the table name has a dot notation.
type Insert ¶
type Insert struct {
// contains filtered or unexported fields
}
Insert type.
func (*Insert) Exec ¶
Exec the sql query through the Builder. If a LastInsertedID is set, the ptr will be set. An error will return if the arguments and placeholders mismatch or no value was set.
func (*Insert) LastInsertedID ¶
LastInsertedID gets the last id over different drivers.
type Placeholder ¶
type Placeholder struct { Numeric bool // must be true if the database uses something like $1,$2,... Char string // database placeholder character // contains filtered or unexported fields }
Placeholder is used to ensure an unique placeholder for different database adapters.
type Select ¶
type Select struct {
// contains filtered or unexported fields
}
Select type.
func (Select) All ¶
All returns the found rows by using the *db.Query method. All returns a *sql.Rows, dont forget to Close it! An error will return if the arguments and placeholders mismatch.
func (*Select) Columns ¶
Columns set new columns to the select stmt. If no columns are added, the * will be used.
type Update ¶
type Update struct {
// contains filtered or unexported fields
}
Update type.
func (*Update) Exec ¶
Exec the sql query through the Builder. An error will return if the arguments and placeholders mismatch, no value was set or the sql query returns one.
Notes ¶
Bugs ¶
condition/render this logic fails if the placeholder is numeric and has the same char as placeholder.
Source Files
¶
Directories
¶
Path | Synopsis |
---|---|
mysql
Package driver contains some out of the box db drivers which implement the sqlquery.Driver interface.
|
Package driver contains some out of the box db drivers which implement the sqlquery.Driver interface. |
oracle
Package driver contains some out of the box db drivers which implement the sqlquery.Driver interface.
|
Package driver contains some out of the box db drivers which implement the sqlquery.Driver interface. |