Co-authored-by: zeripath <art27@cantab.net>tags/v1.16.0-rc1
mvdan.cc/xurls/v2 v2.2.0 | mvdan.cc/xurls/v2 v2.2.0 | ||||
strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251 | strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251 | ||||
xorm.io/builder v0.3.9 | xorm.io/builder v0.3.9 | ||||
xorm.io/xorm v1.2.2 | |||||
xorm.io/xorm v1.2.4 | |||||
) | ) | ||||
replace github.com/hashicorp/go-version => github.com/6543/go-version v1.3.1 | replace github.com/hashicorp/go-version => github.com/6543/go-version v1.3.1 |
xorm.io/builder v0.3.9 h1:Sd65/LdWyO7LR8+Cbd+e7mm3sK/7U9k0jS3999IDHMc= | xorm.io/builder v0.3.9 h1:Sd65/LdWyO7LR8+Cbd+e7mm3sK/7U9k0jS3999IDHMc= | ||||
xorm.io/builder v0.3.9/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE= | xorm.io/builder v0.3.9/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE= | ||||
xorm.io/xorm v1.0.6/go.mod h1:uF9EtbhODq5kNWxMbnBEj8hRRZnlcNSz2t2N7HW/+A4= | xorm.io/xorm v1.0.6/go.mod h1:uF9EtbhODq5kNWxMbnBEj8hRRZnlcNSz2t2N7HW/+A4= | ||||
xorm.io/xorm v1.2.2 h1:FFBOEvJ++8fYBA9cywf2sxDVmFktl1SpJzTAG1ab06Y= | |||||
xorm.io/xorm v1.2.2/go.mod h1:fTG8tSjk6O1BYxwuohZUK+S1glnRycsCF05L1qQyEU0= | |||||
xorm.io/xorm v1.2.4 h1:2MQV4wJt4kY6CYJsLxjCLzBen7+aqVxqDTIwfnR59g4= | |||||
xorm.io/xorm v1.2.4/go.mod h1:fTG8tSjk6O1BYxwuohZUK+S1glnRycsCF05L1qQyEU0= |
# xorm.io/builder v0.3.9 | # xorm.io/builder v0.3.9 | ||||
## explicit | ## explicit | ||||
xorm.io/builder | xorm.io/builder | ||||
# xorm.io/xorm v1.2.2 | |||||
# xorm.io/xorm v1.2.4 | |||||
## explicit | ## explicit | ||||
xorm.io/xorm | xorm.io/xorm | ||||
xorm.io/xorm/caches | xorm.io/xorm/caches |
if src == nil { | if src == nil { | ||||
return nil | return nil | ||||
} | } | ||||
if v, ok := src.(*interface{}); ok { | |||||
return AssignValue(dv, *v) | |||||
} | |||||
if dv.Type().Implements(scannerType) { | if dv.Type().Implements(scannerType) { | ||||
return dv.Interface().(sql.Scanner).Scan(src) | return dv.Interface().(sql.Scanner).Scan(src) |
return db.uri | return db.uri | ||||
} | } | ||||
// CreateTableSQL implements Dialect | |||||
func (db *Base) CreateTableSQL(table *schemas.Table, tableName string) ([]string, bool) { | |||||
if tableName == "" { | |||||
tableName = table.Name | |||||
} | |||||
quoter := db.dialect.Quoter() | |||||
var b strings.Builder | |||||
b.WriteString("CREATE TABLE IF NOT EXISTS ") | |||||
quoter.QuoteTo(&b, tableName) | |||||
b.WriteString(" (") | |||||
for i, colName := range table.ColumnsSeq() { | |||||
col := table.GetColumn(colName) | |||||
s, _ := ColumnString(db.dialect, col, col.IsPrimaryKey && len(table.PrimaryKeys) == 1) | |||||
b.WriteString(s) | |||||
if i != len(table.ColumnsSeq())-1 { | |||||
b.WriteString(", ") | |||||
} | |||||
} | |||||
if len(table.PrimaryKeys) > 1 { | |||||
b.WriteString(", PRIMARY KEY (") | |||||
b.WriteString(quoter.Join(table.PrimaryKeys, ",")) | |||||
b.WriteString(")") | |||||
} | |||||
b.WriteString(")") | |||||
return []string{b.String()}, false | |||||
} | |||||
// DropTableSQL returns drop table SQL | // DropTableSQL returns drop table SQL | ||||
func (db *Base) DropTableSQL(tableName string) (string, bool) { | func (db *Base) DropTableSQL(tableName string) (string, bool) { | ||||
quote := db.dialect.Quoter().Quote | quote := db.dialect.Quoter().Quote |
} | } | ||||
func (db *mssql) CreateTableSQL(table *schemas.Table, tableName string) ([]string, bool) { | func (db *mssql) CreateTableSQL(table *schemas.Table, tableName string) ([]string, bool) { | ||||
var sql string | |||||
if tableName == "" { | if tableName == "" { | ||||
tableName = table.Name | tableName = table.Name | ||||
} | } | ||||
sql = "IF NOT EXISTS (SELECT [name] FROM sys.tables WHERE [name] = '" + tableName + "' ) CREATE TABLE " | |||||
quoter := db.dialect.Quoter() | |||||
var b strings.Builder | |||||
b.WriteString("IF NOT EXISTS (SELECT [name] FROM sys.tables WHERE [name] = '") | |||||
quoter.QuoteTo(&b, tableName) | |||||
b.WriteString("' ) CREATE TABLE ") | |||||
quoter.QuoteTo(&b, tableName) | |||||
b.WriteString(" (") | |||||
sql += db.Quoter().Quote(tableName) + " (" | |||||
pkList := table.PrimaryKeys | |||||
for _, colName := range table.ColumnsSeq() { | |||||
for i, colName := range table.ColumnsSeq() { | |||||
col := table.GetColumn(colName) | col := table.GetColumn(colName) | ||||
s, _ := ColumnString(db, col, col.IsPrimaryKey && len(pkList) == 1) | |||||
sql += s | |||||
sql = strings.TrimSpace(sql) | |||||
sql += ", " | |||||
s, _ := ColumnString(db.dialect, col, col.IsPrimaryKey && len(table.PrimaryKeys) == 1) | |||||
b.WriteString(s) | |||||
if i != len(table.ColumnsSeq())-1 { | |||||
b.WriteString(", ") | |||||
} | |||||
} | } | ||||
if len(pkList) > 1 { | |||||
sql += "PRIMARY KEY ( " | |||||
sql += strings.Join(pkList, ",") | |||||
sql += " ), " | |||||
if len(table.PrimaryKeys) > 1 { | |||||
b.WriteString(", PRIMARY KEY (") | |||||
b.WriteString(quoter.Join(table.PrimaryKeys, ",")) | |||||
b.WriteString(")") | |||||
} | } | ||||
sql = sql[:len(sql)-2] + ")" | |||||
sql += ";" | |||||
return []string{sql}, true | |||||
b.WriteString(")") | |||||
return []string{b.String()}, true | |||||
} | } | ||||
func (db *mssql) ForUpdateSQL(query string) string { | func (db *mssql) ForUpdateSQL(query string) string { |
} | } | ||||
func (db *mysql) CreateTableSQL(table *schemas.Table, tableName string) ([]string, bool) { | func (db *mysql) CreateTableSQL(table *schemas.Table, tableName string) ([]string, bool) { | ||||
var sql = "CREATE TABLE IF NOT EXISTS " | |||||
if tableName == "" { | if tableName == "" { | ||||
tableName = table.Name | tableName = table.Name | ||||
} | } | ||||
quoter := db.Quoter() | |||||
sql += quoter.Quote(tableName) | |||||
sql += " (" | |||||
if len(table.ColumnsSeq()) > 0 { | |||||
pkList := table.PrimaryKeys | |||||
for _, colName := range table.ColumnsSeq() { | |||||
col := table.GetColumn(colName) | |||||
s, _ := ColumnString(db, col, col.IsPrimaryKey && len(pkList) == 1) | |||||
sql += s | |||||
sql = strings.TrimSpace(sql) | |||||
if len(col.Comment) > 0 { | |||||
sql += " COMMENT '" + col.Comment + "'" | |||||
} | |||||
sql += ", " | |||||
quoter := db.dialect.Quoter() | |||||
var b strings.Builder | |||||
b.WriteString("CREATE TABLE IF NOT EXISTS ") | |||||
quoter.QuoteTo(&b, tableName) | |||||
b.WriteString(" (") | |||||
for i, colName := range table.ColumnsSeq() { | |||||
col := table.GetColumn(colName) | |||||
s, _ := ColumnString(db.dialect, col, col.IsPrimaryKey && len(table.PrimaryKeys) == 1) | |||||
b.WriteString(s) | |||||
if len(col.Comment) > 0 { | |||||
b.WriteString(" COMMENT '") | |||||
b.WriteString(col.Comment) | |||||
b.WriteString("'") | |||||
} | } | ||||
if len(pkList) > 1 { | |||||
sql += "PRIMARY KEY ( " | |||||
sql += quoter.Join(pkList, ",") | |||||
sql += " ), " | |||||
if i != len(table.ColumnsSeq())-1 { | |||||
b.WriteString(", ") | |||||
} | } | ||||
} | |||||
sql = sql[:len(sql)-2] | |||||
if len(table.PrimaryKeys) > 1 { | |||||
b.WriteString(", PRIMARY KEY (") | |||||
b.WriteString(quoter.Join(table.PrimaryKeys, ",")) | |||||
b.WriteString(")") | |||||
} | } | ||||
sql += ")" | |||||
b.WriteString(")") | |||||
if table.StoreEngine != "" { | if table.StoreEngine != "" { | ||||
sql += " ENGINE=" + table.StoreEngine | |||||
b.WriteString(" ENGINE=") | |||||
b.WriteString(table.StoreEngine) | |||||
} | } | ||||
var charset = table.Charset | var charset = table.Charset | ||||
charset = db.URI().Charset | charset = db.URI().Charset | ||||
} | } | ||||
if len(charset) != 0 { | if len(charset) != 0 { | ||||
sql += " DEFAULT CHARSET " + charset | |||||
b.WriteString(" DEFAULT CHARSET ") | |||||
b.WriteString(charset) | |||||
} | } | ||||
if db.rowFormat != "" { | if db.rowFormat != "" { | ||||
sql += " ROW_FORMAT=" + db.rowFormat | |||||
b.WriteString(" ROW_FORMAT=") | |||||
b.WriteString(db.rowFormat) | |||||
} | } | ||||
return []string{sql}, true | |||||
return []string{b.String()}, true | |||||
} | } | ||||
func (db *mysql) Filters() []Filter { | func (db *mysql) Filters() []Filter { |
return "" | return "" | ||||
} | } | ||||
func (db *postgres) CreateTableSQL(table *schemas.Table, tableName string) ([]string, bool) { | |||||
var sql string | |||||
sql = "CREATE TABLE IF NOT EXISTS " | |||||
if tableName == "" { | |||||
tableName = table.Name | |||||
} | |||||
quoter := db.Quoter() | |||||
sql += quoter.Quote(tableName) | |||||
sql += " (" | |||||
if len(table.ColumnsSeq()) > 0 { | |||||
pkList := table.PrimaryKeys | |||||
for _, colName := range table.ColumnsSeq() { | |||||
col := table.GetColumn(colName) | |||||
s, _ := ColumnString(db, col, col.IsPrimaryKey && len(pkList) == 1) | |||||
sql += s | |||||
sql = strings.TrimSpace(sql) | |||||
sql += ", " | |||||
} | |||||
if len(pkList) > 1 { | |||||
sql += "PRIMARY KEY ( " | |||||
sql += quoter.Join(pkList, ",") | |||||
sql += " ), " | |||||
} | |||||
sql = sql[:len(sql)-2] | |||||
} | |||||
sql += ")" | |||||
return []string{sql}, true | |||||
} | |||||
func (db *postgres) IndexCheckSQL(tableName, idxName string) (string, []interface{}) { | func (db *postgres) IndexCheckSQL(tableName, idxName string) (string, []interface{}) { | ||||
if len(db.getSchema()) == 0 { | if len(db.getSchema()) == 0 { | ||||
args := []interface{}{tableName, idxName} | args := []interface{}{tableName, idxName} |
return fmt.Sprintf("DROP INDEX %v", db.Quoter().Quote(idxName)) | return fmt.Sprintf("DROP INDEX %v", db.Quoter().Quote(idxName)) | ||||
} | } | ||||
func (db *sqlite3) CreateTableSQL(table *schemas.Table, tableName string) ([]string, bool) { | |||||
var sql string | |||||
sql = "CREATE TABLE IF NOT EXISTS " | |||||
if tableName == "" { | |||||
tableName = table.Name | |||||
} | |||||
quoter := db.Quoter() | |||||
sql += quoter.Quote(tableName) | |||||
sql += " (" | |||||
if len(table.ColumnsSeq()) > 0 { | |||||
pkList := table.PrimaryKeys | |||||
for _, colName := range table.ColumnsSeq() { | |||||
col := table.GetColumn(colName) | |||||
s, _ := ColumnString(db, col, col.IsPrimaryKey && len(pkList) == 1) | |||||
sql += s | |||||
sql = strings.TrimSpace(sql) | |||||
sql += ", " | |||||
} | |||||
if len(pkList) > 1 { | |||||
sql += "PRIMARY KEY ( " | |||||
sql += quoter.Join(pkList, ",") | |||||
sql += " ), " | |||||
} | |||||
sql = sql[:len(sql)-2] | |||||
} | |||||
sql += ")" | |||||
return []string{sql}, true | |||||
} | |||||
func (db *sqlite3) ForUpdateSQL(query string) string { | func (db *sqlite3) ForUpdateSQL(query string) string { | ||||
return query | return query | ||||
} | } |
// Copyright 2021 The Xorm Authors. All rights reserved. | |||||
// Use of this source code is governed by a BSD-style | |||||
// license that can be found in the LICENSE file. | |||||
package utils | |||||
import "reflect" | |||||
// New creates a value according type | |||||
func New(tp reflect.Type, length, cap int) reflect.Value { | |||||
switch tp.Kind() { | |||||
case reflect.Slice: | |||||
slice := reflect.MakeSlice(tp, length, cap) | |||||
x := reflect.New(slice.Type()) | |||||
x.Elem().Set(slice) | |||||
return x | |||||
case reflect.Map: | |||||
mp := reflect.MakeMapWithSize(tp, cap) | |||||
x := reflect.New(mp.Type()) | |||||
x.Elem().Set(mp) | |||||
return x | |||||
default: | |||||
return reflect.New(tp) | |||||
} | |||||
} |
// Next move cursor to next record, return false if end has reached | // Next move cursor to next record, return false if end has reached | ||||
func (rows *Rows) Next() bool { | func (rows *Rows) Next() bool { | ||||
return rows.rows.Next() | |||||
if rows.rows != nil { | |||||
return rows.rows.Next() | |||||
} | |||||
return false | |||||
} | } | ||||
// Err returns the error, if any, that was encountered during iteration. Err may be called after an explicit or implicit Close. | // Err returns the error, if any, that was encountered during iteration. Err may be called after an explicit or implicit Close. | ||||
func (rows *Rows) Err() error { | func (rows *Rows) Err() error { | ||||
return rows.rows.Err() | |||||
if rows.rows != nil { | |||||
return rows.rows.Err() | |||||
} | |||||
return nil | |||||
} | } | ||||
// Scan row record to bean properties | // Scan row record to bean properties |
return session.engine | return session.engine | ||||
} | } | ||||
// Tx returns session tx | |||||
func (session *Session) Tx() *core.Tx { | |||||
return session.tx | |||||
} | |||||
func (session *Session) getQueryer() core.Queryer { | func (session *Session) getQueryer() core.Queryer { | ||||
if session.tx != nil { | if session.tx != nil { | ||||
return session.tx | return session.tx |
} | } | ||||
func (session *Session) noCacheFind(table *schemas.Table, containerValue reflect.Value, sqlStr string, args ...interface{}) error { | func (session *Session) noCacheFind(table *schemas.Table, containerValue reflect.Value, sqlStr string, args ...interface{}) error { | ||||
elemType := containerValue.Type().Elem() | |||||
var isPointer bool | |||||
if elemType.Kind() == reflect.Ptr { | |||||
isPointer = true | |||||
elemType = elemType.Elem() | |||||
} | |||||
if elemType.Kind() == reflect.Ptr { | |||||
return errors.New("pointer to pointer is not supported") | |||||
} | |||||
rows, err := session.queryRows(sqlStr, args...) | rows, err := session.queryRows(sqlStr, args...) | ||||
if err != nil { | if err != nil { | ||||
return err | return err | ||||
return err | return err | ||||
} | } | ||||
var newElemFunc func(fields []string) reflect.Value | |||||
elemType := containerValue.Type().Elem() | |||||
var isPointer bool | |||||
if elemType.Kind() == reflect.Ptr { | |||||
isPointer = true | |||||
elemType = elemType.Elem() | |||||
} | |||||
if elemType.Kind() == reflect.Ptr { | |||||
return errors.New("pointer to pointer is not supported") | |||||
} | |||||
newElemFunc = func(fields []string) reflect.Value { | |||||
switch elemType.Kind() { | |||||
case reflect.Slice: | |||||
slice := reflect.MakeSlice(elemType, len(fields), len(fields)) | |||||
x := reflect.New(slice.Type()) | |||||
x.Elem().Set(slice) | |||||
return x | |||||
case reflect.Map: | |||||
mp := reflect.MakeMap(elemType) | |||||
x := reflect.New(mp.Type()) | |||||
x.Elem().Set(mp) | |||||
return x | |||||
} | |||||
return reflect.New(elemType) | |||||
var newElemFunc = func(fields []string) reflect.Value { | |||||
return utils.New(elemType, len(fields), len(fields)) | |||||
} | } | ||||
var containerValueSetFunc func(*reflect.Value, schemas.PK) error | var containerValueSetFunc func(*reflect.Value, schemas.PK) error | ||||
containerValueSetFunc = func(newValue *reflect.Value, pk schemas.PK) error { | containerValueSetFunc = func(newValue *reflect.Value, pk schemas.PK) error { | ||||
keyValue := reflect.New(keyType) | keyValue := reflect.New(keyType) | ||||
err := convertPKToValue(table, keyValue.Interface(), pk) | |||||
if err != nil { | |||||
return err | |||||
cols := table.PKColumns() | |||||
if len(cols) == 1 { | |||||
if err := convert.AssignValue(keyValue, pk[0]); err != nil { | |||||
return err | |||||
} | |||||
} else { | |||||
keyValue.Set(reflect.ValueOf(&pk)) | |||||
} | } | ||||
if isPointer { | if isPointer { | ||||
containerValue.SetMapIndex(keyValue.Elem(), newValue.Elem().Addr()) | containerValue.SetMapIndex(keyValue.Elem(), newValue.Elem().Addr()) | ||||
} else { | } else { | ||||
if elemType.Kind() == reflect.Struct { | if elemType.Kind() == reflect.Struct { | ||||
var newValue = newElemFunc(fields) | var newValue = newElemFunc(fields) | ||||
dataStruct := utils.ReflectValue(newValue.Interface()) | |||||
tb, err := session.engine.tagParser.ParseWithCache(dataStruct) | |||||
tb, err := session.engine.tagParser.ParseWithCache(newValue) | |||||
if err != nil { | if err != nil { | ||||
return err | return err | ||||
} | } | ||||
default: | default: | ||||
err = rows.Scan(bean) | err = rows.Scan(bean) | ||||
} | } | ||||
if err != nil { | if err != nil { | ||||
return err | return err | ||||
} | } | ||||
return rows.Err() | return rows.Err() | ||||
} | } | ||||
func convertPKToValue(table *schemas.Table, dst interface{}, pk schemas.PK) error { | |||||
cols := table.PKColumns() | |||||
if len(cols) == 1 { | |||||
return convert.Assign(dst, pk[0], nil, nil) | |||||
} | |||||
dst = pk | |||||
return nil | |||||
} | |||||
func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr interface{}, args ...interface{}) (err error) { | func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr interface{}, args ...interface{}) (err error) { | ||||
if !session.canCache() || | if !session.canCache() || | ||||
utils.IndexNoCase(sqlStr, "having") != -1 || | utils.IndexNoCase(sqlStr, "having") != -1 || |