1
0
Fork 0
mirror of https://codeberg.org/forgejo/forgejo.git synced 2024-12-22 12:54:53 -05:00

Upgrade xorm to v0.7.9 to fix some bugs (#8354)

* upgrade xorm to v0.7.9 to fix some bugs

* upgrade xormstore to v1.3.1
This commit is contained in:
Lunny Xiao 2019-10-03 04:47:20 +08:00 committed by techknowlogick
parent 3be43dc5e3
commit c9f819eae0
15 changed files with 381 additions and 238 deletions

4
go.mod
View file

@ -48,7 +48,7 @@ require (
github.com/go-redis/redis v6.15.2+incompatible github.com/go-redis/redis v6.15.2+incompatible
github.com/go-sql-driver/mysql v1.4.1 github.com/go-sql-driver/mysql v1.4.1
github.com/go-swagger/go-swagger v0.20.1 github.com/go-swagger/go-swagger v0.20.1
github.com/go-xorm/xorm v0.7.8 github.com/go-xorm/xorm v0.7.9
github.com/gobwas/glob v0.2.3 github.com/gobwas/glob v0.2.3
github.com/gogits/chardet v0.0.0-20150115103509-2404f7772561 github.com/gogits/chardet v0.0.0-20150115103509-2404f7772561
github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14 github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14
@ -64,7 +64,7 @@ require (
github.com/klauspost/compress v0.0.0-20161025140425-8df558b6cb6f github.com/klauspost/compress v0.0.0-20161025140425-8df558b6cb6f
github.com/klauspost/cpuid v0.0.0-20160302075316-09cded8978dc // indirect github.com/klauspost/cpuid v0.0.0-20160302075316-09cded8978dc // indirect
github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6 // indirect github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6 // indirect
github.com/lafriks/xormstore v1.3.0 github.com/lafriks/xormstore v1.3.1
github.com/lib/pq v1.2.0 github.com/lib/pq v1.2.0
github.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96 github.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96
github.com/lunny/levelqueue v0.0.0-20190217115915-02b525a4418e github.com/lunny/levelqueue v0.0.0-20190217115915-02b525a4418e

8
go.sum
View file

@ -249,8 +249,8 @@ github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013 h1:l
github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013/go.mod h1:b65mBPzqzZWxOZGxSWrqs4GInLIn+u99Q9q7p+GKni0= github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013/go.mod h1:b65mBPzqzZWxOZGxSWrqs4GInLIn+u99Q9q7p+GKni0=
github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:9wScpmSP5A3Bk8V3XHWUcJmYTh+ZnlHVyc+A4oZYS3Y= 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/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:56xuuqnHyryaerycW3BfssRdxQstACi0Epw/yC5E2xM=
github.com/go-xorm/xorm v0.7.8 h1:rKxZJB9mWQ9Nw2TbjsepiThR031jkGePOWXwTtEAU08= github.com/go-xorm/xorm v0.7.9 h1:LZze6n1UvRmM5gpL9/U9Gucwqo6aWlFVlfcHKH10qA0=
github.com/go-xorm/xorm v0.7.8/go.mod h1:XiVxrMMIhFkwSkh96BW7PACl7UhLtx2iJIHMdmjh5sQ= github.com/go-xorm/xorm v0.7.9/go.mod h1:XiVxrMMIhFkwSkh96BW7PACl7UhLtx2iJIHMdmjh5sQ=
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= 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/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
@ -384,8 +384,8 @@ github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lafriks/xormstore v1.3.0 h1:9A2wAZrdEXtTgfjCFtclPz3pwnmmxY7sJxQgIi62li4= github.com/lafriks/xormstore v1.3.1 h1:KpzRUamSV3zmA85Kzw+PZOU9wgMbYsNzuDzLuBMbxpA=
github.com/lafriks/xormstore v1.3.0/go.mod h1:RAhtOztWBjK9xeZpXwKq59rhUxoRgo1zfYl0H1mtK7A= github.com/lafriks/xormstore v1.3.1/go.mod h1:qALRD4Vto2Ic7/A5eplMpu5V62mugtSqFysRwz8FETs=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0= github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=

View file

@ -114,7 +114,18 @@ steps:
commands: commands:
- "go test -v -race -db=\"mssql\" -conn_str=\"server=mssql;user id=sa;password=yourStrong(!)Password;database=xorm_test\" -coverprofile=coverage6-1.txt -covermode=atomic" - "go test -v -race -db=\"mssql\" -conn_str=\"server=mssql;user id=sa;password=yourStrong(!)Password;database=xorm_test\" -coverprofile=coverage6-1.txt -covermode=atomic"
- "go test -v -race -db=\"mssql\" -conn_str=\"server=mssql;user id=sa;password=yourStrong(!)Password;database=xorm_test\" -cache=true -coverprofile=coverage6-2.txt -covermode=atomic" - "go test -v -race -db=\"mssql\" -conn_str=\"server=mssql;user id=sa;password=yourStrong(!)Password;database=xorm_test\" -cache=true -coverprofile=coverage6-2.txt -covermode=atomic"
- gocovmerge coverage1-1.txt coverage1-2.txt coverage2-1.txt coverage2-2.txt coverage2.1-1.txt coverage2.1-2.txt coverage3-1.txt coverage3-2.txt coverage4-1.txt coverage4-2.txt coverage5-1.txt coverage5-2.txt coverage6-1.txt coverage6-2.txt > coverage.txt when:
event:
- push
- pull_request
- name: test-tidb
pull: default
image: golang:1.10
commands:
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(tidb:4000)/xorm_test\" -ignore_select_update=true -coverprofile=coverage7-1.txt -covermode=atomic"
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(tidb:4000)/xorm_test\" -ignore_select_update=true -cache=true -coverprofile=coverage7-2.txt -covermode=atomic"
- gocovmerge coverage1-1.txt coverage1-2.txt coverage2-1.txt coverage2-2.txt coverage2.1-1.txt coverage2.1-2.txt coverage3-1.txt coverage3-2.txt coverage4-1.txt coverage4-2.txt coverage5-1.txt coverage5-2.txt coverage6-1.txt coverage6-2.txt coverage7-1.txt coverage7-2.txt > coverage.txt
when: when:
event: event:
- push - push
@ -133,6 +144,15 @@ services:
- tag - tag
- pull_request - pull_request
- name: tidb
pull: default
image: pingcap/tidb:v3.0.3
when:
event:
- push
- tag
- pull_request
- name: pgsql - name: pgsql
pull: default pull: default
image: postgres:9.5 image: postgres:9.5
@ -309,8 +329,23 @@ steps:
commands: commands:
- "go test -v -race -db=\"mssql\" -conn_str=\"server=mssql;user id=sa;password=yourStrong(!)Password;database=xorm_test\" -coverprofile=coverage6-1.txt -covermode=atomic" - "go test -v -race -db=\"mssql\" -conn_str=\"server=mssql;user id=sa;password=yourStrong(!)Password;database=xorm_test\" -coverprofile=coverage6-1.txt -covermode=atomic"
- "go test -v -race -db=\"mssql\" -conn_str=\"server=mssql;user id=sa;password=yourStrong(!)Password;database=xorm_test\" -cache=true -coverprofile=coverage6-2.txt -covermode=atomic" - "go test -v -race -db=\"mssql\" -conn_str=\"server=mssql;user id=sa;password=yourStrong(!)Password;database=xorm_test\" -cache=true -coverprofile=coverage6-2.txt -covermode=atomic"
when:
event:
- push
- pull_request
- name: test-tidb
pull: default
image: golang:1.11
environment:
GO111MODULE: "on"
GOPROXY: "https://goproxy.cn"
commands:
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(tidb:4000)/xorm_test\" -ignore_select_update=true -coverprofile=coverage7-1.txt -covermode=atomic"
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(tidb:4000)/xorm_test\" -ignore_select_update=true -cache=true -coverprofile=coverage7-2.txt -covermode=atomic"
- go get github.com/wadey/gocovmerge - go get github.com/wadey/gocovmerge
- gocovmerge coverage1-1.txt coverage1-2.txt coverage2-1.txt coverage2-2.txt coverage2.1-1.txt coverage2.1-2.txt coverage3-1.txt coverage3-2.txt coverage4-1.txt coverage4-2.txt coverage5-1.txt coverage5-2.txt coverage6-1.txt coverage6-2.txt > coverage.txt - gocovmerge coverage1-1.txt coverage1-2.txt coverage2-1.txt coverage2-2.txt coverage2.1-1.txt coverage2.1-2.txt coverage3-1.txt coverage3-2.txt coverage4-1.txt coverage4-2.txt coverage5-1.txt coverage5-2.txt coverage6-1.txt coverage6-2.txt coverage7-1.txt coverage7-2.txt > coverage.txt
when: when:
event: event:
- push - push
@ -329,6 +364,15 @@ services:
- tag - tag
- pull_request - pull_request
- name: tidb
pull: default
image: pingcap/tidb:v3.0.3
when:
event:
- push
- tag
- pull_request
- name: pgsql - name: pgsql
pull: default pull: default
image: postgres:9.5 image: postgres:9.5
@ -377,13 +421,6 @@ steps:
depth: 50 depth: 50
tags: true tags: true
- name: init_postgres
pull: default
image: postgres:9.5
commands:
- "until psql -U postgres -d xorm_test -h pgsql \\\n -c \"SELECT 1;\" >/dev/null 2>&1; do sleep 1; done\n"
- "psql -U postgres -d xorm_test -h pgsql \\\n -c \"create schema xorm;\"\n"
- name: build - name: build
pull: default pull: default
image: golang:1.12 image: golang:1.12
@ -505,8 +542,22 @@ steps:
commands: commands:
- "go test -v -race -db=\"mssql\" -conn_str=\"server=mssql;user id=sa;password=yourStrong(!)Password;database=xorm_test\" -coverprofile=coverage6-1.txt -covermode=atomic" - "go test -v -race -db=\"mssql\" -conn_str=\"server=mssql;user id=sa;password=yourStrong(!)Password;database=xorm_test\" -coverprofile=coverage6-1.txt -covermode=atomic"
- "go test -v -race -db=\"mssql\" -conn_str=\"server=mssql;user id=sa;password=yourStrong(!)Password;database=xorm_test\" -cache=true -coverprofile=coverage6-2.txt -covermode=atomic" - "go test -v -race -db=\"mssql\" -conn_str=\"server=mssql;user id=sa;password=yourStrong(!)Password;database=xorm_test\" -cache=true -coverprofile=coverage6-2.txt -covermode=atomic"
- go get -u github.com/wadey/gocovmerge when:
- gocovmerge coverage1-1.txt coverage1-2.txt coverage2-1.txt coverage2-2.txt coverage2.1-1.txt coverage2.1-2.txt coverage3-1.txt coverage3-2.txt coverage4-1.txt coverage4-2.txt coverage5-1.txt coverage5-2.txt coverage6-1.txt coverage6-2.txt > coverage.txt event:
- push
- pull_request
- name: test-tidb
pull: default
image: golang:1.12
environment:
GO111MODULE: "on"
GOPROXY: "https://goproxy.cn"
commands:
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(tidb:4000)/xorm_test\" -ignore_select_update=true -coverprofile=coverage7-1.txt -covermode=atomic"
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(tidb:4000)/xorm_test\" -ignore_select_update=true -cache=true -coverprofile=coverage7-2.txt -covermode=atomic"
- go get github.com/wadey/gocovmerge
- gocovmerge coverage1-1.txt coverage1-2.txt coverage2-1.txt coverage2-2.txt coverage2.1-1.txt coverage2.1-2.txt coverage3-1.txt coverage3-2.txt coverage4-1.txt coverage4-2.txt coverage5-1.txt coverage5-2.txt coverage6-1.txt coverage6-2.txt coverage7-1.txt coverage7-2.txt > coverage.txt
when: when:
event: event:
- push - push
@ -525,6 +576,15 @@ services:
- tag - tag
- pull_request - pull_request
- name: tidb
pull: default
image: pingcap/tidb:v3.0.3
when:
event:
- push
- tag
- pull_request
- name: pgsql - name: pgsql
pull: default pull: default
image: postgres:9.5 image: postgres:9.5
@ -573,13 +633,6 @@ steps:
depth: 50 depth: 50
tags: true tags: true
- name: init_postgres
pull: default
image: postgres:9.5
commands:
- "until psql -U postgres -d xorm_test -h pgsql \\\n -c \"SELECT 1;\" >/dev/null 2>&1; do sleep 1; done\n"
- "psql -U postgres -d xorm_test -h pgsql \\\n -c \"create schema xorm;\"\n"
- name: build - name: build
pull: default pull: default
image: golang:1.13 image: golang:1.13
@ -701,8 +754,22 @@ steps:
commands: commands:
- "go test -v -race -db=\"mssql\" -conn_str=\"server=mssql;user id=sa;password=yourStrong(!)Password;database=xorm_test\" -coverprofile=coverage6-1.txt -covermode=atomic" - "go test -v -race -db=\"mssql\" -conn_str=\"server=mssql;user id=sa;password=yourStrong(!)Password;database=xorm_test\" -coverprofile=coverage6-1.txt -covermode=atomic"
- "go test -v -race -db=\"mssql\" -conn_str=\"server=mssql;user id=sa;password=yourStrong(!)Password;database=xorm_test\" -cache=true -coverprofile=coverage6-2.txt -covermode=atomic" - "go test -v -race -db=\"mssql\" -conn_str=\"server=mssql;user id=sa;password=yourStrong(!)Password;database=xorm_test\" -cache=true -coverprofile=coverage6-2.txt -covermode=atomic"
- go get -u github.com/wadey/gocovmerge when:
- gocovmerge coverage1-1.txt coverage1-2.txt coverage2-1.txt coverage2-2.txt coverage2.1-1.txt coverage2.1-2.txt coverage3-1.txt coverage3-2.txt coverage4-1.txt coverage4-2.txt coverage5-1.txt coverage5-2.txt coverage6-1.txt coverage6-2.txt > coverage.txt event:
- push
- pull_request
- name: test-tidb
pull: default
image: golang:1.13
environment:
GO111MODULE: "on"
GOPROXY: "https://goproxy.cn"
commands:
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(tidb:4000)/xorm_test\" -ignore_select_update=true -coverprofile=coverage7-1.txt -covermode=atomic"
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(tidb:4000)/xorm_test\" -ignore_select_update=true -cache=true -coverprofile=coverage7-2.txt -covermode=atomic"
- go get github.com/wadey/gocovmerge
- gocovmerge coverage1-1.txt coverage1-2.txt coverage2-1.txt coverage2-2.txt coverage2.1-1.txt coverage2.1-2.txt coverage3-1.txt coverage3-2.txt coverage4-1.txt coverage4-2.txt coverage5-1.txt coverage5-2.txt coverage6-1.txt coverage6-2.txt coverage7-1.txt coverage7-2.txt > coverage.txt
when: when:
event: event:
- push - push
@ -721,6 +788,15 @@ services:
- tag - tag
- pull_request - pull_request
- name: tidb
pull: default
image: pingcap/tidb:v3.0.3
when:
event:
- push
- tag
- pull_request
- name: pgsql - name: pgsql
pull: default pull: default
image: postgres:9.5 image: postgres:9.5

View file

@ -338,8 +338,9 @@ func (db *mssql) TableCheckSql(tableName string) (string, []interface{}) {
func (db *mssql) GetColumns(tableName string) ([]string, map[string]*core.Column, error) { func (db *mssql) GetColumns(tableName string) ([]string, map[string]*core.Column, error) {
args := []interface{}{} args := []interface{}{}
s := `select a.name as name, b.name as ctype,a.max_length,a.precision,a.scale,a.is_nullable as nullable, s := `select a.name as name, b.name as ctype,a.max_length,a.precision,a.scale,a.is_nullable as nullable,
"default_is_null" = (CASE WHEN c.text is null THEN 1 ELSE 0 END),
replace(replace(isnull(c.text,''),'(',''),')','') as vdefault, replace(replace(isnull(c.text,''),'(',''),')','') as vdefault,
ISNULL(i.is_primary_key, 0) ISNULL(i.is_primary_key, 0), a.is_identity as is_identity
from sys.columns a from sys.columns a
left join sys.types b on a.user_type_id=b.user_type_id left join sys.types b on a.user_type_id=b.user_type_id
left join sys.syscomments c on a.default_object_id=c.id left join sys.syscomments c on a.default_object_id=c.id
@ -361,8 +362,8 @@ func (db *mssql) GetColumns(tableName string) ([]string, map[string]*core.Column
for rows.Next() { for rows.Next() {
var name, ctype, vdefault string var name, ctype, vdefault string
var maxLen, precision, scale int var maxLen, precision, scale int
var nullable, isPK bool var nullable, isPK, defaultIsNull, isIncrement bool
err = rows.Scan(&name, &ctype, &maxLen, &precision, &scale, &nullable, &vdefault, &isPK) err = rows.Scan(&name, &ctype, &maxLen, &precision, &scale, &nullable, &defaultIsNull, &vdefault, &isPK, &isIncrement)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
@ -371,8 +372,12 @@ func (db *mssql) GetColumns(tableName string) ([]string, map[string]*core.Column
col.Indexes = make(map[string]int) col.Indexes = make(map[string]int)
col.Name = strings.Trim(name, "` ") col.Name = strings.Trim(name, "` ")
col.Nullable = nullable col.Nullable = nullable
col.DefaultIsEmpty = defaultIsNull
if !defaultIsNull {
col.Default = vdefault col.Default = vdefault
}
col.IsPrimaryKey = isPK col.IsPrimaryKey = isPK
col.IsAutoIncrement = isIncrement
ct := strings.ToUpper(ctype) ct := strings.ToUpper(ctype)
if ct == "DECIMAL" { if ct == "DECIMAL" {
col.Length = precision col.Length = precision
@ -395,15 +400,6 @@ func (db *mssql) GetColumns(tableName string) ([]string, map[string]*core.Column
} }
} }
if col.SQLType.IsText() || col.SQLType.IsTime() {
if col.Default != "" {
col.Default = "'" + col.Default + "'"
} else {
if col.DefaultIsEmpty {
col.Default = "''"
}
}
}
cols[col.Name] = col cols[col.Name] = col
colSeq = append(colSeq, col.Name) colSeq = append(colSeq, col.Name)
} }

View file

@ -345,10 +345,10 @@ func (db *mysql) GetColumns(tableName string) ([]string, map[string]*core.Column
if colDefault != nil { if colDefault != nil {
col.Default = *colDefault col.Default = *colDefault
if col.Default == "" { col.DefaultIsEmpty = false
} else {
col.DefaultIsEmpty = true col.DefaultIsEmpty = true
} }
}
cts := strings.Split(colType, "(") cts := strings.Split(colType, "(")
colName := cts[0] colName := cts[0]
@ -411,13 +411,11 @@ func (db *mysql) GetColumns(tableName string) ([]string, map[string]*core.Column
col.IsAutoIncrement = true col.IsAutoIncrement = true
} }
if col.SQLType.IsText() || col.SQLType.IsTime() { if !col.DefaultIsEmpty {
if col.Default != "" { if col.SQLType.IsText() {
col.Default = "'" + col.Default + "'"
} else if col.SQLType.IsTime() && col.Default != "CURRENT_TIMESTAMP" {
col.Default = "'" + col.Default + "'" col.Default = "'" + col.Default + "'"
} else {
if col.DefaultIsEmpty {
col.Default = "''"
}
} }
} }
cols[col.Name] = col cols[col.Name] = col

View file

@ -1005,16 +1005,18 @@ WHERE c.relkind = 'r'::char AND c.relname = $1%s AND f.attnum > 0 ORDER BY f.att
col.Name = strings.Trim(colName, `" `) col.Name = strings.Trim(colName, `" `)
if colDefault != nil || isPK { if colDefault != nil {
if isPK {
col.IsPrimaryKey = true
} else {
col.Default = *colDefault col.Default = *colDefault
col.DefaultIsEmpty = false
if strings.HasPrefix(col.Default, "nextval(") {
col.IsAutoIncrement = true
} }
} else {
col.DefaultIsEmpty = true
} }
if colDefault != nil && strings.HasPrefix(*colDefault, "nextval(") { if isPK {
col.IsAutoIncrement = true col.IsPrimaryKey = true
} }
col.Nullable = (isNullable == "YES") col.Nullable = (isNullable == "YES")
@ -1043,12 +1045,16 @@ WHERE c.relkind = 'r'::char AND c.relname = $1%s AND f.attnum > 0 ORDER BY f.att
col.Length = maxLen col.Length = maxLen
if col.SQLType.IsText() || col.SQLType.IsTime() { if !col.DefaultIsEmpty {
if col.Default != "" { if col.SQLType.IsText() {
if strings.HasSuffix(col.Default, "::character varying") {
col.Default = strings.TrimRight(col.Default, "::character varying")
} else if !strings.HasPrefix(col.Default, "'") {
col.Default = "'" + col.Default + "'" col.Default = "'" + col.Default + "'"
} else { }
if col.DefaultIsEmpty { } else if col.SQLType.IsTime() {
col.Default = "''" if strings.HasSuffix(col.Default, "::timestamp without time zone") {
col.Default = strings.TrimRight(col.Default, "::timestamp without time zone")
} }
} }
} }

View file

@ -270,6 +270,68 @@ func (db *sqlite3) IsColumnExist(tableName, colName string) (bool, error) {
return false, nil return false, nil
} }
// splitColStr splits a sqlite col strings as fields
func splitColStr(colStr string) []string {
colStr = strings.TrimSpace(colStr)
var results = make([]string, 0, 10)
var lastIdx int
var hasC, hasQuote bool
for i, c := range colStr {
if c == ' ' && !hasQuote {
if hasC {
results = append(results, colStr[lastIdx:i])
hasC = false
}
} else {
if c == '\'' {
hasQuote = !hasQuote
}
if !hasC {
lastIdx = i
}
hasC = true
if i == len(colStr)-1 {
results = append(results, colStr[lastIdx:i+1])
}
}
}
return results
}
func parseString(colStr string) (*core.Column, error) {
fields := splitColStr(colStr)
col := new(core.Column)
col.Indexes = make(map[string]int)
col.Nullable = true
col.DefaultIsEmpty = true
for idx, field := range fields {
if idx == 0 {
col.Name = strings.Trim(strings.Trim(field, "`[] "), `"`)
continue
} else if idx == 1 {
col.SQLType = core.SQLType{Name: field, DefaultLength: 0, DefaultLength2: 0}
continue
}
switch field {
case "PRIMARY":
col.IsPrimaryKey = true
case "AUTOINCREMENT":
col.IsAutoIncrement = true
case "NULL":
if fields[idx-1] == "NOT" {
col.Nullable = false
} else {
col.Nullable = true
}
case "DEFAULT":
col.Default = fields[idx+1]
col.DefaultIsEmpty = false
}
}
return col, nil
}
func (db *sqlite3) GetColumns(tableName string) ([]string, map[string]*core.Column, error) { func (db *sqlite3) GetColumns(tableName string) ([]string, map[string]*core.Column, error) {
args := []interface{}{tableName} args := []interface{}{tableName}
s := "SELECT sql FROM sqlite_master WHERE type='table' and name = ?" s := "SELECT sql FROM sqlite_master WHERE type='table' and name = ?"
@ -299,6 +361,7 @@ func (db *sqlite3) GetColumns(tableName string) ([]string, map[string]*core.Colu
colCreates := reg.FindAllString(name[nStart+1:nEnd], -1) colCreates := reg.FindAllString(name[nStart+1:nEnd], -1)
cols := make(map[string]*core.Column) cols := make(map[string]*core.Column)
colSeq := make([]string, 0) colSeq := make([]string, 0)
for _, colStr := range colCreates { for _, colStr := range colCreates {
reg = regexp.MustCompile(`,\s`) reg = regexp.MustCompile(`,\s`)
colStr = reg.ReplaceAllString(colStr, ",") colStr = reg.ReplaceAllString(colStr, ",")
@ -315,38 +378,11 @@ func (db *sqlite3) GetColumns(tableName string) ([]string, map[string]*core.Colu
continue continue
} }
fields := strings.Fields(strings.TrimSpace(colStr)) col, err := parseString(colStr)
col := new(core.Column) if err != nil {
col.Indexes = make(map[string]int) return colSeq, cols, err
col.Nullable = true }
col.DefaultIsEmpty = true
for idx, field := range fields {
if idx == 0 {
col.Name = strings.Trim(strings.Trim(field, "`[] "), `"`)
continue
} else if idx == 1 {
col.SQLType = core.SQLType{Name: field, DefaultLength: 0, DefaultLength2: 0}
}
switch field {
case "PRIMARY":
col.IsPrimaryKey = true
case "AUTOINCREMENT":
col.IsAutoIncrement = true
case "NULL":
if fields[idx-1] == "NOT" {
col.Nullable = false
} else {
col.Nullable = true
}
case "DEFAULT":
col.Default = fields[idx+1]
col.DefaultIsEmpty = false
}
}
if !col.SQLType.IsNumeric() && !col.DefaultIsEmpty {
col.Default = "'" + col.Default + "'"
}
cols[col.Name] = col cols[col.Name] = col
colSeq = append(colSeq, col.Name) colSeq = append(colSeq, col.Name)
} }

View file

@ -377,24 +377,17 @@ func (engine *Engine) NoAutoCondition(no ...bool) *Session {
return session.NoAutoCondition(no...) return session.NoAutoCondition(no...)
} }
// DBMetas Retrieve all tables, columns, indexes' informations from database. func (engine *Engine) loadTableInfo(table *core.Table) error {
func (engine *Engine) DBMetas() ([]*core.Table, error) {
tables, err := engine.dialect.GetTables()
if err != nil {
return nil, err
}
for _, table := range tables {
colSeq, cols, err := engine.dialect.GetColumns(table.Name) colSeq, cols, err := engine.dialect.GetColumns(table.Name)
if err != nil { if err != nil {
return nil, err return err
} }
for _, name := range colSeq { for _, name := range colSeq {
table.AddColumn(cols[name]) table.AddColumn(cols[name])
} }
indexes, err := engine.dialect.GetIndexes(table.Name) indexes, err := engine.dialect.GetIndexes(table.Name)
if err != nil { if err != nil {
return nil, err return err
} }
table.Indexes = indexes table.Indexes = indexes
@ -403,10 +396,24 @@ func (engine *Engine) DBMetas() ([]*core.Table, error) {
if col := table.GetColumn(name); col != nil { if col := table.GetColumn(name); col != nil {
col.Indexes[index.Name] = index.Type col.Indexes[index.Name] = index.Type
} else { } else {
return nil, fmt.Errorf("Unknown col %s in index %v of table %v, columns %v", name, index.Name, table.Name, table.ColumnsSeq()) return fmt.Errorf("Unknown col %s in index %v of table %v, columns %v", name, index.Name, table.Name, table.ColumnsSeq())
} }
} }
} }
return nil
}
// DBMetas Retrieve all tables, columns, indexes' informations from database.
func (engine *Engine) DBMetas() ([]*core.Table, error) {
tables, err := engine.dialect.GetTables()
if err != nil {
return nil, err
}
for _, table := range tables {
if err = engine.loadTableInfo(table); err != nil {
return nil, err
}
} }
return tables, nil return tables, nil
} }
@ -907,8 +914,15 @@ func (engine *Engine) mapType(v reflect.Value) (*core.Table, error) {
fieldType := fieldValue.Type() fieldType := fieldValue.Type()
if ormTagStr != "" { if ormTagStr != "" {
col = &core.Column{FieldName: t.Field(i).Name, Nullable: true, IsPrimaryKey: false, col = &core.Column{
IsAutoIncrement: false, MapType: core.TWOSIDES, Indexes: make(map[string]int)} FieldName: t.Field(i).Name,
Nullable: true,
IsPrimaryKey: false,
IsAutoIncrement: false,
MapType: core.TWOSIDES,
Indexes: make(map[string]int),
DefaultIsEmpty: true,
}
tags := splitTag(ormTagStr) tags := splitTag(ormTagStr)
if len(tags) > 0 { if len(tags) > 0 {

View file

@ -228,7 +228,7 @@ func (session *Session) Sync2(beans ...interface{}) error {
defer session.Close() defer session.Close()
} }
tables, err := engine.DBMetas() tables, err := engine.dialect.GetTables()
if err != nil { if err != nil {
return err return err
} }
@ -239,26 +239,29 @@ func (session *Session) Sync2(beans ...interface{}) error {
session.resetStatement() session.resetStatement()
}() }()
var structTables []*core.Table
for _, bean := range beans { for _, bean := range beans {
v := rValue(bean) v := rValue(bean)
table, err := engine.mapType(v) table, err := engine.mapType(v)
if err != nil { if err != nil {
return err return err
} }
structTables = append(structTables, table) var tbName string
tbName := engine.TableName(bean) if len(session.statement.AltTableName) > 0 {
tbNameWithSchema := engine.TableName(tbName, true) tbName = session.statement.AltTableName
} else {
tbName = engine.TableName(bean)
}
tbNameWithSchema := engine.tbNameWithSchema(tbName)
var oriTable *core.Table var oriTable *core.Table
for _, tb := range tables { for _, tb := range tables {
if strings.EqualFold(tb.Name, tbName) { if strings.EqualFold(engine.tbNameWithSchema(tb.Name), engine.tbNameWithSchema(tbName)) {
oriTable = tb oriTable = tb
break break
} }
} }
// this is a new table
if oriTable == nil { if oriTable == nil {
err = session.StoreEngine(session.statement.StoreEngine).createTable(bean) err = session.StoreEngine(session.statement.StoreEngine).createTable(bean)
if err != nil { if err != nil {
@ -274,7 +277,15 @@ func (session *Session) Sync2(beans ...interface{}) error {
if err != nil { if err != nil {
return err return err
} }
} else { continue
}
// this will modify an old table
if err = engine.loadTableInfo(oriTable); err != nil {
return err
}
// check columns
for _, col := range table.Columns() { for _, col := range table.Columns() {
var oriCol *core.Column var oriCol *core.Column
for _, col2 := range oriTable.Columns() { for _, col2 := range oriTable.Columns() {
@ -284,7 +295,17 @@ func (session *Session) Sync2(beans ...interface{}) error {
} }
} }
if oriCol != nil { // column is not exist on table
if oriCol == nil {
session.statement.RefTable = table
session.statement.tableName = tbNameWithSchema
if err = session.addColumn(col.Name); err != nil {
return err
}
continue
}
err = nil
expectedType := engine.dialect.SqlType(col) expectedType := engine.dialect.SqlType(col)
curType := engine.dialect.SqlType(oriCol) curType := engine.dialect.SqlType(oriCol)
if expectedType != curType { if expectedType != curType {
@ -323,19 +344,21 @@ func (session *Session) Sync2(beans ...interface{}) error {
} }
} }
} }
if col.Default != oriCol.Default { if col.Default != oriCol.Default {
if (col.SQLType.Name == core.Bool || col.SQLType.Name == core.Boolean) &&
((strings.EqualFold(col.Default, "true") && oriCol.Default == "1") ||
(strings.EqualFold(col.Default, "false") && oriCol.Default == "0")) {
} else {
engine.logger.Warnf("Table %s Column %s db default is %s, struct default is %s", engine.logger.Warnf("Table %s Column %s db default is %s, struct default is %s",
tbName, col.Name, oriCol.Default, col.Default) tbName, col.Name, oriCol.Default, col.Default)
} }
}
if col.Nullable != oriCol.Nullable { if col.Nullable != oriCol.Nullable {
engine.logger.Warnf("Table %s Column %s db nullable is %v, struct nullable is %v", engine.logger.Warnf("Table %s Column %s db nullable is %v, struct nullable is %v",
tbName, col.Name, oriCol.Nullable, col.Nullable) tbName, col.Name, oriCol.Nullable, col.Nullable)
} }
} else {
session.statement.RefTable = table
session.statement.tableName = tbNameWithSchema
err = session.addColumn(col.Name)
}
if err != nil { if err != nil {
return err return err
} }
@ -394,28 +417,14 @@ func (session *Session) Sync2(beans ...interface{}) error {
return err return err
} }
} }
// check all the columns which removed from struct fields but left on database tables.
for _, colName := range oriTable.ColumnsSeq() {
if table.GetColumn(colName) == nil {
engine.logger.Warnf("Table %s has column %s but struct has not related field", engine.TableName(oriTable.Name, true), colName)
}
} }
} }
for _, table := range tables {
var oriTable *core.Table
for _, structTable := range structTables {
if strings.EqualFold(table.Name, session.tbNameNoSchema(structTable)) {
oriTable = structTable
break
}
}
if oriTable == nil {
//engine.LogWarnf("Table %s has no struct to mapping it", table.Name)
continue
}
for _, colName := range table.ColumnsSeq() {
if oriTable.GetColumn(colName) == nil {
engine.logger.Warnf("Table %s has column %s but struct has not related field", engine.TableName(table.Name, true), colName)
}
}
}
return nil return nil
} }

View file

@ -266,6 +266,14 @@ func (statement *Statement) buildUpdates(bean interface{},
continue 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.ValueOf(bean)
if err != nil { if err != nil {
engine.logger.Error(err) engine.logger.Error(err)

View file

@ -125,6 +125,7 @@ func DefaultTagHandler(ctx *tagContext) error {
ctx.col.Default = ctx.nextTag ctx.col.Default = ctx.nextTag
ctx.ignoreNext = true ctx.ignoreNext = true
} }
ctx.col.DefaultIsEmpty = false
return nil return nil
} }

View file

@ -1 +1 @@
go test -db=mssql -conn_str="server=localhost;user id=sa;password=MwantsaSecurePassword1;database=xorm_test" go test -db=mssql -conn_str="server=localhost;user id=sa;password=yourStrong(!)Password;database=xorm_test"

View file

@ -3,10 +3,9 @@ module github.com/lafriks/xormstore
go 1.11 go 1.11
require ( require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/denisenkom/go-mssqldb v0.0.0-20190924004331-208c0a498538 github.com/denisenkom/go-mssqldb v0.0.0-20190924004331-208c0a498538
github.com/go-sql-driver/mysql v1.4.1 github.com/go-sql-driver/mysql v1.4.1
github.com/go-xorm/xorm v0.7.8 github.com/go-xorm/xorm v0.7.9
github.com/gorilla/context v1.1.1 github.com/gorilla/context v1.1.1
github.com/gorilla/securecookie v1.1.1 github.com/gorilla/securecookie v1.1.1
github.com/gorilla/sessions v1.2.0 github.com/gorilla/sessions v1.2.0

View file

@ -29,8 +29,8 @@ github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= 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 h1:9wScpmSP5A3Bk8V3XHWUcJmYTh+ZnlHVyc+A4oZYS3Y=
github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:56xuuqnHyryaerycW3BfssRdxQstACi0Epw/yC5E2xM= github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:56xuuqnHyryaerycW3BfssRdxQstACi0Epw/yC5E2xM=
github.com/go-xorm/xorm v0.7.8 h1:rKxZJB9mWQ9Nw2TbjsepiThR031jkGePOWXwTtEAU08= github.com/go-xorm/xorm v0.7.9 h1:LZze6n1UvRmM5gpL9/U9Gucwqo6aWlFVlfcHKH10qA0=
github.com/go-xorm/xorm v0.7.8/go.mod h1:XiVxrMMIhFkwSkh96BW7PACl7UhLtx2iJIHMdmjh5sQ= github.com/go-xorm/xorm v0.7.9/go.mod h1:XiVxrMMIhFkwSkh96BW7PACl7UhLtx2iJIHMdmjh5sQ=
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=

4
vendor/modules.txt vendored
View file

@ -198,7 +198,7 @@ github.com/go-swagger/go-swagger/cmd/swagger/commands/initcmd
github.com/go-swagger/go-swagger/codescan github.com/go-swagger/go-swagger/codescan
github.com/go-swagger/go-swagger/generator github.com/go-swagger/go-swagger/generator
github.com/go-swagger/go-swagger/scan github.com/go-swagger/go-swagger/scan
# github.com/go-xorm/xorm v0.7.8 # github.com/go-xorm/xorm v0.7.9
github.com/go-xorm/xorm github.com/go-xorm/xorm
# github.com/gobwas/glob v0.2.3 # github.com/gobwas/glob v0.2.3
github.com/gobwas/glob github.com/gobwas/glob
@ -281,7 +281,7 @@ github.com/klauspost/crc32
github.com/kr/pretty github.com/kr/pretty
# github.com/kr/text v0.1.0 # github.com/kr/text v0.1.0
github.com/kr/text github.com/kr/text
# github.com/lafriks/xormstore v1.3.0 # github.com/lafriks/xormstore v1.3.1
github.com/lafriks/xormstore github.com/lafriks/xormstore
github.com/lafriks/xormstore/util github.com/lafriks/xormstore/util
# github.com/lib/pq v1.2.0 # github.com/lib/pq v1.2.0