aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/xorm.io
diff options
context:
space:
mode:
authorLunny Xiao <xiaolunwen@gmail.com>2019-06-23 23:22:43 +0800
committerLauris BH <lauris@nix.lv>2019-06-23 18:22:43 +0300
commitaa7c34cf86081b71f796f6e5da60e62a3cda43ce (patch)
treec9e4b4f1490b43e942fa71b37748072d3fe441e8 /vendor/xorm.io
parentbaefea311f1a66a97f9a2779ad3342f4f8167d28 (diff)
downloadgitea-aa7c34cf86081b71f796f6e5da60e62a3cda43ce.tar.gz
gitea-aa7c34cf86081b71f796f6e5da60e62a3cda43ce.zip
Fix error log when loading issues caused by a xorm bug (#7271)
* fix error log when loading issues caused by a xorm bug * upgrade packages * fix fmt * fix Consistency * fix tests
Diffstat (limited to 'vendor/xorm.io')
-rw-r--r--vendor/xorm.io/builder/.drone.yml37
-rw-r--r--vendor/xorm.io/builder/LICENSE27
-rw-r--r--vendor/xorm.io/builder/README.md206
-rw-r--r--vendor/xorm.io/builder/builder.go394
-rw-r--r--vendor/xorm.io/builder/builder_delete.go27
-rw-r--r--vendor/xorm.io/builder/builder_insert.go89
-rw-r--r--vendor/xorm.io/builder/builder_limit.go100
-rw-r--r--vendor/xorm.io/builder/builder_select.go145
-rw-r--r--vendor/xorm.io/builder/builder_union.go47
-rw-r--r--vendor/xorm.io/builder/builder_update.go46
-rw-r--r--vendor/xorm.io/builder/cond.go74
-rw-r--r--vendor/xorm.io/builder/cond_and.go61
-rw-r--r--vendor/xorm.io/builder/cond_between.go65
-rw-r--r--vendor/xorm.io/builder/cond_compare.go160
-rw-r--r--vendor/xorm.io/builder/cond_eq.go112
-rw-r--r--vendor/xorm.io/builder/cond_expr.go39
-rw-r--r--vendor/xorm.io/builder/cond_if.go49
-rw-r--r--vendor/xorm.io/builder/cond_in.go237
-rw-r--r--vendor/xorm.io/builder/cond_like.go41
-rw-r--r--vendor/xorm.io/builder/cond_neq.go94
-rw-r--r--vendor/xorm.io/builder/cond_not.go77
-rw-r--r--vendor/xorm.io/builder/cond_notin.go234
-rw-r--r--vendor/xorm.io/builder/cond_null.go59
-rw-r--r--vendor/xorm.io/builder/cond_or.go69
-rw-r--r--vendor/xorm.io/builder/doc.go120
-rw-r--r--vendor/xorm.io/builder/error.go40
-rw-r--r--vendor/xorm.io/builder/go.mod6
-rw-r--r--vendor/xorm.io/builder/go.sum9
-rw-r--r--vendor/xorm.io/builder/sql.go156
-rw-r--r--vendor/xorm.io/builder/string_builder.go119
-rw-r--r--vendor/xorm.io/core/.gitignore1
-rw-r--r--vendor/xorm.io/core/LICENSE27
-rw-r--r--vendor/xorm.io/core/README.md116
-rw-r--r--vendor/xorm.io/core/benchmark.sh1
-rw-r--r--vendor/xorm.io/core/cache.go91
-rw-r--r--vendor/xorm.io/core/column.go166
-rw-r--r--vendor/xorm.io/core/converstion.go12
-rw-r--r--vendor/xorm.io/core/db.go223
-rw-r--r--vendor/xorm.io/core/dialect.go319
-rw-r--r--vendor/xorm.io/core/driver.go31
-rw-r--r--vendor/xorm.io/core/error.go12
-rw-r--r--vendor/xorm.io/core/filter.go68
-rw-r--r--vendor/xorm.io/core/go.mod7
-rw-r--r--vendor/xorm.io/core/go.sum9
-rw-r--r--vendor/xorm.io/core/ilogger.go35
-rw-r--r--vendor/xorm.io/core/index.go71
-rw-r--r--vendor/xorm.io/core/mapper.go258
-rw-r--r--vendor/xorm.io/core/pk.go30
-rw-r--r--vendor/xorm.io/core/rows.go338
-rw-r--r--vendor/xorm.io/core/scan.go66
-rw-r--r--vendor/xorm.io/core/stmt.go165
-rw-r--r--vendor/xorm.io/core/table.go154
-rw-r--r--vendor/xorm.io/core/tx.go153
-rw-r--r--vendor/xorm.io/core/type.go323
54 files changed, 5615 insertions, 0 deletions
diff --git a/vendor/xorm.io/builder/.drone.yml b/vendor/xorm.io/builder/.drone.yml
new file mode 100644
index 0000000000..ca40377721
--- /dev/null
+++ b/vendor/xorm.io/builder/.drone.yml
@@ -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 ] \ No newline at end of file
diff --git a/vendor/xorm.io/builder/LICENSE b/vendor/xorm.io/builder/LICENSE
new file mode 100644
index 0000000000..614d5e2829
--- /dev/null
+++ b/vendor/xorm.io/builder/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2016 The Xorm Authors
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+* Neither the name of the {organization} nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/xorm.io/builder/README.md b/vendor/xorm.io/builder/README.md
new file mode 100644
index 0000000000..cf516d1fd5
--- /dev/null
+++ b/vendor/xorm.io/builder/README.md
@@ -0,0 +1,206 @@
+# SQL builder
+
+[![GitCI.cn](https://gitci.cn/api/badges/go-xorm/builder/status.svg)](https://gitci.cn/go-xorm/builder) [![codecov](https://codecov.io/gh/go-xorm/builder/branch/master/graph/badge.svg)](https://codecov.io/gh/go-xorm/builder)
+[![](https://goreportcard.com/badge/github.com/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.8+ and then:
+
+ go get github.com/go-xorm/builder
+
+# Insert
+
+```Go
+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
+
+```Go
+sql, args, err := Update(Eq{"a": 2}).From("table1").Where(Eq{"a": 1}).ToSQL()
+```
+
+# Delete
+
+```Go
+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`
+
+```Go
+import . "github.com/go-xorm/builder"
+
+sql, args, _ := ToSQL(Eq{"a":1})
+// a=? [1]
+sql, args, _ := ToSQL(Eq{"b":"c"}.And(Eq{"c": 0}))
+// b=? AND c=? ["c", 0]
+sql, args, _ := ToSQL(Eq{"b":"c", "c":0})
+// b=? AND c=? ["c", 0]
+sql, args, _ := ToSQL(Eq{"b":"c"}.Or(Eq{"b":"d"}))
+// b=? OR b=? ["c", "d"]
+sql, args, _ := ToSQL(Eq{"b": []string{"c", "d"}})
+// b IN (?,?) ["c", "d"]
+sql, args, _ := ToSQL(Eq{"b": 1, "c":[]int{2, 3}})
+// b=? AND c IN (?,?) [1, 2, 3]
+```
+
+* `Neq` is the same to `Eq`
+
+```Go
+import . "github.com/go-xorm/builder"
+
+sql, args, _ := ToSQL(Neq{"a":1})
+// a<>? [1]
+sql, args, _ := ToSQL(Neq{"b":"c"}.And(Neq{"c": 0}))
+// b<>? AND c<>? ["c", 0]
+sql, args, _ := ToSQL(Neq{"b":"c", "c":0})
+// b<>? AND c<>? ["c", 0]
+sql, args, _ := ToSQL(Neq{"b":"c"}.Or(Neq{"b":"d"}))
+// b<>? OR b<>? ["c", "d"]
+sql, args, _ := ToSQL(Neq{"b": []string{"c", "d"}})
+// b NOT IN (?,?) ["c", "d"]
+sql, args, _ := ToSQL(Neq{"b": 1, "c":[]int{2, 3}})
+// b<>? AND c NOT IN (?,?) [1, 2, 3]
+```
+
+* `Gt`, `Gte`, `Lt`, `Lte`
+
+```Go
+import . "github.com/go-xorm/builder"
+
+sql, args, _ := ToSQL(Gt{"a", 1}.And(Gte{"b", 2}))
+// a>? AND b>=? [1, 2]
+sql, args, _ := ToSQL(Lt{"a", 1}.Or(Lte{"b", 2}))
+// a<? OR b<=? [1, 2]
+```
+
+* `Like`
+
+```Go
+import . "github.com/go-xorm/builder"
+
+sql, args, _ := ToSQL(Like{"a", "c"})
+// a LIKE ? [%c%]
+```
+
+* `Expr` you can customerize your sql with `Expr`
+
+```Go
+import . "github.com/go-xorm/builder"
+
+sql, args, _ := ToSQL(Expr("a = ? ", 1))
+// a = ? [1]
+sql, args, _ := ToSQL(Eq{"a": Expr("select id from table where c = ?", 1)})
+// a=(select id from table where c = ?) [1]
+```
+
+* `In` and `NotIn`
+
+```Go
+import . "github.com/go-xorm/builder"
+
+sql, args, _ := ToSQL(In("a", 1, 2, 3))
+// a IN (?,?,?) [1,2,3]
+sql, args, _ := ToSQL(In("a", []int{1, 2, 3}))
+// a IN (?,?,?) [1,2,3]
+sql, args, _ := ToSQL(In("a", Expr("select id from b where c = ?", 1))))
+// a IN (select id from b where c = ?) [1]
+```
+
+* `IsNull` and `NotNull`
+
+```Go
+import . "github.com/go-xorm/builder"
+
+sql, args, _ := ToSQL(IsNull{"a"})
+// a IS NULL []
+sql, args, _ := ToSQL(NotNull{"b"})
+ // b IS NOT NULL []
+```
+
+* `And(conds ...Cond)`, And can connect one or more condtions via And
+
+```Go
+import . "github.com/go-xorm/builder"
+
+sql, args, _ := ToSQL(And(Eq{"a":1}, Like{"b", "c"}, Neq{"d", 2}))
+// a=? AND b LIKE ? AND d<>? [1, %c%, 2]
+```
+
+* `Or(conds ...Cond)`, Or can connect one or more conditions via Or
+
+```Go
+import . "github.com/go-xorm/builder"
+
+sql, args, _ := ToSQL(Or(Eq{"a":1}, Like{"b", "c"}, Neq{"d", 2}))
+// a=? OR b LIKE ? OR d<>? [1, %c%, 2]
+sql, args, _ := ToSQL(Or(Eq{"a":1}, And(Like{"b", "c"}, Neq{"d", 2})))
+// a=? OR (b LIKE ? AND d<>?) [1, %c%, 2]
+```
+
+* `Between`
+
+```Go
+import . "github.com/go-xorm/builder"
+
+sql, args, _ := ToSQL(Between{"a", 1, 2})
+// a BETWEEN 1 AND 2
+```
+
+* Define yourself conditions
+
+Since `Cond` is an interface.
+
+```Go
+type Cond interface {
+ WriteTo(Writer) error
+ And(...Cond) Cond
+ Or(...Cond) Cond
+ IsValid() bool
+}
+```
+
+You can define yourself conditions and compose with other `Cond`. \ No newline at end of file
diff --git a/vendor/xorm.io/builder/builder.go b/vendor/xorm.io/builder/builder.go
new file mode 100644
index 0000000000..ffe86d4dcb
--- /dev/null
+++ b/vendor/xorm.io/builder/builder.go
@@ -0,0 +1,394 @@
+// Copyright 2016 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"
+ "sort"
+)
+
+type optype byte
+
+const (
+ condType optype = iota // only conditions
+ selectType // select
+ insertType // insert
+ updateType // update
+ deleteType // delete
+ unionType // union
+)
+
+const (
+ POSTGRES = "postgres"
+ SQLITE = "sqlite3"
+ MYSQL = "mysql"
+ MSSQL = "mssql"
+ ORACLE = "oracle"
+)
+
+type join struct {
+ joinType string
+ joinTable string
+ 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
+ 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
+}
+
+// Dialect sets the db dialect of Builder.
+func Dialect(dialect string) *Builder {
+ builder := &Builder{cond: NewCond(), dialect: dialect}
+ return builder
+}
+
+// MySQL is shortcut of Dialect(MySQL)
+func MySQL() *Builder {
+ return Dialect(MYSQL)
+}
+
+// MsSQL is shortcut of Dialect(MsSQL)
+func MsSQL() *Builder {
+ return Dialect(MSSQL)
+}
+
+// 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 {
+ if b.cond.IsValid() {
+ b.cond = b.cond.And(cond)
+ } else {
+ b.cond = cond
+ }
+ return b
+}
+
+// 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.into = tableName
+ return b
+}
+
+// Join sets join table and conditions
+func (b *Builder) Join(joinType, joinTable string, joinCond interface{}) *Builder {
+ switch joinCond.(type) {
+ case Cond:
+ b.joins = append(b.joins, join{joinType, joinTable, joinCond.(Cond)})
+ case string:
+ b.joins = append(b.joins, join{joinType, joinTable, Expr(joinCond.(string))})
+ }
+
+ 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)
+}
+
+// LeftJoin sets left join SQL
+func (b *Builder) LeftJoin(joinTable string, joinCond interface{}) *Builder {
+ return b.Join("LEFT", joinTable, joinCond)
+}
+
+// RightJoin sets right join SQL
+func (b *Builder) RightJoin(joinTable string, joinCond interface{}) *Builder {
+ return b.Join("RIGHT", joinTable, joinCond)
+}
+
+// CrossJoin sets cross join SQL
+func (b *Builder) CrossJoin(joinTable string, joinCond interface{}) *Builder {
+ return b.Join("CROSS", joinTable, joinCond)
+}
+
+// FullJoin sets full join SQL
+func (b *Builder) FullJoin(joinTable string, joinCond interface{}) *Builder {
+ return b.Join("FULL", joinTable, joinCond)
+}
+
+// Select sets select SQL
+func (b *Builder) Select(cols ...string) *Builder {
+ b.selects = cols
+ if b.optype == condType {
+ b.optype = selectType
+ }
+ return b
+}
+
+// And sets AND condition
+func (b *Builder) And(cond Cond) *Builder {
+ b.cond = And(b.cond, cond)
+ return b
+}
+
+// Or sets OR condition
+func (b *Builder) Or(cond Cond) *Builder {
+ b.cond = Or(b.cond, cond)
+ return b
+}
+
+type insertColsSorter struct {
+ cols []string
+ vals []interface{}
+}
+
+func (s insertColsSorter) Len() int {
+ return len(s.cols)
+}
+func (s insertColsSorter) Swap(i, j int) {
+ s.cols[i], s.cols[j] = s.cols[j], s.cols[i]
+ s.vals[i], s.vals[j] = s.vals[j], s.vals[i]
+}
+
+func (s insertColsSorter) Less(i, j int) bool {
+ return s.cols[i] < s.cols[j]
+}
+
+// Insert sets insert SQL
+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.Sort(insertColsSorter{
+ cols: b.insertCols,
+ vals: b.insertVals,
+ })
+ }
+ b.optype = insertType
+ return b
+}
+
+// Update sets update SQL
+func (b *Builder) Update(updates ...Eq) *Builder {
+ 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
+}
+
+// Delete sets delete SQL
+func (b *Builder) Delete(conds ...Cond) *Builder {
+ b.cond = b.cond.And(conds...)
+ b.optype = deleteType
+ return b
+}
+
+// WriteTo implements Writer interface
+func (b *Builder) WriteTo(w Writer) error {
+ switch b.optype {
+ /*case condType:
+ return b.cond.WriteTo(w)*/
+ case selectType:
+ return b.selectWriteTo(w)
+ case insertType:
+ return b.insertWriteTo(w)
+ case updateType:
+ return b.updateWriteTo(w)
+ case deleteType:
+ return b.deleteWriteTo(w)
+ case unionType:
+ return b.unionWriteTo(w)
+ }
+
+ return ErrNotSupportType
+}
+
+// ToSQL convert a builder to SQL and args
+func (b *Builder) ToSQL() (string, []interface{}, error) {
+ w := NewWriter()
+ if err := b.WriteTo(w); err != nil {
+ return "", nil, err
+ }
+
+ // 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
+}
+
+// ToBoundSQL
+func (b *Builder) ToBoundSQL() (string, error) {
+ w := NewWriter()
+ if err := b.WriteTo(w); err != nil {
+ return "", err
+ }
+
+ return ConvertToBoundSQL(w.writer.String(), w.args)
+}
diff --git a/vendor/xorm.io/builder/builder_delete.go b/vendor/xorm.io/builder/builder_delete.go
new file mode 100644
index 0000000000..317cc3ff9e
--- /dev/null
+++ b/vendor/xorm.io/builder/builder_delete.go
@@ -0,0 +1,27 @@
+// Copyright 2016 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"
+)
+
+// 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.from) <= 0 {
+ return ErrNoTableName
+ }
+
+ if _, err := fmt.Fprintf(w, "DELETE FROM %s WHERE ", b.from); err != nil {
+ return err
+ }
+
+ return b.cond.WriteTo(w)
+}
diff --git a/vendor/xorm.io/builder/builder_insert.go b/vendor/xorm.io/builder/builder_insert.go
new file mode 100644
index 0000000000..202cad51d8
--- /dev/null
+++ b/vendor/xorm.io/builder/builder_insert.go
@@ -0,0 +1,89 @@
+// Copyright 2016 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 (
+ "bytes"
+ "fmt"
+)
+
+// 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 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)
+
+ for i, col := range b.insertCols {
+ value := b.insertVals[i]
+ fmt.Fprint(w, col)
+ if e, ok := value.(expr); ok {
+ fmt.Fprintf(valBuffer, "(%s)", e.sql)
+ args = append(args, e.args...)
+ } else {
+ fmt.Fprint(valBuffer, "?")
+ args = append(args, value)
+ }
+
+ if i != len(b.insertCols)-1 {
+ if _, err := fmt.Fprint(w, ","); err != nil {
+ return err
+ }
+ if _, err := fmt.Fprint(valBuffer, ","); err != nil {
+ return err
+ }
+ }
+ }
+
+ if _, err := fmt.Fprint(w, ") Values ("); err != nil {
+ return err
+ }
+
+ if _, err := w.Write(valBuffer.Bytes()); err != nil {
+ return err
+ }
+ if _, err := fmt.Fprint(w, ")"); err != nil {
+ return err
+ }
+
+ w.Append(args...)
+
+ return nil
+}
diff --git a/vendor/xorm.io/builder/builder_limit.go b/vendor/xorm.io/builder/builder_limit.go
new file mode 100644
index 0000000000..82435dacbd
--- /dev/null
+++ b/vendor/xorm.io/builder/builder_limit.go
@@ -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
+}
diff --git a/vendor/xorm.io/builder/builder_select.go b/vendor/xorm.io/builder/builder_select.go
new file mode 100644
index 0000000000..c33b38698b
--- /dev/null
+++ b/vendor/xorm.io/builder/builder_select.go
@@ -0,0 +1,145 @@
+// Copyright 2016 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"
+)
+
+// 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.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 {
+ return err
+ }
+ if len(b.selects) > 0 {
+ for i, s := range b.selects {
+ if _, err := fmt.Fprint(w, s); err != nil {
+ return err
+ }
+ if i != len(b.selects)-1 {
+ if _, err := fmt.Fprint(w, ","); err != nil {
+ return err
+ }
+ }
+ }
+ } else {
+ if _, err := fmt.Fprint(w, "*"); 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 {
+ 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 b.cond.IsValid() {
+ if _, err := fmt.Fprint(w, " WHERE "); err != nil {
+ return err
+ }
+
+ if err := b.cond.WriteTo(w); err != nil {
+ return err
+ }
+ }
+
+ 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
+}
diff --git a/vendor/xorm.io/builder/builder_union.go b/vendor/xorm.io/builder/builder_union.go
new file mode 100644
index 0000000000..4ba9216178
--- /dev/null
+++ b/vendor/xorm.io/builder/builder_union.go
@@ -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
+}
diff --git a/vendor/xorm.io/builder/builder_update.go b/vendor/xorm.io/builder/builder_update.go
new file mode 100644
index 0000000000..37b4551526
--- /dev/null
+++ b/vendor/xorm.io/builder/builder_update.go
@@ -0,0 +1,46 @@
+// Copyright 2016 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"
+)
+
+// 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.from) <= 0 {
+ return ErrNoTableName
+ }
+ if len(b.updates) <= 0 {
+ return ErrNoColumnToUpdate
+ }
+
+ if _, err := fmt.Fprintf(w, "UPDATE %s SET ", b.from); err != nil {
+ return err
+ }
+
+ for i, s := range b.updates {
+ if err := s.opWriteTo(",", w); err != nil {
+ return err
+ }
+
+ if i != len(b.updates)-1 {
+ if _, err := fmt.Fprint(w, ","); err != nil {
+ return err
+ }
+ }
+ }
+
+ if _, err := fmt.Fprint(w, " WHERE "); err != nil {
+ return err
+ }
+
+ return b.cond.WriteTo(w)
+}
diff --git a/vendor/xorm.io/builder/cond.go b/vendor/xorm.io/builder/cond.go
new file mode 100644
index 0000000000..e44173bbd5
--- /dev/null
+++ b/vendor/xorm.io/builder/cond.go
@@ -0,0 +1,74 @@
+// Copyright 2016 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 (
+ "io"
+)
+
+// Writer defines the interface
+type Writer interface {
+ io.Writer
+ Append(...interface{})
+}
+
+var _ Writer = NewWriter()
+
+// BytesWriter implments Writer and save SQL in bytes.Buffer
+type BytesWriter struct {
+ writer *StringBuilder
+ args []interface{}
+}
+
+// NewWriter creates a new string writer
+func NewWriter() *BytesWriter {
+ w := &BytesWriter{
+ writer: &StringBuilder{},
+ }
+ return w
+}
+
+// Write writes data to Writer
+func (s *BytesWriter) Write(buf []byte) (int, error) {
+ return s.writer.Write(buf)
+}
+
+// Append appends args to Writer
+func (s *BytesWriter) Append(args ...interface{}) {
+ s.args = append(s.args, args...)
+}
+
+// Cond defines an interface
+type Cond interface {
+ WriteTo(Writer) error
+ And(...Cond) Cond
+ Or(...Cond) Cond
+ IsValid() bool
+}
+
+type condEmpty struct{}
+
+var _ Cond = condEmpty{}
+
+// NewCond creates an empty condition
+func NewCond() Cond {
+ return condEmpty{}
+}
+
+func (condEmpty) WriteTo(w Writer) error {
+ return nil
+}
+
+func (condEmpty) And(conds ...Cond) Cond {
+ return And(conds...)
+}
+
+func (condEmpty) Or(conds ...Cond) Cond {
+ return Or(conds...)
+}
+
+func (condEmpty) IsValid() bool {
+ return false
+}
diff --git a/vendor/xorm.io/builder/cond_and.go b/vendor/xorm.io/builder/cond_and.go
new file mode 100644
index 0000000000..e30bd186cd
--- /dev/null
+++ b/vendor/xorm.io/builder/cond_and.go
@@ -0,0 +1,61 @@
+// Copyright 2016 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"
+
+type condAnd []Cond
+
+var _ Cond = condAnd{}
+
+// And generates AND conditions
+func And(conds ...Cond) Cond {
+ var result = make(condAnd, 0, len(conds))
+ for _, cond := range conds {
+ if cond == nil || !cond.IsValid() {
+ continue
+ }
+ result = append(result, cond)
+ }
+ return result
+}
+
+func (and condAnd) WriteTo(w Writer) error {
+ for i, cond := range and {
+ _, isOr := cond.(condOr)
+ _, isExpr := cond.(expr)
+ wrap := isOr || isExpr
+ if wrap {
+ fmt.Fprint(w, "(")
+ }
+
+ err := cond.WriteTo(w)
+ if err != nil {
+ return err
+ }
+
+ if wrap {
+ fmt.Fprint(w, ")")
+ }
+
+ if i != len(and)-1 {
+ fmt.Fprint(w, " AND ")
+ }
+ }
+
+ return nil
+}
+
+func (and condAnd) And(conds ...Cond) Cond {
+ return And(and, And(conds...))
+}
+
+func (and condAnd) Or(conds ...Cond) Cond {
+ return Or(and, Or(conds...))
+}
+
+func (and condAnd) IsValid() bool {
+ return len(and) > 0
+}
diff --git a/vendor/xorm.io/builder/cond_between.go b/vendor/xorm.io/builder/cond_between.go
new file mode 100644
index 0000000000..10e0b83152
--- /dev/null
+++ b/vendor/xorm.io/builder/cond_between.go
@@ -0,0 +1,65 @@
+// Copyright 2016 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"
+
+// Between implmentes between condition
+type Between struct {
+ Col string
+ LessVal interface{}
+ MoreVal interface{}
+}
+
+var _ Cond = Between{}
+
+// WriteTo write data to Writer
+func (between Between) WriteTo(w Writer) error {
+ if _, err := fmt.Fprintf(w, "%s BETWEEN ", between.Col); err != nil {
+ return err
+ }
+ 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
+}
+
+// And implments And with other conditions
+func (between Between) And(conds ...Cond) Cond {
+ return And(between, And(conds...))
+}
+
+// Or implments Or with other conditions
+func (between Between) Or(conds ...Cond) Cond {
+ return Or(between, Or(conds...))
+}
+
+// IsValid tests if the condition is valid
+func (between Between) IsValid() bool {
+ return len(between.Col) > 0
+}
diff --git a/vendor/xorm.io/builder/cond_compare.go b/vendor/xorm.io/builder/cond_compare.go
new file mode 100644
index 0000000000..1c293719c0
--- /dev/null
+++ b/vendor/xorm.io/builder/cond_compare.go
@@ -0,0 +1,160 @@
+// Copyright 2016 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"
+
+// WriteMap writes conditions' SQL to Writer, op could be =, <>, >, <, <=, >= and etc.
+func WriteMap(w Writer, data map[string]interface{}, op string) error {
+ var args = make([]interface{}, 0, len(data))
+ var i = 0
+ 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 {
+ return err
+ }
+
+ if err := v.(expr).WriteTo(w); err != nil {
+ return err
+ }
+
+ if _, err := fmt.Fprintf(w, ")"); err != nil {
+ return err
+ }
+ case *Builder:
+ if _, err := fmt.Fprintf(w, "%s%s(", k, op); err != nil {
+ return err
+ }
+
+ if err := v.(*Builder).WriteTo(w); err != nil {
+ return err
+ }
+
+ if _, err := fmt.Fprintf(w, ")"); err != nil {
+ return err
+ }
+ default:
+ if _, err := fmt.Fprintf(w, "%s%s?", k, op); err != nil {
+ return err
+ }
+ args = append(args, v)
+ }
+ if i != len(data)-1 {
+ if _, err := fmt.Fprint(w, " AND "); err != nil {
+ return err
+ }
+ }
+ i = i + 1
+ }
+ w.Append(args...)
+ return nil
+}
+
+// Lt defines < condition
+type Lt map[string]interface{}
+
+var _ Cond = Lt{}
+
+// WriteTo write SQL to Writer
+func (lt Lt) WriteTo(w Writer) error {
+ return WriteMap(w, lt, "<")
+}
+
+// And implements And with other conditions
+func (lt Lt) And(conds ...Cond) Cond {
+ return condAnd{lt, And(conds...)}
+}
+
+// Or implements Or with other conditions
+func (lt Lt) Or(conds ...Cond) Cond {
+ return condOr{lt, Or(conds...)}
+}
+
+// IsValid tests if this Eq is valid
+func (lt Lt) IsValid() bool {
+ return len(lt) > 0
+}
+
+// Lte defines <= condition
+type Lte map[string]interface{}
+
+var _ Cond = Lte{}
+
+// WriteTo write SQL to Writer
+func (lte Lte) WriteTo(w Writer) error {
+ return WriteMap(w, lte, "<=")
+}
+
+// And implements And with other conditions
+func (lte Lte) And(conds ...Cond) Cond {
+ return And(lte, And(conds...))
+}
+
+// Or implements Or with other conditions
+func (lte Lte) Or(conds ...Cond) Cond {
+ return Or(lte, Or(conds...))
+}
+
+// IsValid tests if this Eq is valid
+func (lte Lte) IsValid() bool {
+ return len(lte) > 0
+}
+
+// Gt defines > condition
+type Gt map[string]interface{}
+
+var _ Cond = Gt{}
+
+// WriteTo write SQL to Writer
+func (gt Gt) WriteTo(w Writer) error {
+ return WriteMap(w, gt, ">")
+}
+
+// And implements And with other conditions
+func (gt Gt) And(conds ...Cond) Cond {
+ return And(gt, And(conds...))
+}
+
+// Or implements Or with other conditions
+func (gt Gt) Or(conds ...Cond) Cond {
+ return Or(gt, Or(conds...))
+}
+
+// IsValid tests if this Eq is valid
+func (gt Gt) IsValid() bool {
+ return len(gt) > 0
+}
+
+// Gte defines >= condition
+type Gte map[string]interface{}
+
+var _ Cond = Gte{}
+
+// WriteTo write SQL to Writer
+func (gte Gte) WriteTo(w Writer) error {
+ return WriteMap(w, gte, ">=")
+}
+
+// And implements And with other conditions
+func (gte Gte) And(conds ...Cond) Cond {
+ return And(gte, And(conds...))
+}
+
+// Or implements Or with other conditions
+func (gte Gte) Or(conds ...Cond) Cond {
+ return Or(gte, Or(conds...))
+}
+
+// IsValid tests if this Eq is valid
+func (gte Gte) IsValid() bool {
+ return len(gte) > 0
+}
diff --git a/vendor/xorm.io/builder/cond_eq.go b/vendor/xorm.io/builder/cond_eq.go
new file mode 100644
index 0000000000..79d795e6dd
--- /dev/null
+++ b/vendor/xorm.io/builder/cond_eq.go
@@ -0,0 +1,112 @@
+// Copyright 2016 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"
+ "sort"
+)
+
+// Incr implements a type used by Eq
+type Incr int
+
+// Decr implements a type used by Eq
+type Decr int
+
+// Eq defines equals conditions
+type Eq map[string]interface{}
+
+var _ Cond = Eq{}
+
+func (eq Eq) opWriteTo(op string, w Writer) error {
+ var i = 0
+ 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 {
+ return err
+ }
+ case expr:
+ if _, err := fmt.Fprintf(w, "%s=(", k); err != nil {
+ return err
+ }
+
+ if err := v.(expr).WriteTo(w); err != nil {
+ return err
+ }
+
+ if _, err := fmt.Fprintf(w, ")"); err != nil {
+ return err
+ }
+ case *Builder:
+ if _, err := fmt.Fprintf(w, "%s=(", k); err != nil {
+ return err
+ }
+
+ if err := v.(*Builder).WriteTo(w); err != nil {
+ return err
+ }
+
+ if _, err := fmt.Fprintf(w, ")"); err != nil {
+ return err
+ }
+ case Incr:
+ if _, err := fmt.Fprintf(w, "%s=%s+?", k, k); err != nil {
+ return err
+ }
+ w.Append(int(v.(Incr)))
+ case Decr:
+ if _, err := fmt.Fprintf(w, "%s=%s-?", k, k); err != nil {
+ return err
+ }
+ w.Append(int(v.(Decr)))
+ default:
+ if _, err := fmt.Fprintf(w, "%s=?", k); err != nil {
+ return err
+ }
+ w.Append(v)
+ }
+ if i != len(eq)-1 {
+ if _, err := fmt.Fprint(w, op); err != nil {
+ return err
+ }
+ }
+ i = i + 1
+ }
+ return nil
+}
+
+// WriteTo writes SQL to Writer
+func (eq Eq) WriteTo(w Writer) error {
+ return eq.opWriteTo(" AND ", w)
+}
+
+// And implements And with other conditions
+func (eq Eq) And(conds ...Cond) Cond {
+ return And(eq, And(conds...))
+}
+
+// Or implements Or with other conditions
+func (eq Eq) Or(conds ...Cond) Cond {
+ return Or(eq, Or(conds...))
+}
+
+// IsValid tests if this Eq is valid
+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
+}
diff --git a/vendor/xorm.io/builder/cond_expr.go b/vendor/xorm.io/builder/cond_expr.go
new file mode 100644
index 0000000000..e5ed572b15
--- /dev/null
+++ b/vendor/xorm.io/builder/cond_expr.go
@@ -0,0 +1,39 @@
+// Copyright 2016 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"
+
+type expr struct {
+ sql string
+ args []interface{}
+}
+
+var _ Cond = expr{}
+
+// Expr generate customerize SQL
+func Expr(sql string, args ...interface{}) Cond {
+ return expr{sql, args}
+}
+
+func (expr expr) WriteTo(w Writer) error {
+ if _, err := fmt.Fprint(w, expr.sql); err != nil {
+ return err
+ }
+ w.Append(expr.args...)
+ return nil
+}
+
+func (expr expr) And(conds ...Cond) Cond {
+ return And(expr, And(conds...))
+}
+
+func (expr expr) Or(conds ...Cond) Cond {
+ return Or(expr, Or(conds...))
+}
+
+func (expr expr) IsValid() bool {
+ return len(expr.sql) > 0
+}
diff --git a/vendor/xorm.io/builder/cond_if.go b/vendor/xorm.io/builder/cond_if.go
new file mode 100644
index 0000000000..af9eb321fd
--- /dev/null
+++ b/vendor/xorm.io/builder/cond_if.go
@@ -0,0 +1,49 @@
+// Copyright 2019 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
+
+type condIf struct {
+ condition bool
+ condTrue Cond
+ condFalse Cond
+}
+
+var _ Cond = condIf{}
+
+// If returns Cond via condition
+func If(condition bool, condTrue Cond, condFalse ...Cond) Cond {
+ var c = condIf{
+ condition: condition,
+ condTrue: condTrue,
+ }
+ if len(condFalse) > 0 {
+ c.condFalse = condFalse[0]
+ }
+ return c
+}
+
+func (condIf condIf) WriteTo(w Writer) error {
+ if condIf.condition {
+ return condIf.condTrue.WriteTo(w)
+ } else if condIf.condFalse != nil {
+ return condIf.condFalse.WriteTo(w)
+ }
+ return nil
+}
+
+func (condIf condIf) And(conds ...Cond) Cond {
+ return And(condIf, And(conds...))
+}
+
+func (condIf condIf) Or(conds ...Cond) Cond {
+ return Or(condIf, Or(conds...))
+}
+
+func (condIf condIf) IsValid() bool {
+ if condIf.condition {
+ return condIf.condTrue != nil
+ }
+ return condIf.condFalse != nil
+}
diff --git a/vendor/xorm.io/builder/cond_in.go b/vendor/xorm.io/builder/cond_in.go
new file mode 100644
index 0000000000..f6366d35c2
--- /dev/null
+++ b/vendor/xorm.io/builder/cond_in.go
@@ -0,0 +1,237 @@
+// Copyright 2016 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"
+ "reflect"
+ "strings"
+)
+
+type condIn struct {
+ col string
+ vals []interface{}
+}
+
+var _ Cond = condIn{}
+
+// In generates IN condition
+func In(col string, values ...interface{}) Cond {
+ return condIn{col, values}
+}
+
+func (condIn condIn) handleBlank(w Writer) error {
+ _, err := fmt.Fprint(w, "0=1")
+ return err
+}
+
+func (condIn condIn) WriteTo(w Writer) error {
+ if len(condIn.vals) <= 0 {
+ return condIn.handleBlank(w)
+ }
+
+ switch condIn.vals[0].(type) {
+ case []int8:
+ vals := condIn.vals[0].([]int8)
+ if len(vals) <= 0 {
+ return condIn.handleBlank(w)
+ }
+ questionMark := strings.Repeat("?,", len(vals))
+ if _, err := fmt.Fprintf(w, "%s IN (%s)", condIn.col, questionMark[:len(questionMark)-1]); err != nil {
+ return err
+ }
+ for _, val := range vals {
+ w.Append(val)
+ }
+ case []int16:
+ vals := condIn.vals[0].([]int16)
+ if len(vals) <= 0 {
+ return condIn.handleBlank(w)
+ }
+ questionMark := strings.Repeat("?,", len(vals))
+ if _, err := fmt.Fprintf(w, "%s IN (%s)", condIn.col, questionMark[:len(questionMark)-1]); err != nil {
+ return err
+ }
+ for _, val := range vals {
+ w.Append(val)
+ }
+ case []int:
+ vals := condIn.vals[0].([]int)
+ if len(vals) <= 0 {
+ return condIn.handleBlank(w)
+ }
+ questionMark := strings.Repeat("?,", len(vals))
+ if _, err := fmt.Fprintf(w, "%s IN (%s)", condIn.col, questionMark[:len(questionMark)-1]); err != nil {
+ return err
+ }
+ for _, val := range vals {
+ w.Append(val)
+ }
+ case []int32:
+ vals := condIn.vals[0].([]int32)
+ if len(vals) <= 0 {
+ return condIn.handleBlank(w)
+ }
+ questionMark := strings.Repeat("?,", len(vals))
+ if _, err := fmt.Fprintf(w, "%s IN (%s)", condIn.col, questionMark[:len(questionMark)-1]); err != nil {
+ return err
+ }
+ for _, val := range vals {
+ w.Append(val)
+ }
+ case []int64:
+ vals := condIn.vals[0].([]int64)
+ if len(vals) <= 0 {
+ return condIn.handleBlank(w)
+ }
+ questionMark := strings.Repeat("?,", len(vals))
+ if _, err := fmt.Fprintf(w, "%s IN (%s)", condIn.col, questionMark[:len(questionMark)-1]); err != nil {
+ return err
+ }
+ for _, val := range vals {
+ w.Append(val)
+ }
+ case []uint8:
+ vals := condIn.vals[0].([]uint8)
+ if len(vals) <= 0 {
+ return condIn.handleBlank(w)
+ }
+ questionMark := strings.Repeat("?,", len(vals))
+ if _, err := fmt.Fprintf(w, "%s IN (%s)", condIn.col, questionMark[:len(questionMark)-1]); err != nil {
+ return err
+ }
+ for _, val := range vals {
+ w.Append(val)
+ }
+ case []uint16:
+ vals := condIn.vals[0].([]uint16)
+ if len(vals) <= 0 {
+ return condIn.handleBlank(w)
+ }
+ questionMark := strings.Repeat("?,", len(vals))
+ if _, err := fmt.Fprintf(w, "%s IN (%s)", condIn.col, questionMark[:len(questionMark)-1]); err != nil {
+ return err
+ }
+ for _, val := range vals {
+ w.Append(val)
+ }
+ case []uint:
+ vals := condIn.vals[0].([]uint)
+ if len(vals) <= 0 {
+ return condIn.handleBlank(w)
+ }
+ questionMark := strings.Repeat("?,", len(vals))
+ if _, err := fmt.Fprintf(w, "%s IN (%s)", condIn.col, questionMark[:len(questionMark)-1]); err != nil {
+ return err
+ }
+ for _, val := range vals {
+ w.Append(val)
+ }
+ case []uint32:
+ vals := condIn.vals[0].([]uint32)
+ if len(vals) <= 0 {
+ return condIn.handleBlank(w)
+ }
+ questionMark := strings.Repeat("?,", len(vals))
+ if _, err := fmt.Fprintf(w, "%s IN (%s)", condIn.col, questionMark[:len(questionMark)-1]); err != nil {
+ return err
+ }
+ for _, val := range vals {
+ w.Append(val)
+ }
+ case []uint64:
+ vals := condIn.vals[0].([]uint64)
+ if len(vals) <= 0 {
+ return condIn.handleBlank(w)
+ }
+ questionMark := strings.Repeat("?,", len(vals))
+ if _, err := fmt.Fprintf(w, "%s IN (%s)", condIn.col, questionMark[:len(questionMark)-1]); err != nil {
+ return err
+ }
+ for _, val := range vals {
+ w.Append(val)
+ }
+ case []string:
+ vals := condIn.vals[0].([]string)
+ if len(vals) <= 0 {
+ return condIn.handleBlank(w)
+ }
+ questionMark := strings.Repeat("?,", len(vals))
+ if _, err := fmt.Fprintf(w, "%s IN (%s)", condIn.col, questionMark[:len(questionMark)-1]); err != nil {
+ return err
+ }
+ for _, val := range vals {
+ w.Append(val)
+ }
+ case []interface{}:
+ vals := condIn.vals[0].([]interface{})
+ if len(vals) <= 0 {
+ return condIn.handleBlank(w)
+ }
+ questionMark := strings.Repeat("?,", len(vals))
+ if _, err := fmt.Fprintf(w, "%s IN (%s)", condIn.col, questionMark[:len(questionMark)-1]); err != nil {
+ return err
+ }
+ w.Append(vals...)
+ case expr:
+ val := condIn.vals[0].(expr)
+ if _, err := fmt.Fprintf(w, "%s IN (", condIn.col); err != nil {
+ return err
+ }
+ if err := val.WriteTo(w); err != nil {
+ return err
+ }
+ if _, err := fmt.Fprintf(w, ")"); err != nil {
+ return err
+ }
+ case *Builder:
+ bd := condIn.vals[0].(*Builder)
+ if _, err := fmt.Fprintf(w, "%s IN (", condIn.col); err != nil {
+ return err
+ }
+ if err := bd.WriteTo(w); err != nil {
+ return err
+ }
+ if _, err := fmt.Fprintf(w, ")"); err != nil {
+ return err
+ }
+ default:
+ v := reflect.ValueOf(condIn.vals[0])
+ if v.Kind() == reflect.Slice {
+ l := v.Len()
+ if l == 0 {
+ return condIn.handleBlank(w)
+ }
+
+ questionMark := strings.Repeat("?,", l)
+ if _, err := fmt.Fprintf(w, "%s IN (%s)", condIn.col, questionMark[:len(questionMark)-1]); err != nil {
+ return err
+ }
+
+ for i := 0; i < l; i++ {
+ w.Append(v.Index(i).Interface())
+ }
+ } else {
+ questionMark := strings.Repeat("?,", len(condIn.vals))
+ if _, err := fmt.Fprintf(w, "%s IN (%s)", condIn.col, questionMark[:len(questionMark)-1]); err != nil {
+ return err
+ }
+ w.Append(condIn.vals...)
+ }
+ }
+ return nil
+}
+
+func (condIn condIn) And(conds ...Cond) Cond {
+ return And(condIn, And(conds...))
+}
+
+func (condIn condIn) Or(conds ...Cond) Cond {
+ return Or(condIn, Or(conds...))
+}
+
+func (condIn condIn) IsValid() bool {
+ return len(condIn.col) > 0 && len(condIn.vals) > 0
+}
diff --git a/vendor/xorm.io/builder/cond_like.go b/vendor/xorm.io/builder/cond_like.go
new file mode 100644
index 0000000000..e34202f8b0
--- /dev/null
+++ b/vendor/xorm.io/builder/cond_like.go
@@ -0,0 +1,41 @@
+// Copyright 2016 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"
+
+// Like defines like condition
+type Like [2]string
+
+var _ Cond = Like{"", ""}
+
+// WriteTo write SQL to Writer
+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 compatible, keep this
+ if like[1][0] == '%' || like[1][len(like[1])-1] == '%' {
+ w.Append(like[1])
+ } else {
+ w.Append("%" + like[1] + "%")
+ }
+ return nil
+}
+
+// And implements And with other conditions
+func (like Like) And(conds ...Cond) Cond {
+ return And(like, And(conds...))
+}
+
+// Or implements Or with other conditions
+func (like Like) Or(conds ...Cond) Cond {
+ return Or(like, Or(conds...))
+}
+
+// IsValid tests if this condition is valid
+func (like Like) IsValid() bool {
+ return len(like[0]) > 0 && len(like[1]) > 0
+}
diff --git a/vendor/xorm.io/builder/cond_neq.go b/vendor/xorm.io/builder/cond_neq.go
new file mode 100644
index 0000000000..3a8f3136d9
--- /dev/null
+++ b/vendor/xorm.io/builder/cond_neq.go
@@ -0,0 +1,94 @@
+// Copyright 2016 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"
+ "sort"
+)
+
+// Neq defines not equal conditions
+type Neq map[string]interface{}
+
+var _ Cond = Neq{}
+
+// WriteTo writes SQL to Writer
+func (neq Neq) WriteTo(w Writer) error {
+ var args = make([]interface{}, 0, len(neq))
+ var i = 0
+ 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 {
+ return err
+ }
+ case expr:
+ if _, err := fmt.Fprintf(w, "%s<>(", k); err != nil {
+ return err
+ }
+
+ if err := v.(expr).WriteTo(w); err != nil {
+ return err
+ }
+
+ if _, err := fmt.Fprintf(w, ")"); err != nil {
+ return err
+ }
+ case *Builder:
+ if _, err := fmt.Fprintf(w, "%s<>(", k); err != nil {
+ return err
+ }
+
+ if err := v.(*Builder).WriteTo(w); err != nil {
+ return err
+ }
+
+ if _, err := fmt.Fprintf(w, ")"); err != nil {
+ return err
+ }
+ default:
+ if _, err := fmt.Fprintf(w, "%s<>?", k); err != nil {
+ return err
+ }
+ args = append(args, v)
+ }
+ if i != len(neq)-1 {
+ if _, err := fmt.Fprint(w, " AND "); err != nil {
+ return err
+ }
+ }
+ i = i + 1
+ }
+ w.Append(args...)
+ return nil
+}
+
+// And implements And with other conditions
+func (neq Neq) And(conds ...Cond) Cond {
+ return And(neq, And(conds...))
+}
+
+// Or implements Or with other conditions
+func (neq Neq) Or(conds ...Cond) Cond {
+ return Or(neq, Or(conds...))
+}
+
+// IsValid tests if this condition is valid
+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
+}
diff --git a/vendor/xorm.io/builder/cond_not.go b/vendor/xorm.io/builder/cond_not.go
new file mode 100644
index 0000000000..667dfe7293
--- /dev/null
+++ b/vendor/xorm.io/builder/cond_not.go
@@ -0,0 +1,77 @@
+// Copyright 2016 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"
+
+// Not defines NOT condition
+type Not [1]Cond
+
+var _ Cond = Not{}
+
+// WriteTo writes SQL to Writer
+func (not Not) WriteTo(w Writer) error {
+ if _, err := fmt.Fprint(w, "NOT "); err != nil {
+ return err
+ }
+ switch not[0].(type) {
+ case condAnd, condOr:
+ 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 {
+ return err
+ }
+
+ switch not[0].(type) {
+ case condAnd, condOr:
+ 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
+}
+
+// And implements And with other conditions
+func (not Not) And(conds ...Cond) Cond {
+ return And(not, And(conds...))
+}
+
+// Or implements Or with other conditions
+func (not Not) Or(conds ...Cond) Cond {
+ return Or(not, Or(conds...))
+}
+
+// IsValid tests if this condition is valid
+func (not Not) IsValid() bool {
+ return not[0] != nil && not[0].IsValid()
+}
diff --git a/vendor/xorm.io/builder/cond_notin.go b/vendor/xorm.io/builder/cond_notin.go
new file mode 100644
index 0000000000..dc3ac49a35
--- /dev/null
+++ b/vendor/xorm.io/builder/cond_notin.go
@@ -0,0 +1,234 @@
+// Copyright 2016 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"
+ "reflect"
+ "strings"
+)
+
+type condNotIn condIn
+
+var _ Cond = condNotIn{}
+
+// NotIn generate NOT IN condition
+func NotIn(col string, values ...interface{}) Cond {
+ return condNotIn{col, values}
+}
+
+func (condNotIn condNotIn) handleBlank(w Writer) error {
+ _, err := fmt.Fprint(w, "0=0")
+ return err
+}
+
+func (condNotIn condNotIn) WriteTo(w Writer) error {
+ if len(condNotIn.vals) <= 0 {
+ return condNotIn.handleBlank(w)
+ }
+
+ switch condNotIn.vals[0].(type) {
+ case []int8:
+ vals := condNotIn.vals[0].([]int8)
+ if len(vals) <= 0 {
+ return condNotIn.handleBlank(w)
+ }
+ questionMark := strings.Repeat("?,", len(vals))
+ if _, err := fmt.Fprintf(w, "%s NOT IN (%s)", condNotIn.col, questionMark[:len(questionMark)-1]); err != nil {
+ return err
+ }
+ for _, val := range vals {
+ w.Append(val)
+ }
+ case []int16:
+ vals := condNotIn.vals[0].([]int16)
+ if len(vals) <= 0 {
+ return condNotIn.handleBlank(w)
+ }
+ questionMark := strings.Repeat("?,", len(vals))
+ if _, err := fmt.Fprintf(w, "%s NOT IN (%s)", condNotIn.col, questionMark[:len(questionMark)-1]); err != nil {
+ return err
+ }
+ for _, val := range vals {
+ w.Append(val)
+ }
+ case []int:
+ vals := condNotIn.vals[0].([]int)
+ if len(vals) <= 0 {
+ return condNotIn.handleBlank(w)
+ }
+ questionMark := strings.Repeat("?,", len(vals))
+ if _, err := fmt.Fprintf(w, "%s NOT IN (%s)", condNotIn.col, questionMark[:len(questionMark)-1]); err != nil {
+ return err
+ }
+ for _, val := range vals {
+ w.Append(val)
+ }
+ case []int32:
+ vals := condNotIn.vals[0].([]int32)
+ if len(vals) <= 0 {
+ return condNotIn.handleBlank(w)
+ }
+ questionMark := strings.Repeat("?,", len(vals))
+ if _, err := fmt.Fprintf(w, "%s NOT IN (%s)", condNotIn.col, questionMark[:len(questionMark)-1]); err != nil {
+ return err
+ }
+ for _, val := range vals {
+ w.Append(val)
+ }
+ case []int64:
+ vals := condNotIn.vals[0].([]int64)
+ if len(vals) <= 0 {
+ return condNotIn.handleBlank(w)
+ }
+ questionMark := strings.Repeat("?,", len(vals))
+ if _, err := fmt.Fprintf(w, "%s NOT IN (%s)", condNotIn.col, questionMark[:len(questionMark)-1]); err != nil {
+ return err
+ }
+ for _, val := range vals {
+ w.Append(val)
+ }
+ case []uint8:
+ vals := condNotIn.vals[0].([]uint8)
+ if len(vals) <= 0 {
+ return condNotIn.handleBlank(w)
+ }
+ questionMark := strings.Repeat("?,", len(vals))
+ if _, err := fmt.Fprintf(w, "%s NOT IN (%s)", condNotIn.col, questionMark[:len(questionMark)-1]); err != nil {
+ return err
+ }
+ for _, val := range vals {
+ w.Append(val)
+ }
+ case []uint16:
+ vals := condNotIn.vals[0].([]uint16)
+ if len(vals) <= 0 {
+ return condNotIn.handleBlank(w)
+ }
+ questionMark := strings.Repeat("?,", len(vals))
+ if _, err := fmt.Fprintf(w, "%s NOT IN (%s)", condNotIn.col, questionMark[:len(questionMark)-1]); err != nil {
+ return err
+ }
+ for _, val := range vals {
+ w.Append(val)
+ }
+ case []uint:
+ vals := condNotIn.vals[0].([]uint)
+ if len(vals) <= 0 {
+ return condNotIn.handleBlank(w)
+ }
+ questionMark := strings.Repeat("?,", len(vals))
+ if _, err := fmt.Fprintf(w, "%s NOT IN (%s)", condNotIn.col, questionMark[:len(questionMark)-1]); err != nil {
+ return err
+ }
+ for _, val := range vals {
+ w.Append(val)
+ }
+ case []uint32:
+ vals := condNotIn.vals[0].([]uint32)
+ if len(vals) <= 0 {
+ return condNotIn.handleBlank(w)
+ }
+ questionMark := strings.Repeat("?,", len(vals))
+ if _, err := fmt.Fprintf(w, "%s NOT IN (%s)", condNotIn.col, questionMark[:len(questionMark)-1]); err != nil {
+ return err
+ }
+ for _, val := range vals {
+ w.Append(val)
+ }
+ case []uint64:
+ vals := condNotIn.vals[0].([]uint64)
+ if len(vals) <= 0 {
+ return condNotIn.handleBlank(w)
+ }
+ questionMark := strings.Repeat("?,", len(vals))
+ if _, err := fmt.Fprintf(w, "%s NOT IN (%s)", condNotIn.col, questionMark[:len(questionMark)-1]); err != nil {
+ return err
+ }
+ for _, val := range vals {
+ w.Append(val)
+ }
+ case []string:
+ vals := condNotIn.vals[0].([]string)
+ if len(vals) <= 0 {
+ return condNotIn.handleBlank(w)
+ }
+ questionMark := strings.Repeat("?,", len(vals))
+ if _, err := fmt.Fprintf(w, "%s NOT IN (%s)", condNotIn.col, questionMark[:len(questionMark)-1]); err != nil {
+ return err
+ }
+ for _, val := range vals {
+ w.Append(val)
+ }
+ case []interface{}:
+ vals := condNotIn.vals[0].([]interface{})
+ if len(vals) <= 0 {
+ return condNotIn.handleBlank(w)
+ }
+ questionMark := strings.Repeat("?,", len(vals))
+ if _, err := fmt.Fprintf(w, "%s NOT IN (%s)", condNotIn.col, questionMark[:len(questionMark)-1]); err != nil {
+ return err
+ }
+ w.Append(vals...)
+ case expr:
+ val := condNotIn.vals[0].(expr)
+ if _, err := fmt.Fprintf(w, "%s NOT IN (", condNotIn.col); err != nil {
+ return err
+ }
+ if err := val.WriteTo(w); err != nil {
+ return err
+ }
+ if _, err := fmt.Fprintf(w, ")"); err != nil {
+ return err
+ }
+ case *Builder:
+ val := condNotIn.vals[0].(*Builder)
+ if _, err := fmt.Fprintf(w, "%s NOT IN (", condNotIn.col); err != nil {
+ return err
+ }
+ if err := val.WriteTo(w); err != nil {
+ return err
+ }
+ if _, err := fmt.Fprintf(w, ")"); err != nil {
+ return err
+ }
+ default:
+ v := reflect.ValueOf(condNotIn.vals[0])
+ if v.Kind() == reflect.Slice {
+ l := v.Len()
+ if l == 0 {
+ return condNotIn.handleBlank(w)
+ }
+
+ questionMark := strings.Repeat("?,", l)
+ if _, err := fmt.Fprintf(w, "%s NOT IN (%s)", condNotIn.col, questionMark[:len(questionMark)-1]); err != nil {
+ return err
+ }
+
+ for i := 0; i < l; i++ {
+ w.Append(v.Index(i).Interface())
+ }
+ } else {
+ questionMark := strings.Repeat("?,", len(condNotIn.vals))
+ if _, err := fmt.Fprintf(w, "%s NOT IN (%s)", condNotIn.col, questionMark[:len(questionMark)-1]); err != nil {
+ return err
+ }
+ w.Append(condNotIn.vals...)
+ }
+ }
+ return nil
+}
+
+func (condNotIn condNotIn) And(conds ...Cond) Cond {
+ return And(condNotIn, And(conds...))
+}
+
+func (condNotIn condNotIn) Or(conds ...Cond) Cond {
+ return Or(condNotIn, Or(conds...))
+}
+
+func (condNotIn condNotIn) IsValid() bool {
+ return len(condNotIn.col) > 0 && len(condNotIn.vals) > 0
+}
diff --git a/vendor/xorm.io/builder/cond_null.go b/vendor/xorm.io/builder/cond_null.go
new file mode 100644
index 0000000000..bf2aaf8518
--- /dev/null
+++ b/vendor/xorm.io/builder/cond_null.go
@@ -0,0 +1,59 @@
+// Copyright 2016 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"
+
+// IsNull defines IS NULL condition
+type IsNull [1]string
+
+var _ Cond = IsNull{""}
+
+// WriteTo write SQL to Writer
+func (isNull IsNull) WriteTo(w Writer) error {
+ _, err := fmt.Fprintf(w, "%s IS NULL", isNull[0])
+ return err
+}
+
+// And implements And with other conditions
+func (isNull IsNull) And(conds ...Cond) Cond {
+ return And(isNull, And(conds...))
+}
+
+// Or implements Or with other conditions
+func (isNull IsNull) Or(conds ...Cond) Cond {
+ return Or(isNull, Or(conds...))
+}
+
+// IsValid tests if this condition is valid
+func (isNull IsNull) IsValid() bool {
+ return len(isNull[0]) > 0
+}
+
+// NotNull defines NOT NULL condition
+type NotNull [1]string
+
+var _ Cond = NotNull{""}
+
+// WriteTo write SQL to Writer
+func (notNull NotNull) WriteTo(w Writer) error {
+ _, err := fmt.Fprintf(w, "%s IS NOT NULL", notNull[0])
+ return err
+}
+
+// And implements And with other conditions
+func (notNull NotNull) And(conds ...Cond) Cond {
+ return And(notNull, And(conds...))
+}
+
+// Or implements Or with other conditions
+func (notNull NotNull) Or(conds ...Cond) Cond {
+ return Or(notNull, Or(conds...))
+}
+
+// IsValid tests if this condition is valid
+func (notNull NotNull) IsValid() bool {
+ return len(notNull[0]) > 0
+}
diff --git a/vendor/xorm.io/builder/cond_or.go b/vendor/xorm.io/builder/cond_or.go
new file mode 100644
index 0000000000..52442653a8
--- /dev/null
+++ b/vendor/xorm.io/builder/cond_or.go
@@ -0,0 +1,69 @@
+// Copyright 2016 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"
+
+type condOr []Cond
+
+var _ Cond = condOr{}
+
+// Or sets OR conditions
+func Or(conds ...Cond) Cond {
+ var result = make(condOr, 0, len(conds))
+ for _, cond := range conds {
+ if cond == nil || !cond.IsValid() {
+ continue
+ }
+ result = append(result, cond)
+ }
+ return result
+}
+
+// WriteTo implments Cond
+func (o condOr) WriteTo(w Writer) error {
+ for i, cond := range o {
+ var needQuote bool
+ switch cond.(type) {
+ case condAnd, expr:
+ needQuote = true
+ case Eq:
+ needQuote = (len(cond.(Eq)) > 1)
+ case Neq:
+ needQuote = (len(cond.(Neq)) > 1)
+ }
+
+ if needQuote {
+ fmt.Fprint(w, "(")
+ }
+
+ err := cond.WriteTo(w)
+ if err != nil {
+ return err
+ }
+
+ if needQuote {
+ fmt.Fprint(w, ")")
+ }
+
+ if i != len(o)-1 {
+ fmt.Fprint(w, " OR ")
+ }
+ }
+
+ return nil
+}
+
+func (o condOr) And(conds ...Cond) Cond {
+ return And(o, And(conds...))
+}
+
+func (o condOr) Or(conds ...Cond) Cond {
+ return Or(o, Or(conds...))
+}
+
+func (o condOr) IsValid() bool {
+ return len(o) > 0
+}
diff --git a/vendor/xorm.io/builder/doc.go b/vendor/xorm.io/builder/doc.go
new file mode 100644
index 0000000000..162b150f10
--- /dev/null
+++ b/vendor/xorm.io/builder/doc.go
@@ -0,0 +1,120 @@
+// Copyright 2016 The XORM Authors. All rights reserved.
+// Use of this source code is governed by a BSD
+// license that can be found in the LICENSE file.
+
+/*
+
+Package builder is a simple and powerful sql builder for Go.
+
+Make sure you have installed Go 1.1+ and then:
+
+ go get github.com/go-xorm/builder
+
+WARNNING: Currently, only query conditions are supported. Below is the supported conditions.
+
+1. Eq is a redefine of a map, you can give one or more conditions to Eq
+
+ import . "github.com/go-xorm/builder"
+
+ sql, args, _ := ToSQL(Eq{"a":1})
+ // a=? [1]
+ sql, args, _ := ToSQL(Eq{"b":"c"}.And(Eq{"c": 0}))
+ // b=? AND c=? ["c", 0]
+ sql, args, _ := ToSQL(Eq{"b":"c", "c":0})
+ // b=? AND c=? ["c", 0]
+ sql, args, _ := ToSQL(Eq{"b":"c"}.Or(Eq{"b":"d"}))
+ // b=? OR b=? ["c", "d"]
+ sql, args, _ := ToSQL(Eq{"b": []string{"c", "d"}})
+ // b IN (?,?) ["c", "d"]
+ sql, args, _ := ToSQL(Eq{"b": 1, "c":[]int{2, 3}})
+ // b=? AND c IN (?,?) [1, 2, 3]
+
+2. Neq is the same to Eq
+
+ import . "github.com/go-xorm/builder"
+
+ sql, args, _ := ToSQL(Neq{"a":1})
+ // a<>? [1]
+ sql, args, _ := ToSQL(Neq{"b":"c"}.And(Neq{"c": 0}))
+ // b<>? AND c<>? ["c", 0]
+ sql, args, _ := ToSQL(Neq{"b":"c", "c":0})
+ // b<>? AND c<>? ["c", 0]
+ sql, args, _ := ToSQL(Neq{"b":"c"}.Or(Neq{"b":"d"}))
+ // b<>? OR b<>? ["c", "d"]
+ sql, args, _ := ToSQL(Neq{"b": []string{"c", "d"}})
+ // b NOT IN (?,?) ["c", "d"]
+ sql, args, _ := ToSQL(Neq{"b": 1, "c":[]int{2, 3}})
+ // b<>? AND c NOT IN (?,?) [1, 2, 3]
+
+3. Gt, Gte, Lt, Lte
+
+ import . "github.com/go-xorm/builder"
+
+ sql, args, _ := ToSQL(Gt{"a", 1}.And(Gte{"b", 2}))
+ // a>? AND b>=? [1, 2]
+ sql, args, _ := ToSQL(Lt{"a", 1}.Or(Lte{"b", 2}))
+ // a<? OR b<=? [1, 2]
+
+4. Like
+
+ import . "github.com/go-xorm/builder"
+
+ sql, args, _ := ToSQL(Like{"a", "c"})
+ // a LIKE ? [%c%]
+
+5. Expr you can customerize your sql with Expr
+
+ import . "github.com/go-xorm/builder"
+
+ sql, args, _ := ToSQL(Expr("a = ? ", 1))
+ // a = ? [1]
+ sql, args, _ := ToSQL(Eq{"a": Expr("select id from table where c = ?", 1)})
+ // a=(select id from table where c = ?) [1]
+
+6. In and NotIn
+
+ import . "github.com/go-xorm/builder"
+
+ sql, args, _ := ToSQL(In("a", 1, 2, 3))
+ // a IN (?,?,?) [1,2,3]
+ sql, args, _ := ToSQL(In("a", []int{1, 2, 3}))
+ // a IN (?,?,?) [1,2,3]
+ sql, args, _ := ToSQL(In("a", Expr("select id from b where c = ?", 1))))
+ // a IN (select id from b where c = ?) [1]
+
+7. IsNull and NotNull
+
+ import . "github.com/go-xorm/builder"
+
+ sql, args, _ := ToSQL(IsNull{"a"})
+ // a IS NULL []
+ sql, args, _ := ToSQL(NotNull{"b"})
+ // b IS NOT NULL []
+
+8. And(conds ...Cond), And can connect one or more condtions via AND
+
+ import . "github.com/go-xorm/builder"
+
+ sql, args, _ := ToSQL(And(Eq{"a":1}, Like{"b", "c"}, Neq{"d", 2}))
+ // a=? AND b LIKE ? AND d<>? [1, %c%, 2]
+
+9. Or(conds ...Cond), Or can connect one or more conditions via Or
+
+ import . "github.com/go-xorm/builder"
+
+ sql, args, _ := ToSQL(Or(Eq{"a":1}, Like{"b", "c"}, Neq{"d", 2}))
+ // a=? OR b LIKE ? OR d<>? [1, %c%, 2]
+ sql, args, _ := ToSQL(Or(Eq{"a":1}, And(Like{"b", "c"}, Neq{"d", 2})))
+ // a=? OR (b LIKE ? AND d<>?) [1, %c%, 2]
+
+10. Between
+
+ import . "github.com/go-xorm/builder"
+
+ sql, args, _ := ToSQL(Between("a", 1, 2))
+ // a BETWEEN 1 AND 2
+
+11. define yourself conditions
+Since Cond is a interface, you can define yourself conditions and compare with them
+*/
+package builder
diff --git a/vendor/xorm.io/builder/error.go b/vendor/xorm.io/builder/error.go
new file mode 100644
index 0000000000..d830ee9955
--- /dev/null
+++ b/vendor/xorm.io/builder/error.go
@@ -0,0 +1,40 @@
+// Copyright 2016 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 "errors"
+
+var (
+ // ErrNotSupportType not supported SQL type error
+ 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")
+)
diff --git a/vendor/xorm.io/builder/go.mod b/vendor/xorm.io/builder/go.mod
new file mode 100644
index 0000000000..35e43b329f
--- /dev/null
+++ b/vendor/xorm.io/builder/go.mod
@@ -0,0 +1,6 @@
+module xorm.io/builder
+
+require (
+ github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a
+ github.com/stretchr/testify v1.3.0
+)
diff --git a/vendor/xorm.io/builder/go.sum b/vendor/xorm.io/builder/go.sum
new file mode 100644
index 0000000000..468ba4a2d5
--- /dev/null
+++ b/vendor/xorm.io/builder/go.sum
@@ -0,0 +1,9 @@
+github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:9wScpmSP5A3Bk8V3XHWUcJmYTh+ZnlHVyc+A4oZYS3Y=
+github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:56xuuqnHyryaerycW3BfssRdxQstACi0Epw/yC5E2xM=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
diff --git a/vendor/xorm.io/builder/sql.go b/vendor/xorm.io/builder/sql.go
new file mode 100644
index 0000000000..0834242768
--- /dev/null
+++ b/vendor/xorm.io/builder/sql.go
@@ -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
+}
diff --git a/vendor/xorm.io/builder/string_builder.go b/vendor/xorm.io/builder/string_builder.go
new file mode 100644
index 0000000000..d4de8717e7
--- /dev/null
+++ b/vendor/xorm.io/builder/string_builder.go
@@ -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
+}
diff --git a/vendor/xorm.io/core/.gitignore b/vendor/xorm.io/core/.gitignore
new file mode 100644
index 0000000000..98e6ef67fa
--- /dev/null
+++ b/vendor/xorm.io/core/.gitignore
@@ -0,0 +1 @@
+*.db
diff --git a/vendor/xorm.io/core/LICENSE b/vendor/xorm.io/core/LICENSE
new file mode 100644
index 0000000000..1130797806
--- /dev/null
+++ b/vendor/xorm.io/core/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2013 - 2015 Lunny Xiao <xiaolunwen@gmail.com>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+* Neither the name of the {organization} nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/xorm.io/core/README.md b/vendor/xorm.io/core/README.md
new file mode 100644
index 0000000000..09b72c74b3
--- /dev/null
+++ b/vendor/xorm.io/core/README.md
@@ -0,0 +1,116 @@
+Core is a lightweight wrapper of sql.DB.
+
+[![CircleCI](https://circleci.com/gh/go-xorm/core/tree/master.svg?style=svg)](https://circleci.com/gh/go-xorm/core/tree/master)
+
+# Open
+```Go
+db, _ := core.Open(db, connstr)
+```
+
+# SetMapper
+```Go
+db.SetMapper(SameMapper())
+```
+
+## Scan usage
+
+### Scan
+```Go
+rows, _ := db.Query()
+for rows.Next() {
+ rows.Scan()
+}
+```
+
+### ScanMap
+```Go
+rows, _ := db.Query()
+for rows.Next() {
+ rows.ScanMap()
+```
+
+### ScanSlice
+
+You can use `[]string`, `[][]byte`, `[]interface{}`, `[]*string`, `[]sql.NullString` to ScanSclice. Notice, slice's length should be equal or less than select columns.
+
+```Go
+rows, _ := db.Query()
+cols, _ := rows.Columns()
+for rows.Next() {
+ var s = make([]string, len(cols))
+ rows.ScanSlice(&s)
+}
+```
+
+```Go
+rows, _ := db.Query()
+cols, _ := rows.Columns()
+for rows.Next() {
+ var s = make([]*string, len(cols))
+ rows.ScanSlice(&s)
+}
+```
+
+### ScanStruct
+```Go
+rows, _ := db.Query()
+for rows.Next() {
+ rows.ScanStructByName()
+ rows.ScanStructByIndex()
+}
+```
+
+## Query usage
+```Go
+rows, err := db.Query("select * from table where name = ?", name)
+
+user = User{
+ Name:"lunny",
+}
+rows, err := db.QueryStruct("select * from table where name = ?Name",
+ &user)
+
+var user = map[string]interface{}{
+ "name": "lunny",
+}
+rows, err = db.QueryMap("select * from table where name = ?name",
+ &user)
+```
+
+## QueryRow usage
+```Go
+row := db.QueryRow("select * from table where name = ?", name)
+
+user = User{
+ Name:"lunny",
+}
+row := db.QueryRowStruct("select * from table where name = ?Name",
+ &user)
+
+var user = map[string]interface{}{
+ "name": "lunny",
+}
+row = db.QueryRowMap("select * from table where name = ?name",
+ &user)
+```
+
+## Exec usage
+```Go
+db.Exec("insert into user (`name`, title, age, alias, nick_name,created) values (?,?,?,?,?,?)", name, title, age, alias...)
+
+user = User{
+ Name:"lunny",
+ Title:"test",
+ Age: 18,
+}
+result, err = db.ExecStruct("insert into user (`name`, title, age, alias, nick_name,created) values (?Name,?Title,?Age,?Alias,?NickName,?Created)",
+ &user)
+
+var user = map[string]interface{}{
+ "Name": "lunny",
+ "Title": "test",
+ "Age": 18,
+}
+result, err = db.ExecMap("insert into user (`name`, title, age, alias, nick_name,created) values (?Name,?Title,?Age,?Alias,?NickName,?Created)",
+ &user)
+``` \ No newline at end of file
diff --git a/vendor/xorm.io/core/benchmark.sh b/vendor/xorm.io/core/benchmark.sh
new file mode 100644
index 0000000000..eab9e57e9f
--- /dev/null
+++ b/vendor/xorm.io/core/benchmark.sh
@@ -0,0 +1 @@
+go test -v -bench=. -run=XXX
diff --git a/vendor/xorm.io/core/cache.go b/vendor/xorm.io/core/cache.go
new file mode 100644
index 0000000000..dc4992dfb1
--- /dev/null
+++ b/vendor/xorm.io/core/cache.go
@@ -0,0 +1,91 @@
+// Copyright 2019 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 core
+
+import (
+ "bytes"
+ "encoding/gob"
+ "errors"
+ "fmt"
+ "strings"
+ "time"
+)
+
+const (
+ // default cache expired time
+ CacheExpired = 60 * time.Minute
+ // not use now
+ CacheMaxMemory = 256
+ // evey ten minutes to clear all expired nodes
+ CacheGcInterval = 10 * time.Minute
+ // each time when gc to removed max nodes
+ CacheGcMaxRemoved = 20
+)
+
+var (
+ ErrCacheMiss = errors.New("xorm/cache: key not found.")
+ ErrNotStored = errors.New("xorm/cache: not stored.")
+)
+
+// CacheStore is a interface to store cache
+type CacheStore interface {
+ // key is primary key or composite primary key
+ // value is struct's pointer
+ // key format : <tablename>-p-<pk1>-<pk2>...
+ Put(key string, value interface{}) error
+ Get(key string) (interface{}, error)
+ Del(key string) error
+}
+
+// Cacher is an interface to provide cache
+// id format : u-<pk1>-<pk2>...
+type Cacher interface {
+ GetIds(tableName, sql string) interface{}
+ GetBean(tableName string, id string) interface{}
+ PutIds(tableName, sql string, ids interface{})
+ PutBean(tableName string, id string, obj interface{})
+ DelIds(tableName, sql string)
+ DelBean(tableName string, id string)
+ ClearIds(tableName string)
+ ClearBeans(tableName string)
+}
+
+func encodeIds(ids []PK) (string, error) {
+ buf := new(bytes.Buffer)
+ enc := gob.NewEncoder(buf)
+ err := enc.Encode(ids)
+
+ return buf.String(), err
+}
+
+func decodeIds(s string) ([]PK, error) {
+ pks := make([]PK, 0)
+
+ dec := gob.NewDecoder(strings.NewReader(s))
+ err := dec.Decode(&pks)
+
+ return pks, err
+}
+
+func GetCacheSql(m Cacher, tableName, sql string, args interface{}) ([]PK, error) {
+ bytes := m.GetIds(tableName, GenSqlKey(sql, args))
+ if bytes == nil {
+ return nil, errors.New("Not Exist")
+ }
+ return decodeIds(bytes.(string))
+}
+
+func PutCacheSql(m Cacher, ids []PK, tableName, sql string, args interface{}) error {
+ bytes, err := encodeIds(ids)
+ if err != nil {
+ return err
+ }
+ m.PutIds(tableName, GenSqlKey(sql, args), bytes)
+ return nil
+}
+
+func GenSqlKey(sql string, args interface{}) string {
+ return fmt.Sprintf("%v-%v", sql, args)
+}
diff --git a/vendor/xorm.io/core/column.go b/vendor/xorm.io/core/column.go
new file mode 100644
index 0000000000..40d8f9268d
--- /dev/null
+++ b/vendor/xorm.io/core/column.go
@@ -0,0 +1,166 @@
+// Copyright 2019 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 core
+
+import (
+ "fmt"
+ "reflect"
+ "strings"
+ "time"
+)
+
+const (
+ TWOSIDES = iota + 1
+ ONLYTODB
+ ONLYFROMDB
+)
+
+// Column defines database column
+type Column struct {
+ Name string
+ TableName string
+ FieldName string
+ SQLType SQLType
+ IsJSON bool
+ Length int
+ Length2 int
+ Nullable bool
+ Default string
+ Indexes map[string]int
+ IsPrimaryKey bool
+ IsAutoIncrement bool
+ MapType int
+ IsCreated bool
+ IsUpdated bool
+ IsDeleted bool
+ IsCascade bool
+ IsVersion bool
+ DefaultIsEmpty bool
+ EnumOptions map[string]int
+ SetOptions map[string]int
+ DisableTimeZone bool
+ TimeZone *time.Location // column specified time zone
+ Comment string
+}
+
+// NewColumn creates a new column
+func NewColumn(name, fieldName string, sqlType SQLType, len1, len2 int, nullable bool) *Column {
+ return &Column{
+ Name: name,
+ TableName: "",
+ FieldName: fieldName,
+ SQLType: sqlType,
+ Length: len1,
+ Length2: len2,
+ Nullable: nullable,
+ Default: "",
+ Indexes: make(map[string]int),
+ IsPrimaryKey: false,
+ IsAutoIncrement: false,
+ MapType: TWOSIDES,
+ IsCreated: false,
+ IsUpdated: false,
+ IsDeleted: false,
+ IsCascade: false,
+ IsVersion: false,
+ DefaultIsEmpty: false,
+ EnumOptions: make(map[string]int),
+ Comment: "",
+ }
+}
+
+// String generate column description string according dialect
+func (col *Column) String(d Dialect) string {
+ sql := d.QuoteStr() + col.Name + d.QuoteStr() + " "
+
+ sql += d.SqlType(col) + " "
+
+ if col.IsPrimaryKey {
+ sql += "PRIMARY KEY "
+ if col.IsAutoIncrement {
+ sql += d.AutoIncrStr() + " "
+ }
+ }
+
+ if col.Default != "" {
+ sql += "DEFAULT " + col.Default + " "
+ }
+
+ if d.ShowCreateNull() {
+ if col.Nullable {
+ sql += "NULL "
+ } else {
+ sql += "NOT NULL "
+ }
+ }
+
+ return sql
+}
+
+// StringNoPk generate column description string according dialect without primary keys
+func (col *Column) StringNoPk(d Dialect) string {
+ sql := d.QuoteStr() + col.Name + d.QuoteStr() + " "
+
+ sql += d.SqlType(col) + " "
+
+ if col.Default != "" {
+ sql += "DEFAULT " + col.Default + " "
+ }
+
+ if d.ShowCreateNull() {
+ if col.Nullable {
+ sql += "NULL "
+ } else {
+ sql += "NOT NULL "
+ }
+ }
+
+ return sql
+}
+
+// ValueOf returns column's filed of struct's value
+func (col *Column) ValueOf(bean interface{}) (*reflect.Value, error) {
+ dataStruct := reflect.Indirect(reflect.ValueOf(bean))
+ return col.ValueOfV(&dataStruct)
+}
+
+// ValueOfV returns column's filed of struct's value accept reflevt value
+func (col *Column) ValueOfV(dataStruct *reflect.Value) (*reflect.Value, error) {
+ var fieldValue reflect.Value
+ fieldPath := strings.Split(col.FieldName, ".")
+
+ if dataStruct.Type().Kind() == reflect.Map {
+ keyValue := reflect.ValueOf(fieldPath[len(fieldPath)-1])
+ fieldValue = dataStruct.MapIndex(keyValue)
+ return &fieldValue, nil
+ } else if dataStruct.Type().Kind() == reflect.Interface {
+ structValue := reflect.ValueOf(dataStruct.Interface())
+ dataStruct = &structValue
+ }
+
+ level := len(fieldPath)
+ fieldValue = dataStruct.FieldByName(fieldPath[0])
+ for i := 0; i < level-1; i++ {
+ if !fieldValue.IsValid() {
+ break
+ }
+ if fieldValue.Kind() == reflect.Struct {
+ fieldValue = fieldValue.FieldByName(fieldPath[i+1])
+ } else if fieldValue.Kind() == reflect.Ptr {
+ if fieldValue.IsNil() {
+ fieldValue.Set(reflect.New(fieldValue.Type().Elem()))
+ }
+ fieldValue = fieldValue.Elem().FieldByName(fieldPath[i+1])
+ } else {
+ return nil, fmt.Errorf("field %v is not valid", col.FieldName)
+ }
+ }
+
+ if !fieldValue.IsValid() {
+ return nil, fmt.Errorf("field %v is not valid", col.FieldName)
+ }
+
+ return &fieldValue, nil
+}
diff --git a/vendor/xorm.io/core/converstion.go b/vendor/xorm.io/core/converstion.go
new file mode 100644
index 0000000000..9703c36e08
--- /dev/null
+++ b/vendor/xorm.io/core/converstion.go
@@ -0,0 +1,12 @@
+// Copyright 2019 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 core
+
+// Conversion is an interface. A type implements Conversion will according
+// the custom method to fill into database and retrieve from database.
+type Conversion interface {
+ FromDB([]byte) error
+ ToDB() ([]byte, error)
+}
diff --git a/vendor/xorm.io/core/db.go b/vendor/xorm.io/core/db.go
new file mode 100644
index 0000000000..3e50a14795
--- /dev/null
+++ b/vendor/xorm.io/core/db.go
@@ -0,0 +1,223 @@
+// Copyright 2019 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 core
+
+import (
+ "context"
+ "database/sql"
+ "database/sql/driver"
+ "fmt"
+ "reflect"
+ "regexp"
+ "sync"
+)
+
+var (
+ DefaultCacheSize = 200
+)
+
+func MapToSlice(query string, mp interface{}) (string, []interface{}, error) {
+ vv := reflect.ValueOf(mp)
+ if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Map {
+ return "", []interface{}{}, ErrNoMapPointer
+ }
+
+ args := make([]interface{}, 0, len(vv.Elem().MapKeys()))
+ var err error
+ query = re.ReplaceAllStringFunc(query, func(src string) string {
+ v := vv.Elem().MapIndex(reflect.ValueOf(src[1:]))
+ if !v.IsValid() {
+ err = fmt.Errorf("map key %s is missing", src[1:])
+ } else {
+ args = append(args, v.Interface())
+ }
+ return "?"
+ })
+
+ return query, args, err
+}
+
+func StructToSlice(query string, st interface{}) (string, []interface{}, error) {
+ vv := reflect.ValueOf(st)
+ if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct {
+ return "", []interface{}{}, ErrNoStructPointer
+ }
+
+ args := make([]interface{}, 0)
+ var err error
+ query = re.ReplaceAllStringFunc(query, func(src string) string {
+ fv := vv.Elem().FieldByName(src[1:]).Interface()
+ if v, ok := fv.(driver.Valuer); ok {
+ var value driver.Value
+ value, err = v.Value()
+ if err != nil {
+ return "?"
+ }
+ args = append(args, value)
+ } else {
+ args = append(args, fv)
+ }
+ return "?"
+ })
+ if err != nil {
+ return "", []interface{}{}, err
+ }
+ return query, args, nil
+}
+
+type cacheStruct struct {
+ value reflect.Value
+ idx int
+}
+
+// DB is a wrap of sql.DB with extra contents
+type DB struct {
+ *sql.DB
+ Mapper IMapper
+ reflectCache map[reflect.Type]*cacheStruct
+ reflectCacheMutex sync.RWMutex
+}
+
+// Open opens a database
+func Open(driverName, dataSourceName string) (*DB, error) {
+ db, err := sql.Open(driverName, dataSourceName)
+ if err != nil {
+ return nil, err
+ }
+ return &DB{
+ DB: db,
+ Mapper: NewCacheMapper(&SnakeMapper{}),
+ reflectCache: make(map[reflect.Type]*cacheStruct),
+ }, nil
+}
+
+// FromDB creates a DB from a sql.DB
+func FromDB(db *sql.DB) *DB {
+ return &DB{
+ DB: db,
+ Mapper: NewCacheMapper(&SnakeMapper{}),
+ reflectCache: make(map[reflect.Type]*cacheStruct),
+ }
+}
+
+func (db *DB) reflectNew(typ reflect.Type) reflect.Value {
+ db.reflectCacheMutex.Lock()
+ defer db.reflectCacheMutex.Unlock()
+ cs, ok := db.reflectCache[typ]
+ if !ok || cs.idx+1 > DefaultCacheSize-1 {
+ cs = &cacheStruct{reflect.MakeSlice(reflect.SliceOf(typ), DefaultCacheSize, DefaultCacheSize), 0}
+ db.reflectCache[typ] = cs
+ } else {
+ cs.idx = cs.idx + 1
+ }
+ return cs.value.Index(cs.idx).Addr()
+}
+
+// QueryContext overwrites sql.DB.QueryContext
+func (db *DB) QueryContext(ctx context.Context, query string, args ...interface{}) (*Rows, error) {
+ rows, err := db.DB.QueryContext(ctx, query, args...)
+ if err != nil {
+ if rows != nil {
+ rows.Close()
+ }
+ return nil, err
+ }
+ return &Rows{rows, db}, nil
+}
+
+// Query overwrites sql.DB.Query
+func (db *DB) Query(query string, args ...interface{}) (*Rows, error) {
+ return db.QueryContext(context.Background(), query, args...)
+}
+
+func (db *DB) QueryMapContext(ctx context.Context, query string, mp interface{}) (*Rows, error) {
+ query, args, err := MapToSlice(query, mp)
+ if err != nil {
+ return nil, err
+ }
+ return db.QueryContext(ctx, query, args...)
+}
+
+func (db *DB) QueryMap(query string, mp interface{}) (*Rows, error) {
+ return db.QueryMapContext(context.Background(), query, mp)
+}
+
+func (db *DB) QueryStructContext(ctx context.Context, query string, st interface{}) (*Rows, error) {
+ query, args, err := StructToSlice(query, st)
+ if err != nil {
+ return nil, err
+ }
+ return db.QueryContext(ctx, query, args...)
+}
+
+func (db *DB) QueryStruct(query string, st interface{}) (*Rows, error) {
+ return db.QueryStructContext(context.Background(), query, st)
+}
+
+func (db *DB) QueryRowContext(ctx context.Context, query string, args ...interface{}) *Row {
+ rows, err := db.QueryContext(ctx, query, args...)
+ if err != nil {
+ return &Row{nil, err}
+ }
+ return &Row{rows, nil}
+}
+
+func (db *DB) QueryRow(query string, args ...interface{}) *Row {
+ return db.QueryRowContext(context.Background(), query, args...)
+}
+
+func (db *DB) QueryRowMapContext(ctx context.Context, query string, mp interface{}) *Row {
+ query, args, err := MapToSlice(query, mp)
+ if err != nil {
+ return &Row{nil, err}
+ }
+ return db.QueryRowContext(ctx, query, args...)
+}
+
+func (db *DB) QueryRowMap(query string, mp interface{}) *Row {
+ return db.QueryRowMapContext(context.Background(), query, mp)
+}
+
+func (db *DB) QueryRowStructContext(ctx context.Context, query string, st interface{}) *Row {
+ query, args, err := StructToSlice(query, st)
+ if err != nil {
+ return &Row{nil, err}
+ }
+ return db.QueryRowContext(ctx, query, args...)
+}
+
+func (db *DB) QueryRowStruct(query string, st interface{}) *Row {
+ return db.QueryRowStructContext(context.Background(), query, st)
+}
+
+var (
+ re = regexp.MustCompile(`[?](\w+)`)
+)
+
+// insert into (name) values (?)
+// insert into (name) values (?name)
+func (db *DB) ExecMapContext(ctx context.Context, query string, mp interface{}) (sql.Result, error) {
+ query, args, err := MapToSlice(query, mp)
+ if err != nil {
+ return nil, err
+ }
+ return db.DB.ExecContext(ctx, query, args...)
+}
+
+func (db *DB) ExecMap(query string, mp interface{}) (sql.Result, error) {
+ return db.ExecMapContext(context.Background(), query, mp)
+}
+
+func (db *DB) ExecStructContext(ctx context.Context, query string, st interface{}) (sql.Result, error) {
+ query, args, err := StructToSlice(query, st)
+ if err != nil {
+ return nil, err
+ }
+ return db.DB.ExecContext(ctx, query, args...)
+}
+
+func (db *DB) ExecStruct(query string, st interface{}) (sql.Result, error) {
+ return db.ExecStructContext(context.Background(), query, st)
+}
diff --git a/vendor/xorm.io/core/dialect.go b/vendor/xorm.io/core/dialect.go
new file mode 100644
index 0000000000..5d35a4f11d
--- /dev/null
+++ b/vendor/xorm.io/core/dialect.go
@@ -0,0 +1,319 @@
+// Copyright 2019 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 core
+
+import (
+ "fmt"
+ "strings"
+ "time"
+)
+
+type DbType string
+
+type Uri struct {
+ DbType DbType
+ Proto string
+ Host string
+ Port string
+ DbName string
+ User string
+ Passwd string
+ Charset string
+ Laddr string
+ Raddr string
+ Timeout time.Duration
+ Schema string
+}
+
+// a dialect is a driver's wrapper
+type Dialect interface {
+ SetLogger(logger ILogger)
+ Init(*DB, *Uri, string, string) error
+ URI() *Uri
+ DB() *DB
+ DBType() DbType
+ SqlType(*Column) string
+ FormatBytes(b []byte) string
+
+ DriverName() string
+ DataSourceName() string
+
+ QuoteStr() string
+ IsReserved(string) bool
+ Quote(string) string
+ AndStr() string
+ OrStr() string
+ EqStr() string
+ RollBackStr() string
+ AutoIncrStr() string
+
+ SupportInsertMany() bool
+ SupportEngine() bool
+ SupportCharset() bool
+ SupportDropIfExists() bool
+ IndexOnTable() bool
+ ShowCreateNull() bool
+
+ IndexCheckSql(tableName, idxName string) (string, []interface{})
+ TableCheckSql(tableName string) (string, []interface{})
+
+ IsColumnExist(tableName string, colName string) (bool, error)
+
+ CreateTableSql(table *Table, tableName, storeEngine, charset string) string
+ DropTableSql(tableName string) string
+ CreateIndexSql(tableName string, index *Index) string
+ DropIndexSql(tableName string, index *Index) string
+
+ ModifyColumnSql(tableName string, col *Column) string
+
+ ForUpdateSql(query string) string
+
+ //CreateTableIfNotExists(table *Table, tableName, storeEngine, charset string) error
+ //MustDropTable(tableName string) error
+
+ GetColumns(tableName string) ([]string, map[string]*Column, error)
+ GetTables() ([]*Table, error)
+ GetIndexes(tableName string) (map[string]*Index, error)
+
+ Filters() []Filter
+ SetParams(params map[string]string)
+}
+
+func OpenDialect(dialect Dialect) (*DB, error) {
+ return Open(dialect.DriverName(), dialect.DataSourceName())
+}
+
+type Base struct {
+ db *DB
+ dialect Dialect
+ driverName string
+ dataSourceName string
+ logger ILogger
+ *Uri
+}
+
+func (b *Base) DB() *DB {
+ return b.db
+}
+
+func (b *Base) SetLogger(logger ILogger) {
+ b.logger = logger
+}
+
+func (b *Base) Init(db *DB, dialect Dialect, uri *Uri, drivername, dataSourceName string) error {
+ b.db, b.dialect, b.Uri = db, dialect, uri
+ b.driverName, b.dataSourceName = drivername, dataSourceName
+ return nil
+}
+
+func (b *Base) URI() *Uri {
+ return b.Uri
+}
+
+func (b *Base) DBType() DbType {
+ return b.Uri.DbType
+}
+
+func (b *Base) FormatBytes(bs []byte) string {
+ return fmt.Sprintf("0x%x", bs)
+}
+
+func (b *Base) DriverName() string {
+ return b.driverName
+}
+
+func (b *Base) ShowCreateNull() bool {
+ return true
+}
+
+func (b *Base) DataSourceName() string {
+ return b.dataSourceName
+}
+
+func (b *Base) AndStr() string {
+ return "AND"
+}
+
+func (b *Base) OrStr() string {
+ return "OR"
+}
+
+func (b *Base) EqStr() string {
+ return "="
+}
+
+func (db *Base) RollBackStr() string {
+ return "ROLL BACK"
+}
+
+func (db *Base) SupportDropIfExists() bool {
+ return true
+}
+
+func (db *Base) DropTableSql(tableName string) string {
+ quote := db.dialect.Quote
+ return fmt.Sprintf("DROP TABLE IF EXISTS %s", quote(tableName))
+}
+
+func (db *Base) HasRecords(query string, args ...interface{}) (bool, error) {
+ db.LogSQL(query, args)
+ rows, err := db.DB().Query(query, args...)
+ if err != nil {
+ return false, err
+ }
+ defer rows.Close()
+
+ if rows.Next() {
+ return true, nil
+ }
+ return false, nil
+}
+
+func (db *Base) IsColumnExist(tableName, colName string) (bool, error) {
+ query := "SELECT `COLUMN_NAME` FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_SCHEMA` = ? AND `TABLE_NAME` = ? AND `COLUMN_NAME` = ?"
+ query = strings.Replace(query, "`", db.dialect.QuoteStr(), -1)
+ return db.HasRecords(query, db.DbName, tableName, colName)
+}
+
+/*
+func (db *Base) CreateTableIfNotExists(table *Table, tableName, storeEngine, charset string) error {
+ sql, args := db.dialect.TableCheckSql(tableName)
+ rows, err := db.DB().Query(sql, args...)
+ if db.Logger != nil {
+ db.Logger.Info("[sql]", sql, args)
+ }
+ if err != nil {
+ return err
+ }
+ defer rows.Close()
+
+ if rows.Next() {
+ return nil
+ }
+
+ sql = db.dialect.CreateTableSql(table, tableName, storeEngine, charset)
+ _, err = db.DB().Exec(sql)
+ if db.Logger != nil {
+ db.Logger.Info("[sql]", sql)
+ }
+ return err
+}*/
+
+func (db *Base) CreateIndexSql(tableName string, index *Index) string {
+ quote := db.dialect.Quote
+ var unique string
+ var idxName string
+ if index.Type == UniqueType {
+ unique = " UNIQUE"
+ }
+ idxName = index.XName(tableName)
+ return fmt.Sprintf("CREATE%s INDEX %v ON %v (%v)", unique,
+ quote(idxName), quote(tableName),
+ quote(strings.Join(index.Cols, quote(","))))
+}
+
+func (db *Base) DropIndexSql(tableName string, index *Index) string {
+ quote := db.dialect.Quote
+ var name string
+ if index.IsRegular {
+ name = index.XName(tableName)
+ } else {
+ name = index.Name
+ }
+ return fmt.Sprintf("DROP INDEX %v ON %s", quote(name), quote(tableName))
+}
+
+func (db *Base) ModifyColumnSql(tableName string, col *Column) string {
+ return fmt.Sprintf("alter table %s MODIFY COLUMN %s", tableName, col.StringNoPk(db.dialect))
+}
+
+func (b *Base) CreateTableSql(table *Table, tableName, storeEngine, charset string) string {
+ var sql string
+ sql = "CREATE TABLE IF NOT EXISTS "
+ if tableName == "" {
+ tableName = table.Name
+ }
+
+ sql += b.dialect.Quote(tableName)
+ sql += " ("
+
+ if len(table.ColumnsSeq()) > 0 {
+ pkList := table.PrimaryKeys
+
+ for _, colName := range table.ColumnsSeq() {
+ col := table.GetColumn(colName)
+ if col.IsPrimaryKey && len(pkList) == 1 {
+ sql += col.String(b.dialect)
+ } else {
+ sql += col.StringNoPk(b.dialect)
+ }
+ sql = strings.TrimSpace(sql)
+ if b.DriverName() == MYSQL && len(col.Comment) > 0 {
+ sql += " COMMENT '" + col.Comment + "'"
+ }
+ sql += ", "
+ }
+
+ if len(pkList) > 1 {
+ sql += "PRIMARY KEY ( "
+ sql += b.dialect.Quote(strings.Join(pkList, b.dialect.Quote(",")))
+ sql += " ), "
+ }
+
+ sql = sql[:len(sql)-2]
+ }
+ sql += ")"
+
+ if b.dialect.SupportEngine() && storeEngine != "" {
+ sql += " ENGINE=" + storeEngine
+ }
+ if b.dialect.SupportCharset() {
+ if len(charset) == 0 {
+ charset = b.dialect.URI().Charset
+ }
+ if len(charset) > 0 {
+ sql += " DEFAULT CHARSET " + charset
+ }
+ }
+
+ return sql
+}
+
+func (b *Base) ForUpdateSql(query string) string {
+ return query + " FOR UPDATE"
+}
+
+func (b *Base) LogSQL(sql string, args []interface{}) {
+ if b.logger != nil && b.logger.IsShowSQL() {
+ if len(args) > 0 {
+ b.logger.Infof("[SQL] %v %v", sql, args)
+ } else {
+ b.logger.Infof("[SQL] %v", sql)
+ }
+ }
+}
+
+func (b *Base) SetParams(params map[string]string) {
+}
+
+var (
+ dialects = map[string]func() Dialect{}
+)
+
+// RegisterDialect register database dialect
+func RegisterDialect(dbName DbType, dialectFunc func() Dialect) {
+ if dialectFunc == nil {
+ panic("core: Register dialect is nil")
+ }
+ dialects[strings.ToLower(string(dbName))] = dialectFunc // !nashtsai! allow override dialect
+}
+
+// QueryDialect query if registed database dialect
+func QueryDialect(dbName DbType) Dialect {
+ if d, ok := dialects[strings.ToLower(string(dbName))]; ok {
+ return d()
+ }
+ return nil
+}
diff --git a/vendor/xorm.io/core/driver.go b/vendor/xorm.io/core/driver.go
new file mode 100644
index 0000000000..ceef4ba618
--- /dev/null
+++ b/vendor/xorm.io/core/driver.go
@@ -0,0 +1,31 @@
+// Copyright 2019 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 core
+
+type Driver interface {
+ Parse(string, string) (*Uri, error)
+}
+
+var (
+ drivers = map[string]Driver{}
+)
+
+func RegisterDriver(driverName string, driver Driver) {
+ if driver == nil {
+ panic("core: Register driver is nil")
+ }
+ if _, dup := drivers[driverName]; dup {
+ panic("core: Register called twice for driver " + driverName)
+ }
+ drivers[driverName] = driver
+}
+
+func QueryDriver(driverName string) Driver {
+ return drivers[driverName]
+}
+
+func RegisteredDriverSize() int {
+ return len(drivers)
+}
diff --git a/vendor/xorm.io/core/error.go b/vendor/xorm.io/core/error.go
new file mode 100644
index 0000000000..63ea53e466
--- /dev/null
+++ b/vendor/xorm.io/core/error.go
@@ -0,0 +1,12 @@
+// Copyright 2019 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 core
+
+import "errors"
+
+var (
+ ErrNoMapPointer = errors.New("mp should be a map's pointer")
+ ErrNoStructPointer = errors.New("mp should be a struct's pointer")
+)
diff --git a/vendor/xorm.io/core/filter.go b/vendor/xorm.io/core/filter.go
new file mode 100644
index 0000000000..6aeed4244c
--- /dev/null
+++ b/vendor/xorm.io/core/filter.go
@@ -0,0 +1,68 @@
+// Copyright 2019 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 core
+
+import (
+ "fmt"
+ "strings"
+)
+
+// Filter is an interface to filter SQL
+type Filter interface {
+ Do(sql string, dialect Dialect, table *Table) string
+}
+
+// QuoteFilter filter SQL replace ` to database's own quote character
+type QuoteFilter struct {
+}
+
+func (s *QuoteFilter) Do(sql string, dialect Dialect, table *Table) string {
+ return strings.Replace(sql, "`", dialect.QuoteStr(), -1)
+}
+
+// IdFilter filter SQL replace (id) to primary key column name
+type IdFilter struct {
+}
+
+type Quoter struct {
+ dialect Dialect
+}
+
+func NewQuoter(dialect Dialect) *Quoter {
+ return &Quoter{dialect}
+}
+
+func (q *Quoter) Quote(content string) string {
+ return q.dialect.QuoteStr() + content + q.dialect.QuoteStr()
+}
+
+func (i *IdFilter) Do(sql string, dialect Dialect, table *Table) string {
+ quoter := NewQuoter(dialect)
+ if table != nil && len(table.PrimaryKeys) == 1 {
+ sql = strings.Replace(sql, " `(id)` ", " "+quoter.Quote(table.PrimaryKeys[0])+" ", -1)
+ sql = strings.Replace(sql, " "+quoter.Quote("(id)")+" ", " "+quoter.Quote(table.PrimaryKeys[0])+" ", -1)
+ return strings.Replace(sql, " (id) ", " "+quoter.Quote(table.PrimaryKeys[0])+" ", -1)
+ }
+ return sql
+}
+
+// SeqFilter filter SQL replace ?, ? ... to $1, $2 ...
+type SeqFilter struct {
+ Prefix string
+ Start int
+}
+
+func (s *SeqFilter) Do(sql string, dialect Dialect, table *Table) string {
+ segs := strings.Split(sql, "?")
+ size := len(segs)
+ res := ""
+ for i, c := range segs {
+ if i < size-1 {
+ res += c + fmt.Sprintf("%s%v", s.Prefix, i+s.Start)
+ }
+ }
+ res += segs[size-1]
+ return res
+}
diff --git a/vendor/xorm.io/core/go.mod b/vendor/xorm.io/core/go.mod
new file mode 100644
index 0000000000..2703545e69
--- /dev/null
+++ b/vendor/xorm.io/core/go.mod
@@ -0,0 +1,7 @@
+module xorm.io/core
+
+require (
+ github.com/go-sql-driver/mysql v1.4.1
+ github.com/mattn/go-sqlite3 v1.10.0
+ google.golang.org/appengine v1.4.0 // indirect
+)
diff --git a/vendor/xorm.io/core/go.sum b/vendor/xorm.io/core/go.sum
new file mode 100644
index 0000000000..8f20f8bc90
--- /dev/null
+++ b/vendor/xorm.io/core/go.sum
@@ -0,0 +1,9 @@
+github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
+github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o=
+github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
+golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
+google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
diff --git a/vendor/xorm.io/core/ilogger.go b/vendor/xorm.io/core/ilogger.go
new file mode 100644
index 0000000000..348ab88f4f
--- /dev/null
+++ b/vendor/xorm.io/core/ilogger.go
@@ -0,0 +1,35 @@
+// Copyright 2019 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 core
+
+type LogLevel int
+
+const (
+ // !nashtsai! following level also match syslog.Priority value
+ LOG_DEBUG LogLevel = iota
+ LOG_INFO
+ LOG_WARNING
+ LOG_ERR
+ LOG_OFF
+ LOG_UNKNOWN
+)
+
+// logger interface
+type ILogger interface {
+ Debug(v ...interface{})
+ Debugf(format string, v ...interface{})
+ Error(v ...interface{})
+ Errorf(format string, v ...interface{})
+ Info(v ...interface{})
+ Infof(format string, v ...interface{})
+ Warn(v ...interface{})
+ Warnf(format string, v ...interface{})
+
+ Level() LogLevel
+ SetLevel(l LogLevel)
+
+ ShowSQL(show ...bool)
+ IsShowSQL() bool
+}
diff --git a/vendor/xorm.io/core/index.go b/vendor/xorm.io/core/index.go
new file mode 100644
index 0000000000..ac97b68505
--- /dev/null
+++ b/vendor/xorm.io/core/index.go
@@ -0,0 +1,71 @@
+// Copyright 2019 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 core
+
+import (
+ "fmt"
+ "strings"
+)
+
+const (
+ IndexType = iota + 1
+ UniqueType
+)
+
+// database index
+type Index struct {
+ IsRegular bool
+ Name string
+ Type int
+ Cols []string
+}
+
+func (index *Index) XName(tableName string) string {
+ if !strings.HasPrefix(index.Name, "UQE_") &&
+ !strings.HasPrefix(index.Name, "IDX_") {
+ tableName = strings.Replace(tableName, `"`, "", -1)
+ tableName = strings.Replace(tableName, `.`, "_", -1)
+ if index.Type == UniqueType {
+ return fmt.Sprintf("UQE_%v_%v", tableName, index.Name)
+ }
+ return fmt.Sprintf("IDX_%v_%v", tableName, index.Name)
+ }
+ return index.Name
+}
+
+// add columns which will be composite index
+func (index *Index) AddColumn(cols ...string) {
+ for _, col := range cols {
+ index.Cols = append(index.Cols, col)
+ }
+}
+
+func (index *Index) Equal(dst *Index) bool {
+ if index.Type != dst.Type {
+ return false
+ }
+ if len(index.Cols) != len(dst.Cols) {
+ return false
+ }
+
+ for i := 0; i < len(index.Cols); i++ {
+ var found bool
+ for j := 0; j < len(dst.Cols); j++ {
+ if index.Cols[i] == dst.Cols[j] {
+ found = true
+ break
+ }
+ }
+ if !found {
+ return false
+ }
+ }
+ return true
+}
+
+// new an index
+func NewIndex(name string, indexType int) *Index {
+ return &Index{true, name, indexType, make([]string, 0)}
+}
diff --git a/vendor/xorm.io/core/mapper.go b/vendor/xorm.io/core/mapper.go
new file mode 100644
index 0000000000..ec44ea0db9
--- /dev/null
+++ b/vendor/xorm.io/core/mapper.go
@@ -0,0 +1,258 @@
+// Copyright 2019 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 core
+
+import (
+ "strings"
+ "sync"
+)
+
+// name translation between struct, fields names and table, column names
+type IMapper interface {
+ Obj2Table(string) string
+ Table2Obj(string) string
+}
+
+type CacheMapper struct {
+ oriMapper IMapper
+ obj2tableCache map[string]string
+ obj2tableMutex sync.RWMutex
+ table2objCache map[string]string
+ table2objMutex sync.RWMutex
+}
+
+func NewCacheMapper(mapper IMapper) *CacheMapper {
+ return &CacheMapper{oriMapper: mapper, obj2tableCache: make(map[string]string),
+ table2objCache: make(map[string]string),
+ }
+}
+
+func (m *CacheMapper) Obj2Table(o string) string {
+ m.obj2tableMutex.RLock()
+ t, ok := m.obj2tableCache[o]
+ m.obj2tableMutex.RUnlock()
+ if ok {
+ return t
+ }
+
+ t = m.oriMapper.Obj2Table(o)
+ m.obj2tableMutex.Lock()
+ m.obj2tableCache[o] = t
+ m.obj2tableMutex.Unlock()
+ return t
+}
+
+func (m *CacheMapper) Table2Obj(t string) string {
+ m.table2objMutex.RLock()
+ o, ok := m.table2objCache[t]
+ m.table2objMutex.RUnlock()
+ if ok {
+ return o
+ }
+
+ o = m.oriMapper.Table2Obj(t)
+ m.table2objMutex.Lock()
+ m.table2objCache[t] = o
+ m.table2objMutex.Unlock()
+ return o
+}
+
+// SameMapper implements IMapper and provides same name between struct and
+// database table
+type SameMapper struct {
+}
+
+func (m SameMapper) Obj2Table(o string) string {
+ return o
+}
+
+func (m SameMapper) Table2Obj(t string) string {
+ return t
+}
+
+// SnakeMapper implements IMapper and provides name transaltion between
+// struct and database table
+type SnakeMapper struct {
+}
+
+func snakeCasedName(name string) string {
+ newstr := make([]rune, 0)
+ for idx, chr := range name {
+ if isUpper := 'A' <= chr && chr <= 'Z'; isUpper {
+ if idx > 0 {
+ newstr = append(newstr, '_')
+ }
+ chr -= ('A' - 'a')
+ }
+ newstr = append(newstr, chr)
+ }
+
+ return string(newstr)
+}
+
+func (mapper SnakeMapper) Obj2Table(name string) string {
+ return snakeCasedName(name)
+}
+
+func titleCasedName(name string) string {
+ newstr := make([]rune, 0)
+ upNextChar := true
+
+ name = strings.ToLower(name)
+
+ for _, chr := range name {
+ switch {
+ case upNextChar:
+ upNextChar = false
+ if 'a' <= chr && chr <= 'z' {
+ chr -= ('a' - 'A')
+ }
+ case chr == '_':
+ upNextChar = true
+ continue
+ }
+
+ newstr = append(newstr, chr)
+ }
+
+ return string(newstr)
+}
+
+func (mapper SnakeMapper) Table2Obj(name string) string {
+ return titleCasedName(name)
+}
+
+// GonicMapper implements IMapper. It will consider initialisms when mapping names.
+// E.g. id -> ID, user -> User and to table names: UserID -> user_id, MyUID -> my_uid
+type GonicMapper map[string]bool
+
+func isASCIIUpper(r rune) bool {
+ return 'A' <= r && r <= 'Z'
+}
+
+func toASCIIUpper(r rune) rune {
+ if 'a' <= r && r <= 'z' {
+ r -= ('a' - 'A')
+ }
+ return r
+}
+
+func gonicCasedName(name string) string {
+ newstr := make([]rune, 0, len(name)+3)
+ for idx, chr := range name {
+ if isASCIIUpper(chr) && idx > 0 {
+ if !isASCIIUpper(newstr[len(newstr)-1]) {
+ newstr = append(newstr, '_')
+ }
+ }
+
+ if !isASCIIUpper(chr) && idx > 1 {
+ l := len(newstr)
+ if isASCIIUpper(newstr[l-1]) && isASCIIUpper(newstr[l-2]) {
+ newstr = append(newstr, newstr[l-1])
+ newstr[l-1] = '_'
+ }
+ }
+
+ newstr = append(newstr, chr)
+ }
+ return strings.ToLower(string(newstr))
+}
+
+func (mapper GonicMapper) Obj2Table(name string) string {
+ return gonicCasedName(name)
+}
+
+func (mapper GonicMapper) Table2Obj(name string) string {
+ newstr := make([]rune, 0)
+
+ name = strings.ToLower(name)
+ parts := strings.Split(name, "_")
+
+ for _, p := range parts {
+ _, isInitialism := mapper[strings.ToUpper(p)]
+ for i, r := range p {
+ if i == 0 || isInitialism {
+ r = toASCIIUpper(r)
+ }
+ newstr = append(newstr, r)
+ }
+ }
+
+ return string(newstr)
+}
+
+// A GonicMapper that contains a list of common initialisms taken from golang/lint
+var LintGonicMapper = GonicMapper{
+ "API": true,
+ "ASCII": true,
+ "CPU": true,
+ "CSS": true,
+ "DNS": true,
+ "EOF": true,
+ "GUID": true,
+ "HTML": true,
+ "HTTP": true,
+ "HTTPS": true,
+ "ID": true,
+ "IP": true,
+ "JSON": true,
+ "LHS": true,
+ "QPS": true,
+ "RAM": true,
+ "RHS": true,
+ "RPC": true,
+ "SLA": true,
+ "SMTP": true,
+ "SSH": true,
+ "TLS": true,
+ "TTL": true,
+ "UI": true,
+ "UID": true,
+ "UUID": true,
+ "URI": true,
+ "URL": true,
+ "UTF8": true,
+ "VM": true,
+ "XML": true,
+ "XSRF": true,
+ "XSS": true,
+}
+
+// provide prefix table name support
+type PrefixMapper struct {
+ Mapper IMapper
+ Prefix string
+}
+
+func (mapper PrefixMapper) Obj2Table(name string) string {
+ return mapper.Prefix + mapper.Mapper.Obj2Table(name)
+}
+
+func (mapper PrefixMapper) Table2Obj(name string) string {
+ return mapper.Mapper.Table2Obj(name[len(mapper.Prefix):])
+}
+
+func NewPrefixMapper(mapper IMapper, prefix string) PrefixMapper {
+ return PrefixMapper{mapper, prefix}
+}
+
+// provide suffix table name support
+type SuffixMapper struct {
+ Mapper IMapper
+ Suffix string
+}
+
+func (mapper SuffixMapper) Obj2Table(name string) string {
+ return mapper.Mapper.Obj2Table(name) + mapper.Suffix
+}
+
+func (mapper SuffixMapper) Table2Obj(name string) string {
+ return mapper.Mapper.Table2Obj(name[:len(name)-len(mapper.Suffix)])
+}
+
+func NewSuffixMapper(mapper IMapper, suffix string) SuffixMapper {
+ return SuffixMapper{mapper, suffix}
+}
diff --git a/vendor/xorm.io/core/pk.go b/vendor/xorm.io/core/pk.go
new file mode 100644
index 0000000000..05a7672d86
--- /dev/null
+++ b/vendor/xorm.io/core/pk.go
@@ -0,0 +1,30 @@
+// Copyright 2019 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 core
+
+import (
+ "bytes"
+ "encoding/gob"
+)
+
+type PK []interface{}
+
+func NewPK(pks ...interface{}) *PK {
+ p := PK(pks)
+ return &p
+}
+
+func (p *PK) ToString() (string, error) {
+ buf := new(bytes.Buffer)
+ enc := gob.NewEncoder(buf)
+ err := enc.Encode(*p)
+ return buf.String(), err
+}
+
+func (p *PK) FromString(content string) error {
+ dec := gob.NewDecoder(bytes.NewBufferString(content))
+ err := dec.Decode(p)
+ return err
+}
diff --git a/vendor/xorm.io/core/rows.go b/vendor/xorm.io/core/rows.go
new file mode 100644
index 0000000000..2b046d84cc
--- /dev/null
+++ b/vendor/xorm.io/core/rows.go
@@ -0,0 +1,338 @@
+// Copyright 2019 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 core
+
+import (
+ "database/sql"
+ "errors"
+ "reflect"
+ "sync"
+)
+
+type Rows struct {
+ *sql.Rows
+ db *DB
+}
+
+func (rs *Rows) ToMapString() ([]map[string]string, error) {
+ cols, err := rs.Columns()
+ if err != nil {
+ return nil, err
+ }
+
+ var results = make([]map[string]string, 0, 10)
+ for rs.Next() {
+ var record = make(map[string]string, len(cols))
+ err = rs.ScanMap(&record)
+ if err != nil {
+ return nil, err
+ }
+ results = append(results, record)
+ }
+ return results, nil
+}
+
+// scan data to a struct's pointer according field index
+func (rs *Rows) ScanStructByIndex(dest ...interface{}) error {
+ if len(dest) == 0 {
+ return errors.New("at least one struct")
+ }
+
+ vvvs := make([]reflect.Value, len(dest))
+ for i, s := range dest {
+ vv := reflect.ValueOf(s)
+ if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct {
+ return errors.New("dest should be a struct's pointer")
+ }
+
+ vvvs[i] = vv.Elem()
+ }
+
+ cols, err := rs.Columns()
+ if err != nil {
+ return err
+ }
+ newDest := make([]interface{}, len(cols))
+
+ var i = 0
+ for _, vvv := range vvvs {
+ for j := 0; j < vvv.NumField(); j++ {
+ newDest[i] = vvv.Field(j).Addr().Interface()
+ i = i + 1
+ }
+ }
+
+ return rs.Rows.Scan(newDest...)
+}
+
+var (
+ fieldCache = make(map[reflect.Type]map[string]int)
+ fieldCacheMutex sync.RWMutex
+)
+
+func fieldByName(v reflect.Value, name string) reflect.Value {
+ t := v.Type()
+ fieldCacheMutex.RLock()
+ cache, ok := fieldCache[t]
+ fieldCacheMutex.RUnlock()
+ if !ok {
+ cache = make(map[string]int)
+ for i := 0; i < v.NumField(); i++ {
+ cache[t.Field(i).Name] = i
+ }
+ fieldCacheMutex.Lock()
+ fieldCache[t] = cache
+ fieldCacheMutex.Unlock()
+ }
+
+ if i, ok := cache[name]; ok {
+ return v.Field(i)
+ }
+
+ return reflect.Zero(t)
+}
+
+// scan data to a struct's pointer according field name
+func (rs *Rows) ScanStructByName(dest interface{}) error {
+ vv := reflect.ValueOf(dest)
+ if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct {
+ return errors.New("dest should be a struct's pointer")
+ }
+
+ cols, err := rs.Columns()
+ if err != nil {
+ return err
+ }
+
+ newDest := make([]interface{}, len(cols))
+ var v EmptyScanner
+ for j, name := range cols {
+ f := fieldByName(vv.Elem(), rs.db.Mapper.Table2Obj(name))
+ if f.IsValid() {
+ newDest[j] = f.Addr().Interface()
+ } else {
+ newDest[j] = &v
+ }
+ }
+
+ return rs.Rows.Scan(newDest...)
+}
+
+// scan data to a slice's pointer, slice's length should equal to columns' number
+func (rs *Rows) ScanSlice(dest interface{}) error {
+ vv := reflect.ValueOf(dest)
+ if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Slice {
+ return errors.New("dest should be a slice's pointer")
+ }
+
+ vvv := vv.Elem()
+ cols, err := rs.Columns()
+ if err != nil {
+ return err
+ }
+
+ newDest := make([]interface{}, len(cols))
+
+ for j := 0; j < len(cols); j++ {
+ if j >= vvv.Len() {
+ newDest[j] = reflect.New(vvv.Type().Elem()).Interface()
+ } else {
+ newDest[j] = vvv.Index(j).Addr().Interface()
+ }
+ }
+
+ err = rs.Rows.Scan(newDest...)
+ if err != nil {
+ return err
+ }
+
+ srcLen := vvv.Len()
+ for i := srcLen; i < len(cols); i++ {
+ vvv = reflect.Append(vvv, reflect.ValueOf(newDest[i]).Elem())
+ }
+ return nil
+}
+
+// scan data to a map's pointer
+func (rs *Rows) ScanMap(dest interface{}) error {
+ vv := reflect.ValueOf(dest)
+ if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Map {
+ return errors.New("dest should be a map's pointer")
+ }
+
+ cols, err := rs.Columns()
+ if err != nil {
+ return err
+ }
+
+ newDest := make([]interface{}, len(cols))
+ vvv := vv.Elem()
+
+ for i, _ := range cols {
+ newDest[i] = rs.db.reflectNew(vvv.Type().Elem()).Interface()
+ }
+
+ err = rs.Rows.Scan(newDest...)
+ if err != nil {
+ return err
+ }
+
+ for i, name := range cols {
+ vname := reflect.ValueOf(name)
+ vvv.SetMapIndex(vname, reflect.ValueOf(newDest[i]).Elem())
+ }
+
+ return nil
+}
+
+type Row struct {
+ rows *Rows
+ // One of these two will be non-nil:
+ err error // deferred error for easy chaining
+}
+
+// ErrorRow return an error row
+func ErrorRow(err error) *Row {
+ return &Row{
+ err: err,
+ }
+}
+
+// NewRow from rows
+func NewRow(rows *Rows, err error) *Row {
+ return &Row{rows, err}
+}
+
+func (row *Row) Columns() ([]string, error) {
+ if row.err != nil {
+ return nil, row.err
+ }
+ return row.rows.Columns()
+}
+
+func (row *Row) Scan(dest ...interface{}) error {
+ if row.err != nil {
+ return row.err
+ }
+ defer row.rows.Close()
+
+ for _, dp := range dest {
+ if _, ok := dp.(*sql.RawBytes); ok {
+ return errors.New("sql: RawBytes isn't allowed on Row.Scan")
+ }
+ }
+
+ if !row.rows.Next() {
+ if err := row.rows.Err(); err != nil {
+ return err
+ }
+ return sql.ErrNoRows
+ }
+ err := row.rows.Scan(dest...)
+ if err != nil {
+ return err
+ }
+ // Make sure the query can be processed to completion with no errors.
+ return row.rows.Close()
+}
+
+func (row *Row) ScanStructByName(dest interface{}) error {
+ if row.err != nil {
+ return row.err
+ }
+ defer row.rows.Close()
+
+ if !row.rows.Next() {
+ if err := row.rows.Err(); err != nil {
+ return err
+ }
+ return sql.ErrNoRows
+ }
+ err := row.rows.ScanStructByName(dest)
+ if err != nil {
+ return err
+ }
+ // Make sure the query can be processed to completion with no errors.
+ return row.rows.Close()
+}
+
+func (row *Row) ScanStructByIndex(dest interface{}) error {
+ if row.err != nil {
+ return row.err
+ }
+ defer row.rows.Close()
+
+ if !row.rows.Next() {
+ if err := row.rows.Err(); err != nil {
+ return err
+ }
+ return sql.ErrNoRows
+ }
+ err := row.rows.ScanStructByIndex(dest)
+ if err != nil {
+ return err
+ }
+ // Make sure the query can be processed to completion with no errors.
+ return row.rows.Close()
+}
+
+// scan data to a slice's pointer, slice's length should equal to columns' number
+func (row *Row) ScanSlice(dest interface{}) error {
+ if row.err != nil {
+ return row.err
+ }
+ defer row.rows.Close()
+
+ if !row.rows.Next() {
+ if err := row.rows.Err(); err != nil {
+ return err
+ }
+ return sql.ErrNoRows
+ }
+ err := row.rows.ScanSlice(dest)
+ if err != nil {
+ return err
+ }
+
+ // Make sure the query can be processed to completion with no errors.
+ return row.rows.Close()
+}
+
+// scan data to a map's pointer
+func (row *Row) ScanMap(dest interface{}) error {
+ if row.err != nil {
+ return row.err
+ }
+ defer row.rows.Close()
+
+ if !row.rows.Next() {
+ if err := row.rows.Err(); err != nil {
+ return err
+ }
+ return sql.ErrNoRows
+ }
+ err := row.rows.ScanMap(dest)
+ if err != nil {
+ return err
+ }
+
+ // Make sure the query can be processed to completion with no errors.
+ return row.rows.Close()
+}
+
+func (row *Row) ToMapString() (map[string]string, error) {
+ cols, err := row.Columns()
+ if err != nil {
+ return nil, err
+ }
+
+ var record = make(map[string]string, len(cols))
+ err = row.ScanMap(&record)
+ if err != nil {
+ return nil, err
+ }
+
+ return record, nil
+}
diff --git a/vendor/xorm.io/core/scan.go b/vendor/xorm.io/core/scan.go
new file mode 100644
index 0000000000..897b534159
--- /dev/null
+++ b/vendor/xorm.io/core/scan.go
@@ -0,0 +1,66 @@
+// Copyright 2019 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 core
+
+import (
+ "database/sql/driver"
+ "fmt"
+ "time"
+)
+
+type NullTime time.Time
+
+var (
+ _ driver.Valuer = NullTime{}
+)
+
+func (ns *NullTime) Scan(value interface{}) error {
+ if value == nil {
+ return nil
+ }
+ return convertTime(ns, value)
+}
+
+// Value implements the driver Valuer interface.
+func (ns NullTime) Value() (driver.Value, error) {
+ if (time.Time)(ns).IsZero() {
+ return nil, nil
+ }
+ return (time.Time)(ns).Format("2006-01-02 15:04:05"), nil
+}
+
+func convertTime(dest *NullTime, src interface{}) error {
+ // Common cases, without reflect.
+ switch s := src.(type) {
+ case string:
+ t, err := time.Parse("2006-01-02 15:04:05", s)
+ if err != nil {
+ return err
+ }
+ *dest = NullTime(t)
+ return nil
+ case []uint8:
+ t, err := time.Parse("2006-01-02 15:04:05", string(s))
+ if err != nil {
+ return err
+ }
+ *dest = NullTime(t)
+ return nil
+ case time.Time:
+ *dest = NullTime(s)
+ return nil
+ case nil:
+ default:
+ return fmt.Errorf("unsupported driver -> Scan pair: %T -> %T", src, dest)
+ }
+ return nil
+}
+
+type EmptyScanner struct {
+}
+
+func (EmptyScanner) Scan(src interface{}) error {
+ return nil
+}
diff --git a/vendor/xorm.io/core/stmt.go b/vendor/xorm.io/core/stmt.go
new file mode 100644
index 0000000000..20ee202b9b
--- /dev/null
+++ b/vendor/xorm.io/core/stmt.go
@@ -0,0 +1,165 @@
+// Copyright 2019 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 core
+
+import (
+ "context"
+ "database/sql"
+ "errors"
+ "reflect"
+)
+
+type Stmt struct {
+ *sql.Stmt
+ db *DB
+ names map[string]int
+}
+
+func (db *DB) PrepareContext(ctx context.Context, query string) (*Stmt, error) {
+ names := make(map[string]int)
+ var i int
+ query = re.ReplaceAllStringFunc(query, func(src string) string {
+ names[src[1:]] = i
+ i += 1
+ return "?"
+ })
+
+ stmt, err := db.DB.PrepareContext(ctx, query)
+ if err != nil {
+ return nil, err
+ }
+ return &Stmt{stmt, db, names}, nil
+}
+
+func (db *DB) Prepare(query string) (*Stmt, error) {
+ return db.PrepareContext(context.Background(), query)
+}
+
+func (s *Stmt) ExecMapContext(ctx context.Context, mp interface{}) (sql.Result, error) {
+ vv := reflect.ValueOf(mp)
+ if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Map {
+ return nil, errors.New("mp should be a map's pointer")
+ }
+
+ args := make([]interface{}, len(s.names))
+ for k, i := range s.names {
+ args[i] = vv.Elem().MapIndex(reflect.ValueOf(k)).Interface()
+ }
+ return s.Stmt.ExecContext(ctx, args...)
+}
+
+func (s *Stmt) ExecMap(mp interface{}) (sql.Result, error) {
+ return s.ExecMapContext(context.Background(), mp)
+}
+
+func (s *Stmt) ExecStructContext(ctx context.Context, st interface{}) (sql.Result, error) {
+ vv := reflect.ValueOf(st)
+ if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct {
+ return nil, errors.New("mp should be a map's pointer")
+ }
+
+ args := make([]interface{}, len(s.names))
+ for k, i := range s.names {
+ args[i] = vv.Elem().FieldByName(k).Interface()
+ }
+ return s.Stmt.ExecContext(ctx, args...)
+}
+
+func (s *Stmt) ExecStruct(st interface{}) (sql.Result, error) {
+ return s.ExecStructContext(context.Background(), st)
+}
+
+func (s *Stmt) QueryContext(ctx context.Context, args ...interface{}) (*Rows, error) {
+ rows, err := s.Stmt.QueryContext(ctx, args...)
+ if err != nil {
+ return nil, err
+ }
+ return &Rows{rows, s.db}, nil
+}
+
+func (s *Stmt) Query(args ...interface{}) (*Rows, error) {
+ return s.QueryContext(context.Background(), args...)
+}
+
+func (s *Stmt) QueryMapContext(ctx context.Context, mp interface{}) (*Rows, error) {
+ vv := reflect.ValueOf(mp)
+ if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Map {
+ return nil, errors.New("mp should be a map's pointer")
+ }
+
+ args := make([]interface{}, len(s.names))
+ for k, i := range s.names {
+ args[i] = vv.Elem().MapIndex(reflect.ValueOf(k)).Interface()
+ }
+
+ return s.QueryContext(ctx, args...)
+}
+
+func (s *Stmt) QueryMap(mp interface{}) (*Rows, error) {
+ return s.QueryMapContext(context.Background(), mp)
+}
+
+func (s *Stmt) QueryStructContext(ctx context.Context, st interface{}) (*Rows, error) {
+ vv := reflect.ValueOf(st)
+ if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct {
+ return nil, errors.New("mp should be a map's pointer")
+ }
+
+ args := make([]interface{}, len(s.names))
+ for k, i := range s.names {
+ args[i] = vv.Elem().FieldByName(k).Interface()
+ }
+
+ return s.Query(args...)
+}
+
+func (s *Stmt) QueryStruct(st interface{}) (*Rows, error) {
+ return s.QueryStructContext(context.Background(), st)
+}
+
+func (s *Stmt) QueryRowContext(ctx context.Context, args ...interface{}) *Row {
+ rows, err := s.QueryContext(ctx, args...)
+ return &Row{rows, err}
+}
+
+func (s *Stmt) QueryRow(args ...interface{}) *Row {
+ return s.QueryRowContext(context.Background(), args...)
+}
+
+func (s *Stmt) QueryRowMapContext(ctx context.Context, mp interface{}) *Row {
+ vv := reflect.ValueOf(mp)
+ if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Map {
+ return &Row{nil, errors.New("mp should be a map's pointer")}
+ }
+
+ args := make([]interface{}, len(s.names))
+ for k, i := range s.names {
+ args[i] = vv.Elem().MapIndex(reflect.ValueOf(k)).Interface()
+ }
+
+ return s.QueryRowContext(ctx, args...)
+}
+
+func (s *Stmt) QueryRowMap(mp interface{}) *Row {
+ return s.QueryRowMapContext(context.Background(), mp)
+}
+
+func (s *Stmt) QueryRowStructContext(ctx context.Context, st interface{}) *Row {
+ vv := reflect.ValueOf(st)
+ if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct {
+ return &Row{nil, errors.New("st should be a struct's pointer")}
+ }
+
+ args := make([]interface{}, len(s.names))
+ for k, i := range s.names {
+ args[i] = vv.Elem().FieldByName(k).Interface()
+ }
+
+ return s.QueryRowContext(ctx, args...)
+}
+
+func (s *Stmt) QueryRowStruct(st interface{}) *Row {
+ return s.QueryRowStructContext(context.Background(), st)
+}
diff --git a/vendor/xorm.io/core/table.go b/vendor/xorm.io/core/table.go
new file mode 100644
index 0000000000..d129e60f8b
--- /dev/null
+++ b/vendor/xorm.io/core/table.go
@@ -0,0 +1,154 @@
+// Copyright 2019 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 core
+
+import (
+ "reflect"
+ "strings"
+)
+
+// database table
+type Table struct {
+ Name string
+ Type reflect.Type
+ columnsSeq []string
+ columnsMap map[string][]*Column
+ columns []*Column
+ Indexes map[string]*Index
+ PrimaryKeys []string
+ AutoIncrement string
+ Created map[string]bool
+ Updated string
+ Deleted string
+ Version string
+ Cacher Cacher
+ StoreEngine string
+ Charset string
+ Comment string
+}
+
+func (table *Table) Columns() []*Column {
+ return table.columns
+}
+
+func (table *Table) ColumnsSeq() []string {
+ return table.columnsSeq
+}
+
+func NewEmptyTable() *Table {
+ return NewTable("", nil)
+}
+
+func NewTable(name string, t reflect.Type) *Table {
+ return &Table{Name: name, Type: t,
+ columnsSeq: make([]string, 0),
+ columns: make([]*Column, 0),
+ columnsMap: make(map[string][]*Column),
+ Indexes: make(map[string]*Index),
+ Created: make(map[string]bool),
+ PrimaryKeys: make([]string, 0),
+ }
+}
+
+func (table *Table) columnsByName(name string) []*Column {
+ n := len(name)
+
+ for k := range table.columnsMap {
+ if len(k) != n {
+ continue
+ }
+ if strings.EqualFold(k, name) {
+ return table.columnsMap[k]
+ }
+ }
+ return nil
+}
+
+func (table *Table) GetColumn(name string) *Column {
+
+ cols := table.columnsByName(name)
+
+ if cols != nil {
+ return cols[0]
+ }
+
+ return nil
+}
+
+func (table *Table) GetColumnIdx(name string, idx int) *Column {
+ cols := table.columnsByName(name)
+
+ if cols != nil && idx < len(cols) {
+ return cols[idx]
+ }
+
+ return nil
+}
+
+// if has primary key, return column
+func (table *Table) PKColumns() []*Column {
+ columns := make([]*Column, len(table.PrimaryKeys))
+ for i, name := range table.PrimaryKeys {
+ columns[i] = table.GetColumn(name)
+ }
+ return columns
+}
+
+func (table *Table) ColumnType(name string) reflect.Type {
+ t, _ := table.Type.FieldByName(name)
+ return t.Type
+}
+
+func (table *Table) AutoIncrColumn() *Column {
+ return table.GetColumn(table.AutoIncrement)
+}
+
+func (table *Table) VersionColumn() *Column {
+ return table.GetColumn(table.Version)
+}
+
+func (table *Table) UpdatedColumn() *Column {
+ return table.GetColumn(table.Updated)
+}
+
+func (table *Table) DeletedColumn() *Column {
+ return table.GetColumn(table.Deleted)
+}
+
+// add a column to table
+func (table *Table) AddColumn(col *Column) {
+ table.columnsSeq = append(table.columnsSeq, col.Name)
+ table.columns = append(table.columns, col)
+ colName := strings.ToLower(col.Name)
+ if c, ok := table.columnsMap[colName]; ok {
+ table.columnsMap[colName] = append(c, col)
+ } else {
+ table.columnsMap[colName] = []*Column{col}
+ }
+
+ if col.IsPrimaryKey {
+ table.PrimaryKeys = append(table.PrimaryKeys, col.Name)
+ }
+ if col.IsAutoIncrement {
+ table.AutoIncrement = col.Name
+ }
+ if col.IsCreated {
+ table.Created[col.Name] = true
+ }
+ if col.IsUpdated {
+ table.Updated = col.Name
+ }
+ if col.IsDeleted {
+ table.Deleted = col.Name
+ }
+ if col.IsVersion {
+ table.Version = col.Name
+ }
+}
+
+// add an index or an unique to table
+func (table *Table) AddIndex(index *Index) {
+ table.Indexes[index.Name] = index
+}
diff --git a/vendor/xorm.io/core/tx.go b/vendor/xorm.io/core/tx.go
new file mode 100644
index 0000000000..a56b70063e
--- /dev/null
+++ b/vendor/xorm.io/core/tx.go
@@ -0,0 +1,153 @@
+// Copyright 2019 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 core
+
+import (
+ "context"
+ "database/sql"
+)
+
+type Tx struct {
+ *sql.Tx
+ db *DB
+}
+
+func (db *DB) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error) {
+ tx, err := db.DB.BeginTx(ctx, opts)
+ if err != nil {
+ return nil, err
+ }
+ return &Tx{tx, db}, nil
+}
+
+func (db *DB) Begin() (*Tx, error) {
+ tx, err := db.DB.Begin()
+ if err != nil {
+ return nil, err
+ }
+ return &Tx{tx, db}, nil
+}
+
+func (tx *Tx) PrepareContext(ctx context.Context, query string) (*Stmt, error) {
+ names := make(map[string]int)
+ var i int
+ query = re.ReplaceAllStringFunc(query, func(src string) string {
+ names[src[1:]] = i
+ i += 1
+ return "?"
+ })
+
+ stmt, err := tx.Tx.PrepareContext(ctx, query)
+ if err != nil {
+ return nil, err
+ }
+ return &Stmt{stmt, tx.db, names}, nil
+}
+
+func (tx *Tx) Prepare(query string) (*Stmt, error) {
+ return tx.PrepareContext(context.Background(), query)
+}
+
+func (tx *Tx) StmtContext(ctx context.Context, stmt *Stmt) *Stmt {
+ stmt.Stmt = tx.Tx.StmtContext(ctx, stmt.Stmt)
+ return stmt
+}
+
+func (tx *Tx) Stmt(stmt *Stmt) *Stmt {
+ return tx.StmtContext(context.Background(), stmt)
+}
+
+func (tx *Tx) ExecMapContext(ctx context.Context, query string, mp interface{}) (sql.Result, error) {
+ query, args, err := MapToSlice(query, mp)
+ if err != nil {
+ return nil, err
+ }
+ return tx.Tx.ExecContext(ctx, query, args...)
+}
+
+func (tx *Tx) ExecMap(query string, mp interface{}) (sql.Result, error) {
+ return tx.ExecMapContext(context.Background(), query, mp)
+}
+
+func (tx *Tx) ExecStructContext(ctx context.Context, query string, st interface{}) (sql.Result, error) {
+ query, args, err := StructToSlice(query, st)
+ if err != nil {
+ return nil, err
+ }
+ return tx.Tx.ExecContext(ctx, query, args...)
+}
+
+func (tx *Tx) ExecStruct(query string, st interface{}) (sql.Result, error) {
+ return tx.ExecStructContext(context.Background(), query, st)
+}
+
+func (tx *Tx) QueryContext(ctx context.Context, query string, args ...interface{}) (*Rows, error) {
+ rows, err := tx.Tx.QueryContext(ctx, query, args...)
+ if err != nil {
+ return nil, err
+ }
+ return &Rows{rows, tx.db}, nil
+}
+
+func (tx *Tx) Query(query string, args ...interface{}) (*Rows, error) {
+ return tx.QueryContext(context.Background(), query, args...)
+}
+
+func (tx *Tx) QueryMapContext(ctx context.Context, query string, mp interface{}) (*Rows, error) {
+ query, args, err := MapToSlice(query, mp)
+ if err != nil {
+ return nil, err
+ }
+ return tx.QueryContext(ctx, query, args...)
+}
+
+func (tx *Tx) QueryMap(query string, mp interface{}) (*Rows, error) {
+ return tx.QueryMapContext(context.Background(), query, mp)
+}
+
+func (tx *Tx) QueryStructContext(ctx context.Context, query string, st interface{}) (*Rows, error) {
+ query, args, err := StructToSlice(query, st)
+ if err != nil {
+ return nil, err
+ }
+ return tx.QueryContext(ctx, query, args...)
+}
+
+func (tx *Tx) QueryStruct(query string, st interface{}) (*Rows, error) {
+ return tx.QueryStructContext(context.Background(), query, st)
+}
+
+func (tx *Tx) QueryRowContext(ctx context.Context, query string, args ...interface{}) *Row {
+ rows, err := tx.QueryContext(ctx, query, args...)
+ return &Row{rows, err}
+}
+
+func (tx *Tx) QueryRow(query string, args ...interface{}) *Row {
+ return tx.QueryRowContext(context.Background(), query, args...)
+}
+
+func (tx *Tx) QueryRowMapContext(ctx context.Context, query string, mp interface{}) *Row {
+ query, args, err := MapToSlice(query, mp)
+ if err != nil {
+ return &Row{nil, err}
+ }
+ return tx.QueryRowContext(ctx, query, args...)
+}
+
+func (tx *Tx) QueryRowMap(query string, mp interface{}) *Row {
+ return tx.QueryRowMapContext(context.Background(), query, mp)
+}
+
+func (tx *Tx) QueryRowStructContext(ctx context.Context, query string, st interface{}) *Row {
+ query, args, err := StructToSlice(query, st)
+ if err != nil {
+ return &Row{nil, err}
+ }
+ return tx.QueryRowContext(ctx, query, args...)
+}
+
+func (tx *Tx) QueryRowStruct(query string, st interface{}) *Row {
+ return tx.QueryRowStructContext(context.Background(), query, st)
+}
diff --git a/vendor/xorm.io/core/type.go b/vendor/xorm.io/core/type.go
new file mode 100644
index 0000000000..8164953602
--- /dev/null
+++ b/vendor/xorm.io/core/type.go
@@ -0,0 +1,323 @@
+// Copyright 2019 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 core
+
+import (
+ "reflect"
+ "sort"
+ "strings"
+ "time"
+)
+
+const (
+ POSTGRES = "postgres"
+ SQLITE = "sqlite3"
+ MYSQL = "mysql"
+ MSSQL = "mssql"
+ ORACLE = "oracle"
+)
+
+// xorm SQL types
+type SQLType struct {
+ Name string
+ DefaultLength int
+ DefaultLength2 int
+}
+
+const (
+ UNKNOW_TYPE = iota
+ TEXT_TYPE
+ BLOB_TYPE
+ TIME_TYPE
+ NUMERIC_TYPE
+)
+
+func (s *SQLType) IsType(st int) bool {
+ if t, ok := SqlTypes[s.Name]; ok && t == st {
+ return true
+ }
+ return false
+}
+
+func (s *SQLType) IsText() bool {
+ return s.IsType(TEXT_TYPE)
+}
+
+func (s *SQLType) IsBlob() bool {
+ return s.IsType(BLOB_TYPE)
+}
+
+func (s *SQLType) IsTime() bool {
+ return s.IsType(TIME_TYPE)
+}
+
+func (s *SQLType) IsNumeric() bool {
+ return s.IsType(NUMERIC_TYPE)
+}
+
+func (s *SQLType) IsJson() bool {
+ return s.Name == Json || s.Name == Jsonb
+}
+
+var (
+ Bit = "BIT"
+ TinyInt = "TINYINT"
+ SmallInt = "SMALLINT"
+ MediumInt = "MEDIUMINT"
+ Int = "INT"
+ Integer = "INTEGER"
+ BigInt = "BIGINT"
+
+ Enum = "ENUM"
+ Set = "SET"
+
+ Char = "CHAR"
+ Varchar = "VARCHAR"
+ NChar = "NCHAR"
+ NVarchar = "NVARCHAR"
+ TinyText = "TINYTEXT"
+ Text = "TEXT"
+ NText = "NTEXT"
+ Clob = "CLOB"
+ MediumText = "MEDIUMTEXT"
+ LongText = "LONGTEXT"
+ Uuid = "UUID"
+ UniqueIdentifier = "UNIQUEIDENTIFIER"
+ SysName = "SYSNAME"
+
+ Date = "DATE"
+ DateTime = "DATETIME"
+ SmallDateTime = "SMALLDATETIME"
+ Time = "TIME"
+ TimeStamp = "TIMESTAMP"
+ TimeStampz = "TIMESTAMPZ"
+
+ Decimal = "DECIMAL"
+ Numeric = "NUMERIC"
+ Money = "MONEY"
+ SmallMoney = "SMALLMONEY"
+
+ Real = "REAL"
+ Float = "FLOAT"
+ Double = "DOUBLE"
+
+ Binary = "BINARY"
+ VarBinary = "VARBINARY"
+ TinyBlob = "TINYBLOB"
+ Blob = "BLOB"
+ MediumBlob = "MEDIUMBLOB"
+ LongBlob = "LONGBLOB"
+ Bytea = "BYTEA"
+
+ Bool = "BOOL"
+ Boolean = "BOOLEAN"
+
+ Serial = "SERIAL"
+ BigSerial = "BIGSERIAL"
+
+ Json = "JSON"
+ Jsonb = "JSONB"
+
+ SqlTypes = map[string]int{
+ Bit: NUMERIC_TYPE,
+ TinyInt: NUMERIC_TYPE,
+ SmallInt: NUMERIC_TYPE,
+ MediumInt: NUMERIC_TYPE,
+ Int: NUMERIC_TYPE,
+ Integer: NUMERIC_TYPE,
+ BigInt: NUMERIC_TYPE,
+
+ Enum: TEXT_TYPE,
+ Set: TEXT_TYPE,
+ Json: TEXT_TYPE,
+ Jsonb: TEXT_TYPE,
+
+ Char: TEXT_TYPE,
+ NChar: TEXT_TYPE,
+ Varchar: TEXT_TYPE,
+ NVarchar: TEXT_TYPE,
+ TinyText: TEXT_TYPE,
+ Text: TEXT_TYPE,
+ NText: TEXT_TYPE,
+ MediumText: TEXT_TYPE,
+ LongText: TEXT_TYPE,
+ Uuid: TEXT_TYPE,
+ Clob: TEXT_TYPE,
+ SysName: TEXT_TYPE,
+
+ Date: TIME_TYPE,
+ DateTime: TIME_TYPE,
+ Time: TIME_TYPE,
+ TimeStamp: TIME_TYPE,
+ TimeStampz: TIME_TYPE,
+ SmallDateTime: TIME_TYPE,
+
+ Decimal: NUMERIC_TYPE,
+ Numeric: NUMERIC_TYPE,
+ Real: NUMERIC_TYPE,
+ Float: NUMERIC_TYPE,
+ Double: NUMERIC_TYPE,
+ Money: NUMERIC_TYPE,
+ SmallMoney: NUMERIC_TYPE,
+
+ Binary: BLOB_TYPE,
+ VarBinary: BLOB_TYPE,
+
+ TinyBlob: BLOB_TYPE,
+ Blob: BLOB_TYPE,
+ MediumBlob: BLOB_TYPE,
+ LongBlob: BLOB_TYPE,
+ Bytea: BLOB_TYPE,
+ UniqueIdentifier: BLOB_TYPE,
+
+ Bool: NUMERIC_TYPE,
+
+ Serial: NUMERIC_TYPE,
+ BigSerial: NUMERIC_TYPE,
+ }
+
+ intTypes = sort.StringSlice{"*int", "*int16", "*int32", "*int8"}
+ uintTypes = sort.StringSlice{"*uint", "*uint16", "*uint32", "*uint8"}
+)
+
+// !nashtsai! treat following var as interal const values, these are used for reflect.TypeOf comparison
+var (
+ c_EMPTY_STRING string
+ c_BOOL_DEFAULT bool
+ c_BYTE_DEFAULT byte
+ c_COMPLEX64_DEFAULT complex64
+ c_COMPLEX128_DEFAULT complex128
+ c_FLOAT32_DEFAULT float32
+ c_FLOAT64_DEFAULT float64
+ c_INT64_DEFAULT int64
+ c_UINT64_DEFAULT uint64
+ c_INT32_DEFAULT int32
+ c_UINT32_DEFAULT uint32
+ c_INT16_DEFAULT int16
+ c_UINT16_DEFAULT uint16
+ c_INT8_DEFAULT int8
+ c_UINT8_DEFAULT uint8
+ c_INT_DEFAULT int
+ c_UINT_DEFAULT uint
+ c_TIME_DEFAULT time.Time
+)
+
+var (
+ IntType = reflect.TypeOf(c_INT_DEFAULT)
+ Int8Type = reflect.TypeOf(c_INT8_DEFAULT)
+ Int16Type = reflect.TypeOf(c_INT16_DEFAULT)
+ Int32Type = reflect.TypeOf(c_INT32_DEFAULT)
+ Int64Type = reflect.TypeOf(c_INT64_DEFAULT)
+
+ UintType = reflect.TypeOf(c_UINT_DEFAULT)
+ Uint8Type = reflect.TypeOf(c_UINT8_DEFAULT)
+ Uint16Type = reflect.TypeOf(c_UINT16_DEFAULT)
+ Uint32Type = reflect.TypeOf(c_UINT32_DEFAULT)
+ Uint64Type = reflect.TypeOf(c_UINT64_DEFAULT)
+
+ Float32Type = reflect.TypeOf(c_FLOAT32_DEFAULT)
+ Float64Type = reflect.TypeOf(c_FLOAT64_DEFAULT)
+
+ Complex64Type = reflect.TypeOf(c_COMPLEX64_DEFAULT)
+ Complex128Type = reflect.TypeOf(c_COMPLEX128_DEFAULT)
+
+ StringType = reflect.TypeOf(c_EMPTY_STRING)
+ BoolType = reflect.TypeOf(c_BOOL_DEFAULT)
+ ByteType = reflect.TypeOf(c_BYTE_DEFAULT)
+ BytesType = reflect.SliceOf(ByteType)
+
+ TimeType = reflect.TypeOf(c_TIME_DEFAULT)
+)
+
+var (
+ PtrIntType = reflect.PtrTo(IntType)
+ PtrInt8Type = reflect.PtrTo(Int8Type)
+ PtrInt16Type = reflect.PtrTo(Int16Type)
+ PtrInt32Type = reflect.PtrTo(Int32Type)
+ PtrInt64Type = reflect.PtrTo(Int64Type)
+
+ PtrUintType = reflect.PtrTo(UintType)
+ PtrUint8Type = reflect.PtrTo(Uint8Type)
+ PtrUint16Type = reflect.PtrTo(Uint16Type)
+ PtrUint32Type = reflect.PtrTo(Uint32Type)
+ PtrUint64Type = reflect.PtrTo(Uint64Type)
+
+ PtrFloat32Type = reflect.PtrTo(Float32Type)
+ PtrFloat64Type = reflect.PtrTo(Float64Type)
+
+ PtrComplex64Type = reflect.PtrTo(Complex64Type)
+ PtrComplex128Type = reflect.PtrTo(Complex128Type)
+
+ PtrStringType = reflect.PtrTo(StringType)
+ PtrBoolType = reflect.PtrTo(BoolType)
+ PtrByteType = reflect.PtrTo(ByteType)
+
+ PtrTimeType = reflect.PtrTo(TimeType)
+)
+
+// Type2SQLType generate SQLType acorrding Go's type
+func Type2SQLType(t reflect.Type) (st SQLType) {
+ switch k := t.Kind(); k {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32:
+ st = SQLType{Int, 0, 0}
+ case reflect.Int64, reflect.Uint64:
+ st = SQLType{BigInt, 0, 0}
+ case reflect.Float32:
+ st = SQLType{Float, 0, 0}
+ case reflect.Float64:
+ st = SQLType{Double, 0, 0}
+ case reflect.Complex64, reflect.Complex128:
+ st = SQLType{Varchar, 64, 0}
+ case reflect.Array, reflect.Slice, reflect.Map:
+ if t.Elem() == reflect.TypeOf(c_BYTE_DEFAULT) {
+ st = SQLType{Blob, 0, 0}
+ } else {
+ st = SQLType{Text, 0, 0}
+ }
+ case reflect.Bool:
+ st = SQLType{Bool, 0, 0}
+ case reflect.String:
+ st = SQLType{Varchar, 255, 0}
+ case reflect.Struct:
+ if t.ConvertibleTo(TimeType) {
+ st = SQLType{DateTime, 0, 0}
+ } else {
+ // TODO need to handle association struct
+ st = SQLType{Text, 0, 0}
+ }
+ case reflect.Ptr:
+ st = Type2SQLType(t.Elem())
+ default:
+ st = SQLType{Text, 0, 0}
+ }
+ return
+}
+
+// default sql type change to go types
+func SQLType2Type(st SQLType) reflect.Type {
+ name := strings.ToUpper(st.Name)
+ switch name {
+ case Bit, TinyInt, SmallInt, MediumInt, Int, Integer, Serial:
+ return reflect.TypeOf(1)
+ case BigInt, BigSerial:
+ return reflect.TypeOf(int64(1))
+ case Float, Real:
+ return reflect.TypeOf(float32(1))
+ case Double:
+ return reflect.TypeOf(float64(1))
+ case Char, NChar, Varchar, NVarchar, TinyText, Text, NText, MediumText, LongText, Enum, Set, Uuid, Clob, SysName:
+ return reflect.TypeOf("")
+ case TinyBlob, Blob, LongBlob, Bytea, Binary, MediumBlob, VarBinary, UniqueIdentifier:
+ return reflect.TypeOf([]byte{})
+ case Bool:
+ return reflect.TypeOf(true)
+ case DateTime, Date, Time, TimeStamp, TimeStampz, SmallDateTime:
+ return reflect.TypeOf(c_TIME_DEFAULT)
+ case Decimal, Numeric, Money, SmallMoney:
+ return reflect.TypeOf("")
+ default:
+ return reflect.TypeOf("")
+ }
+}