Add dameng support #2007

Merged
lunny merged 59 commits from lunny/dm into master 2021-08-24 05:46:09 +00:00
47 changed files with 1852 additions and 398 deletions

View File

@ -363,6 +363,41 @@ services:
commands: commands:
- /cockroach/cockroach start --insecure - /cockroach/cockroach start --insecure
# ---
# kind: pipeline
# name: test-dameng
# depends_on:
# - test-cockroach
# trigger:
# ref:
# - refs/heads/master
# - refs/pull/*/head
# steps:
# - name: test-dameng
# pull: never
# image: golang:1.15
# volumes:
# - name: cache
# path: /go/pkg/mod
# environment:
# TEST_DAMENG_HOST: "dameng:5236"
# TEST_DAMENG_USERNAME: SYSDBA
# TEST_DAMENG_PASSWORD: SYSDBA
# commands:
# - sleep 30
# - make test-dameng
# volumes:
# - name: cache
# host:
# path: /tmp/cache
# services:
# - name: dameng
# image: lunny/dm:v1.0
# commands:
# - /bin/bash /startDm.sh
--- ---
kind: pipeline kind: pipeline
name: merge_coverage name: merge_coverage
@ -374,6 +409,7 @@ depends_on:
- test-mssql - test-mssql
- test-tidb - test-tidb
- test-cockroach - test-cockroach
#- test-dameng
trigger: trigger:
ref: ref:
- refs/heads/master - refs/heads/master

View File

@ -43,6 +43,10 @@ TEST_TIDB_DBNAME ?= xorm_test
TEST_TIDB_USERNAME ?= root TEST_TIDB_USERNAME ?= root
TEST_TIDB_PASSWORD ?= TEST_TIDB_PASSWORD ?=
TEST_DAMENG_HOST ?= dameng:5236
TEST_DAMENG_USERNAME ?= SYSDBA
TEST_DAMENG_PASSWORD ?= SYSDBA
TEST_CACHE_ENABLE ?= false TEST_CACHE_ENABLE ?= false
TEST_QUOTE_POLICY ?= always TEST_QUOTE_POLICY ?= always
@ -240,7 +244,6 @@ test-sqlite\#%: go-check
$(GO) test $(INTEGRATION_PACKAGES) -v -race -run $* -cache=$(TEST_CACHE_ENABLE) -db=sqlite -conn_str="./test.db?cache=shared&mode=rwc" \ $(GO) test $(INTEGRATION_PACKAGES) -v -race -run $* -cache=$(TEST_CACHE_ENABLE) -db=sqlite -conn_str="./test.db?cache=shared&mode=rwc" \
-quote=$(TEST_QUOTE_POLICY) -coverprofile=sqlite.$(TEST_QUOTE_POLICY).$(TEST_CACHE_ENABLE).coverage.out -covermode=atomic -quote=$(TEST_QUOTE_POLICY) -coverprofile=sqlite.$(TEST_QUOTE_POLICY).$(TEST_CACHE_ENABLE).coverage.out -covermode=atomic
.PNONY: test-tidb .PNONY: test-tidb
test-tidb: go-check test-tidb: go-check
$(GO) test $(INTEGRATION_PACKAGES) -v -race -db=mysql -cache=$(TEST_CACHE_ENABLE) -ignore_select_update=true \ $(GO) test $(INTEGRATION_PACKAGES) -v -race -db=mysql -cache=$(TEST_CACHE_ENABLE) -ignore_select_update=true \
@ -253,6 +256,18 @@ test-tidb\#%: go-check
-conn_str="$(TEST_TIDB_USERNAME):$(TEST_TIDB_PASSWORD)@tcp($(TEST_TIDB_HOST))/$(TEST_TIDB_DBNAME)" \ -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
.PNONY: test-dameng
test-dameng: go-check
$(GO) test $(INTEGRATION_PACKAGES) -v -race -db=dm -cache=$(TEST_CACHE_ENABLE) -quote=$(TEST_QUOTE_POLICY) \
-conn_str="dm://$(TEST_DAMENG_USERNAME):$(TEST_DAMENG_PASSWORD)@$(TEST_DAMENG_HOST)" \
-coverprofile=dameng.$(TEST_QUOTE_POLICY).$(TEST_CACHE_ENABLE).coverage.out -covermode=atomic -timeout=20m
.PHONY: test-dameng\#%
test-dameng\#%: go-check
$(GO) test $(INTEGRATION_PACKAGES) -v -race -run $* -db=dm -cache=$(TEST_CACHE_ENABLE) -quote=$(TEST_QUOTE_POLICY) \
-conn_str="dm://$(TEST_DAMENG_USERNAME):$(TEST_DAMENG_PASSWORD)@$(TEST_DAMENG_HOST)" \
-coverprofile=dameng.$(TEST_QUOTE_POLICY).$(TEST_CACHE_ENABLE).coverage.out -covermode=atomic -timeout=20m
.PHONY: vet .PHONY: vet
vet: vet:
$(GO) vet $(shell $(GO) list ./...) $(GO) vet $(shell $(GO) list ./...)

View File

@ -283,11 +283,9 @@ func Assign(dest, src interface{}, originalLocation *time.Location, convertedLoc
} }
} }
var sv reflect.Value
switch d := dest.(type) { switch d := dest.(type) {
case *string: case *string:
sv = reflect.ValueOf(src) var sv = reflect.ValueOf(src)
switch sv.Kind() { switch sv.Kind() {
case reflect.Bool, case reflect.Bool,
reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,

1181
dialects/dameng.go Normal file

File diff suppressed because it is too large Load Diff

View File

@ -38,11 +38,21 @@ func (uri *URI) SetSchema(schema string) {
} }
} }
const (
IncrAutoincrMode = iota
SequenceAutoincrMode
)
type DialectFeatures struct {
AutoincrMode int // 0 autoincrement column, 1 sequence
}
// Dialect represents a kind of database // Dialect represents a kind of database
type Dialect interface { type Dialect interface {
Init(*URI) error Init(*URI) error
URI() *URI URI() *URI
Version(ctx context.Context, queryer core.Queryer) (*schemas.Version, error) Version(ctx context.Context, queryer core.Queryer) (*schemas.Version, error)
Features() *DialectFeatures
SQLType(*schemas.Column) string SQLType(*schemas.Column) string
Alias(string) string // return what a sql type's alias of Alias(string) string // return what a sql type's alias of
@ -61,9 +71,13 @@ type Dialect interface {
GetTables(queryer core.Queryer, ctx context.Context) ([]*schemas.Table, error) GetTables(queryer core.Queryer, ctx context.Context) ([]*schemas.Table, error)
IsTableExist(queryer core.Queryer, ctx context.Context, tableName string) (bool, error) IsTableExist(queryer core.Queryer, ctx context.Context, tableName string) (bool, error)
CreateTableSQL(table *schemas.Table, tableName string) ([]string, bool) CreateTableSQL(ctx context.Context, queryer core.Queryer, table *schemas.Table, tableName string) (string, bool, error)
DropTableSQL(tableName string) (string, bool) DropTableSQL(tableName string) (string, bool)
CreateSequenceSQL(ctx context.Context, queryer core.Queryer, seqName string) (string, error)
IsSequenceExist(ctx context.Context, queryer core.Queryer, seqName string) (bool, error)
DropSequenceSQL(seqName string) (string, error)
GetColumns(queryer core.Queryer, ctx context.Context, tableName string) ([]string, map[string]*schemas.Column, error) GetColumns(queryer core.Queryer, ctx context.Context, tableName string) ([]string, map[string]*schemas.Column, error)
IsColumnExist(queryer core.Queryer, ctx context.Context, tableName string, colName string) (bool, error) IsColumnExist(queryer core.Queryer, ctx context.Context, tableName string, colName string) (bool, error)
AddColumnSQL(tableName string, col *schemas.Column) string AddColumnSQL(tableName string, col *schemas.Column) string
@ -104,7 +118,7 @@ func (db *Base) URI() *URI {
} }
// CreateTableSQL implements Dialect // CreateTableSQL implements Dialect
func (db *Base) CreateTableSQL(table *schemas.Table, tableName string) ([]string, bool) { func (db *Base) CreateTableSQL(ctx context.Context, queryer core.Queryer, table *schemas.Table, tableName string) (string, bool, error) {
if tableName == "" { if tableName == "" {
tableName = table.Name tableName = table.Name
} }
@ -133,7 +147,25 @@ func (db *Base) CreateTableSQL(table *schemas.Table, tableName string) ([]string
b.WriteString(")") b.WriteString(")")
return []string{b.String()}, false return b.String(), false, nil
}
func (db *Base) CreateSequenceSQL(ctx context.Context, queryer core.Queryer, seqName string) (string, error) {
return fmt.Sprintf(`CREATE SEQUENCE %s
minvalue 1
nomaxvalue
start with 1
increment by 1
nocycle
nocache`, seqName), nil
}
func (db *Base) IsSequenceExist(ctx context.Context, queryer core.Queryer, seqName string) (bool, error) {
return false, fmt.Errorf("unsupported sequence feature")
}
func (db *Base) DropSequenceSQL(seqName string) (string, error) {
return fmt.Sprintf("DROP SEQUENCE %s", seqName), nil
} }
// DropTableSQL returns drop table SQL // DropTableSQL returns drop table SQL
@ -285,43 +317,41 @@ func ColumnString(dialect Dialect, col *schemas.Column, includePrimaryKey bool)
return "", err return "", err
} }
if err := bd.WriteByte(' '); err != nil {
return "", err
}
if includePrimaryKey && col.IsPrimaryKey { if includePrimaryKey && col.IsPrimaryKey {
if _, err := bd.WriteString("PRIMARY KEY "); err != nil { if _, err := bd.WriteString(" PRIMARY KEY"); err != nil {
return "", err return "", err
} }
if col.IsAutoIncrement { if col.IsAutoIncrement {
if _, err := bd.WriteString(dialect.AutoIncrStr()); err != nil {
return "", err
}
if err := bd.WriteByte(' '); err != nil { if err := bd.WriteByte(' '); err != nil {
return "", err return "", err
} }
if _, err := bd.WriteString(dialect.AutoIncrStr()); err != nil {
return "", err
}
} }
} }
if col.Default != "" { if !col.DefaultIsEmpty {
if _, err := bd.WriteString("DEFAULT "); err != nil { if _, err := bd.WriteString(" DEFAULT "); err != nil {
return "", err return "", err
} }
if _, err := bd.WriteString(col.Default); err != nil { if col.Default == "" {
return "", err if _, err := bd.WriteString("''"); err != nil {
} return "", err
if err := bd.WriteByte(' '); err != nil { }
return "", err } else {
if _, err := bd.WriteString(col.Default); err != nil {
return "", err
}
} }
} }
if col.Nullable { if col.Nullable {
if _, err := bd.WriteString("NULL "); err != nil { if _, err := bd.WriteString(" NULL"); err != nil {
return "", err return "", err
} }
} else { } else {
if _, err := bd.WriteString("NOT NULL "); err != nil { if _, err := bd.WriteString(" NOT NULL"); err != nil {
return "", err return "", err
} }
} }

View File

@ -282,6 +282,12 @@ func (db *mssql) Version(ctx context.Context, queryer core.Queryer) (*schemas.Ve
}, nil }, nil
} }
func (db *mssql) Features() *DialectFeatures {
return &DialectFeatures{
AutoincrMode: IncrAutoincrMode,
}
}
func (db *mssql) SQLType(c *schemas.Column) string { func (db *mssql) SQLType(c *schemas.Column) string {
var res string var res string
switch t := c.SQLType.Name; t { switch t := c.SQLType.Name; t {
@ -625,7 +631,7 @@ WHERE IXS.TYPE_DESC='NONCLUSTERED' and OBJECT_NAME(IXS.OBJECT_ID) =?
return indexes, nil return indexes, nil
} }
func (db *mssql) CreateTableSQL(table *schemas.Table, tableName string) ([]string, bool) { func (db *mssql) CreateTableSQL(ctx context.Context, queryer core.Queryer, table *schemas.Table, tableName string) (string, bool, error) {
if tableName == "" { if tableName == "" {
tableName = table.Name tableName = table.Name
} }
@ -656,7 +662,7 @@ func (db *mssql) CreateTableSQL(table *schemas.Table, tableName string) ([]strin
b.WriteString(")") b.WriteString(")")
return []string{b.String()}, true return b.String(), true, nil
} }
func (db *mssql) ForUpdateSQL(query string) string { func (db *mssql) ForUpdateSQL(query string) string {

View File

@ -244,6 +244,12 @@ func (db *mysql) Version(ctx context.Context, queryer core.Queryer) (*schemas.Ve
}, nil }, nil
} }
func (db *mysql) Features() *DialectFeatures {
return &DialectFeatures{
AutoincrMode: IncrAutoincrMode,
}
}
func (db *mysql) SetParams(params map[string]string) { func (db *mysql) SetParams(params map[string]string) {
rowFormat, ok := params["rowFormat"] rowFormat, ok := params["rowFormat"]
if ok { if ok {
@ -625,7 +631,7 @@ func (db *mysql) GetIndexes(queryer core.Queryer, ctx context.Context, tableName
return indexes, nil return indexes, nil
} }
func (db *mysql) CreateTableSQL(table *schemas.Table, tableName string) ([]string, bool) { func (db *mysql) CreateTableSQL(ctx context.Context, queryer core.Queryer, table *schemas.Table, tableName string) (string, bool, error) {
if tableName == "" { if tableName == "" {
tableName = table.Name tableName = table.Name
} }
@ -678,7 +684,8 @@ func (db *mysql) CreateTableSQL(table *schemas.Table, tableName string) ([]strin
b.WriteString(" ROW_FORMAT=") b.WriteString(" ROW_FORMAT=")
b.WriteString(db.rowFormat) b.WriteString(db.rowFormat)
} }
return []string{b.String()}, true
return b.String(), true, nil
} }
func (db *mysql) Filters() []Filter { func (db *mysql) Filters() []Filter {

View File

@ -539,6 +539,12 @@ func (db *oracle) Version(ctx context.Context, queryer core.Queryer) (*schemas.V
}, nil }, nil
} }
func (db *oracle) Features() *DialectFeatures {
return &DialectFeatures{
AutoincrMode: SequenceAutoincrMode,
}
}
func (db *oracle) SQLType(c *schemas.Column) string { func (db *oracle) SQLType(c *schemas.Column) string {
var res string var res string
switch t := c.SQLType.Name; t { switch t := c.SQLType.Name; t {
@ -599,7 +605,7 @@ func (db *oracle) DropTableSQL(tableName string) (string, bool) {
return fmt.Sprintf("DROP TABLE `%s`", tableName), false return fmt.Sprintf("DROP TABLE `%s`", tableName), false
} }
func (db *oracle) CreateTableSQL(table *schemas.Table, tableName string) ([]string, bool) { func (db *oracle) CreateTableSQL(ctx context.Context, queryer core.Queryer, table *schemas.Table, tableName string) (string, bool, error) {
var sql = "CREATE TABLE " var sql = "CREATE TABLE "
if tableName == "" { if tableName == "" {
tableName = table.Name tableName = table.Name
@ -629,7 +635,7 @@ func (db *oracle) CreateTableSQL(table *schemas.Table, tableName string) ([]stri
} }
sql = sql[:len(sql)-2] + ")" sql = sql[:len(sql)-2] + ")"
return []string{sql}, false return sql, false, nil
} }
func (db *oracle) SetQuotePolicy(quotePolicy QuotePolicy) { func (db *oracle) SetQuotePolicy(quotePolicy QuotePolicy) {

View File

@ -941,6 +941,12 @@ func (db *postgres) SQLType(c *schemas.Column) string {
return res return res
} }
func (db *postgres) Features() *DialectFeatures {
return &DialectFeatures{
AutoincrMode: IncrAutoincrMode,
}
}
func (db *postgres) ColumnTypeKind(t string) int { func (db *postgres) ColumnTypeKind(t string) int {
switch strings.ToUpper(t) { switch strings.ToUpper(t) {
case "DATETIME", "TIMESTAMP": case "DATETIME", "TIMESTAMP":

View File

@ -184,6 +184,12 @@ func (db *sqlite3) Version(ctx context.Context, queryer core.Queryer) (*schemas.
}, nil }, nil
} }
func (db *sqlite3) Features() *DialectFeatures {
return &DialectFeatures{
AutoincrMode: IncrAutoincrMode,
}
}
func (db *sqlite3) SetQuotePolicy(quotePolicy QuotePolicy) { func (db *sqlite3) SetQuotePolicy(quotePolicy QuotePolicy) {
switch quotePolicy { switch quotePolicy {
case QuotePolicyNone: case QuotePolicyNone:

View File

@ -248,11 +248,6 @@ func (engine *Engine) SQLType(c *schemas.Column) string {
return engine.dialect.SQLType(c) return engine.dialect.SQLType(c)
} }
// AutoIncrStr Database's autoincrement statement
func (engine *Engine) AutoIncrStr() string {
return engine.dialect.AutoIncrStr()
}
// SetConnMaxLifetime sets the maximum amount of time a connection may be reused. // SetConnMaxLifetime sets the maximum amount of time a connection may be reused.
func (engine *Engine) SetConnMaxLifetime(d time.Duration) { func (engine *Engine) SetConnMaxLifetime(d time.Duration) {
engine.DB().SetConnMaxLifetime(d) engine.DB().SetConnMaxLifetime(d)
@ -441,7 +436,7 @@ func (engine *Engine) DumpTablesToFile(tables []*schemas.Table, fp string, tp ..
// DumpTables dump specify tables to io.Writer // DumpTables dump specify tables to io.Writer
func (engine *Engine) DumpTables(tables []*schemas.Table, w io.Writer, tp ...schemas.DBType) error { func (engine *Engine) DumpTables(tables []*schemas.Table, w io.Writer, tp ...schemas.DBType) error {
return engine.dumpTables(tables, w, tp...) return engine.dumpTables(context.Background(), tables, w, tp...)
} }
func formatBool(s string, dstDialect dialects.Dialect) string { func formatBool(s string, dstDialect dialects.Dialect) string {
@ -457,7 +452,7 @@ func formatBool(s string, dstDialect dialects.Dialect) string {
} }
// dumpTables dump database all table structs and data to w with specify db type // dumpTables dump database all table structs and data to w with specify db type
func (engine *Engine) dumpTables(tables []*schemas.Table, w io.Writer, tp ...schemas.DBType) error { func (engine *Engine) dumpTables(ctx context.Context, tables []*schemas.Table, w io.Writer, tp ...schemas.DBType) error {
var dstDialect dialects.Dialect var dstDialect dialects.Dialect
if len(tp) == 0 { if len(tp) == 0 {
dstDialect = engine.dialect dstDialect = engine.dialect
@ -494,9 +489,12 @@ func (engine *Engine) dumpTables(tables []*schemas.Table, w io.Writer, tp ...sch
} }
} }
dstTableName := dstTable.Name var dstTableName = dstTable.Name
var quoter = dstDialect.Quoter().Quote
var quotedDstTableName = quoter(dstTable.Name)
if dstDialect.URI().Schema != "" { if dstDialect.URI().Schema != "" {
dstTableName = fmt.Sprintf("%s.%s", dstDialect.URI().Schema, dstTable.Name) dstTableName = fmt.Sprintf("%s.%s", dstDialect.URI().Schema, dstTable.Name)
quotedDstTableName = fmt.Sprintf("%s.%s", quoter(dstDialect.URI().Schema), quoter(dstTable.Name))
} }
originalTableName := table.Name originalTableName := table.Name
if engine.dialect.URI().Schema != "" { if engine.dialect.URI().Schema != "" {
@ -509,13 +507,26 @@ func (engine *Engine) dumpTables(tables []*schemas.Table, w io.Writer, tp ...sch
} }
} }
sqls, _ := dstDialect.CreateTableSQL(dstTable, dstTableName) if dstTable.AutoIncrement != "" && dstDialect.Features().AutoincrMode == dialects.SequenceAutoincrMode {
for _, s := range sqls { sqlstr, err := dstDialect.CreateSequenceSQL(ctx, engine.db, utils.SeqName(dstTableName))
_, err = io.WriteString(w, s+";\n") if err != nil {
return err
}
_, err = io.WriteString(w, sqlstr+";\n")
if err != nil { if err != nil {
return err return err
} }
} }
sqlstr, _, err := dstDialect.CreateTableSQL(ctx, engine.db, dstTable, dstTableName)
if err != nil {
return err
}
_, err = io.WriteString(w, sqlstr+";\n")
if err != nil {
return err
}
if len(dstTable.PKColumns()) > 0 && dstDialect.URI().DBType == schemas.MSSQL { if len(dstTable.PKColumns()) > 0 && dstDialect.URI().DBType == schemas.MSSQL {
fmt.Fprintf(w, "SET IDENTITY_INSERT [%s] ON;\n", dstTable.Name) fmt.Fprintf(w, "SET IDENTITY_INSERT [%s] ON;\n", dstTable.Name)
} }
@ -552,7 +563,7 @@ func (engine *Engine) dumpTables(tables []*schemas.Table, w io.Writer, tp ...sch
sess := engine.NewSession() sess := engine.NewSession()
defer sess.Close() defer sess.Close()
for rows.Next() { for rows.Next() {
_, err = io.WriteString(w, "INSERT INTO "+dstDialect.Quoter().Quote(dstTableName)+" ("+destColNames+") VALUES (") _, err = io.WriteString(w, "INSERT INTO "+quotedDstTableName+" ("+destColNames+") VALUES (")
if err != nil { if err != nil {
return err return err
} }
@ -563,36 +574,27 @@ func (engine *Engine) dumpTables(tables []*schemas.Table, w io.Writer, tp ...sch
} }
for i, scanResult := range scanResults { for i, scanResult := range scanResults {
stp := schemas.SQLType{Name: types[i].DatabaseTypeName()} stp := schemas.SQLType{Name: types[i].DatabaseTypeName()}
if stp.IsNumeric() { s := scanResult.(*sql.NullString)
s := scanResult.(*sql.NullString) if !s.Valid {
if s.Valid { if _, err = io.WriteString(w, "NULL"); err != nil {
if _, err = io.WriteString(w, formatBool(s.String, dstDialect)); err != nil { return err
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 { } else {
s := scanResult.(*sql.NullString) if stp.IsBool() || (dstDialect.URI().DBType == schemas.MSSQL && strings.EqualFold(stp.Name, schemas.Bit)) {
if s.Valid { if _, err = io.WriteString(w, formatBool(s.String, dstDialect)); err != nil {
if _, err = io.WriteString(w, "'"+strings.ReplaceAll(s.String, "'", "''")+"'"); err != nil { return err
}
} else if stp.IsNumeric() {
if _, err = io.WriteString(w, s.String); err != nil {
return err
}
} else if sess.engine.dialect.URI().DBType == schemas.DAMENG && stp.IsTime() && len(s.String) == 25 {
r := strings.Replace(s.String[:19], "T", " ", -1)
if _, err = io.WriteString(w, "'"+r+"'"); err != nil {
return err return err
} }
} else { } else {
if _, err = io.WriteString(w, "NULL"); err != nil { if _, err = io.WriteString(w, "'"+strings.ReplaceAll(s.String, "'", "''")+"'"); err != nil {
return err return err
} }
} }

1
go.mod
View File

@ -3,6 +3,7 @@ module xorm.io/xorm
go 1.13 go 1.13
require ( require (
gitee.com/travelliu/dm v1.8.11192
github.com/denisenkom/go-mssqldb v0.10.0 github.com/denisenkom/go-mssqldb v0.10.0
github.com/go-sql-driver/mysql v1.6.0 github.com/go-sql-driver/mysql v1.6.0
github.com/goccy/go-json v0.7.4 github.com/goccy/go-json v0.7.4

5
go.sum
View File

@ -2,6 +2,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s= 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= gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
gitee.com/travelliu/dm v1.8.11192 h1:aqJT0xhodZjRutIfEXxKYv0CxqmHUHzsbz6SFaRL6OY=
gitee.com/travelliu/dm v1.8.11192/go.mod h1:DHTzyhCrM843x9VdKVbZ+GKXGRbKM2sJ4LxihRxShkE=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 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/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 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
@ -95,8 +97,9 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
github.com/golang/protobuf v1.3.1/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 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 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/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/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.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=

View File

@ -62,7 +62,8 @@ func TestCacheFind(t *testing.T) {
} }
boxes = make([]MailBox, 0, 2) boxes = make([]MailBox, 0, 2)
assert.NoError(t, testEngine.Alias("a").Where("a.id > -1").Asc("a.id").Find(&boxes)) assert.NoError(t, testEngine.Alias("a").Where("`a`.`id`> -1").
Asc("`a`.`id`").Find(&boxes))
assert.EqualValues(t, 2, len(boxes)) assert.EqualValues(t, 2, len(boxes))
for i, box := range boxes { for i, box := range boxes {
assert.Equal(t, inserts[i].Id, box.Id) assert.Equal(t, inserts[i].Id, box.Id)
@ -77,7 +78,8 @@ func TestCacheFind(t *testing.T) {
} }
boxes2 := make([]MailBox4, 0, 2) boxes2 := make([]MailBox4, 0, 2)
assert.NoError(t, testEngine.Table("mail_box").Where("mail_box.id > -1").Asc("mail_box.id").Find(&boxes2)) assert.NoError(t, testEngine.Table("mail_box").Where("`mail_box`.`id` > -1").
Asc("mail_box.id").Find(&boxes2))
assert.EqualValues(t, 2, len(boxes2)) assert.EqualValues(t, 2, len(boxes2))
for i, box := range boxes2 { for i, box := range boxes2 {
assert.Equal(t, inserts[i].Id, box.Id) assert.Equal(t, inserts[i].Id, box.Id)
@ -164,14 +166,14 @@ func TestCacheGet(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
var box1 MailBox3 var box1 MailBox3
has, err := testEngine.Where("id = ?", inserts[0].Id).Get(&box1) has, err := testEngine.Where("`id` = ?", inserts[0].Id).Get(&box1)
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, has) assert.True(t, has)
assert.EqualValues(t, "user1", box1.Username) assert.EqualValues(t, "user1", box1.Username)
assert.EqualValues(t, "pass1", box1.Password) assert.EqualValues(t, "pass1", box1.Password)
var box2 MailBox3 var box2 MailBox3
has, err = testEngine.Where("id = ?", inserts[0].Id).Get(&box2) has, err = testEngine.Where("`id` = ?", inserts[0].Id).Get(&box2)
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, has) assert.True(t, has)
assert.EqualValues(t, "user1", box2.Username) assert.EqualValues(t, "user1", box2.Username)

View File

@ -0,0 +1,13 @@
// 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 dm
package integrations
import "xorm.io/xorm/schemas"
func init() {
dbtypes = append(dbtypes, schemas.DAMENG)
}

View File

@ -14,6 +14,7 @@ import (
"xorm.io/xorm" "xorm.io/xorm"
"xorm.io/xorm/schemas" "xorm.io/xorm/schemas"
_ "gitee.com/travelliu/dm"
_ "github.com/denisenkom/go-mssqldb" _ "github.com/denisenkom/go-mssqldb"
_ "github.com/go-sql-driver/mysql" _ "github.com/go-sql-driver/mysql"
_ "github.com/jackc/pgx/v4/stdlib" _ "github.com/jackc/pgx/v4/stdlib"
@ -134,6 +135,8 @@ func TestDump(t *testing.T) {
} }
} }
var dbtypes = []schemas.DBType{schemas.SQLITE, schemas.MYSQL, schemas.POSTGRES, schemas.MSSQL}
func TestDumpTables(t *testing.T) { func TestDumpTables(t *testing.T) {
assert.NoError(t, PrepareEngine()) assert.NoError(t, PrepareEngine())
@ -169,7 +172,7 @@ func TestDumpTables(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
assert.NoError(t, sess.Commit()) assert.NoError(t, sess.Commit())
for _, tp := range []schemas.DBType{schemas.SQLITE, schemas.MYSQL, schemas.POSTGRES, schemas.MSSQL} { for _, tp := range dbtypes {
name := fmt.Sprintf("dump_%v-table.sql", tp) name := fmt.Sprintf("dump_%v-table.sql", tp)
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
assert.NoError(t, testEngine.(*xorm.Engine).DumpTablesToFile([]*schemas.Table{tb}, name, tp)) assert.NoError(t, testEngine.(*xorm.Engine).DumpTablesToFile([]*schemas.Table{tb}, name, tp))

View File

@ -32,7 +32,7 @@ func BenchmarkGetVars(b *testing.B) {
b.StartTimer() b.StartTimer()
var myname string var myname string
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
has, err := testEngine.Cols("name").Table("benchmark_get_vars").Where("id=?", v.Id).Get(&myname) has, err := testEngine.Cols("name").Table("benchmark_get_vars").Where("`id`=?", v.Id).Get(&myname)
b.StopTimer() b.StopTimer()
myname = "" myname = ""
assert.True(b, has) assert.True(b, has)

View File

@ -45,7 +45,7 @@ func TestSetExpr(t *testing.T) {
assert.EqualValues(t, 1, cnt) assert.EqualValues(t, 1, cnt)
var not = "NOT" var not = "NOT"
if testEngine.Dialect().URI().DBType == schemas.MSSQL { if testEngine.Dialect().URI().DBType == schemas.MSSQL || testEngine.Dialect().URI().DBType == schemas.DAMENG {
not = "~" not = "~"
} }
cnt, err = testEngine.SetExpr("show", not+" `show`").ID(1).Update(new(UserExpr)) cnt, err = testEngine.SetExpr("show", not+" `show`").ID(1).Update(new(UserExpr))
@ -54,9 +54,9 @@ func TestSetExpr(t *testing.T) {
tableName := testEngine.TableName(new(UserExprIssue), true) tableName := testEngine.TableName(new(UserExprIssue), true)
cnt, err = testEngine.SetExpr("issue_id", cnt, err = testEngine.SetExpr("issue_id",
builder.Select("id"). builder.Select("`id`").
From(tableName). From(testEngine.Quote(tableName)).
Where(builder.Eq{"id": issue.Id})). Where(builder.Eq{"`id`": issue.Id})).
ID(1). ID(1).
Update(new(UserExpr)) Update(new(UserExpr))
assert.NoError(t, err) assert.NoError(t, err)

View File

@ -37,49 +37,50 @@ func TestBuilder(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
var cond Condition var cond Condition
has, err := testEngine.Where(builder.Eq{"col_name": "col1"}).Get(&cond) var q = testEngine.Quote
has, err := testEngine.Where(builder.Eq{q("col_name"): "col1"}).Get(&cond)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, true, has, "records should exist") assert.Equal(t, true, has, "records should exist")
has, err = testEngine.Where(builder.Eq{"col_name": "col1"}. has, err = testEngine.Where(builder.Eq{q("col_name"): "col1"}.
And(builder.Eq{"op": OpEqual})). And(builder.Eq{q("op"): OpEqual})).
NoAutoCondition(). NoAutoCondition().
Get(&cond) Get(&cond)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, true, has, "records should exist") assert.Equal(t, true, has, "records should exist")
has, err = testEngine.Where(builder.Eq{"col_name": "col1", "op": OpEqual, "value": "1"}). has, err = testEngine.Where(builder.Eq{q("col_name"): "col1", q("op"): OpEqual, q("value"): "1"}).
NoAutoCondition(). NoAutoCondition().
Get(&cond) Get(&cond)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, true, has, "records should exist") assert.Equal(t, true, has, "records should exist")
has, err = testEngine.Where(builder.Eq{"col_name": "col1"}. has, err = testEngine.Where(builder.Eq{q("col_name"): "col1"}.
And(builder.Neq{"op": OpEqual})). And(builder.Neq{q("op"): OpEqual})).
NoAutoCondition(). NoAutoCondition().
Get(&cond) Get(&cond)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, false, has, "records should not exist") assert.Equal(t, false, has, "records should not exist")
var conds []Condition var conds []Condition
err = testEngine.Where(builder.Eq{"col_name": "col1"}. err = testEngine.Where(builder.Eq{q("col_name"): "col1"}.
And(builder.Eq{"op": OpEqual})). And(builder.Eq{q("op"): OpEqual})).
Find(&conds) Find(&conds)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 1, len(conds), "records should exist") assert.EqualValues(t, 1, len(conds), "records should exist")
conds = make([]Condition, 0) conds = make([]Condition, 0)
err = testEngine.Where(builder.Like{"col_name", "col"}).Find(&conds) err = testEngine.Where(builder.Like{q("col_name"), "col"}).Find(&conds)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 1, len(conds), "records should exist") assert.EqualValues(t, 1, len(conds), "records should exist")
conds = make([]Condition, 0) conds = make([]Condition, 0)
err = testEngine.Where(builder.Expr("col_name = ?", "col1")).Find(&conds) err = testEngine.Where(builder.Expr(q("col_name")+" = ?", "col1")).Find(&conds)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 1, len(conds), "records should exist") assert.EqualValues(t, 1, len(conds), "records should exist")
conds = make([]Condition, 0) conds = make([]Condition, 0)
err = testEngine.Where(builder.In("col_name", "col1", "col2")).Find(&conds) err = testEngine.Where(builder.In(q("col_name"), "col1", "col2")).Find(&conds)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 1, len(conds), "records should exist") assert.EqualValues(t, 1, len(conds), "records should exist")
@ -91,8 +92,8 @@ func TestBuilder(t *testing.T) {
// complex condtions // complex condtions
var where = builder.NewCond() var where = builder.NewCond()
if true { if true {
where = where.And(builder.Eq{"col_name": "col1"}) where = where.And(builder.Eq{q("col_name"): "col1"})
where = where.Or(builder.And(builder.In("col_name", "col1", "col2"), builder.Expr("col_name = ?", "col1"))) where = where.Or(builder.And(builder.In(q("col_name"), "col1", "col2"), builder.Expr(q("col_name")+" = ?", "col1")))
} }
conds = make([]Condition, 0) conds = make([]Condition, 0)
@ -215,7 +216,7 @@ func TestFindAndCount(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
var results []FindAndCount var results []FindAndCount
sess := testEngine.Where("name = ?", "test1") sess := testEngine.Where("`name` = ?", "test1")
conds := sess.Conds() conds := sess.Conds()
err = sess.Find(&results) err = sess.Find(&results)
assert.NoError(t, err) assert.NoError(t, err)

View File

@ -63,7 +63,7 @@ func TestSQLCount(t *testing.T) {
assertSync(t, new(UserinfoCount2), new(UserinfoBooks)) assertSync(t, new(UserinfoCount2), new(UserinfoBooks))
total, err := testEngine.SQL("SELECT count(id) FROM " + testEngine.TableName("userinfo_count2", true)). total, err := testEngine.SQL("SELECT count(`id`) FROM " + testEngine.Quote(testEngine.TableName("userinfo_count2", true))).
Count() Count()
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 0, total) assert.EqualValues(t, 0, total)
@ -89,7 +89,7 @@ func TestCountWithOthers(t *testing.T) {
}) })
assert.NoError(t, err) assert.NoError(t, err)
total, err := testEngine.OrderBy("id desc").Limit(1).Count(new(CountWithOthers)) total, err := testEngine.OrderBy("`id` desc").Limit(1).Count(new(CountWithOthers))
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 2, total) assert.EqualValues(t, 2, total)
} }
@ -118,11 +118,11 @@ func TestWithTableName(t *testing.T) {
}) })
assert.NoError(t, err) assert.NoError(t, err)
total, err := testEngine.OrderBy("id desc").Count(new(CountWithTableName)) total, err := testEngine.OrderBy("`id` desc").Count(new(CountWithTableName))
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 2, total) assert.EqualValues(t, 2, total)
total, err = testEngine.OrderBy("id desc").Count(CountWithTableName{}) total, err = testEngine.OrderBy("`id` desc").Count(CountWithTableName{})
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 2, total) assert.EqualValues(t, 2, total)
} }
@ -146,7 +146,7 @@ func TestCountWithSelectCols(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 2, total) assert.EqualValues(t, 2, total)
total, err = testEngine.Select("count(id)").Count(CountWithTableName{}) total, err = testEngine.Select("count(`id`)").Count(CountWithTableName{})
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 2, total) assert.EqualValues(t, 2, total)
} }
@ -166,7 +166,7 @@ func TestCountWithGroupBy(t *testing.T) {
}) })
assert.NoError(t, err) assert.NoError(t, err)
cnt, err := testEngine.GroupBy("name").Count(new(CountWithTableName)) cnt, err := testEngine.GroupBy("`name`").Count(new(CountWithTableName))
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 2, cnt) assert.EqualValues(t, 2, cnt)
} }

View File

@ -48,19 +48,19 @@ func TestExistStruct(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
assert.False(t, has) assert.False(t, has)
has, err = testEngine.Where("name = ?", "test1").Exist(&RecordExist{}) has, err = testEngine.Where("`name` = ?", "test1").Exist(&RecordExist{})
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, has) assert.True(t, has)
has, err = testEngine.Where("name = ?", "test2").Exist(&RecordExist{}) has, err = testEngine.Where("`name` = ?", "test2").Exist(&RecordExist{})
assert.NoError(t, err) assert.NoError(t, err)
assert.False(t, has) assert.False(t, has)
has, err = testEngine.SQL("select * from "+testEngine.TableName("record_exist", true)+" where name = ?", "test1").Exist() has, err = testEngine.SQL("select * from "+testEngine.Quote(testEngine.TableName("record_exist", true))+" where `name` = ?", "test1").Exist()
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, has) assert.True(t, has)
has, err = testEngine.SQL("select * from "+testEngine.TableName("record_exist", true)+" where name = ?", "test2").Exist() has, err = testEngine.SQL("select * from "+testEngine.Quote(testEngine.TableName("record_exist", true))+" where `name` = ?", "test2").Exist()
assert.NoError(t, err) assert.NoError(t, err)
assert.False(t, has) assert.False(t, has)
@ -68,11 +68,11 @@ func TestExistStruct(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, has) assert.True(t, has)
has, err = testEngine.Table("record_exist").Where("name = ?", "test1").Exist() has, err = testEngine.Table("record_exist").Where("`name` = ?", "test1").Exist()
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, has) assert.True(t, has)
has, err = testEngine.Table("record_exist").Where("name = ?", "test2").Exist() has, err = testEngine.Table("record_exist").Where("`name` = ?", "test2").Exist()
assert.NoError(t, err) assert.NoError(t, err)
assert.False(t, has) assert.False(t, has)
@ -124,43 +124,43 @@ func TestExistStructForJoin(t *testing.T) {
defer session.Close() defer session.Close()
session.Table("number"). session.Table("number").
Join("INNER", "order_list", "order_list.id = number.lid"). Join("INNER", "order_list", "`order_list`.`id` = `number`.`lid`").
Join("LEFT", "player", "player.id = order_list.eid"). Join("LEFT", "player", "`player`.`id` = `order_list`.`eid`").
Where("number.lid = ?", 1) Where("`number`.`lid` = ?", 1)
has, err := session.Exist() has, err := session.Exist()
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, has) assert.True(t, has)
session.Table("number"). session.Table("number").
Join("INNER", "order_list", "order_list.id = number.lid"). Join("INNER", "order_list", "`order_list`.`id` = `number`.`lid`").
Join("LEFT", "player", "player.id = order_list.eid"). Join("LEFT", "player", "`player`.`id` = `order_list`.`eid`").
Where("number.lid = ?", 2) Where("`number`.`lid` = ?", 2)
has, err = session.Exist() has, err = session.Exist()
assert.NoError(t, err) assert.NoError(t, err)
assert.False(t, has) assert.False(t, has)
session.Table("number"). session.Table("number").
Select("order_list.id"). Select("`order_list`.`id`").
Join("INNER", "order_list", "order_list.id = number.lid"). Join("INNER", "order_list", "`order_list`.`id` = `number`.`lid`").
Join("LEFT", "player", "player.id = order_list.eid"). Join("LEFT", "player", "`player`.`id` = `order_list`.`eid`").
Where("order_list.id = ?", 1) Where("`order_list`.`id` = ?", 1)
has, err = session.Exist() has, err = session.Exist()
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, has) assert.True(t, has)
session.Table("number"). session.Table("number").
Select("player.id"). Select("player.id").
Join("INNER", "order_list", "order_list.id = number.lid"). Join("INNER", "order_list", "`order_list`.`id` = `number`.`lid`").
Join("LEFT", "player", "player.id = order_list.eid"). Join("LEFT", "player", "`player`.`id` = `order_list`.`eid`").
Where("player.id = ?", 2) Where("`player`.`id` = ?", 2)
has, err = session.Exist() has, err = session.Exist()
assert.NoError(t, err) assert.NoError(t, err)
assert.False(t, has) assert.False(t, has)
session.Table("number"). session.Table("number").
Select("player.id"). Select("player.id").
Join("INNER", "order_list", "order_list.id = number.lid"). Join("INNER", "order_list", "`order_list`.`id` = `number`.`lid`").
Join("LEFT", "player", "player.id = order_list.eid") Join("LEFT", "player", "`player`.`id` = `order_list`.`eid`")
has, err = session.Exist() has, err = session.Exist()
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, has) assert.True(t, has)
@ -174,15 +174,15 @@ func TestExistStructForJoin(t *testing.T) {
session.Table("number"). session.Table("number").
Select("player.id"). Select("player.id").
Join("INNER", "order_list", "order_list.id = number.lid"). Join("INNER", "order_list", "`order_list`.`id` = `number`.`lid`").
Join("LEFT", "player", "player.id = order_list.eid") Join("LEFT", "player", "`player`.`id` = `order_list`.`eid`")
has, err = session.Exist() has, err = session.Exist()
assert.Error(t, err) assert.Error(t, err)
assert.False(t, has) assert.False(t, has)
session.Table("number"). session.Table("number").
Select("player.id"). Select("player.id").
Join("LEFT", "player", "player.id = number.lid") Join("LEFT", "player", "`player`.`id` = `number`.`lid`")
has, err = session.Exist() has, err = session.Exist()
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, has) assert.True(t, has)

View File

@ -56,8 +56,8 @@ func TestJoinLimit(t *testing.T) {
var salaries []Salary var salaries []Salary
err = testEngine.Table("salary"). err = testEngine.Table("salary").
Join("INNER", "check_list", "check_list.id = salary.lid"). Join("INNER", "check_list", "`check_list`.`id` = `salary`.`lid`").
Join("LEFT", "empsetting", "empsetting.id = check_list.eid"). Join("LEFT", "empsetting", "`empsetting`.`id` = `check_list`.`eid`").
Limit(10, 0). Limit(10, 0).
Find(&salaries) Find(&salaries)
assert.NoError(t, err) assert.NoError(t, err)
@ -69,10 +69,10 @@ func TestWhere(t *testing.T) {
assertSync(t, new(Userinfo)) assertSync(t, new(Userinfo))
users := make([]Userinfo, 0) users := make([]Userinfo, 0)
err := testEngine.Where("id > ?", 2).Find(&users) err := testEngine.Where("`id` > ?", 2).Find(&users)
assert.NoError(t, err) assert.NoError(t, err)
err = testEngine.Where("id > ?", 2).And("id < ?", 10).Find(&users) err = testEngine.Where("`id` > ?", 2).And("`id` < ?", 10).Find(&users)
assert.NoError(t, err) assert.NoError(t, err)
} }
@ -125,50 +125,50 @@ func TestFind3(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
var teams []Team var teams []Team
err = testEngine.Cols("`team`.id"). err = testEngine.Cols("`team`.`id`").
Where("`team_user`.org_id=?", 1). Where("`team_user`.`org_id`=?", 1).
And("`team_user`.uid=?", 2). And("`team_user`.`uid`=?", 2).
Join("INNER", "`team_user`", "`team_user`.team_id=`team`.id"). Join("INNER", "`team_user`", "`team_user`.`team_id`=`team`.`id`").
Find(&teams) Find(&teams)
assert.NoError(t, err) assert.NoError(t, err)
teams = make([]Team, 0) teams = make([]Team, 0)
err = testEngine.Cols("`team`.id"). err = testEngine.Cols("`team`.id").
Where("`team_user`.org_id=?", 1). Where("`team_user`.`org_id`=?", 1).
And("`team_user`.uid=?", 2). And("`team_user`.`uid`=?", 2).
Join("INNER", teamUser, "`team_user`.team_id=`team`.id"). Join("INNER", teamUser, "`team_user`.`team_id`=`team`.`id`").
Find(&teams) Find(&teams)
assert.NoError(t, err) assert.NoError(t, err)
teams = make([]Team, 0) teams = make([]Team, 0)
err = testEngine.Cols("`team`.id"). err = testEngine.Cols("`team`.`id`").
Where("`team_user`.org_id=?", 1). Where("`team_user`.`org_id`=?", 1).
And("`team_user`.uid=?", 2). And("`team_user`.`uid`=?", 2).
Join("INNER", []interface{}{teamUser}, "`team_user`.team_id=`team`.id"). Join("INNER", []interface{}{teamUser}, "`team_user`.`team_id`=`team`.`id`").
Find(&teams) Find(&teams)
assert.NoError(t, err) assert.NoError(t, err)
teams = make([]Team, 0) teams = make([]Team, 0)
err = testEngine.Cols("`team`.id"). err = testEngine.Cols("`team`.`id`").
Where("`tu`.org_id=?", 1). Where("`tu`.`org_id`=?", 1).
And("`tu`.uid=?", 2). And("`tu`.`uid`=?", 2).
Join("INNER", []string{"team_user", "tu"}, "`tu`.team_id=`team`.id"). Join("INNER", []string{"team_user", "tu"}, "`tu`.`team_id`=`team`.`id`").
Find(&teams) Find(&teams)
assert.NoError(t, err) assert.NoError(t, err)
teams = make([]Team, 0) teams = make([]Team, 0)
err = testEngine.Cols("`team`.id"). err = testEngine.Cols("`team`.`id`").
Where("`tu`.org_id=?", 1). Where("`tu`.`org_id`=?", 1).
And("`tu`.uid=?", 2). And("`tu`.`uid`=?", 2).
Join("INNER", []interface{}{"team_user", "tu"}, "`tu`.team_id=`team`.id"). Join("INNER", []interface{}{"team_user", "tu"}, "`tu`.`team_id`=`team`.`id`").
Find(&teams) Find(&teams)
assert.NoError(t, err) assert.NoError(t, err)
teams = make([]Team, 0) teams = make([]Team, 0)
err = testEngine.Cols("`team`.id"). err = testEngine.Cols("`team`.`id`").
Where("`tu`.org_id=?", 1). Where("`tu`.`org_id`=?", 1).
And("`tu`.uid=?", 2). And("`tu`.`uid`=?", 2).
Join("INNER", []interface{}{teamUser, "tu"}, "`tu`.team_id=`team`.id"). Join("INNER", []interface{}{teamUser, "tu"}, "`tu`.`team_id`=`team`.`id`").
Find(&teams) Find(&teams)
assert.NoError(t, err) assert.NoError(t, err)
} }
@ -241,7 +241,7 @@ func TestOrder(t *testing.T) {
assertSync(t, new(Userinfo)) assertSync(t, new(Userinfo))
users := make([]Userinfo, 0) users := make([]Userinfo, 0)
err := testEngine.OrderBy("id desc").Find(&users) err := testEngine.OrderBy("`id` desc").Find(&users)
assert.NoError(t, err) assert.NoError(t, err)
users2 := make([]Userinfo, 0) users2 := make([]Userinfo, 0)
@ -254,7 +254,7 @@ func TestGroupBy(t *testing.T) {
assertSync(t, new(Userinfo)) assertSync(t, new(Userinfo))
users := make([]Userinfo, 0) users := make([]Userinfo, 0)
err := testEngine.GroupBy("id, username").Find(&users) err := testEngine.GroupBy("`id`, `username`").Find(&users)
assert.NoError(t, err) assert.NoError(t, err)
} }
@ -263,7 +263,7 @@ func TestHaving(t *testing.T) {
assertSync(t, new(Userinfo)) assertSync(t, new(Userinfo))
users := make([]Userinfo, 0) users := make([]Userinfo, 0)
err := testEngine.GroupBy("username").Having("username='xlw'").Find(&users) err := testEngine.GroupBy("`username`").Having("`username`='xlw'").Find(&users)
assert.NoError(t, err) assert.NoError(t, err)
} }
@ -499,7 +499,7 @@ func TestFindAndCountOneFunc(t *testing.T) {
assert.EqualValues(t, 2, cnt) assert.EqualValues(t, 2, cnt)
results = make([]FindAndCountStruct, 0, 1) results = make([]FindAndCountStruct, 0, 1)
cnt, err = testEngine.Where("msg = ?", true).FindAndCount(&results) cnt, err = testEngine.Where("`msg` = ?", true).FindAndCount(&results)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 1, len(results)) assert.EqualValues(t, 1, len(results))
assert.EqualValues(t, 1, cnt) assert.EqualValues(t, 1, cnt)
@ -549,21 +549,21 @@ func TestFindAndCountOneFunc(t *testing.T) {
}, results[0]) }, results[0])
results = make([]FindAndCountStruct, 0, 1) results = make([]FindAndCountStruct, 0, 1)
cnt, err = testEngine.Where("msg = ?", true).Select("id, content, msg"). cnt, err = testEngine.Where("`msg` = ?", true).Select("`id`, `content`, `msg`").
Limit(1).FindAndCount(&results) Limit(1).FindAndCount(&results)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 1, len(results)) assert.EqualValues(t, 1, len(results))
assert.EqualValues(t, 1, cnt) assert.EqualValues(t, 1, cnt)
results = make([]FindAndCountStruct, 0, 1) results = make([]FindAndCountStruct, 0, 1)
cnt, err = testEngine.Where("msg = ?", true).Cols("id", "content", "msg"). cnt, err = testEngine.Where("`msg` = ?", true).Cols("id", "content", "msg").
Limit(1).FindAndCount(&results) Limit(1).FindAndCount(&results)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 1, len(results)) assert.EqualValues(t, 1, len(results))
assert.EqualValues(t, 1, cnt) assert.EqualValues(t, 1, cnt)
results = make([]FindAndCountStruct, 0, 1) results = make([]FindAndCountStruct, 0, 1)
cnt, err = testEngine.Where("msg = ?", true).Desc("id"). cnt, err = testEngine.Where("`msg` = ?", true).Desc("id").
Limit(1).Cols("content").FindAndCount(&results) Limit(1).Cols("content").FindAndCount(&results)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 1, len(results)) assert.EqualValues(t, 1, len(results))
@ -649,7 +649,7 @@ func TestFindAndCount2(t *testing.T) {
cnt, err = testEngine. cnt, err = testEngine.
Table(new(TestFindAndCountHotel)). Table(new(TestFindAndCountHotel)).
Alias("t"). Alias("t").
Where("t.region like '6501%'"). Where("`t`.`region` like '6501%'").
Limit(10, 0). Limit(10, 0).
FindAndCount(&hotels) FindAndCount(&hotels)
assert.NoError(t, err) assert.NoError(t, err)
@ -705,7 +705,7 @@ func TestFindAndCountWithGroupBy(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
var results []FindAndCountWithGroupBy var results []FindAndCountWithGroupBy
cnt, err := testEngine.GroupBy("age").FindAndCount(&results) cnt, err := testEngine.GroupBy("`age`").FindAndCount(&results)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 2, cnt) assert.EqualValues(t, 2, cnt)
assert.EqualValues(t, 2, len(results)) assert.EqualValues(t, 2, len(results))
@ -735,14 +735,14 @@ func TestFindMapStringId(t *testing.T) {
deviceMaps := make(map[string]*FindMapDevice, len(deviceIDs)) deviceMaps := make(map[string]*FindMapDevice, len(deviceIDs))
err = testEngine. err = testEngine.
Where("status = ?", 1). Where("`status` = ?", 1).
In("deviceid", deviceIDs). In("deviceid", deviceIDs).
Find(&deviceMaps) Find(&deviceMaps)
assert.NoError(t, err) assert.NoError(t, err)
deviceMaps2 := make(map[string]FindMapDevice, len(deviceIDs)) deviceMaps2 := make(map[string]FindMapDevice, len(deviceIDs))
err = testEngine. err = testEngine.
Where("status = ?", 1). Where("`status` = ?", 1).
In("deviceid", deviceIDs). In("deviceid", deviceIDs).
Find(&deviceMaps2) Find(&deviceMaps2)
assert.NoError(t, err) assert.NoError(t, err)
@ -919,17 +919,17 @@ func TestFindJoin(t *testing.T) {
assertSync(t, new(SceneItem), new(DeviceUserPrivrels), new(Order)) assertSync(t, new(SceneItem), new(DeviceUserPrivrels), new(Order))
var scenes []SceneItem var scenes []SceneItem
err := testEngine.Join("LEFT OUTER", "device_user_privrels", "device_user_privrels.device_id=scene_item.device_id"). err := testEngine.Join("LEFT OUTER", "device_user_privrels", "`device_user_privrels`.`device_id`=`scene_item`.`device_id`").
Where("scene_item.type=?", 3).Or("device_user_privrels.user_id=?", 339).Find(&scenes) Where("`scene_item`.`type`=?", 3).Or("`device_user_privrels`.`user_id`=?", 339).Find(&scenes)
assert.NoError(t, err) assert.NoError(t, err)
scenes = make([]SceneItem, 0) scenes = make([]SceneItem, 0)
err = testEngine.Join("LEFT OUTER", new(DeviceUserPrivrels), "device_user_privrels.device_id=scene_item.device_id"). err = testEngine.Join("LEFT OUTER", new(DeviceUserPrivrels), "`device_user_privrels`.`device_id`=`scene_item`.`device_id`").
Where("scene_item.type=?", 3).Or("device_user_privrels.user_id=?", 339).Find(&scenes) Where("`scene_item`.`type`=?", 3).Or("`device_user_privrels`.`user_id`=?", 339).Find(&scenes)
assert.NoError(t, err) assert.NoError(t, err)
scenes = make([]SceneItem, 0) scenes = make([]SceneItem, 0)
err = testEngine.Join("INNER", "order", "`scene_item`.device_id=`order`.id").Find(&scenes) err = testEngine.Join("INNER", "order", "`scene_item`.`device_id`=`order`.`id`").Find(&scenes)
assert.NoError(t, err) assert.NoError(t, err)
} }
@ -949,7 +949,7 @@ func TestJoinFindLimit(t *testing.T) {
assertSync(t, new(JoinFindLimit1), new(JoinFindLimit2)) assertSync(t, new(JoinFindLimit1), new(JoinFindLimit2))
var finds []JoinFindLimit1 var finds []JoinFindLimit1
err := testEngine.Join("INNER", new(JoinFindLimit2), "join_find_limit2.eid=join_find_limit1.id"). err := testEngine.Join("INNER", new(JoinFindLimit2), "`join_find_limit2`.`eid`=`join_find_limit1`.`id`").
Limit(10, 10).Find(&finds) Limit(10, 10).Find(&finds)
assert.NoError(t, err) assert.NoError(t, err)
} }
@ -981,9 +981,9 @@ func TestMoreExtends(t *testing.T) {
assertSync(t, new(MoreExtendsUsers), new(MoreExtendsBooks)) assertSync(t, new(MoreExtendsUsers), new(MoreExtendsBooks))
var books []MoreExtendsBooksExtend var books []MoreExtendsBooksExtend
err := testEngine.Table("more_extends_books").Select("more_extends_books.*, more_extends_users.*"). err := testEngine.Table("more_extends_books").Select("`more_extends_books`.*, `more_extends_users`.*").
Join("INNER", "more_extends_users", "more_extends_books.user_id = more_extends_users.id"). Join("INNER", "more_extends_users", "`more_extends_books`.`user_id` = `more_extends_users`.`id`").
Where("more_extends_books.name LIKE ?", "abc"). Where("`more_extends_books`.`name` LIKE ?", "abc").
Limit(10, 10). Limit(10, 10).
Find(&books) Find(&books)
assert.NoError(t, err) assert.NoError(t, err)
@ -991,9 +991,9 @@ func TestMoreExtends(t *testing.T) {
books = make([]MoreExtendsBooksExtend, 0, len(books)) books = make([]MoreExtendsBooksExtend, 0, len(books))
err = testEngine.Table("more_extends_books"). err = testEngine.Table("more_extends_books").
Alias("m"). Alias("m").
Select("m.*, more_extends_users.*"). Select("`m`.*, `more_extends_users`.*").
Join("INNER", "more_extends_users", "m.user_id = more_extends_users.id"). Join("INNER", "more_extends_users", "`m`.`user_id` = `more_extends_users`.`id`").
Where("m.name LIKE ?", "abc"). Where("`m`.`name` LIKE ?", "abc").
Limit(10, 10). Limit(10, 10).
Find(&books) Find(&books)
assert.NoError(t, err) assert.NoError(t, err)
@ -1038,11 +1038,11 @@ func TestUpdateFind(t *testing.T) {
} }
_, err := session.Insert(&tuf) _, err := session.Insert(&tuf)
assert.NoError(t, err) assert.NoError(t, err)
_, err = session.Where("id = ?", tuf.Id).Update(&TestUpdateFind{}) _, err = session.Where("`id` = ?", tuf.Id).Update(&TestUpdateFind{})
assert.EqualError(t, xorm.ErrNoColumnsTobeUpdated, err.Error()) assert.EqualError(t, xorm.ErrNoColumnsTobeUpdated, err.Error())
var tufs []TestUpdateFind var tufs []TestUpdateFind
err = session.Where("id = ?", tuf.Id).Find(&tufs) err = session.Where("`id` = ?", tuf.Id).Find(&tufs)
assert.NoError(t, err) assert.NoError(t, err)
} }

View File

@ -15,6 +15,7 @@ import (
"xorm.io/xorm" "xorm.io/xorm"
"xorm.io/xorm/contexts" "xorm.io/xorm/contexts"
"xorm.io/xorm/convert" "xorm.io/xorm/convert"
"xorm.io/xorm/dialects"
"xorm.io/xorm/schemas" "xorm.io/xorm/schemas"
"github.com/shopspring/decimal" "github.com/shopspring/decimal"
@ -55,15 +56,15 @@ func TestGetVar(t *testing.T) {
assert.Equal(t, 28, age) assert.Equal(t, 28, age)
var ageMax int var ageMax int
has, err = testEngine.SQL("SELECT max(age) FROM "+testEngine.TableName("get_var", true)+" WHERE `id` = ?", data.Id).Get(&ageMax) has, err = testEngine.SQL("SELECT max(`age`) FROM "+testEngine.Quote(testEngine.TableName("get_var", true))+" WHERE `id` = ?", data.Id).Get(&ageMax)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, true, has) assert.Equal(t, true, has)
assert.Equal(t, 28, ageMax) assert.Equal(t, 28, ageMax)
var age2 int64 var age2 int64
has, err = testEngine.Table("get_var").Cols("age"). has, err = testEngine.Table("get_var").Cols("age").
Where("age > ?", 20). Where("`age` > ?", 20).
And("age < ?", 30). And("`age` < ?", 30).
Get(&age2) Get(&age2)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, true, has) assert.Equal(t, true, has)
@ -77,8 +78,8 @@ func TestGetVar(t *testing.T) {
var age4 int16 var age4 int16
has, err = testEngine.Table("get_var").Cols("age"). has, err = testEngine.Table("get_var").Cols("age").
Where("age > ?", 20). Where("`age` > ?", 20).
And("age < ?", 30). And("`age` < ?", 30).
Get(&age4) Get(&age4)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, true, has) assert.Equal(t, true, has)
@ -86,8 +87,8 @@ func TestGetVar(t *testing.T) {
var age5 int32 var age5 int32
has, err = testEngine.Table("get_var").Cols("age"). has, err = testEngine.Table("get_var").Cols("age").
Where("age > ?", 20). Where("`age` > ?", 20).
And("age < ?", 30). And("`age` < ?", 30).
Get(&age5) Get(&age5)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, true, has) assert.Equal(t, true, has)
@ -101,8 +102,8 @@ func TestGetVar(t *testing.T) {
var age7 int64 var age7 int64
has, err = testEngine.Table("get_var").Cols("age"). has, err = testEngine.Table("get_var").Cols("age").
Where("age > ?", 20). Where("`age` > ?", 20).
And("age < ?", 30). And("`age` < ?", 30).
Get(&age7) Get(&age7)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, true, has) assert.Equal(t, true, has)
@ -116,8 +117,8 @@ func TestGetVar(t *testing.T) {
var age9 int16 var age9 int16
has, err = testEngine.Table("get_var").Cols("age"). has, err = testEngine.Table("get_var").Cols("age").
Where("age > ?", 20). Where("`age` > ?", 20).
And("age < ?", 30). And("`age` < ?", 30).
Get(&age9) Get(&age9)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, true, has) assert.Equal(t, true, has)
@ -125,8 +126,8 @@ func TestGetVar(t *testing.T) {
var age10 int32 var age10 int32
has, err = testEngine.Table("get_var").Cols("age"). has, err = testEngine.Table("get_var").Cols("age").
Where("age > ?", 20). Where("`age` > ?", 20).
And("age < ?", 30). And("`age` < ?", 30).
Get(&age10) Get(&age10)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, true, has) assert.Equal(t, true, has)
@ -161,16 +162,16 @@ func TestGetVar(t *testing.T) {
var money2 float64 var money2 float64
if testEngine.Dialect().URI().DBType == schemas.MSSQL { if testEngine.Dialect().URI().DBType == schemas.MSSQL {
has, err = testEngine.SQL("SELECT TOP 1 money FROM " + testEngine.TableName("get_var", true)).Get(&money2) has, err = testEngine.SQL("SELECT TOP 1 `money` FROM " + testEngine.Quote(testEngine.TableName("get_var", true))).Get(&money2)
} else { } else {
has, err = testEngine.SQL("SELECT money FROM " + testEngine.TableName("get_var", true) + " LIMIT 1").Get(&money2) has, err = testEngine.SQL("SELECT `money` FROM " + testEngine.Quote(testEngine.TableName("get_var", true)) + " LIMIT 1").Get(&money2)
} }
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, true, has) assert.Equal(t, true, has)
assert.Equal(t, "1.5", fmt.Sprintf("%.1f", money2)) assert.Equal(t, "1.5", fmt.Sprintf("%.1f", money2))
var money3 float64 var money3 float64
has, err = testEngine.SQL("SELECT money FROM " + testEngine.TableName("get_var", true) + " WHERE money > 20").Get(&money3) has, err = testEngine.SQL("SELECT `money` FROM " + testEngine.Quote(testEngine.TableName("get_var", true)) + " WHERE `money` > 20").Get(&money3)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, false, has) assert.Equal(t, false, has)
@ -187,7 +188,7 @@ func TestGetVar(t *testing.T) {
// for mymysql driver, interface{} will be []byte, so ignore it currently // for mymysql driver, interface{} will be []byte, so ignore it currently
if testEngine.DriverName() != "mymysql" { if testEngine.DriverName() != "mymysql" {
var valuesInter = make(map[string]interface{}) var valuesInter = make(map[string]interface{})
has, err = testEngine.Table("get_var").Where("id = ?", 1).Select("*").Get(&valuesInter) has, err = testEngine.Table("get_var").Where("`id` = ?", 1).Select("*").Get(&valuesInter)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, true, has) assert.Equal(t, true, has)
assert.Equal(t, 5, len(valuesInter)) assert.Equal(t, 5, len(valuesInter))
@ -243,7 +244,7 @@ func TestGetStruct(t *testing.T) {
if testEngine.Dialect().URI().DBType == schemas.MSSQL { if testEngine.Dialect().URI().DBType == schemas.MSSQL {
err = session.Begin() err = session.Begin()
assert.NoError(t, err) assert.NoError(t, err)
_, err = session.Exec("SET IDENTITY_INSERT userinfo_get ON") _, err = session.Exec("SET IDENTITY_INSERT `userinfo_get` ON")
assert.NoError(t, err) assert.NoError(t, err)
} }
cnt, err := session.Insert(&UserinfoGet{Uid: 2}) cnt, err := session.Insert(&UserinfoGet{Uid: 2})
@ -300,6 +301,11 @@ func TestGetSlice(t *testing.T) {
func TestGetMap(t *testing.T) { func TestGetMap(t *testing.T) {
assert.NoError(t, PrepareEngine()) assert.NoError(t, PrepareEngine())
if testEngine.Dialect().Features().AutoincrMode == dialects.SequenceAutoincrMode {
t.SkipNow()
return
}
type UserinfoMap struct { type UserinfoMap struct {
Uid int `xorm:"pk autoincr"` Uid int `xorm:"pk autoincr"`
IsMan bool IsMan bool
@ -308,7 +314,7 @@ func TestGetMap(t *testing.T) {
assertSync(t, new(UserinfoMap)) assertSync(t, new(UserinfoMap))
tableName := testEngine.Quote(testEngine.TableName("userinfo_map", true)) tableName := testEngine.Quote(testEngine.TableName("userinfo_map", true))
_, err := testEngine.Exec(fmt.Sprintf("INSERT INTO %s (is_man) VALUES (NULL)", tableName)) _, err := testEngine.Exec(fmt.Sprintf("INSERT INTO %s (`is_man`) VALUES (NULL)", tableName))
assert.NoError(t, err) assert.NoError(t, err)
var valuesString = make(map[string]string) var valuesString = make(map[string]string)
@ -479,7 +485,7 @@ func TestGetStructId(t *testing.T) {
//var id int64 //var id int64
var maxid maxidst var maxid maxidst
sql := "select max(id) as id from " + testEngine.TableName(&TestGetStruct{}, true) sql := "select max(`id`) as id from " + testEngine.Quote(testEngine.TableName(&TestGetStruct{}, true))
has, err := testEngine.SQL(sql).Get(&maxid) has, err := testEngine.SQL(sql).Get(&maxid)
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, has) assert.True(t, has)
@ -597,73 +603,78 @@ func TestGetNullVar(t *testing.T) {
assert.NoError(t, PrepareEngine()) assert.NoError(t, PrepareEngine())
assertSync(t, new(TestGetNullVarStruct)) assertSync(t, new(TestGetNullVarStruct))
affected, err := testEngine.Exec("insert into " + testEngine.TableName(new(TestGetNullVarStruct), true) + " (name,age) values (null,null)") if testEngine.Dialect().Features().AutoincrMode == dialects.SequenceAutoincrMode {
t.SkipNow()
return
}
affected, err := testEngine.Exec("insert into " + testEngine.Quote(testEngine.TableName(new(TestGetNullVarStruct), true)) + " (`name`,`age`) values (null,null)")
assert.NoError(t, err) assert.NoError(t, err)
a, _ := affected.RowsAffected() a, _ := affected.RowsAffected()
assert.EqualValues(t, 1, a) assert.EqualValues(t, 1, a)
var name string var name string
has, err := testEngine.Table(new(TestGetNullVarStruct)).Where("id = ?", 1).Cols("name").Get(&name) has, err := testEngine.Table(new(TestGetNullVarStruct)).Where("`id` = ?", 1).Cols("name").Get(&name)
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, has) assert.True(t, has)
assert.EqualValues(t, "", name) assert.EqualValues(t, "", name)
var age int var age int
has, err = testEngine.Table(new(TestGetNullVarStruct)).Where("id = ?", 1).Cols("age").Get(&age) has, err = testEngine.Table(new(TestGetNullVarStruct)).Where("`id` = ?", 1).Cols("age").Get(&age)
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, has) assert.True(t, has)
assert.EqualValues(t, 0, age) assert.EqualValues(t, 0, age)
var age2 int8 var age2 int8
has, err = testEngine.Table(new(TestGetNullVarStruct)).Where("id = ?", 1).Cols("age").Get(&age2) has, err = testEngine.Table(new(TestGetNullVarStruct)).Where("`id` = ?", 1).Cols("age").Get(&age2)
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, has) assert.True(t, has)
assert.EqualValues(t, 0, age2) assert.EqualValues(t, 0, age2)
var age3 int16 var age3 int16
has, err = testEngine.Table(new(TestGetNullVarStruct)).Where("id = ?", 1).Cols("age").Get(&age3) has, err = testEngine.Table(new(TestGetNullVarStruct)).Where("`id` = ?", 1).Cols("age").Get(&age3)
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, has) assert.True(t, has)
assert.EqualValues(t, 0, age3) assert.EqualValues(t, 0, age3)
var age4 int32 var age4 int32
has, err = testEngine.Table(new(TestGetNullVarStruct)).Where("id = ?", 1).Cols("age").Get(&age4) has, err = testEngine.Table(new(TestGetNullVarStruct)).Where("`id` = ?", 1).Cols("age").Get(&age4)
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, has) assert.True(t, has)
assert.EqualValues(t, 0, age4) assert.EqualValues(t, 0, age4)
var age5 int64 var age5 int64
has, err = testEngine.Table(new(TestGetNullVarStruct)).Where("id = ?", 1).Cols("age").Get(&age5) has, err = testEngine.Table(new(TestGetNullVarStruct)).Where("`id` = ?", 1).Cols("age").Get(&age5)
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, has) assert.True(t, has)
assert.EqualValues(t, 0, age5) assert.EqualValues(t, 0, age5)
var age6 uint var age6 uint
has, err = testEngine.Table(new(TestGetNullVarStruct)).Where("id = ?", 1).Cols("age").Get(&age6) has, err = testEngine.Table(new(TestGetNullVarStruct)).Where("`id` = ?", 1).Cols("age").Get(&age6)
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, has) assert.True(t, has)
assert.EqualValues(t, 0, age6) assert.EqualValues(t, 0, age6)
var age7 uint8 var age7 uint8
has, err = testEngine.Table(new(TestGetNullVarStruct)).Where("id = ?", 1).Cols("age").Get(&age7) has, err = testEngine.Table(new(TestGetNullVarStruct)).Where("`id` = ?", 1).Cols("age").Get(&age7)
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, has) assert.True(t, has)
assert.EqualValues(t, 0, age7) assert.EqualValues(t, 0, age7)
var age8 int16 var age8 int16
has, err = testEngine.Table(new(TestGetNullVarStruct)).Where("id = ?", 1).Cols("age").Get(&age8) has, err = testEngine.Table(new(TestGetNullVarStruct)).Where("`id` = ?", 1).Cols("age").Get(&age8)
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, has) assert.True(t, has)
assert.EqualValues(t, 0, age8) assert.EqualValues(t, 0, age8)
var age9 int32 var age9 int32
has, err = testEngine.Table(new(TestGetNullVarStruct)).Where("id = ?", 1).Cols("age").Get(&age9) has, err = testEngine.Table(new(TestGetNullVarStruct)).Where("`id` = ?", 1).Cols("age").Get(&age9)
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, has) assert.True(t, has)
assert.EqualValues(t, 0, age9) assert.EqualValues(t, 0, age9)
var age10 int64 var age10 int64
has, err = testEngine.Table(new(TestGetNullVarStruct)).Where("id = ?", 1).Cols("age").Get(&age10) has, err = testEngine.Table(new(TestGetNullVarStruct)).Where("`id` = ?", 1).Cols("age").Get(&age10)
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, has) assert.True(t, has)
assert.EqualValues(t, 0, age10) assert.EqualValues(t, 0, age10)
@ -697,7 +708,7 @@ func TestCustomTypes(t *testing.T) {
assert.EqualValues(t, "test", name) assert.EqualValues(t, "test", name)
var age MyInt var age MyInt
has, err = testEngine.Table(new(TestCustomizeStruct)).ID(s.Id).Select("age").Get(&age) has, err = testEngine.Table(new(TestCustomizeStruct)).ID(s.Id).Select("`age`").Get(&age)
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, has) assert.True(t, has)
assert.EqualValues(t, 32, age) assert.EqualValues(t, 32, age)
@ -759,7 +770,7 @@ func TestGetBigFloat(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
var m big.Float var m big.Float
has, err := testEngine.Table("get_big_float").Cols("money").Where("id=?", gf.Id).Get(&m) has, err := testEngine.Table("get_big_float").Cols("money").Where("`id`=?", gf.Id).Get(&m)
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, has) assert.True(t, has)
assert.True(t, m.String() == gf.Money.String(), "%v != %v", m.String(), gf.Money.String()) assert.True(t, m.String() == gf.Money.String(), "%v != %v", m.String(), gf.Money.String())
@ -785,7 +796,7 @@ func TestGetBigFloat(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
var m2 big.Float var m2 big.Float
has, err := testEngine.Table("get_big_float2").Cols("money").Where("id=?", gf2.Id).Get(&m2) has, err := testEngine.Table("get_big_float2").Cols("money").Where("`id`=?", gf2.Id).Get(&m2)
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, has) assert.True(t, has)
assert.True(t, m2.String() == gf2.Money.String(), "%v != %v", m2.String(), gf2.Money.String()) assert.True(t, m2.String() == gf2.Money.String(), "%v != %v", m2.String(), gf2.Money.String())
@ -825,7 +836,7 @@ func TestGetDecimal(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
var m decimal.Decimal var m decimal.Decimal
has, err := testEngine.Table("get_decimal").Cols("money").Where("id=?", gf.Id).Get(&m) has, err := testEngine.Table("get_decimal").Cols("money").Where("`id`=?", gf.Id).Get(&m)
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, has) assert.True(t, has)
assert.True(t, m.String() == gf.Money.String(), "%v != %v", m.String(), gf.Money.String()) assert.True(t, m.String() == gf.Money.String(), "%v != %v", m.String(), gf.Money.String())
@ -850,7 +861,7 @@ func TestGetDecimal(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
var m decimal.Decimal var m decimal.Decimal
has, err := testEngine.Table("get_decimal2").Cols("money").Where("id=?", gf.Id).Get(&m) has, err := testEngine.Table("get_decimal2").Cols("money").Where("`id`=?", gf.Id).Get(&m)
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, has) assert.True(t, has)
assert.True(t, m.String() == gf.Money.String(), "%v != %v", m.String(), gf.Money.String()) assert.True(t, m.String() == gf.Money.String(), "%v != %v", m.String(), gf.Money.String())

View File

@ -11,6 +11,7 @@ import (
"time" "time"
"xorm.io/xorm" "xorm.io/xorm"
"xorm.io/xorm/schemas"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -191,8 +192,8 @@ func TestInsertDefault(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, has) assert.True(t, has)
assert.EqualValues(t, -1, di.Status) assert.EqualValues(t, -1, di.Status)
assert.EqualValues(t, di2.Updated.Unix(), di.Updated.Unix()) assert.EqualValues(t, di2.Updated.Unix(), di.Updated.Unix(), di.Updated)
assert.EqualValues(t, di2.Created.Unix(), di.Created.Unix()) assert.EqualValues(t, di2.Created.Unix(), di.Created.Unix(), di.Created)
} }
func TestInsertDefault2(t *testing.T) { func TestInsertDefault2(t *testing.T) {
@ -624,6 +625,11 @@ func TestAnonymousStruct(t *testing.T) {
} }
func TestInsertMap(t *testing.T) { func TestInsertMap(t *testing.T) {
if testEngine.Dialect().URI().DBType == schemas.DAMENG {
t.SkipNow()
return
}
type InsertMap struct { type InsertMap struct {
Id int64 Id int64
Width uint32 Width uint32
@ -727,7 +733,7 @@ func TestInsertWhere(t *testing.T) {
} }
inserted, err := testEngine.SetExpr("`index`", "coalesce(MAX(`index`),0)+1"). inserted, err := testEngine.SetExpr("`index`", "coalesce(MAX(`index`),0)+1").
Where("repo_id=?", 1). Where("`repo_id`=?", 1).
Insert(&i) Insert(&i)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 1, inserted) assert.EqualValues(t, 1, inserted)
@ -740,7 +746,12 @@ func TestInsertWhere(t *testing.T) {
i.Index = 1 i.Index = 1
assert.EqualValues(t, i, j) assert.EqualValues(t, i, j)
inserted, err = testEngine.Table(new(InsertWhere)).Where("repo_id=?", 1). if testEngine.Dialect().URI().DBType == schemas.DAMENG {
t.SkipNow()
return
}
inserted, err = testEngine.Table(new(InsertWhere)).Where("`repo_id`=?", 1).
SetExpr("`index`", "coalesce(MAX(`index`),0)+1"). SetExpr("`index`", "coalesce(MAX(`index`),0)+1").
Insert(map[string]interface{}{ Insert(map[string]interface{}{
"repo_id": 1, "repo_id": 1,
@ -761,7 +772,7 @@ func TestInsertWhere(t *testing.T) {
assert.EqualValues(t, "trest2", j2.Name) assert.EqualValues(t, "trest2", j2.Name)
assert.EqualValues(t, 2, j2.Index) assert.EqualValues(t, 2, j2.Index)
inserted, err = testEngine.Table(new(InsertWhere)).Where("repo_id=?", 1). inserted, err = testEngine.Table(new(InsertWhere)).Where("`repo_id`=?", 1).
SetExpr("`index`", "coalesce(MAX(`index`),0)+1"). SetExpr("`index`", "coalesce(MAX(`index`),0)+1").
SetExpr("repo_id", "1"). SetExpr("repo_id", "1").
Insert(map[string]string{ Insert(map[string]string{
@ -777,7 +788,7 @@ func TestInsertWhere(t *testing.T) {
assert.EqualValues(t, "trest3", j3.Name) assert.EqualValues(t, "trest3", j3.Name)
assert.EqualValues(t, 3, j3.Index) assert.EqualValues(t, 3, j3.Index)
inserted, err = testEngine.Table(new(InsertWhere)).Where("repo_id=?", 1). inserted, err = testEngine.Table(new(InsertWhere)).Where("`repo_id`=?", 1).
SetExpr("`index`", "coalesce(MAX(`index`),0)+1"). SetExpr("`index`", "coalesce(MAX(`index`),0)+1").
Insert(map[string]interface{}{ Insert(map[string]interface{}{
"repo_id": 1, "repo_id": 1,
@ -793,7 +804,7 @@ func TestInsertWhere(t *testing.T) {
assert.EqualValues(t, "10';delete * from insert_where; --", j4.Name) assert.EqualValues(t, "10';delete * from insert_where; --", j4.Name)
assert.EqualValues(t, 4, j4.Index) assert.EqualValues(t, 4, j4.Index)
inserted, err = testEngine.Table(new(InsertWhere)).Where("repo_id=?", 1). inserted, err = testEngine.Table(new(InsertWhere)).Where("`repo_id`=?", 1).
SetExpr("`index`", "coalesce(MAX(`index`),0)+1"). SetExpr("`index`", "coalesce(MAX(`index`),0)+1").
Insert(map[string]interface{}{ Insert(map[string]interface{}{
"repo_id": 1, "repo_id": 1,
@ -846,6 +857,11 @@ func TestInsertExpr2(t *testing.T) {
assert.EqualValues(t, 1, ie2.RepoId) assert.EqualValues(t, 1, ie2.RepoId)
assert.EqualValues(t, true, ie2.IsTag) assert.EqualValues(t, true, ie2.IsTag)
if testEngine.Dialect().URI().DBType == schemas.DAMENG {
t.SkipNow()
return
}
inserted, err = testEngine.Table(new(InsertExprsRelease)). inserted, err = testEngine.Table(new(InsertExprsRelease)).
SetExpr("is_draft", true). SetExpr("is_draft", true).
SetExpr("num_commits", 0). SetExpr("num_commits", 0).
@ -1067,6 +1083,11 @@ func TestInsertDeleted(t *testing.T) {
} }
func TestInsertMultipleMap(t *testing.T) { func TestInsertMultipleMap(t *testing.T) {
if testEngine.Dialect().URI().DBType == schemas.DAMENG {
t.SkipNow()
return
}
type InsertMultipleMap struct { type InsertMultipleMap struct {
Id int64 Id int64
Width uint32 Width uint32

View File

@ -91,7 +91,7 @@ func TestBufferIterate(t *testing.T) {
assert.EqualValues(t, 7, cnt) assert.EqualValues(t, 7, cnt)
cnt = 0 cnt = 0
err = testEngine.Where("id <= 10").BufferSize(2).Iterate(new(UserBufferIterate), func(i int, bean interface{}) error { err = testEngine.Where("`id` <= 10").BufferSize(2).Iterate(new(UserBufferIterate), func(i int, bean interface{}) error {
user := bean.(*UserBufferIterate) user := bean.(*UserBufferIterate)
assert.EqualValues(t, cnt+1, user.Id) assert.EqualValues(t, cnt+1, user.Id)
assert.EqualValues(t, true, user.IsMan) assert.EqualValues(t, true, user.IsMan)

View File

@ -5,7 +5,6 @@
package integrations package integrations
import ( import (
"fmt"
"strconv" "strconv"
"testing" "testing"
"time" "time"
@ -37,7 +36,7 @@ func TestQueryString(t *testing.T) {
_, err := testEngine.InsertOne(data) _, err := testEngine.InsertOne(data)
assert.NoError(t, err) assert.NoError(t, err)
records, err := testEngine.QueryString("select * from " + testEngine.TableName("get_var2", true)) records, err := testEngine.QueryString("select * from " + testEngine.Quote(testEngine.TableName("get_var2", true)))
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, 1, len(records)) assert.Equal(t, 1, len(records))
assert.Equal(t, 5, len(records[0])) assert.Equal(t, 5, len(records[0]))
@ -63,7 +62,7 @@ func TestQueryString2(t *testing.T) {
_, err := testEngine.Insert(data) _, err := testEngine.Insert(data)
assert.NoError(t, err) assert.NoError(t, err)
records, err := testEngine.QueryString("select * from " + testEngine.TableName("get_var3", true)) records, err := testEngine.QueryString("select * from " + testEngine.Quote(testEngine.TableName("get_var3", true)))
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, 1, len(records)) assert.Equal(t, 1, len(records))
assert.Equal(t, 2, len(records[0])) assert.Equal(t, 2, len(records[0]))
@ -71,42 +70,6 @@ func TestQueryString2(t *testing.T) {
assert.True(t, "0" == records[0]["msg"] || "false" == records[0]["msg"]) assert.True(t, "0" == records[0]["msg"] || "false" == records[0]["msg"])
} }
func toString(i interface{}) string {
switch i.(type) {
case []byte:
return string(i.([]byte))
case string:
return i.(string)
}
return fmt.Sprintf("%v", i)
}
func toInt64(i interface{}) int64 {
switch i.(type) {
case []byte:
n, _ := strconv.ParseInt(string(i.([]byte)), 10, 64)
return n
case int:
return int64(i.(int))
case int64:
return i.(int64)
}
return 0
}
func toFloat64(i interface{}) float64 {
switch i.(type) {
case []byte:
n, _ := strconv.ParseFloat(string(i.([]byte)), 64)
return n
case float64:
return i.(float64)
case float32:
return float64(i.(float32))
}
return 0
}
func toBool(i interface{}) bool { func toBool(i interface{}) bool {
switch t := i.(type) { switch t := i.(type) {
case int32: case int32:
@ -138,7 +101,7 @@ func TestQueryInterface(t *testing.T) {
_, err := testEngine.InsertOne(data) _, err := testEngine.InsertOne(data)
assert.NoError(t, err) assert.NoError(t, err)
records, err := testEngine.QueryInterface("select * from " + testEngine.TableName("get_var_interface", true)) records, err := testEngine.QueryInterface("select * from " + testEngine.Quote(testEngine.TableName("get_var_interface", true)))
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, 1, len(records)) assert.Equal(t, 1, len(records))
assert.Equal(t, 5, len(records[0])) assert.Equal(t, 5, len(records[0]))
@ -192,7 +155,7 @@ func TestQueryNoParams(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
assertResult(t, results) assertResult(t, results)
results, err = testEngine.SQL("select * from " + testEngine.TableName("query_no_params", true)).Query() results, err = testEngine.SQL("select * from " + testEngine.Quote(testEngine.TableName("query_no_params", true))).Query()
assert.NoError(t, err) assert.NoError(t, err)
assertResult(t, results) assertResult(t, results)
} }
@ -223,7 +186,7 @@ func TestQueryStringNoParam(t *testing.T) {
assert.EqualValues(t, "0", records[0]["msg"]) assert.EqualValues(t, "0", records[0]["msg"])
} }
records, err = testEngine.Table("get_var4").Where(builder.Eq{"id": 1}).QueryString() records, err = testEngine.Table("get_var4").Where(builder.Eq{"`id`": 1}).QueryString()
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 1, len(records)) assert.EqualValues(t, 1, len(records))
assert.EqualValues(t, "1", records[0]["id"]) assert.EqualValues(t, "1", records[0]["id"])
@ -260,7 +223,7 @@ func TestQuerySliceStringNoParam(t *testing.T) {
assert.EqualValues(t, "0", records[0][1]) assert.EqualValues(t, "0", records[0][1])
} }
records, err = testEngine.Table("get_var6").Where(builder.Eq{"id": 1}).QuerySliceString() records, err = testEngine.Table("get_var6").Where(builder.Eq{"`id`": 1}).QuerySliceString()
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 1, len(records)) assert.EqualValues(t, 1, len(records))
assert.EqualValues(t, "1", records[0][0]) assert.EqualValues(t, "1", records[0][0])
@ -293,7 +256,7 @@ func TestQueryInterfaceNoParam(t *testing.T) {
assert.EqualValues(t, 1, records[0]["id"]) assert.EqualValues(t, 1, records[0]["id"])
assert.False(t, toBool(records[0]["msg"])) assert.False(t, toBool(records[0]["msg"]))
records, err = testEngine.Table("get_var5").Where(builder.Eq{"id": 1}).QueryInterface() records, err = testEngine.Table("get_var5").Where(builder.Eq{"`id`": 1}).QueryInterface()
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 1, len(records)) assert.EqualValues(t, 1, len(records))
assert.EqualValues(t, 1, records[0]["id"]) assert.EqualValues(t, 1, records[0]["id"])
@ -340,7 +303,7 @@ func TestQueryWithBuilder(t *testing.T) {
assert.EqualValues(t, 3000, money) assert.EqualValues(t, 3000, money)
} }
results, err := testEngine.Query(builder.Select("*").From(testEngine.TableName("query_with_builder", true))) results, err := testEngine.Query(builder.Select("*").From(testEngine.Quote(testEngine.TableName("query_with_builder", true))))
assert.NoError(t, err) assert.NoError(t, err)
assertResult(t, results) assertResult(t, results)
} }
@ -383,14 +346,14 @@ func TestJoinWithSubQuery(t *testing.T) {
tbName := testEngine.Quote(testEngine.TableName("join_with_sub_query_depart", true)) tbName := testEngine.Quote(testEngine.TableName("join_with_sub_query_depart", true))
var querys []JoinWithSubQuery1 var querys []JoinWithSubQuery1
err = testEngine.Join("INNER", builder.Select("id").From(tbName), err = testEngine.Join("INNER", builder.Select("`id`").From(tbName),
"join_with_sub_query_depart.id = join_with_sub_query1.depart_id").Find(&querys) "`join_with_sub_query_depart`.`id` = `join_with_sub_query1`.`depart_id`").Find(&querys)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 1, len(querys)) assert.EqualValues(t, 1, len(querys))
assert.EqualValues(t, q, querys[0]) assert.EqualValues(t, q, querys[0])
querys = make([]JoinWithSubQuery1, 0, 1) querys = make([]JoinWithSubQuery1, 0, 1)
err = testEngine.Join("INNER", "(SELECT id FROM "+tbName+") join_with_sub_query_depart", "join_with_sub_query_depart.id = join_with_sub_query1.depart_id"). err = testEngine.Join("INNER", "(SELECT `id` FROM "+tbName+") `a`", "`a`.`id` = `join_with_sub_query1`.`depart_id`").
Find(&querys) Find(&querys)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 1, len(querys)) assert.EqualValues(t, 1, len(querys))

View File

@ -22,13 +22,13 @@ func TestExecAndQuery(t *testing.T) {
assert.NoError(t, testEngine.Sync2(new(UserinfoQuery))) assert.NoError(t, testEngine.Sync2(new(UserinfoQuery)))
res, err := testEngine.Exec("INSERT INTO "+testEngine.TableName("`userinfo_query`", true)+" (uid, name) VALUES (?, ?)", 1, "user") res, err := testEngine.Exec("INSERT INTO "+testEngine.TableName("`userinfo_query`", true)+" (`uid`, `name`) VALUES (?, ?)", 1, "user")
assert.NoError(t, err) assert.NoError(t, err)
cnt, err := res.RowsAffected() cnt, err := res.RowsAffected()
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 1, cnt) assert.EqualValues(t, 1, cnt)
results, err := testEngine.Query("select * from " + testEngine.TableName("userinfo_query", true)) results, err := testEngine.Query("select * from " + testEngine.Quote(testEngine.TableName("userinfo_query", true)))
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 1, len(results)) assert.EqualValues(t, 1, len(results))
id, err := strconv.Atoi(string(results[0]["uid"])) id, err := strconv.Atoi(string(results[0]["uid"]))
@ -48,19 +48,19 @@ func TestExecTime(t *testing.T) {
assert.NoError(t, testEngine.Sync2(new(UserinfoExecTime))) assert.NoError(t, testEngine.Sync2(new(UserinfoExecTime)))
now := time.Now() now := time.Now()
res, err := testEngine.Exec("INSERT INTO "+testEngine.TableName("`userinfo_exec_time`", true)+" (uid, name, created) VALUES (?, ?, ?)", 1, "user", now) res, err := testEngine.Exec("INSERT INTO "+testEngine.TableName("`userinfo_exec_time`", true)+" (`uid`, `name`, `created`) VALUES (?, ?, ?)", 1, "user", now)
assert.NoError(t, err) assert.NoError(t, err)
cnt, err := res.RowsAffected() cnt, err := res.RowsAffected()
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 1, cnt) assert.EqualValues(t, 1, cnt)
results, err := testEngine.QueryString("SELECT * FROM " + testEngine.TableName("`userinfo_exec_time`", true)) results, err := testEngine.QueryString("SELECT * FROM " + testEngine.Quote(testEngine.TableName("userinfo_exec_time", true)))
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 1, len(results)) assert.EqualValues(t, 1, len(results))
assert.EqualValues(t, now.In(testEngine.GetTZLocation()).Format("2006-01-02 15:04:05"), results[0]["created"]) assert.EqualValues(t, now.In(testEngine.GetTZLocation()).Format("2006-01-02 15:04:05"), results[0]["created"])
var uet UserinfoExecTime var uet UserinfoExecTime
has, err := testEngine.Where("uid=?", 1).Get(&uet) has, err := testEngine.Where("`uid`=?", 1).Get(&uet)
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, has) assert.True(t, has)
assert.EqualValues(t, now.In(testEngine.GetTZLocation()).Format("2006-01-02 15:04:05"), uet.Created.Format("2006-01-02 15:04:05")) assert.EqualValues(t, now.In(testEngine.GetTZLocation()).Format("2006-01-02 15:04:05"), uet.Created.Format("2006-01-02 15:04:05"))

View File

@ -526,8 +526,9 @@ func TestModifyColum(t *testing.T) {
SQLType: schemas.SQLType{ SQLType: schemas.SQLType{
Name: "VARCHAR", Name: "VARCHAR",
}, },
Length: 16, Length: 16,
Nullable: false, Nullable: false,
DefaultIsEmpty: true,
}) })
_, err := testEngine.Exec(alterSQL) _, err := testEngine.Exec(alterSQL)
assert.NoError(t, err) assert.NoError(t, err)

View File

@ -18,7 +18,7 @@ func TestClose(t *testing.T) {
sess1.Close() sess1.Close()
assert.True(t, sess1.IsClosed()) assert.True(t, sess1.IsClosed())
sess2 := testEngine.Where("a = ?", 1) sess2 := testEngine.Where("`a` = ?", 1)
sess2.Close() sess2.Close()
assert.True(t, sess2.IsClosed()) assert.True(t, sess2.IsClosed())
} }

View File

@ -37,7 +37,7 @@ func TestTransaction(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
user2 := Userinfo{Username: "yyy"} user2 := Userinfo{Username: "yyy"}
_, err = session.Where("id = ?", 0).Update(&user2) _, err = session.Where("`id` = ?", 0).Update(&user2)
assert.NoError(t, err) assert.NoError(t, err)
_, err = session.Delete(&user2) _, err = session.Delete(&user2)
@ -70,10 +70,10 @@ func TestCombineTransaction(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
user2 := Userinfo{Username: "zzz"} user2 := Userinfo{Username: "zzz"}
_, err = session.Where("id = ?", 0).Update(&user2) _, err = session.Where("`id` = ?", 0).Update(&user2)
assert.NoError(t, err) assert.NoError(t, err)
_, err = session.Exec("delete from "+testEngine.TableName("userinfo", true)+" where username = ?", user2.Username) _, err = session.Exec("delete from "+testEngine.Quote(testEngine.TableName("userinfo", true))+" where `username` = ?", user2.Username)
assert.NoError(t, err) assert.NoError(t, err)
err = session.Commit() err = session.Commit()
@ -113,10 +113,10 @@ func TestCombineTransactionSameMapper(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
user2 := Userinfo{Username: "zzz"} user2 := Userinfo{Username: "zzz"}
_, err = session.Where("id = ?", 0).Update(&user2) _, err = session.Where("`id` = ?", 0).Update(&user2)
assert.NoError(t, err) assert.NoError(t, err)
_, err = session.Exec("delete from "+testEngine.TableName("`Userinfo`", true)+" where `Username` = ?", user2.Username) _, err = session.Exec("delete from "+testEngine.Quote(testEngine.TableName("Userinfo", true))+" where `Username` = ?", user2.Username)
assert.NoError(t, err) assert.NoError(t, err)
err = session.Commit() err = session.Commit()
@ -144,7 +144,7 @@ func TestMultipleTransaction(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
user2 := MultipleTransaction{Name: "zzz"} user2 := MultipleTransaction{Name: "zzz"}
_, err = session.Where("id = ?", 0).Update(&user2) _, err = session.Where("`id` = ?", 0).Update(&user2)
assert.NoError(t, err) assert.NoError(t, err)
err = session.Commit() err = session.Commit()
@ -158,7 +158,7 @@ func TestMultipleTransaction(t *testing.T) {
err = session.Begin() err = session.Begin()
assert.NoError(t, err) assert.NoError(t, err)
_, err = session.Where("id=?", m1.Id).Delete(new(MultipleTransaction)) _, err = session.Where("`id`=?", m1.Id).Delete(new(MultipleTransaction))
assert.NoError(t, err) assert.NoError(t, err)
err = session.Commit() err = session.Commit()

View File

@ -35,7 +35,7 @@ func TestUpdateMap(t *testing.T) {
_, err := testEngine.Insert(&tb) _, err := testEngine.Insert(&tb)
assert.NoError(t, err) assert.NoError(t, err)
cnt, err := testEngine.Table("update_table").Where("id = ?", tb.Id).Update(map[string]interface{}{ cnt, err := testEngine.Table("update_table").Where("`id` = ?", tb.Id).Update(map[string]interface{}{
"name": "test2", "name": "test2",
"age": 36, "age": 36,
}) })
@ -93,7 +93,12 @@ func TestUpdateLimit(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 1, cnt) assert.EqualValues(t, 1, cnt)
cnt, err = testEngine.OrderBy("name desc").Limit(1).Update(&UpdateTable2{ if testEngine.Dialect().URI().DBType == schemas.DAMENG {
t.SkipNow()
return
}
cnt, err = testEngine.OrderBy("`name` desc").Limit(1).Update(&UpdateTable2{
Age: 30, Age: 30,
}) })
assert.NoError(t, err) assert.NoError(t, err)
@ -166,7 +171,7 @@ func TestForUpdate(t *testing.T) {
// use lock // use lock
fList := make([]ForUpdate, 0) fList := make([]ForUpdate, 0)
session1.ForUpdate() session1.ForUpdate()
session1.Where("id = ?", 1) session1.Where("`id` = ?", 1)
err = session1.Find(&fList) err = session1.Find(&fList)
switch { switch {
case err != nil: case err != nil:
@ -187,7 +192,7 @@ func TestForUpdate(t *testing.T) {
wg.Add(1) wg.Add(1)
go func() { go func() {
f2 := new(ForUpdate) f2 := new(ForUpdate)
session2.Where("id = ?", 1).ForUpdate() session2.Where("`id` = ?", 1).ForUpdate()
has, err := session2.Get(f2) // wait release lock has, err := session2.Get(f2) // wait release lock
switch { switch {
case err != nil: case err != nil:
@ -207,7 +212,7 @@ func TestForUpdate(t *testing.T) {
wg2.Add(1) wg2.Add(1)
go func() { go func() {
f3 := new(ForUpdate) f3 := new(ForUpdate)
session3.Where("id = ?", 1) session3.Where("`id` = ?", 1)
has, err := session3.Get(f3) // wait release lock has, err := session3.Get(f3) // wait release lock
switch { switch {
case err != nil: case err != nil:
@ -225,7 +230,7 @@ func TestForUpdate(t *testing.T) {
f := new(ForUpdate) f := new(ForUpdate)
f.Name = "updated by session1" f.Name = "updated by session1"
session1.Where("id = ?", 1) session1.Where("`id` = ?", 1)
session1.Update(f) session1.Update(f)
// release lock // release lock
@ -300,7 +305,7 @@ func TestUpdateMap2(t *testing.T) {
assert.NoError(t, PrepareEngine()) assert.NoError(t, PrepareEngine())
assertSync(t, new(UpdateMustCols)) assertSync(t, new(UpdateMustCols))
_, err := testEngine.Table("update_must_cols").Where("id =?", 1).Update(map[string]interface{}{ _, err := testEngine.Table("update_must_cols").Where("`id` =?", 1).Update(map[string]interface{}{
"bool": true, "bool": true,
}) })
assert.NoError(t, err) assert.NoError(t, err)
@ -345,11 +350,11 @@ func TestUpdate1(t *testing.T) {
userID := user.Uid userID := user.Uid
has, err := testEngine.ID(userID). has, err := testEngine.ID(userID).
And("username = ?", user.Username). And("`username` = ?", user.Username).
And("height = ?", user.Height). And("`height` = ?", user.Height).
And("departname = ?", ""). And("`departname` = ?", "").
And("detail_id = ?", 0). And("`detail_id` = ?", 0).
And("is_man = ?", false). And("`is_man` = ?", false).
Get(&Userinfo{}) Get(&Userinfo{})
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, has, "cannot insert properly") assert.True(t, has, "cannot insert properly")
@ -362,12 +367,12 @@ func TestUpdate1(t *testing.T) {
assert.EqualValues(t, 1, cnt, "update not returned 1") assert.EqualValues(t, 1, cnt, "update not returned 1")
has, err = testEngine.ID(userID). has, err = testEngine.ID(userID).
And("username = ?", updatedUser.Username). And("`username` = ?", updatedUser.Username).
And("height IS NULL"). And("`height` IS NULL").
And("departname IS NULL"). And("`departname` IS NULL").
And("is_man IS NULL"). And("`is_man` IS NULL").
And("created IS NULL"). And("`created` IS NULL").
And("detail_id = ?", 0). And("`detail_id` = ?", 0).
Get(&Userinfo{}) Get(&Userinfo{})
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, has, "cannot update with null properly") assert.True(t, has, "cannot update with null properly")
@ -825,7 +830,7 @@ func TestNewUpdate(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 0, af) assert.EqualValues(t, 0, af)
af, err = testEngine.Table(new(TbUserInfo)).Where("phone=?", "13126564922").Update(&changeUsr) af, err = testEngine.Table(new(TbUserInfo)).Where("`phone`=?", "13126564922").Update(&changeUsr)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 0, af) assert.EqualValues(t, 0, af)
} }
@ -1166,7 +1171,7 @@ func TestUpdateExprs(t *testing.T) {
}) })
assert.NoError(t, err) assert.NoError(t, err)
_, err = testEngine.SetExpr("num_issues", "num_issues+1").AllCols().Update(&UpdateExprs{ _, err = testEngine.SetExpr("num_issues", "`num_issues`+1").AllCols().Update(&UpdateExprs{
NumIssues: 3, NumIssues: 3,
Name: "lunny xiao", Name: "lunny xiao",
}) })
@ -1197,7 +1202,7 @@ func TestUpdateAlias(t *testing.T) {
}) })
assert.NoError(t, err) assert.NoError(t, err)
_, err = testEngine.Alias("ua").Where("ua.id = ?", 1).Update(&UpdateAlias{ _, err = testEngine.Alias("ua").Where("ua.`id` = ?", 1).Update(&UpdateAlias{
NumIssues: 2, NumIssues: 2,
Name: "lunny xiao", Name: "lunny xiao",
}) })
@ -1237,7 +1242,7 @@ func TestUpdateExprs2(t *testing.T) {
assert.EqualValues(t, 1, inserted) assert.EqualValues(t, 1, inserted)
updated, err := testEngine. updated, err := testEngine.
Where("repo_id = ? AND is_tag = ?", 1, false). Where("`repo_id` = ? AND `is_tag` = ?", 1, false).
SetExpr("is_draft", true). SetExpr("is_draft", true).
SetExpr("num_commits", 0). SetExpr("num_commits", 0).
SetExpr("sha1", ""). SetExpr("sha1", "").
@ -1257,6 +1262,11 @@ func TestUpdateExprs2(t *testing.T) {
} }
func TestUpdateMap3(t *testing.T) { func TestUpdateMap3(t *testing.T) {
if testEngine.Dialect().URI().DBType == schemas.DAMENG {
t.SkipNow()
return
}
assert.NoError(t, PrepareEngine()) assert.NoError(t, PrepareEngine())
type UpdateMapUser struct { type UpdateMapUser struct {
@ -1308,7 +1318,7 @@ func TestUpdateIgnoreOnlyFromDBFields(t *testing.T) {
assertGetRecord := func() *TestOnlyFromDBField { assertGetRecord := func() *TestOnlyFromDBField {
var record TestOnlyFromDBField var record TestOnlyFromDBField
has, err := testEngine.Where("id = ?", 1).Get(&record) has, err := testEngine.Where("`id` = ?", 1).Get(&record)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, true, has) assert.EqualValues(t, true, has)
assert.EqualValues(t, "", record.OnlyFromDBField) assert.EqualValues(t, "", record.OnlyFromDBField)

View File

@ -458,7 +458,7 @@ func TestExtends5(t *testing.T) {
list := make([]Book, 0) list := make([]Book, 0)
err = session. err = session.
Select(fmt.Sprintf( Select(fmt.Sprintf(
"%s.%s, sc.%s AS %s, sc.%s AS %s, s.%s, s.%s", "%s.%s, `sc`.%s AS %s, `sc`.%s AS %s, `s`.%s, `s`.%s",
quote(bookTableName), quote(bookTableName),
quote("id"), quote("id"),
quote("Width"), quote("Width"),
@ -472,12 +472,12 @@ func TestExtends5(t *testing.T) {
Join( Join(
"LEFT", "LEFT",
sizeTableName+" AS `sc`", sizeTableName+" AS `sc`",
bookTableName+".`SizeClosed`=sc.`id`", bookTableName+".`SizeClosed`=`sc`.`id`",
). ).
Join( Join(
"LEFT", "LEFT",
sizeTableName+" AS `s`", sizeTableName+" AS `s`",
bookTableName+".`Size`=s.`id`", bookTableName+".`Size`=`s`.`id`",
). ).
Find(&list) Find(&list)
assert.NoError(t, err) assert.NoError(t, err)
@ -730,7 +730,7 @@ func TestLowerCase(t *testing.T) {
err := testEngine.Sync2(&Lowercase{}) err := testEngine.Sync2(&Lowercase{})
assert.NoError(t, err) assert.NoError(t, err)
_, err = testEngine.Where("id > 0").Delete(&Lowercase{}) _, err = testEngine.Where("`id` > 0").Delete(&Lowercase{})
assert.NoError(t, err) assert.NoError(t, err)
_, err = testEngine.Insert(&Lowercase{ended: 1}) _, err = testEngine.Insert(&Lowercase{ended: 1})

View File

@ -324,7 +324,7 @@ func TestTimeUserDeleted(t *testing.T) {
fmt.Println("user2 str", user2.CreatedAtStr, user2.UpdatedAtStr) fmt.Println("user2 str", user2.CreatedAtStr, user2.UpdatedAtStr)
var user3 UserDeleted var user3 UserDeleted
cnt, err = testEngine.Where("id = ?", "lunny").Delete(&user3) cnt, err = testEngine.Where("`id` = ?", "lunny").Delete(&user3)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 1, cnt) assert.EqualValues(t, 1, cnt)
assert.True(t, !utils.IsTimeZero(user3.DeletedAt)) assert.True(t, !utils.IsTimeZero(user3.DeletedAt))
@ -386,7 +386,7 @@ func TestTimeUserDeletedDiffLoc(t *testing.T) {
fmt.Println("user2", user2.CreatedAt, user2.UpdatedAt, user2.DeletedAt) fmt.Println("user2", user2.CreatedAt, user2.UpdatedAt, user2.DeletedAt)
var user3 UserDeleted2 var user3 UserDeleted2
cnt, err = testEngine.Where("id = ?", "lunny").Delete(&user3) cnt, err = testEngine.Where("`id` = ?", "lunny").Delete(&user3)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 1, cnt) assert.EqualValues(t, 1, cnt)
assert.True(t, !utils.IsTimeZero(user3.DeletedAt)) assert.True(t, !utils.IsTimeZero(user3.DeletedAt))
@ -457,7 +457,7 @@ func TestCustomTimeUserDeleted(t *testing.T) {
fmt.Println("user2", user2.CreatedAt, user2.UpdatedAt, user2.DeletedAt) fmt.Println("user2", user2.CreatedAt, user2.UpdatedAt, user2.DeletedAt)
var user3 UserDeleted3 var user3 UserDeleted3
cnt, err = testEngine.Where("id = ?", "lunny").Delete(&user3) cnt, err = testEngine.Where("`id` = ?", "lunny").Delete(&user3)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 1, cnt) assert.EqualValues(t, 1, cnt)
assert.True(t, !utils.IsTimeZero(time.Time(user3.DeletedAt))) assert.True(t, !utils.IsTimeZero(time.Time(user3.DeletedAt)))
@ -519,7 +519,7 @@ func TestCustomTimeUserDeletedDiffLoc(t *testing.T) {
fmt.Println("user2", user2.CreatedAt, user2.UpdatedAt, user2.DeletedAt) fmt.Println("user2", user2.CreatedAt, user2.UpdatedAt, user2.DeletedAt)
var user3 UserDeleted4 var user3 UserDeleted4
cnt, err = testEngine.Where("id = ?", "lunny").Delete(&user3) cnt, err = testEngine.Where("`id` = ?", "lunny").Delete(&user3)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 1, cnt) assert.EqualValues(t, 1, cnt)
assert.True(t, !utils.IsTimeZero(time.Time(user3.DeletedAt))) assert.True(t, !utils.IsTimeZero(time.Time(user3.DeletedAt)))

View File

@ -15,7 +15,7 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
type NullType struct { type NullStruct struct {
Id int `xorm:"pk autoincr"` Id int `xorm:"pk autoincr"`
Name sql.NullString Name sql.NullString
Age sql.NullInt64 Age sql.NullInt64
@ -65,26 +65,26 @@ func (m CustomStruct) Value() (driver.Value, error) {
func TestCreateNullStructTable(t *testing.T) { func TestCreateNullStructTable(t *testing.T) {
assert.NoError(t, PrepareEngine()) assert.NoError(t, PrepareEngine())
err := testEngine.CreateTables(new(NullType)) err := testEngine.CreateTables(new(NullStruct))
assert.NoError(t, err) assert.NoError(t, err)
} }
func TestDropNullStructTable(t *testing.T) { func TestDropNullStructTable(t *testing.T) {
assert.NoError(t, PrepareEngine()) assert.NoError(t, PrepareEngine())
err := testEngine.DropTables(new(NullType)) err := testEngine.DropTables(new(NullStruct))
assert.NoError(t, err) assert.NoError(t, err)
} }
func TestNullStructInsert(t *testing.T) { func TestNullStructInsert(t *testing.T) {
assert.NoError(t, PrepareEngine()) assert.NoError(t, PrepareEngine())
assertSync(t, new(NullType)) assertSync(t, new(NullStruct))
item1 := new(NullType) item1 := new(NullStruct)
_, err := testEngine.Insert(item1) _, err := testEngine.Insert(item1)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 1, item1.Id) assert.EqualValues(t, 1, item1.Id)
item := NullType{ item := NullStruct{
Name: sql.NullString{String: "haolei", Valid: true}, Name: sql.NullString{String: "haolei", Valid: true},
Age: sql.NullInt64{Int64: 34, Valid: true}, Age: sql.NullInt64{Int64: 34, Valid: true},
Height: sql.NullFloat64{Float64: 1.72, Valid: true}, Height: sql.NullFloat64{Float64: 1.72, Valid: true},
@ -95,9 +95,9 @@ func TestNullStructInsert(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 2, item.Id) assert.EqualValues(t, 2, item.Id)
items := []NullType{} items := []NullStruct{}
for i := 0; i < 5; i++ { for i := 0; i < 5; i++ {
item := NullType{ item := NullStruct{
Name: sql.NullString{String: "haolei_" + fmt.Sprint(i+1), Valid: true}, Name: sql.NullString{String: "haolei_" + fmt.Sprint(i+1), Valid: true},
Age: sql.NullInt64{Int64: 30 + int64(i), Valid: true}, Age: sql.NullInt64{Int64: 30 + int64(i), Valid: true},
Height: sql.NullFloat64{Float64: 1.5 + 1.1*float64(i), Valid: true}, Height: sql.NullFloat64{Float64: 1.5 + 1.1*float64(i), Valid: true},
@ -111,7 +111,7 @@ func TestNullStructInsert(t *testing.T) {
_, err = testEngine.Insert(&items) _, err = testEngine.Insert(&items)
assert.NoError(t, err) assert.NoError(t, err)
items = make([]NullType, 0, 7) items = make([]NullStruct, 0, 7)
err = testEngine.Find(&items) err = testEngine.Find(&items)
assert.NoError(t, err) assert.NoError(t, err)
assert.EqualValues(t, 7, len(items)) assert.EqualValues(t, 7, len(items))
@ -119,9 +119,9 @@ func TestNullStructInsert(t *testing.T) {
func TestNullStructUpdate(t *testing.T) { func TestNullStructUpdate(t *testing.T) {
assert.NoError(t, PrepareEngine()) assert.NoError(t, PrepareEngine())
assertSync(t, new(NullType)) assertSync(t, new(NullStruct))
_, err := testEngine.Insert([]NullType{ _, err := testEngine.Insert([]NullStruct{
{ {
Name: sql.NullString{ Name: sql.NullString{
String: "name1", String: "name1",
@ -150,7 +150,7 @@ func TestNullStructUpdate(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
if true { // 测试可插入NULL if true { // 测试可插入NULL
item := new(NullType) item := new(NullStruct)
item.Age = sql.NullInt64{Int64: 23, Valid: true} item.Age = sql.NullInt64{Int64: 23, Valid: true}
item.Height = sql.NullFloat64{Float64: 0, Valid: false} // update to NULL item.Height = sql.NullFloat64{Float64: 0, Valid: false} // update to NULL
@ -160,7 +160,7 @@ func TestNullStructUpdate(t *testing.T) {
} }
if true { // 测试In update if true { // 测试In update
item := new(NullType) item := new(NullStruct)
item.Age = sql.NullInt64{Int64: 23, Valid: true} item.Age = sql.NullInt64{Int64: 23, Valid: true}
affected, err := testEngine.In("id", 3, 4).Cols("age", "height", "is_man").Update(item) affected, err := testEngine.In("id", 3, 4).Cols("age", "height", "is_man").Update(item)
assert.NoError(t, err) assert.NoError(t, err)
@ -168,17 +168,17 @@ func TestNullStructUpdate(t *testing.T) {
} }
if true { // 测试where if true { // 测试where
item := new(NullType) item := new(NullStruct)
item.Name = sql.NullString{String: "nullname", Valid: true} item.Name = sql.NullString{String: "nullname", Valid: true}
item.IsMan = sql.NullBool{Bool: true, Valid: true} item.IsMan = sql.NullBool{Bool: true, Valid: true}
item.Age = sql.NullInt64{Int64: 34, Valid: true} item.Age = sql.NullInt64{Int64: 34, Valid: true}
_, err := testEngine.Where("age > ?", 34).Update(item) _, err := testEngine.Where("`age` > ?", 34).Update(item)
assert.NoError(t, err) assert.NoError(t, err)
} }
if true { // 修改全部时,插入空值 if true { // 修改全部时,插入空值
item := &NullType{ item := &NullStruct{
Name: sql.NullString{String: "winxxp", Valid: true}, Name: sql.NullString{String: "winxxp", Valid: true},
Age: sql.NullInt64{Int64: 30, Valid: true}, Age: sql.NullInt64{Int64: 30, Valid: true},
Height: sql.NullFloat64{Float64: 1.72, Valid: true}, Height: sql.NullFloat64{Float64: 1.72, Valid: true},
@ -192,9 +192,9 @@ func TestNullStructUpdate(t *testing.T) {
func TestNullStructFind(t *testing.T) { func TestNullStructFind(t *testing.T) {
assert.NoError(t, PrepareEngine()) assert.NoError(t, PrepareEngine())
assertSync(t, new(NullType)) assertSync(t, new(NullStruct))
_, err := testEngine.Insert([]NullType{ _, err := testEngine.Insert([]NullStruct{
{ {
Name: sql.NullString{ Name: sql.NullString{
String: "name1", String: "name1",
@ -223,7 +223,7 @@ func TestNullStructFind(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
if true { if true {
item := new(NullType) item := new(NullStruct)
has, err := testEngine.ID(1).Get(item) has, err := testEngine.ID(1).Get(item)
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, has) assert.True(t, has)
@ -235,7 +235,7 @@ func TestNullStructFind(t *testing.T) {
} }
if true { if true {
item := new(NullType) item := new(NullStruct)
item.Id = 2 item.Id = 2
has, err := testEngine.Get(item) has, err := testEngine.Get(item)
assert.NoError(t, err) assert.NoError(t, err)
@ -243,13 +243,13 @@ func TestNullStructFind(t *testing.T) {
} }
if true { if true {
item := make([]NullType, 0) item := make([]NullStruct, 0)
err := testEngine.ID(2).Find(&item) err := testEngine.ID(2).Find(&item)
assert.NoError(t, err) assert.NoError(t, err)
} }
if true { if true {
item := make([]NullType, 0) item := make([]NullStruct, 0)
err := testEngine.Asc("age").Find(&item) err := testEngine.Asc("age").Find(&item)
assert.NoError(t, err) assert.NoError(t, err)
} }
@ -257,12 +257,12 @@ func TestNullStructFind(t *testing.T) {
func TestNullStructIterate(t *testing.T) { func TestNullStructIterate(t *testing.T) {
assert.NoError(t, PrepareEngine()) assert.NoError(t, PrepareEngine())
assertSync(t, new(NullType)) assertSync(t, new(NullStruct))
if true { if true {
err := testEngine.Where("age IS NOT NULL").OrderBy("age").Iterate(new(NullType), err := testEngine.Where("`age` IS NOT NULL").OrderBy("age").Iterate(new(NullStruct),
func(i int, bean interface{}) error { func(i int, bean interface{}) error {
nultype := bean.(*NullType) nultype := bean.(*NullStruct)
fmt.Println(i, nultype) fmt.Println(i, nultype)
return nil return nil
}) })
@ -272,21 +272,21 @@ func TestNullStructIterate(t *testing.T) {
func TestNullStructCount(t *testing.T) { func TestNullStructCount(t *testing.T) {
assert.NoError(t, PrepareEngine()) assert.NoError(t, PrepareEngine())
assertSync(t, new(NullType)) assertSync(t, new(NullStruct))
if true { if true {
item := new(NullType) item := new(NullStruct)
_, err := testEngine.Where("age IS NOT NULL").Count(item) _, err := testEngine.Where("`age` IS NOT NULL").Count(item)
assert.NoError(t, err) assert.NoError(t, err)
} }
} }
func TestNullStructRows(t *testing.T) { func TestNullStructRows(t *testing.T) {
assert.NoError(t, PrepareEngine()) assert.NoError(t, PrepareEngine())
assertSync(t, new(NullType)) assertSync(t, new(NullStruct))
item := new(NullType) item := new(NullStruct)
rows, err := testEngine.Where("id > ?", 1).Rows(item) rows, err := testEngine.Where("`id` > ?", 1).Rows(item)
assert.NoError(t, err) assert.NoError(t, err)
defer rows.Close() defer rows.Close()
@ -298,13 +298,13 @@ func TestNullStructRows(t *testing.T) {
func TestNullStructDelete(t *testing.T) { func TestNullStructDelete(t *testing.T) {
assert.NoError(t, PrepareEngine()) assert.NoError(t, PrepareEngine())
assertSync(t, new(NullType)) assertSync(t, new(NullStruct))
item := new(NullType) item := new(NullStruct)
_, err := testEngine.ID(1).Delete(item) _, err := testEngine.ID(1).Delete(item)
assert.NoError(t, err) assert.NoError(t, err)
_, err = testEngine.Where("id > ?", 1).Delete(item) _, err = testEngine.Where("`id` > ?", 1).Delete(item)
assert.NoError(t, err) assert.NoError(t, err)
} }

View File

@ -428,7 +428,7 @@ func TestUnsignedUint64(t *testing.T) {
assert.EqualValues(t, "INTEGER", tables[0].Columns()[0].SQLType.Name) assert.EqualValues(t, "INTEGER", tables[0].Columns()[0].SQLType.Name)
case schemas.MYSQL: case schemas.MYSQL:
assert.EqualValues(t, "UNSIGNED BIGINT", tables[0].Columns()[0].SQLType.Name) assert.EqualValues(t, "UNSIGNED BIGINT", tables[0].Columns()[0].SQLType.Name)
case schemas.POSTGRES: case schemas.POSTGRES, schemas.DAMENG:
assert.EqualValues(t, "BIGINT", tables[0].Columns()[0].SQLType.Name) assert.EqualValues(t, "BIGINT", tables[0].Columns()[0].SQLType.Name)
case schemas.MSSQL: case schemas.MSSQL:
assert.EqualValues(t, "BIGINT", tables[0].Columns()[0].SQLType.Name) assert.EqualValues(t, "BIGINT", tables[0].Columns()[0].SQLType.Name)
@ -472,9 +472,7 @@ func TestUnsignedUint32(t *testing.T) {
assert.EqualValues(t, "INTEGER", tables[0].Columns()[0].SQLType.Name) assert.EqualValues(t, "INTEGER", tables[0].Columns()[0].SQLType.Name)
case schemas.MYSQL: case schemas.MYSQL:
assert.EqualValues(t, "UNSIGNED INT", tables[0].Columns()[0].SQLType.Name) assert.EqualValues(t, "UNSIGNED INT", tables[0].Columns()[0].SQLType.Name)
case schemas.POSTGRES: case schemas.POSTGRES, schemas.MSSQL, schemas.DAMENG:
assert.EqualValues(t, "BIGINT", tables[0].Columns()[0].SQLType.Name)
case schemas.MSSQL:
assert.EqualValues(t, "BIGINT", tables[0].Columns()[0].SQLType.Name) assert.EqualValues(t, "BIGINT", tables[0].Columns()[0].SQLType.Name)
default: default:
assert.False(t, true, "Unsigned is not implemented") assert.False(t, true, "Unsigned is not implemented")
@ -507,7 +505,7 @@ func TestUnsignedTinyInt(t *testing.T) {
assert.EqualValues(t, 1, len(tables[0].Columns())) assert.EqualValues(t, 1, len(tables[0].Columns()))
switch testEngine.Dialect().URI().DBType { switch testEngine.Dialect().URI().DBType {
case schemas.SQLITE: case schemas.SQLITE, schemas.DAMENG:
assert.EqualValues(t, "INTEGER", tables[0].Columns()[0].SQLType.Name) assert.EqualValues(t, "INTEGER", tables[0].Columns()[0].SQLType.Name)
case schemas.MYSQL: case schemas.MYSQL:
assert.EqualValues(t, "UNSIGNED TINYINT", tables[0].Columns()[0].SQLType.Name) assert.EqualValues(t, "UNSIGNED TINYINT", tables[0].Columns()[0].SQLType.Name)
@ -516,7 +514,7 @@ func TestUnsignedTinyInt(t *testing.T) {
case schemas.MSSQL: case schemas.MSSQL:
assert.EqualValues(t, "INT", tables[0].Columns()[0].SQLType.Name) assert.EqualValues(t, "INT", tables[0].Columns()[0].SQLType.Name)
default: default:
assert.False(t, true, "Unsigned is not implemented") assert.False(t, true, fmt.Sprintf("Unsigned is not implemented, returned %s", tables[0].Columns()[0].SQLType.Name))
} }
cnt, err := testEngine.Insert(&MyUnsignedTinyIntStruct{ cnt, err := testEngine.Insert(&MyUnsignedTinyIntStruct{

View File

@ -10,6 +10,7 @@ import (
"strings" "strings"
"xorm.io/builder" "xorm.io/builder"
"xorm.io/xorm/internal/utils"
"xorm.io/xorm/schemas" "xorm.io/xorm/schemas"
) )
@ -42,7 +43,19 @@ func (statement *Statement) GenInsertSQL(colNames []string, args []interface{})
return "", nil, err return "", nil, err
} }
if len(colNames) <= 0 { var hasInsertColumns = len(colNames) > 0
var needSeq = len(table.AutoIncrement) > 0 && (statement.dialect.URI().DBType == schemas.ORACLE || statement.dialect.URI().DBType == schemas.DAMENG)
if needSeq {
for _, col := range colNames {
if strings.EqualFold(col, table.AutoIncrement) {
needSeq = false
break
}
}
}
if !hasInsertColumns && statement.dialect.URI().DBType != schemas.ORACLE &&
statement.dialect.URI().DBType != schemas.DAMENG {
if statement.dialect.URI().DBType == schemas.MYSQL { if statement.dialect.URI().DBType == schemas.MYSQL {
if _, err := buf.WriteString(" VALUES ()"); err != nil { if _, err := buf.WriteString(" VALUES ()"); err != nil {
return "", nil, err return "", nil, err
@ -60,6 +73,10 @@ func (statement *Statement) GenInsertSQL(colNames []string, args []interface{})
return "", nil, err return "", nil, err
} }
if needSeq {
colNames = append(colNames, table.AutoIncrement)
}
if err := statement.dialect.Quoter().JoinWrite(buf.Builder, append(colNames, exprs.ColNames()...), ","); err != nil { if err := statement.dialect.Quoter().JoinWrite(buf.Builder, append(colNames, exprs.ColNames()...), ","); err != nil {
return "", nil, err return "", nil, err
} }
@ -80,13 +97,23 @@ func (statement *Statement) GenInsertSQL(colNames []string, args []interface{})
return "", nil, err return "", nil, err
} }
if needSeq {
if len(args) > 0 {
if _, err := buf.WriteString(","); err != nil {
return "", nil, err
}
}
if _, err := buf.WriteString(utils.SeqName(tableName) + ".nextval"); err != nil {
return "", nil, err
}
}
if len(exprs) > 0 { if len(exprs) > 0 {
if _, err := buf.WriteString(","); err != nil { if _, err := buf.WriteString(","); err != nil {
return "", nil, err return "", nil, err
} }
} if err := exprs.WriteArgs(buf); err != nil {
if err := exprs.WriteArgs(buf); err != nil { return "", nil, err
return "", nil, err }
} }
if _, err := buf.WriteString(" FROM "); err != nil { if _, err := buf.WriteString(" FROM "); err != nil {
@ -113,6 +140,18 @@ func (statement *Statement) GenInsertSQL(colNames []string, args []interface{})
return "", nil, err return "", nil, err
} }
// Insert tablename (id) Values(seq_tablename.nextval)
if needSeq {
if hasInsertColumns {
if _, err := buf.WriteString(","); err != nil {
return "", nil, err
}
}
if _, err := buf.WriteString(utils.SeqName(tableName) + ".nextval"); err != nil {
return "", nil, err
}
}
if len(exprs) > 0 { if len(exprs) > 0 {
if _, err := buf.WriteString(","); err != nil { if _, err := buf.WriteString(","); err != nil {
return "", nil, err return "", nil, err

View File

@ -539,7 +539,7 @@ func (statement *Statement) Join(joinOP string, tablename interface{}, condition
aliasName := statement.dialect.Quoter().Trim(fields[len(fields)-1]) aliasName := statement.dialect.Quoter().Trim(fields[len(fields)-1])
aliasName = schemas.CommonQuoter.Trim(aliasName) aliasName = schemas.CommonQuoter.Trim(aliasName)
fmt.Fprintf(&buf, "(%s) %s ON %v", statement.ReplaceQuote(subSQL), aliasName, statement.ReplaceQuote(condition)) fmt.Fprintf(&buf, "(%s) %s ON %v", statement.ReplaceQuote(subSQL), statement.quote(aliasName), statement.ReplaceQuote(condition))
statement.joinArgs = append(statement.joinArgs, subQueryArgs...) statement.joinArgs = append(statement.joinArgs, subQueryArgs...)
case *builder.Builder: case *builder.Builder:
subSQL, subQueryArgs, err := tp.ToSQL() subSQL, subQueryArgs, err := tp.ToSQL()
@ -552,7 +552,7 @@ func (statement *Statement) Join(joinOP string, tablename interface{}, condition
aliasName := statement.dialect.Quoter().Trim(fields[len(fields)-1]) aliasName := statement.dialect.Quoter().Trim(fields[len(fields)-1])
aliasName = schemas.CommonQuoter.Trim(aliasName) aliasName = schemas.CommonQuoter.Trim(aliasName)
fmt.Fprintf(&buf, "(%s) %s ON %v", statement.ReplaceQuote(subSQL), aliasName, statement.ReplaceQuote(condition)) fmt.Fprintf(&buf, "(%s) %s ON %v", statement.ReplaceQuote(subSQL), statement.quote(aliasName), statement.ReplaceQuote(condition))
statement.joinArgs = append(statement.joinArgs, subQueryArgs...) statement.joinArgs = append(statement.joinArgs, subQueryArgs...)
default: default:
tbName := dialects.FullTableName(statement.dialect, statement.tagParser.GetTableMapper(), tablename, true) tbName := dialects.FullTableName(statement.dialect, statement.tagParser.GetTableMapper(), tablename, true)
@ -560,6 +560,8 @@ func (statement *Statement) Join(joinOP string, tablename interface{}, condition
var buf strings.Builder var buf strings.Builder
statement.dialect.Quoter().QuoteTo(&buf, tbName) statement.dialect.Quoter().QuoteTo(&buf, tbName)
tbName = buf.String() tbName = buf.String()
} else {
tbName = statement.ReplaceQuote(tbName)
} }
fmt.Fprintf(&buf, "%s ON %v", tbName, statement.ReplaceQuote(condition)) fmt.Fprintf(&buf, "%s ON %v", tbName, statement.ReplaceQuote(condition))
} }
@ -642,14 +644,6 @@ func (statement *Statement) genColumnStr() string {
return buf.String() return buf.String()
} }
// GenCreateTableSQL generated create table SQL
func (statement *Statement) GenCreateTableSQL() []string {
statement.RefTable.StoreEngine = statement.StoreEngine
statement.RefTable.Charset = statement.Charset
s, _ := statement.dialect.CreateTableSQL(statement.RefTable, statement.TableName())
return s
}
// GenIndexSQL generated create index SQL // GenIndexSQL generated create index SQL
func (statement *Statement) GenIndexSQL() []string { func (statement *Statement) GenIndexSQL() []string {
var sqls []string var sqls []string

View File

@ -6,9 +6,15 @@ package utils
import ( import (
"fmt" "fmt"
"strings"
) )
// IndexName returns index name // IndexName returns index name
func IndexName(tableName, idxName string) string { func IndexName(tableName, idxName string) string {
return fmt.Sprintf("IDX_%v_%v", tableName, idxName) return fmt.Sprintf("IDX_%v_%v", tableName, idxName)
} }
// SeqName returns sequence name for some table
func SeqName(tableName string) string {
return "SEQ_" + strings.ToUpper(tableName)
}

View File

@ -11,8 +11,8 @@ func SliceEq(left, right []string) bool {
if len(left) != len(right) { if len(left) != len(right) {
return false return false
} }
sort.Sort(sort.StringSlice(left)) sort.Strings(left)
sort.Sort(sort.StringSlice(right)) sort.Strings(right)
for i := 0; i < len(left); i++ { for i := 0; i < len(left); i++ {
if left[i] != right[i] { if left[i] != right[i] {
return false return false
@ -20,3 +20,12 @@ func SliceEq(left, right []string) bool {
} }
return true return true
} }
func IndexSlice(s []string, c string) int {
for i, ss := range s {
if c == ss {
return i
}
}
return -1
}

View File

@ -136,7 +136,10 @@ func (engine *Engine) row2mapStr(rows *core.Rows, types []*sql.ColumnType, field
scanResults[i] = &s scanResults[i] = &s
} }
if err := rows.Scan(scanResults...); err != nil { if err := engine.driver.Scan(&dialects.ScanContext{
DBLocation: engine.DatabaseTZ,
UserLocation: engine.TZLocation,
}, rows, types, scanResults...); err != nil {
return nil, err return nil, err
} }

View File

@ -176,6 +176,10 @@ func TestReplace(t *testing.T) {
"UPDATE table SET `a` = ~ `a`, `b`='abc`'", "UPDATE table SET `a` = ~ `a`, `b`='abc`'",
"UPDATE table SET [a] = ~ [a], [b]='abc`'", "UPDATE table SET [a] = ~ [a], [b]='abc`'",
}, },
{
"INSERT INTO `insert_where` (`height`,`name`,`repo_id`,`width`,`index`) SELECT $1,$2,$3,$4,coalesce(MAX(`index`),0)+1 FROM `insert_where` WHERE (`repo_id`=$5)",
"INSERT INTO [insert_where] ([height],[name],[repo_id],[width],[index]) SELECT $1,$2,$3,$4,coalesce(MAX([index]),0)+1 FROM [insert_where] WHERE ([repo_id]=$5)",
},
} }
for _, kase := range kases { for _, kase := range kases {

View File

@ -22,6 +22,7 @@ const (
MYSQL DBType = "mysql" MYSQL DBType = "mysql"
MSSQL DBType = "mssql" MSSQL DBType = "mssql"
ORACLE DBType = "oracle" ORACLE DBType = "oracle"
DAMENG DBType = "dameng"
) )
// SQLType represents SQL types // SQLType represents SQL types
@ -105,12 +106,14 @@ var (
Integer = "INTEGER" Integer = "INTEGER"
BigInt = "BIGINT" BigInt = "BIGINT"
UnsignedBigInt = "UNSIGNED BIGINT" UnsignedBigInt = "UNSIGNED BIGINT"
Number = "NUMBER"
Enum = "ENUM" Enum = "ENUM"
Set = "SET" Set = "SET"
Char = "CHAR" Char = "CHAR"
Varchar = "VARCHAR" Varchar = "VARCHAR"
VARCHAR2 = "VARCHAR2"
NChar = "NCHAR" NChar = "NCHAR"
NVarchar = "NVARCHAR" NVarchar = "NVARCHAR"
TinyText = "TINYTEXT" TinyText = "TINYTEXT"
@ -174,6 +177,7 @@ var (
Integer: NUMERIC_TYPE, Integer: NUMERIC_TYPE,
BigInt: NUMERIC_TYPE, BigInt: NUMERIC_TYPE,
UnsignedBigInt: NUMERIC_TYPE, UnsignedBigInt: NUMERIC_TYPE,
Number: NUMERIC_TYPE,
Enum: TEXT_TYPE, Enum: TEXT_TYPE,
Set: TEXT_TYPE, Set: TEXT_TYPE,
@ -185,6 +189,7 @@ var (
Char: TEXT_TYPE, Char: TEXT_TYPE,
NChar: TEXT_TYPE, NChar: TEXT_TYPE,
Varchar: TEXT_TYPE, Varchar: TEXT_TYPE,
VARCHAR2: TEXT_TYPE,
NVarchar: TEXT_TYPE, NVarchar: TEXT_TYPE,
TinyText: TEXT_TYPE, TinyText: TEXT_TYPE,
Text: TEXT_TYPE, Text: TEXT_TYPE,

View File

@ -524,6 +524,9 @@ func (session *Session) convertBeanField(col *schemas.Column, fieldValue *reflec
if !ok { if !ok {
return fmt.Errorf("cannot convert %#v as bytes", scanResult) return fmt.Errorf("cannot convert %#v as bytes", scanResult)
} }
if data == nil {
return nil
}
return structConvert.FromDB(data) return structConvert.FromDB(data)
} }
} }

View File

@ -130,9 +130,6 @@ var (
valuerTypePlaceHolder driver.Valuer valuerTypePlaceHolder driver.Valuer
valuerType = reflect.TypeOf(&valuerTypePlaceHolder).Elem() valuerType = reflect.TypeOf(&valuerTypePlaceHolder).Elem()
scannerTypePlaceHolder sql.Scanner
scannerType = reflect.TypeOf(&scannerTypePlaceHolder).Elem()
conversionTypePlaceHolder convert.Conversion conversionTypePlaceHolder convert.Conversion
conversionType = reflect.TypeOf(&conversionTypePlaceHolder).Elem() conversionType = reflect.TypeOf(&conversionTypePlaceHolder).Elem()
) )

View File

@ -123,6 +123,12 @@ func (session *Session) insertMultipleStruct(rowsSlicePtr interface{}) (int64, e
} }
fieldValue := *ptrFieldValue fieldValue := *ptrFieldValue
if col.IsAutoIncrement && utils.IsZero(fieldValue.Interface()) { if col.IsAutoIncrement && utils.IsZero(fieldValue.Interface()) {
if session.engine.dialect.Features().AutoincrMode == dialects.SequenceAutoincrMode {
if i == 0 {
colNames = append(colNames, col.Name)
}
colPlaces = append(colPlaces, utils.SeqName(tableName)+".nextval")
}
continue continue
} }
if col.MapType == schemas.ONLYFROMDB { if col.MapType == schemas.ONLYFROMDB {
@ -277,6 +283,7 @@ func (session *Session) insertStruct(bean interface{}) (int64, error) {
if err != nil { if err != nil {
return 0, err return 0, err
} }
sqlStr = session.engine.dialect.Quoter().Replace(sqlStr)
handleAfterInsertProcessorFunc := func(bean interface{}) { handleAfterInsertProcessorFunc := func(bean interface{}) {
if session.isAutoCommit { if session.isAutoCommit {
@ -307,16 +314,49 @@ func (session *Session) insertStruct(bean interface{}) (int64, error) {
// if there is auto increment column and driver don't support return it // if there is auto increment column and driver don't support return it
if len(table.AutoIncrement) > 0 && !session.engine.driver.Features().SupportReturnInsertedID { if len(table.AutoIncrement) > 0 && !session.engine.driver.Features().SupportReturnInsertedID {
var sql = sqlStr var sql string
if session.engine.dialect.URI().DBType == schemas.ORACLE { var newArgs []interface{}
sql = "select seq_atable.currval from dual" var needCommit bool
var id int64
if session.engine.dialect.URI().DBType == schemas.ORACLE || session.engine.dialect.URI().DBType == schemas.DAMENG {
if session.isAutoCommit { // if it's not in transaction
if err := session.Begin(); err != nil {
return 0, err
}
needCommit = true
}
_, err := session.exec(sqlStr, args...)
if err != nil {
return 0, err
}
i := utils.IndexSlice(colNames, table.AutoIncrement)
if i > -1 {
id, err = convert.AsInt64(args[i])
if err != nil {
return 0, err
}
} else {
sql = fmt.Sprintf("select %s.currval from dual", utils.SeqName(tableName))
}
} else {
sql = sqlStr
newArgs = args
} }
rows, err := session.queryRows(sql, args...) if id == 0 {
if err != nil { err := session.queryRow(sql, newArgs...).Scan(&id)
return 0, err if err != nil {
return 0, err
}
if needCommit {
if err := session.Commit(); err != nil {
return 0, err
}
}
if id == 0 {
return 0, errors.New("insert successfully but not returned id")
}
} }
defer rows.Close()
defer handleAfterInsertProcessorFunc(bean) defer handleAfterInsertProcessorFunc(bean)
@ -331,16 +371,6 @@ func (session *Session) insertStruct(bean interface{}) (int64, error) {
} }
} }
var id int64
if !rows.Next() {
if rows.Err() != nil {
return 0, rows.Err()
}
return 0, errors.New("insert successfully but not returned id")
}
if err := rows.Scan(&id); err != nil {
return 1, err
}
aiValue, err := table.AutoIncrColumn().ValueOf(bean) aiValue, err := table.AutoIncrColumn().ValueOf(bean)
if err != nil { if err != nil {
session.engine.logger.Errorf("%v", err) session.engine.logger.Errorf("%v", err)
@ -628,6 +658,7 @@ func (session *Session) insertMap(columns []string, args []interface{}) (int64,
if err != nil { if err != nil {
return 0, err return 0, err
} }
sql = session.engine.dialect.Quoter().Replace(sql)
if err := session.cacheInsert(tableName); err != nil { if err := session.cacheInsert(tableName); err != nil {
return 0, err return 0, err
@ -654,6 +685,7 @@ func (session *Session) insertMultipleMap(columns []string, argss [][]interface{
if err != nil { if err != nil {
return 0, err return 0, err
} }
sql = session.engine.dialect.Quoter().Replace(sql)
if err := session.cacheInsert(tableName); err != nil { if err := session.cacheInsert(tableName); err != nil {
return 0, err return 0, err

View File

@ -6,12 +6,14 @@ package xorm
import ( import (
"bufio" "bufio"
"context"
"database/sql" "database/sql"
"fmt" "fmt"
"io" "io"
"os" "os"
"strings" "strings"
"xorm.io/xorm/dialects"
"xorm.io/xorm/internal/utils" "xorm.io/xorm/internal/utils"
"xorm.io/xorm/schemas" "xorm.io/xorm/schemas"
) )
@ -40,13 +42,28 @@ func (session *Session) createTable(bean interface{}) error {
return err return err
} }
sqlStrs := session.statement.GenCreateTableSQL() session.statement.RefTable.StoreEngine = session.statement.StoreEngine
for _, s := range sqlStrs { session.statement.RefTable.Charset = session.statement.Charset
_, err := session.exec(s) tableName := session.statement.TableName()
refTable := session.statement.RefTable
if refTable.AutoIncrement != "" && session.engine.dialect.Features().AutoincrMode == dialects.SequenceAutoincrMode {
sqlStr, err := session.engine.dialect.CreateSequenceSQL(context.Background(), session.engine.db, utils.SeqName(tableName))
if err != nil { if err != nil {
return err return err
} }
if _, err := session.exec(sqlStr); err != nil {
return err
}
} }
sqlStr, _, err := session.engine.dialect.CreateTableSQL(context.Background(), session.engine.db, refTable, tableName)
if err != nil {
return err
}
if _, err := session.exec(sqlStr); err != nil {
return err
}
return nil return nil
} }
@ -141,11 +158,32 @@ func (session *Session) dropTable(beanOrTableName interface{}) error {
checkIfExist = exist checkIfExist = exist
} }
if checkIfExist { if !checkIfExist {
_, err := session.exec(sqlStr) return nil
}
if _, err := session.exec(sqlStr); err != nil {
return err return err
} }
return nil
if session.engine.dialect.Features().AutoincrMode == dialects.IncrAutoincrMode {
return nil
}
var seqName = utils.SeqName(tableName)
exist, err := session.engine.dialect.IsSequenceExist(session.ctx, session.getQueryer(), seqName)
if err != nil {
return err
}
if !exist {
return nil
}
sqlStr, err = session.engine.dialect.DropSequenceSQL(seqName)
if err != nil {
return err
}
_, err = session.exec(sqlStr)
return err
} }
// IsTableExist if a table is exist // IsTableExist if a table is exist

View File

@ -278,7 +278,11 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
condBeanIsStruct := false condBeanIsStruct := false
if len(condiBean) > 0 { if len(condiBean) > 0 {
if c, ok := condiBean[0].(map[string]interface{}); ok { if c, ok := condiBean[0].(map[string]interface{}); ok {
autoCond = builder.Eq(c) var eq = make(builder.Eq)
for k, v := range c {
eq[session.engine.Quote(k)] = v
}
autoCond = builder.Eq(eq)
} else { } else {
ct := reflect.TypeOf(condiBean[0]) ct := reflect.TypeOf(condiBean[0])
k := ct.Kind() k := ct.Kind()