From 93aaca03e7aebb7e9c320f1dfa997412c90e698d Mon Sep 17 00:00:00 2001 From: liujian Date: Mon, 20 Nov 2023 17:18:35 +0800 Subject: [PATCH] Update xsql Update,Delete --- src/xsql/README.md | 23 +++++++++--- src/xsql/db.go | 4 +-- src/xsql/db_test.go | 29 +++++++++++---- src/xsql/executor.go | 84 ++++++++++++++++++++++++++++++++++++-------- 4 files changed, 112 insertions(+), 28 deletions(-) diff --git a/src/xsql/README.md b/src/xsql/README.md index f5eb4c2..f8e9847 100644 --- a/src/xsql/README.md +++ b/src/xsql/README.md @@ -141,13 +141,24 @@ if err != nil { > Oracle placeholder needs to be modified to :id +Update full + ```go test := Test{ - Id: 10, + Id: 8, Foo: "test", Bar: time.Now(), } -res, err := DB.Update(&test, "id = ?", 10) +res, err := DB.Update(&test, "id = ?", 8) +``` + +Update columns + +```go +test := map[string]interface{}{ + "foo": "test", +} +res, err := DB.Model(&Test{}).Update(test, "id = ?", 8) ``` ## Delete @@ -156,11 +167,15 @@ res, err := DB.Update(&test, "id = ?", 10) ```go test := Test{ - Id: 10, + Id: 8, Foo: "test", Bar: time.Now(), } -res, err := DB.Delete(&test, "id = ?", test.Id) +res, err := DB.Model(&test).Delete("id = ?", test.Id) +``` + +```go +res, err := DB.Model(&Test{}).Delete("id = ?", 8) ``` ## Exec diff --git a/src/xsql/db.go b/src/xsql/db.go index 8b9388f..c096dbb 100644 --- a/src/xsql/db.go +++ b/src/xsql/db.go @@ -48,8 +48,8 @@ func (t *DB) Update(data interface{}, expr string, args ...interface{}) (sql.Res return t.executor.Update(data, expr, args, t.Options) } -func (t *DB) Delete(data interface{}, expr string, args ...interface{}) (sql.Result, error) { - return t.executor.Delete(data, expr, args, t.Options) +func (t *DB) Model(s interface{}) *ModelExecutor { + return t.executor.model(s, t.Options) } func (t *DB) Exec(query string, args ...interface{}) (sql.Result, error) { diff --git a/src/xsql/db_test.go b/src/xsql/db_test.go index 62ec696..e08e435 100644 --- a/src/xsql/db_test.go +++ b/src/xsql/db_test.go @@ -211,7 +211,7 @@ func TestEmbeddingUpdate(t *testing.T) { Bar: time.Now(), }, } - _, err := DB.Update(&test, "id = ?", 10) + _, err := DB.Update(&test, "id = ?", 8) a.Empty(err) } @@ -222,11 +222,24 @@ func TestUpdate(t *testing.T) { DB := newDB() test := Test{ - Id: 999, - Foo: "test update", + Id: 8, + Foo: "test update 1", Bar: time.Now(), } - _, err := DB.Update(&test, "id = ?", 10) + _, err := DB.Update(&test, "id = ?", 999) + + a.Empty(err) +} + +func TestUpdateColumns(t *testing.T) { + a := assert.New(t) + + DB := newDB() + + test := map[string]interface{}{ + "foo": "test update 2", + } + _, err := DB.Model(&Test{}).Update(test, "id = ?", 8) a.Empty(err) } @@ -237,12 +250,14 @@ func TestDelete(t *testing.T) { DB := newDB() test := Test{ - Id: 10, + Id: 8, Foo: "test", Bar: time.Now(), } - _, err := DB.Delete(&test, "id = ?", test.Id) + _, err := DB.Model(&test).Delete("id = ?", test.Id) + a.Empty(err) + _, err = DB.Model(&Test{}).Delete("id = ?", 8) a.Empty(err) } @@ -251,7 +266,7 @@ func TestExec(t *testing.T) { DB := newDB() - _, err := DB.Exec("DELETE FROM xsql WHERE id = ?", 10) + _, err := DB.Exec("DELETE FROM xsql WHERE id = ?", 7) a.Empty(err) } diff --git a/src/xsql/executor.go b/src/xsql/executor.go index b477685..4c41909 100644 --- a/src/xsql/executor.go +++ b/src/xsql/executor.go @@ -13,6 +13,12 @@ type executor struct { Executor } +type ModelExecutor struct { + Executor + Options *sqlOptions + TableName string +} + func (t *executor) Insert(data interface{}, opts *sqlOptions) (sql.Result, error) { fields := make([]string, 0) vars := make([]string, 0) @@ -143,6 +149,27 @@ func (t *executor) BatchInsert(array interface{}, opts *sqlOptions) (sql.Result, return res, nil } +func (t *executor) model(s interface{}, opts *sqlOptions) *ModelExecutor { + var table string + value := reflect.ValueOf(s) + switch value.Kind() { + case reflect.Ptr: + return t.model(value.Elem().Interface(), opts) + case reflect.Struct: + if tab, ok := s.(Table); ok { + table = tab.TableName() + } else { + table = value.Type().Name() + } + break + } + return &ModelExecutor{ + Executor: t.Executor, + Options: opts, + TableName: table, + } +} + func (t *executor) Update(data interface{}, expr string, args []interface{}, opts *sqlOptions) (sql.Result, error) { set := make([]string, 0) bindArgs := make([]interface{}, 0) @@ -196,24 +223,16 @@ func (t *executor) Update(data interface{}, expr string, args []interface{}, opt return res, nil } -func (t *executor) Delete(data interface{}, expr string, args []interface{}, opts *sqlOptions) (sql.Result, error) { +func (t *ModelExecutor) Update(data map[string]interface{}, expr string, args ...interface{}) (sql.Result, error) { + set := make([]string, 0) bindArgs := make([]interface{}, 0) - table := "" + table := t.TableName + opts := t.Options - value := reflect.ValueOf(data) - switch value.Kind() { - case reflect.Ptr: - return t.Delete(value.Elem().Interface(), expr, args, opts) - case reflect.Struct: - if tab, ok := data.(Table); ok { - table = tab.TableName() - } else { - table = value.Type().Name() - } - break - default: - return nil, errors.New("xsql: only for struct type") + for k, v := range data { + set = append(set, fmt.Sprintf("`%s` = ?", k)) + bindArgs = append(bindArgs, v) } where := "" @@ -222,6 +241,41 @@ func (t *executor) Delete(data interface{}, expr string, args []interface{}, opt bindArgs = append(bindArgs, args...) } + SQL := fmt.Sprintf(`UPDATE %s SET %s%s`, table, strings.Join(set, ", "), where) + + startTime := time.Now() + res, err := t.Executor.Exec(SQL, bindArgs...) + var rowsAffected int64 + if res != nil { + rowsAffected, _ = res.RowsAffected() + } + l := &Log{ + Duration: time.Now().Sub(startTime), + SQL: SQL, + Bindings: bindArgs, + RowsAffected: rowsAffected, + Error: err, + } + opts.doDebug(l) + if err != nil { + return nil, err + } + + return res, nil +} + +func (t *ModelExecutor) Delete(expr string, args ...interface{}) (sql.Result, error) { + bindArgs := make([]interface{}, 0) + + table := t.TableName + opts := t.Options + + where := "" + if expr != "" { + where = fmt.Sprintf(` WHERE %s`, expr) + bindArgs = append(bindArgs, args...) + } + SQL := fmt.Sprintf(`DELETE FROM %s%s`, table, where) startTime := time.Now()