@@ -114,5 +114,5 @@ require ( | |||
mvdan.cc/xurls/v2 v2.1.0 | |||
strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251 | |||
xorm.io/builder v0.3.7 | |||
xorm.io/xorm v1.0.4-0.20200718080127-318102c9ff87 | |||
xorm.io/xorm v1.0.4 | |||
) |
@@ -1227,5 +1227,5 @@ xorm.io/builder v0.3.7/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE= | |||
xorm.io/core v0.7.2 h1:mEO22A2Z7a3fPaZMk6gKL/jMD80iiyNwRrX5HOv3XLw= | |||
xorm.io/core v0.7.2/go.mod h1:jJfd0UAEzZ4t87nbQYtVjmqpIODugN6PD2D9E+dJvdM= | |||
xorm.io/xorm v0.8.0/go.mod h1:ZkJLEYLoVyg7amJK/5r779bHyzs2AU8f8VMiP6BM7uY= | |||
xorm.io/xorm v1.0.4-0.20200718080127-318102c9ff87 h1:vgc2F0wjD0cyrNrSKiIdWu123wuKkPQI84DZUKvJ6ns= | |||
xorm.io/xorm v1.0.4-0.20200718080127-318102c9ff87/go.mod h1:uF9EtbhODq5kNWxMbnBEj8hRRZnlcNSz2t2N7HW/+A4= | |||
xorm.io/xorm v1.0.4 h1:UBXA4I3NhiyjXfPqxXUkS2t5hMta9SSPATeMMaZg9oA= | |||
xorm.io/xorm v1.0.4/go.mod h1:uF9EtbhODq5kNWxMbnBEj8hRRZnlcNSz2t2N7HW/+A4= |
@@ -949,7 +949,7 @@ strk.kbt.io/projects/go/libravatar | |||
# xorm.io/builder v0.3.7 | |||
## explicit | |||
xorm.io/builder | |||
# xorm.io/xorm v1.0.4-0.20200718080127-318102c9ff87 | |||
# xorm.io/xorm v1.0.4 | |||
## explicit | |||
xorm.io/xorm | |||
xorm.io/xorm/caches |
@@ -10,6 +10,7 @@ steps: | |||
commands: | |||
- make vet | |||
- make test | |||
- make fmt-check | |||
when: | |||
event: | |||
- push | |||
@@ -109,6 +110,25 @@ steps: | |||
- push | |||
- pull_request | |||
- name: test-mariadb | |||
image: golang:1.12 | |||
environment: | |||
GO111MODULE: "on" | |||
GOPROXY: "https://goproxy.cn" | |||
TEST_MYSQL_HOST: mariadb | |||
TEST_MYSQL_CHARSET: utf8mb4 | |||
TEST_MYSQL_DBNAME: xorm_test | |||
TEST_MYSQL_USERNAME: root | |||
TEST_MYSQL_PASSWORD: | |||
commands: | |||
- make test-mysql | |||
- TEST_CACHE_ENABLE=true make test-mysql | |||
- TEST_QUOTE_POLICY=reserved make test-mysql | |||
when: | |||
event: | |||
- push | |||
- pull_request | |||
- name: test-postgres | |||
pull: default | |||
image: golang:1.12 | |||
@@ -258,6 +278,18 @@ services: | |||
- tag | |||
- pull_request | |||
- name: mariadb | |||
pull: default | |||
image: mariadb:10.4 | |||
environment: | |||
MYSQL_ALLOW_EMPTY_PASSWORD: yes | |||
MYSQL_DATABASE: xorm_test | |||
when: | |||
event: | |||
- push | |||
- tag | |||
- pull_request | |||
- name: pgsql | |||
pull: default | |||
image: postgres:9.5 |
@@ -313,7 +313,7 @@ err := engine.Where(builder.NotIn("a", 1, 2).And(builder.In("b", "c", "d", "e")) | |||
// SELECT id, name ... FROM user WHERE a NOT IN (?, ?) AND b IN (?, ?, ?) | |||
``` | |||
* Multiple operations in one go routine, no transation here but resue session memory | |||
* Multiple operations in one go routine, no transaction here but resue session memory | |||
```Go | |||
session := engine.NewSession() | |||
@@ -336,7 +336,7 @@ if _, err := session.Exec("delete from userinfo where username = ?", user2.Usern | |||
return nil | |||
``` | |||
* Transation should be on one go routine. There is transaction and resue session memory | |||
* Transaction should be on one go routine. There is transaction and resue session memory | |||
```Go | |||
session := engine.NewSession() |
@@ -307,9 +307,17 @@ func (db *mysql) AddColumnSQL(tableName string, col *schemas.Column) string { | |||
func (db *mysql) GetColumns(queryer core.Queryer, ctx context.Context, tableName string) ([]string, map[string]*schemas.Column, error) { | |||
args := []interface{}{db.uri.DBName, tableName} | |||
alreadyQuoted := "(INSTR(VERSION(), 'maria') > 0 && " + | |||
"(SUBSTRING_INDEX(VERSION(), '.', 1) > 10 || " + | |||
"(SUBSTRING_INDEX(VERSION(), '.', 1) = 10 && " + | |||
"(SUBSTRING_INDEX(SUBSTRING(VERSION(), 4), '.', 1) > 2 || " + | |||
"(SUBSTRING_INDEX(SUBSTRING(VERSION(), 4), '.', 1) = 2 && " + | |||
"SUBSTRING_INDEX(SUBSTRING(VERSION(), 6), '-', 1) >= 7)))))" | |||
s := "SELECT `COLUMN_NAME`, `IS_NULLABLE`, `COLUMN_DEFAULT`, `COLUMN_TYPE`," + | |||
" `COLUMN_KEY`, `EXTRA`,`COLUMN_COMMENT` FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_SCHEMA` = ? AND `TABLE_NAME` = ?" + | |||
" ORDER BY `INFORMATION_SCHEMA`.`COLUMNS`.ORDINAL_POSITION" | |||
" `COLUMN_KEY`, `EXTRA`, `COLUMN_COMMENT`, " + | |||
alreadyQuoted + " AS NEEDS_QUOTE " + | |||
"FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_SCHEMA` = ? AND `TABLE_NAME` = ?" + | |||
" ORDER BY `COLUMNS`.ORDINAL_POSITION" | |||
rows, err := queryer.QueryContext(ctx, s, args...) | |||
if err != nil { | |||
@@ -324,8 +332,9 @@ func (db *mysql) GetColumns(queryer core.Queryer, ctx context.Context, tableName | |||
col.Indexes = make(map[string]int) | |||
var columnName, isNullable, colType, colKey, extra, comment string | |||
var alreadyQuoted bool | |||
var colDefault *string | |||
err = rows.Scan(&columnName, &isNullable, &colDefault, &colType, &colKey, &extra, &comment) | |||
err = rows.Scan(&columnName, &isNullable, &colDefault, &colType, &colKey, &extra, &comment, &alreadyQuoted) | |||
if err != nil { | |||
return nil, nil, err | |||
} | |||
@@ -335,7 +344,7 @@ func (db *mysql) GetColumns(queryer core.Queryer, ctx context.Context, tableName | |||
col.Nullable = true | |||
} | |||
if colDefault != nil { | |||
if colDefault != nil && (!alreadyQuoted || *colDefault != "NULL") { | |||
col.Default = *colDefault | |||
col.DefaultIsEmpty = false | |||
} else { | |||
@@ -404,9 +413,9 @@ func (db *mysql) GetColumns(queryer core.Queryer, ctx context.Context, tableName | |||
} | |||
if !col.DefaultIsEmpty { | |||
if col.SQLType.IsText() { | |||
if !alreadyQuoted && col.SQLType.IsText() { | |||
col.Default = "'" + col.Default + "'" | |||
} else if col.SQLType.IsTime() && col.Default != "CURRENT_TIMESTAMP" { | |||
} else if col.SQLType.IsTime() && !alreadyQuoted && col.Default != "CURRENT_TIMESTAMP" { | |||
col.Default = "'" + col.Default + "'" | |||
} | |||
} |
@@ -27,4 +27,3 @@ func SplitNNoCase(s, sep string, n int) []string { | |||
} | |||
return strings.SplitN(s, s[idx:idx+len(sep)], n) | |||
} | |||
@@ -102,7 +102,7 @@ func newSessionID() string { | |||
func newSession(engine *Engine) *Session { | |||
var ctx context.Context | |||
if engine.logSessionID { | |||
ctx = context.WithValue(engine.defaultContext, log.SessionIDKey, newSessionID()) | |||
ctx = context.WithValue(engine.defaultContext, log.SessionIDKey, newSessionID()) | |||
} else { | |||
ctx = engine.defaultContext | |||
} |
@@ -4,12 +4,6 @@ | |||
package xorm | |||
import ( | |||
"time" | |||
"xorm.io/xorm/log" | |||
) | |||
// Begin a transaction | |||
func (session *Session) Begin() error { | |||
if session.isAutoCommit { | |||
@@ -33,24 +27,7 @@ func (session *Session) Rollback() error { | |||
session.isCommitedOrRollbacked = true | |||
session.isAutoCommit = true | |||
start := time.Now() | |||
needSQL := session.DB().NeedLogSQL(session.ctx) | |||
if needSQL { | |||
session.engine.logger.BeforeSQL(log.LogContext{ | |||
Ctx: session.ctx, | |||
SQL: "ROLL BACK", | |||
}) | |||
} | |||
err := session.tx.Rollback() | |||
if needSQL { | |||
session.engine.logger.AfterSQL(log.LogContext{ | |||
Ctx: session.ctx, | |||
SQL: "ROLL BACK", | |||
ExecuteTime: time.Now().Sub(start), | |||
Err: err, | |||
}) | |||
} | |||
return err | |||
return session.tx.Rollback() | |||
} | |||
return nil | |||
} | |||
@@ -62,25 +39,7 @@ func (session *Session) Commit() error { | |||
session.isCommitedOrRollbacked = true | |||
session.isAutoCommit = true | |||
start := time.Now() | |||
needSQL := session.DB().NeedLogSQL(session.ctx) | |||
if needSQL { | |||
session.engine.logger.BeforeSQL(log.LogContext{ | |||
Ctx: session.ctx, | |||
SQL: "COMMIT", | |||
}) | |||
} | |||
err := session.tx.Commit() | |||
if needSQL { | |||
session.engine.logger.AfterSQL(log.LogContext{ | |||
Ctx: session.ctx, | |||
SQL: "COMMIT", | |||
ExecuteTime: time.Now().Sub(start), | |||
Err: err, | |||
}) | |||
} | |||
if err != nil { | |||
if err := session.tx.Commit(); err != nil { | |||
return err | |||
} | |||