From 4b8ecced83fda708d4bcdfab10ec6b2cda3b66d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cfudali113=E2=80=9D?= <“fudali113@gmail.com”> Date: Wed, 20 Jul 2016 14:37:05 +0800 Subject: [PATCH 01/13] orm insert or update --- orm/db.go | 106 ++++++++++++++++++++++++++++++++++++++++++++++++ orm/orm.go | 13 ++++++ orm/orm_test.go | 73 +++++++++++++++++++++++++++++++++ orm/types.go | 6 +++ 4 files changed, 198 insertions(+) diff --git a/orm/db.go b/orm/db.go index 9964e263..c4b0e046 100644 --- a/orm/db.go +++ b/orm/db.go @@ -488,6 +488,112 @@ func (d *dbBase) InsertValue(q dbQuerier, mi *modelInfo, isMulti bool, names []s return id, err } +//insert or update a row +//If your primary key or unique column conflict will update +//if no will insert +func (d *dbBase) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location, dn string, args ...string) (int64, error) { + iouStr := "" + mysql := "mysql" + postgres := "postgres" + argsMap := map[string]string{} + args0 := "" + if dn == mysql { + iouStr = "ON DUPLICATE KEY UPDATE" + } else if dn == postgres { + if len(args) == 0 || (len(strings.Split(args0, "=")) != 1) { + return 0, fmt.Errorf("`%s` use insert or update must have a conflict column arg in first", dn) + } else { + args0 = args[0] + iouStr = fmt.Sprintf("ON CONFLICT (%s) DO UPDATE SET", args0) + } + } else { + return 0, fmt.Errorf("`%s` nonsupport insert or update in beego", dn) + } + //Get on the key-value pairs + for _, v := range args { + kv := strings.Split(v, "=") + if len(kv) == 2 { + argsMap[kv[0]] = kv[1] + } + } + + isMulti := false + names := make([]string, 0, len(mi.fields.dbcols)-1) + Q := d.ins.TableQuote() + values, _, err := d.collectValues(mi, ind, mi.fields.dbcols, true, true, &names, tz) + + if err != nil { + return 0, err + } + + marks := make([]string, len(names)) + updateValues := make([]interface{}, 0) + updates := make([]string, len(names)) + var conflitValue interface{} + for i, v := range names { + marks[i] = "?" + valueStr := argsMap[v] + if v == args0 { + conflitValue = values[i] + } + if valueStr != "" { + switch dn { + case mysql: + updates[i] = v + "=" + valueStr + break + case postgres: + if conflitValue != nil { + //postgres ON CONFLICT DO UPDATE SET can`t use colu=colu+values + updates[i] = fmt.Sprintf("%s=(select %s from %s where %s = ? )", v, valueStr, mi.table, args[0]) + updateValues = append(updateValues, conflitValue) + } else { + return 0, fmt.Errorf("`%s` must be in front of `%s` in your struct", args[0], v) + } + break + } + } else { + updates[i] = v + "=?" + updateValues = append(updateValues, values[i]) + } + } + + values = append(values, updateValues...) + + sep := fmt.Sprintf("%s, %s", Q, Q) + qmarks := strings.Join(marks, ", ") + qupdates := strings.Join(updates, ", ") + columns := strings.Join(names, sep) + + multi := len(values) / len(names) + + if isMulti { + qmarks = strings.Repeat(qmarks+"), (", multi-1) + qmarks + } + //conflitValue maybe is a int,can`t use fmt.Sprintf + query := fmt.Sprintf("INSERT INTO %s%s%s (%s%s%s) VALUES (%s) %s "+qupdates, Q, mi.table, Q, Q, columns, Q, qmarks, iouStr) + + d.ins.ReplaceMarks(&query) + + if isMulti || !d.ins.HasReturningID(mi, &query) { + res, err := q.Exec(query, values...) + if err == nil { + if isMulti { + return res.RowsAffected() + } + return res.LastInsertId() + } + return 0, err + } + + row := q.QueryRow(query, values...) + var id int64 + err = row.Scan(&id) + if err.Error() == `pq: syntax error at or near "ON"` { + err = fmt.Errorf("postgres version must 9.5 or higher") + } + return id, err +} + // execute update sql dbQuerier with given struct reflect.Value. func (d *dbBase) Update(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location, cols []string) (int64, error) { pkName, pkValue, ok := getExistPk(mi, ind) diff --git a/orm/orm.go b/orm/orm.go index 5e43ae59..fe189037 100644 --- a/orm/orm.go +++ b/orm/orm.go @@ -209,6 +209,19 @@ func (o *orm) InsertMulti(bulk int, mds interface{}) (int64, error) { return cnt, nil } +//insert or update data to database +func (o *orm) InsertOrUpdate(md interface{}, colConflitAndArgs ...string) (int64, error) { + mi, ind := o.getMiInd(md, true) + id, err := o.alias.DbBaser.InsertOrUpdate(o.db, mi, ind, o.alias.TZ, o.alias.DriverName, colConflitAndArgs...) + if err != nil { + return id, err + } + + o.setPk(mi, ind, id) + + return id, nil +} + // update model to database. // cols set the columns those want to update. func (o *orm) Update(md interface{}, cols ...string) (int64, error) { diff --git a/orm/orm_test.go b/orm/orm_test.go index b5973448..aac9fef8 100644 --- a/orm/orm_test.go +++ b/orm/orm_test.go @@ -2174,3 +2174,76 @@ func TestIgnoreCaseTag(t *testing.T) { throwFail(t, AssertIs(info.fields.GetByName("Name02").column, "Name")) throwFail(t, AssertIs(info.fields.GetByName("Name03").column, "name")) } +func TestInsertOrUpdate(t *testing.T) { + user := User{UserName: "unique_username133", Status: 1, Password: "o"} + user1 := User{UserName: "unique_username133", Status: 2, Password: "o"} + user2 := User{UserName: "unique_username133", Status: 3, Password: "oo"} + dORM.Insert(&user) + fmt.Println(dORM.Driver().Name()) + if dORM.Driver().Name() == "sqlite3" { + fmt.Println("sqlite3 is nonsupport") + return + } + //test1 普通操作 + _, err := dORM.InsertOrUpdate(&user1, "UserName") + if err != nil && (err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport insert or update in beego") { + fmt.Println(err) + } else { + throwFailNow(t, err) + } + test := User{UserName: "unique_username133"} + time.Sleep(time.Second * 1) + dORM.Read(&test, "UserName") + throwFailNow(t, AssertIs(user1.Status, test.Status)) + //test2 普通操作 + _, err = dORM.InsertOrUpdate(&user2, "UserName") + if err != nil && (err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport insert or update in beego") { + fmt.Println(err) + } else { + throwFailNow(t, err) + time.Sleep(time.Second * 1) + dORM.Read(&test, "UserName") + throwFailNow(t, AssertIs(user2.Status, test.Status)) + throwFailNow(t, AssertIs(user2.Password, strings.TrimSpace(test.Password))) + } + //test3 数字 + 操作 + _, err = dORM.InsertOrUpdate(&user2, "UserName", "Status=Status+1") + if err != nil && (err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport insert or update in beego") { + fmt.Println(err) + } else { + throwFailNow(t, err) + time.Sleep(time.Second * 1) + dORM.Read(&test, "UserName") + throwFailNow(t, AssertIs(user2.Status+1, test.Status)) + } + //test4 数字 - 操作 + _, err = dORM.InsertOrUpdate(&user2, "UserName", "Status=Status-1") + if err != nil && (err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport insert or update in beego") { + fmt.Println(err) + } else { + throwFailNow(t, err) + time.Sleep(time.Second * 1) + dORM.Read(&test, "UserName") + throwFailNow(t, AssertIs((user2.Status+1)-1, test.Status)) + } + //test5 数字 * 操作 + _, err = dORM.InsertOrUpdate(&user2, "UserName", "Status=Status*3") + if err != nil && (err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport insert or update in beego") { + fmt.Println(err) + } else { + throwFailNow(t, err) + time.Sleep(time.Second * 1) + dORM.Read(&test, "UserName") + throwFailNow(t, AssertIs(((user2.Status+1)-1)*3, test.Status)) + } + //test6 数字 / 操作 + _, err = dORM.InsertOrUpdate(&user2, "UserName", "Status=Status/3") + if err != nil && (err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport insert or update in beego") { + fmt.Println(err) + } else { + throwFailNow(t, err) + time.Sleep(time.Second * 1) + dORM.Read(&test, "UserName") + throwFailNow(t, AssertIs((((user2.Status+1)-1)*3)/3, test.Status)) + } +} diff --git a/orm/types.go b/orm/types.go index cb55e71a..7864e315 100644 --- a/orm/types.go +++ b/orm/types.go @@ -53,6 +53,11 @@ type Ormer interface { // id, err = Ormer.Insert(user) // user must a pointer and Insert will set user's pk field Insert(interface{}) (int64, error) + //mysql:InsertOrUpdate(model) or InsertOrUpdate(model,"colu=colu+value") + //if colu type is integer : can use(+-*/), string : convert(colu,"value") + //postgres: InsertOrUpdate(model,"conflictColumnName") or InsertOrUpdate(model,"conflictColumnName","colu=colu+value") + //if colu type is integer : can use(+-*/), string : colu || "value" + InsertOrUpdate(md interface{}, colConflitAndArgs ...string) (int64, error) // insert some models to database InsertMulti(bulk int, mds interface{}) (int64, error) // update model to database. @@ -391,6 +396,7 @@ type txEnder interface { type dbBaser interface { Read(dbQuerier, *modelInfo, reflect.Value, *time.Location, []string) error Insert(dbQuerier, *modelInfo, reflect.Value, *time.Location) (int64, error) + InsertOrUpdate(dbQuerier, *modelInfo, reflect.Value, *time.Location, string, ...string) (int64, error) InsertMulti(dbQuerier, *modelInfo, reflect.Value, int, *time.Location) (int64, error) InsertValue(dbQuerier, *modelInfo, bool, []string, []interface{}) (int64, error) InsertStmt(stmtQuerier, *modelInfo, reflect.Value, *time.Location) (int64, error) From ec521ad166bdeab116ca296773c3f1776bcd2870 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cfudali113=E2=80=9D?= <“fudali113@gmail.com”> Date: Wed, 20 Jul 2016 15:13:18 +0800 Subject: [PATCH 02/13] update --- orm/orm_test.go | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/orm/orm_test.go b/orm/orm_test.go index aac9fef8..d2d10a6d 100644 --- a/orm/orm_test.go +++ b/orm/orm_test.go @@ -2175,10 +2175,12 @@ func TestIgnoreCaseTag(t *testing.T) { throwFail(t, AssertIs(info.fields.GetByName("Name03").column, "name")) } func TestInsertOrUpdate(t *testing.T) { + RegisterModel(new(User)) user := User{UserName: "unique_username133", Status: 1, Password: "o"} user1 := User{UserName: "unique_username133", Status: 2, Password: "o"} user2 := User{UserName: "unique_username133", Status: 3, Password: "oo"} dORM.Insert(&user) + test := User{UserName: "unique_username133"} fmt.Println(dORM.Driver().Name()) if dORM.Driver().Name() == "sqlite3" { fmt.Println("sqlite3 is nonsupport") @@ -2190,18 +2192,15 @@ func TestInsertOrUpdate(t *testing.T) { fmt.Println(err) } else { throwFailNow(t, err) + dORM.Read(&test, "UserName") + throwFailNow(t, AssertIs(user1.Status, test.Status)) } - test := User{UserName: "unique_username133"} - time.Sleep(time.Second * 1) - dORM.Read(&test, "UserName") - throwFailNow(t, AssertIs(user1.Status, test.Status)) //test2 普通操作 _, err = dORM.InsertOrUpdate(&user2, "UserName") if err != nil && (err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport insert or update in beego") { fmt.Println(err) } else { throwFailNow(t, err) - time.Sleep(time.Second * 1) dORM.Read(&test, "UserName") throwFailNow(t, AssertIs(user2.Status, test.Status)) throwFailNow(t, AssertIs(user2.Password, strings.TrimSpace(test.Password))) @@ -2212,7 +2211,6 @@ func TestInsertOrUpdate(t *testing.T) { fmt.Println(err) } else { throwFailNow(t, err) - time.Sleep(time.Second * 1) dORM.Read(&test, "UserName") throwFailNow(t, AssertIs(user2.Status+1, test.Status)) } @@ -2222,7 +2220,6 @@ func TestInsertOrUpdate(t *testing.T) { fmt.Println(err) } else { throwFailNow(t, err) - time.Sleep(time.Second * 1) dORM.Read(&test, "UserName") throwFailNow(t, AssertIs((user2.Status+1)-1, test.Status)) } @@ -2232,7 +2229,6 @@ func TestInsertOrUpdate(t *testing.T) { fmt.Println(err) } else { throwFailNow(t, err) - time.Sleep(time.Second * 1) dORM.Read(&test, "UserName") throwFailNow(t, AssertIs(((user2.Status+1)-1)*3, test.Status)) } @@ -2242,7 +2238,6 @@ func TestInsertOrUpdate(t *testing.T) { fmt.Println(err) } else { throwFailNow(t, err) - time.Sleep(time.Second * 1) dORM.Read(&test, "UserName") throwFailNow(t, AssertIs((((user2.Status+1)-1)*3)/3, test.Status)) } From 530c32017cb04cd9d790f382ade868321193d08d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cfudali113=E2=80=9D?= <“fudali113@gmail.com”> Date: Wed, 20 Jul 2016 15:33:30 +0800 Subject: [PATCH 03/13] update --- orm/db.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/orm/db.go b/orm/db.go index c4b0e046..5fbb8ab3 100644 --- a/orm/db.go +++ b/orm/db.go @@ -533,7 +533,7 @@ func (d *dbBase) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Value, t for i, v := range names { marks[i] = "?" valueStr := argsMap[v] - if v == args0 { + if strings.ToLower(v) == strings.ToLower(args0) { conflitValue = values[i] } if valueStr != "" { From 50c5df32b1bdfe6cd2ba7ada6527b5cc312a49ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cfudali113=E2=80=9D?= <“fudali113@gmail.com”> Date: Wed, 20 Jul 2016 16:26:02 +0800 Subject: [PATCH 04/13] update --- orm/db.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/orm/db.go b/orm/db.go index 5fbb8ab3..871f4a5d 100644 --- a/orm/db.go +++ b/orm/db.go @@ -503,7 +503,7 @@ func (d *dbBase) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Value, t if len(args) == 0 || (len(strings.Split(args0, "=")) != 1) { return 0, fmt.Errorf("`%s` use insert or update must have a conflict column arg in first", dn) } else { - args0 = args[0] + args0 = strings.ToLower(args[0]) iouStr = fmt.Sprintf("ON CONFLICT (%s) DO UPDATE SET", args0) } } else { @@ -513,7 +513,8 @@ func (d *dbBase) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Value, t for _, v := range args { kv := strings.Split(v, "=") if len(kv) == 2 { - argsMap[kv[0]] = kv[1] + k := strings.ToLower(kv[0]) + argsMap[k] = kv[1] } } @@ -532,8 +533,9 @@ func (d *dbBase) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Value, t var conflitValue interface{} for i, v := range names { marks[i] = "?" - valueStr := argsMap[v] - if strings.ToLower(v) == strings.ToLower(args0) { + vtl := strings.ToLower(v) + valueStr := argsMap[vtl] + if vtl == args0 { conflitValue = values[i] } if valueStr != "" { @@ -544,10 +546,10 @@ func (d *dbBase) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Value, t case postgres: if conflitValue != nil { //postgres ON CONFLICT DO UPDATE SET can`t use colu=colu+values - updates[i] = fmt.Sprintf("%s=(select %s from %s where %s = ? )", v, valueStr, mi.table, args[0]) + updates[i] = fmt.Sprintf("%s=(select %s from %s where %s = ? )", v, valueStr, mi.table, args0) updateValues = append(updateValues, conflitValue) } else { - return 0, fmt.Errorf("`%s` must be in front of `%s` in your struct", args[0], v) + return 0, fmt.Errorf("`%s` must be in front of `%s` in your struct", args0, v) } break } From 6d1b203bcabe9b3e79435617ecf05ecc4c05c956 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cfudali113=E2=80=9D?= <“fudali113@gmail.com”> Date: Wed, 20 Jul 2016 16:52:14 +0800 Subject: [PATCH 05/13] update --- orm/orm_test.go | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/orm/orm_test.go b/orm/orm_test.go index d2d10a6d..c4f2d8da 100644 --- a/orm/orm_test.go +++ b/orm/orm_test.go @@ -2187,58 +2187,58 @@ func TestInsertOrUpdate(t *testing.T) { return } //test1 普通操作 - _, err := dORM.InsertOrUpdate(&user1, "UserName") + _, err := dORM.InsertOrUpdate(&user1, "user_name") if err != nil && (err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport insert or update in beego") { fmt.Println(err) } else { throwFailNow(t, err) - dORM.Read(&test, "UserName") + dORM.Read(&test, "user_name") throwFailNow(t, AssertIs(user1.Status, test.Status)) } //test2 普通操作 - _, err = dORM.InsertOrUpdate(&user2, "UserName") + _, err = dORM.InsertOrUpdate(&user2, "user_name") if err != nil && (err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport insert or update in beego") { fmt.Println(err) } else { throwFailNow(t, err) - dORM.Read(&test, "UserName") + dORM.Read(&test, "user_name") throwFailNow(t, AssertIs(user2.Status, test.Status)) throwFailNow(t, AssertIs(user2.Password, strings.TrimSpace(test.Password))) } //test3 数字 + 操作 - _, err = dORM.InsertOrUpdate(&user2, "UserName", "Status=Status+1") + _, err = dORM.InsertOrUpdate(&user2, "user_name", "Status=Status+1") if err != nil && (err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport insert or update in beego") { fmt.Println(err) } else { throwFailNow(t, err) - dORM.Read(&test, "UserName") + dORM.Read(&test, "user_name") throwFailNow(t, AssertIs(user2.Status+1, test.Status)) } //test4 数字 - 操作 - _, err = dORM.InsertOrUpdate(&user2, "UserName", "Status=Status-1") + _, err = dORM.InsertOrUpdate(&user2, "user_name", "Status=Status-1") if err != nil && (err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport insert or update in beego") { fmt.Println(err) } else { throwFailNow(t, err) - dORM.Read(&test, "UserName") + dORM.Read(&test, "user_name") throwFailNow(t, AssertIs((user2.Status+1)-1, test.Status)) } //test5 数字 * 操作 - _, err = dORM.InsertOrUpdate(&user2, "UserName", "Status=Status*3") + _, err = dORM.InsertOrUpdate(&user2, "user_name", "Status=Status*3") if err != nil && (err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport insert or update in beego") { fmt.Println(err) } else { throwFailNow(t, err) - dORM.Read(&test, "UserName") + dORM.Read(&test, "user_name") throwFailNow(t, AssertIs(((user2.Status+1)-1)*3, test.Status)) } //test6 数字 / 操作 - _, err = dORM.InsertOrUpdate(&user2, "UserName", "Status=Status/3") + _, err = dORM.InsertOrUpdate(&user2, "user_name", "Status=Status/3") if err != nil && (err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport insert or update in beego") { fmt.Println(err) } else { throwFailNow(t, err) - dORM.Read(&test, "UserName") + dORM.Read(&test, "user_name") throwFailNow(t, AssertIs((((user2.Status+1)-1)*3)/3, test.Status)) } } From e2316c4b9ececa12b2b48078c8d8d192eeb4f756 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cfudali113=E2=80=9D?= <“fudali113@gmail.com”> Date: Wed, 20 Jul 2016 17:28:26 +0800 Subject: [PATCH 06/13] update --- orm/orm_test.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/orm/orm_test.go b/orm/orm_test.go index c4f2d8da..5b44f286 100644 --- a/orm/orm_test.go +++ b/orm/orm_test.go @@ -2186,7 +2186,7 @@ func TestInsertOrUpdate(t *testing.T) { fmt.Println("sqlite3 is nonsupport") return } - //test1 普通操作 + //test1 _, err := dORM.InsertOrUpdate(&user1, "user_name") if err != nil && (err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport insert or update in beego") { fmt.Println(err) @@ -2195,7 +2195,7 @@ func TestInsertOrUpdate(t *testing.T) { dORM.Read(&test, "user_name") throwFailNow(t, AssertIs(user1.Status, test.Status)) } - //test2 普通操作 + //test2 _, err = dORM.InsertOrUpdate(&user2, "user_name") if err != nil && (err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport insert or update in beego") { fmt.Println(err) @@ -2205,7 +2205,7 @@ func TestInsertOrUpdate(t *testing.T) { throwFailNow(t, AssertIs(user2.Status, test.Status)) throwFailNow(t, AssertIs(user2.Password, strings.TrimSpace(test.Password))) } - //test3 数字 + 操作 + //test3 + _, err = dORM.InsertOrUpdate(&user2, "user_name", "Status=Status+1") if err != nil && (err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport insert or update in beego") { fmt.Println(err) @@ -2214,7 +2214,7 @@ func TestInsertOrUpdate(t *testing.T) { dORM.Read(&test, "user_name") throwFailNow(t, AssertIs(user2.Status+1, test.Status)) } - //test4 数字 - 操作 + //test4 - _, err = dORM.InsertOrUpdate(&user2, "user_name", "Status=Status-1") if err != nil && (err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport insert or update in beego") { fmt.Println(err) @@ -2223,7 +2223,7 @@ func TestInsertOrUpdate(t *testing.T) { dORM.Read(&test, "user_name") throwFailNow(t, AssertIs((user2.Status+1)-1, test.Status)) } - //test5 数字 * 操作 + //test5 * _, err = dORM.InsertOrUpdate(&user2, "user_name", "Status=Status*3") if err != nil && (err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport insert or update in beego") { fmt.Println(err) @@ -2232,7 +2232,7 @@ func TestInsertOrUpdate(t *testing.T) { dORM.Read(&test, "user_name") throwFailNow(t, AssertIs(((user2.Status+1)-1)*3, test.Status)) } - //test6 数字 / 操作 + //test6 / _, err = dORM.InsertOrUpdate(&user2, "user_name", "Status=Status/3") if err != nil && (err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport insert or update in beego") { fmt.Println(err) From 3583ad8cc0784cf208ccce1272440f004e60cf5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cfudali113=E2=80=9D?= <“fudali113@gmail.com”> Date: Thu, 21 Jul 2016 15:49:55 +0800 Subject: [PATCH 07/13] update annotation --- orm/db.go | 6 +++--- orm/orm.go | 2 +- orm/types.go | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/orm/db.go b/orm/db.go index 871f4a5d..40e71d12 100644 --- a/orm/db.go +++ b/orm/db.go @@ -488,9 +488,9 @@ func (d *dbBase) InsertValue(q dbQuerier, mi *modelInfo, isMulti bool, names []s return id, err } -//insert or update a row -//If your primary key or unique column conflict will update -//if no will insert +// InsertOrUpdate a row +// If your primary key or unique column conflict will update +// If no will insert func (d *dbBase) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location, dn string, args ...string) (int64, error) { iouStr := "" mysql := "mysql" diff --git a/orm/orm.go b/orm/orm.go index fe189037..c84dddea 100644 --- a/orm/orm.go +++ b/orm/orm.go @@ -209,7 +209,7 @@ func (o *orm) InsertMulti(bulk int, mds interface{}) (int64, error) { return cnt, nil } -//insert or update data to database +// InsertOrUpdate data to database func (o *orm) InsertOrUpdate(md interface{}, colConflitAndArgs ...string) (int64, error) { mi, ind := o.getMiInd(md, true) id, err := o.alias.DbBaser.InsertOrUpdate(o.db, mi, ind, o.alias.TZ, o.alias.DriverName, colConflitAndArgs...) diff --git a/orm/types.go b/orm/types.go index 7864e315..b375fd65 100644 --- a/orm/types.go +++ b/orm/types.go @@ -53,10 +53,10 @@ type Ormer interface { // id, err = Ormer.Insert(user) // user must a pointer and Insert will set user's pk field Insert(interface{}) (int64, error) - //mysql:InsertOrUpdate(model) or InsertOrUpdate(model,"colu=colu+value") - //if colu type is integer : can use(+-*/), string : convert(colu,"value") - //postgres: InsertOrUpdate(model,"conflictColumnName") or InsertOrUpdate(model,"conflictColumnName","colu=colu+value") - //if colu type is integer : can use(+-*/), string : colu || "value" + // mysql:InsertOrUpdate(model) or InsertOrUpdate(model,"colu=colu+value") + // if colu type is integer : can use(+-*/), string : convert(colu,"value") + // postgres: InsertOrUpdate(model,"conflictColumnName") or InsertOrUpdate(model,"conflictColumnName","colu=colu+value") + // if colu type is integer : can use(+-*/), string : colu || "value" InsertOrUpdate(md interface{}, colConflitAndArgs ...string) (int64, error) // insert some models to database InsertMulti(bulk int, mds interface{}) (int64, error) From e0e888ab8f2050cbe4aedbdd91b391e644ce3d94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cfudali113=E2=80=9D?= <“fudali113@gmail.com”> Date: Fri, 22 Jul 2016 12:10:37 +0800 Subject: [PATCH 08/13] =?UTF-8?q?update=20=E2=80=9Cmodification=20hardcode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- orm/db.go | 16 ++++++++-------- orm/orm.go | 2 +- orm/types.go | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/orm/db.go b/orm/db.go index 40e71d12..29c1c825 100644 --- a/orm/db.go +++ b/orm/db.go @@ -491,23 +491,23 @@ func (d *dbBase) InsertValue(q dbQuerier, mi *modelInfo, isMulti bool, names []s // InsertOrUpdate a row // If your primary key or unique column conflict will update // If no will insert -func (d *dbBase) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location, dn string, args ...string) (int64, error) { +func (d *dbBase) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location, driver DriverType, args ...string) (int64, error) { iouStr := "" - mysql := "mysql" - postgres := "postgres" + mysql := DRMySQL + postgres := DRPostgres argsMap := map[string]string{} args0 := "" - if dn == mysql { + if driver == mysql { iouStr = "ON DUPLICATE KEY UPDATE" - } else if dn == postgres { + } else if driver == postgres { if len(args) == 0 || (len(strings.Split(args0, "=")) != 1) { - return 0, fmt.Errorf("`%s` use insert or update must have a conflict column arg in first", dn) + return 0, fmt.Errorf("`%s` use insert or update must have a conflict column arg in first", driver) } else { args0 = strings.ToLower(args[0]) iouStr = fmt.Sprintf("ON CONFLICT (%s) DO UPDATE SET", args0) } } else { - return 0, fmt.Errorf("`%s` nonsupport insert or update in beego", dn) + return 0, fmt.Errorf("`%s` nonsupport insert or update in beego", driver) } //Get on the key-value pairs for _, v := range args { @@ -539,7 +539,7 @@ func (d *dbBase) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Value, t conflitValue = values[i] } if valueStr != "" { - switch dn { + switch driver { case mysql: updates[i] = v + "=" + valueStr break diff --git a/orm/orm.go b/orm/orm.go index c84dddea..d7ebb371 100644 --- a/orm/orm.go +++ b/orm/orm.go @@ -212,7 +212,7 @@ func (o *orm) InsertMulti(bulk int, mds interface{}) (int64, error) { // InsertOrUpdate data to database func (o *orm) InsertOrUpdate(md interface{}, colConflitAndArgs ...string) (int64, error) { mi, ind := o.getMiInd(md, true) - id, err := o.alias.DbBaser.InsertOrUpdate(o.db, mi, ind, o.alias.TZ, o.alias.DriverName, colConflitAndArgs...) + id, err := o.alias.DbBaser.InsertOrUpdate(o.db, mi, ind, o.alias.TZ, o.alias.Driver, colConflitAndArgs...) if err != nil { return id, err } diff --git a/orm/types.go b/orm/types.go index b375fd65..32d8c233 100644 --- a/orm/types.go +++ b/orm/types.go @@ -396,7 +396,7 @@ type txEnder interface { type dbBaser interface { Read(dbQuerier, *modelInfo, reflect.Value, *time.Location, []string) error Insert(dbQuerier, *modelInfo, reflect.Value, *time.Location) (int64, error) - InsertOrUpdate(dbQuerier, *modelInfo, reflect.Value, *time.Location, string, ...string) (int64, error) + InsertOrUpdate(dbQuerier, *modelInfo, reflect.Value, *time.Location, DriverType, ...string) (int64, error) InsertMulti(dbQuerier, *modelInfo, reflect.Value, int, *time.Location) (int64, error) InsertValue(dbQuerier, *modelInfo, bool, []string, []interface{}) (int64, error) InsertStmt(stmtQuerier, *modelInfo, reflect.Value, *time.Location) (int64, error) From bf17558d066d5bc0c25d807e8e6a0c5a78d13a1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cfudali113=E2=80=9D?= <“fudali113@gmail.com”> Date: Fri, 22 Jul 2016 12:25:30 +0800 Subject: [PATCH 09/13] =?UTF-8?q?update=20=E2=80=9Cmodification=20hardcode?= =?UTF-8?q?=202?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- orm/db.go | 9 +++++---- orm/orm.go | 2 +- orm/types.go | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/orm/db.go b/orm/db.go index 29c1c825..613fc8a9 100644 --- a/orm/db.go +++ b/orm/db.go @@ -491,23 +491,24 @@ func (d *dbBase) InsertValue(q dbQuerier, mi *modelInfo, isMulti bool, names []s // InsertOrUpdate a row // If your primary key or unique column conflict will update // If no will insert -func (d *dbBase) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location, driver DriverType, args ...string) (int64, error) { +func (d *dbBase) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Value, a *alias, args ...string) (int64, error) { iouStr := "" mysql := DRMySQL postgres := DRPostgres + driver := a.Driver argsMap := map[string]string{} args0 := "" if driver == mysql { iouStr = "ON DUPLICATE KEY UPDATE" } else if driver == postgres { if len(args) == 0 || (len(strings.Split(args0, "=")) != 1) { - return 0, fmt.Errorf("`%s` use insert or update must have a conflict column arg in first", driver) + return 0, fmt.Errorf("`%s` use insert or update must have a conflict column arg in first", a.DriverName) } else { args0 = strings.ToLower(args[0]) iouStr = fmt.Sprintf("ON CONFLICT (%s) DO UPDATE SET", args0) } } else { - return 0, fmt.Errorf("`%s` nonsupport insert or update in beego", driver) + return 0, fmt.Errorf("`%s` nonsupport insert or update in beego", a.DriverName) } //Get on the key-value pairs for _, v := range args { @@ -521,7 +522,7 @@ func (d *dbBase) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Value, t isMulti := false names := make([]string, 0, len(mi.fields.dbcols)-1) Q := d.ins.TableQuote() - values, _, err := d.collectValues(mi, ind, mi.fields.dbcols, true, true, &names, tz) + values, _, err := d.collectValues(mi, ind, mi.fields.dbcols, true, true, &names, a.TZ) if err != nil { return 0, err diff --git a/orm/orm.go b/orm/orm.go index d7ebb371..994ed7e3 100644 --- a/orm/orm.go +++ b/orm/orm.go @@ -212,7 +212,7 @@ func (o *orm) InsertMulti(bulk int, mds interface{}) (int64, error) { // InsertOrUpdate data to database func (o *orm) InsertOrUpdate(md interface{}, colConflitAndArgs ...string) (int64, error) { mi, ind := o.getMiInd(md, true) - id, err := o.alias.DbBaser.InsertOrUpdate(o.db, mi, ind, o.alias.TZ, o.alias.Driver, colConflitAndArgs...) + id, err := o.alias.DbBaser.InsertOrUpdate(o.db, mi, ind, o.alias, colConflitAndArgs...) if err != nil { return id, err } diff --git a/orm/types.go b/orm/types.go index 32d8c233..8c17271d 100644 --- a/orm/types.go +++ b/orm/types.go @@ -396,7 +396,7 @@ type txEnder interface { type dbBaser interface { Read(dbQuerier, *modelInfo, reflect.Value, *time.Location, []string) error Insert(dbQuerier, *modelInfo, reflect.Value, *time.Location) (int64, error) - InsertOrUpdate(dbQuerier, *modelInfo, reflect.Value, *time.Location, DriverType, ...string) (int64, error) + InsertOrUpdate(dbQuerier, *modelInfo, reflect.Value, *alias, ...string) (int64, error) InsertMulti(dbQuerier, *modelInfo, reflect.Value, int, *time.Location) (int64, error) InsertValue(dbQuerier, *modelInfo, bool, []string, []interface{}) (int64, error) InsertStmt(stmtQuerier, *modelInfo, reflect.Value, *time.Location) (int64, error) From 182a21172fabf88763301622476ce99b09bf57c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cfudali113=E2=80=9D?= <“fudali113@gmail.com”> Date: Tue, 26 Jul 2016 11:15:59 +0800 Subject: [PATCH 10/13] Optimize the code logic --- orm/db.go | 37 ++++++++++++++++--------------------- orm/orm_test.go | 13 +++++++------ 2 files changed, 23 insertions(+), 27 deletions(-) diff --git a/orm/db.go b/orm/db.go index 613fc8a9..92b6cfe8 100644 --- a/orm/db.go +++ b/orm/db.go @@ -492,30 +492,28 @@ func (d *dbBase) InsertValue(q dbQuerier, mi *modelInfo, isMulti bool, names []s // If your primary key or unique column conflict will update // If no will insert func (d *dbBase) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Value, a *alias, args ...string) (int64, error) { - iouStr := "" - mysql := DRMySQL - postgres := DRPostgres - driver := a.Driver - argsMap := map[string]string{} args0 := "" - if driver == mysql { + iouStr := "" + argsMap := map[string]string{} + switch a.Driver { + case DRMySQL: iouStr = "ON DUPLICATE KEY UPDATE" - } else if driver == postgres { - if len(args) == 0 || (len(strings.Split(args0, "=")) != 1) { - return 0, fmt.Errorf("`%s` use insert or update must have a conflict column arg in first", a.DriverName) + case DRPostgres: + if len(args) == 0 { + return 0, fmt.Errorf("`%s` use InsertOrUpdate must have a conflict column", a.DriverName) } else { args0 = strings.ToLower(args[0]) iouStr = fmt.Sprintf("ON CONFLICT (%s) DO UPDATE SET", args0) } - } else { - return 0, fmt.Errorf("`%s` nonsupport insert or update in beego", a.DriverName) + default: + return 0, fmt.Errorf("`%s` nonsupport InsertOrUpdate in beego", a.DriverName) } + //Get on the key-value pairs for _, v := range args { kv := strings.Split(v, "=") if len(kv) == 2 { - k := strings.ToLower(kv[0]) - argsMap[k] = kv[1] + argsMap[strings.ToLower(kv[0])] = kv[1] } } @@ -534,17 +532,15 @@ func (d *dbBase) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Value, a var conflitValue interface{} for i, v := range names { marks[i] = "?" - vtl := strings.ToLower(v) - valueStr := argsMap[vtl] - if vtl == args0 { + valueStr := argsMap[v] + if v == args0 { conflitValue = values[i] } if valueStr != "" { - switch driver { - case mysql: + switch a.Driver { + case DRMySQL: updates[i] = v + "=" + valueStr - break - case postgres: + case DRPostgres: if conflitValue != nil { //postgres ON CONFLICT DO UPDATE SET can`t use colu=colu+values updates[i] = fmt.Sprintf("%s=(select %s from %s where %s = ? )", v, valueStr, mi.table, args0) @@ -552,7 +548,6 @@ func (d *dbBase) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Value, a } else { return 0, fmt.Errorf("`%s` must be in front of `%s` in your struct", args0, v) } - break } } else { updates[i] = v + "=?" diff --git a/orm/orm_test.go b/orm/orm_test.go index 5b44f286..c0e7dacd 100644 --- a/orm/orm_test.go +++ b/orm/orm_test.go @@ -2188,8 +2188,9 @@ func TestInsertOrUpdate(t *testing.T) { } //test1 _, err := dORM.InsertOrUpdate(&user1, "user_name") - if err != nil && (err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport insert or update in beego") { + if err != nil && (err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport InsertOrUpdate in beego") { fmt.Println(err) + return } else { throwFailNow(t, err) dORM.Read(&test, "user_name") @@ -2197,7 +2198,7 @@ func TestInsertOrUpdate(t *testing.T) { } //test2 _, err = dORM.InsertOrUpdate(&user2, "user_name") - if err != nil && (err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport insert or update in beego") { + if err != nil && (err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport InsertOrUpdate in beego") { fmt.Println(err) } else { throwFailNow(t, err) @@ -2207,7 +2208,7 @@ func TestInsertOrUpdate(t *testing.T) { } //test3 + _, err = dORM.InsertOrUpdate(&user2, "user_name", "Status=Status+1") - if err != nil && (err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport insert or update in beego") { + if err != nil && (err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport InsertOrUpdate in beego") { fmt.Println(err) } else { throwFailNow(t, err) @@ -2216,7 +2217,7 @@ func TestInsertOrUpdate(t *testing.T) { } //test4 - _, err = dORM.InsertOrUpdate(&user2, "user_name", "Status=Status-1") - if err != nil && (err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport insert or update in beego") { + if err != nil && (err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport InsertOrUpdate in beego") { fmt.Println(err) } else { throwFailNow(t, err) @@ -2225,7 +2226,7 @@ func TestInsertOrUpdate(t *testing.T) { } //test5 * _, err = dORM.InsertOrUpdate(&user2, "user_name", "Status=Status*3") - if err != nil && (err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport insert or update in beego") { + if err != nil && (err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport InsertOrUpdate in beego") { fmt.Println(err) } else { throwFailNow(t, err) @@ -2234,7 +2235,7 @@ func TestInsertOrUpdate(t *testing.T) { } //test6 / _, err = dORM.InsertOrUpdate(&user2, "user_name", "Status=Status/3") - if err != nil && (err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport insert or update in beego") { + if err != nil && (err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport InsertOrUpdate in beego") { fmt.Println(err) } else { throwFailNow(t, err) From f471ee90250ffcc5ce1038b835aac8199a2fc2df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cfudali113=E2=80=9D?= <“fudali113@gmail.com”> Date: Tue, 26 Jul 2016 12:19:06 +0800 Subject: [PATCH 11/13] update orm_test --- orm/orm_test.go | 43 +++++++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/orm/orm_test.go b/orm/orm_test.go index c0e7dacd..eaf78738 100644 --- a/orm/orm_test.go +++ b/orm/orm_test.go @@ -2187,19 +2187,26 @@ func TestInsertOrUpdate(t *testing.T) { return } //test1 +test1: _, err := dORM.InsertOrUpdate(&user1, "user_name") - if err != nil && (err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport InsertOrUpdate in beego") { + if err != nil { fmt.Println(err) - return + if err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport InsertOrUpdate in beego" { + goto test2 + } } else { throwFailNow(t, err) dORM.Read(&test, "user_name") throwFailNow(t, AssertIs(user1.Status, test.Status)) } //test2 +test2: _, err = dORM.InsertOrUpdate(&user2, "user_name") - if err != nil && (err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport InsertOrUpdate in beego") { + if err != nil { fmt.Println(err) + if err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport InsertOrUpdate in beego" { + goto test3 + } } else { throwFailNow(t, err) dORM.Read(&test, "user_name") @@ -2207,36 +2214,52 @@ func TestInsertOrUpdate(t *testing.T) { throwFailNow(t, AssertIs(user2.Password, strings.TrimSpace(test.Password))) } //test3 + - _, err = dORM.InsertOrUpdate(&user2, "user_name", "Status=Status+1") - if err != nil && (err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport InsertOrUpdate in beego") { +test3: + _, err = dORM.InsertOrUpdate(&user2, "user_name", "status=status+1") + if err != nil { fmt.Println(err) + if err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport InsertOrUpdate in beego" { + goto test4 + } } else { throwFailNow(t, err) dORM.Read(&test, "user_name") throwFailNow(t, AssertIs(user2.Status+1, test.Status)) } //test4 - - _, err = dORM.InsertOrUpdate(&user2, "user_name", "Status=Status-1") - if err != nil && (err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport InsertOrUpdate in beego") { +test4: + _, err = dORM.InsertOrUpdate(&user2, "user_name", "status=status-1") + if err != nil { fmt.Println(err) + if err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport InsertOrUpdate in beego" { + goto test5 + } } else { throwFailNow(t, err) dORM.Read(&test, "user_name") throwFailNow(t, AssertIs((user2.Status+1)-1, test.Status)) } //test5 * - _, err = dORM.InsertOrUpdate(&user2, "user_name", "Status=Status*3") - if err != nil && (err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport InsertOrUpdate in beego") { +test5: + _, err = dORM.InsertOrUpdate(&user2, "user_name", "status=status*3") + if err != nil { fmt.Println(err) + if err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport InsertOrUpdate in beego" { + goto test6 + } } else { throwFailNow(t, err) dORM.Read(&test, "user_name") throwFailNow(t, AssertIs(((user2.Status+1)-1)*3, test.Status)) } //test6 / +test6: _, err = dORM.InsertOrUpdate(&user2, "user_name", "Status=Status/3") - if err != nil && (err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport InsertOrUpdate in beego") { + if err != nil { fmt.Println(err) + if err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport InsertOrUpdate in beego" { + return + } } else { throwFailNow(t, err) dORM.Read(&test, "user_name") From 4e10100575ce5de5fec0d1d39d129b8e9ecedd39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cfudali113=E2=80=9D?= <“fudali113@gmail.com”> Date: Tue, 26 Jul 2016 12:44:16 +0800 Subject: [PATCH 12/13] update orm_test --- orm/orm_test.go | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/orm/orm_test.go b/orm/orm_test.go index eaf78738..1410fd8a 100644 --- a/orm/orm_test.go +++ b/orm/orm_test.go @@ -2187,81 +2187,75 @@ func TestInsertOrUpdate(t *testing.T) { return } //test1 -test1: _, err := dORM.InsertOrUpdate(&user1, "user_name") if err != nil { fmt.Println(err) if err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport InsertOrUpdate in beego" { - goto test2 + } else { + throwFailNow(t, err) } } else { - throwFailNow(t, err) dORM.Read(&test, "user_name") throwFailNow(t, AssertIs(user1.Status, test.Status)) } //test2 -test2: _, err = dORM.InsertOrUpdate(&user2, "user_name") if err != nil { fmt.Println(err) if err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport InsertOrUpdate in beego" { - goto test3 + } else { + throwFailNow(t, err) } } else { - throwFailNow(t, err) dORM.Read(&test, "user_name") throwFailNow(t, AssertIs(user2.Status, test.Status)) throwFailNow(t, AssertIs(user2.Password, strings.TrimSpace(test.Password))) } //test3 + -test3: _, err = dORM.InsertOrUpdate(&user2, "user_name", "status=status+1") if err != nil { fmt.Println(err) if err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport InsertOrUpdate in beego" { - goto test4 + } else { + throwFailNow(t, err) } } else { - throwFailNow(t, err) dORM.Read(&test, "user_name") throwFailNow(t, AssertIs(user2.Status+1, test.Status)) } //test4 - -test4: _, err = dORM.InsertOrUpdate(&user2, "user_name", "status=status-1") if err != nil { fmt.Println(err) if err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport InsertOrUpdate in beego" { - goto test5 + } else { + throwFailNow(t, err) } } else { - throwFailNow(t, err) dORM.Read(&test, "user_name") throwFailNow(t, AssertIs((user2.Status+1)-1, test.Status)) } //test5 * -test5: _, err = dORM.InsertOrUpdate(&user2, "user_name", "status=status*3") if err != nil { fmt.Println(err) if err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport InsertOrUpdate in beego" { - goto test6 + } else { + throwFailNow(t, err) } } else { - throwFailNow(t, err) dORM.Read(&test, "user_name") throwFailNow(t, AssertIs(((user2.Status+1)-1)*3, test.Status)) } //test6 / -test6: _, err = dORM.InsertOrUpdate(&user2, "user_name", "Status=Status/3") if err != nil { fmt.Println(err) if err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport InsertOrUpdate in beego" { - return + } else { + throwFailNow(t, err) } } else { - throwFailNow(t, err) dORM.Read(&test, "user_name") throwFailNow(t, AssertIs((((user2.Status+1)-1)*3)/3, test.Status)) } From cacf6cde194d909c1c307c0a2f1c284b3943bd9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cfudali113=E2=80=9D?= <“fudali113@gmail.com”> Date: Tue, 26 Jul 2016 14:27:22 +0800 Subject: [PATCH 13/13] update db.go --- orm/db.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/orm/db.go b/orm/db.go index 92b6cfe8..ec23e383 100644 --- a/orm/db.go +++ b/orm/db.go @@ -532,7 +532,7 @@ func (d *dbBase) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Value, a var conflitValue interface{} for i, v := range names { marks[i] = "?" - valueStr := argsMap[v] + valueStr := argsMap[strings.ToLower(v)] if v == args0 { conflitValue = values[i] }