Fix some bugs about Update and Delete

This commit is contained in:
Jinzhu 2013-10-26 23:30:17 +08:00
parent 2a03332f53
commit 09b6fc3ab0
4 changed files with 44 additions and 26 deletions

View File

@ -3,7 +3,6 @@
Yet Another ORM library for Go, aims for developer friendly Yet Another ORM library for Go, aims for developer friendly
## TODO ## TODO
* Delete
* Complex where query (= / > / < / <> / in) * Complex where query (= / > / < / <> / in)
* Order * Order
* Limit * Limit
@ -11,12 +10,12 @@ Yet Another ORM library for Go, aims for developer friendly
* Offset * Offset
* Or query * Or query
* Not query * Not query
* Better First method (First(&user, primary_key, where conditions))
* Even more complex where query (with map or struct) * Even more complex where query (with map or struct)
* ORM.Errors * ORM.Errors
* Better First method (First(&user, primary_key, where conditions))
* Soft Delete
* After/Before Save/Update/Create/Delete * After/Before Save/Update/Create/Delete
* CreatedAt, UpdatedAt * CreatedAt, UpdatedAt
* Soft Delete
* FindOrInitialize / FindOrCreate * FindOrInitialize / FindOrCreate
* SQL Log * SQL Log
* Auto Migration * Auto Migration

View File

@ -25,8 +25,18 @@ func (s *Orm) toModel(value interface{}) *Model {
} }
func (m *Model) PrimaryKeyIsEmpty() bool { func (m *Model) PrimaryKeyIsEmpty() bool {
result := reflect.ValueOf(m.Data).Elem() return m.PrimaryKeyValue() == 0
return result.FieldByName(m.PrimaryKey()).Interface().(int64) == 0 }
func (m *Model) PrimaryKeyValue() int64 {
t := reflect.TypeOf(m.Data).Elem()
switch t.Kind() {
case reflect.Array, reflect.Chan, reflect.Map, reflect.Ptr, reflect.Slice:
return 0
default:
result := reflect.ValueOf(m.Data).Elem()
return result.FieldByName(m.PrimaryKey()).Interface().(int64)
}
} }
func (m *Model) PrimaryKey() string { func (m *Model) PrimaryKey() string {

42
sql.go
View File

@ -4,7 +4,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"reflect" "reflect"
"strconv"
"strings" "strings"
) )
@ -74,14 +73,19 @@ func (s *Orm) query(out interface{}) {
func (s *Orm) createSql(value interface{}) { func (s *Orm) createSql(value interface{}) {
columns, values := s.Model.ColumnsAndValues() columns, values := s.Model.ColumnsAndValues()
var sqls []string
for _, value := range values {
sqls = append(sqls, s.addToVars(value))
}
s.Sql = fmt.Sprintf( s.Sql = fmt.Sprintf(
"INSERT INTO \"%v\" (%v) VALUES (%v) %v", "INSERT INTO \"%v\" (%v) VALUES (%v) %v",
s.TableName, s.TableName,
strings.Join(s.quoteMap(columns), ","), strings.Join(s.quoteMap(columns), ","),
valuesToBinVar(values), strings.Join(sqls, ","),
s.Model.ReturningStr(), s.Model.ReturningStr(),
) )
s.SqlVars = values
return return
} }
@ -102,15 +106,16 @@ func (s *Orm) updateSql(value interface{}) {
columns, values := s.Model.ColumnsAndValues() columns, values := s.Model.ColumnsAndValues()
var sets []string var sets []string
for index, column := range columns { for index, column := range columns {
s.SqlVars = append(s.SqlVars, values[index]) sets = append(sets, fmt.Sprintf("%v = %v", s.quote(column), s.addToVars(values[index])))
sets = append(sets, fmt.Sprintf("%v = $%d", s.quote(column), len(s.SqlVars)))
} }
s.Sql = fmt.Sprintf( s.Sql = fmt.Sprintf(
"UPDATE %v SET %v", "UPDATE %v SET %v %v",
s.TableName, s.TableName,
strings.Join(sets, ", "), strings.Join(sets, ", "),
s.whereSql(),
) )
return return
} }
@ -125,18 +130,31 @@ func (s *Orm) deleteSql(value interface{}) {
} }
func (s *Orm) whereSql() (sql string) { func (s *Orm) whereSql() (sql string) {
if len(s.whereClause) == 0 { var conditions []string
return if !s.Model.PrimaryKeyIsEmpty() {
} else { conditions = append(conditions, fmt.Sprintf("(%v = %v)", s.quote(s.Model.PrimaryKeyDb()), s.addToVars(s.Model.PrimaryKeyValue())))
sql = "WHERE " }
if len(s.whereClause) > 0 {
for _, clause := range s.whereClause { for _, clause := range s.whereClause {
sql += clause["query"].(string) str := "( " + clause["query"].(string) + " )"
args := clause["args"].([]interface{}) args := clause["args"].([]interface{})
for _, arg := range args { for _, arg := range args {
s.SqlVars = append(s.SqlVars, arg.([]interface{})...) s.SqlVars = append(s.SqlVars, arg.([]interface{})...)
sql = strings.Replace(sql, "?", "$"+strconv.Itoa(len(s.SqlVars)), 1) str = strings.Replace(str, "?", fmt.Sprintf("$%d", len(s.SqlVars)), 1)
} }
conditions = append(conditions, str)
} }
} }
if len(conditions) > 0 {
sql = "WHERE " + strings.Join(conditions, " AND ")
}
return return
} }
func (s *Orm) addToVars(value interface{}) string {
s.SqlVars = append(s.SqlVars, value)
return fmt.Sprintf("$%d", len(s.SqlVars))
}

View File

@ -7,15 +7,6 @@ import (
"strings" "strings"
) )
// FIXME
func valuesToBinVar(values []interface{}) string {
var sqls []string
for index, _ := range values {
sqls = append(sqls, fmt.Sprintf("$%d", index+1))
}
return strings.Join(sqls, ",")
}
func (s *Orm) quote(value string) string { func (s *Orm) quote(value string) string {
return "\"" + value + "\"" return "\"" + value + "\""
} }