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/glycerine/goconvey v0.0.0-20190315024820-982ee783a72e // indirect
|
||||||
github.com/go-redis/redis v6.15.2+incompatible
|
github.com/go-redis/redis v6.15.2+incompatible
|
||||||
github.com/go-sql-driver/mysql v1.4.1
|
github.com/go-sql-driver/mysql v1.4.1
|
||||||
github.com/go-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/gogits/chardet v0.0.0-20150115103509-2404f7772561
|
||||||
github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14
|
github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14
|
||||||
github.com/google/go-github/v24 v24.0.1
|
github.com/google/go-github/v24 v24.0.1
|
||||||
|
@ -117,5 +117,5 @@ require (
|
||||||
mvdan.cc/xurls/v2 v2.0.0
|
mvdan.cc/xurls/v2 v2.0.0
|
||||||
strk.kbt.io/projects/go/libravatar v0.0.0-20160628055650-5eed7bff870a
|
strk.kbt.io/projects/go/libravatar v0.0.0-20160628055650-5eed7bff870a
|
||||||
xorm.io/builder v0.3.5
|
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/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 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.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 h1:deE7ritpK04PgtpyVOS2TYcQEld9qLCD5b5EbVNOuLA=
|
||||||
github.com/gogits/chardet v0.0.0-20150115103509-2404f7772561/go.mod h1:YgYOrVn3Nj9Tq0EvjmFbphRytDj7JNRoWSStJZWDJTQ=
|
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=
|
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-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-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-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-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-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190730183949-1393eb018365/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-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-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-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-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-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
|
||||||
golang.org/x/tools v0.0.0-20190731214159-1e85ed8060aa h1:kwa/4M1dbmhZqOIqYiTtbA6JrvPwo1+jqlub2qDXX90=
|
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.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.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.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 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I=
|
||||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
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=
|
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/builder v0.3.5/go.mod h1:ZFbByS/KxZI1FKRjL05PyJ4YrK2bcxlUaAxdum5aTR8=
|
||||||
xorm.io/core v0.6.3 h1:n1NhVZt1s2oLw1BZfX2ocIJsHyso259uPgg63BGr37M=
|
xorm.io/core v0.6.3 h1:n1NhVZt1s2oLw1BZfX2ocIJsHyso259uPgg63BGr37M=
|
||||||
xorm.io/core v0.6.3/go.mod h1:8kz/C6arVW/O9vk3PgCiMJO2hIAm1UcuOL3dSPyZ2qo=
|
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
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"path"
|
"path"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
@ -74,6 +73,7 @@ var (
|
||||||
|
|
||||||
const issueTasksRegexpStr = `(^\s*[-*]\s\[[\sx]\]\s.)|(\n\s*[-*]\s\[[\sx]\]\s.)`
|
const issueTasksRegexpStr = `(^\s*[-*]\s\[[\sx]\]\s.)|(\n\s*[-*]\s\[[\sx]\]\s.)`
|
||||||
const issueTasksDoneRegexpStr = `(^\s*[-*]\s\[[x]\]\s.)|(\n\s*[-*]\s\[[x]\]\s.)`
|
const issueTasksDoneRegexpStr = `(^\s*[-*]\s\[[x]\]\s.)|(\n\s*[-*]\s\[[x]\]\s.)`
|
||||||
|
const issueMaxDupIndexAttempts = 3
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
issueTasksPat = regexp.MustCompile(issueTasksRegexpStr)
|
issueTasksPat = regexp.MustCompile(issueTasksRegexpStr)
|
||||||
|
@ -1031,36 +1031,9 @@ type NewIssueOptions struct {
|
||||||
IsPull bool
|
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) {
|
func newIssue(e *xorm.Session, doer *User, opts NewIssueOptions) (err error) {
|
||||||
opts.Issue.Title = strings.TrimSpace(opts.Issue.Title)
|
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 {
|
if opts.Issue.MilestoneID > 0 {
|
||||||
milestone, err := getMilestoneByRepoID(e, opts.Issue.RepoID, opts.Issue.MilestoneID)
|
milestone, err := getMilestoneByRepoID(e, opts.Issue.RepoID, opts.Issue.MilestoneID)
|
||||||
if err != nil && !IsErrMilestoneNotExist(err) {
|
if err != nil && !IsErrMilestoneNotExist(err) {
|
||||||
|
@ -1109,9 +1082,30 @@ func newIssue(e *xorm.Session, doer *User, opts NewIssueOptions) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Milestone and assignee validation should happen before insert actual object.
|
// 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
|
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 opts.Issue.MilestoneID > 0 {
|
||||||
if err = changeMilestoneAssign(e, doer, opts.Issue, -1); err != nil {
|
if err = changeMilestoneAssign(e, doer, opts.Issue, -1); err != nil {
|
||||||
|
|
|
@ -252,15 +252,8 @@ func CreatePullRequest(ctx *context.APIContext, form api.CreatePullRequestOption
|
||||||
deadlineUnix = timeutil.TimeStamp(form.Deadline.Unix())
|
deadlineUnix = timeutil.TimeStamp(form.Deadline.Unix())
|
||||||
}
|
}
|
||||||
|
|
||||||
maxIndex, err := models.GetMaxIndexOfIssue(repo.ID)
|
|
||||||
if err != nil {
|
|
||||||
ctx.ServerError("GetPatch", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
prIssue := &models.Issue{
|
prIssue := &models.Issue{
|
||||||
RepoID: repo.ID,
|
RepoID: repo.ID,
|
||||||
Index: maxIndex + 1,
|
|
||||||
Title: form.Title,
|
Title: form.Title,
|
||||||
PosterID: ctx.User.ID,
|
PosterID: ctx.User.ID,
|
||||||
Poster: ctx.User,
|
Poster: ctx.User,
|
||||||
|
|
|
@ -710,15 +710,8 @@ func CompareAndPullRequestPost(ctx *context.Context, form auth.CreateIssueForm)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
maxIndex, err := models.GetMaxIndexOfIssue(repo.ID)
|
|
||||||
if err != nil {
|
|
||||||
ctx.ServerError("GetPatch", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
pullIssue := &models.Issue{
|
pullIssue := &models.Issue{
|
||||||
RepoID: repo.ID,
|
RepoID: repo.ID,
|
||||||
Index: maxIndex + 1,
|
|
||||||
Title: form.Title,
|
Title: form.Title,
|
||||||
PosterID: ctx.User.ID,
|
PosterID: ctx.User.ID,
|
||||||
Poster: ctx.User,
|
Poster: ctx.User,
|
||||||
|
|
|
@ -1,125 +1,431 @@
|
||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
name: matrix-1
|
||||||
|
|
||||||
|
platform:
|
||||||
|
os: linux
|
||||||
|
arch: amd64
|
||||||
|
|
||||||
|
clone:
|
||||||
|
disable: true
|
||||||
|
|
||||||
workspace:
|
workspace:
|
||||||
base: /go
|
base: /go
|
||||||
path: src/github.com/go-xorm/xorm
|
path: src/github.com/go-xorm/xorm
|
||||||
|
|
||||||
clone:
|
steps:
|
||||||
git:
|
- name: git
|
||||||
|
pull: default
|
||||||
image: plugins/git:next
|
image: plugins/git:next
|
||||||
|
settings:
|
||||||
depth: 50
|
depth: 50
|
||||||
tags: true
|
tags: true
|
||||||
|
|
||||||
services:
|
- name: init_postgres
|
||||||
mysql:
|
pull: default
|
||||||
image: mysql:5.7
|
|
||||||
environment:
|
|
||||||
- MYSQL_DATABASE=xorm_test
|
|
||||||
- MYSQL_ALLOW_EMPTY_PASSWORD=yes
|
|
||||||
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 ]
|
|
||||||
|
|
||||||
#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"
|
|
||||||
|
|
||||||
matrix:
|
|
||||||
GO_VERSION:
|
|
||||||
- 1.8
|
|
||||||
- 1.9
|
|
||||||
- 1.10
|
|
||||||
- 1.11
|
|
||||||
|
|
||||||
pipeline:
|
|
||||||
init_postgres:
|
|
||||||
image: postgres:9.5
|
image: postgres:9.5
|
||||||
commands:
|
commands:
|
||||||
# wait for postgres service to become available
|
- "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"
|
||||||
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;"
|
|
||||||
|
|
||||||
build:
|
- name: build
|
||||||
image: golang:${GO_VERSION}
|
pull: default
|
||||||
|
image: golang:1.10
|
||||||
commands:
|
commands:
|
||||||
- go get -t -d -v ./...
|
- go get -t -d -v ./...
|
||||||
- go get -u xorm.io/core
|
- go get -u xorm.io/core
|
||||||
- go get -u xorm.io/builder
|
- go get -u xorm.io/builder
|
||||||
- go build -v
|
- go build -v
|
||||||
when:
|
when:
|
||||||
event: [ push, pull_request ]
|
event:
|
||||||
|
- push
|
||||||
|
- pull_request
|
||||||
|
|
||||||
test-sqlite:
|
- name: test-sqlite
|
||||||
image: golang:${GO_VERSION}
|
pull: default
|
||||||
|
image: golang:1.10
|
||||||
commands:
|
commands:
|
||||||
- go get -u github.com/wadey/gocovmerge
|
- 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\" -coverprofile=coverage1-1.txt -covermode=atomic"
|
||||||
- go test -v -race -db="sqlite3" -conn_str="./test.db" -cache=true -coverprofile=coverage1-2.txt -covermode=atomic
|
- "go test -v -race -db=\"sqlite3\" -conn_str=\"./test.db\" -cache=true -coverprofile=coverage1-2.txt -covermode=atomic"
|
||||||
when:
|
when:
|
||||||
event: [ push, pull_request ]
|
event:
|
||||||
|
- push
|
||||||
|
- pull_request
|
||||||
|
|
||||||
test-mysql:
|
- name: test-mysql
|
||||||
image: golang:${GO_VERSION}
|
pull: default
|
||||||
|
image: golang:1.10
|
||||||
commands:
|
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\" -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
|
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test\" -cache=true -coverprofile=coverage2-2.txt -covermode=atomic"
|
||||||
when:
|
when:
|
||||||
event: [ push, pull_request ]
|
event:
|
||||||
|
- push
|
||||||
|
- pull_request
|
||||||
|
|
||||||
test-mysql-utf8mb4:
|
- name: test-mysql-utf8mb4
|
||||||
image: golang:${GO_VERSION}
|
pull: default
|
||||||
|
image: golang:1.10
|
||||||
commands:
|
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\" -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
|
- "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:
|
when:
|
||||||
event: [ push, pull_request ]
|
event:
|
||||||
|
- push
|
||||||
|
- pull_request
|
||||||
|
|
||||||
test-mymysql:
|
- name: test-mymysql
|
||||||
image: golang:${GO_VERSION}
|
pull: default
|
||||||
|
image: golang:1.10
|
||||||
commands:
|
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/\" -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
|
- "go test -v -race -db=\"mymysql\" -conn_str=\"tcp:mysql:3306*xorm_test/root/\" -cache=true -coverprofile=coverage3-2.txt -covermode=atomic"
|
||||||
when:
|
when:
|
||||||
event: [ push, pull_request ]
|
event:
|
||||||
|
- push
|
||||||
|
- pull_request
|
||||||
|
|
||||||
test-postgres:
|
- name: test-postgres
|
||||||
image: golang:${GO_VERSION}
|
pull: default
|
||||||
|
image: golang:1.10
|
||||||
commands:
|
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\" -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
|
- "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -cache=true -coverprofile=coverage4-2.txt -covermode=atomic"
|
||||||
when:
|
when:
|
||||||
event: [ push, pull_request ]
|
event:
|
||||||
|
- push
|
||||||
|
- pull_request
|
||||||
|
|
||||||
test-postgres-schema:
|
- name: test-postgres-schema
|
||||||
image: golang:${GO_VERSION}
|
pull: default
|
||||||
|
image: golang:1.10
|
||||||
commands:
|
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 -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
|
- "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
|
- 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:
|
when:
|
||||||
event: [ push, pull_request ]
|
event:
|
||||||
|
- push
|
||||||
|
- pull_request
|
||||||
|
|
||||||
#coverage:
|
services:
|
||||||
# image: robertstettner/drone-codecov
|
- name: mysql
|
||||||
# secrets: [ codecov_token ]
|
pull: default
|
||||||
# files:
|
image: mysql:5.7
|
||||||
# - coverage.txt
|
environment:
|
||||||
# when:
|
MYSQL_ALLOW_EMPTY_PASSWORD: yes
|
||||||
# event: [ push, pull_request ]
|
MYSQL_DATABASE: xorm_test
|
||||||
# branch: [ master ]
|
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-2
|
||||||
|
|
||||||
|
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.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
|
||||||
|
|
||||||
|
- 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
|
||||||
|
|
||||||
|
- 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
|
||||||
|
|
||||||
|
- 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
|
// 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
|
* `Sum` sum functions
|
||||||
|
|
||||||
```Go
|
```Go
|
||||||
|
|
|
@ -286,10 +286,6 @@ func (db *mssql) Quote(name string) string {
|
||||||
return "\"" + name + "\""
|
return "\"" + name + "\""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *mssql) QuoteStr() string {
|
|
||||||
return "\""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (db *mssql) SupportEngine() bool {
|
func (db *mssql) SupportEngine() bool {
|
||||||
return false
|
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 = "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
|
pkList := table.PrimaryKeys
|
||||||
|
|
||||||
|
|
|
@ -220,7 +220,7 @@ func (db *mysql) SqlType(c *core.Column) string {
|
||||||
case core.TimeStampz:
|
case core.TimeStampz:
|
||||||
res = core.Char
|
res = core.Char
|
||||||
c.Length = 64
|
c.Length = 64
|
||||||
case core.Enum: //mysql enum
|
case core.Enum: // mysql enum
|
||||||
res = core.Enum
|
res = core.Enum
|
||||||
res += "("
|
res += "("
|
||||||
opts := ""
|
opts := ""
|
||||||
|
@ -229,7 +229,7 @@ func (db *mysql) SqlType(c *core.Column) string {
|
||||||
}
|
}
|
||||||
res += strings.TrimLeft(opts, ",")
|
res += strings.TrimLeft(opts, ",")
|
||||||
res += ")"
|
res += ")"
|
||||||
case core.Set: //mysql set
|
case core.Set: // mysql set
|
||||||
res = core.Set
|
res = core.Set
|
||||||
res += "("
|
res += "("
|
||||||
opts := ""
|
opts := ""
|
||||||
|
@ -278,10 +278,6 @@ func (db *mysql) Quote(name string) string {
|
||||||
return "`" + name + "`"
|
return "`" + name + "`"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *mysql) QuoteStr() string {
|
|
||||||
return "`"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (db *mysql) SupportEngine() bool {
|
func (db *mysql) SupportEngine() bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -360,7 +356,7 @@ func (db *mysql) GetColumns(tableName string) ([]string, map[string]*core.Column
|
||||||
var len1, len2 int
|
var len1, len2 int
|
||||||
if len(cts) == 2 {
|
if len(cts) == 2 {
|
||||||
idx := strings.Index(cts[1], ")")
|
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], ",")
|
options := strings.Split(cts[1][0:idx], ",")
|
||||||
col.EnumOptions = make(map[string]int)
|
col.EnumOptions = make(map[string]int)
|
||||||
for k, v := range options {
|
for k, v := range options {
|
||||||
|
@ -408,7 +404,7 @@ func (db *mysql) GetColumns(tableName string) ([]string, map[string]*core.Column
|
||||||
col.IsPrimaryKey = true
|
col.IsPrimaryKey = true
|
||||||
}
|
}
|
||||||
if colKey == "UNI" {
|
if colKey == "UNI" {
|
||||||
//col.is
|
// col.is
|
||||||
}
|
}
|
||||||
|
|
||||||
if extra == "auto_increment" {
|
if extra == "auto_increment" {
|
||||||
|
@ -559,8 +555,6 @@ func (db *mysql) CreateTableSql(table *core.Table, tableName, storeEngine, chars
|
||||||
sql += " DEFAULT CHARSET " + charset
|
sql += " DEFAULT CHARSET " + charset
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if db.rowFormat != "" {
|
if db.rowFormat != "" {
|
||||||
sql += " ROW_FORMAT=" + 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<dbname>.*?)` + // /dbname
|
||||||
`(?:\?(?P<params>[^\?]*))?$`) // [?param1=value1¶mN=valueN]
|
`(?:\?(?P<params>[^\?]*))?$`) // [?param1=value1¶mN=valueN]
|
||||||
matches := dsnPattern.FindStringSubmatch(dataSourceName)
|
matches := dsnPattern.FindStringSubmatch(dataSourceName)
|
||||||
//tlsConfigRegister := make(map[string]*tls.Config)
|
// tlsConfigRegister := make(map[string]*tls.Config)
|
||||||
names := dsnPattern.SubexpNames()
|
names := dsnPattern.SubexpNames()
|
||||||
|
|
||||||
uri := &core.Uri{DbType: core.MYSQL}
|
uri := &core.Uri{DbType: core.MYSQL}
|
||||||
|
|
|
@ -552,11 +552,7 @@ func (db *oracle) IsReserved(name string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *oracle) Quote(name string) string {
|
func (db *oracle) Quote(name string) string {
|
||||||
return "\"" + name + "\""
|
return "[" + name + "]"
|
||||||
}
|
|
||||||
|
|
||||||
func (db *oracle) QuoteStr() string {
|
|
||||||
return "\""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *oracle) SupportEngine() bool {
|
func (db *oracle) SupportEngine() bool {
|
||||||
|
@ -596,7 +592,7 @@ func (db *oracle) CreateTableSql(table *core.Table, tableName, storeEngine, char
|
||||||
sql += col.String(b.dialect)
|
sql += col.String(b.dialect)
|
||||||
} else {*/
|
} else {*/
|
||||||
sql += col.StringNoPk(db)
|
sql += col.StringNoPk(db)
|
||||||
//}
|
// }
|
||||||
sql = strings.TrimSpace(sql)
|
sql = strings.TrimSpace(sql)
|
||||||
sql += ", "
|
sql += ", "
|
||||||
}
|
}
|
||||||
|
@ -865,7 +861,7 @@ func (cfg *goracleDriver) Parse(driverName, dataSourceName string) (*core.Uri, e
|
||||||
`\/(?P<dbname>.*?)` + // /dbname
|
`\/(?P<dbname>.*?)` + // /dbname
|
||||||
`(?:\?(?P<params>[^\?]*))?$`) // [?param1=value1¶mN=valueN]
|
`(?:\?(?P<params>[^\?]*))?$`) // [?param1=value1¶mN=valueN]
|
||||||
matches := dsnPattern.FindStringSubmatch(dataSourceName)
|
matches := dsnPattern.FindStringSubmatch(dataSourceName)
|
||||||
//tlsConfigRegister := make(map[string]*tls.Config)
|
// tlsConfigRegister := make(map[string]*tls.Config)
|
||||||
names := dsnPattern.SubexpNames()
|
names := dsnPattern.SubexpNames()
|
||||||
|
|
||||||
for i, match := range matches {
|
for i, match := range matches {
|
||||||
|
@ -883,8 +879,8 @@ func (cfg *goracleDriver) Parse(driverName, dataSourceName string) (*core.Uri, e
|
||||||
type oci8Driver struct {
|
type oci8Driver struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
//dataSourceName=user/password@ipv4:port/dbname
|
// dataSourceName=user/password@ipv4:port/dbname
|
||||||
//dataSourceName=user/password@[ipv6]:port/dbname
|
// dataSourceName=user/password@[ipv6]:port/dbname
|
||||||
func (p *oci8Driver) Parse(driverName, dataSourceName string) (*core.Uri, error) {
|
func (p *oci8Driver) Parse(driverName, dataSourceName string) (*core.Uri, error) {
|
||||||
db := &core.Uri{DbType: core.ORACLE}
|
db := &core.Uri{DbType: core.ORACLE}
|
||||||
dsnPattern := regexp.MustCompile(
|
dsnPattern := regexp.MustCompile(
|
||||||
|
|
|
@ -863,10 +863,6 @@ func (db *postgres) Quote(name string) string {
|
||||||
return "\"" + name + "\""
|
return "\"" + name + "\""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *postgres) QuoteStr() string {
|
|
||||||
return "\""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (db *postgres) AutoIncrStr() string {
|
func (db *postgres) AutoIncrStr() string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
@ -998,7 +994,7 @@ WHERE c.relkind = 'r'::char AND c.relname = $1%s AND f.attnum > 0 ORDER BY f.att
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
//fmt.Println(args, colName, isNullable, dataType, maxLenStr, colDefault, numPrecision, numRadix, isPK, isUnique)
|
// fmt.Println(args, colName, isNullable, dataType, maxLenStr, colDefault, numPrecision, numRadix, isPK, isUnique)
|
||||||
var maxLen int
|
var maxLen int
|
||||||
if maxLenStr != nil {
|
if maxLenStr != nil {
|
||||||
maxLen, err = strconv.Atoi(*maxLenStr)
|
maxLen, err = strconv.Atoi(*maxLenStr)
|
||||||
|
@ -1093,7 +1089,6 @@ func (db *postgres) GetTables() ([]*core.Table, error) {
|
||||||
return tables, nil
|
return tables, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func getIndexColName(indexdef string) []string {
|
func getIndexColName(indexdef string) []string {
|
||||||
var colNames []string
|
var colNames []string
|
||||||
|
|
||||||
|
@ -1105,7 +1100,6 @@ func getIndexColName(indexdef string) []string {
|
||||||
return colNames
|
return colNames
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (db *postgres) GetIndexes(tableName string) (map[string]*core.Index, error) {
|
func (db *postgres) GetIndexes(tableName string) (map[string]*core.Index, error) {
|
||||||
args := []interface{}{tableName}
|
args := []interface{}{tableName}
|
||||||
s := fmt.Sprintf("SELECT indexname, indexdef FROM pg_indexes WHERE tablename=$1")
|
s := fmt.Sprintf("SELECT indexname, indexdef FROM pg_indexes WHERE tablename=$1")
|
||||||
|
|
|
@ -202,10 +202,6 @@ func (db *sqlite3) Quote(name string) string {
|
||||||
return "`" + name + "`"
|
return "`" + name + "`"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *sqlite3) QuoteStr() string {
|
|
||||||
return "`"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (db *sqlite3) AutoIncrStr() string {
|
func (db *sqlite3) AutoIncrStr() string {
|
||||||
return "AUTOINCREMENT"
|
return "AUTOINCREMENT"
|
||||||
}
|
}
|
||||||
|
|
|
@ -175,12 +175,6 @@ func (engine *Engine) SupportInsertMany() bool {
|
||||||
return engine.dialect.SupportInsertMany()
|
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 {
|
func (engine *Engine) quoteColumns(columnStr string) string {
|
||||||
columns := strings.Split(columnStr, ",")
|
columns := strings.Split(columnStr, ",")
|
||||||
for i := 0; i < len(columns); i++ {
|
for i := 0; i < len(columns); i++ {
|
||||||
|
@ -196,13 +190,10 @@ func (engine *Engine) Quote(value string) string {
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
if string(value[0]) == engine.dialect.QuoteStr() || value[0] == '`' {
|
buf := builder.StringBuilder{}
|
||||||
return value
|
engine.QuoteTo(&buf, value)
|
||||||
}
|
|
||||||
|
|
||||||
value = strings.Replace(value, ".", engine.dialect.QuoteStr()+"."+engine.dialect.QuoteStr(), -1)
|
return buf.String()
|
||||||
|
|
||||||
return engine.dialect.QuoteStr() + value + engine.dialect.QuoteStr()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// QuoteTo quotes string and writes into the buffer
|
// QuoteTo quotes string and writes into the buffer
|
||||||
|
@ -216,20 +207,30 @@ func (engine *Engine) QuoteTo(buf *builder.StringBuilder, value string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if string(value[0]) == engine.dialect.QuoteStr() || value[0] == '`' {
|
quotePair := engine.dialect.Quote("")
|
||||||
buf.WriteString(value)
|
|
||||||
|
if value[0] == '`' || len(quotePair) < 2 || value[0] == quotePair[0] { // no quote
|
||||||
|
_, _ = buf.WriteString(value)
|
||||||
return
|
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 {
|
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
|
// 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{}) {
|
func (engine *Engine) formatTime(sqlTypeName string, t time.Time) (v interface{}) {
|
||||||
switch sqlTypeName {
|
switch sqlTypeName {
|
||||||
case core.Time:
|
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]
|
v = s[11:19]
|
||||||
case core.Date:
|
case core.Date:
|
||||||
v = t.Format("2006-01-02")
|
v = t.Format("2006-01-02")
|
||||||
|
|
|
@ -15,5 +15,5 @@ require (
|
||||||
github.com/stretchr/testify v1.3.0
|
github.com/stretchr/testify v1.3.0
|
||||||
github.com/ziutek/mymysql v1.5.4
|
github.com/ziutek/mymysql v1.5.4
|
||||||
xorm.io/builder v0.3.5
|
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.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.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 h1:glPeL3BQJsbF6aIIYfZizMwc5LTYz250bDMjttbBGAU=
|
||||||
cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw=
|
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/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 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
|
||||||
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
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.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 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
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.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
github.com/golang/mock v1.2.0/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.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/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/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
|
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=
|
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-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-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-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/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-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
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-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-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-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-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
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-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-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-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-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-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-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-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-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-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-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.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.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/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-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-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-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-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/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.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.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-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-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||||
google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/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=
|
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 h1:EilU39fvWDxjb1cDaELpYhsF+zziRBhew8xk4pngO+A=
|
||||||
xorm.io/builder v0.3.5/go.mod h1:ZFbByS/KxZI1FKRjL05PyJ4YrK2bcxlUaAxdum5aTR8=
|
xorm.io/builder v0.3.5/go.mod h1:ZFbByS/KxZI1FKRjL05PyJ4YrK2bcxlUaAxdum5aTR8=
|
||||||
xorm.io/core v0.6.3 h1:n1NhVZt1s2oLw1BZfX2ocIJsHyso259uPgg63BGr37M=
|
xorm.io/core v0.7.0 h1:hKxuOKWZNeiFQsSuGet/KV8HZ788hclvAl+7azx3tkM=
|
||||||
xorm.io/core v0.6.3/go.mod h1:8kz/C6arVW/O9vk3PgCiMJO2hIAm1UcuOL3dSPyZ2qo=
|
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 {
|
func rType(bean interface{}) reflect.Type {
|
||||||
sliceValue := reflect.Indirect(reflect.ValueOf(bean))
|
sliceValue := reflect.Indirect(reflect.ValueOf(bean))
|
||||||
//return reflect.TypeOf(sliceValue.Interface())
|
// return reflect.TypeOf(sliceValue.Interface())
|
||||||
return sliceValue.Type()
|
return sliceValue.Type()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,3 +309,24 @@ func sliceEq(left, right []string) bool {
|
||||||
func indexName(tableName, idxName string) string {
|
func indexName(tableName, idxName string) string {
|
||||||
return fmt.Sprintf("IDX_%v_%v", tableName, idxName)
|
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 {
|
func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{}) error {
|
||||||
|
defer session.resetStatement()
|
||||||
|
|
||||||
if session.statement.lastError != nil {
|
if session.statement.lastError != nil {
|
||||||
return session.statement.lastError
|
return session.statement.lastError
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,8 @@ func (session *Session) Get(bean interface{}) (bool, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *Session) get(bean interface{}) (bool, error) {
|
func (session *Session) get(bean interface{}) (bool, error) {
|
||||||
|
defer session.resetStatement()
|
||||||
|
|
||||||
if session.statement.lastError != nil {
|
if session.statement.lastError != nil {
|
||||||
return false, session.statement.lastError
|
return false, session.statement.lastError
|
||||||
}
|
}
|
||||||
|
@ -75,6 +77,8 @@ func (session *Session) get(bean interface{}) (bool, error) {
|
||||||
if context != nil {
|
if context != nil {
|
||||||
res := context.Get(fmt.Sprintf("%v-%v", sqlStr, args))
|
res := context.Get(fmt.Sprintf("%v-%v", sqlStr, args))
|
||||||
if res != nil {
|
if res != nil {
|
||||||
|
session.engine.logger.Debug("hit context cache", sqlStr)
|
||||||
|
|
||||||
structValue := reflect.Indirect(reflect.ValueOf(bean))
|
structValue := reflect.Indirect(reflect.ValueOf(bean))
|
||||||
structValue.Set(reflect.Indirect(reflect.ValueOf(res)))
|
structValue.Set(reflect.Indirect(reflect.ValueOf(res)))
|
||||||
session.lastSQL = ""
|
session.lastSQL = ""
|
||||||
|
@ -114,6 +118,114 @@ func (session *Session) nocacheGet(beanKind reflect.Kind, table *core.Table, bea
|
||||||
return true, rows.Scan(&bean)
|
return true, rows.Scan(&bean)
|
||||||
case *sql.NullInt64, *sql.NullBool, *sql.NullFloat64, *sql.NullString:
|
case *sql.NullInt64, *sql.NullBool, *sql.NullFloat64, *sql.NullString:
|
||||||
return true, rows.Scan(bean)
|
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 {
|
switch beanKind {
|
||||||
|
@ -142,6 +254,9 @@ func (session *Session) nocacheGet(beanKind reflect.Kind, table *core.Table, bea
|
||||||
err = rows.ScanSlice(bean)
|
err = rows.ScanSlice(bean)
|
||||||
case reflect.Map:
|
case reflect.Map:
|
||||||
err = rows.ScanMap(bean)
|
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:
|
default:
|
||||||
err = rows.Scan(bean)
|
err = rows.Scan(bean)
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"xorm.io/builder"
|
||||||
"xorm.io/core"
|
"xorm.io/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -242,23 +243,17 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error
|
||||||
|
|
||||||
var sql string
|
var sql string
|
||||||
if session.engine.dialect.DBType() == core.ORACLE {
|
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.Quote(tableName),
|
||||||
session.engine.QuoteStr(),
|
quoteColumns(colNames, session.engine.Quote, ","))
|
||||||
strings.Join(colNames, session.engine.QuoteStr()+", "+session.engine.QuoteStr()),
|
sql = fmt.Sprintf("INSERT ALL INTO %s (%v) VALUES (%v) SELECT 1 FROM DUAL",
|
||||||
session.engine.QuoteStr())
|
|
||||||
sql = fmt.Sprintf("INSERT ALL INTO %s (%v%v%v) VALUES (%v) SELECT 1 FROM DUAL",
|
|
||||||
session.engine.Quote(tableName),
|
session.engine.Quote(tableName),
|
||||||
session.engine.QuoteStr(),
|
quoteColumns(colNames, session.engine.Quote, ","),
|
||||||
strings.Join(colNames, session.engine.QuoteStr()+", "+session.engine.QuoteStr()),
|
|
||||||
session.engine.QuoteStr(),
|
|
||||||
strings.Join(colMultiPlaces, temp))
|
strings.Join(colMultiPlaces, temp))
|
||||||
} else {
|
} 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.Quote(tableName),
|
||||||
session.engine.QuoteStr(),
|
quoteColumns(colNames, session.engine.Quote, ","),
|
||||||
strings.Join(colNames, session.engine.QuoteStr()+", "+session.engine.QuoteStr()),
|
|
||||||
session.engine.QuoteStr(),
|
|
||||||
strings.Join(colMultiPlaces, "),("))
|
strings.Join(colMultiPlaces, "),("))
|
||||||
}
|
}
|
||||||
res, err := session.exec(sql, args...)
|
res, err := session.exec(sql, args...)
|
||||||
|
@ -351,7 +346,7 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) {
|
||||||
for _, v := range exprColumns {
|
for _, v := range exprColumns {
|
||||||
// remove the expr columns
|
// remove the expr columns
|
||||||
for i, colName := range colNames {
|
for i, colName := range colNames {
|
||||||
if colName == v.colName {
|
if colName == strings.Trim(v.colName, "`") {
|
||||||
colNames = append(colNames[:i], colNames[i+1:]...)
|
colNames = append(colNames[:i], colNames[i+1:]...)
|
||||||
args = append(args[:i], args[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 {
|
if session.engine.dialect.DBType() == core.MSSQL && len(table.AutoIncrement) > 0 {
|
||||||
output = fmt.Sprintf(" OUTPUT Inserted.%s", table.AutoIncrement)
|
output = fmt.Sprintf(" OUTPUT Inserted.%s", table.AutoIncrement)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(colPlaces) > 0 {
|
if len(colPlaces) > 0 {
|
||||||
sqlStr = fmt.Sprintf("INSERT INTO %s (%v%v%v)%s VALUES (%v)",
|
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),
|
session.engine.Quote(tableName),
|
||||||
session.engine.QuoteStr(),
|
quoteColumns(colNames, session.engine.Quote, ","),
|
||||||
strings.Join(colNames, session.engine.Quote(", ")),
|
output,
|
||||||
session.engine.QuoteStr(),
|
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,
|
output,
|
||||||
colPlaces)
|
colPlaces)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if session.engine.dialect.DBType() == core.MYSQL {
|
if session.engine.dialect.DBType() == core.MYSQL {
|
||||||
sqlStr = fmt.Sprintf("INSERT INTO %s VALUES ()", session.engine.Quote(tableName))
|
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
|
return 0, ErrParamsType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tableName := session.statement.TableName()
|
||||||
|
if len(tableName) <= 0 {
|
||||||
|
return 0, ErrTableNotFound
|
||||||
|
}
|
||||||
|
|
||||||
var columns = make([]string, 0, len(m))
|
var columns = make([]string, 0, len(m))
|
||||||
for k := range m {
|
for k := range m {
|
||||||
columns = append(columns, k)
|
columns = append(columns, k)
|
||||||
|
@ -678,19 +694,40 @@ func (session *Session) insertMapInterface(m map[string]interface{}) (int64, err
|
||||||
sort.Strings(columns)
|
sort.Strings(columns)
|
||||||
|
|
||||||
qm := strings.Repeat("?,", len(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))
|
var args = make([]interface{}, 0, len(m))
|
||||||
for _, colName := range columns {
|
for _, colName := range columns {
|
||||||
args = append(args, m[colName])
|
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 {
|
if err := session.cacheInsert(tableName); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
@ -711,26 +748,53 @@ func (session *Session) insertMapString(m map[string]string) (int64, error) {
|
||||||
return 0, ErrParamsType
|
return 0, ErrParamsType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tableName := session.statement.TableName()
|
||||||
|
if len(tableName) <= 0 {
|
||||||
|
return 0, ErrTableNotFound
|
||||||
|
}
|
||||||
|
|
||||||
var columns = make([]string, 0, len(m))
|
var columns = make([]string, 0, len(m))
|
||||||
for k := range m {
|
for k := range m {
|
||||||
columns = append(columns, k)
|
columns = append(columns, k)
|
||||||
}
|
}
|
||||||
sort.Strings(columns)
|
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))
|
var args = make([]interface{}, 0, len(m))
|
||||||
for _, colName := range columns {
|
for _, colName := range columns {
|
||||||
args = append(args, m[colName])
|
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 {
|
if err := session.cacheInsert(tableName); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,14 +96,15 @@ func (session *Session) cacheUpdate(table *core.Table, tableName, sqlStr string,
|
||||||
return ErrCacheFailed
|
return ErrCacheFailed
|
||||||
}
|
}
|
||||||
kvs := strings.Split(strings.TrimSpace(sqls[1]), ",")
|
kvs := strings.Split(strings.TrimSpace(sqls[1]), ",")
|
||||||
|
|
||||||
for idx, kv := range kvs {
|
for idx, kv := range kvs {
|
||||||
sps := strings.SplitN(kv, "=", 2)
|
sps := strings.SplitN(kv, "=", 2)
|
||||||
sps2 := strings.Split(sps[0], ".")
|
sps2 := strings.Split(sps[0], ".")
|
||||||
colName := sps2[len(sps2)-1]
|
colName := sps2[len(sps2)-1]
|
||||||
if strings.Contains(colName, "`") {
|
// treat quote prefix, suffix and '`' as quotes
|
||||||
colName = strings.TrimSpace(strings.Replace(colName, "`", "", -1))
|
quotes := append(strings.Split(session.engine.Quote(""), ""), "`")
|
||||||
} else if strings.Contains(colName, session.engine.QuoteStr()) {
|
if strings.ContainsAny(colName, strings.Join(quotes, "")) {
|
||||||
colName = strings.TrimSpace(strings.Replace(colName, session.engine.QuoteStr(), "", -1))
|
colName = strings.TrimSpace(eraseAny(colName, quotes...))
|
||||||
} else {
|
} else {
|
||||||
session.engine.logger.Debug("[cacheUpdate] cannot find column", tableName, colName)
|
session.engine.logger.Debug("[cacheUpdate] cannot find column", tableName, colName)
|
||||||
return ErrCacheFailed
|
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()
|
incColumns := session.statement.getInc()
|
||||||
for _, v := range incColumns {
|
for _, v := range incColumns {
|
||||||
colNames = append(colNames, session.engine.Quote(v.colName)+" = "+session.engine.Quote(v.colName)+" + ?")
|
colNames = append(colNames, session.engine.Quote(v.colName)+" = "+session.engine.Quote(v.colName)+" + ?")
|
||||||
args = append(args, v.arg)
|
args = append(args, v.arg)
|
||||||
}
|
}
|
||||||
//for update action to like "column = column - ?"
|
// for update action to like "column = column - ?"
|
||||||
decColumns := session.statement.getDec()
|
decColumns := session.statement.getDec()
|
||||||
for _, v := range decColumns {
|
for _, v := range decColumns {
|
||||||
colNames = append(colNames, session.engine.Quote(v.colName)+" = "+session.engine.Quote(v.colName)+" - ?")
|
colNames = append(colNames, session.engine.Quote(v.colName)+" = "+session.engine.Quote(v.colName)+" - ?")
|
||||||
args = append(args, v.arg)
|
args = append(args, v.arg)
|
||||||
}
|
}
|
||||||
//for update action to like "column = expression"
|
// for update action to like "column = expression"
|
||||||
exprColumns := session.statement.getExpr()
|
exprColumns := session.statement.getExpr()
|
||||||
for _, v := range exprColumns {
|
for _, v := range exprColumns {
|
||||||
colNames = append(colNames, session.engine.Quote(v.colName)+" = "+v.expr)
|
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 {
|
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)
|
session.engine.logger.Debug("[cacheUpdate] clear table ", tableName)
|
||||||
cacher.ClearIds(tableName)
|
cacher.ClearIds(tableName)
|
||||||
cacher.ClearBeans(tableName)
|
cacher.ClearBeans(tableName)
|
||||||
|
|
|
@ -6,7 +6,6 @@ package xorm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql/driver"
|
"database/sql/driver"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -398,7 +397,7 @@ func (statement *Statement) buildUpdates(bean interface{},
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//TODO: how to handler?
|
// TODO: how to handler?
|
||||||
panic("not supported")
|
panic("not supported")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -579,21 +578,9 @@ func (statement *Statement) getExpr() map[string]exprParam {
|
||||||
|
|
||||||
func (statement *Statement) col2NewColsWithQuote(columns ...string) []string {
|
func (statement *Statement) col2NewColsWithQuote(columns ...string) []string {
|
||||||
newColumns := make([]string, 0)
|
newColumns := make([]string, 0)
|
||||||
|
quotes := append(strings.Split(statement.Engine.Quote(""), ""), "`")
|
||||||
for _, col := range columns {
|
for _, col := range columns {
|
||||||
col = strings.Replace(col, "`", "", -1)
|
newColumns = append(newColumns, statement.Engine.Quote(eraseAny(col, quotes...)))
|
||||||
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"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return newColumns
|
return newColumns
|
||||||
}
|
}
|
||||||
|
@ -764,7 +751,9 @@ func (statement *Statement) Join(joinOP string, tablename interface{}, condition
|
||||||
return statement
|
return statement
|
||||||
}
|
}
|
||||||
tbs := strings.Split(tp.TableName(), ".")
|
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)
|
fmt.Fprintf(&buf, "(%s) %s ON %v", subSQL, aliasName, condition)
|
||||||
statement.joinArgs = append(statement.joinArgs, subQueryArgs...)
|
statement.joinArgs = append(statement.joinArgs, subQueryArgs...)
|
||||||
case *builder.Builder:
|
case *builder.Builder:
|
||||||
|
@ -774,7 +763,9 @@ func (statement *Statement) Join(joinOP string, tablename interface{}, condition
|
||||||
return statement
|
return statement
|
||||||
}
|
}
|
||||||
tbs := strings.Split(tp.TableName(), ".")
|
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)
|
fmt.Fprintf(&buf, "(%s) %s ON %v", subSQL, aliasName, condition)
|
||||||
statement.joinArgs = append(statement.joinArgs, subQueryArgs...)
|
statement.joinArgs = append(statement.joinArgs, subQueryArgs...)
|
||||||
default:
|
default:
|
||||||
|
@ -1157,8 +1148,12 @@ func (statement *Statement) genSelectSQL(columnStr, condSQL string, needLimit, n
|
||||||
if statement.Start != 0 || statement.LimitN != 0 {
|
if statement.Start != 0 || statement.LimitN != 0 {
|
||||||
oldString := buf.String()
|
oldString := buf.String()
|
||||||
buf.Reset()
|
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",
|
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]
|
var whereStr = sqls[1]
|
||||||
|
|
||||||
//TODO: for postgres only, if any other database?
|
// TODO: for postgres only, if any other database?
|
||||||
var paraStr string
|
var paraStr string
|
||||||
if statement.Engine.dialect.DBType() == core.POSTGRES {
|
if statement.Engine.dialect.DBType() == core.POSTGRES {
|
||||||
paraStr = "$"
|
paraStr = "$"
|
||||||
|
|
|
@ -148,7 +148,7 @@ github.com/go-redis/redis/internal/proto
|
||||||
github.com/go-redis/redis/internal/util
|
github.com/go-redis/redis/internal/util
|
||||||
# github.com/go-sql-driver/mysql v1.4.1
|
# github.com/go-sql-driver/mysql v1.4.1
|
||||||
github.com/go-sql-driver/mysql
|
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/go-xorm/xorm
|
||||||
# github.com/gogits/chardet v0.0.0-20150115103509-2404f7772561
|
# github.com/gogits/chardet v0.0.0-20150115103509-2404f7772561
|
||||||
github.com/gogits/chardet
|
github.com/gogits/chardet
|
||||||
|
@ -482,5 +482,5 @@ mvdan.cc/xurls/v2
|
||||||
strk.kbt.io/projects/go/libravatar
|
strk.kbt.io/projects/go/libravatar
|
||||||
# xorm.io/builder v0.3.5
|
# xorm.io/builder v0.3.5
|
||||||
xorm.io/builder
|
xorm.io/builder
|
||||||
# xorm.io/core v0.6.3
|
# xorm.io/core v0.7.0
|
||||||
xorm.io/core
|
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.
|
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
|
# Open
|
||||||
```Go
|
```Go
|
||||||
|
|
|
@ -14,19 +14,20 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// default cache expired time
|
// CacheExpired is default cache expired time
|
||||||
CacheExpired = 60 * time.Minute
|
CacheExpired = 60 * time.Minute
|
||||||
// not use now
|
// CacheMaxMemory is not use now
|
||||||
CacheMaxMemory = 256
|
CacheMaxMemory = 256
|
||||||
// evey ten minutes to clear all expired nodes
|
// CacheGcInterval represents interval time to clear all expired nodes
|
||||||
CacheGcInterval = 10 * time.Minute
|
CacheGcInterval = 10 * time.Minute
|
||||||
// each time when gc to removed max nodes
|
// CacheGcMaxRemoved represents max nodes removed when gc
|
||||||
CacheGcMaxRemoved = 20
|
CacheGcMaxRemoved = 20
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// list all the errors
|
||||||
var (
|
var (
|
||||||
ErrCacheMiss = errors.New("xorm/cache: key not found.")
|
ErrCacheMiss = errors.New("xorm/cache: key not found")
|
||||||
ErrNotStored = errors.New("xorm/cache: not stored.")
|
ErrNotStored = errors.New("xorm/cache: not stored")
|
||||||
)
|
)
|
||||||
|
|
||||||
// CacheStore is a interface to store cache
|
// CacheStore is a interface to store cache
|
||||||
|
@ -69,6 +70,7 @@ func decodeIds(s string) ([]PK, error) {
|
||||||
return pks, err
|
return pks, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetCacheSql returns cacher PKs via SQL
|
||||||
func GetCacheSql(m Cacher, tableName, sql string, args interface{}) ([]PK, error) {
|
func GetCacheSql(m Cacher, tableName, sql string, args interface{}) ([]PK, error) {
|
||||||
bytes := m.GetIds(tableName, GenSqlKey(sql, args))
|
bytes := m.GetIds(tableName, GenSqlKey(sql, args))
|
||||||
if bytes == nil {
|
if bytes == nil {
|
||||||
|
@ -77,6 +79,7 @@ func GetCacheSql(m Cacher, tableName, sql string, args interface{}) ([]PK, error
|
||||||
return decodeIds(bytes.(string))
|
return decodeIds(bytes.(string))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PutCacheSql puts cacher SQL and PKs
|
||||||
func PutCacheSql(m Cacher, ids []PK, tableName, sql string, args interface{}) error {
|
func PutCacheSql(m Cacher, ids []PK, tableName, sql string, args interface{}) error {
|
||||||
bytes, err := encodeIds(ids)
|
bytes, err := encodeIds(ids)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -86,6 +89,7 @@ func PutCacheSql(m Cacher, ids []PK, tableName, sql string, args interface{}) er
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GenSqlKey generates cache key
|
||||||
func GenSqlKey(sql string, args interface{}) string {
|
func GenSqlKey(sql string, args interface{}) string {
|
||||||
return fmt.Sprintf("%v-%v", sql, args)
|
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
|
// String generate column description string according dialect
|
||||||
func (col *Column) String(d Dialect) string {
|
func (col *Column) String(d Dialect) string {
|
||||||
sql := d.QuoteStr() + col.Name + d.QuoteStr() + " "
|
sql := d.Quote(col.Name) + " "
|
||||||
|
|
||||||
sql += d.SqlType(col) + " "
|
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
|
// StringNoPk generate column description string according dialect without primary keys
|
||||||
func (col *Column) StringNoPk(d Dialect) string {
|
func (col *Column) StringNoPk(d Dialect) string {
|
||||||
sql := d.QuoteStr() + col.Name + d.QuoteStr() + " "
|
sql := d.Quote(col.Name) + " "
|
||||||
|
|
||||||
sql += d.SqlType(col) + " "
|
sql += d.SqlType(col) + " "
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
// DefaultCacheSize sets the default cache size
|
||||||
DefaultCacheSize = 200
|
DefaultCacheSize = 200
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -132,6 +133,7 @@ func (db *DB) Query(query string, args ...interface{}) (*Rows, error) {
|
||||||
return db.QueryContext(context.Background(), query, args...)
|
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) {
|
func (db *DB) QueryMapContext(ctx context.Context, query string, mp interface{}) (*Rows, error) {
|
||||||
query, args, err := MapToSlice(query, mp)
|
query, args, err := MapToSlice(query, mp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -140,6 +142,7 @@ func (db *DB) QueryMapContext(ctx context.Context, query string, mp interface{})
|
||||||
return db.QueryContext(ctx, query, args...)
|
return db.QueryContext(ctx, query, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// QueryMap executes query with parameters via map
|
||||||
func (db *DB) QueryMap(query string, mp interface{}) (*Rows, error) {
|
func (db *DB) QueryMap(query string, mp interface{}) (*Rows, error) {
|
||||||
return db.QueryMapContext(context.Background(), query, mp)
|
return db.QueryMapContext(context.Background(), query, mp)
|
||||||
}
|
}
|
||||||
|
@ -196,6 +199,7 @@ var (
|
||||||
re = regexp.MustCompile(`[?](\w+)`)
|
re = regexp.MustCompile(`[?](\w+)`)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ExecMapContext exec map with context.Context
|
||||||
// insert into (name) values (?)
|
// insert into (name) values (?)
|
||||||
// insert into (name) values (?name)
|
// insert into (name) values (?name)
|
||||||
func (db *DB) ExecMapContext(ctx context.Context, query string, mp interface{}) (sql.Result, error) {
|
func (db *DB) ExecMapContext(ctx context.Context, query string, mp interface{}) (sql.Result, error) {
|
||||||
|
|
|
@ -40,9 +40,9 @@ type Dialect interface {
|
||||||
DriverName() string
|
DriverName() string
|
||||||
DataSourceName() string
|
DataSourceName() string
|
||||||
|
|
||||||
QuoteStr() string
|
|
||||||
IsReserved(string) bool
|
IsReserved(string) bool
|
||||||
Quote(string) string
|
Quote(string) string
|
||||||
|
|
||||||
AndStr() string
|
AndStr() string
|
||||||
OrStr() string
|
OrStr() string
|
||||||
EqStr() string
|
EqStr() string
|
||||||
|
@ -70,8 +70,8 @@ type Dialect interface {
|
||||||
|
|
||||||
ForUpdateSql(query string) string
|
ForUpdateSql(query string) string
|
||||||
|
|
||||||
//CreateTableIfNotExists(table *Table, tableName, storeEngine, charset string) error
|
// CreateTableIfNotExists(table *Table, tableName, storeEngine, charset string) error
|
||||||
//MustDropTable(tableName string) error
|
// MustDropTable(tableName string) error
|
||||||
|
|
||||||
GetColumns(tableName string) ([]string, map[string]*Column, error)
|
GetColumns(tableName string) ([]string, map[string]*Column, error)
|
||||||
GetTables() ([]*Table, error)
|
GetTables() ([]*Table, error)
|
||||||
|
@ -85,6 +85,7 @@ func OpenDialect(dialect Dialect) (*DB, error) {
|
||||||
return Open(dialect.DriverName(), dialect.DataSourceName())
|
return Open(dialect.DriverName(), dialect.DataSourceName())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Base represents a basic dialect and all real dialects could embed this struct
|
||||||
type Base struct {
|
type Base struct {
|
||||||
db *DB
|
db *DB
|
||||||
dialect Dialect
|
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) {
|
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 := fmt.Sprintf(
|
||||||
query = strings.Replace(query, "`", db.dialect.QuoteStr(), -1)
|
"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)
|
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
|
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 {
|
func QueryDialect(dbName DbType) Dialect {
|
||||||
if d, ok := dialects[strings.ToLower(string(dbName))]; ok {
|
if d, ok := dialects[strings.ToLower(string(dbName))]; ok {
|
||||||
return d()
|
return d()
|
||||||
|
|
|
@ -7,6 +7,8 @@ package core
|
||||||
import "errors"
|
import "errors"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
// ErrNoMapPointer represents error when no map pointer
|
||||||
ErrNoMapPointer = errors.New("mp should be a map's 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")
|
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 {
|
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
|
// 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 {
|
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 {
|
func (i *IdFilter) Do(sql string, dialect Dialect, table *Table) string {
|
||||||
|
|
|
@ -2,6 +2,12 @@ module xorm.io/core
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/go-sql-driver/mysql v1.4.1
|
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
|
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 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
|
||||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
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.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 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o=
|
||||||
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
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-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.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 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
|
||||||
google.golang.org/appengine v1.4.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=
|
||||||
|
|
|
@ -4,8 +4,10 @@
|
||||||
|
|
||||||
package core
|
package core
|
||||||
|
|
||||||
|
// LogLevel defines a log level
|
||||||
type LogLevel int
|
type LogLevel int
|
||||||
|
|
||||||
|
// enumerate all LogLevels
|
||||||
const (
|
const (
|
||||||
// !nashtsai! following level also match syslog.Priority value
|
// !nashtsai! following level also match syslog.Priority value
|
||||||
LOG_DEBUG LogLevel = iota
|
LOG_DEBUG LogLevel = iota
|
||||||
|
@ -16,7 +18,7 @@ const (
|
||||||
LOG_UNKNOWN
|
LOG_UNKNOWN
|
||||||
)
|
)
|
||||||
|
|
||||||
// logger interface
|
// ILogger is a logger interface
|
||||||
type ILogger interface {
|
type ILogger interface {
|
||||||
Debug(v ...interface{})
|
Debug(v ...interface{})
|
||||||
Debugf(format string, v ...interface{})
|
Debugf(format string, v ...interface{})
|
||||||
|
|
|
@ -9,12 +9,13 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// enumerate all index types
|
||||||
const (
|
const (
|
||||||
IndexType = iota + 1
|
IndexType = iota + 1
|
||||||
UniqueType
|
UniqueType
|
||||||
)
|
)
|
||||||
|
|
||||||
// database index
|
// Index represents a database index
|
||||||
type Index struct {
|
type Index struct {
|
||||||
IsRegular bool
|
IsRegular bool
|
||||||
Name string
|
Name string
|
||||||
|
@ -35,7 +36,7 @@ func (index *Index) XName(tableName string) string {
|
||||||
return index.Name
|
return index.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
// add columns which will be composite index
|
// AddColumn add columns which will be composite index
|
||||||
func (index *Index) AddColumn(cols ...string) {
|
func (index *Index) AddColumn(cols ...string) {
|
||||||
for _, col := range cols {
|
for _, col := range cols {
|
||||||
index.Cols = append(index.Cols, col)
|
index.Cols = append(index.Cols, col)
|
||||||
|
@ -65,7 +66,7 @@ func (index *Index) Equal(dst *Index) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// new an index
|
// NewIndex new an index object
|
||||||
func NewIndex(name string, indexType int) *Index {
|
func NewIndex(name string, indexType int) *Index {
|
||||||
return &Index{true, name, indexType, make([]string, 0)}
|
return &Index{true, name, indexType, make([]string, 0)}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
"sync"
|
"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 {
|
type IMapper interface {
|
||||||
Obj2Table(string) string
|
Obj2Table(string) string
|
||||||
Table2Obj(string) string
|
Table2Obj(string) string
|
||||||
|
@ -184,7 +184,7 @@ func (mapper GonicMapper) Table2Obj(name string) string {
|
||||||
return string(newstr)
|
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{
|
var LintGonicMapper = GonicMapper{
|
||||||
"API": true,
|
"API": true,
|
||||||
"ASCII": true,
|
"ASCII": true,
|
||||||
|
@ -221,7 +221,7 @@ var LintGonicMapper = GonicMapper{
|
||||||
"XSS": true,
|
"XSS": true,
|
||||||
}
|
}
|
||||||
|
|
||||||
// provide prefix table name support
|
// PrefixMapper provides prefix table name support
|
||||||
type PrefixMapper struct {
|
type PrefixMapper struct {
|
||||||
Mapper IMapper
|
Mapper IMapper
|
||||||
Prefix string
|
Prefix string
|
||||||
|
@ -239,7 +239,7 @@ func NewPrefixMapper(mapper IMapper, prefix string) PrefixMapper {
|
||||||
return PrefixMapper{mapper, prefix}
|
return PrefixMapper{mapper, prefix}
|
||||||
}
|
}
|
||||||
|
|
||||||
// provide suffix table name support
|
// SuffixMapper provides suffix table name support
|
||||||
type SuffixMapper struct {
|
type SuffixMapper struct {
|
||||||
Mapper IMapper
|
Mapper IMapper
|
||||||
Suffix string
|
Suffix string
|
||||||
|
|
|
@ -170,7 +170,7 @@ func (rs *Rows) ScanMap(dest interface{}) error {
|
||||||
newDest := make([]interface{}, len(cols))
|
newDest := make([]interface{}, len(cols))
|
||||||
vvv := vv.Elem()
|
vvv := vv.Elem()
|
||||||
|
|
||||||
for i, _ := range cols {
|
for i := range cols {
|
||||||
newDest[i] = rs.db.reflectNew(vvv.Type().Elem()).Interface()
|
newDest[i] = rs.db.reflectNew(vvv.Type().Elem()).Interface()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Stmt reprents a stmt objects
|
||||||
type Stmt struct {
|
type Stmt struct {
|
||||||
*sql.Stmt
|
*sql.Stmt
|
||||||
db *DB
|
db *DB
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// database table
|
// Table represents a database table
|
||||||
type Table struct {
|
type Table struct {
|
||||||
Name string
|
Name string
|
||||||
Type reflect.Type
|
Type reflect.Type
|
||||||
|
@ -41,6 +41,7 @@ func NewEmptyTable() *Table {
|
||||||
return NewTable("", nil)
|
return NewTable("", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewTable creates a new Table object
|
||||||
func NewTable(name string, t reflect.Type) *Table {
|
func NewTable(name string, t reflect.Type) *Table {
|
||||||
return &Table{Name: name, Type: t,
|
return &Table{Name: name, Type: t,
|
||||||
columnsSeq: make([]string, 0),
|
columnsSeq: make([]string, 0),
|
||||||
|
@ -87,7 +88,7 @@ func (table *Table) GetColumnIdx(name string, idx int) *Column {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// if has primary key, return column
|
// PKColumns reprents all primary key columns
|
||||||
func (table *Table) PKColumns() []*Column {
|
func (table *Table) PKColumns() []*Column {
|
||||||
columns := make([]*Column, len(table.PrimaryKeys))
|
columns := make([]*Column, len(table.PrimaryKeys))
|
||||||
for i, name := range table.PrimaryKeys {
|
for i, name := range table.PrimaryKeys {
|
||||||
|
@ -117,7 +118,7 @@ func (table *Table) DeletedColumn() *Column {
|
||||||
return table.GetColumn(table.Deleted)
|
return table.GetColumn(table.Deleted)
|
||||||
}
|
}
|
||||||
|
|
||||||
// add a column to table
|
// AddColumn adds a column to table
|
||||||
func (table *Table) AddColumn(col *Column) {
|
func (table *Table) AddColumn(col *Column) {
|
||||||
table.columnsSeq = append(table.columnsSeq, col.Name)
|
table.columnsSeq = append(table.columnsSeq, col.Name)
|
||||||
table.columns = append(table.columns, col)
|
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) {
|
func (table *Table) AddIndex(index *Index) {
|
||||||
table.Indexes[index.Name] = index
|
table.Indexes[index.Name] = index
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue