Move zero functions to a standalone package #1548
48
engine.go
48
engine.go
@ -191,11 +191,6 @@ func (engine *Engine) SupportInsertMany() bool {
|
||||
return engine.dialect.SupportInsertMany()
|
||||
}
|
||||
|
||||
func (engine *Engine) quoteColumns(columnStr string) string {
|
||||
columns := strings.Split(columnStr, ",")
|
||||
return engine.dialect.Quoter().Join(columns, ",")
|
||||
}
|
||||
|
||||
// Quote Use QuoteStr quote the string sql
|
||||
func (engine *Engine) Quote(value string) string {
|
||||
value = strings.TrimSpace(value)
|
||||
@ -222,18 +217,6 @@ func (engine *Engine) QuoteTo(buf *strings.Builder, value string) {
|
||||
engine.dialect.Quoter().QuoteTo(buf, value)
|
||||
}
|
||||
|
||||
/*
|
||||
func (engine *Engine) quote(sql string) string {
|
||||
return engine.dialect.Quote(sql)
|
||||
}*/
|
||||
|
||||
// SqlType will be deprecated, please use SQLType instead
|
||||
//
|
||||
// Deprecated: use SQLType instead
|
||||
func (engine *Engine) SqlType(c *schemas.Column) string {
|
||||
return engine.SQLType(c)
|
||||
}
|
||||
|
||||
// SQLType A simple wrapper to dialect's core.SqlType method
|
||||
func (engine *Engine) SQLType(c *schemas.Column) string {
|
||||
return engine.dialect.SQLType(c)
|
||||
@ -335,14 +318,6 @@ func (engine *Engine) logSQL(sqlStr string, sqlArgs ...interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
// Sql provides raw sql input parameter. When you have a complex SQL statement
|
||||
// and cannot use Where, Id, In and etc. Methods to describe, you can use SQL.
|
||||
//
|
||||
// Deprecated: use SQL instead.
|
||||
func (engine *Engine) Sql(querystring string, args ...interface{}) *Session {
|
||||
return engine.SQL(querystring, args...)
|
||||
}
|
||||
|
||||
// SQL method let's you manually write raw SQL and operate
|
||||
// For example:
|
||||
//
|
||||
@ -597,13 +572,6 @@ func (engine *Engine) Where(query interface{}, args ...interface{}) *Session {
|
||||
return session.Where(query, args...)
|
||||
}
|
||||
|
||||
// Id will be deprecated, please use ID instead
|
||||
func (engine *Engine) Id(id interface{}) *Session {
|
||||
session := engine.NewSession()
|
||||
session.isAutoClose = true
|
||||
return session.Id(id)
|
||||
}
|
||||
|
||||
// ID method provoide a condition as (id) = ?
|
||||
func (engine *Engine) ID(id interface{}) *Session {
|
||||
session := engine.NewSession()
|
||||
@ -1092,23 +1060,9 @@ func (engine *Engine) IsTableExist(beanOrTableName interface{}) (bool, error) {
|
||||
return session.IsTableExist(beanOrTableName)
|
||||
}
|
||||
|
||||
// IdOf get id from one struct
|
||||
//
|
||||
// Deprecated: use IDOf instead.
|
||||
func (engine *Engine) IdOf(bean interface{}) schemas.PK {
|
||||
return engine.IDOf(bean)
|
||||
}
|
||||
|
||||
// IDOf get id from one struct
|
||||
func (engine *Engine) IDOf(bean interface{}) schemas.PK {
|
||||
return engine.IdOfV(reflect.ValueOf(bean))
|
||||
}
|
||||
|
||||
// IdOfV get id from one value of struct
|
||||
//
|
||||
// Deprecated: use IDOfV instead.
|
||||
func (engine *Engine) IdOfV(rv reflect.Value) schemas.PK {
|
||||
return engine.IDOfV(rv)
|
||||
return engine.IDOfV(reflect.ValueOf(bean))
|
||||
}
|
||||
|
||||
// IDOfV get id from one value of struct
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"time"
|
||||
|
||||
"xorm.io/builder"
|
||||
"xorm.io/xorm/internal/utils"
|
||||
"xorm.io/xorm/schemas"
|
||||
)
|
||||
|
||||
@ -169,7 +170,7 @@ func (engine *Engine) buildConds(table *schemas.Table, bean interface{},
|
||||
pkField := reflect.Indirect(fieldValue).FieldByName(table.PKColumns()[0].FieldName)
|
||||
// fix non-int pk issues
|
||||
//if pkField.Int() != 0 {
|
||||
if pkField.IsValid() && !isZero(pkField.Interface()) {
|
||||
if pkField.IsValid() && !utils.IsZero(pkField.Interface()) {
|
||||
val = pkField.Interface()
|
||||
} else {
|
||||
continue
|
||||
|
107
helpers.go
107
helpers.go
@ -11,8 +11,6 @@ import (
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"xorm.io/xorm/schemas"
|
||||
)
|
||||
|
||||
// str2PK convert string value to primary key value according to tp
|
||||
@ -95,95 +93,6 @@ func str2PK(s string, tp reflect.Type) (interface{}, error) {
|
||||
return v.Interface(), nil
|
||||
}
|
||||
|
||||
type zeroable interface {
|
||||
IsZero() bool
|
||||
}
|
||||
|
||||
func isZero(k interface{}) bool {
|
||||
switch k.(type) {
|
||||
case int:
|
||||
return k.(int) == 0
|
||||
case int8:
|
||||
return k.(int8) == 0
|
||||
case int16:
|
||||
return k.(int16) == 0
|
||||
case int32:
|
||||
return k.(int32) == 0
|
||||
case int64:
|
||||
return k.(int64) == 0
|
||||
case uint:
|
||||
return k.(uint) == 0
|
||||
case uint8:
|
||||
return k.(uint8) == 0
|
||||
case uint16:
|
||||
return k.(uint16) == 0
|
||||
case uint32:
|
||||
return k.(uint32) == 0
|
||||
case uint64:
|
||||
return k.(uint64) == 0
|
||||
case float32:
|
||||
return k.(float32) == 0
|
||||
case float64:
|
||||
return k.(float64) == 0
|
||||
case bool:
|
||||
return k.(bool) == false
|
||||
case string:
|
||||
return k.(string) == ""
|
||||
case zeroable:
|
||||
return k.(zeroable).IsZero()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isZeroValue(v reflect.Value) bool {
|
||||
if isZero(v.Interface()) {
|
||||
return true
|
||||
}
|
||||
switch v.Kind() {
|
||||
case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
|
||||
return v.IsNil()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isStructZero(v reflect.Value) bool {
|
||||
if !v.IsValid() {
|
||||
return true
|
||||
}
|
||||
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
field := v.Field(i)
|
||||
switch field.Kind() {
|
||||
case reflect.Ptr:
|
||||
field = field.Elem()
|
||||
fallthrough
|
||||
case reflect.Struct:
|
||||
if !isStructZero(field) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
if field.CanInterface() && !isZero(field.Interface()) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isArrayValueZero(v reflect.Value) bool {
|
||||
if !v.IsValid() || v.Len() == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
if !isZero(v.Index(i).Interface()) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func int64ToIntValue(id int64, tp reflect.Type) reflect.Value {
|
||||
var v interface{}
|
||||
kind := tp.Kind()
|
||||
@ -229,15 +138,6 @@ func int64ToInt(id int64, tp reflect.Type) interface{} {
|
||||
return int64ToIntValue(id, tp).Interface()
|
||||
}
|
||||
|
||||
func isPKZero(pk schemas.PK) bool {
|
||||
for _, k := range pk {
|
||||
if isZero(k) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func indexNoCase(s, sep string) int {
|
||||
return strings.Index(strings.ToLower(s), strings.ToLower(sep))
|
||||
}
|
||||
@ -314,10 +214,3 @@ func eraseAny(value string, strToErase ...string) string {
|
||||
|
||||
return replacer.Replace(value)
|
||||
}
|
||||
|
||||
func quoteColumns(cols []string, quoteFunc func(string) string, sep string) string {
|
||||
for i := range cols {
|
||||
cols[i] = quoteFunc(cols[i])
|
||||
}
|
||||
return strings.Join(cols, sep+" ")
|
||||
}
|
||||
|
@ -16,12 +16,3 @@ func TestEraseAny(t *testing.T) {
|
||||
assert.EqualValues(t, "SELECT * FROM table.[table_name]", eraseAny(raw, "`"))
|
||||
assert.EqualValues(t, "SELECT * FROM table.table_name", eraseAny(raw, "`", "[", "]"))
|
||||
}
|
||||
|
||||
func TestQuoteColumns(t *testing.T) {
|
||||
cols := []string{"f1", "f2", "f3"}
|
||||
quoteFunc := func(value string) string {
|
||||
return "[" + value + "]"
|
||||
}
|
||||
|
||||
assert.EqualValues(t, "[f1], [f2], [f3]", quoteColumns(cols, quoteFunc, ","))
|
||||
}
|
||||
|
98
internal/utils/zero.go
Normal file
98
internal/utils/zero.go
Normal file
@ -0,0 +1,98 @@
|
||||
// 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 utils
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
)
|
||||
|
||||
type Zeroable interface {
|
||||
IsZero() bool
|
||||
}
|
||||
|
||||
func IsZero(k interface{}) bool {
|
||||
switch k.(type) {
|
||||
case int:
|
||||
return k.(int) == 0
|
||||
case int8:
|
||||
return k.(int8) == 0
|
||||
case int16:
|
||||
return k.(int16) == 0
|
||||
case int32:
|
||||
return k.(int32) == 0
|
||||
case int64:
|
||||
return k.(int64) == 0
|
||||
case uint:
|
||||
return k.(uint) == 0
|
||||
case uint8:
|
||||
return k.(uint8) == 0
|
||||
case uint16:
|
||||
return k.(uint16) == 0
|
||||
case uint32:
|
||||
return k.(uint32) == 0
|
||||
case uint64:
|
||||
return k.(uint64) == 0
|
||||
case float32:
|
||||
return k.(float32) == 0
|
||||
case float64:
|
||||
return k.(float64) == 0
|
||||
case bool:
|
||||
return k.(bool) == false
|
||||
case string:
|
||||
return k.(string) == ""
|
||||
case Zeroable:
|
||||
return k.(Zeroable).IsZero()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func IsValueZero(v reflect.Value) bool {
|
||||
if IsZero(v.Interface()) {
|
||||
return true
|
||||
}
|
||||
switch v.Kind() {
|
||||
case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
|
||||
return v.IsNil()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func IsStructZero(v reflect.Value) bool {
|
||||
if !v.IsValid() {
|
||||
return true
|
||||
}
|
||||
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
field := v.Field(i)
|
||||
switch field.Kind() {
|
||||
case reflect.Ptr:
|
||||
field = field.Elem()
|
||||
fallthrough
|
||||
case reflect.Struct:
|
||||
if !IsStructZero(field) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
if field.CanInterface() && !IsZero(field.Interface()) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func IsArrayZero(v reflect.Value) bool {
|
||||
if !v.IsValid() || v.Len() == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
if !IsZero(v.Index(i).Interface()) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
@ -7,6 +7,8 @@ package schemas
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/gob"
|
||||
|
||||
"xorm.io/xorm/internal/utils"
|
||||
)
|
||||
|
||||
type PK []interface{}
|
||||
@ -16,6 +18,15 @@ func NewPK(pks ...interface{}) *PK {
|
||||
return &p
|
||||
}
|
||||
|
||||
func (p *PK) IsZero() bool {
|
||||
for _, k := range *p {
|
||||
if utils.IsZero(k) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *PK) ToString() (string, error) {
|
||||
buf := new(bytes.Buffer)
|
||||
enc := gob.NewEncoder(buf)
|
||||
|
@ -5,7 +5,6 @@
|
||||
package schemas
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@ -76,7 +75,7 @@ func (q Quoter) Trim(s string) string {
|
||||
return s
|
||||
}
|
||||
|
||||
func TrimSpaceJoin(a []string, sep string) string {
|
||||
func (q Quoter) Join(a []string, sep string) string {
|
||||
switch len(a) {
|
||||
case 0:
|
||||
return ""
|
||||
@ -90,19 +89,21 @@ func TrimSpaceJoin(a []string, sep string) string {
|
||||
|
||||
var b strings.Builder
|
||||
b.Grow(n)
|
||||
b.WriteString(strings.TrimSpace(a[0]))
|
||||
for _, s := range a[1:] {
|
||||
for i, s := range a {
|
||||
if i > 0 {
|
||||
b.WriteString(sep)
|
||||
}
|
||||
if q[0] != "" {
|
||||
b.WriteString(q[0])
|
||||
}
|
||||
b.WriteString(strings.TrimSpace(s))
|
||||
if q[1] != "" {
|
||||
b.WriteString(q[1])
|
||||
}
|
||||
}
|
||||
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)
|
||||
|
@ -45,3 +45,13 @@ func TestQuoteTo(t *testing.T) {
|
||||
quoter.QuoteTo(buf, "noquote")
|
||||
assert.EqualValues(t, "noquote", buf.String())
|
||||
}
|
||||
|
||||
func TestJoin(t *testing.T) {
|
||||
cols := []string{"f1", "f2", "f3"}
|
||||
quoter := Quoter{"[", "]"}
|
||||
|
||||
assert.EqualValues(t, "[f1], [f2], [f3]", quoter.Join(cols, ", "))
|
||||
|
||||
quoter = Quoter{"", ""}
|
||||
assert.EqualValues(t, "f1, f2, f3", quoter.Join(cols, ", "))
|
||||
}
|
||||
|
@ -703,7 +703,7 @@ func (session *Session) slice2Bean(scanResults []interface{}, fields []string, b
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !isPKZero(pk) {
|
||||
if !pk.IsZero() {
|
||||
// !nashtsai! TODO for hasOne relationship, it's preferred to use join query for eager fetch
|
||||
// however, also need to consider adding a 'lazy' attribute to xorm tag which allow hasOne
|
||||
// property to be fetched lazily
|
||||
|
@ -6,14 +6,6 @@ package xorm
|
||||
|
||||
import "xorm.io/builder"
|
||||
|
||||
// Sql provides raw sql input parameter. When you have a complex SQL statement
|
||||
// and cannot use Where, Id, In and etc. Methods to describe, you can use SQL.
|
||||
//
|
||||
// Deprecated: use SQL instead.
|
||||
func (session *Session) Sql(query string, args ...interface{}) *Session {
|
||||
return session.SQL(query, args...)
|
||||
}
|
||||
|
||||
// SQL provides raw sql input parameter. When you have a complex SQL statement
|
||||
// and cannot use Where, Id, In and etc. Methods to describe, you can use SQL.
|
||||
func (session *Session) SQL(query interface{}, args ...interface{}) *Session {
|
||||
@ -39,13 +31,6 @@ func (session *Session) Or(query interface{}, args ...interface{}) *Session {
|
||||
return session
|
||||
}
|
||||
|
||||
// Id provides converting id as a query condition
|
||||
//
|
||||
// Deprecated: use ID instead
|
||||
func (session *Session) Id(id interface{}) *Session {
|
||||
return session.ID(id)
|
||||
}
|
||||
|
||||
// ID provides converting id as a query condition
|
||||
func (session *Session) ID(id interface{}) *Session {
|
||||
session.statement.ID(id)
|
||||
|
@ -224,7 +224,7 @@ func (session *Session) bytes2Value(col *schemas.Column, fieldValue *reflect.Val
|
||||
return err
|
||||
}
|
||||
|
||||
if !isPKZero(pk) {
|
||||
if !pk.IsZero() {
|
||||
// !nashtsai! TODO for hasOne relationship, it's preferred to use join query for eager fetch
|
||||
// however, also need to consider adding a 'lazy' attribute to xorm tag which allow hasOne
|
||||
// property to be fetched lazily
|
||||
@ -506,7 +506,7 @@ func (session *Session) bytes2Value(col *schemas.Column, fieldValue *reflect.Val
|
||||
return err
|
||||
}
|
||||
|
||||
if !isPKZero(pk) {
|
||||
if !pk.IsZero() {
|
||||
// !nashtsai! TODO for hasOne relationship, it's preferred to use join query for eager fetch
|
||||
// however, also need to consider adding a 'lazy' attribute to xorm tag which allow hasOne
|
||||
// property to be fetched lazily
|
||||
|
@ -142,7 +142,7 @@ func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{})
|
||||
if session.statement.JoinStr == "" {
|
||||
if columnStr == "" {
|
||||
if session.statement.GroupByStr != "" {
|
||||
columnStr = session.engine.quoteColumns(session.statement.GroupByStr)
|
||||
columnStr = session.statement.quoteColumnStr(session.statement.GroupByStr)
|
||||
} else {
|
||||
columnStr = session.statement.genColumnStr()
|
||||
}
|
||||
@ -150,7 +150,7 @@ func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{})
|
||||
} else {
|
||||
if columnStr == "" {
|
||||
if session.statement.GroupByStr != "" {
|
||||
columnStr = session.engine.quoteColumns(session.statement.GroupByStr)
|
||||
columnStr = session.statement.quoteColumnStr(session.statement.GroupByStr)
|
||||
} else {
|
||||
columnStr = "*"
|
||||
}
|
||||
@ -417,7 +417,7 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
|
||||
} else {
|
||||
session.engine.logger.Debug("[cacheFind] cache hit bean:", tableName, id, bean)
|
||||
|
||||
pk := session.engine.IdOf(bean)
|
||||
pk := session.engine.IDOf(bean)
|
||||
xid, err := pk.ToString()
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"xorm.io/builder"
|
||||
"xorm.io/xorm/internal/utils"
|
||||
"xorm.io/xorm/schemas"
|
||||
)
|
||||
|
||||
@ -153,7 +154,7 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error
|
||||
return 0, err
|
||||
}
|
||||
fieldValue := *ptrFieldValue
|
||||
if col.IsAutoIncrement && isZero(fieldValue.Interface()) {
|
||||
if col.IsAutoIncrement && utils.IsZero(fieldValue.Interface()) {
|
||||
continue
|
||||
}
|
||||
if col.MapType == schemas.ONLYFROMDB {
|
||||
@ -204,7 +205,7 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error
|
||||
}
|
||||
fieldValue := *ptrFieldValue
|
||||
|
||||
if col.IsAutoIncrement && isZero(fieldValue.Interface()) {
|
||||
if col.IsAutoIncrement && utils.IsZero(fieldValue.Interface()) {
|
||||
continue
|
||||
}
|
||||
if col.MapType == schemas.ONLYFROMDB {
|
||||
@ -250,19 +251,21 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error
|
||||
}
|
||||
cleanupProcessorsClosures(&session.beforeClosures)
|
||||
|
||||
quoter := session.engine.dialect.Quoter()
|
||||
var sql string
|
||||
colStr := quoter.Join(colNames, ",")
|
||||
if session.engine.dialect.DBType() == schemas.ORACLE {
|
||||
temp := fmt.Sprintf(") INTO %s (%v) VALUES (",
|
||||
session.engine.Quote(tableName),
|
||||
quoteColumns(colNames, session.engine.Quote, ","))
|
||||
quoter.Quote(tableName),
|
||||
colStr)
|
||||
sql = fmt.Sprintf("INSERT ALL INTO %s (%v) VALUES (%v) SELECT 1 FROM DUAL",
|
||||
session.engine.Quote(tableName),
|
||||
quoteColumns(colNames, session.engine.Quote, ","),
|
||||
quoter.Quote(tableName),
|
||||
colStr,
|
||||
strings.Join(colMultiPlaces, temp))
|
||||
} else {
|
||||
sql = fmt.Sprintf("INSERT INTO %s (%v) VALUES (%v)",
|
||||
session.engine.Quote(tableName),
|
||||
quoteColumns(colNames, session.engine.Quote, ","),
|
||||
quoter.Quote(tableName),
|
||||
colStr,
|
||||
strings.Join(colMultiPlaces, "),("))
|
||||
}
|
||||
res, err := session.exec(sql, args...)
|
||||
@ -679,7 +682,7 @@ func (session *Session) genInsertColumns(bean interface{}) ([]string, []interfac
|
||||
|
||||
// !evalphobia! set fieldValue as nil when column is nullable and zero-value
|
||||
if _, ok := getFlagForColumn(session.statement.nullableMap, col); ok {
|
||||
if col.Nullable && isZeroValue(fieldValue) {
|
||||
if col.Nullable && utils.IsValueZero(fieldValue) {
|
||||
var nilValue *int
|
||||
fieldValue = reflect.ValueOf(nilValue)
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ func (session *Session) genQuerySQL(sqlOrArgs ...interface{}) (string, []interfa
|
||||
if session.statement.JoinStr == "" {
|
||||
if columnStr == "" {
|
||||
if session.statement.GroupByStr != "" {
|
||||
columnStr = session.engine.quoteColumns(session.statement.GroupByStr)
|
||||
columnStr = session.statement.quoteColumnStr(session.statement.GroupByStr)
|
||||
} else {
|
||||
columnStr = session.statement.genColumnStr()
|
||||
}
|
||||
@ -44,7 +44,7 @@ func (session *Session) genQuerySQL(sqlOrArgs ...interface{}) (string, []interfa
|
||||
} else {
|
||||
if columnStr == "" {
|
||||
if session.statement.GroupByStr != "" {
|
||||
columnStr = session.engine.quoteColumns(session.statement.GroupByStr)
|
||||
columnStr = session.statement.quoteColumnStr(session.statement.GroupByStr)
|
||||
} else {
|
||||
columnStr = "*"
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
|
||||
"xorm.io/builder"
|
||||
"xorm.io/xorm/caches"
|
||||
"xorm.io/xorm/internal/utils"
|
||||
"xorm.io/xorm/schemas"
|
||||
)
|
||||
|
||||
@ -518,7 +519,7 @@ func (session *Session) genUpdateColumns(bean interface{}) ([]string, []interfac
|
||||
|
||||
// !evalphobia! set fieldValue as nil when column is nullable and zero-value
|
||||
if _, ok := getFlagForColumn(session.statement.nullableMap, col); ok {
|
||||
if col.Nullable && isZeroValue(fieldValue) {
|
||||
if col.Nullable && utils.IsValueZero(fieldValue) {
|
||||
var nilValue *int
|
||||
fieldValue = reflect.ValueOf(nilValue)
|
||||
}
|
||||
|
18
statement.go
18
statement.go
@ -13,6 +13,7 @@ import (
|
||||
|
||||
"xorm.io/builder"
|
||||
"xorm.io/xorm/dialects"
|
||||
"xorm.io/xorm/internal/utils"
|
||||
"xorm.io/xorm/schemas"
|
||||
)
|
||||
|
||||
@ -304,7 +305,7 @@ func (statement *Statement) buildUpdates(bean interface{},
|
||||
|
||||
// !evalphobia! set fieldValue as nil when column is nullable and zero-value
|
||||
if b, ok := getFlagForColumn(nullableMap, col); ok {
|
||||
if b && col.Nullable && isZero(fieldValue.Interface()) {
|
||||
if b && col.Nullable && utils.IsZero(fieldValue.Interface()) {
|
||||
var nilValue *int
|
||||
fieldValue = reflect.ValueOf(nilValue)
|
||||
fieldType = reflect.TypeOf(fieldValue.Interface())
|
||||
@ -404,7 +405,7 @@ func (statement *Statement) buildUpdates(bean interface{},
|
||||
if len(table.PrimaryKeys) == 1 {
|
||||
pkField := reflect.Indirect(fieldValue).FieldByName(table.PKColumns()[0].FieldName)
|
||||
// fix non-int pk issues
|
||||
if pkField.IsValid() && (!requiredField && !isZero(pkField.Interface())) {
|
||||
if pkField.IsValid() && (!requiredField && !utils.IsZero(pkField.Interface())) {
|
||||
val = pkField.Interface()
|
||||
} else {
|
||||
continue
|
||||
@ -418,7 +419,7 @@ func (statement *Statement) buildUpdates(bean interface{},
|
||||
}
|
||||
} else {
|
||||
// Blank struct could not be as update data
|
||||
if requiredField || !isStructZero(fieldValue) {
|
||||
if requiredField || !utils.IsStructZero(fieldValue) {
|
||||
bytes, err := DefaultJSONHandler.Marshal(fieldValue.Interface())
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("mashal %v failed", fieldValue.Interface()))
|
||||
@ -439,7 +440,7 @@ func (statement *Statement) buildUpdates(bean interface{},
|
||||
continue
|
||||
}
|
||||
if fieldType.Kind() == reflect.Array {
|
||||
if isArrayValueZero(fieldValue) {
|
||||
if utils.IsArrayZero(fieldValue) {
|
||||
continue
|
||||
}
|
||||
} else if fieldValue.IsNil() || !fieldValue.IsValid() || fieldValue.Len() == 0 {
|
||||
@ -939,6 +940,11 @@ func (statement *Statement) genConds(bean interface{}) (string, []interface{}, e
|
||||
return builder.ToSQL(statement.cond)
|
||||
}
|
||||
|
||||
func (statement *Statement) quoteColumnStr(columnStr string) string {
|
||||
columns := strings.Split(columnStr, ",")
|
||||
return statement.Engine.dialect.Quoter().Join(columns, ",")
|
||||
}
|
||||
|
||||
func (statement *Statement) genGetSQL(bean interface{}) (string, []interface{}, error) {
|
||||
v := rValue(bean)
|
||||
isStruct := v.Kind() == reflect.Struct
|
||||
@ -954,7 +960,7 @@ func (statement *Statement) genGetSQL(bean interface{}) (string, []interface{},
|
||||
if len(statement.JoinStr) == 0 {
|
||||
if len(columnStr) == 0 {
|
||||
if len(statement.GroupByStr) > 0 {
|
||||
columnStr = statement.Engine.quoteColumns(statement.GroupByStr)
|
||||
columnStr = statement.quoteColumnStr(statement.GroupByStr)
|
||||
} else {
|
||||
columnStr = statement.genColumnStr()
|
||||
}
|
||||
@ -962,7 +968,7 @@ func (statement *Statement) genGetSQL(bean interface{}) (string, []interface{},
|
||||
} else {
|
||||
if len(columnStr) == 0 {
|
||||
if len(statement.GroupByStr) > 0 {
|
||||
columnStr = statement.Engine.quoteColumns(statement.GroupByStr)
|
||||
columnStr = statement.quoteColumnStr(statement.GroupByStr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user