From d20e498c8f2ae859c0bd4c862636c57bd1bf0408 Mon Sep 17 00:00:00 2001 From: akushman Date: Sun, 15 Dec 2019 17:00:43 +0100 Subject: [PATCH] #36: Add tests for Rename / WhereIn / WhereNotNull --- builder.go | 83 ++++++++++++++++++++++++++++++++----------------- builder_test.go | 41 ++++++++++++++++++++++++ helpers.go | 21 +++++++++++++ 3 files changed, 117 insertions(+), 28 deletions(-) create mode 100644 helpers.go diff --git a/builder.go b/builder.go index 6ac7732..94f31d4 100644 --- a/builder.go +++ b/builder.go @@ -16,6 +16,9 @@ const ( joinRight = "RIGHT" joinFull = "FULL" joinFullOuter = "FULL OUTER" + where = " WHERE " + and = " AND " + or = " OR " ) // inner type to build qualified sql @@ -136,13 +139,13 @@ func (r *DB) HavingRaw(raw string) *DB { // OrHavingRaw accepts custom string to apply it to having clause with logical OR func (r *DB) OrHavingRaw(raw string) *DB { - r.Builder.having += " OR " + raw + r.Builder.having += or + raw return r } // AndHavingRaw accepts custom string to apply it to having clause with logical OR func (r *DB) AndHavingRaw(raw string) *DB { - r.Builder.having += " AND " + raw + r.Builder.having += and + raw return r } @@ -249,37 +252,37 @@ func (r *DB) buildWhere(prefix, operand, operator string, val interface{}) *DB { // WhereBetween sets the clause BETWEEN 2 values func (r *DB) WhereBetween(col string, val1, val2 interface{}) *DB { - r.Builder.where = " WHERE " + col + " BETWEEN " + convertToStr(val1) + " AND " + convertToStr(val2) + r.Builder.where = where + col + " BETWEEN " + convertToStr(val1) + and + convertToStr(val2) return r } // OrWhereBetween sets the clause OR BETWEEN 2 values func (r *DB) OrWhereBetween(col string, val1, val2 interface{}) *DB { - r.Builder.where += " OR " + col + " BETWEEN " + convertToStr(val1) + " AND " + convertToStr(val2) + r.Builder.where += or + col + " BETWEEN " + convertToStr(val1) + and + convertToStr(val2) return r } // AndWhereBetween sets the clause AND BETWEEN 2 values func (r *DB) AndWhereBetween(col string, val1, val2 interface{}) *DB { - r.Builder.where += " AND " + col + " BETWEEN " + convertToStr(val1) + " AND " + convertToStr(val2) + r.Builder.where += and + col + " BETWEEN " + convertToStr(val1) + and + convertToStr(val2) return r } // WhereBetween sets the clause BETWEEN 2 values func (r *DB) WhereNotBetween(col string, val1, val2 interface{}) *DB { - r.Builder.where = " WHERE " + col + " NOT BETWEEN " + convertToStr(val1) + " AND " + convertToStr(val2) + r.Builder.where = where + col + " NOT BETWEEN " + convertToStr(val1) + and + convertToStr(val2) return r } // OrWhereBetween sets the clause OR BETWEEN 2 values func (r *DB) OrWhereNotBetween(col string, val1, val2 interface{}) *DB { - r.Builder.where += " OR " + col + " NOT BETWEEN " + convertToStr(val1) + " AND " + convertToStr(val2) + r.Builder.where += or + col + " NOT BETWEEN " + convertToStr(val1) + and + convertToStr(val2) return r } // AndWhereBetween sets the clause AND BETWEEN 2 values func (r *DB) AndWhereNotBetween(col string, val1, val2 interface{}) *DB { - r.Builder.where += " AND " + col + " NOT BETWEEN " + convertToStr(val1) + " AND " + convertToStr(val2) + r.Builder.where += and + col + " NOT BETWEEN " + convertToStr(val1) + and + convertToStr(val2) return r } @@ -302,19 +305,19 @@ func convertToStr(val interface{}) string { // WhereRaw accepts custom string to apply it to where clause func (r *DB) WhereRaw(raw string) *DB { - r.Builder.where = " WHERE " + raw + r.Builder.where = where + raw return r } // OrWhereRaw accepts custom string to apply it to where clause with logical OR func (r *DB) OrWhereRaw(raw string) *DB { - r.Builder.where += " OR " + raw + r.Builder.where += or + raw return r } // AndWhereRaw accepts custom string to apply it to where clause with logical OR func (r *DB) AndWhereRaw(raw string) *DB { - r.Builder.where += " AND " + raw + r.Builder.where += and + raw return r } @@ -355,74 +358,98 @@ func (r *DB) Rename(from, to string) (sql.Result, error) { } // WhereIn appends IN (val1, val2, val3...) stmt to WHERE clause -func (r *DB) WhereIn(field string, in []interface{}) *DB { - r.Builder.where += " " + field + " IN (" + strings.Join(prepareSlice(in), ", ") + ")" +func (r *DB) WhereIn(field string, in interface{}) *DB { + ins, err := interfaceToSlice(in) + if err != nil { + return nil + } + r.Builder.where += where + field + " IN (" + strings.Join(prepareSlice(ins), ", ") + ")" return r } // WhereNotIn appends NOT IN (val1, val2, val3...) stmt to WHERE clause -func (r *DB) WhereNotIn(field string, in []interface{}) *DB { - r.Builder.where += " " + field + " NOT IN (" + strings.Join(prepareSlice(in), ", ") + ")" +func (r *DB) WhereNotIn(field string, in interface{}) *DB { + ins, err := interfaceToSlice(in) + if err != nil { + return nil + } + r.Builder.where += where + field + " NOT IN (" + strings.Join(prepareSlice(ins), ", ") + ")" return r } // OrWhereIn appends OR IN (val1, val2, val3...) stmt to WHERE clause -func (r *DB) OrWhereIn(field string, in []interface{}) *DB { - r.Builder.where += " OR " + field + " IN (" + strings.Join(prepareSlice(in), ", ") + ")" +func (r *DB) OrWhereIn(field string, in interface{}) *DB { + ins, err := interfaceToSlice(in) + if err != nil { + return nil + } + r.Builder.where += or + field + " IN (" + strings.Join(prepareSlice(ins), ", ") + ")" return r } // OrWhereNotIn appends OR NOT IN (val1, val2, val3...) stmt to WHERE clause -func (r *DB) OrWhereNotIn(field string, in []interface{}) *DB { - r.Builder.where += " OR " + field + " NOT IN (" + strings.Join(prepareSlice(in), ", ") + ")" +func (r *DB) OrWhereNotIn(field string, in interface{}) *DB { + ins, err := interfaceToSlice(in) + if err != nil { + return nil + } + r.Builder.where += or + field + " NOT IN (" + strings.Join(prepareSlice(ins), ", ") + ")" return r } // AndWhereIn appends OR IN (val1, val2, val3...) stmt to WHERE clause -func (r *DB) AndWhereIn(field string, in []interface{}) *DB { - r.Builder.where += " AND " + field + " IN (" + strings.Join(prepareSlice(in), ", ") + ")" +func (r *DB) AndWhereIn(field string, in interface{}) *DB { + ins, err := interfaceToSlice(in) + if err != nil { + return nil + } + r.Builder.where += and + field + " IN (" + strings.Join(prepareSlice(ins), ", ") + ")" return r } // AndWhereNotIn appends OR NOT IN (val1, val2, val3...) stmt to WHERE clause func (r *DB) AndWhereNotIn(field string, in []interface{}) *DB { - r.Builder.where += " AND " + field + " NOT IN (" + strings.Join(prepareSlice(in), ", ") + ")" + ins, err := interfaceToSlice(in) + if err != nil { + return nil + } + r.Builder.where += and + field + " NOT IN (" + strings.Join(prepareSlice(ins), ", ") + ")" return r } // WhereIsNull appends fieldName IS NULL stmt to WHERE clause func (r *DB) WhereNull(field string) *DB { - r.Builder.where += " " + field + " IS NULL" + r.Builder.where = where + field + " IS NULL" return r } // WhereNotNull appends fieldName IS NOT NULL stmt to WHERE clause func (r *DB) WhereNotNull(field string) *DB { - r.Builder.where += " " + field + " IS NOT NULL" + r.Builder.where = where + field + " IS NOT NULL" return r } // OrWhereIsNull appends fieldName IS NULL stmt to WHERE clause func (r *DB) OrWhereNull(field string) *DB { - r.Builder.where += " OR " + field + " IS NULL" + r.Builder.where += or + field + " IS NULL" return r } // OrWhereNotNull appends fieldName IS NOT NULL stmt to WHERE clause func (r *DB) OrWhereNotNull(field string) *DB { - r.Builder.where += " OR " + field + " IS NOT NULL" + r.Builder.where += or + field + " IS NOT NULL" return r } // AndWhereIsNull appends fieldName IS NULL stmt to WHERE clause func (r *DB) AndWhereNull(field string) *DB { - r.Builder.where += " AND " + field + " IS NULL" + r.Builder.where += and + field + " IS NULL" return r } // AndWhereNotNull appends fieldName IS NOT NULL stmt to WHERE clause func (r *DB) AndWhereNotNull(field string) *DB { - r.Builder.where += " AND " + field + " IS NOT NULL" + r.Builder.where += and + field + " IS NOT NULL" return r } diff --git a/builder_test.go b/builder_test.go index e81c32a..951f1f3 100644 --- a/builder_test.go +++ b/builder_test.go @@ -639,3 +639,44 @@ func TestDB_Offset(t *testing.T) { db.Truncate(UsersTable) } + +func TestDB_Rename(t *testing.T) { + tbl := "tbl1" + tbl2 := "tbl2" + db.Drop(tbl) + db.Drop(tbl2) + + _, err := db.Schema(tbl, func(table *Table) { + table.Increments("id") + }) + assert.NoError(t, err) + + _, err = db.Rename(tbl, tbl2) + assert.NoError(t, err) + + exists, err := db.HasTable("public", tbl2) + assert.NoError(t, err) + assert.True(t, exists) +} + +func TestDB_WhereIn(t *testing.T) { + db.Truncate(UsersTable) + err := db.Table(UsersTable).InsertBatch(batchUsers) + assert.NoError(t, err) + + res, err := db.Table(UsersTable).Select("name").WhereIn("points", []int64{123, 1234}).OrWhereIn("points", []int64{1, 2, 3}).Get() + assert.NoError(t, err) + assert.Equal(t, len(res), 2) + db.Truncate(UsersTable) +} + +func TestDB_WhereNotNull(t *testing.T) { + db.Truncate(UsersTable) + err := db.Table(UsersTable).InsertBatch(batchUsers) + assert.NoError(t, err) + + res, err := db.Table(UsersTable).Select("name").WhereNotNull("points").AndWhereNotNull("name").Get() + assert.NoError(t, err) + assert.Equal(t, len(res), len(batchUsers)) + db.Truncate(UsersTable) +} diff --git a/helpers.go b/helpers.go new file mode 100644 index 0000000..4d4f9be --- /dev/null +++ b/helpers.go @@ -0,0 +1,21 @@ +package buildsqlx + +import ( + "errors" + "reflect" +) + +func interfaceToSlice(slice interface{}) ([]interface{}, error) { + var err error + s := reflect.ValueOf(slice) + if s.Kind() != reflect.Slice { + err = errors.New("interfaceToSlice() given a non-slice type") + } + + ret := make([]interface{}, s.Len()) + for i := 0; i < s.Len(); i++ { + ret[i] = s.Index(i).Interface() + } + + return ret, err +}