aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/xorm.io
diff options
context:
space:
mode:
authorLunny Xiao <xiaolunwen@gmail.com>2021-08-13 07:11:42 +0800
committerGitHub <noreply@github.com>2021-08-13 01:11:42 +0200
commit7224cfc578c1ff9f6b52ad13d18d3ca37d7f8186 (patch)
tree763e29950bed8c31caba1dc2b943da87e6810202 /vendor/xorm.io
parent5fbccad906f803c63e758ad3a168714430c9d1a9 (diff)
downloadgitea-7224cfc578c1ff9f6b52ad13d18d3ca37d7f8186.tar.gz
gitea-7224cfc578c1ff9f6b52ad13d18d3ca37d7f8186.zip
Upgrade xorm to v1.2.2 (#16663)
* Upgrade xorm to v1.2.2 * Change the Engine interface to match xorm v1.2.2
Diffstat (limited to 'vendor/xorm.io')
-rw-r--r--vendor/xorm.io/xorm/.drone.yml54
-rw-r--r--vendor/xorm.io/xorm/CHANGELOG.md49
-rw-r--r--vendor/xorm.io/xorm/Makefile36
-rw-r--r--vendor/xorm.io/xorm/README.md22
-rw-r--r--vendor/xorm.io/xorm/README_CN.md10
-rw-r--r--vendor/xorm.io/xorm/convert.go378
-rw-r--r--vendor/xorm.io/xorm/convert/bool.go51
-rw-r--r--vendor/xorm.io/xorm/convert/conversion.go376
-rw-r--r--vendor/xorm.io/xorm/convert/float.go142
-rw-r--r--vendor/xorm.io/xorm/convert/int.go178
-rw-r--r--vendor/xorm.io/xorm/convert/interface.go49
-rw-r--r--vendor/xorm.io/xorm/convert/scanner.go19
-rw-r--r--vendor/xorm.io/xorm/convert/string.go75
-rw-r--r--vendor/xorm.io/xorm/convert/time.go117
-rw-r--r--vendor/xorm.io/xorm/dialects/dialect.go18
-rw-r--r--vendor/xorm.io/xorm/dialects/driver.go24
-rw-r--r--vendor/xorm.io/xorm/dialects/mssql.go88
-rw-r--r--vendor/xorm.io/xorm/dialects/mysql.go180
-rw-r--r--vendor/xorm.io/xorm/dialects/oracle.go68
-rw-r--r--vendor/xorm.io/xorm/dialects/postgres.go194
-rw-r--r--vendor/xorm.io/xorm/dialects/sqlite3.go72
-rw-r--r--vendor/xorm.io/xorm/dialects/time.go71
-rw-r--r--vendor/xorm.io/xorm/doc.go68
-rw-r--r--vendor/xorm.io/xorm/engine.go235
-rw-r--r--vendor/xorm.io/xorm/engine_group.go28
-rw-r--r--vendor/xorm.io/xorm/go.mod17
-rw-r--r--vendor/xorm.io/xorm/go.sum509
-rw-r--r--vendor/xorm.io/xorm/interface.go3
-rw-r--r--vendor/xorm.io/xorm/internal/json/gojson.go28
-rw-r--r--vendor/xorm.io/xorm/internal/statements/insert.go53
-rw-r--r--vendor/xorm.io/xorm/internal/statements/query.go5
-rw-r--r--vendor/xorm.io/xorm/internal/statements/statement.go290
-rw-r--r--vendor/xorm.io/xorm/internal/statements/update.go21
-rw-r--r--vendor/xorm.io/xorm/internal/statements/values.go26
-rw-r--r--vendor/xorm.io/xorm/internal/utils/strings.go4
-rw-r--r--vendor/xorm.io/xorm/names/mapper.go2
-rw-r--r--vendor/xorm.io/xorm/rows.go41
-rw-r--r--vendor/xorm.io/xorm/scan.go271
-rw-r--r--vendor/xorm.io/xorm/schemas/type.go200
-rw-r--r--vendor/xorm.io/xorm/session.go638
-rw-r--r--vendor/xorm.io/xorm/session_convert.go521
-rw-r--r--vendor/xorm.io/xorm/session_delete.go77
-rw-r--r--vendor/xorm.io/xorm/session_exist.go5
-rw-r--r--vendor/xorm.io/xorm/session_find.go21
-rw-r--r--vendor/xorm.io/xorm/session_get.go273
-rw-r--r--vendor/xorm.io/xorm/session_insert.go267
-rw-r--r--vendor/xorm.io/xorm/session_iterate.go2
-rw-r--r--vendor/xorm.io/xorm/session_query.go87
-rw-r--r--vendor/xorm.io/xorm/session_raw.go34
-rw-r--r--vendor/xorm.io/xorm/session_schema.go8
-rw-r--r--vendor/xorm.io/xorm/session_update.go13
-rw-r--r--vendor/xorm.io/xorm/tags/parser.go54
-rw-r--r--vendor/xorm.io/xorm/tags/tag.go20
53 files changed, 3697 insertions, 2395 deletions
diff --git a/vendor/xorm.io/xorm/.drone.yml b/vendor/xorm.io/xorm/.drone.yml
index 8a9f887742..34b9a514de 100644
--- a/vendor/xorm.io/xorm/.drone.yml
+++ b/vendor/xorm.io/xorm/.drone.yml
@@ -30,9 +30,15 @@ steps:
- make test
- make test-sqlite3
- TEST_CACHE_ENABLE=true make test-sqlite3
- - TEST_QUOTE_POLICY=reserved make test-sqlite3
+- name: test-sqlite
+ image: golang:1.15
+ volumes:
+ - name: cache
+ path: /go/pkg/mod
+ depends_on:
+ - test-vet
+ commands:
- make test-sqlite
- - TEST_CACHE_ENABLE=true make test-sqlite
- TEST_QUOTE_POLICY=reserved make test-sqlite
- name: test-mysql
image: golang:1.15
@@ -106,7 +112,6 @@ steps:
commands:
- make test-mysql
- TEST_CACHE_ENABLE=true make test-mysql
- - TEST_QUOTE_POLICY=reserved make test-mysql
volumes:
- name: cache
@@ -144,7 +149,6 @@ steps:
TEST_MYSQL_PASSWORD:
commands:
- make test-mysql
- - TEST_CACHE_ENABLE=true make test-mysql
- TEST_QUOTE_POLICY=reserved make test-mysql
volumes:
@@ -201,6 +205,43 @@ steps:
commands:
- TEST_QUOTE_POLICY=reserved make test-postgres
+- name: test-pgx
+ pull: never
+ image: golang:1.15
+ volumes:
+ - name: cache
+ path: /go/pkg/mod
+ depends_on:
+ - test-postgres-schema
+ environment:
+ TEST_PGSQL_HOST: pgsql
+ TEST_PGSQL_DBNAME: xorm_test
+ TEST_PGSQL_USERNAME: postgres
+ TEST_PGSQL_PASSWORD: postgres
+ commands:
+ - make test-pgx
+ - TEST_CACHE_ENABLE=true make test-pgx
+ - TEST_QUOTE_POLICY=reserved make test-pgx
+
+- name: test-pgx-schema
+ pull: never
+ image: golang:1.15
+ volumes:
+ - name: cache
+ path: /go/pkg/mod
+ depends_on:
+ - test-pgx
+ environment:
+ TEST_PGSQL_HOST: pgsql
+ TEST_PGSQL_SCHEMA: xorm
+ TEST_PGSQL_DBNAME: xorm_test
+ TEST_PGSQL_USERNAME: postgres
+ TEST_PGSQL_PASSWORD: postgres
+ commands:
+ - make test-pgx
+ - TEST_CACHE_ENABLE=true make test-pgx
+ - TEST_QUOTE_POLICY=reserved make test-pgx
+
volumes:
- name: cache
host:
@@ -237,8 +278,6 @@ steps:
TEST_MSSQL_PASSWORD: "yourStrong(!)Password"
commands:
- make test-mssql
- - 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
volumes:
@@ -278,8 +317,6 @@ steps:
TEST_TIDB_PASSWORD:
commands:
- make test-tidb
- - TEST_CACHE_ENABLE=true make test-tidb
- - TEST_QUOTE_POLICY=reserved make test-tidb
volumes:
- name: cache
@@ -314,7 +351,6 @@ steps:
commands:
- sleep 10
- make test-cockroach
- - TEST_CACHE_ENABLE=true make test-cockroach
volumes:
- name: cache
diff --git a/vendor/xorm.io/xorm/CHANGELOG.md b/vendor/xorm.io/xorm/CHANGELOG.md
index cd567b27a3..0f0f93e7b6 100644
--- a/vendor/xorm.io/xorm/CHANGELOG.md
+++ b/vendor/xorm.io/xorm/CHANGELOG.md
@@ -3,6 +3,55 @@
This changelog goes through all the changes that have been made in each release
without substantial changes to our git log.
+## [1.2.2](https://gitea.com/xorm/xorm/releases/tag/1.2.2) - 2021-08-11
+
+* MISC
+ * Move convert back to xorm.io/xorm/convert (#2030)
+
+## [1.2.1](https://gitea.com/xorm/xorm/releases/tag/1.2.1) - 2021-08-08
+
+* FEATURES
+ * Add pgx driver support (#1795)
+* BUGFIXES
+ * Fix wrong comment (#2027)
+ * Fix import file bug (#2025)
+* ENHANCEMENTS
+ * Fix timesatmp (#2021)
+
+## [1.2.0](https://gitea.com/xorm/xorm/releases/tag/1.2.0) - 2021-08-04
+
+* BREAKING
+ * Exec with time arg now will obey time zone settings on engine (#1989)
+ * Query interface (#1965)
+ * Support delete with no bean (#1926)
+ * Nil ptr is nullable (#1919)
+* FEATURES
+ * Support batch insert map (#2019)
+ * Support big.Float (#1973)
+* BUGFIXES
+ * fix possible null dereference in internal/statements/query.go (#1988)
+ * Fix bug on dumptable (#1984)
+* ENHANCEMENTS
+ * Move assign functions to convert package (#2015)
+ * refactor conversion (#2001)
+ * refactor some code (#2000)
+ * refactor insert condition generation (#1998)
+ * refactor and add setjson function (#1997)
+ * Get struct and Find support big.Float (#1976)
+ * refactor slice2Bean (#1974, #1975)
+ * refactor get (#1967)
+ * Replace #1044 (#1935)
+ * Support Get time.Time (#1933)
+* TESTING
+ * Add benchmark tests (#1978)
+ * Add tests for github.com/shopspring/decimal support (#1977)
+ * Add test for get map with NULL column (#1948)
+ * Add test for limit with query (#1787)
+* MISC
+ * Fix DBMetas returned unsigned tinyint (#2017)
+ * Fix deleted column (#2014)
+ * Add database alias table and fix wrong warning (#1947)
+
## [1.1.2](https://gitea.com/xorm/xorm/releases/tag/1.1.2) - 2021-07-04
* BUILD
diff --git a/vendor/xorm.io/xorm/Makefile b/vendor/xorm.io/xorm/Makefile
index bf71b0f42d..e986082e99 100644
--- a/vendor/xorm.io/xorm/Makefile
+++ b/vendor/xorm.io/xorm/Makefile
@@ -6,7 +6,7 @@ GOFMT ?= gofmt -s
TAGS ?=
SED_INPLACE := sed -i
-GO_DIRS := caches contexts integrations convert core dialects internal log migrate names schemas tags
+GO_DIRS := caches contexts integrations 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
@@ -138,7 +138,7 @@ test: go-check
test-cockroach: go-check
$(GO) test $(INTEGRATION_PACKAGES) -v -race -db=postgres -schema='$(TEST_COCKROACH_SCHEMA)' -cache=$(TEST_CACHE_ENABLE) \
-conn_str="postgres://$(TEST_COCKROACH_USERNAME):$(TEST_COCKROACH_PASSWORD)@$(TEST_COCKROACH_HOST)/$(TEST_COCKROACH_DBNAME)?sslmode=disable&experimental_serial_normalization=sql_sequence" \
- -ignore_update_limit=true -coverprofile=cockroach.$(TEST_COCKROACH_SCHEMA).$(TEST_CACHE_ENABLE).coverage.out -covermode=atomic
+ -ignore_update_limit=true -coverprofile=cockroach.$(TEST_COCKROACH_SCHEMA).$(TEST_CACHE_ENABLE).coverage.out -covermode=atomic -timeout=20m
.PHONY: test-cockroach\#%
test-cockroach\#%: go-check
@@ -152,7 +152,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) \
- -coverprofile=mssql.$(TEST_QUOTE_POLICY).$(TEST_CACHE_ENABLE).coverage.out -covermode=atomic
+ -coverprofile=mssql.$(TEST_QUOTE_POLICY).$(TEST_CACHE_ENABLE).coverage.out -covermode=atomic -timeout=20m
.PNONY: test-mssql\#%
test-mssql\#%: go-check
@@ -166,7 +166,7 @@ test-mssql\#%: go-check
test-mymysql: go-check
$(GO) test $(INTEGRATION_PACKAGES) -v -race -db=mymysql -cache=$(TEST_CACHE_ENABLE) -quote=$(TEST_QUOTE_POLICY) \
-conn_str="tcp:$(TEST_MYSQL_HOST)*$(TEST_MYSQL_DBNAME)/$(TEST_MYSQL_USERNAME)/$(TEST_MYSQL_PASSWORD)" \
- -coverprofile=mymysql.$(TEST_QUOTE_POLICY).$(TEST_CACHE_ENABLE).coverage.out -covermode=atomic
+ -coverprofile=mymysql.$(TEST_QUOTE_POLICY).$(TEST_CACHE_ENABLE).coverage.out -covermode=atomic -timeout=20m
.PNONY: test-mymysql\#%
test-mymysql\#%: go-check
@@ -178,7 +178,7 @@ test-mymysql\#%: go-check
test-mysql: go-check
$(GO) test $(INTEGRATION_PACKAGES) -v -race -db=mysql -cache=$(TEST_CACHE_ENABLE) -quote=$(TEST_QUOTE_POLICY) \
-conn_str="$(TEST_MYSQL_USERNAME):$(TEST_MYSQL_PASSWORD)@tcp($(TEST_MYSQL_HOST))/$(TEST_MYSQL_DBNAME)?charset=$(TEST_MYSQL_CHARSET)" \
- -coverprofile=mysql.$(TEST_QUOTE_POLICY).$(TEST_CACHE_ENABLE).coverage.out -covermode=atomic
+ -coverprofile=mysql.$(TEST_QUOTE_POLICY).$(TEST_CACHE_ENABLE).coverage.out -covermode=atomic -timeout=20m
.PHONY: test-mysql\#%
test-mysql\#%: go-check
@@ -190,7 +190,7 @@ test-mysql\#%: go-check
test-postgres: go-check
$(GO) test $(INTEGRATION_PACKAGES) -v -race -db=postgres -schema='$(TEST_PGSQL_SCHEMA)' -cache=$(TEST_CACHE_ENABLE) \
-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
+ -quote=$(TEST_QUOTE_POLICY) -coverprofile=postgres.$(TEST_QUOTE_POLICY).$(TEST_CACHE_ENABLE).coverage.out -covermode=atomic -timeout=20m
.PHONY: test-postgres\#%
test-postgres\#%: go-check
@@ -201,27 +201,39 @@ test-postgres\#%: go-check
.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
+ -quote=$(TEST_QUOTE_POLICY) -coverprofile=sqlite3.$(TEST_QUOTE_POLICY).$(TEST_CACHE_ENABLE).coverage.out -covermode=atomic -timeout=20m
.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
+ -quote=$(TEST_QUOTE_POLICY) -coverprofile=sqlite3.$(TEST_QUOTE_POLICY).$(TEST_CACHE_ENABLE).coverage.out -covermode=atomic -timeout=20m
.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
+ -quote=$(TEST_QUOTE_POLICY) -coverprofile=sqlite3.$(TEST_QUOTE_POLICY).$(TEST_CACHE_ENABLE).coverage.out -covermode=atomic -timeout=20m
+
+.PNONY: test-pgx
+test-pgx: go-check
+ $(GO) test $(INTEGRATION_PACKAGES) -v -race -db=pgx -schema='$(TEST_PGSQL_SCHEMA)' -cache=$(TEST_CACHE_ENABLE) \
+ -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 -timeout=20m
+
+.PHONY: test-pgx\#%
+test-pgx\#%: go-check
+ $(GO) test $(INTEGRATION_PACKAGES) -v -race -run $* -db=pgx -schema='$(TEST_PGSQL_SCHEMA)' -cache=$(TEST_CACHE_ENABLE) \
+ -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 -timeout=20m
.PHONY: test-sqlite
test-sqlite: go-check
$(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
+ -quote=$(TEST_QUOTE_POLICY) -coverprofile=sqlite.$(TEST_QUOTE_POLICY).$(TEST_CACHE_ENABLE).coverage.out -covermode=atomic -timeout=20m
.PHONY: test-sqlite-schema
test-sqlite-schema: go-check
$(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
+ -quote=$(TEST_QUOTE_POLICY) -coverprofile=sqlite.$(TEST_QUOTE_POLICY).$(TEST_CACHE_ENABLE).coverage.out -covermode=atomic -timeout=20m
.PHONY: test-sqlite\#%
test-sqlite\#%: go-check
@@ -233,7 +245,7 @@ test-sqlite\#%: go-check
test-tidb: go-check
$(GO) test $(INTEGRATION_PACKAGES) -v -race -db=mysql -cache=$(TEST_CACHE_ENABLE) -ignore_select_update=true \
-conn_str="$(TEST_TIDB_USERNAME):$(TEST_TIDB_PASSWORD)@tcp($(TEST_TIDB_HOST))/$(TEST_TIDB_DBNAME)" \
- -quote=$(TEST_QUOTE_POLICY) -coverprofile=tidb.$(TEST_QUOTE_POLICY).$(TEST_CACHE_ENABLE).coverage.out -covermode=atomic
+ -quote=$(TEST_QUOTE_POLICY) -coverprofile=tidb.$(TEST_QUOTE_POLICY).$(TEST_CACHE_ENABLE).coverage.out -covermode=atomic -timeout=20m
.PHONY: test-tidb\#%
test-tidb\#%: go-check
diff --git a/vendor/xorm.io/xorm/README.md b/vendor/xorm.io/xorm/README.md
index 6738083943..f4bee6b638 100644
--- a/vendor/xorm.io/xorm/README.md
+++ b/vendor/xorm.io/xorm/README.md
@@ -41,14 +41,17 @@ Drivers for Go's sql package which currently support database/sql includes:
* [Postgres](https://github.com/postgres/postgres) / [Cockroach](https://github.com/cockroachdb/cockroach)
- [github.com/lib/pq](https://github.com/lib/pq)
+ - [github.com/jackc/pgx](https://github.com/jackc/pgx)
* [SQLite](https://sqlite.org)
- [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3)
+ - [modernc.org/sqlite](https://gitlab.com/cznic/sqlite) (windows unsupported)
* MsSql
- [github.com/denisenkom/go-mssqldb](https://github.com/denisenkom/go-mssqldb)
* Oracle
+ - [github.com/godror/godror](https://github.com/godror/godror) (experiment)
- [github.com/mattn/go-oci8](https://github.com/mattn/go-oci8) (experiment)
## Installation
@@ -245,35 +248,38 @@ for rows.Next() {
```Go
affected, err := engine.ID(1).Update(&user)
-// UPDATE user SET ... Where id = ?
+// UPDATE user SET ... WHERE id = ?
affected, err := engine.Update(&user, &User{Name:name})
-// UPDATE user SET ... Where name = ?
+// UPDATE user SET ... WHERE name = ?
var ids = []int64{1, 2, 3}
affected, err := engine.In("id", ids).Update(&user)
-// UPDATE user SET ... Where id IN (?, ?, ?)
+// UPDATE user SET ... WHERE id IN (?, ?, ?)
// force update indicated columns by Cols
affected, err := engine.ID(1).Cols("age").Update(&User{Name:name, Age: 12})
-// UPDATE user SET age = ?, updated=? Where id = ?
+// UPDATE user SET age = ?, updated=? WHERE id = ?
// force NOT update indicated columns by Omit
affected, err := engine.ID(1).Omit("name").Update(&User{Name:name, Age: 12})
-// UPDATE user SET age = ?, updated=? Where id = ?
+// UPDATE user SET age = ?, updated=? WHERE id = ?
affected, err := engine.ID(1).AllCols().Update(&user)
-// UPDATE user SET name=?,age=?,salt=?,passwd=?,updated=? Where id = ?
+// UPDATE user SET name=?,age=?,salt=?,passwd=?,updated=? WHERE id = ?
```
* `Delete` delete one or more records, Delete MUST have condition
```Go
affected, err := engine.Where(...).Delete(&user)
-// DELETE FROM user Where ...
+// DELETE FROM user WHERE ...
affected, err := engine.ID(2).Delete(&user)
-// DELETE FROM user Where id = ?
+// DELETE FROM user WHERE id = ?
+
+affected, err := engine.Table("user").Where(...).Delete()
+// DELETE FROM user WHERE ...
```
* `Count` count records
diff --git a/vendor/xorm.io/xorm/README_CN.md b/vendor/xorm.io/xorm/README_CN.md
index 80245dd33f..500bb1fb3e 100644
--- a/vendor/xorm.io/xorm/README_CN.md
+++ b/vendor/xorm.io/xorm/README_CN.md
@@ -40,14 +40,17 @@ v1.0.0 相对于 v0.8.2 有以下不兼容的变更:
* [Postgres](https://github.com/postgres/postgres) / [Cockroach](https://github.com/cockroachdb/cockroach)
- [github.com/lib/pq](https://github.com/lib/pq)
+ - [github.com/jackc/pgx](https://github.com/jackc/pgx)
* [SQLite](https://sqlite.org)
- [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3)
+ - [modernc.org/sqlite](https://gitlab.com/cznic/sqlite) (Windows试验性支持)
* MsSql
- [github.com/denisenkom/go-mssqldb](https://github.com/denisenkom/go-mssqldb)
* Oracle
+ - [github.com/godror/godror](https://github.com/godror/godror) (试验性支持)
- [github.com/mattn/go-oci8](https://github.com/mattn/go-oci8) (试验性支持)
## 安装
@@ -62,7 +65,7 @@ v1.0.0 相对于 v0.8.2 有以下不兼容的变更:
# 快速开始
-* 第一步创建引擎,driverName, dataSourceName和database/sql接口相同
+* 第一步创建引擎,`driverName`, `dataSourceName` 和 `database/sql` 接口相同
```Go
engine, err := xorm.NewEngine(driverName, dataSourceName)
@@ -100,7 +103,7 @@ engineGroup, err := xorm.NewEngineGroup(masterEngine, []*Engine{slave1Engine, sl
所有使用 `engine` 都可以简单的用 `engineGroup` 来替换。
-* `Query` 最原始的也支持SQL语句查询,返回的结果类型为 []map[string][]byte。`QueryString` 返回 []map[string]string, `QueryInterface` 返回 `[]map[string]interface{}`.
+* `Query` 最原始的也支持SQL语句查询,返回的结果类型为 `[]map[string][]byte`。`QueryString` 返回 `[]map[string]string`, `QueryInterface` 返回 `[]map[string]interface{}`.
```Go
results, err := engine.Query("select * from user")
@@ -271,6 +274,9 @@ affected, err := engine.Where(...).Delete(&user)
affected, err := engine.ID(2).Delete(&user)
// DELETE FROM user Where id = ?
+
+affected, err := engine.Table("user").Where(...).Delete()
+// DELETE FROM user WHERE ...
```
* `Count` 获取记录条数
diff --git a/vendor/xorm.io/xorm/convert.go b/vendor/xorm.io/xorm/convert.go
deleted file mode 100644
index b7f30caddc..0000000000
--- a/vendor/xorm.io/xorm/convert.go
+++ /dev/null
@@ -1,378 +0,0 @@
-// Copyright 2017 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 xorm
-
-import (
- "database/sql/driver"
- "errors"
- "fmt"
- "reflect"
- "strconv"
- "time"
-)
-
-var errNilPtr = errors.New("destination pointer is nil") // embedded in descriptive error
-
-func strconvErr(err error) error {
- if ne, ok := err.(*strconv.NumError); ok {
- return ne.Err
- }
- return err
-}
-
-func cloneBytes(b []byte) []byte {
- if b == nil {
- return nil
- }
- c := make([]byte, len(b))
- copy(c, b)
- return c
-}
-
-func asString(src interface{}) string {
- switch v := src.(type) {
- case string:
- return v
- case []byte:
- return string(v)
- }
- rv := reflect.ValueOf(src)
- switch rv.Kind() {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return strconv.FormatInt(rv.Int(), 10)
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- return strconv.FormatUint(rv.Uint(), 10)
- case reflect.Float64:
- return strconv.FormatFloat(rv.Float(), 'g', -1, 64)
- case reflect.Float32:
- return strconv.FormatFloat(rv.Float(), 'g', -1, 32)
- case reflect.Bool:
- return strconv.FormatBool(rv.Bool())
- }
- return fmt.Sprintf("%v", src)
-}
-
-func asBytes(buf []byte, rv reflect.Value) (b []byte, ok bool) {
- switch rv.Kind() {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return strconv.AppendInt(buf, rv.Int(), 10), true
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- return strconv.AppendUint(buf, rv.Uint(), 10), true
- case reflect.Float32:
- return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 32), true
- case reflect.Float64:
- return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 64), true
- case reflect.Bool:
- return strconv.AppendBool(buf, rv.Bool()), true
- case reflect.String:
- s := rv.String()
- return append(buf, s...), true
- }
- return
-}
-
-// convertAssign copies to dest the value in src, converting it if possible.
-// An error is returned if the copy would result in loss of information.
-// dest should be a pointer type.
-func convertAssign(dest, src interface{}) error {
- // Common cases, without reflect.
- switch s := src.(type) {
- case string:
- switch d := dest.(type) {
- case *string:
- if d == nil {
- return errNilPtr
- }
- *d = s
- return nil
- case *[]byte:
- if d == nil {
- return errNilPtr
- }
- *d = []byte(s)
- return nil
- }
- case []byte:
- switch d := dest.(type) {
- case *string:
- if d == nil {
- return errNilPtr
- }
- *d = string(s)
- return nil
- case *interface{}:
- if d == nil {
- return errNilPtr
- }
- *d = cloneBytes(s)
- return nil
- case *[]byte:
- if d == nil {
- return errNilPtr
- }
- *d = cloneBytes(s)
- return nil
- }
-
- case time.Time:
- switch d := dest.(type) {
- case *string:
- *d = s.Format(time.RFC3339Nano)
- return nil
- case *[]byte:
- if d == nil {
- return errNilPtr
- }
- *d = []byte(s.Format(time.RFC3339Nano))
- return nil
- }
- case nil:
- switch d := dest.(type) {
- case *interface{}:
- if d == nil {
- return errNilPtr
- }
- *d = nil
- return nil
- case *[]byte:
- if d == nil {
- return errNilPtr
- }
- *d = nil
- return nil
- }
- }
-
- var sv reflect.Value
-
- switch d := dest.(type) {
- case *string:
- sv = reflect.ValueOf(src)
- switch sv.Kind() {
- case reflect.Bool,
- reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
- reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
- reflect.Float32, reflect.Float64:
- *d = asString(src)
- return nil
- }
- case *[]byte:
- sv = reflect.ValueOf(src)
- if b, ok := asBytes(nil, sv); ok {
- *d = b
- return nil
- }
- case *bool:
- bv, err := driver.Bool.ConvertValue(src)
- if err == nil {
- *d = bv.(bool)
- }
- return err
- case *interface{}:
- *d = src
- return nil
- }
-
- return convertAssignV(reflect.ValueOf(dest), src)
-}
-
-func convertAssignV(dpv reflect.Value, src interface{}) error {
- if dpv.Kind() != reflect.Ptr {
- return errors.New("destination not a pointer")
- }
- if dpv.IsNil() {
- return errNilPtr
- }
-
- var sv = reflect.ValueOf(src)
-
- dv := reflect.Indirect(dpv)
- if sv.IsValid() && sv.Type().AssignableTo(dv.Type()) {
- switch b := src.(type) {
- case []byte:
- dv.Set(reflect.ValueOf(cloneBytes(b)))
- default:
- dv.Set(sv)
- }
- return nil
- }
-
- if dv.Kind() == sv.Kind() && sv.Type().ConvertibleTo(dv.Type()) {
- dv.Set(sv.Convert(dv.Type()))
- return nil
- }
-
- switch dv.Kind() {
- case reflect.Ptr:
- if src == nil {
- dv.Set(reflect.Zero(dv.Type()))
- return nil
- }
-
- dv.Set(reflect.New(dv.Type().Elem()))
- return convertAssign(dv.Interface(), src)
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- s := asString(src)
- i64, err := strconv.ParseInt(s, 10, dv.Type().Bits())
- if err != nil {
- err = strconvErr(err)
- return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err)
- }
- dv.SetInt(i64)
- return nil
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- s := asString(src)
- u64, err := strconv.ParseUint(s, 10, dv.Type().Bits())
- if err != nil {
- err = strconvErr(err)
- return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err)
- }
- dv.SetUint(u64)
- return nil
- case reflect.Float32, reflect.Float64:
- s := asString(src)
- f64, err := strconv.ParseFloat(s, dv.Type().Bits())
- if err != nil {
- err = strconvErr(err)
- return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err)
- }
- dv.SetFloat(f64)
- return nil
- case reflect.String:
- dv.SetString(asString(src))
- return nil
- }
-
- return fmt.Errorf("unsupported Scan, storing driver.Value type %T into type %T", src, dpv.Interface())
-}
-
-func asKind(vv reflect.Value, tp reflect.Type) (interface{}, error) {
- switch tp.Kind() {
- case reflect.Int64:
- return vv.Int(), nil
- case reflect.Int:
- return int(vv.Int()), nil
- case reflect.Int32:
- return int32(vv.Int()), nil
- case reflect.Int16:
- return int16(vv.Int()), nil
- case reflect.Int8:
- return int8(vv.Int()), nil
- case reflect.Uint64:
- return vv.Uint(), nil
- case reflect.Uint:
- return uint(vv.Uint()), nil
- case reflect.Uint32:
- return uint32(vv.Uint()), nil
- case reflect.Uint16:
- return uint16(vv.Uint()), nil
- case reflect.Uint8:
- return uint8(vv.Uint()), nil
- case reflect.String:
- return vv.String(), nil
- case reflect.Slice:
- if tp.Elem().Kind() == reflect.Uint8 {
- v, err := strconv.ParseInt(string(vv.Interface().([]byte)), 10, 64)
- if err != nil {
- return nil, err
- }
- return v, nil
- }
-
- }
- return nil, fmt.Errorf("unsupported primary key type: %v, %v", tp, vv)
-}
-
-func asBool(bs []byte) (bool, error) {
- if len(bs) == 0 {
- return false, nil
- }
- if bs[0] == 0x00 {
- return false, nil
- } else if bs[0] == 0x01 {
- return true, nil
- }
- return strconv.ParseBool(string(bs))
-}
-
-// str2PK convert string value to primary key value according to tp
-func str2PKValue(s string, tp reflect.Type) (reflect.Value, error) {
- var err error
- var result interface{}
- var defReturn = reflect.Zero(tp)
-
- switch tp.Kind() {
- case reflect.Int:
- result, err = strconv.Atoi(s)
- if err != nil {
- return defReturn, fmt.Errorf("convert %s as int: %s", s, err.Error())
- }
- case reflect.Int8:
- x, err := strconv.Atoi(s)
- if err != nil {
- return defReturn, fmt.Errorf("convert %s as int8: %s", s, err.Error())
- }
- result = int8(x)
- case reflect.Int16:
- x, err := strconv.Atoi(s)
- if err != nil {
- return defReturn, fmt.Errorf("convert %s as int16: %s", s, err.Error())
- }
- result = int16(x)
- case reflect.Int32:
- x, err := strconv.Atoi(s)
- if err != nil {
- return defReturn, fmt.Errorf("convert %s as int32: %s", s, err.Error())
- }
- result = int32(x)
- case reflect.Int64:
- result, err = strconv.ParseInt(s, 10, 64)
- if err != nil {
- return defReturn, fmt.Errorf("convert %s as int64: %s", s, err.Error())
- }
- case reflect.Uint:
- x, err := strconv.ParseUint(s, 10, 64)
- if err != nil {
- return defReturn, fmt.Errorf("convert %s as uint: %s", s, err.Error())
- }
- result = uint(x)
- case reflect.Uint8:
- x, err := strconv.ParseUint(s, 10, 64)
- if err != nil {
- return defReturn, fmt.Errorf("convert %s as uint8: %s", s, err.Error())
- }
- result = uint8(x)
- case reflect.Uint16:
- x, err := strconv.ParseUint(s, 10, 64)
- if err != nil {
- return defReturn, fmt.Errorf("convert %s as uint16: %s", s, err.Error())
- }
- result = uint16(x)
- case reflect.Uint32:
- x, err := strconv.ParseUint(s, 10, 64)
- if err != nil {
- return defReturn, fmt.Errorf("convert %s as uint32: %s", s, err.Error())
- }
- result = uint32(x)
- case reflect.Uint64:
- result, err = strconv.ParseUint(s, 10, 64)
- if err != nil {
- return defReturn, fmt.Errorf("convert %s as uint64: %s", s, err.Error())
- }
- case reflect.String:
- result = s
- default:
- return defReturn, errors.New("unsupported convert type")
- }
- return reflect.ValueOf(result).Convert(tp), nil
-}
-
-func str2PK(s string, tp reflect.Type) (interface{}, error) {
- v, err := str2PKValue(s, tp)
- if err != nil {
- return nil, err
- }
- return v.Interface(), nil
-}
diff --git a/vendor/xorm.io/xorm/convert/bool.go b/vendor/xorm.io/xorm/convert/bool.go
new file mode 100644
index 0000000000..58b23f4bb4
--- /dev/null
+++ b/vendor/xorm.io/xorm/convert/bool.go
@@ -0,0 +1,51 @@
+// Copyright 2021 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 convert
+
+import (
+ "database/sql"
+ "fmt"
+ "strconv"
+)
+
+// AsBool convert interface as bool
+func AsBool(src interface{}) (bool, error) {
+ switch v := src.(type) {
+ case bool:
+ return v, nil
+ case *bool:
+ return *v, nil
+ case *sql.NullBool:
+ return v.Bool, nil
+ case int64:
+ return v > 0, nil
+ case int:
+ return v > 0, nil
+ case int8:
+ return v > 0, nil
+ case int16:
+ return v > 0, nil
+ case int32:
+ return v > 0, nil
+ case []byte:
+ if len(v) == 0 {
+ return false, nil
+ }
+ if v[0] == 0x00 {
+ return false, nil
+ } else if v[0] == 0x01 {
+ return true, nil
+ }
+ return strconv.ParseBool(string(v))
+ case string:
+ return strconv.ParseBool(v)
+ case *sql.NullInt64:
+ return v.Int64 > 0, nil
+ case *sql.NullInt32:
+ return v.Int32 > 0, nil
+ default:
+ return false, fmt.Errorf("unknow type %T as bool", src)
+ }
+}
diff --git a/vendor/xorm.io/xorm/convert/conversion.go b/vendor/xorm.io/xorm/convert/conversion.go
index 16f1a92a16..096fcfaff3 100644
--- a/vendor/xorm.io/xorm/convert/conversion.go
+++ b/vendor/xorm.io/xorm/convert/conversion.go
@@ -4,9 +4,385 @@
package convert
+import (
+ "database/sql"
+ "database/sql/driver"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "math/big"
+ "reflect"
+ "strconv"
+ "time"
+)
+
// Conversion is an interface. A type implements Conversion will according
// the custom method to fill into database and retrieve from database.
type Conversion interface {
FromDB([]byte) error
ToDB() ([]byte, error)
}
+
+// ErrNilPtr represents an error
+var ErrNilPtr = errors.New("destination pointer is nil") // embedded in descriptive error
+
+func strconvErr(err error) error {
+ if ne, ok := err.(*strconv.NumError); ok {
+ return ne.Err
+ }
+ return err
+}
+
+func cloneBytes(b []byte) []byte {
+ if b == nil {
+ return nil
+ }
+ c := make([]byte, len(b))
+ copy(c, b)
+ return c
+}
+
+// Assign copies to dest the value in src, converting it if possible.
+// An error is returned if the copy would result in loss of information.
+// dest should be a pointer type.
+func Assign(dest, src interface{}, originalLocation *time.Location, convertedLocation *time.Location) error {
+ // Common cases, without reflect.
+ switch s := src.(type) {
+ case *interface{}:
+ return Assign(dest, *s, originalLocation, convertedLocation)
+ case string:
+ switch d := dest.(type) {
+ case *string:
+ if d == nil {
+ return ErrNilPtr
+ }
+ *d = s
+ return nil
+ case *[]byte:
+ if d == nil {
+ return ErrNilPtr
+ }
+ *d = []byte(s)
+ return nil
+ }
+ case []byte:
+ switch d := dest.(type) {
+ case *string:
+ if d == nil {
+ return ErrNilPtr
+ }
+ *d = string(s)
+ return nil
+ case *interface{}:
+ if d == nil {
+ return ErrNilPtr
+ }
+ *d = cloneBytes(s)
+ return nil
+ case *[]byte:
+ if d == nil {
+ return ErrNilPtr
+ }
+ *d = cloneBytes(s)
+ return nil
+ }
+ case time.Time:
+ switch d := dest.(type) {
+ case *string:
+ *d = s.Format(time.RFC3339Nano)
+ return nil
+ case *[]byte:
+ if d == nil {
+ return ErrNilPtr
+ }
+ *d = []byte(s.Format(time.RFC3339Nano))
+ return nil
+ }
+ case nil:
+ switch d := dest.(type) {
+ case *interface{}:
+ if d == nil {
+ return ErrNilPtr
+ }
+ *d = nil
+ return nil
+ case *[]byte:
+ if d == nil {
+ return ErrNilPtr
+ }
+ *d = nil
+ return nil
+ }
+ case *sql.NullString:
+ switch d := dest.(type) {
+ case *int:
+ if s.Valid {
+ *d, _ = strconv.Atoi(s.String)
+ }
+ return nil
+ case *int64:
+ if s.Valid {
+ *d, _ = strconv.ParseInt(s.String, 10, 64)
+ }
+ return nil
+ case *string:
+ if s.Valid {
+ *d = s.String
+ }
+ return nil
+ case *time.Time:
+ if s.Valid {
+ var err error
+ dt, err := String2Time(s.String, originalLocation, convertedLocation)
+ if err != nil {
+ return err
+ }
+ *d = *dt
+ }
+ return nil
+ case *sql.NullTime:
+ if s.Valid {
+ var err error
+ dt, err := String2Time(s.String, originalLocation, convertedLocation)
+ if err != nil {
+ return err
+ }
+ d.Valid = true
+ d.Time = *dt
+ }
+ return nil
+ case *big.Float:
+ if s.Valid {
+ if d == nil {
+ d = big.NewFloat(0)
+ }
+ d.SetString(s.String)
+ }
+ return nil
+ }
+ case *sql.NullInt32:
+ switch d := dest.(type) {
+ case *int:
+ if s.Valid {
+ *d = int(s.Int32)
+ }
+ return nil
+ case *int8:
+ if s.Valid {
+ *d = int8(s.Int32)
+ }
+ return nil
+ case *int16:
+ if s.Valid {
+ *d = int16(s.Int32)
+ }
+ return nil
+ case *int32:
+ if s.Valid {
+ *d = s.Int32
+ }
+ return nil
+ case *int64:
+ if s.Valid {
+ *d = int64(s.Int32)
+ }
+ return nil
+ }
+ case *sql.NullInt64:
+ switch d := dest.(type) {
+ case *int:
+ if s.Valid {
+ *d = int(s.Int64)
+ }
+ return nil
+ case *int8:
+ if s.Valid {
+ *d = int8(s.Int64)
+ }
+ return nil
+ case *int16:
+ if s.Valid {
+ *d = int16(s.Int64)
+ }
+ return nil
+ case *int32:
+ if s.Valid {
+ *d = int32(s.Int64)
+ }
+ return nil
+ case *int64:
+ if s.Valid {
+ *d = s.Int64
+ }
+ return nil
+ }
+ case *sql.NullFloat64:
+ switch d := dest.(type) {
+ case *int:
+ if s.Valid {
+ *d = int(s.Float64)
+ }
+ return nil
+ case *float64:
+ if s.Valid {
+ *d = s.Float64
+ }
+ return nil
+ }
+ case *sql.NullBool:
+ switch d := dest.(type) {
+ case *bool:
+ if s.Valid {
+ *d = s.Bool
+ }
+ return nil
+ }
+ case *sql.NullTime:
+ switch d := dest.(type) {
+ case *time.Time:
+ if s.Valid {
+ *d = s.Time
+ }
+ return nil
+ case *string:
+ if s.Valid {
+ *d = s.Time.In(convertedLocation).Format("2006-01-02 15:04:05")
+ }
+ return nil
+ }
+ case *NullUint32:
+ switch d := dest.(type) {
+ case *uint8:
+ if s.Valid {
+ *d = uint8(s.Uint32)
+ }
+ return nil
+ case *uint16:
+ if s.Valid {
+ *d = uint16(s.Uint32)
+ }
+ return nil
+ case *uint:
+ if s.Valid {
+ *d = uint(s.Uint32)
+ }
+ return nil
+ }
+ case *NullUint64:
+ switch d := dest.(type) {
+ case *uint64:
+ if s.Valid {
+ *d = s.Uint64
+ }
+ return nil
+ }
+ case *sql.RawBytes:
+ switch d := dest.(type) {
+ case Conversion:
+ return d.FromDB(*s)
+ }
+ }
+
+ var sv reflect.Value
+
+ switch d := dest.(type) {
+ case *string:
+ sv = reflect.ValueOf(src)
+ switch sv.Kind() {
+ case reflect.Bool,
+ reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
+ reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
+ reflect.Float32, reflect.Float64:
+ *d = AsString(src)
+ return nil
+ }
+ case *[]byte:
+ if b, ok := AsBytes(src); ok {
+ *d = b
+ return nil
+ }
+ case *bool:
+ bv, err := driver.Bool.ConvertValue(src)
+ if err == nil {
+ *d = bv.(bool)
+ }
+ return err
+ case *interface{}:
+ *d = src
+ return nil
+ }
+
+ return AssignValue(reflect.ValueOf(dest), src)
+}
+
+var (
+ scannerTypePlaceHolder sql.Scanner
+ scannerType = reflect.TypeOf(&scannerTypePlaceHolder).Elem()
+)
+
+// AssignValue assign src as dv
+func AssignValue(dv reflect.Value, src interface{}) error {
+ if src == nil {
+ return nil
+ }
+
+ if dv.Type().Implements(scannerType) {
+ return dv.Interface().(sql.Scanner).Scan(src)
+ }
+
+ switch dv.Kind() {
+ case reflect.Ptr:
+ if dv.IsNil() {
+ dv.Set(reflect.New(dv.Type().Elem()))
+ }
+ return AssignValue(dv.Elem(), src)
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ i64, err := AsInt64(src)
+ if err != nil {
+ err = strconvErr(err)
+ return fmt.Errorf("converting driver.Value type %T to a %s: %v", src, dv.Kind(), err)
+ }
+ dv.SetInt(i64)
+ return nil
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ u64, err := AsUint64(src)
+ if err != nil {
+ err = strconvErr(err)
+ return fmt.Errorf("converting driver.Value type %T to a %s: %v", src, dv.Kind(), err)
+ }
+ dv.SetUint(u64)
+ return nil
+ case reflect.Float32, reflect.Float64:
+ f64, err := AsFloat64(src)
+ if err != nil {
+ err = strconvErr(err)
+ return fmt.Errorf("converting driver.Value type %T to a %s: %v", src, dv.Kind(), err)
+ }
+ dv.SetFloat(f64)
+ return nil
+ case reflect.String:
+ dv.SetString(AsString(src))
+ return nil
+ case reflect.Bool:
+ b, err := AsBool(src)
+ if err != nil {
+ return err
+ }
+ dv.SetBool(b)
+ return nil
+ case reflect.Slice, reflect.Map, reflect.Struct, reflect.Array:
+ data, ok := AsBytes(src)
+ if !ok {
+ return fmt.Errorf("convert.AssignValue: src cannot be as bytes %#v", src)
+ }
+ if data == nil {
+ return nil
+ }
+ if dv.Kind() != reflect.Ptr {
+ dv = dv.Addr()
+ }
+ return json.Unmarshal(data, dv.Interface())
+ default:
+ return fmt.Errorf("convert.AssignValue: unsupported Scan, storing driver.Value type %T into type %T", src, dv.Interface())
+ }
+}
diff --git a/vendor/xorm.io/xorm/convert/float.go b/vendor/xorm.io/xorm/convert/float.go
new file mode 100644
index 0000000000..51b441cefe
--- /dev/null
+++ b/vendor/xorm.io/xorm/convert/float.go
@@ -0,0 +1,142 @@
+// Copyright 2021 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 convert
+
+import (
+ "database/sql"
+ "fmt"
+ "math/big"
+ "reflect"
+ "strconv"
+)
+
+// AsFloat64 convets interface as float64
+func AsFloat64(src interface{}) (float64, error) {
+ switch v := src.(type) {
+ case int:
+ return float64(v), nil
+ case int16:
+ return float64(v), nil
+ case int32:
+ return float64(v), nil
+ case int8:
+ return float64(v), nil
+ case int64:
+ return float64(v), nil
+ case uint:
+ return float64(v), nil
+ case uint8:
+ return float64(v), nil
+ case uint16:
+ return float64(v), nil
+ case uint32:
+ return float64(v), nil
+ case uint64:
+ return float64(v), nil
+ case []byte:
+ return strconv.ParseFloat(string(v), 64)
+ case string:
+ return strconv.ParseFloat(v, 64)
+ case *sql.NullString:
+ return strconv.ParseFloat(v.String, 64)
+ case *sql.NullInt32:
+ return float64(v.Int32), nil
+ case *sql.NullInt64:
+ return float64(v.Int64), nil
+ case *sql.NullFloat64:
+ return v.Float64, nil
+ }
+
+ rv := reflect.ValueOf(src)
+ switch rv.Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return float64(rv.Int()), nil
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ return float64(rv.Uint()), nil
+ case reflect.Float64, reflect.Float32:
+ return float64(rv.Float()), nil
+ case reflect.String:
+ return strconv.ParseFloat(rv.String(), 64)
+ }
+ return 0, fmt.Errorf("unsupported value %T as int64", src)
+}
+
+// AsBigFloat converts interface as big.Float
+func AsBigFloat(src interface{}) (*big.Float, error) {
+ res := big.NewFloat(0)
+ switch v := src.(type) {
+ case int:
+ res.SetInt64(int64(v))
+ return res, nil
+ case int16:
+ res.SetInt64(int64(v))
+ return res, nil
+ case int32:
+ res.SetInt64(int64(v))
+ return res, nil
+ case int8:
+ res.SetInt64(int64(v))
+ return res, nil
+ case int64:
+ res.SetInt64(int64(v))
+ return res, nil
+ case uint:
+ res.SetUint64(uint64(v))
+ return res, nil
+ case uint8:
+ res.SetUint64(uint64(v))
+ return res, nil
+ case uint16:
+ res.SetUint64(uint64(v))
+ return res, nil
+ case uint32:
+ res.SetUint64(uint64(v))
+ return res, nil
+ case uint64:
+ res.SetUint64(uint64(v))
+ return res, nil
+ case []byte:
+ res.SetString(string(v))
+ return res, nil
+ case string:
+ res.SetString(v)
+ return res, nil
+ case *sql.NullString:
+ if v.Valid {
+ res.SetString(v.String)
+ return res, nil
+ }
+ return nil, nil
+ case *sql.NullInt32:
+ if v.Valid {
+ res.SetInt64(int64(v.Int32))
+ return res, nil
+ }
+ return nil, nil
+ case *sql.NullInt64:
+ if v.Valid {
+ res.SetInt64(int64(v.Int64))
+ return res, nil
+ }
+ return nil, nil
+ }
+
+ rv := reflect.ValueOf(src)
+ switch rv.Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ res.SetInt64(rv.Int())
+ return res, nil
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ res.SetUint64(rv.Uint())
+ return res, nil
+ case reflect.Float64, reflect.Float32:
+ res.SetFloat64(rv.Float())
+ return res, nil
+ case reflect.String:
+ res.SetString(rv.String())
+ return res, nil
+ }
+ return nil, fmt.Errorf("unsupported value %T as big.Float", src)
+}
diff --git a/vendor/xorm.io/xorm/convert/int.go b/vendor/xorm.io/xorm/convert/int.go
new file mode 100644
index 0000000000..af8d4f7557
--- /dev/null
+++ b/vendor/xorm.io/xorm/convert/int.go
@@ -0,0 +1,178 @@
+// Copyright 2021 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 convert
+
+import (
+ "database/sql"
+ "database/sql/driver"
+ "fmt"
+ "reflect"
+ "strconv"
+)
+
+// AsInt64 converts interface as int64
+func AsInt64(src interface{}) (int64, error) {
+ switch v := src.(type) {
+ case int:
+ return int64(v), nil
+ case int16:
+ return int64(v), nil
+ case int32:
+ return int64(v), nil
+ case int8:
+ return int64(v), nil
+ case int64:
+ return v, nil
+ case uint:
+ return int64(v), nil
+ case uint8:
+ return int64(v), nil
+ case uint16:
+ return int64(v), nil
+ case uint32:
+ return int64(v), nil
+ case uint64:
+ return int64(v), nil
+ case []byte:
+ return strconv.ParseInt(string(v), 10, 64)
+ case string:
+ return strconv.ParseInt(v, 10, 64)
+ case *sql.NullString:
+ return strconv.ParseInt(v.String, 10, 64)
+ case *sql.NullInt32:
+ return int64(v.Int32), nil
+ case *sql.NullInt64:
+ return int64(v.Int64), nil
+ }
+
+ rv := reflect.ValueOf(src)
+ switch rv.Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return rv.Int(), nil
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ return int64(rv.Uint()), nil
+ case reflect.Float64, reflect.Float32:
+ return int64(rv.Float()), nil
+ case reflect.String:
+ return strconv.ParseInt(rv.String(), 10, 64)
+ }
+ return 0, fmt.Errorf("unsupported value %T as int64", src)
+}
+
+// AsUint64 converts interface as uint64
+func AsUint64(src interface{}) (uint64, error) {
+ switch v := src.(type) {
+ case int:
+ return uint64(v), nil
+ case int16:
+ return uint64(v), nil
+ case int32:
+ return uint64(v), nil
+ case int8:
+ return uint64(v), nil
+ case int64:
+ return uint64(v), nil
+ case uint:
+ return uint64(v), nil
+ case uint8:
+ return uint64(v), nil
+ case uint16:
+ return uint64(v), nil
+ case uint32:
+ return uint64(v), nil
+ case uint64:
+ return v, nil
+ case []byte:
+ return strconv.ParseUint(string(v), 10, 64)
+ case string:
+ return strconv.ParseUint(v, 10, 64)
+ case *sql.NullString:
+ return strconv.ParseUint(v.String, 10, 64)
+ case *sql.NullInt32:
+ return uint64(v.Int32), nil
+ case *sql.NullInt64:
+ return uint64(v.Int64), nil
+ }
+
+ rv := reflect.ValueOf(src)
+ switch rv.Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return uint64(rv.Int()), nil
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ return uint64(rv.Uint()), nil
+ case reflect.Float64, reflect.Float32:
+ return uint64(rv.Float()), nil
+ case reflect.String:
+ return strconv.ParseUint(rv.String(), 10, 64)
+ }
+ return 0, fmt.Errorf("unsupported value %T as uint64", src)
+}
+
+var (
+ _ sql.Scanner = &NullUint64{}
+)
+
+// NullUint64 represents an uint64 that may be null.
+// NullUint64 implements the Scanner interface so
+// it can be used as a scan destination, similar to NullString.
+type NullUint64 struct {
+ Uint64 uint64
+ Valid bool
+}
+
+// Scan implements the Scanner interface.
+func (n *NullUint64) Scan(value interface{}) error {
+ if value == nil {
+ n.Uint64, n.Valid = 0, false
+ return nil
+ }
+ n.Valid = true
+ var err error
+ n.Uint64, err = AsUint64(value)
+ return err
+}
+
+// Value implements the driver Valuer interface.
+func (n NullUint64) Value() (driver.Value, error) {
+ if !n.Valid {
+ return nil, nil
+ }
+ return n.Uint64, nil
+}
+
+var (
+ _ sql.Scanner = &NullUint32{}
+)
+
+// NullUint32 represents an uint32 that may be null.
+// NullUint32 implements the Scanner interface so
+// it can be used as a scan destination, similar to NullString.
+type NullUint32 struct {
+ Uint32 uint32
+ Valid bool // Valid is true if Uint32 is not NULL
+}
+
+// Scan implements the Scanner interface.
+func (n *NullUint32) Scan(value interface{}) error {
+ if value == nil {
+ n.Uint32, n.Valid = 0, false
+ return nil
+ }
+ n.Valid = true
+ i64, err := AsUint64(value)
+ if err != nil {
+ return err
+ }
+ n.Uint32 = uint32(i64)
+ return nil
+}
+
+// Value implements the driver Valuer interface.
+func (n NullUint32) Value() (driver.Value, error) {
+ if !n.Valid {
+ return nil, nil
+ }
+ return int64(n.Uint32), nil
+}
diff --git a/vendor/xorm.io/xorm/convert/interface.go b/vendor/xorm.io/xorm/convert/interface.go
new file mode 100644
index 0000000000..b0f28c81f0
--- /dev/null
+++ b/vendor/xorm.io/xorm/convert/interface.go
@@ -0,0 +1,49 @@
+// Copyright 2021 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 convert
+
+import (
+ "database/sql"
+ "fmt"
+ "time"
+)
+
+// Interface2Interface converts interface of pointer as interface of value
+func Interface2Interface(userLocation *time.Location, v interface{}) (interface{}, error) {
+ if v == nil {
+ return nil, nil
+ }
+ switch vv := v.(type) {
+ case *int64:
+ return *vv, nil
+ case *int8:
+ return *vv, nil
+ case *sql.NullString:
+ return vv.String, nil
+ case *sql.RawBytes:
+ if len([]byte(*vv)) > 0 {
+ return []byte(*vv), nil
+ }
+ return nil, nil
+ case *sql.NullInt32:
+ return vv.Int32, nil
+ case *sql.NullInt64:
+ return vv.Int64, nil
+ case *sql.NullFloat64:
+ return vv.Float64, nil
+ case *sql.NullBool:
+ if vv.Valid {
+ return vv.Bool, nil
+ }
+ return nil, nil
+ case *sql.NullTime:
+ if vv.Valid {
+ return vv.Time.In(userLocation).Format("2006-01-02 15:04:05"), nil
+ }
+ return "", nil
+ default:
+ return "", fmt.Errorf("convert assign string unsupported type: %#v", vv)
+ }
+}
diff --git a/vendor/xorm.io/xorm/convert/scanner.go b/vendor/xorm.io/xorm/convert/scanner.go
new file mode 100644
index 0000000000..505d3be063
--- /dev/null
+++ b/vendor/xorm.io/xorm/convert/scanner.go
@@ -0,0 +1,19 @@
+// Copyright 2021 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 convert
+
+import "database/sql"
+
+var (
+ _ sql.Scanner = &EmptyScanner{}
+)
+
+// EmptyScanner represents an empty scanner which will ignore the scan
+type EmptyScanner struct{}
+
+// Scan implements sql.Scanner
+func (EmptyScanner) Scan(value interface{}) error {
+ return nil
+}
diff --git a/vendor/xorm.io/xorm/convert/string.go b/vendor/xorm.io/xorm/convert/string.go
new file mode 100644
index 0000000000..de11fa01a3
--- /dev/null
+++ b/vendor/xorm.io/xorm/convert/string.go
@@ -0,0 +1,75 @@
+// Copyright 2021 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 convert
+
+import (
+ "database/sql"
+ "fmt"
+ "reflect"
+ "strconv"
+)
+
+// AsString converts interface as string
+func AsString(src interface{}) string {
+ switch v := src.(type) {
+ case string:
+ return v
+ case []byte:
+ return string(v)
+ case *sql.NullString:
+ return v.String
+ case *sql.NullInt32:
+ return fmt.Sprintf("%d", v.Int32)
+ case *sql.NullInt64:
+ return fmt.Sprintf("%d", v.Int64)
+ }
+ rv := reflect.ValueOf(src)
+ switch rv.Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return strconv.FormatInt(rv.Int(), 10)
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ return strconv.FormatUint(rv.Uint(), 10)
+ case reflect.Float64:
+ return strconv.FormatFloat(rv.Float(), 'g', -1, 64)
+ case reflect.Float32:
+ return strconv.FormatFloat(rv.Float(), 'g', -1, 32)
+ case reflect.Bool:
+ return strconv.FormatBool(rv.Bool())
+ }
+ return fmt.Sprintf("%v", src)
+}
+
+// AsBytes converts interface as bytes
+func AsBytes(src interface{}) ([]byte, bool) {
+ switch t := src.(type) {
+ case []byte:
+ return t, true
+ case *sql.NullString:
+ if !t.Valid {
+ return nil, true
+ }
+ return []byte(t.String), true
+ case *sql.RawBytes:
+ return *t, true
+ }
+
+ rv := reflect.ValueOf(src)
+
+ switch rv.Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return strconv.AppendInt(nil, rv.Int(), 10), true
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ return strconv.AppendUint(nil, rv.Uint(), 10), true
+ case reflect.Float32:
+ return strconv.AppendFloat(nil, rv.Float(), 'g', -1, 32), true
+ case reflect.Float64:
+ return strconv.AppendFloat(nil, rv.Float(), 'g', -1, 64), true
+ case reflect.Bool:
+ return strconv.AppendBool(nil, rv.Bool()), true
+ case reflect.String:
+ return []byte(rv.String()), true
+ }
+ return nil, false
+}
diff --git a/vendor/xorm.io/xorm/convert/time.go b/vendor/xorm.io/xorm/convert/time.go
new file mode 100644
index 0000000000..e53a19cd76
--- /dev/null
+++ b/vendor/xorm.io/xorm/convert/time.go
@@ -0,0 +1,117 @@
+// Copyright 2021 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 convert
+
+import (
+ "database/sql"
+ "fmt"
+ "strconv"
+ "strings"
+ "time"
+
+ "xorm.io/xorm/internal/utils"
+)
+
+// String2Time converts a string to time with original location
+func String2Time(s string, originalLocation *time.Location, convertedLocation *time.Location) (*time.Time, error) {
+ if len(s) == 19 {
+ if s == utils.ZeroTime0 || s == utils.ZeroTime1 {
+ return &time.Time{}, nil
+ }
+ dt, err := time.ParseInLocation("2006-01-02 15:04:05", s, originalLocation)
+ if err != nil {
+ return nil, err
+ }
+ dt = dt.In(convertedLocation)
+ return &dt, nil
+ } else if len(s) == 20 && s[10] == 'T' && s[19] == 'Z' {
+ dt, err := time.ParseInLocation("2006-01-02T15:04:05", s[:19], originalLocation)
+ if err != nil {
+ return nil, err
+ }
+ dt = dt.In(convertedLocation)
+ return &dt, nil
+ } else if len(s) == 25 && s[10] == 'T' && s[19] == '+' && s[22] == ':' {
+ dt, err := time.Parse(time.RFC3339, s)
+ if err != nil {
+ return nil, err
+ }
+ dt = dt.In(convertedLocation)
+ return &dt, nil
+ } else if len(s) >= 21 && s[19] == '.' {
+ var layout = "2006-01-02 15:04:05." + strings.Repeat("0", len(s)-20)
+ dt, err := time.ParseInLocation(layout, s, originalLocation)
+ if err != nil {
+ return nil, err
+ }
+ dt = dt.In(convertedLocation)
+ return &dt, nil
+ } else {
+ i, err := strconv.ParseInt(s, 10, 64)
+ if err == nil {
+ tm := time.Unix(i, 0).In(convertedLocation)
+ return &tm, nil
+ }
+ }
+ return nil, fmt.Errorf("unsupported conversion from %s to time", s)
+}
+
+// AsTime converts interface as time
+func AsTime(src interface{}, dbLoc *time.Location, uiLoc *time.Location) (*time.Time, error) {
+ switch t := src.(type) {
+ case string:
+ return String2Time(t, dbLoc, uiLoc)
+ case *sql.NullString:
+ if !t.Valid {
+ return nil, nil
+ }
+ return String2Time(t.String, dbLoc, uiLoc)
+ case []uint8:
+ if t == nil {
+ return nil, nil
+ }
+ return String2Time(string(t), dbLoc, uiLoc)
+ case *sql.NullTime:
+ if !t.Valid {
+ return nil, nil
+ }
+ z, _ := t.Time.Zone()
+ if len(z) == 0 || t.Time.Year() == 0 || t.Time.Location().String() != dbLoc.String() {
+ tm := time.Date(t.Time.Year(), t.Time.Month(), t.Time.Day(), t.Time.Hour(),
+ t.Time.Minute(), t.Time.Second(), t.Time.Nanosecond(), dbLoc).In(uiLoc)
+ return &tm, nil
+ }
+ tm := t.Time.In(uiLoc)
+ return &tm, nil
+ case *time.Time:
+ z, _ := t.Zone()
+ if len(z) == 0 || t.Year() == 0 || t.Location().String() != dbLoc.String() {
+ tm := time.Date(t.Year(), t.Month(), t.Day(), t.Hour(),
+ t.Minute(), t.Second(), t.Nanosecond(), dbLoc).In(uiLoc)
+ return &tm, nil
+ }
+ tm := t.In(uiLoc)
+ return &tm, nil
+ case time.Time:
+ z, _ := t.Zone()
+ if len(z) == 0 || t.Year() == 0 || t.Location().String() != dbLoc.String() {
+ tm := time.Date(t.Year(), t.Month(), t.Day(), t.Hour(),
+ t.Minute(), t.Second(), t.Nanosecond(), dbLoc).In(uiLoc)
+ return &tm, nil
+ }
+ tm := t.In(uiLoc)
+ return &tm, nil
+ case int:
+ tm := time.Unix(int64(t), 0).In(uiLoc)
+ return &tm, nil
+ case int64:
+ tm := time.Unix(t, 0).In(uiLoc)
+ return &tm, nil
+ case *sql.NullInt64:
+ tm := time.Unix(t.Int64, 0).In(uiLoc)
+ return &tm, nil
+ }
+ return nil, fmt.Errorf("unsupported value %#v as time", src)
+}
diff --git a/vendor/xorm.io/xorm/dialects/dialect.go b/vendor/xorm.io/xorm/dialects/dialect.go
index 325836b484..fc11eac15c 100644
--- a/vendor/xorm.io/xorm/dialects/dialect.go
+++ b/vendor/xorm.io/xorm/dialects/dialect.go
@@ -42,10 +42,12 @@ func (uri *URI) SetSchema(schema string) {
type Dialect interface {
Init(*URI) error
URI() *URI
- SQLType(*schemas.Column) string
- FormatBytes(b []byte) string
Version(ctx context.Context, queryer core.Queryer) (*schemas.Version, error)
+ SQLType(*schemas.Column) string
+ Alias(string) string // return what a sql type's alias of
+ ColumnTypeKind(string) int // database column type kind
+
IsReserved(string) bool
Quoter() schemas.Quoter
SetQuotePolicy(quotePolicy QuotePolicy)
@@ -80,6 +82,11 @@ type Base struct {
quoter schemas.Quoter
}
+// Alias returned col itself
+func (db *Base) Alias(col string) string {
+ return col
+}
+
// Quoter returns the current database Quoter
func (db *Base) Quoter() schemas.Quoter {
return db.quoter
@@ -96,11 +103,6 @@ func (db *Base) URI() *URI {
return db.uri
}
-// 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
@@ -118,7 +120,7 @@ func (db *Base) HasRecords(queryer core.Queryer, ctx context.Context, query stri
if rows.Next() {
return true, nil
}
- return false, nil
+ return false, rows.Err()
}
// IsColumnExist returns true if the column of the table exist
diff --git a/vendor/xorm.io/xorm/dialects/driver.go b/vendor/xorm.io/xorm/dialects/driver.go
index bb46a9368e..c63dbfa3f9 100644
--- a/vendor/xorm.io/xorm/dialects/driver.go
+++ b/vendor/xorm.io/xorm/dialects/driver.go
@@ -5,12 +5,30 @@
package dialects
import (
+ "database/sql"
"fmt"
+ "time"
+
+ "xorm.io/xorm/core"
)
+// ScanContext represents a context when Scan
+type ScanContext struct {
+ DBLocation *time.Location
+ UserLocation *time.Location
+}
+
+// DriverFeatures represents driver feature
+type DriverFeatures struct {
+ SupportReturnInsertedID bool
+}
+
// Driver represents a database driver
type Driver interface {
Parse(string, string) (*URI, error)
+ Features() *DriverFeatures
+ GenScanResult(string) (interface{}, error) // according given column type generating a suitable scan interface
+ Scan(*ScanContext, *core.Rows, []*sql.ColumnType, ...interface{}) error
}
var (
@@ -59,3 +77,9 @@ func OpenDialect(driverName, connstr string) (Dialect, error) {
return dialect, nil
}
+
+type baseDriver struct{}
+
+func (b *baseDriver) Scan(ctx *ScanContext, rows *core.Rows, types []*sql.ColumnType, v ...interface{}) error {
+ return rows.Scan(v...)
+}
diff --git a/vendor/xorm.io/xorm/dialects/mssql.go b/vendor/xorm.io/xorm/dialects/mssql.go
index 7e922e621e..2121e71dd3 100644
--- a/vendor/xorm.io/xorm/dialects/mssql.go
+++ b/vendor/xorm.io/xorm/dialects/mssql.go
@@ -6,6 +6,7 @@ package dialects
import (
"context"
+ "database/sql"
"errors"
"fmt"
"net/url"
@@ -263,6 +264,9 @@ func (db *mssql) Version(ctx context.Context, queryer core.Queryer) (*schemas.Ve
var version, level, edition string
if !rows.Next() {
+ if rows.Err() != nil {
+ return nil, rows.Err()
+ }
return nil, errors.New("unknow version")
}
@@ -281,7 +285,7 @@ func (db *mssql) Version(ctx context.Context, queryer core.Queryer) (*schemas.Ve
func (db *mssql) SQLType(c *schemas.Column) string {
var res string
switch t := c.SQLType.Name; t {
- case schemas.Bool:
+ case schemas.Bool, schemas.Boolean:
res = schemas.Bit
if strings.EqualFold(c.Default, "true") {
c.Default = "1"
@@ -299,17 +303,26 @@ func (db *mssql) SQLType(c *schemas.Column) string {
c.IsPrimaryKey = true
c.Nullable = false
res = schemas.BigInt
- case schemas.Bytea, schemas.Blob, schemas.Binary, schemas.TinyBlob, schemas.MediumBlob, schemas.LongBlob:
+ case schemas.Bytea, schemas.Binary:
res = schemas.VarBinary
if c.Length == 0 {
c.Length = 50
}
- case schemas.TimeStamp:
- res = schemas.DateTime
+ case schemas.Blob, schemas.TinyBlob, schemas.MediumBlob, schemas.LongBlob:
+ res = schemas.VarBinary
+ if c.Length == 0 {
+ res += "(MAX)"
+ }
+ case schemas.TimeStamp, schemas.DateTime:
+ if c.Length > 3 {
+ res = "DATETIME2"
+ } else {
+ return schemas.DateTime
+ }
case schemas.TimeStampz:
res = "DATETIMEOFFSET"
c.Length = 7
- case schemas.MediumInt:
+ case schemas.MediumInt, schemas.TinyInt, schemas.SmallInt, schemas.UnsignedMediumInt, schemas.UnsignedTinyInt, schemas.UnsignedSmallInt:
res = schemas.Int
case schemas.Text, schemas.MediumText, schemas.TinyText, schemas.LongText, schemas.Json:
res = db.defaultVarchar + "(MAX)"
@@ -348,7 +361,7 @@ func (db *mssql) SQLType(c *schemas.Column) string {
res = t
}
- if res == schemas.Int || res == schemas.Bit || res == schemas.DateTime {
+ if res == schemas.Int || res == schemas.Bit {
return res
}
@@ -363,6 +376,19 @@ func (db *mssql) SQLType(c *schemas.Column) string {
return res
}
+func (db *mssql) ColumnTypeKind(t string) int {
+ switch strings.ToUpper(t) {
+ case "DATE", "DATETIME", "DATETIME2", "TIME":
+ return schemas.TIME_TYPE
+ case "VARCHAR", "TEXT", "CHAR", "NVARCHAR", "NCHAR", "NTEXT":
+ return schemas.TEXT_TYPE
+ case "FLOAT", "REAL", "BIGINT", "DATETIMEOFFSET", "TINYINT", "SMALLINT", "INT":
+ return schemas.NUMERIC_TYPE
+ default:
+ return schemas.UNKNOW_TYPE
+ }
+}
+
func (db *mssql) IsReserved(name string) bool {
_, ok := mssqlReservedWords[strings.ToUpper(name)]
return ok
@@ -476,6 +502,12 @@ func (db *mssql) GetColumns(queryer core.Queryer, ctx context.Context, tableName
col.Length /= 2
col.Length2 /= 2
}
+ case "DATETIME2":
+ col.SQLType = schemas.SQLType{Name: schemas.DateTime, DefaultLength: 7, DefaultLength2: 0}
+ col.Length = scale
+ case "DATETIME":
+ col.SQLType = schemas.SQLType{Name: schemas.DateTime, DefaultLength: 3, DefaultLength2: 0}
+ col.Length = scale
case "IMAGE":
col.SQLType = schemas.SQLType{Name: schemas.VarBinary, DefaultLength: 0, DefaultLength2: 0}
case "NCHAR":
@@ -495,6 +527,9 @@ func (db *mssql) GetColumns(queryer core.Queryer, ctx context.Context, tableName
cols[col.Name] = col
colSeq = append(colSeq, col.Name)
}
+ if rows.Err() != nil {
+ return nil, nil, rows.Err()
+ }
return colSeq, cols, nil
}
@@ -519,6 +554,9 @@ func (db *mssql) GetTables(queryer core.Queryer, ctx context.Context) ([]*schema
table.Name = strings.Trim(name, "` ")
tables = append(tables, table)
}
+ if rows.Err() != nil {
+ return nil, rows.Err()
+ }
return tables, nil
}
@@ -542,7 +580,7 @@ WHERE IXS.TYPE_DESC='NONCLUSTERED' and OBJECT_NAME(IXS.OBJECT_ID) =?
}
defer rows.Close()
- indexes := make(map[string]*schemas.Index, 0)
+ indexes := make(map[string]*schemas.Index)
for rows.Next() {
var indexType int
var indexName, colName, isUnique string
@@ -581,6 +619,9 @@ WHERE IXS.TYPE_DESC='NONCLUSTERED' and OBJECT_NAME(IXS.OBJECT_ID) =?
}
index.AddColumn(colName)
}
+ if rows.Err() != nil {
+ return nil, rows.Err()
+ }
return indexes, nil
}
@@ -624,6 +665,13 @@ func (db *mssql) Filters() []Filter {
}
type odbcDriver struct {
+ baseDriver
+}
+
+func (p *odbcDriver) Features() *DriverFeatures {
+ return &DriverFeatures{
+ SupportReturnInsertedID: false,
+ }
}
func (p *odbcDriver) Parse(driverName, dataSourceName string) (*URI, error) {
@@ -640,8 +688,7 @@ func (p *odbcDriver) Parse(driverName, dataSourceName string) (*URI, error) {
for _, c := range kv {
vv := strings.Split(strings.TrimSpace(c), "=")
if len(vv) == 2 {
- switch strings.ToLower(vv[0]) {
- case "database":
+ if strings.ToLower(vv[0]) == "database" {
dbName = vv[1]
}
}
@@ -652,3 +699,26 @@ func (p *odbcDriver) Parse(driverName, dataSourceName string) (*URI, error) {
}
return &URI{DBName: dbName, DBType: schemas.MSSQL}, nil
}
+
+func (p *odbcDriver) GenScanResult(colType string) (interface{}, error) {
+ switch colType {
+ case "VARCHAR", "TEXT", "CHAR", "NVARCHAR", "NCHAR", "NTEXT":
+ fallthrough
+ case "DATE", "DATETIME", "DATETIME2", "TIME":
+ var s sql.NullString
+ return &s, nil
+ case "FLOAT", "REAL":
+ var s sql.NullFloat64
+ return &s, nil
+ case "BIGINT", "DATETIMEOFFSET":
+ var s sql.NullInt64
+ return &s, nil
+ case "TINYINT", "SMALLINT", "INT":
+ var s sql.NullInt32
+ return &s, nil
+
+ default:
+ var r sql.RawBytes
+ return &r, nil
+ }
+}
diff --git a/vendor/xorm.io/xorm/dialects/mysql.go b/vendor/xorm.io/xorm/dialects/mysql.go
index a169b9010e..2112852751 100644
--- a/vendor/xorm.io/xorm/dialects/mysql.go
+++ b/vendor/xorm.io/xorm/dialects/mysql.go
@@ -7,6 +7,7 @@ package dialects
import (
"context"
"crypto/tls"
+ "database/sql"
"errors"
"fmt"
"regexp"
@@ -188,6 +189,21 @@ func (db *mysql) Init(uri *URI) error {
return db.Base.Init(db, uri)
}
+var (
+ mysqlColAliases = map[string]string{
+ "numeric": "decimal",
+ }
+)
+
+// Alias returns a alias of column
+func (db *mysql) Alias(col string) string {
+ v, ok := mysqlColAliases[strings.ToLower(col)]
+ if ok {
+ return v
+ }
+ return col
+}
+
func (db *mysql) Version(ctx context.Context, queryer core.Queryer) (*schemas.Version, error) {
rows, err := queryer.QueryContext(ctx, "SELECT @@VERSION")
if err != nil {
@@ -197,7 +213,10 @@ func (db *mysql) Version(ctx context.Context, queryer core.Queryer) (*schemas.Ve
var version string
if !rows.Next() {
- return nil, errors.New("Unknow version")
+ if rows.Err() != nil {
+ return nil, rows.Err()
+ }
+ return nil, errors.New("unknow version")
}
if err := rows.Scan(&version); err != nil {
@@ -238,15 +257,13 @@ func (db *mysql) SetParams(params map[string]string) {
fallthrough
case "COMPRESSED":
db.rowFormat = t
- break
- default:
- break
}
}
}
func (db *mysql) SQLType(c *schemas.Column) string {
var res string
+ var isUnsigned bool
switch t := c.SQLType.Name; t {
case schemas.Bool:
res = schemas.TinyInt
@@ -293,8 +310,19 @@ func (db *mysql) SQLType(c *schemas.Column) string {
res = schemas.Text
case schemas.UnsignedInt:
res = schemas.Int
+ isUnsigned = true
case schemas.UnsignedBigInt:
res = schemas.BigInt
+ isUnsigned = true
+ case schemas.UnsignedMediumInt:
+ res = schemas.MediumInt
+ isUnsigned = true
+ case schemas.UnsignedSmallInt:
+ res = schemas.SmallInt
+ isUnsigned = true
+ case schemas.UnsignedTinyInt:
+ res = schemas.TinyInt
+ isUnsigned = true
default:
res = t
}
@@ -313,13 +341,28 @@ func (db *mysql) SQLType(c *schemas.Column) string {
res += "(" + strconv.Itoa(c.Length) + ")"
}
- if c.SQLType.Name == schemas.UnsignedBigInt || c.SQLType.Name == schemas.UnsignedInt {
+ if isUnsigned {
res += " UNSIGNED"
}
return res
}
+func (db *mysql) ColumnTypeKind(t string) int {
+ switch strings.ToUpper(t) {
+ case "DATETIME":
+ return schemas.TIME_TYPE
+ case "CHAR", "VARCHAR", "TINYTEXT", "TEXT", "MEDIUMTEXT", "LONGTEXT", "ENUM", "SET":
+ return schemas.TEXT_TYPE
+ case "BIGINT", "TINYINT", "SMALLINT", "MEDIUMINT", "INT", "FLOAT", "REAL", "DOUBLE PRECISION", "DECIMAL", "NUMERIC", "BIT":
+ return schemas.NUMERIC_TYPE
+ case "BINARY", "VARBINARY", "TINYBLOB", "BLOB", "MEDIUMBLOB", "LONGBLOB":
+ return schemas.BLOB_TYPE
+ default:
+ return schemas.UNKNOW_TYPE
+ }
+}
+
func (db *mysql) IsReserved(name string) bool {
_, ok := mysqlReservedWords[strings.ToUpper(name)]
return ok
@@ -472,6 +515,9 @@ func (db *mysql) GetColumns(queryer core.Queryer, ctx context.Context, tableName
cols[col.Name] = col
colSeq = append(colSeq, col.Name)
}
+ if rows.Err() != nil {
+ return nil, nil, rows.Err()
+ }
return colSeq, cols, nil
}
@@ -503,6 +549,9 @@ func (db *mysql) GetTables(queryer core.Queryer, ctx context.Context) ([]*schema
table.StoreEngine = engine
tables = append(tables, table)
}
+ if rows.Err() != nil {
+ return nil, rows.Err()
+ }
return tables, nil
}
@@ -533,7 +582,7 @@ func (db *mysql) GetIndexes(queryer core.Queryer, ctx context.Context, tableName
}
defer rows.Close()
- indexes := make(map[string]*schemas.Index, 0)
+ indexes := make(map[string]*schemas.Index)
for rows.Next() {
var indexType int
var indexName, colName, nonUnique string
@@ -546,7 +595,7 @@ func (db *mysql) GetIndexes(queryer core.Queryer, ctx context.Context, tableName
continue
}
- if "YES" == nonUnique || nonUnique == "1" {
+ if nonUnique == "YES" || nonUnique == "1" {
indexType = schemas.IndexType
} else {
indexType = schemas.UniqueType
@@ -570,6 +619,9 @@ func (db *mysql) GetIndexes(queryer core.Queryer, ctx context.Context, tableName
}
index.AddColumn(colName)
}
+ if rows.Err() != nil {
+ return nil, rows.Err()
+ }
return indexes, nil
}
@@ -630,7 +682,83 @@ func (db *mysql) Filters() []Filter {
return []Filter{}
}
+type mysqlDriver struct {
+ baseDriver
+}
+
+func (p *mysqlDriver) Features() *DriverFeatures {
+ return &DriverFeatures{
+ SupportReturnInsertedID: true,
+ }
+}
+
+func (p *mysqlDriver) Parse(driverName, dataSourceName string) (*URI, error) {
+ dsnPattern := regexp.MustCompile(
+ `^(?:(?P<user>.*?)(?::(?P<passwd>.*))?@)?` + // [user[:password]@]
+ `(?:(?P<net>[^\(]*)(?:\((?P<addr>[^\)]*)\))?)?` + // [net[(addr)]]
+ `\/(?P<dbname>.*?)` + // /dbname
+ `(?:\?(?P<params>[^\?]*))?$`) // [?param1=value1&paramN=valueN]
+ matches := dsnPattern.FindStringSubmatch(dataSourceName)
+ // tlsConfigRegister := make(map[string]*tls.Config)
+ names := dsnPattern.SubexpNames()
+
+ uri := &URI{DBType: schemas.MYSQL}
+
+ for i, match := range matches {
+ switch names[i] {
+ case "dbname":
+ uri.DBName = match
+ case "params":
+ if len(match) > 0 {
+ kvs := strings.Split(match, "&")
+ for _, kv := range kvs {
+ splits := strings.Split(kv, "=")
+ if len(splits) == 2 {
+ if splits[0] == "charset" {
+ uri.Charset = splits[1]
+ }
+ }
+ }
+ }
+ }
+ }
+ return uri, nil
+}
+
+func (p *mysqlDriver) GenScanResult(colType string) (interface{}, error) {
+ switch colType {
+ case "CHAR", "VARCHAR", "TINYTEXT", "TEXT", "MEDIUMTEXT", "LONGTEXT", "ENUM", "SET":
+ var s sql.NullString
+ return &s, nil
+ case "BIGINT":
+ var s sql.NullInt64
+ return &s, nil
+ case "TINYINT", "SMALLINT", "MEDIUMINT", "INT":
+ var s sql.NullInt32
+ return &s, nil
+ case "FLOAT", "REAL", "DOUBLE PRECISION", "DOUBLE":
+ var s sql.NullFloat64
+ return &s, nil
+ case "DECIMAL", "NUMERIC":
+ var s sql.NullString
+ return &s, nil
+ case "DATETIME", "TIMESTAMP":
+ var s sql.NullTime
+ return &s, nil
+ case "BIT":
+ var s sql.RawBytes
+ return &s, nil
+ case "BINARY", "VARBINARY", "TINYBLOB", "BLOB", "MEDIUMBLOB", "LONGBLOB":
+ var r sql.RawBytes
+ return &r, nil
+ default:
+ var r sql.RawBytes
+ return &r, nil
+ }
+}
+
type mymysqlDriver struct {
+ mysqlDriver
}
func (p *mymysqlDriver) Parse(driverName, dataSourceName string) (*URI, error) {
@@ -681,41 +809,3 @@ func (p *mymysqlDriver) Parse(driverName, dataSourceName string) (*URI, error) {
return uri, nil
}
-
-type mysqlDriver struct {
-}
-
-func (p *mysqlDriver) Parse(driverName, dataSourceName string) (*URI, error) {
- dsnPattern := regexp.MustCompile(
- `^(?:(?P<user>.*?)(?::(?P<passwd>.*))?@)?` + // [user[:password]@]
- `(?:(?P<net>[^\(]*)(?:\((?P<addr>[^\)]*)\))?)?` + // [net[(addr)]]
- `\/(?P<dbname>.*?)` + // /dbname
- `(?:\?(?P<params>[^\?]*))?$`) // [?param1=value1&paramN=valueN]
- matches := dsnPattern.FindStringSubmatch(dataSourceName)
- // tlsConfigRegister := make(map[string]*tls.Config)
- names := dsnPattern.SubexpNames()
-
- uri := &URI{DBType: schemas.MYSQL}
-
- for i, match := range matches {
- switch names[i] {
- case "dbname":
- uri.DBName = match
- case "params":
- if len(match) > 0 {
- kvs := strings.Split(match, "&")
- for _, kv := range kvs {
- splits := strings.Split(kv, "=")
- if len(splits) == 2 {
- switch splits[0] {
- case "charset":
- uri.Charset = splits[1]
- }
- }
- }
- }
-
- }
- }
- return uri, nil
-}
diff --git a/vendor/xorm.io/xorm/dialects/oracle.go b/vendor/xorm.io/xorm/dialects/oracle.go
index 0b06c4c63c..11a6653b1b 100644
--- a/vendor/xorm.io/xorm/dialects/oracle.go
+++ b/vendor/xorm.io/xorm/dialects/oracle.go
@@ -6,6 +6,7 @@ package dialects
import (
"context"
+ "database/sql"
"errors"
"fmt"
"regexp"
@@ -524,6 +525,9 @@ func (db *oracle) Version(ctx context.Context, queryer core.Queryer) (*schemas.V
var version string
if !rows.Next() {
+ if rows.Err() != nil {
+ return nil, rows.Err()
+ }
return nil, errors.New("unknow version")
}
@@ -567,6 +571,21 @@ func (db *oracle) SQLType(c *schemas.Column) string {
return res
}
+func (db *oracle) ColumnTypeKind(t string) int {
+ switch strings.ToUpper(t) {
+ case "DATE":
+ return schemas.TIME_TYPE
+ case "CHAR", "NCHAR", "VARCHAR", "VARCHAR2", "NVARCHAR2", "LONG", "CLOB", "NCLOB":
+ return schemas.TEXT_TYPE
+ case "NUMBER":
+ return schemas.NUMERIC_TYPE
+ case "BLOB":
+ return schemas.BLOB_TYPE
+ default:
+ return schemas.UNKNOW_TYPE
+ }
+}
+
func (db *oracle) AutoIncrStr() string {
return "AUTO_INCREMENT"
}
@@ -740,6 +759,9 @@ func (db *oracle) GetColumns(queryer core.Queryer, ctx context.Context, tableNam
cols[col.Name] = col
colSeq = append(colSeq, col.Name)
}
+ if rows.Err() != nil {
+ return nil, nil, rows.Err()
+ }
return colSeq, cols, nil
}
@@ -764,6 +786,9 @@ func (db *oracle) GetTables(queryer core.Queryer, ctx context.Context) ([]*schem
tables = append(tables, table)
}
+ if rows.Err() != nil {
+ return nil, rows.Err()
+ }
return tables, nil
}
@@ -778,7 +803,7 @@ func (db *oracle) GetIndexes(queryer core.Queryer, ctx context.Context, tableNam
}
defer rows.Close()
- indexes := make(map[string]*schemas.Index, 0)
+ indexes := make(map[string]*schemas.Index)
for rows.Next() {
var indexType int
var indexName, colName, uniqueness string
@@ -813,6 +838,9 @@ func (db *oracle) GetIndexes(queryer core.Queryer, ctx context.Context, tableNam
}
index.AddColumn(colName)
}
+ if rows.Err() != nil {
+ return nil, rows.Err()
+ }
return indexes, nil
}
@@ -823,9 +851,16 @@ func (db *oracle) Filters() []Filter {
}
type godrorDriver struct {
+ baseDriver
}
-func (cfg *godrorDriver) Parse(driverName, dataSourceName string) (*URI, error) {
+func (g *godrorDriver) Features() *DriverFeatures {
+ return &DriverFeatures{
+ SupportReturnInsertedID: false,
+ }
+}
+
+func (g *godrorDriver) Parse(driverName, dataSourceName string) (*URI, error) {
db := &URI{DBType: schemas.ORACLE}
dsnPattern := regexp.MustCompile(
`^(?:(?P<user>.*?)(?::(?P<passwd>.*))?@)?` + // [user[:password]@]
@@ -837,8 +872,7 @@ func (cfg *godrorDriver) Parse(driverName, dataSourceName string) (*URI, error)
names := dsnPattern.SubexpNames()
for i, match := range matches {
- switch names[i] {
- case "dbname":
+ if names[i] == "dbname" {
db.DBName = match
}
}
@@ -848,12 +882,33 @@ func (cfg *godrorDriver) Parse(driverName, dataSourceName string) (*URI, error)
return db, nil
}
+func (g *godrorDriver) GenScanResult(colType string) (interface{}, error) {
+ switch colType {
+ case "CHAR", "NCHAR", "VARCHAR", "VARCHAR2", "NVARCHAR2", "LONG", "CLOB", "NCLOB":
+ var s sql.NullString
+ return &s, nil
+ case "NUMBER":
+ var s sql.NullString
+ return &s, nil
+ case "DATE":
+ var s sql.NullTime
+ return &s, nil
+ case "BLOB":
+ var r sql.RawBytes
+ return &r, nil
+ default:
+ var r sql.RawBytes
+ return &r, nil
+ }
+}
+
type oci8Driver struct {
+ godrorDriver
}
// dataSourceName=user/password@ipv4:port/dbname
// dataSourceName=user/password@[ipv6]:port/dbname
-func (p *oci8Driver) Parse(driverName, dataSourceName string) (*URI, error) {
+func (o *oci8Driver) Parse(driverName, dataSourceName string) (*URI, error) {
db := &URI{DBType: schemas.ORACLE}
dsnPattern := regexp.MustCompile(
`^(?P<user>.*)\/(?P<password>.*)@` + // user:password@
@@ -862,8 +917,7 @@ func (p *oci8Driver) Parse(driverName, dataSourceName string) (*URI, error) {
matches := dsnPattern.FindStringSubmatch(dataSourceName)
names := dsnPattern.SubexpNames()
for i, match := range matches {
- switch names[i] {
- case "dbname":
+ if names[i] == "dbname" {
db.DBName = match
}
}
diff --git a/vendor/xorm.io/xorm/dialects/postgres.go b/vendor/xorm.io/xorm/dialects/postgres.go
index 9acf763ab4..96ebfc850d 100644
--- a/vendor/xorm.io/xorm/dialects/postgres.go
+++ b/vendor/xorm.io/xorm/dialects/postgres.go
@@ -6,6 +6,7 @@ package dialects
import (
"context"
+ "database/sql"
"errors"
"fmt"
"net/url"
@@ -777,12 +778,24 @@ var (
var (
// DefaultPostgresSchema default postgres schema
DefaultPostgresSchema = "public"
+ postgresColAliases = map[string]string{
+ "numeric": "decimal",
+ }
)
type postgres struct {
Base
}
+// Alias returns a alias of column
+func (db *postgres) Alias(col string) string {
+ v, ok := postgresColAliases[strings.ToLower(col)]
+ if ok {
+ return v
+ }
+ return col
+}
+
func (db *postgres) Init(uri *URI) error {
db.quoter = postgresQuoter
return db.Base.Init(db, uri)
@@ -797,7 +810,10 @@ func (db *postgres) Version(ctx context.Context, queryer core.Queryer) (*schemas
var version string
if !rows.Next() {
- return nil, errors.New("Unknow version")
+ if rows.Err() != nil {
+ return nil, rows.Err()
+ }
+ return nil, errors.New("unknow version")
}
if err := rows.Scan(&version); err != nil {
@@ -860,21 +876,16 @@ 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 {
- case schemas.TinyInt:
+ case schemas.TinyInt, schemas.UnsignedTinyInt:
res = schemas.SmallInt
return res
case schemas.Bit:
res = schemas.Boolean
return res
- case schemas.MediumInt, schemas.Int, schemas.Integer:
+ case schemas.MediumInt, schemas.Int, schemas.Integer, schemas.UnsignedMediumInt, schemas.UnsignedSmallInt:
if c.IsAutoIncrement {
return schemas.Serial
}
@@ -930,6 +941,21 @@ func (db *postgres) SQLType(c *schemas.Column) string {
return res
}
+func (db *postgres) ColumnTypeKind(t string) int {
+ switch strings.ToUpper(t) {
+ case "DATETIME", "TIMESTAMP":
+ return schemas.TIME_TYPE
+ case "VARCHAR", "TEXT":
+ return schemas.TEXT_TYPE
+ case "BIGINT", "BIGSERIAL", "SMALLINT", "INT", "INT8", "INT4", "INTEGER", "SERIAL", "FLOAT", "FLOAT4", "REAL", "DOUBLE PRECISION":
+ return schemas.NUMERIC_TYPE
+ case "BOOL":
+ return schemas.BOOL_TYPE
+ default:
+ return schemas.UNKNOW_TYPE
+ }
+}
+
func (db *postgres) IsReserved(name string) bool {
_, ok := postgresReservedWords[strings.ToUpper(name)]
return ok
@@ -1039,7 +1065,10 @@ func (db *postgres) IsColumnExist(queryer core.Queryer, ctx context.Context, tab
}
defer rows.Close()
- return rows.Next(), nil
+ if rows.Next() {
+ return true, nil
+ }
+ return false, rows.Err()
}
func (db *postgres) GetColumns(queryer core.Queryer, ctx context.Context, tableName string) ([]string, map[string]*schemas.Column, error) {
@@ -1169,7 +1198,7 @@ WHERE n.nspname= s.table_schema AND c.relkind = 'r'::char AND c.relname = $1%s A
}
}
if _, ok := schemas.SqlTypes[col.SQLType.Name]; !ok {
- return nil, nil, fmt.Errorf("Unknown colType: %s - %s", dataType, col.SQLType.Name)
+ return nil, nil, fmt.Errorf("unknown colType: %s - %s", dataType, col.SQLType.Name)
}
col.Length = maxLen
@@ -1177,19 +1206,22 @@ WHERE n.nspname= s.table_schema AND c.relkind = 'r'::char AND c.relname = $1%s A
if !col.DefaultIsEmpty {
if col.SQLType.IsText() {
if strings.HasSuffix(col.Default, "::character varying") {
- col.Default = strings.TrimRight(col.Default, "::character varying")
+ col.Default = strings.TrimSuffix(col.Default, "::character varying")
} else if !strings.HasPrefix(col.Default, "'") {
col.Default = "'" + col.Default + "'"
}
} else if col.SQLType.IsTime() {
if strings.HasSuffix(col.Default, "::timestamp without time zone") {
- col.Default = strings.TrimRight(col.Default, "::timestamp without time zone")
+ col.Default = strings.TrimSuffix(col.Default, "::timestamp without time zone")
}
}
}
cols[col.Name] = col
colSeq = append(colSeq, col.Name)
}
+ if rows.Err() != nil {
+ return nil, nil, rows.Err()
+ }
return colSeq, cols, nil
}
@@ -1220,6 +1252,9 @@ func (db *postgres) GetTables(queryer core.Queryer, ctx context.Context) ([]*sch
table.Name = name
tables = append(tables, table)
}
+ if rows.Err() != nil {
+ return nil, rows.Err()
+ }
return tables, nil
}
@@ -1236,7 +1271,7 @@ func getIndexColName(indexdef string) []string {
func (db *postgres) GetIndexes(queryer core.Queryer, ctx context.Context, tableName string) (map[string]*schemas.Index, error) {
args := []interface{}{tableName}
- s := fmt.Sprintf("SELECT indexname, indexdef FROM pg_indexes WHERE tablename=$1")
+ s := "SELECT indexname, indexdef FROM pg_indexes WHERE tablename=$1"
if len(db.getSchema()) != 0 {
args = append(args, db.getSchema())
s = s + " AND schemaname=$2"
@@ -1248,7 +1283,7 @@ func (db *postgres) GetIndexes(queryer core.Queryer, ctx context.Context, tableN
}
defer rows.Close()
- indexes := make(map[string]*schemas.Index, 0)
+ indexes := make(map[string]*schemas.Index)
for rows.Next() {
var indexType int
var indexName, indexdef string
@@ -1290,6 +1325,9 @@ func (db *postgres) GetIndexes(queryer core.Queryer, ctx context.Context, tableN
index.IsRegular = isRegular
indexes[index.Name] = index
}
+ if rows.Err() != nil {
+ return nil, rows.Err()
+ }
return indexes, nil
}
@@ -1298,18 +1336,11 @@ func (db *postgres) Filters() []Filter {
}
type pqDriver struct {
+ baseDriver
}
type values map[string]string
-func (vs values) Set(k, v string) {
- vs[k] = v
-}
-
-func (vs values) Get(k string) (v string) {
- return vs[k]
-}
-
func parseURL(connstr string) (string, error) {
u, err := url.Parse(connstr)
if err != nil {
@@ -1329,30 +1360,94 @@ func parseURL(connstr string) (string, error) {
return "", nil
}
-func parseOpts(name string, o values) error {
- if len(name) == 0 {
- return fmt.Errorf("invalid options: %s", name)
+func parseOpts(urlStr string, o values) error {
+ if len(urlStr) == 0 {
+ return fmt.Errorf("invalid options: %s", urlStr)
}
- name = strings.TrimSpace(name)
+ urlStr = strings.TrimSpace(urlStr)
+
+ var (
+ inQuote bool
+ state int // 0 key, 1 space, 2 value, 3 equal
+ start int
+ key string
+ )
+ for i, c := range urlStr {
+ switch c {
+ case ' ':
+ if !inQuote {
+ if state == 2 {
+ state = 1
+ v := urlStr[start:i]
+ if strings.HasPrefix(v, "'") && strings.HasSuffix(v, "'") {
+ v = v[1 : len(v)-1]
+ } else if strings.HasPrefix(v, "'") || strings.HasSuffix(v, "'") {
+ return fmt.Errorf("wrong single quote in %d of %s", i, urlStr)
+ }
+ o[key] = v
+ } else if state != 1 {
+ return fmt.Errorf("wrong format: %v", urlStr)
+ }
+ }
+ case '\'':
+ if state == 3 {
+ state = 2
+ start = i
+ } else if state != 2 {
+ return fmt.Errorf("wrong format: %v", urlStr)
+ }
+ inQuote = !inQuote
+ case '=':
+ if !inQuote {
+ if state != 0 {
+ return fmt.Errorf("wrong format: %v", urlStr)
+ }
+ key = urlStr[start:i]
+ state = 3
+ }
+ default:
+ if state == 3 {
+ state = 2
+ start = i
+ } else if state == 1 {
+ state = 0
+ start = i
+ }
+ }
- ps := strings.Split(name, " ")
- for _, p := range ps {
- kv := strings.Split(p, "=")
- if len(kv) < 2 {
- return fmt.Errorf("invalid option: %q", p)
+ if i == len(urlStr)-1 {
+ if state != 2 {
+ return errors.New("no value matched key")
+ }
+ v := urlStr[start : i+1]
+ if strings.HasPrefix(v, "'") && strings.HasSuffix(v, "'") {
+ v = v[1 : len(v)-1]
+ } else if strings.HasPrefix(v, "'") || strings.HasSuffix(v, "'") {
+ return fmt.Errorf("wrong single quote in %d of %s", i, urlStr)
+ }
+ o[key] = v
}
- o.Set(kv[0], kv[1])
}
return nil
}
+func (p *pqDriver) Features() *DriverFeatures {
+ return &DriverFeatures{
+ SupportReturnInsertedID: false,
+ }
+}
+
func (p *pqDriver) Parse(driverName, dataSourceName string) (*URI, error) {
db := &URI{DBType: schemas.POSTGRES}
+
var err error
+ if strings.Contains(dataSourceName, "://") {
+ if !strings.HasPrefix(dataSourceName, "postgresql://") && !strings.HasPrefix(dataSourceName, "postgres://") {
+ return nil, fmt.Errorf("unsupported protocol %v", dataSourceName)
+ }
- if strings.HasPrefix(dataSourceName, "postgresql://") || strings.HasPrefix(dataSourceName, "postgres://") {
db.DBName, err = parseURL(dataSourceName)
if err != nil {
return nil, err
@@ -1364,7 +1459,7 @@ func (p *pqDriver) Parse(driverName, dataSourceName string) (*URI, error) {
return nil, err
}
- db.DBName = o.Get("dbname")
+ db.DBName = o["dbname"]
}
if db.DBName == "" {
@@ -1374,6 +1469,32 @@ func (p *pqDriver) Parse(driverName, dataSourceName string) (*URI, error) {
return db, nil
}
+func (p *pqDriver) GenScanResult(colType string) (interface{}, error) {
+ switch colType {
+ case "VARCHAR", "TEXT":
+ var s sql.NullString
+ return &s, nil
+ case "BIGINT", "BIGSERIAL":
+ var s sql.NullInt64
+ return &s, nil
+ case "SMALLINT", "INT", "INT8", "INT4", "INTEGER", "SERIAL":
+ var s sql.NullInt32
+ return &s, nil
+ case "FLOAT", "FLOAT4", "REAL", "DOUBLE PRECISION":
+ var s sql.NullFloat64
+ return &s, nil
+ case "DATETIME", "TIMESTAMP":
+ var s sql.NullTime
+ return &s, nil
+ case "BOOL":
+ var s sql.NullBool
+ return &s, nil
+ default:
+ var r sql.RawBytes
+ return &r, nil
+ }
+}
+
type pqDriverPgx struct {
pqDriver
}
@@ -1401,6 +1522,9 @@ func QueryDefaultPostgresSchema(ctx context.Context, queryer core.Queryer) (stri
parts := strings.Split(defaultSchema, ",")
return strings.TrimSpace(parts[len(parts)-1]), nil
}
+ if rows.Err() != nil {
+ return "", rows.Err()
+ }
- return "", errors.New("No default schema")
+ return "", errors.New("no default schema")
}
diff --git a/vendor/xorm.io/xorm/dialects/sqlite3.go b/vendor/xorm.io/xorm/dialects/sqlite3.go
index a42aad4867..ac17fd927d 100644
--- a/vendor/xorm.io/xorm/dialects/sqlite3.go
+++ b/vendor/xorm.io/xorm/dialects/sqlite3.go
@@ -169,7 +169,10 @@ func (db *sqlite3) Version(ctx context.Context, queryer core.Queryer) (*schemas.
var version string
if !rows.Next() {
- return nil, errors.New("Unknow version")
+ if rows.Err() != nil {
+ return nil, rows.Err()
+ }
+ return nil, errors.New("unknow version")
}
if err := rows.Scan(&version); err != nil {
@@ -214,8 +217,9 @@ 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,
- schemas.UnsignedBigInt, schemas.UnsignedInt:
+ case schemas.Bit, schemas.TinyInt, schemas.UnsignedTinyInt, schemas.SmallInt,
+ schemas.UnsignedSmallInt, schemas.MediumInt, schemas.Int, schemas.UnsignedInt,
+ schemas.BigInt, schemas.UnsignedBigInt, schemas.Integer:
return schemas.Integer
case schemas.Float, schemas.Double, schemas.Real:
return schemas.Real
@@ -233,8 +237,19 @@ func (db *sqlite3) SQLType(c *schemas.Column) string {
}
}
-func (db *sqlite3) FormatBytes(bs []byte) string {
- return fmt.Sprintf("X'%x'", bs)
+func (db *sqlite3) ColumnTypeKind(t string) int {
+ switch strings.ToUpper(t) {
+ case "DATETIME":
+ return schemas.TIME_TYPE
+ case "TEXT":
+ return schemas.TEXT_TYPE
+ case "INTEGER", "REAL", "NUMERIC", "DECIMAL":
+ return schemas.NUMERIC_TYPE
+ case "BLOB":
+ return schemas.BLOB_TYPE
+ default:
+ return schemas.UNKNOW_TYPE
+ }
}
func (db *sqlite3) IsReserved(name string) bool {
@@ -404,12 +419,14 @@ func (db *sqlite3) GetColumns(queryer core.Queryer, ctx context.Context, tableNa
defer rows.Close()
var name string
- for rows.Next() {
+ if rows.Next() {
err = rows.Scan(&name)
if err != nil {
return nil, nil, err
}
- break
+ }
+ if rows.Err() != nil {
+ return nil, nil, rows.Err()
}
if name == "" {
@@ -472,6 +489,9 @@ func (db *sqlite3) GetTables(queryer core.Queryer, ctx context.Context) ([]*sche
}
tables = append(tables, table)
}
+ if rows.Err() != nil {
+ return nil, rows.Err()
+ }
return tables, nil
}
@@ -485,7 +505,7 @@ func (db *sqlite3) GetIndexes(queryer core.Queryer, ctx context.Context, tableNa
}
defer rows.Close()
- indexes := make(map[string]*schemas.Index, 0)
+ indexes := make(map[string]*schemas.Index)
for rows.Next() {
var tmpSQL sql.NullString
err = rows.Scan(&tmpSQL)
@@ -531,6 +551,9 @@ func (db *sqlite3) GetIndexes(queryer core.Queryer, ctx context.Context, tableNa
index.IsRegular = isRegular
indexes[index.Name] = index
}
+ if rows.Err() != nil {
+ return nil, rows.Err()
+ }
return indexes, nil
}
@@ -540,6 +563,13 @@ func (db *sqlite3) Filters() []Filter {
}
type sqlite3Driver struct {
+ baseDriver
+}
+
+func (p *sqlite3Driver) Features() *DriverFeatures {
+ return &DriverFeatures{
+ SupportReturnInsertedID: true,
+ }
}
func (p *sqlite3Driver) Parse(driverName, dataSourceName string) (*URI, error) {
@@ -549,3 +579,29 @@ func (p *sqlite3Driver) Parse(driverName, dataSourceName string) (*URI, error) {
return &URI{DBType: schemas.SQLITE, DBName: dataSourceName}, nil
}
+
+func (p *sqlite3Driver) GenScanResult(colType string) (interface{}, error) {
+ switch colType {
+ case "TEXT":
+ var s sql.NullString
+ return &s, nil
+ case "INTEGER":
+ var s sql.NullInt64
+ return &s, nil
+ case "DATETIME":
+ var s sql.NullTime
+ return &s, nil
+ case "REAL":
+ var s sql.NullFloat64
+ return &s, nil
+ case "NUMERIC", "DECIMAL":
+ var s sql.NullString
+ return &s, nil
+ case "BLOB":
+ var s sql.RawBytes
+ return &s, nil
+ default:
+ var r sql.NullString
+ return &r, nil
+ }
+}
diff --git a/vendor/xorm.io/xorm/dialects/time.go b/vendor/xorm.io/xorm/dialects/time.go
index 5aee0c103f..f0bbb76518 100644
--- a/vendor/xorm.io/xorm/dialects/time.go
+++ b/vendor/xorm.io/xorm/dialects/time.go
@@ -5,50 +5,57 @@
package dialects
import (
+ "strings"
"time"
"xorm.io/xorm/schemas"
)
-// FormatTime format time as column type
-func FormatTime(dialect Dialect, sqlTypeName string, t time.Time) (v interface{}) {
- switch sqlTypeName {
- case schemas.Time:
- s := t.Format("2006-01-02 15:04:05") // time.RFC3339
- v = s[11:19]
+// FormatColumnTime format column time
+func FormatColumnTime(dialect Dialect, dbLocation *time.Location, col *schemas.Column, t time.Time) (interface{}, error) {
+ if t.IsZero() {
+ if col.Nullable {
+ return nil, nil
+ }
+
+ if col.SQLType.IsNumeric() {
+ return 0, nil
+ }
+ }
+
+ var tmZone = dbLocation
+ if col.TimeZone != nil {
+ tmZone = col.TimeZone
+ }
+
+ t = t.In(tmZone)
+
+ switch col.SQLType.Name {
case schemas.Date:
- v = t.Format("2006-01-02")
- case schemas.DateTime, schemas.TimeStamp, schemas.Varchar: // !DarthPestilane! format time when sqlTypeName is schemas.Varchar.
- if dialect.URI().DBType == schemas.ORACLE {
- v = t
- } else {
- v = t.Format("2006-01-02 15:04:05")
+ return t.Format("2006-01-02"), nil
+ case schemas.Time:
+ var layout = "15:04:05"
+ if col.Length > 0 {
+ layout += "." + strings.Repeat("0", col.Length)
}
+ return t.Format(layout), nil
+ case schemas.DateTime, schemas.TimeStamp:
+ var layout = "2006-01-02 15:04:05"
+ if col.Length > 0 {
+ layout += "." + strings.Repeat("0", col.Length)
+ }
+ return t.Format(layout), nil
+ case schemas.Varchar:
+ return t.Format("2006-01-02 15:04:05"), nil
case schemas.TimeStampz:
if dialect.URI().DBType == schemas.MSSQL {
- v = t.Format("2006-01-02T15:04:05.9999999Z07:00")
+ return t.Format("2006-01-02T15:04:05.9999999Z07:00"), nil
} else {
- v = t.Format(time.RFC3339Nano)
+ return t.Format(time.RFC3339Nano), nil
}
case schemas.BigInt, schemas.Int:
- v = t.Unix()
+ return t.Unix(), nil
default:
- v = t
- }
- 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 {
- return nil
- }
- return ""
- }
-
- if col.TimeZone != nil {
- return FormatTime(dialect, col.SQLType.Name, t.In(col.TimeZone))
+ return t, nil
}
- return FormatTime(dialect, col.SQLType.Name, t.In(defaultTimeZone))
}
diff --git a/vendor/xorm.io/xorm/doc.go b/vendor/xorm.io/xorm/doc.go
index ea6a222671..d065323263 100644
--- a/vendor/xorm.io/xorm/doc.go
+++ b/vendor/xorm.io/xorm/doc.go
@@ -14,23 +14,30 @@ Make sure you have installed Go 1.11+ and then:
Create Engine
-Firstly, we should new an engine for a database
+Firstly, we should create an engine for a database
engine, err := xorm.NewEngine(driverName, dataSourceName)
-Method NewEngine's parameters is the same as sql.Open. It depends
-drivers' implementation.
-Generally, one engine for an application is enough. You can set it as package variable.
+Method NewEngine's parameters are the same as sql.Open which depend drivers' implementation.
+Generally, one engine for an application is enough. You can define it as a package variable.
Raw Methods
-XORM also support raw SQL execution:
+XORM supports raw SQL execution:
-1. query a SQL string, the returned results is []map[string][]byte
+1. query with a SQL string, the returned results is []map[string][]byte
results, err := engine.Query("select * from user")
-2. execute a SQL string, the returned results
+2. query with a SQL string, the returned results is []map[string]string
+
+ results, err := engine.QueryString("select * from user")
+
+3. query with a SQL string, the returned results is []map[string]interface{}
+
+ results, err := engine.QueryInterface("select * from user")
+
+4. execute with a SQL string, the returned results
affected, err := engine.Exec("update user set .... where ...")
@@ -77,7 +84,9 @@ There are 8 major ORM methods and many helpful methods to use to operate databas
4. Query multiple records and record by record handle, there two methods, one is Iterate,
another is Rows
- err := engine.Iterate(...)
+ err := engine.Iterate(new(User), func(i int, bean interface{}) error {
+ // do something
+ })
// SELECT * FROM user
rows, err := engine.Rows(...)
@@ -120,7 +129,7 @@ another is Rows
Conditions
The above 8 methods could use with condition methods chainable.
-Attention: the above 8 methods should be the last chainable method.
+Notice: the above 8 methods should be the last chainable method.
1. ID, In
@@ -179,6 +188,47 @@ Attention: the above 8 methods should be the last chainable method.
engine.Join("LEFT", "userdetail", "user.id=userdetail.id").Find(&users)
//SELECT * FROM user LEFT JOIN userdetail ON user.id=userdetail.id
+Builder
+
+xorm could work with xorm.io/builder directly.
+
+1. With Where
+
+ var cond = builder.Eq{"a":1, "b":2}
+ engine.Where(cond).Find(&users)
+
+2. With In
+
+ var subQuery = builder.Select("name").From("group")
+ engine.In("group_name", subQuery).Find(&users)
+
+3. With Join
+
+ var subQuery = builder.Select("name").From("group")
+ engine.Join("INNER", subQuery, "group.id = user.group_id").Find(&users)
+
+4. With SetExprs
+
+ var subQuery = builder.Select("name").From("group")
+ engine.ID(1).SetExprs("name", subQuery).Update(new(User))
+
+5. With SQL
+
+ var query = builder.Select("name").From("group")
+ results, err := engine.SQL(query).Find(&groups)
+
+6. With Query
+
+ var query = builder.Select("name").From("group")
+ results, err := engine.Query(query)
+ results, err := engine.QueryString(query)
+ results, err := engine.QueryInterface(query)
+
+7. With Exec
+
+ var query = builder.Insert("a, b").Into("table1").Select("b, c").From("table2")
+ results, err := engine.Exec(query)
+
More usage, please visit http://xorm.io/docs
*/
package xorm
diff --git a/vendor/xorm.io/xorm/engine.go b/vendor/xorm.io/xorm/engine.go
index 0eb429b148..ec06610917 100644
--- a/vendor/xorm.io/xorm/engine.go
+++ b/vendor/xorm.io/xorm/engine.go
@@ -13,7 +13,6 @@ import (
"os"
"reflect"
"runtime"
- "strconv"
"strings"
"time"
@@ -21,7 +20,6 @@ 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"
@@ -35,6 +33,7 @@ type Engine struct {
cacherMgr *caches.Manager
defaultContext context.Context
dialect dialects.Dialect
+ driver dialects.Driver
engineGroup *EngineGroup
logger log.ContextLogger
tagParser *tags.Parser
@@ -72,6 +71,7 @@ func newEngine(driverName, dataSourceName string, dialect dialects.Dialect, db *
engine := &Engine{
dialect: dialect,
+ driver: dialects.QueryDriver(driverName),
TZLocation: time.Local,
defaultContext: context.Background(),
cacherMgr: cacherMgr,
@@ -444,93 +444,14 @@ func (engine *Engine) DumpTables(tables []*schemas.Table, w io.Writer, tp ...sch
return engine.dumpTables(tables, w, tp...)
}
-func formatColumnValue(dbLocation *time.Location, dstDialect dialects.Dialect, d interface{}, col *schemas.Column) string {
- if d == nil {
- return "NULL"
- }
-
- if dq, ok := d.(bool); ok && (dstDialect.URI().DBType == schemas.SQLITE ||
- dstDialect.URI().DBType == schemas.MSSQL) {
- if dq {
+func formatBool(s string, dstDialect dialects.Dialect) string {
+ if dstDialect.URI().DBType == schemas.MSSQL {
+ switch s {
+ case "true":
return "1"
+ case "false":
+ return "0"
}
- return "0"
- }
-
- if col.SQLType.IsText() {
- 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 t, ok := d.(time.Time); ok {
- return "'" + t.In(dbLocation).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")])
- } else if strings.HasSuffix(v, " +0000 +0000") {
- return fmt.Sprintf("'%s'", v[0:len(v)-len(" +0000 +0000")])
- }
- return "'" + strings.Replace(v, "'", "''", -1) + "'"
- } else if col.SQLType.IsBlob() {
- if reflect.TypeOf(d).Kind() == reflect.Slice {
- return fmt.Sprintf("%s", dstDialect.FormatBytes(d.([]byte)))
- } else if reflect.TypeOf(d).Kind() == reflect.String {
- return fmt.Sprintf("'%s'", d.(string))
- }
- } else if col.SQLType.IsNumeric() {
- switch reflect.TypeOf(d).Kind() {
- case reflect.Slice:
- if col.SQLType.Name == schemas.Bool {
- return fmt.Sprintf("%v", strconv.FormatBool(d.([]byte)[0] != byte('0')))
- }
- return fmt.Sprintf("%s", string(d.([]byte)))
- case reflect.Int16, reflect.Int8, reflect.Int32, reflect.Int64, reflect.Int:
- if col.SQLType.Name == schemas.Bool {
- v := reflect.ValueOf(d).Int() > 0
- if dstDialect.URI().DBType == schemas.SQLITE {
- if v {
- return "1"
- }
- return "0"
- }
- return fmt.Sprintf("%v", strconv.FormatBool(v))
- }
- 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
- if dstDialect.URI().DBType == schemas.SQLITE {
- if v {
- return "1"
- }
- return "0"
- }
- return fmt.Sprintf("%v", strconv.FormatBool(v))
- }
- return fmt.Sprintf("%d", d)
- default:
- return fmt.Sprintf("%v", d)
- }
- }
-
- s := fmt.Sprintf("%v", d)
- if strings.Contains(s, ":") || strings.Contains(s, "-") {
- if strings.HasSuffix(s, " +0000 UTC") {
- return fmt.Sprintf("'%s'", s[0:len(s)-len(" +0000 UTC")])
- }
- return fmt.Sprintf("'%s'", s)
}
return s
}
@@ -543,13 +464,14 @@ func (engine *Engine) dumpTables(tables []*schemas.Table, w io.Writer, tp ...sch
} else {
dstDialect = dialects.QueryDialect(tp[0])
if dstDialect == nil {
- return errors.New("Unsupported database type")
+ return fmt.Errorf("unsupported database type %v", tp[0])
}
uri := engine.dialect.URI()
destURI := dialects.URI{
DBType: tp[0],
DBName: uri.DBName,
+ Schema: uri.Schema,
}
dstDialect.Init(&destURI)
}
@@ -617,74 +539,77 @@ func (engine *Engine) dumpTables(tables []*schemas.Table, w io.Writer, tp ...sch
}
defer rows.Close()
- 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
- }
+ types, err := rows.ColumnTypes()
+ 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, err := rows.Columns()
+ if err != nil {
+ return err
+ }
- field := dataStruct.FieldByIndex(col.FieldIndex)
- temp += "," + formatColumnValue(engine.DatabaseTZ, dstDialect, field.Interface(), col)
- }
- _, err = io.WriteString(w, temp[1:]+");\n")
- if err != nil {
- return err
- }
+ sess := engine.NewSession()
+ defer sess.Close()
+ for rows.Next() {
+ _, err = io.WriteString(w, "INSERT INTO "+dstDialect.Quoter().Quote(dstTableName)+" ("+destColNames+") VALUES (")
+ 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")
+ scanResults, err := sess.engine.scanStringInterface(rows, fields, types)
+ if err != nil {
+ return err
+ }
+ for i, scanResult := range scanResults {
+ stp := schemas.SQLType{Name: types[i].DatabaseTypeName()}
+ if stp.IsNumeric() {
+ s := scanResult.(*sql.NullString)
+ if s.Valid {
+ if _, err = io.WriteString(w, formatBool(s.String, dstDialect)); err != nil {
+ return err
+ }
+ } else {
+ if _, err = io.WriteString(w, "NULL"); err != nil {
+ return err
+ }
+ }
+ } else if stp.IsBool() {
+ s := scanResult.(*sql.NullString)
+ if s.Valid {
+ if _, err = io.WriteString(w, formatBool(s.String, dstDialect)); err != nil {
+ return err
+ }
+ } else {
+ if _, err = io.WriteString(w, "NULL"); err != nil {
+ return err
+ }
+ }
+ } else {
+ s := scanResult.(*sql.NullString)
+ if s.Valid {
+ if _, err = io.WriteString(w, "'"+strings.ReplaceAll(s.String, "'", "''")+"'"); err != nil {
+ return err
+ }
+ } else {
+ if _, err = io.WriteString(w, "NULL"); err != nil {
+ return err
+ }
}
-
- temp += "," + formatColumnValue(engine.DatabaseTZ, dstDialect, d, col)
}
- _, err = io.WriteString(w, temp[1:]+");\n")
- if err != nil {
- return err
+ if i < len(scanResults)-1 {
+ if _, err = io.WriteString(w, ","); err != nil {
+ return err
+ }
}
}
+ _, err = io.WriteString(w, ");\n")
+ if err != nil {
+ return err
+ }
+ }
+ if rows.Err() != nil {
+ return rows.Err()
}
// FIXME: Hack for postgres
@@ -1200,10 +1125,10 @@ func (engine *Engine) Update(bean interface{}, condiBeans ...interface{}) (int64
}
// Delete records, bean's non-empty fields are conditions
-func (engine *Engine) Delete(bean interface{}) (int64, error) {
+func (engine *Engine) Delete(beans ...interface{}) (int64, error) {
session := engine.NewSession()
defer session.Close()
- return session.Delete(bean)
+ return session.Delete(beans...)
}
// Get retrieve one record from table, bean's non-empty fields
@@ -1302,13 +1227,13 @@ func (engine *Engine) Import(r io.Reader) ([]sql.Result, error) {
}
// nowTime return current time
-func (engine *Engine) nowTime(col *schemas.Column) (interface{}, time.Time) {
+func (engine *Engine) nowTime(col *schemas.Column) (interface{}, time.Time, error) {
t := time.Now()
- var tz = engine.DatabaseTZ
- if !col.DisableTimeZone && col.TimeZone != nil {
- tz = col.TimeZone
+ result, err := dialects.FormatColumnTime(engine.dialect, engine.DatabaseTZ, col, t)
+ if err != nil {
+ return nil, time.Time{}, err
}
- return dialects.FormatTime(engine.dialect, col.SQLType.Name, t.In(tz)), t.In(engine.TZLocation)
+ return result, t.In(engine.TZLocation), nil
}
// GetColumnMapper returns the column name mapper
diff --git a/vendor/xorm.io/xorm/engine_group.go b/vendor/xorm.io/xorm/engine_group.go
index 3569690b16..f2fe913dd9 100644
--- a/vendor/xorm.io/xorm/engine_group.go
+++ b/vendor/xorm.io/xorm/engine_group.go
@@ -237,3 +237,31 @@ func (eg *EngineGroup) Slave() *Engine {
func (eg *EngineGroup) Slaves() []*Engine {
return eg.slaves
}
+
+// Query execcute a select SQL and return the result
+func (eg *EngineGroup) Query(sqlOrArgs ...interface{}) (resultsSlice []map[string][]byte, err error) {
+ sess := eg.NewSession()
+ sess.isAutoClose = true
+ return sess.Query(sqlOrArgs...)
+}
+
+// QueryInterface execcute a select SQL and return the result
+func (eg *EngineGroup) QueryInterface(sqlOrArgs ...interface{}) ([]map[string]interface{}, error) {
+ sess := eg.NewSession()
+ sess.isAutoClose = true
+ return sess.QueryInterface(sqlOrArgs...)
+}
+
+// QueryString execcute a select SQL and return the result
+func (eg *EngineGroup) QueryString(sqlOrArgs ...interface{}) ([]map[string]string, error) {
+ sess := eg.NewSession()
+ sess.isAutoClose = true
+ return sess.QueryString(sqlOrArgs...)
+}
+
+// Rows execcute a select SQL and return the result
+func (eg *EngineGroup) Rows(bean interface{}) (*Rows, error) {
+ sess := eg.NewSession()
+ sess.isAutoClose = true
+ return sess.Rows(bean)
+}
diff --git a/vendor/xorm.io/xorm/go.mod b/vendor/xorm.io/xorm/go.mod
index f6e4af9083..d645011c3b 100644
--- a/vendor/xorm.io/xorm/go.mod
+++ b/vendor/xorm.io/xorm/go.mod
@@ -3,14 +3,17 @@ module xorm.io/xorm
go 1.13
require (
- github.com/denisenkom/go-mssqldb v0.9.0
- github.com/go-sql-driver/mysql v1.5.0
+ github.com/denisenkom/go-mssqldb v0.10.0
+ github.com/go-sql-driver/mysql v1.6.0
+ github.com/goccy/go-json v0.7.4
+ github.com/jackc/pgx/v4 v4.12.0
github.com/json-iterator/go v1.1.11
- github.com/lib/pq v1.7.0
- github.com/mattn/go-sqlite3 v1.14.6
- github.com/stretchr/testify v1.4.0
+ github.com/lib/pq v1.10.2
+ github.com/mattn/go-sqlite3 v1.14.8
+ github.com/shopspring/decimal v1.2.0
+ github.com/stretchr/testify v1.7.0
github.com/syndtr/goleveldb v1.0.0
github.com/ziutek/mymysql v1.5.4
- modernc.org/sqlite v1.10.1-0.20210314190707-798bbeb9bb84
- xorm.io/builder v0.3.8
+ modernc.org/sqlite v1.11.2
+ xorm.io/builder v0.3.9
)
diff --git a/vendor/xorm.io/xorm/go.sum b/vendor/xorm.io/xorm/go.sum
index 3c79850cc6..e802494511 100644
--- a/vendor/xorm.io/xorm/go.sum
+++ b/vendor/xorm.io/xorm/go.sum
@@ -1,130 +1,573 @@
+cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
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/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
+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/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
+github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
+github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
+github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
+github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
+github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
+github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
+github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
+github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
+github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
+github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
+github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
+github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
+github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
+github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
+github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
+github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
+github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
+github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
+github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
+github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
+github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
+github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
+github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
+github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
+github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
+github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
+github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
+github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
+github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
+github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
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.9.0 h1:RSohk2RsiZqLZ0zCjtfn3S4Gp4exhpBWHyQ7D0yGjAk=
-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/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
+github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
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/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
+github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
+github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
+github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
+github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
+github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
+github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
+github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
+github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
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=
-github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
+github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
+github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
+github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
+github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
+github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
+github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
+github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
+github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
+github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/goccy/go-json v0.7.4 h1:B44qRUFwz/vxPKPISQ1KhvzRi9kZ28RAf6YtjriBZ5k=
+github.com/goccy/go-json v0.7.4/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
+github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
+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/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
+github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
+github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
+github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
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/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
+github.com/golang/protobuf v1.3.2/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/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
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/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
+github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
+github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
+github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
+github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
+github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
+github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
+github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
+github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
+github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
+github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
+github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
+github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
+github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
+github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
+github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
+github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
+github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
+github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
+github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
+github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
+github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
+github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
+github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
+github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
+github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
+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=
+github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
+github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA=
+github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE=
+github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s=
+github.com/jackc/pgconn v1.4.0/go.mod h1:Y2O3ZDF0q4mMacyWV3AstPJpeHXWGEetiFttmq5lahk=
+github.com/jackc/pgconn v1.5.0/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI=
+github.com/jackc/pgconn v1.5.1-0.20200601181101-fa742c524853/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI=
+github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o=
+github.com/jackc/pgconn v1.8.1/go.mod h1:JV6m6b6jhjdmzchES0drzCcYcAHS1OPD5xu3OZ/lE2g=
+github.com/jackc/pgconn v1.9.0 h1:gqibKSTJup/ahCsNKyMZAniPuZEfIqfXFc8FOWVYR+Q=
+github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY=
+github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
+github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
+github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=
+github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd h1:eDErF6V/JPJON/B7s68BxwHgfmyOntHJQ8IOaz0x4R8=
+github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c=
+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=
+github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
+github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
+github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
+github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
+github.com/jackc/pgproto3/v2 v2.1.1 h1:7PQ/4gLoqnl87ZxL7xjO0DR5gYuviDCZxQJsUlFW1eI=
+github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
+github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
+github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg=
+github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
+github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg=
+github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc=
+github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw=
+github.com/jackc/pgtype v1.2.0/go.mod h1:5m2OfMh1wTK7x+Fk952IDmI4nw3nPrvtQdM0ZT4WpC0=
+github.com/jackc/pgtype v1.3.1-0.20200510190516-8cd94a14c75a/go.mod h1:vaogEUkALtxZMCH411K+tKzNpwzCKU+AnPzBKZ+I+Po=
+github.com/jackc/pgtype v1.3.1-0.20200606141011-f6355165a91c/go.mod h1:cvk9Bgu/VzJ9/lxTO5R5sf80p0DiucVtN7ZxvaC4GmQ=
+github.com/jackc/pgtype v1.7.0/go.mod h1:ZnHF+rMePVqDKaOfJVI4Q8IVvAQMryDlDkZnKOI75BE=
+github.com/jackc/pgtype v1.8.0 h1:iFVCcVhYlw0PulYCVoguRGm0SE9guIcPcccnLzHj8bA=
+github.com/jackc/pgtype v1.8.0/go.mod h1:PqDKcEBtllAtk/2p6z6SHdXW5UB+MhE75tUol2OKexE=
+github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
+github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
+github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
+github.com/jackc/pgx/v4 v4.5.0/go.mod h1:EpAKPLdnTorwmPUUsqrPxy5fphV18j9q3wrfRXgo+kA=
+github.com/jackc/pgx/v4 v4.6.1-0.20200510190926-94ba730bb1e9/go.mod h1:t3/cdRQl6fOLDxqtlyhe9UWgfIi9R8+8v8GKV5TRA/o=
+github.com/jackc/pgx/v4 v4.6.1-0.20200606145419-4e5062306904/go.mod h1:ZDaNWkt9sW1JMiNn0kdYBaLelIhw7Pg4qd+Vk6tw7Hg=
+github.com/jackc/pgx/v4 v4.11.0/go.mod h1:i62xJgdrtVDsnL3U8ekyrQXEwGNTRoG7/8r+CIdYfcc=
+github.com/jackc/pgx/v4 v4.12.0 h1:xiP3TdnkwyslWNp77yE5XAPfxAsU9RMFDe0c1SwN8h4=
+github.com/jackc/pgx/v4 v4.12.0/go.mod h1:fE547h6VulLPA3kySjfnSG/e2D861g/50JlVUa/ub60=
+github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
+github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
+github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
+github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
+github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
+github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
+github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
+github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
+github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ=
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
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/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
+github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+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/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=
+github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8=
+github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
+github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
+github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
+github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
+github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
+github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
+github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
+github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
+github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
+github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
+github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
+github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
+github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
+github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
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-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
-github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
+github.com/mattn/go-sqlite3 v1.14.8 h1:gDp86IdQsN/xWjIEmr9MF6o9mpksUgh0fu+9ByFxzIU=
+github.com/mattn/go-sqlite3 v1.14.8/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
+github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
+github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
+github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
+github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
+github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
+github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
+github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
+github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
-github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
+github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
+github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
+github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
+github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
+github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=
+github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k=
+github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w=
+github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
+github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
+github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
+github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
+github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
+github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
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/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
+github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
+github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
+github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
+github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
+github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA=
+github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
+github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
+github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
+github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
+github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
+github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
+github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
+github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
+github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
+github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+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/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
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/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
+github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
+github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
+github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
+github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
+github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
+github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
+github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
+github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
+github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
+github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
+github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
+github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/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/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
+github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
+github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
+github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
+github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
+github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
+github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
+github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
+github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
+github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
+github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
+github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
+github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
+github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
+github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
+github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
+github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
+github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
+github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
+github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
+github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
+github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
+github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
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/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
+github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
+github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
+github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
+github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
+github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
+go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
+go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
+go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
+go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
+go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
+go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
+go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
+go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
+go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
+go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
+go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
+go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
+go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
+go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
+golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
+golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/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 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
+golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/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-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
+golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e h1:gsTQYXdTw2Gq7RBsWvlQ91b+aEQ6bXFUngBGuR8sPpI=
+golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
+golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+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 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
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-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 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck=
+golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/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-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/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/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/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.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
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 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
+golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+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 h1:M8tBwCtWD/cZV9DZpFYRUgaymAYAr+aIUTWzDaM3uPs=
golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+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 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=
+google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
+google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
+google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
+google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
+google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
+google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
+google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
+google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
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=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
+gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
+gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
+gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
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/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
+gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
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=
-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=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
+lukechampine.com/uint128 v1.1.1 h1:pnxCASz787iMf+02ssImqk6OLt+Z5QHMoZyUXR4z6JU=
+lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
+modernc.org/cc/v3 v3.33.6 h1:r63dgSzVzRxUpAJFPQWHy1QeZeY1ydNENUDaBx1GqYc=
+modernc.org/cc/v3 v3.33.6/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
+modernc.org/ccgo/v3 v3.9.5 h1:dEuUSf8WN51rDkprFuAqjfchKEzN0WttP/Py3enBwjk=
+modernc.org/ccgo/v3 v3.9.5/go.mod h1:umuo2EP2oDSBnD3ckjaVUXMrmeAw8C8OSICVa0iFf60=
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/libc v1.9.8/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w=
+modernc.org/libc v1.9.11 h1:QUxZMs48Ahg2F7SN41aERvMfGLY2HU/ADnB9DC4Yts8=
+modernc.org/libc v1.9.11/go.mod h1:NyF3tsA5ArIjJ83XB0JlqhjTabTCHm9aX4XMPHyQn0Q=
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/mathutil v1.4.0 h1:GCjoRaBew8ECCKINQA2nYjzvufFW9YiEuuB+rQ9bn2E=
+modernc.org/mathutil v1.4.0/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/sqlite v1.11.2 h1:ShWQpeD3ag/bmx6TqidBlIWonWmQaSQKls3aenCbt+w=
+modernc.org/sqlite v1.11.2/go.mod h1:+mhs/P1ONd+6G7hcAs6irwDi/bjTQ7nLW6LHRBsEa3A=
+modernc.org/strutil v1.1.1 h1:xv+J1BXY3Opl2ALrBwyfEikFAj8pmqcpnfmuwUwcozs=
+modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw=
+modernc.org/tcl v1.5.5 h1:N03RwthgTR/l/eQvz3UjfYnvVVj1G2sZqzFGfoD4HE4=
+modernc.org/tcl v1.5.5/go.mod h1:ADkaTUuwukkrlhqwERyq0SM8OvyXo7+TjFz7yAF56EI=
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=
+sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
+sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
+xorm.io/builder v0.3.9 h1:Sd65/LdWyO7LR8+Cbd+e7mm3sK/7U9k0jS3999IDHMc=
+xorm.io/builder v0.3.9/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
diff --git a/vendor/xorm.io/xorm/interface.go b/vendor/xorm.io/xorm/interface.go
index d31323ffd7..5d68f536c1 100644
--- a/vendor/xorm.io/xorm/interface.go
+++ b/vendor/xorm.io/xorm/interface.go
@@ -30,7 +30,7 @@ type Interface interface {
CreateUniques(bean interface{}) error
Decr(column string, arg ...interface{}) *Session
Desc(...string) *Session
- Delete(interface{}) (int64, error)
+ Delete(...interface{}) (int64, error)
Distinct(columns ...string) *Session
DropIndexes(bean interface{}) error
Exec(sqlOrArgs ...interface{}) (sql.Result, error)
@@ -51,6 +51,7 @@ type Interface interface {
MustCols(columns ...string) *Session
NoAutoCondition(...bool) *Session
NotIn(string, ...interface{}) *Session
+ Nullable(...string) *Session
Join(joinOperator string, tablename interface{}, condition string, args ...interface{}) *Session
Omit(columns ...string) *Session
OrderBy(order string) *Session
diff --git a/vendor/xorm.io/xorm/internal/json/gojson.go b/vendor/xorm.io/xorm/internal/json/gojson.go
new file mode 100644
index 0000000000..4f1448e7e7
--- /dev/null
+++ b/vendor/xorm.io/xorm/internal/json/gojson.go
@@ -0,0 +1,28 @@
+// Copyright 2021 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.
+
+// +build gojson
+
+package json
+
+import (
+ gojson "github.com/goccy/go-json"
+)
+
+func init() {
+ DefaultJSONHandler = GOjson{}
+}
+
+// GOjson implements JSONInterface via gojson
+type GOjson struct{}
+
+// Marshal implements JSONInterface
+func (GOjson) Marshal(v interface{}) ([]byte, error) {
+ return gojson.Marshal(v)
+}
+
+// Unmarshal implements JSONInterface
+func (GOjson) Unmarshal(data []byte, v interface{}) error {
+ return gojson.Unmarshal(data, v)
+}
diff --git a/vendor/xorm.io/xorm/internal/statements/insert.go b/vendor/xorm.io/xorm/internal/statements/insert.go
index 4e43c5bd36..84547cdfa2 100644
--- a/vendor/xorm.io/xorm/internal/statements/insert.go
+++ b/vendor/xorm.io/xorm/internal/statements/insert.go
@@ -5,6 +5,7 @@
package statements
import (
+ "errors"
"fmt"
"strings"
@@ -205,3 +206,55 @@ func (statement *Statement) GenInsertMapSQL(columns []string, args []interface{}
return buf.String(), buf.Args(), nil
}
+
+func (statement *Statement) GenInsertMultipleMapSQL(columns []string, argss [][]interface{}) (string, []interface{}, error) {
+ var (
+ buf = builder.NewWriter()
+ exprs = statement.ExprColumns
+ tableName = statement.TableName()
+ )
+
+ if _, err := buf.WriteString(fmt.Sprintf("INSERT INTO %s (", statement.quote(tableName))); err != nil {
+ return "", nil, err
+ }
+
+ if err := statement.dialect.Quoter().JoinWrite(buf.Builder, append(columns, exprs.ColNames()...), ","); err != nil {
+ return "", nil, err
+ }
+
+ // if insert where
+ if statement.Conds().IsValid() {
+ return "", nil, errors.New("batch insert don't support with where")
+ }
+
+ if _, err := buf.WriteString(") VALUES "); err != nil {
+ return "", nil, err
+ }
+ for i, args := range argss {
+ if _, err := buf.WriteString("("); err != nil {
+ return "", nil, err
+ }
+ if err := statement.WriteArgs(buf, args); err != nil {
+ return "", nil, err
+ }
+
+ if len(exprs) > 0 {
+ if _, err := buf.WriteString(","); err != nil {
+ return "", nil, err
+ }
+ if err := exprs.WriteArgs(buf); err != nil {
+ return "", nil, err
+ }
+ }
+ if _, err := buf.WriteString(")"); err != nil {
+ return "", nil, err
+ }
+ if i < len(argss)-1 {
+ if _, err := buf.WriteString(","); err != nil {
+ return "", nil, err
+ }
+ }
+ }
+
+ return buf.String(), buf.Args(), nil
+}
diff --git a/vendor/xorm.io/xorm/internal/statements/query.go b/vendor/xorm.io/xorm/internal/statements/query.go
index a972a8e077..76946cbdf4 100644
--- a/vendor/xorm.io/xorm/internal/statements/query.go
+++ b/vendor/xorm.io/xorm/internal/statements/query.go
@@ -247,6 +247,9 @@ func (statement *Statement) genSelectSQL(columnStr string, needLimit, needOrderB
top = fmt.Sprintf("TOP %d ", LimitNValue)
}
if statement.Start > 0 {
+ if statement.RefTable == nil {
+ return "", nil, errors.New("Unsupported query limit without reference table")
+ }
var column string
if len(statement.RefTable.PKColumns()) == 0 {
for _, index := range statement.RefTable.Indexes {
@@ -314,7 +317,7 @@ func (statement *Statement) genSelectSQL(columnStr string, needLimit, needOrderB
fmt.Fprint(&buf, " LIMIT ", *pLimitN)
}
} else if dialect.URI().DBType == schemas.ORACLE {
- if statement.Start != 0 || pLimitN != nil {
+ if statement.Start != 0 && pLimitN != nil {
oldString := buf.String()
buf.Reset()
rawColStr := columnStr
diff --git a/vendor/xorm.io/xorm/internal/statements/statement.go b/vendor/xorm.io/xorm/internal/statements/statement.go
index 2d173b876b..1fcc0bbacd 100644
--- a/vendor/xorm.io/xorm/internal/statements/statement.go
+++ b/vendor/xorm.io/xorm/internal/statements/statement.go
@@ -8,6 +8,7 @@ import (
"database/sql/driver"
"errors"
"fmt"
+ "math/big"
"reflect"
"strings"
"time"
@@ -662,10 +663,6 @@ func (statement *Statement) GenIndexSQL() []string {
return sqls
}
-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
@@ -693,6 +690,142 @@ func (statement *Statement) GenDelIndexSQL() []string {
return sqls
}
+func (statement *Statement) asDBCond(fieldValue reflect.Value, fieldType reflect.Type, col *schemas.Column, allUseBool, requiredField bool) (interface{}, bool, error) {
+ switch fieldType.Kind() {
+ case reflect.Ptr:
+ if fieldValue.IsNil() {
+ return nil, true, nil
+ }
+ return statement.asDBCond(fieldValue.Elem(), fieldType.Elem(), col, allUseBool, requiredField)
+ case reflect.Bool:
+ if allUseBool || requiredField {
+ return fieldValue.Interface(), true, nil
+ }
+ // if a bool in a struct, it will not be as a condition because it default is false,
+ // please use Where() instead
+ return nil, false, nil
+ case reflect.String:
+ if !requiredField && fieldValue.String() == "" {
+ return nil, false, nil
+ }
+ // for MyString, should convert to string or panic
+ if fieldType.String() != reflect.String.String() {
+ return fieldValue.String(), true, nil
+ }
+ return fieldValue.Interface(), true, nil
+ case reflect.Int8, reflect.Int16, reflect.Int, reflect.Int32, reflect.Int64:
+ if !requiredField && fieldValue.Int() == 0 {
+ return nil, false, nil
+ }
+ return fieldValue.Interface(), true, nil
+ case reflect.Float32, reflect.Float64:
+ if !requiredField && fieldValue.Float() == 0.0 {
+ return nil, false, nil
+ }
+ return fieldValue.Interface(), true, nil
+ case reflect.Uint8, reflect.Uint16, reflect.Uint, reflect.Uint32, reflect.Uint64:
+ if !requiredField && fieldValue.Uint() == 0 {
+ return nil, false, nil
+ }
+ return fieldValue.Interface(), true, nil
+ case reflect.Struct:
+ if fieldType.ConvertibleTo(schemas.TimeType) {
+ t := fieldValue.Convert(schemas.TimeType).Interface().(time.Time)
+ if !requiredField && (t.IsZero() || !fieldValue.IsValid()) {
+ return nil, false, nil
+ }
+ res, err := dialects.FormatColumnTime(statement.dialect, statement.defaultTimeZone, col, t)
+ if err != nil {
+ return nil, false, err
+ }
+ return res, true, nil
+ } else if fieldType.ConvertibleTo(schemas.BigFloatType) {
+ t := fieldValue.Convert(schemas.BigFloatType).Interface().(big.Float)
+ v := t.String()
+ if v == "0" {
+ return nil, false, nil
+ }
+ return t.String(), true, nil
+ } else if _, ok := reflect.New(fieldType).Interface().(convert.Conversion); ok {
+ return nil, false, nil
+ } else if valNul, ok := fieldValue.Interface().(driver.Valuer); ok {
+ val, _ := valNul.Value()
+ if val == nil && !requiredField {
+ return nil, false, nil
+ }
+ return val, true, nil
+ } else {
+ if col.IsJSON {
+ if col.SQLType.IsText() {
+ bytes, err := json.DefaultJSONHandler.Marshal(fieldValue.Interface())
+ if err != nil {
+ return nil, false, err
+ }
+ return string(bytes), true, nil
+ } else if col.SQLType.IsBlob() {
+ var bytes []byte
+ var err error
+ bytes, err = json.DefaultJSONHandler.Marshal(fieldValue.Interface())
+ if err != nil {
+ return nil, false, err
+ }
+ return bytes, true, nil
+ }
+ } else {
+ table, err := statement.tagParser.ParseWithCache(fieldValue)
+ if err != nil {
+ return fieldValue.Interface(), true, nil
+ }
+
+ if len(table.PrimaryKeys) == 1 {
+ pkField := reflect.Indirect(fieldValue).FieldByName(table.PKColumns()[0].FieldName)
+ // fix non-int pk issues
+ //if pkField.Int() != 0 {
+ if pkField.IsValid() && !utils.IsZero(pkField.Interface()) {
+ return pkField.Interface(), true, nil
+ }
+ return nil, false, nil
+ }
+ return nil, false, fmt.Errorf("not supported %v as %v", fieldValue.Interface(), table.PrimaryKeys)
+ }
+ }
+ case reflect.Array:
+ return nil, false, nil
+ case reflect.Slice, reflect.Map:
+ if fieldValue == reflect.Zero(fieldType) {
+ return nil, false, nil
+ }
+ if fieldValue.IsNil() || !fieldValue.IsValid() || fieldValue.Len() == 0 {
+ return nil, false, nil
+ }
+
+ if col.SQLType.IsText() {
+ bytes, err := json.DefaultJSONHandler.Marshal(fieldValue.Interface())
+ if err != nil {
+ return nil, false, err
+ }
+ return string(bytes), true, nil
+ } else if col.SQLType.IsBlob() {
+ var bytes []byte
+ var err error
+ if (fieldType.Kind() == reflect.Array || fieldType.Kind() == reflect.Slice) &&
+ fieldType.Elem().Kind() == reflect.Uint8 {
+ if fieldValue.Len() > 0 {
+ return fieldValue.Bytes(), true, nil
+ }
+ return nil, false, nil
+ }
+ bytes, err = json.DefaultJSONHandler.Marshal(fieldValue.Interface())
+ if err != nil {
+ return nil, false, err
+ }
+ return bytes, true, nil
+ }
+ return nil, false, nil
+ }
+ return fieldValue.Interface(), true, nil
+}
+
func (statement *Statement) buildConds2(table *schemas.Table, bean interface{},
includeVersion bool, includeUpdated bool, includeNil bool,
includeAutoIncr bool, allUseBool bool, useAllCols bool, unscoped bool,
@@ -747,9 +880,7 @@ func (statement *Statement) buildConds2(table *schemas.Table, bean interface{},
continue
}
- fieldType := reflect.TypeOf(fieldValue.Interface())
requiredField := useAllCols
-
if b, ok := getFlagForColumn(mustColumnMap, col); ok {
if b {
requiredField = true
@@ -758,6 +889,7 @@ func (statement *Statement) buildConds2(table *schemas.Table, bean interface{},
}
}
+ fieldType := reflect.TypeOf(fieldValue.Interface())
if fieldType.Kind() == reflect.Ptr {
if fieldValue.IsNil() {
if includeNil {
@@ -774,131 +906,12 @@ func (statement *Statement) buildConds2(table *schemas.Table, bean interface{},
}
}
- var val interface{}
- switch fieldType.Kind() {
- case reflect.Bool:
- if allUseBool || requiredField {
- val = fieldValue.Interface()
- } else {
- // if a bool in a struct, it will not be as a condition because it default is false,
- // please use Where() instead
- continue
- }
- case reflect.String:
- if !requiredField && fieldValue.String() == "" {
- continue
- }
- // for MyString, should convert to string or panic
- if fieldType.String() != reflect.String.String() {
- val = fieldValue.String()
- } else {
- val = fieldValue.Interface()
- }
- case reflect.Int8, reflect.Int16, reflect.Int, reflect.Int32, reflect.Int64:
- if !requiredField && fieldValue.Int() == 0 {
- continue
- }
- val = fieldValue.Interface()
- case reflect.Float32, reflect.Float64:
- if !requiredField && fieldValue.Float() == 0.0 {
- continue
- }
- val = fieldValue.Interface()
- case reflect.Uint8, reflect.Uint16, reflect.Uint, reflect.Uint32, reflect.Uint64:
- if !requiredField && fieldValue.Uint() == 0 {
- continue
- }
- val = fieldValue.Interface()
- case reflect.Struct:
- if fieldType.ConvertibleTo(schemas.TimeType) {
- t := fieldValue.Convert(schemas.TimeType).Interface().(time.Time)
- if !requiredField && (t.IsZero() || !fieldValue.IsValid()) {
- continue
- }
- val = dialects.FormatColumnTime(statement.dialect, statement.defaultTimeZone, col, t)
- } else if _, ok := reflect.New(fieldType).Interface().(convert.Conversion); ok {
- continue
- } else if valNul, ok := fieldValue.Interface().(driver.Valuer); ok {
- val, _ = valNul.Value()
- if val == nil && !requiredField {
- continue
- }
- } else {
- if col.IsJSON {
- if col.SQLType.IsText() {
- bytes, err := json.DefaultJSONHandler.Marshal(fieldValue.Interface())
- if err != nil {
- return nil, err
- }
- val = string(bytes)
- } else if col.SQLType.IsBlob() {
- var bytes []byte
- var err error
- bytes, err = json.DefaultJSONHandler.Marshal(fieldValue.Interface())
- if err != nil {
- return nil, err
- }
- val = bytes
- }
- } else {
- table, err := statement.tagParser.ParseWithCache(fieldValue)
- if err != nil {
- val = fieldValue.Interface()
- } else {
- if len(table.PrimaryKeys) == 1 {
- pkField := reflect.Indirect(fieldValue).FieldByName(table.PKColumns()[0].FieldName)
- // fix non-int pk issues
- //if pkField.Int() != 0 {
- if pkField.IsValid() && !utils.IsZero(pkField.Interface()) {
- val = pkField.Interface()
- } else {
- continue
- }
- } else {
- //TODO: how to handler?
- return nil, fmt.Errorf("not supported %v as %v", fieldValue.Interface(), table.PrimaryKeys)
- }
- }
- }
- }
- case reflect.Array:
+ val, ok, err := statement.asDBCond(fieldValue, fieldType, col, allUseBool, requiredField)
+ if err != nil {
+ return nil, err
+ }
+ if !ok {
continue
- case reflect.Slice, reflect.Map:
- if fieldValue == reflect.Zero(fieldType) {
- continue
- }
- if fieldValue.IsNil() || !fieldValue.IsValid() || fieldValue.Len() == 0 {
- continue
- }
-
- if col.SQLType.IsText() {
- bytes, err := json.DefaultJSONHandler.Marshal(fieldValue.Interface())
- if err != nil {
- return nil, err
- }
- val = string(bytes)
- } else if col.SQLType.IsBlob() {
- var bytes []byte
- var err error
- if (fieldType.Kind() == reflect.Array || fieldType.Kind() == reflect.Slice) &&
- fieldType.Elem().Kind() == reflect.Uint8 {
- if fieldValue.Len() > 0 {
- val = fieldValue.Bytes()
- } else {
- continue
- }
- } else {
- bytes, err = json.DefaultJSONHandler.Marshal(fieldValue.Interface())
- if err != nil {
- return nil, err
- }
- val = bytes
- }
- } else {
- continue
- }
- default:
- val = fieldValue.Interface()
}
conds = append(conds, builder.Eq{colName: val})
@@ -942,16 +955,29 @@ func (statement *Statement) quoteColumnStr(columnStr string) string {
// ConvertSQLOrArgs converts sql or args
func (statement *Statement) ConvertSQLOrArgs(sqlOrArgs ...interface{}) (string, []interface{}, error) {
- sql, args, err := convertSQLOrArgs(sqlOrArgs...)
+ sql, args, err := statement.convertSQLOrArgs(sqlOrArgs...)
if err != nil {
return "", nil, err
}
return statement.ReplaceQuote(sql), args, nil
}
-func convertSQLOrArgs(sqlOrArgs ...interface{}) (string, []interface{}, error) {
+func (statement *Statement) convertSQLOrArgs(sqlOrArgs ...interface{}) (string, []interface{}, error) {
switch sqlOrArgs[0].(type) {
case string:
+ if len(sqlOrArgs) > 1 {
+ var newArgs = make([]interface{}, 0, len(sqlOrArgs)-1)
+ for _, arg := range sqlOrArgs[1:] {
+ if v, ok := arg.(*time.Time); ok {
+ newArgs = append(newArgs, v.In(statement.defaultTimeZone).Format("2006-01-02 15:04:05"))
+ } else if v, ok := arg.(time.Time); ok {
+ newArgs = append(newArgs, v.In(statement.defaultTimeZone).Format("2006-01-02 15:04:05"))
+ } else {
+ newArgs = append(newArgs, arg)
+ }
+ }
+ return sqlOrArgs[0].(string), newArgs, nil
+ }
return sqlOrArgs[0].(string), sqlOrArgs[1:], nil
case *builder.Builder:
return sqlOrArgs[0].(*builder.Builder).ToSQL()
diff --git a/vendor/xorm.io/xorm/internal/statements/update.go b/vendor/xorm.io/xorm/internal/statements/update.go
index 06cf068929..40159e0c10 100644
--- a/vendor/xorm.io/xorm/internal/statements/update.go
+++ b/vendor/xorm.io/xorm/internal/statements/update.go
@@ -127,8 +127,12 @@ func (statement *Statement) BuildUpdates(tableValue reflect.Value,
if err != nil {
return nil, nil, err
}
-
- val = data
+ if data != nil {
+ val = data
+ if !col.SQLType.IsBlob() {
+ val = string(data)
+ }
+ }
goto APPEND
}
}
@@ -138,8 +142,12 @@ func (statement *Statement) BuildUpdates(tableValue reflect.Value,
if err != nil {
return nil, nil, err
}
-
- val = data
+ if data != nil {
+ val = data
+ if !col.SQLType.IsBlob() {
+ val = string(data)
+ }
+ }
goto APPEND
}
@@ -200,7 +208,10 @@ func (statement *Statement) BuildUpdates(tableValue reflect.Value,
if !requiredField && (t.IsZero() || !fieldValue.IsValid()) {
continue
}
- val = dialects.FormatColumnTime(statement.dialect, statement.defaultTimeZone, col, t)
+ val, err = dialects.FormatColumnTime(statement.dialect, statement.defaultTimeZone, col, t)
+ if err != nil {
+ return nil, nil, err
+ }
} else if nulType, ok := fieldValue.Interface().(driver.Valuer); ok {
val, _ = nulType.Value()
if val == nil && !requiredField {
diff --git a/vendor/xorm.io/xorm/internal/statements/values.go b/vendor/xorm.io/xorm/internal/statements/values.go
index 71327c5568..4c1360ed21 100644
--- a/vendor/xorm.io/xorm/internal/statements/values.go
+++ b/vendor/xorm.io/xorm/internal/statements/values.go
@@ -8,6 +8,7 @@ import (
"database/sql"
"database/sql/driver"
"fmt"
+ "math/big"
"reflect"
"time"
@@ -19,9 +20,10 @@ import (
var (
nullFloatType = reflect.TypeOf(sql.NullFloat64{})
+ bigFloatType = reflect.TypeOf(big.Float{})
)
-// Value2Interface convert a field value of a struct to interface for puting into database
+// Value2Interface convert a field value of a struct to interface for putting into database
func (statement *Statement) Value2Interface(col *schemas.Column, fieldValue reflect.Value) (interface{}, error) {
if fieldValue.CanAddr() {
if fieldConvert, ok := fieldValue.Addr().Interface().(convert.Conversion); ok {
@@ -29,6 +31,12 @@ func (statement *Statement) Value2Interface(col *schemas.Column, fieldValue refl
if err != nil {
return nil, err
}
+ if data == nil {
+ if col.Nullable {
+ return nil, nil
+ }
+ data = []byte{}
+ }
if col.SQLType.IsBlob() {
return data, nil
}
@@ -43,12 +51,15 @@ func (statement *Statement) Value2Interface(col *schemas.Column, fieldValue refl
if err != nil {
return nil, err
}
+ if data == nil {
+ if col.Nullable {
+ return nil, nil
+ }
+ data = []byte{}
+ }
if col.SQLType.IsBlob() {
return data, nil
}
- if nil == data {
- return nil, nil
- }
return string(data), nil
}
}
@@ -76,14 +87,17 @@ func (statement *Statement) Value2Interface(col *schemas.Column, fieldValue refl
case reflect.Struct:
if fieldType.ConvertibleTo(schemas.TimeType) {
t := fieldValue.Convert(schemas.TimeType).Interface().(time.Time)
- tf := dialects.FormatColumnTime(statement.dialect, statement.defaultTimeZone, col, t)
- return tf, nil
+ tf, err := dialects.FormatColumnTime(statement.dialect, statement.defaultTimeZone, col, t)
+ return tf, err
} else if fieldType.ConvertibleTo(nullFloatType) {
t := fieldValue.Convert(nullFloatType).Interface().(sql.NullFloat64)
if !t.Valid {
return nil, nil
}
return t.Float64, nil
+ } else if fieldType.ConvertibleTo(bigFloatType) {
+ t := fieldValue.Convert(bigFloatType).Interface().(big.Float)
+ return t.String(), nil
}
if !col.IsJSON {
diff --git a/vendor/xorm.io/xorm/internal/utils/strings.go b/vendor/xorm.io/xorm/internal/utils/strings.go
index 86469c0fb9..159e287609 100644
--- a/vendor/xorm.io/xorm/internal/utils/strings.go
+++ b/vendor/xorm.io/xorm/internal/utils/strings.go
@@ -13,7 +13,7 @@ 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
+// SplitNoCase split a string by a separator with no care of capitalize
func SplitNoCase(s, sep string) []string {
idx := IndexNoCase(s, sep)
if idx < 0 {
@@ -22,7 +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
+// SplitNNoCase split n by a separator with no care of capitalize
func SplitNNoCase(s, sep string, n int) []string {
idx := IndexNoCase(s, sep)
if idx < 0 {
diff --git a/vendor/xorm.io/xorm/names/mapper.go b/vendor/xorm.io/xorm/names/mapper.go
index b0ce8076a4..69f67171c3 100644
--- a/vendor/xorm.io/xorm/names/mapper.go
+++ b/vendor/xorm.io/xorm/names/mapper.go
@@ -79,7 +79,7 @@ func (m SameMapper) Table2Obj(t string) string {
return t
}
-// SnakeMapper implements IMapper and provides name transaltion between
+// SnakeMapper implements IMapper and provides name translation between
// struct and database table
type SnakeMapper struct {
}
diff --git a/vendor/xorm.io/xorm/rows.go b/vendor/xorm.io/xorm/rows.go
index a56ea1c9e6..8e7cc0759a 100644
--- a/vendor/xorm.io/xorm/rows.go
+++ b/vendor/xorm.io/xorm/rows.go
@@ -5,7 +5,6 @@
package xorm
import (
- "database/sql"
"errors"
"fmt"
"reflect"
@@ -17,10 +16,9 @@ import (
// Rows rows wrapper a rows to
type Rows struct {
- session *Session
- rows *core.Rows
- beanType reflect.Type
- lastError error
+ session *Session
+ rows *core.Rows
+ beanType reflect.Type
}
func newRows(session *Session, bean interface{}) (*Rows, error) {
@@ -62,15 +60,6 @@ func newRows(session *Session, bean interface{}) (*Rows, error) {
// !oinume! Add "<col> IS NULL" to WHERE whatever condiBean is given.
// See https://gitea.com/xorm/xorm/issues/179
if col := table.DeletedColumn(); col != nil && !session.statement.GetUnscoped() { // tag "deleted" is enabled
- var colName = session.engine.Quote(col.Name)
- if addedTableName {
- var nm = session.statement.TableName()
- if len(session.statement.TableAlias) > 0 {
- nm = session.statement.TableAlias
- }
- colName = session.engine.Quote(nm) + "." + colName
- }
-
autoCond = session.statement.CondDeleted(col)
}
}
@@ -86,7 +75,6 @@ func newRows(session *Session, bean interface{}) (*Rows, error) {
rows.rows, err = rows.session.queryRows(sqlStr, args...)
if err != nil {
- rows.lastError = err
rows.Close()
return nil, err
}
@@ -96,25 +84,18 @@ func newRows(session *Session, bean interface{}) (*Rows, error) {
// Next move cursor to next record, return false if end has reached
func (rows *Rows) Next() bool {
- if rows.lastError == nil && rows.rows != nil {
- hasNext := rows.rows.Next()
- if !hasNext {
- rows.lastError = sql.ErrNoRows
- }
- return hasNext
- }
- return false
+ return rows.rows.Next()
}
// Err returns the error, if any, that was encountered during iteration. Err may be called after an explicit or implicit Close.
func (rows *Rows) Err() error {
- return rows.lastError
+ return rows.rows.Err()
}
// Scan row record to bean properties
func (rows *Rows) Scan(bean interface{}) error {
- if rows.lastError != nil {
- return rows.lastError
+ if rows.Err() != nil {
+ return rows.Err()
}
if reflect.Indirect(reflect.ValueOf(bean)).Type() != rows.beanType {
@@ -129,8 +110,12 @@ func (rows *Rows) Scan(bean interface{}) error {
if err != nil {
return err
}
+ types, err := rows.rows.ColumnTypes()
+ if err != nil {
+ return err
+ }
- scanResults, err := rows.session.row2Slice(rows.rows, fields, bean)
+ scanResults, err := rows.session.row2Slice(rows.rows, fields, types, bean)
if err != nil {
return err
}
@@ -154,5 +139,5 @@ func (rows *Rows) Close() error {
return rows.rows.Close()
}
- return rows.lastError
+ return rows.Err()
}
diff --git a/vendor/xorm.io/xorm/scan.go b/vendor/xorm.io/xorm/scan.go
index e19037a058..56d3c9d650 100644
--- a/vendor/xorm.io/xorm/scan.go
+++ b/vendor/xorm.io/xorm/scan.go
@@ -6,10 +6,129 @@ package xorm
import (
"database/sql"
+ "fmt"
+ "math/big"
+ "reflect"
+ "time"
+ "xorm.io/xorm/convert"
"xorm.io/xorm/core"
+ "xorm.io/xorm/dialects"
+ "xorm.io/xorm/schemas"
)
+// genScanResultsByBeanNullabale generates scan result
+func genScanResultsByBeanNullable(bean interface{}) (interface{}, bool, error) {
+ switch t := bean.(type) {
+ case *interface{}:
+ return t, false, nil
+ case *sql.NullInt64, *sql.NullBool, *sql.NullFloat64, *sql.NullString, *sql.RawBytes:
+ return t, false, nil
+ case *time.Time:
+ return &sql.NullString{}, true, nil
+ case *sql.NullTime:
+ return &sql.NullString{}, true, nil
+ case *string:
+ return &sql.NullString{}, true, nil
+ case *int, *int8, *int16, *int32:
+ return &sql.NullInt32{}, true, nil
+ case *int64:
+ return &sql.NullInt64{}, true, nil
+ case *uint, *uint8, *uint16, *uint32:
+ return &convert.NullUint32{}, true, nil
+ case *uint64:
+ return &convert.NullUint64{}, true, nil
+ case *float32, *float64:
+ return &sql.NullFloat64{}, true, nil
+ case *bool:
+ return &sql.NullBool{}, true, nil
+ case sql.NullInt64, sql.NullBool, sql.NullFloat64, sql.NullString,
+ time.Time,
+ string,
+ int, int8, int16, int32, int64,
+ uint, uint8, uint16, uint32, uint64,
+ float32, float64,
+ bool:
+ return nil, false, fmt.Errorf("unsupported scan type: %t", t)
+ case convert.Conversion:
+ return &sql.RawBytes{}, true, nil
+ }
+
+ tp := reflect.TypeOf(bean).Elem()
+ switch tp.Kind() {
+ case reflect.String:
+ return &sql.NullString{}, true, nil
+ case reflect.Int64:
+ return &sql.NullInt64{}, true, nil
+ case reflect.Int32, reflect.Int, reflect.Int16, reflect.Int8:
+ return &sql.NullInt32{}, true, nil
+ case reflect.Uint64:
+ return &convert.NullUint64{}, true, nil
+ case reflect.Uint32, reflect.Uint, reflect.Uint16, reflect.Uint8:
+ return &convert.NullUint32{}, true, nil
+ default:
+ return nil, false, fmt.Errorf("unsupported type: %#v", bean)
+ }
+}
+
+func genScanResultsByBean(bean interface{}) (interface{}, bool, error) {
+ switch t := bean.(type) {
+ case *interface{}:
+ return t, false, nil
+ case *sql.NullInt64, *sql.NullBool, *sql.NullFloat64, *sql.NullString,
+ *sql.RawBytes,
+ *string,
+ *int, *int8, *int16, *int32, *int64,
+ *uint, *uint8, *uint16, *uint32, *uint64,
+ *float32, *float64,
+ *bool:
+ return t, false, nil
+ case *time.Time, *sql.NullTime:
+ return &sql.NullString{}, true, nil
+ case sql.NullInt64, sql.NullBool, sql.NullFloat64, sql.NullString,
+ time.Time,
+ string,
+ int, int8, int16, int32, int64,
+ uint, uint8, uint16, uint32, uint64,
+ bool:
+ return nil, false, fmt.Errorf("unsupported scan type: %t", t)
+ case convert.Conversion:
+ return &sql.RawBytes{}, true, nil
+ }
+
+ tp := reflect.TypeOf(bean).Elem()
+ switch tp.Kind() {
+ case reflect.String:
+ return new(string), true, nil
+ case reflect.Int64:
+ return new(int64), true, nil
+ case reflect.Int32:
+ return new(int32), true, nil
+ case reflect.Int:
+ return new(int32), true, nil
+ case reflect.Int16:
+ return new(int32), true, nil
+ case reflect.Int8:
+ return new(int32), true, nil
+ case reflect.Uint64:
+ return new(uint64), true, nil
+ case reflect.Uint32:
+ return new(uint32), true, nil
+ case reflect.Uint:
+ return new(uint), true, nil
+ case reflect.Uint16:
+ return new(uint16), true, nil
+ case reflect.Uint8:
+ return new(uint8), true, nil
+ case reflect.Float32:
+ return new(float32), true, nil
+ case reflect.Float64:
+ return new(float64), true, nil
+ default:
+ return nil, false, fmt.Errorf("unsupported type: %#v", bean)
+ }
+}
+
func (engine *Engine) row2mapStr(rows *core.Rows, types []*sql.ColumnType, fields []string) (map[string]string, error) {
var scanResults = make([]interface{}, len(fields))
for i := 0; i < len(fields); i++ {
@@ -22,14 +141,27 @@ func (engine *Engine) row2mapStr(rows *core.Rows, types []*sql.ColumnType, field
}
result := make(map[string]string, len(fields))
- for ii, key := range fields {
- s := scanResults[ii].(*sql.NullString)
- result[key] = s.String
+ for i, key := range fields {
+ s := scanResults[i].(*sql.NullString)
+ if s.String == "" {
+ result[key] = ""
+ continue
+ }
+
+ if schemas.TIME_TYPE == engine.dialect.ColumnTypeKind(types[i].DatabaseTypeName()) {
+ t, err := convert.String2Time(s.String, engine.DatabaseTZ, engine.TZLocation)
+ if err != nil {
+ return nil, err
+ }
+ result[key] = t.Format("2006-01-02 15:04:05")
+ } else {
+ result[key] = s.String
+ }
}
return result, nil
}
-func (engine *Engine) row2mapBytes(rows *core.Rows, types []*sql.ColumnType, fields []string) (map[string][]byte, error) {
+func row2mapBytes(rows *core.Rows, types []*sql.ColumnType, fields []string) (map[string][]byte, error) {
var scanResults = make([]interface{}, len(fields))
for i := 0; i < len(fields); i++ {
var s sql.NullString
@@ -48,20 +180,141 @@ func (engine *Engine) row2mapBytes(rows *core.Rows, types []*sql.ColumnType, fie
return result, nil
}
-func (engine *Engine) row2sliceStr(rows *core.Rows, types []*sql.ColumnType, fields []string) ([]string, error) {
- results := make([]string, 0, len(fields))
- var scanResults = make([]interface{}, len(fields))
- for i := 0; i < len(fields); i++ {
+func (engine *Engine) scanStringInterface(rows *core.Rows, fields []string, types []*sql.ColumnType) ([]interface{}, error) {
+ var scanResults = make([]interface{}, len(types))
+ for i := 0; i < len(types); i++ {
var s sql.NullString
scanResults[i] = &s
}
- if err := rows.Scan(scanResults...); err != nil {
+ if err := engine.scan(rows, fields, types, scanResults...); err != nil {
+ return nil, err
+ }
+ return scanResults, nil
+}
+
+// scan is a wrap of driver.Scan but will automatically change the input values according requirements
+func (engine *Engine) scan(rows *core.Rows, fields []string, types []*sql.ColumnType, vv ...interface{}) error {
+ var scanResults = make([]interface{}, 0, len(types))
+ var replaces = make([]bool, 0, len(types))
+ var err error
+ for _, v := range vv {
+ var replaced bool
+ var scanResult interface{}
+ switch t := v.(type) {
+ case *big.Float, *time.Time, *sql.NullTime:
+ scanResult = &sql.NullString{}
+ replaced = true
+ case sql.Scanner:
+ scanResult = t
+ case convert.Conversion:
+ scanResult = &sql.RawBytes{}
+ replaced = true
+ default:
+ nullable, ok := types[0].Nullable()
+ if !ok || nullable {
+ scanResult, replaced, err = genScanResultsByBeanNullable(v)
+ } else {
+ scanResult, replaced, err = genScanResultsByBean(v)
+ }
+ if err != nil {
+ return err
+ }
+ }
+
+ scanResults = append(scanResults, scanResult)
+ replaces = append(replaces, replaced)
+ }
+
+ if err = engine.driver.Scan(&dialects.ScanContext{
+ DBLocation: engine.DatabaseTZ,
+ UserLocation: engine.TZLocation,
+ }, rows, types, scanResults...); err != nil {
+ return err
+ }
+
+ for i, replaced := range replaces {
+ if replaced {
+ if err = convert.Assign(vv[i], scanResults[i], engine.DatabaseTZ, engine.TZLocation); err != nil {
+ return err
+ }
+ }
+ }
+
+ return nil
+}
+
+func (engine *Engine) scanInterfaces(rows *core.Rows, fields []string, types []*sql.ColumnType) ([]interface{}, error) {
+ var scanResultContainers = make([]interface{}, len(types))
+ for i := 0; i < len(types); i++ {
+ scanResult, err := engine.driver.GenScanResult(types[i].DatabaseTypeName())
+ if err != nil {
+ return nil, err
+ }
+ scanResultContainers[i] = scanResult
+ }
+ if err := engine.scan(rows, fields, types, scanResultContainers...); err != nil {
+ return nil, err
+ }
+ return scanResultContainers, nil
+}
+
+func (engine *Engine) row2sliceStr(rows *core.Rows, types []*sql.ColumnType, fields []string) ([]string, error) {
+ scanResults, err := engine.scanStringInterface(rows, fields, types)
+ if err != nil {
return nil, err
}
+ var results = make([]string, 0, len(fields))
for i := 0; i < len(fields); i++ {
results = append(results, scanResults[i].(*sql.NullString).String)
}
return results, nil
}
+
+func rows2maps(rows *core.Rows) (resultsSlice []map[string][]byte, err error) {
+ fields, err := rows.Columns()
+ if err != nil {
+ return nil, err
+ }
+ types, err := rows.ColumnTypes()
+ if err != nil {
+ return nil, err
+ }
+ for rows.Next() {
+ result, err := row2mapBytes(rows, types, fields)
+ if err != nil {
+ return nil, err
+ }
+ resultsSlice = append(resultsSlice, result)
+ }
+ if rows.Err() != nil {
+ return nil, rows.Err()
+ }
+
+ return resultsSlice, nil
+}
+
+func (engine *Engine) row2mapInterface(rows *core.Rows, types []*sql.ColumnType, fields []string) (map[string]interface{}, error) {
+ var resultsMap = make(map[string]interface{}, len(fields))
+ var scanResultContainers = make([]interface{}, len(fields))
+ for i := 0; i < len(fields); i++ {
+ scanResult, err := engine.driver.GenScanResult(types[i].DatabaseTypeName())
+ if err != nil {
+ return nil, err
+ }
+ scanResultContainers[i] = scanResult
+ }
+ if err := engine.scan(rows, fields, types, scanResultContainers...); err != nil {
+ return nil, err
+ }
+
+ for ii, key := range fields {
+ res, err := convert.Interface2Interface(engine.TZLocation, scanResultContainers[ii])
+ if err != nil {
+ return nil, err
+ }
+ resultsMap[key] = res
+ }
+ return resultsMap, nil
+}
diff --git a/vendor/xorm.io/xorm/schemas/type.go b/vendor/xorm.io/xorm/schemas/type.go
index fc02f015eb..cf73013419 100644
--- a/vendor/xorm.io/xorm/schemas/type.go
+++ b/vendor/xorm.io/xorm/schemas/type.go
@@ -5,8 +5,9 @@
package schemas
import (
+ "database/sql"
+ "math/big"
"reflect"
- "sort"
"strings"
"time"
)
@@ -38,6 +39,7 @@ const (
TIME_TYPE
NUMERIC_TYPE
ARRAY_TYPE
+ BOOL_TYPE
)
// IsType reutrns ture if the column type is the same as the parameter
@@ -63,6 +65,11 @@ func (s *SQLType) IsTime() bool {
return s.IsType(TIME_TYPE)
}
+// IsBool returns true if column is a boolean type
+func (s *SQLType) IsBool() bool {
+ return s.IsType(BOOL_TYPE)
+}
+
// IsNumeric returns true if column is a numeric type
func (s *SQLType) IsNumeric() bool {
return s.IsType(NUMERIC_TYPE)
@@ -85,16 +92,19 @@ func (s *SQLType) IsXML() bool {
// enumerates all the database column types
var (
- Bit = "BIT"
- UnsignedBit = "UNSIGNED BIT"
- TinyInt = "TINYINT"
- SmallInt = "SMALLINT"
- MediumInt = "MEDIUMINT"
- Int = "INT"
- UnsignedInt = "UNSIGNED INT"
- Integer = "INTEGER"
- BigInt = "BIGINT"
- UnsignedBigInt = "UNSIGNED BIGINT"
+ Bit = "BIT"
+ UnsignedBit = "UNSIGNED BIT"
+ TinyInt = "TINYINT"
+ UnsignedTinyInt = "UNSIGNED TINYINT"
+ SmallInt = "SMALLINT"
+ UnsignedSmallInt = "UNSIGNED SMALLINT"
+ MediumInt = "MEDIUMINT"
+ UnsignedMediumInt = "UNSIGNED MEDIUMINT"
+ Int = "INT"
+ UnsignedInt = "UNSIGNED INT"
+ Integer = "INTEGER"
+ BigInt = "BIGINT"
+ UnsignedBigInt = "UNSIGNED BIGINT"
Enum = "ENUM"
Set = "SET"
@@ -151,16 +161,19 @@ var (
Array = "ARRAY"
SqlTypes = map[string]int{
- 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,
+ Bit: NUMERIC_TYPE,
+ UnsignedBit: NUMERIC_TYPE,
+ TinyInt: NUMERIC_TYPE,
+ UnsignedTinyInt: NUMERIC_TYPE,
+ SmallInt: NUMERIC_TYPE,
+ UnsignedSmallInt: NUMERIC_TYPE,
+ MediumInt: NUMERIC_TYPE,
+ UnsignedMediumInt: NUMERIC_TYPE,
+ Int: NUMERIC_TYPE,
+ UnsignedInt: NUMERIC_TYPE,
+ Integer: NUMERIC_TYPE,
+ BigInt: NUMERIC_TYPE,
+ UnsignedBigInt: NUMERIC_TYPE,
Enum: TEXT_TYPE,
Set: TEXT_TYPE,
@@ -208,93 +221,50 @@ var (
Bytea: BLOB_TYPE,
UniqueIdentifier: BLOB_TYPE,
- Bool: NUMERIC_TYPE,
+ Bool: BOOL_TYPE,
+ Boolean: BOOL_TYPE,
Serial: NUMERIC_TYPE,
BigSerial: NUMERIC_TYPE,
+ "INT8": NUMERIC_TYPE,
+
Array: ARRAY_TYPE,
}
-
- intTypes = sort.StringSlice{"*int", "*int16", "*int32", "*int8"}
- uintTypes = sort.StringSlice{"*uint", "*uint16", "*uint32", "*uint8"}
-)
-
-// !nashtsai! treat following var as interal const values, these are used for reflect.TypeOf comparison
-var (
- 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(intDefault)
- Int8Type = reflect.TypeOf(int8Default)
- Int16Type = reflect.TypeOf(int16Default)
- Int32Type = reflect.TypeOf(int32Default)
- Int64Type = reflect.TypeOf(int64Default)
-
- UintType = reflect.TypeOf(uintDefault)
- Uint8Type = reflect.TypeOf(uint8Default)
- Uint16Type = reflect.TypeOf(uint16Default)
- Uint32Type = reflect.TypeOf(uint32Default)
- Uint64Type = reflect.TypeOf(uint64Default)
-
- Float32Type = reflect.TypeOf(float32Default)
- Float64Type = reflect.TypeOf(float64Default)
-
- Complex64Type = reflect.TypeOf(complex64Default)
- Complex128Type = reflect.TypeOf(complex128Default)
-
- StringType = reflect.TypeOf(emptyString)
- BoolType = reflect.TypeOf(boolDefault)
- ByteType = reflect.TypeOf(byteDefault)
+ IntType = reflect.TypeOf((*int)(nil)).Elem()
+ Int8Type = reflect.TypeOf((*int8)(nil)).Elem()
+ Int16Type = reflect.TypeOf((*int16)(nil)).Elem()
+ Int32Type = reflect.TypeOf((*int32)(nil)).Elem()
+ Int64Type = reflect.TypeOf((*int64)(nil)).Elem()
+
+ UintType = reflect.TypeOf((*uint)(nil)).Elem()
+ Uint8Type = reflect.TypeOf((*uint8)(nil)).Elem()
+ Uint16Type = reflect.TypeOf((*uint16)(nil)).Elem()
+ Uint32Type = reflect.TypeOf((*uint32)(nil)).Elem()
+ Uint64Type = reflect.TypeOf((*uint64)(nil)).Elem()
+
+ Float32Type = reflect.TypeOf((*float32)(nil)).Elem()
+ Float64Type = reflect.TypeOf((*float64)(nil)).Elem()
+
+ Complex64Type = reflect.TypeOf((*complex64)(nil)).Elem()
+ Complex128Type = reflect.TypeOf((*complex128)(nil)).Elem()
+
+ StringType = reflect.TypeOf((*string)(nil)).Elem()
+ BoolType = reflect.TypeOf((*bool)(nil)).Elem()
+ ByteType = reflect.TypeOf((*byte)(nil)).Elem()
BytesType = reflect.SliceOf(ByteType)
- TimeType = reflect.TypeOf(timeDefault)
-)
-
-// enumerates all types
-var (
- PtrIntType = reflect.PtrTo(IntType)
- PtrInt8Type = reflect.PtrTo(Int8Type)
- PtrInt16Type = reflect.PtrTo(Int16Type)
- PtrInt32Type = reflect.PtrTo(Int32Type)
- PtrInt64Type = reflect.PtrTo(Int64Type)
-
- PtrUintType = reflect.PtrTo(UintType)
- PtrUint8Type = reflect.PtrTo(Uint8Type)
- PtrUint16Type = reflect.PtrTo(Uint16Type)
- PtrUint32Type = reflect.PtrTo(Uint32Type)
- PtrUint64Type = reflect.PtrTo(Uint64Type)
-
- PtrFloat32Type = reflect.PtrTo(Float32Type)
- PtrFloat64Type = reflect.PtrTo(Float64Type)
-
- PtrComplex64Type = reflect.PtrTo(Complex64Type)
- PtrComplex128Type = reflect.PtrTo(Complex128Type)
-
- PtrStringType = reflect.PtrTo(StringType)
- PtrBoolType = reflect.PtrTo(BoolType)
- PtrByteType = reflect.PtrTo(ByteType)
-
- PtrTimeType = reflect.PtrTo(TimeType)
+ TimeType = reflect.TypeOf((*time.Time)(nil)).Elem()
+ BigFloatType = reflect.TypeOf((*big.Float)(nil)).Elem()
+ NullFloat64Type = reflect.TypeOf((*sql.NullFloat64)(nil)).Elem()
+ NullStringType = reflect.TypeOf((*sql.NullString)(nil)).Elem()
+ NullInt32Type = reflect.TypeOf((*sql.NullInt32)(nil)).Elem()
+ NullInt64Type = reflect.TypeOf((*sql.NullInt64)(nil)).Elem()
+ NullBoolType = reflect.TypeOf((*sql.NullBool)(nil)).Elem()
)
// Type2SQLType generate SQLType acorrding Go's type
@@ -315,7 +285,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(byteDefault) {
+ if t.Elem() == ByteType {
st = SQLType{Blob, 0, 0}
} else {
st = SQLType{Text, 0, 0}
@@ -327,6 +297,16 @@ func Type2SQLType(t reflect.Type) (st SQLType) {
case reflect.Struct:
if t.ConvertibleTo(TimeType) {
st = SQLType{DateTime, 0, 0}
+ } else if t.ConvertibleTo(NullFloat64Type) {
+ st = SQLType{Double, 0, 0}
+ } else if t.ConvertibleTo(NullStringType) {
+ st = SQLType{Varchar, 255, 0}
+ } else if t.ConvertibleTo(NullInt32Type) {
+ st = SQLType{Integer, 0, 0}
+ } else if t.ConvertibleTo(NullInt64Type) {
+ st = SQLType{BigInt, 0, 0}
+ } else if t.ConvertibleTo(NullBoolType) {
+ st = SQLType{Boolean, 0, 0}
} else {
// TODO need to handle association struct
st = SQLType{Text, 0, 0}
@@ -344,24 +324,30 @@ func SQLType2Type(st SQLType) reflect.Type {
name := strings.ToUpper(st.Name)
switch name {
case Bit, TinyInt, SmallInt, MediumInt, Int, Integer, Serial:
- return reflect.TypeOf(1)
+ return IntType
case BigInt, BigSerial:
- return reflect.TypeOf(int64(1))
+ return Int64Type
case Float, Real:
- return reflect.TypeOf(float32(1))
+ return Float32Type
case Double:
- return reflect.TypeOf(float64(1))
+ return Float64Type
case Char, NChar, Varchar, NVarchar, TinyText, Text, NText, MediumText, LongText, Enum, Set, Uuid, Clob, SysName:
- return reflect.TypeOf("")
+ return StringType
case TinyBlob, Blob, LongBlob, Bytea, Binary, MediumBlob, VarBinary, UniqueIdentifier:
- return reflect.TypeOf([]byte{})
+ return BytesType
case Bool:
- return reflect.TypeOf(true)
+ return BoolType
case DateTime, Date, Time, TimeStamp, TimeStampz, SmallDateTime, Year:
- return reflect.TypeOf(timeDefault)
+ return TimeType
case Decimal, Numeric, Money, SmallMoney:
- return reflect.TypeOf("")
+ return StringType
default:
- return reflect.TypeOf("")
+ return StringType
}
}
+
+// SQLTypeName returns sql type name
+func SQLTypeName(tp string) string {
+ fields := strings.Split(tp, "(")
+ return fields[0]
+}
diff --git a/vendor/xorm.io/xorm/session.go b/vendor/xorm.io/xorm/session.go
index 6df9e20d87..563dfaf235 100644
--- a/vendor/xorm.io/xorm/session.go
+++ b/vendor/xorm.io/xorm/session.go
@@ -15,8 +15,8 @@ import (
"hash/crc32"
"io"
"reflect"
+ "strconv"
"strings"
- "time"
"xorm.io/xorm/contexts"
"xorm.io/xorm/convert"
@@ -34,7 +34,7 @@ type ErrFieldIsNotExist struct {
}
func (e ErrFieldIsNotExist) Error() string {
- return fmt.Sprintf("field %s is not valid on table %s", e.FieldName, e.TableName)
+ return fmt.Sprintf("field %s is not exist on table %s", e.FieldName, e.TableName)
}
// ErrFieldIsNotValid is not valid
@@ -365,31 +365,30 @@ func (session *Session) doPrepare(db *core.DB, sqlStr string) (stmt *core.Stmt,
return
}
-func (session *Session) getField(dataStruct *reflect.Value, key string, table *schemas.Table, idx int) (*reflect.Value, error) {
- var col *schemas.Column
- if col = table.GetColumnIdx(key, idx); col == nil {
- return nil, ErrFieldIsNotExist{key, table.Name}
+func (session *Session) getField(dataStruct *reflect.Value, table *schemas.Table, colName string, idx int) (*schemas.Column, *reflect.Value, error) {
+ var col = table.GetColumnIdx(colName, idx)
+ if col == nil {
+ return nil, nil, ErrFieldIsNotExist{colName, table.Name}
}
fieldValue, err := col.ValueOfV(dataStruct)
if err != nil {
- return nil, err
+ return nil, nil, err
}
if fieldValue == nil {
- return nil, ErrFieldIsNotValid{key, table.Name}
+ return nil, nil, ErrFieldIsNotValid{colName, table.Name}
}
-
if !fieldValue.IsValid() || !fieldValue.CanSet() {
- return nil, ErrFieldIsNotValid{key, table.Name}
+ return nil, nil, ErrFieldIsNotValid{colName, table.Name}
}
- return fieldValue, nil
+ return col, fieldValue, nil
}
// Cell cell is a result of one column field
type Cell *interface{}
-func (session *Session) rows2Beans(rows *core.Rows, fields []string,
+func (session *Session) rows2Beans(rows *core.Rows, fields []string, types []*sql.ColumnType,
table *schemas.Table, newElemFunc func([]string) reflect.Value,
sliceValueSetFunc func(*reflect.Value, schemas.PK) error) error {
for rows.Next() {
@@ -398,7 +397,7 @@ func (session *Session) rows2Beans(rows *core.Rows, fields []string,
dataStruct := newValue.Elem()
// handle beforeClosures
- scanResults, err := session.row2Slice(rows, fields, bean)
+ scanResults, err := session.row2Slice(rows, fields, types, bean)
if err != nil {
return err
}
@@ -414,10 +413,10 @@ func (session *Session) rows2Beans(rows *core.Rows, fields []string,
bean: bean,
})
}
- return nil
+ return rows.Err()
}
-func (session *Session) row2Slice(rows *core.Rows, fields []string, bean interface{}) ([]interface{}, error) {
+func (session *Session) row2Slice(rows *core.Rows, fields []string, types []*sql.ColumnType, bean interface{}) ([]interface{}, error) {
for _, closure := range session.beforeClosures {
closure(bean)
}
@@ -427,7 +426,7 @@ func (session *Session) row2Slice(rows *core.Rows, fields []string, bean interfa
var cell interface{}
scanResults[i] = &cell
}
- if err := rows.Scan(scanResults...); err != nil {
+ if err := session.engine.scan(rows, fields, types, scanResults...); err != nil {
return nil, err
}
@@ -436,438 +435,263 @@ func (session *Session) row2Slice(rows *core.Rows, fields []string, bean interfa
return scanResults, nil
}
-func (session *Session) slice2Bean(scanResults []interface{}, fields []string, bean interface{}, dataStruct *reflect.Value, table *schemas.Table) (schemas.PK, error) {
- defer func() {
- executeAfterSet(bean, fields, scanResults)
- }()
-
- buildAfterProcessors(session, bean)
+func (session *Session) setJSON(fieldValue *reflect.Value, fieldType reflect.Type, scanResult interface{}) error {
+ bs, ok := convert.AsBytes(scanResult)
+ if !ok {
+ return fmt.Errorf("unsupported database data type: %#v", scanResult)
+ }
+ if len(bs) == 0 {
+ return nil
+ }
- var tempMap = make(map[string]int)
- var pk schemas.PK
- for ii, key := range fields {
- var idx int
- var ok bool
- var lKey = strings.ToLower(key)
- if idx, ok = tempMap[lKey]; !ok {
- idx = 0
- } else {
- idx = idx + 1
- }
- tempMap[lKey] = idx
+ if fieldType.Kind() == reflect.String {
+ fieldValue.SetString(string(bs))
+ return nil
+ }
- fieldValue, err := session.getField(dataStruct, key, table, idx)
+ if fieldValue.CanAddr() {
+ err := json.DefaultJSONHandler.Unmarshal(bs, fieldValue.Addr().Interface())
if err != nil {
- if !strings.Contains(err.Error(), "is not valid") {
- session.engine.logger.Warnf("%v", err)
- }
- continue
+ return err
}
- if fieldValue == nil {
- continue
+ } else {
+ x := reflect.New(fieldType)
+ err := json.DefaultJSONHandler.Unmarshal(bs, x.Interface())
+ if err != nil {
+ return err
}
- rawValue := reflect.Indirect(reflect.ValueOf(scanResults[ii]))
+ fieldValue.Set(x.Elem())
+ }
+ return nil
+}
- // if row is null then ignore
- if rawValue.Interface() == nil {
- continue
+func asKind(vv reflect.Value, tp reflect.Type) (interface{}, error) {
+ switch tp.Kind() {
+ case reflect.Ptr:
+ return asKind(vv.Elem(), tp.Elem())
+ case reflect.Int64:
+ return vv.Int(), nil
+ case reflect.Int:
+ return int(vv.Int()), nil
+ case reflect.Int32:
+ return int32(vv.Int()), nil
+ case reflect.Int16:
+ return int16(vv.Int()), nil
+ case reflect.Int8:
+ return int8(vv.Int()), nil
+ case reflect.Uint64:
+ return vv.Uint(), nil
+ case reflect.Uint:
+ return uint(vv.Uint()), nil
+ case reflect.Uint32:
+ return uint32(vv.Uint()), nil
+ case reflect.Uint16:
+ return uint16(vv.Uint()), nil
+ case reflect.Uint8:
+ return uint8(vv.Uint()), nil
+ case reflect.String:
+ return vv.String(), nil
+ case reflect.Slice:
+ if tp.Elem().Kind() == reflect.Uint8 {
+ v, err := strconv.ParseInt(string(vv.Interface().([]byte)), 10, 64)
+ if err != nil {
+ return nil, err
+ }
+ return v, nil
}
+ }
+ return nil, fmt.Errorf("unsupported primary key type: %v, %v", tp, vv)
+}
- if fieldValue.CanAddr() {
- if structConvert, ok := fieldValue.Addr().Interface().(convert.Conversion); ok {
- if data, err := value2Bytes(&rawValue); err == nil {
- if err := structConvert.FromDB(data); err != nil {
- return nil, err
- }
- } else {
- return nil, err
- }
- continue
+func (session *Session) convertBeanField(col *schemas.Column, fieldValue *reflect.Value,
+ scanResult interface{}, table *schemas.Table) error {
+ v, ok := scanResult.(*interface{})
+ if ok {
+ scanResult = *v
+ }
+ if scanResult == nil {
+ return nil
+ }
+
+ if fieldValue.CanAddr() {
+ if structConvert, ok := fieldValue.Addr().Interface().(convert.Conversion); ok {
+ data, ok := convert.AsBytes(scanResult)
+ if !ok {
+ return fmt.Errorf("cannot convert %#v as bytes", scanResult)
}
+ return structConvert.FromDB(data)
}
+ }
- if _, ok := fieldValue.Interface().(convert.Conversion); ok {
- if data, err := value2Bytes(&rawValue); err == nil {
- if fieldValue.Kind() == reflect.Ptr && fieldValue.IsNil() {
- fieldValue.Set(reflect.New(fieldValue.Type().Elem()))
- }
- fieldValue.Interface().(convert.Conversion).FromDB(data)
- } else {
- return nil, err
- }
- continue
+ if structConvert, ok := fieldValue.Interface().(convert.Conversion); ok {
+ data, ok := convert.AsBytes(scanResult)
+ if !ok {
+ return fmt.Errorf("cannot convert %#v as bytes", scanResult)
+ }
+ if data == nil {
+ return nil
}
- rawValueType := reflect.TypeOf(rawValue.Interface())
- vv := reflect.ValueOf(rawValue.Interface())
- col := table.GetColumnIdx(key, idx)
- if col.IsPrimaryKey {
- pk = append(pk, rawValue.Interface())
+ if fieldValue.Kind() == reflect.Ptr && fieldValue.IsNil() {
+ fieldValue.Set(reflect.New(fieldValue.Type().Elem()))
+ return fieldValue.Interface().(convert.Conversion).FromDB(data)
}
- fieldType := fieldValue.Type()
- hasAssigned := false
-
- if col.IsJSON {
- var bs []byte
- if rawValueType.Kind() == reflect.String {
- bs = []byte(vv.String())
- } else if rawValueType.ConvertibleTo(schemas.BytesType) {
- bs = vv.Bytes()
- } else {
- return nil, fmt.Errorf("unsupported database data type: %s %v", key, rawValueType.Kind())
- }
+ return structConvert.FromDB(data)
+ }
- hasAssigned = true
+ vv := reflect.ValueOf(scanResult)
+ fieldType := fieldValue.Type()
- if len(bs) > 0 {
- if fieldType.Kind() == reflect.String {
- fieldValue.SetString(string(bs))
- continue
+ if col.IsJSON {
+ return session.setJSON(fieldValue, fieldType, scanResult)
+ }
+
+ switch fieldType.Kind() {
+ case reflect.Ptr:
+ var e reflect.Value
+ if fieldValue.IsNil() {
+ e = reflect.New(fieldType.Elem()).Elem()
+ } else {
+ e = fieldValue.Elem()
+ }
+ if err := session.convertBeanField(col, &e, scanResult, table); err != nil {
+ return err
+ }
+ if fieldValue.IsNil() {
+ fieldValue.Set(e.Addr())
+ }
+ return nil
+ case reflect.Complex64, reflect.Complex128:
+ return session.setJSON(fieldValue, fieldType, scanResult)
+ case reflect.Slice, reflect.Array:
+ bs, ok := convert.AsBytes(scanResult)
+ if ok && fieldType.Elem().Kind() == reflect.Uint8 {
+ if col.SQLType.IsText() {
+ x := reflect.New(fieldType)
+ err := json.DefaultJSONHandler.Unmarshal(bs, x.Interface())
+ if err != nil {
+ return err
}
- if fieldValue.CanAddr() {
- err := json.DefaultJSONHandler.Unmarshal(bs, fieldValue.Addr().Interface())
- if err != nil {
- return nil, err
+ fieldValue.Set(x.Elem())
+ } else {
+ if fieldValue.Len() > 0 {
+ for i := 0; i < fieldValue.Len(); i++ {
+ if i < vv.Len() {
+ fieldValue.Index(i).Set(vv.Index(i))
+ }
}
} else {
- x := reflect.New(fieldType)
- err := json.DefaultJSONHandler.Unmarshal(bs, x.Interface())
- if err != nil {
- return nil, err
+ for i := 0; i < vv.Len(); i++ {
+ fieldValue.Set(reflect.Append(*fieldValue, vv.Index(i)))
}
- fieldValue.Set(x.Elem())
}
}
-
- continue
+ return nil
}
-
- switch fieldType.Kind() {
- case reflect.Complex64, reflect.Complex128:
- // TODO: reimplement this
- var bs []byte
- if rawValueType.Kind() == reflect.String {
- bs = []byte(vv.String())
- } else if rawValueType.ConvertibleTo(schemas.BytesType) {
- bs = vv.Bytes()
+ case reflect.Struct:
+ if fieldType.ConvertibleTo(schemas.BigFloatType) {
+ v, err := convert.AsBigFloat(scanResult)
+ if err != nil {
+ return err
}
+ fieldValue.Set(reflect.ValueOf(v).Elem().Convert(fieldType))
+ return nil
+ }
- hasAssigned = true
- if len(bs) > 0 {
- if fieldValue.CanAddr() {
- err := json.DefaultJSONHandler.Unmarshal(bs, fieldValue.Addr().Interface())
- if err != nil {
- return nil, err
- }
- } else {
- x := reflect.New(fieldType)
- err := json.DefaultJSONHandler.Unmarshal(bs, x.Interface())
- if err != nil {
- return nil, err
- }
- fieldValue.Set(x.Elem())
- }
- }
- case reflect.Slice, reflect.Array:
- switch rawValueType.Kind() {
- case reflect.Slice, reflect.Array:
- switch rawValueType.Elem().Kind() {
- case reflect.Uint8:
- if fieldType.Elem().Kind() == reflect.Uint8 {
- hasAssigned = true
- if col.SQLType.IsText() {
- x := reflect.New(fieldType)
- err := json.DefaultJSONHandler.Unmarshal(vv.Bytes(), x.Interface())
- if err != nil {
- return nil, err
- }
- fieldValue.Set(x.Elem())
- } else {
- if fieldValue.Len() > 0 {
- for i := 0; i < fieldValue.Len(); i++ {
- if i < vv.Len() {
- fieldValue.Index(i).Set(vv.Index(i))
- }
- }
- } else {
- for i := 0; i < vv.Len(); i++ {
- fieldValue.Set(reflect.Append(*fieldValue, vv.Index(i)))
- }
- }
- }
- }
- }
+ if fieldType.ConvertibleTo(schemas.TimeType) {
+ dbTZ := session.engine.DatabaseTZ
+ if col.TimeZone != nil {
+ dbTZ = col.TimeZone
}
- case reflect.String:
- if rawValueType.Kind() == reflect.String {
- hasAssigned = true
- fieldValue.SetString(vv.String())
+
+ t, err := convert.AsTime(scanResult, dbTZ, session.engine.TZLocation)
+ if err != nil {
+ return err
}
- case reflect.Bool:
- if rawValueType.Kind() == reflect.Bool {
- hasAssigned = true
- fieldValue.SetBool(vv.Bool())
+
+ fieldValue.Set(reflect.ValueOf(*t).Convert(fieldType))
+ return nil
+ } else if nulVal, ok := fieldValue.Addr().Interface().(sql.Scanner); ok {
+ err := nulVal.Scan(scanResult)
+ if err == nil {
+ return nil
}
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- switch rawValueType.Kind() {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- hasAssigned = true
- fieldValue.SetInt(vv.Int())
+ session.engine.logger.Errorf("sql.Sanner error: %v", err)
+ } else if session.statement.UseCascade {
+ table, err := session.engine.tagParser.ParseWithCache(*fieldValue)
+ if err != nil {
+ return err
}
- case reflect.Float32, reflect.Float64:
- switch rawValueType.Kind() {
- case reflect.Float32, reflect.Float64:
- hasAssigned = true
- fieldValue.SetFloat(vv.Float())
+
+ if len(table.PrimaryKeys) != 1 {
+ return errors.New("unsupported non or composited primary key cascade")
}
- case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
- switch rawValueType.Kind() {
- case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
- hasAssigned = true
- fieldValue.SetUint(vv.Uint())
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- hasAssigned = true
- fieldValue.SetUint(uint64(vv.Int()))
+ var pk = make(schemas.PK, len(table.PrimaryKeys))
+ pk[0], err = asKind(vv, reflect.TypeOf(scanResult))
+ if err != nil {
+ return err
}
- case reflect.Struct:
- if fieldType.ConvertibleTo(schemas.TimeType) {
- dbTZ := session.engine.DatabaseTZ
- if col.TimeZone != nil {
- dbTZ = col.TimeZone
- }
-
- if rawValueType == schemas.TimeType {
- hasAssigned = true
- t := vv.Convert(schemas.TimeType).Interface().(time.Time)
+ if !pk.IsZero() {
+ // !nashtsai! TODO for hasOne relationship, it's preferred to use join query for eager fetch
+ // however, also need to consider adding a 'lazy' attribute to xorm tag which allow hasOne
+ // property to be fetched lazily
+ structInter := reflect.New(fieldValue.Type())
+ has, err := session.ID(pk).NoCascade().get(structInter.Interface())
+ if err != nil {
+ return err
+ }
+ if has {
+ fieldValue.Set(structInter.Elem())
+ } else {
+ return errors.New("cascade obj is not exist")
+ }
+ }
+ return nil
+ }
+ } // switch fieldType.Kind()
- z, _ := t.Zone()
- // set new location if database don't save timezone or give an incorrect timezone
- if len(z) == 0 || t.Year() == 0 || t.Location().String() != dbTZ.String() { // !nashtsai! HACK tmp work around for lib/pq doesn't properly time with location
- session.engine.logger.Debugf("empty zone key[%v] : %v | zone: %v | location: %+v\n", key, t, z, *t.Location())
- t = time.Date(t.Year(), t.Month(), t.Day(), t.Hour(),
- t.Minute(), t.Second(), t.Nanosecond(), dbTZ)
- }
+ return convert.AssignValue(fieldValue.Addr(), scanResult)
+}
- t = t.In(session.engine.TZLocation)
- fieldValue.Set(reflect.ValueOf(t).Convert(fieldType))
- } else if rawValueType == schemas.IntType || rawValueType == schemas.Int64Type ||
- rawValueType == schemas.Int32Type {
- hasAssigned = true
+func (session *Session) slice2Bean(scanResults []interface{}, fields []string, bean interface{}, dataStruct *reflect.Value, table *schemas.Table) (schemas.PK, error) {
+ defer func() {
+ executeAfterSet(bean, fields, scanResults)
+ }()
- t := time.Unix(vv.Int(), 0).In(session.engine.TZLocation)
- fieldValue.Set(reflect.ValueOf(t).Convert(fieldType))
- } else {
- if d, ok := vv.Interface().([]uint8); ok {
- hasAssigned = true
- t, err := session.byte2Time(col, d)
- if err != nil {
- session.engine.logger.Errorf("byte2Time error: %v", err)
- hasAssigned = false
- } else {
- fieldValue.Set(reflect.ValueOf(t).Convert(fieldType))
- }
- } else if d, ok := vv.Interface().(string); ok {
- hasAssigned = true
- t, err := session.str2Time(col, d)
- if err != nil {
- session.engine.logger.Errorf("byte2Time error: %v", err)
- hasAssigned = false
- } else {
- fieldValue.Set(reflect.ValueOf(t).Convert(fieldType))
- }
- } else {
- return nil, fmt.Errorf("rawValueType is %v, value is %v", rawValueType, vv.Interface())
- }
- }
- } else if nulVal, ok := fieldValue.Addr().Interface().(sql.Scanner); ok {
- // !<winxxp>! 增加支持sql.Scanner接口的结构,如sql.NullString
- hasAssigned = true
- if err := nulVal.Scan(vv.Interface()); err != nil {
- session.engine.logger.Errorf("sql.Sanner error: %v", err)
- hasAssigned = false
- }
- } else if col.IsJSON {
- if rawValueType.Kind() == reflect.String {
- hasAssigned = true
- x := reflect.New(fieldType)
- if len([]byte(vv.String())) > 0 {
- err := json.DefaultJSONHandler.Unmarshal([]byte(vv.String()), x.Interface())
- if err != nil {
- return nil, err
- }
- fieldValue.Set(x.Elem())
- }
- } else if rawValueType.Kind() == reflect.Slice {
- hasAssigned = true
- x := reflect.New(fieldType)
- if len(vv.Bytes()) > 0 {
- err := json.DefaultJSONHandler.Unmarshal(vv.Bytes(), x.Interface())
- if err != nil {
- return nil, err
- }
- fieldValue.Set(x.Elem())
- }
- }
- } else if session.statement.UseCascade {
- table, err := session.engine.tagParser.ParseWithCache(*fieldValue)
- if err != nil {
- return nil, err
- }
+ buildAfterProcessors(session, bean)
- hasAssigned = true
- if len(table.PrimaryKeys) != 1 {
- return nil, errors.New("unsupported non or composited primary key cascade")
- }
- var pk = make(schemas.PK, len(table.PrimaryKeys))
- pk[0], err = asKind(vv, rawValueType)
- if err != nil {
- return nil, err
- }
+ var tempMap = make(map[string]int)
+ var pk schemas.PK
+ for i, colName := range fields {
+ var idx int
+ var lKey = strings.ToLower(colName)
+ var ok bool
- if !pk.IsZero() {
- // !nashtsai! TODO for hasOne relationship, it's preferred to use join query for eager fetch
- // however, also need to consider adding a 'lazy' attribute to xorm tag which allow hasOne
- // property to be fetched lazily
- structInter := reflect.New(fieldValue.Type())
- has, err := session.ID(pk).NoCascade().get(structInter.Interface())
- if err != nil {
- return nil, err
- }
- if has {
- fieldValue.Set(structInter.Elem())
- } else {
- return nil, errors.New("cascade obj is not exist")
- }
- }
- }
- case reflect.Ptr:
- // !nashtsai! TODO merge duplicated codes above
- switch fieldType {
- // following types case matching ptr's native type, therefore assign ptr directly
- case schemas.PtrStringType:
- if rawValueType.Kind() == reflect.String {
- x := vv.String()
- hasAssigned = true
- fieldValue.Set(reflect.ValueOf(&x))
- }
- case schemas.PtrBoolType:
- if rawValueType.Kind() == reflect.Bool {
- x := vv.Bool()
- hasAssigned = true
- fieldValue.Set(reflect.ValueOf(&x))
- }
- case schemas.PtrTimeType:
- if rawValueType == schemas.PtrTimeType {
- hasAssigned = true
- var x = rawValue.Interface().(time.Time)
- fieldValue.Set(reflect.ValueOf(&x))
- }
- case schemas.PtrFloat64Type:
- if rawValueType.Kind() == reflect.Float64 {
- x := vv.Float()
- hasAssigned = true
- fieldValue.Set(reflect.ValueOf(&x))
- }
- case schemas.PtrUint64Type:
- if rawValueType.Kind() == reflect.Int64 {
- var x = uint64(vv.Int())
- hasAssigned = true
- fieldValue.Set(reflect.ValueOf(&x))
- }
- case schemas.PtrInt64Type:
- if rawValueType.Kind() == reflect.Int64 {
- x := vv.Int()
- hasAssigned = true
- fieldValue.Set(reflect.ValueOf(&x))
- }
- case schemas.PtrFloat32Type:
- if rawValueType.Kind() == reflect.Float64 {
- var x = float32(vv.Float())
- hasAssigned = true
- fieldValue.Set(reflect.ValueOf(&x))
- }
- case schemas.PtrIntType:
- if rawValueType.Kind() == reflect.Int64 {
- var x = int(vv.Int())
- hasAssigned = true
- fieldValue.Set(reflect.ValueOf(&x))
- }
- case schemas.PtrInt32Type:
- if rawValueType.Kind() == reflect.Int64 {
- var x = int32(vv.Int())
- hasAssigned = true
- fieldValue.Set(reflect.ValueOf(&x))
- }
- case schemas.PtrInt8Type:
- if rawValueType.Kind() == reflect.Int64 {
- var x = int8(vv.Int())
- hasAssigned = true
- fieldValue.Set(reflect.ValueOf(&x))
- }
- case schemas.PtrInt16Type:
- if rawValueType.Kind() == reflect.Int64 {
- var x = int16(vv.Int())
- hasAssigned = true
- fieldValue.Set(reflect.ValueOf(&x))
- }
- case schemas.PtrUintType:
- if rawValueType.Kind() == reflect.Int64 {
- var x = uint(vv.Int())
- hasAssigned = true
- fieldValue.Set(reflect.ValueOf(&x))
- }
- case schemas.PtrUint32Type:
- if rawValueType.Kind() == reflect.Int64 {
- var x = uint32(vv.Int())
- hasAssigned = true
- fieldValue.Set(reflect.ValueOf(&x))
- }
- case schemas.Uint8Type:
- if rawValueType.Kind() == reflect.Int64 {
- var x = uint8(vv.Int())
- hasAssigned = true
- fieldValue.Set(reflect.ValueOf(&x))
- }
- case schemas.Uint16Type:
- if rawValueType.Kind() == reflect.Int64 {
- var x = uint16(vv.Int())
- hasAssigned = true
- fieldValue.Set(reflect.ValueOf(&x))
- }
- case schemas.Complex64Type:
- var x complex64
- if len([]byte(vv.String())) > 0 {
- err := json.DefaultJSONHandler.Unmarshal([]byte(vv.String()), &x)
- if err != nil {
- return nil, err
- }
- fieldValue.Set(reflect.ValueOf(&x))
- }
- hasAssigned = true
- case schemas.Complex128Type:
- var x complex128
- if len([]byte(vv.String())) > 0 {
- err := json.DefaultJSONHandler.Unmarshal([]byte(vv.String()), &x)
- if err != nil {
- return nil, err
- }
- fieldValue.Set(reflect.ValueOf(&x))
- }
- hasAssigned = true
- } // switch fieldType
- } // switch fieldType.Kind()
+ if idx, ok = tempMap[lKey]; !ok {
+ idx = 0
+ } else {
+ idx = idx + 1
+ }
+ tempMap[lKey] = idx
- // !nashtsai! for value can't be assigned directly fallback to convert to []byte then back to value
- if !hasAssigned {
- data, err := value2Bytes(&rawValue)
- if err != nil {
+ col, fieldValue, err := session.getField(dataStruct, table, colName, idx)
+ if err != nil {
+ if _, ok := err.(ErrFieldIsNotExist); ok {
+ continue
+ } else {
return nil, err
}
+ }
+ if fieldValue == nil {
+ continue
+ }
- if err = session.bytes2Value(col, fieldValue, data); err != nil {
- return nil, err
- }
+ if err := session.convertBeanField(col, fieldValue, scanResults[i], table); err != nil {
+ return nil, err
+ }
+ if col.IsPrimaryKey {
+ pk = append(pk, scanResults[i])
}
}
return pk, nil
diff --git a/vendor/xorm.io/xorm/session_convert.go b/vendor/xorm.io/xorm/session_convert.go
deleted file mode 100644
index b8218a7749..0000000000
--- a/vendor/xorm.io/xorm/session_convert.go
+++ /dev/null
@@ -1,521 +0,0 @@
-// Copyright 2017 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 xorm
-
-import (
- "database/sql"
- "errors"
- "fmt"
- "reflect"
- "strconv"
- "strings"
- "time"
-
- "xorm.io/xorm/convert"
- "xorm.io/xorm/internal/json"
- "xorm.io/xorm/internal/utils"
- "xorm.io/xorm/schemas"
-)
-
-func (session *Session) str2Time(col *schemas.Column, data string) (outTime time.Time, outErr error) {
- sdata := strings.TrimSpace(data)
- var x time.Time
- var err error
-
- var parseLoc = session.engine.DatabaseTZ
- if col.TimeZone != nil {
- parseLoc = col.TimeZone
- }
-
- if sdata == utils.ZeroTime0 || sdata == utils.ZeroTime1 {
- } else if !strings.ContainsAny(sdata, "- :") { // !nashtsai! has only found that mymysql driver is using this for time type column
- // time stamp
- sd, err := strconv.ParseInt(sdata, 10, 64)
- if err == nil {
- x = time.Unix(sd, 0)
- }
- } else if len(sdata) > 19 && strings.Contains(sdata, "-") {
- x, err = time.ParseInLocation(time.RFC3339Nano, sdata, parseLoc)
- session.engine.logger.Debugf("time(1) key[%v]: %+v | sdata: [%v]\n", col.Name, x, sdata)
- if err != nil {
- x, err = time.ParseInLocation("2006-01-02 15:04:05.999999999", sdata, parseLoc)
- }
- if err != nil {
- x, err = time.ParseInLocation("2006-01-02 15:04:05.9999999 Z07:00", sdata, parseLoc)
- }
- } else if len(sdata) == 19 && strings.Contains(sdata, "-") {
- x, err = time.ParseInLocation("2006-01-02 15:04:05", sdata, parseLoc)
- } else if len(sdata) == 10 && sdata[4] == '-' && sdata[7] == '-' {
- x, err = time.ParseInLocation("2006-01-02", sdata, parseLoc)
- } else if col.SQLType.Name == schemas.Time {
- if strings.Contains(sdata, " ") {
- ssd := strings.Split(sdata, " ")
- sdata = ssd[1]
- }
-
- sdata = strings.TrimSpace(sdata)
- if session.engine.dialect.URI().DBType == schemas.MYSQL && len(sdata) > 8 {
- sdata = sdata[len(sdata)-8:]
- }
-
- st := fmt.Sprintf("2006-01-02 %v", sdata)
- x, err = time.ParseInLocation("2006-01-02 15:04:05", st, parseLoc)
- } else {
- outErr = fmt.Errorf("unsupported time format %v", sdata)
- return
- }
- if err != nil {
- outErr = fmt.Errorf("unsupported time format %v: %v", sdata, err)
- return
- }
- outTime = x.In(session.engine.TZLocation)
- return
-}
-
-func (session *Session) byte2Time(col *schemas.Column, data []byte) (outTime time.Time, outErr error) {
- return session.str2Time(col, string(data))
-}
-
-// convert a db data([]byte) to a field value
-func (session *Session) bytes2Value(col *schemas.Column, fieldValue *reflect.Value, data []byte) error {
- if structConvert, ok := fieldValue.Addr().Interface().(convert.Conversion); ok {
- return structConvert.FromDB(data)
- }
-
- if structConvert, ok := fieldValue.Interface().(convert.Conversion); ok {
- return structConvert.FromDB(data)
- }
-
- var v interface{}
- key := col.Name
- fieldType := fieldValue.Type()
-
- switch fieldType.Kind() {
- case reflect.Complex64, reflect.Complex128:
- x := reflect.New(fieldType)
- if len(data) > 0 {
- err := json.DefaultJSONHandler.Unmarshal(data, x.Interface())
- if err != nil {
- return err
- }
- fieldValue.Set(x.Elem())
- }
- case reflect.Slice, reflect.Array, reflect.Map:
- v = data
- t := fieldType.Elem()
- k := t.Kind()
- if col.SQLType.IsText() {
- x := reflect.New(fieldType)
- if len(data) > 0 {
- err := json.DefaultJSONHandler.Unmarshal(data, x.Interface())
- if err != nil {
- return err
- }
- fieldValue.Set(x.Elem())
- }
- } else if col.SQLType.IsBlob() {
- if k == reflect.Uint8 {
- fieldValue.Set(reflect.ValueOf(v))
- } else {
- x := reflect.New(fieldType)
- if len(data) > 0 {
- err := json.DefaultJSONHandler.Unmarshal(data, x.Interface())
- if err != nil {
- return err
- }
- fieldValue.Set(x.Elem())
- }
- }
- } else {
- return ErrUnSupportedType
- }
- case reflect.String:
- fieldValue.SetString(string(data))
- case reflect.Bool:
- v, err := asBool(data)
- if err != nil {
- return fmt.Errorf("arg %v as bool: %s", key, err.Error())
- }
- fieldValue.Set(reflect.ValueOf(v))
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- sdata := string(data)
- var x int64
- var err error
- // for mysql, when use bit, it returned \x01
- if col.SQLType.Name == schemas.Bit &&
- session.engine.dialect.URI().DBType == schemas.MYSQL { // !nashtsai! TODO dialect needs to provide conversion interface API
- if len(data) == 1 {
- x = int64(data[0])
- } else {
- x = 0
- }
- } else if strings.HasPrefix(sdata, "0x") {
- x, err = strconv.ParseInt(sdata, 16, 64)
- } else if strings.HasPrefix(sdata, "0") {
- x, err = strconv.ParseInt(sdata, 8, 64)
- } else if strings.EqualFold(sdata, "true") {
- x = 1
- } else if strings.EqualFold(sdata, "false") {
- x = 0
- } else {
- x, err = strconv.ParseInt(sdata, 10, 64)
- }
- if err != nil {
- return fmt.Errorf("arg %v as int: %s", key, err.Error())
- }
- fieldValue.SetInt(x)
- case reflect.Float32, reflect.Float64:
- x, err := strconv.ParseFloat(string(data), 64)
- if err != nil {
- return fmt.Errorf("arg %v as float64: %s", key, err.Error())
- }
- fieldValue.SetFloat(x)
- case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
- x, err := strconv.ParseUint(string(data), 10, 64)
- if err != nil {
- return fmt.Errorf("arg %v as int: %s", key, err.Error())
- }
- fieldValue.SetUint(x)
- //Currently only support Time type
- case reflect.Struct:
- // !<winxxp>! 增加支持sql.Scanner接口的结构,如sql.NullString
- if nulVal, ok := fieldValue.Addr().Interface().(sql.Scanner); ok {
- if err := nulVal.Scan(data); err != nil {
- return fmt.Errorf("sql.Scan(%v) failed: %s ", data, err.Error())
- }
- } else {
- if fieldType.ConvertibleTo(schemas.TimeType) {
- x, err := session.byte2Time(col, data)
- if err != nil {
- return err
- }
- v = x
- fieldValue.Set(reflect.ValueOf(v).Convert(fieldType))
- } else if session.statement.UseCascade {
- table, err := session.engine.tagParser.ParseWithCache(*fieldValue)
- if err != nil {
- return err
- }
-
- // TODO: current only support 1 primary key
- if len(table.PrimaryKeys) > 1 {
- return errors.New("unsupported composited primary key cascade")
- }
-
- var pk = make(schemas.PK, len(table.PrimaryKeys))
- rawValueType := table.ColumnType(table.PKColumns()[0].FieldName)
- pk[0], err = str2PK(string(data), rawValueType)
- if err != nil {
- return err
- }
-
- if !pk.IsZero() {
- // !nashtsai! TODO for hasOne relationship, it's preferred to use join query for eager fetch
- // however, also need to consider adding a 'lazy' attribute to xorm tag which allow hasOne
- // property to be fetched lazily
- structInter := reflect.New(fieldValue.Type())
- has, err := session.ID(pk).NoCascade().get(structInter.Interface())
- if err != nil {
- return err
- }
- if has {
- v = structInter.Elem().Interface()
- fieldValue.Set(reflect.ValueOf(v))
- } else {
- return errors.New("cascade obj is not exist")
- }
- }
- }
- }
- case reflect.Ptr:
- // !nashtsai! TODO merge duplicated codes above
- //typeStr := fieldType.String()
- switch fieldType.Elem().Kind() {
- // case "*string":
- case schemas.StringType.Kind():
- x := string(data)
- fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
- // case "*bool":
- case schemas.BoolType.Kind():
- d := string(data)
- v, err := strconv.ParseBool(d)
- if err != nil {
- return fmt.Errorf("arg %v as bool: %s", key, err.Error())
- }
- fieldValue.Set(reflect.ValueOf(&v).Convert(fieldType))
- // case "*complex64":
- case schemas.Complex64Type.Kind():
- var x complex64
- if len(data) > 0 {
- err := json.DefaultJSONHandler.Unmarshal(data, &x)
- if err != nil {
- return err
- }
- fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
- }
- // case "*complex128":
- case schemas.Complex128Type.Kind():
- var x complex128
- if len(data) > 0 {
- err := json.DefaultJSONHandler.Unmarshal(data, &x)
- if err != nil {
- return err
- }
- fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
- }
- // case "*float64":
- case schemas.Float64Type.Kind():
- x, err := strconv.ParseFloat(string(data), 64)
- if err != nil {
- return fmt.Errorf("arg %v as float64: %s", key, err.Error())
- }
- fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
- // case "*float32":
- case schemas.Float32Type.Kind():
- var x float32
- x1, err := strconv.ParseFloat(string(data), 32)
- if err != nil {
- return fmt.Errorf("arg %v as float32: %s", key, err.Error())
- }
- x = float32(x1)
- fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
- // case "*uint64":
- case schemas.Uint64Type.Kind():
- var x uint64
- x, err := strconv.ParseUint(string(data), 10, 64)
- if err != nil {
- return fmt.Errorf("arg %v as int: %s", key, err.Error())
- }
- fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
- // case "*uint":
- case schemas.UintType.Kind():
- var x uint
- x1, err := strconv.ParseUint(string(data), 10, 64)
- if err != nil {
- return fmt.Errorf("arg %v as int: %s", key, err.Error())
- }
- x = uint(x1)
- fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
- // case "*uint32":
- case schemas.Uint32Type.Kind():
- var x uint32
- x1, err := strconv.ParseUint(string(data), 10, 64)
- if err != nil {
- return fmt.Errorf("arg %v as int: %s", key, err.Error())
- }
- x = uint32(x1)
- fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
- // case "*uint8":
- case schemas.Uint8Type.Kind():
- var x uint8
- x1, err := strconv.ParseUint(string(data), 10, 64)
- if err != nil {
- return fmt.Errorf("arg %v as int: %s", key, err.Error())
- }
- x = uint8(x1)
- fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
- // case "*uint16":
- case schemas.Uint16Type.Kind():
- var x uint16
- x1, err := strconv.ParseUint(string(data), 10, 64)
- if err != nil {
- return fmt.Errorf("arg %v as int: %s", key, err.Error())
- }
- x = uint16(x1)
- fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
- // case "*int64":
- case schemas.Int64Type.Kind():
- sdata := string(data)
- var x int64
- var err error
- // for mysql, when use bit, it returned \x01
- if col.SQLType.Name == schemas.Bit &&
- strings.Contains(session.engine.DriverName(), "mysql") {
- if len(data) == 1 {
- x = int64(data[0])
- } else {
- x = 0
- }
- } else if strings.HasPrefix(sdata, "0x") {
- x, err = strconv.ParseInt(sdata, 16, 64)
- } else if strings.HasPrefix(sdata, "0") {
- x, err = strconv.ParseInt(sdata, 8, 64)
- } else {
- x, err = strconv.ParseInt(sdata, 10, 64)
- }
- if err != nil {
- return fmt.Errorf("arg %v as int: %s", key, err.Error())
- }
- fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
- // case "*int":
- case schemas.IntType.Kind():
- sdata := string(data)
- var x int
- var x1 int64
- var err error
- // for mysql, when use bit, it returned \x01
- if col.SQLType.Name == schemas.Bit &&
- strings.Contains(session.engine.DriverName(), "mysql") {
- if len(data) == 1 {
- x = int(data[0])
- } else {
- x = 0
- }
- } else if strings.HasPrefix(sdata, "0x") {
- x1, err = strconv.ParseInt(sdata, 16, 64)
- x = int(x1)
- } else if strings.HasPrefix(sdata, "0") {
- x1, err = strconv.ParseInt(sdata, 8, 64)
- x = int(x1)
- } else {
- x1, err = strconv.ParseInt(sdata, 10, 64)
- x = int(x1)
- }
- if err != nil {
- return fmt.Errorf("arg %v as int: %s", key, err.Error())
- }
- fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
- // case "*int32":
- case schemas.Int32Type.Kind():
- sdata := string(data)
- var x int32
- var x1 int64
- var err error
- // for mysql, when use bit, it returned \x01
- if col.SQLType.Name == schemas.Bit &&
- session.engine.dialect.URI().DBType == schemas.MYSQL {
- if len(data) == 1 {
- x = int32(data[0])
- } else {
- x = 0
- }
- } else if strings.HasPrefix(sdata, "0x") {
- x1, err = strconv.ParseInt(sdata, 16, 64)
- x = int32(x1)
- } else if strings.HasPrefix(sdata, "0") {
- x1, err = strconv.ParseInt(sdata, 8, 64)
- x = int32(x1)
- } else {
- x1, err = strconv.ParseInt(sdata, 10, 64)
- x = int32(x1)
- }
- if err != nil {
- return fmt.Errorf("arg %v as int: %s", key, err.Error())
- }
- fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
- // case "*int8":
- case schemas.Int8Type.Kind():
- sdata := string(data)
- var x int8
- var x1 int64
- var err error
- // for mysql, when use bit, it returned \x01
- if col.SQLType.Name == schemas.Bit &&
- strings.Contains(session.engine.DriverName(), "mysql") {
- if len(data) == 1 {
- x = int8(data[0])
- } else {
- x = 0
- }
- } else if strings.HasPrefix(sdata, "0x") {
- x1, err = strconv.ParseInt(sdata, 16, 64)
- x = int8(x1)
- } else if strings.HasPrefix(sdata, "0") {
- x1, err = strconv.ParseInt(sdata, 8, 64)
- x = int8(x1)
- } else {
- x1, err = strconv.ParseInt(sdata, 10, 64)
- x = int8(x1)
- }
- if err != nil {
- return fmt.Errorf("arg %v as int: %s", key, err.Error())
- }
- fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
- // case "*int16":
- case schemas.Int16Type.Kind():
- sdata := string(data)
- var x int16
- var x1 int64
- var err error
- // for mysql, when use bit, it returned \x01
- if col.SQLType.Name == schemas.Bit &&
- strings.Contains(session.engine.DriverName(), "mysql") {
- if len(data) == 1 {
- x = int16(data[0])
- } else {
- x = 0
- }
- } else if strings.HasPrefix(sdata, "0x") {
- x1, err = strconv.ParseInt(sdata, 16, 64)
- x = int16(x1)
- } else if strings.HasPrefix(sdata, "0") {
- x1, err = strconv.ParseInt(sdata, 8, 64)
- x = int16(x1)
- } else {
- x1, err = strconv.ParseInt(sdata, 10, 64)
- x = int16(x1)
- }
- if err != nil {
- return fmt.Errorf("arg %v as int: %s", key, err.Error())
- }
- fieldValue.Set(reflect.ValueOf(&x).Convert(fieldType))
- // case "*SomeStruct":
- case reflect.Struct:
- switch fieldType {
- // case "*.time.Time":
- case schemas.PtrTimeType:
- x, err := session.byte2Time(col, data)
- if err != nil {
- return err
- }
- v = x
- fieldValue.Set(reflect.ValueOf(&x))
- default:
- if session.statement.UseCascade {
- structInter := reflect.New(fieldType.Elem())
- table, err := session.engine.tagParser.ParseWithCache(structInter.Elem())
- if err != nil {
- return err
- }
-
- if len(table.PrimaryKeys) > 1 {
- return errors.New("unsupported composited primary key cascade")
- }
-
- var pk = make(schemas.PK, len(table.PrimaryKeys))
- rawValueType := table.ColumnType(table.PKColumns()[0].FieldName)
- pk[0], err = str2PK(string(data), rawValueType)
- if err != nil {
- return err
- }
-
- if !pk.IsZero() {
- // !nashtsai! TODO for hasOne relationship, it's preferred to use join query for eager fetch
- // however, also need to consider adding a 'lazy' attribute to xorm tag which allow hasOne
- // property to be fetched lazily
- has, err := session.ID(pk).NoCascade().get(structInter.Interface())
- if err != nil {
- return err
- }
- if has {
- v = structInter.Interface()
- fieldValue.Set(reflect.ValueOf(v))
- } else {
- return errors.New("cascade obj is not exist")
- }
- }
- } else {
- return fmt.Errorf("unsupported struct type in Scan: %s", fieldValue.Type().String())
- }
- }
- default:
- return fmt.Errorf("unsupported type in Scan: %s", fieldValue.Type().String())
- }
- default:
- return fmt.Errorf("unsupported type in Scan: %s", fieldValue.Type().String())
- }
-
- return nil
-}
diff --git a/vendor/xorm.io/xorm/session_delete.go b/vendor/xorm.io/xorm/session_delete.go
index 13bf791fed..37b9c1cdaa 100644
--- a/vendor/xorm.io/xorm/session_delete.go
+++ b/vendor/xorm.io/xorm/session_delete.go
@@ -83,7 +83,7 @@ func (session *Session) cacheDelete(table *schemas.Table, tableName, sqlStr stri
}
// Delete records, bean's non-empty fields are conditions
-func (session *Session) Delete(bean interface{}) (int64, error) {
+func (session *Session) Delete(beans ...interface{}) (int64, error) {
if session.isAutoClose {
defer session.Close()
}
@@ -92,20 +92,32 @@ func (session *Session) Delete(bean interface{}) (int64, error) {
return 0, session.statement.LastError
}
- if err := session.statement.SetRefBean(bean); err != nil {
- return 0, err
- }
+ var (
+ condSQL string
+ condArgs []interface{}
+ err error
+ bean interface{}
+ )
+ if len(beans) > 0 {
+ bean = beans[0]
+ if err = session.statement.SetRefBean(bean); err != nil {
+ return 0, err
+ }
- executeBeforeClosures(session, bean)
+ executeBeforeClosures(session, bean)
- if processor, ok := interface{}(bean).(BeforeDeleteProcessor); ok {
- processor.BeforeDelete()
- }
+ if processor, ok := interface{}(bean).(BeforeDeleteProcessor); ok {
+ processor.BeforeDelete()
+ }
- condSQL, condArgs, err := session.statement.GenConds(bean)
+ condSQL, condArgs, err = session.statement.GenConds(bean)
+ } else {
+ condSQL, condArgs, err = session.statement.GenCondSQL(session.statement.Conds())
+ }
if err != nil {
return 0, err
}
+
pLimitN := session.statement.LimitN
if len(condSQL) == 0 && (pLimitN == nil || *pLimitN == 0) {
return 0, ErrNeedDeletedCond
@@ -156,7 +168,7 @@ func (session *Session) Delete(bean interface{}) (int64, error) {
var realSQL string
argsForCache := make([]interface{}, 0, len(condArgs)*2)
- if session.statement.GetUnscoped() || table.DeletedColumn() == nil { // tag "deleted" is disabled
+ if session.statement.GetUnscoped() || table == nil || table.DeletedColumn() == nil { // tag "deleted" is disabled
realSQL = deleteSQL
copy(argsForCache, condArgs)
argsForCache = append(condArgs, argsForCache...)
@@ -200,7 +212,10 @@ func (session *Session) Delete(bean interface{}) (int64, error) {
paramsLen := len(condArgs)
copy(condArgs[1:paramsLen], condArgs[0:paramsLen-1])
- val, t := session.engine.nowTime(deletedColumn)
+ val, t, err := session.engine.nowTime(deletedColumn)
+ if err != nil {
+ return 0, err
+ }
condArgs[0] = val
var colName = deletedColumn.Name
@@ -220,27 +235,29 @@ func (session *Session) Delete(bean interface{}) (int64, error) {
return 0, err
}
- // handle after delete processors
- if session.isAutoCommit {
- for _, closure := range session.afterClosures {
- closure(bean)
- }
- if processor, ok := interface{}(bean).(AfterDeleteProcessor); ok {
- processor.AfterDelete()
- }
- } else {
- lenAfterClosures := len(session.afterClosures)
- if lenAfterClosures > 0 {
- if value, has := session.afterDeleteBeans[bean]; has && value != nil {
- *value = append(*value, session.afterClosures...)
- } else {
- afterClosures := make([]func(interface{}), lenAfterClosures)
- copy(afterClosures, session.afterClosures)
- session.afterDeleteBeans[bean] = &afterClosures
+ if bean != nil {
+ // handle after delete processors
+ if session.isAutoCommit {
+ for _, closure := range session.afterClosures {
+ closure(bean)
+ }
+ if processor, ok := interface{}(bean).(AfterDeleteProcessor); ok {
+ processor.AfterDelete()
}
} else {
- if _, ok := interface{}(bean).(AfterDeleteProcessor); ok {
- session.afterDeleteBeans[bean] = nil
+ lenAfterClosures := len(session.afterClosures)
+ if lenAfterClosures > 0 && len(beans) > 0 {
+ if value, has := session.afterDeleteBeans[beans[0]]; has && value != nil {
+ *value = append(*value, session.afterClosures...)
+ } else {
+ afterClosures := make([]func(interface{}), lenAfterClosures)
+ copy(afterClosures, session.afterClosures)
+ session.afterDeleteBeans[bean] = &afterClosures
+ }
+ } else {
+ if _, ok := interface{}(bean).(AfterDeleteProcessor); ok {
+ session.afterDeleteBeans[bean] = nil
+ }
}
}
}
diff --git a/vendor/xorm.io/xorm/session_exist.go b/vendor/xorm.io/xorm/session_exist.go
index e52c618e71..b5e4a6551b 100644
--- a/vendor/xorm.io/xorm/session_exist.go
+++ b/vendor/xorm.io/xorm/session_exist.go
@@ -25,5 +25,8 @@ func (session *Session) Exist(bean ...interface{}) (bool, error) {
}
defer rows.Close()
- return rows.Next(), nil
+ if rows.Next() {
+ return true, nil
+ }
+ return false, rows.Err()
}
diff --git a/vendor/xorm.io/xorm/session_find.go b/vendor/xorm.io/xorm/session_find.go
index 0daea005dd..df3bd85da3 100644
--- a/vendor/xorm.io/xorm/session_find.go
+++ b/vendor/xorm.io/xorm/session_find.go
@@ -6,11 +6,11 @@ package xorm
import (
"errors"
- "fmt"
"reflect"
"xorm.io/builder"
"xorm.io/xorm/caches"
+ "xorm.io/xorm/convert"
"xorm.io/xorm/internal/statements"
"xorm.io/xorm/internal/utils"
"xorm.io/xorm/schemas"
@@ -172,6 +172,11 @@ func (session *Session) noCacheFind(table *schemas.Table, containerValue reflect
return err
}
+ types, err := rows.ColumnTypes()
+ if err != nil {
+ return err
+ }
+
var newElemFunc func(fields []string) reflect.Value
elemType := containerValue.Type().Elem()
var isPointer bool
@@ -241,7 +246,7 @@ func (session *Session) noCacheFind(table *schemas.Table, containerValue reflect
if err != nil {
return err
}
- err = session.rows2Beans(rows, fields, tb, newElemFunc, containerValueSetFunc)
+ err = session.rows2Beans(rows, fields, types, tb, newElemFunc, containerValueSetFunc)
rows.Close()
if err != nil {
return err
@@ -270,13 +275,13 @@ func (session *Session) noCacheFind(table *schemas.Table, containerValue reflect
return err
}
}
- return nil
+ return rows.Err()
}
func convertPKToValue(table *schemas.Table, dst interface{}, pk schemas.PK) error {
cols := table.PKColumns()
if len(cols) == 1 {
- return convertAssign(dst, pk[0])
+ return convert.Assign(dst, pk[0], nil, nil)
}
dst = pk
@@ -337,6 +342,9 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
ids = append(ids, pk)
}
+ if rows.Err() != nil {
+ return rows.Err()
+ }
session.engine.logger.Debugf("[cache] cache sql: %v, %v, %v, %v, %v", ids, tableName, sqlStr, newsql, args)
err = caches.PutCacheSql(cacher, ids, tableName, newsql, args)
@@ -468,12 +476,13 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
} else if sliceValue.Kind() == reflect.Map {
var key = ids[j]
keyType := sliceValue.Type().Key()
+ keyValue := reflect.New(keyType)
var ikey interface{}
if len(key) == 1 {
- ikey, err = str2PK(fmt.Sprintf("%v", key[0]), keyType)
- if err != nil {
+ if err := convert.AssignValue(keyValue, key[0]); err != nil {
return err
}
+ ikey = keyValue.Elem().Interface()
} else {
if keyType.Kind() != reflect.Slice {
return errors.New("table have multiple primary keys, key is not schemas.PK or slice")
diff --git a/vendor/xorm.io/xorm/session_get.go b/vendor/xorm.io/xorm/session_get.go
index e303176d16..0817252428 100644
--- a/vendor/xorm.io/xorm/session_get.go
+++ b/vendor/xorm.io/xorm/session_get.go
@@ -6,12 +6,17 @@ package xorm
import (
"database/sql"
+ "database/sql/driver"
"errors"
"fmt"
+ "math/big"
"reflect"
"strconv"
+ "time"
"xorm.io/xorm/caches"
+ "xorm.io/xorm/convert"
+ "xorm.io/xorm/core"
"xorm.io/xorm/internal/utils"
"xorm.io/xorm/schemas"
)
@@ -30,6 +35,19 @@ func (session *Session) Get(bean interface{}) (bool, error) {
return session.get(bean)
}
+func isPtrOfTime(v interface{}) bool {
+ if _, ok := v.(*time.Time); ok {
+ return true
+ }
+
+ el := reflect.ValueOf(v).Elem()
+ if el.Kind() != reflect.Struct {
+ return false
+ }
+
+ return el.Type().ConvertibleTo(schemas.TimeType)
+}
+
func (session *Session) get(bean interface{}) (bool, error) {
defer session.resetStatement()
@@ -46,7 +64,7 @@ func (session *Session) get(bean interface{}) (bool, error) {
return false, ErrObjectIsNil
}
- if beanValue.Elem().Kind() == reflect.Struct {
+ if beanValue.Elem().Kind() == reflect.Struct && !isPtrOfTime(bean) {
if err := session.statement.SetRefBean(bean); err != nil {
return false, err
}
@@ -108,6 +126,31 @@ func (session *Session) get(bean interface{}) (bool, error) {
return true, nil
}
+var (
+ valuerTypePlaceHolder driver.Valuer
+ valuerType = reflect.TypeOf(&valuerTypePlaceHolder).Elem()
+
+ scannerTypePlaceHolder sql.Scanner
+ scannerType = reflect.TypeOf(&scannerTypePlaceHolder).Elem()
+
+ conversionTypePlaceHolder convert.Conversion
+ conversionType = reflect.TypeOf(&conversionTypePlaceHolder).Elem()
+)
+
+func isScannableStruct(bean interface{}, typeLen int) bool {
+ switch bean.(type) {
+ case *time.Time:
+ return false
+ case sql.Scanner:
+ return false
+ case convert.Conversion:
+ return typeLen > 1
+ case *big.Float:
+ return false
+ }
+ return true
+}
+
func (session *Session) nocacheGet(beanKind reflect.Kind, table *schemas.Table, bean interface{}, sqlStr string, args ...interface{}) (bool, error) {
rows, err := session.queryRows(sqlStr, args...)
if err != nil {
@@ -116,161 +159,126 @@ func (session *Session) nocacheGet(beanKind reflect.Kind, table *schemas.Table,
defer rows.Close()
if !rows.Next() {
- if rows.Err() != nil {
- return false, rows.Err()
- }
- return false, nil
+ return false, rows.Err()
}
- switch bean.(type) {
- case sql.NullInt64, sql.NullBool, sql.NullFloat64, sql.NullString:
- return true, rows.Scan(&bean)
- case *sql.NullInt64, *sql.NullBool, *sql.NullFloat64, *sql.NullString:
- return true, rows.Scan(bean)
- case *string:
- var res sql.NullString
- if err := rows.Scan(&res); err != nil {
- return true, err
- }
- if res.Valid {
- *(bean.(*string)) = res.String
- }
- return true, nil
- case *int:
- var res sql.NullInt64
- if err := rows.Scan(&res); err != nil {
- return true, err
- }
- if res.Valid {
- *(bean.(*int)) = int(res.Int64)
- }
- return true, nil
- case *int8:
- var res sql.NullInt64
- if err := rows.Scan(&res); err != nil {
- return true, err
- }
- if res.Valid {
- *(bean.(*int8)) = int8(res.Int64)
- }
- return true, nil
- case *int16:
- var res sql.NullInt64
- if err := rows.Scan(&res); err != nil {
- return true, err
- }
- if res.Valid {
- *(bean.(*int16)) = int16(res.Int64)
- }
- return true, nil
- case *int32:
- var res sql.NullInt64
- if err := rows.Scan(&res); err != nil {
- return true, err
- }
- if res.Valid {
- *(bean.(*int32)) = int32(res.Int64)
- }
- return true, nil
- case *int64:
- var res sql.NullInt64
- if err := rows.Scan(&res); err != nil {
- return true, err
- }
- if res.Valid {
- *(bean.(*int64)) = int64(res.Int64)
- }
- return true, nil
- case *uint:
- var res sql.NullInt64
- if err := rows.Scan(&res); err != nil {
- return true, err
- }
- if res.Valid {
- *(bean.(*uint)) = uint(res.Int64)
- }
- return true, nil
- case *uint8:
- var res sql.NullInt64
- if err := rows.Scan(&res); err != nil {
- return true, err
- }
- if res.Valid {
- *(bean.(*uint8)) = uint8(res.Int64)
+ // WARN: Alougth rows return true, but we may also return error.
+ types, err := rows.ColumnTypes()
+ if err != nil {
+ return true, err
+ }
+ fields, err := rows.Columns()
+ if err != nil {
+ return true, err
+ }
+ switch beanKind {
+ case reflect.Struct:
+ if !isScannableStruct(bean, len(types)) {
+ break
}
- return true, nil
- case *uint16:
- var res sql.NullInt64
- if err := rows.Scan(&res); err != nil {
+ return session.getStruct(rows, types, fields, table, bean)
+ case reflect.Slice:
+ return session.getSlice(rows, types, fields, bean)
+ case reflect.Map:
+ return session.getMap(rows, types, fields, bean)
+ }
+
+ return session.getVars(rows, types, fields, bean)
+}
+
+func (session *Session) getSlice(rows *core.Rows, types []*sql.ColumnType, fields []string, bean interface{}) (bool, error) {
+ switch t := bean.(type) {
+ case *[]string:
+ res, err := session.engine.scanStringInterface(rows, fields, types)
+ if err != nil {
return true, err
}
- if res.Valid {
- *(bean.(*uint16)) = uint16(res.Int64)
+
+ var needAppend = len(*t) == 0 // both support slice is empty or has been initlized
+ for i, r := range res {
+ if needAppend {
+ *t = append(*t, r.(*sql.NullString).String)
+ } else {
+ (*t)[i] = r.(*sql.NullString).String
+ }
}
return true, nil
- case *uint32:
- var res sql.NullInt64
- if err := rows.Scan(&res); err != nil {
+ case *[]interface{}:
+ scanResults, err := session.engine.scanInterfaces(rows, fields, types)
+ if err != nil {
return true, err
}
- if res.Valid {
- *(bean.(*uint32)) = uint32(res.Int64)
+ var needAppend = len(*t) == 0
+ for ii := range fields {
+ s, err := convert.Interface2Interface(session.engine.DatabaseTZ, scanResults[ii])
+ if err != nil {
+ return true, err
+ }
+ if needAppend {
+ *t = append(*t, s)
+ } else {
+ (*t)[ii] = s
+ }
}
return true, nil
- case *uint64:
- var res sql.NullInt64
- if err := rows.Scan(&res); err != nil {
+ default:
+ return true, fmt.Errorf("unspoorted slice type: %t", t)
+ }
+}
+
+func (session *Session) getMap(rows *core.Rows, types []*sql.ColumnType, fields []string, bean interface{}) (bool, error) {
+ switch t := bean.(type) {
+ case *map[string]string:
+ scanResults, err := session.engine.scanStringInterface(rows, fields, types)
+ if err != nil {
return true, err
}
- if res.Valid {
- *(bean.(*uint64)) = uint64(res.Int64)
+ for ii, key := range fields {
+ (*t)[key] = scanResults[ii].(*sql.NullString).String
}
return true, nil
- case *bool:
- var res sql.NullBool
- if err := rows.Scan(&res); err != nil {
+ case *map[string]interface{}:
+ scanResults, err := session.engine.scanInterfaces(rows, fields, types)
+ if err != nil {
return true, err
}
- if res.Valid {
- *(bean.(*bool)) = res.Bool
+ for ii, key := range fields {
+ s, err := convert.Interface2Interface(session.engine.DatabaseTZ, scanResults[ii])
+ if err != nil {
+ return true, err
+ }
+ (*t)[key] = s
}
return true, nil
+ default:
+ return true, fmt.Errorf("unspoorted map type: %t", t)
}
+}
- switch beanKind {
- case reflect.Struct:
- fields, err := rows.Columns()
- if err != nil {
- // WARN: Alougth rows return true, but get fields failed
- return true, err
- }
+func (session *Session) getVars(rows *core.Rows, types []*sql.ColumnType, fields []string, beans ...interface{}) (bool, error) {
+ if len(beans) != len(types) {
+ return false, fmt.Errorf("expected columns %d, but only %d variables", len(types), len(beans))
+ }
- scanResults, err := session.row2Slice(rows, fields, bean)
- if err != nil {
- return false, err
- }
- // close it before convert data
- rows.Close()
+ err := session.engine.scan(rows, fields, types, beans...)
+ return true, err
+}
- dataStruct := utils.ReflectValue(bean)
- _, err = session.slice2Bean(scanResults, fields, bean, &dataStruct, table)
- if err != nil {
- return true, err
- }
+func (session *Session) getStruct(rows *core.Rows, types []*sql.ColumnType, fields []string, table *schemas.Table, bean interface{}) (bool, error) {
+ scanResults, err := session.row2Slice(rows, fields, types, bean)
+ if err != nil {
+ return false, err
+ }
+ // close it before convert data
+ rows.Close()
- return true, session.executeProcessors()
- case reflect.Slice:
- err = rows.ScanSlice(bean)
- case reflect.Map:
- err = rows.ScanMap(bean)
- case reflect.String, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
- reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- err = rows.Scan(bean)
- default:
- err = rows.Scan(bean)
+ dataStruct := utils.ReflectValue(bean)
+ _, err = session.slice2Bean(scanResults, fields, bean, &dataStruct, table)
+ if err != nil {
+ return true, err
}
- return true, err
+ return true, session.executeProcessors()
}
func (session *Session) cacheGet(bean interface{}, sqlStr string, args ...interface{}) (has bool, err error) {
@@ -304,9 +312,12 @@ func (session *Session) cacheGet(bean interface{}, sqlStr string, args ...interf
if rows.Next() {
err = rows.ScanSlice(&res)
if err != nil {
- return false, err
+ return true, err
}
} else {
+ if rows.Err() != nil {
+ return false, rows.Err()
+ }
return false, ErrCacheFailed
}
diff --git a/vendor/xorm.io/xorm/session_insert.go b/vendor/xorm.io/xorm/session_insert.go
index e733e06e06..a8f365c75b 100644
--- a/vendor/xorm.io/xorm/session_insert.go
+++ b/vendor/xorm.io/xorm/session_insert.go
@@ -9,16 +9,17 @@ import (
"fmt"
"reflect"
"sort"
- "strconv"
"strings"
"time"
+ "xorm.io/xorm/convert"
+ "xorm.io/xorm/dialects"
"xorm.io/xorm/internal/utils"
"xorm.io/xorm/schemas"
)
// ErrNoElementsOnSlice represents an error there is no element when insert
-var ErrNoElementsOnSlice = errors.New("No element on slice when insert")
+var ErrNoElementsOnSlice = errors.New("no element on slice when insert")
// Insert insert one or more beans
func (session *Session) Insert(beans ...interface{}) (int64, error) {
@@ -36,71 +37,42 @@ func (session *Session) Insert(beans ...interface{}) (int64, error) {
}()
for _, bean := range beans {
- switch bean.(type) {
+ var cnt int64
+ var err error
+ switch v := bean.(type) {
case map[string]interface{}:
- cnt, err := session.insertMapInterface(bean.(map[string]interface{}))
- if err != nil {
- return affected, err
- }
- affected += cnt
+ cnt, err = session.insertMapInterface(v)
case []map[string]interface{}:
- s := bean.([]map[string]interface{})
- for i := 0; i < len(s); i++ {
- cnt, err := session.insertMapInterface(s[i])
- if err != nil {
- return affected, err
- }
- affected += cnt
- }
+ cnt, err = session.insertMultipleMapInterface(v)
case map[string]string:
- cnt, err := session.insertMapString(bean.(map[string]string))
- if err != nil {
- return affected, err
- }
- affected += cnt
+ cnt, err = session.insertMapString(v)
case []map[string]string:
- s := bean.([]map[string]string)
- for i := 0; i < len(s); i++ {
- cnt, err := session.insertMapString(s[i])
- if err != nil {
- return affected, err
- }
- affected += cnt
- }
+ cnt, err = session.insertMultipleMapString(v)
default:
sliceValue := reflect.Indirect(reflect.ValueOf(bean))
if sliceValue.Kind() == reflect.Slice {
- size := sliceValue.Len()
- if size <= 0 {
- return 0, ErrNoElementsOnSlice
- }
-
- cnt, err := session.innerInsertMulti(bean)
- if err != nil {
- return affected, err
- }
- affected += cnt
+ cnt, err = session.insertMultipleStruct(bean)
} else {
- cnt, err := session.innerInsert(bean)
- if err != nil {
- return affected, err
- }
- affected += cnt
+ cnt, err = session.insertStruct(bean)
}
}
+ if err != nil {
+ return affected, err
+ }
+ affected += cnt
}
return affected, err
}
-func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error) {
+func (session *Session) insertMultipleStruct(rowsSlicePtr interface{}) (int64, error) {
sliceValue := reflect.Indirect(reflect.ValueOf(rowsSlicePtr))
if sliceValue.Kind() != reflect.Slice {
return 0, errors.New("needs a pointer to a slice")
}
if sliceValue.Len() <= 0 {
- return 0, errors.New("could not insert a empty slice")
+ return 0, ErrNoElementsOnSlice
}
if err := session.statement.SetRefBean(sliceValue.Index(0).Interface()); err != nil {
@@ -166,7 +138,10 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error
continue
}
if (col.IsCreated || col.IsUpdated) && session.statement.UseAutoTime {
- val, t := session.engine.nowTime(col)
+ val, t, err := session.engine.nowTime(col)
+ if err != nil {
+ return 0, err
+ }
args = append(args, val)
var colName = col.Name
@@ -269,14 +244,10 @@ func (session *Session) InsertMulti(rowsSlicePtr interface{}) (int64, error) {
return 0, ErrPtrSliceType
}
- if sliceValue.Len() <= 0 {
- return 0, ErrNoElementsOnSlice
- }
-
- return session.innerInsertMulti(rowsSlicePtr)
+ return session.insertMultipleStruct(rowsSlicePtr)
}
-func (session *Session) innerInsert(bean interface{}) (int64, error) {
+func (session *Session) insertStruct(bean interface{}) (int64, error) {
if err := session.statement.SetRefBean(bean); err != nil {
return 0, err
}
@@ -325,7 +296,6 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) {
copy(afterClosures, session.afterClosures)
session.afterInsertBeans[bean] = &afterClosures
}
-
} else {
if _, ok := interface{}(bean).(AfterInsertProcessor); ok {
session.afterInsertBeans[bean] = nil
@@ -335,54 +305,19 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) {
cleanupProcessorsClosures(&session.afterClosures) // cleanup after used
}
- // for postgres, many of them didn't implement lastInsertId, so we should
- // implemented it ourself.
- if session.engine.dialect.URI().DBType == schemas.ORACLE && len(table.AutoIncrement) > 0 {
- res, err := session.queryBytes("select seq_atable.currval from dual", args...)
- if err != nil {
- return 0, err
- }
-
- defer handleAfterInsertProcessorFunc(bean)
-
- session.cacheInsert(tableName)
-
- if table.Version != "" && session.statement.CheckVersion {
- verValue, err := table.VersionColumn().ValueOf(bean)
- if err != nil {
- session.engine.logger.Errorf("%v", err)
- } else if verValue.IsValid() && verValue.CanSet() {
- session.incrVersionFieldValue(verValue)
- }
- }
-
- if len(res) < 1 {
- return 0, errors.New("insert no error but not returned id")
- }
-
- idByte := res[0][table.AutoIncrement]
- id, err := strconv.ParseInt(string(idByte), 10, 64)
- if err != nil || id <= 0 {
- return 1, err
+ // if there is auto increment column and driver don't support return it
+ if len(table.AutoIncrement) > 0 && !session.engine.driver.Features().SupportReturnInsertedID {
+ var sql = sqlStr
+ if session.engine.dialect.URI().DBType == schemas.ORACLE {
+ sql = "select seq_atable.currval from dual"
}
- aiValue, err := table.AutoIncrColumn().ValueOf(bean)
- if err != nil {
- session.engine.logger.Errorf("%v", err)
- }
-
- if aiValue == nil || !aiValue.IsValid() || !aiValue.CanSet() {
- return 1, nil
- }
-
- return 1, convertAssignV(aiValue.Addr(), id)
- } else if len(table.AutoIncrement) > 0 && (session.engine.dialect.URI().DBType == schemas.POSTGRES ||
- session.engine.dialect.URI().DBType == schemas.MSSQL) {
- res, err := session.queryBytes(sqlStr, args...)
-
+ rows, err := session.queryRows(sql, args...)
if err != nil {
return 0, err
}
+ defer rows.Close()
+
defer handleAfterInsertProcessorFunc(bean)
session.cacheInsert(tableName)
@@ -396,16 +331,16 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) {
}
}
- if len(res) < 1 {
+ var id int64
+ if !rows.Next() {
+ if rows.Err() != nil {
+ return 0, rows.Err()
+ }
return 0, errors.New("insert successfully but not returned id")
}
-
- idByte := res[0][table.AutoIncrement]
- id, err := strconv.ParseInt(string(idByte), 10, 64)
- if err != nil || id <= 0 {
+ if err := rows.Scan(&id); err != nil {
return 1, err
}
-
aiValue, err := table.AutoIncrColumn().ValueOf(bean)
if err != nil {
session.engine.logger.Errorf("%v", err)
@@ -415,7 +350,7 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) {
return 1, nil
}
- return 1, convertAssignV(aiValue.Addr(), id)
+ return 1, convert.AssignValue(*aiValue, id)
}
res, err := session.exec(sqlStr, args...)
@@ -455,7 +390,7 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) {
return res.RowsAffected()
}
- if err := convertAssignV(aiValue.Addr(), id); err != nil {
+ if err := convert.AssignValue(*aiValue, id); err != nil {
return 0, err
}
@@ -470,7 +405,7 @@ func (session *Session) InsertOne(bean interface{}) (int64, error) {
defer session.Close()
}
- return session.innerInsert(bean)
+ return session.insertStruct(bean)
}
func (session *Session) cacheInsert(table string) error {
@@ -496,29 +431,12 @@ func (session *Session) genInsertColumns(bean interface{}) ([]string, []interfac
if col.MapType == schemas.ONLYFROMDB {
continue
}
-
- if col.IsDeleted {
- colNames = append(colNames, col.Name)
- if !col.Nullable {
- if col.SQLType.IsNumeric() {
- args = append(args, 0)
- } else {
- args = append(args, time.Time{}.Format("2006-01-02 15:04:05"))
- }
- } else {
- args = append(args, nil)
- }
- continue
- }
-
if session.statement.OmitColumnMap.Contain(col.Name) {
continue
}
-
if len(session.statement.ColumnMap) > 0 && !session.statement.ColumnMap.Contain(col.Name) {
continue
}
-
if session.statement.IncrColumns.IsColExist(col.Name) {
continue
} else if session.statement.DecrColumns.IsColExist(col.Name) {
@@ -527,6 +445,16 @@ func (session *Session) genInsertColumns(bean interface{}) ([]string, []interfac
continue
}
+ if col.IsDeleted {
+ arg, err := dialects.FormatColumnTime(session.engine.dialect, session.engine.DatabaseTZ, col, time.Time{})
+ if err != nil {
+ return nil, nil, err
+ }
+ args = append(args, arg)
+ colNames = append(colNames, col.Name)
+ continue
+ }
+
fieldValuePtr, err := col.ValueOf(bean)
if err != nil {
return nil, nil, err
@@ -547,7 +475,10 @@ func (session *Session) genInsertColumns(bean interface{}) ([]string, []interfac
if (col.IsCreated || col.IsUpdated) && session.statement.UseAutoTime /*&& isZero(fieldValue.Interface())*/ {
// if time is non-empty, then set to auto time
- val, t := session.engine.nowTime(col)
+ val, t, err := session.engine.nowTime(col)
+ if err != nil {
+ return nil, nil, err
+ }
args = append(args, val)
var colName = col.Name
@@ -597,6 +528,37 @@ func (session *Session) insertMapInterface(m map[string]interface{}) (int64, err
return session.insertMap(columns, args)
}
+func (session *Session) insertMultipleMapInterface(maps []map[string]interface{}) (int64, error) {
+ if len(maps) <= 0 {
+ return 0, ErrNoElementsOnSlice
+ }
+
+ tableName := session.statement.TableName()
+ if len(tableName) <= 0 {
+ return 0, ErrTableNotFound
+ }
+
+ var columns = make([]string, 0, len(maps[0]))
+ exprs := session.statement.ExprColumns
+ for k := range maps[0] {
+ if !exprs.IsColExist(k) {
+ columns = append(columns, k)
+ }
+ }
+ sort.Strings(columns)
+
+ var argss = make([][]interface{}, 0, len(maps))
+ for _, m := range maps {
+ var args = make([]interface{}, 0, len(m))
+ for _, colName := range columns {
+ args = append(args, m[colName])
+ }
+ argss = append(argss, args)
+ }
+
+ return session.insertMultipleMap(columns, argss)
+}
+
func (session *Session) insertMapString(m map[string]string) (int64, error) {
if len(m) == 0 {
return 0, ErrParamsType
@@ -625,6 +587,37 @@ func (session *Session) insertMapString(m map[string]string) (int64, error) {
return session.insertMap(columns, args)
}
+func (session *Session) insertMultipleMapString(maps []map[string]string) (int64, error) {
+ if len(maps) <= 0 {
+ return 0, ErrNoElementsOnSlice
+ }
+
+ tableName := session.statement.TableName()
+ if len(tableName) <= 0 {
+ return 0, ErrTableNotFound
+ }
+
+ var columns = make([]string, 0, len(maps[0]))
+ exprs := session.statement.ExprColumns
+ for k := range maps[0] {
+ if !exprs.IsColExist(k) {
+ columns = append(columns, k)
+ }
+ }
+ sort.Strings(columns)
+
+ var argss = make([][]interface{}, 0, len(maps))
+ for _, m := range maps {
+ var args = make([]interface{}, 0, len(m))
+ for _, colName := range columns {
+ args = append(args, m[colName])
+ }
+ argss = append(argss, args)
+ }
+
+ return session.insertMultipleMap(columns, argss)
+}
+
func (session *Session) insertMap(columns []string, args []interface{}) (int64, error) {
tableName := session.statement.TableName()
if len(tableName) <= 0 {
@@ -650,3 +643,29 @@ func (session *Session) insertMap(columns []string, args []interface{}) (int64,
}
return affected, nil
}
+
+func (session *Session) insertMultipleMap(columns []string, argss [][]interface{}) (int64, error) {
+ tableName := session.statement.TableName()
+ if len(tableName) <= 0 {
+ return 0, ErrTableNotFound
+ }
+
+ sql, args, err := session.statement.GenInsertMultipleMapSQL(columns, argss)
+ if err != nil {
+ return 0, err
+ }
+
+ if err := session.cacheInsert(tableName); err != nil {
+ return 0, err
+ }
+
+ res, err := session.exec(sql, args...)
+ if err != nil {
+ return 0, err
+ }
+ affected, err := res.RowsAffected()
+ if err != nil {
+ return 0, err
+ }
+ return affected, nil
+}
diff --git a/vendor/xorm.io/xorm/session_iterate.go b/vendor/xorm.io/xorm/session_iterate.go
index 8cab8f48f4..f6301009c0 100644
--- a/vendor/xorm.io/xorm/session_iterate.go
+++ b/vendor/xorm.io/xorm/session_iterate.go
@@ -54,7 +54,7 @@ func (session *Session) Iterate(bean interface{}, fun IterFunc) error {
}
i++
}
- return err
+ return rows.Err()
}
// BufferSize sets the buffersize for iterate
diff --git a/vendor/xorm.io/xorm/session_query.go b/vendor/xorm.io/xorm/session_query.go
index 379ad0e1c2..a4070985d5 100644
--- a/vendor/xorm.io/xorm/session_query.go
+++ b/vendor/xorm.io/xorm/session_query.go
@@ -5,13 +5,7 @@
package xorm
import (
- "fmt"
- "reflect"
- "strconv"
- "time"
-
"xorm.io/xorm/core"
- "xorm.io/xorm/schemas"
)
// Query runs a raw sql and return records as []map[string][]byte
@@ -28,53 +22,6 @@ func (session *Session) Query(sqlOrArgs ...interface{}) ([]map[string][]byte, er
return session.queryBytes(sqlStr, args...)
}
-func value2String(rawValue *reflect.Value) (str string, err error) {
- aa := reflect.TypeOf((*rawValue).Interface())
- vv := reflect.ValueOf((*rawValue).Interface())
- switch aa.Kind() {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- str = strconv.FormatInt(vv.Int(), 10)
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- str = strconv.FormatUint(vv.Uint(), 10)
- case reflect.Float32, reflect.Float64:
- str = strconv.FormatFloat(vv.Float(), 'f', -1, 64)
- case reflect.String:
- str = vv.String()
- case reflect.Array, reflect.Slice:
- switch aa.Elem().Kind() {
- case reflect.Uint8:
- data := rawValue.Interface().([]byte)
- str = string(data)
- if str == "\x00" {
- str = "0"
- }
- default:
- err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name())
- }
- // time type
- case reflect.Struct:
- if aa.ConvertibleTo(schemas.TimeType) {
- str = vv.Convert(schemas.TimeType).Interface().(time.Time).Format(time.RFC3339Nano)
- } else {
- err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name())
- }
- case reflect.Bool:
- str = strconv.FormatBool(vv.Bool())
- case reflect.Complex128, reflect.Complex64:
- str = fmt.Sprintf("%v", vv.Complex())
- /* TODO: unsupported types below
- case reflect.Map:
- case reflect.Ptr:
- case reflect.Uintptr:
- case reflect.UnsafePointer:
- case reflect.Chan, reflect.Func, reflect.Interface:
- */
- default:
- err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name())
- }
- return
-}
-
func (session *Session) rows2Strings(rows *core.Rows) (resultsSlice []map[string]string, err error) {
fields, err := rows.Columns()
if err != nil {
@@ -92,6 +39,9 @@ func (session *Session) rows2Strings(rows *core.Rows) (resultsSlice []map[string
}
resultsSlice = append(resultsSlice, result)
}
+ if rows.Err() != nil {
+ return nil, rows.Err()
+ }
return resultsSlice, nil
}
@@ -113,6 +63,9 @@ func (session *Session) rows2SliceString(rows *core.Rows) (resultsSlice [][]stri
}
resultsSlice = append(resultsSlice, record)
}
+ if rows.Err() != nil {
+ return nil, rows.Err()
+ }
return resultsSlice, nil
}
@@ -157,35 +110,25 @@ func (session *Session) QuerySliceString(sqlOrArgs ...interface{}) ([][]string,
return session.rows2SliceString(rows)
}
-func row2mapInterface(rows *core.Rows, fields []string) (resultsMap map[string]interface{}, err error) {
- resultsMap = make(map[string]interface{}, len(fields))
- scanResultContainers := make([]interface{}, len(fields))
- for i := 0; i < len(fields); i++ {
- var scanResultContainer interface{}
- scanResultContainers[i] = &scanResultContainer
- }
- if err := rows.Scan(scanResultContainers...); err != nil {
+func (session *Session) rows2Interfaces(rows *core.Rows) (resultsSlice []map[string]interface{}, err error) {
+ fields, err := rows.Columns()
+ if err != nil {
return nil, err
}
-
- for ii, key := range fields {
- resultsMap[key] = reflect.Indirect(reflect.ValueOf(scanResultContainers[ii])).Interface()
- }
- return
-}
-
-func rows2Interfaces(rows *core.Rows) (resultsSlice []map[string]interface{}, err error) {
- fields, err := rows.Columns()
+ types, err := rows.ColumnTypes()
if err != nil {
return nil, err
}
for rows.Next() {
- result, err := row2mapInterface(rows, fields)
+ result, err := session.engine.row2mapInterface(rows, types, fields)
if err != nil {
return nil, err
}
resultsSlice = append(resultsSlice, result)
}
+ if rows.Err() != nil {
+ return nil, rows.Err()
+ }
return resultsSlice, nil
}
@@ -207,5 +150,5 @@ func (session *Session) QueryInterface(sqlOrArgs ...interface{}) ([]map[string]i
}
defer rows.Close()
- return rows2Interfaces(rows)
+ return session.rows2Interfaces(rows)
}
diff --git a/vendor/xorm.io/xorm/session_raw.go b/vendor/xorm.io/xorm/session_raw.go
index d5c4520b97..2b48898873 100644
--- a/vendor/xorm.io/xorm/session_raw.go
+++ b/vendor/xorm.io/xorm/session_raw.go
@@ -6,7 +6,7 @@ package xorm
import (
"database/sql"
- "reflect"
+ "strings"
"xorm.io/xorm/core"
)
@@ -33,7 +33,7 @@ func (session *Session) queryRows(sqlStr string, args ...interface{}) (*core.Row
if session.isAutoCommit {
var db *core.DB
- if session.sessionType == groupSession {
+ if session.sessionType == groupSession && strings.EqualFold(sqlStr[:6], "select") {
db = session.engine.engineGroup.Slave().DB()
} else {
db = session.DB()
@@ -71,34 +71,6 @@ func (session *Session) queryRow(sqlStr string, args ...interface{}) *core.Row {
return core.NewRow(session.queryRows(sqlStr, args...))
}
-func value2Bytes(rawValue *reflect.Value) ([]byte, error) {
- str, err := value2String(rawValue)
- if err != nil {
- return nil, err
- }
- return []byte(str), nil
-}
-
-func (session *Session) rows2maps(rows *core.Rows) (resultsSlice []map[string][]byte, err error) {
- fields, err := rows.Columns()
- if err != nil {
- return nil, err
- }
- types, err := rows.ColumnTypes()
- if err != nil {
- return nil, err
- }
- for rows.Next() {
- result, err := session.engine.row2mapBytes(rows, types, fields)
- if err != nil {
- return nil, err
- }
- resultsSlice = append(resultsSlice, result)
- }
-
- return resultsSlice, nil
-}
-
func (session *Session) queryBytes(sqlStr string, args ...interface{}) ([]map[string][]byte, error) {
rows, err := session.queryRows(sqlStr, args...)
if err != nil {
@@ -106,7 +78,7 @@ func (session *Session) queryBytes(sqlStr string, args ...interface{}) ([]map[st
}
defer rows.Close()
- return session.rows2maps(rows)
+ return rows2maps(rows)
}
func (session *Session) exec(sqlStr string, args ...interface{}) (sql.Result, error) {
diff --git a/vendor/xorm.io/xorm/session_schema.go b/vendor/xorm.io/xorm/session_schema.go
index 7d36ae7f8d..2e64350f6b 100644
--- a/vendor/xorm.io/xorm/session_schema.go
+++ b/vendor/xorm.io/xorm/session_schema.go
@@ -336,8 +336,10 @@ func (session *Session) Sync2(beans ...interface{}) error {
}
} else {
if !(strings.HasPrefix(curType, expectedType) && curType[len(expectedType)] == '(') {
- engine.logger.Warnf("Table %s column %s db type is %s, struct type is %s",
- tbNameWithSchema, col.Name, curType, expectedType)
+ if !strings.EqualFold(schemas.SQLTypeName(curType), engine.dialect.Alias(schemas.SQLTypeName(expectedType))) {
+ engine.logger.Warnf("Table %s column %s db type is %s, struct type is %s",
+ tbNameWithSchema, col.Name, curType, expectedType)
+ }
}
}
} else if expectedType == schemas.Varchar {
@@ -467,7 +469,7 @@ func (session *Session) Import(r io.Reader) ([]sql.Result, error) {
startComment = false
}
} else {
- if i > 0 && data[i-1] == '-' && data[i] == '-' {
+ if !inSingleQuote && i > 0 && data[i-1] == '-' && data[i] == '-' {
startComment = true
continue
}
diff --git a/vendor/xorm.io/xorm/session_update.go b/vendor/xorm.io/xorm/session_update.go
index 78907e431d..7d91346e22 100644
--- a/vendor/xorm.io/xorm/session_update.go
+++ b/vendor/xorm.io/xorm/session_update.go
@@ -81,6 +81,9 @@ func (session *Session) cacheUpdate(table *schemas.Table, tableName, sqlStr stri
ids = append(ids, pk)
}
+ if rows.Err() != nil {
+ return rows.Err()
+ }
session.engine.logger.Debugf("[cache] find updated id: %v", ids)
} /*else {
session.engine.LogDebug("[xorm:cacheUpdate] del cached sql:", tableName, newsql, args)
@@ -212,7 +215,10 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
!session.statement.OmitColumnMap.Contain(table.Updated) {
colNames = append(colNames, session.engine.Quote(table.Updated)+" = ?")
col := table.UpdatedColumn()
- val, t := session.engine.nowTime(col)
+ val, t, err := session.engine.nowTime(col)
+ if err != nil {
+ return 0, err
+ }
if session.engine.dialect.URI().DBType == schemas.ORACLE {
args = append(args, t)
} else {
@@ -518,7 +524,10 @@ func (session *Session) genUpdateColumns(bean interface{}) ([]string, []interfac
if col.IsUpdated && session.statement.UseAutoTime /*&& isZero(fieldValue.Interface())*/ {
// if time is non-empty, then set to auto time
- val, t := session.engine.nowTime(col)
+ val, t, err := session.engine.nowTime(col)
+ if err != nil {
+ return nil, nil, err
+ }
args = append(args, val)
var colName = col.Name
diff --git a/vendor/xorm.io/xorm/tags/parser.go b/vendor/xorm.io/xorm/tags/parser.go
index b793a8f119..efee11e775 100644
--- a/vendor/xorm.io/xorm/tags/parser.go
+++ b/vendor/xorm.io/xorm/tags/parser.go
@@ -7,6 +7,7 @@ package tags
import (
"encoding/gob"
"errors"
+ "fmt"
"reflect"
"strings"
"sync"
@@ -124,8 +125,28 @@ func addIndex(indexName string, table *schemas.Table, col *schemas.Column, index
}
}
+// ErrIgnoreField represents an error to ignore field
var ErrIgnoreField = errors.New("field will be ignored")
+func (parser *Parser) getSQLTypeByType(t reflect.Type) (schemas.SQLType, error) {
+ if t.Kind() == reflect.Ptr {
+ t = t.Elem()
+ }
+ if t.Kind() == reflect.Struct {
+ v, ok := parser.tableCache.Load(t)
+ if ok {
+ pkCols := v.(*schemas.Table).PKColumns()
+ if len(pkCols) == 1 {
+ return pkCols[0].SQLType, nil
+ }
+ if len(pkCols) > 1 {
+ return schemas.SQLType{}, fmt.Errorf("unsupported mulitiple primary key on cascade")
+ }
+ }
+ }
+ return schemas.Type2SQLType(t), nil
+}
+
func (parser *Parser) parseFieldWithNoTag(fieldIndex int, field reflect.StructField, fieldValue reflect.Value) (*schemas.Column, error) {
var sqlType schemas.SQLType
if fieldValue.CanAddr() {
@@ -136,7 +157,11 @@ func (parser *Parser) parseFieldWithNoTag(fieldIndex int, field reflect.StructFi
if _, ok := fieldValue.Interface().(convert.Conversion); ok {
sqlType = schemas.SQLType{Name: schemas.Text}
} else {
- sqlType = schemas.Type2SQLType(field.Type)
+ var err error
+ sqlType, err = parser.getSQLTypeByType(field.Type)
+ if err != nil {
+ return nil, err
+ }
}
col := schemas.NewColumn(parser.columnMapper.Obj2Table(field.Name),
field.Name, sqlType, sqlType.DefaultLength,
@@ -214,8 +239,16 @@ func (parser *Parser) parseFieldWithTags(table *schemas.Table, fieldIndex int, f
}
if col.SQLType.Name == "" {
- col.SQLType = schemas.Type2SQLType(field.Type)
+ var err error
+ col.SQLType, err = parser.getSQLTypeByType(field.Type)
+ if err != nil {
+ return nil, err
+ }
+ }
+ if ctx.isUnsigned && col.SQLType.IsNumeric() && !strings.HasPrefix(col.SQLType.Name, "UNSIGNED") {
+ col.SQLType.Name = "UNSIGNED " + col.SQLType.Name
}
+
parser.dialect.SQLType(col)
if col.Length == 0 {
col.Length = col.SQLType.DefaultLength
@@ -241,6 +274,10 @@ func (parser *Parser) parseFieldWithTags(table *schemas.Table, fieldIndex int, f
}
func (parser *Parser) parseField(table *schemas.Table, fieldIndex int, field reflect.StructField, fieldValue reflect.Value) (*schemas.Column, error) {
+ if isNotTitle(field.Name) {
+ return nil, ErrIgnoreField
+ }
+
var (
tag = field.Tag
ormTagStr = strings.TrimSpace(tag.Get(parser.identifier))
@@ -281,12 +318,7 @@ func (parser *Parser) Parse(v reflect.Value) (*schemas.Table, error) {
table.Name = names.GetTableName(parser.tableMapper, v)
for i := 0; i < t.NumField(); i++ {
- var field = t.Field(i)
- if isNotTitle(field.Name) {
- continue
- }
-
- col, err := parser.parseField(table, i, field, v.Field(i))
+ col, err := parser.parseField(table, i, t.Field(i), v.Field(i))
if err == ErrIgnoreField {
continue
} else if err != nil {
@@ -296,11 +328,5 @@ func (parser *Parser) Parse(v reflect.Value) (*schemas.Table, error) {
table.AddColumn(col)
} // end for
- deletedColumn := table.DeletedColumn()
- // check columns
- if deletedColumn != nil {
- deletedColumn.Nullable = true
- }
-
return table, nil
}
diff --git a/vendor/xorm.io/xorm/tags/tag.go b/vendor/xorm.io/xorm/tags/tag.go
index 641b8c529a..4e1f1ce727 100644
--- a/vendor/xorm.io/xorm/tags/tag.go
+++ b/vendor/xorm.io/xorm/tags/tag.go
@@ -93,6 +93,7 @@ type Context struct {
hasCacheTag bool
hasNoCacheTag bool
ignoreNext bool
+ isUnsigned bool
}
// Handler describes tag handler for XORM
@@ -101,11 +102,12 @@ type Handler func(ctx *Context) error
var (
// defaultTagHandlers enumerates all the default tag handler
defaultTagHandlers = map[string]Handler{
+ "-": IgnoreHandler,
"<-": OnlyFromDBTagHandler,
"->": OnlyToDBTagHandler,
"PK": PKTagHandler,
"NULL": NULLTagHandler,
- "NOT": IgnoreTagHandler,
+ "NOT": NotTagHandler,
"AUTOINCR": AutoIncrTagHandler,
"DEFAULT": DefaultTagHandler,
"CREATED": CreatedTagHandler,
@@ -121,6 +123,7 @@ var (
"NOCACHE": NoCacheTagHandler,
"COMMENT": CommentTagHandler,
"EXTENDS": ExtendsTagHandler,
+ "UNSIGNED": UnsignedTagHandler,
}
)
@@ -130,11 +133,16 @@ func init() {
}
}
-// IgnoreTagHandler describes ignored tag handler
-func IgnoreTagHandler(ctx *Context) error {
+// NotTagHandler describes ignored tag handler
+func NotTagHandler(ctx *Context) error {
return nil
}
+// IgnoreHandler represetns the field should be ignored
+func IgnoreHandler(ctx *Context) error {
+ return ErrIgnoreField
+}
+
// OnlyFromDBTagHandler describes mapping direction tag handler
func OnlyFromDBTagHandler(ctx *Context) error {
ctx.col.MapType = schemas.ONLYFROMDB
@@ -262,6 +270,12 @@ func UniqueTagHandler(ctx *Context) error {
return nil
}
+// UnsignedTagHandler represents the column is unsigned
+func UnsignedTagHandler(ctx *Context) error {
+ ctx.isUnsigned = true
+ return nil
+}
+
// CommentTagHandler add comment to column
func CommentTagHandler(ctx *Context) error {
if len(ctx.params) > 0 {