* upgrade xorm to v0.7.9 to fix some bugs * upgrade xormstore to v1.3.1tags/v1.11.0-dev
@@ -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 | ||||
@@ -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.8/go.mod h1:XiVxrMMIhFkwSkh96BW7PACl7UhLtx2iJIHMdmjh5sQ= | |||||
github.com/go-xorm/xorm v0.7.9 h1:LZze6n1UvRmM5gpL9/U9Gucwqo6aWlFVlfcHKH10qA0= | |||||
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.0/go.mod h1:RAhtOztWBjK9xeZpXwKq59rhUxoRgo1zfYl0H1mtK7A= | |||||
github.com/lafriks/xormstore v1.3.1 h1:KpzRUamSV3zmA85Kzw+PZOU9wgMbYsNzuDzLuBMbxpA= | |||||
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= | ||||
@@ -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 | |||||
- 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.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 | |||||
- 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.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 | ||||
@@ -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 | |||||
err = rows.Scan(&name, &ctype, &maxLen, &precision, &scale, &nullable, &vdefault, &isPK) | |||||
var nullable, isPK, defaultIsNull, isIncrement bool | |||||
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.Default = vdefault | |||||
col.DefaultIsEmpty = defaultIsNull | |||||
if !defaultIsNull { | |||||
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) | ||||
} | } | ||||
@@ -345,9 +345,9 @@ 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 = true | |||||
} | |||||
col.DefaultIsEmpty = false | |||||
} else { | |||||
col.DefaultIsEmpty = true | |||||
} | } | ||||
cts := strings.Split(colType, "(") | cts := strings.Split(colType, "(") | ||||
@@ -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.Default != "" { | |||||
if !col.DefaultIsEmpty { | |||||
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 | ||||
@@ -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 isPK { | |||||
col.IsPrimaryKey = true | |||||
} else { | |||||
col.Default = *colDefault | |||||
if colDefault != nil { | |||||
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(") { | |||||
col.IsAutoIncrement = true | |||||
if isPK { | |||||
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.Default != "" { | |||||
col.Default = "'" + col.Default + "'" | |||||
} else { | |||||
if col.DefaultIsEmpty { | |||||
col.Default = "''" | |||||
if !col.DefaultIsEmpty { | |||||
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 + "'" | |||||
} | |||||
} else if col.SQLType.IsTime() { | |||||
if strings.HasSuffix(col.Default, "::timestamp without time zone") { | |||||
col.Default = strings.TrimRight(col.Default, "::timestamp without time zone") | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -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 := 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} | |||||
} | |||||
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 + "'" | |||||
col, err := parseString(colStr) | |||||
if err != nil { | |||||
return colSeq, cols, err | |||||
} | } | ||||
cols[col.Name] = col | cols[col.Name] = col | ||||
colSeq = append(colSeq, col.Name) | colSeq = append(colSeq, col.Name) | ||||
} | } | ||||
@@ -377,6 +377,32 @@ func (engine *Engine) NoAutoCondition(no ...bool) *Session { | |||||
return session.NoAutoCondition(no...) | return session.NoAutoCondition(no...) | ||||
} | } | ||||
func (engine *Engine) loadTableInfo(table *core.Table) error { | |||||
colSeq, cols, err := engine.dialect.GetColumns(table.Name) | |||||
if err != nil { | |||||
return err | |||||
} | |||||
for _, name := range colSeq { | |||||
table.AddColumn(cols[name]) | |||||
} | |||||
indexes, err := engine.dialect.GetIndexes(table.Name) | |||||
if err != nil { | |||||
return err | |||||
} | |||||
table.Indexes = indexes | |||||
for _, index := range indexes { | |||||
for _, name := range index.Cols { | |||||
if col := table.GetColumn(name); col != nil { | |||||
col.Indexes[index.Name] = index.Type | |||||
} else { | |||||
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. | // DBMetas Retrieve all tables, columns, indexes' informations from database. | ||||
func (engine *Engine) DBMetas() ([]*core.Table, error) { | func (engine *Engine) DBMetas() ([]*core.Table, error) { | ||||
tables, err := engine.dialect.GetTables() | tables, err := engine.dialect.GetTables() | ||||
@@ -385,28 +411,9 @@ func (engine *Engine) DBMetas() ([]*core.Table, error) { | |||||
} | } | ||||
for _, table := range tables { | for _, table := range tables { | ||||
colSeq, cols, err := engine.dialect.GetColumns(table.Name) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
for _, name := range colSeq { | |||||
table.AddColumn(cols[name]) | |||||
} | |||||
indexes, err := engine.dialect.GetIndexes(table.Name) | |||||
if err != nil { | |||||
if err = engine.loadTableInfo(table); err != nil { | |||||
return nil, err | return nil, err | ||||
} | } | ||||
table.Indexes = indexes | |||||
for _, index := range indexes { | |||||
for _, name := range index.Cols { | |||||
if col := table.GetColumn(name); col != nil { | |||||
col.Indexes[index.Name] = index.Type | |||||
} else { | |||||
return nil, fmt.Errorf("Unknown col %s in index %v of table %v, columns %v", name, index.Name, table.Name, table.ColumnsSeq()) | |||||
} | |||||
} | |||||
} | |||||
} | } | ||||
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, | |||||
IsAutoIncrement: false, MapType: core.TWOSIDES, Indexes: make(map[string]int)} | |||||
col = &core.Column{ | |||||
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 { | ||||
@@ -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) | |||||
tbName := engine.TableName(bean) | |||||
tbNameWithSchema := engine.TableName(tbName, true) | |||||
var tbName string | |||||
if len(session.statement.AltTableName) > 0 { | |||||
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,148 +277,154 @@ func (session *Session) Sync2(beans ...interface{}) error { | |||||
if err != nil { | if err != nil { | ||||
return err | return err | ||||
} | } | ||||
} else { | |||||
for _, col := range table.Columns() { | |||||
var oriCol *core.Column | |||||
for _, col2 := range oriTable.Columns() { | |||||
if strings.EqualFold(col.Name, col2.Name) { | |||||
oriCol = col2 | |||||
break | |||||
} | |||||
} | |||||
continue | |||||
} | |||||
if oriCol != nil { | |||||
expectedType := engine.dialect.SqlType(col) | |||||
curType := engine.dialect.SqlType(oriCol) | |||||
if expectedType != curType { | |||||
if expectedType == core.Text && | |||||
strings.HasPrefix(curType, core.Varchar) { | |||||
// currently only support mysql & postgres | |||||
if engine.dialect.DBType() == core.MYSQL || | |||||
engine.dialect.DBType() == core.POSTGRES { | |||||
engine.logger.Infof("Table %s column %s change type from %s to %s\n", | |||||
tbNameWithSchema, col.Name, curType, expectedType) | |||||
_, err = session.exec(engine.dialect.ModifyColumnSql(tbNameWithSchema, col)) | |||||
} else { | |||||
engine.logger.Warnf("Table %s column %s db type is %s, struct type is %s\n", | |||||
tbNameWithSchema, col.Name, curType, expectedType) | |||||
} | |||||
} else if strings.HasPrefix(curType, core.Varchar) && strings.HasPrefix(expectedType, core.Varchar) { | |||||
if engine.dialect.DBType() == core.MYSQL { | |||||
if oriCol.Length < col.Length { | |||||
engine.logger.Infof("Table %s column %s change type from varchar(%d) to varchar(%d)\n", | |||||
tbNameWithSchema, col.Name, oriCol.Length, col.Length) | |||||
_, err = session.exec(engine.dialect.ModifyColumnSql(tbNameWithSchema, col)) | |||||
} | |||||
} | |||||
} else { | |||||
if !(strings.HasPrefix(curType, expectedType) && curType[len(expectedType)] == '(') { | |||||
engine.logger.Warnf("Table %s column %s db type is %s, struct type is %s", | |||||
tbNameWithSchema, col.Name, curType, expectedType) | |||||
} | |||||
} | |||||
} else if expectedType == core.Varchar { | |||||
if engine.dialect.DBType() == core.MYSQL { | |||||
if oriCol.Length < col.Length { | |||||
engine.logger.Infof("Table %s column %s change type from varchar(%d) to varchar(%d)\n", | |||||
tbNameWithSchema, col.Name, oriCol.Length, col.Length) | |||||
_, err = session.exec(engine.dialect.ModifyColumnSql(tbNameWithSchema, col)) | |||||
} | |||||
} | |||||
} | |||||
if col.Default != oriCol.Default { | |||||
engine.logger.Warnf("Table %s Column %s db default is %s, struct default is %s", | |||||
tbName, col.Name, oriCol.Default, col.Default) | |||||
} | |||||
if col.Nullable != oriCol.Nullable { | |||||
engine.logger.Warnf("Table %s Column %s db nullable is %v, struct nullable is %v", | |||||
tbName, col.Name, oriCol.Nullable, col.Nullable) | |||||
} | |||||
} else { | |||||
session.statement.RefTable = table | |||||
session.statement.tableName = tbNameWithSchema | |||||
err = session.addColumn(col.Name) | |||||
// this will modify an old table | |||||
if err = engine.loadTableInfo(oriTable); err != nil { | |||||
return err | |||||
} | |||||
// check columns | |||||
for _, col := range table.Columns() { | |||||
var oriCol *core.Column | |||||
for _, col2 := range oriTable.Columns() { | |||||
if strings.EqualFold(col.Name, col2.Name) { | |||||
oriCol = col2 | |||||
break | |||||
} | } | ||||
if err != 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 | return err | ||||
} | } | ||||
continue | |||||
} | } | ||||
var foundIndexNames = make(map[string]bool) | |||||
var addedNames = make(map[string]*core.Index) | |||||
for name, index := range table.Indexes { | |||||
var oriIndex *core.Index | |||||
for name2, index2 := range oriTable.Indexes { | |||||
if index.Equal(index2) { | |||||
oriIndex = index2 | |||||
foundIndexNames[name2] = true | |||||
break | |||||
err = nil | |||||
expectedType := engine.dialect.SqlType(col) | |||||
curType := engine.dialect.SqlType(oriCol) | |||||
if expectedType != curType { | |||||
if expectedType == core.Text && | |||||
strings.HasPrefix(curType, core.Varchar) { | |||||
// currently only support mysql & postgres | |||||
if engine.dialect.DBType() == core.MYSQL || | |||||
engine.dialect.DBType() == core.POSTGRES { | |||||
engine.logger.Infof("Table %s column %s change type from %s to %s\n", | |||||
tbNameWithSchema, col.Name, curType, expectedType) | |||||
_, err = session.exec(engine.dialect.ModifyColumnSql(tbNameWithSchema, col)) | |||||
} else { | |||||
engine.logger.Warnf("Table %s column %s db type is %s, struct type is %s\n", | |||||
tbNameWithSchema, col.Name, curType, expectedType) | |||||
} | } | ||||
} | |||||
if oriIndex != nil { | |||||
if oriIndex.Type != index.Type { | |||||
sql := engine.dialect.DropIndexSql(tbNameWithSchema, oriIndex) | |||||
_, err = session.exec(sql) | |||||
if err != nil { | |||||
return err | |||||
} else if strings.HasPrefix(curType, core.Varchar) && strings.HasPrefix(expectedType, core.Varchar) { | |||||
if engine.dialect.DBType() == core.MYSQL { | |||||
if oriCol.Length < col.Length { | |||||
engine.logger.Infof("Table %s column %s change type from varchar(%d) to varchar(%d)\n", | |||||
tbNameWithSchema, col.Name, oriCol.Length, col.Length) | |||||
_, err = session.exec(engine.dialect.ModifyColumnSql(tbNameWithSchema, col)) | |||||
} | } | ||||
oriIndex = nil | |||||
} | |||||
} else { | |||||
if !(strings.HasPrefix(curType, expectedType) && curType[len(expectedType)] == '(') { | |||||
engine.logger.Warnf("Table %s column %s db type is %s, struct type is %s", | |||||
tbNameWithSchema, col.Name, curType, expectedType) | |||||
} | |||||
} | |||||
} else if expectedType == core.Varchar { | |||||
if engine.dialect.DBType() == core.MYSQL { | |||||
if oriCol.Length < col.Length { | |||||
engine.logger.Infof("Table %s column %s change type from varchar(%d) to varchar(%d)\n", | |||||
tbNameWithSchema, col.Name, oriCol.Length, col.Length) | |||||
_, err = session.exec(engine.dialect.ModifyColumnSql(tbNameWithSchema, col)) | |||||
} | } | ||||
} | } | ||||
} | |||||
if oriIndex == nil { | |||||
addedNames[name] = index | |||||
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", | |||||
tbName, col.Name, oriCol.Default, col.Default) | |||||
} | } | ||||
} | } | ||||
if col.Nullable != oriCol.Nullable { | |||||
engine.logger.Warnf("Table %s Column %s db nullable is %v, struct nullable is %v", | |||||
tbName, col.Name, oriCol.Nullable, col.Nullable) | |||||
} | |||||
if err != nil { | |||||
return err | |||||
} | |||||
} | |||||
var foundIndexNames = make(map[string]bool) | |||||
var addedNames = make(map[string]*core.Index) | |||||
for name, index := range table.Indexes { | |||||
var oriIndex *core.Index | |||||
for name2, index2 := range oriTable.Indexes { | for name2, index2 := range oriTable.Indexes { | ||||
if _, ok := foundIndexNames[name2]; !ok { | |||||
sql := engine.dialect.DropIndexSql(tbNameWithSchema, index2) | |||||
if index.Equal(index2) { | |||||
oriIndex = index2 | |||||
foundIndexNames[name2] = true | |||||
break | |||||
} | |||||
} | |||||
if oriIndex != nil { | |||||
if oriIndex.Type != index.Type { | |||||
sql := engine.dialect.DropIndexSql(tbNameWithSchema, oriIndex) | |||||
_, err = session.exec(sql) | _, err = session.exec(sql) | ||||
if err != nil { | if err != nil { | ||||
return err | return err | ||||
} | } | ||||
oriIndex = nil | |||||
} | } | ||||
} | } | ||||
for name, index := range addedNames { | |||||
if index.Type == core.UniqueType { | |||||
session.statement.RefTable = table | |||||
session.statement.tableName = tbNameWithSchema | |||||
err = session.addUnique(tbNameWithSchema, name) | |||||
} else if index.Type == core.IndexType { | |||||
session.statement.RefTable = table | |||||
session.statement.tableName = tbNameWithSchema | |||||
err = session.addIndex(tbNameWithSchema, name) | |||||
} | |||||
if oriIndex == nil { | |||||
addedNames[name] = index | |||||
} | |||||
} | |||||
for name2, index2 := range oriTable.Indexes { | |||||
if _, ok := foundIndexNames[name2]; !ok { | |||||
sql := engine.dialect.DropIndexSql(tbNameWithSchema, index2) | |||||
_, err = session.exec(sql) | |||||
if err != nil { | if err != nil { | ||||
return err | return err | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | |||||
for _, table := range tables { | |||||
var oriTable *core.Table | |||||
for _, structTable := range structTables { | |||||
if strings.EqualFold(table.Name, session.tbNameNoSchema(structTable)) { | |||||
oriTable = structTable | |||||
break | |||||
for name, index := range addedNames { | |||||
if index.Type == core.UniqueType { | |||||
session.statement.RefTable = table | |||||
session.statement.tableName = tbNameWithSchema | |||||
err = session.addUnique(tbNameWithSchema, name) | |||||
} else if index.Type == core.IndexType { | |||||
session.statement.RefTable = table | |||||
session.statement.tableName = tbNameWithSchema | |||||
err = session.addIndex(tbNameWithSchema, name) | |||||
} | |||||
if err != nil { | |||||
return err | |||||
} | } | ||||
} | } | ||||
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) | |||||
// 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) | |||||
} | } | ||||
} | } | ||||
} | } | ||||
return nil | return nil | ||||
} | } |
@@ -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) | ||||
@@ -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 | ||||
} | } | ||||
@@ -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" |
@@ -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 | ||||
@@ -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.8/go.mod h1:XiVxrMMIhFkwSkh96BW7PACl7UhLtx2iJIHMdmjh5sQ= | |||||
github.com/go-xorm/xorm v0.7.9 h1:LZze6n1UvRmM5gpL9/U9Gucwqo6aWlFVlfcHKH10qA0= | |||||
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= | ||||
@@ -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 | ||||