Skip to content

Commit

Permalink
distinct, isnull and having added
Browse files Browse the repository at this point in the history
  • Loading branch information
Mesut GENEZ committed Jun 5, 2024
1 parent 7a69eb3 commit 49d6a5a
Show file tree
Hide file tree
Showing 6 changed files with 603 additions and 386 deletions.
26 changes: 13 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ var gb GoBuilder

```go
// all columns
gb.Select("users").Where("id","=","1").Sql()
gb.Select("users").Where("id","=","1").ToSql()

// filter columns
gb.Select("users", "firstname", "lastname", "create_date").
Where("id", "=", "1").
Sql()
ToSql()
```
```sql
Result: SELECT * FROM users WHERE id = '1'
Expand All @@ -28,7 +28,7 @@ Result: SELECT firstname,lastname,create_date FROM users WHERE id = '1'
gb.Select("users").
Where("id", "=", "1").
OrWhere("email", "=", "[email protected]").
Sql()
ToSql()
```
```sql
Result: SELECT * FROM users WHERE id='1' OR email='[email protected]'
Expand All @@ -38,7 +38,7 @@ Result: SELECT * FROM users WHERE id='1' OR email='[email protected]'
gb.Select("users as u", "u.firstname", "u.lastname", "a.address").
Join("INNER", "address as a", "a.user_id=u.id").
Where("u.email", "=", "[email protected]").
Sql()
ToSql()
```
```sql
Result: SELECT u.firstname,u.lastname,a.address FROM users as u INNER JOIN address as a ON a.user_id=u.id WHERE u.email='[email protected]'
Expand All @@ -48,7 +48,7 @@ Result: SELECT u.firstname,u.lastname,a.address FROM users as u INNER JOIN addre
gb.Select("users").
Where("id", "=", "1").
Between("create_date", "2021-01-01", "2021-03-16").
Sql()
ToSql()
```
```sql
Result: SELECT * FROM users WHERE id='1' AND create_date BETWEEN '2021-01-01' AND '2021-03-16'
Expand All @@ -59,7 +59,7 @@ gb.Select("users").
Where("id", "=", "1").
Between("create_date", "2021-01-01", "2021-03-16").
Limit(1, 5).
Sql()
ToSql()
```
```sql
Result: SELECT * FROM users WHERE id='1' AND create_date BETWEEN '2021-01-01' AND '2021-03-16' LIMIT 1,5
Expand All @@ -70,7 +70,7 @@ gb.Select("users").
Where("id", "=", "1").
Between("create_date", "2021-01-01", "2021-03-16").
GroupBy("lastname").
Sql()
ToSql()
```
```sql
Result: SELECT * FROM users WHERE id='1' AND create_date BETWEEN '2021-01-01' AND '2021-03-16' GROUP BY lastname
Expand All @@ -82,15 +82,15 @@ gb.Select("users").
Between("create_date", "2021-01-01", "2021-03-16").
GroupBy("lastname").
OrderBy("id", "DESC").
Sql()
ToSql()
```
```sql
Result: SELECT * FROM users WHERE id='1' AND create_date BETWEEN '2021-01-01' AND '2021-03-16' GROUP BY lastname ORDER BY id DESC
```
### union
```go
s1 := gb.Select("users").Where("lastname", "=", "lorem").Sql()
s2 := gb.Select("users").Where("lastname", "=", "ipsum").Union(s1).Sql()
s1 := gb.Select("users").Where("lastname", "=", "lorem").ToSql()
s2 := gb.Select("users").Where("lastname", "=", "ipsum").Union(s1).ToSql()
```
```sql
Result: SELECT * FROM users WHERE lastname='ipsum' UNION SELECT * FROM users WHERE lastname='lorem'
Expand All @@ -102,7 +102,7 @@ args := map[string]string{
"firstname": "Lorem",
"lastname": "IPSUM",
}
gb.Insert("users", args).Sql()
gb.Insert("users", args).ToSql()
```
```sql
Result : INSERT INTO users (lastname,firstname) VALUES ('Lorem','IPSUM')
Expand All @@ -114,15 +114,15 @@ args := map[string]string{
"firstname": "Lorem",
"lastname": "IPSUM",
}
gb.Update("users", args).Where("email", "=", "[email protected]").Sql()
gb.Update("users", args).Where("email", "=", "[email protected]").ToSql()
```
```sql
Result: UPDATE users SET firstname='Lorem', lastname='IPSUM' WHERE email='[email protected]'
```

## Delete
```go
gb.Delete("users").Where("email", "=", "[email protected]").Sql()
gb.Delete("users").Where("email", "=", "[email protected]").ToSql()
```
```sql
Result: DELETE FROM users WHERE email='[email protected]'
Expand Down
231 changes: 231 additions & 0 deletions builder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
package gobuilder

import (
"fmt"
"strings"

"golang.org/x/exp/maps"
)

type GoBuilder struct {
sql string
}

func (gb *GoBuilder) Select(table string, columns ...string) *GoBuilder {
if len(columns) == 0 {
columns = append(columns, "*")
}
gb.sql = fmt.Sprintf("SELECT %v FROM %v", strings.Join(columns, ", "), table)
return gb
}

func (gb *GoBuilder) SelectDistinct(table string, columns ...string) *GoBuilder {
if len(columns) == 0 {
columns = append(columns, "*")
}
gb.sql = fmt.Sprintf("SELECT DISTINCT %v FROM %v", strings.Join(columns, ", "), table)
return gb
}

func (gb *GoBuilder) Insert(table string, args map[string]any) *GoBuilder {
if len(args) != 0 {
keys := maps.Keys(args)
var values []string
for _, v := range maps.Values(args) {
values = append(values, fmt.Sprintf("'%v'", v))
}
gb.sql = fmt.Sprintf("INSERT INTO %v (%v) VALUES (%v)", table, strings.Join(keys, ", "), strings.Join(values, ", "))
}
return gb
}

func (gb *GoBuilder) Update(table string, args map[string]any) *GoBuilder {
if len(args) != 0 {
var setClauses []string
for key, value := range args {
setClauses = append(setClauses, fmt.Sprintf("%v = '%v'", key, value))
}
gb.sql = fmt.Sprintf("UPDATE %v SET %v", table, strings.Join(setClauses, ", "))
}
return gb
}

func (gb *GoBuilder) Delete(table string) *GoBuilder {
gb.sql = fmt.Sprintf("DELETE FROM %v", table)
return gb
}

func (gb *GoBuilder) Where(key, opt string, val any) *GoBuilder {
return gb.where("AND", key, opt, val)
}

func (gb *GoBuilder) OrWhere(key, opt string, val any) *GoBuilder {
return gb.where("OR", key, opt, val)
}

func (gb *GoBuilder) where(OP, key, opt string, val any) *GoBuilder {
var clause string

switch v := val.(type) {
case int, int64, float32, float64:
clause = fmt.Sprintf("%v %v %v", key, opt, v)
case *GoBuilder:
clause = fmt.Sprintf("%v %v (%v)", key, opt, v.ToSql())
default:
clause = fmt.Sprintf("%v %v '%v'", key, opt, v)
}

if strings.Contains(gb.sql, "WHERE") {
gb.sql = fmt.Sprintf("%v %v %v", gb.sql, OP, clause)
} else {
gb.sql = fmt.Sprintf("%v WHERE %v", gb.sql, clause)
}
return gb
}

func (gb *GoBuilder) In(column string, args ...any) *GoBuilder {
return gb.in("AND", column, args...)
}

func (gb *GoBuilder) OrIn(column string, args ...any) *GoBuilder {
return gb.in("OR", column, args...)
}

func (gb *GoBuilder) in(OP, column string, args ...any) *GoBuilder {
if len(args) > 0 {
var values []string
for _, arg := range args {
switch v := arg.(type) {
case int, int64, float32, float64:
values = append(values, fmt.Sprintf("%v", v))
default:
values = append(values, fmt.Sprintf("'%v'", v))
}
}
clause := fmt.Sprintf("%v IN (%v)", column, strings.Join(values, ", "))
if strings.Contains(gb.sql, "WHERE") {
gb.sql = fmt.Sprintf("%v %v %v", gb.sql, OP, clause)
} else {
gb.sql = fmt.Sprintf("%v WHERE %v", gb.sql, clause)
}
}
return gb
}

func (gb *GoBuilder) Between(column string, args ...any) *GoBuilder {
return gb.between("AND", column, args...)
}

func (gb *GoBuilder) OrBetween(column string, args ...any) *GoBuilder {
return gb.between("OR", column, args...)
}

func (gb *GoBuilder) between(OP, column string, args ...any) *GoBuilder {
if len(args) == 2 {
var clause string
switch args[0].(type) {
case int, int64, float32, float64:
clause = fmt.Sprintf("%v BETWEEN %v AND %v", column, args[0], args[1])
default:
clause = fmt.Sprintf("%v BETWEEN '%v' AND '%v'", column, args[0], args[1])
}
if strings.Contains(gb.sql, "WHERE") {
gb.sql = fmt.Sprintf("%v %v %v", gb.sql, OP, clause)
} else {
gb.sql = fmt.Sprintf("%v WHERE %v", gb.sql, clause)
}
}
return gb
}

func (gb *GoBuilder) IsNull(column string) *GoBuilder {
clause := fmt.Sprintf("%v IS NULL", column)
if strings.Contains(gb.sql, "WHERE") {
gb.sql = fmt.Sprintf("%v AND %v", gb.sql, clause)
} else {
gb.sql = fmt.Sprintf("%v WHERE %v", gb.sql, clause)
}
return gb
}

func (gb *GoBuilder) OrIsNull(column string) *GoBuilder {
clause := fmt.Sprintf("%v IS NULL", column)
if strings.Contains(gb.sql, "WHERE") {
gb.sql = fmt.Sprintf("%v OR %v", gb.sql, clause)
} else {
gb.sql = fmt.Sprintf("%v WHERE %v", gb.sql, clause)
}
return gb
}

func (gb *GoBuilder) IsNotNull(column string) *GoBuilder {
clause := fmt.Sprintf("%v IS NOT NULL", column)
if strings.Contains(gb.sql, "WHERE") {
gb.sql = fmt.Sprintf("%v AND %v", gb.sql, clause)
} else {
gb.sql = fmt.Sprintf("%v WHERE %v", gb.sql, clause)
}
return gb
}

func (gb *GoBuilder) OrIsNotNull(column string) *GoBuilder {
clause := fmt.Sprintf("%v IS NOT NULL", column)
if strings.Contains(gb.sql, "WHERE") {
gb.sql = fmt.Sprintf("%v OR %v", gb.sql, clause)
} else {
gb.sql = fmt.Sprintf("%v WHERE %v", gb.sql, clause)
}
return gb
}

func (gb *GoBuilder) Having(condition string) *GoBuilder {
if strings.Contains(gb.sql, "HAVING") {
gb.sql = fmt.Sprintf("%v AND %v", gb.sql, condition)
} else {
gb.sql = fmt.Sprintf("%v HAVING %v", gb.sql, condition)
}
return gb
}

func (gb *GoBuilder) OrHaving(condition string) *GoBuilder {
if strings.Contains(gb.sql, "HAVING") {
gb.sql = fmt.Sprintf("%v OR %v", gb.sql, condition)
} else {
gb.sql = fmt.Sprintf("%v HAVING %v", gb.sql, condition)
}
return gb
}

func (gb *GoBuilder) Join(joinType, table, onCondition string) *GoBuilder {
gb.sql = fmt.Sprintf("%v %v JOIN %v ON %v", gb.sql, joinType, table, onCondition)
return gb
}

func (gb *GoBuilder) Limit(start, limit int) *GoBuilder {
gb.sql = fmt.Sprintf("%v LIMIT %v, %v", gb.sql, start, limit)
return gb
}

func (gb *GoBuilder) GroupBy(columns ...string) *GoBuilder {
gb.sql = fmt.Sprintf("%v GROUP BY %v", gb.sql, strings.Join(columns, ", "))
return gb
}

func (gb *GoBuilder) OrderBy(columns ...string) *GoBuilder {
gb.sql = fmt.Sprintf("%v ORDER BY %v ASC", gb.sql, strings.Join(columns, ", "))
return gb
}

func (gb *GoBuilder) OrderByDesc(columns ...string) *GoBuilder {
gb.sql = fmt.Sprintf("%v ORDER BY %v DESC", gb.sql, strings.Join(columns, ", "))
return gb
}

func (gb *GoBuilder) Union(sql string) *GoBuilder {
gb.sql = fmt.Sprintf("%v UNION %v", gb.sql, sql)
return gb
}

func (gb *GoBuilder) ToSql() string {
return gb.sql
}
Loading

0 comments on commit 49d6a5a

Please sign in to comment.