Fix join table name quote bug (#1534)
Fix test Fix test Add new Quoter object to handle quote Fix join table name quote bug Move reserve words related files into dialects sub package (#1544) Move reserve words related files into dialects sub package Reviewed-on: https://gitea.com/xorm/xorm/pulls/1544 Fix mssql quote (#1535) Fix some quotes Fix mssql quote Merge core package back into the main repository and split into serval sub packages. (#1543) Fix test Improve fmt update go.mod Move core as a sub package Reviewed-on: https://gitea.com/xorm/xorm/pulls/1543 Fix int time deleted bug (#1539) Fix panic Fix test Fix test for mssql time Add sql type check on deleted cond Fix int time deleted bug Reviewed-on: https://gitea.com/xorm/xorm/pulls/1539 Add test for mysql8.0 (#1538) Fix pk order on test Add test for mysql8.0 Reviewed-on: https://gitea.com/xorm/xorm/pulls/1538 Add test for join limit (#1536) Add test for join limit Reviewed-on: https://gitea.com/xorm/xorm/pulls/1536 Improve drone (#1537) Fix drone Improve drone * use traditional positional parameters on inser... Reviewed-on: https://gitea.com/xorm/xorm/pulls/1537 Fix slice of struct not cache bug (#895) Fix failure caused by nil bean Judge both type of struct and pointer in case of out-of-range Fix issue #894 Add test for join subquery (#1528) Fix test Fix subquery with schema Add test for join subquery Add makefile (#1531) Fix drone Fix ci Add deps Improve drone Fix envs Add makefile Reviewed-on: https://gitea.com/xorm/xorm/pulls/1531 Add password for postgres drone image (#1530) Add password for postgres drone image Reviewed-on: https://gitea.com/xorm/xorm/pulls/1530 format time when sqlTypeName is core.Varchar (#1026) fix time test add test for time format sign codes according to contributing rules. format time when sqlTypeName is core.Varchar. Same with core.DateTime or core.TimeStamp Add test for second insert error (#1527) Add test for second insert error Reviewed-on: https://gitea.com/xorm/xorm/pulls/1527 Add tests for table name (#1517) add tests for table name Fix test (#1526) Fix test Reviewed-on: https://gitea.com/xorm/xorm/pulls/1526 Fix test (#1526) Fix test Reviewed-on: https://gitea.com/xorm/xorm/pulls/1526 Fix wrong warning log on autoincrement column when sync table (#1525) improve doc Fix wrong warning log on autoincrement column when sync table Reviewed-on: https://gitea.com/xorm/xorm/pulls/1525 Fixed Join strings on func Exist (#1520) fix test fixed Join strings on func Exist Co-authored-by: Tomofumi Kusana <tkusana@morisawa.co.jp> Reviewed-on: https://gitea.com/xorm/xorm/pulls/1520 For nullable columns, store nil values as NULL (#531) Merge branch 'master' into jcsalem/fix/nil_ptr_is_nullable fix bug when buffersize with iterate (#941) Merge branch 'master' into lunny/fix_buffer_iterate Exclude schema from index name (#1505) Merge branch 'master' into fix-schema-idx SetExpr support more go types (#1499) Improve tests SetExpr support more go types fix vet fix drone lint remove go1.10 test on drone Reviewed-on: https://gitea.com/xorm/xorm/pulls/1499 fix vet fix drone lint remove go1.10 test on drone Exclude schema from the index name Co-authored-by: Guillermo Prandi <guillep2k@users.noreply.github.com> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com> Reviewed-on: https://gitea.com/xorm/xorm/pulls/1505 fix test fix bug fix bug when buffersize with iterate SetExpr support more go types (#1499) Improve tests SetExpr support more go types fix vet fix drone lint remove go1.10 test on drone Reviewed-on: https://gitea.com/xorm/xorm/pulls/1499 fix vet fix drone lint remove go1.10 test on drone Fix update with Alias (#1455) Co-authored-by: Guillermo Prandi <guillep2k@noreply.gitea.io> Reviewed-on: https://gitea.com/xorm/xorm/pulls/941 fix update map with version (#1448) fix test fix update map with version SetExpr support more go types (#1499) Improve tests SetExpr support more go types fix vet fix drone lint remove go1.10 test on drone Reviewed-on: https://gitea.com/xorm/xorm/pulls/1499 fix vet fix drone lint remove go1.10 test on drone Fix update with Alias (#1455) Reviewed-on: https://gitea.com/xorm/xorm/pulls/1448 Exclude schema from index name (#1505) Merge branch 'master' into fix-schema-idx SetExpr support more go types (#1499) Improve tests SetExpr support more go types fix vet fix drone lint remove go1.10 test on drone Reviewed-on: https://gitea.com/xorm/xorm/pulls/1499 fix vet fix drone lint remove go1.10 test on drone Exclude schema from the index name Co-authored-by: Guillermo Prandi <guillep2k@users.noreply.github.com> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com> Reviewed-on: https://gitea.com/xorm/xorm/pulls/1505 SetExpr support more go types (#1499) Improve tests SetExpr support more go types fix vet fix drone lint remove go1.10 test on drone Reviewed-on: https://gitea.com/xorm/xorm/pulls/1499 For nullable columns, store nil values as NULL fix vet fix drone lint remove go1.10 test on drone Fix update with Alias (#1455) Improve c... Reviewed-on: https://gitea.com/xorm/xorm/pulls/1534
This commit is contained in:
parent
3df77142b3
commit
cc33b2d305
|
@ -45,11 +45,8 @@ type Dialect interface {
|
||||||
DataSourceName() string
|
DataSourceName() string
|
||||||
|
|
||||||
IsReserved(string) bool
|
IsReserved(string) bool
|
||||||
Quote(string) string
|
Quoter() schemas.Quoter
|
||||||
|
|
||||||
AndStr() string
|
|
||||||
OrStr() string
|
|
||||||
EqStr() string
|
|
||||||
RollBackStr() string
|
RollBackStr() string
|
||||||
AutoIncrStr() string
|
AutoIncrStr() string
|
||||||
|
|
||||||
|
@ -101,7 +98,7 @@ type Base struct {
|
||||||
|
|
||||||
// String generate column description string according dialect
|
// String generate column description string according dialect
|
||||||
func String(d Dialect, col *schemas.Column) string {
|
func String(d Dialect, col *schemas.Column) string {
|
||||||
sql := d.Quote(col.Name) + " "
|
sql := d.Quoter().Quote(col.Name) + " "
|
||||||
|
|
||||||
sql += d.SQLType(col) + " "
|
sql += d.SQLType(col) + " "
|
||||||
|
|
||||||
|
@ -129,7 +126,7 @@ func String(d Dialect, col *schemas.Column) string {
|
||||||
|
|
||||||
// StringNoPk generate column description string according dialect without primary keys
|
// StringNoPk generate column description string according dialect without primary keys
|
||||||
func StringNoPk(d Dialect, col *schemas.Column) string {
|
func StringNoPk(d Dialect, col *schemas.Column) string {
|
||||||
sql := d.Quote(col.Name) + " "
|
sql := d.Quoter().Quote(col.Name) + " "
|
||||||
|
|
||||||
sql += d.SQLType(col) + " "
|
sql += d.SQLType(col) + " "
|
||||||
|
|
||||||
|
@ -186,18 +183,6 @@ func (b *Base) DataSourceName() string {
|
||||||
return b.dataSourceName
|
return b.dataSourceName
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Base) AndStr() string {
|
|
||||||
return "AND"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *Base) OrStr() string {
|
|
||||||
return "OR"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *Base) EqStr() string {
|
|
||||||
return "="
|
|
||||||
}
|
|
||||||
|
|
||||||
func (db *Base) RollBackStr() string {
|
func (db *Base) RollBackStr() string {
|
||||||
return "ROLL BACK"
|
return "ROLL BACK"
|
||||||
}
|
}
|
||||||
|
@ -207,7 +192,7 @@ func (db *Base) SupportDropIfExists() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *Base) DropTableSQL(tableName string) string {
|
func (db *Base) DropTableSQL(tableName string) string {
|
||||||
quote := db.dialect.Quote
|
quote := db.dialect.Quoter().Quote
|
||||||
return fmt.Sprintf("DROP TABLE IF EXISTS %s", quote(tableName))
|
return fmt.Sprintf("DROP TABLE IF EXISTS %s", quote(tableName))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,14 +211,15 @@ func (db *Base) HasRecords(query string, args ...interface{}) (bool, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *Base) IsColumnExist(tableName, colName string) (bool, error) {
|
func (db *Base) IsColumnExist(tableName, colName string) (bool, error) {
|
||||||
|
quote := db.dialect.Quoter().Quote
|
||||||
query := fmt.Sprintf(
|
query := fmt.Sprintf(
|
||||||
"SELECT %v FROM %v.%v WHERE %v = ? AND %v = ? AND %v = ?",
|
"SELECT %v FROM %v.%v WHERE %v = ? AND %v = ? AND %v = ?",
|
||||||
db.dialect.Quote("COLUMN_NAME"),
|
quote("COLUMN_NAME"),
|
||||||
db.dialect.Quote("INFORMATION_SCHEMA"),
|
quote("INFORMATION_SCHEMA"),
|
||||||
db.dialect.Quote("COLUMNS"),
|
quote("COLUMNS"),
|
||||||
db.dialect.Quote("TABLE_SCHEMA"),
|
quote("TABLE_SCHEMA"),
|
||||||
db.dialect.Quote("TABLE_NAME"),
|
quote("TABLE_NAME"),
|
||||||
db.dialect.Quote("COLUMN_NAME"),
|
quote("COLUMN_NAME"),
|
||||||
)
|
)
|
||||||
return db.HasRecords(query, db.uri.DBName, tableName, colName)
|
return db.HasRecords(query, db.uri.DBName, tableName, colName)
|
||||||
}
|
}
|
||||||
|
@ -263,8 +249,7 @@ func (db *Base) CreateTableIfNotExists(table *Table, tableName, storeEngine, cha
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
func (db *Base) CreateIndexSQL(tableName string, index *schemas.Index) string {
|
func (db *Base) CreateIndexSQL(tableName string, index *schemas.Index) string {
|
||||||
quotes := db.dialect.Quote("")
|
quoter := db.dialect.Quoter()
|
||||||
quote := db.dialect.Quote
|
|
||||||
var unique string
|
var unique string
|
||||||
var idxName string
|
var idxName string
|
||||||
if index.Type == schemas.UniqueType {
|
if index.Type == schemas.UniqueType {
|
||||||
|
@ -272,12 +257,12 @@ func (db *Base) CreateIndexSQL(tableName string, index *schemas.Index) string {
|
||||||
}
|
}
|
||||||
idxName = index.XName(tableName)
|
idxName = index.XName(tableName)
|
||||||
return fmt.Sprintf("CREATE%s INDEX %v ON %v (%v)", unique,
|
return fmt.Sprintf("CREATE%s INDEX %v ON %v (%v)", unique,
|
||||||
quote(idxName), quote(tableName),
|
quoter.Quote(idxName), quoter.Quote(tableName),
|
||||||
quote(strings.Join(index.Cols, fmt.Sprintf("%c,%c", quotes[1], quotes[0]))))
|
quoter.Quote(strings.Join(index.Cols, quoter.ReverseQuote(","))))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *Base) DropIndexSQL(tableName string, index *schemas.Index) string {
|
func (db *Base) DropIndexSQL(tableName string, index *schemas.Index) string {
|
||||||
quote := db.dialect.Quote
|
quote := db.dialect.Quoter().Quote
|
||||||
var name string
|
var name string
|
||||||
if index.IsRegular {
|
if index.IsRegular {
|
||||||
name = index.XName(tableName)
|
name = index.XName(tableName)
|
||||||
|
@ -298,11 +283,10 @@ func (b *Base) CreateTableSQL(table *schemas.Table, tableName, storeEngine, char
|
||||||
tableName = table.Name
|
tableName = table.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
sql += b.dialect.Quote(tableName)
|
quoter := b.dialect.Quoter()
|
||||||
|
sql += quoter.Quote(tableName)
|
||||||
sql += " ("
|
sql += " ("
|
||||||
|
|
||||||
quotes := b.dialect.Quote("")
|
|
||||||
|
|
||||||
if len(table.ColumnsSeq()) > 0 {
|
if len(table.ColumnsSeq()) > 0 {
|
||||||
pkList := table.PrimaryKeys
|
pkList := table.PrimaryKeys
|
||||||
|
|
||||||
|
@ -322,7 +306,7 @@ func (b *Base) CreateTableSQL(table *schemas.Table, tableName, storeEngine, char
|
||||||
|
|
||||||
if len(pkList) > 1 {
|
if len(pkList) > 1 {
|
||||||
sql += "PRIMARY KEY ( "
|
sql += "PRIMARY KEY ( "
|
||||||
sql += b.dialect.Quote(strings.Join(pkList, fmt.Sprintf("%c,%c", quotes[1], quotes[0])))
|
sql += quoter.Quote(strings.Join(pkList, quoter.ReverseQuote(",")))
|
||||||
sql += " ), "
|
sql += " ), "
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,11 +21,12 @@ type QuoteFilter struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *QuoteFilter) Do(sql string, dialect Dialect, table *schemas.Table) string {
|
func (s *QuoteFilter) Do(sql string, dialect Dialect, table *schemas.Table) string {
|
||||||
dummy := dialect.Quote("")
|
quoter := dialect.Quoter()
|
||||||
if len(dummy) != 2 {
|
if quoter.IsEmpty() {
|
||||||
return sql
|
return sql
|
||||||
}
|
}
|
||||||
prefix, suffix := dummy[0], dummy[1]
|
|
||||||
|
prefix, suffix := quoter[0][0], quoter[1][0]
|
||||||
raw := []byte(sql)
|
raw := []byte(sql)
|
||||||
for i, cnt := 0, 0; i < len(raw); i = i + 1 {
|
for i, cnt := 0, 0; i < len(raw); i = i + 1 {
|
||||||
if raw[i] == '`' {
|
if raw[i] == '`' {
|
||||||
|
@ -38,32 +39,7 @@ func (s *QuoteFilter) Do(sql string, dialect Dialect, table *schemas.Table) stri
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return string(raw)
|
return string(raw)
|
||||||
}
|
|
||||||
|
|
||||||
// IdFilter filter SQL replace (id) to primary key column name
|
|
||||||
type IdFilter struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
type Quoter struct {
|
|
||||||
dialect Dialect
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewQuoter(dialect Dialect) *Quoter {
|
|
||||||
return &Quoter{dialect}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (q *Quoter) Quote(content string) string {
|
|
||||||
return q.dialect.Quote(content)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i *IdFilter) Do(sql string, dialect Dialect, table *schemas.Table) string {
|
|
||||||
quoter := NewQuoter(dialect)
|
|
||||||
if table != nil && len(table.PrimaryKeys) == 1 {
|
|
||||||
sql = strings.Replace(sql, " `(id)` ", " "+quoter.Quote(table.PrimaryKeys[0])+" ", -1)
|
|
||||||
sql = strings.Replace(sql, " "+quoter.Quote("(id)")+" ", " "+quoter.Quote(table.PrimaryKeys[0])+" ", -1)
|
|
||||||
return strings.Replace(sql, " (id) ", " "+quoter.Quote(table.PrimaryKeys[0])+" ", -1)
|
|
||||||
}
|
|
||||||
return sql
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SeqFilter filter SQL replace ?, ? ... to $1, $2 ...
|
// SeqFilter filter SQL replace ?, ? ... to $1, $2 ...
|
||||||
|
|
|
@ -286,8 +286,8 @@ func (db *mssql) IsReserved(name string) bool {
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *mssql) Quote(name string) string {
|
func (db *mssql) Quoter() schemas.Quoter {
|
||||||
return "[" + name + "]"
|
return schemas.Quoter{"[", "]"}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *mssql) SupportEngine() bool {
|
func (db *mssql) SupportEngine() bool {
|
||||||
|
@ -503,7 +503,7 @@ func (db *mssql) CreateTableSQL(table *schemas.Table, tableName, storeEngine, ch
|
||||||
|
|
||||||
sql = "IF NOT EXISTS (SELECT [name] FROM sys.tables WHERE [name] = '" + tableName + "' ) CREATE TABLE "
|
sql = "IF NOT EXISTS (SELECT [name] FROM sys.tables WHERE [name] = '" + tableName + "' ) CREATE TABLE "
|
||||||
|
|
||||||
sql += db.Quote(tableName) + " ("
|
sql += db.Quoter().Quote(tableName) + " ("
|
||||||
|
|
||||||
pkList := table.PrimaryKeys
|
pkList := table.PrimaryKeys
|
||||||
|
|
||||||
|
@ -534,7 +534,7 @@ func (db *mssql) ForUpdateSQL(query string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *mssql) Filters() []Filter {
|
func (db *mssql) Filters() []Filter {
|
||||||
return []Filter{&IdFilter{}, &QuoteFilter{}}
|
return []Filter{&QuoteFilter{}}
|
||||||
}
|
}
|
||||||
|
|
||||||
type odbcDriver struct {
|
type odbcDriver struct {
|
||||||
|
|
|
@ -275,8 +275,8 @@ func (db *mysql) IsReserved(name string) bool {
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *mysql) Quote(name string) string {
|
func (db *mysql) Quoter() schemas.Quoter {
|
||||||
return "`" + name + "`"
|
return schemas.Quoter{"`", "`"}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *mysql) SupportEngine() bool {
|
func (db *mysql) SupportEngine() bool {
|
||||||
|
@ -512,9 +512,9 @@ func (db *mysql) CreateTableSQL(table *schemas.Table, tableName, storeEngine, ch
|
||||||
tableName = table.Name
|
tableName = table.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
quotes := db.Quote("")
|
quoter := db.Quoter()
|
||||||
|
|
||||||
sql += db.Quote(tableName)
|
sql += quoter.Quote(tableName)
|
||||||
sql += " ("
|
sql += " ("
|
||||||
|
|
||||||
if len(table.ColumnsSeq()) > 0 {
|
if len(table.ColumnsSeq()) > 0 {
|
||||||
|
@ -536,7 +536,7 @@ func (db *mysql) CreateTableSQL(table *schemas.Table, tableName, storeEngine, ch
|
||||||
|
|
||||||
if len(pkList) > 1 {
|
if len(pkList) > 1 {
|
||||||
sql += "PRIMARY KEY ( "
|
sql += "PRIMARY KEY ( "
|
||||||
sql += db.Quote(strings.Join(pkList, fmt.Sprintf("%c,%c", quotes[1], quotes[0])))
|
sql += quoter.Quote(strings.Join(pkList, quoter.ReverseQuote(",")))
|
||||||
sql += " ), "
|
sql += " ), "
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -562,7 +562,7 @@ func (db *mysql) CreateTableSQL(table *schemas.Table, tableName, storeEngine, ch
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *mysql) Filters() []Filter {
|
func (db *mysql) Filters() []Filter {
|
||||||
return []Filter{&IdFilter{}}
|
return []Filter{}
|
||||||
}
|
}
|
||||||
|
|
||||||
type mymysqlDriver struct {
|
type mymysqlDriver struct {
|
||||||
|
|
|
@ -552,8 +552,8 @@ func (db *oracle) IsReserved(name string) bool {
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *oracle) Quote(name string) string {
|
func (db *oracle) Quoter() schemas.Quoter {
|
||||||
return "[" + name + "]"
|
return schemas.Quoter{"[", "]"}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *oracle) SupportEngine() bool {
|
func (db *oracle) SupportEngine() bool {
|
||||||
|
@ -582,7 +582,8 @@ func (db *oracle) CreateTableSQL(table *schemas.Table, tableName, storeEngine, c
|
||||||
tableName = table.Name
|
tableName = table.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
sql += db.Quote(tableName) + " ("
|
quoter := db.Quoter()
|
||||||
|
sql += quoter.Quote(tableName) + " ("
|
||||||
|
|
||||||
pkList := table.PrimaryKeys
|
pkList := table.PrimaryKeys
|
||||||
|
|
||||||
|
@ -597,11 +598,9 @@ func (db *oracle) CreateTableSQL(table *schemas.Table, tableName, storeEngine, c
|
||||||
sql += ", "
|
sql += ", "
|
||||||
}
|
}
|
||||||
|
|
||||||
quotes := db.Quote("")
|
|
||||||
|
|
||||||
if len(pkList) > 0 {
|
if len(pkList) > 0 {
|
||||||
sql += "PRIMARY KEY ( "
|
sql += "PRIMARY KEY ( "
|
||||||
sql += db.Quote(strings.Join(pkList, fmt.Sprintf("%c,%c", quotes[1], quotes[0])))
|
sql += quoter.Quote(strings.Join(pkList, quoter.ReverseQuote(",")))
|
||||||
sql += " ), "
|
sql += " ), "
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -849,7 +848,7 @@ func (db *oracle) GetIndexes(tableName string) (map[string]*schemas.Index, error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *oracle) Filters() []Filter {
|
func (db *oracle) Filters() []Filter {
|
||||||
return []Filter{&QuoteFilter{}, &SeqFilter{Prefix: ":", Start: 1}, &IdFilter{}}
|
return []Filter{&QuoteFilter{}, &SeqFilter{Prefix: ":", Start: 1}}
|
||||||
}
|
}
|
||||||
|
|
||||||
type goracleDriver struct {
|
type goracleDriver struct {
|
||||||
|
|
|
@ -859,9 +859,8 @@ func (db *postgres) IsReserved(name string) bool {
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *postgres) Quote(name string) string {
|
func (db *postgres) Quoter() schemas.Quoter {
|
||||||
name = strings.Replace(name, ".", `"."`, -1)
|
return schemas.Quoter{`"`, `"`}
|
||||||
return "\"" + name + "\""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *postgres) AutoIncrStr() string {
|
func (db *postgres) AutoIncrStr() string {
|
||||||
|
@ -911,7 +910,6 @@ func (db *postgres) ModifyColumnSQL(tableName string, col *schemas.Column) strin
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *postgres) DropIndexSQL(tableName string, index *schemas.Index) string {
|
func (db *postgres) DropIndexSQL(tableName string, index *schemas.Index) string {
|
||||||
quote := db.Quote
|
|
||||||
idxName := index.Name
|
idxName := index.Name
|
||||||
|
|
||||||
tableParts := strings.Split(strings.Replace(tableName, `"`, "", -1), ".")
|
tableParts := strings.Split(strings.Replace(tableName, `"`, "", -1), ".")
|
||||||
|
@ -928,7 +926,7 @@ func (db *postgres) DropIndexSQL(tableName string, index *schemas.Index) string
|
||||||
if db.uri.Schema != "" {
|
if db.uri.Schema != "" {
|
||||||
idxName = db.uri.Schema + "." + idxName
|
idxName = db.uri.Schema + "." + idxName
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("DROP INDEX %v", quote(idxName))
|
return fmt.Sprintf("DROP INDEX %v", db.Quoter().Quote(idxName))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *postgres) IsColumnExist(tableName, colName string) (bool, error) {
|
func (db *postgres) IsColumnExist(tableName, colName string) (bool, error) {
|
||||||
|
@ -1161,7 +1159,7 @@ func (db *postgres) GetIndexes(tableName string) (map[string]*schemas.Index, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *postgres) Filters() []Filter {
|
func (db *postgres) Filters() []Filter {
|
||||||
return []Filter{&IdFilter{}, &QuoteFilter{}, &SeqFilter{Prefix: "$", Start: 1}}
|
return []Filter{&QuoteFilter{}, &SeqFilter{Prefix: "$", Start: 1}}
|
||||||
}
|
}
|
||||||
|
|
||||||
type pqDriver struct {
|
type pqDriver struct {
|
||||||
|
|
|
@ -199,8 +199,8 @@ func (db *sqlite3) IsReserved(name string) bool {
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *sqlite3) Quote(name string) string {
|
func (db *sqlite3) Quoter() schemas.Quoter {
|
||||||
return "`" + name + "`"
|
return schemas.Quoter{"`", "`"}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *sqlite3) AutoIncrStr() string {
|
func (db *sqlite3) AutoIncrStr() string {
|
||||||
|
@ -231,7 +231,6 @@ func (db *sqlite3) TableCheckSQL(tableName string) (string, []interface{}) {
|
||||||
|
|
||||||
func (db *sqlite3) DropIndexSQL(tableName string, index *schemas.Index) string {
|
func (db *sqlite3) DropIndexSQL(tableName string, index *schemas.Index) string {
|
||||||
// var unique string
|
// var unique string
|
||||||
quote := db.Quote
|
|
||||||
idxName := index.Name
|
idxName := index.Name
|
||||||
|
|
||||||
if !strings.HasPrefix(idxName, "UQE_") &&
|
if !strings.HasPrefix(idxName, "UQE_") &&
|
||||||
|
@ -242,7 +241,7 @@ func (db *sqlite3) DropIndexSQL(tableName string, index *schemas.Index) string {
|
||||||
idxName = fmt.Sprintf("IDX_%v_%v", tableName, index.Name)
|
idxName = fmt.Sprintf("IDX_%v_%v", tableName, index.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("DROP INDEX %v", quote(idxName))
|
return fmt.Sprintf("DROP INDEX %v", db.Quoter().Quote(idxName))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *sqlite3) ForUpdateSQL(query string) string {
|
func (db *sqlite3) ForUpdateSQL(query string) string {
|
||||||
|
@ -478,7 +477,7 @@ func (db *sqlite3) GetIndexes(tableName string) (map[string]*schemas.Index, erro
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *sqlite3) Filters() []Filter {
|
func (db *sqlite3) Filters() []Filter {
|
||||||
return []Filter{&IdFilter{}}
|
return []Filter{}
|
||||||
}
|
}
|
||||||
|
|
||||||
type sqlite3Driver struct {
|
type sqlite3Driver struct {
|
||||||
|
|
59
engine.go
59
engine.go
|
@ -193,10 +193,7 @@ func (engine *Engine) SupportInsertMany() bool {
|
||||||
|
|
||||||
func (engine *Engine) quoteColumns(columnStr string) string {
|
func (engine *Engine) quoteColumns(columnStr string) string {
|
||||||
columns := strings.Split(columnStr, ",")
|
columns := strings.Split(columnStr, ",")
|
||||||
for i := 0; i < len(columns); i++ {
|
return engine.dialect.Quoter().Join(columns, ",")
|
||||||
columns[i] = engine.Quote(strings.TrimSpace(columns[i]))
|
|
||||||
}
|
|
||||||
return strings.Join(columns, ",")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Quote Use QuoteStr quote the string sql
|
// Quote Use QuoteStr quote the string sql
|
||||||
|
@ -222,53 +219,13 @@ func (engine *Engine) QuoteTo(buf *strings.Builder, value string) {
|
||||||
if value == "" {
|
if value == "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
engine.dialect.Quoter().QuoteTo(buf, value)
|
||||||
quoteTo(buf, engine.dialect.Quote(""), value)
|
|
||||||
}
|
|
||||||
|
|
||||||
func quoteTo(buf *strings.Builder, quotePair string, value string) {
|
|
||||||
if len(quotePair) < 2 { // no quote
|
|
||||||
_, _ = buf.WriteString(value)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
prefix, suffix := quotePair[0], quotePair[1]
|
|
||||||
|
|
||||||
i := 0
|
|
||||||
for i < len(value) {
|
|
||||||
// start of a token; might be already quoted
|
|
||||||
if value[i] == '.' {
|
|
||||||
_ = buf.WriteByte('.')
|
|
||||||
i++
|
|
||||||
} else if value[i] == prefix || value[i] == '`' {
|
|
||||||
// Has quotes; skip/normalize `name` to prefix+name+sufix
|
|
||||||
var ch byte
|
|
||||||
if value[i] == prefix {
|
|
||||||
ch = suffix
|
|
||||||
} else {
|
|
||||||
ch = '`'
|
|
||||||
}
|
|
||||||
i++
|
|
||||||
_ = buf.WriteByte(prefix)
|
|
||||||
for ; i < len(value) && value[i] != ch; i++ {
|
|
||||||
_ = buf.WriteByte(value[i])
|
|
||||||
}
|
|
||||||
_ = buf.WriteByte(suffix)
|
|
||||||
i++
|
|
||||||
} else {
|
|
||||||
// Requires quotes
|
|
||||||
_ = buf.WriteByte(prefix)
|
|
||||||
for ; i < len(value) && value[i] != '.'; i++ {
|
|
||||||
_ = buf.WriteByte(value[i])
|
|
||||||
}
|
|
||||||
_ = buf.WriteByte(suffix)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
func (engine *Engine) quote(sql string) string {
|
func (engine *Engine) quote(sql string) string {
|
||||||
return engine.dialect.Quote(sql)
|
return engine.dialect.Quote(sql)
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// SqlType will be deprecated, please use SQLType instead
|
// SqlType will be deprecated, please use SQLType instead
|
||||||
//
|
//
|
||||||
|
@ -530,8 +487,8 @@ func (engine *Engine) dumpTables(tables []*schemas.Table, w io.Writer, tp ...dia
|
||||||
}
|
}
|
||||||
|
|
||||||
cols := table.ColumnsSeq()
|
cols := table.ColumnsSeq()
|
||||||
colNames := engine.dialect.Quote(strings.Join(cols, engine.dialect.Quote(", ")))
|
colNames := engine.dialect.Quoter().Join(cols, ", ")
|
||||||
destColNames := dialect.Quote(strings.Join(cols, dialect.Quote(", ")))
|
destColNames := dialect.Quoter().Join(cols, ", ")
|
||||||
|
|
||||||
rows, err := engine.DB().Query("SELECT " + colNames + " FROM " + engine.Quote(table.Name))
|
rows, err := engine.DB().Query("SELECT " + colNames + " FROM " + engine.Quote(table.Name))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -546,7 +503,7 @@ func (engine *Engine) dumpTables(tables []*schemas.Table, w io.Writer, tp ...dia
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = io.WriteString(w, "INSERT INTO "+dialect.Quote(table.Name)+" ("+destColNames+") VALUES (")
|
_, err = io.WriteString(w, "INSERT INTO "+dialect.Quoter().Quote(table.Name)+" ("+destColNames+") VALUES (")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -617,7 +574,7 @@ func (engine *Engine) dumpTables(tables []*schemas.Table, w io.Writer, tp ...dia
|
||||||
|
|
||||||
// FIXME: Hack for postgres
|
// FIXME: Hack for postgres
|
||||||
if string(dialect.DBType()) == schemas.POSTGRES && table.AutoIncrColumn() != nil {
|
if string(dialect.DBType()) == schemas.POSTGRES && table.AutoIncrColumn() != nil {
|
||||||
_, err = io.WriteString(w, "SELECT setval('"+table.Name+"_id_seq', COALESCE((SELECT MAX("+table.AutoIncrColumn().Name+") + 1 FROM "+dialect.Quote(table.Name)+"), 1), false);\n")
|
_, err = io.WriteString(w, "SELECT setval('"+table.Name+"_id_seq', COALESCE((SELECT MAX("+table.AutoIncrColumn().Name+") + 1 FROM "+dialect.Quoter().Quote(table.Name)+"), 1), false);\n")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,165 @@
|
||||||
|
// Copyright 2020 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package schemas
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Quoter represents two quote characters
|
||||||
|
type Quoter [2]string
|
||||||
|
|
||||||
|
// CommonQuoter represetns a common quoter
|
||||||
|
var CommonQuoter = Quoter{"`", "`"}
|
||||||
|
|
||||||
|
func (q Quoter) IsEmpty() bool {
|
||||||
|
return q[0] == "" && q[1] == ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q Quoter) Quote(s string) string {
|
||||||
|
var buf strings.Builder
|
||||||
|
q.QuoteTo(&buf, s)
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q Quoter) Replace(sql string, newQuoter Quoter) string {
|
||||||
|
if q.IsEmpty() {
|
||||||
|
return sql
|
||||||
|
}
|
||||||
|
|
||||||
|
if newQuoter.IsEmpty() {
|
||||||
|
var buf strings.Builder
|
||||||
|
for i := 0; i < len(sql); i = i + 1 {
|
||||||
|
if sql[i] != q[0][0] && sql[i] != q[1][0] {
|
||||||
|
_ = buf.WriteByte(sql[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
prefix, suffix := newQuoter[0][0], newQuoter[1][0]
|
||||||
|
var buf strings.Builder
|
||||||
|
for i, cnt := 0, 0; i < len(sql); i = i + 1 {
|
||||||
|
if cnt == 0 && sql[i] == q[0][0] {
|
||||||
|
_ = buf.WriteByte(prefix)
|
||||||
|
cnt = 1
|
||||||
|
} else if cnt == 1 && sql[i] == q[1][0] {
|
||||||
|
_ = buf.WriteByte(suffix)
|
||||||
|
cnt = 0
|
||||||
|
} else {
|
||||||
|
_ = buf.WriteByte(sql[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q Quoter) ReverseQuote(s string) string {
|
||||||
|
reverseQuoter := Quoter{q[1], q[0]}
|
||||||
|
return reverseQuoter.Quote(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trim removes quotes from s
|
||||||
|
func (q Quoter) Trim(s string) string {
|
||||||
|
if len(s) < 2 {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
if s[0:1] == q[0] {
|
||||||
|
s = s[1:]
|
||||||
|
}
|
||||||
|
if len(s) > 0 && s[len(s)-1:] == q[0] {
|
||||||
|
return s[:len(s)-1]
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func TrimSpaceJoin(a []string, sep string) string {
|
||||||
|
switch len(a) {
|
||||||
|
case 0:
|
||||||
|
return ""
|
||||||
|
case 1:
|
||||||
|
return a[0]
|
||||||
|
}
|
||||||
|
n := len(sep) * (len(a) - 1)
|
||||||
|
for i := 0; i < len(a); i++ {
|
||||||
|
n += len(a[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
var b strings.Builder
|
||||||
|
b.Grow(n)
|
||||||
|
b.WriteString(strings.TrimSpace(a[0]))
|
||||||
|
for _, s := range a[1:] {
|
||||||
|
b.WriteString(sep)
|
||||||
|
b.WriteString(strings.TrimSpace(s))
|
||||||
|
}
|
||||||
|
return b.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q Quoter) Join(s []string, splitter string) string {
|
||||||
|
//return fmt.Sprintf("%s%s%s", q[0], TrimSpaceJoin(s, fmt.Sprintf("%s%s%s", q[1], splitter, q[0])), q[1])
|
||||||
|
return q.Quote(TrimSpaceJoin(s, fmt.Sprintf("%s%s%s", q[1], splitter, q[0])))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q Quoter) QuoteTo(buf *strings.Builder, value string) {
|
||||||
|
if q.IsEmpty() {
|
||||||
|
buf.WriteString(value)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
prefix, suffix := q[0][0], q[1][0]
|
||||||
|
lastCh := 0 // 0 prefix, 1 char, 2 suffix
|
||||||
|
i := 0
|
||||||
|
for i < len(value) {
|
||||||
|
// start of a token; might be already quoted
|
||||||
|
if value[i] == '.' {
|
||||||
|
_ = buf.WriteByte('.')
|
||||||
|
lastCh = 1
|
||||||
|
i++
|
||||||
|
} else if value[i] == prefix || value[i] == '`' {
|
||||||
|
// Has quotes; skip/normalize `name` to prefix+name+sufix
|
||||||
|
var ch byte
|
||||||
|
if value[i] == prefix {
|
||||||
|
ch = suffix
|
||||||
|
} else {
|
||||||
|
ch = '`'
|
||||||
|
}
|
||||||
|
_ = buf.WriteByte(prefix)
|
||||||
|
i++
|
||||||
|
lastCh = 0
|
||||||
|
for ; i < len(value) && value[i] != ch && value[i] != ' '; i++ {
|
||||||
|
_ = buf.WriteByte(value[i])
|
||||||
|
lastCh = 1
|
||||||
|
}
|
||||||
|
_ = buf.WriteByte(suffix)
|
||||||
|
lastCh = 2
|
||||||
|
i++
|
||||||
|
} else if value[i] == ' ' {
|
||||||
|
if lastCh != 2 {
|
||||||
|
_ = buf.WriteByte(suffix)
|
||||||
|
lastCh = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
// a AS b or a b
|
||||||
|
for ; i < len(value); i++ {
|
||||||
|
if value[i] != ' ' && value[i-1] == ' ' && (len(value) > i+1 && !strings.EqualFold(value[i:i+2], "AS")) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = buf.WriteByte(value[i])
|
||||||
|
lastCh = 1
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Requires quotes
|
||||||
|
_ = buf.WriteByte(prefix)
|
||||||
|
for ; i < len(value) && value[i] != '.' && value[i] != ' '; i++ {
|
||||||
|
_ = buf.WriteByte(value[i])
|
||||||
|
lastCh = 1
|
||||||
|
}
|
||||||
|
_ = buf.WriteByte(suffix)
|
||||||
|
lastCh = 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,7 +2,7 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package xorm
|
package schemas
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -12,10 +12,11 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestQuoteTo(t *testing.T) {
|
func TestQuoteTo(t *testing.T) {
|
||||||
|
var quoter = Quoter{"[", "]"}
|
||||||
|
|
||||||
test := func(t *testing.T, expected string, value string) {
|
test := func(t *testing.T, expected string, value string) {
|
||||||
buf := &strings.Builder{}
|
buf := &strings.Builder{}
|
||||||
quoteTo(buf, "[]", value)
|
quoter.QuoteTo(buf, value)
|
||||||
assert.EqualValues(t, expected, buf.String())
|
assert.EqualValues(t, expected, buf.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +36,12 @@ func TestQuoteTo(t *testing.T) {
|
||||||
|
|
||||||
test(t, `["myschema].[mytable"]`, `"myschema.mytable"`)
|
test(t, `["myschema].[mytable"]`, `"myschema.mytable"`)
|
||||||
|
|
||||||
|
test(t, "[message_user] AS [sender]", "`message_user` AS `sender`")
|
||||||
|
|
||||||
|
assert.EqualValues(t, "[a],[b]", quoter.Join([]string{"a", " b"}, ","))
|
||||||
|
|
||||||
buf := &strings.Builder{}
|
buf := &strings.Builder{}
|
||||||
quoteTo(buf, "", "noquote")
|
quoter = Quoter{"", ""}
|
||||||
|
quoter.QuoteTo(buf, "noquote")
|
||||||
assert.EqualValues(t, "noquote", buf.String())
|
assert.EqualValues(t, "noquote", buf.String())
|
||||||
}
|
}
|
|
@ -137,13 +137,13 @@ func TestIn(t *testing.T) {
|
||||||
idsStr = idsStr[:len(idsStr)-1]
|
idsStr = idsStr[:len(idsStr)-1]
|
||||||
|
|
||||||
users := make([]Userinfo, 0)
|
users := make([]Userinfo, 0)
|
||||||
err = testEngine.In("(id)", ids[0], ids[1], ids[2]).Find(&users)
|
err = testEngine.In("id", ids[0], ids[1], ids[2]).Find(&users)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
fmt.Println(users)
|
fmt.Println(users)
|
||||||
assert.EqualValues(t, 3, len(users))
|
assert.EqualValues(t, 3, len(users))
|
||||||
|
|
||||||
users = make([]Userinfo, 0)
|
users = make([]Userinfo, 0)
|
||||||
err = testEngine.In("(id)", ids).Find(&users)
|
err = testEngine.In("id", ids).Find(&users)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
fmt.Println(users)
|
fmt.Println(users)
|
||||||
assert.EqualValues(t, 3, len(users))
|
assert.EqualValues(t, 3, len(users))
|
||||||
|
@ -161,7 +161,7 @@ func TestIn(t *testing.T) {
|
||||||
idsInterface = append(idsInterface, id)
|
idsInterface = append(idsInterface, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = testEngine.Where(department+" = ?", "dev").In("(id)", idsInterface...).Find(&users)
|
err = testEngine.Where(department+" = ?", "dev").In("id", idsInterface...).Find(&users)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
fmt.Println(users)
|
fmt.Println(users)
|
||||||
assert.EqualValues(t, 3, len(users))
|
assert.EqualValues(t, 3, len(users))
|
||||||
|
@ -175,11 +175,11 @@ func TestIn(t *testing.T) {
|
||||||
|
|
||||||
dev := testEngine.GetColumnMapper().Obj2Table("Dev")
|
dev := testEngine.GetColumnMapper().Obj2Table("Dev")
|
||||||
|
|
||||||
err = testEngine.In("(id)", 1).In("(id)", 2).In(department, dev).Find(&users)
|
err = testEngine.In("id", 1).In("id", 2).In(department, dev).Find(&users)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
fmt.Println(users)
|
fmt.Println(users)
|
||||||
|
|
||||||
cnt, err = testEngine.In("(id)", ids[0]).Update(&Userinfo{Departname: "dev-"})
|
cnt, err = testEngine.In("id", ids[0]).Update(&Userinfo{Departname: "dev-"})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.EqualValues(t, 1, cnt)
|
assert.EqualValues(t, 1, cnt)
|
||||||
|
|
||||||
|
@ -189,11 +189,11 @@ func TestIn(t *testing.T) {
|
||||||
assert.True(t, has)
|
assert.True(t, has)
|
||||||
assert.EqualValues(t, "dev-", user.Departname)
|
assert.EqualValues(t, "dev-", user.Departname)
|
||||||
|
|
||||||
cnt, err = testEngine.In("(id)", ids[0]).Update(&Userinfo{Departname: "dev"})
|
cnt, err = testEngine.In("id", ids[0]).Update(&Userinfo{Departname: "dev"})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.EqualValues(t, 1, cnt)
|
assert.EqualValues(t, 1, cnt)
|
||||||
|
|
||||||
cnt, err = testEngine.In("(id)", ids[1]).Delete(&Userinfo{})
|
cnt, err = testEngine.In("id", ids[1]).Delete(&Userinfo{})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.EqualValues(t, 1, cnt)
|
assert.EqualValues(t, 1, cnt)
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,14 +77,14 @@ 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)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
fmt.Println(users)
|
fmt.Println(users)
|
||||||
|
|
||||||
err = testEngine.Where("(id) > ?", 2).And("(id) < ?", 10).Find(&users)
|
err = testEngine.Where("id > ?", 2).And("id < ?", 10).Find(&users)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
panic(err)
|
panic(err)
|
||||||
|
@ -312,12 +312,12 @@ func TestOrderSameMapper(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)
|
||||||
fmt.Println(users)
|
fmt.Println(users)
|
||||||
|
|
||||||
users2 := make([]Userinfo, 0)
|
users2 := make([]Userinfo, 0)
|
||||||
err = testEngine.Asc("(id)", "Username").Desc("Height").Find(&users2)
|
err = testEngine.Asc("id", "Username").Desc("Height").Find(&users2)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
fmt.Println(users2)
|
fmt.Println(users2)
|
||||||
}
|
}
|
||||||
|
@ -790,8 +790,12 @@ func TestFindJoin(t *testing.T) {
|
||||||
DeviceId int64
|
DeviceId int64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Order struct {
|
||||||
|
Id int64
|
||||||
|
}
|
||||||
|
|
||||||
assert.NoError(t, prepareEngine())
|
assert.NoError(t, prepareEngine())
|
||||||
assertSync(t, new(SceneItem), new(DeviceUserPrivrels))
|
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").
|
||||||
|
@ -802,6 +806,10 @@ func TestFindJoin(t *testing.T) {
|
||||||
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)
|
||||||
|
err = testEngine.Join("INNER", "order", "`scene_item`.device_id=`order`.id").Find(&scenes)
|
||||||
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestJoinFindLimit(t *testing.T) {
|
func TestJoinFindLimit(t *testing.T) {
|
||||||
|
|
|
@ -201,7 +201,7 @@ func TestInsertDefault(t *testing.T) {
|
||||||
_, err = testEngine.Omit(testEngine.GetColumnMapper().Obj2Table("Status")).Insert(&di2)
|
_, err = testEngine.Omit(testEngine.GetColumnMapper().Obj2Table("Status")).Insert(&di2)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
has, err := testEngine.Desc("(id)").Get(di)
|
has, err := testEngine.Desc("id").Get(di)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
if !has {
|
if !has {
|
||||||
err = errors.New("error with no data")
|
err = errors.New("error with no data")
|
||||||
|
@ -247,7 +247,7 @@ func TestInsertDefault2(t *testing.T) {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
has, err := testEngine.Desc("(id)").Get(di)
|
has, err := testEngine.Desc("id").Get(di)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
@ -257,7 +257,7 @@ func TestInsertDefault2(t *testing.T) {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
has, err = testEngine.NoAutoCondition().Desc("(id)").Get(&di2)
|
has, err = testEngine.NoAutoCondition().Desc("id").Get(&di2)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
@ -330,7 +330,7 @@ func TestInsertCreated(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
has, err := testEngine.Desc("(id)").Get(di)
|
has, err := testEngine.Desc("id").Get(di)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -352,7 +352,7 @@ func TestInsertCreated(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
has, err = testEngine.Desc("(id)").Get(di2)
|
has, err = testEngine.Desc("id").Get(di2)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -374,7 +374,7 @@ func TestInsertCreated(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
has, err = testEngine.Desc("(id)").Get(di3)
|
has, err = testEngine.Desc("id").Get(di3)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -396,7 +396,7 @@ func TestInsertCreated(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
has, err = testEngine.Desc("(id)").Get(di4)
|
has, err = testEngine.Desc("id").Get(di4)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -418,7 +418,7 @@ func TestInsertCreated(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
has, err = testEngine.Desc("(id)").Get(di5)
|
has, err = testEngine.Desc("id").Get(di5)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -442,7 +442,7 @@ func TestInsertCreated(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
has, err = testEngine.Desc("(id)").Get(di6)
|
has, err = testEngine.Desc("id").Get(di6)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -517,7 +517,7 @@ func TestCreatedJsonTime(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
has, err := testEngine.Desc("(id)").Get(di5)
|
has, err := testEngine.Desc("id").Get(di5)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,15 +17,12 @@ func TestTransaction(t *testing.T) {
|
||||||
assert.NoError(t, prepareEngine())
|
assert.NoError(t, prepareEngine())
|
||||||
assertSync(t, new(Userinfo))
|
assertSync(t, new(Userinfo))
|
||||||
|
|
||||||
counter := func() {
|
counter := func(t *testing.T) {
|
||||||
total, err := testEngine.Count(&Userinfo{})
|
_, err := testEngine.Count(&Userinfo{})
|
||||||
if err != nil {
|
assert.NoError(t, err)
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
fmt.Printf("----now total %v records\n", total)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
counter()
|
counter(t)
|
||||||
//defer counter()
|
//defer counter()
|
||||||
|
|
||||||
session := testEngine.NewSession()
|
session := testEngine.NewSession()
|
||||||
|
@ -39,7 +36,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)
|
||||||
|
@ -119,7 +116,7 @@ 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.TableName("`Userinfo`", true)+" where `Username` = ?", user2.Username)
|
||||||
|
|
|
@ -137,7 +137,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:
|
||||||
|
@ -158,7 +158,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:
|
||||||
|
@ -175,7 +175,7 @@ func TestForUpdate(t *testing.T) {
|
||||||
wg.Add(1)
|
wg.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:
|
||||||
|
@ -193,7 +193,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
|
||||||
|
|
|
@ -618,7 +618,7 @@ func (statement *Statement) Cols(columns ...string) *Statement {
|
||||||
newColumns := statement.colmap2NewColsWithQuote()
|
newColumns := statement.colmap2NewColsWithQuote()
|
||||||
|
|
||||||
statement.ColumnStr = strings.Join(newColumns, ", ")
|
statement.ColumnStr = strings.Join(newColumns, ", ")
|
||||||
statement.ColumnStr = strings.Replace(statement.ColumnStr, statement.Engine.quote("*"), "*", -1)
|
statement.ColumnStr = strings.Replace(statement.ColumnStr, statement.Engine.dialect.Quoter().Quote("*"), "*", -1)
|
||||||
return statement
|
return statement
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -765,6 +765,11 @@ func (statement *Statement) Join(joinOP string, tablename interface{}, condition
|
||||||
statement.joinArgs = append(statement.joinArgs, subQueryArgs...)
|
statement.joinArgs = append(statement.joinArgs, subQueryArgs...)
|
||||||
default:
|
default:
|
||||||
tbName := statement.Engine.TableName(tablename, true)
|
tbName := statement.Engine.TableName(tablename, true)
|
||||||
|
if !isSubQuery(tbName) {
|
||||||
|
var buf strings.Builder
|
||||||
|
statement.Engine.QuoteTo(&buf, tbName)
|
||||||
|
tbName = buf.String()
|
||||||
|
}
|
||||||
fmt.Fprintf(&buf, "%s ON %v", tbName, condition)
|
fmt.Fprintf(&buf, "%s ON %v", tbName, condition)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"xorm.io/builder"
|
"xorm.io/builder"
|
||||||
|
"xorm.io/xorm/schemas"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ErrUnsupportedExprType struct {
|
type ErrUnsupportedExprType struct {
|
||||||
|
@ -40,7 +41,7 @@ func (exprs *exprParams) addParam(colName string, arg interface{}) {
|
||||||
|
|
||||||
func (exprs *exprParams) isColExist(colName string) bool {
|
func (exprs *exprParams) isColExist(colName string) bool {
|
||||||
for _, name := range exprs.colNames {
|
for _, name := range exprs.colNames {
|
||||||
if strings.EqualFold(trimQuote(name), trimQuote(colName)) {
|
if strings.EqualFold(schemas.CommonQuoter.Trim(name), schemas.CommonQuoter.Trim(colName)) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
// Copyright 2019 The Xorm Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package xorm
|
|
||||||
|
|
||||||
func trimQuote(s string) string {
|
|
||||||
if len(s) == 0 {
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
if s[0] == '`' {
|
|
||||||
s = s[1:]
|
|
||||||
}
|
|
||||||
if len(s) > 0 && s[len(s)-1] == '`' {
|
|
||||||
return s[:len(s)-1]
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
Loading…
Reference in New Issue