|
@@ -26,6 +26,11 @@ type decrParam struct {
|
|
|
arg interface{}
|
|
arg interface{}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+type exprParam struct {
|
|
|
|
|
+ colName string
|
|
|
|
|
+ expr string
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// statement save all the sql info for executing SQL
|
|
// statement save all the sql info for executing SQL
|
|
|
type Statement struct {
|
|
type Statement struct {
|
|
|
RefTable *core.Table
|
|
RefTable *core.Table
|
|
@@ -63,6 +68,7 @@ type Statement struct {
|
|
|
inColumns map[string]*inParam
|
|
inColumns map[string]*inParam
|
|
|
incrColumns map[string]incrParam
|
|
incrColumns map[string]incrParam
|
|
|
decrColumns map[string]decrParam
|
|
decrColumns map[string]decrParam
|
|
|
|
|
+ exprColumns map[string]exprParam
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// init
|
|
// init
|
|
@@ -98,6 +104,7 @@ func (statement *Statement) Init() {
|
|
|
statement.inColumns = make(map[string]*inParam)
|
|
statement.inColumns = make(map[string]*inParam)
|
|
|
statement.incrColumns = make(map[string]incrParam)
|
|
statement.incrColumns = make(map[string]incrParam)
|
|
|
statement.decrColumns = make(map[string]decrParam)
|
|
statement.decrColumns = make(map[string]decrParam)
|
|
|
|
|
+ statement.exprColumns = make(map[string]exprParam)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// add the raw sql statement
|
|
// add the raw sql statement
|
|
@@ -153,9 +160,6 @@ func (statement *Statement) Table(tableNameOrBean interface{}) *Statement {
|
|
|
t := v.Type()
|
|
t := v.Type()
|
|
|
if t.Kind() == reflect.String {
|
|
if t.Kind() == reflect.String {
|
|
|
statement.AltTableName = tableNameOrBean.(string)
|
|
statement.AltTableName = tableNameOrBean.(string)
|
|
|
- if statement.AltTableName[0] == '~' {
|
|
|
|
|
- statement.AltTableName = statement.Engine.TableMapper.TableName(statement.AltTableName[1:])
|
|
|
|
|
- }
|
|
|
|
|
} else if t.Kind() == reflect.Struct {
|
|
} else if t.Kind() == reflect.Struct {
|
|
|
statement.RefTable = statement.Engine.autoMapType(v)
|
|
statement.RefTable = statement.Engine.autoMapType(v)
|
|
|
}
|
|
}
|
|
@@ -282,7 +286,7 @@ func (statement *Statement) Table(tableNameOrBean interface{}) *Statement {
|
|
|
func buildUpdates(engine *Engine, table *core.Table, bean interface{},
|
|
func buildUpdates(engine *Engine, table *core.Table, bean interface{},
|
|
|
includeVersion bool, includeUpdated bool, includeNil bool,
|
|
includeVersion bool, includeUpdated bool, includeNil bool,
|
|
|
includeAutoIncr bool, allUseBool bool, useAllCols bool,
|
|
includeAutoIncr bool, allUseBool bool, useAllCols bool,
|
|
|
- mustColumnMap map[string]bool, update bool) ([]string, []interface{}) {
|
|
|
|
|
|
|
+ mustColumnMap map[string]bool, columnMap map[string]bool, update bool) ([]string, []interface{}) {
|
|
|
|
|
|
|
|
colNames := make([]string, 0)
|
|
colNames := make([]string, 0)
|
|
|
var args = make([]interface{}, 0)
|
|
var args = make([]interface{}, 0)
|
|
@@ -302,6 +306,9 @@ func buildUpdates(engine *Engine, table *core.Table, bean interface{},
|
|
|
if col.IsDeleted {
|
|
if col.IsDeleted {
|
|
|
continue
|
|
continue
|
|
|
}
|
|
}
|
|
|
|
|
+ if use, ok := columnMap[col.Name]; ok && !use {
|
|
|
|
|
+ continue
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
if engine.dialect.DBType() == core.MSSQL && col.SQLType.Name == core.Text {
|
|
if engine.dialect.DBType() == core.MSSQL && col.SQLType.Name == core.Text {
|
|
|
continue
|
|
continue
|
|
@@ -414,13 +421,16 @@ func buildUpdates(engine *Engine, table *core.Table, bean interface{},
|
|
|
if table, ok := engine.Tables[fieldValue.Type()]; ok {
|
|
if table, ok := engine.Tables[fieldValue.Type()]; ok {
|
|
|
if len(table.PrimaryKeys) == 1 {
|
|
if len(table.PrimaryKeys) == 1 {
|
|
|
pkField := reflect.Indirect(fieldValue).FieldByName(table.PKColumns()[0].FieldName)
|
|
pkField := reflect.Indirect(fieldValue).FieldByName(table.PKColumns()[0].FieldName)
|
|
|
- if pkField.Int() != 0 {
|
|
|
|
|
|
|
+ // fix non-int pk issues
|
|
|
|
|
+ //if pkField.Int() != 0 {
|
|
|
|
|
+ if pkField.IsValid() && !isZero(pkField.Interface()) {
|
|
|
val = pkField.Interface()
|
|
val = pkField.Interface()
|
|
|
} else {
|
|
} else {
|
|
|
continue
|
|
continue
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
//TODO: how to handler?
|
|
//TODO: how to handler?
|
|
|
|
|
+ panic("not supported")
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
val = fieldValue.Interface()
|
|
val = fieldValue.Interface()
|
|
@@ -579,24 +589,29 @@ func buildConditions(engine *Engine, table *core.Table, bean interface{},
|
|
|
t := int64(fieldValue.Uint())
|
|
t := int64(fieldValue.Uint())
|
|
|
val = reflect.ValueOf(&t).Interface()
|
|
val = reflect.ValueOf(&t).Interface()
|
|
|
case reflect.Struct:
|
|
case reflect.Struct:
|
|
|
- if fieldType == reflect.TypeOf(time.Now()) {
|
|
|
|
|
- t := fieldValue.Interface().(time.Time)
|
|
|
|
|
|
|
+ if fieldType.ConvertibleTo(core.TimeType) {
|
|
|
|
|
+ t := fieldValue.Convert(core.TimeType).Interface().(time.Time)
|
|
|
if !requiredField && (t.IsZero() || !fieldValue.IsValid()) {
|
|
if !requiredField && (t.IsZero() || !fieldValue.IsValid()) {
|
|
|
continue
|
|
continue
|
|
|
}
|
|
}
|
|
|
val = engine.FormatTime(col.SQLType.Name, t)
|
|
val = engine.FormatTime(col.SQLType.Name, t)
|
|
|
|
|
+ } else if _, ok := reflect.New(fieldType).Interface().(core.Conversion); ok {
|
|
|
|
|
+ continue
|
|
|
} else {
|
|
} else {
|
|
|
engine.autoMapType(fieldValue)
|
|
engine.autoMapType(fieldValue)
|
|
|
if table, ok := engine.Tables[fieldValue.Type()]; ok {
|
|
if table, ok := engine.Tables[fieldValue.Type()]; ok {
|
|
|
if len(table.PrimaryKeys) == 1 {
|
|
if len(table.PrimaryKeys) == 1 {
|
|
|
pkField := reflect.Indirect(fieldValue).FieldByName(table.PKColumns()[0].FieldName)
|
|
pkField := reflect.Indirect(fieldValue).FieldByName(table.PKColumns()[0].FieldName)
|
|
|
- if pkField.Int() != 0 {
|
|
|
|
|
|
|
+ // fix non-int pk issues
|
|
|
|
|
+ //if pkField.Int() != 0 {
|
|
|
|
|
+ if pkField.IsValid() && !isZero(pkField.Interface()) {
|
|
|
val = pkField.Interface()
|
|
val = pkField.Interface()
|
|
|
} else {
|
|
} else {
|
|
|
continue
|
|
continue
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
//TODO: how to handler?
|
|
//TODO: how to handler?
|
|
|
|
|
+ panic("not supported")
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
val = fieldValue.Interface()
|
|
val = fieldValue.Interface()
|
|
@@ -716,6 +731,13 @@ func (statement *Statement) Decr(column string, arg ...interface{}) *Statement {
|
|
|
return statement
|
|
return statement
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+// Generate "Update ... Set column = {expression}" statment
|
|
|
|
|
+func (statement *Statement) SetExpr(column string, expression string) *Statement {
|
|
|
|
|
+ k := strings.ToLower(column)
|
|
|
|
|
+ statement.exprColumns[k] = exprParam{column, expression}
|
|
|
|
|
+ return statement
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// Generate "Update ... Set column = column + arg" statment
|
|
// Generate "Update ... Set column = column + arg" statment
|
|
|
func (statement *Statement) getInc() map[string]incrParam {
|
|
func (statement *Statement) getInc() map[string]incrParam {
|
|
|
return statement.incrColumns
|
|
return statement.incrColumns
|
|
@@ -726,6 +748,11 @@ func (statement *Statement) getDec() map[string]decrParam {
|
|
|
return statement.decrColumns
|
|
return statement.decrColumns
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+// Generate "Update ... Set column = {expression}" statment
|
|
|
|
|
+func (statement *Statement) getExpr() map[string]exprParam {
|
|
|
|
|
+ return statement.exprColumns
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// Generate "Where column IN (?) " statment
|
|
// Generate "Where column IN (?) " statment
|
|
|
func (statement *Statement) In(column string, args ...interface{}) *Statement {
|
|
func (statement *Statement) In(column string, args ...interface{}) *Statement {
|
|
|
k := strings.ToLower(column)
|
|
k := strings.ToLower(column)
|
|
@@ -941,15 +968,9 @@ func (statement *Statement) Join(join_operator string, tablename interface{}, co
|
|
|
l := len(t)
|
|
l := len(t)
|
|
|
if l > 1 {
|
|
if l > 1 {
|
|
|
table := t[0]
|
|
table := t[0]
|
|
|
- if table[0] == '~' {
|
|
|
|
|
- table = statement.Engine.TableMapper.TableName(table[1:])
|
|
|
|
|
- }
|
|
|
|
|
joinTable = statement.Engine.Quote(table) + " AS " + statement.Engine.Quote(t[1])
|
|
joinTable = statement.Engine.Quote(table) + " AS " + statement.Engine.Quote(t[1])
|
|
|
} else if l == 1 {
|
|
} else if l == 1 {
|
|
|
table := t[0]
|
|
table := t[0]
|
|
|
- if table[0] == '~' {
|
|
|
|
|
- table = statement.Engine.TableMapper.TableName(table[1:])
|
|
|
|
|
- }
|
|
|
|
|
joinTable = statement.Engine.Quote(table)
|
|
joinTable = statement.Engine.Quote(table)
|
|
|
}
|
|
}
|
|
|
case []interface{}:
|
|
case []interface{}:
|
|
@@ -962,9 +983,6 @@ func (statement *Statement) Join(join_operator string, tablename interface{}, co
|
|
|
t := v.Type()
|
|
t := v.Type()
|
|
|
if t.Kind() == reflect.String {
|
|
if t.Kind() == reflect.String {
|
|
|
table = f.(string)
|
|
table = f.(string)
|
|
|
- if table[0] == '~' {
|
|
|
|
|
- table = statement.Engine.TableMapper.TableName(table[1:])
|
|
|
|
|
- }
|
|
|
|
|
} else if t.Kind() == reflect.Struct {
|
|
} else if t.Kind() == reflect.Struct {
|
|
|
r := statement.Engine.autoMapType(v)
|
|
r := statement.Engine.autoMapType(v)
|
|
|
table = r.Name
|
|
table = r.Name
|
|
@@ -977,9 +995,6 @@ func (statement *Statement) Join(join_operator string, tablename interface{}, co
|
|
|
}
|
|
}
|
|
|
default:
|
|
default:
|
|
|
t := fmt.Sprintf("%v", tablename)
|
|
t := fmt.Sprintf("%v", tablename)
|
|
|
- if t[0] == '~' {
|
|
|
|
|
- t = statement.Engine.TableMapper.TableName(t[1:])
|
|
|
|
|
- }
|
|
|
|
|
joinTable = statement.Engine.Quote(t)
|
|
joinTable = statement.Engine.Quote(t)
|
|
|
}
|
|
}
|
|
|
if statement.JoinStr != "" {
|
|
if statement.JoinStr != "" {
|
|
@@ -1105,9 +1120,10 @@ func (s *Statement) genDelIndexSQL() []string {
|
|
|
return sqls
|
|
return sqls
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+/*
|
|
|
func (s *Statement) genDropSQL() string {
|
|
func (s *Statement) genDropSQL() string {
|
|
|
- return s.Engine.dialect.DropTableSql(s.TableName()) + ";"
|
|
|
|
|
-}
|
|
|
|
|
|
|
+ return s.Engine.dialect.MustDropTa(s.TableName()) + ";"
|
|
|
|
|
+}*/
|
|
|
|
|
|
|
|
func (statement *Statement) genGetSql(bean interface{}) (string, []interface{}) {
|
|
func (statement *Statement) genGetSql(bean interface{}) (string, []interface{}) {
|
|
|
var table *core.Table
|
|
var table *core.Table
|
|
@@ -1126,13 +1142,21 @@ func (statement *Statement) genGetSql(bean interface{}) (string, []interface{})
|
|
|
statement.BeanArgs = args
|
|
statement.BeanArgs = args
|
|
|
|
|
|
|
|
var columnStr string = statement.ColumnStr
|
|
var columnStr string = statement.ColumnStr
|
|
|
- if statement.JoinStr == "" {
|
|
|
|
|
- if columnStr == "" {
|
|
|
|
|
- columnStr = statement.genColumnStr()
|
|
|
|
|
|
|
+ if len(statement.JoinStr) == 0 {
|
|
|
|
|
+ if len(columnStr) == 0 {
|
|
|
|
|
+ if statement.GroupByStr != "" {
|
|
|
|
|
+ columnStr = statement.Engine.Quote(strings.Replace(statement.GroupByStr, ",", statement.Engine.Quote(","), -1))
|
|
|
|
|
+ } else {
|
|
|
|
|
+ columnStr = statement.genColumnStr()
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
- if columnStr == "" {
|
|
|
|
|
- columnStr = "*"
|
|
|
|
|
|
|
+ if len(columnStr) == 0 {
|
|
|
|
|
+ if statement.GroupByStr != "" {
|
|
|
|
|
+ columnStr = statement.Engine.Quote(strings.Replace(statement.GroupByStr, ",", statement.Engine.Quote(","), -1))
|
|
|
|
|
+ } else {
|
|
|
|
|
+ columnStr = "*"
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1178,14 +1202,16 @@ func (statement *Statement) genCountSql(bean interface{}) (string, []interface{}
|
|
|
id = ""
|
|
id = ""
|
|
|
}
|
|
}
|
|
|
statement.attachInSql()
|
|
statement.attachInSql()
|
|
|
- return statement.genSelectSql(fmt.Sprintf("count(%v) AS %v", id, statement.Engine.Quote("total"))), append(statement.Params, statement.BeanArgs...)
|
|
|
|
|
|
|
+ return statement.genSelectSql(fmt.Sprintf("count(%v)", id)), append(statement.Params, statement.BeanArgs...)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
func (statement *Statement) genSelectSql(columnStr string) (a string) {
|
|
func (statement *Statement) genSelectSql(columnStr string) (a string) {
|
|
|
- if statement.GroupByStr != "" {
|
|
|
|
|
- columnStr = statement.Engine.Quote(strings.Replace(statement.GroupByStr, ",", statement.Engine.Quote(","), -1))
|
|
|
|
|
- statement.GroupByStr = columnStr
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ /*if statement.GroupByStr != "" {
|
|
|
|
|
+ if columnStr == "" {
|
|
|
|
|
+ columnStr = statement.Engine.Quote(strings.Replace(statement.GroupByStr, ",", statement.Engine.Quote(","), -1))
|
|
|
|
|
+ }
|
|
|
|
|
+ //statement.GroupByStr = columnStr
|
|
|
|
|
+ }*/
|
|
|
var distinct string
|
|
var distinct string
|
|
|
if statement.IsDistinct {
|
|
if statement.IsDistinct {
|
|
|
distinct = "DISTINCT "
|
|
distinct = "DISTINCT "
|
|
@@ -1210,7 +1236,11 @@ func (statement *Statement) genSelectSql(columnStr string) (a string) {
|
|
|
}
|
|
}
|
|
|
var fromStr string = " FROM " + statement.Engine.Quote(statement.TableName())
|
|
var fromStr string = " FROM " + statement.Engine.Quote(statement.TableName())
|
|
|
if statement.TableAlias != "" {
|
|
if statement.TableAlias != "" {
|
|
|
- fromStr += " AS " + statement.Engine.Quote(statement.TableAlias)
|
|
|
|
|
|
|
+ if statement.Engine.dialect.DBType() == core.ORACLE {
|
|
|
|
|
+ fromStr += " " + statement.Engine.Quote(statement.TableAlias)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ fromStr += " AS " + statement.Engine.Quote(statement.TableAlias)
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
if statement.JoinStr != "" {
|
|
if statement.JoinStr != "" {
|
|
|
fromStr = fmt.Sprintf("%v %v", fromStr, statement.JoinStr)
|
|
fromStr = fmt.Sprintf("%v %v", fromStr, statement.JoinStr)
|
|
@@ -1233,8 +1263,16 @@ func (statement *Statement) genSelectSql(columnStr string) (a string) {
|
|
|
column = statement.RefTable.ColumnsSeq()[0]
|
|
column = statement.RefTable.ColumnsSeq()[0]
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- mssqlCondi = fmt.Sprintf("(%s NOT IN (SELECT TOP %d %s%s%s))",
|
|
|
|
|
- column, statement.Start, column, fromStr, whereStr)
|
|
|
|
|
|
|
+ var orderStr string
|
|
|
|
|
+ if len(statement.OrderStr) > 0 {
|
|
|
|
|
+ orderStr = " ORDER BY " + statement.OrderStr
|
|
|
|
|
+ }
|
|
|
|
|
+ var groupStr string
|
|
|
|
|
+ if len(statement.GroupByStr) > 0 {
|
|
|
|
|
+ groupStr = " GROUP BY " + statement.GroupByStr
|
|
|
|
|
+ }
|
|
|
|
|
+ mssqlCondi = fmt.Sprintf("(%s NOT IN (SELECT TOP %d %s%s%s%s%s))",
|
|
|
|
|
+ column, statement.Start, column, fromStr, whereStr, orderStr, groupStr)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1258,12 +1296,16 @@ func (statement *Statement) genSelectSql(columnStr string) (a string) {
|
|
|
if statement.OrderStr != "" {
|
|
if statement.OrderStr != "" {
|
|
|
a = fmt.Sprintf("%v ORDER BY %v", a, statement.OrderStr)
|
|
a = fmt.Sprintf("%v ORDER BY %v", a, statement.OrderStr)
|
|
|
}
|
|
}
|
|
|
- if statement.Engine.dialect.DBType() != core.MSSQL {
|
|
|
|
|
|
|
+ if statement.Engine.dialect.DBType() != core.MSSQL && statement.Engine.dialect.DBType() != core.ORACLE {
|
|
|
if statement.Start > 0 {
|
|
if statement.Start > 0 {
|
|
|
a = fmt.Sprintf("%v LIMIT %v OFFSET %v", a, statement.LimitN, statement.Start)
|
|
a = fmt.Sprintf("%v LIMIT %v OFFSET %v", a, statement.LimitN, statement.Start)
|
|
|
} else if statement.LimitN > 0 {
|
|
} else if statement.LimitN > 0 {
|
|
|
a = fmt.Sprintf("%v LIMIT %v", a, statement.LimitN)
|
|
a = fmt.Sprintf("%v LIMIT %v", a, statement.LimitN)
|
|
|
}
|
|
}
|
|
|
|
|
+ } else if statement.Engine.dialect.DBType() == core.ORACLE {
|
|
|
|
|
+ if statement.Start != 0 || statement.LimitN != 0 {
|
|
|
|
|
+ a = fmt.Sprintf("SELECT %v FROM (SELECT %v,ROWNUM RN FROM (%v) at WHERE ROWNUM <= %d) aat WHERE RN > %d", columnStr, columnStr, a, statement.Start+statement.LimitN, statement.Start)
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return
|
|
return
|