From 995ccd680caccd060a2053155914c649907ce625 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Garcia?= Date: Wed, 30 Dec 2020 12:33:52 -0300 Subject: [PATCH] Fix Delete() to work with postgres --- kiss_orm.go | 12 +- kiss_orm_test.go | 290 ++++++++++++++++++++++++----------------------- 2 files changed, 156 insertions(+), 146 deletions(-) diff --git a/kiss_orm.go b/kiss_orm.go index b971d7d..70da2b2 100644 --- a/kiss_orm.go +++ b/kiss_orm.go @@ -348,7 +348,7 @@ func (c Client) Delete( return nil } - query := buildDeleteQuery(c.tableName, ids) + query := buildDeleteQuery(c.dialect, c.tableName, ids) _, err := c.db.DB().ExecContext(ctx, query, ids...) @@ -737,15 +737,15 @@ func getCachedTagInfo(tagInfoCache map[reflect.Type]structInfo, key reflect.Type return info } -func buildDeleteQuery(table string, ids []interface{}) string { +func buildDeleteQuery(dialect dialect, table string, ids []interface{}) string { values := []string{} - for range ids { - values = append(values, "?") + for i := range ids { + values = append(values, dialect.Placeholder(i)) } return fmt.Sprintf( - "DELETE FROM `%s` WHERE id IN (%s)", - table, + "DELETE FROM %s WHERE id IN (%s)", + dialect.Escape(table), strings.Join(values, ","), ) } diff --git a/kiss_orm_test.go b/kiss_orm_test.go index 2e6dadd..809a6d8 100644 --- a/kiss_orm_test.go +++ b/kiss_orm_test.go @@ -228,147 +228,157 @@ func TestInsert(t *testing.T) { } func TestDelete(t *testing.T) { - err := createTable("sqlite3") - if err != nil { - t.Fatal("could not create test table!, reason:", err.Error()) + for _, driver := range []string{"sqlite3", "postgres"} { + t.Run(driver, func(t *testing.T) { + err := createTable(driver) + if err != nil { + t.Fatal("could not create test table!, reason:", err.Error()) + } + + t.Run("should ignore empty lists of ids", func(t *testing.T) { + db := connectDB(t, driver) + defer db.Close() + + ctx := context.Background() + c := newTestClient(db, driver, "users") + + u := User{ + Name: "Won't be deleted", + } + + err := c.Insert(ctx, &u) + assert.Equal(t, nil, err) + assert.NotEqual(t, uint(0), u.ID) + + result := User{} + it := c.db.Raw("SELECT * FROM users WHERE id="+c.dialect.Placeholder(0), u.ID) + it.Scan(&result) + assert.Equal(t, u.ID, result.ID) + + err = c.Delete(ctx) + assert.Equal(t, nil, err) + + result = User{} + it = c.db.Raw("SELECT * FROM users WHERE id="+c.dialect.Placeholder(0), u.ID) + it.Scan(&result) + assert.Equal(t, u.ID, result.ID) + }) + + t.Run("should delete one id correctly", func(t *testing.T) { + db := connectDB(t, driver) + defer db.Close() + + ctx := context.Background() + c := newTestClient(db, driver, "users") + + u1 := User{ + Name: "Fernanda", + } + + err := c.Insert(ctx, &u1) + assert.Equal(t, nil, err) + assert.NotEqual(t, uint(0), u1.ID) + + result := User{} + it := c.db.Raw("SELECT * FROM users WHERE id="+c.dialect.Placeholder(0), u1.ID) + it.Scan(&result) + assert.Equal(t, u1.ID, result.ID) + + u2 := User{ + Name: "Won't be deleted", + } + + err = c.Insert(ctx, &u2) + assert.Equal(t, nil, err) + assert.NotEqual(t, uint(0), u2.ID) + + result = User{} + it = c.db.Raw("SELECT * FROM users WHERE id="+c.dialect.Placeholder(0), u2.ID) + it.Scan(&result) + assert.Equal(t, u2.ID, result.ID) + + err = c.Delete(ctx, u1.ID) + assert.Equal(t, nil, err) + + result = User{} + it = c.db.Raw("SELECT * FROM users WHERE id="+c.dialect.Placeholder(0), u1.ID) + it.Scan(&result) + + assert.Equal(t, nil, it.Error) + assert.Equal(t, uint(0), result.ID) + assert.Equal(t, "", result.Name) + + result = User{} + it = c.db.Raw("SELECT * FROM users WHERE id="+c.dialect.Placeholder(0), u2.ID) + it.Scan(&result) + + assert.Equal(t, nil, it.Error) + assert.NotEqual(t, uint(0), result.ID) + assert.Equal(t, "Won't be deleted", result.Name) + }) + + t.Run("should delete multiple ids correctly", func(t *testing.T) { + db := connectDB(t, driver) + defer db.Close() + + ctx := context.Background() + c := newTestClient(db, driver, "users") + + u1 := User{ + Name: "Fernanda", + } + err := c.Insert(ctx, &u1) + assert.Equal(t, nil, err) + assert.NotEqual(t, uint(0), u1.ID) + + u2 := User{ + Name: "Juliano", + } + err = c.Insert(ctx, &u2) + assert.Equal(t, nil, err) + assert.NotEqual(t, uint(0), u2.ID) + + u3 := User{ + Name: "This won't be deleted", + } + err = c.Insert(ctx, &u3) + assert.Equal(t, nil, err) + assert.NotEqual(t, uint(0), u3.ID) + + result := User{} + it := c.db.Raw("SELECT * FROM users WHERE id="+c.dialect.Placeholder(0), u1.ID) + it.Scan(&result) + assert.Equal(t, u1.ID, result.ID) + + result = User{} + it = c.db.Raw("SELECT * FROM users WHERE id="+c.dialect.Placeholder(0), u2.ID) + it.Scan(&result) + assert.Equal(t, u2.ID, result.ID) + + result = User{} + it = c.db.Raw("SELECT * FROM users WHERE id="+c.dialect.Placeholder(0), 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( + fmt.Sprintf( + "SELECT * FROM users WHERE id IN (%s, %s, %s)", + c.dialect.Placeholder(0), c.dialect.Placeholder(1), c.dialect.Placeholder(2), + ), + 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) + }) + }) } - - t.Run("should ignore empty lists of ids", func(t *testing.T) { - db := connectDB(t, "sqlite3") - defer db.Close() - - ctx := context.Background() - c := newTestClient(db, "sqlite3", "users") - - u := User{ - Name: "Won't be deleted", - } - - err := c.Insert(ctx, &u) - assert.Equal(t, nil, err) - assert.NotEqual(t, uint(0), u.ID) - - result := User{} - it := c.db.Raw("SELECT * FROM users WHERE id=?", u.ID) - it.Scan(&result) - assert.Equal(t, u.ID, result.ID) - - err = c.Delete(ctx) - assert.Equal(t, nil, err) - - result = User{} - it = c.db.Raw("SELECT * FROM users WHERE id=?", u.ID) - it.Scan(&result) - assert.Equal(t, u.ID, result.ID) - }) - - t.Run("should delete one id correctly", func(t *testing.T) { - db := connectDB(t, "sqlite3") - defer db.Close() - - ctx := context.Background() - c := newTestClient(db, "sqlite3", "users") - - u1 := User{ - Name: "Fernanda", - } - - err := c.Insert(ctx, &u1) - assert.Equal(t, nil, err) - assert.NotEqual(t, uint(0), u1.ID) - - result := User{} - it := c.db.Raw("SELECT * FROM users WHERE id=?", u1.ID) - it.Scan(&result) - assert.Equal(t, u1.ID, result.ID) - - u2 := User{ - Name: "Won't be deleted", - } - - err = c.Insert(ctx, &u2) - assert.Equal(t, nil, err) - assert.NotEqual(t, uint(0), u2.ID) - - result = User{} - it = c.db.Raw("SELECT * FROM users WHERE id=?", u2.ID) - it.Scan(&result) - assert.Equal(t, u2.ID, result.ID) - - err = c.Delete(ctx, u1.ID) - assert.Equal(t, nil, err) - - result = User{} - it = c.db.Raw("SELECT * FROM users WHERE id=?", u1.ID) - it.Scan(&result) - - assert.Equal(t, nil, it.Error) - assert.Equal(t, uint(0), result.ID) - assert.Equal(t, "", result.Name) - - result = User{} - it = c.db.Raw("SELECT * FROM users WHERE id=?", u2.ID) - it.Scan(&result) - - assert.Equal(t, nil, it.Error) - assert.NotEqual(t, uint(0), result.ID) - assert.Equal(t, "Won't be deleted", result.Name) - }) - - t.Run("should delete multiple ids correctly", func(t *testing.T) { - db := connectDB(t, "sqlite3") - defer db.Close() - - ctx := context.Background() - c := newTestClient(db, "sqlite3", "users") - - u1 := User{ - Name: "Fernanda", - } - err := c.Insert(ctx, &u1) - assert.Equal(t, nil, err) - assert.NotEqual(t, uint(0), u1.ID) - - u2 := User{ - Name: "Juliano", - } - err = c.Insert(ctx, &u2) - assert.Equal(t, nil, err) - assert.NotEqual(t, uint(0), u2.ID) - - u3 := User{ - Name: "This won't be deleted", - } - err = c.Insert(ctx, &u3) - assert.Equal(t, nil, err) - assert.NotEqual(t, uint(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) {