mirror of https://github.com/go-gitea/gitea.git
Retry create issue to cope with duplicate keys (#7898)
* Retry create issue to cope with duplicate keys * Use .SetExpr().Where().Insert()
This commit is contained in:
parent
541fab196f
commit
5fe2ec264f
4
go.mod
4
go.mod
|
@ -45,7 +45,7 @@ require (
|
|||
github.com/glycerine/goconvey v0.0.0-20190315024820-982ee783a72e // indirect
|
||||
github.com/go-redis/redis v6.15.2+incompatible
|
||||
github.com/go-sql-driver/mysql v1.4.1
|
||||
github.com/go-xorm/xorm v0.7.4
|
||||
github.com/go-xorm/xorm v0.7.7-0.20190822154023-17592d96b35b
|
||||
github.com/gogits/chardet v0.0.0-20150115103509-2404f7772561
|
||||
github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14
|
||||
github.com/google/go-github/v24 v24.0.1
|
||||
|
@ -117,5 +117,5 @@ require (
|
|||
mvdan.cc/xurls/v2 v2.0.0
|
||||
strk.kbt.io/projects/go/libravatar v0.0.0-20160628055650-5eed7bff870a
|
||||
xorm.io/builder v0.3.5
|
||||
xorm.io/core v0.6.3
|
||||
xorm.io/core v0.7.0
|
||||
)
|
||||
|
|
7
go.sum
7
go.sum
|
@ -143,6 +143,8 @@ github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:9wScpmSP5A3Bk
|
|||
github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:56xuuqnHyryaerycW3BfssRdxQstACi0Epw/yC5E2xM=
|
||||
github.com/go-xorm/xorm v0.7.4 h1:g/NgC590SzqV5VKmdRDNe/K3Holw3YJUCXX28r+rFGw=
|
||||
github.com/go-xorm/xorm v0.7.4/go.mod h1:vpza5fydeRgt+stvo9qgMhSNohYqmNt0I1/D6hkCekA=
|
||||
github.com/go-xorm/xorm v0.7.7-0.20190822154023-17592d96b35b h1:Y0hWUheXDHpIs7BWtJcykO4d1VOsVDKg1PsP5YJwxxM=
|
||||
github.com/go-xorm/xorm v0.7.7-0.20190822154023-17592d96b35b/go.mod h1:nqz2TAsuOHWH2yk4FYWtacCGgdbrcdZ5mF1XadqEHls=
|
||||
github.com/gogits/chardet v0.0.0-20150115103509-2404f7772561 h1:deE7ritpK04PgtpyVOS2TYcQEld9qLCD5b5EbVNOuLA=
|
||||
github.com/gogits/chardet v0.0.0-20150115103509-2404f7772561/go.mod h1:YgYOrVn3Nj9Tq0EvjmFbphRytDj7JNRoWSStJZWDJTQ=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
|
@ -430,6 +432,7 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
|
|||
golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190730183949-1393eb018365/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
@ -446,6 +449,7 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm
|
|||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
|
||||
golang.org/x/tools v0.0.0-20190731214159-1e85ed8060aa h1:kwa/4M1dbmhZqOIqYiTtbA6JrvPwo1+jqlub2qDXX90=
|
||||
|
@ -454,6 +458,7 @@ google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMt
|
|||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
|
@ -509,3 +514,5 @@ xorm.io/builder v0.3.5 h1:EilU39fvWDxjb1cDaELpYhsF+zziRBhew8xk4pngO+A=
|
|||
xorm.io/builder v0.3.5/go.mod h1:ZFbByS/KxZI1FKRjL05PyJ4YrK2bcxlUaAxdum5aTR8=
|
||||
xorm.io/core v0.6.3 h1:n1NhVZt1s2oLw1BZfX2ocIJsHyso259uPgg63BGr37M=
|
||||
xorm.io/core v0.6.3/go.mod h1:8kz/C6arVW/O9vk3PgCiMJO2hIAm1UcuOL3dSPyZ2qo=
|
||||
xorm.io/core v0.7.0 h1:hKxuOKWZNeiFQsSuGet/KV8HZ788hclvAl+7azx3tkM=
|
||||
xorm.io/core v0.7.0/go.mod h1:TuOJjIVa7e3w/rN8tDcAvuLBMtwzdHPbyOzE6Gk1EUI=
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"path"
|
||||
"regexp"
|
||||
|
@ -74,6 +73,7 @@ var (
|
|||
|
||||
const issueTasksRegexpStr = `(^\s*[-*]\s\[[\sx]\]\s.)|(\n\s*[-*]\s\[[\sx]\]\s.)`
|
||||
const issueTasksDoneRegexpStr = `(^\s*[-*]\s\[[x]\]\s.)|(\n\s*[-*]\s\[[x]\]\s.)`
|
||||
const issueMaxDupIndexAttempts = 3
|
||||
|
||||
func init() {
|
||||
issueTasksPat = regexp.MustCompile(issueTasksRegexpStr)
|
||||
|
@ -1031,36 +1031,9 @@ type NewIssueOptions struct {
|
|||
IsPull bool
|
||||
}
|
||||
|
||||
// GetMaxIndexOfIssue returns the max index on issue
|
||||
func GetMaxIndexOfIssue(repoID int64) (int64, error) {
|
||||
return getMaxIndexOfIssue(x, repoID)
|
||||
}
|
||||
|
||||
func getMaxIndexOfIssue(e Engine, repoID int64) (int64, error) {
|
||||
var (
|
||||
maxIndex int64
|
||||
has bool
|
||||
err error
|
||||
)
|
||||
|
||||
has, err = e.SQL("SELECT COALESCE((SELECT MAX(`index`) FROM issue WHERE repo_id = ?),0)", repoID).Get(&maxIndex)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
} else if !has {
|
||||
return 0, errors.New("Retrieve Max index from issue failed")
|
||||
}
|
||||
return maxIndex, nil
|
||||
}
|
||||
|
||||
func newIssue(e *xorm.Session, doer *User, opts NewIssueOptions) (err error) {
|
||||
opts.Issue.Title = strings.TrimSpace(opts.Issue.Title)
|
||||
|
||||
maxIndex, err := getMaxIndexOfIssue(e, opts.Issue.RepoID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
opts.Issue.Index = maxIndex + 1
|
||||
|
||||
if opts.Issue.MilestoneID > 0 {
|
||||
milestone, err := getMilestoneByRepoID(e, opts.Issue.RepoID, opts.Issue.MilestoneID)
|
||||
if err != nil && !IsErrMilestoneNotExist(err) {
|
||||
|
@ -1109,10 +1082,31 @@ func newIssue(e *xorm.Session, doer *User, opts NewIssueOptions) (err error) {
|
|||
}
|
||||
|
||||
// Milestone and assignee validation should happen before insert actual object.
|
||||
if _, err = e.Insert(opts.Issue); err != nil {
|
||||
|
||||
// There's no good way to identify a duplicate key error in database/sql; brute force some retries
|
||||
dupIndexAttempts := issueMaxDupIndexAttempts
|
||||
for {
|
||||
_, err := e.SetExpr("`index`", "coalesce(MAX(`index`),0)+1").
|
||||
Where("repo_id=?", opts.Issue.RepoID).
|
||||
Insert(opts.Issue)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
|
||||
dupIndexAttempts--
|
||||
if dupIndexAttempts <= 0 {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
inserted, err := getIssueByID(e, opts.Issue.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch Index with the value calculated by the database
|
||||
opts.Issue.Index = inserted.Index
|
||||
|
||||
if opts.Issue.MilestoneID > 0 {
|
||||
if err = changeMilestoneAssign(e, doer, opts.Issue, -1); err != nil {
|
||||
return err
|
||||
|
|
|
@ -252,15 +252,8 @@ func CreatePullRequest(ctx *context.APIContext, form api.CreatePullRequestOption
|
|||
deadlineUnix = timeutil.TimeStamp(form.Deadline.Unix())
|
||||
}
|
||||
|
||||
maxIndex, err := models.GetMaxIndexOfIssue(repo.ID)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetPatch", err)
|
||||
return
|
||||
}
|
||||
|
||||
prIssue := &models.Issue{
|
||||
RepoID: repo.ID,
|
||||
Index: maxIndex + 1,
|
||||
Title: form.Title,
|
||||
PosterID: ctx.User.ID,
|
||||
Poster: ctx.User,
|
||||
|
|
|
@ -710,15 +710,8 @@ func CompareAndPullRequestPost(ctx *context.Context, form auth.CreateIssueForm)
|
|||
return
|
||||
}
|
||||
|
||||
maxIndex, err := models.GetMaxIndexOfIssue(repo.ID)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetPatch", err)
|
||||
return
|
||||
}
|
||||
|
||||
pullIssue := &models.Issue{
|
||||
RepoID: repo.ID,
|
||||
Index: maxIndex + 1,
|
||||
Title: form.Title,
|
||||
PosterID: ctx.User.ID,
|
||||
Poster: ctx.User,
|
||||
|
|
|
@ -1,125 +1,431 @@
|
|||
---
|
||||
kind: pipeline
|
||||
name: matrix-1
|
||||
|
||||
platform:
|
||||
os: linux
|
||||
arch: amd64
|
||||
|
||||
clone:
|
||||
disable: true
|
||||
|
||||
workspace:
|
||||
base: /go
|
||||
path: src/github.com/go-xorm/xorm
|
||||
|
||||
clone:
|
||||
git:
|
||||
image: plugins/git:next
|
||||
steps:
|
||||
- name: git
|
||||
pull: default
|
||||
image: plugins/git:next
|
||||
settings:
|
||||
depth: 50
|
||||
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
|
||||
pull: default
|
||||
image: golang:1.10
|
||||
commands:
|
||||
- go get -t -d -v ./...
|
||||
- go get -u xorm.io/core
|
||||
- go get -u xorm.io/builder
|
||||
- go build -v
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
|
||||
- name: test-sqlite
|
||||
pull: default
|
||||
image: golang:1.10
|
||||
commands:
|
||||
- go get -u github.com/wadey/gocovmerge
|
||||
- "go test -v -race -db=\"sqlite3\" -conn_str=\"./test.db\" -coverprofile=coverage1-1.txt -covermode=atomic"
|
||||
- "go test -v -race -db=\"sqlite3\" -conn_str=\"./test.db\" -cache=true -coverprofile=coverage1-2.txt -covermode=atomic"
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
|
||||
- name: test-mysql
|
||||
pull: default
|
||||
image: golang:1.10
|
||||
commands:
|
||||
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test\" -coverprofile=coverage2-1.txt -covermode=atomic"
|
||||
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test\" -cache=true -coverprofile=coverage2-2.txt -covermode=atomic"
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
|
||||
- name: test-mysql-utf8mb4
|
||||
pull: default
|
||||
image: golang:1.10
|
||||
commands:
|
||||
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test?charset=utf8mb4\" -coverprofile=coverage2.1-1.txt -covermode=atomic"
|
||||
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test?charset=utf8mb4\" -cache=true -coverprofile=coverage2.1-2.txt -covermode=atomic"
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
|
||||
- name: test-mymysql
|
||||
pull: default
|
||||
image: golang:1.10
|
||||
commands:
|
||||
- "go test -v -race -db=\"mymysql\" -conn_str=\"tcp:mysql:3306*xorm_test/root/\" -coverprofile=coverage3-1.txt -covermode=atomic"
|
||||
- "go test -v -race -db=\"mymysql\" -conn_str=\"tcp:mysql:3306*xorm_test/root/\" -cache=true -coverprofile=coverage3-2.txt -covermode=atomic"
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
|
||||
- name: test-postgres
|
||||
pull: default
|
||||
image: golang:1.10
|
||||
commands:
|
||||
- "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -coverprofile=coverage4-1.txt -covermode=atomic"
|
||||
- "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -cache=true -coverprofile=coverage4-2.txt -covermode=atomic"
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
|
||||
- name: test-postgres-schema
|
||||
pull: default
|
||||
image: golang:1.10
|
||||
commands:
|
||||
- "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -schema=xorm -coverprofile=coverage5-1.txt -covermode=atomic"
|
||||
- "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -schema=xorm -cache=true -coverprofile=coverage5-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 > coverage.txt
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
|
||||
services:
|
||||
mysql:
|
||||
image: mysql:5.7
|
||||
environment:
|
||||
- MYSQL_DATABASE=xorm_test
|
||||
- MYSQL_ALLOW_EMPTY_PASSWORD=yes
|
||||
when:
|
||||
event: [ push, tag, pull_request ]
|
||||
- name: mysql
|
||||
pull: default
|
||||
image: mysql:5.7
|
||||
environment:
|
||||
MYSQL_ALLOW_EMPTY_PASSWORD: yes
|
||||
MYSQL_DATABASE: xorm_test
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- tag
|
||||
- pull_request
|
||||
|
||||
pgsql:
|
||||
image: postgres:9.5
|
||||
environment:
|
||||
- POSTGRES_USER=postgres
|
||||
- POSTGRES_DB=xorm_test
|
||||
when:
|
||||
event: [ push, tag, pull_request ]
|
||||
- name: pgsql
|
||||
pull: default
|
||||
image: postgres:9.5
|
||||
environment:
|
||||
POSTGRES_DB: xorm_test
|
||||
POSTGRES_USER: postgres
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- tag
|
||||
- pull_request
|
||||
|
||||
#mssql:
|
||||
# image: microsoft/mssql-server-linux:2017-CU11
|
||||
# environment:
|
||||
# - ACCEPT_EULA=Y
|
||||
# - SA_PASSWORD=yourStrong(!)Password
|
||||
# - MSSQL_PID=Developer
|
||||
# commands:
|
||||
# - echo 'CREATE DATABASE xorm_test' > create.sql
|
||||
# - /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P yourStrong(!)Password -i "create.sql"
|
||||
---
|
||||
kind: pipeline
|
||||
name: matrix-2
|
||||
|
||||
matrix:
|
||||
GO_VERSION:
|
||||
- 1.8
|
||||
- 1.9
|
||||
- 1.10
|
||||
- 1.11
|
||||
platform:
|
||||
os: linux
|
||||
arch: amd64
|
||||
|
||||
pipeline:
|
||||
init_postgres:
|
||||
image: postgres:9.5
|
||||
commands:
|
||||
# wait for postgres service to become available
|
||||
- |
|
||||
until psql -U postgres -d xorm_test -h pgsql \
|
||||
-c "SELECT 1;" >/dev/null 2>&1; do sleep 1; done
|
||||
# query the database
|
||||
- |
|
||||
psql -U postgres -d xorm_test -h pgsql \
|
||||
-c "create schema xorm;"
|
||||
clone:
|
||||
disable: true
|
||||
|
||||
build:
|
||||
image: golang:${GO_VERSION}
|
||||
commands:
|
||||
- go get -t -d -v ./...
|
||||
- go get -u xorm.io/core
|
||||
- go get -u xorm.io/builder
|
||||
- go build -v
|
||||
when:
|
||||
event: [ push, pull_request ]
|
||||
workspace:
|
||||
base: /go
|
||||
path: src/github.com/go-xorm/xorm
|
||||
|
||||
test-sqlite:
|
||||
image: golang:${GO_VERSION}
|
||||
commands:
|
||||
- go get -u github.com/wadey/gocovmerge
|
||||
- go test -v -race -db="sqlite3" -conn_str="./test.db" -coverprofile=coverage1-1.txt -covermode=atomic
|
||||
- go test -v -race -db="sqlite3" -conn_str="./test.db" -cache=true -coverprofile=coverage1-2.txt -covermode=atomic
|
||||
when:
|
||||
event: [ push, pull_request ]
|
||||
steps:
|
||||
- name: git
|
||||
pull: default
|
||||
image: plugins/git:next
|
||||
settings:
|
||||
depth: 50
|
||||
tags: true
|
||||
|
||||
test-mysql:
|
||||
image: golang:${GO_VERSION}
|
||||
commands:
|
||||
- go test -v -race -db="mysql" -conn_str="root:@tcp(mysql)/xorm_test" -coverprofile=coverage2-1.txt -covermode=atomic
|
||||
- go test -v -race -db="mysql" -conn_str="root:@tcp(mysql)/xorm_test" -cache=true -coverprofile=coverage2-2.txt -covermode=atomic
|
||||
when:
|
||||
event: [ push, pull_request ]
|
||||
- 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"
|
||||
|
||||
test-mysql-utf8mb4:
|
||||
image: golang:${GO_VERSION}
|
||||
commands:
|
||||
- go test -v -race -db="mysql" -conn_str="root:@tcp(mysql)/xorm_test?charset=utf8mb4" -coverprofile=coverage2.1-1.txt -covermode=atomic
|
||||
- go test -v -race -db="mysql" -conn_str="root:@tcp(mysql)/xorm_test?charset=utf8mb4" -cache=true -coverprofile=coverage2.1-2.txt -covermode=atomic
|
||||
when:
|
||||
event: [ push, pull_request ]
|
||||
- name: build
|
||||
pull: default
|
||||
image: golang:1.11
|
||||
commands:
|
||||
- go get -t -d -v ./...
|
||||
- go get -u xorm.io/core
|
||||
- go get -u xorm.io/builder
|
||||
- GO111MODULE=off go build -v
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
|
||||
test-mymysql:
|
||||
image: golang:${GO_VERSION}
|
||||
commands:
|
||||
- go test -v -race -db="mymysql" -conn_str="tcp:mysql:3306*xorm_test/root/" -coverprofile=coverage3-1.txt -covermode=atomic
|
||||
- go test -v -race -db="mymysql" -conn_str="tcp:mysql:3306*xorm_test/root/" -cache=true -coverprofile=coverage3-2.txt -covermode=atomic
|
||||
when:
|
||||
event: [ push, pull_request ]
|
||||
- name: build-gomod
|
||||
pull: default
|
||||
image: golang:1.11
|
||||
environment:
|
||||
GOPROXY: "https://goproxy.cn"
|
||||
commands:
|
||||
- GO111MODULE=on go build -v
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
|
||||
test-postgres:
|
||||
image: golang:${GO_VERSION}
|
||||
commands:
|
||||
- go test -v -race -db="postgres" -conn_str="postgres://postgres:@pgsql/xorm_test?sslmode=disable" -coverprofile=coverage4-1.txt -covermode=atomic
|
||||
- go test -v -race -db="postgres" -conn_str="postgres://postgres:@pgsql/xorm_test?sslmode=disable" -cache=true -coverprofile=coverage4-2.txt -covermode=atomic
|
||||
when:
|
||||
event: [ push, pull_request ]
|
||||
|
||||
test-postgres-schema:
|
||||
image: golang:${GO_VERSION}
|
||||
commands:
|
||||
- go test -v -race -db="postgres" -conn_str="postgres://postgres:@pgsql/xorm_test?sslmode=disable" -schema=xorm -coverprofile=coverage5-1.txt -covermode=atomic
|
||||
- go test -v -race -db="postgres" -conn_str="postgres://postgres:@pgsql/xorm_test?sslmode=disable" -schema=xorm -cache=true -coverprofile=coverage5-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 > coverage.txt
|
||||
when:
|
||||
event: [ push, pull_request ]
|
||||
- name: test-sqlite
|
||||
pull: default
|
||||
image: golang:1.11
|
||||
commands:
|
||||
- go get -u github.com/wadey/gocovmerge
|
||||
- "go test -v -race -db=\"sqlite3\" -conn_str=\"./test.db\" -coverprofile=coverage1-1.txt -covermode=atomic"
|
||||
- "go test -v -race -db=\"sqlite3\" -conn_str=\"./test.db\" -cache=true -coverprofile=coverage1-2.txt -covermode=atomic"
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
|
||||
#coverage:
|
||||
# image: robertstettner/drone-codecov
|
||||
# secrets: [ codecov_token ]
|
||||
# files:
|
||||
# - coverage.txt
|
||||
# when:
|
||||
# event: [ push, pull_request ]
|
||||
# branch: [ master ]
|
||||
- name: test-mysql
|
||||
pull: default
|
||||
image: golang:1.11
|
||||
commands:
|
||||
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test\" -coverprofile=coverage2-1.txt -covermode=atomic"
|
||||
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test\" -cache=true -coverprofile=coverage2-2.txt -covermode=atomic"
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
|
||||
- name: test-mysql-utf8mb4
|
||||
pull: default
|
||||
image: golang:1.11
|
||||
commands:
|
||||
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test?charset=utf8mb4\" -coverprofile=coverage2.1-1.txt -covermode=atomic"
|
||||
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test?charset=utf8mb4\" -cache=true -coverprofile=coverage2.1-2.txt -covermode=atomic"
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
|
||||
- name: test-mymysql
|
||||
pull: default
|
||||
image: golang:1.11
|
||||
commands:
|
||||
- "go test -v -race -db=\"mymysql\" -conn_str=\"tcp:mysql:3306*xorm_test/root/\" -coverprofile=coverage3-1.txt -covermode=atomic"
|
||||
- "go test -v -race -db=\"mymysql\" -conn_str=\"tcp:mysql:3306*xorm_test/root/\" -cache=true -coverprofile=coverage3-2.txt -covermode=atomic"
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
|
||||
- name: test-postgres
|
||||
pull: default
|
||||
image: golang:1.11
|
||||
commands:
|
||||
- "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -coverprofile=coverage4-1.txt -covermode=atomic"
|
||||
- "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -cache=true -coverprofile=coverage4-2.txt -covermode=atomic"
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
|
||||
- name: test-postgres-schema
|
||||
pull: default
|
||||
image: golang:1.11
|
||||
commands:
|
||||
- "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -schema=xorm -coverprofile=coverage5-1.txt -covermode=atomic"
|
||||
- "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -schema=xorm -cache=true -coverprofile=coverage5-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 > coverage.txt
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
|
||||
services:
|
||||
- name: mysql
|
||||
pull: default
|
||||
image: mysql:5.7
|
||||
environment:
|
||||
MYSQL_ALLOW_EMPTY_PASSWORD: yes
|
||||
MYSQL_DATABASE: xorm_test
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- tag
|
||||
- pull_request
|
||||
|
||||
- name: pgsql
|
||||
pull: default
|
||||
image: postgres:9.5
|
||||
environment:
|
||||
POSTGRES_DB: xorm_test
|
||||
POSTGRES_USER: postgres
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- tag
|
||||
- pull_request
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
name: matrix-3
|
||||
|
||||
platform:
|
||||
os: linux
|
||||
arch: amd64
|
||||
|
||||
clone:
|
||||
disable: true
|
||||
|
||||
workspace:
|
||||
base: /go
|
||||
path: src/github.com/go-xorm/xorm
|
||||
|
||||
steps:
|
||||
- name: git
|
||||
pull: default
|
||||
image: plugins/git:next
|
||||
settings:
|
||||
depth: 50
|
||||
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
|
||||
pull: default
|
||||
image: golang:1.12
|
||||
commands:
|
||||
- go get -t -d -v ./...
|
||||
- go get -u xorm.io/core
|
||||
- go get -u xorm.io/builder
|
||||
- GO111MODULE=off go build -v
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
|
||||
- name: build-gomod
|
||||
pull: default
|
||||
image: golang:1.12
|
||||
environment:
|
||||
GOPROXY: "https://goproxy.cn"
|
||||
commands:
|
||||
- GO111MODULE=on go build -v
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
|
||||
- name: test-sqlite
|
||||
pull: default
|
||||
image: golang:1.12
|
||||
commands:
|
||||
- go get -u github.com/wadey/gocovmerge
|
||||
- "go test -v -race -db=\"sqlite3\" -conn_str=\"./test.db\" -coverprofile=coverage1-1.txt -covermode=atomic"
|
||||
- "go test -v -race -db=\"sqlite3\" -conn_str=\"./test.db\" -cache=true -coverprofile=coverage1-2.txt -covermode=atomic"
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
|
||||
- name: test-mysql
|
||||
pull: default
|
||||
image: golang:1.12
|
||||
commands:
|
||||
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test\" -coverprofile=coverage2-1.txt -covermode=atomic"
|
||||
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test\" -cache=true -coverprofile=coverage2-2.txt -covermode=atomic"
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
|
||||
- name: test-mysql-utf8mb4
|
||||
pull: default
|
||||
image: golang:1.12
|
||||
commands:
|
||||
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test?charset=utf8mb4\" -coverprofile=coverage2.1-1.txt -covermode=atomic"
|
||||
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test?charset=utf8mb4\" -cache=true -coverprofile=coverage2.1-2.txt -covermode=atomic"
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
|
||||
- name: test-mymysql
|
||||
pull: default
|
||||
image: golang:1.12
|
||||
commands:
|
||||
- "go test -v -race -db=\"mymysql\" -conn_str=\"tcp:mysql:3306*xorm_test/root/\" -coverprofile=coverage3-1.txt -covermode=atomic"
|
||||
- "go test -v -race -db=\"mymysql\" -conn_str=\"tcp:mysql:3306*xorm_test/root/\" -cache=true -coverprofile=coverage3-2.txt -covermode=atomic"
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
|
||||
- name: test-postgres
|
||||
pull: default
|
||||
image: golang:1.12
|
||||
commands:
|
||||
- "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -coverprofile=coverage4-1.txt -covermode=atomic"
|
||||
- "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -cache=true -coverprofile=coverage4-2.txt -covermode=atomic"
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
|
||||
- name: test-postgres-schema
|
||||
pull: default
|
||||
image: golang:1.12
|
||||
commands:
|
||||
- "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -schema=xorm -coverprofile=coverage5-1.txt -covermode=atomic"
|
||||
- "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -schema=xorm -cache=true -coverprofile=coverage5-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 > coverage.txt
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
|
||||
services:
|
||||
- name: mysql
|
||||
pull: default
|
||||
image: mysql:5.7
|
||||
environment:
|
||||
MYSQL_ALLOW_EMPTY_PASSWORD: yes
|
||||
MYSQL_DATABASE: xorm_test
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- tag
|
||||
- pull_request
|
||||
|
||||
- name: pgsql
|
||||
pull: default
|
||||
image: postgres:9.5
|
||||
environment:
|
||||
POSTGRES_DB: xorm_test
|
||||
POSTGRES_USER: postgres
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- tag
|
||||
- pull_request
|
|
@ -284,6 +284,13 @@ counts, err := engine.Count(&user)
|
|||
// SELECT count(*) AS total FROM user
|
||||
```
|
||||
|
||||
* `FindAndCount` combines function `Find` with `Count` which is usually used in query by page
|
||||
|
||||
```Go
|
||||
var users []User
|
||||
counts, err := engine.FindAndCount(&users)
|
||||
```
|
||||
|
||||
* `Sum` sum functions
|
||||
|
||||
```Go
|
||||
|
|
|
@ -16,191 +16,191 @@ import (
|
|||
|
||||
var (
|
||||
mssqlReservedWords = map[string]bool{
|
||||
"ADD": true,
|
||||
"EXTERNAL": true,
|
||||
"PROCEDURE": true,
|
||||
"ALL": true,
|
||||
"FETCH": true,
|
||||
"PUBLIC": true,
|
||||
"ALTER": true,
|
||||
"FILE": true,
|
||||
"RAISERROR": true,
|
||||
"AND": true,
|
||||
"FILLFACTOR": true,
|
||||
"READ": true,
|
||||
"ANY": true,
|
||||
"FOR": true,
|
||||
"READTEXT": true,
|
||||
"AS": true,
|
||||
"FOREIGN": true,
|
||||
"RECONFIGURE": true,
|
||||
"ASC": true,
|
||||
"FREETEXT": true,
|
||||
"REFERENCES": true,
|
||||
"AUTHORIZATION": true,
|
||||
"FREETEXTTABLE": true,
|
||||
"REPLICATION": true,
|
||||
"BACKUP": true,
|
||||
"FROM": true,
|
||||
"RESTORE": true,
|
||||
"BEGIN": true,
|
||||
"FULL": true,
|
||||
"RESTRICT": true,
|
||||
"BETWEEN": true,
|
||||
"FUNCTION": true,
|
||||
"RETURN": true,
|
||||
"BREAK": true,
|
||||
"GOTO": true,
|
||||
"REVERT": true,
|
||||
"BROWSE": true,
|
||||
"GRANT": true,
|
||||
"REVOKE": true,
|
||||
"BULK": true,
|
||||
"GROUP": true,
|
||||
"RIGHT": true,
|
||||
"BY": true,
|
||||
"HAVING": true,
|
||||
"ROLLBACK": true,
|
||||
"CASCADE": true,
|
||||
"HOLDLOCK": true,
|
||||
"ROWCOUNT": true,
|
||||
"CASE": true,
|
||||
"IDENTITY": true,
|
||||
"ROWGUIDCOL": true,
|
||||
"CHECK": true,
|
||||
"IDENTITY_INSERT": true,
|
||||
"RULE": true,
|
||||
"CHECKPOINT": true,
|
||||
"IDENTITYCOL": true,
|
||||
"SAVE": true,
|
||||
"CLOSE": true,
|
||||
"IF": true,
|
||||
"SCHEMA": true,
|
||||
"CLUSTERED": true,
|
||||
"IN": true,
|
||||
"SECURITYAUDIT": true,
|
||||
"COALESCE": true,
|
||||
"INDEX": true,
|
||||
"SELECT": true,
|
||||
"COLLATE": true,
|
||||
"INNER": true,
|
||||
"SEMANTICKEYPHRASETABLE": true,
|
||||
"COLUMN": true,
|
||||
"INSERT": true,
|
||||
"ADD": true,
|
||||
"EXTERNAL": true,
|
||||
"PROCEDURE": true,
|
||||
"ALL": true,
|
||||
"FETCH": true,
|
||||
"PUBLIC": true,
|
||||
"ALTER": true,
|
||||
"FILE": true,
|
||||
"RAISERROR": true,
|
||||
"AND": true,
|
||||
"FILLFACTOR": true,
|
||||
"READ": true,
|
||||
"ANY": true,
|
||||
"FOR": true,
|
||||
"READTEXT": true,
|
||||
"AS": true,
|
||||
"FOREIGN": true,
|
||||
"RECONFIGURE": true,
|
||||
"ASC": true,
|
||||
"FREETEXT": true,
|
||||
"REFERENCES": true,
|
||||
"AUTHORIZATION": true,
|
||||
"FREETEXTTABLE": true,
|
||||
"REPLICATION": true,
|
||||
"BACKUP": true,
|
||||
"FROM": true,
|
||||
"RESTORE": true,
|
||||
"BEGIN": true,
|
||||
"FULL": true,
|
||||
"RESTRICT": true,
|
||||
"BETWEEN": true,
|
||||
"FUNCTION": true,
|
||||
"RETURN": true,
|
||||
"BREAK": true,
|
||||
"GOTO": true,
|
||||
"REVERT": true,
|
||||
"BROWSE": true,
|
||||
"GRANT": true,
|
||||
"REVOKE": true,
|
||||
"BULK": true,
|
||||
"GROUP": true,
|
||||
"RIGHT": true,
|
||||
"BY": true,
|
||||
"HAVING": true,
|
||||
"ROLLBACK": true,
|
||||
"CASCADE": true,
|
||||
"HOLDLOCK": true,
|
||||
"ROWCOUNT": true,
|
||||
"CASE": true,
|
||||
"IDENTITY": true,
|
||||
"ROWGUIDCOL": true,
|
||||
"CHECK": true,
|
||||
"IDENTITY_INSERT": true,
|
||||
"RULE": true,
|
||||
"CHECKPOINT": true,
|
||||
"IDENTITYCOL": true,
|
||||
"SAVE": true,
|
||||
"CLOSE": true,
|
||||
"IF": true,
|
||||
"SCHEMA": true,
|
||||
"CLUSTERED": true,
|
||||
"IN": true,
|
||||
"SECURITYAUDIT": true,
|
||||
"COALESCE": true,
|
||||
"INDEX": true,
|
||||
"SELECT": true,
|
||||
"COLLATE": true,
|
||||
"INNER": true,
|
||||
"SEMANTICKEYPHRASETABLE": true,
|
||||
"COLUMN": true,
|
||||
"INSERT": true,
|
||||
"SEMANTICSIMILARITYDETAILSTABLE": true,
|
||||
"COMMIT": true,
|
||||
"INTERSECT": true,
|
||||
"SEMANTICSIMILARITYTABLE": true,
|
||||
"COMPUTE": true,
|
||||
"INTO": true,
|
||||
"SESSION_USER": true,
|
||||
"CONSTRAINT": true,
|
||||
"IS": true,
|
||||
"SET": true,
|
||||
"CONTAINS": true,
|
||||
"JOIN": true,
|
||||
"SETUSER": true,
|
||||
"CONTAINSTABLE": true,
|
||||
"KEY": true,
|
||||
"SHUTDOWN": true,
|
||||
"CONTINUE": true,
|
||||
"KILL": true,
|
||||
"SOME": true,
|
||||
"CONVERT": true,
|
||||
"LEFT": true,
|
||||
"STATISTICS": true,
|
||||
"CREATE": true,
|
||||
"LIKE": true,
|
||||
"SYSTEM_USER": true,
|
||||
"CROSS": true,
|
||||
"LINENO": true,
|
||||
"TABLE": true,
|
||||
"CURRENT": true,
|
||||
"LOAD": true,
|
||||
"TABLESAMPLE": true,
|
||||
"CURRENT_DATE": true,
|
||||
"MERGE": true,
|
||||
"TEXTSIZE": true,
|
||||
"CURRENT_TIME": true,
|
||||
"NATIONAL": true,
|
||||
"THEN": true,
|
||||
"CURRENT_TIMESTAMP": true,
|
||||
"NOCHECK": true,
|
||||
"TO": true,
|
||||
"CURRENT_USER": true,
|
||||
"NONCLUSTERED": true,
|
||||
"TOP": true,
|
||||
"CURSOR": true,
|
||||
"NOT": true,
|
||||
"TRAN": true,
|
||||
"DATABASE": true,
|
||||
"NULL": true,
|
||||
"TRANSACTION": true,
|
||||
"DBCC": true,
|
||||
"NULLIF": true,
|
||||
"TRIGGER": true,
|
||||
"DEALLOCATE": true,
|
||||
"OF": true,
|
||||
"TRUNCATE": true,
|
||||
"DECLARE": true,
|
||||
"OFF": true,
|
||||
"TRY_CONVERT": true,
|
||||
"DEFAULT": true,
|
||||
"OFFSETS": true,
|
||||
"TSEQUAL": true,
|
||||
"DELETE": true,
|
||||
"ON": true,
|
||||
"UNION": true,
|
||||
"DENY": true,
|
||||
"OPEN": true,
|
||||
"UNIQUE": true,
|
||||
"DESC": true,
|
||||
"OPENDATASOURCE": true,
|
||||
"UNPIVOT": true,
|
||||
"DISK": true,
|
||||
"OPENQUERY": true,
|
||||
"UPDATE": true,
|
||||
"DISTINCT": true,
|
||||
"OPENROWSET": true,
|
||||
"UPDATETEXT": true,
|
||||
"DISTRIBUTED": true,
|
||||
"OPENXML": true,
|
||||
"USE": true,
|
||||
"DOUBLE": true,
|
||||
"OPTION": true,
|
||||
"USER": true,
|
||||
"DROP": true,
|
||||
"OR": true,
|
||||
"VALUES": true,
|
||||
"DUMP": true,
|
||||
"ORDER": true,
|
||||
"VARYING": true,
|
||||
"ELSE": true,
|
||||
"OUTER": true,
|
||||
"VIEW": true,
|
||||
"END": true,
|
||||
"OVER": true,
|
||||
"WAITFOR": true,
|
||||
"ERRLVL": true,
|
||||
"PERCENT": true,
|
||||
"WHEN": true,
|
||||
"ESCAPE": true,
|
||||
"PIVOT": true,
|
||||
"WHERE": true,
|
||||
"EXCEPT": true,
|
||||
"PLAN": true,
|
||||
"WHILE": true,
|
||||
"EXEC": true,
|
||||
"PRECISION": true,
|
||||
"WITH": true,
|
||||
"EXECUTE": true,
|
||||
"PRIMARY": true,
|
||||
"WITHIN": true,
|
||||
"EXISTS": true,
|
||||
"PRINT": true,
|
||||
"WRITETEXT": true,
|
||||
"EXIT": true,
|
||||
"PROC": true,
|
||||
"COMMIT": true,
|
||||
"INTERSECT": true,
|
||||
"SEMANTICSIMILARITYTABLE": true,
|
||||
"COMPUTE": true,
|
||||
"INTO": true,
|
||||
"SESSION_USER": true,
|
||||
"CONSTRAINT": true,
|
||||
"IS": true,
|
||||
"SET": true,
|
||||
"CONTAINS": true,
|
||||
"JOIN": true,
|
||||
"SETUSER": true,
|
||||
"CONTAINSTABLE": true,
|
||||
"KEY": true,
|
||||
"SHUTDOWN": true,
|
||||
"CONTINUE": true,
|
||||
"KILL": true,
|
||||
"SOME": true,
|
||||
"CONVERT": true,
|
||||
"LEFT": true,
|
||||
"STATISTICS": true,
|
||||
"CREATE": true,
|
||||
"LIKE": true,
|
||||
"SYSTEM_USER": true,
|
||||
"CROSS": true,
|
||||
"LINENO": true,
|
||||
"TABLE": true,
|
||||
"CURRENT": true,
|
||||
"LOAD": true,
|
||||
"TABLESAMPLE": true,
|
||||
"CURRENT_DATE": true,
|
||||
"MERGE": true,
|
||||
"TEXTSIZE": true,
|
||||
"CURRENT_TIME": true,
|
||||
"NATIONAL": true,
|
||||
"THEN": true,
|
||||
"CURRENT_TIMESTAMP": true,
|
||||
"NOCHECK": true,
|
||||
"TO": true,
|
||||
"CURRENT_USER": true,
|
||||
"NONCLUSTERED": true,
|
||||
"TOP": true,
|
||||
"CURSOR": true,
|
||||
"NOT": true,
|
||||
"TRAN": true,
|
||||
"DATABASE": true,
|
||||
"NULL": true,
|
||||
"TRANSACTION": true,
|
||||
"DBCC": true,
|
||||
"NULLIF": true,
|
||||
"TRIGGER": true,
|
||||
"DEALLOCATE": true,
|
||||
"OF": true,
|
||||
"TRUNCATE": true,
|
||||
"DECLARE": true,
|
||||
"OFF": true,
|
||||
"TRY_CONVERT": true,
|
||||
"DEFAULT": true,
|
||||
"OFFSETS": true,
|
||||
"TSEQUAL": true,
|
||||
"DELETE": true,
|
||||
"ON": true,
|
||||
"UNION": true,
|
||||
"DENY": true,
|
||||
"OPEN": true,
|
||||
"UNIQUE": true,
|
||||
"DESC": true,
|
||||
"OPENDATASOURCE": true,
|
||||
"UNPIVOT": true,
|
||||
"DISK": true,
|
||||
"OPENQUERY": true,
|
||||
"UPDATE": true,
|
||||
"DISTINCT": true,
|
||||
"OPENROWSET": true,
|
||||
"UPDATETEXT": true,
|
||||
"DISTRIBUTED": true,
|
||||
"OPENXML": true,
|
||||
"USE": true,
|
||||
"DOUBLE": true,
|
||||
"OPTION": true,
|
||||
"USER": true,
|
||||
"DROP": true,
|
||||
"OR": true,
|
||||
"VALUES": true,
|
||||
"DUMP": true,
|
||||
"ORDER": true,
|
||||
"VARYING": true,
|
||||
"ELSE": true,
|
||||
"OUTER": true,
|
||||
"VIEW": true,
|
||||
"END": true,
|
||||
"OVER": true,
|
||||
"WAITFOR": true,
|
||||
"ERRLVL": true,
|
||||
"PERCENT": true,
|
||||
"WHEN": true,
|
||||
"ESCAPE": true,
|
||||
"PIVOT": true,
|
||||
"WHERE": true,
|
||||
"EXCEPT": true,
|
||||
"PLAN": true,
|
||||
"WHILE": true,
|
||||
"EXEC": true,
|
||||
"PRECISION": true,
|
||||
"WITH": true,
|
||||
"EXECUTE": true,
|
||||
"PRIMARY": true,
|
||||
"WITHIN": true,
|
||||
"EXISTS": true,
|
||||
"PRINT": true,
|
||||
"WRITETEXT": true,
|
||||
"EXIT": true,
|
||||
"PROC": true,
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -286,10 +286,6 @@ func (db *mssql) Quote(name string) string {
|
|||
return "\"" + name + "\""
|
||||
}
|
||||
|
||||
func (db *mssql) QuoteStr() string {
|
||||
return "\""
|
||||
}
|
||||
|
||||
func (db *mssql) SupportEngine() bool {
|
||||
return false
|
||||
}
|
||||
|
@ -507,7 +503,7 @@ func (db *mssql) CreateTableSql(table *core.Table, tableName, storeEngine, chars
|
|||
|
||||
sql = "IF NOT EXISTS (SELECT [name] FROM sys.tables WHERE [name] = '" + tableName + "' ) CREATE TABLE "
|
||||
|
||||
sql += db.QuoteStr() + tableName + db.QuoteStr() + " ("
|
||||
sql += db.Quote(tableName) + " ("
|
||||
|
||||
pkList := table.PrimaryKeys
|
||||
|
||||
|
|
|
@ -220,7 +220,7 @@ func (db *mysql) SqlType(c *core.Column) string {
|
|||
case core.TimeStampz:
|
||||
res = core.Char
|
||||
c.Length = 64
|
||||
case core.Enum: //mysql enum
|
||||
case core.Enum: // mysql enum
|
||||
res = core.Enum
|
||||
res += "("
|
||||
opts := ""
|
||||
|
@ -229,7 +229,7 @@ func (db *mysql) SqlType(c *core.Column) string {
|
|||
}
|
||||
res += strings.TrimLeft(opts, ",")
|
||||
res += ")"
|
||||
case core.Set: //mysql set
|
||||
case core.Set: // mysql set
|
||||
res = core.Set
|
||||
res += "("
|
||||
opts := ""
|
||||
|
@ -278,10 +278,6 @@ func (db *mysql) Quote(name string) string {
|
|||
return "`" + name + "`"
|
||||
}
|
||||
|
||||
func (db *mysql) QuoteStr() string {
|
||||
return "`"
|
||||
}
|
||||
|
||||
func (db *mysql) SupportEngine() bool {
|
||||
return true
|
||||
}
|
||||
|
@ -360,7 +356,7 @@ func (db *mysql) GetColumns(tableName string) ([]string, map[string]*core.Column
|
|||
var len1, len2 int
|
||||
if len(cts) == 2 {
|
||||
idx := strings.Index(cts[1], ")")
|
||||
if colType == core.Enum && cts[1][0] == '\'' { //enum
|
||||
if colType == core.Enum && cts[1][0] == '\'' { // enum
|
||||
options := strings.Split(cts[1][0:idx], ",")
|
||||
col.EnumOptions = make(map[string]int)
|
||||
for k, v := range options {
|
||||
|
@ -408,7 +404,7 @@ func (db *mysql) GetColumns(tableName string) ([]string, map[string]*core.Column
|
|||
col.IsPrimaryKey = true
|
||||
}
|
||||
if colKey == "UNI" {
|
||||
//col.is
|
||||
// col.is
|
||||
}
|
||||
|
||||
if extra == "auto_increment" {
|
||||
|
@ -554,12 +550,10 @@ func (db *mysql) CreateTableSql(table *core.Table, tableName, storeEngine, chars
|
|||
|
||||
if len(charset) == 0 {
|
||||
charset = db.URI().Charset
|
||||
}
|
||||
}
|
||||
if len(charset) != 0 {
|
||||
sql += " DEFAULT CHARSET " + charset
|
||||
}
|
||||
|
||||
|
||||
|
||||
if db.rowFormat != "" {
|
||||
sql += " ROW_FORMAT=" + db.rowFormat
|
||||
|
@ -633,7 +627,7 @@ func (p *mysqlDriver) Parse(driverName, dataSourceName string) (*core.Uri, error
|
|||
`\/(?P<dbname>.*?)` + // /dbname
|
||||
`(?:\?(?P<params>[^\?]*))?$`) // [?param1=value1¶mN=valueN]
|
||||
matches := dsnPattern.FindStringSubmatch(dataSourceName)
|
||||
//tlsConfigRegister := make(map[string]*tls.Config)
|
||||
// tlsConfigRegister := make(map[string]*tls.Config)
|
||||
names := dsnPattern.SubexpNames()
|
||||
|
||||
uri := &core.Uri{DbType: core.MYSQL}
|
||||
|
|
|
@ -230,271 +230,271 @@ var (
|
|||
"LOGGING": true,
|
||||
"LOGICAL_READS_PER_CALL": true,
|
||||
"LOGICAL_READS_PER_SESSION": true,
|
||||
"LONG": true,
|
||||
"MANAGE": true,
|
||||
"MASTER": true,
|
||||
"MAX": true,
|
||||
"MAXARCHLOGS": true,
|
||||
"MAXDATAFILES": true,
|
||||
"MAXEXTENTS": true,
|
||||
"MAXINSTANCES": true,
|
||||
"MAXLOGFILES": true,
|
||||
"MAXLOGHISTORY": true,
|
||||
"MAXLOGMEMBERS": true,
|
||||
"MAXSIZE": true,
|
||||
"MAXTRANS": true,
|
||||
"MAXVALUE": true,
|
||||
"MIN": true,
|
||||
"MEMBER": true,
|
||||
"MINIMUM": true,
|
||||
"MINEXTENTS": true,
|
||||
"MINUS": true,
|
||||
"MINVALUE": true,
|
||||
"MLSLABEL": true,
|
||||
"MLS_LABEL_FORMAT": true,
|
||||
"MODE": true,
|
||||
"MODIFY": true,
|
||||
"MOUNT": true,
|
||||
"MOVE": true,
|
||||
"MTS_DISPATCHERS": true,
|
||||
"MULTISET": true,
|
||||
"NATIONAL": true,
|
||||
"NCHAR": true,
|
||||
"NCHAR_CS": true,
|
||||
"NCLOB": true,
|
||||
"NEEDED": true,
|
||||
"NESTED": true,
|
||||
"NETWORK": true,
|
||||
"NEW": true,
|
||||
"NEXT": true,
|
||||
"NOARCHIVELOG": true,
|
||||
"NOAUDIT": true,
|
||||
"NOCACHE": true,
|
||||
"NOCOMPRESS": true,
|
||||
"NOCYCLE": true,
|
||||
"NOFORCE": true,
|
||||
"NOLOGGING": true,
|
||||
"NOMAXVALUE": true,
|
||||
"NOMINVALUE": true,
|
||||
"NONE": true,
|
||||
"NOORDER": true,
|
||||
"NOOVERRIDE": true,
|
||||
"NOPARALLEL": true,
|
||||
"NOREVERSE": true,
|
||||
"NORMAL": true,
|
||||
"NOSORT": true,
|
||||
"NOT": true,
|
||||
"NOTHING": true,
|
||||
"NOWAIT": true,
|
||||
"NULL": true,
|
||||
"NUMBER": true,
|
||||
"NUMERIC": true,
|
||||
"NVARCHAR2": true,
|
||||
"OBJECT": true,
|
||||
"OBJNO": true,
|
||||
"OBJNO_REUSE": true,
|
||||
"OF": true,
|
||||
"OFF": true,
|
||||
"OFFLINE": true,
|
||||
"OID": true,
|
||||
"OIDINDEX": true,
|
||||
"OLD": true,
|
||||
"ON": true,
|
||||
"ONLINE": true,
|
||||
"ONLY": true,
|
||||
"OPCODE": true,
|
||||
"OPEN": true,
|
||||
"OPTIMAL": true,
|
||||
"OPTIMIZER_GOAL": true,
|
||||
"OPTION": true,
|
||||
"OR": true,
|
||||
"ORDER": true,
|
||||
"ORGANIZATION": true,
|
||||
"OSLABEL": true,
|
||||
"OVERFLOW": true,
|
||||
"OWN": true,
|
||||
"PACKAGE": true,
|
||||
"PARALLEL": true,
|
||||
"PARTITION": true,
|
||||
"PASSWORD": true,
|
||||
"PASSWORD_GRACE_TIME": true,
|
||||
"PASSWORD_LIFE_TIME": true,
|
||||
"PASSWORD_LOCK_TIME": true,
|
||||
"PASSWORD_REUSE_MAX": true,
|
||||
"PASSWORD_REUSE_TIME": true,
|
||||
"PASSWORD_VERIFY_FUNCTION": true,
|
||||
"PCTFREE": true,
|
||||
"PCTINCREASE": true,
|
||||
"PCTTHRESHOLD": true,
|
||||
"PCTUSED": true,
|
||||
"PCTVERSION": true,
|
||||
"PERCENT": true,
|
||||
"PERMANENT": true,
|
||||
"PLAN": true,
|
||||
"PLSQL_DEBUG": true,
|
||||
"POST_TRANSACTION": true,
|
||||
"PRECISION": true,
|
||||
"PRESERVE": true,
|
||||
"PRIMARY": true,
|
||||
"PRIOR": true,
|
||||
"PRIVATE": true,
|
||||
"PRIVATE_SGA": true,
|
||||
"PRIVILEGE": true,
|
||||
"PRIVILEGES": true,
|
||||
"PROCEDURE": true,
|
||||
"PROFILE": true,
|
||||
"PUBLIC": true,
|
||||
"PURGE": true,
|
||||
"QUEUE": true,
|
||||
"QUOTA": true,
|
||||
"RANGE": true,
|
||||
"RAW": true,
|
||||
"RBA": true,
|
||||
"READ": true,
|
||||
"READUP": true,
|
||||
"REAL": true,
|
||||
"REBUILD": true,
|
||||
"RECOVER": true,
|
||||
"RECOVERABLE": true,
|
||||
"RECOVERY": true,
|
||||
"REF": true,
|
||||
"REFERENCES": true,
|
||||
"REFERENCING": true,
|
||||
"REFRESH": true,
|
||||
"RENAME": true,
|
||||
"REPLACE": true,
|
||||
"RESET": true,
|
||||
"RESETLOGS": true,
|
||||
"RESIZE": true,
|
||||
"RESOURCE": true,
|
||||
"RESTRICTED": true,
|
||||
"RETURN": true,
|
||||
"RETURNING": true,
|
||||
"REUSE": true,
|
||||
"REVERSE": true,
|
||||
"REVOKE": true,
|
||||
"ROLE": true,
|
||||
"ROLES": true,
|
||||
"ROLLBACK": true,
|
||||
"ROW": true,
|
||||
"ROWID": true,
|
||||
"ROWNUM": true,
|
||||
"ROWS": true,
|
||||
"RULE": true,
|
||||
"SAMPLE": true,
|
||||
"SAVEPOINT": true,
|
||||
"SB4": true,
|
||||
"SCAN_INSTANCES": true,
|
||||
"SCHEMA": true,
|
||||
"SCN": true,
|
||||
"SCOPE": true,
|
||||
"SD_ALL": true,
|
||||
"SD_INHIBIT": true,
|
||||
"SD_SHOW": true,
|
||||
"SEGMENT": true,
|
||||
"SEG_BLOCK": true,
|
||||
"SEG_FILE": true,
|
||||
"SELECT": true,
|
||||
"SEQUENCE": true,
|
||||
"SERIALIZABLE": true,
|
||||
"SESSION": true,
|
||||
"SESSION_CACHED_CURSORS": true,
|
||||
"SESSIONS_PER_USER": true,
|
||||
"SET": true,
|
||||
"SHARE": true,
|
||||
"SHARED": true,
|
||||
"SHARED_POOL": true,
|
||||
"SHRINK": true,
|
||||
"SIZE": true,
|
||||
"SKIP": true,
|
||||
"SKIP_UNUSABLE_INDEXES": true,
|
||||
"SMALLINT": true,
|
||||
"SNAPSHOT": true,
|
||||
"SOME": true,
|
||||
"SORT": true,
|
||||
"SPECIFICATION": true,
|
||||
"SPLIT": true,
|
||||
"SQL_TRACE": true,
|
||||
"STANDBY": true,
|
||||
"START": true,
|
||||
"STATEMENT_ID": true,
|
||||
"STATISTICS": true,
|
||||
"STOP": true,
|
||||
"STORAGE": true,
|
||||
"STORE": true,
|
||||
"STRUCTURE": true,
|
||||
"SUCCESSFUL": true,
|
||||
"SWITCH": true,
|
||||
"SYS_OP_ENFORCE_NOT_NULL$": true,
|
||||
"SYS_OP_NTCIMG$": true,
|
||||
"SYNONYM": true,
|
||||
"SYSDATE": true,
|
||||
"SYSDBA": true,
|
||||
"SYSOPER": true,
|
||||
"SYSTEM": true,
|
||||
"TABLE": true,
|
||||
"TABLES": true,
|
||||
"TABLESPACE": true,
|
||||
"TABLESPACE_NO": true,
|
||||
"TABNO": true,
|
||||
"TEMPORARY": true,
|
||||
"THAN": true,
|
||||
"THE": true,
|
||||
"THEN": true,
|
||||
"THREAD": true,
|
||||
"TIMESTAMP": true,
|
||||
"TIME": true,
|
||||
"TO": true,
|
||||
"TOPLEVEL": true,
|
||||
"TRACE": true,
|
||||
"TRACING": true,
|
||||
"TRANSACTION": true,
|
||||
"TRANSITIONAL": true,
|
||||
"TRIGGER": true,
|
||||
"TRIGGERS": true,
|
||||
"TRUE": true,
|
||||
"TRUNCATE": true,
|
||||
"TX": true,
|
||||
"TYPE": true,
|
||||
"UB2": true,
|
||||
"UBA": true,
|
||||
"UID": true,
|
||||
"UNARCHIVED": true,
|
||||
"UNDO": true,
|
||||
"UNION": true,
|
||||
"UNIQUE": true,
|
||||
"UNLIMITED": true,
|
||||
"UNLOCK": true,
|
||||
"UNRECOVERABLE": true,
|
||||
"UNTIL": true,
|
||||
"UNUSABLE": true,
|
||||
"UNUSED": true,
|
||||
"UPDATABLE": true,
|
||||
"UPDATE": true,
|
||||
"USAGE": true,
|
||||
"USE": true,
|
||||
"USER": true,
|
||||
"USING": true,
|
||||
"VALIDATE": true,
|
||||
"VALIDATION": true,
|
||||
"VALUE": true,
|
||||
"VALUES": true,
|
||||
"VARCHAR": true,
|
||||
"VARCHAR2": true,
|
||||
"VARYING": true,
|
||||
"VIEW": true,
|
||||
"WHEN": true,
|
||||
"WHENEVER": true,
|
||||
"WHERE": true,
|
||||
"WITH": true,
|
||||
"WITHOUT": true,
|
||||
"WORK": true,
|
||||
"WRITE": true,
|
||||
"WRITEDOWN": true,
|
||||
"WRITEUP": true,
|
||||
"XID": true,
|
||||
"YEAR": true,
|
||||
"ZONE": true,
|
||||
"LONG": true,
|
||||
"MANAGE": true,
|
||||
"MASTER": true,
|
||||
"MAX": true,
|
||||
"MAXARCHLOGS": true,
|
||||
"MAXDATAFILES": true,
|
||||
"MAXEXTENTS": true,
|
||||
"MAXINSTANCES": true,
|
||||
"MAXLOGFILES": true,
|
||||
"MAXLOGHISTORY": true,
|
||||
"MAXLOGMEMBERS": true,
|
||||
"MAXSIZE": true,
|
||||
"MAXTRANS": true,
|
||||
"MAXVALUE": true,
|
||||
"MIN": true,
|
||||
"MEMBER": true,
|
||||
"MINIMUM": true,
|
||||
"MINEXTENTS": true,
|
||||
"MINUS": true,
|
||||
"MINVALUE": true,
|
||||
"MLSLABEL": true,
|
||||
"MLS_LABEL_FORMAT": true,
|
||||
"MODE": true,
|
||||
"MODIFY": true,
|
||||
"MOUNT": true,
|
||||
"MOVE": true,
|
||||
"MTS_DISPATCHERS": true,
|
||||
"MULTISET": true,
|
||||
"NATIONAL": true,
|
||||
"NCHAR": true,
|
||||
"NCHAR_CS": true,
|
||||
"NCLOB": true,
|
||||
"NEEDED": true,
|
||||
"NESTED": true,
|
||||
"NETWORK": true,
|
||||
"NEW": true,
|
||||
"NEXT": true,
|
||||
"NOARCHIVELOG": true,
|
||||
"NOAUDIT": true,
|
||||
"NOCACHE": true,
|
||||
"NOCOMPRESS": true,
|
||||
"NOCYCLE": true,
|
||||
"NOFORCE": true,
|
||||
"NOLOGGING": true,
|
||||
"NOMAXVALUE": true,
|
||||
"NOMINVALUE": true,
|
||||
"NONE": true,
|
||||
"NOORDER": true,
|
||||
"NOOVERRIDE": true,
|
||||
"NOPARALLEL": true,
|
||||
"NOREVERSE": true,
|
||||
"NORMAL": true,
|
||||
"NOSORT": true,
|
||||
"NOT": true,
|
||||
"NOTHING": true,
|
||||
"NOWAIT": true,
|
||||
"NULL": true,
|
||||
"NUMBER": true,
|
||||
"NUMERIC": true,
|
||||
"NVARCHAR2": true,
|
||||
"OBJECT": true,
|
||||
"OBJNO": true,
|
||||
"OBJNO_REUSE": true,
|
||||
"OF": true,
|
||||
"OFF": true,
|
||||
"OFFLINE": true,
|
||||
"OID": true,
|
||||
"OIDINDEX": true,
|
||||
"OLD": true,
|
||||
"ON": true,
|
||||
"ONLINE": true,
|
||||
"ONLY": true,
|
||||
"OPCODE": true,
|
||||
"OPEN": true,
|
||||
"OPTIMAL": true,
|
||||
"OPTIMIZER_GOAL": true,
|
||||
"OPTION": true,
|
||||
"OR": true,
|
||||
"ORDER": true,
|
||||
"ORGANIZATION": true,
|
||||
"OSLABEL": true,
|
||||
"OVERFLOW": true,
|
||||
"OWN": true,
|
||||
"PACKAGE": true,
|
||||
"PARALLEL": true,
|
||||
"PARTITION": true,
|
||||
"PASSWORD": true,
|
||||
"PASSWORD_GRACE_TIME": true,
|
||||
"PASSWORD_LIFE_TIME": true,
|
||||
"PASSWORD_LOCK_TIME": true,
|
||||
"PASSWORD_REUSE_MAX": true,
|
||||
"PASSWORD_REUSE_TIME": true,
|
||||
"PASSWORD_VERIFY_FUNCTION": true,
|
||||
"PCTFREE": true,
|
||||
"PCTINCREASE": true,
|
||||
"PCTTHRESHOLD": true,
|
||||
"PCTUSED": true,
|
||||
"PCTVERSION": true,
|
||||
"PERCENT": true,
|
||||
"PERMANENT": true,
|
||||
"PLAN": true,
|
||||
"PLSQL_DEBUG": true,
|
||||
"POST_TRANSACTION": true,
|
||||
"PRECISION": true,
|
||||
"PRESERVE": true,
|
||||
"PRIMARY": true,
|
||||
"PRIOR": true,
|
||||
"PRIVATE": true,
|
||||
"PRIVATE_SGA": true,
|
||||
"PRIVILEGE": true,
|
||||
"PRIVILEGES": true,
|
||||
"PROCEDURE": true,
|
||||
"PROFILE": true,
|
||||
"PUBLIC": true,
|
||||
"PURGE": true,
|
||||
"QUEUE": true,
|
||||
"QUOTA": true,
|
||||
"RANGE": true,
|
||||
"RAW": true,
|
||||
"RBA": true,
|
||||
"READ": true,
|
||||
"READUP": true,
|
||||
"REAL": true,
|
||||
"REBUILD": true,
|
||||
"RECOVER": true,
|
||||
"RECOVERABLE": true,
|
||||
"RECOVERY": true,
|
||||
"REF": true,
|
||||
"REFERENCES": true,
|
||||
"REFERENCING": true,
|
||||
"REFRESH": true,
|
||||
"RENAME": true,
|
||||
"REPLACE": true,
|
||||
"RESET": true,
|
||||
"RESETLOGS": true,
|
||||
"RESIZE": true,
|
||||
"RESOURCE": true,
|
||||
"RESTRICTED": true,
|
||||
"RETURN": true,
|
||||
"RETURNING": true,
|
||||
"REUSE": true,
|
||||
"REVERSE": true,
|
||||
"REVOKE": true,
|
||||
"ROLE": true,
|
||||
"ROLES": true,
|
||||
"ROLLBACK": true,
|
||||
"ROW": true,
|
||||
"ROWID": true,
|
||||
"ROWNUM": true,
|
||||
"ROWS": true,
|
||||
"RULE": true,
|
||||
"SAMPLE": true,
|
||||
"SAVEPOINT": true,
|
||||
"SB4": true,
|
||||
"SCAN_INSTANCES": true,
|
||||
"SCHEMA": true,
|
||||
"SCN": true,
|
||||
"SCOPE": true,
|
||||
"SD_ALL": true,
|
||||
"SD_INHIBIT": true,
|
||||
"SD_SHOW": true,
|
||||
"SEGMENT": true,
|
||||
"SEG_BLOCK": true,
|
||||
"SEG_FILE": true,
|
||||
"SELECT": true,
|
||||
"SEQUENCE": true,
|
||||
"SERIALIZABLE": true,
|
||||
"SESSION": true,
|
||||
"SESSION_CACHED_CURSORS": true,
|
||||
"SESSIONS_PER_USER": true,
|
||||
"SET": true,
|
||||
"SHARE": true,
|
||||
"SHARED": true,
|
||||
"SHARED_POOL": true,
|
||||
"SHRINK": true,
|
||||
"SIZE": true,
|
||||
"SKIP": true,
|
||||
"SKIP_UNUSABLE_INDEXES": true,
|
||||
"SMALLINT": true,
|
||||
"SNAPSHOT": true,
|
||||
"SOME": true,
|
||||
"SORT": true,
|
||||
"SPECIFICATION": true,
|
||||
"SPLIT": true,
|
||||
"SQL_TRACE": true,
|
||||
"STANDBY": true,
|
||||
"START": true,
|
||||
"STATEMENT_ID": true,
|
||||
"STATISTICS": true,
|
||||
"STOP": true,
|
||||
"STORAGE": true,
|
||||
"STORE": true,
|
||||
"STRUCTURE": true,
|
||||
"SUCCESSFUL": true,
|
||||
"SWITCH": true,
|
||||
"SYS_OP_ENFORCE_NOT_NULL$": true,
|
||||
"SYS_OP_NTCIMG$": true,
|
||||
"SYNONYM": true,
|
||||
"SYSDATE": true,
|
||||
"SYSDBA": true,
|
||||
"SYSOPER": true,
|
||||
"SYSTEM": true,
|
||||
"TABLE": true,
|
||||
"TABLES": true,
|
||||
"TABLESPACE": true,
|
||||
"TABLESPACE_NO": true,
|
||||
"TABNO": true,
|
||||
"TEMPORARY": true,
|
||||
"THAN": true,
|
||||
"THE": true,
|
||||
"THEN": true,
|
||||
"THREAD": true,
|
||||
"TIMESTAMP": true,
|
||||
"TIME": true,
|
||||
"TO": true,
|
||||
"TOPLEVEL": true,
|
||||
"TRACE": true,
|
||||
"TRACING": true,
|
||||
"TRANSACTION": true,
|
||||
"TRANSITIONAL": true,
|
||||
"TRIGGER": true,
|
||||
"TRIGGERS": true,
|
||||
"TRUE": true,
|
||||
"TRUNCATE": true,
|
||||
"TX": true,
|
||||
"TYPE": true,
|
||||
"UB2": true,
|
||||
"UBA": true,
|
||||
"UID": true,
|
||||
"UNARCHIVED": true,
|
||||
"UNDO": true,
|
||||
"UNION": true,
|
||||
"UNIQUE": true,
|
||||
"UNLIMITED": true,
|
||||
"UNLOCK": true,
|
||||
"UNRECOVERABLE": true,
|
||||
"UNTIL": true,
|
||||
"UNUSABLE": true,
|
||||
"UNUSED": true,
|
||||
"UPDATABLE": true,
|
||||
"UPDATE": true,
|
||||
"USAGE": true,
|
||||
"USE": true,
|
||||
"USER": true,
|
||||
"USING": true,
|
||||
"VALIDATE": true,
|
||||
"VALIDATION": true,
|
||||
"VALUE": true,
|
||||
"VALUES": true,
|
||||
"VARCHAR": true,
|
||||
"VARCHAR2": true,
|
||||
"VARYING": true,
|
||||
"VIEW": true,
|
||||
"WHEN": true,
|
||||
"WHENEVER": true,
|
||||
"WHERE": true,
|
||||
"WITH": true,
|
||||
"WITHOUT": true,
|
||||
"WORK": true,
|
||||
"WRITE": true,
|
||||
"WRITEDOWN": true,
|
||||
"WRITEUP": true,
|
||||
"XID": true,
|
||||
"YEAR": true,
|
||||
"ZONE": true,
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -552,11 +552,7 @@ func (db *oracle) IsReserved(name string) bool {
|
|||
}
|
||||
|
||||
func (db *oracle) Quote(name string) string {
|
||||
return "\"" + name + "\""
|
||||
}
|
||||
|
||||
func (db *oracle) QuoteStr() string {
|
||||
return "\""
|
||||
return "[" + name + "]"
|
||||
}
|
||||
|
||||
func (db *oracle) SupportEngine() bool {
|
||||
|
@ -596,7 +592,7 @@ func (db *oracle) CreateTableSql(table *core.Table, tableName, storeEngine, char
|
|||
sql += col.String(b.dialect)
|
||||
} else {*/
|
||||
sql += col.StringNoPk(db)
|
||||
//}
|
||||
// }
|
||||
sql = strings.TrimSpace(sql)
|
||||
sql += ", "
|
||||
}
|
||||
|
@ -865,7 +861,7 @@ func (cfg *goracleDriver) Parse(driverName, dataSourceName string) (*core.Uri, e
|
|||
`\/(?P<dbname>.*?)` + // /dbname
|
||||
`(?:\?(?P<params>[^\?]*))?$`) // [?param1=value1¶mN=valueN]
|
||||
matches := dsnPattern.FindStringSubmatch(dataSourceName)
|
||||
//tlsConfigRegister := make(map[string]*tls.Config)
|
||||
// tlsConfigRegister := make(map[string]*tls.Config)
|
||||
names := dsnPattern.SubexpNames()
|
||||
|
||||
for i, match := range matches {
|
||||
|
@ -883,8 +879,8 @@ func (cfg *goracleDriver) Parse(driverName, dataSourceName string) (*core.Uri, e
|
|||
type oci8Driver struct {
|
||||
}
|
||||
|
||||
//dataSourceName=user/password@ipv4:port/dbname
|
||||
//dataSourceName=user/password@[ipv6]:port/dbname
|
||||
// dataSourceName=user/password@ipv4:port/dbname
|
||||
// dataSourceName=user/password@[ipv6]:port/dbname
|
||||
func (p *oci8Driver) Parse(driverName, dataSourceName string) (*core.Uri, error) {
|
||||
db := &core.Uri{DbType: core.ORACLE}
|
||||
dsnPattern := regexp.MustCompile(
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -202,10 +202,6 @@ func (db *sqlite3) Quote(name string) string {
|
|||
return "`" + name + "`"
|
||||
}
|
||||
|
||||
func (db *sqlite3) QuoteStr() string {
|
||||
return "`"
|
||||
}
|
||||
|
||||
func (db *sqlite3) AutoIncrStr() string {
|
||||
return "AUTOINCREMENT"
|
||||
}
|
||||
|
|
|
@ -175,12 +175,6 @@ func (engine *Engine) SupportInsertMany() bool {
|
|||
return engine.dialect.SupportInsertMany()
|
||||
}
|
||||
|
||||
// QuoteStr Engine's database use which character as quote.
|
||||
// mysql, sqlite use ` and postgres use "
|
||||
func (engine *Engine) QuoteStr() string {
|
||||
return engine.dialect.QuoteStr()
|
||||
}
|
||||
|
||||
func (engine *Engine) quoteColumns(columnStr string) string {
|
||||
columns := strings.Split(columnStr, ",")
|
||||
for i := 0; i < len(columns); i++ {
|
||||
|
@ -196,13 +190,10 @@ func (engine *Engine) Quote(value string) string {
|
|||
return value
|
||||
}
|
||||
|
||||
if string(value[0]) == engine.dialect.QuoteStr() || value[0] == '`' {
|
||||
return value
|
||||
}
|
||||
buf := builder.StringBuilder{}
|
||||
engine.QuoteTo(&buf, value)
|
||||
|
||||
value = strings.Replace(value, ".", engine.dialect.QuoteStr()+"."+engine.dialect.QuoteStr(), -1)
|
||||
|
||||
return engine.dialect.QuoteStr() + value + engine.dialect.QuoteStr()
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// QuoteTo quotes string and writes into the buffer
|
||||
|
@ -216,20 +207,30 @@ func (engine *Engine) QuoteTo(buf *builder.StringBuilder, value string) {
|
|||
return
|
||||
}
|
||||
|
||||
if string(value[0]) == engine.dialect.QuoteStr() || value[0] == '`' {
|
||||
buf.WriteString(value)
|
||||
quotePair := engine.dialect.Quote("")
|
||||
|
||||
if value[0] == '`' || len(quotePair) < 2 || value[0] == quotePair[0] { // no quote
|
||||
_, _ = buf.WriteString(value)
|
||||
return
|
||||
} else {
|
||||
prefix, suffix := quotePair[0], quotePair[1]
|
||||
|
||||
_ = buf.WriteByte(prefix)
|
||||
for i := 0; i < len(value); i++ {
|
||||
if value[i] == '.' {
|
||||
_ = buf.WriteByte(suffix)
|
||||
_ = buf.WriteByte('.')
|
||||
_ = buf.WriteByte(prefix)
|
||||
} else {
|
||||
_ = buf.WriteByte(value[i])
|
||||
}
|
||||
}
|
||||
_ = buf.WriteByte(suffix)
|
||||
}
|
||||
|
||||
value = strings.Replace(value, ".", engine.dialect.QuoteStr()+"."+engine.dialect.QuoteStr(), -1)
|
||||
|
||||
buf.WriteString(engine.dialect.QuoteStr())
|
||||
buf.WriteString(value)
|
||||
buf.WriteString(engine.dialect.QuoteStr())
|
||||
}
|
||||
|
||||
func (engine *Engine) quote(sql string) string {
|
||||
return engine.dialect.QuoteStr() + sql + engine.dialect.QuoteStr()
|
||||
return engine.dialect.Quote(sql)
|
||||
}
|
||||
|
||||
// SqlType will be deprecated, please use SQLType instead
|
||||
|
@ -1581,7 +1582,7 @@ func (engine *Engine) formatColTime(col *core.Column, t time.Time) (v interface{
|
|||
func (engine *Engine) formatTime(sqlTypeName string, t time.Time) (v interface{}) {
|
||||
switch sqlTypeName {
|
||||
case core.Time:
|
||||
s := t.Format("2006-01-02 15:04:05") //time.RFC3339
|
||||
s := t.Format("2006-01-02 15:04:05") // time.RFC3339
|
||||
v = s[11:19]
|
||||
case core.Date:
|
||||
v = t.Format("2006-01-02")
|
||||
|
|
|
@ -15,5 +15,5 @@ require (
|
|||
github.com/stretchr/testify v1.3.0
|
||||
github.com/ziutek/mymysql v1.5.4
|
||||
xorm.io/builder v0.3.5
|
||||
xorm.io/core v0.6.3
|
||||
xorm.io/core v0.7.0
|
||||
)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0 h1:eOI3/cP2VTU6uZLDYAoic+eyzzB9YyGmJ7eIjl8rOPg=
|
||||
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=
|
||||
|
@ -13,7 +12,6 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24
|
|||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
|
||||
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
||||
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/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
|
@ -36,6 +34,7 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU
|
|||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
|
||||
|
@ -100,8 +99,9 @@ github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wK
|
|||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c h1:Vj5n4GlwjmQteupaxJ9+0FNOmBrHfq7vN4btdGoDZgI=
|
||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 h1:58fnuSXlxZmFdJyvtTFVmVhcMLU6v5fEb/ok4wyqtNU=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
|
@ -114,29 +114,38 @@ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73r
|
|||
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.0 h1:Tfd7cKwKbFRsI8RMAD3oqqw7JPFRrvFlOsfbgVkjOOw=
|
||||
google.golang.org/appengine v1.6.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
|
@ -155,5 +164,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.5 h1:EilU39fvWDxjb1cDaELpYhsF+zziRBhew8xk4pngO+A=
|
||||
xorm.io/builder v0.3.5/go.mod h1:ZFbByS/KxZI1FKRjL05PyJ4YrK2bcxlUaAxdum5aTR8=
|
||||
xorm.io/core v0.6.3 h1:n1NhVZt1s2oLw1BZfX2ocIJsHyso259uPgg63BGr37M=
|
||||
xorm.io/core v0.6.3/go.mod h1:8kz/C6arVW/O9vk3PgCiMJO2hIAm1UcuOL3dSPyZ2qo=
|
||||
xorm.io/core v0.7.0 h1:hKxuOKWZNeiFQsSuGet/KV8HZ788hclvAl+7azx3tkM=
|
||||
xorm.io/core v0.7.0/go.mod h1:TuOJjIVa7e3w/rN8tDcAvuLBMtwzdHPbyOzE6Gk1EUI=
|
||||
|
|
|
@ -281,7 +281,7 @@ func rValue(bean interface{}) reflect.Value {
|
|||
|
||||
func rType(bean interface{}) reflect.Type {
|
||||
sliceValue := reflect.Indirect(reflect.ValueOf(bean))
|
||||
//return reflect.TypeOf(sliceValue.Interface())
|
||||
// return reflect.TypeOf(sliceValue.Interface())
|
||||
return sliceValue.Type()
|
||||
}
|
||||
|
||||
|
@ -309,3 +309,24 @@ func sliceEq(left, right []string) bool {
|
|||
func indexName(tableName, idxName string) string {
|
||||
return fmt.Sprintf("IDX_%v_%v", tableName, idxName)
|
||||
}
|
||||
|
||||
func eraseAny(value string, strToErase ...string) string {
|
||||
if len(strToErase) == 0 {
|
||||
return value
|
||||
}
|
||||
var replaceSeq []string
|
||||
for _, s := range strToErase {
|
||||
replaceSeq = append(replaceSeq, s, "")
|
||||
}
|
||||
|
||||
replacer := strings.NewReplacer(replaceSeq...)
|
||||
|
||||
return replacer.Replace(value)
|
||||
}
|
||||
|
||||
func quoteColumns(cols []string, quoteFunc func(string) string, sep string) string {
|
||||
for i := range cols {
|
||||
cols[i] = quoteFunc(cols[i])
|
||||
}
|
||||
return strings.Join(cols, sep+" ")
|
||||
}
|
||||
|
|
|
@ -63,6 +63,8 @@ func (session *Session) FindAndCount(rowsSlicePtr interface{}, condiBean ...inte
|
|||
}
|
||||
|
||||
func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{}) error {
|
||||
defer session.resetStatement()
|
||||
|
||||
if session.statement.lastError != nil {
|
||||
return session.statement.lastError
|
||||
}
|
||||
|
|
|
@ -24,6 +24,8 @@ func (session *Session) Get(bean interface{}) (bool, error) {
|
|||
}
|
||||
|
||||
func (session *Session) get(bean interface{}) (bool, error) {
|
||||
defer session.resetStatement()
|
||||
|
||||
if session.statement.lastError != nil {
|
||||
return false, session.statement.lastError
|
||||
}
|
||||
|
@ -75,6 +77,8 @@ func (session *Session) get(bean interface{}) (bool, error) {
|
|||
if context != nil {
|
||||
res := context.Get(fmt.Sprintf("%v-%v", sqlStr, args))
|
||||
if res != nil {
|
||||
session.engine.logger.Debug("hit context cache", sqlStr)
|
||||
|
||||
structValue := reflect.Indirect(reflect.ValueOf(bean))
|
||||
structValue.Set(reflect.Indirect(reflect.ValueOf(res)))
|
||||
session.lastSQL = ""
|
||||
|
@ -114,6 +118,114 @@ func (session *Session) nocacheGet(beanKind reflect.Kind, table *core.Table, bea
|
|||
return true, rows.Scan(&bean)
|
||||
case *sql.NullInt64, *sql.NullBool, *sql.NullFloat64, *sql.NullString:
|
||||
return true, rows.Scan(bean)
|
||||
case *string:
|
||||
var res sql.NullString
|
||||
if err := rows.Scan(&res); err != nil {
|
||||
return true, err
|
||||
}
|
||||
if res.Valid {
|
||||
*(bean.(*string)) = res.String
|
||||
}
|
||||
return true, nil
|
||||
case *int:
|
||||
var res sql.NullInt64
|
||||
if err := rows.Scan(&res); err != nil {
|
||||
return true, err
|
||||
}
|
||||
if res.Valid {
|
||||
*(bean.(*int)) = int(res.Int64)
|
||||
}
|
||||
return true, nil
|
||||
case *int8:
|
||||
var res sql.NullInt64
|
||||
if err := rows.Scan(&res); err != nil {
|
||||
return true, err
|
||||
}
|
||||
if res.Valid {
|
||||
*(bean.(*int8)) = int8(res.Int64)
|
||||
}
|
||||
return true, nil
|
||||
case *int16:
|
||||
var res sql.NullInt64
|
||||
if err := rows.Scan(&res); err != nil {
|
||||
return true, err
|
||||
}
|
||||
if res.Valid {
|
||||
*(bean.(*int16)) = int16(res.Int64)
|
||||
}
|
||||
return true, nil
|
||||
case *int32:
|
||||
var res sql.NullInt64
|
||||
if err := rows.Scan(&res); err != nil {
|
||||
return true, err
|
||||
}
|
||||
if res.Valid {
|
||||
*(bean.(*int32)) = int32(res.Int64)
|
||||
}
|
||||
return true, nil
|
||||
case *int64:
|
||||
var res sql.NullInt64
|
||||
if err := rows.Scan(&res); err != nil {
|
||||
return true, err
|
||||
}
|
||||
if res.Valid {
|
||||
*(bean.(*int64)) = int64(res.Int64)
|
||||
}
|
||||
return true, nil
|
||||
case *uint:
|
||||
var res sql.NullInt64
|
||||
if err := rows.Scan(&res); err != nil {
|
||||
return true, err
|
||||
}
|
||||
if res.Valid {
|
||||
*(bean.(*uint)) = uint(res.Int64)
|
||||
}
|
||||
return true, nil
|
||||
case *uint8:
|
||||
var res sql.NullInt64
|
||||
if err := rows.Scan(&res); err != nil {
|
||||
return true, err
|
||||
}
|
||||
if res.Valid {
|
||||
*(bean.(*uint8)) = uint8(res.Int64)
|
||||
}
|
||||
return true, nil
|
||||
case *uint16:
|
||||
var res sql.NullInt64
|
||||
if err := rows.Scan(&res); err != nil {
|
||||
return true, err
|
||||
}
|
||||
if res.Valid {
|
||||
*(bean.(*uint16)) = uint16(res.Int64)
|
||||
}
|
||||
return true, nil
|
||||
case *uint32:
|
||||
var res sql.NullInt64
|
||||
if err := rows.Scan(&res); err != nil {
|
||||
return true, err
|
||||
}
|
||||
if res.Valid {
|
||||
*(bean.(*uint32)) = uint32(res.Int64)
|
||||
}
|
||||
return true, nil
|
||||
case *uint64:
|
||||
var res sql.NullInt64
|
||||
if err := rows.Scan(&res); err != nil {
|
||||
return true, err
|
||||
}
|
||||
if res.Valid {
|
||||
*(bean.(*uint64)) = uint64(res.Int64)
|
||||
}
|
||||
return true, nil
|
||||
case *bool:
|
||||
var res sql.NullBool
|
||||
if err := rows.Scan(&res); err != nil {
|
||||
return true, err
|
||||
}
|
||||
if res.Valid {
|
||||
*(bean.(*bool)) = res.Bool
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
switch beanKind {
|
||||
|
@ -142,6 +254,9 @@ func (session *Session) nocacheGet(beanKind reflect.Kind, table *core.Table, bea
|
|||
err = rows.ScanSlice(bean)
|
||||
case reflect.Map:
|
||||
err = rows.ScanMap(bean)
|
||||
case reflect.String, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
|
||||
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
err = rows.Scan(bean)
|
||||
default:
|
||||
err = rows.Scan(bean)
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"xorm.io/builder"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
|
@ -242,23 +243,17 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error
|
|||
|
||||
var sql string
|
||||
if session.engine.dialect.DBType() == core.ORACLE {
|
||||
temp := fmt.Sprintf(") INTO %s (%v%v%v) VALUES (",
|
||||
temp := fmt.Sprintf(") INTO %s (%v) VALUES (",
|
||||
session.engine.Quote(tableName),
|
||||
session.engine.QuoteStr(),
|
||||
strings.Join(colNames, session.engine.QuoteStr()+", "+session.engine.QuoteStr()),
|
||||
session.engine.QuoteStr())
|
||||
sql = fmt.Sprintf("INSERT ALL INTO %s (%v%v%v) VALUES (%v) SELECT 1 FROM DUAL",
|
||||
quoteColumns(colNames, session.engine.Quote, ","))
|
||||
sql = fmt.Sprintf("INSERT ALL INTO %s (%v) VALUES (%v) SELECT 1 FROM DUAL",
|
||||
session.engine.Quote(tableName),
|
||||
session.engine.QuoteStr(),
|
||||
strings.Join(colNames, session.engine.QuoteStr()+", "+session.engine.QuoteStr()),
|
||||
session.engine.QuoteStr(),
|
||||
quoteColumns(colNames, session.engine.Quote, ","),
|
||||
strings.Join(colMultiPlaces, temp))
|
||||
} else {
|
||||
sql = fmt.Sprintf("INSERT INTO %s (%v%v%v) VALUES (%v)",
|
||||
sql = fmt.Sprintf("INSERT INTO %s (%v) VALUES (%v)",
|
||||
session.engine.Quote(tableName),
|
||||
session.engine.QuoteStr(),
|
||||
strings.Join(colNames, session.engine.QuoteStr()+", "+session.engine.QuoteStr()),
|
||||
session.engine.QuoteStr(),
|
||||
quoteColumns(colNames, session.engine.Quote, ","),
|
||||
strings.Join(colMultiPlaces, "),("))
|
||||
}
|
||||
res, err := session.exec(sql, args...)
|
||||
|
@ -351,7 +346,7 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) {
|
|||
for _, v := range exprColumns {
|
||||
// remove the expr columns
|
||||
for i, colName := range colNames {
|
||||
if colName == v.colName {
|
||||
if colName == strings.Trim(v.colName, "`") {
|
||||
colNames = append(colNames[:i], colNames[i+1:]...)
|
||||
args = append(args[:i], args[i+1:]...)
|
||||
}
|
||||
|
@ -377,14 +372,30 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) {
|
|||
if session.engine.dialect.DBType() == core.MSSQL && len(table.AutoIncrement) > 0 {
|
||||
output = fmt.Sprintf(" OUTPUT Inserted.%s", table.AutoIncrement)
|
||||
}
|
||||
|
||||
if len(colPlaces) > 0 {
|
||||
sqlStr = fmt.Sprintf("INSERT INTO %s (%v%v%v)%s VALUES (%v)",
|
||||
session.engine.Quote(tableName),
|
||||
session.engine.QuoteStr(),
|
||||
strings.Join(colNames, session.engine.Quote(", ")),
|
||||
session.engine.QuoteStr(),
|
||||
output,
|
||||
colPlaces)
|
||||
if session.statement.cond.IsValid() {
|
||||
condSQL, condArgs, err := builder.ToSQL(session.statement.cond)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
sqlStr = fmt.Sprintf("INSERT INTO %s (%v)%s SELECT %v FROM %v WHERE %v",
|
||||
session.engine.Quote(tableName),
|
||||
quoteColumns(colNames, session.engine.Quote, ","),
|
||||
output,
|
||||
colPlaces,
|
||||
session.engine.Quote(tableName),
|
||||
condSQL,
|
||||
)
|
||||
args = append(args, condArgs...)
|
||||
} else {
|
||||
sqlStr = fmt.Sprintf("INSERT INTO %s (%v)%s VALUES (%v)",
|
||||
session.engine.Quote(tableName),
|
||||
quoteColumns(colNames, session.engine.Quote, ","),
|
||||
output,
|
||||
colPlaces)
|
||||
}
|
||||
} else {
|
||||
if session.engine.dialect.DBType() == core.MYSQL {
|
||||
sqlStr = fmt.Sprintf("INSERT INTO %s VALUES ()", session.engine.Quote(tableName))
|
||||
|
@ -671,6 +682,11 @@ func (session *Session) insertMapInterface(m map[string]interface{}) (int64, err
|
|||
return 0, ErrParamsType
|
||||
}
|
||||
|
||||
tableName := session.statement.TableName()
|
||||
if len(tableName) <= 0 {
|
||||
return 0, ErrTableNotFound
|
||||
}
|
||||
|
||||
var columns = make([]string, 0, len(m))
|
||||
for k := range m {
|
||||
columns = append(columns, k)
|
||||
|
@ -678,19 +694,40 @@ func (session *Session) insertMapInterface(m map[string]interface{}) (int64, err
|
|||
sort.Strings(columns)
|
||||
|
||||
qm := strings.Repeat("?,", len(columns))
|
||||
qm = "(" + qm[:len(qm)-1] + ")"
|
||||
|
||||
tableName := session.statement.TableName()
|
||||
if len(tableName) <= 0 {
|
||||
return 0, ErrTableNotFound
|
||||
}
|
||||
|
||||
var sql = fmt.Sprintf("INSERT INTO %s (`%s`) VALUES %s", session.engine.Quote(tableName), strings.Join(columns, "`,`"), qm)
|
||||
var args = make([]interface{}, 0, len(m))
|
||||
for _, colName := range columns {
|
||||
args = append(args, m[colName])
|
||||
}
|
||||
|
||||
// insert expr columns, override if exists
|
||||
exprColumns := session.statement.getExpr()
|
||||
for _, col := range exprColumns {
|
||||
columns = append(columns, strings.Trim(col.colName, "`"))
|
||||
qm = qm + col.expr + ","
|
||||
}
|
||||
|
||||
qm = qm[:len(qm)-1]
|
||||
|
||||
var sql string
|
||||
|
||||
if session.statement.cond.IsValid() {
|
||||
condSQL, condArgs, err := builder.ToSQL(session.statement.cond)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
sql = fmt.Sprintf("INSERT INTO %s (`%s`) SELECT %s FROM %s WHERE %s",
|
||||
session.engine.Quote(tableName),
|
||||
strings.Join(columns, "`,`"),
|
||||
qm,
|
||||
session.engine.Quote(tableName),
|
||||
condSQL,
|
||||
)
|
||||
args = append(args, condArgs...)
|
||||
} else {
|
||||
sql = fmt.Sprintf("INSERT INTO %s (`%s`) VALUES (%s)", session.engine.Quote(tableName), strings.Join(columns, "`,`"), qm)
|
||||
}
|
||||
|
||||
if err := session.cacheInsert(tableName); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
@ -711,26 +748,53 @@ func (session *Session) insertMapString(m map[string]string) (int64, error) {
|
|||
return 0, ErrParamsType
|
||||
}
|
||||
|
||||
tableName := session.statement.TableName()
|
||||
if len(tableName) <= 0 {
|
||||
return 0, ErrTableNotFound
|
||||
}
|
||||
|
||||
var columns = make([]string, 0, len(m))
|
||||
for k := range m {
|
||||
columns = append(columns, k)
|
||||
}
|
||||
sort.Strings(columns)
|
||||
|
||||
qm := strings.Repeat("?,", len(columns))
|
||||
qm = "(" + qm[:len(qm)-1] + ")"
|
||||
|
||||
tableName := session.statement.TableName()
|
||||
if len(tableName) <= 0 {
|
||||
return 0, ErrTableNotFound
|
||||
}
|
||||
|
||||
var sql = fmt.Sprintf("INSERT INTO %s (`%s`) VALUES %s", session.engine.Quote(tableName), strings.Join(columns, "`,`"), qm)
|
||||
var args = make([]interface{}, 0, len(m))
|
||||
for _, colName := range columns {
|
||||
args = append(args, m[colName])
|
||||
}
|
||||
|
||||
qm := strings.Repeat("?,", len(columns))
|
||||
|
||||
// insert expr columns, override if exists
|
||||
exprColumns := session.statement.getExpr()
|
||||
for _, col := range exprColumns {
|
||||
columns = append(columns, strings.Trim(col.colName, "`"))
|
||||
qm = qm + col.expr + ","
|
||||
}
|
||||
|
||||
qm = qm[:len(qm)-1]
|
||||
|
||||
var sql string
|
||||
|
||||
if session.statement.cond.IsValid() {
|
||||
qm = "(" + qm[:len(qm)-1] + ")"
|
||||
condSQL, condArgs, err := builder.ToSQL(session.statement.cond)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
sql = fmt.Sprintf("INSERT INTO %s (`%s`) SELECT %s FROM %s WHERE %s",
|
||||
session.engine.Quote(tableName),
|
||||
strings.Join(columns, "`,`"),
|
||||
qm,
|
||||
session.engine.Quote(tableName),
|
||||
condSQL,
|
||||
)
|
||||
args = append(args, condArgs...)
|
||||
} else {
|
||||
sql = fmt.Sprintf("INSERT INTO %s (`%s`) VALUES (%s)", session.engine.Quote(tableName), strings.Join(columns, "`,`"), qm)
|
||||
}
|
||||
|
||||
if err := session.cacheInsert(tableName); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
|
|
@ -96,14 +96,15 @@ func (session *Session) cacheUpdate(table *core.Table, tableName, sqlStr string,
|
|||
return ErrCacheFailed
|
||||
}
|
||||
kvs := strings.Split(strings.TrimSpace(sqls[1]), ",")
|
||||
|
||||
for idx, kv := range kvs {
|
||||
sps := strings.SplitN(kv, "=", 2)
|
||||
sps2 := strings.Split(sps[0], ".")
|
||||
colName := sps2[len(sps2)-1]
|
||||
if strings.Contains(colName, "`") {
|
||||
colName = strings.TrimSpace(strings.Replace(colName, "`", "", -1))
|
||||
} else if strings.Contains(colName, session.engine.QuoteStr()) {
|
||||
colName = strings.TrimSpace(strings.Replace(colName, session.engine.QuoteStr(), "", -1))
|
||||
// treat quote prefix, suffix and '`' as quotes
|
||||
quotes := append(strings.Split(session.engine.Quote(""), ""), "`")
|
||||
if strings.ContainsAny(colName, strings.Join(quotes, "")) {
|
||||
colName = strings.TrimSpace(eraseAny(colName, quotes...))
|
||||
} else {
|
||||
session.engine.logger.Debug("[cacheUpdate] cannot find column", tableName, colName)
|
||||
return ErrCacheFailed
|
||||
|
@ -221,19 +222,19 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
|
|||
}
|
||||
}
|
||||
|
||||
//for update action to like "column = column + ?"
|
||||
// for update action to like "column = column + ?"
|
||||
incColumns := session.statement.getInc()
|
||||
for _, v := range incColumns {
|
||||
colNames = append(colNames, session.engine.Quote(v.colName)+" = "+session.engine.Quote(v.colName)+" + ?")
|
||||
args = append(args, v.arg)
|
||||
}
|
||||
//for update action to like "column = column - ?"
|
||||
// for update action to like "column = column - ?"
|
||||
decColumns := session.statement.getDec()
|
||||
for _, v := range decColumns {
|
||||
colNames = append(colNames, session.engine.Quote(v.colName)+" = "+session.engine.Quote(v.colName)+" - ?")
|
||||
args = append(args, v.arg)
|
||||
}
|
||||
//for update action to like "column = expression"
|
||||
// for update action to like "column = expression"
|
||||
exprColumns := session.statement.getExpr()
|
||||
for _, v := range exprColumns {
|
||||
colNames = append(colNames, session.engine.Quote(v.colName)+" = "+v.expr)
|
||||
|
@ -382,7 +383,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
|
|||
}
|
||||
|
||||
if cacher := session.engine.getCacher(tableName); cacher != nil && session.statement.UseCache {
|
||||
//session.cacheUpdate(table, tableName, sqlStr, args...)
|
||||
// session.cacheUpdate(table, tableName, sqlStr, args...)
|
||||
session.engine.logger.Debug("[cacheUpdate] clear table ", tableName)
|
||||
cacher.ClearIds(tableName)
|
||||
cacher.ClearBeans(tableName)
|
||||
|
|
|
@ -6,7 +6,6 @@ package xorm
|
|||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
@ -398,7 +397,7 @@ func (statement *Statement) buildUpdates(bean interface{},
|
|||
continue
|
||||
}
|
||||
} else {
|
||||
//TODO: how to handler?
|
||||
// TODO: how to handler?
|
||||
panic("not supported")
|
||||
}
|
||||
} else {
|
||||
|
@ -579,21 +578,9 @@ func (statement *Statement) getExpr() map[string]exprParam {
|
|||
|
||||
func (statement *Statement) col2NewColsWithQuote(columns ...string) []string {
|
||||
newColumns := make([]string, 0)
|
||||
quotes := append(strings.Split(statement.Engine.Quote(""), ""), "`")
|
||||
for _, col := range columns {
|
||||
col = strings.Replace(col, "`", "", -1)
|
||||
col = strings.Replace(col, statement.Engine.QuoteStr(), "", -1)
|
||||
ccols := strings.Split(col, ",")
|
||||
for _, c := range ccols {
|
||||
fields := strings.Split(strings.TrimSpace(c), ".")
|
||||
if len(fields) == 1 {
|
||||
newColumns = append(newColumns, statement.Engine.quote(fields[0]))
|
||||
} else if len(fields) == 2 {
|
||||
newColumns = append(newColumns, statement.Engine.quote(fields[0])+"."+
|
||||
statement.Engine.quote(fields[1]))
|
||||
} else {
|
||||
panic(errors.New("unwanted colnames"))
|
||||
}
|
||||
}
|
||||
newColumns = append(newColumns, statement.Engine.Quote(eraseAny(col, quotes...)))
|
||||
}
|
||||
return newColumns
|
||||
}
|
||||
|
@ -764,7 +751,9 @@ func (statement *Statement) Join(joinOP string, tablename interface{}, condition
|
|||
return statement
|
||||
}
|
||||
tbs := strings.Split(tp.TableName(), ".")
|
||||
var aliasName = strings.Trim(tbs[len(tbs)-1], statement.Engine.QuoteStr())
|
||||
quotes := append(strings.Split(statement.Engine.Quote(""), ""), "`")
|
||||
|
||||
var aliasName = strings.Trim(tbs[len(tbs)-1], strings.Join(quotes, ""))
|
||||
fmt.Fprintf(&buf, "(%s) %s ON %v", subSQL, aliasName, condition)
|
||||
statement.joinArgs = append(statement.joinArgs, subQueryArgs...)
|
||||
case *builder.Builder:
|
||||
|
@ -774,7 +763,9 @@ func (statement *Statement) Join(joinOP string, tablename interface{}, condition
|
|||
return statement
|
||||
}
|
||||
tbs := strings.Split(tp.TableName(), ".")
|
||||
var aliasName = strings.Trim(tbs[len(tbs)-1], statement.Engine.QuoteStr())
|
||||
quotes := append(strings.Split(statement.Engine.Quote(""), ""), "`")
|
||||
|
||||
var aliasName = strings.Trim(tbs[len(tbs)-1], strings.Join(quotes, ""))
|
||||
fmt.Fprintf(&buf, "(%s) %s ON %v", subSQL, aliasName, condition)
|
||||
statement.joinArgs = append(statement.joinArgs, subQueryArgs...)
|
||||
default:
|
||||
|
@ -1157,8 +1148,12 @@ func (statement *Statement) genSelectSQL(columnStr, condSQL string, needLimit, n
|
|||
if statement.Start != 0 || statement.LimitN != 0 {
|
||||
oldString := buf.String()
|
||||
buf.Reset()
|
||||
rawColStr := columnStr
|
||||
if rawColStr == "*" {
|
||||
rawColStr = "at.*"
|
||||
}
|
||||
fmt.Fprintf(&buf, "SELECT %v FROM (SELECT %v,ROWNUM RN FROM (%v) at WHERE ROWNUM <= %d) aat WHERE RN > %d",
|
||||
columnStr, columnStr, oldString, statement.Start+statement.LimitN, statement.Start)
|
||||
columnStr, rawColStr, oldString, statement.Start+statement.LimitN, statement.Start)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1242,7 +1237,7 @@ func (statement *Statement) convertUpdateSQL(sqlStr string) (string, string) {
|
|||
|
||||
var whereStr = sqls[1]
|
||||
|
||||
//TODO: for postgres only, if any other database?
|
||||
// TODO: for postgres only, if any other database?
|
||||
var paraStr string
|
||||
if statement.Engine.dialect.DBType() == core.POSTGRES {
|
||||
paraStr = "$"
|
||||
|
|
|
@ -148,7 +148,7 @@ github.com/go-redis/redis/internal/proto
|
|||
github.com/go-redis/redis/internal/util
|
||||
# github.com/go-sql-driver/mysql v1.4.1
|
||||
github.com/go-sql-driver/mysql
|
||||
# github.com/go-xorm/xorm v0.7.4
|
||||
# github.com/go-xorm/xorm v0.7.7-0.20190822154023-17592d96b35b
|
||||
github.com/go-xorm/xorm
|
||||
# github.com/gogits/chardet v0.0.0-20150115103509-2404f7772561
|
||||
github.com/gogits/chardet
|
||||
|
@ -482,5 +482,5 @@ mvdan.cc/xurls/v2
|
|||
strk.kbt.io/projects/go/libravatar
|
||||
# xorm.io/builder v0.3.5
|
||||
xorm.io/builder
|
||||
# xorm.io/core v0.6.3
|
||||
# xorm.io/core v0.7.0
|
||||
xorm.io/core
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
workspace:
|
||||
base: /go
|
||||
path: src/xorm.io/core
|
||||
|
||||
clone:
|
||||
git:
|
||||
image: plugins/git:next
|
||||
depth: 50
|
||||
tags: true
|
||||
|
||||
matrix:
|
||||
GO_VERSION:
|
||||
- 1.9
|
||||
- 1.10
|
||||
- 1.11
|
||||
- 1.12
|
||||
|
||||
pipeline:
|
||||
test:
|
||||
image: golang:${GO_VERSION}
|
||||
environment:
|
||||
GOPROXY: https://goproxy.cn
|
||||
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
|
||||
- go get -u github.com/go-sql-driver/mysql
|
||||
- go get -u github.com/mattn/go-sqlite3
|
||||
- go vet
|
||||
- go test -v -race -coverprofile=coverage.txt -covermode=atomic -dbConn="root:@tcp(mysql:3306)/core_test?charset=utf8mb4"
|
||||
when:
|
||||
event: [ push, tag, pull_request ]
|
||||
|
||||
|
||||
services:
|
||||
mysql:
|
||||
image: mysql:5.7
|
||||
environment:
|
||||
- MYSQL_DATABASE=core_test
|
||||
- MYSQL_ALLOW_EMPTY_PASSWORD=yes
|
||||
when:
|
||||
event: [ push, tag, pull_request ]
|
|
@ -1,6 +1,8 @@
|
|||
Core is a lightweight wrapper of sql.DB.
|
||||
|
||||
[![CircleCI](https://circleci.com/gh/go-xorm/core/tree/master.svg?style=svg)](https://circleci.com/gh/go-xorm/core/tree/master)
|
||||
[![Build Status](https://drone.gitea.com/api/badges/xorm/core/status.svg)](https://drone.gitea.com/xorm/core)
|
||||
[![](http://gocover.io/_badge/xorm.io/core)](http://gocover.io/xorm.io/core)
|
||||
[![Go Report Card](https://goreportcard.com/badge/code.gitea.io/gitea)](https://goreportcard.com/report/xorm.io/core)
|
||||
|
||||
# Open
|
||||
```Go
|
||||
|
|
|
@ -14,19 +14,20 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
// default cache expired time
|
||||
// CacheExpired is default cache expired time
|
||||
CacheExpired = 60 * time.Minute
|
||||
// not use now
|
||||
// CacheMaxMemory is not use now
|
||||
CacheMaxMemory = 256
|
||||
// evey ten minutes to clear all expired nodes
|
||||
// CacheGcInterval represents interval time to clear all expired nodes
|
||||
CacheGcInterval = 10 * time.Minute
|
||||
// each time when gc to removed max nodes
|
||||
// CacheGcMaxRemoved represents max nodes removed when gc
|
||||
CacheGcMaxRemoved = 20
|
||||
)
|
||||
|
||||
// list all the errors
|
||||
var (
|
||||
ErrCacheMiss = errors.New("xorm/cache: key not found.")
|
||||
ErrNotStored = errors.New("xorm/cache: not stored.")
|
||||
ErrCacheMiss = errors.New("xorm/cache: key not found")
|
||||
ErrNotStored = errors.New("xorm/cache: not stored")
|
||||
)
|
||||
|
||||
// CacheStore is a interface to store cache
|
||||
|
@ -69,6 +70,7 @@ func decodeIds(s string) ([]PK, error) {
|
|||
return pks, err
|
||||
}
|
||||
|
||||
// GetCacheSql returns cacher PKs via SQL
|
||||
func GetCacheSql(m Cacher, tableName, sql string, args interface{}) ([]PK, error) {
|
||||
bytes := m.GetIds(tableName, GenSqlKey(sql, args))
|
||||
if bytes == nil {
|
||||
|
@ -77,6 +79,7 @@ func GetCacheSql(m Cacher, tableName, sql string, args interface{}) ([]PK, error
|
|||
return decodeIds(bytes.(string))
|
||||
}
|
||||
|
||||
// PutCacheSql puts cacher SQL and PKs
|
||||
func PutCacheSql(m Cacher, ids []PK, tableName, sql string, args interface{}) error {
|
||||
bytes, err := encodeIds(ids)
|
||||
if err != nil {
|
||||
|
@ -86,6 +89,7 @@ func PutCacheSql(m Cacher, ids []PK, tableName, sql string, args interface{}) er
|
|||
return nil
|
||||
}
|
||||
|
||||
// GenSqlKey generates cache key
|
||||
func GenSqlKey(sql string, args interface{}) string {
|
||||
return fmt.Sprintf("%v-%v", sql, args)
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ func NewColumn(name, fieldName string, sqlType SQLType, len1, len2 int, nullable
|
|||
|
||||
// String generate column description string according dialect
|
||||
func (col *Column) String(d Dialect) string {
|
||||
sql := d.QuoteStr() + col.Name + d.QuoteStr() + " "
|
||||
sql := d.Quote(col.Name) + " "
|
||||
|
||||
sql += d.SqlType(col) + " "
|
||||
|
||||
|
@ -101,7 +101,7 @@ func (col *Column) String(d Dialect) string {
|
|||
|
||||
// StringNoPk generate column description string according dialect without primary keys
|
||||
func (col *Column) StringNoPk(d Dialect) string {
|
||||
sql := d.QuoteStr() + col.Name + d.QuoteStr() + " "
|
||||
sql := d.Quote(col.Name) + " "
|
||||
|
||||
sql += d.SqlType(col) + " "
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
// DefaultCacheSize sets the default cache size
|
||||
DefaultCacheSize = 200
|
||||
)
|
||||
|
||||
|
@ -132,6 +133,7 @@ func (db *DB) Query(query string, args ...interface{}) (*Rows, error) {
|
|||
return db.QueryContext(context.Background(), query, args...)
|
||||
}
|
||||
|
||||
// QueryMapContext executes query with parameters via map and context
|
||||
func (db *DB) QueryMapContext(ctx context.Context, query string, mp interface{}) (*Rows, error) {
|
||||
query, args, err := MapToSlice(query, mp)
|
||||
if err != nil {
|
||||
|
@ -140,6 +142,7 @@ func (db *DB) QueryMapContext(ctx context.Context, query string, mp interface{})
|
|||
return db.QueryContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
// QueryMap executes query with parameters via map
|
||||
func (db *DB) QueryMap(query string, mp interface{}) (*Rows, error) {
|
||||
return db.QueryMapContext(context.Background(), query, mp)
|
||||
}
|
||||
|
@ -196,6 +199,7 @@ var (
|
|||
re = regexp.MustCompile(`[?](\w+)`)
|
||||
)
|
||||
|
||||
// ExecMapContext exec map with context.Context
|
||||
// insert into (name) values (?)
|
||||
// insert into (name) values (?name)
|
||||
func (db *DB) ExecMapContext(ctx context.Context, query string, mp interface{}) (sql.Result, error) {
|
||||
|
|
|
@ -40,9 +40,9 @@ type Dialect interface {
|
|||
DriverName() string
|
||||
DataSourceName() string
|
||||
|
||||
QuoteStr() string
|
||||
IsReserved(string) bool
|
||||
Quote(string) string
|
||||
|
||||
AndStr() string
|
||||
OrStr() string
|
||||
EqStr() string
|
||||
|
@ -70,8 +70,8 @@ type Dialect interface {
|
|||
|
||||
ForUpdateSql(query string) string
|
||||
|
||||
//CreateTableIfNotExists(table *Table, tableName, storeEngine, charset string) error
|
||||
//MustDropTable(tableName string) error
|
||||
// CreateTableIfNotExists(table *Table, tableName, storeEngine, charset string) error
|
||||
// MustDropTable(tableName string) error
|
||||
|
||||
GetColumns(tableName string) ([]string, map[string]*Column, error)
|
||||
GetTables() ([]*Table, error)
|
||||
|
@ -85,6 +85,7 @@ func OpenDialect(dialect Dialect) (*DB, error) {
|
|||
return Open(dialect.DriverName(), dialect.DataSourceName())
|
||||
}
|
||||
|
||||
// Base represents a basic dialect and all real dialects could embed this struct
|
||||
type Base struct {
|
||||
db *DB
|
||||
dialect Dialect
|
||||
|
@ -172,8 +173,15 @@ func (db *Base) HasRecords(query string, args ...interface{}) (bool, error) {
|
|||
}
|
||||
|
||||
func (db *Base) IsColumnExist(tableName, colName string) (bool, error) {
|
||||
query := "SELECT `COLUMN_NAME` FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_SCHEMA` = ? AND `TABLE_NAME` = ? AND `COLUMN_NAME` = ?"
|
||||
query = strings.Replace(query, "`", db.dialect.QuoteStr(), -1)
|
||||
query := fmt.Sprintf(
|
||||
"SELECT %v FROM %v.%v WHERE %v = ? AND %v = ? AND %v = ?",
|
||||
db.dialect.Quote("COLUMN_NAME"),
|
||||
db.dialect.Quote("INFORMATION_SCHEMA"),
|
||||
db.dialect.Quote("COLUMNS"),
|
||||
db.dialect.Quote("TABLE_SCHEMA"),
|
||||
db.dialect.Quote("TABLE_NAME"),
|
||||
db.dialect.Quote("COLUMN_NAME"),
|
||||
)
|
||||
return db.HasRecords(query, db.DbName, tableName, colName)
|
||||
}
|
||||
|
||||
|
@ -310,7 +318,7 @@ func RegisterDialect(dbName DbType, dialectFunc func() Dialect) {
|
|||
dialects[strings.ToLower(string(dbName))] = dialectFunc // !nashtsai! allow override dialect
|
||||
}
|
||||
|
||||
// QueryDialect query if registed database dialect
|
||||
// QueryDialect query if registered database dialect
|
||||
func QueryDialect(dbName DbType) Dialect {
|
||||
if d, ok := dialects[strings.ToLower(string(dbName))]; ok {
|
||||
return d()
|
||||
|
|
|
@ -7,6 +7,8 @@ package core
|
|||
import "errors"
|
||||
|
||||
var (
|
||||
ErrNoMapPointer = errors.New("mp should be a map's pointer")
|
||||
// ErrNoMapPointer represents error when no map pointer
|
||||
ErrNoMapPointer = errors.New("mp should be a map's pointer")
|
||||
// ErrNoStructPointer represents error when no struct pointer
|
||||
ErrNoStructPointer = errors.New("mp should be a struct's pointer")
|
||||
)
|
||||
|
|
|
@ -19,7 +19,23 @@ type QuoteFilter struct {
|
|||
}
|
||||
|
||||
func (s *QuoteFilter) Do(sql string, dialect Dialect, table *Table) string {
|
||||
return strings.Replace(sql, "`", dialect.QuoteStr(), -1)
|
||||
dummy := dialect.Quote("")
|
||||
if len(dummy) != 2 {
|
||||
return sql
|
||||
}
|
||||
prefix, suffix := dummy[0], dummy[1]
|
||||
raw := []byte(sql)
|
||||
for i, cnt := 0, 0; i < len(raw); i = i + 1 {
|
||||
if raw[i] == '`' {
|
||||
if cnt%2 == 0 {
|
||||
raw[i] = prefix
|
||||
} else {
|
||||
raw[i] = suffix
|
||||
}
|
||||
cnt++
|
||||
}
|
||||
}
|
||||
return string(raw)
|
||||
}
|
||||
|
||||
// IdFilter filter SQL replace (id) to primary key column name
|
||||
|
@ -35,7 +51,7 @@ func NewQuoter(dialect Dialect) *Quoter {
|
|||
}
|
||||
|
||||
func (q *Quoter) Quote(content string) string {
|
||||
return q.dialect.QuoteStr() + content + q.dialect.QuoteStr()
|
||||
return q.dialect.Quote(content)
|
||||
}
|
||||
|
||||
func (i *IdFilter) Do(sql string, dialect Dialect, table *Table) string {
|
||||
|
|
|
@ -2,6 +2,12 @@ module xorm.io/core
|
|||
|
||||
require (
|
||||
github.com/go-sql-driver/mysql v1.4.1
|
||||
github.com/golang/protobuf v1.3.1 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.10.0
|
||||
google.golang.org/appengine v1.4.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 // indirect
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65 // indirect
|
||||
golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed // indirect
|
||||
golang.org/x/text v0.3.2 // indirect
|
||||
golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468 // indirect
|
||||
google.golang.org/appengine v1.6.0 // indirect
|
||||
)
|
||||
|
|
|
@ -1,9 +1,23 @@
|
|||
github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
|
||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o=
|
||||
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
|
|
|
@ -4,8 +4,10 @@
|
|||
|
||||
package core
|
||||
|
||||
// LogLevel defines a log level
|
||||
type LogLevel int
|
||||
|
||||
// enumerate all LogLevels
|
||||
const (
|
||||
// !nashtsai! following level also match syslog.Priority value
|
||||
LOG_DEBUG LogLevel = iota
|
||||
|
@ -16,7 +18,7 @@ const (
|
|||
LOG_UNKNOWN
|
||||
)
|
||||
|
||||
// logger interface
|
||||
// ILogger is a logger interface
|
||||
type ILogger interface {
|
||||
Debug(v ...interface{})
|
||||
Debugf(format string, v ...interface{})
|
||||
|
|
|
@ -9,12 +9,13 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
// enumerate all index types
|
||||
const (
|
||||
IndexType = iota + 1
|
||||
UniqueType
|
||||
)
|
||||
|
||||
// database index
|
||||
// Index represents a database index
|
||||
type Index struct {
|
||||
IsRegular bool
|
||||
Name string
|
||||
|
@ -35,7 +36,7 @@ func (index *Index) XName(tableName string) string {
|
|||
return index.Name
|
||||
}
|
||||
|
||||
// add columns which will be composite index
|
||||
// AddColumn add columns which will be composite index
|
||||
func (index *Index) AddColumn(cols ...string) {
|
||||
for _, col := range cols {
|
||||
index.Cols = append(index.Cols, col)
|
||||
|
@ -65,7 +66,7 @@ func (index *Index) Equal(dst *Index) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
// new an index
|
||||
// NewIndex new an index object
|
||||
func NewIndex(name string, indexType int) *Index {
|
||||
return &Index{true, name, indexType, make([]string, 0)}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"sync"
|
||||
)
|
||||
|
||||
// name translation between struct, fields names and table, column names
|
||||
// IMapper represents a name convertation between struct's fields name and table's column name
|
||||
type IMapper interface {
|
||||
Obj2Table(string) string
|
||||
Table2Obj(string) string
|
||||
|
@ -184,7 +184,7 @@ func (mapper GonicMapper) Table2Obj(name string) string {
|
|||
return string(newstr)
|
||||
}
|
||||
|
||||
// A GonicMapper that contains a list of common initialisms taken from golang/lint
|
||||
// LintGonicMapper is A GonicMapper that contains a list of common initialisms taken from golang/lint
|
||||
var LintGonicMapper = GonicMapper{
|
||||
"API": true,
|
||||
"ASCII": true,
|
||||
|
@ -221,7 +221,7 @@ var LintGonicMapper = GonicMapper{
|
|||
"XSS": true,
|
||||
}
|
||||
|
||||
// provide prefix table name support
|
||||
// PrefixMapper provides prefix table name support
|
||||
type PrefixMapper struct {
|
||||
Mapper IMapper
|
||||
Prefix string
|
||||
|
@ -239,7 +239,7 @@ func NewPrefixMapper(mapper IMapper, prefix string) PrefixMapper {
|
|||
return PrefixMapper{mapper, prefix}
|
||||
}
|
||||
|
||||
// provide suffix table name support
|
||||
// SuffixMapper provides suffix table name support
|
||||
type SuffixMapper struct {
|
||||
Mapper IMapper
|
||||
Suffix string
|
||||
|
|
|
@ -170,7 +170,7 @@ func (rs *Rows) ScanMap(dest interface{}) error {
|
|||
newDest := make([]interface{}, len(cols))
|
||||
vvv := vv.Elem()
|
||||
|
||||
for i, _ := range cols {
|
||||
for i := range cols {
|
||||
newDest[i] = rs.db.reflectNew(vvv.Type().Elem()).Interface()
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"reflect"
|
||||
)
|
||||
|
||||
// Stmt reprents a stmt objects
|
||||
type Stmt struct {
|
||||
*sql.Stmt
|
||||
db *DB
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
// database table
|
||||
// Table represents a database table
|
||||
type Table struct {
|
||||
Name string
|
||||
Type reflect.Type
|
||||
|
@ -41,6 +41,7 @@ func NewEmptyTable() *Table {
|
|||
return NewTable("", nil)
|
||||
}
|
||||
|
||||
// NewTable creates a new Table object
|
||||
func NewTable(name string, t reflect.Type) *Table {
|
||||
return &Table{Name: name, Type: t,
|
||||
columnsSeq: make([]string, 0),
|
||||
|
@ -87,7 +88,7 @@ func (table *Table) GetColumnIdx(name string, idx int) *Column {
|
|||
return nil
|
||||
}
|
||||
|
||||
// if has primary key, return column
|
||||
// PKColumns reprents all primary key columns
|
||||
func (table *Table) PKColumns() []*Column {
|
||||
columns := make([]*Column, len(table.PrimaryKeys))
|
||||
for i, name := range table.PrimaryKeys {
|
||||
|
@ -117,7 +118,7 @@ func (table *Table) DeletedColumn() *Column {
|
|||
return table.GetColumn(table.Deleted)
|
||||
}
|
||||
|
||||
// add a column to table
|
||||
// AddColumn adds a column to table
|
||||
func (table *Table) AddColumn(col *Column) {
|
||||
table.columnsSeq = append(table.columnsSeq, col.Name)
|
||||
table.columns = append(table.columns, col)
|
||||
|
@ -148,7 +149,7 @@ func (table *Table) AddColumn(col *Column) {
|
|||
}
|
||||
}
|
||||
|
||||
// add an index or an unique to table
|
||||
// AddIndex adds an index or an unique to table
|
||||
func (table *Table) AddIndex(index *Index) {
|
||||
table.Indexes[index.Name] = index
|
||||
}
|
||||
|
|
|
@ -87,16 +87,16 @@ var (
|
|||
UniqueIdentifier = "UNIQUEIDENTIFIER"
|
||||
SysName = "SYSNAME"
|
||||
|
||||
Date = "DATE"
|
||||
DateTime = "DATETIME"
|
||||
SmallDateTime = "SMALLDATETIME"
|
||||
Time = "TIME"
|
||||
TimeStamp = "TIMESTAMP"
|
||||
TimeStampz = "TIMESTAMPZ"
|
||||
Date = "DATE"
|
||||
DateTime = "DATETIME"
|
||||
SmallDateTime = "SMALLDATETIME"
|
||||
Time = "TIME"
|
||||
TimeStamp = "TIMESTAMP"
|
||||
TimeStampz = "TIMESTAMPZ"
|
||||
|
||||
Decimal = "DECIMAL"
|
||||
Numeric = "NUMERIC"
|
||||
Money = "MONEY"
|
||||
Decimal = "DECIMAL"
|
||||
Numeric = "NUMERIC"
|
||||
Money = "MONEY"
|
||||
SmallMoney = "SMALLMONEY"
|
||||
|
||||
Real = "REAL"
|
||||
|
@ -147,19 +147,19 @@ var (
|
|||
Clob: TEXT_TYPE,
|
||||
SysName: TEXT_TYPE,
|
||||
|
||||
Date: TIME_TYPE,
|
||||
DateTime: TIME_TYPE,
|
||||
Time: TIME_TYPE,
|
||||
TimeStamp: TIME_TYPE,
|
||||
TimeStampz: TIME_TYPE,
|
||||
SmallDateTime: TIME_TYPE,
|
||||
Date: TIME_TYPE,
|
||||
DateTime: TIME_TYPE,
|
||||
Time: TIME_TYPE,
|
||||
TimeStamp: TIME_TYPE,
|
||||
TimeStampz: TIME_TYPE,
|
||||
SmallDateTime: TIME_TYPE,
|
||||
|
||||
Decimal: NUMERIC_TYPE,
|
||||
Numeric: NUMERIC_TYPE,
|
||||
Real: NUMERIC_TYPE,
|
||||
Float: NUMERIC_TYPE,
|
||||
Double: NUMERIC_TYPE,
|
||||
Money: NUMERIC_TYPE,
|
||||
Decimal: NUMERIC_TYPE,
|
||||
Numeric: NUMERIC_TYPE,
|
||||
Real: NUMERIC_TYPE,
|
||||
Float: NUMERIC_TYPE,
|
||||
Double: NUMERIC_TYPE,
|
||||
Money: NUMERIC_TYPE,
|
||||
SmallMoney: NUMERIC_TYPE,
|
||||
|
||||
Binary: BLOB_TYPE,
|
||||
|
|
Loading…
Reference in New Issue