diff --git a/builder.go b/builder.go index 851a422..003e39e 100644 --- a/builder.go +++ b/builder.go @@ -36,15 +36,18 @@ type GoBuilder struct { paramsClause []any counterClause int holderClause SQLDialect + holderCode string } // NewGoBuilder initializes a new instance of GoBuilder func NewGoBuilder(holderClause SQLDialect) *GoBuilder { - return &GoBuilder{ + gb := &GoBuilder{ paramsClause: []any{}, counterClause: 1, holderClause: holderClause, } + gb.holderCode = gb.getPlaceholderCode() + return gb } // Table specifies the table name for the query @@ -219,8 +222,33 @@ func (gb *GoBuilder) Union(sql string) *GoBuilder { return gb } -// ToSql returns the final SQL query and the associated bind parameters -func (gb *GoBuilder) ToSql() (string, []any) { +// Sql returns the final SQL query +func (gb *GoBuilder) Sql() string { + clauses := []string{ + gb.selectClause, + gb.joinClause, + gb.whereClause, + gb.groupByClause, + gb.havingClause, + gb.orderByClause, + gb.limitClause, + gb.unionClause, + } + query := strings.Join(clauses, " ") + re := regexp.MustCompile(`\s+`) + query = strings.TrimSpace(re.ReplaceAllString(query, " ")) + + params := gb.paramsClause + for i, param := range params { + placeholder := fmt.Sprintf("%s%d", gb.holderCode, i+1) + query = strings.Replace(query, placeholder, gb.cleanValue(param), 1) + } + gb.reset() + return query +} + +// Prepare returns the final SQL query and the associated bind parameters +func (gb *GoBuilder) Prepare() (string, []any) { clauses := []string{ gb.selectClause, gb.joinClause, @@ -241,27 +269,13 @@ func (gb *GoBuilder) ToSql() (string, []any) { // Private method to RESET builder func (gb *GoBuilder) reset() { - *gb = GoBuilder{ - paramsClause: []any{}, - counterClause: 1, - holderClause: gb.holderClause, - } + *gb = *NewGoBuilder(Postgres) } // Private method to add parameters func (gb *GoBuilder) addParam(value any) string { gb.paramsClause = append(gb.paramsClause, value) - var placeholder string - switch gb.holderClause { - case Postgres: - placeholder = fmt.Sprintf("$%d", gb.counterClause) - case SQLServer: - placeholder = fmt.Sprintf("@%d", gb.counterClause) - case Oracle: - placeholder = fmt.Sprintf(":%d", gb.counterClause) - default: // mysql and sqlite - placeholder = fmt.Sprintf("?%d", gb.counterClause) - } + placeholder := fmt.Sprintf("%s%d", gb.holderCode, gb.counterClause) gb.counterClause++ return placeholder } @@ -296,3 +310,29 @@ func (gb *GoBuilder) between(OP, column string, args ...any) *GoBuilder { } return gb } + +// cleanValue trims and escapes potentially harmful characters from the value +func (gb *GoBuilder) cleanValue(value any) string { + switch v := value.(type) { + case string: + cleaned := strings.ReplaceAll(v, "'", "''") + return "'" + cleaned + "'" + default: + return fmt.Sprintf("%v", v) + } +} + +func (gb *GoBuilder) getPlaceholderCode() string { + var code string + switch gb.holderClause { + case Postgres: + code = "$" + case SQLServer: + code = "@" + case Oracle: + code = ":" + default: // mysql and sqlite + code = "?" + } + return code +} diff --git a/builder_test.go b/builder_test.go index 5f6c136..2c1eb1d 100644 --- a/builder_test.go +++ b/builder_test.go @@ -10,339 +10,475 @@ var ( params []any queryExpected string paramsExpected []any - s = NewGoBuilder(Postgres) + gb = NewGoBuilder(Postgres) ) func TestSql_Select(t *testing.T) { queryExpected = "SELECT * FROM users" paramsExpected = []any{} - query, params = s.Table("users").Select().ToSql() + query, params = gb.Table("users").Select().Prepare() if !reflect.DeepEqual(queryExpected, query) { t.Errorf("queryExpected = %v, query %v", queryExpected, query) } if !reflect.DeepEqual(paramsExpected, params) { t.Errorf("paramsExpected = %v, params %v", paramsExpected, params) } + queryExpected = "SELECT * FROM users" + query = gb.Table("users").Select().Sql() + if !reflect.DeepEqual(queryExpected, query) { + t.Errorf("queryExpected = %v, query %v", queryExpected, query) + } } func TestSql_Select_With_Columns(t *testing.T) { queryExpected = "SELECT firstname, lastname FROM users" paramsExpected = []any{} - query, params = s.Table("users").Select("firstname", "lastname").ToSql() + query, params = gb.Table("users").Select("firstname", "lastname").Prepare() if !reflect.DeepEqual(queryExpected, query) { t.Errorf("queryExpected = %v, query %v", queryExpected, query) } if !reflect.DeepEqual(paramsExpected, params) { t.Errorf("paramsExpected = %v, params %v", paramsExpected, params) } + queryExpected = "SELECT firstname, lastname FROM users" + query = gb.Table("users").Select("firstname", "lastname").Sql() + if !reflect.DeepEqual(queryExpected, query) { + t.Errorf("queryExpected = %v, query %v", queryExpected, query) + } } func TestSql_Distinct(t *testing.T) { queryExpected = "SELECT DISTINCT name, age FROM users" paramsExpected := []any{} - query, params = s.Table("users").SelectDistinct("name", "age").ToSql() + query, params = gb.Table("users").SelectDistinct("name", "age").Prepare() if !reflect.DeepEqual(queryExpected, query) { t.Errorf("queryExpected = %v, query %v", queryExpected, query) } if !reflect.DeepEqual(paramsExpected, params) { t.Errorf("paramsExpected = %v, params %v", paramsExpected, params) } + queryExpected = "SELECT DISTINCT name, age FROM users" + query = gb.Table("users").SelectDistinct("name", "age").Sql() + if !reflect.DeepEqual(queryExpected, query) { + t.Errorf("queryExpected = %v, query %v", queryExpected, query) + } } func TestSql_Insert(t *testing.T) { queryExpected = "INSERT INTO users (firstname, lastname) VALUES ($1, $2)" paramsExpected := []any{"Mesut", "GENEZ"} args := map[string]any{"firstname": "Mesut", "lastname": "GENEZ"} - query, params = s.Table("users").Insert(args).ToSql() + query, params = gb.Table("users").Insert(args).Prepare() if !reflect.DeepEqual(queryExpected, query) { t.Errorf("queryExpected = %v, query %v", queryExpected, query) } if !reflect.DeepEqual(paramsExpected, params) { t.Errorf("paramsExpected = %v, params %v", paramsExpected, params) } + queryExpected = "INSERT INTO users (firstname, lastname) VALUES ('Mesut', 'GENEZ')" + query = gb.Table("users").Insert(args).Sql() + if !reflect.DeepEqual(queryExpected, query) { + t.Errorf("queryExpected = %v, query %v", queryExpected, query) + } } func TestSql_Update(t *testing.T) { // sometimes it may not pass the test because the map is unordered + args := map[string]any{"firstname": "Mesut", "lastname": "GENEZ"} queryExpected = "UPDATE users SET firstname = $1, lastname = $2" paramsExpected := []any{"Mesut", "GENEZ"} - query, params = s.Table("users").Update(map[string]any{"firstname": "Mesut", "lastname": "GENEZ"}).ToSql() + query, params = gb.Table("users").Update(args).Prepare() if !reflect.DeepEqual(queryExpected, query) { t.Errorf("queryExpected = %v, query %v", queryExpected, query) } if !reflect.DeepEqual(paramsExpected, params) { t.Errorf("paramsExpected = %v, params %v", paramsExpected, params) } + queryExpected = "UPDATE users SET firstname = 'Mesut', lastname = 'GENEZ'" + query = gb.Table("users").Update(args).Sql() + if !reflect.DeepEqual(queryExpected, query) { + t.Errorf("queryExpected = %v, query %v", queryExpected, query) + } } func TestSql_Delete(t *testing.T) { queryExpected = "DELETE FROM users" paramsExpected := []any{} - query, params = s.Table("users").Delete().ToSql() + query, params = gb.Table("users").Delete().Prepare() if !reflect.DeepEqual(queryExpected, query) { t.Errorf("queryExpected = %v, query %v", queryExpected, query) } if !reflect.DeepEqual(paramsExpected, params) { t.Errorf("paramsExpected = %v, params %v", paramsExpected, params) } + queryExpected = "DELETE FROM users" + query = gb.Table("users").Delete().Sql() + if !reflect.DeepEqual(queryExpected, query) { + t.Errorf("queryExpected = %v, query %v", queryExpected, query) + } } func TestSql_Where(t *testing.T) { queryExpected = "WHERE firstname = $1" paramsExpected := []any{"Mesut"} - query, params = s.Where("firstname", "=", "Mesut").ToSql() + query, params = gb.Where("firstname", "=", "Mesut").Prepare() if !reflect.DeepEqual(queryExpected, query) { t.Errorf("queryExpected = %v, query %v", queryExpected, query) } if !reflect.DeepEqual(paramsExpected, params) { t.Errorf("paramsExpected = %v, params %v", paramsExpected, params) } + queryExpected = "WHERE firstname = 'Mesut'" + query = gb.Where("firstname", "=", "Mesut").Sql() + if !reflect.DeepEqual(queryExpected, query) { + t.Errorf("queryExpected = %v, query %v", queryExpected, query) + } } func TestSql_WhereWithInt(t *testing.T) { queryExpected = "WHERE id = $1" paramsExpected := []any{55} - query, params = s.Where("id", "=", 55).ToSql() + query, params = gb.Where("id", "=", 55).Prepare() if !reflect.DeepEqual(queryExpected, query) { t.Errorf("queryExpected = %v, query %v", queryExpected, query) } if !reflect.DeepEqual(paramsExpected, params) { t.Errorf("paramsExpected = %v, params %v", paramsExpected, params) } + queryExpected = "WHERE id = 55" + query = gb.Where("id", "=", 55).Sql() + if !reflect.DeepEqual(queryExpected, query) { + t.Errorf("queryExpected = %v, query %v", queryExpected, query) + } } func TestSql_WhereWithFloat(t *testing.T) { queryExpected = "WHERE amount = $1" paramsExpected := []any{55.5} - query, params = s.Where("amount", "=", 55.5).ToSql() + query, params = gb.Where("amount", "=", 55.5).Prepare() if !reflect.DeepEqual(queryExpected, query) { t.Errorf("queryExpected = %v, query %v", queryExpected, query) } if !reflect.DeepEqual(paramsExpected, params) { t.Errorf("paramsExpected = %v, params %v", paramsExpected, params) } + queryExpected = "WHERE amount = 55.5" + query = gb.Where("amount", "=", 55.5).Sql() + if !reflect.DeepEqual(queryExpected, query) { + t.Errorf("queryExpected = %v, query %v", queryExpected, query) + } } func TestSql_Where_With_And(t *testing.T) { queryExpected = "WHERE firstname = $1 AND lastname = $2" paramsExpected := []any{"Mesut", "GENEZ"} - query, params = s.Where("firstname", "=", "Mesut").Where("lastname", "=", "GENEZ").ToSql() + query, params = gb.Where("firstname", "=", "Mesut").Where("lastname", "=", "GENEZ").Prepare() if !reflect.DeepEqual(queryExpected, query) { t.Errorf("queryExpected = %v, query %v", queryExpected, query) } if !reflect.DeepEqual(paramsExpected, params) { t.Errorf("paramsExpected = %v, params %v", paramsExpected, params) } + queryExpected = "WHERE firstname = 'Mesut' AND lastname = 'GENEZ'" + query = gb.Where("firstname", "=", "Mesut").Where("lastname", "=", "GENEZ").Sql() + if !reflect.DeepEqual(queryExpected, query) { + t.Errorf("queryExpected = %v, query %v", queryExpected, query) + } } func TestSql_OrWhere(t *testing.T) { queryExpected = "WHERE firstname = $1" paramsExpected := []any{"Mesut"} - query, params = s.OrWhere("firstname", "=", "Mesut").ToSql() + query, params = gb.OrWhere("firstname", "=", "Mesut").Prepare() if !reflect.DeepEqual(queryExpected, query) { t.Errorf("queryExpected = %v, query %v", queryExpected, query) } if !reflect.DeepEqual(paramsExpected, params) { t.Errorf("paramsExpected = %v, params %v", paramsExpected, params) } + queryExpected = "WHERE firstname = 'Mesut'" + query = gb.OrWhere("firstname", "=", "Mesut").Sql() + if !reflect.DeepEqual(queryExpected, query) { + t.Errorf("queryExpected = %v, query %v", queryExpected, query) + } } func TestSql_OrWhere_With_And(t *testing.T) { queryExpected = "WHERE firstname = $1 OR lastname = $2" paramsExpected := []any{"Mesut", "GENEZ"} - query, params = s.OrWhere("firstname", "=", "Mesut").OrWhere("lastname", "=", "GENEZ").ToSql() + query, params = gb.OrWhere("firstname", "=", "Mesut").OrWhere("lastname", "=", "GENEZ").Prepare() if !reflect.DeepEqual(queryExpected, query) { t.Errorf("queryExpected = %v, query %v", queryExpected, query) } if !reflect.DeepEqual(paramsExpected, params) { t.Errorf("paramsExpected = %v, params %v", paramsExpected, params) } + queryExpected = "WHERE firstname = 'Mesut' OR lastname = 'GENEZ'" + query = gb.OrWhere("firstname", "=", "Mesut").OrWhere("lastname", "=", "GENEZ").Sql() + if !reflect.DeepEqual(queryExpected, query) { + t.Errorf("queryExpected = %v, query %v", queryExpected, query) + } } func TestSql_In(t *testing.T) { queryExpected = "WHERE firstname IN ($1, $2)" paramsExpected := []any{"Mesut", 33} - query, params = s.In("firstname", "Mesut", 33).ToSql() + query, params = gb.In("firstname", "Mesut", 33).Prepare() if !reflect.DeepEqual(queryExpected, query) { t.Errorf("queryExpected = %v, query %v", queryExpected, query) } if !reflect.DeepEqual(paramsExpected, params) { t.Errorf("paramsExpected = %v, params %v", paramsExpected, params) } + queryExpected = "WHERE firstname IN ('Mesut', 33)" + query = gb.In("firstname", "Mesut", 33).Sql() + if !reflect.DeepEqual(queryExpected, query) { + t.Errorf("queryExpected = %v, query %v", queryExpected, query) + } } func TestSql_InWithInt(t *testing.T) { queryExpected = "WHERE id IN ($1, $2, $3)" paramsExpected := []any{12, 34, 55} - query, params = s.In("id", 12, 34, 55).ToSql() + query, params = gb.In("id", 12, 34, 55).Prepare() if !reflect.DeepEqual(queryExpected, query) { t.Errorf("queryExpected = %v, query %v", queryExpected, query) } if !reflect.DeepEqual(paramsExpected, params) { t.Errorf("paramsExpected = %v, params %v", paramsExpected, params) } + queryExpected = "WHERE id IN (12, 34, 55)" + query = gb.In("id", 12, 34, 55).Sql() + if !reflect.DeepEqual(queryExpected, query) { + t.Errorf("queryExpected = %v, query %v", queryExpected, query) + } } func TestSql_InAnd(t *testing.T) { queryExpected = "WHERE firstname IN ($1) AND lastname IN ($2)" paramsExpected := []any{"Mesut", "GENEZ"} - query, params = s.In("firstname", "Mesut").In("lastname", "GENEZ").ToSql() + query, params = gb.In("firstname", "Mesut").In("lastname", "GENEZ").Prepare() if !reflect.DeepEqual(queryExpected, query) { t.Errorf("queryExpected = %v, query %v", queryExpected, query) } if !reflect.DeepEqual(paramsExpected, params) { t.Errorf("paramsExpected = %v, params %v", paramsExpected, params) } + queryExpected = "WHERE firstname IN ('Mesut') AND lastname IN ('GENEZ')" + query = gb.In("firstname", "Mesut").In("lastname", "GENEZ").Sql() + if !reflect.DeepEqual(queryExpected, query) { + t.Errorf("queryExpected = %v, query %v", queryExpected, query) + } } func TestSql_OrIn(t *testing.T) { queryExpected = "WHERE firstname IN ($1)" paramsExpected := []any{"Mesut"} - query, params = s.OrIn("firstname", "Mesut").ToSql() + query, params = gb.OrIn("firstname", "Mesut").Prepare() if !reflect.DeepEqual(queryExpected, query) { t.Errorf("queryExpected = %v, query %v", queryExpected, query) } if !reflect.DeepEqual(paramsExpected, params) { t.Errorf("paramsExpected = %v, params %v", paramsExpected, params) } + queryExpected = "WHERE firstname IN ('Mesut')" + query = gb.OrIn("firstname", "Mesut").Sql() + if !reflect.DeepEqual(queryExpected, query) { + t.Errorf("queryExpected = %v, query %v", queryExpected, query) + } } func TestSql_OrInAnd(t *testing.T) { queryExpected = "WHERE firstname IN ($1, $2) OR lastname IN ($3)" paramsExpected := []any{"Mesut", "GENEZ", "GENEZ"} - query, params = s.OrIn("firstname", "Mesut", "GENEZ").OrIn("lastname", "GENEZ").ToSql() + query, params = gb.OrIn("firstname", "Mesut", "GENEZ").OrIn("lastname", "GENEZ").Prepare() if !reflect.DeepEqual(queryExpected, query) { t.Errorf("queryExpected = %v, query %v", queryExpected, query) } if !reflect.DeepEqual(paramsExpected, params) { t.Errorf("paramsExpected = %v, params %v", paramsExpected, params) } + queryExpected = "WHERE firstname IN ('Mesut', 'GENEZ') OR lastname IN ('GENEZ')" + query = gb.OrIn("firstname", "Mesut", "GENEZ").OrIn("lastname", "GENEZ").Sql() + if !reflect.DeepEqual(queryExpected, query) { + t.Errorf("queryExpected = %v, query %v", queryExpected, query) + } } func TestSql_Between(t *testing.T) { queryExpected = "WHERE firstname BETWEEN $1 AND $2" paramsExpected := []any{"Mesut", "GENEZ"} - query, params = s.Between("firstname", "Mesut", "GENEZ").ToSql() + query, params = gb.Between("firstname", "Mesut", "GENEZ").Prepare() if !reflect.DeepEqual(queryExpected, query) { t.Errorf("queryExpected = %v, query %v", queryExpected, query) } if !reflect.DeepEqual(paramsExpected, params) { t.Errorf("paramsExpected = %v, params %v", paramsExpected, params) } + queryExpected = "WHERE firstname BETWEEN 'Mesut' AND 'GENEZ'" + query = gb.Between("firstname", "Mesut", "GENEZ").Sql() + if !reflect.DeepEqual(queryExpected, query) { + t.Errorf("queryExpected = %v, query %v", queryExpected, query) + } } func TestSql_BetweenWithInt(t *testing.T) { queryExpected = "WHERE id BETWEEN $1 AND $2" paramsExpected := []any{12, 55} - query, params = s.Between("id", 12, 55).ToSql() + query, params = gb.Between("id", 12, 55).Prepare() if !reflect.DeepEqual(queryExpected, query) { t.Errorf("queryExpected = %v, query %v", queryExpected, query) } if !reflect.DeepEqual(paramsExpected, params) { t.Errorf("paramsExpected = %v, params %v", paramsExpected, params) } + queryExpected = "WHERE id BETWEEN 12 AND 55" + query = gb.Between("id", 12, 55).Sql() + if !reflect.DeepEqual(queryExpected, query) { + t.Errorf("queryExpected = %v, query %v", queryExpected, query) + } } func TestSql_BetweenWithWhere(t *testing.T) { queryExpected = "WHERE firstname BETWEEN $1 AND $2 AND lastname BETWEEN $3 AND $4" paramsExpected := []any{"Mesut", "GENEZ", "Mesut", "GENEZ"} - query, params = s.Between("firstname", "Mesut", "GENEZ").Between("lastname", "Mesut", "GENEZ").ToSql() + query, params = gb.Between("firstname", "Mesut", "GENEZ").Between("lastname", "Mesut", "GENEZ").Prepare() if !reflect.DeepEqual(queryExpected, query) { t.Errorf("queryExpected = %v, query %v", queryExpected, query) } if !reflect.DeepEqual(paramsExpected, params) { t.Errorf("paramsExpected = %v, params %v", paramsExpected, params) } + queryExpected = "WHERE firstname BETWEEN 'Mesut' AND 'GENEZ' AND lastname BETWEEN 'Mesut' AND 'GENEZ'" + query = gb.Between("firstname", "Mesut", "GENEZ").Between("lastname", "Mesut", "GENEZ").Sql() + if !reflect.DeepEqual(queryExpected, query) { + t.Errorf("queryExpected = %v, query %v", queryExpected, query) + } } func TestSql_OrBetween(t *testing.T) { queryExpected = "WHERE firstname BETWEEN $1 AND $2" paramsExpected := []any{"Mesut", "GENEZ"} - query, params = s.OrBetween("firstname", "Mesut", "GENEZ").ToSql() + query, params = gb.OrBetween("firstname", "Mesut", "GENEZ").Prepare() if !reflect.DeepEqual(queryExpected, query) { t.Errorf("queryExpected = %v, query %v", queryExpected, query) } if !reflect.DeepEqual(paramsExpected, params) { t.Errorf("paramsExpected = %v, params %v", paramsExpected, params) } + queryExpected = "WHERE firstname BETWEEN 'Mesut' AND 'GENEZ'" + query = gb.OrBetween("firstname", "Mesut", "GENEZ").Sql() + if !reflect.DeepEqual(queryExpected, query) { + t.Errorf("queryExpected = %v, query %v", queryExpected, query) + } } func TestSql_OrBetweenWithWhere(t *testing.T) { queryExpected = "WHERE firstname BETWEEN $1 AND $2 OR lastname BETWEEN $3 AND $4" paramsExpected := []any{"Mesut", "GENEZ", "Mesut", "GENEZ"} - query, params = s.OrBetween("firstname", "Mesut", "GENEZ").OrBetween("lastname", "Mesut", "GENEZ").ToSql() + query, params = gb.OrBetween("firstname", "Mesut", "GENEZ").OrBetween("lastname", "Mesut", "GENEZ").Prepare() if !reflect.DeepEqual(queryExpected, query) { t.Errorf("queryExpected = %v, query %v", queryExpected, query) } if !reflect.DeepEqual(paramsExpected, params) { t.Errorf("paramsExpected = %v, params %v", paramsExpected, params) } + queryExpected = "WHERE firstname BETWEEN 'Mesut' AND 'GENEZ' OR lastname BETWEEN 'Mesut' AND 'GENEZ'" + query = gb.OrBetween("firstname", "Mesut", "GENEZ").OrBetween("lastname", "Mesut", "GENEZ").Sql() + if !reflect.DeepEqual(queryExpected, query) { + t.Errorf("queryExpected = %v, query %v", queryExpected, query) + } } func TestSql_IsNull(t *testing.T) { queryExpected = "SELECT * FROM users WHERE age = $1 AND name IS NULL" paramsExpected := []any{30} - query, params = s.Table("users").Select().Where("age", "=", 30).IsNull("name").ToSql() + query, params = gb.Table("users").Select().Where("age", "=", 30).IsNull("name").Prepare() if !reflect.DeepEqual(queryExpected, query) { t.Errorf("queryExpected = %v, query %v", queryExpected, query) } if !reflect.DeepEqual(paramsExpected, params) { t.Errorf("paramsExpected = %v, params %v", paramsExpected, params) } + queryExpected = "SELECT * FROM users WHERE age = 30 AND name IS NULL" + query = gb.Table("users").Select().Where("age", "=", 30).IsNull("name").Sql() + if !reflect.DeepEqual(queryExpected, query) { + t.Errorf("queryExpected = %v, query %v", queryExpected, query) + } } func TestSql_IsNotNull(t *testing.T) { queryExpected = "SELECT * FROM users WHERE age = $1 AND name IS NOT NULL" paramsExpected := []any{30} - query, params = s.Table("users").Select().Where("age", "=", 30).IsNotNull("name").ToSql() + query, params = gb.Table("users").Select().Where("age", "=", 30).IsNotNull("name").Prepare() if !reflect.DeepEqual(queryExpected, query) { t.Errorf("queryExpected = %v, query %v", queryExpected, query) } if !reflect.DeepEqual(paramsExpected, params) { t.Errorf("paramsExpected = %v, params %v", paramsExpected, params) } + queryExpected = "SELECT * FROM users WHERE age = 30 AND name IS NOT NULL" + query = gb.Table("users").Select().Where("age", "=", 30).IsNotNull("name").Sql() + if !reflect.DeepEqual(queryExpected, query) { + t.Errorf("queryExpected = %v, query %v", queryExpected, query) + } } func TestSql_Having(t *testing.T) { queryExpected = "SELECT * FROM orders GROUP BY user_id HAVING COUNT(*) > 1" paramsExpected := []any{} - query, params = s.Table("orders").Select().GroupBy("user_id").Having("COUNT(*) > 1").ToSql() + query, params = gb.Table("orders").Select().GroupBy("user_id").Having("COUNT(*) > 1").Prepare() if !reflect.DeepEqual(queryExpected, query) { t.Errorf("queryExpected = %v, query %v", queryExpected, query) } if !reflect.DeepEqual(paramsExpected, params) { t.Errorf("paramsExpected = %v, params %v", paramsExpected, params) } + queryExpected = "SELECT * FROM orders GROUP BY user_id HAVING COUNT(*) > 1" + query = gb.Table("orders").Select().GroupBy("user_id").Having("COUNT(*) > 1").Sql() + if !reflect.DeepEqual(queryExpected, query) { + t.Errorf("queryExpected = %v, query %v", queryExpected, query) + } } func TestSql_Join(t *testing.T) { queryExpected = "INNER JOIN users ON roles" paramsExpected := []any{} - query, params = s.Join("INNER", "users", "roles").ToSql() + query, params = gb.Join("INNER", "users", "roles").Prepare() if !reflect.DeepEqual(queryExpected, query) { t.Errorf("queryExpected = %v, query %v", queryExpected, query) } if !reflect.DeepEqual(paramsExpected, params) { t.Errorf("paramsExpected = %v, params %v", paramsExpected, params) } + queryExpected = "INNER JOIN users ON roles" + query = gb.Join("INNER", "users", "roles").Sql() + if !reflect.DeepEqual(queryExpected, query) { + t.Errorf("queryExpected = %v, query %v", queryExpected, query) + } } func TestSql_Limit(t *testing.T) { queryExpected = "LIMIT 1, 5" paramsExpected := []any{} - query, params = s.Limit(1, 5).ToSql() + query, params = gb.Limit(1, 5).Prepare() if !reflect.DeepEqual(queryExpected, query) { t.Errorf("queryExpected = %v, query %v", queryExpected, query) } if !reflect.DeepEqual(paramsExpected, params) { t.Errorf("paramsExpected = %v, params %v", paramsExpected, params) } + queryExpected = "LIMIT 1, 5" + query = gb.Limit(1, 5).Sql() + if !reflect.DeepEqual(queryExpected, query) { + t.Errorf("queryExpected = %v, query %v", queryExpected, query) + } } func TestSql_Group(t *testing.T) { queryExpected = "GROUP BY firstname" paramsExpected := []any{} - query, params = s.GroupBy("firstname").ToSql() + query, params = gb.GroupBy("firstname").Prepare() if !reflect.DeepEqual(queryExpected, query) { t.Errorf("queryExpected = %v, query %v", queryExpected, query) } @@ -354,7 +490,7 @@ func TestSql_Group(t *testing.T) { func TestSql_GroupMultiple(t *testing.T) { queryExpected = "GROUP BY firstname, lastname, email" paramsExpected := []any{} - query, params = s.GroupBy("firstname", "lastname", "email").ToSql() + query, params = gb.GroupBy("firstname", "lastname", "email").Prepare() if !reflect.DeepEqual(queryExpected, query) { t.Errorf("queryExpected = %v, query %v", queryExpected, query) } @@ -366,7 +502,7 @@ func TestSql_GroupMultiple(t *testing.T) { func TestSql_OrderBy(t *testing.T) { queryExpected = "ORDER BY firstname ASC" paramsExpected := []any{} - query, params = s.OrderBy("firstname").ToSql() + query, params = gb.OrderBy("firstname").Prepare() if !reflect.DeepEqual(queryExpected, query) { t.Errorf("queryExpected = %v, query %v", queryExpected, query) } @@ -378,7 +514,7 @@ func TestSql_OrderBy(t *testing.T) { func TestSql_OrderByMultiple(t *testing.T) { queryExpected = "ORDER BY firstname, lastname ASC" paramsExpected := []any{} - query, params = s.OrderBy("firstname", "lastname").ToSql() + query, params = gb.OrderBy("firstname", "lastname").Prepare() if !reflect.DeepEqual(queryExpected, query) { t.Errorf("queryExpected = %v, query %v", queryExpected, query) } @@ -390,7 +526,7 @@ func TestSql_OrderByMultiple(t *testing.T) { func TestSql_OrderByDesc(t *testing.T) { queryExpected = "ORDER BY firstname DESC" paramsExpected := []any{} - query, params = s.OrderByDesc("firstname").ToSql() + query, params = gb.OrderByDesc("firstname").Prepare() if !reflect.DeepEqual(queryExpected, query) { t.Errorf("queryExpected = %v, query %v", queryExpected, query) } @@ -402,7 +538,7 @@ func TestSql_OrderByDesc(t *testing.T) { func TestSql_OrderByDescMultiple(t *testing.T) { queryExpected = "ORDER BY firstname, lastname DESC" paramsExpected := []any{} - query, params = s.OrderByDesc("firstname", "lastname").ToSql() + query, params = gb.OrderByDesc("firstname", "lastname").Prepare() if !reflect.DeepEqual(queryExpected, query) { t.Errorf("queryExpected = %v, query %v", queryExpected, query) } @@ -414,7 +550,7 @@ func TestSql_OrderByDescMultiple(t *testing.T) { func TestSql_Union(t *testing.T) { queryExpected = "UNION select * from companies" paramsExpected := []any{} - query, params = s.Union("select * from companies").ToSql() + query, params = gb.Union("select * from companies").Prepare() if !reflect.DeepEqual(queryExpected, query) { t.Errorf("queryExpected = %v, query %v", queryExpected, query) } @@ -428,8 +564,8 @@ func TestSql_SubQuery(t *testing.T) { mainBuilder := NewGoBuilder(Postgres) subBuilder := NewGoBuilder(Postgres) - query, params = subBuilder.Table("users").Select("id").Where("age", ">", 30).ToSql() - query, params = mainBuilder.Table("orders").Select("order_id", "user_id").In("user_id", query).ToSql() + query, params = subBuilder.Table("users").Select("id").Where("age", ">", 30).Prepare() + query, params = mainBuilder.Table("orders").Select("order_id", "user_id").In("user_id", query).Prepare() queryExpected = "SELECT order_id, user_id FROM orders WHERE user_id IN ($1)" diff --git a/example/main.go b/example/main.go index 5818e4e..104cbee 100644 --- a/example/main.go +++ b/example/main.go @@ -14,67 +14,89 @@ var ( func main() { - query, params = gb.Table("users").Select().Where("id", "=", "1").ToSql() - fmt.Printf("All Columns: \n%s\n%v\n\n", query, params) + query, params = gb.Table("users").Select().Where("id", "=", "1").Prepare() + fmt.Printf("All Columns Prepare: \n%s\t%v\n", query, params) + query = gb.Table("users").Select().Where("id", "=", "1").Sql() + fmt.Printf("All Columns Sql: \n%s\n\n", query) - query, params = gb.Table("users").Select("firstname", "lastname", "created_at"). - Where("id", "=", 1). - ToSql() - fmt.Printf("Filter Columns: \n%s\n%v\n\n", query, params) + query, params = gb.Table("users").Select("firstname", "lastname", "created_at").Where("id", "=", 1).Prepare() + fmt.Printf("Filter Columns Prepare: \n%s\t%v\n", query, params) + query = gb.Table("users").Select("firstname", "lastname", "created_at").Where("id", "=", 1).Sql() + fmt.Printf("Filter Columns Sql: \n%s\n\n", query) - query, params = gb.Table("users").Select(). - Where("id", "=", "1"). - OrWhere("email", "=", "loremipsum@lrmpsm.com"). - ToSql() - fmt.Printf("Where Or Where: \n%s\n%v\n\n", query, params) + query, params = gb.Table("users").Select().Where("id", "=", "1").OrWhere("email", "=", "loremipsum@lrmpsm.com").Prepare() + fmt.Printf("Where Or Where Prepare: \n%s\t%v\n\n", query, params) + query = gb.Table("users").Select().Where("id", "=", "1").OrWhere("email", "=", "loremipsum@lrmpsm.com").Sql() + fmt.Printf("Where Or Where Sql: \n%s\n\n", query) query, params = gb.Table("users as u").Select("u.firstname", "u.lastname", "a.address"). Join("INNER", "address as a", "a.user_id=u.id"). - Where("u.email", "=", "loremipsum@lrmpsm.com"). - ToSql() - fmt.Printf("Join: \n%s\n%v\n\n", query, params) + Where("u.email", "=", "loremipsum@lrmpsm.com").Prepare() + fmt.Printf("Join Prepare: \n%s\t%v\n", query, params) + query = gb.Table("users as u").Select("u.firstname", "u.lastname", "a.address"). + Join("INNER", "address as a", "a.user_id=u.id"). + Where("u.email", "=", "loremipsum@lrmpsm.com").Sql() + fmt.Printf("Join Sql: \n%s\n\n", query) query, params = gb.Table("users").Select(). Where("id", "=", "1"). - Between("created_at", "2021-01-01", "2021-03-16"). - ToSql() - fmt.Printf("Between: \n%s\n%v\n\n", query, params) + Between("created_at", "2021-01-01", "2021-03-16").Prepare() + fmt.Printf("Between Prepare: \n%s\t%v\n", query, params) + query = gb.Table("users").Select(). + Where("id", "=", "1"). + Between("created_at", "2021-01-01", "2021-03-16").Sql() + fmt.Printf("Between Sql: \n%s\n\n", query) query, params = gb.Table("users").Select(). Where("id", "=", "1"). Between("created_at", "2021-01-01", "2021-03-16"). - Limit(1, 5). - ToSql() - fmt.Printf("Limit: \n%s\n%v\n\n", query, params) + Limit(1, 5).Prepare() + fmt.Printf("Limit Prepare: \n%s\t%v\n", query, params) + query = gb.Table("users").Select(). + Where("id", "=", "1"). + Between("created_at", "2021-01-01", "2021-03-16"). + Limit(1, 5).Sql() + fmt.Printf("Limit Sql: \n%s\n\n", query) query, params = gb.Table("users").Select(). Where("id", "=", "1"). Between("created_at", "2021-01-01", "2021-03-16"). - GroupBy("lastname"). - ToSql() - fmt.Printf("Group By: \n%s\n%v\n\n", query, params) + GroupBy("lastname").Prepare() + fmt.Printf("Group By Prepare: \n%s\t%v\n", query, params) + query = gb.Table("users").Select(). + Where("id", "=", "1"). + Between("created_at", "2021-01-01", "2021-03-16"). + GroupBy("lastname").Sql() + fmt.Printf("Group By Sql: \n%s\n\n", query) query, params = gb.Table("users").Select(). Where("id", "=", "1"). Between("created_at", "2021-01-01", "2021-03-16"). GroupBy("lastname"). - OrderBy("id"). - ToSql() - fmt.Printf("Order By: \n%s\n%v\n\n", query, params) + OrderBy("id").Prepare() + fmt.Printf("Order By Prepare: \n%s\t%v\n", query, params) + query = gb.Table("users").Select(). + Where("id", "=", "1"). + Between("created_at", "2021-01-01", "2021-03-16"). + GroupBy("lastname"). + OrderBy("id").Sql() + fmt.Printf("Order By Sql: \n%s\n\n", query) - query, params = gb.Table("users").Delete().Where("email", "=", "loremipsum@lrmpsm.com").ToSql() - fmt.Printf("Delete: \n%s\n%v\n\n", query, params) + query, params = gb.Table("users").Delete().Where("email", "=", "loremipsum@lrmpsm.com").Prepare() + fmt.Printf("Delete Prepare: \n%s\t%v\n", query, params) + query = gb.Table("users").Delete().Where("email", "=", "loremipsum@lrmpsm.com").Sql() + fmt.Printf("Delete Sql: \n%s\n\n", query) - query, params = gb.Table("users").Select().Where("lastname", "=", "lorem").ToSql() - query, params = gb.Table("users").Select().Where("lastname", "=", "ipsum").Union(query).ToSql() + query, params = gb.Table("users").Select().Where("lastname", "=", "lorem").Prepare() + query, params = gb.Table("users").Select().Where("lastname", "=", "ipsum").Union(query).Prepare() fmt.Printf("Union: \n%s\n%v\n\n", query, params) // example subquery mainBuilder := gobuilder.NewGoBuilder(gobuilder.Postgres) subBuilder := gobuilder.NewGoBuilder(gobuilder.Postgres) - query, params = subBuilder.Table("users").Select("id").Where("age", ">", 30).ToSql() - query, params = mainBuilder.Table("orders").Select("order_id", "user_id").Where("user_id", "IN", query).ToSql() + query, params = subBuilder.Table("users").Select("id").Where("age", ">", 30).Prepare() + query, params = mainBuilder.Table("orders").Select("order_id", "user_id").Where("user_id", "IN", query).Prepare() fmt.Printf("SubQuery: \n%s\n%v\n\n", query, params) }