upgrade xorm to v1.0.0 #10

Merged
lunny merged 1 commits from lunny/upgrade_xorm_1.0.0 into master 2020-03-23 08:48:38 +00:00
39 changed files with 450 additions and 336 deletions

2
go.mod
View File

@ -12,5 +12,5 @@ require (
github.com/spf13/cobra v0.0.5
github.com/stretchr/testify v1.4.0
gopkg.in/yaml.v2 v2.2.2
xorm.io/xorm v0.8.3-0.20200310061142-2f95c750c348
xorm.io/xorm v1.0.0
)

12
go.sum
View File

@ -4,6 +4,8 @@ cloud.google.com/go v0.37.4 h1:glPeL3BQJsbF6aIIYfZizMwc5LTYz250bDMjttbBGAU=
cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw=
gitea.com/lunny/log v0.0.0-20190322053110-01b5df579c4e h1:r1en/D7xJmcY24VkHkjkcJFa+7ZWubVWPBrvsHkmHxk=
gitea.com/lunny/log v0.0.0-20190322053110-01b5df579c4e/go.mod h1:uJEsN4LQpeGYRCjuPXPZBClU7N5pWzGuyF4uqLpE/e0=
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
@ -32,8 +34,6 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9
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/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
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/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
@ -185,7 +185,7 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
xorm.io/builder v0.3.6 h1:ha28mQ2M+TFx96Hxo+iq6tQgnkC9IZkM6D8w9sKHHF8=
xorm.io/builder v0.3.6/go.mod h1:LEFAPISnRzG+zxaxj2vPicRwz67BdhFreKg8yv8/TgU=
xorm.io/xorm v0.8.3-0.20200310061142-2f95c750c348 h1:tOLP/MsqfZ0Eyu6txXvjtqgPk2WGD4avJmLd4HnY0Wk=
xorm.io/xorm v0.8.3-0.20200310061142-2f95c750c348/go.mod h1:zylddI/y190bUT26wbSjzDrDnZzs6Gxq33nY2eL2VXI=
xorm.io/builder v0.3.7 h1:2pETdKRK+2QG4mLX4oODHEhn5Z8j1m8sXa7jfu+/SZI=
xorm.io/builder v0.3.7/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
xorm.io/xorm v1.0.0 h1:ceiwUTrJHqfNFxIUcWjkcbz6kt7sINf2dOXlgLLhaQM=
xorm.io/xorm v1.0.0/go.mod h1:o4vnEsQ5V2F1/WK6w4XTwmiWJeGj82tqjAnHe44wVHY=

4
vendor/modules.txt vendored
View File

@ -54,9 +54,9 @@ golang.org/x/crypto/md4
google.golang.org/appengine/cloudsql
# gopkg.in/yaml.v2 v2.2.2
gopkg.in/yaml.v2
# xorm.io/builder v0.3.6
# xorm.io/builder v0.3.7
xorm.io/builder
# xorm.io/xorm v0.8.3-0.20200310061142-2f95c750c348
# xorm.io/xorm v1.0.0
xorm.io/xorm
xorm.io/xorm/caches
xorm.io/xorm/contexts

71
vendor/xorm.io/builder/.drone.yml generated vendored
View File

@ -1,31 +1,6 @@
---
kind: pipeline
name: go1.10
workspace:
base: /go
path: src/xorm.io/builder
steps:
- name: test
pull: default
image: golang:1.10
commands:
- go get -u golang.org/x/lint/golint
- go get -u github.com/stretchr/testify/assert
- go get -u github.com/go-xorm/sqlfiddle
- golint ./...
- go vet
- go test -v -race -coverprofile=coverage.txt -covermode=atomic
when:
event:
- push
- tag
- pull_request
---
kind: pipeline
name: go1.11
name: testing
steps:
- name: test
@ -36,50 +11,6 @@ steps:
- golint ./...
- go vet
- go test -v -race -coverprofile=coverage.txt -covermode=atomic
environment:
GOPROXY: https://goproxy.cn
GO111MODULE: "on"
when:
event:
- push
- tag
- pull_request
---
kind: pipeline
name: go1.12
steps:
- name: test
pull: default
image: golang:1.12
commands:
- go get -u golang.org/x/lint/golint
- golint ./...
- go vet
- go test -v -race -coverprofile=coverage.txt -covermode=atomic
environment:
GOPROXY: https://goproxy.cn
GO111MODULE: "on"
when:
event:
- push
- tag
- pull_request
---
kind: pipeline
name: go1.13
steps:
- name: test
pull: default
image: golang:1.13
commands:
- go get -u golang.org/x/lint/golint
- golint ./...
- go vet
- go test -v -race -coverprofile=coverage.txt -covermode=atomic
environment:
GOPROXY: https://goproxy.cn
GO111MODULE: "on"

1
vendor/xorm.io/builder/.gitignore generated vendored Normal file
View File

@ -0,0 +1 @@
.idea

60
vendor/xorm.io/builder/builder.go generated vendored
View File

@ -17,7 +17,7 @@ const (
insertType // insert
updateType // update
deleteType // delete
unionType // union
setOpType // set operation
)
// all databasees
@ -27,6 +27,10 @@ const (
MYSQL = "mysql"
MSSQL = "mssql"
ORACLE = "oracle"
UNION = "union"
INTERSECT = "intersect"
EXCEPT = "except"
)
type join struct {
@ -35,9 +39,10 @@ type join struct {
joinCond Cond
}
type union struct {
unionType string
builder *Builder
type setOp struct {
opType string
distinctType string
builder *Builder
}
type limit struct {
@ -56,7 +61,7 @@ type Builder struct {
cond Cond
selects []string
joins []join
unions []union
setOps []setOp
limitation *limit
insertCols []string
insertVals []interface{}
@ -144,33 +149,48 @@ func (b *Builder) Into(tableName string) *Builder {
}
// Union sets union conditions
func (b *Builder) Union(unionTp string, unionCond *Builder) *Builder {
func (b *Builder) Union(distinctType string, cond *Builder) *Builder {
return b.setOperation(UNION, distinctType, cond)
}
// Intersect sets intersect conditions
func (b *Builder) Intersect(distinctType string, cond *Builder) *Builder {
return b.setOperation(INTERSECT, distinctType, cond)
}
// Except sets except conditions
func (b *Builder) Except(distinctType string, cond *Builder) *Builder {
return b.setOperation(EXCEPT, distinctType, cond)
}
func (b *Builder) setOperation(opType, distinctType string, cond *Builder) *Builder {
var builder *Builder
if b.optype != unionType {
if b.optype != setOpType {
builder = &Builder{cond: NewCond()}
builder.optype = unionType
builder.optype = setOpType
builder.dialect = b.dialect
builder.selects = b.selects
currentUnions := b.unions
// erase sub unions (actually append to new Builder.unions)
b.unions = nil
currentSetOps := b.setOps
// erase sub setOps (actually append to new Builder.unions)
b.setOps = nil
for e := range currentUnions {
currentUnions[e].builder.dialect = b.dialect
for e := range currentSetOps {
currentSetOps[e].builder.dialect = b.dialect
}
builder.unions = append(append(builder.unions, union{"", b}), currentUnions...)
builder.setOps = append(append(builder.setOps, setOp{opType, "", b}), currentSetOps...)
} else {
builder = b
}
if unionCond != nil {
if unionCond.dialect == "" && builder.dialect != "" {
unionCond.dialect = builder.dialect
if cond != nil {
if cond.dialect == "" && builder.dialect != "" {
cond.dialect = builder.dialect
}
builder.unions = append(builder.unions, union{unionTp, unionCond})
builder.setOps = append(builder.setOps, setOp{opType, distinctType, cond})
}
return builder
@ -240,8 +260,8 @@ func (b *Builder) WriteTo(w Writer) error {
return b.updateWriteTo(w)
case deleteType:
return b.deleteWriteTo(w)
case unionType:
return b.unionWriteTo(w)
case setOpType:
return b.setOpWriteTo(w)
}
return ErrNotSupportType

View File

@ -58,6 +58,8 @@ func (b *Builder) insertWriteTo(w Writer) error {
if e, ok := value.(expr); ok {
fmt.Fprintf(valBuffer, "(%s)", e.sql)
args = append(args, e.args...)
} else if value == nil {
fmt.Fprintf(valBuffer, `null`)
} else {
fmt.Fprint(valBuffer, "?")
args = append(args, value)

View File

@ -21,6 +21,9 @@ func (b *Builder) limitWriteTo(w Writer) error {
}
// erase limit condition
b.limitation = nil
defer func() {
b.limitation = limit
}()
ow := w.(*BytesWriter)
switch strings.ToLower(strings.TrimSpace(b.dialect)) {
@ -34,7 +37,7 @@ func (b *Builder) limitWriteTo(w Writer) error {
b.selects = append(selects, "ROWNUM RN")
var wb *Builder
if b.optype == unionType {
if b.optype == setOpType {
wb = Dialect(b.dialect).Select("at.*", "ROWNUM RN").
From(b, "at")
} else {
@ -55,7 +58,7 @@ func (b *Builder) limitWriteTo(w Writer) error {
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 b.optype == setOpType {
if err := b.WriteTo(ow); err != nil {
return err
}
@ -77,7 +80,7 @@ func (b *Builder) limitWriteTo(w Writer) error {
b.selects[1:]...), "ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS RN")
var wb *Builder
if b.optype == unionType {
if b.optype == setOpType {
wb = Dialect(b.dialect).Select("*", "ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS RN").
From(b, "at")
} else {

View File

@ -63,7 +63,7 @@ func (b *Builder) selectWriteTo(w Writer) error {
}
switch b.subQuery.optype {
case selectType, unionType:
case selectType, setOpType:
fmt.Fprint(w, " FROM (")
if err := b.subQuery.WriteTo(w); err != nil {
return err

View File

@ -9,19 +9,19 @@ import (
"strings"
)
func (b *Builder) unionWriteTo(w Writer) error {
func (b *Builder) setOpWriteTo(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
for idx, o := range b.setOps {
current := o.builder
if current.optype != selectType {
return ErrUnsupportedUnionMembers
}
if len(b.unions) == 1 {
if len(b.setOps) == 1 {
if err := current.selectWriteTo(w); err != nil {
return err
}
@ -31,7 +31,11 @@ func (b *Builder) unionWriteTo(w Writer) error {
}
if idx != 0 {
fmt.Fprint(w, fmt.Sprintf(" UNION %v ", strings.ToUpper(u.unionType)))
if o.distinctType == "" {
fmt.Fprint(w, fmt.Sprintf(" %s ", strings.ToUpper(o.opType)))
} else {
fmt.Fprint(w, fmt.Sprintf(" %s %s ", strings.ToUpper(o.opType), strings.ToUpper(o.distinctType)))
}
}
fmt.Fprint(w, "(")

View File

@ -45,6 +45,10 @@ func (b *Builder) updateWriteTo(w Writer) error {
}
}
if !b.cond.IsValid() {
return nil
}
if _, err := fmt.Fprint(w, " WHERE "); err != nil {
return err
}

4
vendor/xorm.io/builder/cond_eq.go generated vendored
View File

@ -64,6 +64,10 @@ func (eq Eq) OpWriteTo(op string, w Writer) error {
return err
}
w.Append(int(v.(Decr)))
case nil:
if _, err := fmt.Fprintf(w, "%s=null", k); err != nil {
return err
}
default:
if _, err := fmt.Fprintf(w, "%s=?", k); err != nil {
return err

2
vendor/xorm.io/builder/go.mod generated vendored
View File

@ -3,6 +3,6 @@ module xorm.io/builder
go 1.11
require (
github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a
github.com/stretchr/testify v1.3.0
)

4
vendor/xorm.io/builder/go.sum generated vendored
View File

@ -1,7 +1,7 @@
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
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=

9
vendor/xorm.io/builder/sql.go generated vendored
View File

@ -75,6 +75,7 @@ func noSQLQuoteNeeded(a interface{}) bool {
}
t := reflect.TypeOf(a)
switch t.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return true
@ -133,12 +134,16 @@ func ConvertToBoundSQL(sql string, args []interface{}) (string, error) {
return buf.String(), nil
}
// ConvertPlaceholder replaces ? to $1, $2 ... or :1, :2 ... according prefix
// ConvertPlaceholder replaces the place holder ? to $1, $2 ... or :1, :2 ... according prefix
func ConvertPlaceholder(sql, prefix string) (string, error) {
buf := strings.Builder{}
var i, j, start int
var ready = true
for ; i < len(sql); i++ {
if sql[i] == '?' {
if sql[i] == '\'' && i > 0 && sql[i-1] != '\\' {
ready = !ready
}
if ready && sql[i] == '?' {
if _, err := buf.WriteString(sql[start:i]); err != nil {
return "", err
}

4
vendor/xorm.io/xorm/.changelog.yml generated vendored
View File

@ -36,10 +36,6 @@ groups:
name: TESTING
labels:
- kind/testing
-
name: TRANSLATION
labels:
- kind/translation
-
name: BUILD
labels:

56
vendor/xorm.io/xorm/CHANGELOG.md generated vendored
View File

@ -3,14 +3,53 @@
This changelog goes through all the changes that have been made in each release
without substantial changes to our git log.
## [1.0.0](https://gitea.com/xorm/xorm/pulls?q=&type=all&state=closed&milestone=1242) - to be released
## [1.0.0](https://gitea.com/xorm/xorm/pulls?q=&type=all&state=closed&milestone=1242) - 2020-03-22
* BREAKING
* Add context for dialects (#1558)
* Move zero functions to a standalone package (#1548)
* Merge core package back into the main repository and split into serval sub packages. (#1543)
* FEATURES
* Use a new ContextLogger interface to implement logger (#1557)
* BUGFIXES
* Fix setschema (#1606)
* Fix dump/import bug (#1603)
* Fix pk bug (#1602)
* Fix master/slave bug (#1601)
* Fix bug when dump (#1597)
* Ignore schema when dbtype is not postgres (#1593)
* Fix table name (#1590)
* Fix find alias bug (#1581)
* Fix rows bug (#1576)
* Fix map with cols (#1575)
* Fix bug on deleted with join (#1570)
* Improve quote policy (#1567)
* Fix break session sql enable feature (#1566)
* Fix mssql quote (#1535)
* Fix join table name quote bug (#1534)
* Fix mssql issue with duplicate columns. (#1225)
* Fix mysql8.0 sync failed (#808)
* ENHANCEMENTS
* Fix batch insert interface slice be panic (#1598)
* Move some codes to statement sub package (#1574)
* Remove circle file (#1569)
* Move statement as a sub package (#1564)
* Move maptype to tag parser (#1561)
* Move caches to manager (#1553)
* Improve code (#1552)
* Improve some codes (#1551)
* Improve statement (#1549)
* Move tag parser related codes as a standalone sub package (#1547)
* Move reserve words related files into dialects sub package (#1544)
* Merge core package back into the main repository and split into serval sub packages. (#1543)
* Fix `Conversion` method `ToDB() ([]byte, error)` return type is nil (#1296)
* Check driver.Valuer response, and skip the column if nil (#1167)
* Add cockroach support and tests (#896)
* TESTING
* Improve tests (#1572)
* BUILD
* Add changelog file and tool configuration (#1546)
* DOCS
* Fix outdate changelog (#1565)
## old changelog
@ -106,16 +145,29 @@ without substantial changes to our git log.
* **v0.2.3** : Improved documents; Optimistic Locking support; Timestamp with time zone support; Mapper change to tableMapper and columnMapper & added PrefixMapper & SuffixMapper support custom table or column name's prefix and suffix;Insert now return affected, err instead of id, err; Added UseBool & Distinct;
* **v0.2.2** : Postgres drivers now support lib/pq; Added method Iterate for record by record to handlerAdded SetMaxConns(go1.2+) support; some bugs fixed.
* **v0.2.1** : Added database reverse tool, now support generate go & c++ codes, see [Xorm Tool README](https://github.com/go-xorm/xorm/blob/master/xorm/README.md); some bug fixed.
* **v0.2.0** : Added Cache supported, select is speeder up 3~5x; Added SameMapper for same name between struct and table; Added Sync method for auto added tables, columns, indexes;
* **v0.1.9** : Added postgres and mymysql supported; Added ` and ? supported on Raw SQL even if postgres; Added Cols, StoreEngine, Charset function, Added many column data type supported, please see [Mapping Rules](#mapping).
* **v0.1.8** : Added union index and union unique supported, please see [Mapping Rules](#mapping).
* **v0.1.7** : Added IConnectPool interface and NoneConnectPool, SysConnectPool, SimpleConnectPool the three implements. You can choose one of them and the default is SysConnectPool. You can customrize your own connection pool. struct Engine added Close method, It should be invoked before system exit.
* **v0.1.6** : Added conversion interface support; added struct derive support; added single mapping support
* **v0.1.5** : Added multi threads support; added Sql() function for struct query; Get function changed return inteface; MakeSession and Create are instead with NewSession and NewEngine.
* **v0.1.4** : Added simple cascade load support; added more data type supports.
* **v0.1.3** : Find function now supports both slice and map; Add Table function for multi tables and temperory tables support
* **v0.1.2** : Insert function now supports both struct and slice pointer parameters, batch inserting and auto transaction
* **v0.1.1** : Add Id, In functions and improved README
* **v0.1.0** : Initial release.

5
vendor/xorm.io/xorm/Makefile generated vendored
View File

@ -187,6 +187,11 @@ test-sqlite: go-check
$(GO) test -v -race -cache=$(TEST_CACHE_ENABLE) -db=sqlite3 -conn_str="./test.db?cache=shared&mode=rwc" \
-quote=$(TEST_QUOTE_POLICY) -coverprofile=sqlite.$(TEST_QUOTE_POLICY).$(TEST_CACHE_ENABLE).coverage.out -covermode=atomic
.PHONY: test-sqlite-schema
test-sqlite-schema: go-check
$(GO) test -v -race -schema=xorm -cache=$(TEST_CACHE_ENABLE) -db=sqlite3 -conn_str="./test.db?cache=shared&mode=rwc" \
-quote=$(TEST_QUOTE_POLICY) -coverprofile=sqlite.$(TEST_QUOTE_POLICY).$(TEST_CACHE_ENABLE).coverage.out -covermode=atomic
.PHONY: test-sqlite\#%
test-sqlite\#%: go-check
$(GO) test -v -race -run $* -cache=$(TEST_CACHE_ENABLE) -db=sqlite3 -conn_str="./test.db?cache=shared&mode=rwc" \

23
vendor/xorm.io/xorm/README.md generated vendored
View File

@ -8,33 +8,30 @@ Xorm is a simple and powerful ORM for Go.
[![](https://goreportcard.com/badge/xorm.io/xorm)](https://goreportcard.com/report/xorm.io/xorm)
[![Join the chat at https://img.shields.io/discord/323460943201959939.svg](https://img.shields.io/discord/323460943201959939.svg)](https://discord.gg/HuR2CF3)
## Notice
v1.0.0 has some break changes from v0.8.2.
- Removed some non gonic function name `Id`, `Sql`, please use `ID`, `SQL` instead.
- Removed the dependent from `xorm.io/core` and moved the codes to `xorm.io/xorm/core`, `xorm.io/xorm/names`, `xorm.io/xorm/schemas` and others.
- Renamed some interface names. i.e. `core.IMapper` -> `names.Mapper`, `core.ILogger` -> `log.Logger`.
## Features
* Struct <-> Table Mapping Support
* Chainable APIs
* Transaction Support
* Both ORM and raw SQL operation Support
* Sync database schema Support
* Query Cache speed up
* Database Reverse support via [xorm.io/reverse](https://xorm.io/reverse)
* Simple cascade loading support
* Optimistic Locking support
* SQL Builder support via [xorm.io/builder](https://xorm.io/builder)
* Automatical Read/Write seperatelly
* Postgres schema support
* Context Cache support
* Support log/SQLLog context
## Drivers Support
@ -64,7 +61,7 @@ Drivers for Go's sql package which currently support database/sql includes:
* [Manual](http://xorm.io/docs)
* [GoDoc](http://godoc.org/xorm.io/xorm)
* [GoDoc](http://pkg.go.dev/xorm.io/xorm)
## Quick Start

22
vendor/xorm.io/xorm/README_CN.md generated vendored
View File

@ -8,31 +8,29 @@ xorm 是一个简单而强大的Go语言ORM库. 通过它可以使数据库操
[![](https://goreportcard.com/badge/xorm.io/xorm)](https://goreportcard.com/report/xorm.io/xorm)
[![Join the chat at https://img.shields.io/discord/323460943201959939.svg](https://img.shields.io/discord/323460943201959939.svg)](https://discord.gg/HuR2CF3)
## Notice
v1.0.0 相对于 v0.8.2 有以下不兼容的变更:
- 移除了部分不符合Go语言命名的函数`Id`, `Sql`,请使用 `ID`, `SQL` 替代。
- 删除了对 `xorm.io/core` 的依赖。大部分代码迁移到了 `xorm.io/xorm/core`, `xorm.io/xorm/names`, `xorm.io/xorm/schemas` 等等几个包中.
- 重命名了几个结构体,如: `core.IMapper` -> `names.Mapper`, `core.ILogger` -> `log.Logger`.
## 特性
* 支持 Struct 和数据库表之间的灵活映射,并支持自动同步
* 事务支持
* 同时支持原始SQL语句和ORM操作的混合执行
* 使用连写来简化调用
* 支持使用ID, In, Where, Limit, Join, Having, Table, SQL, Cols等函数和结构体等方式作为条件
* 支持级联加载Struct
* Schema支持仅Postgres
* 支持缓存
* 通过 [xorm.io/reverse](https://xorm.io/reverse) 支持根据数据库自动生成 xorm 结构体
* 支持记录版本(即乐观锁)
* 通过 [xorm.io/builder](https://xorm.io/builder) 内置 SQL Builder 支持
* 上下文缓存支持
* 支持日志上下文
## 驱动支持
@ -62,7 +60,7 @@ xorm 是一个简单而强大的Go语言ORM库. 通过它可以使数据库操
* [操作指南](http://xorm.io/docs)
* [Godoc代码文档](http://godoc.org/xorm.io/xorm)
* [Godoc代码文档](http://pkg.go.dev/xorm.io/xorm)
# 快速开始

View File

@ -14,6 +14,7 @@ import (
"xorm.io/xorm/schemas"
)
// URI represents an uri to visit database
type URI struct {
DBType schemas.DBType
Proto string
@ -29,6 +30,13 @@ type URI struct {
Schema string
}
// SetSchema set schema
func (uri *URI) SetSchema(schema string) {
if uri.DBType == schemas.POSTGRES {
uri.Schema = schema
}
}
// Dialect represents a kind of database
type Dialect interface {
Init(*core.DB, *URI) error

View File

@ -1000,7 +1000,7 @@ func (db *postgres) IsColumnExist(ctx context.Context, tableName, colName string
}
func (db *postgres) GetColumns(ctx context.Context, tableName string) ([]string, map[string]*schemas.Column, error) {
args := []interface{}{tableName}
args := []interface{}{db.uri.Schema, tableName, db.uri.Schema}
s := `SELECT column_name, column_default, is_nullable, data_type, character_maximum_length,
CASE WHEN p.contype = 'p' THEN true ELSE false END AS primarykey,
CASE WHEN p.contype = 'u' THEN true ELSE false END AS uniquekey
@ -1011,14 +1011,7 @@ FROM pg_attribute f
LEFT JOIN pg_constraint p ON p.conrelid = c.oid AND f.attnum = ANY (p.conkey)
LEFT JOIN pg_class AS g ON p.confrelid = g.oid
LEFT JOIN INFORMATION_SCHEMA.COLUMNS s ON s.column_name=f.attname AND c.relname=s.table_name
WHERE c.relkind = 'r'::char AND c.relname = $1%s AND f.attnum > 0 ORDER BY f.attnum;`
var f string
if len(db.uri.Schema) != 0 {
args = append(args, db.uri.Schema)
f = " AND s.table_schema = $2"
}
s = fmt.Sprintf(s, f)
WHERE n.nspname= $1 AND c.relkind = 'r'::char AND c.relname = $2 AND s.table_schema = $3 AND f.attnum > 0 ORDER BY f.attnum;`
rows, err := db.DB().QueryContext(ctx, s, args...)
if err != nil {
@ -1071,6 +1064,8 @@ WHERE c.relkind = 'r'::char AND c.relname = $1%s AND f.attnum > 0 ORDER BY f.att
col.DefaultIsEmpty = false
if strings.HasPrefix(col.Default, "nextval(") {
col.IsAutoIncrement = true
col.Default = ""
col.DefaultIsEmpty = true
}
} else {
col.DefaultIsEmpty = true

96
vendor/xorm.io/xorm/engine.go generated vendored
View File

@ -5,8 +5,6 @@
package xorm
import (
"bufio"
"bytes"
"context"
"database/sql"
"errors"
@ -32,7 +30,6 @@ import (
// Commonly, an application only need one engine
type Engine struct {
cacherMgr *caches.Manager
db *core.DB
defaultContext context.Context
dialect dialects.Dialect
engineGroup *EngineGroup
@ -353,42 +350,54 @@ func (engine *Engine) DumpTables(tables []*schemas.Table, w io.Writer, tp ...sch
// dumpTables dump database all table structs and data to w with specify db type
func (engine *Engine) dumpTables(tables []*schemas.Table, w io.Writer, tp ...schemas.DBType) error {
var dialect dialects.Dialect
var distDBName string
var dstDialect dialects.Dialect
if len(tp) == 0 {
dialect = engine.dialect
distDBName = string(engine.dialect.URI().DBType)
dstDialect = engine.dialect
} else {
dialect = dialects.QueryDialect(tp[0])
if dialect == nil {
dstDialect = dialects.QueryDialect(tp[0])
if dstDialect == nil {
return errors.New("Unsupported database type")
}
dialect.Init(nil, engine.dialect.URI())
distDBName = string(tp[0])
uri := engine.dialect.URI()
destURI := *uri
dstDialect.Init(nil, &destURI)
}
_, err := io.WriteString(w, fmt.Sprintf("/*Generated by xorm %s, from %s to %s*/\n\n",
time.Now().In(engine.TZLocation).Format("2006-01-02 15:04:05"), engine.dialect.URI().DBType, strings.ToUpper(distDBName)))
time.Now().In(engine.TZLocation).Format("2006-01-02 15:04:05"), engine.dialect.URI().DBType, dstDialect.URI().DBType))
if err != nil {
return err
}
for i, table := range tables {
tableName := table.Name
if dstDialect.URI().Schema != "" {
tableName = fmt.Sprintf("%s.%s", dstDialect.URI().Schema, table.Name)
}
originalTableName := table.Name
if engine.dialect.URI().Schema != "" {
originalTableName = fmt.Sprintf("%s.%s", engine.dialect.URI().Schema, table.Name)
}
if i > 0 {
_, err = io.WriteString(w, "\n")
if err != nil {
return err
}
}
sqls, _ := dialect.CreateTableSQL(table, "")
sqls, _ := dstDialect.CreateTableSQL(table, tableName)
for _, s := range sqls {
_, err = io.WriteString(w, s+";\n")
if err != nil {
return err
}
}
if len(table.PKColumns()) > 0 && dstDialect.URI().DBType == schemas.MSSQL {
fmt.Fprintf(w, "SET IDENTITY_INSERT [%s] ON;\n", table.Name)
}
for _, index := range table.Indexes {
_, err = io.WriteString(w, dialect.CreateIndexSQL(table.Name, index)+";\n")
_, err = io.WriteString(w, dstDialect.CreateIndexSQL(table.Name, index)+";\n")
if err != nil {
return err
}
@ -396,9 +405,9 @@ func (engine *Engine) dumpTables(tables []*schemas.Table, w io.Writer, tp ...sch
cols := table.ColumnsSeq()
colNames := engine.dialect.Quoter().Join(cols, ", ")
destColNames := dialect.Quoter().Join(cols, ", ")
destColNames := dstDialect.Quoter().Join(cols, ", ")
rows, err := engine.DB().QueryContext(engine.defaultContext, "SELECT "+colNames+" FROM "+engine.Quote(table.Name))
rows, err := engine.DB().QueryContext(engine.defaultContext, "SELECT "+colNames+" FROM "+engine.Quote(originalTableName))
if err != nil {
return err
}
@ -411,7 +420,7 @@ func (engine *Engine) dumpTables(tables []*schemas.Table, w io.Writer, tp ...sch
return err
}
_, err = io.WriteString(w, "INSERT INTO "+dialect.Quoter().Quote(table.Name)+" ("+destColNames+") VALUES (")
_, err = io.WriteString(w, "INSERT INTO "+dstDialect.Quoter().Quote(tableName)+" ("+destColNames+") VALUES (")
if err != nil {
return err
}
@ -434,7 +443,7 @@ func (engine *Engine) dumpTables(tables []*schemas.Table, w io.Writer, tp ...sch
}
} else if col.SQLType.IsBlob() {
if reflect.TypeOf(d).Kind() == reflect.Slice {
temp += fmt.Sprintf(", %s", dialect.FormatBytes(d.([]byte)))
temp += fmt.Sprintf(", %s", dstDialect.FormatBytes(d.([]byte)))
} else if reflect.TypeOf(d).Kind() == reflect.String {
temp += fmt.Sprintf(", '%s'", d.(string))
}
@ -481,8 +490,8 @@ func (engine *Engine) dumpTables(tables []*schemas.Table, w io.Writer, tp ...sch
}
// FIXME: Hack for postgres
if dialect.URI().DBType == schemas.POSTGRES && table.AutoIncrColumn() != nil {
_, err = io.WriteString(w, "SELECT setval('"+table.Name+"_id_seq', COALESCE((SELECT MAX("+table.AutoIncrColumn().Name+") + 1 FROM "+dialect.Quoter().Quote(table.Name)+"), 1), false);\n")
if dstDialect.URI().DBType == schemas.POSTGRES && table.AutoIncrColumn() != nil {
_, err = io.WriteString(w, "SELECT setval('"+tableName+"_id_seq', COALESCE((SELECT MAX("+table.AutoIncrColumn().Name+") + 1 FROM "+dstDialect.Quoter().Quote(tableName)+"), 1), false);\n")
if err != nil {
return err
}
@ -1158,49 +1167,16 @@ func (engine *Engine) SumsInt(bean interface{}, colNames ...string) ([]int64, er
// ImportFile SQL DDL file
func (engine *Engine) ImportFile(ddlPath string) ([]sql.Result, error) {
file, err := os.Open(ddlPath)
if err != nil {
return nil, err
}
defer file.Close()
return engine.Import(file)
session := engine.NewSession()
defer session.Close()
return session.ImportFile(ddlPath)
}
// Import SQL DDL from io.Reader
func (engine *Engine) Import(r io.Reader) ([]sql.Result, error) {
var results []sql.Result
var lastError error
scanner := bufio.NewScanner(r)
semiColSpliter := func(data []byte, atEOF bool) (advance int, token []byte, err error) {
if atEOF && len(data) == 0 {
return 0, nil, nil
}
if i := bytes.IndexByte(data, ';'); i >= 0 {
return i + 1, data[0:i], nil
}
// If we're at EOF, we have a final, non-terminated line. Return it.
if atEOF {
return len(data), data, nil
}
// Request more data.
return 0, nil, nil
}
scanner.Split(semiColSpliter)
for scanner.Scan() {
query := strings.Trim(scanner.Text(), " \t\n\r")
if len(query) > 0 {
result, err := engine.DB().ExecContext(engine.defaultContext, query)
results = append(results, result)
if err != nil {
return nil, err
}
}
}
return results, lastError
session := engine.NewSession()
defer session.Close()
return session.Import(r)
}
// nowTime return current time
@ -1245,7 +1221,7 @@ func (engine *Engine) SetTZDatabase(tz *time.Location) {
// SetSchema sets the schema of database
func (engine *Engine) SetSchema(schema string) {
engine.dialect.URI().Schema = schema
engine.dialect.URI().SetSchema(schema)
}
// Unscoped always disable struct tag "deleted"

View File

@ -161,17 +161,17 @@ func (eg *EngineGroup) SetMapper(mapper names.Mapper) {
// SetMaxIdleConns set the max idle connections on pool, default is 2
func (eg *EngineGroup) SetMaxIdleConns(conns int) {
eg.Engine.db.SetMaxIdleConns(conns)
eg.Engine.dialect.DB().SetMaxIdleConns(conns)
for i := 0; i < len(eg.slaves); i++ {
eg.slaves[i].db.SetMaxIdleConns(conns)
eg.slaves[i].dialect.DB().SetMaxIdleConns(conns)
}
}
// SetMaxOpenConns is only available for go 1.2+
func (eg *EngineGroup) SetMaxOpenConns(conns int) {
eg.Engine.db.SetMaxOpenConns(conns)
eg.Engine.dialect.DB().SetMaxOpenConns(conns)
for i := 0; i < len(eg.slaves); i++ {
eg.slaves[i].db.SetMaxOpenConns(conns)
eg.slaves[i].dialect.DB().SetMaxOpenConns(conns)
}
}

2
vendor/xorm.io/xorm/go.mod generated vendored
View File

@ -12,5 +12,5 @@ require (
github.com/syndtr/goleveldb v1.0.0
github.com/ziutek/mymysql v1.5.4
google.golang.org/appengine v1.6.0 // indirect
xorm.io/builder v0.3.6
xorm.io/builder v0.3.7
)

3
vendor/xorm.io/xorm/go.sum generated vendored
View File

@ -2,6 +2,7 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.37.4 h1:glPeL3BQJsbF6aIIYfZizMwc5LTYz250bDMjttbBGAU=
cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw=
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
@ -159,3 +160,5 @@ honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
xorm.io/builder v0.3.6 h1:ha28mQ2M+TFx96Hxo+iq6tQgnkC9IZkM6D8w9sKHHF8=
xorm.io/builder v0.3.6/go.mod h1:LEFAPISnRzG+zxaxj2vPicRwz67BdhFreKg8yv8/TgU=
xorm.io/builder v0.3.7 h1:2pETdKRK+2QG4mLX4oODHEhn5Z8j1m8sXa7jfu+/SZI=
xorm.io/builder v0.3.7/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=

2
vendor/xorm.io/xorm/interface.go generated vendored
View File

@ -59,6 +59,7 @@ type Interface interface {
QueryString(sqlOrArgs ...interface{}) ([]map[string]string, error)
Rows(bean interface{}) (*Rows, error)
SetExpr(string, interface{}) *Session
Select(string) *Session
SQL(interface{}, ...interface{}) *Session
Sum(bean interface{}, colName string) (float64, error)
SumInt(bean interface{}, colName string) (int64, error)
@ -91,6 +92,7 @@ type EngineInterface interface {
GetTableMapper() names.Mapper
GetTZDatabase() *time.Location
GetTZLocation() *time.Location
ImportFile(fp string) ([]sql.Result, error)
MapCacher(interface{}, caches.Cacher) error
NewSession() *Session
NoAutoTime() *Session

79
vendor/xorm.io/xorm/internal/statements/pk.go generated vendored Normal file
View File

@ -0,0 +1,79 @@
// Copyright 2017 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 statements
import (
"fmt"
"reflect"
"xorm.io/builder"
"xorm.io/xorm/schemas"
)
var (
ptrPkType = reflect.TypeOf(&schemas.PK{})
pkType = reflect.TypeOf(schemas.PK{})
stringType = reflect.TypeOf("")
intType = reflect.TypeOf(int64(0))
uintType = reflect.TypeOf(uint64(0))
)
// ID generate "where id = ? " statement or for composite key "where key1 = ? and key2 = ?"
func (statement *Statement) ID(id interface{}) *Statement {
switch t := id.(type) {
case *schemas.PK:
statement.idParam = *t
case schemas.PK:
statement.idParam = t
case string, int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
statement.idParam = schemas.PK{id}
default:
idValue := reflect.ValueOf(id)
idType := idValue.Type()
switch idType.Kind() {
case reflect.String:
statement.idParam = schemas.PK{idValue.Convert(stringType).Interface()}
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
statement.idParam = schemas.PK{idValue.Convert(intType).Interface()}
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
statement.idParam = schemas.PK{idValue.Convert(uintType).Interface()}
case reflect.Slice:
if idType.ConvertibleTo(pkType) {
statement.idParam = idValue.Convert(pkType).Interface().(schemas.PK)
}
case reflect.Ptr:
if idType.ConvertibleTo(ptrPkType) {
statement.idParam = idValue.Convert(ptrPkType).Elem().Interface().(schemas.PK)
}
}
}
if statement.idParam == nil {
statement.LastError = fmt.Errorf("ID param %#v is not supported", id)
}
return statement
}
func (statement *Statement) ProcessIDParam() error {
if statement.idParam == nil || statement.RefTable == nil {
return nil
}
if len(statement.RefTable.PrimaryKeys) != len(statement.idParam) {
fmt.Println("=====", statement.RefTable.PrimaryKeys, statement.idParam)
return fmt.Errorf("ID condition is error, expect %d primarykeys, there are %d",
len(statement.RefTable.PrimaryKeys),
len(statement.idParam),
)
}
for i, col := range statement.RefTable.PKColumns() {
var colName = statement.colName(col, statement.TableName())
statement.cond = statement.cond.And(builder.Eq{colName: statement.idParam[i]})
}
return nil
}

View File

@ -153,6 +153,7 @@ func (statement *Statement) GenGetSQL(bean interface{}) (string, []interface{},
return sqlStr, append(statement.joinArgs, condArgs...), nil
}
// GenCountSQL generates the SQL for counting
func (statement *Statement) GenCountSQL(beans ...interface{}) (string, []interface{}, error) {
if statement.RawSQL != "" {
return statement.GenRawSQL(), statement.RawParams, nil
@ -171,6 +172,8 @@ func (statement *Statement) GenCountSQL(beans ...interface{}) (string, []interfa
if len(selectSQL) <= 0 {
if statement.IsDistinct {
selectSQL = fmt.Sprintf("count(DISTINCT %s)", statement.ColumnStr())
} else if statement.ColumnStr() != "" {
selectSQL = fmt.Sprintf("count(%s)", statement.ColumnStr())
} else {
selectSQL = "count(*)"
}

View File

@ -41,7 +41,7 @@ type Statement struct {
tagParser *tags.Parser
Start int
LimitN *int
idParam *schemas.PK
idParam schemas.PK
OrderStr string
JoinStr string
joinArgs []interface{}
@ -319,34 +319,6 @@ func (statement *Statement) TableName() string {
return statement.tableName
}
// ID generate "where id = ? " statement or for composite key "where key1 = ? and key2 = ?"
func (statement *Statement) ID(id interface{}) *Statement {
idValue := reflect.ValueOf(id)
idType := reflect.TypeOf(idValue.Interface())
switch idType {
case ptrPkType:
if pkPtr, ok := (id).(*schemas.PK); ok {
statement.idParam = pkPtr
return statement
}
case pkType:
if pk, ok := (id).(schemas.PK); ok {
statement.idParam = &pk
return statement
}
}
switch idType.Kind() {
case reflect.String:
statement.idParam = &schemas.PK{idValue.Convert(reflect.TypeOf("")).Interface()}
return statement
}
statement.idParam = &schemas.PK{id}
return statement
}
// Incr Generate "Update ... Set column = column + arg" statement
func (statement *Statement) Incr(column string, arg ...interface{}) *Statement {
if len(arg) > 0 {
@ -981,25 +953,6 @@ func convertSQLOrArgs(sqlOrArgs ...interface{}) (string, []interface{}, error) {
return "", nil, ErrUnSupportedType
}
func (statement *Statement) ProcessIDParam() error {
if statement.idParam == nil || statement.RefTable == nil {
return nil
}
if len(statement.RefTable.PrimaryKeys) != len(*statement.idParam) {
return fmt.Errorf("ID condition is error, expect %d primarykeys, there are %d",
len(statement.RefTable.PrimaryKeys),
len(*statement.idParam),
)
}
for i, col := range statement.RefTable.PKColumns() {
var colName = statement.colName(col, statement.TableName())
statement.cond = statement.cond.And(builder.Eq{colName: (*(statement.idParam))[i]})
}
return nil
}
func (statement *Statement) joinColumns(cols []*schemas.Column, includeTableName bool) string {
var colnames = make([]string, len(cols))
for i, col := range cols {

View File

@ -1,16 +0,0 @@
// Copyright 2017 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 statements
import (
"reflect"
"xorm.io/xorm/schemas"
)
var (
ptrPkType = reflect.TypeOf(&schemas.PK{})
pkType = reflect.TypeOf(schemas.PK{})
)

View File

@ -18,58 +18,73 @@ import (
"xorm.io/xorm/schemas"
)
func (statement *Statement) ifAddColUpdate(col *schemas.Column, includeVersion, includeUpdated, includeNil,
includeAutoIncr, update bool) (bool, error) {
columnMap := statement.ColumnMap
omitColumnMap := statement.OmitColumnMap
unscoped := statement.unscoped
if !includeVersion && col.IsVersion {
return false, nil
}
if col.IsCreated && !columnMap.Contain(col.Name) {
return false, nil
}
if !includeUpdated && col.IsUpdated {
return false, nil
}
if !includeAutoIncr && col.IsAutoIncrement {
return false, nil
}
if col.IsDeleted && !unscoped {
return false, nil
}
if omitColumnMap.Contain(col.Name) {
return false, nil
}
if len(columnMap) > 0 && !columnMap.Contain(col.Name) {
return false, nil
}
if col.MapType == schemas.ONLYFROMDB {
return false, nil
}
if statement.IncrColumns.IsColExist(col.Name) {
return false, nil
} else if statement.DecrColumns.IsColExist(col.Name) {
return false, nil
} else if statement.ExprColumns.IsColExist(col.Name) {
return false, nil
}
return true, nil
}
// BuildUpdates auto generating update columnes and values according a struct
func (statement *Statement) BuildUpdates(bean interface{},
func (statement *Statement) BuildUpdates(tableValue reflect.Value,
includeVersion, includeUpdated, includeNil,
includeAutoIncr, update bool) ([]string, []interface{}, error) {
//engine := statement.Engine
table := statement.RefTable
allUseBool := statement.allUseBool
useAllCols := statement.useAllCols
mustColumnMap := statement.MustColumnMap
nullableMap := statement.NullableMap
columnMap := statement.ColumnMap
omitColumnMap := statement.OmitColumnMap
unscoped := statement.unscoped
var colNames = make([]string, 0)
var args = make([]interface{}, 0)
for _, col := range table.Columns() {
if !includeVersion && col.IsVersion {
continue
ok, err := statement.ifAddColUpdate(col, includeVersion, includeUpdated, includeNil,
includeAutoIncr, update)
if err != nil {
return nil, nil, err
}
if col.IsCreated && !columnMap.Contain(col.Name) {
continue
}
if !includeUpdated && col.IsUpdated {
continue
}
if !includeAutoIncr && col.IsAutoIncrement {
continue
}
if col.IsDeleted && !unscoped {
continue
}
if omitColumnMap.Contain(col.Name) {
continue
}
if len(columnMap) > 0 && !columnMap.Contain(col.Name) {
if !ok {
continue
}
if col.MapType == schemas.ONLYFROMDB {
continue
}
if statement.IncrColumns.IsColExist(col.Name) {
continue
} else if statement.DecrColumns.IsColExist(col.Name) {
continue
} else if statement.ExprColumns.IsColExist(col.Name) {
continue
}
fieldValuePtr, err := col.ValueOf(bean)
fieldValuePtr, err := col.ValueOfV(&tableValue)
if err != nil {
return nil, nil, err
}
@ -273,9 +288,6 @@ func (statement *Statement) BuildUpdates(bean interface{},
APPEND:
args = append(args, val)
if col.IsPrimaryKey {
continue
}
colNames = append(colNames, fmt.Sprintf("%v = ?", statement.quote(col.Name)))
}

View File

@ -27,3 +27,4 @@ func SplitNNoCase(s, sep string, n int) []string {
}
return strings.SplitN(s, s[idx:idx+len(sep)], n)
}

View File

@ -6,6 +6,7 @@ package names
import (
"reflect"
"sync"
)
// TableName table name interface to define customerize table name
@ -15,23 +16,40 @@ type TableName interface {
var (
tpTableName = reflect.TypeOf((*TableName)(nil)).Elem()
tvCache sync.Map
)
func GetTableName(mapper Mapper, v reflect.Value) string {
if t, ok := v.Interface().(TableName); ok {
return t.TableName()
}
if v.Type().Implements(tpTableName) {
return v.Interface().(TableName).TableName()
}
if v.Kind() == reflect.Ptr {
v = v.Elem()
if t, ok := v.Interface().(TableName); ok {
return t.TableName()
}
if v.Type().Implements(tpTableName) {
return v.Interface().(TableName).TableName()
}
} else if v.CanAddr() {
v1 := v.Addr()
if v1.Type().Implements(tpTableName) {
return v1.Interface().(TableName).TableName()
}
} else {
name, ok := tvCache.Load(v.Type())
if ok {
if name.(string) != "" {
return name.(string)
}
} else {
v2 := reflect.New(v.Type())
if v2.Type().Implements(tpTableName) {
tableName := v2.Interface().(TableName).TableName()
tvCache.Store(v.Type(), tableName)
return tableName
}
tvCache.Store(v.Type(), "")
}
}
return mapper.Obj2Table(v.Type().Name())

View File

@ -21,7 +21,7 @@ const (
type Column struct {
Name string
TableName string
FieldName string
FieldName string // Avaiable only when parsed from a struct
SQLType SQLType
IsJSON bool
Length int

View File

@ -53,13 +53,9 @@ func (table *Table) ColumnsSeq() []string {
}
func (table *Table) columnsByName(name string) []*Column {
n := len(name)
for k := range table.columnsMap {
if len(k) != n {
continue
}
for k, cols := range table.columnsMap {
if strings.EqualFold(k, name) {
return table.columnsMap[k]
return cols
}
}
return nil

View File

@ -122,7 +122,13 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error
for i := 0; i < size; i++ {
v := sliceValue.Index(i)
vv := reflect.Indirect(v)
var vv reflect.Value
switch v.Kind() {
case reflect.Interface:
vv = reflect.Indirect(v.Elem())
default:
vv = reflect.Indirect(v)
}
elemValue := v.Interface()
var colPlaces []string

View File

@ -5,8 +5,11 @@
package xorm
import (
"bufio"
"database/sql"
"fmt"
"io"
"os"
"strings"
"xorm.io/xorm/internal/utils"
@ -432,3 +435,56 @@ func (session *Session) Sync2(beans ...interface{}) error {
return nil
}
// ImportFile SQL DDL file
func (session *Session) ImportFile(ddlPath string) ([]sql.Result, error) {
file, err := os.Open(ddlPath)
if err != nil {
return nil, err
}
defer file.Close()
return session.Import(file)
}
// Import SQL DDL from io.Reader
func (session *Session) Import(r io.Reader) ([]sql.Result, error) {
var results []sql.Result
var lastError error
scanner := bufio.NewScanner(r)
var inSingleQuote bool
semiColSpliter := func(data []byte, atEOF bool) (advance int, token []byte, err error) {
if atEOF && len(data) == 0 {
return 0, nil, nil
}
for i, b := range data {
if b == '\'' {
inSingleQuote = !inSingleQuote
}
if !inSingleQuote && b == ';' {
return i + 1, data[0:i], nil
}
}
// If we're at EOF, we have a final, non-terminated line. Return it.
if atEOF {
return len(data), data, nil
}
// Request more data.
return 0, nil, nil
}
scanner.Split(semiColSpliter)
for scanner.Scan() {
query := strings.Trim(scanner.Text(), " \t\n\r")
if len(query) > 0 {
result, err := session.Exec(query)
results = append(results, result)
if err != nil {
return nil, err
}
}
}
return results, lastError
}

View File

@ -177,7 +177,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
}
if session.statement.ColumnStr() == "" {
colNames, args, err = session.statement.BuildUpdates(bean, false, false,
colNames, args, err = session.statement.BuildUpdates(v, false, false,
false, false, true)
} else {
colNames, args, err = session.genUpdateColumns(bean)