forked from gitea/gitea
Upgrade xorm to v1.1.0 (#15869)
This commit is contained in:
parent
e2f39c2b64
commit
f6be429781
2
go.mod
2
go.mod
|
@ -131,7 +131,7 @@ require (
|
|||
mvdan.cc/xurls/v2 v2.2.0
|
||||
strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251
|
||||
xorm.io/builder v0.3.9
|
||||
xorm.io/xorm v1.0.7
|
||||
xorm.io/xorm v1.1.0
|
||||
)
|
||||
|
||||
replace github.com/hashicorp/go-version => github.com/6543/go-version v1.3.1
|
||||
|
|
38
go.sum
38
go.sum
|
@ -250,6 +250,7 @@ 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/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/denisenkom/go-mssqldb v0.10.0 h1:QykgLZBorFE95+gO3u9esLd0BmbvpWp0/waNNZfHBM8=
|
||||
github.com/denisenkom/go-mssqldb v0.10.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
|
@ -812,6 +813,7 @@ github.com/mattn/go-runewidth v0.0.12 h1:Y41i/hVW3Pgwr8gV+J23B9YEY0zxjptBuCWEaxm
|
|||
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
||||
github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
|
||||
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mattn/go-sqlite3 v1.14.7 h1:fxWBnXkxfM6sRiuH3bqJ4CfzZojMOLVc0UTsTglEghA=
|
||||
github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
|
@ -982,6 +984,8 @@ github.com/quasoft/websspi v1.0.0 h1:5nDgdM5xSur9s+B5w2xQ5kxf5nUGqgFgU4W0aDLZ8Mw
|
|||
github.com/quasoft/websspi v1.0.0/go.mod h1:HmVdl939dQ0WIXZhyik+ARdI03M6bQzaSEKcgpFmewk=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
|
@ -1403,6 +1407,7 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
@ -1496,6 +1501,7 @@ golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82u
|
|||
golang.org/x/tools v0.0.0-20200928182047-19e03678916f/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||
golang.org/x/tools v0.0.0-20200929161345-d7fc70abf50f/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
|
@ -1663,6 +1669,33 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt
|
|||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4 h1:UoveltGrhghAA7ePc+e+QYDHXrBps2PqFZiHkGR/xK8=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
modernc.org/cc/v3 v3.31.5-0.20210308123301-7a3e9dab9009 h1:u0oCo5b9wyLr++HF3AN9JicGhkUxJhMz51+8TIZH9N0=
|
||||
modernc.org/cc/v3 v3.31.5-0.20210308123301-7a3e9dab9009/go.mod h1:0R6jl1aZlIl2avnYfbfHBS1QB6/f+16mihBObaBC878=
|
||||
modernc.org/ccgo/v3 v3.9.0 h1:JbcEIqjw4Agf+0g3Tc85YvfYqkkFOv6xBwS4zkfqSoA=
|
||||
modernc.org/ccgo/v3 v3.9.0/go.mod h1:nQbgkn8mwzPdp4mm6BT6+p85ugQ7FrGgIcYaE7nSrpY=
|
||||
modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM=
|
||||
modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=
|
||||
modernc.org/libc v1.7.13-0.20210308123627-12f642a52bb8/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w=
|
||||
modernc.org/libc v1.8.0 h1:Pp4uv9g0csgBMpGPABKtkieF6O5MGhfGo6ZiOdlYfR8=
|
||||
modernc.org/libc v1.8.0/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w=
|
||||
modernc.org/mathutil v1.1.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/mathutil v1.2.2 h1:+yFk8hBprV+4c0U9GjFtL+dV3N8hOJ8JCituQcMShFY=
|
||||
modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/memory v1.0.4 h1:utMBrFcpnQDdNsmM6asmyH/FM9TqLPS7XF7otpJmrwM=
|
||||
modernc.org/memory v1.0.4/go.mod h1:nV2OApxradM3/OVbs2/0OsP6nPfakXpi50C7dcoHXlc=
|
||||
modernc.org/opt v0.1.1 h1:/0RX92k9vwVeDXj+Xn23DKp2VJubL7k8qNffND6qn3A=
|
||||
modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||
modernc.org/sqlite v1.10.1-0.20210314190707-798bbeb9bb84 h1:rgEUzE849tFlHSoeCrKyS9cZAljC+DY7MdMHKq6R6sY=
|
||||
modernc.org/sqlite v1.10.1-0.20210314190707-798bbeb9bb84/go.mod h1:PGzq6qlhyYjL6uVbSgS6WoF7ZopTW/sI7+7p+mb4ZVU=
|
||||
modernc.org/strutil v1.1.0 h1:+1/yCzZxY2pZwwrsbH+4T7BQMoLQ9QiBshRC9eicYsc=
|
||||
modernc.org/strutil v1.1.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs=
|
||||
modernc.org/tcl v1.5.0 h1:euZSUNfE0Fd4W8VqXI1Ly1v7fqDJoBuAV88Ea+SnaSs=
|
||||
modernc.org/tcl v1.5.0/go.mod h1:gb57hj4pO8fRrK54zveIfFXBaMHK3SKJNWcmRw1cRzc=
|
||||
modernc.org/token v1.0.0 h1:a0jaWiNMDhDUtqOj09wvjWWAqd3q7WpBulmL9H2egsk=
|
||||
modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||
modernc.org/z v1.0.1-0.20210308123920-1f282aa71362/go.mod h1:8/SRk5C/HgiQWCgXdfpb+1RvhORdkz5sw72d3jjtyqA=
|
||||
modernc.org/z v1.0.1 h1:WyIDpEpAIx4Hel6q/Pcgj/VhaQV5XPJ2I6ryIYbjnpc=
|
||||
modernc.org/z v1.0.1/go.mod h1:8/SRk5C/HgiQWCgXdfpb+1RvhORdkz5sw72d3jjtyqA=
|
||||
mvdan.cc/xurls/v2 v2.2.0 h1:NSZPykBXJFCetGZykLAxaL6SIpvbVy/UFEniIfHAa8A=
|
||||
mvdan.cc/xurls/v2 v2.2.0/go.mod h1:EV1RMtya9D6G5DMYPGD8zTQzaHet6Jh8gFlRgGRJeO8=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
|
@ -1673,8 +1706,9 @@ sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1
|
|||
strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251 h1:mUcz5b3FJbP5Cvdq7Khzn6J9OCUQJaBwgBkCR+MOwSs=
|
||||
strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251/go.mod h1:FJGmPh3vz9jSos1L/F91iAgnC/aejc0wIIrF2ZwJxdY=
|
||||
xorm.io/builder v0.3.7/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
|
||||
xorm.io/builder v0.3.8/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
|
||||
xorm.io/builder v0.3.9 h1:Sd65/LdWyO7LR8+Cbd+e7mm3sK/7U9k0jS3999IDHMc=
|
||||
xorm.io/builder v0.3.9/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
|
||||
xorm.io/xorm v1.0.6/go.mod h1:uF9EtbhODq5kNWxMbnBEj8hRRZnlcNSz2t2N7HW/+A4=
|
||||
xorm.io/xorm v1.0.7 h1:26yBTDVI+CfQpVz2Y88fISh+aiJXIPP4eNoTJlwzsC4=
|
||||
xorm.io/xorm v1.0.7/go.mod h1:uF9EtbhODq5kNWxMbnBEj8hRRZnlcNSz2t2N7HW/+A4=
|
||||
xorm.io/xorm v1.1.0 h1:mkEsQXLauZajiOld2cB2PkFcUZKePepPgs1bC1dw8RA=
|
||||
xorm.io/xorm v1.1.0/go.mod h1:EDzNHMuCVZNszkIRSLL2nI0zX+nQE8RstAVranlSfqI=
|
||||
|
|
|
@ -1014,7 +1014,7 @@ strk.kbt.io/projects/go/libravatar
|
|||
# xorm.io/builder v0.3.9
|
||||
## explicit
|
||||
xorm.io/builder
|
||||
# xorm.io/xorm v1.0.7
|
||||
# xorm.io/xorm v1.1.0
|
||||
## explicit
|
||||
xorm.io/xorm
|
||||
xorm.io/xorm/caches
|
||||
|
|
|
@ -2,58 +2,288 @@
|
|||
kind: pipeline
|
||||
name: testing
|
||||
steps:
|
||||
- name: restore-cache
|
||||
image: meltwater/drone-cache
|
||||
pull: always
|
||||
settings:
|
||||
backend: "filesystem"
|
||||
restore: true
|
||||
cache_key: '{{ .Repo.Name }}_{{ checksum "go.mod" }}_{{ checksum "go.sum" }}_{{ arch }}_{{ os }}'
|
||||
archive_format: "gzip"
|
||||
filesystem_cache_root: "/go"
|
||||
mount:
|
||||
- pkg.mod
|
||||
- pkg.build
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /go
|
||||
|
||||
- name: test-vet
|
||||
image: golang:1.11 # The lowest golang requirement
|
||||
image: golang:1.15
|
||||
environment:
|
||||
GO111MODULE: "on"
|
||||
GOPROXY: "https://goproxy.cn"
|
||||
GOPROXY: "https://goproxy.io"
|
||||
CGO_ENABLED: 1
|
||||
GOMODCACHE: '/drone/src/pkg.mod'
|
||||
GOCACHE: '/drone/src/pkg.build'
|
||||
commands:
|
||||
- make vet
|
||||
- make test
|
||||
- make fmt-check
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /go
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
|
||||
- name: test-sqlite
|
||||
image: golang:1.12
|
||||
- name: rebuild-cache
|
||||
image: meltwater/drone-cache
|
||||
pull: true
|
||||
settings:
|
||||
backend: "filesystem"
|
||||
rebuild: true
|
||||
cache_key: '{{ .Repo.Name }}_{{ checksum "go.mod" }}_{{ checksum "go.sum" }}_{{ arch }}_{{ os }}'
|
||||
archive_format: "gzip"
|
||||
filesystem_cache_root: "/go"
|
||||
mount:
|
||||
- pkg.mod
|
||||
- pkg.build
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /go
|
||||
|
||||
volumes:
|
||||
- name: cache
|
||||
temp: {}
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
name: test-sqlite
|
||||
depends_on:
|
||||
- testing
|
||||
steps:
|
||||
- name: restore-cache
|
||||
image: meltwater/drone-cache:dev
|
||||
pull: always
|
||||
settings:
|
||||
backend: "filesystem"
|
||||
restore: true
|
||||
cache_key: '{{ .Repo.Name }}_{{ checksum "go.mod" }}_{{ checksum "go.sum" }}_{{ arch }}_{{ os }}'
|
||||
archive_format: "gzip"
|
||||
filesystem_cache_root: "/go"
|
||||
mount:
|
||||
- pkg.mod
|
||||
- pkg.build
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /go
|
||||
|
||||
- name: test-sqlite3
|
||||
image: golang:1.15
|
||||
environment:
|
||||
GO111MODULE: "on"
|
||||
GOPROXY: "https://goproxy.cn"
|
||||
GOPROXY: "https://goproxy.io"
|
||||
CGO_ENABLED: 1
|
||||
GOMODCACHE: '/drone/src/pkg.mod'
|
||||
GOCACHE: '/drone/src/pkg.build'
|
||||
commands:
|
||||
- make test-sqlite3
|
||||
- TEST_CACHE_ENABLE=true make test-sqlite3
|
||||
- TEST_QUOTE_POLICY=reserved make test-sqlite3
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /go
|
||||
|
||||
- name: test-sqlite
|
||||
image: golang:1.15
|
||||
environment:
|
||||
GO111MODULE: "on"
|
||||
GOPROXY: "https://goproxy.io"
|
||||
CGO_ENABLED: 1
|
||||
GOMODCACHE: '/drone/src/pkg.mod'
|
||||
GOCACHE: '/drone/src/pkg.build'
|
||||
commands:
|
||||
- make test-sqlite
|
||||
- TEST_CACHE_ENABLE=true make test-sqlite
|
||||
- TEST_QUOTE_POLICY=reserved make test-sqlite
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /go
|
||||
|
||||
- name: rebuild-cache
|
||||
image: meltwater/drone-cache:dev
|
||||
pull: true
|
||||
settings:
|
||||
backend: "filesystem"
|
||||
rebuild: true
|
||||
cache_key: '{{ .Repo.Name }}_{{ checksum "go.mod" }}_{{ checksum "go.sum" }}_{{ arch }}_{{ os }}'
|
||||
archive_format: "gzip"
|
||||
filesystem_cache_root: "/go"
|
||||
mount:
|
||||
- pkg.mod
|
||||
- pkg.build
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /go
|
||||
|
||||
volumes:
|
||||
- name: cache
|
||||
temp: {}
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
name: test-mysql
|
||||
depends_on:
|
||||
- testing
|
||||
steps:
|
||||
- name: restore-cache
|
||||
image: meltwater/drone-cache
|
||||
pull: always
|
||||
settings:
|
||||
backend: "filesystem"
|
||||
restore: true
|
||||
cache_key: '{{ .Repo.Name }}_{{ checksum "go.mod" }}_{{ checksum "go.sum" }}_{{ arch }}_{{ os }}'
|
||||
archive_format: "gzip"
|
||||
filesystem_cache_root: "/go"
|
||||
mount:
|
||||
- pkg.mod
|
||||
- pkg.build
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /go
|
||||
|
||||
- name: test-mysql
|
||||
image: golang:1.12
|
||||
image: golang:1.15
|
||||
environment:
|
||||
GO111MODULE: "on"
|
||||
GOPROXY: "https://goproxy.cn"
|
||||
GOPROXY: "https://goproxy.io"
|
||||
CGO_ENABLED: 1
|
||||
GOMODCACHE: '/drone/src/pkg.mod'
|
||||
GOCACHE: '/drone/src/pkg.build'
|
||||
TEST_MYSQL_HOST: mysql
|
||||
TEST_MYSQL_CHARSET: utf8
|
||||
TEST_MYSQL_DBNAME: xorm_test
|
||||
TEST_MYSQL_USERNAME: root
|
||||
TEST_MYSQL_PASSWORD:
|
||||
commands:
|
||||
- make test
|
||||
- make test-mysql
|
||||
- TEST_CACHE_ENABLE=true make test-mysql
|
||||
- TEST_QUOTE_POLICY=reserved make test-mysql
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /go
|
||||
|
||||
- name: test-mysql-utf8mb4
|
||||
image: golang:1.15
|
||||
depends_on:
|
||||
- test-mysql
|
||||
environment:
|
||||
GO111MODULE: "on"
|
||||
GOPROXY: "https://goproxy.io"
|
||||
CGO_ENABLED: 1
|
||||
GOMODCACHE: '/drone/src/pkg.mod'
|
||||
GOCACHE: '/drone/src/pkg.build'
|
||||
TEST_MYSQL_HOST: mysql
|
||||
TEST_MYSQL_CHARSET: utf8mb4
|
||||
TEST_MYSQL_DBNAME: xorm_test
|
||||
TEST_MYSQL_USERNAME: root
|
||||
TEST_MYSQL_PASSWORD:
|
||||
commands:
|
||||
- make test-mysql
|
||||
- TEST_CACHE_ENABLE=true make test-mysql
|
||||
- TEST_QUOTE_POLICY=reserved make test-mysql
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /go
|
||||
|
||||
- name: test-mysql8
|
||||
image: golang:1.12
|
||||
- name: test-mymysql
|
||||
pull: default
|
||||
image: golang:1.15
|
||||
depends_on:
|
||||
- test-mysql-utf8mb4
|
||||
environment:
|
||||
GO111MODULE: "on"
|
||||
GOPROXY: "https://goproxy.cn"
|
||||
GOPROXY: "https://goproxy.io"
|
||||
CGO_ENABLED: 1
|
||||
GOMODCACHE: '/drone/src/pkg.mod'
|
||||
GOCACHE: '/drone/src/pkg.build'
|
||||
TEST_MYSQL_HOST: mysql:3306
|
||||
TEST_MYSQL_DBNAME: xorm_test
|
||||
TEST_MYSQL_USERNAME: root
|
||||
TEST_MYSQL_PASSWORD:
|
||||
commands:
|
||||
- make test-mymysql
|
||||
- TEST_CACHE_ENABLE=true make test-mymysql
|
||||
- TEST_QUOTE_POLICY=reserved make test-mymysql
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /go
|
||||
|
||||
- name: rebuild-cache
|
||||
image: meltwater/drone-cache
|
||||
depends_on:
|
||||
- test-mysql
|
||||
- test-mysql-utf8mb4
|
||||
- test-mymysql
|
||||
pull: true
|
||||
settings:
|
||||
backend: "filesystem"
|
||||
rebuild: true
|
||||
cache_key: '{{ .Repo.Name }}_{{ checksum "go.mod" }}_{{ checksum "go.sum" }}_{{ arch }}_{{ os }}'
|
||||
archive_format: "gzip"
|
||||
filesystem_cache_root: "/go"
|
||||
mount:
|
||||
- pkg.mod
|
||||
- pkg.build
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /go
|
||||
|
||||
volumes:
|
||||
- name: cache
|
||||
temp: {}
|
||||
|
||||
services:
|
||||
- name: mysql
|
||||
pull: default
|
||||
image: mysql:5.7
|
||||
environment:
|
||||
MYSQL_ALLOW_EMPTY_PASSWORD: yes
|
||||
MYSQL_DATABASE: xorm_test
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
name: test-mysql8
|
||||
depends_on:
|
||||
- test-mysql
|
||||
- test-sqlite
|
||||
steps:
|
||||
- name: restore-cache
|
||||
image: meltwater/drone-cache
|
||||
pull: always
|
||||
settings:
|
||||
backend: "filesystem"
|
||||
restore: true
|
||||
cache_key: '{{ .Repo.Name }}_{{ checksum "go.mod" }}_{{ checksum "go.sum" }}_{{ arch }}_{{ os }}'
|
||||
archive_format: "gzip"
|
||||
filesystem_cache_root: "/go"
|
||||
mount:
|
||||
- pkg.mod
|
||||
- pkg.build
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /go
|
||||
|
||||
- name: test-mysql8
|
||||
image: golang:1.15
|
||||
environment:
|
||||
GO111MODULE: "on"
|
||||
GOPROXY: "https://goproxy.io"
|
||||
CGO_ENABLED: 1
|
||||
GOMODCACHE: '/drone/src/pkg.mod'
|
||||
GOCACHE: '/drone/src/pkg.build'
|
||||
TEST_MYSQL_HOST: mysql8
|
||||
TEST_MYSQL_CHARSET: utf8mb4
|
||||
TEST_MYSQL_DBNAME: xorm_test
|
||||
|
@ -63,58 +293,70 @@ steps:
|
|||
- make test-mysql
|
||||
- TEST_CACHE_ENABLE=true make test-mysql
|
||||
- TEST_QUOTE_POLICY=reserved make test-mysql
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /go
|
||||
|
||||
- name: test-mysql-utf8mb4
|
||||
image: golang:1.12
|
||||
- name: rebuild-cache
|
||||
image: meltwater/drone-cache:dev
|
||||
pull: true
|
||||
depends_on:
|
||||
- test-mysql
|
||||
environment:
|
||||
GO111MODULE: "on"
|
||||
GOPROXY: "https://goproxy.cn"
|
||||
TEST_MYSQL_HOST: mysql
|
||||
TEST_MYSQL_CHARSET: utf8mb4
|
||||
TEST_MYSQL_DBNAME: xorm_test
|
||||
TEST_MYSQL_USERNAME: root
|
||||
TEST_MYSQL_PASSWORD:
|
||||
commands:
|
||||
- make test-mysql
|
||||
- TEST_CACHE_ENABLE=true make test-mysql
|
||||
- TEST_QUOTE_POLICY=reserved make test-mysql
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
- test-mysql8
|
||||
settings:
|
||||
backend: "filesystem"
|
||||
rebuild: true
|
||||
cache_key: '{{ .Repo.Name }}_{{ checksum "go.mod" }}_{{ checksum "go.sum" }}_{{ arch }}_{{ os }}'
|
||||
archive_format: "gzip"
|
||||
filesystem_cache_root: "/go"
|
||||
mount:
|
||||
- pkg.mod
|
||||
- pkg.build
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /go
|
||||
|
||||
- name: test-mymysql
|
||||
volumes:
|
||||
- name: cache
|
||||
temp: {}
|
||||
|
||||
services:
|
||||
- name: mysql8
|
||||
pull: default
|
||||
image: golang:1.12
|
||||
depends_on:
|
||||
- test-mysql-utf8mb4
|
||||
image: mysql:8.0
|
||||
environment:
|
||||
GO111MODULE: "on"
|
||||
GOPROXY: "https://goproxy.cn"
|
||||
TEST_MYSQL_HOST: mysql:3306
|
||||
TEST_MYSQL_DBNAME: xorm_test
|
||||
TEST_MYSQL_USERNAME: root
|
||||
TEST_MYSQL_PASSWORD:
|
||||
commands:
|
||||
- make test-mymysql
|
||||
- TEST_CACHE_ENABLE=true make test-mymysql
|
||||
- TEST_QUOTE_POLICY=reserved make test-mymysql
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
MYSQL_ALLOW_EMPTY_PASSWORD: yes
|
||||
MYSQL_DATABASE: xorm_test
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
name: test-mariadb
|
||||
depends_on:
|
||||
- test-mysql8
|
||||
steps:
|
||||
- name: restore-cache
|
||||
image: meltwater/drone-cache
|
||||
pull: always
|
||||
settings:
|
||||
backend: "filesystem"
|
||||
restore: true
|
||||
cache_key: '{{ .Repo.Name }}_{{ checksum "go.mod" }}_{{ checksum "go.sum" }}_{{ arch }}_{{ os }}'
|
||||
archive_format: "gzip"
|
||||
filesystem_cache_root: "/go"
|
||||
mount:
|
||||
- pkg.mod
|
||||
- pkg.build
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /go
|
||||
|
||||
- name: test-mariadb
|
||||
image: golang:1.12
|
||||
image: golang:1.15
|
||||
environment:
|
||||
GO111MODULE: "on"
|
||||
GOPROXY: "https://goproxy.cn"
|
||||
GOPROXY: "https://goproxy.io"
|
||||
CGO_ENABLED: 1
|
||||
GOMODCACHE: '/drone/src/pkg.mod'
|
||||
GOCACHE: '/drone/src/pkg.build'
|
||||
TEST_MYSQL_HOST: mariadb
|
||||
TEST_MYSQL_CHARSET: utf8mb4
|
||||
TEST_MYSQL_DBNAME: xorm_test
|
||||
|
@ -124,17 +366,71 @@ steps:
|
|||
- make test-mysql
|
||||
- TEST_CACHE_ENABLE=true make test-mysql
|
||||
- TEST_QUOTE_POLICY=reserved make test-mysql
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /go
|
||||
|
||||
- name: rebuild-cache
|
||||
image: meltwater/drone-cache:dev
|
||||
depends_on:
|
||||
- test-mariadb
|
||||
pull: true
|
||||
settings:
|
||||
backend: "filesystem"
|
||||
rebuild: true
|
||||
cache_key: '{{ .Repo.Name }}_{{ checksum "go.mod" }}_{{ checksum "go.sum" }}_{{ arch }}_{{ os }}'
|
||||
archive_format: "gzip"
|
||||
filesystem_cache_root: "/go"
|
||||
mount:
|
||||
- pkg.mod
|
||||
- pkg.build
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /go
|
||||
|
||||
volumes:
|
||||
- name: cache
|
||||
temp: {}
|
||||
|
||||
services:
|
||||
- name: mariadb
|
||||
pull: default
|
||||
image: mariadb:10.4
|
||||
environment:
|
||||
MYSQL_ALLOW_EMPTY_PASSWORD: yes
|
||||
MYSQL_DATABASE: xorm_test
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
name: test-postgres
|
||||
depends_on:
|
||||
- test-mariadb
|
||||
steps:
|
||||
- name: restore-cache
|
||||
image: meltwater/drone-cache
|
||||
pull: always
|
||||
settings:
|
||||
backend: "filesystem"
|
||||
restore: true
|
||||
cache_key: '{{ .Repo.Name }}_{{ checksum "go.mod" }}_{{ checksum "go.sum" }}_{{ arch }}_{{ os }}'
|
||||
archive_format: "gzip"
|
||||
filesystem_cache_root: "/go"
|
||||
mount:
|
||||
- pkg.mod
|
||||
- pkg.build
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /go
|
||||
|
||||
- name: test-postgres
|
||||
pull: default
|
||||
image: golang:1.12
|
||||
image: golang:1.15
|
||||
environment:
|
||||
GO111MODULE: "on"
|
||||
GOPROXY: "https://goproxy.cn"
|
||||
GOPROXY: "https://goproxy.io"
|
||||
CGO_ENABLED: 1
|
||||
GOMODCACHE: '/drone/src/pkg.mod'
|
||||
GOCACHE: '/drone/src/pkg.build'
|
||||
TEST_PGSQL_HOST: pgsql
|
||||
TEST_PGSQL_DBNAME: xorm_test
|
||||
TEST_PGSQL_USERNAME: postgres
|
||||
|
@ -143,19 +439,21 @@ steps:
|
|||
- make test-postgres
|
||||
- TEST_CACHE_ENABLE=true make test-postgres
|
||||
- TEST_QUOTE_POLICY=reserved make test-postgres
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /go
|
||||
|
||||
- name: test-postgres-schema
|
||||
pull: default
|
||||
image: golang:1.12
|
||||
image: golang:1.15
|
||||
depends_on:
|
||||
- test-postgres
|
||||
environment:
|
||||
GO111MODULE: "on"
|
||||
GOPROXY: "https://goproxy.cn"
|
||||
GOPROXY: "https://goproxy.io"
|
||||
CGO_ENABLED: 1
|
||||
GOMODCACHE: '/drone/src/pkg.mod'
|
||||
GOCACHE: '/drone/src/pkg.build'
|
||||
TEST_PGSQL_HOST: pgsql
|
||||
TEST_PGSQL_SCHEMA: xorm
|
||||
TEST_PGSQL_DBNAME: xorm_test
|
||||
|
@ -165,17 +463,72 @@ steps:
|
|||
- make test-postgres
|
||||
- TEST_CACHE_ENABLE=true make test-postgres
|
||||
- TEST_QUOTE_POLICY=reserved make test-postgres
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /go
|
||||
|
||||
- name: rebuild-cache
|
||||
image: meltwater/drone-cache:dev
|
||||
pull: true
|
||||
depends_on:
|
||||
- test-postgres-schema
|
||||
settings:
|
||||
backend: "filesystem"
|
||||
rebuild: true
|
||||
cache_key: '{{ .Repo.Name }}_{{ checksum "go.mod" }}_{{ checksum "go.sum" }}_{{ arch }}_{{ os }}'
|
||||
archive_format: "gzip"
|
||||
filesystem_cache_root: "/go"
|
||||
mount:
|
||||
- pkg.mod
|
||||
- pkg.build
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /go
|
||||
|
||||
volumes:
|
||||
- name: cache
|
||||
temp: {}
|
||||
|
||||
services:
|
||||
- name: pgsql
|
||||
pull: default
|
||||
image: postgres:9.5
|
||||
environment:
|
||||
POSTGRES_DB: xorm_test
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
name: test-mssql
|
||||
depends_on:
|
||||
- test-postgres
|
||||
steps:
|
||||
- name: restore-cache
|
||||
image: meltwater/drone-cache
|
||||
pull: always
|
||||
settings:
|
||||
backend: "filesystem"
|
||||
restore: true
|
||||
cache_key: '{{ .Repo.Name }}_{{ checksum "go.mod" }}_{{ checksum "go.sum" }}_{{ arch }}_{{ os }}'
|
||||
archive_format: "gzip"
|
||||
filesystem_cache_root: "/go"
|
||||
mount:
|
||||
- pkg.mod
|
||||
- pkg.build
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /go
|
||||
|
||||
- name: test-mssql
|
||||
pull: default
|
||||
image: golang:1.12
|
||||
image: golang:1.15
|
||||
environment:
|
||||
GO111MODULE: "on"
|
||||
GOPROXY: "https://goproxy.cn"
|
||||
GOPROXY: "https://goproxy.io"
|
||||
CGO_ENABLED: 1
|
||||
GOMODCACHE: '/drone/src/pkg.mod'
|
||||
GOCACHE: '/drone/src/pkg.build'
|
||||
TEST_MSSQL_HOST: mssql
|
||||
TEST_MSSQL_DBNAME: xorm_test
|
||||
TEST_MSSQL_USERNAME: sa
|
||||
|
@ -185,17 +538,70 @@ steps:
|
|||
- TEST_CACHE_ENABLE=true make test-mssql
|
||||
- TEST_QUOTE_POLICY=reserved make test-mssql
|
||||
- TEST_MSSQL_DEFAULT_VARCHAR=NVARCHAR TEST_MSSQL_DEFAULT_CHAR=NCHAR make test-mssql
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /go
|
||||
|
||||
- name: rebuild-cache
|
||||
image: meltwater/drone-cache:dev
|
||||
pull: true
|
||||
settings:
|
||||
backend: "filesystem"
|
||||
rebuild: true
|
||||
cache_key: '{{ .Repo.Name }}_{{ checksum "go.mod" }}_{{ checksum "go.sum" }}_{{ arch }}_{{ os }}'
|
||||
archive_format: "gzip"
|
||||
filesystem_cache_root: "/go"
|
||||
mount:
|
||||
- pkg.mod
|
||||
- pkg.build
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /go
|
||||
|
||||
volumes:
|
||||
- name: cache
|
||||
temp: {}
|
||||
|
||||
services:
|
||||
- name: mssql
|
||||
pull: default
|
||||
image: microsoft/mssql-server-linux:latest
|
||||
environment:
|
||||
ACCEPT_EULA: Y
|
||||
SA_PASSWORD: yourStrong(!)Password
|
||||
MSSQL_PID: Developer
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
name: test-tidb
|
||||
depends_on:
|
||||
- test-mssql
|
||||
steps:
|
||||
- name: restore-cache
|
||||
image: meltwater/drone-cache
|
||||
pull: always
|
||||
settings:
|
||||
backend: "filesystem"
|
||||
restore: true
|
||||
cache_key: '{{ .Repo.Name }}_{{ checksum "go.mod" }}_{{ checksum "go.sum" }}_{{ arch }}_{{ os }}'
|
||||
archive_format: "gzip"
|
||||
filesystem_cache_root: "/go"
|
||||
mount:
|
||||
- pkg.mod
|
||||
- pkg.build
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /go
|
||||
|
||||
- name: test-tidb
|
||||
pull: default
|
||||
image: golang:1.12
|
||||
image: golang:1.15
|
||||
environment:
|
||||
GO111MODULE: "on"
|
||||
GOPROXY: "https://goproxy.cn"
|
||||
GOPROXY: "https://goproxy.io"
|
||||
CGO_ENABLED: 1
|
||||
GOMODCACHE: '/drone/src/pkg.mod'
|
||||
GOCACHE: '/drone/src/pkg.build'
|
||||
TEST_TIDB_HOST: "tidb:4000"
|
||||
TEST_TIDB_DBNAME: xorm_test
|
||||
TEST_TIDB_USERNAME: root
|
||||
|
@ -204,17 +610,66 @@ steps:
|
|||
- make test-tidb
|
||||
- TEST_CACHE_ENABLE=true make test-tidb
|
||||
- TEST_QUOTE_POLICY=reserved make test-tidb
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /go
|
||||
|
||||
- name: rebuild-cache
|
||||
image: meltwater/drone-cache:dev
|
||||
pull: true
|
||||
settings:
|
||||
backend: "filesystem"
|
||||
rebuild: true
|
||||
cache_key: '{{ .Repo.Name }}_{{ checksum "go.mod" }}_{{ checksum "go.sum" }}_{{ arch }}_{{ os }}'
|
||||
archive_format: "gzip"
|
||||
filesystem_cache_root: "/go"
|
||||
mount:
|
||||
- pkg.mod
|
||||
- pkg.build
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /go
|
||||
|
||||
volumes:
|
||||
- name: cache
|
||||
temp: {}
|
||||
|
||||
services:
|
||||
- name: tidb
|
||||
pull: default
|
||||
image: pingcap/tidb:v3.0.3
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
name: test-cockroach
|
||||
depends_on:
|
||||
- test-tidb
|
||||
steps:
|
||||
- name: restore-cache
|
||||
image: meltwater/drone-cache
|
||||
pull: always
|
||||
settings:
|
||||
backend: "filesystem"
|
||||
restore: true
|
||||
cache_key: '{{ .Repo.Name }}_{{ checksum "go.mod" }}_{{ checksum "go.sum" }}_{{ arch }}_{{ os }}'
|
||||
archive_format: "gzip"
|
||||
filesystem_cache_root: "/go"
|
||||
mount:
|
||||
- pkg.mod
|
||||
- pkg.build
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /go
|
||||
|
||||
- name: test-cockroach
|
||||
pull: default
|
||||
image: golang:1.13
|
||||
image: golang:1.15
|
||||
environment:
|
||||
GO111MODULE: "on"
|
||||
GOPROXY: "https://goproxy.cn"
|
||||
GOPROXY: "https://goproxy.io"
|
||||
CGO_ENABLED: 1
|
||||
GOMODCACHE: '/drone/src/pkg.mod'
|
||||
GOCACHE: '/drone/src/pkg.build'
|
||||
TEST_COCKROACH_HOST: "cockroach:26257"
|
||||
TEST_COCKROACH_DBNAME: xorm_test
|
||||
TEST_COCKROACH_USERNAME: root
|
||||
|
@ -223,115 +678,62 @@ steps:
|
|||
- sleep 10
|
||||
- make test-cockroach
|
||||
- TEST_CACHE_ENABLE=true make test-cockroach
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /go
|
||||
|
||||
- name: merge_coverage
|
||||
pull: default
|
||||
image: golang:1.12
|
||||
environment:
|
||||
GO111MODULE: "on"
|
||||
GOPROXY: "https://goproxy.cn"
|
||||
depends_on:
|
||||
- test-vet
|
||||
- test-sqlite
|
||||
- test-mysql
|
||||
- test-mysql8
|
||||
- test-mymysql
|
||||
- test-postgres
|
||||
- test-postgres-schema
|
||||
- test-mssql
|
||||
- test-tidb
|
||||
- test-cockroach
|
||||
commands:
|
||||
- make coverage
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
- name: rebuild-cache
|
||||
image: meltwater/drone-cache:dev
|
||||
pull: true
|
||||
settings:
|
||||
backend: "filesystem"
|
||||
rebuild: true
|
||||
cache_key: '{{ .Repo.Name }}_{{ checksum "go.mod" }}_{{ checksum "go.sum" }}_{{ arch }}_{{ os }}'
|
||||
archive_format: "gzip"
|
||||
filesystem_cache_root: "/go"
|
||||
mount:
|
||||
- pkg.mod
|
||||
- pkg.build
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /go
|
||||
|
||||
volumes:
|
||||
- name: cache
|
||||
temp: {}
|
||||
|
||||
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: mysql8
|
||||
pull: default
|
||||
image: mysql:8.0
|
||||
environment:
|
||||
MYSQL_ALLOW_EMPTY_PASSWORD: yes
|
||||
MYSQL_DATABASE: xorm_test
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- tag
|
||||
- pull_request
|
||||
|
||||
- name: mariadb
|
||||
pull: default
|
||||
image: mariadb:10.4
|
||||
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
|
||||
POSTGRES_PASSWORD: postgres
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- tag
|
||||
- pull_request
|
||||
|
||||
- name: mssql
|
||||
pull: default
|
||||
image: microsoft/mssql-server-linux:latest
|
||||
environment:
|
||||
ACCEPT_EULA: Y
|
||||
SA_PASSWORD: yourStrong(!)Password
|
||||
MSSQL_PID: Developer
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- tag
|
||||
- pull_request
|
||||
|
||||
- name: tidb
|
||||
pull: default
|
||||
image: pingcap/tidb:v3.0.3
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- tag
|
||||
- pull_request
|
||||
|
||||
- name: cockroach
|
||||
pull: default
|
||||
image: cockroachdb/cockroach:v19.2.4
|
||||
commands:
|
||||
- /cockroach/cockroach start --insecure
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
name: merge_coverage
|
||||
depends_on:
|
||||
- testing
|
||||
- test-sqlite
|
||||
- test-mysql
|
||||
- test-mysql8
|
||||
- test-mariadb
|
||||
- test-postgres
|
||||
- test-mssql
|
||||
- test-tidb
|
||||
- test-cockroach
|
||||
steps:
|
||||
- name: merge_coverage
|
||||
pull: default
|
||||
image: golang:1.15
|
||||
environment:
|
||||
GO111MODULE: "on"
|
||||
GOPROXY: "https://goproxy.io"
|
||||
commands:
|
||||
- make coverage
|
||||
when:
|
||||
branch:
|
||||
- master
|
||||
event:
|
||||
- push
|
||||
- tag
|
||||
- pull_request
|
||||
- push
|
||||
- pull_request
|
||||
|
|
|
@ -36,3 +36,4 @@ test.db.sql
|
|||
*coverage.out
|
||||
test.db
|
||||
integrations/*.sql
|
||||
integrations/test_sqlite*
|
|
@ -15,6 +15,7 @@ warningCode = 1
|
|||
[rule.if-return]
|
||||
[rule.increment-decrement]
|
||||
[rule.var-naming]
|
||||
arguments = [["ID", "UID", "UUID", "URL", "JSON"], []]
|
||||
[rule.var-declaration]
|
||||
[rule.package-comments]
|
||||
[rule.range]
|
||||
|
@ -22,4 +23,5 @@ warningCode = 1
|
|||
[rule.time-naming]
|
||||
[rule.unexported-return]
|
||||
[rule.indent-error-flow]
|
||||
[rule.errorf]
|
||||
[rule.errorf]
|
||||
[rule.struct-tag]
|
|
@ -3,6 +3,21 @@
|
|||
This changelog goes through all the changes that have been made in each release
|
||||
without substantial changes to our git log.
|
||||
|
||||
## [1.1.0](https://gitea.com/xorm/xorm/releases/tag/1.1.0) - 2021-05-14
|
||||
|
||||
* FEATURES
|
||||
* Unsigned Support for mysql (#1889)
|
||||
* Support modernc.org/sqlite (#1850)
|
||||
* TESTING
|
||||
* More tests (#1890)
|
||||
* MISC
|
||||
* Byte strings in postgres aren't 0x... (#1906)
|
||||
* Fix another bug with #1872 (#1905)
|
||||
* Fix two issues with dumptables (#1903)
|
||||
* Fix comments (#1896)
|
||||
* Fix comments (#1893)
|
||||
* MariaDB 10.5 adds a suffix on old datatypes (#1885)
|
||||
|
||||
## [1.0.7](https://gitea.com/xorm/xorm/pulls?q=&type=all&state=closed&milestone=1336) - 2021-01-21
|
||||
|
||||
* BUGFIXES
|
||||
|
|
|
@ -6,7 +6,9 @@ GOFMT ?= gofmt -s
|
|||
TAGS ?=
|
||||
SED_INPLACE := sed -i
|
||||
|
||||
GOFILES := $(shell find . -name "*.go" -type f)
|
||||
GO_DIRS := caches contexts integrations convert core dialects internal log migrate names schemas tags
|
||||
GOFILES := $(wildcard *.go)
|
||||
GOFILES += $(shell find $(GO_DIRS) -name "*.go" -type f)
|
||||
INTEGRATION_PACKAGES := xorm.io/xorm/integrations
|
||||
PACKAGES ?= $(filter-out $(INTEGRATION_PACKAGES),$(shell $(GO) list ./...))
|
||||
|
||||
|
@ -99,7 +101,8 @@ help:
|
|||
@echo " - test-mysql run integration tests for mysql"
|
||||
@echo " - test-mssql run integration tests for mssql"
|
||||
@echo " - test-postgres run integration tests for postgres"
|
||||
@echo " - test-sqlite run integration tests for sqlite"
|
||||
@echo " - test-sqlite3 run integration tests for sqlite"
|
||||
@echo " - test-sqlite run integration tests for pure go sqlite"
|
||||
@echo " - test-tidb run integration tests for tidb"
|
||||
@echo " - vet examines Go source code and reports suspicious constructs"
|
||||
|
||||
|
@ -195,21 +198,37 @@ test-postgres\#%: go-check
|
|||
-conn_str="postgres://$(TEST_PGSQL_USERNAME):$(TEST_PGSQL_PASSWORD)@$(TEST_PGSQL_HOST)/$(TEST_PGSQL_DBNAME)?sslmode=disable" \
|
||||
-quote=$(TEST_QUOTE_POLICY) -coverprofile=postgres.$(TEST_QUOTE_POLICY).$(TEST_CACHE_ENABLE).coverage.out -covermode=atomic
|
||||
|
||||
.PHONY: test-sqlite3
|
||||
test-sqlite3: go-check
|
||||
$(GO) test $(INTEGRATION_PACKAGES) -v -race -cache=$(TEST_CACHE_ENABLE) -db=sqlite3 -conn_str="./test.db?cache=shared&mode=rwc" \
|
||||
-quote=$(TEST_QUOTE_POLICY) -coverprofile=sqlite3.$(TEST_QUOTE_POLICY).$(TEST_CACHE_ENABLE).coverage.out -covermode=atomic
|
||||
|
||||
.PHONY: test-sqlite3-schema
|
||||
test-sqlite3-schema: go-check
|
||||
$(GO) test $(INTEGRATION_PACKAGES) -v -race -schema=xorm -cache=$(TEST_CACHE_ENABLE) -db=sqlite3 -conn_str="./test.db?cache=shared&mode=rwc" \
|
||||
-quote=$(TEST_QUOTE_POLICY) -coverprofile=sqlite3.$(TEST_QUOTE_POLICY).$(TEST_CACHE_ENABLE).coverage.out -covermode=atomic
|
||||
|
||||
.PHONY: test-sqlite3\#%
|
||||
test-sqlite3\#%: go-check
|
||||
$(GO) test $(INTEGRATION_PACKAGES) -v -race -run $* -cache=$(TEST_CACHE_ENABLE) -db=sqlite3 -conn_str="./test.db?cache=shared&mode=rwc" \
|
||||
-quote=$(TEST_QUOTE_POLICY) -coverprofile=sqlite3.$(TEST_QUOTE_POLICY).$(TEST_CACHE_ENABLE).coverage.out -covermode=atomic
|
||||
|
||||
.PHONY: test-sqlite
|
||||
test-sqlite: go-check
|
||||
$(GO) test $(INTEGRATION_PACKAGES) -v -race -cache=$(TEST_CACHE_ENABLE) -db=sqlite3 -conn_str="./test.db?cache=shared&mode=rwc" \
|
||||
$(GO) test $(INTEGRATION_PACKAGES) -v -race -cache=$(TEST_CACHE_ENABLE) -db=sqlite -conn_str="./test.db?cache=shared&mode=rwc" \
|
||||
-quote=$(TEST_QUOTE_POLICY) -coverprofile=sqlite.$(TEST_QUOTE_POLICY).$(TEST_CACHE_ENABLE).coverage.out -covermode=atomic
|
||||
|
||||
.PHONY: test-sqlite-schema
|
||||
test-sqlite-schema: go-check
|
||||
$(GO) test $(INTEGRATION_PACKAGES) -v -race -schema=xorm -cache=$(TEST_CACHE_ENABLE) -db=sqlite3 -conn_str="./test.db?cache=shared&mode=rwc" \
|
||||
$(GO) test $(INTEGRATION_PACKAGES) -v -race -schema=xorm -cache=$(TEST_CACHE_ENABLE) -db=sqlite -conn_str="./test.db?cache=shared&mode=rwc" \
|
||||
-quote=$(TEST_QUOTE_POLICY) -coverprofile=sqlite.$(TEST_QUOTE_POLICY).$(TEST_CACHE_ENABLE).coverage.out -covermode=atomic
|
||||
|
||||
.PHONY: test-sqlite\#%
|
||||
test-sqlite\#%: go-check
|
||||
$(GO) test $(INTEGRATION_PACKAGES) -v -race -run $* -cache=$(TEST_CACHE_ENABLE) -db=sqlite3 -conn_str="./test.db?cache=shared&mode=rwc" \
|
||||
$(GO) test $(INTEGRATION_PACKAGES) -v -race -run $* -cache=$(TEST_CACHE_ENABLE) -db=sqlite -conn_str="./test.db?cache=shared&mode=rwc" \
|
||||
-quote=$(TEST_QUOTE_POLICY) -coverprofile=sqlite.$(TEST_QUOTE_POLICY).$(TEST_CACHE_ENABLE).coverage.out -covermode=atomic
|
||||
|
||||
|
||||
.PNONY: test-tidb
|
||||
test-tidb: go-check
|
||||
$(GO) test $(INTEGRATION_PACKAGES) -v -race -db=mysql -cache=$(TEST_CACHE_ENABLE) -ignore_select_update=true \
|
||||
|
@ -224,4 +243,4 @@ test-tidb\#%: go-check
|
|||
|
||||
.PHONY: vet
|
||||
vet:
|
||||
$(GO) vet $(shell $(GO) list ./...)
|
||||
$(GO) vet $(shell $(GO) list ./...)
|
||||
|
|
|
@ -13,22 +13,26 @@ import (
|
|||
"io"
|
||||
)
|
||||
|
||||
// md5 hash string
|
||||
// Md5 return md5 hash string
|
||||
func Md5(str string) string {
|
||||
m := md5.New()
|
||||
io.WriteString(m, str)
|
||||
return fmt.Sprintf("%x", m.Sum(nil))
|
||||
}
|
||||
|
||||
// Encode Encode data
|
||||
func Encode(data interface{}) ([]byte, error) {
|
||||
//return JsonEncode(data)
|
||||
return GobEncode(data)
|
||||
}
|
||||
|
||||
// Decode decode data
|
||||
func Decode(data []byte, to interface{}) error {
|
||||
//return JsonDecode(data, to)
|
||||
return GobDecode(data, to)
|
||||
}
|
||||
|
||||
// GobEncode encode data with gob
|
||||
func GobEncode(data interface{}) ([]byte, error) {
|
||||
var buf bytes.Buffer
|
||||
enc := gob.NewEncoder(&buf)
|
||||
|
@ -39,12 +43,14 @@ func GobEncode(data interface{}) ([]byte, error) {
|
|||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
// GobDecode decode data with gob
|
||||
func GobDecode(data []byte, to interface{}) error {
|
||||
buf := bytes.NewBuffer(data)
|
||||
dec := gob.NewDecoder(buf)
|
||||
return dec.Decode(to)
|
||||
}
|
||||
|
||||
// JsonEncode encode data with json
|
||||
func JsonEncode(data interface{}) ([]byte, error) {
|
||||
val, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
|
@ -53,6 +59,7 @@ func JsonEncode(data interface{}) ([]byte, error) {
|
|||
return val, nil
|
||||
}
|
||||
|
||||
// JsonDecode decode data with json
|
||||
func JsonDecode(data []byte, to interface{}) error {
|
||||
return json.Unmarshal(data, to)
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ type LevelDBStore struct {
|
|||
|
||||
var _ CacheStore = &LevelDBStore{}
|
||||
|
||||
// NewLevelDBStore creates a leveldb store
|
||||
func NewLevelDBStore(dbfile string) (*LevelDBStore, error) {
|
||||
db := &LevelDBStore{}
|
||||
h, err := leveldb.OpenFile(dbfile, nil)
|
||||
|
@ -29,6 +30,7 @@ func NewLevelDBStore(dbfile string) (*LevelDBStore, error) {
|
|||
return db, nil
|
||||
}
|
||||
|
||||
// Put implements CacheStore
|
||||
func (s *LevelDBStore) Put(key string, value interface{}) error {
|
||||
val, err := Encode(value)
|
||||
if err != nil {
|
||||
|
@ -50,6 +52,7 @@ func (s *LevelDBStore) Put(key string, value interface{}) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// Get implements CacheStore
|
||||
func (s *LevelDBStore) Get(key string) (interface{}, error) {
|
||||
data, err := s.store.Get([]byte(key), nil)
|
||||
if err != nil {
|
||||
|
@ -75,6 +78,7 @@ func (s *LevelDBStore) Get(key string) (interface{}, error) {
|
|||
return s.v, err
|
||||
}
|
||||
|
||||
// Del implements CacheStore
|
||||
func (s *LevelDBStore) Del(key string) error {
|
||||
err := s.store.Delete([]byte(key), nil)
|
||||
if err != nil {
|
||||
|
@ -89,6 +93,7 @@ func (s *LevelDBStore) Del(key string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// Close implements CacheStore
|
||||
func (s *LevelDBStore) Close() {
|
||||
s.store.Close()
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ package caches
|
|||
|
||||
import "sync"
|
||||
|
||||
// Manager represents a cache manager
|
||||
type Manager struct {
|
||||
cacher Cacher
|
||||
disableGlobalCache bool
|
||||
|
@ -14,6 +15,7 @@ type Manager struct {
|
|||
cacherLock sync.RWMutex
|
||||
}
|
||||
|
||||
// NewManager creates a cache manager
|
||||
func NewManager() *Manager {
|
||||
return &Manager{
|
||||
cachers: make(map[string]Cacher),
|
||||
|
@ -27,12 +29,14 @@ func (mgr *Manager) SetDisableGlobalCache(disable bool) {
|
|||
}
|
||||
}
|
||||
|
||||
// SetCacher set cacher of table
|
||||
func (mgr *Manager) SetCacher(tableName string, cacher Cacher) {
|
||||
mgr.cacherLock.Lock()
|
||||
mgr.cachers[tableName] = cacher
|
||||
mgr.cacherLock.Unlock()
|
||||
}
|
||||
|
||||
// GetCacher returns a cache of a table
|
||||
func (mgr *Manager) GetCacher(tableName string) Cacher {
|
||||
var cacher Cacher
|
||||
var ok bool
|
||||
|
|
|
@ -31,6 +31,7 @@ func NewContextHook(ctx context.Context, sql string, args []interface{}) *Contex
|
|||
}
|
||||
}
|
||||
|
||||
// End finish the hook invokation
|
||||
func (c *ContextHook) End(ctx context.Context, result sql.Result, err error) {
|
||||
c.Ctx = ctx
|
||||
c.Result = result
|
||||
|
@ -38,19 +39,23 @@ func (c *ContextHook) End(ctx context.Context, result sql.Result, err error) {
|
|||
c.ExecuteTime = time.Now().Sub(c.start)
|
||||
}
|
||||
|
||||
// Hook represents a hook behaviour
|
||||
type Hook interface {
|
||||
BeforeProcess(c *ContextHook) (context.Context, error)
|
||||
AfterProcess(c *ContextHook) error
|
||||
}
|
||||
|
||||
// Hooks implements Hook interface but contains multiple Hook
|
||||
type Hooks struct {
|
||||
hooks []Hook
|
||||
}
|
||||
|
||||
// AddHook adds a Hook
|
||||
func (h *Hooks) AddHook(hooks ...Hook) {
|
||||
h.hooks = append(h.hooks, hooks...)
|
||||
}
|
||||
|
||||
// BeforeProcess invoked before execute the process
|
||||
func (h *Hooks) BeforeProcess(c *ContextHook) (context.Context, error) {
|
||||
ctx := c.Ctx
|
||||
for _, h := range h.hooks {
|
||||
|
@ -63,6 +68,7 @@ func (h *Hooks) BeforeProcess(c *ContextHook) (context.Context, error) {
|
|||
return ctx, nil
|
||||
}
|
||||
|
||||
// AfterProcess invoked after exetue the process
|
||||
func (h *Hooks) AfterProcess(c *ContextHook) error {
|
||||
firstErr := c.Err
|
||||
for _, h := range h.hooks {
|
||||
|
|
|
@ -23,6 +23,7 @@ var (
|
|||
DefaultCacheSize = 200
|
||||
)
|
||||
|
||||
// MapToSlice map query and struct as sql and args
|
||||
func MapToSlice(query string, mp interface{}) (string, []interface{}, error) {
|
||||
vv := reflect.ValueOf(mp)
|
||||
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Map {
|
||||
|
@ -44,6 +45,7 @@ func MapToSlice(query string, mp interface{}) (string, []interface{}, error) {
|
|||
return query, args, err
|
||||
}
|
||||
|
||||
// StructToSlice converts a query and struct as sql and args
|
||||
func StructToSlice(query string, st interface{}) (string, []interface{}, error) {
|
||||
vv := reflect.ValueOf(st)
|
||||
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct {
|
||||
|
@ -176,6 +178,7 @@ func (db *DB) QueryMap(query string, mp interface{}) (*Rows, error) {
|
|||
return db.QueryMapContext(context.Background(), query, mp)
|
||||
}
|
||||
|
||||
// QueryStructContext query rows with struct
|
||||
func (db *DB) QueryStructContext(ctx context.Context, query string, st interface{}) (*Rows, error) {
|
||||
query, args, err := StructToSlice(query, st)
|
||||
if err != nil {
|
||||
|
@ -184,10 +187,12 @@ func (db *DB) QueryStructContext(ctx context.Context, query string, st interface
|
|||
return db.QueryContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
// QueryStruct query rows with struct
|
||||
func (db *DB) QueryStruct(query string, st interface{}) (*Rows, error) {
|
||||
return db.QueryStructContext(context.Background(), query, st)
|
||||
}
|
||||
|
||||
// QueryRowContext query row with args
|
||||
func (db *DB) QueryRowContext(ctx context.Context, query string, args ...interface{}) *Row {
|
||||
rows, err := db.QueryContext(ctx, query, args...)
|
||||
if err != nil {
|
||||
|
@ -196,10 +201,12 @@ func (db *DB) QueryRowContext(ctx context.Context, query string, args ...interfa
|
|||
return &Row{rows, nil}
|
||||
}
|
||||
|
||||
// QueryRow query row with args
|
||||
func (db *DB) QueryRow(query string, args ...interface{}) *Row {
|
||||
return db.QueryRowContext(context.Background(), query, args...)
|
||||
}
|
||||
|
||||
// QueryRowMapContext query row with map
|
||||
func (db *DB) QueryRowMapContext(ctx context.Context, query string, mp interface{}) *Row {
|
||||
query, args, err := MapToSlice(query, mp)
|
||||
if err != nil {
|
||||
|
@ -208,10 +215,12 @@ func (db *DB) QueryRowMapContext(ctx context.Context, query string, mp interface
|
|||
return db.QueryRowContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
// QueryRowMap query row with map
|
||||
func (db *DB) QueryRowMap(query string, mp interface{}) *Row {
|
||||
return db.QueryRowMapContext(context.Background(), query, mp)
|
||||
}
|
||||
|
||||
// QueryRowStructContext query row with struct
|
||||
func (db *DB) QueryRowStructContext(ctx context.Context, query string, st interface{}) *Row {
|
||||
query, args, err := StructToSlice(query, st)
|
||||
if err != nil {
|
||||
|
@ -220,6 +229,7 @@ func (db *DB) QueryRowStructContext(ctx context.Context, query string, st interf
|
|||
return db.QueryRowContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
// QueryRowStruct query row with struct
|
||||
func (db *DB) QueryRowStruct(query string, st interface{}) *Row {
|
||||
return db.QueryRowStructContext(context.Background(), query, st)
|
||||
}
|
||||
|
@ -239,10 +249,12 @@ func (db *DB) ExecMapContext(ctx context.Context, query string, mp interface{})
|
|||
return db.ExecContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
// ExecMap exec query with map
|
||||
func (db *DB) ExecMap(query string, mp interface{}) (sql.Result, error) {
|
||||
return db.ExecMapContext(context.Background(), query, mp)
|
||||
}
|
||||
|
||||
// ExecStructContext exec query with map
|
||||
func (db *DB) ExecStructContext(ctx context.Context, query string, st interface{}) (sql.Result, error) {
|
||||
query, args, err := StructToSlice(query, st)
|
||||
if err != nil {
|
||||
|
@ -251,6 +263,7 @@ func (db *DB) ExecStructContext(ctx context.Context, query string, st interface{
|
|||
return db.ExecContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
// ExecContext exec query with args
|
||||
func (db *DB) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error) {
|
||||
hookCtx := contexts.NewContextHook(ctx, query, args)
|
||||
ctx, err := db.beforeProcess(hookCtx)
|
||||
|
@ -265,6 +278,7 @@ func (db *DB) ExecContext(ctx context.Context, query string, args ...interface{}
|
|||
return res, nil
|
||||
}
|
||||
|
||||
// ExecStruct exec query with struct
|
||||
func (db *DB) ExecStruct(query string, st interface{}) (sql.Result, error) {
|
||||
return db.ExecStructContext(context.Background(), query, st)
|
||||
}
|
||||
|
@ -288,6 +302,7 @@ func (db *DB) afterProcess(c *contexts.ContextHook) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// AddHook adds hook
|
||||
func (db *DB) AddHook(h ...contexts.Hook) {
|
||||
db.hooks.AddHook(h...)
|
||||
}
|
||||
|
|
|
@ -11,11 +11,13 @@ import (
|
|||
"sync"
|
||||
)
|
||||
|
||||
// Rows represents rows of table
|
||||
type Rows struct {
|
||||
*sql.Rows
|
||||
db *DB
|
||||
}
|
||||
|
||||
// ToMapString returns all records
|
||||
func (rs *Rows) ToMapString() ([]map[string]string, error) {
|
||||
cols, err := rs.Columns()
|
||||
if err != nil {
|
||||
|
@ -34,7 +36,7 @@ func (rs *Rows) ToMapString() ([]map[string]string, error) {
|
|||
return results, nil
|
||||
}
|
||||
|
||||
// scan data to a struct's pointer according field index
|
||||
// ScanStructByIndex scan data to a struct's pointer according field index
|
||||
func (rs *Rows) ScanStructByIndex(dest ...interface{}) error {
|
||||
if len(dest) == 0 {
|
||||
return errors.New("at least one struct")
|
||||
|
@ -94,7 +96,7 @@ func fieldByName(v reflect.Value, name string) reflect.Value {
|
|||
return reflect.Zero(t)
|
||||
}
|
||||
|
||||
// scan data to a struct's pointer according field name
|
||||
// ScanStructByName scan data to a struct's pointer according field name
|
||||
func (rs *Rows) ScanStructByName(dest interface{}) error {
|
||||
vv := reflect.ValueOf(dest)
|
||||
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct {
|
||||
|
@ -120,7 +122,7 @@ func (rs *Rows) ScanStructByName(dest interface{}) error {
|
|||
return rs.Rows.Scan(newDest...)
|
||||
}
|
||||
|
||||
// scan data to a slice's pointer, slice's length should equal to columns' number
|
||||
// ScanSlice scan data to a slice's pointer, slice's length should equal to columns' number
|
||||
func (rs *Rows) ScanSlice(dest interface{}) error {
|
||||
vv := reflect.ValueOf(dest)
|
||||
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Slice {
|
||||
|
@ -155,7 +157,7 @@ func (rs *Rows) ScanSlice(dest interface{}) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// scan data to a map's pointer
|
||||
// ScanMap scan data to a map's pointer
|
||||
func (rs *Rows) ScanMap(dest interface{}) error {
|
||||
vv := reflect.ValueOf(dest)
|
||||
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Map {
|
||||
|
@ -187,6 +189,7 @@ func (rs *Rows) ScanMap(dest interface{}) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Row reprents a row of a tab
|
||||
type Row struct {
|
||||
rows *Rows
|
||||
// One of these two will be non-nil:
|
||||
|
@ -205,6 +208,7 @@ func NewRow(rows *Rows, err error) *Row {
|
|||
return &Row{rows, err}
|
||||
}
|
||||
|
||||
// Columns returns all columns of the row
|
||||
func (row *Row) Columns() ([]string, error) {
|
||||
if row.err != nil {
|
||||
return nil, row.err
|
||||
|
@ -212,6 +216,7 @@ func (row *Row) Columns() ([]string, error) {
|
|||
return row.rows.Columns()
|
||||
}
|
||||
|
||||
// Scan retrieves all row column values
|
||||
func (row *Row) Scan(dest ...interface{}) error {
|
||||
if row.err != nil {
|
||||
return row.err
|
||||
|
@ -238,6 +243,7 @@ func (row *Row) Scan(dest ...interface{}) error {
|
|||
return row.rows.Close()
|
||||
}
|
||||
|
||||
// ScanStructByName retrieves all row column values into a struct
|
||||
func (row *Row) ScanStructByName(dest interface{}) error {
|
||||
if row.err != nil {
|
||||
return row.err
|
||||
|
@ -258,6 +264,7 @@ func (row *Row) ScanStructByName(dest interface{}) error {
|
|||
return row.rows.Close()
|
||||
}
|
||||
|
||||
// ScanStructByIndex retrieves all row column values into a struct
|
||||
func (row *Row) ScanStructByIndex(dest interface{}) error {
|
||||
if row.err != nil {
|
||||
return row.err
|
||||
|
@ -278,7 +285,7 @@ func (row *Row) ScanStructByIndex(dest interface{}) error {
|
|||
return row.rows.Close()
|
||||
}
|
||||
|
||||
// scan data to a slice's pointer, slice's length should equal to columns' number
|
||||
// ScanSlice scan data to a slice's pointer, slice's length should equal to columns' number
|
||||
func (row *Row) ScanSlice(dest interface{}) error {
|
||||
if row.err != nil {
|
||||
return row.err
|
||||
|
@ -300,7 +307,7 @@ func (row *Row) ScanSlice(dest interface{}) error {
|
|||
return row.rows.Close()
|
||||
}
|
||||
|
||||
// scan data to a map's pointer
|
||||
// ScanMap scan data to a map's pointer
|
||||
func (row *Row) ScanMap(dest interface{}) error {
|
||||
if row.err != nil {
|
||||
return row.err
|
||||
|
@ -322,6 +329,7 @@ func (row *Row) ScanMap(dest interface{}) error {
|
|||
return row.rows.Close()
|
||||
}
|
||||
|
||||
// ToMapString returns all clumns of this record
|
||||
func (row *Row) ToMapString() (map[string]string, error) {
|
||||
cols, err := row.Columns()
|
||||
if err != nil {
|
||||
|
|
|
@ -10,12 +10,14 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// NullTime defines a customize type NullTime
|
||||
type NullTime time.Time
|
||||
|
||||
var (
|
||||
_ driver.Valuer = NullTime{}
|
||||
)
|
||||
|
||||
// Scan implements driver.Valuer
|
||||
func (ns *NullTime) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
return nil
|
||||
|
@ -58,9 +60,11 @@ func convertTime(dest *NullTime, src interface{}) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// EmptyScanner represents an empty scanner
|
||||
type EmptyScanner struct {
|
||||
}
|
||||
|
||||
// Scan implements
|
||||
func (EmptyScanner) Scan(src interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ type Stmt struct {
|
|||
query string
|
||||
}
|
||||
|
||||
// PrepareContext creates a prepare statement
|
||||
func (db *DB) PrepareContext(ctx context.Context, query string) (*Stmt, error) {
|
||||
names := make(map[string]int)
|
||||
var i int
|
||||
|
@ -42,10 +43,12 @@ func (db *DB) PrepareContext(ctx context.Context, query string) (*Stmt, error) {
|
|||
return &Stmt{stmt, db, names, query}, nil
|
||||
}
|
||||
|
||||
// Prepare creates a prepare statement
|
||||
func (db *DB) Prepare(query string) (*Stmt, error) {
|
||||
return db.PrepareContext(context.Background(), query)
|
||||
}
|
||||
|
||||
// ExecMapContext execute with map
|
||||
func (s *Stmt) ExecMapContext(ctx context.Context, mp interface{}) (sql.Result, error) {
|
||||
vv := reflect.ValueOf(mp)
|
||||
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Map {
|
||||
|
@ -59,10 +62,12 @@ func (s *Stmt) ExecMapContext(ctx context.Context, mp interface{}) (sql.Result,
|
|||
return s.ExecContext(ctx, args...)
|
||||
}
|
||||
|
||||
// ExecMap executes with map
|
||||
func (s *Stmt) ExecMap(mp interface{}) (sql.Result, error) {
|
||||
return s.ExecMapContext(context.Background(), mp)
|
||||
}
|
||||
|
||||
// ExecStructContext executes with struct
|
||||
func (s *Stmt) ExecStructContext(ctx context.Context, st interface{}) (sql.Result, error) {
|
||||
vv := reflect.ValueOf(st)
|
||||
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct {
|
||||
|
@ -76,10 +81,12 @@ func (s *Stmt) ExecStructContext(ctx context.Context, st interface{}) (sql.Resul
|
|||
return s.ExecContext(ctx, args...)
|
||||
}
|
||||
|
||||
// ExecStruct executes with struct
|
||||
func (s *Stmt) ExecStruct(st interface{}) (sql.Result, error) {
|
||||
return s.ExecStructContext(context.Background(), st)
|
||||
}
|
||||
|
||||
// ExecContext with args
|
||||
func (s *Stmt) ExecContext(ctx context.Context, args ...interface{}) (sql.Result, error) {
|
||||
hookCtx := contexts.NewContextHook(ctx, s.query, args)
|
||||
ctx, err := s.db.beforeProcess(hookCtx)
|
||||
|
@ -94,6 +101,7 @@ func (s *Stmt) ExecContext(ctx context.Context, args ...interface{}) (sql.Result
|
|||
return res, nil
|
||||
}
|
||||
|
||||
// QueryContext query with args
|
||||
func (s *Stmt) QueryContext(ctx context.Context, args ...interface{}) (*Rows, error) {
|
||||
hookCtx := contexts.NewContextHook(ctx, s.query, args)
|
||||
ctx, err := s.db.beforeProcess(hookCtx)
|
||||
|
@ -108,10 +116,12 @@ func (s *Stmt) QueryContext(ctx context.Context, args ...interface{}) (*Rows, er
|
|||
return &Rows{rows, s.db}, nil
|
||||
}
|
||||
|
||||
// Query query with args
|
||||
func (s *Stmt) Query(args ...interface{}) (*Rows, error) {
|
||||
return s.QueryContext(context.Background(), args...)
|
||||
}
|
||||
|
||||
// QueryMapContext query with map
|
||||
func (s *Stmt) QueryMapContext(ctx context.Context, mp interface{}) (*Rows, error) {
|
||||
vv := reflect.ValueOf(mp)
|
||||
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Map {
|
||||
|
@ -126,10 +136,12 @@ func (s *Stmt) QueryMapContext(ctx context.Context, mp interface{}) (*Rows, erro
|
|||
return s.QueryContext(ctx, args...)
|
||||
}
|
||||
|
||||
// QueryMap query with map
|
||||
func (s *Stmt) QueryMap(mp interface{}) (*Rows, error) {
|
||||
return s.QueryMapContext(context.Background(), mp)
|
||||
}
|
||||
|
||||
// QueryStructContext query with struct
|
||||
func (s *Stmt) QueryStructContext(ctx context.Context, st interface{}) (*Rows, error) {
|
||||
vv := reflect.ValueOf(st)
|
||||
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct {
|
||||
|
@ -144,19 +156,23 @@ func (s *Stmt) QueryStructContext(ctx context.Context, st interface{}) (*Rows, e
|
|||
return s.QueryContext(ctx, args...)
|
||||
}
|
||||
|
||||
// QueryStruct query with struct
|
||||
func (s *Stmt) QueryStruct(st interface{}) (*Rows, error) {
|
||||
return s.QueryStructContext(context.Background(), st)
|
||||
}
|
||||
|
||||
// QueryRowContext query row with args
|
||||
func (s *Stmt) QueryRowContext(ctx context.Context, args ...interface{}) *Row {
|
||||
rows, err := s.QueryContext(ctx, args...)
|
||||
return &Row{rows, err}
|
||||
}
|
||||
|
||||
// QueryRow query row with args
|
||||
func (s *Stmt) QueryRow(args ...interface{}) *Row {
|
||||
return s.QueryRowContext(context.Background(), args...)
|
||||
}
|
||||
|
||||
// QueryRowMapContext query row with map
|
||||
func (s *Stmt) QueryRowMapContext(ctx context.Context, mp interface{}) *Row {
|
||||
vv := reflect.ValueOf(mp)
|
||||
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Map {
|
||||
|
@ -171,10 +187,12 @@ func (s *Stmt) QueryRowMapContext(ctx context.Context, mp interface{}) *Row {
|
|||
return s.QueryRowContext(ctx, args...)
|
||||
}
|
||||
|
||||
// QueryRowMap query row with map
|
||||
func (s *Stmt) QueryRowMap(mp interface{}) *Row {
|
||||
return s.QueryRowMapContext(context.Background(), mp)
|
||||
}
|
||||
|
||||
// QueryRowStructContext query row with struct
|
||||
func (s *Stmt) QueryRowStructContext(ctx context.Context, st interface{}) *Row {
|
||||
vv := reflect.ValueOf(st)
|
||||
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct {
|
||||
|
@ -189,6 +207,7 @@ func (s *Stmt) QueryRowStructContext(ctx context.Context, st interface{}) *Row {
|
|||
return s.QueryRowContext(ctx, args...)
|
||||
}
|
||||
|
||||
// QueryRowStruct query row with struct
|
||||
func (s *Stmt) QueryRowStruct(st interface{}) *Row {
|
||||
return s.QueryRowStructContext(context.Background(), st)
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ type Tx struct {
|
|||
ctx context.Context
|
||||
}
|
||||
|
||||
// BeginTx begin a transaction with option
|
||||
func (db *DB) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error) {
|
||||
hookCtx := contexts.NewContextHook(ctx, "BEGIN TRANSACTION", nil)
|
||||
ctx, err := db.beforeProcess(hookCtx)
|
||||
|
@ -36,10 +37,12 @@ func (db *DB) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error) {
|
|||
return &Tx{tx, db, ctx}, nil
|
||||
}
|
||||
|
||||
// Begin begins a transaction
|
||||
func (db *DB) Begin() (*Tx, error) {
|
||||
return db.BeginTx(context.Background(), nil)
|
||||
}
|
||||
|
||||
// Commit submit the transaction
|
||||
func (tx *Tx) Commit() error {
|
||||
hookCtx := contexts.NewContextHook(tx.ctx, "COMMIT", nil)
|
||||
ctx, err := tx.db.beforeProcess(hookCtx)
|
||||
|
@ -48,12 +51,10 @@ func (tx *Tx) Commit() error {
|
|||
}
|
||||
err = tx.Tx.Commit()
|
||||
hookCtx.End(ctx, nil, err)
|
||||
if err := tx.db.afterProcess(hookCtx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return tx.db.afterProcess(hookCtx)
|
||||
}
|
||||
|
||||
// Rollback rollback the transaction
|
||||
func (tx *Tx) Rollback() error {
|
||||
hookCtx := contexts.NewContextHook(tx.ctx, "ROLLBACK", nil)
|
||||
ctx, err := tx.db.beforeProcess(hookCtx)
|
||||
|
@ -62,12 +63,10 @@ func (tx *Tx) Rollback() error {
|
|||
}
|
||||
err = tx.Tx.Rollback()
|
||||
hookCtx.End(ctx, nil, err)
|
||||
if err := tx.db.afterProcess(hookCtx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return tx.db.afterProcess(hookCtx)
|
||||
}
|
||||
|
||||
// PrepareContext prepare the query
|
||||
func (tx *Tx) PrepareContext(ctx context.Context, query string) (*Stmt, error) {
|
||||
names := make(map[string]int)
|
||||
var i int
|
||||
|
@ -89,19 +88,23 @@ func (tx *Tx) PrepareContext(ctx context.Context, query string) (*Stmt, error) {
|
|||
return &Stmt{stmt, tx.db, names, query}, nil
|
||||
}
|
||||
|
||||
// Prepare prepare the query
|
||||
func (tx *Tx) Prepare(query string) (*Stmt, error) {
|
||||
return tx.PrepareContext(context.Background(), query)
|
||||
}
|
||||
|
||||
// StmtContext creates Stmt with context
|
||||
func (tx *Tx) StmtContext(ctx context.Context, stmt *Stmt) *Stmt {
|
||||
stmt.Stmt = tx.Tx.StmtContext(ctx, stmt.Stmt)
|
||||
return stmt
|
||||
}
|
||||
|
||||
// Stmt creates Stmt
|
||||
func (tx *Tx) Stmt(stmt *Stmt) *Stmt {
|
||||
return tx.StmtContext(context.Background(), stmt)
|
||||
}
|
||||
|
||||
// ExecMapContext executes query with args in a map
|
||||
func (tx *Tx) ExecMapContext(ctx context.Context, query string, mp interface{}) (sql.Result, error) {
|
||||
query, args, err := MapToSlice(query, mp)
|
||||
if err != nil {
|
||||
|
@ -110,10 +113,12 @@ func (tx *Tx) ExecMapContext(ctx context.Context, query string, mp interface{})
|
|||
return tx.ExecContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
// ExecMap executes query with args in a map
|
||||
func (tx *Tx) ExecMap(query string, mp interface{}) (sql.Result, error) {
|
||||
return tx.ExecMapContext(context.Background(), query, mp)
|
||||
}
|
||||
|
||||
// ExecStructContext executes query with args in a struct
|
||||
func (tx *Tx) ExecStructContext(ctx context.Context, query string, st interface{}) (sql.Result, error) {
|
||||
query, args, err := StructToSlice(query, st)
|
||||
if err != nil {
|
||||
|
@ -122,6 +127,7 @@ func (tx *Tx) ExecStructContext(ctx context.Context, query string, st interface{
|
|||
return tx.ExecContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
// ExecContext executes a query with args
|
||||
func (tx *Tx) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error) {
|
||||
hookCtx := contexts.NewContextHook(ctx, query, args)
|
||||
ctx, err := tx.db.beforeProcess(hookCtx)
|
||||
|
@ -136,10 +142,12 @@ func (tx *Tx) ExecContext(ctx context.Context, query string, args ...interface{}
|
|||
return res, err
|
||||
}
|
||||
|
||||
// ExecStruct executes query with args in a struct
|
||||
func (tx *Tx) ExecStruct(query string, st interface{}) (sql.Result, error) {
|
||||
return tx.ExecStructContext(context.Background(), query, st)
|
||||
}
|
||||
|
||||
// QueryContext query with args
|
||||
func (tx *Tx) QueryContext(ctx context.Context, query string, args ...interface{}) (*Rows, error) {
|
||||
hookCtx := contexts.NewContextHook(ctx, query, args)
|
||||
ctx, err := tx.db.beforeProcess(hookCtx)
|
||||
|
@ -157,10 +165,12 @@ func (tx *Tx) QueryContext(ctx context.Context, query string, args ...interface{
|
|||
return &Rows{rows, tx.db}, nil
|
||||
}
|
||||
|
||||
// Query query with args
|
||||
func (tx *Tx) Query(query string, args ...interface{}) (*Rows, error) {
|
||||
return tx.QueryContext(context.Background(), query, args...)
|
||||
}
|
||||
|
||||
// QueryMapContext query with args in a map
|
||||
func (tx *Tx) QueryMapContext(ctx context.Context, query string, mp interface{}) (*Rows, error) {
|
||||
query, args, err := MapToSlice(query, mp)
|
||||
if err != nil {
|
||||
|
@ -169,10 +179,12 @@ func (tx *Tx) QueryMapContext(ctx context.Context, query string, mp interface{})
|
|||
return tx.QueryContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
// QueryMap query with args in a map
|
||||
func (tx *Tx) QueryMap(query string, mp interface{}) (*Rows, error) {
|
||||
return tx.QueryMapContext(context.Background(), query, mp)
|
||||
}
|
||||
|
||||
// QueryStructContext query with args in struct
|
||||
func (tx *Tx) QueryStructContext(ctx context.Context, query string, st interface{}) (*Rows, error) {
|
||||
query, args, err := StructToSlice(query, st)
|
||||
if err != nil {
|
||||
|
@ -181,19 +193,23 @@ func (tx *Tx) QueryStructContext(ctx context.Context, query string, st interface
|
|||
return tx.QueryContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
// QueryStruct query with args in struct
|
||||
func (tx *Tx) QueryStruct(query string, st interface{}) (*Rows, error) {
|
||||
return tx.QueryStructContext(context.Background(), query, st)
|
||||
}
|
||||
|
||||
// QueryRowContext query one row with args
|
||||
func (tx *Tx) QueryRowContext(ctx context.Context, query string, args ...interface{}) *Row {
|
||||
rows, err := tx.QueryContext(ctx, query, args...)
|
||||
return &Row{rows, err}
|
||||
}
|
||||
|
||||
// QueryRow query one row with args
|
||||
func (tx *Tx) QueryRow(query string, args ...interface{}) *Row {
|
||||
return tx.QueryRowContext(context.Background(), query, args...)
|
||||
}
|
||||
|
||||
// QueryRowMapContext query one row with args in a map
|
||||
func (tx *Tx) QueryRowMapContext(ctx context.Context, query string, mp interface{}) *Row {
|
||||
query, args, err := MapToSlice(query, mp)
|
||||
if err != nil {
|
||||
|
@ -202,10 +218,12 @@ func (tx *Tx) QueryRowMapContext(ctx context.Context, query string, mp interface
|
|||
return tx.QueryRowContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
// QueryRowMap query one row with args in a map
|
||||
func (tx *Tx) QueryRowMap(query string, mp interface{}) *Row {
|
||||
return tx.QueryRowMapContext(context.Background(), query, mp)
|
||||
}
|
||||
|
||||
// QueryRowStructContext query one row with args in struct
|
||||
func (tx *Tx) QueryRowStructContext(ctx context.Context, query string, st interface{}) *Row {
|
||||
query, args, err := StructToSlice(query, st)
|
||||
if err != nil {
|
||||
|
@ -214,6 +232,7 @@ func (tx *Tx) QueryRowStructContext(ctx context.Context, query string, st interf
|
|||
return tx.QueryRowContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
// QueryRowStruct query one row with args in struct
|
||||
func (tx *Tx) QueryRowStruct(query string, st interface{}) *Row {
|
||||
return tx.QueryRowStructContext(context.Background(), query, st)
|
||||
}
|
||||
|
|
|
@ -79,32 +79,34 @@ type Base struct {
|
|||
quoter schemas.Quoter
|
||||
}
|
||||
|
||||
func (b *Base) Quoter() schemas.Quoter {
|
||||
return b.quoter
|
||||
// Quoter returns the current database Quoter
|
||||
func (db *Base) Quoter() schemas.Quoter {
|
||||
return db.quoter
|
||||
}
|
||||
|
||||
func (b *Base) Init(dialect Dialect, uri *URI) error {
|
||||
b.dialect, b.uri = dialect, uri
|
||||
// Init initialize the dialect
|
||||
func (db *Base) Init(dialect Dialect, uri *URI) error {
|
||||
db.dialect, db.uri = dialect, uri
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Base) URI() *URI {
|
||||
return b.uri
|
||||
// URI returns the uri of database
|
||||
func (db *Base) URI() *URI {
|
||||
return db.uri
|
||||
}
|
||||
|
||||
func (b *Base) DBType() schemas.DBType {
|
||||
return b.uri.DBType
|
||||
}
|
||||
|
||||
func (b *Base) FormatBytes(bs []byte) string {
|
||||
// FormatBytes formats bytes
|
||||
func (db *Base) FormatBytes(bs []byte) string {
|
||||
return fmt.Sprintf("0x%x", bs)
|
||||
}
|
||||
|
||||
// DropTableSQL returns drop table SQL
|
||||
func (db *Base) DropTableSQL(tableName string) (string, bool) {
|
||||
quote := db.dialect.Quoter().Quote
|
||||
return fmt.Sprintf("DROP TABLE IF EXISTS %s", quote(tableName)), true
|
||||
}
|
||||
|
||||
// HasRecords returns true if the SQL has records returned
|
||||
func (db *Base) HasRecords(queryer core.Queryer, ctx context.Context, query string, args ...interface{}) (bool, error) {
|
||||
rows, err := queryer.QueryContext(ctx, query, args...)
|
||||
if err != nil {
|
||||
|
@ -118,6 +120,7 @@ func (db *Base) HasRecords(queryer core.Queryer, ctx context.Context, query stri
|
|||
return false, nil
|
||||
}
|
||||
|
||||
// IsColumnExist returns true if the column of the table exist
|
||||
func (db *Base) IsColumnExist(queryer core.Queryer, ctx context.Context, tableName, colName string) (bool, error) {
|
||||
quote := db.dialect.Quoter().Quote
|
||||
query := fmt.Sprintf(
|
||||
|
@ -132,11 +135,13 @@ func (db *Base) IsColumnExist(queryer core.Queryer, ctx context.Context, tableNa
|
|||
return db.HasRecords(queryer, ctx, query, db.uri.DBName, tableName, colName)
|
||||
}
|
||||
|
||||
// AddColumnSQL returns a SQL to add a column
|
||||
func (db *Base) AddColumnSQL(tableName string, col *schemas.Column) string {
|
||||
s, _ := ColumnString(db.dialect, col, true)
|
||||
return fmt.Sprintf("ALTER TABLE %v ADD %v", db.dialect.Quoter().Quote(tableName), s)
|
||||
}
|
||||
|
||||
// CreateIndexSQL returns a SQL to create index
|
||||
func (db *Base) CreateIndexSQL(tableName string, index *schemas.Index) string {
|
||||
quoter := db.dialect.Quoter()
|
||||
var unique string
|
||||
|
@ -150,6 +155,7 @@ func (db *Base) CreateIndexSQL(tableName string, index *schemas.Index) string {
|
|||
quoter.Join(index.Cols, ","))
|
||||
}
|
||||
|
||||
// DropIndexSQL returns a SQL to drop index
|
||||
func (db *Base) DropIndexSQL(tableName string, index *schemas.Index) string {
|
||||
quote := db.dialect.Quoter().Quote
|
||||
var name string
|
||||
|
@ -161,16 +167,19 @@ func (db *Base) DropIndexSQL(tableName string, index *schemas.Index) string {
|
|||
return fmt.Sprintf("DROP INDEX %v ON %s", quote(name), quote(tableName))
|
||||
}
|
||||
|
||||
// ModifyColumnSQL returns a SQL to modify SQL
|
||||
func (db *Base) ModifyColumnSQL(tableName string, col *schemas.Column) string {
|
||||
s, _ := ColumnString(db.dialect, col, false)
|
||||
return fmt.Sprintf("ALTER TABLE %s MODIFY COLUMN %s", tableName, s)
|
||||
}
|
||||
|
||||
func (b *Base) ForUpdateSQL(query string) string {
|
||||
// ForUpdateSQL returns for updateSQL
|
||||
func (db *Base) ForUpdateSQL(query string) string {
|
||||
return query + " FOR UPDATE"
|
||||
}
|
||||
|
||||
func (b *Base) SetParams(params map[string]string) {
|
||||
// SetParams set params
|
||||
func (db *Base) SetParams(params map[string]string) {
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -206,6 +215,7 @@ func regDrvsNDialects() bool {
|
|||
"postgres": {"postgres", func() Driver { return &pqDriver{} }, func() Dialect { return &postgres{} }},
|
||||
"pgx": {"postgres", func() Driver { return &pqDriverPgx{} }, func() Dialect { return &postgres{} }},
|
||||
"sqlite3": {"sqlite3", func() Driver { return &sqlite3Driver{} }, func() Dialect { return &sqlite3{} }},
|
||||
"sqlite": {"sqlite3", func() Driver { return &sqlite3Driver{} }, func() Dialect { return &sqlite3{} }},
|
||||
"oci8": {"oracle", func() Driver { return &oci8Driver{} }, func() Dialect { return &oracle{} }},
|
||||
"goracle": {"oracle", func() Driver { return &goracleDriver{} }, func() Dialect { return &oracle{} }},
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"fmt"
|
||||
)
|
||||
|
||||
// Driver represents a database driver
|
||||
type Driver interface {
|
||||
Parse(string, string) (*URI, error)
|
||||
}
|
||||
|
@ -16,6 +17,7 @@ var (
|
|||
drivers = map[string]Driver{}
|
||||
)
|
||||
|
||||
// RegisterDriver register a driver
|
||||
func RegisterDriver(driverName string, driver Driver) {
|
||||
if driver == nil {
|
||||
panic("core: Register driver is nil")
|
||||
|
@ -26,10 +28,12 @@ func RegisterDriver(driverName string, driver Driver) {
|
|||
drivers[driverName] = driver
|
||||
}
|
||||
|
||||
// QueryDriver query a driver with name
|
||||
func QueryDriver(driverName string) Driver {
|
||||
return drivers[driverName]
|
||||
}
|
||||
|
||||
// RegisteredDriverSize returned all drivers's length
|
||||
func RegisteredDriverSize() int {
|
||||
return len(drivers)
|
||||
}
|
||||
|
@ -38,7 +42,7 @@ func RegisteredDriverSize() int {
|
|||
func OpenDialect(driverName, connstr string) (Dialect, error) {
|
||||
driver := QueryDriver(driverName)
|
||||
if driver == nil {
|
||||
return nil, fmt.Errorf("Unsupported driver name: %v", driverName)
|
||||
return nil, fmt.Errorf("unsupported driver name: %v", driverName)
|
||||
}
|
||||
|
||||
uri, err := driver.Parse(driverName, connstr)
|
||||
|
@ -48,7 +52,7 @@ func OpenDialect(driverName, connstr string) (Dialect, error) {
|
|||
|
||||
dialect := QueryDialect(uri.DBType)
|
||||
if dialect == nil {
|
||||
return nil, fmt.Errorf("Unsupported dialect type: %v", uri.DBType)
|
||||
return nil, fmt.Errorf("unsupported dialect type: %v", uri.DBType)
|
||||
}
|
||||
|
||||
dialect.Init(uri)
|
||||
|
|
|
@ -38,6 +38,7 @@ func convertQuestionMark(sql, prefix string, start int) string {
|
|||
return buf.String()
|
||||
}
|
||||
|
||||
// Do implements Filter
|
||||
func (s *SeqFilter) Do(sql string) string {
|
||||
return convertQuestionMark(sql, s.Prefix, s.Start)
|
||||
}
|
||||
|
|
|
@ -284,7 +284,7 @@ func (db *mssql) SQLType(c *schemas.Column) string {
|
|||
case schemas.TimeStampz:
|
||||
res = "DATETIMEOFFSET"
|
||||
c.Length = 7
|
||||
case schemas.MediumInt:
|
||||
case schemas.MediumInt, schemas.UnsignedInt:
|
||||
res = schemas.Int
|
||||
case schemas.Text, schemas.MediumText, schemas.TinyText, schemas.LongText, schemas.Json:
|
||||
res = db.defaultVarchar + "(MAX)"
|
||||
|
@ -296,7 +296,7 @@ func (db *mssql) SQLType(c *schemas.Column) string {
|
|||
case schemas.TinyInt:
|
||||
res = schemas.TinyInt
|
||||
c.Length = 0
|
||||
case schemas.BigInt:
|
||||
case schemas.BigInt, schemas.UnsignedBigInt:
|
||||
res = schemas.BigInt
|
||||
c.Length = 0
|
||||
case schemas.NVarchar:
|
||||
|
|
|
@ -254,6 +254,10 @@ func (db *mysql) SQLType(c *schemas.Column) string {
|
|||
c.Length = 40
|
||||
case schemas.Json:
|
||||
res = schemas.Text
|
||||
case schemas.UnsignedInt:
|
||||
res = schemas.Int
|
||||
case schemas.UnsignedBigInt:
|
||||
res = schemas.BigInt
|
||||
default:
|
||||
res = t
|
||||
}
|
||||
|
@ -271,6 +275,11 @@ func (db *mysql) SQLType(c *schemas.Column) string {
|
|||
} else if hasLen1 {
|
||||
res += "(" + strconv.Itoa(c.Length) + ")"
|
||||
}
|
||||
|
||||
if c.SQLType.Name == schemas.UnsignedBigInt || c.SQLType.Name == schemas.UnsignedInt {
|
||||
res += " UNSIGNED"
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
|
@ -331,16 +340,16 @@ func (db *mysql) GetColumns(queryer core.Queryer, ctx context.Context, tableName
|
|||
col := new(schemas.Column)
|
||||
col.Indexes = make(map[string]int)
|
||||
|
||||
var columnName, isNullable, colType, colKey, extra, comment string
|
||||
var alreadyQuoted bool
|
||||
var columnName, nullableStr, colType, colKey, extra, comment string
|
||||
var alreadyQuoted, isUnsigned bool
|
||||
var colDefault *string
|
||||
err = rows.Scan(&columnName, &isNullable, &colDefault, &colType, &colKey, &extra, &comment, &alreadyQuoted)
|
||||
err = rows.Scan(&columnName, &nullableStr, &colDefault, &colType, &colKey, &extra, &comment, &alreadyQuoted)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
col.Name = strings.Trim(columnName, "` ")
|
||||
col.Comment = comment
|
||||
if "YES" == isNullable {
|
||||
if nullableStr == "YES" {
|
||||
col.Nullable = true
|
||||
}
|
||||
|
||||
|
@ -351,8 +360,15 @@ func (db *mysql) GetColumns(queryer core.Queryer, ctx context.Context, tableName
|
|||
col.DefaultIsEmpty = true
|
||||
}
|
||||
|
||||
fields := strings.Fields(colType)
|
||||
if len(fields) == 2 && fields[1] == "unsigned" {
|
||||
isUnsigned = true
|
||||
}
|
||||
colType = fields[0]
|
||||
cts := strings.Split(colType, "(")
|
||||
colName := cts[0]
|
||||
// Remove the /* mariadb-5.3 */ suffix from coltypes
|
||||
colName = strings.TrimSuffix(colName, "/* mariadb-5.3 */")
|
||||
colType = strings.ToUpper(colName)
|
||||
var len1, len2 int
|
||||
if len(cts) == 2 {
|
||||
|
@ -387,11 +403,8 @@ func (db *mysql) GetColumns(queryer core.Queryer, ctx context.Context, tableName
|
|||
}
|
||||
}
|
||||
}
|
||||
if colType == "FLOAT UNSIGNED" {
|
||||
colType = "FLOAT"
|
||||
}
|
||||
if colType == "DOUBLE UNSIGNED" {
|
||||
colType = "DOUBLE"
|
||||
if isUnsigned {
|
||||
colType = "UNSIGNED " + colType
|
||||
}
|
||||
col.Length = len1
|
||||
col.Length2 = len2
|
||||
|
|
|
@ -824,6 +824,11 @@ func (db *postgres) SetQuotePolicy(quotePolicy QuotePolicy) {
|
|||
}
|
||||
}
|
||||
|
||||
// FormatBytes formats bytes
|
||||
func (db *postgres) FormatBytes(bs []byte) string {
|
||||
return fmt.Sprintf("E'\\x%x'", bs)
|
||||
}
|
||||
|
||||
func (db *postgres) SQLType(c *schemas.Column) string {
|
||||
var res string
|
||||
switch t := c.SQLType.Name; t {
|
||||
|
@ -833,12 +838,12 @@ func (db *postgres) SQLType(c *schemas.Column) string {
|
|||
case schemas.Bit:
|
||||
res = schemas.Boolean
|
||||
return res
|
||||
case schemas.MediumInt, schemas.Int, schemas.Integer:
|
||||
case schemas.MediumInt, schemas.Int, schemas.Integer, schemas.UnsignedInt:
|
||||
if c.IsAutoIncrement {
|
||||
return schemas.Serial
|
||||
}
|
||||
return schemas.Integer
|
||||
case schemas.BigInt:
|
||||
case schemas.BigInt, schemas.UnsignedBigInt:
|
||||
if c.IsAutoIncrement {
|
||||
return schemas.BigSerial
|
||||
}
|
||||
|
@ -1052,6 +1057,10 @@ WHERE n.nspname= s.table_schema AND c.relkind = 'r'::char AND c.relname = $1%s A
|
|||
}
|
||||
}
|
||||
|
||||
if colDefault != nil && *colDefault == "unique_rowid()" { // ignore the system column added by cockroach
|
||||
continue
|
||||
}
|
||||
|
||||
col.Name = strings.Trim(colName, `" `)
|
||||
|
||||
if colDefault != nil {
|
||||
|
|
|
@ -193,7 +193,8 @@ func (db *sqlite3) SQLType(c *schemas.Column) string {
|
|||
case schemas.Char, schemas.Varchar, schemas.NVarchar, schemas.TinyText,
|
||||
schemas.Text, schemas.MediumText, schemas.LongText, schemas.Json:
|
||||
return schemas.Text
|
||||
case schemas.Bit, schemas.TinyInt, schemas.SmallInt, schemas.MediumInt, schemas.Int, schemas.Integer, schemas.BigInt:
|
||||
case schemas.Bit, schemas.TinyInt, schemas.SmallInt, schemas.MediumInt, schemas.Int, schemas.Integer, schemas.BigInt,
|
||||
schemas.UnsignedBigInt, schemas.UnsignedInt:
|
||||
return schemas.Integer
|
||||
case schemas.Float, schemas.Double, schemas.Real:
|
||||
return schemas.Real
|
||||
|
|
|
@ -19,7 +19,11 @@ func FormatTime(dialect Dialect, sqlTypeName string, t time.Time) (v interface{}
|
|||
case schemas.Date:
|
||||
v = t.Format("2006-01-02")
|
||||
case schemas.DateTime, schemas.TimeStamp, schemas.Varchar: // !DarthPestilane! format time when sqlTypeName is schemas.Varchar.
|
||||
v = t.Format("2006-01-02 15:04:05")
|
||||
if dialect.URI().DBType == schemas.ORACLE {
|
||||
v = t
|
||||
} else {
|
||||
v = t.Format("2006-01-02 15:04:05")
|
||||
}
|
||||
case schemas.TimeStampz:
|
||||
if dialect.URI().DBType == schemas.MSSQL {
|
||||
v = t.Format("2006-01-02T15:04:05.9999999Z07:00")
|
||||
|
@ -34,6 +38,7 @@ func FormatTime(dialect Dialect, sqlTypeName string, t time.Time) (v interface{}
|
|||
return
|
||||
}
|
||||
|
||||
// FormatColumnTime format column time
|
||||
func FormatColumnTime(dialect Dialect, defaultTimeZone *time.Location, col *schemas.Column, t time.Time) (v interface{}) {
|
||||
if t.IsZero() {
|
||||
if col.Nullable {
|
||||
|
|
|
@ -21,6 +21,7 @@ import (
|
|||
"xorm.io/xorm/contexts"
|
||||
"xorm.io/xorm/core"
|
||||
"xorm.io/xorm/dialects"
|
||||
"xorm.io/xorm/internal/json"
|
||||
"xorm.io/xorm/internal/utils"
|
||||
"xorm.io/xorm/log"
|
||||
"xorm.io/xorm/names"
|
||||
|
@ -105,6 +106,15 @@ func NewEngineWithParams(driverName string, dataSourceName string, params map[st
|
|||
return engine, err
|
||||
}
|
||||
|
||||
// NewEngineWithDB new a db manager with db. The params will be passed to db.
|
||||
func NewEngineWithDB(driverName string, dataSourceName string, db *core.DB) (*Engine, error) {
|
||||
dialect, err := dialects.OpenDialect(driverName, dataSourceName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newEngine(driverName, dataSourceName, dialect, db)
|
||||
}
|
||||
|
||||
// NewEngineWithDialectAndDB new a db manager according to the parameter.
|
||||
// If you do not want to use your own dialect or db, please use NewEngine.
|
||||
// For creating dialect, you can call dialects.OpenDialect. And, for creating db,
|
||||
|
@ -159,6 +169,8 @@ func (engine *Engine) SetLogger(logger interface{}) {
|
|||
realLogger = t
|
||||
case log.Logger:
|
||||
realLogger = log.NewLoggerAdapter(t)
|
||||
default:
|
||||
panic("logger should implement either log.ContextLogger or log.Logger")
|
||||
}
|
||||
engine.logger = realLogger
|
||||
engine.DB().Logger = realLogger
|
||||
|
@ -200,6 +212,11 @@ func (engine *Engine) SetColumnMapper(mapper names.Mapper) {
|
|||
engine.tagParser.SetColumnMapper(mapper)
|
||||
}
|
||||
|
||||
// SetTagIdentifier set the tag identifier
|
||||
func (engine *Engine) SetTagIdentifier(tagIdentifier string) {
|
||||
engine.tagParser.SetIdentifier(tagIdentifier)
|
||||
}
|
||||
|
||||
// Quote Use QuoteStr quote the string sql
|
||||
func (engine *Engine) Quote(value string) string {
|
||||
value = strings.TrimSpace(value)
|
||||
|
@ -441,9 +458,26 @@ func formatColumnValue(dstDialect dialects.Dialect, d interface{}, col *schemas.
|
|||
}
|
||||
|
||||
if col.SQLType.IsText() {
|
||||
var v = fmt.Sprintf("%s", d)
|
||||
var v string
|
||||
switch reflect.TypeOf(d).Kind() {
|
||||
case reflect.Struct, reflect.Array, reflect.Slice, reflect.Map:
|
||||
bytes, err := json.DefaultJSONHandler.Marshal(d)
|
||||
if err != nil {
|
||||
v = fmt.Sprintf("%s", d)
|
||||
} else {
|
||||
v = string(bytes)
|
||||
}
|
||||
default:
|
||||
v = fmt.Sprintf("%s", d)
|
||||
}
|
||||
|
||||
return "'" + strings.Replace(v, "'", "''", -1) + "'"
|
||||
} else if col.SQLType.IsTime() {
|
||||
if dstDialect.URI().DBType == schemas.MSSQL && col.SQLType.Name == schemas.DateTime {
|
||||
if t, ok := d.(time.Time); ok {
|
||||
return "'" + t.UTC().Format("2006-01-02 15:04:05") + "'"
|
||||
}
|
||||
}
|
||||
var v = fmt.Sprintf("%s", d)
|
||||
if strings.HasSuffix(v, " +0000 UTC") {
|
||||
return fmt.Sprintf("'%s'", v[0:len(v)-len(" +0000 UTC")])
|
||||
|
@ -475,7 +509,7 @@ func formatColumnValue(dstDialect dialects.Dialect, d interface{}, col *schemas.
|
|||
}
|
||||
return fmt.Sprintf("%v", strconv.FormatBool(v))
|
||||
}
|
||||
return fmt.Sprintf("%v", d)
|
||||
return fmt.Sprintf("%d", d)
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
if col.SQLType.Name == schemas.Bool {
|
||||
v := reflect.ValueOf(d).Uint() > 0
|
||||
|
@ -487,7 +521,7 @@ func formatColumnValue(dstDialect dialects.Dialect, d interface{}, col *schemas.
|
|||
}
|
||||
return fmt.Sprintf("%v", strconv.FormatBool(v))
|
||||
}
|
||||
return fmt.Sprintf("%v", d)
|
||||
return fmt.Sprintf("%d", d)
|
||||
default:
|
||||
return fmt.Sprintf("%v", d)
|
||||
}
|
||||
|
@ -521,6 +555,8 @@ func (engine *Engine) dumpTables(tables []*schemas.Table, w io.Writer, tp ...sch
|
|||
}
|
||||
dstDialect.Init(&destURI)
|
||||
}
|
||||
cacherMgr := caches.NewManager()
|
||||
dstTableCache := tags.NewParser("xorm", dstDialect, engine.GetTableMapper(), engine.GetColumnMapper(), cacherMgr)
|
||||
|
||||
_, err := io.WriteString(w, fmt.Sprintf("/*Generated by xorm %s, from %s to %s*/\n\n",
|
||||
time.Now().In(engine.TZLocation).Format("2006-01-02 15:04:05"), engine.dialect.URI().DBType, dstDialect.URI().DBType))
|
||||
|
@ -529,9 +565,18 @@ func (engine *Engine) dumpTables(tables []*schemas.Table, w io.Writer, tp ...sch
|
|||
}
|
||||
|
||||
for i, table := range tables {
|
||||
tableName := table.Name
|
||||
dstTable := table
|
||||
if table.Type != nil {
|
||||
dstTable, err = dstTableCache.Parse(reflect.New(table.Type).Elem())
|
||||
if err != nil {
|
||||
engine.logger.Errorf("Unable to infer table for %s in new dialect. Error: %v", table.Name)
|
||||
dstTable = table
|
||||
}
|
||||
}
|
||||
|
||||
dstTableName := dstTable.Name
|
||||
if dstDialect.URI().Schema != "" {
|
||||
tableName = fmt.Sprintf("%s.%s", dstDialect.URI().Schema, table.Name)
|
||||
dstTableName = fmt.Sprintf("%s.%s", dstDialect.URI().Schema, dstTable.Name)
|
||||
}
|
||||
originalTableName := table.Name
|
||||
if engine.dialect.URI().Schema != "" {
|
||||
|
@ -543,27 +588,30 @@ func (engine *Engine) dumpTables(tables []*schemas.Table, w io.Writer, tp ...sch
|
|||
return err
|
||||
}
|
||||
}
|
||||
sqls, _ := dstDialect.CreateTableSQL(table, tableName)
|
||||
|
||||
sqls, _ := dstDialect.CreateTableSQL(dstTable, dstTableName)
|
||||
for _, s := range sqls {
|
||||
_, err = io.WriteString(w, s+";\n")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if len(table.PKColumns()) > 0 && dstDialect.URI().DBType == schemas.MSSQL {
|
||||
fmt.Fprintf(w, "SET IDENTITY_INSERT [%s] ON;\n", table.Name)
|
||||
if len(dstTable.PKColumns()) > 0 && dstDialect.URI().DBType == schemas.MSSQL {
|
||||
fmt.Fprintf(w, "SET IDENTITY_INSERT [%s] ON;\n", dstTable.Name)
|
||||
}
|
||||
|
||||
for _, index := range table.Indexes {
|
||||
_, err = io.WriteString(w, dstDialect.CreateIndexSQL(table.Name, index)+";\n")
|
||||
for _, index := range dstTable.Indexes {
|
||||
_, err = io.WriteString(w, dstDialect.CreateIndexSQL(dstTable.Name, index)+";\n")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
cols := table.ColumnsSeq()
|
||||
dstCols := dstTable.ColumnsSeq()
|
||||
|
||||
colNames := engine.dialect.Quoter().Join(cols, ", ")
|
||||
destColNames := dstDialect.Quoter().Join(cols, ", ")
|
||||
destColNames := dstDialect.Quoter().Join(dstCols, ", ")
|
||||
|
||||
rows, err := engine.DB().QueryContext(engine.defaultContext, "SELECT "+colNames+" FROM "+engine.Quote(originalTableName))
|
||||
if err != nil {
|
||||
|
@ -571,35 +619,83 @@ func (engine *Engine) dumpTables(tables []*schemas.Table, w io.Writer, tp ...sch
|
|||
}
|
||||
defer rows.Close()
|
||||
|
||||
for rows.Next() {
|
||||
dest := make([]interface{}, len(cols))
|
||||
err = rows.ScanSlice(&dest)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = io.WriteString(w, "INSERT INTO "+dstDialect.Quoter().Quote(tableName)+" ("+destColNames+") VALUES (")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var temp string
|
||||
for i, d := range dest {
|
||||
col := table.GetColumn(cols[i])
|
||||
if col == nil {
|
||||
return errors.New("unknow column error")
|
||||
if table.Type != nil {
|
||||
sess := engine.NewSession()
|
||||
defer sess.Close()
|
||||
for rows.Next() {
|
||||
beanValue := reflect.New(table.Type)
|
||||
bean := beanValue.Interface()
|
||||
fields, err := rows.Columns()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
scanResults, err := sess.row2Slice(rows, fields, bean)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dataStruct := utils.ReflectValue(bean)
|
||||
_, err = sess.slice2Bean(scanResults, fields, bean, &dataStruct, table)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = io.WriteString(w, "INSERT INTO "+dstDialect.Quoter().Quote(dstTableName)+" ("+destColNames+") VALUES (")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var temp string
|
||||
for _, d := range dstCols {
|
||||
col := table.GetColumn(d)
|
||||
if col == nil {
|
||||
return errors.New("unknown column error")
|
||||
}
|
||||
|
||||
fields := strings.Split(col.FieldName, ".")
|
||||
field := dataStruct
|
||||
for _, fieldName := range fields {
|
||||
field = field.FieldByName(fieldName)
|
||||
}
|
||||
temp += "," + formatColumnValue(dstDialect, field.Interface(), col)
|
||||
}
|
||||
_, err = io.WriteString(w, temp[1:]+");\n")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
temp += "," + formatColumnValue(dstDialect, d, col)
|
||||
}
|
||||
_, err = io.WriteString(w, temp[1:]+");\n")
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
for rows.Next() {
|
||||
dest := make([]interface{}, len(cols))
|
||||
err = rows.ScanSlice(&dest)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = io.WriteString(w, "INSERT INTO "+dstDialect.Quoter().Quote(dstTableName)+" ("+destColNames+") VALUES (")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var temp string
|
||||
for i, d := range dest {
|
||||
col := table.GetColumn(cols[i])
|
||||
if col == nil {
|
||||
return errors.New("unknow column error")
|
||||
}
|
||||
|
||||
temp += "," + formatColumnValue(dstDialect, d, col)
|
||||
}
|
||||
_, err = io.WriteString(w, temp[1:]+");\n")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Hack for postgres
|
||||
if dstDialect.URI().DBType == schemas.POSTGRES && table.AutoIncrColumn() != nil {
|
||||
_, err = io.WriteString(w, "SELECT setval('"+tableName+"_id_seq', COALESCE((SELECT MAX("+table.AutoIncrColumn().Name+") + 1 FROM "+dstDialect.Quoter().Quote(tableName)+"), 1), false);\n")
|
||||
_, err = io.WriteString(w, "SELECT setval('"+dstTableName+"_id_seq', COALESCE((SELECT MAX("+table.AutoIncrColumn().Name+") + 1 FROM "+dstDialect.Quoter().Quote(dstTableName)+"), 1), false);\n")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -1262,6 +1358,7 @@ func (engine *Engine) SetSchema(schema string) {
|
|||
engine.dialect.URI().SetSchema(schema)
|
||||
}
|
||||
|
||||
// AddHook adds a context Hook
|
||||
func (engine *Engine) AddHook(hook contexts.Hook) {
|
||||
engine.db.AddHook(hook)
|
||||
}
|
||||
|
@ -1277,7 +1374,7 @@ func (engine *Engine) tbNameWithSchema(v string) string {
|
|||
return dialects.TableNameWithSchema(engine.dialect, v)
|
||||
}
|
||||
|
||||
// ContextHook creates a session with the context
|
||||
// Context creates a session with the context
|
||||
func (engine *Engine) Context(ctx context.Context) *Session {
|
||||
session := engine.NewSession()
|
||||
session.isAutoClose = true
|
||||
|
|
|
@ -79,7 +79,7 @@ func (eg *EngineGroup) Close() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// ContextHook returned a group session
|
||||
// Context returned a group session
|
||||
func (eg *EngineGroup) Context(ctx context.Context) *Session {
|
||||
sess := eg.NewSession()
|
||||
sess.isAutoClose = true
|
||||
|
@ -144,6 +144,7 @@ func (eg *EngineGroup) SetLogger(logger interface{}) {
|
|||
}
|
||||
}
|
||||
|
||||
// AddHook adds Hook
|
||||
func (eg *EngineGroup) AddHook(hook contexts.Hook) {
|
||||
eg.Engine.AddHook(hook)
|
||||
for i := 0; i < len(eg.slaves); i++ {
|
||||
|
@ -167,6 +168,14 @@ func (eg *EngineGroup) SetMapper(mapper names.Mapper) {
|
|||
}
|
||||
}
|
||||
|
||||
// SetTagIdentifier set the tag identifier
|
||||
func (eg *EngineGroup) SetTagIdentifier(tagIdentifier string) {
|
||||
eg.Engine.SetTagIdentifier(tagIdentifier)
|
||||
for i := 0; i < len(eg.slaves); i++ {
|
||||
eg.slaves[i].SetTagIdentifier(tagIdentifier)
|
||||
}
|
||||
}
|
||||
|
||||
// SetMaxIdleConns set the max idle connections on pool, default is 2
|
||||
func (eg *EngineGroup) SetMaxIdleConns(conns int) {
|
||||
eg.Engine.DB().SetMaxIdleConns(conns)
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
module xorm.io/xorm
|
||||
|
||||
go 1.11
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc
|
||||
github.com/denisenkom/go-mssqldb v0.9.0
|
||||
github.com/go-sql-driver/mysql v1.5.0
|
||||
github.com/lib/pq v1.7.0
|
||||
github.com/mattn/go-sqlite3 v1.14.0
|
||||
github.com/mattn/go-sqlite3 v1.14.6
|
||||
github.com/stretchr/testify v1.4.0
|
||||
github.com/syndtr/goleveldb v1.0.0
|
||||
github.com/ziutek/mymysql v1.5.4
|
||||
xorm.io/builder v0.3.7
|
||||
modernc.org/sqlite v1.10.1-0.20210314190707-798bbeb9bb84
|
||||
xorm.io/builder v0.3.8
|
||||
)
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
|
||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
|
||||
github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
|
||||
github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
|
||||
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/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc h1:VRRKCwnzqk8QCaRC4os14xoKDdbHqqlJtJA0oc1ZAjg=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/denisenkom/go-mssqldb v0.9.0 h1:RSohk2RsiZqLZ0zCjtfn3S4Gp4exhpBWHyQ7D0yGjAk=
|
||||
github.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
|
||||
|
@ -16,12 +16,18 @@ github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM
|
|||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/go-cmp v0.5.3 h1:x95R7cp+rSeeqAMI2knLtQ0DKlaBhv2NrtrOvafPHRo=
|
||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
github.com/lib/pq v1.7.0 h1:h93mCPfUSkaul3Ka/VG8uZdmW1uMHDGxzu0NWHuJmHY=
|
||||
github.com/lib/pq v1.7.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/mattn/go-sqlite3 v1.14.0 h1:mLyGNKR8+Vv9CAU7PphKa2hkEqxxhn8i32J6FPj1/QA=
|
||||
github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg=
|
||||
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
|
@ -29,34 +35,53 @@ github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
|
|||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
||||
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=
|
||||
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
|
||||
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/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78 h1:M8tBwCtWD/cZV9DZpFYRUgaymAYAr+aIUTWzDaM3uPs=
|
||||
golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
|
@ -66,5 +91,32 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD
|
|||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
xorm.io/builder v0.3.7 h1:2pETdKRK+2QG4mLX4oODHEhn5Z8j1m8sXa7jfu+/SZI=
|
||||
xorm.io/builder v0.3.7/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
|
||||
modernc.org/cc/v3 v3.31.5-0.20210308123301-7a3e9dab9009 h1:u0oCo5b9wyLr++HF3AN9JicGhkUxJhMz51+8TIZH9N0=
|
||||
modernc.org/cc/v3 v3.31.5-0.20210308123301-7a3e9dab9009/go.mod h1:0R6jl1aZlIl2avnYfbfHBS1QB6/f+16mihBObaBC878=
|
||||
modernc.org/ccgo/v3 v3.9.0 h1:JbcEIqjw4Agf+0g3Tc85YvfYqkkFOv6xBwS4zkfqSoA=
|
||||
modernc.org/ccgo/v3 v3.9.0/go.mod h1:nQbgkn8mwzPdp4mm6BT6+p85ugQ7FrGgIcYaE7nSrpY=
|
||||
modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM=
|
||||
modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=
|
||||
modernc.org/libc v1.7.13-0.20210308123627-12f642a52bb8/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w=
|
||||
modernc.org/libc v1.8.0 h1:Pp4uv9g0csgBMpGPABKtkieF6O5MGhfGo6ZiOdlYfR8=
|
||||
modernc.org/libc v1.8.0/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w=
|
||||
modernc.org/mathutil v1.1.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/mathutil v1.2.2 h1:+yFk8hBprV+4c0U9GjFtL+dV3N8hOJ8JCituQcMShFY=
|
||||
modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/memory v1.0.4 h1:utMBrFcpnQDdNsmM6asmyH/FM9TqLPS7XF7otpJmrwM=
|
||||
modernc.org/memory v1.0.4/go.mod h1:nV2OApxradM3/OVbs2/0OsP6nPfakXpi50C7dcoHXlc=
|
||||
modernc.org/opt v0.1.1 h1:/0RX92k9vwVeDXj+Xn23DKp2VJubL7k8qNffND6qn3A=
|
||||
modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||
modernc.org/sqlite v1.10.1-0.20210314190707-798bbeb9bb84 h1:rgEUzE849tFlHSoeCrKyS9cZAljC+DY7MdMHKq6R6sY=
|
||||
modernc.org/sqlite v1.10.1-0.20210314190707-798bbeb9bb84/go.mod h1:PGzq6qlhyYjL6uVbSgS6WoF7ZopTW/sI7+7p+mb4ZVU=
|
||||
modernc.org/strutil v1.1.0 h1:+1/yCzZxY2pZwwrsbH+4T7BQMoLQ9QiBshRC9eicYsc=
|
||||
modernc.org/strutil v1.1.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs=
|
||||
modernc.org/tcl v1.5.0 h1:euZSUNfE0Fd4W8VqXI1Ly1v7fqDJoBuAV88Ea+SnaSs=
|
||||
modernc.org/tcl v1.5.0/go.mod h1:gb57hj4pO8fRrK54zveIfFXBaMHK3SKJNWcmRw1cRzc=
|
||||
modernc.org/token v1.0.0 h1:a0jaWiNMDhDUtqOj09wvjWWAqd3q7WpBulmL9H2egsk=
|
||||
modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||
modernc.org/z v1.0.1-0.20210308123920-1f282aa71362/go.mod h1:8/SRk5C/HgiQWCgXdfpb+1RvhORdkz5sw72d3jjtyqA=
|
||||
modernc.org/z v1.0.1 h1:WyIDpEpAIx4Hel6q/Pcgj/VhaQV5XPJ2I6ryIYbjnpc=
|
||||
modernc.org/z v1.0.1/go.mod h1:8/SRk5C/HgiQWCgXdfpb+1RvhORdkz5sw72d3jjtyqA=
|
||||
xorm.io/builder v0.3.8 h1:P/wPgRqa9kX5uE0aA1/ukJ23u9KH0aSRpHLwDKXigSE=
|
||||
xorm.io/builder v0.3.8/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
|
||||
|
|
|
@ -101,6 +101,7 @@ type EngineInterface interface {
|
|||
SetCacher(string, caches.Cacher)
|
||||
SetConnMaxLifetime(time.Duration)
|
||||
SetColumnMapper(names.Mapper)
|
||||
SetTagIdentifier(string)
|
||||
SetDefaultCacher(caches.Cacher)
|
||||
SetLogger(logger interface{})
|
||||
SetLogLevel(log.LogLevel)
|
||||
|
|
|
@ -6,15 +6,15 @@ package json
|
|||
|
||||
import "encoding/json"
|
||||
|
||||
// JSONInterface represents an interface to handle json data
|
||||
type JSONInterface interface {
|
||||
// Interface represents an interface to handle json data
|
||||
type Interface interface {
|
||||
Marshal(v interface{}) ([]byte, error)
|
||||
Unmarshal(data []byte, v interface{}) error
|
||||
}
|
||||
|
||||
var (
|
||||
// DefaultJSONHandler default json handler
|
||||
DefaultJSONHandler JSONInterface = StdJSON{}
|
||||
DefaultJSONHandler Interface = StdJSON{}
|
||||
)
|
||||
|
||||
// StdJSON implements JSONInterface via encoding/json
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"xorm.io/xorm/schemas"
|
||||
)
|
||||
|
||||
// ConvertIDSQL converts SQL with id
|
||||
func (statement *Statement) ConvertIDSQL(sqlStr string) string {
|
||||
if statement.RefTable != nil {
|
||||
cols := statement.RefTable.PKColumns()
|
||||
|
@ -37,6 +38,7 @@ func (statement *Statement) ConvertIDSQL(sqlStr string) string {
|
|||
return ""
|
||||
}
|
||||
|
||||
// ConvertUpdateSQL converts update SQL
|
||||
func (statement *Statement) ConvertUpdateSQL(sqlStr string) (string, string) {
|
||||
if statement.RefTable == nil || len(statement.RefTable.PrimaryKeys) != 1 {
|
||||
return "", ""
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"xorm.io/xorm/schemas"
|
||||
)
|
||||
|
||||
// ErrUnsupportedExprType represents an error with unsupported express type
|
||||
type ErrUnsupportedExprType struct {
|
||||
tp string
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
"xorm.io/xorm/schemas"
|
||||
)
|
||||
|
||||
// GenQuerySQL generate query SQL
|
||||
func (statement *Statement) GenQuerySQL(sqlOrArgs ...interface{}) (string, []interface{}, error) {
|
||||
if len(sqlOrArgs) > 0 {
|
||||
return statement.ConvertSQLOrArgs(sqlOrArgs...)
|
||||
|
@ -72,6 +73,7 @@ func (statement *Statement) GenQuerySQL(sqlOrArgs ...interface{}) (string, []int
|
|||
return sqlStr, args, nil
|
||||
}
|
||||
|
||||
// GenSumSQL generates sum SQL
|
||||
func (statement *Statement) GenSumSQL(bean interface{}, columns ...string) (string, []interface{}, error) {
|
||||
if statement.RawSQL != "" {
|
||||
return statement.GenRawSQL(), statement.RawParams, nil
|
||||
|
@ -102,6 +104,7 @@ func (statement *Statement) GenSumSQL(bean interface{}, columns ...string) (stri
|
|||
return sqlStr, append(statement.joinArgs, condArgs...), nil
|
||||
}
|
||||
|
||||
// GenGetSQL generates Get SQL
|
||||
func (statement *Statement) GenGetSQL(bean interface{}) (string, []interface{}, error) {
|
||||
v := rValue(bean)
|
||||
isStruct := v.Kind() == reflect.Struct
|
||||
|
@ -316,6 +319,7 @@ func (statement *Statement) genSelectSQL(columnStr string, needLimit, needOrderB
|
|||
return buf.String(), condArgs, nil
|
||||
}
|
||||
|
||||
// GenExistSQL generates Exist SQL
|
||||
func (statement *Statement) GenExistSQL(bean ...interface{}) (string, []interface{}, error) {
|
||||
if statement.RawSQL != "" {
|
||||
return statement.GenRawSQL(), statement.RawParams, nil
|
||||
|
@ -385,6 +389,7 @@ func (statement *Statement) GenExistSQL(bean ...interface{}) (string, []interfac
|
|||
return sqlStr, args, nil
|
||||
}
|
||||
|
||||
// GenFindSQL generates Find SQL
|
||||
func (statement *Statement) GenFindSQL(autoCond builder.Cond) (string, []interface{}, error) {
|
||||
if statement.RawSQL != "" {
|
||||
return statement.GenRawSQL(), statement.RawParams, nil
|
||||
|
|
|
@ -90,19 +90,17 @@ func NewStatement(dialect dialects.Dialect, tagParser *tags.Parser, defaultTimeZ
|
|||
return statement
|
||||
}
|
||||
|
||||
// SetTableName set table name
|
||||
func (statement *Statement) SetTableName(tableName string) {
|
||||
statement.tableName = tableName
|
||||
}
|
||||
|
||||
func (statement *Statement) omitStr() string {
|
||||
return statement.dialect.Quoter().Join(statement.OmitColumnMap, " ,")
|
||||
}
|
||||
|
||||
// GenRawSQL generates correct raw sql
|
||||
func (statement *Statement) GenRawSQL() string {
|
||||
return statement.ReplaceQuote(statement.RawSQL)
|
||||
}
|
||||
|
||||
// GenCondSQL generates condition SQL
|
||||
func (statement *Statement) GenCondSQL(condOrBuilder interface{}) (string, []interface{}, error) {
|
||||
condSQL, condArgs, err := builder.ToSQL(condOrBuilder)
|
||||
if err != nil {
|
||||
|
@ -111,6 +109,7 @@ func (statement *Statement) GenCondSQL(condOrBuilder interface{}) (string, []int
|
|||
return statement.ReplaceQuote(condSQL), condArgs, nil
|
||||
}
|
||||
|
||||
// ReplaceQuote replace sql key words with quote
|
||||
func (statement *Statement) ReplaceQuote(sql string) string {
|
||||
if sql == "" || statement.dialect.URI().DBType == schemas.MYSQL ||
|
||||
statement.dialect.URI().DBType == schemas.SQLITE {
|
||||
|
@ -119,11 +118,12 @@ func (statement *Statement) ReplaceQuote(sql string) string {
|
|||
return statement.dialect.Quoter().Replace(sql)
|
||||
}
|
||||
|
||||
// SetContextCache sets context cache
|
||||
func (statement *Statement) SetContextCache(ctxCache contexts.ContextCache) {
|
||||
statement.Context = ctxCache
|
||||
}
|
||||
|
||||
// Init reset all the statement's fields
|
||||
// Reset reset all the statement's fields
|
||||
func (statement *Statement) Reset() {
|
||||
statement.RefTable = nil
|
||||
statement.Start = 0
|
||||
|
@ -163,7 +163,7 @@ func (statement *Statement) Reset() {
|
|||
statement.LastError = nil
|
||||
}
|
||||
|
||||
// NoAutoCondition if you do not want convert bean's field as query condition, then use this function
|
||||
// SetNoAutoCondition if you do not want convert bean's field as query condition, then use this function
|
||||
func (statement *Statement) SetNoAutoCondition(no ...bool) *Statement {
|
||||
statement.NoAutoCondition = true
|
||||
if len(no) > 0 {
|
||||
|
@ -271,6 +271,7 @@ func (statement *Statement) NotIn(column string, args ...interface{}) *Statement
|
|||
return statement
|
||||
}
|
||||
|
||||
// SetRefValue set ref value
|
||||
func (statement *Statement) SetRefValue(v reflect.Value) error {
|
||||
var err error
|
||||
statement.RefTable, err = statement.tagParser.ParseWithCache(reflect.Indirect(v))
|
||||
|
@ -285,6 +286,7 @@ func rValue(bean interface{}) reflect.Value {
|
|||
return reflect.Indirect(reflect.ValueOf(bean))
|
||||
}
|
||||
|
||||
// SetRefBean set ref bean
|
||||
func (statement *Statement) SetRefBean(bean interface{}) error {
|
||||
var err error
|
||||
statement.RefTable, err = statement.tagParser.ParseWithCache(rValue(bean))
|
||||
|
@ -390,6 +392,7 @@ func (statement *Statement) Cols(columns ...string) *Statement {
|
|||
return statement
|
||||
}
|
||||
|
||||
// ColumnStr returns column string
|
||||
func (statement *Statement) ColumnStr() string {
|
||||
return statement.dialect.Quoter().Join(statement.ColumnMap, ", ")
|
||||
}
|
||||
|
@ -493,11 +496,12 @@ func (statement *Statement) Asc(colNames ...string) *Statement {
|
|||
return statement
|
||||
}
|
||||
|
||||
// Conds returns condtions
|
||||
func (statement *Statement) Conds() builder.Cond {
|
||||
return statement.cond
|
||||
}
|
||||
|
||||
// Table tempororily set table name, the parameter could be a string or a pointer of struct
|
||||
// SetTable tempororily set table name, the parameter could be a string or a pointer of struct
|
||||
func (statement *Statement) SetTable(tableNameOrBean interface{}) error {
|
||||
v := rValue(tableNameOrBean)
|
||||
t := v.Type()
|
||||
|
@ -564,7 +568,7 @@ func (statement *Statement) Join(joinOP string, tablename interface{}, condition
|
|||
return statement
|
||||
}
|
||||
|
||||
// tbName get some table's table name
|
||||
// tbNameNoSchema get some table's table name
|
||||
func (statement *Statement) tbNameNoSchema(table *schemas.Table) string {
|
||||
if len(statement.AltTableName) > 0 {
|
||||
return statement.AltTableName
|
||||
|
@ -585,12 +589,13 @@ func (statement *Statement) Having(conditions string) *Statement {
|
|||
return statement
|
||||
}
|
||||
|
||||
// Unscoped always disable struct tag "deleted"
|
||||
// SetUnscoped always disable struct tag "deleted"
|
||||
func (statement *Statement) SetUnscoped() *Statement {
|
||||
statement.unscoped = true
|
||||
return statement
|
||||
}
|
||||
|
||||
// GetUnscoped return true if it's unscoped
|
||||
func (statement *Statement) GetUnscoped() bool {
|
||||
return statement.unscoped
|
||||
}
|
||||
|
@ -636,6 +641,7 @@ func (statement *Statement) genColumnStr() string {
|
|||
return buf.String()
|
||||
}
|
||||
|
||||
// GenCreateTableSQL generated create table SQL
|
||||
func (statement *Statement) GenCreateTableSQL() []string {
|
||||
statement.RefTable.StoreEngine = statement.StoreEngine
|
||||
statement.RefTable.Charset = statement.Charset
|
||||
|
@ -643,6 +649,7 @@ func (statement *Statement) GenCreateTableSQL() []string {
|
|||
return s
|
||||
}
|
||||
|
||||
// GenIndexSQL generated create index SQL
|
||||
func (statement *Statement) GenIndexSQL() []string {
|
||||
var sqls []string
|
||||
tbName := statement.TableName()
|
||||
|
@ -659,6 +666,7 @@ func uniqueName(tableName, uqeName string) string {
|
|||
return fmt.Sprintf("UQE_%v_%v", tableName, uqeName)
|
||||
}
|
||||
|
||||
// GenUniqueSQL generates unique SQL
|
||||
func (statement *Statement) GenUniqueSQL() []string {
|
||||
var sqls []string
|
||||
tbName := statement.TableName()
|
||||
|
@ -671,6 +679,7 @@ func (statement *Statement) GenUniqueSQL() []string {
|
|||
return sqls
|
||||
}
|
||||
|
||||
// GenDelIndexSQL generate delete index SQL
|
||||
func (statement *Statement) GenDelIndexSQL() []string {
|
||||
var sqls []string
|
||||
tbName := statement.TableName()
|
||||
|
@ -896,6 +905,7 @@ func (statement *Statement) buildConds2(table *schemas.Table, bean interface{},
|
|||
return builder.And(conds...), nil
|
||||
}
|
||||
|
||||
// BuildConds builds condition
|
||||
func (statement *Statement) BuildConds(table *schemas.Table, bean interface{}, includeVersion bool, includeUpdated bool, includeNil bool, includeAutoIncr bool, addedTableName bool) (builder.Cond, error) {
|
||||
return statement.buildConds2(table, bean, includeVersion, includeUpdated, includeNil, includeAutoIncr, statement.allUseBool, statement.useAllCols,
|
||||
statement.unscoped, statement.MustColumnMap, statement.TableName(), statement.TableAlias, addedTableName)
|
||||
|
@ -911,12 +921,10 @@ func (statement *Statement) mergeConds(bean interface{}) error {
|
|||
statement.cond = statement.cond.And(autoCond)
|
||||
}
|
||||
|
||||
if err := statement.ProcessIDParam(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return statement.ProcessIDParam()
|
||||
}
|
||||
|
||||
// GenConds generates conditions
|
||||
func (statement *Statement) GenConds(bean interface{}) (string, []interface{}, error) {
|
||||
if err := statement.mergeConds(bean); err != nil {
|
||||
return "", nil, err
|
||||
|
@ -930,6 +938,7 @@ func (statement *Statement) quoteColumnStr(columnStr string) string {
|
|||
return statement.dialect.Quoter().Join(columns, ",")
|
||||
}
|
||||
|
||||
// ConvertSQLOrArgs converts sql or args
|
||||
func (statement *Statement) ConvertSQLOrArgs(sqlOrArgs ...interface{}) (string, []interface{}, error) {
|
||||
sql, args, err := convertSQLOrArgs(sqlOrArgs...)
|
||||
if err != nil {
|
||||
|
|
|
@ -77,6 +77,7 @@ func convertArg(arg interface{}, convertFunc func(string) string) string {
|
|||
|
||||
const insertSelectPlaceHolder = true
|
||||
|
||||
// WriteArg writes an arg
|
||||
func (statement *Statement) WriteArg(w *builder.BytesWriter, arg interface{}) error {
|
||||
switch argv := arg.(type) {
|
||||
case *builder.Builder:
|
||||
|
@ -116,6 +117,7 @@ func (statement *Statement) WriteArg(w *builder.BytesWriter, arg interface{}) er
|
|||
return nil
|
||||
}
|
||||
|
||||
// WriteArgs writes args
|
||||
func (statement *Statement) WriteArgs(w *builder.BytesWriter, args []interface{}) error {
|
||||
for i, arg := range args {
|
||||
if err := statement.WriteArg(w, arg); err != nil {
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"fmt"
|
||||
)
|
||||
|
||||
// IndexName returns index name
|
||||
func IndexName(tableName, idxName string) string {
|
||||
return fmt.Sprintf("IDX_%v_%v", tableName, idxName)
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"reflect"
|
||||
)
|
||||
|
||||
// ReflectValue returns value of a bean
|
||||
func ReflectValue(bean interface{}) reflect.Value {
|
||||
return reflect.Indirect(reflect.ValueOf(bean))
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
// IsSubQuery returns true if it contains a sub query
|
||||
func IsSubQuery(tbName string) bool {
|
||||
const selStr = "select"
|
||||
if len(tbName) <= len(selStr)+1 {
|
||||
|
|
|
@ -8,10 +8,12 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
// IndexNoCase index a string in a string with no care of capitalize
|
||||
func IndexNoCase(s, sep string) int {
|
||||
return strings.Index(strings.ToLower(s), strings.ToLower(sep))
|
||||
}
|
||||
|
||||
// SplitNoCase split a string by a seperator with no care of capitalize
|
||||
func SplitNoCase(s, sep string) []string {
|
||||
idx := IndexNoCase(s, sep)
|
||||
if idx < 0 {
|
||||
|
@ -20,6 +22,7 @@ func SplitNoCase(s, sep string) []string {
|
|||
return strings.Split(s, s[idx:idx+len(sep)])
|
||||
}
|
||||
|
||||
// SplitNNoCase split n by a seperator with no care of capitalize
|
||||
func SplitNNoCase(s, sep string, n int) []string {
|
||||
idx := IndexNoCase(s, sep)
|
||||
if idx < 0 {
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// Zeroable represents an interface which could know if it's a zero value
|
||||
type Zeroable interface {
|
||||
IsZero() bool
|
||||
}
|
||||
|
@ -21,39 +22,39 @@ func IsZero(k interface{}) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
switch k.(type) {
|
||||
switch t := k.(type) {
|
||||
case int:
|
||||
return k.(int) == 0
|
||||
return t == 0
|
||||
case int8:
|
||||
return k.(int8) == 0
|
||||
return t == 0
|
||||
case int16:
|
||||
return k.(int16) == 0
|
||||
return t == 0
|
||||
case int32:
|
||||
return k.(int32) == 0
|
||||
return t == 0
|
||||
case int64:
|
||||
return k.(int64) == 0
|
||||
return t == 0
|
||||
case uint:
|
||||
return k.(uint) == 0
|
||||
return t == 0
|
||||
case uint8:
|
||||
return k.(uint8) == 0
|
||||
return t == 0
|
||||
case uint16:
|
||||
return k.(uint16) == 0
|
||||
return t == 0
|
||||
case uint32:
|
||||
return k.(uint32) == 0
|
||||
return t == 0
|
||||
case uint64:
|
||||
return k.(uint64) == 0
|
||||
return t == 0
|
||||
case float32:
|
||||
return k.(float32) == 0
|
||||
return t == 0
|
||||
case float64:
|
||||
return k.(float64) == 0
|
||||
return t == 0
|
||||
case bool:
|
||||
return k.(bool) == false
|
||||
return !t
|
||||
case string:
|
||||
return k.(string) == ""
|
||||
return t == ""
|
||||
case *time.Time:
|
||||
return k.(*time.Time) == nilTime || IsTimeZero(*k.(*time.Time))
|
||||
return t == nilTime || IsTimeZero(*t)
|
||||
case time.Time:
|
||||
return IsTimeZero(k.(time.Time))
|
||||
return IsTimeZero(t)
|
||||
case Zeroable:
|
||||
return k.(Zeroable) == nil || k.(Zeroable).IsZero()
|
||||
case reflect.Value: // for go version less than 1.13 because reflect.Value has no method IsZero
|
||||
|
@ -65,6 +66,7 @@ func IsZero(k interface{}) bool {
|
|||
|
||||
var zeroType = reflect.TypeOf((*Zeroable)(nil)).Elem()
|
||||
|
||||
// IsValueZero returns true if the reflect Value is a zero
|
||||
func IsValueZero(v reflect.Value) bool {
|
||||
switch v.Kind() {
|
||||
case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Slice:
|
||||
|
@ -88,6 +90,7 @@ func IsValueZero(v reflect.Value) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// IsStructZero returns true if the Value is a struct and all fields is zero
|
||||
func IsStructZero(v reflect.Value) bool {
|
||||
if !v.IsValid() || v.NumField() == 0 {
|
||||
return true
|
||||
|
@ -120,6 +123,7 @@ func IsStructZero(v reflect.Value) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
// IsArrayZero returns true is a slice of array is zero
|
||||
func IsArrayZero(v reflect.Value) bool {
|
||||
if !v.IsValid() || v.Len() == 0 {
|
||||
return true
|
||||
|
@ -134,11 +138,13 @@ func IsArrayZero(v reflect.Value) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
// represents all zero times
|
||||
const (
|
||||
ZeroTime0 = "0000-00-00 00:00:00"
|
||||
ZeroTime1 = "0001-01-01 00:00:00"
|
||||
)
|
||||
|
||||
// IsTimeZero return true if a time is zero
|
||||
func IsTimeZero(t time.Time) bool {
|
||||
return t.IsZero() || t.Format("2006-01-02 15:04:05") == ZeroTime0 ||
|
||||
t.Format("2006-01-02 15:04:05") == ZeroTime1
|
||||
|
|
|
@ -16,6 +16,7 @@ type Mapper interface {
|
|||
Table2Obj(string) string
|
||||
}
|
||||
|
||||
// CacheMapper represents a cache mapper
|
||||
type CacheMapper struct {
|
||||
oriMapper Mapper
|
||||
obj2tableCache map[string]string
|
||||
|
@ -24,12 +25,14 @@ type CacheMapper struct {
|
|||
table2objMutex sync.RWMutex
|
||||
}
|
||||
|
||||
// NewCacheMapper creates a cache mapper
|
||||
func NewCacheMapper(mapper Mapper) *CacheMapper {
|
||||
return &CacheMapper{oriMapper: mapper, obj2tableCache: make(map[string]string),
|
||||
table2objCache: make(map[string]string),
|
||||
}
|
||||
}
|
||||
|
||||
// Obj2Table implements Mapper
|
||||
func (m *CacheMapper) Obj2Table(o string) string {
|
||||
m.obj2tableMutex.RLock()
|
||||
t, ok := m.obj2tableCache[o]
|
||||
|
@ -45,6 +48,7 @@ func (m *CacheMapper) Obj2Table(o string) string {
|
|||
return t
|
||||
}
|
||||
|
||||
// Table2Obj implements Mapper
|
||||
func (m *CacheMapper) Table2Obj(t string) string {
|
||||
m.table2objMutex.RLock()
|
||||
o, ok := m.table2objCache[t]
|
||||
|
@ -60,15 +64,17 @@ func (m *CacheMapper) Table2Obj(t string) string {
|
|||
return o
|
||||
}
|
||||
|
||||
// SameMapper implements IMapper and provides same name between struct and
|
||||
// SameMapper implements Mapper and provides same name between struct and
|
||||
// database table
|
||||
type SameMapper struct {
|
||||
}
|
||||
|
||||
// Obj2Table implements Mapper
|
||||
func (m SameMapper) Obj2Table(o string) string {
|
||||
return o
|
||||
}
|
||||
|
||||
// Table2Obj implements Mapper
|
||||
func (m SameMapper) Table2Obj(t string) string {
|
||||
return t
|
||||
}
|
||||
|
@ -98,6 +104,7 @@ func snakeCasedName(name string) string {
|
|||
return b2s(newstr)
|
||||
}
|
||||
|
||||
// Obj2Table implements Mapper
|
||||
func (mapper SnakeMapper) Obj2Table(name string) string {
|
||||
return snakeCasedName(name)
|
||||
}
|
||||
|
@ -127,6 +134,7 @@ func titleCasedName(name string) string {
|
|||
return b2s(newstr)
|
||||
}
|
||||
|
||||
// Table2Obj implements Mapper
|
||||
func (mapper SnakeMapper) Table2Obj(name string) string {
|
||||
return titleCasedName(name)
|
||||
}
|
||||
|
@ -168,10 +176,12 @@ func gonicCasedName(name string) string {
|
|||
return strings.ToLower(string(newstr))
|
||||
}
|
||||
|
||||
// Obj2Table implements Mapper
|
||||
func (mapper GonicMapper) Obj2Table(name string) string {
|
||||
return gonicCasedName(name)
|
||||
}
|
||||
|
||||
// Table2Obj implements Mapper
|
||||
func (mapper GonicMapper) Table2Obj(name string) string {
|
||||
newstr := make([]rune, 0)
|
||||
|
||||
|
@ -234,14 +244,17 @@ type PrefixMapper struct {
|
|||
Prefix string
|
||||
}
|
||||
|
||||
// Obj2Table implements Mapper
|
||||
func (mapper PrefixMapper) Obj2Table(name string) string {
|
||||
return mapper.Prefix + mapper.Mapper.Obj2Table(name)
|
||||
}
|
||||
|
||||
// Table2Obj implements Mapper
|
||||
func (mapper PrefixMapper) Table2Obj(name string) string {
|
||||
return mapper.Mapper.Table2Obj(name[len(mapper.Prefix):])
|
||||
}
|
||||
|
||||
// NewPrefixMapper creates a prefix mapper
|
||||
func NewPrefixMapper(mapper Mapper, prefix string) PrefixMapper {
|
||||
return PrefixMapper{mapper, prefix}
|
||||
}
|
||||
|
@ -252,14 +265,17 @@ type SuffixMapper struct {
|
|||
Suffix string
|
||||
}
|
||||
|
||||
// Obj2Table implements Mapper
|
||||
func (mapper SuffixMapper) Obj2Table(name string) string {
|
||||
return mapper.Mapper.Obj2Table(name) + mapper.Suffix
|
||||
}
|
||||
|
||||
// Table2Obj implements Mapper
|
||||
func (mapper SuffixMapper) Table2Obj(name string) string {
|
||||
return mapper.Mapper.Table2Obj(name[:len(name)-len(mapper.Suffix)])
|
||||
}
|
||||
|
||||
// NewSuffixMapper creates a suffix mapper
|
||||
func NewSuffixMapper(mapper Mapper, suffix string) SuffixMapper {
|
||||
return SuffixMapper{mapper, suffix}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ var (
|
|||
tvCache sync.Map
|
||||
)
|
||||
|
||||
// GetTableName returns table name
|
||||
func GetTableName(mapper Mapper, v reflect.Value) string {
|
||||
if v.Type().Implements(tpTableName) {
|
||||
return v.Interface().(TableName).TableName()
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// enumerates all database mapping way
|
||||
const (
|
||||
TWOSIDES = iota + 1
|
||||
ONLYTODB
|
||||
|
|
|
@ -28,6 +28,7 @@ func NewIndex(name string, indexType int) *Index {
|
|||
return &Index{true, name, indexType, make([]string, 0)}
|
||||
}
|
||||
|
||||
// XName returns the special index name for the table
|
||||
func (index *Index) XName(tableName string) string {
|
||||
if !strings.HasPrefix(index.Name, "UQE_") &&
|
||||
!strings.HasPrefix(index.Name, "IDX_") {
|
||||
|
@ -43,11 +44,10 @@ func (index *Index) XName(tableName string) string {
|
|||
|
||||
// AddColumn add columns which will be composite index
|
||||
func (index *Index) AddColumn(cols ...string) {
|
||||
for _, col := range cols {
|
||||
index.Cols = append(index.Cols, col)
|
||||
}
|
||||
index.Cols = append(index.Cols, cols...)
|
||||
}
|
||||
|
||||
// Equal return true if the two Index is equal
|
||||
func (index *Index) Equal(dst *Index) bool {
|
||||
if index.Type != dst.Type {
|
||||
return false
|
||||
|
|
|
@ -11,13 +11,16 @@ import (
|
|||
"xorm.io/xorm/internal/utils"
|
||||
)
|
||||
|
||||
// PK represents primary key values
|
||||
type PK []interface{}
|
||||
|
||||
// NewPK creates primay keys
|
||||
func NewPK(pks ...interface{}) *PK {
|
||||
p := PK(pks)
|
||||
return &p
|
||||
}
|
||||
|
||||
// IsZero return true if primay keys are zero
|
||||
func (p *PK) IsZero() bool {
|
||||
for _, k := range *p {
|
||||
if utils.IsZero(k) {
|
||||
|
@ -27,6 +30,7 @@ func (p *PK) IsZero() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// ToString convert to SQL string
|
||||
func (p *PK) ToString() (string, error) {
|
||||
buf := new(bytes.Buffer)
|
||||
enc := gob.NewEncoder(buf)
|
||||
|
@ -34,6 +38,7 @@ func (p *PK) ToString() (string, error) {
|
|||
return buf.String(), err
|
||||
}
|
||||
|
||||
// FromString reads content to load primary keys
|
||||
func (p *PK) FromString(content string) error {
|
||||
dec := gob.NewDecoder(bytes.NewBufferString(content))
|
||||
err := dec.Decode(p)
|
||||
|
|
|
@ -16,10 +16,10 @@ type Quoter struct {
|
|||
}
|
||||
|
||||
var (
|
||||
// AlwaysFalseReverse always think it's not a reverse word
|
||||
// AlwaysNoReserve always think it's not a reverse word
|
||||
AlwaysNoReserve = func(string) bool { return false }
|
||||
|
||||
// AlwaysReverse always reverse the word
|
||||
// AlwaysReserve always reverse the word
|
||||
AlwaysReserve = func(string) bool { return true }
|
||||
|
||||
// CommanQuoteMark represnets the common quote mark
|
||||
|
@ -29,10 +29,12 @@ var (
|
|||
CommonQuoter = Quoter{CommanQuoteMark, CommanQuoteMark, AlwaysReserve}
|
||||
)
|
||||
|
||||
// IsEmpty return true if no prefix and suffix
|
||||
func (q Quoter) IsEmpty() bool {
|
||||
return q.Prefix == 0 && q.Suffix == 0
|
||||
}
|
||||
|
||||
// Quote quote a string
|
||||
func (q Quoter) Quote(s string) string {
|
||||
var buf strings.Builder
|
||||
q.QuoteTo(&buf, s)
|
||||
|
@ -59,12 +61,14 @@ func (q Quoter) Trim(s string) string {
|
|||
return buf.String()
|
||||
}
|
||||
|
||||
// Join joins a slice with quoters
|
||||
func (q Quoter) Join(a []string, sep string) string {
|
||||
var b strings.Builder
|
||||
q.JoinWrite(&b, a, sep)
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// JoinWrite writes quoted content to a builder
|
||||
func (q Quoter) JoinWrite(b *strings.Builder, a []string, sep string) error {
|
||||
if len(a) == 0 {
|
||||
return nil
|
||||
|
|
|
@ -90,23 +90,28 @@ func (table *Table) PKColumns() []*Column {
|
|||
return columns
|
||||
}
|
||||
|
||||
// ColumnType returns a column's type
|
||||
func (table *Table) ColumnType(name string) reflect.Type {
|
||||
t, _ := table.Type.FieldByName(name)
|
||||
return t.Type
|
||||
}
|
||||
|
||||
// AutoIncrColumn returns autoincrement column
|
||||
func (table *Table) AutoIncrColumn() *Column {
|
||||
return table.GetColumn(table.AutoIncrement)
|
||||
}
|
||||
|
||||
// VersionColumn returns version column's information
|
||||
func (table *Table) VersionColumn() *Column {
|
||||
return table.GetColumn(table.Version)
|
||||
}
|
||||
|
||||
// UpdatedColumn returns updated column's information
|
||||
func (table *Table) UpdatedColumn() *Column {
|
||||
return table.GetColumn(table.Updated)
|
||||
}
|
||||
|
||||
// DeletedColumn returns deleted column's information
|
||||
func (table *Table) DeletedColumn() *Column {
|
||||
return table.GetColumn(table.Deleted)
|
||||
}
|
||||
|
|
|
@ -11,8 +11,10 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// DBType represents a database type
|
||||
type DBType string
|
||||
|
||||
// enumerates all database types
|
||||
const (
|
||||
POSTGRES DBType = "postgres"
|
||||
SQLITE DBType = "sqlite3"
|
||||
|
@ -28,6 +30,7 @@ type SQLType struct {
|
|||
DefaultLength2 int
|
||||
}
|
||||
|
||||
// enumerates all columns types
|
||||
const (
|
||||
UNKNOW_TYPE = iota
|
||||
TEXT_TYPE
|
||||
|
@ -37,6 +40,7 @@ const (
|
|||
ARRAY_TYPE
|
||||
)
|
||||
|
||||
// IsType reutrns ture if the column type is the same as the parameter
|
||||
func (s *SQLType) IsType(st int) bool {
|
||||
if t, ok := SqlTypes[s.Name]; ok && t == st {
|
||||
return true
|
||||
|
@ -44,42 +48,53 @@ func (s *SQLType) IsType(st int) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// IsText returns true if column is a text type
|
||||
func (s *SQLType) IsText() bool {
|
||||
return s.IsType(TEXT_TYPE)
|
||||
}
|
||||
|
||||
// IsBlob returns true if column is a binary type
|
||||
func (s *SQLType) IsBlob() bool {
|
||||
return s.IsType(BLOB_TYPE)
|
||||
}
|
||||
|
||||
// IsTime returns true if column is a time type
|
||||
func (s *SQLType) IsTime() bool {
|
||||
return s.IsType(TIME_TYPE)
|
||||
}
|
||||
|
||||
// IsNumeric returns true if column is a numeric type
|
||||
func (s *SQLType) IsNumeric() bool {
|
||||
return s.IsType(NUMERIC_TYPE)
|
||||
}
|
||||
|
||||
// IsArray returns true if column is an array type
|
||||
func (s *SQLType) IsArray() bool {
|
||||
return s.IsType(ARRAY_TYPE)
|
||||
}
|
||||
|
||||
// IsJson returns true if column is an array type
|
||||
func (s *SQLType) IsJson() bool {
|
||||
return s.Name == Json || s.Name == Jsonb
|
||||
}
|
||||
|
||||
// IsXML returns true if column is an xml type
|
||||
func (s *SQLType) IsXML() bool {
|
||||
return s.Name == XML
|
||||
}
|
||||
|
||||
// enumerates all the database column types
|
||||
var (
|
||||
Bit = "BIT"
|
||||
TinyInt = "TINYINT"
|
||||
SmallInt = "SMALLINT"
|
||||
MediumInt = "MEDIUMINT"
|
||||
Int = "INT"
|
||||
Integer = "INTEGER"
|
||||
BigInt = "BIGINT"
|
||||
Bit = "BIT"
|
||||
UnsignedBit = "UNSIGNED BIT"
|
||||
TinyInt = "TINYINT"
|
||||
SmallInt = "SMALLINT"
|
||||
MediumInt = "MEDIUMINT"
|
||||
Int = "INT"
|
||||
UnsignedInt = "UNSIGNED INT"
|
||||
Integer = "INTEGER"
|
||||
BigInt = "BIGINT"
|
||||
UnsignedBigInt = "UNSIGNED BIGINT"
|
||||
|
||||
Enum = "ENUM"
|
||||
Set = "SET"
|
||||
|
@ -136,13 +151,16 @@ var (
|
|||
Array = "ARRAY"
|
||||
|
||||
SqlTypes = map[string]int{
|
||||
Bit: NUMERIC_TYPE,
|
||||
TinyInt: NUMERIC_TYPE,
|
||||
SmallInt: NUMERIC_TYPE,
|
||||
MediumInt: NUMERIC_TYPE,
|
||||
Int: NUMERIC_TYPE,
|
||||
Integer: NUMERIC_TYPE,
|
||||
BigInt: NUMERIC_TYPE,
|
||||
Bit: NUMERIC_TYPE,
|
||||
UnsignedBit: NUMERIC_TYPE,
|
||||
TinyInt: NUMERIC_TYPE,
|
||||
SmallInt: NUMERIC_TYPE,
|
||||
MediumInt: NUMERIC_TYPE,
|
||||
Int: NUMERIC_TYPE,
|
||||
UnsignedInt: NUMERIC_TYPE,
|
||||
Integer: NUMERIC_TYPE,
|
||||
BigInt: NUMERIC_TYPE,
|
||||
UnsignedBigInt: NUMERIC_TYPE,
|
||||
|
||||
Enum: TEXT_TYPE,
|
||||
Set: TEXT_TYPE,
|
||||
|
@ -204,53 +222,55 @@ var (
|
|||
|
||||
// !nashtsai! treat following var as interal const values, these are used for reflect.TypeOf comparison
|
||||
var (
|
||||
c_EMPTY_STRING string
|
||||
c_BOOL_DEFAULT bool
|
||||
c_BYTE_DEFAULT byte
|
||||
c_COMPLEX64_DEFAULT complex64
|
||||
c_COMPLEX128_DEFAULT complex128
|
||||
c_FLOAT32_DEFAULT float32
|
||||
c_FLOAT64_DEFAULT float64
|
||||
c_INT64_DEFAULT int64
|
||||
c_UINT64_DEFAULT uint64
|
||||
c_INT32_DEFAULT int32
|
||||
c_UINT32_DEFAULT uint32
|
||||
c_INT16_DEFAULT int16
|
||||
c_UINT16_DEFAULT uint16
|
||||
c_INT8_DEFAULT int8
|
||||
c_UINT8_DEFAULT uint8
|
||||
c_INT_DEFAULT int
|
||||
c_UINT_DEFAULT uint
|
||||
c_TIME_DEFAULT time.Time
|
||||
emptyString string
|
||||
boolDefault bool
|
||||
byteDefault byte
|
||||
complex64Default complex64
|
||||
complex128Default complex128
|
||||
float32Default float32
|
||||
float64Default float64
|
||||
int64Default int64
|
||||
uint64Default uint64
|
||||
int32Default int32
|
||||
uint32Default uint32
|
||||
int16Default int16
|
||||
uint16Default uint16
|
||||
int8Default int8
|
||||
uint8Default uint8
|
||||
intDefault int
|
||||
uintDefault uint
|
||||
timeDefault time.Time
|
||||
)
|
||||
|
||||
// enumerates all types
|
||||
var (
|
||||
IntType = reflect.TypeOf(c_INT_DEFAULT)
|
||||
Int8Type = reflect.TypeOf(c_INT8_DEFAULT)
|
||||
Int16Type = reflect.TypeOf(c_INT16_DEFAULT)
|
||||
Int32Type = reflect.TypeOf(c_INT32_DEFAULT)
|
||||
Int64Type = reflect.TypeOf(c_INT64_DEFAULT)
|
||||
IntType = reflect.TypeOf(intDefault)
|
||||
Int8Type = reflect.TypeOf(int8Default)
|
||||
Int16Type = reflect.TypeOf(int16Default)
|
||||
Int32Type = reflect.TypeOf(int32Default)
|
||||
Int64Type = reflect.TypeOf(int64Default)
|
||||
|
||||
UintType = reflect.TypeOf(c_UINT_DEFAULT)
|
||||
Uint8Type = reflect.TypeOf(c_UINT8_DEFAULT)
|
||||
Uint16Type = reflect.TypeOf(c_UINT16_DEFAULT)
|
||||
Uint32Type = reflect.TypeOf(c_UINT32_DEFAULT)
|
||||
Uint64Type = reflect.TypeOf(c_UINT64_DEFAULT)
|
||||
UintType = reflect.TypeOf(uintDefault)
|
||||
Uint8Type = reflect.TypeOf(uint8Default)
|
||||
Uint16Type = reflect.TypeOf(uint16Default)
|
||||
Uint32Type = reflect.TypeOf(uint32Default)
|
||||
Uint64Type = reflect.TypeOf(uint64Default)
|
||||
|
||||
Float32Type = reflect.TypeOf(c_FLOAT32_DEFAULT)
|
||||
Float64Type = reflect.TypeOf(c_FLOAT64_DEFAULT)
|
||||
Float32Type = reflect.TypeOf(float32Default)
|
||||
Float64Type = reflect.TypeOf(float64Default)
|
||||
|
||||
Complex64Type = reflect.TypeOf(c_COMPLEX64_DEFAULT)
|
||||
Complex128Type = reflect.TypeOf(c_COMPLEX128_DEFAULT)
|
||||
Complex64Type = reflect.TypeOf(complex64Default)
|
||||
Complex128Type = reflect.TypeOf(complex128Default)
|
||||
|
||||
StringType = reflect.TypeOf(c_EMPTY_STRING)
|
||||
BoolType = reflect.TypeOf(c_BOOL_DEFAULT)
|
||||
ByteType = reflect.TypeOf(c_BYTE_DEFAULT)
|
||||
StringType = reflect.TypeOf(emptyString)
|
||||
BoolType = reflect.TypeOf(boolDefault)
|
||||
ByteType = reflect.TypeOf(byteDefault)
|
||||
BytesType = reflect.SliceOf(ByteType)
|
||||
|
||||
TimeType = reflect.TypeOf(c_TIME_DEFAULT)
|
||||
TimeType = reflect.TypeOf(timeDefault)
|
||||
)
|
||||
|
||||
// enumerates all types
|
||||
var (
|
||||
PtrIntType = reflect.PtrTo(IntType)
|
||||
PtrInt8Type = reflect.PtrTo(Int8Type)
|
||||
|
@ -280,10 +300,14 @@ var (
|
|||
// Type2SQLType generate SQLType acorrding Go's type
|
||||
func Type2SQLType(t reflect.Type) (st SQLType) {
|
||||
switch k := t.Kind(); k {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32:
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32:
|
||||
st = SQLType{Int, 0, 0}
|
||||
case reflect.Int64, reflect.Uint64:
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32:
|
||||
st = SQLType{UnsignedInt, 0, 0}
|
||||
case reflect.Int64:
|
||||
st = SQLType{BigInt, 0, 0}
|
||||
case reflect.Uint64:
|
||||
st = SQLType{UnsignedBigInt, 0, 0}
|
||||
case reflect.Float32:
|
||||
st = SQLType{Float, 0, 0}
|
||||
case reflect.Float64:
|
||||
|
@ -291,7 +315,7 @@ func Type2SQLType(t reflect.Type) (st SQLType) {
|
|||
case reflect.Complex64, reflect.Complex128:
|
||||
st = SQLType{Varchar, 64, 0}
|
||||
case reflect.Array, reflect.Slice, reflect.Map:
|
||||
if t.Elem() == reflect.TypeOf(c_BYTE_DEFAULT) {
|
||||
if t.Elem() == reflect.TypeOf(byteDefault) {
|
||||
st = SQLType{Blob, 0, 0}
|
||||
} else {
|
||||
st = SQLType{Text, 0, 0}
|
||||
|
@ -315,7 +339,7 @@ func Type2SQLType(t reflect.Type) (st SQLType) {
|
|||
return
|
||||
}
|
||||
|
||||
// default sql type change to go types
|
||||
// SQLType2Type convert default sql type change to go types
|
||||
func SQLType2Type(st SQLType) reflect.Type {
|
||||
name := strings.ToUpper(st.Name)
|
||||
switch name {
|
||||
|
@ -334,7 +358,7 @@ func SQLType2Type(st SQLType) reflect.Type {
|
|||
case Bool:
|
||||
return reflect.TypeOf(true)
|
||||
case DateTime, Date, Time, TimeStamp, TimeStampz, SmallDateTime, Year:
|
||||
return reflect.TypeOf(c_TIME_DEFAULT)
|
||||
return reflect.TypeOf(timeDefault)
|
||||
case Decimal, Numeric, Money, SmallMoney:
|
||||
return reflect.TypeOf("")
|
||||
default:
|
||||
|
|
|
@ -169,6 +169,7 @@ func (session *Session) db() *core.DB {
|
|||
return session.engine.db
|
||||
}
|
||||
|
||||
// Engine returns session Engine
|
||||
func (session *Session) Engine() *Engine {
|
||||
return session.engine
|
||||
}
|
||||
|
@ -895,7 +896,7 @@ func (session *Session) incrVersionFieldValue(fieldValue *reflect.Value) {
|
|||
}
|
||||
}
|
||||
|
||||
// ContextHook sets the context on this session
|
||||
// Context sets the context on this session
|
||||
func (session *Session) Context(ctx context.Context) *Session {
|
||||
session.ctx = ctx
|
||||
return session
|
||||
|
|
|
@ -168,29 +168,7 @@ func (session *Session) bytes2Value(col *schemas.Column, fieldValue *reflect.Val
|
|||
} else if strings.EqualFold(sdata, "false") {
|
||||
x = 0
|
||||
} else {
|
||||
if col.SQLType.Name == schemas.DateTime {
|
||||
if len(sdata) == 20 {
|
||||
t, err := time.Parse("2006-01-02T15:04:05Z", sdata)
|
||||
if err != nil {
|
||||
return fmt.Errorf("arg %v as int: %s", key, err.Error())
|
||||
}
|
||||
x = t.Unix()
|
||||
} else if len(sdata) == 19 {
|
||||
var parseFormat = "2006-01-02 15:04:05"
|
||||
if sdata[10] == 'T' {
|
||||
parseFormat = "2006-01-02T15:04:05"
|
||||
}
|
||||
t, err := time.Parse(parseFormat, sdata)
|
||||
if err != nil {
|
||||
return fmt.Errorf("arg %v as int: %s", key, err.Error())
|
||||
}
|
||||
x = t.Unix()
|
||||
} else {
|
||||
x, err = strconv.ParseInt(sdata, 10, 64)
|
||||
}
|
||||
} else {
|
||||
x, err = strconv.ParseInt(sdata, 10, 64)
|
||||
}
|
||||
x, err = strconv.ParseInt(sdata, 10, 64)
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("arg %v as int: %s", key, err.Error())
|
||||
|
|
|
@ -16,6 +16,11 @@ import (
|
|||
"xorm.io/xorm/schemas"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrObjectIsNil return error of object is nil
|
||||
ErrObjectIsNil = errors.New("object should not be nil")
|
||||
)
|
||||
|
||||
// Get retrieve one record from database, bean's non-empty fields
|
||||
// will be as conditions
|
||||
func (session *Session) Get(bean interface{}) (bool, error) {
|
||||
|
@ -37,6 +42,8 @@ func (session *Session) get(bean interface{}) (bool, error) {
|
|||
return false, errors.New("needs a pointer to a value")
|
||||
} else if beanValue.Elem().Kind() == reflect.Ptr {
|
||||
return false, errors.New("a pointer to a pointer is not allowed")
|
||||
} else if beanValue.IsNil() {
|
||||
return false, ErrObjectIsNil
|
||||
}
|
||||
|
||||
if beanValue.Elem().Kind() == reflect.Struct {
|
||||
|
|
|
@ -448,27 +448,43 @@ func (session *Session) ImportFile(ddlPath string) ([]sql.Result, error) {
|
|||
|
||||
// Import SQL DDL from io.Reader
|
||||
func (session *Session) Import(r io.Reader) ([]sql.Result, error) {
|
||||
var results []sql.Result
|
||||
var lastError error
|
||||
scanner := bufio.NewScanner(r)
|
||||
var (
|
||||
results []sql.Result
|
||||
lastError error
|
||||
inSingleQuote bool
|
||||
startComment bool
|
||||
)
|
||||
|
||||
var inSingleQuote bool
|
||||
scanner := bufio.NewScanner(r)
|
||||
semiColSpliter := func(data []byte, atEOF bool) (advance int, token []byte, err error) {
|
||||
if atEOF && len(data) == 0 {
|
||||
return 0, nil, nil
|
||||
}
|
||||
var oriInSingleQuote = inSingleQuote
|
||||
for i, b := range data {
|
||||
if b == '\'' {
|
||||
inSingleQuote = !inSingleQuote
|
||||
}
|
||||
if !inSingleQuote && b == ';' {
|
||||
return i + 1, data[0:i], nil
|
||||
if startComment {
|
||||
if b == '\n' {
|
||||
startComment = false
|
||||
}
|
||||
} else {
|
||||
if i > 0 && data[i-1] == '-' && data[i] == '-' {
|
||||
startComment = true
|
||||
continue
|
||||
}
|
||||
|
||||
if b == '\'' {
|
||||
inSingleQuote = !inSingleQuote
|
||||
}
|
||||
if !inSingleQuote && b == ';' {
|
||||
return i + 1, data[0:i], nil
|
||||
}
|
||||
}
|
||||
}
|
||||
// If we're at EOF, we have a final, non-terminated line. Return it.
|
||||
if atEOF {
|
||||
return len(data), data, nil
|
||||
}
|
||||
inSingleQuote = oriInSingleQuote
|
||||
// Request more data.
|
||||
return 0, nil, nil
|
||||
}
|
||||
|
@ -479,10 +495,10 @@ func (session *Session) Import(r io.Reader) ([]sql.Result, error) {
|
|||
query := strings.Trim(scanner.Text(), " \t\n\r")
|
||||
if len(query) > 0 {
|
||||
result, err := session.Exec(query)
|
||||
results = append(results, result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
results = append(results, result)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -84,3 +84,8 @@ func (session *Session) Commit() error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsInTx if current session is in a transaction
|
||||
func (session *Session) IsInTx() bool {
|
||||
return !session.isAutoCommit
|
||||
}
|
||||
|
|
|
@ -21,9 +21,11 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
// ErrUnsupportedType represents an unsupported type error
|
||||
ErrUnsupportedType = errors.New("Unsupported type")
|
||||
)
|
||||
|
||||
// Parser represents a parser for xorm tag
|
||||
type Parser struct {
|
||||
identifier string
|
||||
dialect dialects.Dialect
|
||||
|
@ -34,6 +36,7 @@ type Parser struct {
|
|||
tableCache sync.Map // map[reflect.Type]*schemas.Table
|
||||
}
|
||||
|
||||
// NewParser creates a tag parser
|
||||
func NewParser(identifier string, dialect dialects.Dialect, tableMapper, columnMapper names.Mapper, cacherMgr *caches.Manager) *Parser {
|
||||
return &Parser{
|
||||
identifier: identifier,
|
||||
|
@ -45,24 +48,35 @@ func NewParser(identifier string, dialect dialects.Dialect, tableMapper, columnM
|
|||
}
|
||||
}
|
||||
|
||||
// GetTableMapper returns table mapper
|
||||
func (parser *Parser) GetTableMapper() names.Mapper {
|
||||
return parser.tableMapper
|
||||
}
|
||||
|
||||
// SetTableMapper sets table mapper
|
||||
func (parser *Parser) SetTableMapper(mapper names.Mapper) {
|
||||
parser.ClearCaches()
|
||||
parser.tableMapper = mapper
|
||||
}
|
||||
|
||||
// GetColumnMapper returns column mapper
|
||||
func (parser *Parser) GetColumnMapper() names.Mapper {
|
||||
return parser.columnMapper
|
||||
}
|
||||
|
||||
// SetColumnMapper sets column mapper
|
||||
func (parser *Parser) SetColumnMapper(mapper names.Mapper) {
|
||||
parser.ClearCaches()
|
||||
parser.columnMapper = mapper
|
||||
}
|
||||
|
||||
// SetIdentifier sets tag identifier
|
||||
func (parser *Parser) SetIdentifier(identifier string) {
|
||||
parser.ClearCaches()
|
||||
parser.identifier = identifier
|
||||
}
|
||||
|
||||
// ParseWithCache parse a struct with cache
|
||||
func (parser *Parser) ParseWithCache(v reflect.Value) (*schemas.Table, error) {
|
||||
t := v.Type()
|
||||
tableI, ok := parser.tableCache.Load(t)
|
||||
|
|
Loading…
Reference in New Issue