DB Migrations (#67)
This commit is contained in:
37
vendor/github.com/go-xorm/builder/.drone.yml
generated
vendored
Normal file
37
vendor/github.com/go-xorm/builder/.drone.yml
generated
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
workspace:
|
||||
base: /go
|
||||
path: src/github.com/go-xorm/builder
|
||||
|
||||
clone:
|
||||
git:
|
||||
image: plugins/git:next
|
||||
depth: 50
|
||||
tags: true
|
||||
|
||||
matrix:
|
||||
GO_VERSION:
|
||||
- 1.8
|
||||
- 1.9
|
||||
- 1.10
|
||||
- 1.11
|
||||
|
||||
pipeline:
|
||||
test:
|
||||
image: golang:${GO_VERSION}
|
||||
commands:
|
||||
- go get -u github.com/golang/lint/golint
|
||||
- go get -u github.com/stretchr/testify/assert
|
||||
- go get -u github.com/go-xorm/sqlfiddle
|
||||
- golint ./...
|
||||
- go test -v -race -coverprofile=coverage.txt -covermode=atomic
|
||||
when:
|
||||
event: [ push, tag, pull_request ]
|
||||
|
||||
codecov:
|
||||
image: robertstettner/drone-codecov
|
||||
group: build
|
||||
secrets: [ codecov_token ]
|
||||
files:
|
||||
- coverage.txt
|
||||
when:
|
||||
event: [ push, pull_request ]
|
39
vendor/github.com/go-xorm/builder/README.md
generated
vendored
39
vendor/github.com/go-xorm/builder/README.md
generated
vendored
@ -1,26 +1,47 @@
|
||||
# SQL builder
|
||||
|
||||
[](https://circleci.com/gh/go-xorm/builder/tree/master)
|
||||
[](https://gitci.cn/go-xorm/builder) [](https://codecov.io/gh/go-xorm/builder)
|
||||
[](https://goreportcard.com/report/github.com/go-xorm/builder)
|
||||
|
||||
Package builder is a lightweight and fast SQL builder for Go and XORM.
|
||||
|
||||
Make sure you have installed Go 1.1+ and then:
|
||||
Make sure you have installed Go 1.8+ and then:
|
||||
|
||||
go get github.com/go-xorm/builder
|
||||
|
||||
# Insert
|
||||
|
||||
```Go
|
||||
sql, args, err := Insert(Eq{"c": 1, "d": 2}).Into("table1").ToSQL()
|
||||
sql, args, err := builder.Insert(Eq{"c": 1, "d": 2}).Into("table1").ToSQL()
|
||||
|
||||
// INSERT INTO table1 SELECT * FROM table2
|
||||
sql, err := builder.Insert().Into("table1").Select().From("table2").ToBoundSQL()
|
||||
|
||||
// INSERT INTO table1 (a, b) SELECT b, c FROM table2
|
||||
sql, err = builder.Insert("a, b").Into("table1").Select("b, c").From("table2").ToBoundSQL()
|
||||
```
|
||||
|
||||
# Select
|
||||
|
||||
```Go
|
||||
// Simple Query
|
||||
sql, args, err := Select("c, d").From("table1").Where(Eq{"a": 1}).ToSQL()
|
||||
|
||||
// With join
|
||||
sql, args, err = Select("c, d").From("table1").LeftJoin("table2", Eq{"table1.id": 1}.And(Lt{"table2.id": 3})).
|
||||
RightJoin("table3", "table2.id = table3.tid").Where(Eq{"a": 1}).ToSQL()
|
||||
// From sub query
|
||||
sql, args, err := Select("sub.id").From(Select("c").From("table1").Where(Eq{"a": 1}), "sub").Where(Eq{"b": 1}).ToSQL()
|
||||
// From union query
|
||||
sql, args, err = Select("sub.id").From(
|
||||
Select("id").From("table1").Where(Eq{"a": 1}).Union("all", Select("id").From("table1").Where(Eq{"a": 2})),"sub").
|
||||
Where(Eq{"b": 1}).ToSQL()
|
||||
// With order by
|
||||
sql, args, err = Select("a", "b", "c").From("table1").Where(Eq{"f1": "v1", "f2": "v2"}).
|
||||
OrderBy("a ASC").ToSQL()
|
||||
// With limit.
|
||||
// Be careful! You should set up specific dialect for builder before performing a query with LIMIT
|
||||
sql, args, err = Dialect(MYSQL).Select("a", "b", "c").From("table1").OrderBy("a ASC").
|
||||
Limit(5, 10).ToSQL()
|
||||
```
|
||||
|
||||
# Update
|
||||
@ -35,6 +56,16 @@ sql, args, err := Update(Eq{"a": 2}).From("table1").Where(Eq{"a": 1}).ToSQL()
|
||||
sql, args, err := Delete(Eq{"a": 1}).From("table1").ToSQL()
|
||||
```
|
||||
|
||||
# Union
|
||||
|
||||
```Go
|
||||
sql, args, err := Select("*").From("a").Where(Eq{"status": "1"}).
|
||||
Union("all", Select("*").From("a").Where(Eq{"status": "2"})).
|
||||
Union("distinct", Select("*").From("a").Where(Eq{"status": "3"})).
|
||||
Union("", Select("*").From("a").Where(Eq{"status": "4"})).
|
||||
ToSQL()
|
||||
```
|
||||
|
||||
# Conditions
|
||||
|
||||
* `Eq` is a redefine of a map, you can give one or more conditions to `Eq`
|
||||
|
273
vendor/github.com/go-xorm/builder/builder.go
generated
vendored
273
vendor/github.com/go-xorm/builder/builder.go
generated
vendored
@ -4,6 +4,12 @@
|
||||
|
||||
package builder
|
||||
|
||||
import (
|
||||
sql2 "database/sql"
|
||||
"fmt"
|
||||
"sort"
|
||||
)
|
||||
|
||||
type optype byte
|
||||
|
||||
const (
|
||||
@ -12,6 +18,15 @@ const (
|
||||
insertType // insert
|
||||
updateType // update
|
||||
deleteType // delete
|
||||
unionType // union
|
||||
)
|
||||
|
||||
const (
|
||||
POSTGRES = "postgres"
|
||||
SQLITE = "sqlite3"
|
||||
MYSQL = "mysql"
|
||||
MSSQL = "mssql"
|
||||
ORACLE = "oracle"
|
||||
)
|
||||
|
||||
type join struct {
|
||||
@ -20,60 +35,115 @@ type join struct {
|
||||
joinCond Cond
|
||||
}
|
||||
|
||||
type union struct {
|
||||
unionType string
|
||||
builder *Builder
|
||||
}
|
||||
|
||||
type limit struct {
|
||||
limitN int
|
||||
offset int
|
||||
}
|
||||
|
||||
// Builder describes a SQL statement
|
||||
type Builder struct {
|
||||
optype
|
||||
tableName string
|
||||
cond Cond
|
||||
selects []string
|
||||
joins []join
|
||||
inserts Eq
|
||||
updates []Eq
|
||||
dialect string
|
||||
isNested bool
|
||||
into string
|
||||
from string
|
||||
subQuery *Builder
|
||||
cond Cond
|
||||
selects []string
|
||||
joins []join
|
||||
unions []union
|
||||
limitation *limit
|
||||
insertCols []string
|
||||
insertVals []interface{}
|
||||
updates []Eq
|
||||
orderBy string
|
||||
groupBy string
|
||||
having string
|
||||
}
|
||||
|
||||
// Select creates a select Builder
|
||||
func Select(cols ...string) *Builder {
|
||||
builder := &Builder{cond: NewCond()}
|
||||
return builder.Select(cols...)
|
||||
// Dialect sets the db dialect of Builder.
|
||||
func Dialect(dialect string) *Builder {
|
||||
builder := &Builder{cond: NewCond(), dialect: dialect}
|
||||
return builder
|
||||
}
|
||||
|
||||
// Insert creates an insert Builder
|
||||
func Insert(eq Eq) *Builder {
|
||||
builder := &Builder{cond: NewCond()}
|
||||
return builder.Insert(eq)
|
||||
// MySQL is shortcut of Dialect(MySQL)
|
||||
func MySQL() *Builder {
|
||||
return Dialect(MYSQL)
|
||||
}
|
||||
|
||||
// Update creates an update Builder
|
||||
func Update(updates ...Eq) *Builder {
|
||||
builder := &Builder{cond: NewCond()}
|
||||
return builder.Update(updates...)
|
||||
// MsSQL is shortcut of Dialect(MsSQL)
|
||||
func MsSQL() *Builder {
|
||||
return Dialect(MSSQL)
|
||||
}
|
||||
|
||||
// Delete creates a delete Builder
|
||||
func Delete(conds ...Cond) *Builder {
|
||||
builder := &Builder{cond: NewCond()}
|
||||
return builder.Delete(conds...)
|
||||
// Oracle is shortcut of Dialect(Oracle)
|
||||
func Oracle() *Builder {
|
||||
return Dialect(ORACLE)
|
||||
}
|
||||
|
||||
// Postgres is shortcut of Dialect(Postgres)
|
||||
func Postgres() *Builder {
|
||||
return Dialect(POSTGRES)
|
||||
}
|
||||
|
||||
// SQLite is shortcut of Dialect(SQLITE)
|
||||
func SQLite() *Builder {
|
||||
return Dialect(SQLITE)
|
||||
}
|
||||
|
||||
// Where sets where SQL
|
||||
func (b *Builder) Where(cond Cond) *Builder {
|
||||
b.cond = b.cond.And(cond)
|
||||
if b.cond.IsValid() {
|
||||
b.cond = b.cond.And(cond)
|
||||
} else {
|
||||
b.cond = cond
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// From sets the table name
|
||||
func (b *Builder) From(tableName string) *Builder {
|
||||
b.tableName = tableName
|
||||
// From sets from subject(can be a table name in string or a builder pointer) and its alias
|
||||
func (b *Builder) From(subject interface{}, alias ...string) *Builder {
|
||||
switch subject.(type) {
|
||||
case *Builder:
|
||||
b.subQuery = subject.(*Builder)
|
||||
|
||||
if len(alias) > 0 {
|
||||
b.from = alias[0]
|
||||
} else {
|
||||
b.isNested = true
|
||||
}
|
||||
case string:
|
||||
b.from = subject.(string)
|
||||
|
||||
if len(alias) > 0 {
|
||||
b.from = b.from + " " + alias[0]
|
||||
}
|
||||
}
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
// TableName returns the table name
|
||||
func (b *Builder) TableName() string {
|
||||
if b.optype == insertType {
|
||||
return b.into
|
||||
}
|
||||
return b.from
|
||||
}
|
||||
|
||||
// Into sets insert table name
|
||||
func (b *Builder) Into(tableName string) *Builder {
|
||||
b.tableName = tableName
|
||||
b.into = tableName
|
||||
return b
|
||||
}
|
||||
|
||||
// Join sets join table and contions
|
||||
// Join sets join table and conditions
|
||||
func (b *Builder) Join(joinType, joinTable string, joinCond interface{}) *Builder {
|
||||
switch joinCond.(type) {
|
||||
case Cond:
|
||||
@ -85,6 +155,50 @@ func (b *Builder) Join(joinType, joinTable string, joinCond interface{}) *Builde
|
||||
return b
|
||||
}
|
||||
|
||||
// Union sets union conditions
|
||||
func (b *Builder) Union(unionTp string, unionCond *Builder) *Builder {
|
||||
var builder *Builder
|
||||
if b.optype != unionType {
|
||||
builder = &Builder{cond: NewCond()}
|
||||
builder.optype = unionType
|
||||
builder.dialect = b.dialect
|
||||
builder.selects = b.selects
|
||||
|
||||
currentUnions := b.unions
|
||||
// erase sub unions (actually append to new Builder.unions)
|
||||
b.unions = nil
|
||||
|
||||
for e := range currentUnions {
|
||||
currentUnions[e].builder.dialect = b.dialect
|
||||
}
|
||||
|
||||
builder.unions = append(append(builder.unions, union{"", b}), currentUnions...)
|
||||
} else {
|
||||
builder = b
|
||||
}
|
||||
|
||||
if unionCond != nil {
|
||||
if unionCond.dialect == "" && builder.dialect != "" {
|
||||
unionCond.dialect = builder.dialect
|
||||
}
|
||||
|
||||
builder.unions = append(builder.unions, union{unionTp, unionCond})
|
||||
}
|
||||
|
||||
return builder
|
||||
}
|
||||
|
||||
// Limit sets limitN condition
|
||||
func (b *Builder) Limit(limitN int, offset ...int) *Builder {
|
||||
b.limitation = &limit{limitN: limitN}
|
||||
|
||||
if len(offset) > 0 {
|
||||
b.limitation.offset = offset[0]
|
||||
}
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
// InnerJoin sets inner join
|
||||
func (b *Builder) InnerJoin(joinTable string, joinCond interface{}) *Builder {
|
||||
return b.Join("INNER", joinTable, joinCond)
|
||||
@ -113,7 +227,9 @@ func (b *Builder) FullJoin(joinTable string, joinCond interface{}) *Builder {
|
||||
// Select sets select SQL
|
||||
func (b *Builder) Select(cols ...string) *Builder {
|
||||
b.selects = cols
|
||||
b.optype = selectType
|
||||
if b.optype == condType {
|
||||
b.optype = selectType
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
@ -130,15 +246,52 @@ func (b *Builder) Or(cond Cond) *Builder {
|
||||
}
|
||||
|
||||
// Insert sets insert SQL
|
||||
func (b *Builder) Insert(eq Eq) *Builder {
|
||||
b.inserts = eq
|
||||
func (b *Builder) Insert(eq ...interface{}) *Builder {
|
||||
if len(eq) > 0 {
|
||||
var paramType = -1
|
||||
for _, e := range eq {
|
||||
switch t := e.(type) {
|
||||
case Eq:
|
||||
if paramType == -1 {
|
||||
paramType = 0
|
||||
}
|
||||
if paramType != 0 {
|
||||
break
|
||||
}
|
||||
for k, v := range t {
|
||||
b.insertCols = append(b.insertCols, k)
|
||||
b.insertVals = append(b.insertVals, v)
|
||||
}
|
||||
case string:
|
||||
if paramType == -1 {
|
||||
paramType = 1
|
||||
}
|
||||
if paramType != 1 {
|
||||
break
|
||||
}
|
||||
b.insertCols = append(b.insertCols, t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(b.insertCols) == len(b.insertVals) {
|
||||
sort.Slice(b.insertVals, func(i, j int) bool {
|
||||
return b.insertCols[i] < b.insertCols[j]
|
||||
})
|
||||
sort.Strings(b.insertCols)
|
||||
}
|
||||
b.optype = insertType
|
||||
return b
|
||||
}
|
||||
|
||||
// Update sets update SQL
|
||||
func (b *Builder) Update(updates ...Eq) *Builder {
|
||||
b.updates = updates
|
||||
b.updates = make([]Eq, 0, len(updates))
|
||||
for _, update := range updates {
|
||||
if update.IsValid() {
|
||||
b.updates = append(b.updates, update)
|
||||
}
|
||||
}
|
||||
b.optype = updateType
|
||||
return b
|
||||
}
|
||||
@ -153,8 +306,8 @@ func (b *Builder) Delete(conds ...Cond) *Builder {
|
||||
// WriteTo implements Writer interface
|
||||
func (b *Builder) WriteTo(w Writer) error {
|
||||
switch b.optype {
|
||||
case condType:
|
||||
return b.cond.WriteTo(w)
|
||||
/*case condType:
|
||||
return b.cond.WriteTo(w)*/
|
||||
case selectType:
|
||||
return b.selectWriteTo(w)
|
||||
case insertType:
|
||||
@ -163,6 +316,8 @@ func (b *Builder) WriteTo(w Writer) error {
|
||||
return b.updateWriteTo(w)
|
||||
case deleteType:
|
||||
return b.deleteWriteTo(w)
|
||||
case unionType:
|
||||
return b.unionWriteTo(w)
|
||||
}
|
||||
|
||||
return ErrNotSupportType
|
||||
@ -175,16 +330,48 @@ func (b *Builder) ToSQL() (string, []interface{}, error) {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
return w.writer.String(), w.args, nil
|
||||
// in case of sql.NamedArg in args
|
||||
for e := range w.args {
|
||||
if namedArg, ok := w.args[e].(sql2.NamedArg); ok {
|
||||
w.args[e] = namedArg.Value
|
||||
}
|
||||
}
|
||||
|
||||
var sql = w.writer.String()
|
||||
var err error
|
||||
|
||||
switch b.dialect {
|
||||
case ORACLE, MSSQL:
|
||||
// This is for compatibility with different sql drivers
|
||||
for e := range w.args {
|
||||
w.args[e] = sql2.Named(fmt.Sprintf("p%d", e+1), w.args[e])
|
||||
}
|
||||
|
||||
var prefix string
|
||||
if b.dialect == ORACLE {
|
||||
prefix = ":p"
|
||||
} else {
|
||||
prefix = "@p"
|
||||
}
|
||||
|
||||
if sql, err = ConvertPlaceholder(sql, prefix); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
case POSTGRES:
|
||||
if sql, err = ConvertPlaceholder(sql, "$"); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return sql, w.args, nil
|
||||
}
|
||||
|
||||
// ToSQL convert a builder or condtions to SQL and args
|
||||
func ToSQL(cond interface{}) (string, []interface{}, error) {
|
||||
switch cond.(type) {
|
||||
case Cond:
|
||||
return condToSQL(cond.(Cond))
|
||||
case *Builder:
|
||||
return cond.(*Builder).ToSQL()
|
||||
// ToBoundSQL
|
||||
func (b *Builder) ToBoundSQL() (string, error) {
|
||||
w := NewWriter()
|
||||
if err := b.WriteTo(w); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return "", nil, ErrNotSupportType
|
||||
|
||||
return ConvertToBoundSQL(w.writer.String(), w.args)
|
||||
}
|
||||
|
13
vendor/github.com/go-xorm/builder/builder_delete.go
generated
vendored
13
vendor/github.com/go-xorm/builder/builder_delete.go
generated
vendored
@ -5,16 +5,21 @@
|
||||
package builder
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Delete creates a delete Builder
|
||||
func Delete(conds ...Cond) *Builder {
|
||||
builder := &Builder{cond: NewCond()}
|
||||
return builder.Delete(conds...)
|
||||
}
|
||||
|
||||
func (b *Builder) deleteWriteTo(w Writer) error {
|
||||
if len(b.tableName) <= 0 {
|
||||
return errors.New("no table indicated")
|
||||
if len(b.from) <= 0 {
|
||||
return ErrNoTableName
|
||||
}
|
||||
|
||||
if _, err := fmt.Fprintf(w, "DELETE FROM %s WHERE ", b.tableName); err != nil {
|
||||
if _, err := fmt.Fprintf(w, "DELETE FROM %s WHERE ", b.from); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
51
vendor/github.com/go-xorm/builder/builder_insert.go
generated
vendored
51
vendor/github.com/go-xorm/builder/builder_insert.go
generated
vendored
@ -6,37 +6,63 @@ package builder
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func (b *Builder) insertWriteTo(w Writer) error {
|
||||
if len(b.tableName) <= 0 {
|
||||
return errors.New("no table indicated")
|
||||
}
|
||||
if len(b.inserts) <= 0 {
|
||||
return errors.New("no column to be update")
|
||||
// Insert creates an insert Builder
|
||||
func Insert(eq ...interface{}) *Builder {
|
||||
builder := &Builder{cond: NewCond()}
|
||||
return builder.Insert(eq...)
|
||||
}
|
||||
|
||||
func (b *Builder) insertSelectWriteTo(w Writer) error {
|
||||
if _, err := fmt.Fprintf(w, "INSERT INTO %s ", b.into); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := fmt.Fprintf(w, "INSERT INTO %s (", b.tableName); err != nil {
|
||||
if len(b.insertCols) > 0 {
|
||||
fmt.Fprintf(w, "(")
|
||||
for _, col := range b.insertCols {
|
||||
fmt.Fprintf(w, col)
|
||||
}
|
||||
fmt.Fprintf(w, ") ")
|
||||
}
|
||||
|
||||
return b.selectWriteTo(w)
|
||||
}
|
||||
|
||||
func (b *Builder) insertWriteTo(w Writer) error {
|
||||
if len(b.into) <= 0 {
|
||||
return ErrNoTableName
|
||||
}
|
||||
if len(b.insertCols) <= 0 && b.from == "" {
|
||||
return ErrNoColumnToInsert
|
||||
}
|
||||
|
||||
if b.into != "" && b.from != "" {
|
||||
return b.insertSelectWriteTo(w)
|
||||
}
|
||||
|
||||
if _, err := fmt.Fprintf(w, "INSERT INTO %s (", b.into); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var args = make([]interface{}, 0)
|
||||
var bs []byte
|
||||
var valBuffer = bytes.NewBuffer(bs)
|
||||
var i = 0
|
||||
for col, value := range b.inserts {
|
||||
|
||||
for i, col := range b.insertCols {
|
||||
value := b.insertVals[i]
|
||||
fmt.Fprint(w, col)
|
||||
if e, ok := value.(expr); ok {
|
||||
fmt.Fprint(valBuffer, e.sql)
|
||||
fmt.Fprintf(valBuffer, "(%s)", e.sql)
|
||||
args = append(args, e.args...)
|
||||
} else {
|
||||
fmt.Fprint(valBuffer, "?")
|
||||
args = append(args, value)
|
||||
}
|
||||
|
||||
if i != len(b.inserts)-1 {
|
||||
if i != len(b.insertCols)-1 {
|
||||
if _, err := fmt.Fprint(w, ","); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -44,7 +70,6 @@ func (b *Builder) insertWriteTo(w Writer) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
i = i + 1
|
||||
}
|
||||
|
||||
if _, err := fmt.Fprint(w, ") Values ("); err != nil {
|
||||
|
100
vendor/github.com/go-xorm/builder/builder_limit.go
generated
vendored
Normal file
100
vendor/github.com/go-xorm/builder/builder_limit.go
generated
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
// Copyright 2018 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package builder
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func (b *Builder) limitWriteTo(w Writer) error {
|
||||
if strings.TrimSpace(b.dialect) == "" {
|
||||
return ErrDialectNotSetUp
|
||||
}
|
||||
|
||||
if b.limitation != nil {
|
||||
limit := b.limitation
|
||||
if limit.offset < 0 || limit.limitN <= 0 {
|
||||
return ErrInvalidLimitation
|
||||
}
|
||||
// erase limit condition
|
||||
b.limitation = nil
|
||||
ow := w.(*BytesWriter)
|
||||
|
||||
switch strings.ToLower(strings.TrimSpace(b.dialect)) {
|
||||
case ORACLE:
|
||||
if len(b.selects) == 0 {
|
||||
b.selects = append(b.selects, "*")
|
||||
}
|
||||
|
||||
var final *Builder
|
||||
selects := b.selects
|
||||
b.selects = append(selects, "ROWNUM RN")
|
||||
|
||||
var wb *Builder
|
||||
if b.optype == unionType {
|
||||
wb = Dialect(b.dialect).Select("at.*", "ROWNUM RN").
|
||||
From(b, "at")
|
||||
} else {
|
||||
wb = b
|
||||
}
|
||||
|
||||
if limit.offset == 0 {
|
||||
final = Dialect(b.dialect).Select(selects...).From(wb, "at").
|
||||
Where(Lte{"at.RN": limit.limitN})
|
||||
} else {
|
||||
sub := Dialect(b.dialect).Select("*").
|
||||
From(b, "at").Where(Lte{"at.RN": limit.offset + limit.limitN})
|
||||
|
||||
final = Dialect(b.dialect).Select(selects...).From(sub, "att").
|
||||
Where(Gt{"att.RN": limit.offset})
|
||||
}
|
||||
|
||||
return final.WriteTo(ow)
|
||||
case SQLITE, MYSQL, POSTGRES:
|
||||
// if type UNION, we need to write previous content back to current writer
|
||||
if b.optype == unionType {
|
||||
if err := b.WriteTo(ow); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if limit.offset == 0 {
|
||||
fmt.Fprint(ow, " LIMIT ", limit.limitN)
|
||||
} else {
|
||||
fmt.Fprintf(ow, " LIMIT %v OFFSET %v", limit.limitN, limit.offset)
|
||||
}
|
||||
case MSSQL:
|
||||
if len(b.selects) == 0 {
|
||||
b.selects = append(b.selects, "*")
|
||||
}
|
||||
|
||||
var final *Builder
|
||||
selects := b.selects
|
||||
b.selects = append(append([]string{fmt.Sprintf("TOP %d %v", limit.limitN+limit.offset, b.selects[0])},
|
||||
b.selects[1:]...), "ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS RN")
|
||||
|
||||
var wb *Builder
|
||||
if b.optype == unionType {
|
||||
wb = Dialect(b.dialect).Select("*", "ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS RN").
|
||||
From(b, "at")
|
||||
} else {
|
||||
wb = b
|
||||
}
|
||||
|
||||
if limit.offset == 0 {
|
||||
final = Dialect(b.dialect).Select(selects...).From(wb, "at")
|
||||
} else {
|
||||
final = Dialect(b.dialect).Select(selects...).From(wb, "at").Where(Gt{"at.RN": limit.offset})
|
||||
}
|
||||
|
||||
return final.WriteTo(ow)
|
||||
default:
|
||||
return ErrNotSupportType
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
110
vendor/github.com/go-xorm/builder/builder_select.go
generated
vendored
110
vendor/github.com/go-xorm/builder/builder_select.go
generated
vendored
@ -5,13 +5,24 @@
|
||||
package builder
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Select creates a select Builder
|
||||
func Select(cols ...string) *Builder {
|
||||
builder := &Builder{cond: NewCond()}
|
||||
return builder.Select(cols...)
|
||||
}
|
||||
|
||||
func (b *Builder) selectWriteTo(w Writer) error {
|
||||
if len(b.tableName) <= 0 {
|
||||
return errors.New("no table indicated")
|
||||
if len(b.from) <= 0 && !b.isNested {
|
||||
return ErrNoTableName
|
||||
}
|
||||
|
||||
// perform limit before writing to writer when b.dialect between ORACLE and MSSQL
|
||||
// this avoid a duplicate writing problem in simple limit query
|
||||
if b.limitation != nil && (b.dialect == ORACLE || b.dialect == MSSQL) {
|
||||
return b.limitWriteTo(w)
|
||||
}
|
||||
|
||||
if _, err := fmt.Fprint(w, "SELECT "); err != nil {
|
||||
@ -34,20 +45,101 @@ func (b *Builder) selectWriteTo(w Writer) error {
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := fmt.Fprintf(w, " FROM %s", b.tableName); err != nil {
|
||||
return err
|
||||
if b.subQuery == nil {
|
||||
if _, err := fmt.Fprint(w, " FROM ", b.from); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if b.cond.IsValid() && len(b.from) <= 0 {
|
||||
return ErrUnnamedDerivedTable
|
||||
}
|
||||
if b.subQuery.dialect != "" && b.dialect != b.subQuery.dialect {
|
||||
return ErrInconsistentDialect
|
||||
}
|
||||
|
||||
// dialect of sub-query will inherit from the main one (if not set up)
|
||||
if b.dialect != "" && b.subQuery.dialect == "" {
|
||||
b.subQuery.dialect = b.dialect
|
||||
}
|
||||
|
||||
switch b.subQuery.optype {
|
||||
case selectType, unionType:
|
||||
fmt.Fprint(w, " FROM (")
|
||||
if err := b.subQuery.WriteTo(w); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(b.from) == 0 {
|
||||
fmt.Fprintf(w, ")")
|
||||
} else {
|
||||
fmt.Fprintf(w, ") %v", b.from)
|
||||
}
|
||||
default:
|
||||
return ErrUnexpectedSubQuery
|
||||
}
|
||||
}
|
||||
|
||||
for _, v := range b.joins {
|
||||
fmt.Fprintf(w, " %s JOIN %s ON ", v.joinType, v.joinTable)
|
||||
if _, err := fmt.Fprintf(w, " %s JOIN %s ON ", v.joinType, v.joinTable); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := v.joinCond.WriteTo(w); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := fmt.Fprint(w, " WHERE "); err != nil {
|
||||
return err
|
||||
if b.cond.IsValid() {
|
||||
if _, err := fmt.Fprint(w, " WHERE "); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := b.cond.WriteTo(w); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return b.cond.WriteTo(w)
|
||||
if len(b.groupBy) > 0 {
|
||||
if _, err := fmt.Fprint(w, " GROUP BY ", b.groupBy); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(b.having) > 0 {
|
||||
if _, err := fmt.Fprint(w, " HAVING ", b.having); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(b.orderBy) > 0 {
|
||||
if _, err := fmt.Fprint(w, " ORDER BY ", b.orderBy); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if b.limitation != nil {
|
||||
if err := b.limitWriteTo(w); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// OrderBy orderBy SQL
|
||||
func (b *Builder) OrderBy(orderBy string) *Builder {
|
||||
b.orderBy = orderBy
|
||||
return b
|
||||
}
|
||||
|
||||
// GroupBy groupby SQL
|
||||
func (b *Builder) GroupBy(groupby string) *Builder {
|
||||
b.groupBy = groupby
|
||||
return b
|
||||
}
|
||||
|
||||
// Having having SQL
|
||||
func (b *Builder) Having(having string) *Builder {
|
||||
b.having = having
|
||||
return b
|
||||
}
|
||||
|
47
vendor/github.com/go-xorm/builder/builder_union.go
generated
vendored
Normal file
47
vendor/github.com/go-xorm/builder/builder_union.go
generated
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
// Copyright 2018 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package builder
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func (b *Builder) unionWriteTo(w Writer) error {
|
||||
if b.limitation != nil || b.cond.IsValid() ||
|
||||
b.orderBy != "" || b.having != "" || b.groupBy != "" {
|
||||
return ErrNotUnexpectedUnionConditions
|
||||
}
|
||||
|
||||
for idx, u := range b.unions {
|
||||
current := u.builder
|
||||
if current.optype != selectType {
|
||||
return ErrUnsupportedUnionMembers
|
||||
}
|
||||
|
||||
if len(b.unions) == 1 {
|
||||
if err := current.selectWriteTo(w); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if b.dialect != "" && b.dialect != current.dialect {
|
||||
return ErrInconsistentDialect
|
||||
}
|
||||
|
||||
if idx != 0 {
|
||||
fmt.Fprint(w, fmt.Sprintf(" UNION %v ", strings.ToUpper(u.unionType)))
|
||||
}
|
||||
fmt.Fprint(w, "(")
|
||||
|
||||
if err := current.selectWriteTo(w); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Fprint(w, ")")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
15
vendor/github.com/go-xorm/builder/builder_update.go
generated
vendored
15
vendor/github.com/go-xorm/builder/builder_update.go
generated
vendored
@ -5,19 +5,24 @@
|
||||
package builder
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Update creates an update Builder
|
||||
func Update(updates ...Eq) *Builder {
|
||||
builder := &Builder{cond: NewCond()}
|
||||
return builder.Update(updates...)
|
||||
}
|
||||
|
||||
func (b *Builder) updateWriteTo(w Writer) error {
|
||||
if len(b.tableName) <= 0 {
|
||||
return errors.New("no table indicated")
|
||||
if len(b.from) <= 0 {
|
||||
return ErrNoTableName
|
||||
}
|
||||
if len(b.updates) <= 0 {
|
||||
return errors.New("no column to be update")
|
||||
return ErrNoColumnToUpdate
|
||||
}
|
||||
|
||||
if _, err := fmt.Fprintf(w, "UPDATE %s SET ", b.tableName); err != nil {
|
||||
if _, err := fmt.Fprintf(w, "UPDATE %s SET ", b.from); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
12
vendor/github.com/go-xorm/builder/circle.yml
generated
vendored
12
vendor/github.com/go-xorm/builder/circle.yml
generated
vendored
@ -1,12 +0,0 @@
|
||||
dependencies:
|
||||
override:
|
||||
# './...' is a relative pattern which means all subdirectories
|
||||
- go get -t -d -v ./...
|
||||
- go build -v
|
||||
- go get -u github.com/golang/lint/golint
|
||||
|
||||
test:
|
||||
override:
|
||||
# './...' is a relative pattern which means all subdirectories
|
||||
- golint ./...
|
||||
- go test -v -race
|
21
vendor/github.com/go-xorm/builder/cond.go
generated
vendored
21
vendor/github.com/go-xorm/builder/cond.go
generated
vendored
@ -5,7 +5,6 @@
|
||||
package builder
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
)
|
||||
|
||||
@ -19,15 +18,15 @@ var _ Writer = NewWriter()
|
||||
|
||||
// BytesWriter implments Writer and save SQL in bytes.Buffer
|
||||
type BytesWriter struct {
|
||||
writer *bytes.Buffer
|
||||
buffer []byte
|
||||
writer *StringBuilder
|
||||
args []interface{}
|
||||
}
|
||||
|
||||
// NewWriter creates a new string writer
|
||||
func NewWriter() *BytesWriter {
|
||||
w := &BytesWriter{}
|
||||
w.writer = bytes.NewBuffer(w.buffer)
|
||||
w := &BytesWriter{
|
||||
writer: &StringBuilder{},
|
||||
}
|
||||
return w
|
||||
}
|
||||
|
||||
@ -73,15 +72,3 @@ func (condEmpty) Or(conds ...Cond) Cond {
|
||||
func (condEmpty) IsValid() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func condToSQL(cond Cond) (string, []interface{}, error) {
|
||||
if cond == nil || !cond.IsValid() {
|
||||
return "", nil, nil
|
||||
}
|
||||
|
||||
w := NewWriter()
|
||||
if err := cond.WriteTo(w); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
return w.writer.String(), w.args, nil
|
||||
}
|
||||
|
6
vendor/github.com/go-xorm/builder/cond_and.go
generated
vendored
6
vendor/github.com/go-xorm/builder/cond_and.go
generated
vendored
@ -25,7 +25,9 @@ func And(conds ...Cond) Cond {
|
||||
func (and condAnd) WriteTo(w Writer) error {
|
||||
for i, cond := range and {
|
||||
_, isOr := cond.(condOr)
|
||||
if isOr {
|
||||
_, isExpr := cond.(expr)
|
||||
wrap := isOr || isExpr
|
||||
if wrap {
|
||||
fmt.Fprint(w, "(")
|
||||
}
|
||||
|
||||
@ -34,7 +36,7 @@ func (and condAnd) WriteTo(w Writer) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if isOr {
|
||||
if wrap {
|
||||
fmt.Fprint(w, ")")
|
||||
}
|
||||
|
||||
|
29
vendor/github.com/go-xorm/builder/cond_between.go
generated
vendored
29
vendor/github.com/go-xorm/builder/cond_between.go
generated
vendored
@ -17,10 +17,35 @@ var _ Cond = Between{}
|
||||
|
||||
// WriteTo write data to Writer
|
||||
func (between Between) WriteTo(w Writer) error {
|
||||
if _, err := fmt.Fprintf(w, "%s BETWEEN ? AND ?", between.Col); err != nil {
|
||||
if _, err := fmt.Fprintf(w, "%s BETWEEN ", between.Col); err != nil {
|
||||
return err
|
||||
}
|
||||
w.Append(between.LessVal, between.MoreVal)
|
||||
if lv, ok := between.LessVal.(expr); ok {
|
||||
if err := lv.WriteTo(w); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if _, err := fmt.Fprint(w, "?"); err != nil {
|
||||
return err
|
||||
}
|
||||
w.Append(between.LessVal)
|
||||
}
|
||||
|
||||
if _, err := fmt.Fprint(w, " AND "); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if mv, ok := between.MoreVal.(expr); ok {
|
||||
if err := mv.WriteTo(w); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if _, err := fmt.Fprint(w, "?"); err != nil {
|
||||
return err
|
||||
}
|
||||
w.Append(between.MoreVal)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
8
vendor/github.com/go-xorm/builder/cond_compare.go
generated
vendored
8
vendor/github.com/go-xorm/builder/cond_compare.go
generated
vendored
@ -10,7 +10,13 @@ import "fmt"
|
||||
func WriteMap(w Writer, data map[string]interface{}, op string) error {
|
||||
var args = make([]interface{}, 0, len(data))
|
||||
var i = 0
|
||||
for k, v := range data {
|
||||
keys := make([]string, 0, len(data))
|
||||
for k := range data {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
|
||||
for _, k := range keys {
|
||||
v := data[k]
|
||||
switch v.(type) {
|
||||
case expr:
|
||||
if _, err := fmt.Fprintf(w, "%s%s(", k, op); err != nil {
|
||||
|
20
vendor/github.com/go-xorm/builder/cond_eq.go
generated
vendored
20
vendor/github.com/go-xorm/builder/cond_eq.go
generated
vendored
@ -4,7 +4,10 @@
|
||||
|
||||
package builder
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// Incr implements a type used by Eq
|
||||
type Incr int
|
||||
@ -19,7 +22,8 @@ var _ Cond = Eq{}
|
||||
|
||||
func (eq Eq) opWriteTo(op string, w Writer) error {
|
||||
var i = 0
|
||||
for k, v := range eq {
|
||||
for _, k := range eq.sortedKeys() {
|
||||
v := eq[k]
|
||||
switch v.(type) {
|
||||
case []int, []int64, []string, []int32, []int16, []int8, []uint, []uint64, []uint32, []uint16, []interface{}:
|
||||
if err := In(k, v).WriteTo(w); err != nil {
|
||||
@ -94,3 +98,15 @@ func (eq Eq) Or(conds ...Cond) Cond {
|
||||
func (eq Eq) IsValid() bool {
|
||||
return len(eq) > 0
|
||||
}
|
||||
|
||||
// sortedKeys returns all keys of this Eq sorted with sort.Strings.
|
||||
// It is used internally for consistent ordering when generating
|
||||
// SQL, see https://github.com/go-xorm/builder/issues/10
|
||||
func (eq Eq) sortedKeys() []string {
|
||||
keys := make([]string, 0, len(eq))
|
||||
for key := range eq {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
return keys
|
||||
}
|
||||
|
2
vendor/github.com/go-xorm/builder/cond_like.go
generated
vendored
2
vendor/github.com/go-xorm/builder/cond_like.go
generated
vendored
@ -16,7 +16,7 @@ func (like Like) WriteTo(w Writer) error {
|
||||
if _, err := fmt.Fprintf(w, "%s LIKE ?", like[0]); err != nil {
|
||||
return err
|
||||
}
|
||||
// FIXME: if use other regular express, this will be failed. but for compitable, keep this
|
||||
// FIXME: if use other regular express, this will be failed. but for compatible, keep this
|
||||
if like[1][0] == '%' || like[1][len(like[1])-1] == '%' {
|
||||
w.Append(like[1])
|
||||
} else {
|
||||
|
20
vendor/github.com/go-xorm/builder/cond_neq.go
generated
vendored
20
vendor/github.com/go-xorm/builder/cond_neq.go
generated
vendored
@ -4,7 +4,10 @@
|
||||
|
||||
package builder
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// Neq defines not equal conditions
|
||||
type Neq map[string]interface{}
|
||||
@ -15,7 +18,8 @@ var _ Cond = Neq{}
|
||||
func (neq Neq) WriteTo(w Writer) error {
|
||||
var args = make([]interface{}, 0, len(neq))
|
||||
var i = 0
|
||||
for k, v := range neq {
|
||||
for _, k := range neq.sortedKeys() {
|
||||
v := neq[k]
|
||||
switch v.(type) {
|
||||
case []int, []int64, []string, []int32, []int16, []int8:
|
||||
if err := NotIn(k, v).WriteTo(w); err != nil {
|
||||
@ -76,3 +80,15 @@ func (neq Neq) Or(conds ...Cond) Cond {
|
||||
func (neq Neq) IsValid() bool {
|
||||
return len(neq) > 0
|
||||
}
|
||||
|
||||
// sortedKeys returns all keys of this Neq sorted with sort.Strings.
|
||||
// It is used internally for consistent ordering when generating
|
||||
// SQL, see https://github.com/go-xorm/builder/issues/10
|
||||
func (neq Neq) sortedKeys() []string {
|
||||
keys := make([]string, 0, len(neq))
|
||||
for key := range neq {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
return keys
|
||||
}
|
||||
|
24
vendor/github.com/go-xorm/builder/cond_not.go
generated
vendored
24
vendor/github.com/go-xorm/builder/cond_not.go
generated
vendored
@ -21,6 +21,18 @@ func (not Not) WriteTo(w Writer) error {
|
||||
if _, err := fmt.Fprint(w, "("); err != nil {
|
||||
return err
|
||||
}
|
||||
case Eq:
|
||||
if len(not[0].(Eq)) > 1 {
|
||||
if _, err := fmt.Fprint(w, "("); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
case Neq:
|
||||
if len(not[0].(Neq)) > 1 {
|
||||
if _, err := fmt.Fprint(w, "("); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := not[0].WriteTo(w); err != nil {
|
||||
@ -32,6 +44,18 @@ func (not Not) WriteTo(w Writer) error {
|
||||
if _, err := fmt.Fprint(w, ")"); err != nil {
|
||||
return err
|
||||
}
|
||||
case Eq:
|
||||
if len(not[0].(Eq)) > 1 {
|
||||
if _, err := fmt.Fprint(w, ")"); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
case Neq:
|
||||
if len(not[0].(Neq)) > 1 {
|
||||
if _, err := fmt.Fprint(w, ")"); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
4
vendor/github.com/go-xorm/builder/cond_or.go
generated
vendored
4
vendor/github.com/go-xorm/builder/cond_or.go
generated
vendored
@ -27,10 +27,12 @@ func (o condOr) WriteTo(w Writer) error {
|
||||
for i, cond := range o {
|
||||
var needQuote bool
|
||||
switch cond.(type) {
|
||||
case condAnd:
|
||||
case condAnd, expr:
|
||||
needQuote = true
|
||||
case Eq:
|
||||
needQuote = (len(cond.(Eq)) > 1)
|
||||
case Neq:
|
||||
needQuote = (len(cond.(Neq)) > 1)
|
||||
}
|
||||
|
||||
if needQuote {
|
||||
|
26
vendor/github.com/go-xorm/builder/error.go
generated
vendored
26
vendor/github.com/go-xorm/builder/error.go
generated
vendored
@ -8,9 +8,33 @@ import "errors"
|
||||
|
||||
var (
|
||||
// ErrNotSupportType not supported SQL type error
|
||||
ErrNotSupportType = errors.New("not supported SQL type")
|
||||
ErrNotSupportType = errors.New("Not supported SQL type")
|
||||
// ErrNoNotInConditions no NOT IN params error
|
||||
ErrNoNotInConditions = errors.New("No NOT IN conditions")
|
||||
// ErrNoInConditions no IN params error
|
||||
ErrNoInConditions = errors.New("No IN conditions")
|
||||
// ErrNeedMoreArguments need more arguments
|
||||
ErrNeedMoreArguments = errors.New("Need more sql arguments")
|
||||
// ErrNoTableName no table name
|
||||
ErrNoTableName = errors.New("No table indicated")
|
||||
// ErrNoColumnToInsert no column to update
|
||||
ErrNoColumnToUpdate = errors.New("No column(s) to update")
|
||||
// ErrNoColumnToInsert no column to update
|
||||
ErrNoColumnToInsert = errors.New("No column(s) to insert")
|
||||
// ErrNotSupportDialectType not supported dialect type error
|
||||
ErrNotSupportDialectType = errors.New("Not supported dialect type")
|
||||
// ErrNotUnexpectedUnionConditions using union in a wrong way
|
||||
ErrNotUnexpectedUnionConditions = errors.New("Unexpected conditional fields in UNION query")
|
||||
// ErrUnsupportedUnionMembers unexpected members in UNION query
|
||||
ErrUnsupportedUnionMembers = errors.New("Unexpected members in UNION query")
|
||||
// ErrUnexpectedSubQuery Unexpected sub-query in SELECT query
|
||||
ErrUnexpectedSubQuery = errors.New("Unexpected sub-query in SELECT query")
|
||||
// ErrDialectNotSetUp dialect is not setup yet
|
||||
ErrDialectNotSetUp = errors.New("Dialect is not setup yet, try to use `Dialect(dbType)` at first")
|
||||
// ErrInvalidLimitation offset or limit is not correct
|
||||
ErrInvalidLimitation = errors.New("Offset or limit is not correct")
|
||||
// ErrUnnamedDerivedTable Every derived table must have its own alias
|
||||
ErrUnnamedDerivedTable = errors.New("Every derived table must have its own alias")
|
||||
// ErrInconsistentDialect Inconsistent dialect in same builder
|
||||
ErrInconsistentDialect = errors.New("Inconsistent dialect in same builder")
|
||||
)
|
||||
|
1
vendor/github.com/go-xorm/builder/go.mod
generated
vendored
Normal file
1
vendor/github.com/go-xorm/builder/go.mod
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
module "github.com/go-xorm/builder"
|
156
vendor/github.com/go-xorm/builder/sql.go
generated
vendored
Normal file
156
vendor/github.com/go-xorm/builder/sql.go
generated
vendored
Normal file
@ -0,0 +1,156 @@
|
||||
// Copyright 2018 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package builder
|
||||
|
||||
import (
|
||||
sql2 "database/sql"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"time"
|
||||
)
|
||||
|
||||
func condToSQL(cond Cond) (string, []interface{}, error) {
|
||||
if cond == nil || !cond.IsValid() {
|
||||
return "", nil, nil
|
||||
}
|
||||
|
||||
w := NewWriter()
|
||||
if err := cond.WriteTo(w); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
return w.writer.String(), w.args, nil
|
||||
}
|
||||
|
||||
func condToBoundSQL(cond Cond) (string, error) {
|
||||
if cond == nil || !cond.IsValid() {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
w := NewWriter()
|
||||
if err := cond.WriteTo(w); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return ConvertToBoundSQL(w.writer.String(), w.args)
|
||||
}
|
||||
|
||||
// ToSQL convert a builder or conditions to SQL and args
|
||||
func ToSQL(cond interface{}) (string, []interface{}, error) {
|
||||
switch cond.(type) {
|
||||
case Cond:
|
||||
return condToSQL(cond.(Cond))
|
||||
case *Builder:
|
||||
return cond.(*Builder).ToSQL()
|
||||
}
|
||||
return "", nil, ErrNotSupportType
|
||||
}
|
||||
|
||||
// ToBoundSQL convert a builder or conditions to parameters bound SQL
|
||||
func ToBoundSQL(cond interface{}) (string, error) {
|
||||
switch cond.(type) {
|
||||
case Cond:
|
||||
return condToBoundSQL(cond.(Cond))
|
||||
case *Builder:
|
||||
return cond.(*Builder).ToBoundSQL()
|
||||
}
|
||||
return "", ErrNotSupportType
|
||||
}
|
||||
|
||||
func noSQLQuoteNeeded(a interface{}) bool {
|
||||
switch a.(type) {
|
||||
case int, int8, int16, int32, int64:
|
||||
return true
|
||||
case uint, uint8, uint16, uint32, uint64:
|
||||
return true
|
||||
case float32, float64:
|
||||
return true
|
||||
case bool:
|
||||
return true
|
||||
case string:
|
||||
return false
|
||||
case time.Time, *time.Time:
|
||||
return false
|
||||
}
|
||||
|
||||
t := reflect.TypeOf(a)
|
||||
switch t.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
return true
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
return true
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return true
|
||||
case reflect.Bool:
|
||||
return true
|
||||
case reflect.String:
|
||||
return false
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// ConvertToBoundSQL will convert SQL and args to a bound SQL
|
||||
func ConvertToBoundSQL(sql string, args []interface{}) (string, error) {
|
||||
buf := StringBuilder{}
|
||||
var i, j, start int
|
||||
for ; i < len(sql); i++ {
|
||||
if sql[i] == '?' {
|
||||
_, err := buf.WriteString(sql[start:i])
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
start = i + 1
|
||||
|
||||
if len(args) == j {
|
||||
return "", ErrNeedMoreArguments
|
||||
}
|
||||
|
||||
arg := args[j]
|
||||
if namedArg, ok := arg.(sql2.NamedArg); ok {
|
||||
arg = namedArg.Value
|
||||
}
|
||||
|
||||
if noSQLQuoteNeeded(arg) {
|
||||
_, err = fmt.Fprint(&buf, arg)
|
||||
} else {
|
||||
_, err = fmt.Fprintf(&buf, "'%v'", arg)
|
||||
}
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
j = j + 1
|
||||
}
|
||||
}
|
||||
_, err := buf.WriteString(sql[start:])
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return buf.String(), nil
|
||||
}
|
||||
|
||||
// ConvertPlaceholder replaces ? to $1, $2 ... or :1, :2 ... according prefix
|
||||
func ConvertPlaceholder(sql, prefix string) (string, error) {
|
||||
buf := StringBuilder{}
|
||||
var i, j, start int
|
||||
for ; i < len(sql); i++ {
|
||||
if sql[i] == '?' {
|
||||
if _, err := buf.WriteString(sql[start:i]); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
start = i + 1
|
||||
j = j + 1
|
||||
|
||||
if _, err := buf.WriteString(fmt.Sprintf("%v%d", prefix, j)); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := buf.WriteString(sql[start:]); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return buf.String(), nil
|
||||
}
|
119
vendor/github.com/go-xorm/builder/string_builder.go
generated
vendored
Normal file
119
vendor/github.com/go-xorm/builder/string_builder.go
generated
vendored
Normal file
@ -0,0 +1,119 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package builder
|
||||
|
||||
import (
|
||||
"unicode/utf8"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// A StringBuilder is used to efficiently build a string using Write methods.
|
||||
// It minimizes memory copying. The zero value is ready to use.
|
||||
// Do not copy a non-zero Builder.
|
||||
type StringBuilder struct {
|
||||
addr *StringBuilder // of receiver, to detect copies by value
|
||||
buf []byte
|
||||
}
|
||||
|
||||
// noescape hides a pointer from escape analysis. noescape is
|
||||
// the identity function but escape analysis doesn't think the
|
||||
// output depends on the input. noescape is inlined and currently
|
||||
// compiles down to zero instructions.
|
||||
// USE CAREFULLY!
|
||||
// This was copied from the runtime; see issues 23382 and 7921.
|
||||
//go:nosplit
|
||||
func noescape(p unsafe.Pointer) unsafe.Pointer {
|
||||
x := uintptr(p)
|
||||
return unsafe.Pointer(x ^ 0)
|
||||
}
|
||||
|
||||
func (b *StringBuilder) copyCheck() {
|
||||
if b.addr == nil {
|
||||
// This hack works around a failing of Go's escape analysis
|
||||
// that was causing b to escape and be heap allocated.
|
||||
// See issue 23382.
|
||||
// TODO: once issue 7921 is fixed, this should be reverted to
|
||||
// just "b.addr = b".
|
||||
b.addr = (*StringBuilder)(noescape(unsafe.Pointer(b)))
|
||||
} else if b.addr != b {
|
||||
panic("strings: illegal use of non-zero Builder copied by value")
|
||||
}
|
||||
}
|
||||
|
||||
// String returns the accumulated string.
|
||||
func (b *StringBuilder) String() string {
|
||||
return *(*string)(unsafe.Pointer(&b.buf))
|
||||
}
|
||||
|
||||
// Len returns the number of accumulated bytes; b.Len() == len(b.String()).
|
||||
func (b *StringBuilder) Len() int { return len(b.buf) }
|
||||
|
||||
// Reset resets the Builder to be empty.
|
||||
func (b *StringBuilder) Reset() {
|
||||
b.addr = nil
|
||||
b.buf = nil
|
||||
}
|
||||
|
||||
// grow copies the buffer to a new, larger buffer so that there are at least n
|
||||
// bytes of capacity beyond len(b.buf).
|
||||
func (b *StringBuilder) grow(n int) {
|
||||
buf := make([]byte, len(b.buf), 2*cap(b.buf)+n)
|
||||
copy(buf, b.buf)
|
||||
b.buf = buf
|
||||
}
|
||||
|
||||
// Grow grows b's capacity, if necessary, to guarantee space for
|
||||
// another n bytes. After Grow(n), at least n bytes can be written to b
|
||||
// without another allocation. If n is negative, Grow panics.
|
||||
func (b *StringBuilder) Grow(n int) {
|
||||
b.copyCheck()
|
||||
if n < 0 {
|
||||
panic("strings.Builder.Grow: negative count")
|
||||
}
|
||||
if cap(b.buf)-len(b.buf) < n {
|
||||
b.grow(n)
|
||||
}
|
||||
}
|
||||
|
||||
// Write appends the contents of p to b's buffer.
|
||||
// Write always returns len(p), nil.
|
||||
func (b *StringBuilder) Write(p []byte) (int, error) {
|
||||
b.copyCheck()
|
||||
b.buf = append(b.buf, p...)
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
// WriteByte appends the byte c to b's buffer.
|
||||
// The returned error is always nil.
|
||||
func (b *StringBuilder) WriteByte(c byte) error {
|
||||
b.copyCheck()
|
||||
b.buf = append(b.buf, c)
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteRune appends the UTF-8 encoding of Unicode code point r to b's buffer.
|
||||
// It returns the length of r and a nil error.
|
||||
func (b *StringBuilder) WriteRune(r rune) (int, error) {
|
||||
b.copyCheck()
|
||||
if r < utf8.RuneSelf {
|
||||
b.buf = append(b.buf, byte(r))
|
||||
return 1, nil
|
||||
}
|
||||
l := len(b.buf)
|
||||
if cap(b.buf)-l < utf8.UTFMax {
|
||||
b.grow(utf8.UTFMax)
|
||||
}
|
||||
n := utf8.EncodeRune(b.buf[l:l+utf8.UTFMax], r)
|
||||
b.buf = b.buf[:l+n]
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// WriteString appends the contents of s to b's buffer.
|
||||
// It returns the length of s and a nil error.
|
||||
func (b *StringBuilder) WriteString(s string) (int, error) {
|
||||
b.copyCheck()
|
||||
b.buf = append(b.buf, s...)
|
||||
return len(s), nil
|
||||
}
|
Reference in New Issue
Block a user