From 9e84e4bb1b69f388788ac0b37dcdc3dcfd17ff05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Garcia?= Date: Thu, 26 Nov 2020 22:35:36 -0300 Subject: [PATCH] Remove gorm dependency from Delete() --- kiss_orm.go | 30 ++++++++++++++++++------- kiss_orm_test.go | 58 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 8 deletions(-) diff --git a/kiss_orm.go b/kiss_orm.go index 748bfae..a619cbb 100644 --- a/kiss_orm.go +++ b/kiss_orm.go @@ -48,11 +48,11 @@ func (c Client) ChangeTable(ctx context.Context, tableName string) ORMProvider { } // Query queries several rows from the database, -// the input should be a slice of structs passed +// the input should be a slice of structs (or *struct) passed // by reference and it will be filled with all the results. // // Note: it is very important to make sure the query will -// return a small number of results, otherwise you risk +// return a small known number of results, otherwise you risk // of overloading the available memory. func (c Client) Query( ctx context.Context, @@ -271,14 +271,15 @@ func (c Client) Delete( ctx context.Context, ids ...interface{}, ) error { - for _, id := range ids { - r := c.db.Table(c.tableName).Delete(id) - if r.Error != nil { - return r.Error - } + if len(ids) == 0 { + return nil } - return nil + query := buildDeleteQuery(c.tableName, ids) + + _, err := c.db.DB().ExecContext(ctx, query, ids...) + + return err } // Update updates the given instances on the database by id. @@ -606,3 +607,16 @@ func getTagInfoWithCache(tagInfoCache map[reflect.Type]structInfo, key reflect.T } return info } + +func buildDeleteQuery(table string, ids []interface{}) string { + values := []string{} + for range ids { + values = append(values, "?") + } + + return fmt.Sprintf( + "DELETE FROM `%s` WHERE id IN (%s)", + table, + strings.Join(values, ","), + ) +} diff --git a/kiss_orm_test.go b/kiss_orm_test.go index 500b970..6417410 100644 --- a/kiss_orm_test.go +++ b/kiss_orm_test.go @@ -294,6 +294,64 @@ func TestDelete(t *testing.T) { assert.Equal(t, uint(0), result.ID) assert.Equal(t, "", result.Name) }) + + t.Run("should delete multiple ids correctly", func(t *testing.T) { + db := connectDB(t) + defer db.Close() + + ctx := context.Background() + c := Client{ + db: db, + tableName: "users", + } + + u1 := User{ + Name: "Fernanda", + } + err := c.Insert(ctx, &u1) + assert.Equal(t, nil, err) + assert.NotEqual(t, 0, u1.ID) + + u2 := User{ + Name: "Juliano", + } + err = c.Insert(ctx, &u2) + assert.Equal(t, nil, err) + assert.NotEqual(t, 0, u2.ID) + + u3 := User{ + Name: "This won't be deleted", + } + err = c.Insert(ctx, &u3) + assert.Equal(t, nil, err) + assert.NotEqual(t, 0, u3.ID) + + result := User{} + it := c.db.Raw("SELECT * FROM users WHERE id=?", u1.ID) + it.Scan(&result) + assert.Equal(t, u1.ID, result.ID) + + result = User{} + it = c.db.Raw("SELECT * FROM users WHERE id=?", u2.ID) + it.Scan(&result) + assert.Equal(t, u2.ID, result.ID) + + result = User{} + it = c.db.Raw("SELECT * FROM users WHERE id=?", u3.ID) + it.Scan(&result) + assert.Equal(t, u3.ID, result.ID) + + err = c.Delete(ctx, u1.ID, u2.ID) + assert.Equal(t, nil, err) + + results := []User{} + it = c.db.Raw("SELECT * FROM users WHERE id IN (?, ?, ?)", u1.ID, u2.ID, u3.ID) + it.Scan(&results) + + assert.Equal(t, nil, it.Error) + assert.Equal(t, 1, len(results)) + assert.Equal(t, "This won't be deleted", results[0].Name) + }) } func TestUpdate(t *testing.T) {