Merge remote-tracking branch 'xorm/v1' into v1
This commit is contained in:
commit
3e6294dc7e
|
@ -13,7 +13,7 @@ jobs:
|
|||
with:
|
||||
fetch-depth: 0
|
||||
- name: setup go
|
||||
uses: actions/setup-go@v4
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '>=1.20.1'
|
||||
- name: Use Go Action
|
||||
|
|
|
@ -33,7 +33,7 @@ jobs:
|
|||
# restore-keys: |
|
||||
# go_cache-${{ github.repository }}-
|
||||
# go_cache-
|
||||
- uses: actions/setup-go@v3
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: 1.20
|
||||
- uses: actions/checkout@v3
|
||||
|
|
|
@ -33,7 +33,7 @@ jobs:
|
|||
# restore-keys: |
|
||||
# go_cache-${{ github.repository }}-
|
||||
# go_cache-
|
||||
- uses: actions/setup-go@v3
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: 1.20
|
||||
- uses: actions/checkout@v3
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
name: test mssql
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
|
||||
env:
|
||||
GOPROXY: https://goproxy.io,direct
|
||||
GOPATH: /go_path
|
||||
GOCACHE: /go_cache
|
||||
RUNNER_TOOL_CACHE: /toolcache # specify with your cache path
|
||||
|
||||
jobs:
|
||||
test-mssql-collation:
|
||||
name: test mssql with collation
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# - name: cache go path
|
||||
# id: cache-go-path
|
||||
# uses: https://github.com/actions/cache@v3
|
||||
# with:
|
||||
# path: /go_path
|
||||
# key: go_path-${{ github.repository }}-${{ github.ref_name }}
|
||||
# restore-keys: |
|
||||
# go_path-${{ github.repository }}-
|
||||
# go_path-
|
||||
# - name: cache go cache
|
||||
# id: cache-go-cache
|
||||
# uses: https://github.com/actions/cache@v3
|
||||
# with:
|
||||
# path: /go_cache
|
||||
# key: go_cache-${{ github.repository }}-${{ github.ref_name }}
|
||||
# restore-keys: |
|
||||
# go_cache-${{ github.repository }}-
|
||||
# go_cache-
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.20
|
||||
- uses: actions/checkout@v3
|
||||
- name: test mssql with collation
|
||||
env:
|
||||
TEST_MSSQL_HOST: mssql2
|
||||
TEST_MSSQL_DBNAME: xorm_test
|
||||
TEST_MSSQL_USERNAME: sa
|
||||
TEST_MSSQL_PASSWORD: "yourStrong(!)Password"
|
||||
TEST_MSSQL_COLLATION: SQL_Latin1_General_CP1_CS_AS
|
||||
run: TEST_MSSQL_DEFAULT_VARCHAR=NVARCHAR TEST_MSSQL_DEFAULT_CHAR=NCHAR make test-mssql
|
||||
|
||||
services:
|
||||
mssql2:
|
||||
image: mcr.microsoft.com/mssql/server:latest
|
||||
env:
|
||||
ACCEPT_EULA: Y
|
||||
SA_PASSWORD: yourStrong(!)Password
|
||||
MSSQL_PID: Standard
|
||||
ports:
|
||||
- 1433:1433
|
|
@ -33,7 +33,7 @@ jobs:
|
|||
# restore-keys: |
|
||||
# go_cache-${{ github.repository }}-
|
||||
# go_cache-
|
||||
- uses: actions/setup-go@v3
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: 1.20
|
||||
- uses: actions/checkout@v3
|
||||
|
|
|
@ -33,7 +33,7 @@ jobs:
|
|||
# restore-keys: |
|
||||
# go_cache-${{ github.repository }}-
|
||||
# go_cache-
|
||||
- uses: actions/setup-go@v3
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: 1.20
|
||||
- uses: actions/checkout@v3
|
||||
|
|
|
@ -33,7 +33,7 @@ jobs:
|
|||
# restore-keys: |
|
||||
# go_cache-${{ github.repository }}-
|
||||
# go_cache-
|
||||
- uses: actions/setup-go@v3
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: 1.20
|
||||
- uses: actions/checkout@v3
|
||||
|
|
|
@ -33,7 +33,7 @@ jobs:
|
|||
# restore-keys: |
|
||||
# go_cache-${{ github.repository }}-
|
||||
# go_cache-
|
||||
- uses: actions/setup-go@v3
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: 1.20
|
||||
- uses: actions/checkout@v3
|
||||
|
|
|
@ -33,7 +33,7 @@ jobs:
|
|||
# restore-keys: |
|
||||
# go_cache-${{ github.repository }}-
|
||||
# go_cache-
|
||||
- uses: actions/setup-go@v3
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: 1.20
|
||||
- uses: actions/checkout@v3
|
||||
|
|
|
@ -33,7 +33,7 @@ jobs:
|
|||
# restore-keys: |
|
||||
# go_cache-${{ github.repository }}-
|
||||
# go_cache-
|
||||
- uses: actions/setup-go@v3
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: 1.20
|
||||
- uses: actions/checkout@v3
|
||||
|
|
2
Makefile
2
Makefile
|
@ -25,6 +25,7 @@ TEST_MSSQL_PASSWORD ?= MwantsaSecurePassword1
|
|||
TEST_MSSQL_DEFAULT_VARCHAR ?= varchar
|
||||
TEST_MSSQL_DEFAULT_CHAR ?= char
|
||||
TEST_MSSQL_DO_NVARCHAR_OVERRIDE_TEST ?= true
|
||||
TEST_MSSQL_COLLATION ?=
|
||||
|
||||
TEST_MYSQL_HOST ?= mysql:3306
|
||||
TEST_MYSQL_CHARSET ?= utf8
|
||||
|
@ -153,6 +154,7 @@ test-mssql: go-check
|
|||
-conn_str="server=$(TEST_MSSQL_HOST);user id=$(TEST_MSSQL_USERNAME);password=$(TEST_MSSQL_PASSWORD);database=$(TEST_MSSQL_DBNAME)" \
|
||||
-default_varchar=$(TEST_MSSQL_DEFAULT_VARCHAR) -default_char=$(TEST_MSSQL_DEFAULT_CHAR) \
|
||||
-do_nvarchar_override_test=$(TEST_MSSQL_DO_NVARCHAR_OVERRIDE_TEST) \
|
||||
-collation=$(TEST_MSSQL_COLLATION) \
|
||||
-coverprofile=mssql.$(TEST_QUOTE_POLICY).$(TEST_CACHE_ENABLE).coverage.out -covermode=atomic -timeout=20m
|
||||
|
||||
.PNONY: test-mssql\#%
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# xorm
|
||||
|
||||
[中文](https://gitea.com/xorm/xorm/src/branch/master/README_CN.md)
|
||||
[中文](https://gitea.com/xorm/xorm/src/branch/v1/README_CN.md)
|
||||
|
||||
Xorm is a simple and powerful ORM for Go.
|
||||
|
||||
|
@ -48,7 +48,7 @@ Drivers for Go's sql package which currently support database/sql includes:
|
|||
- [modernc.org/sqlite](https://gitlab.com/cznic/sqlite)
|
||||
|
||||
* MsSql
|
||||
- [github.com/denisenkom/go-mssqldb](https://github.com/denisenkom/go-mssqldb)
|
||||
- [github.com/microsoft/go-mssqldb](https://github.com/microsoft/go-mssqldb)
|
||||
|
||||
* Oracle
|
||||
- [github.com/godror/godror](https://github.com/godror/godror) (experiment)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# xorm
|
||||
|
||||
[English](https://gitea.com/xorm/xorm/src/branch/master/README.md)
|
||||
[English](https://gitea.com/xorm/xorm/src/branch/v1/README.md)
|
||||
|
||||
xorm 是一个简单而强大的Go语言ORM库. 通过它可以使数据库操作非常简便。
|
||||
|
||||
|
@ -47,7 +47,7 @@ v1.0.0 相对于 v0.8.2 有以下不兼容的变更:
|
|||
- [modernc.org/sqlite](https://gitlab.com/cznic/sqlite)
|
||||
|
||||
* MsSql
|
||||
- [github.com/denisenkom/go-mssqldb](https://github.com/denisenkom/go-mssqldb)
|
||||
- [github.com/microsoft/go-mssqldb](https://github.com/microsoft/go-mssqldb)
|
||||
|
||||
* Oracle
|
||||
- [github.com/godror/godror](https://github.com/godror/godror) (试验性支持)
|
||||
|
|
|
@ -831,6 +831,13 @@ func (d *dmClobScanner) Scan(data interface{}) error {
|
|||
d.data = string(t)
|
||||
d.valid = true
|
||||
return nil
|
||||
case string:
|
||||
if len(t) <= 0 {
|
||||
return nil
|
||||
}
|
||||
d.data = string(t)
|
||||
d.valid = true
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("cannot convert %T as dmClobScanner", data)
|
||||
}
|
||||
|
|
|
@ -582,10 +582,10 @@ func (db *mssql) GetIndexes(queryer core.Queryer, ctx context.Context, tableName
|
|||
IXS.NAME AS [INDEX_NAME],
|
||||
C.NAME AS [COLUMN_NAME],
|
||||
IXS.is_unique AS [IS_UNIQUE]
|
||||
FROM SYS.INDEXES IXS
|
||||
INNER JOIN SYS.INDEX_COLUMNS IXCS
|
||||
FROM sys.indexes IXS
|
||||
INNER JOIN sys.index_columns IXCS
|
||||
ON IXS.OBJECT_ID=IXCS.OBJECT_ID AND IXS.INDEX_ID = IXCS.INDEX_ID
|
||||
INNER JOIN SYS.COLUMNS C ON IXS.OBJECT_ID=C.OBJECT_ID
|
||||
INNER JOIN sys.columns C ON IXS.OBJECT_ID=C.OBJECT_ID
|
||||
AND IXCS.COLUMN_ID=C.COLUMN_ID
|
||||
WHERE IXS.TYPE_DESC='NONCLUSTERED' and OBJECT_NAME(IXS.OBJECT_ID) =?
|
||||
`
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"xorm.io/xorm/core"
|
||||
"xorm.io/xorm/schemas"
|
||||
|
@ -320,7 +321,7 @@ func splitColStr(colStr string) []string {
|
|||
var lastIdx int
|
||||
var hasC, hasQuote bool
|
||||
for i, c := range colStr {
|
||||
if c == ' ' && !hasQuote {
|
||||
if unicode.IsSpace(c) && !hasQuote {
|
||||
if hasC {
|
||||
results = append(results, colStr[lastIdx:i])
|
||||
hasC = false
|
||||
|
@ -350,7 +351,7 @@ func parseString(colStr string) (*schemas.Column, error) {
|
|||
|
||||
for idx, field := range fields {
|
||||
if idx == 0 {
|
||||
col.Name = strings.Trim(strings.Trim(field, "`[] "), `"`)
|
||||
col.Name = strings.Trim(strings.TrimSpace(field), "`[]'\"")
|
||||
continue
|
||||
} else if idx == 1 {
|
||||
col.SQLType = schemas.SQLType{Name: field, DefaultLength: 0, DefaultLength2: 0}
|
||||
|
@ -400,6 +401,8 @@ func (db *sqlite3) GetColumns(queryer core.Queryer, ctx context.Context, tableNa
|
|||
return nil, nil, errors.New("no table named " + tableName)
|
||||
}
|
||||
|
||||
name = strings.ReplaceAll(name, "\n", " ")
|
||||
|
||||
nStart := strings.Index(name, "(")
|
||||
nEnd := strings.LastIndex(name, ")")
|
||||
reg := regexp.MustCompile(`[^\(,\)]*(\([^\(]*\))?`)
|
||||
|
@ -483,7 +486,7 @@ func (db *sqlite3) GetIndexes(queryer core.Queryer, ctx context.Context, tableNa
|
|||
if !tmpSQL.Valid {
|
||||
continue
|
||||
}
|
||||
sql := tmpSQL.String
|
||||
sql := strings.ReplaceAll(tmpSQL.String, "\n", " ")
|
||||
|
||||
index := new(schemas.Index)
|
||||
nNStart := strings.Index(sql, "INDEX")
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
)
|
||||
|
||||
func TestSplitColStr(t *testing.T) {
|
||||
var kases = []struct {
|
||||
kases := []struct {
|
||||
colStr string
|
||||
fields []string
|
||||
}{
|
||||
|
@ -27,6 +27,13 @@ func TestSplitColStr(t *testing.T) {
|
|||
"`created`", "DATETIME", "DEFAULT", "'2006-01-02 15:04:05'", "NULL",
|
||||
},
|
||||
},
|
||||
{
|
||||
colStr: ` id INTEGER not null
|
||||
primary key autoincrement`,
|
||||
fields: []string{
|
||||
"id", "INTEGER", "not", "null", "primary", "key", "autoincrement",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, kase := range kases {
|
||||
|
|
15
engine.go
15
engine.go
|
@ -51,7 +51,7 @@ type Engine struct {
|
|||
|
||||
// NewEngine new a db manager according to the parameter. Currently support four
|
||||
// drivers
|
||||
func NewEngine(driverName string, dataSourceName string) (*Engine, error) {
|
||||
func NewEngine(driverName string, dataSourceName string, driverOptions ...func(db *sql.DB) error) (*Engine, error) {
|
||||
dialect, err := dialects.OpenDialect(driverName, dataSourceName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -62,6 +62,12 @@ func NewEngine(driverName string, dataSourceName string) (*Engine, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
for _, driverOption := range driverOptions {
|
||||
if err := driverOption(db.DB); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return newEngine(driverName, dataSourceName, dialect, db)
|
||||
}
|
||||
|
||||
|
@ -1433,3 +1439,10 @@ func (engine *Engine) Transaction(f func(*Session) (interface{}, error)) (interf
|
|||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (engine *Engine) IndexHint(op, forType, indexerOrColName string) *Session {
|
||||
session := engine.NewSession()
|
||||
session.isAutoClose = true
|
||||
session.statement.LastError = session.statement.IndexHint(op, forType, indexerOrColName)
|
||||
return session
|
||||
}
|
||||
|
|
44
go.mod
44
go.mod
|
@ -1,21 +1,57 @@
|
|||
module xorm.io/xorm
|
||||
|
||||
go 1.16
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
gitee.com/travelliu/dm v1.8.11192
|
||||
github.com/denisenkom/go-mssqldb v0.12.3
|
||||
github.com/go-sql-driver/mysql v1.7.0
|
||||
github.com/goccy/go-json v0.8.1
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/jackc/pgx/v4 v4.18.0
|
||||
github.com/json-iterator/go v1.1.12
|
||||
github.com/lib/pq v1.10.7
|
||||
github.com/mattn/go-sqlite3 v1.14.16
|
||||
github.com/microsoft/go-mssqldb v1.6.0
|
||||
github.com/shopspring/decimal v1.3.1
|
||||
github.com/stretchr/testify v1.8.1
|
||||
github.com/stretchr/testify v1.8.4
|
||||
github.com/syndtr/goleveldb v1.0.0
|
||||
github.com/ziutek/mymysql v1.5.4
|
||||
modernc.org/sqlite v1.20.4
|
||||
xorm.io/builder v0.3.11-0.20220531020008-1bd24a7dc978
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/dustin/go-humanize v1.0.0 // indirect
|
||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
|
||||
github.com/golang-sql/sqlexp v0.1.0 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
|
||||
github.com/jackc/pgconn v1.14.0 // indirect
|
||||
github.com/jackc/pgio v1.0.0 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgproto3/v2 v2.3.2 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
|
||||
github.com/jackc/pgtype v1.14.0 // indirect
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||
github.com/mattn/go-isatty v0.0.16 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
|
||||
golang.org/x/crypto v0.12.0 // indirect
|
||||
golang.org/x/mod v0.8.0 // indirect
|
||||
golang.org/x/sys v0.11.0 // indirect
|
||||
golang.org/x/text v0.12.0 // indirect
|
||||
golang.org/x/tools v0.6.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
lukechampine.com/uint128 v1.2.0 // indirect
|
||||
modernc.org/cc/v3 v3.40.0 // indirect
|
||||
modernc.org/ccgo/v3 v3.16.13 // indirect
|
||||
modernc.org/libc v1.22.2 // indirect
|
||||
modernc.org/mathutil v1.5.0 // indirect
|
||||
modernc.org/memory v1.4.0 // indirect
|
||||
modernc.org/opt v0.1.3 // indirect
|
||||
modernc.org/strutil v1.1.3 // indirect
|
||||
modernc.org/token v1.0.1 // indirect
|
||||
)
|
||||
|
|
89
go.sum
89
go.sum
|
@ -2,15 +2,15 @@ gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGq
|
|||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
|
||||
gitee.com/travelliu/dm v1.8.11192 h1:aqJT0xhodZjRutIfEXxKYv0CxqmHUHzsbz6SFaRL6OY=
|
||||
gitee.com/travelliu/dm v1.8.11192/go.mod h1:DHTzyhCrM843x9VdKVbZ+GKXGRbKM2sJ4LxihRxShkE=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v0.19.0/go.mod h1:h6H6c8enJmmocHUbLiiGY6sx7f9i+X3m1CHdd5c6Rdw=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.11.0/go.mod h1:HcM1YX14R7CJcghJGOYCgdezslRSVzqwLf/q+4Y2r/0=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v0.7.0/go.mod h1:yqy467j36fJxcRV2TzfVZ1pCb5vxm4BtZPUdYWe/Xo8=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.1 h1:/iHxaJhsFr0+xVFfbMr5vxz848jyiWuIEDhYq3y5odY=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0 h1:vcYCAze6p19qBW7MhZybIsqD8sMV8js0NyQM8JDnVtg=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 h1:sXr+ck84g/ZlZUOZiNELInmMgOsuGwdjjVkEIde0OtY=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.0 h1:yfJe15aSwEQ6Oo6J+gdfdulPNoZ3TEhmbhLIoxZcA+U=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v0.8.0 h1:T028gtTPiYt/RMUfs8nVsAL7FDQrfLlrm/NnRG/zcC4=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.1.0 h1:HCc0+LpPfpCKs6LGGLAhwBARt9632unrVcI6i8s/8os=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
|
||||
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
|
||||
github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY=
|
||||
github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic=
|
||||
github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
|
||||
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
|
@ -19,9 +19,6 @@ github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7Do
|
|||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/denisenkom/go-mssqldb v0.12.3 h1:pBSGx9Tq67pBOTLmxNuirNTeB8Vjmf886Kx+8Y+8shw=
|
||||
github.com/denisenkom/go-mssqldb v0.12.3/go.mod h1:k0mtMFOnU+AihqFxPMiF05rtiDrorD1Vrm1KEz5hxDo=
|
||||
github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
|
||||
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/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
|
@ -34,8 +31,9 @@ github.com/goccy/go-json v0.8.1 h1:4/Wjm0JIJaTDm8K1KcGrLHJoa8EsJ13YWeX+6Kfq6uI=
|
|||
github.com/goccy/go-json v0.8.1/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw=
|
||||
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE=
|
||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA=
|
||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
|
||||
github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
|
@ -43,19 +41,14 @@ github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8l
|
|||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
|
||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
|
||||
github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0=
|
||||
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
|
||||
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
||||
github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=
|
||||
|
@ -76,7 +69,6 @@ github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65 h1:DadwsjnMwFjfWc9y5W
|
|||
github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak=
|
||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||
github.com/jackc/pgproto3 v1.1.0 h1:FYYE4yRw+AgI8wXIinMlNjBbp/UitDJwfj5LqqewP1A=
|
||||
github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78=
|
||||
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA=
|
||||
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg=
|
||||
|
@ -118,6 +110,7 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
|||
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
|
@ -131,20 +124,20 @@ github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd
|
|||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/microsoft/go-mssqldb v1.6.0 h1:mM3gYdVwEPFrlg/Dvr2DNVEgYFG7L42l+dGc67NNNpc=
|
||||
github.com/microsoft/go-mssqldb v1.6.0/go.mod h1:00mDtPbeQCRGC1HwOOR5K/gr30P1NcEG0vx6Kbv2aJU=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8=
|
||||
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=
|
||||
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/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA=
|
||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
|
@ -174,11 +167,11 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
|
|||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
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/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
||||
github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=
|
||||
|
@ -200,36 +193,32 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
|
|||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc=
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
|
||||
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0 h1:L4ZwwTvKW9gr0ZMS1yrHD9GZhIuVjOBBnaKH+SPQK0Q=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
|
@ -241,16 +230,14 @@ golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/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-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
|
@ -261,8 +248,9 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
|
||||
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
|
@ -272,14 +260,13 @@ golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtn
|
|||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
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/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
|
@ -291,44 +278,26 @@ gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:a
|
|||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
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=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
|
||||
lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI=
|
||||
lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
|
||||
modernc.org/cc/v3 v3.37.0/go.mod h1:vtL+3mdHx/wcj3iEGz84rQa8vEqR6XM84v5Lcvfph20=
|
||||
modernc.org/cc/v3 v3.38.1/go.mod h1:vtL+3mdHx/wcj3iEGz84rQa8vEqR6XM84v5Lcvfph20=
|
||||
modernc.org/cc/v3 v3.40.0 h1:P3g79IUS/93SYhtoeaHW+kRCIrYaxJ27MFPv+7kaTOw=
|
||||
modernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0=
|
||||
modernc.org/ccgo/v3 v3.0.0-20220904174949-82d86e1b6d56/go.mod h1:YSXjPL62P2AMSxBphRHPn7IkzhVHqkvOnRKAKh+W6ZI=
|
||||
modernc.org/ccgo/v3 v3.0.0-20220910160915-348f15de615a/go.mod h1:8p47QxPkdugex9J4n9P2tLZ9bK01yngIVp00g4nomW0=
|
||||
modernc.org/ccgo/v3 v3.16.13-0.20221017192402-261537637ce8/go.mod h1:fUB3Vn0nVPReA+7IG7yZDfjv1TMWjhQP8gCxrFAtL5g=
|
||||
modernc.org/ccgo/v3 v3.16.13 h1:Mkgdzl46i5F/CNR/Kj80Ri59hC8TKAhZrYSaqvkwzUw=
|
||||
modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY=
|
||||
modernc.org/ccorpus v1.11.6 h1:J16RXiiqiCgua6+ZvQot4yUuUy8zxgqbqEEUuGPlISk=
|
||||
modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=
|
||||
modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM=
|
||||
modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=
|
||||
modernc.org/libc v1.17.4/go.mod h1:WNg2ZH56rDEwdropAJeZPQkXmDwh+JCA1s/htl6r2fA=
|
||||
modernc.org/libc v1.18.0/go.mod h1:vj6zehR5bfc98ipowQOM2nIDUZnVew/wNC/2tOGS+q0=
|
||||
modernc.org/libc v1.19.0/go.mod h1:ZRfIaEkgrYgZDl6pa4W39HgN5G/yDW+NRmNKZBDFrk0=
|
||||
modernc.org/libc v1.20.3/go.mod h1:ZRfIaEkgrYgZDl6pa4W39HgN5G/yDW+NRmNKZBDFrk0=
|
||||
modernc.org/libc v1.21.4/go.mod h1:przBsL5RDOZajTVslkugzLBj1evTue36jEomFQOoYuI=
|
||||
modernc.org/libc v1.22.2 h1:4U7v51GyhlWqQmwCHj28Rdq2Yzwk55ovjFrdPjs8Hb0=
|
||||
modernc.org/libc v1.22.2/go.mod h1:uvQavJ1pZ0hIoC/jfqNoMLURIMhKzINIWypNM17puug=
|
||||
modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ=
|
||||
modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/memory v1.3.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
|
||||
modernc.org/memory v1.4.0 h1:crykUfNSnMAXaOJnnxcSzbUGMqkLWjklJKkBK2nwZwk=
|
||||
modernc.org/memory v1.4.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
|
||||
modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||
modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
|
||||
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||
modernc.org/sqlite v1.20.4 h1:J8+m2trkN+KKoE7jglyHYYYiaq5xmz2HoHJIiBlRzbE=
|
||||
|
@ -336,10 +305,8 @@ modernc.org/sqlite v1.20.4/go.mod h1:zKcGyrICaxNTMEHSr1HQ2GUraP0j+845GYw37+EyT6A
|
|||
modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY=
|
||||
modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw=
|
||||
modernc.org/tcl v1.15.0 h1:oY+JeD11qVVSgVvodMJsu7Edf8tr5E/7tuhF5cNYz34=
|
||||
modernc.org/tcl v1.15.0/go.mod h1:xRoGotBZ6dU+Zo2tca+2EqVEeMmOUBzHnhIwq4YrVnE=
|
||||
modernc.org/token v1.0.1 h1:A3qvTqOwexpfZZeyI0FeGPDlSWX5pjZu9hF4lU+EKWg=
|
||||
modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||
modernc.org/z v1.7.0 h1:xkDw/KepgEjeizO2sNco+hqYkU12taxQFqPEmgm1GWE=
|
||||
modernc.org/z v1.7.0/go.mod h1:hVdgNMh8ggTuRG1rGU8x+xGRFfiQUIAw0ZqlPy8+HyQ=
|
||||
xorm.io/builder v0.3.11-0.20220531020008-1bd24a7dc978 h1:bvLlAPW1ZMTWA32LuZMBEGHAUOcATZjzHcotf3SWweM=
|
||||
xorm.io/builder v0.3.11-0.20220531020008-1bd24a7dc978/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
// Copyright 2023 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package statements
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"xorm.io/builder"
|
||||
"xorm.io/xorm/schemas"
|
||||
)
|
||||
|
||||
type ErrInvalidIndexHintOperator struct {
|
||||
Op string
|
||||
}
|
||||
|
||||
func (e ErrInvalidIndexHintOperator) Error() string {
|
||||
return "invalid index hint operator: " + e.Op
|
||||
}
|
||||
|
||||
func (statement *Statement) IndexHint(op, forType, indexName string) error {
|
||||
op = strings.ToUpper(op)
|
||||
statement.indexHints = append(statement.indexHints, indexHint{
|
||||
op: op,
|
||||
forType: forType,
|
||||
indexName: indexName,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (statement *Statement) writeIndexHints(w *builder.BytesWriter) error {
|
||||
if len(statement.indexHints) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch statement.dialect.URI().DBType {
|
||||
case schemas.MYSQL:
|
||||
return statement.writeIndexHintsMySQL(w)
|
||||
default:
|
||||
return ErrNotImplemented
|
||||
}
|
||||
}
|
||||
|
||||
func (statement *Statement) writeIndexHintsMySQL(w *builder.BytesWriter) error {
|
||||
for _, hint := range statement.indexHints {
|
||||
if hint.op != "USE" && hint.op != "FORCE" && hint.op != "IGNORE" {
|
||||
return ErrInvalidIndexHintOperator{Op: hint.op}
|
||||
}
|
||||
if err := statement.writeStrings(" ", hint.op, " INDEX")(w); err != nil {
|
||||
return err
|
||||
}
|
||||
if hint.forType != "" {
|
||||
if err := statement.writeStrings(" FOR ", hint.forType)(w); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := statement.writeStrings("(", hint.indexName, ")")(w); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -34,13 +34,7 @@ func (statement *Statement) writeJoins(w *builder.BytesWriter) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (statement *Statement) writeJoin(buf *builder.BytesWriter, join join) error {
|
||||
// write join operator
|
||||
if _, err := fmt.Fprint(buf, " ", join.op, " JOIN"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// write join table or subquery
|
||||
func (statement *Statement) writeJoinTable(buf *builder.BytesWriter, join join) error {
|
||||
switch tp := join.table.(type) {
|
||||
case builder.Builder:
|
||||
if _, err := fmt.Fprintf(buf, " ("); err != nil {
|
||||
|
@ -87,6 +81,19 @@ func (statement *Statement) writeJoin(buf *builder.BytesWriter, join join) error
|
|||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (statement *Statement) writeJoin(buf *builder.BytesWriter, join join) error {
|
||||
// write join operator
|
||||
if _, err := fmt.Fprint(buf, " ", join.op, " JOIN"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// write join table or subquery
|
||||
if err := statement.writeJoinTable(buf, join); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// write on condition
|
||||
if _, err := fmt.Fprint(buf, " ON "); err != nil {
|
||||
|
@ -109,3 +116,14 @@ func (statement *Statement) writeJoin(buf *builder.BytesWriter, join join) error
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (statement *Statement) convertJoinCondition(join join) (builder.Cond, error) {
|
||||
switch condTp := join.condition.(type) {
|
||||
case string:
|
||||
return builder.Expr(statement.ReplaceQuote(condTp), join.args...), nil
|
||||
case builder.Cond:
|
||||
return condTp, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported join condition type: %v", condTp)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ func (statement *Statement) writeOracleLegacySelect(buf *builder.BytesWriter, co
|
|||
return statement.writeMultiple(buf,
|
||||
statement.writeSelectColumns(columnStr),
|
||||
statement.writeFrom,
|
||||
statement.writeWhere,
|
||||
statement.writeOracleLimit(columnStr),
|
||||
statement.writeGroupBy,
|
||||
statement.writeHaving,
|
||||
|
|
|
@ -10,11 +10,12 @@ import (
|
|||
|
||||
"xorm.io/builder"
|
||||
"xorm.io/xorm/internal/utils"
|
||||
"xorm.io/xorm/schemas"
|
||||
)
|
||||
|
||||
func (statement *Statement) writePagination(bw *builder.BytesWriter) error {
|
||||
dbType := statement.dialect.URI().DBType
|
||||
if dbType == "mssql" || dbType == "oracle" {
|
||||
if dbType == schemas.MSSQL || dbType == schemas.ORACLE {
|
||||
return statement.writeOffsetFetch(bw)
|
||||
}
|
||||
return statement.writeLimitOffset(bw)
|
||||
|
@ -50,15 +51,15 @@ func (statement *Statement) writeOffsetFetch(w builder.Writer) error {
|
|||
}
|
||||
|
||||
func (statement *Statement) writeWhereWithMssqlPagination(w *builder.BytesWriter) error {
|
||||
if !statement.cond.IsValid() {
|
||||
return statement.writeMssqlPaginationCond(w)
|
||||
}
|
||||
if _, err := fmt.Fprint(w, " WHERE "); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := statement.cond.WriteTo(statement.QuoteReplacer(w)); err != nil {
|
||||
return err
|
||||
if statement.cond.IsValid() {
|
||||
if _, err := fmt.Fprint(w, " WHERE "); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := statement.cond.WriteTo(statement.QuoteReplacer(w)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return statement.writeMssqlPaginationCond(w)
|
||||
}
|
||||
|
||||
|
@ -115,15 +116,8 @@ func (statement *Statement) writeMssqlPaginationCond(w *builder.BytesWriter) err
|
|||
if _, err := fmt.Fprint(subWriter, "))"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if statement.cond.IsValid() {
|
||||
if _, err := fmt.Fprint(w, " AND "); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if _, err := fmt.Fprint(w, " WHERE "); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := statement.writeWhereOrAnd(w, statement.cond.IsValid()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return utils.WriteBuilder(w, subWriter)
|
||||
|
|
|
@ -184,6 +184,7 @@ func (statement *Statement) writeFrom(w *builder.BytesWriter) error {
|
|||
statement.writeStrings(" FROM "),
|
||||
statement.writeTableName,
|
||||
statement.writeAlias,
|
||||
statement.writeIndexHints,
|
||||
statement.writeJoins,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -41,6 +41,12 @@ type join struct {
|
|||
args []interface{}
|
||||
}
|
||||
|
||||
type indexHint struct {
|
||||
op string
|
||||
forType string
|
||||
indexName string
|
||||
}
|
||||
|
||||
// Statement save all the sql info for executing SQL
|
||||
type Statement struct {
|
||||
RefTable *schemas.Table
|
||||
|
@ -84,6 +90,7 @@ type Statement struct {
|
|||
BufferSize int
|
||||
Context contexts.ContextCache
|
||||
LastError error
|
||||
indexHints []indexHint
|
||||
}
|
||||
|
||||
// NewStatement creates a new statement
|
||||
|
|
|
@ -341,12 +341,59 @@ func (statement *Statement) writeUpdateTableName(updateWriter *builder.BytesWrit
|
|||
}
|
||||
}
|
||||
|
||||
func (statement *Statement) writeUpdateFrom(updateWriter *builder.BytesWriter) error {
|
||||
if statement.dialect.URI().DBType != schemas.MSSQL || statement.TableAlias == "" {
|
||||
return nil
|
||||
func (statement *Statement) writeUpdateFrom(updateWriter *builder.BytesWriter) (builder.Cond, error) {
|
||||
if statement.dialect.URI().DBType == schemas.MSSQL {
|
||||
if _, err := fmt.Fprint(updateWriter, " FROM"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if _, err := fmt.Fprint(updateWriter, " ", statement.quote(statement.TableName())); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if statement.TableAlias != "" {
|
||||
if _, err := fmt.Fprint(updateWriter, " ", statement.TableAlias); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_, err := fmt.Fprint(updateWriter, " FROM ", statement.quote(statement.TableName()), " ", statement.TableAlias)
|
||||
if len(statement.joins) == 0 {
|
||||
return builder.NewCond(), nil
|
||||
}
|
||||
|
||||
if statement.dialect.URI().DBType != schemas.MSSQL {
|
||||
if _, err := fmt.Fprint(updateWriter, " FROM"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
cond := builder.NewCond()
|
||||
for i, join := range statement.joins {
|
||||
if statement.dialect.URI().DBType == schemas.MSSQL || i > 0 {
|
||||
if _, err := fmt.Fprint(updateWriter, ","); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if err := statement.writeJoinTable(updateWriter, join); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
joinCond, err := statement.convertJoinCondition(join)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cond = cond.And(joinCond)
|
||||
}
|
||||
|
||||
return cond, nil
|
||||
}
|
||||
|
||||
func (statement *Statement) writeWhereOrAnd(updateWriter *builder.BytesWriter, hasConditions bool) error {
|
||||
if hasConditions {
|
||||
_, err := fmt.Fprint(updateWriter, " AND ")
|
||||
return err
|
||||
}
|
||||
_, err := fmt.Fprint(updateWriter, " WHERE ")
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -364,14 +411,8 @@ func (statement *Statement) writeUpdateLimit(updateWriter *builder.BytesWriter,
|
|||
_, err := fmt.Fprintf(updateWriter, " LIMIT %d", limitValue)
|
||||
return err
|
||||
case schemas.SQLITE:
|
||||
if cond.IsValid() {
|
||||
if _, err := fmt.Fprint(updateWriter, " AND "); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if _, err := fmt.Fprint(updateWriter, " WHERE "); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := statement.writeWhereOrAnd(updateWriter, cond.IsValid()); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprint(updateWriter, "rowid IN (SELECT rowid FROM ", statement.quote(tableName)); err != nil {
|
||||
return err
|
||||
|
@ -385,14 +426,8 @@ func (statement *Statement) writeUpdateLimit(updateWriter *builder.BytesWriter,
|
|||
_, err := fmt.Fprintf(updateWriter, " LIMIT %d)", limitValue)
|
||||
return err
|
||||
case schemas.POSTGRES:
|
||||
if cond.IsValid() {
|
||||
if _, err := fmt.Fprint(updateWriter, " AND "); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if _, err := fmt.Fprint(updateWriter, " WHERE "); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := statement.writeWhereOrAnd(updateWriter, cond.IsValid()); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprint(updateWriter, "CTID IN (SELECT CTID FROM ", statement.quote(tableName)); err != nil {
|
||||
return err
|
||||
|
@ -477,9 +512,9 @@ func (statement *Statement) writeVersionIncrSet(w builder.Writer, v reflect.Valu
|
|||
return nil
|
||||
}
|
||||
|
||||
func (statement *Statement) writeIncrSets(w builder.Writer, hasPreviousSet bool) error {
|
||||
func (statement *Statement) writeIncrSets(w builder.Writer, hasPreviousSets bool) error {
|
||||
for i, expr := range statement.IncrColumns {
|
||||
if i > 0 || hasPreviousSet {
|
||||
if i > 0 || hasPreviousSets {
|
||||
if _, err := fmt.Fprint(w, ", "); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -492,10 +527,10 @@ func (statement *Statement) writeIncrSets(w builder.Writer, hasPreviousSet bool)
|
|||
return nil
|
||||
}
|
||||
|
||||
func (statement *Statement) writeDecrSets(w builder.Writer, hasPreviousSet bool) error {
|
||||
func (statement *Statement) writeDecrSets(w builder.Writer, hasPreviousSets bool) error {
|
||||
// for update action to like "column = column - ?"
|
||||
for i, expr := range statement.DecrColumns {
|
||||
if i > 0 || hasPreviousSet {
|
||||
if i > 0 || hasPreviousSets {
|
||||
if _, err := fmt.Fprint(w, ", "); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -508,10 +543,10 @@ func (statement *Statement) writeDecrSets(w builder.Writer, hasPreviousSet bool)
|
|||
return nil
|
||||
}
|
||||
|
||||
func (statement *Statement) writeExprSets(w *builder.BytesWriter, hasPreviousSet bool) error {
|
||||
func (statement *Statement) writeExprSets(w *builder.BytesWriter, hasPreviousSets bool) error {
|
||||
// for update action to like "column = expression"
|
||||
for i, expr := range statement.ExprColumns {
|
||||
if i > 0 || hasPreviousSet {
|
||||
if i > 0 || hasPreviousSets {
|
||||
if _, err := fmt.Fprint(w, ", "); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -544,41 +579,114 @@ func (statement *Statement) writeExprSets(w *builder.BytesWriter, hasPreviousSet
|
|||
return nil
|
||||
}
|
||||
|
||||
func (statement *Statement) writeUpdateSets(w *builder.BytesWriter, v reflect.Value, colNames []string, args []interface{}) error {
|
||||
previousLen := w.Len()
|
||||
for i, colName := range colNames {
|
||||
if i > 0 {
|
||||
if _, err := fmt.Fprint(w, ", "); err != nil {
|
||||
return err
|
||||
func (statement *Statement) writeSetColumns(colNames []string, args []interface{}) func(w *builder.BytesWriter) error {
|
||||
return func(w *builder.BytesWriter) error {
|
||||
if len(colNames) == 0 {
|
||||
return nil
|
||||
}
|
||||
if len(colNames) != len(args) {
|
||||
return fmt.Errorf("columns elements %d but args elements %d", len(colNames), len(args))
|
||||
}
|
||||
for i, colName := range colNames {
|
||||
if i > 0 {
|
||||
if _, err := fmt.Fprint(w, ", "); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if statement.dialect.URI().DBType != schemas.SQLITE && statement.dialect.URI().DBType != schemas.POSTGRES && len(statement.joins) > 0 {
|
||||
tbName := statement.TableAlias
|
||||
if tbName == "" {
|
||||
tbName = statement.TableName()
|
||||
}
|
||||
if _, err := fmt.Fprint(w, tbName, ".", colName); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if _, err := fmt.Fprint(w, colName); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
if _, err := fmt.Fprint(w, colName); err != nil {
|
||||
return err
|
||||
}
|
||||
w.Append(args...)
|
||||
return nil
|
||||
}
|
||||
w.Append(args...)
|
||||
}
|
||||
|
||||
if err := statement.writeIncrSets(w, w.Len() > previousLen); err != nil {
|
||||
func (statement *Statement) writeUpdateSets(w *builder.BytesWriter, v reflect.Value, colNames []string, args []interface{}) error {
|
||||
// write set
|
||||
if _, err := fmt.Fprint(w, " SET "); err != nil {
|
||||
return err
|
||||
}
|
||||
previousLen := w.Len()
|
||||
|
||||
if err := statement.writeSetColumns(colNames, args)(w); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := statement.writeDecrSets(w, w.Len() > previousLen); err != nil {
|
||||
setNumber := len(colNames)
|
||||
if err := statement.writeIncrSets(w, setNumber > 0); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := statement.writeExprSets(w, w.Len() > previousLen); err != nil {
|
||||
setNumber += len(statement.IncrColumns)
|
||||
if err := statement.writeDecrSets(w, setNumber > 0); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := statement.writeVersionIncrSet(w, v, w.Len() > previousLen); err != nil {
|
||||
setNumber += len(statement.DecrColumns)
|
||||
if err := statement.writeExprSets(w, setNumber > 0); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
setNumber += len(statement.ExprColumns)
|
||||
if err := statement.writeVersionIncrSet(w, v, setNumber > 0); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// if no columns to be updated, return error
|
||||
if previousLen == w.Len() {
|
||||
return ErrNoColumnsTobeUpdated
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var ErrNoColumnsTobeUpdated = errors.New("no columns found to be updated")
|
||||
|
||||
func (statement *Statement) WriteUpdate(updateWriter *builder.BytesWriter, cond builder.Cond, v reflect.Value, colNames []string, args []interface{}) error {
|
||||
switch statement.dialect.URI().DBType {
|
||||
case schemas.MYSQL:
|
||||
return statement.writeUpdateMySQL(updateWriter, cond, v, colNames, args)
|
||||
case schemas.MSSQL:
|
||||
return statement.writeUpdateMSSQL(updateWriter, cond, v, colNames, args)
|
||||
default:
|
||||
return statement.writeUpdateCommon(updateWriter, cond, v, colNames, args)
|
||||
}
|
||||
}
|
||||
|
||||
func (statement *Statement) writeUpdateMySQL(updateWriter *builder.BytesWriter, cond builder.Cond, v reflect.Value, colNames []string, args []interface{}) error {
|
||||
if _, err := fmt.Fprintf(updateWriter, "UPDATE"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := statement.writeUpdateTableName(updateWriter); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := statement.writeJoins(updateWriter); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := statement.writeUpdateSets(updateWriter, v, colNames, args); err != nil {
|
||||
return err
|
||||
}
|
||||
// write where
|
||||
if err := statement.writeWhereCond(updateWriter, cond); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := statement.writeOrderBys(updateWriter); err != nil {
|
||||
return err
|
||||
}
|
||||
return statement.writeUpdateLimit(updateWriter, cond)
|
||||
}
|
||||
|
||||
func (statement *Statement) writeUpdateMSSQL(updateWriter *builder.BytesWriter, cond builder.Cond, v reflect.Value, colNames []string, args []interface{}) error {
|
||||
if _, err := fmt.Fprintf(updateWriter, "UPDATE"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -591,47 +699,56 @@ func (statement *Statement) WriteUpdate(updateWriter *builder.BytesWriter, cond
|
|||
return err
|
||||
}
|
||||
|
||||
// write set
|
||||
if _, err := fmt.Fprint(updateWriter, " SET "); err != nil {
|
||||
if err := statement.writeUpdateSets(updateWriter, v, colNames, args); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// write from
|
||||
joinConds, err := statement.writeUpdateFrom(updateWriter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
table := statement.RefTable
|
||||
if statement.HasOrderBy() && table != nil && len(table.PrimaryKeys) == 1 {
|
||||
} else {
|
||||
// write where
|
||||
if err := statement.writeWhereCond(updateWriter, cond.And(joinConds)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return statement.writeUpdateLimit(updateWriter, cond.And(joinConds))
|
||||
}
|
||||
|
||||
// writeUpdateCommon write update sql for non mysql && non mssql
|
||||
func (statement *Statement) writeUpdateCommon(updateWriter *builder.BytesWriter, cond builder.Cond, v reflect.Value, colNames []string, args []interface{}) error {
|
||||
if _, err := fmt.Fprintf(updateWriter, "UPDATE"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := statement.writeUpdateTop(updateWriter); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := statement.writeUpdateTableName(updateWriter); err != nil {
|
||||
return err
|
||||
}
|
||||
previousLen := updateWriter.Len()
|
||||
|
||||
if err := statement.writeUpdateSets(updateWriter, v, colNames, args); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// if no columns to be updated, return error
|
||||
if previousLen == updateWriter.Len() {
|
||||
return ErrNoColumnsTobeUpdated
|
||||
}
|
||||
|
||||
// write from
|
||||
if err := statement.writeUpdateFrom(updateWriter); err != nil {
|
||||
joinConds, err := statement.writeUpdateFrom(updateWriter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if statement.dialect.URI().DBType == schemas.MSSQL {
|
||||
table := statement.RefTable
|
||||
if statement.HasOrderBy() && table != nil && len(table.PrimaryKeys) == 1 {
|
||||
} else {
|
||||
// write where
|
||||
if err := statement.writeWhereCond(updateWriter, cond); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// write where
|
||||
if err := statement.writeWhereCond(updateWriter, cond); err != nil {
|
||||
return err
|
||||
}
|
||||
// write where
|
||||
if err := statement.writeWhereCond(updateWriter, cond.And(joinConds)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if statement.dialect.URI().DBType == schemas.MYSQL {
|
||||
if err := statement.writeOrderBys(updateWriter); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return statement.writeUpdateLimit(updateWriter, cond)
|
||||
return statement.writeUpdateLimit(updateWriter, cond.And(joinConds))
|
||||
}
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
package migrate
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"xorm.io/xorm"
|
||||
"xorm.io/xorm/schemas"
|
||||
)
|
||||
|
||||
// MigrateFunc is the func signature for migrating.
|
||||
|
@ -87,7 +90,11 @@ func (m *Migrate) Migrate() error {
|
|||
return err
|
||||
}
|
||||
|
||||
if m.initSchema != nil && m.isFirstRun() {
|
||||
isFirstRun, err := m.isFirstRun()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if m.initSchema != nil && isFirstRun {
|
||||
return m.runInitSchema()
|
||||
}
|
||||
|
||||
|
@ -136,7 +143,9 @@ func (m *Migrate) RollbackMigration(mig *Migration) error {
|
|||
return err
|
||||
}
|
||||
|
||||
sql := fmt.Sprintf("DELETE FROM %s WHERE %s = ?", m.options.TableName, m.options.IDColumnName)
|
||||
tableName := m.db.TableName(m.options.TableName, true)
|
||||
|
||||
sql := fmt.Sprintf("DELETE FROM %s WHERE %s = ?", tableName, m.options.IDColumnName)
|
||||
if _, err := m.db.Exec(sql, mig.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -188,7 +197,19 @@ func (m *Migrate) createMigrationTableIfNotExists() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
sql := fmt.Sprintf("CREATE TABLE %s (%s VARCHAR(255) PRIMARY KEY)", m.options.TableName, m.options.IDColumnName)
|
||||
idCol := schemas.NewColumn(m.options.IDColumnName, "", schemas.SQLType{
|
||||
Name: "VARCHAR",
|
||||
}, 255, 0, true)
|
||||
idCol.IsPrimaryKey = true
|
||||
|
||||
table := schemas.NewTable(m.options.TableName, reflect.TypeOf(new(schemas.Table)))
|
||||
table.AddColumn(idCol)
|
||||
|
||||
sql, _, err := m.db.Dialect().CreateTableSQL(context.Background(), m.db.DB(), table, m.options.TableName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := m.db.Exec(sql); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -196,19 +217,21 @@ func (m *Migrate) createMigrationTableIfNotExists() error {
|
|||
}
|
||||
|
||||
func (m *Migrate) migrationDidRun(mig *Migration) (bool, error) {
|
||||
count, err := m.db.SQL(fmt.Sprintf("SELECT COUNT(*) FROM %s WHERE %s = ?", m.options.TableName, m.options.IDColumnName), mig.ID).Count()
|
||||
tableName := m.db.TableName(m.options.TableName, true)
|
||||
count, err := m.db.SQL(fmt.Sprintf("SELECT COUNT(*) FROM %s WHERE %s = ?", tableName, m.options.IDColumnName), mig.ID).Count()
|
||||
return count > 0, err
|
||||
}
|
||||
|
||||
func (m *Migrate) isFirstRun() bool {
|
||||
row := m.db.DB().QueryRow(fmt.Sprintf("SELECT COUNT(*) FROM %s", m.options.TableName))
|
||||
func (m *Migrate) isFirstRun() (bool, error) {
|
||||
var count int
|
||||
_ = row.Scan(&count)
|
||||
return count == 0
|
||||
tableName := m.db.TableName(m.options.TableName, true)
|
||||
_, err := m.db.SQL(fmt.Sprintf("SELECT COUNT(*) FROM %s", tableName)).Get(&count)
|
||||
return count == 0, err
|
||||
}
|
||||
|
||||
func (m *Migrate) insertMigration(id string) error {
|
||||
sql := fmt.Sprintf("INSERT INTO %s (%s) VALUES (?)", m.options.TableName, m.options.IDColumnName)
|
||||
tableName := m.db.TableName(m.options.TableName, true)
|
||||
sql := fmt.Sprintf("INSERT INTO %s (%s) VALUES (?)", tableName, m.options.IDColumnName)
|
||||
_, err := m.db.Exec(sql, id)
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -26,28 +26,26 @@ const (
|
|||
dbName = "testdb.sqlite3"
|
||||
)
|
||||
|
||||
var (
|
||||
migrations = []*Migration{
|
||||
{
|
||||
ID: "201608301400",
|
||||
Migrate: func(tx *xorm.Engine) error {
|
||||
return tx.Sync(&Person{})
|
||||
},
|
||||
Rollback: func(tx *xorm.Engine) error {
|
||||
return tx.DropTables(&Person{})
|
||||
},
|
||||
var migrations = []*Migration{
|
||||
{
|
||||
ID: "201608301400",
|
||||
Migrate: func(tx *xorm.Engine) error {
|
||||
return tx.Sync(&Person{})
|
||||
},
|
||||
{
|
||||
ID: "201608301430",
|
||||
Migrate: func(tx *xorm.Engine) error {
|
||||
return tx.Sync(&Pet{})
|
||||
},
|
||||
Rollback: func(tx *xorm.Engine) error {
|
||||
return tx.DropTables(&Pet{})
|
||||
},
|
||||
Rollback: func(tx *xorm.Engine) error {
|
||||
return tx.DropTables(&Person{})
|
||||
},
|
||||
}
|
||||
)
|
||||
},
|
||||
{
|
||||
ID: "201608301430",
|
||||
Migrate: func(tx *xorm.Engine) error {
|
||||
return tx.Sync(&Pet{})
|
||||
},
|
||||
Rollback: func(tx *xorm.Engine) error {
|
||||
return tx.DropTables(&Pet{})
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func TestMigration(t *testing.T) {
|
||||
_ = os.Remove(dbName)
|
||||
|
@ -58,7 +56,7 @@ func TestMigration(t *testing.T) {
|
|||
}
|
||||
defer db.Close()
|
||||
|
||||
if err = db.DB().Ping(); err != nil {
|
||||
if err = db.Ping(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
|
@ -97,7 +95,7 @@ func TestInitSchema(t *testing.T) {
|
|||
log.Fatal(err)
|
||||
}
|
||||
defer db.Close()
|
||||
if err = db.DB().Ping(); err != nil {
|
||||
if err = db.Ping(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
|
@ -126,7 +124,7 @@ func TestMissingID(t *testing.T) {
|
|||
if db != nil {
|
||||
defer db.Close()
|
||||
}
|
||||
assert.NoError(t, db.DB().Ping())
|
||||
assert.NoError(t, db.Ping())
|
||||
|
||||
migrationsMissingID := []*Migration{
|
||||
{
|
||||
|
@ -141,7 +139,6 @@ func TestMissingID(t *testing.T) {
|
|||
}
|
||||
|
||||
func tableCount(db *xorm.Engine, tableName string) (count int) {
|
||||
row := db.DB().QueryRow(fmt.Sprintf("SELECT COUNT(*) FROM %s", tableName))
|
||||
_ = row.Scan(&count)
|
||||
_, _ = db.SQL(fmt.Sprintf("SELECT COUNT(*) FROM %s", tableName)).Get(&count)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -240,7 +240,7 @@ func (session *Session) getSlice(rows *core.Rows, types []*sql.ColumnType, field
|
|||
}
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("unspoorted slice type: %t", t)
|
||||
return fmt.Errorf("unsupported slice type: %t", t)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -269,7 +269,7 @@ func (session *Session) getMap(rows *core.Rows, types []*sql.ColumnType, fields
|
|||
}
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("unspoorted map type: %t", t)
|
||||
return fmt.Errorf("unsupported map type: %t", t)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,12 @@ func (session *Session) Iterate(bean interface{}, fun IterFunc) error {
|
|||
defer session.Close()
|
||||
}
|
||||
|
||||
session.autoResetStatement = false
|
||||
defer func() {
|
||||
session.autoResetStatement = true
|
||||
session.resetStatement()
|
||||
}()
|
||||
|
||||
if session.statement.LastError != nil {
|
||||
return session.statement.LastError
|
||||
}
|
||||
|
@ -64,15 +70,15 @@ func (session *Session) BufferSize(size int) *Session {
|
|||
}
|
||||
|
||||
func (session *Session) bufferIterate(bean interface{}, fun IterFunc) error {
|
||||
var bufferSize = session.statement.BufferSize
|
||||
var pLimitN = session.statement.LimitN
|
||||
bufferSize := session.statement.BufferSize
|
||||
pLimitN := session.statement.LimitN
|
||||
if pLimitN != nil && bufferSize > *pLimitN {
|
||||
bufferSize = *pLimitN
|
||||
}
|
||||
var start = session.statement.Start
|
||||
start := session.statement.Start
|
||||
v := utils.ReflectValue(bean)
|
||||
sliceType := reflect.SliceOf(v.Type())
|
||||
var idx = 0
|
||||
idx := 0
|
||||
session.autoResetStatement = false
|
||||
defer func() {
|
||||
session.autoResetStatement = true
|
||||
|
|
|
@ -311,3 +311,8 @@ func (session *Session) Import(r io.Reader) ([]sql.Result, error) {
|
|||
|
||||
return results, lastError
|
||||
}
|
||||
|
||||
func (session *Session) IndexHint(op, forType, indexerOrColName string) *Session {
|
||||
session.statement.IndexHint(op, forType, indexerOrColName)
|
||||
return session
|
||||
}
|
||||
|
|
|
@ -15,11 +15,11 @@ import (
|
|||
"xorm.io/xorm/schemas"
|
||||
|
||||
_ "gitee.com/travelliu/dm"
|
||||
_ "github.com/denisenkom/go-mssqldb"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
_ "github.com/jackc/pgx/v4/stdlib"
|
||||
_ "github.com/lib/pq"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
_ "github.com/microsoft/go-mssqldb"
|
||||
"github.com/stretchr/testify/assert"
|
||||
_ "github.com/ziutek/mymysql/godrv"
|
||||
_ "modernc.org/sqlite"
|
||||
|
|
|
@ -111,4 +111,25 @@ func TestBufferIterate(t *testing.T) {
|
|||
})
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 10, cnt)
|
||||
|
||||
// test reset statement
|
||||
cnt = 0
|
||||
sess := testEngine.NewSession()
|
||||
defer sess.Close()
|
||||
// generate: SELECT `id`, `is_man` FROM `user_buffer_iterate` WHERE (`id` <= 10) LIMIT 2 OFFSET 10 []
|
||||
err = sess.Where("`id` <= 10").BufferSize(2).Iterate(new(UserBufferIterate), func(i int, bean interface{}) error {
|
||||
user := bean.(*UserBufferIterate)
|
||||
assert.EqualValues(t, cnt+1, user.Id)
|
||||
assert.EqualValues(t, true, user.IsMan)
|
||||
cnt++
|
||||
return nil
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 10, cnt)
|
||||
|
||||
beans := make([]*UserBufferIterate, 0, 10)
|
||||
// generate: SELECT `id`, `is_man` FROM `user_buffer_iterate` WHERE (`id` <= 10) AND (`id` >= 10) LIMIT 2 OFFSET 10 []
|
||||
err = sess.Where("`id` >= 10").Limit(2).Find(&beans)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, beans, 2)
|
||||
}
|
||||
|
|
|
@ -62,3 +62,27 @@ func TestEnableSessionId(t *testing.T) {
|
|||
_, err := testEngine.Table("userinfo").MustLogSQL(true).Get(new(Userinfo))
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestIndexHint(t *testing.T) {
|
||||
assert.NoError(t, PrepareEngine())
|
||||
assertSync(t, new(Userinfo), new(Userdetail))
|
||||
if testEngine.Dialect().URI().DBType != "mysql" {
|
||||
return
|
||||
}
|
||||
|
||||
_, err := testEngine.Table("userinfo").IndexHint("USE", "", "UQE_userinfo_username").Get(new(Userinfo))
|
||||
assert.NoError(t, err)
|
||||
|
||||
_, err = testEngine.Table("userinfo").IndexHint("USE", "ORDER BY", "UQE_userinfo_username").Get(new(Userinfo))
|
||||
assert.NoError(t, err)
|
||||
|
||||
_, err = testEngine.Table("userinfo").IndexHint("USE", "GROUP BY", "UQE_userinfo_username").Get(new(Userinfo))
|
||||
assert.NoError(t, err)
|
||||
|
||||
// with join
|
||||
_, err = testEngine.Table("userinfo").
|
||||
Join("LEFT", "userdetail", "userinfo.id = userdetail.id").
|
||||
IndexHint("USE", "", "UQE_userinfo_username").
|
||||
Get(new(Userinfo))
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
|
|
@ -1471,7 +1471,6 @@ func TestNilFromDB(t *testing.T) {
|
|||
assert.NotNil(t, tt4.Field1.cb)
|
||||
}
|
||||
|
||||
/*
|
||||
func TestUpdateWithJoin(t *testing.T) {
|
||||
type TestUpdateWithJoin struct {
|
||||
Id int64
|
||||
|
@ -1494,10 +1493,15 @@ func TestUpdateWithJoin(t *testing.T) {
|
|||
_, err = testEngine.Insert(&TestUpdateWithJoin{ExtId: b.Id, Name: "test"})
|
||||
assert.NoError(t, err)
|
||||
|
||||
_, err = testEngine.Table("test_update_with_join").
|
||||
Join("INNER", "test_update_with_join2 AS b", "test_update_with_join.ext_id = b.id").
|
||||
Where("b.`name` = ?", "test").
|
||||
Update(&TestUpdateWithJoin{Name: "test2"})
|
||||
assert.NoError(t, err)
|
||||
|
||||
_, err = testEngine.Table("test_update_with_join").
|
||||
Join("INNER", "test_update_with_join2", "test_update_with_join.ext_id = test_update_with_join2.id").
|
||||
Where("test_update_with_join2.name = ?", "test").
|
||||
Where("test_update_with_join2.`name` = ?", "test").
|
||||
Update(&TestUpdateWithJoin{Name: "test2"})
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -40,6 +40,7 @@ var (
|
|||
quotePolicyStr = flag.String("quote", "always", "quote could be always, none, reversed")
|
||||
defaultVarchar = flag.String("default_varchar", "varchar", "default varchar type, mssql only, could be varchar or nvarchar, default is varchar")
|
||||
defaultChar = flag.String("default_char", "char", "default char type, mssql only, could be char or nchar, default is char")
|
||||
collation = flag.String("collation", "", "default database collation, it's different for different database")
|
||||
tableMapper names.Mapper
|
||||
colMapper names.Mapper
|
||||
)
|
||||
|
@ -55,7 +56,12 @@ func createEngine(dbType, connStr string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = db.Exec("If(db_id(N'xorm_test') IS NULL) BEGIN CREATE DATABASE xorm_test; END;"); err != nil {
|
||||
createDBSQL := "If(db_id(N'xorm_test') IS NULL) BEGIN CREATE DATABASE xorm_test"
|
||||
if collation != nil && *collation != "" {
|
||||
createDBSQL += fmt.Sprintf(" COLLATE %s", *collation)
|
||||
}
|
||||
createDBSQL += "; END;"
|
||||
if _, err = db.Exec(createDBSQL); err != nil {
|
||||
return fmt.Errorf("db.Exec: %v", err)
|
||||
}
|
||||
db.Close()
|
||||
|
|
Loading…
Reference in New Issue