Skip to content

Commit ec51b45

Browse files
committed
add where and or
1 parent 50e7934 commit ec51b45

File tree

8 files changed

+203
-31
lines changed

8 files changed

+203
-31
lines changed

sqlx/and.go

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,55 @@
11
package sqlx
22

3-
import "strings"
3+
import (
4+
"fmt"
5+
"strings"
6+
)
47

5-
type AndClause []Sqlizer
8+
type AndClause struct {
9+
depth uint
10+
conditions []Sqlizer
11+
}
612

7-
func And(conditions ...Sqlizer) AndClause {
8-
return conditions
13+
func And(conditions ...Sqlizer) *AndClause {
14+
return &AndClause{0, conditions}
915
}
1016

1117
func (self AndClause) Sql() string {
12-
parts := make([]string, len(self))
18+
parts := []string{}
1319

14-
for i, cond := range self {
15-
parts[i] = cond.Sql()
20+
for _, cond := range self.conditions {
21+
parts = append(parts, cond.Sql())
22+
}
23+
24+
sql := strings.Join(parts, " AND ")
25+
26+
if self.depth > 0 && len(parts) > 1 {
27+
sql = fmt.Sprintf("(%s)", sql)
1628
}
1729

18-
sql := strings.Join(parts, "")
1930
return sql
2031
}
32+
33+
func (self AndClause) SqlPretty() string {
34+
parts := []string{}
35+
36+
for _, cond := range self.conditions {
37+
parts = append(parts, cond.Sql())
38+
}
39+
40+
sql := strings.Join(parts, "\nAND ")
41+
42+
if self.depth > 0 && len(parts) > 1 {
43+
sql = fmt.Sprintf("(%s)", sql)
44+
}
45+
46+
return sql
47+
}
48+
49+
func (self *AndClause) setDepth(depth uint) {
50+
self.depth = depth
51+
52+
for _, cond := range self.conditions {
53+
cond.setDepth(self.depth + 1)
54+
}
55+
}

sqlx/as.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ package sqlx
33
import "fmt"
44

55
type AsClause struct {
6+
depth uint
67
stmt Sqlizer
78
alias string
89
}
910

1011
func As(stmt Sqlizer, alias string) *AsClause {
11-
return &AsClause{stmt, alias}
12+
return &AsClause{0, stmt, alias}
1213
}
1314

1415
func (self AsClause) Sql() string {
@@ -18,3 +19,8 @@ func (self AsClause) Sql() string {
1819
func (self AsClause) SqlPretty() string {
1920
return fmt.Sprintf("%s as \"%s\"", self.stmt.SqlPretty(), self.alias)
2021
}
22+
23+
func (self *AsClause) setDepth(depth uint) {
24+
self.depth = depth
25+
self.stmt.setDepth(depth + 1)
26+
}

sqlx/or.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package sqlx
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
)
7+
8+
type OrClause struct {
9+
depth uint
10+
conditions []Sqlizer
11+
}
12+
13+
func Or(conditions ...Sqlizer) *OrClause {
14+
return &OrClause{0, conditions}
15+
}
16+
17+
func (self OrClause) Sql() string {
18+
parts := []string{}
19+
20+
for _, cond := range self.conditions {
21+
parts = append(parts, cond.Sql())
22+
}
23+
24+
sql := strings.Join(parts, " OR ")
25+
26+
if self.depth > 0 && len(parts) > 1 {
27+
sql = fmt.Sprintf("(%s)", sql)
28+
}
29+
30+
return sql
31+
}
32+
33+
func (self OrClause) SqlPretty() string {
34+
parts := []string{}
35+
36+
for _, cond := range self.conditions {
37+
parts = append(parts, cond.Sql())
38+
}
39+
40+
sql := strings.Join(parts, "\nOR ")
41+
42+
if self.depth > 0 && len(parts) > 1 {
43+
sql = fmt.Sprintf("(%s)", sql)
44+
}
45+
46+
return sql
47+
}
48+
49+
func (self *OrClause) setDepth(depth uint) {
50+
self.depth = depth
51+
52+
for _, cond := range self.conditions {
53+
cond.setDepth(self.depth + 1)
54+
}
55+
}

sqlx/raw.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
package sqlx
22

33
type RawStatement struct {
4-
stmt string
4+
depth uint
5+
stmt string
56
}
67

78
func Raw(stmt string) *RawStatement {
8-
return &RawStatement{stmt}
9+
return &RawStatement{0, stmt}
910
}
1011

1112
func (self RawStatement) Sql() string {
@@ -15,3 +16,7 @@ func (self RawStatement) Sql() string {
1516
func (self RawStatement) SqlPretty() string {
1617
return self.stmt
1718
}
19+
20+
func (self *RawStatement) setDepth(depth uint) {
21+
self.depth = depth
22+
}

sqlx/select.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ type SelectStatement struct {
99
depth uint
1010
columns []Sqlizer
1111
from Sqlizer
12+
where Sqlizer
1213
}
1314

1415
func Select(columns ...string) *SelectStatement {
@@ -22,6 +23,7 @@ func Select(columns ...string) *SelectStatement {
2223
depth: 0,
2324
columns: cols,
2425
from: nil,
26+
where: nil,
2527
}
2628
}
2729

@@ -46,6 +48,12 @@ func (self *SelectStatement) FromSelect(stmt *SelectStatement, alias string) *Se
4648
return self
4749
}
4850

51+
func (self *SelectStatement) Where(where Sqlizer) *SelectStatement {
52+
where.setDepth(self.depth)
53+
self.where = where
54+
return self
55+
}
56+
4957
func (self SelectStatement) Sql() string {
5058
parts := []string{"SELECT"}
5159
columns := []string{}
@@ -55,7 +63,15 @@ func (self SelectStatement) Sql() string {
5563
}
5664

5765
parts = append(parts, strings.Join(columns, ", "))
58-
parts = append(parts, "FROM", self.from.Sql())
66+
67+
if self.from != nil {
68+
parts = append(parts, "FROM", self.from.Sql())
69+
}
70+
71+
if self.where != nil {
72+
parts = append(parts, "WHERE", self.where.Sql())
73+
}
74+
5975
sql := strings.Join(parts, " ")
6076

6177
if self.depth == 0 {
@@ -70,3 +86,7 @@ func (self SelectStatement) Sql() string {
7086
func (self SelectStatement) SqlPretty() string {
7187
return strings.Join([]string{}, "\n")
7288
}
89+
90+
func (self *SelectStatement) setDepth(depth uint) {
91+
self.depth = depth
92+
}

sqlx/select_test.go

Lines changed: 68 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,77 @@ import (
77
)
88

99
func TestSelect(t *testing.T) {
10-
t.Run("should build basic", func(t *testing.T) {
11-
sql := sqlx.Select("a", "b", "c").From("test").Sql()
10+
t.Run("from", func(t *testing.T) {
11+
t.Run("string", func(t *testing.T) {
12+
sql := sqlx.Select("a", "b", "c").From("test").Sql()
1213

13-
if sql != "SELECT a, b, c FROM test;" {
14-
t.Fatalf(sql)
15-
}
14+
if sql != "SELECT a, b, c FROM test;" {
15+
t.Fatalf(sql)
16+
}
17+
})
18+
19+
t.Run("select", func(t *testing.T) {
20+
sql := sqlx.Select("a", "b", "c").FromSelect(
21+
sqlx.Select("d", "e", "f").From("test"),
22+
"test",
23+
).Sql()
24+
25+
if sql != "SELECT a, b, c FROM (SELECT d, e, f FROM test) as \"test\";" {
26+
t.Fatalf(sql)
27+
}
28+
})
1629
})
1730

18-
t.Run("should build with nested from", func(t *testing.T) {
19-
sql := sqlx.Select("a", "b", "c").FromSelect(
20-
sqlx.Select("d", "e", "f").From("test"),
21-
"test",
22-
).Sql()
31+
t.Run("where", func(t *testing.T) {
32+
t.Run("and", func(t *testing.T) {
33+
sql := sqlx.Select(
34+
"a", "b", "c",
35+
).From("test").Where(
36+
sqlx.And(
37+
sqlx.Raw("a = b"),
38+
sqlx.Raw("b = c"),
39+
),
40+
).Sql()
41+
42+
if sql != "SELECT a, b, c FROM test WHERE a = b AND b = c;" {
43+
t.Fatalf(sql)
44+
}
45+
})
46+
47+
t.Run("or", func(t *testing.T) {
48+
sql := sqlx.Select(
49+
"a", "b", "c",
50+
).From("test").Where(
51+
sqlx.Or(
52+
sqlx.Raw("a = b"),
53+
sqlx.Raw("b = c"),
54+
),
55+
).Sql()
56+
57+
if sql != "SELECT a, b, c FROM test WHERE a = b OR b = c;" {
58+
t.Fatalf(sql)
59+
}
60+
})
61+
62+
t.Run("and or", func(t *testing.T) {
63+
sql := sqlx.Select(
64+
"a", "b", "c",
65+
).From("test").Where(
66+
sqlx.And(
67+
sqlx.And(
68+
sqlx.Raw("a = b"),
69+
sqlx.Raw("b = c"),
70+
),
71+
sqlx.Or(
72+
sqlx.Raw("a = b"),
73+
sqlx.Raw("b = c"),
74+
),
75+
),
76+
).Sql()
2377

24-
if sql != "SELECT a, b, c FROM (SELECT d, e, f FROM test) as \"test\";" {
25-
t.Fatalf(sql)
26-
}
78+
if sql != "SELECT a, b, c FROM test WHERE (a = b AND b = c) AND (a = b OR b = c);" {
79+
t.Fatalf(sql)
80+
}
81+
})
2782
})
2883
}

sqlx/sqlizer.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,6 @@ package sqlx
33
type Sqlizer interface {
44
Sql() string
55
SqlPretty() string
6+
7+
setDepth(depth uint)
68
}

sqlx/where.go

Lines changed: 0 additions & 6 deletions
This file was deleted.

0 commit comments

Comments
 (0)