Skip to content

Commit

Permalink
add join
Browse files Browse the repository at this point in the history
  • Loading branch information
aacebo committed Nov 22, 2024
1 parent 97765e5 commit 5704917
Show file tree
Hide file tree
Showing 7 changed files with 165 additions and 0 deletions.
67 changes: 67 additions & 0 deletions sqlx/join.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package sqlx

import (
"fmt"
"strings"
)

type JoinClause struct {
method *string
table string
where *WhereClause
}

func LeftJoin(table string, predicate any) *JoinClause {
method := "LEFT"
return &JoinClause{&method, table, Where(predicate)}
}

func LeftOuterJoin(table string, predicate any) *JoinClause {
method := "LEFT OUTER"
return &JoinClause{&method, table, Where(predicate)}
}

func (self *JoinClause) And(predicate any) *JoinClause {
self.where.And(predicate)
return self
}

func (self *JoinClause) Or(predicate any) *JoinClause {
self.where.Or(predicate)
return self
}

func (self JoinClause) Sql() string {
parts := []string{}

if self.method != nil {
parts = append(parts, *self.method)
}

parts = append(parts, "JOIN", self.table, "ON")
parts = append(parts, self.where.Sql())
return strings.Join(parts, " ")
}

func (self JoinClause) SqlPretty(indent string) string {
parts := []string{}

if self.method != nil {
parts = append(parts, fmt.Sprintf("%s JOIN %s", *self.method, self.table))
} else {
parts = append(parts, fmt.Sprintf("JOIN %s", self.table))
}

lines := strings.Split(self.where.SqlPretty(indent), "\n")
parts = append(parts, indent+"ON "+lines[0])

for _, line := range lines[1:] {
parts = append(parts, indent+line)
}

return strings.Join(parts, "\n")
}

func (self *JoinClause) setDepth(_ uint) {

}
16 changes: 16 additions & 0 deletions sqlx/select.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ type SelectStatement struct {
columns Columns
from Sqlizer
where *WhereClause
joins []Sqlizer
groupBy Sqlizer
orderBy Sqlizer
limit Sqlizer
Expand All @@ -26,6 +27,7 @@ func Select(columns ...any) *SelectStatement {
return &SelectStatement{
depth: 0,
columns: cols,
joins: []Sqlizer{},
}
}

Expand All @@ -39,6 +41,11 @@ func (self *SelectStatement) From(from any) *SelectStatement {
return self
}

func (self *SelectStatement) Join(join Sqlizer) *SelectStatement {
self.joins = append(self.joins, join)
return self
}

func (self *SelectStatement) Where(predicate any) *SelectStatement {
self.where = Where(predicate)
return self
Expand Down Expand Up @@ -93,6 +100,10 @@ func (self SelectStatement) Sql() string {
parts = append(parts, "FROM", self.from.Sql())
}

for _, join := range self.joins {
parts = append(parts, join.Sql())
}

if self.where != nil {
parts = append(parts, "WHERE", self.where.Sql())
}
Expand Down Expand Up @@ -144,6 +155,11 @@ func (self SelectStatement) SqlPretty(indent string) string {
parts = append(parts, lines[1:]...)
}

for _, join := range self.joins {
lines := strings.Split(join.SqlPretty(indent), "\n")
parts = append(parts, lines...)
}

if self.where != nil {
lines := strings.Split(self.where.SqlPretty(indent), "\n")
parts = append(parts, "WHERE "+lines[0])
Expand Down
68 changes: 68 additions & 0 deletions sqlx/select_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,40 @@ func TestSelect(t *testing.T) {
})
})

t.Run("join", func(t *testing.T) {
t.Run("left", func(t *testing.T) {
expected, err := os.ReadFile("./testcases/select/left_join.sql")

if err != nil {
t.Fatal(err)
}

sql := sqlx.Select("*").From("a").Join(
sqlx.LeftJoin("b", "a.id = b.id").And("b.deleted_at IS NULL"),
).Sql()

if sql != strings.TrimSuffix(string(expected), "\n") {
t.Fatalf(sql)
}
})

t.Run("left outer", func(t *testing.T) {
expected, err := os.ReadFile("./testcases/select/left_outer_join.sql")

if err != nil {
t.Fatal(err)
}

sql := sqlx.Select("*").From("a").Join(
sqlx.LeftOuterJoin("b", "a.id = b.id").And("b.deleted_at IS NULL"),
).Sql()

if sql != strings.TrimSuffix(string(expected), "\n") {
t.Fatalf(sql)
}
})
})

t.Run("group by", func(t *testing.T) {
expected, err := os.ReadFile("./testcases/select/group_by.sql")

Expand Down Expand Up @@ -399,6 +433,40 @@ func TestSelect(t *testing.T) {
})
})

t.Run("join", func(t *testing.T) {
t.Run("left", func(t *testing.T) {
expected, err := os.ReadFile("./testcases/select/left_join_pretty.sql")

if err != nil {
t.Fatal(err)
}

sql := sqlx.Select("*").From("a").Join(
sqlx.LeftJoin("b", "a.id = b.id").And("b.deleted_at IS NULL"),
).SqlPretty(" ")

if sql != strings.TrimSuffix(string(expected), "\n") {
t.Fatalf(sql)
}
})

t.Run("left outer", func(t *testing.T) {
expected, err := os.ReadFile("./testcases/select/left_outer_join_pretty.sql")

if err != nil {
t.Fatal(err)
}

sql := sqlx.Select("*").From("a").Join(
sqlx.LeftOuterJoin("b", "a.id = b.id").And("b.deleted_at IS NULL"),
).SqlPretty(" ")

if sql != strings.TrimSuffix(string(expected), "\n") {
t.Fatalf(sql)
}
})
})

t.Run("group by", func(t *testing.T) {
expected, err := os.ReadFile("./testcases/select/group_by_pretty.sql")

Expand Down
1 change: 1 addition & 0 deletions sqlx/testcases/select/left_join.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT * FROM a LEFT JOIN b ON a.id = b.id AND b.deleted_at IS NULL;
6 changes: 6 additions & 0 deletions sqlx/testcases/select/left_join_pretty.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
SELECT
*
FROM a
LEFT JOIN b
ON a.id = b.id
AND b.deleted_at IS NULL;
1 change: 1 addition & 0 deletions sqlx/testcases/select/left_outer_join.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT * FROM a LEFT OUTER JOIN b ON a.id = b.id AND b.deleted_at IS NULL;
6 changes: 6 additions & 0 deletions sqlx/testcases/select/left_outer_join_pretty.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
SELECT
*
FROM a
LEFT OUTER JOIN b
ON a.id = b.id
AND b.deleted_at IS NULL;

0 comments on commit 5704917

Please sign in to comment.