diff --git a/sqlx/join.go b/sqlx/join.go index 983f3ea..45b9c48 100644 --- a/sqlx/join.go +++ b/sqlx/join.go @@ -25,6 +25,26 @@ func LeftOuterJoin(table string, predicate any) *JoinClause { return &JoinClause{&method, table, Where(predicate)} } +func RightJoin(table string, predicate any) *JoinClause { + method := "RIGHT" + return &JoinClause{&method, table, Where(predicate)} +} + +func RightOuterJoin(table string, predicate any) *JoinClause { + method := "RIGHT OUTER" + return &JoinClause{&method, table, Where(predicate)} +} + +func FullOuterJoin(table string, predicate any) *JoinClause { + method := "FULL OUTER" + return &JoinClause{&method, table, Where(predicate)} +} + +func CrossJoin(table string, predicate any) *JoinClause { + method := "CROSS" + return &JoinClause{&method, table, Where(predicate)} +} + func (self *JoinClause) And(predicate any) *JoinClause { self.where.And(predicate) return self diff --git a/sqlx/select_test.go b/sqlx/select_test.go index 1591454..f5aaa9c 100644 --- a/sqlx/select_test.go +++ b/sqlx/select_test.go @@ -214,6 +214,70 @@ func TestSelect(t *testing.T) { t.Fatalf(sql) } }) + + t.Run("right", func(t *testing.T) { + expected, err := os.ReadFile("./testcases/select/join/right_join.sql") + + if err != nil { + t.Fatal(err) + } + + sql := sqlx.Select("*").From("a").Join( + sqlx.RightJoin("b", "a.id = b.id").And("b.deleted_at IS NULL"), + ).Sql() + + if sql != strings.TrimSuffix(string(expected), "\n") { + t.Fatalf(sql) + } + }) + + t.Run("right outer", func(t *testing.T) { + expected, err := os.ReadFile("./testcases/select/join/right_outer_join.sql") + + if err != nil { + t.Fatal(err) + } + + sql := sqlx.Select("*").From("a").Join( + sqlx.RightOuterJoin("b", "a.id = b.id").And("b.deleted_at IS NULL"), + ).Sql() + + if sql != strings.TrimSuffix(string(expected), "\n") { + t.Fatalf(sql) + } + }) + + t.Run("full outer", func(t *testing.T) { + expected, err := os.ReadFile("./testcases/select/join/full_outer_join.sql") + + if err != nil { + t.Fatal(err) + } + + sql := sqlx.Select("*").From("a").Join( + sqlx.FullOuterJoin("b", "a.id = b.id").And("b.deleted_at IS NULL"), + ).Sql() + + if sql != strings.TrimSuffix(string(expected), "\n") { + t.Fatalf(sql) + } + }) + + t.Run("cross", func(t *testing.T) { + expected, err := os.ReadFile("./testcases/select/join/cross_join.sql") + + if err != nil { + t.Fatal(err) + } + + sql := sqlx.Select("*").From("a").Join( + sqlx.CrossJoin("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) { @@ -497,6 +561,70 @@ func TestSelect(t *testing.T) { t.Fatalf(sql) } }) + + t.Run("right", func(t *testing.T) { + expected, err := os.ReadFile("./testcases/select/join/right_join_pretty.sql") + + if err != nil { + t.Fatal(err) + } + + sql := sqlx.Select("*").From("a").Join( + sqlx.RightJoin("b", "a.id = b.id").And("b.deleted_at IS NULL"), + ).SqlPretty(" ") + + if sql != strings.TrimSuffix(string(expected), "\n") { + t.Fatalf(sql) + } + }) + + t.Run("right outer", func(t *testing.T) { + expected, err := os.ReadFile("./testcases/select/join/right_outer_join_pretty.sql") + + if err != nil { + t.Fatal(err) + } + + sql := sqlx.Select("*").From("a").Join( + sqlx.RightOuterJoin("b", "a.id = b.id").And("b.deleted_at IS NULL"), + ).SqlPretty(" ") + + if sql != strings.TrimSuffix(string(expected), "\n") { + t.Fatalf(sql) + } + }) + + t.Run("full outer", func(t *testing.T) { + expected, err := os.ReadFile("./testcases/select/join/full_outer_join_pretty.sql") + + if err != nil { + t.Fatal(err) + } + + sql := sqlx.Select("*").From("a").Join( + sqlx.FullOuterJoin("b", "a.id = b.id").And("b.deleted_at IS NULL"), + ).SqlPretty(" ") + + if sql != strings.TrimSuffix(string(expected), "\n") { + t.Fatalf(sql) + } + }) + + t.Run("cross", func(t *testing.T) { + expected, err := os.ReadFile("./testcases/select/join/cross_join_pretty.sql") + + if err != nil { + t.Fatal(err) + } + + sql := sqlx.Select("*").From("a").Join( + sqlx.CrossJoin("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) { diff --git a/sqlx/testcases/select/join/cross_join.sql b/sqlx/testcases/select/join/cross_join.sql new file mode 100644 index 0000000..79706d4 --- /dev/null +++ b/sqlx/testcases/select/join/cross_join.sql @@ -0,0 +1 @@ +SELECT * FROM a CROSS JOIN b ON a.id = b.id AND b.deleted_at IS NULL; diff --git a/sqlx/testcases/select/join/cross_join_pretty.sql b/sqlx/testcases/select/join/cross_join_pretty.sql new file mode 100644 index 0000000..5fe0f80 --- /dev/null +++ b/sqlx/testcases/select/join/cross_join_pretty.sql @@ -0,0 +1,6 @@ +SELECT + * +FROM a +CROSS JOIN b + ON a.id = b.id + AND b.deleted_at IS NULL; diff --git a/sqlx/testcases/select/join/full_outer_join.sql b/sqlx/testcases/select/join/full_outer_join.sql new file mode 100644 index 0000000..3249a90 --- /dev/null +++ b/sqlx/testcases/select/join/full_outer_join.sql @@ -0,0 +1 @@ +SELECT * FROM a FULL OUTER JOIN b ON a.id = b.id AND b.deleted_at IS NULL; diff --git a/sqlx/testcases/select/join/full_outer_join_pretty.sql b/sqlx/testcases/select/join/full_outer_join_pretty.sql new file mode 100644 index 0000000..06553d0 --- /dev/null +++ b/sqlx/testcases/select/join/full_outer_join_pretty.sql @@ -0,0 +1,6 @@ +SELECT + * +FROM a +FULL OUTER JOIN b + ON a.id = b.id + AND b.deleted_at IS NULL; diff --git a/sqlx/testcases/select/join/right_join.sql b/sqlx/testcases/select/join/right_join.sql new file mode 100644 index 0000000..b9faf02 --- /dev/null +++ b/sqlx/testcases/select/join/right_join.sql @@ -0,0 +1 @@ +SELECT * FROM a RIGHT JOIN b ON a.id = b.id AND b.deleted_at IS NULL; diff --git a/sqlx/testcases/select/join/right_join_pretty.sql b/sqlx/testcases/select/join/right_join_pretty.sql new file mode 100644 index 0000000..d0d7c23 --- /dev/null +++ b/sqlx/testcases/select/join/right_join_pretty.sql @@ -0,0 +1,6 @@ +SELECT + * +FROM a +RIGHT JOIN b + ON a.id = b.id + AND b.deleted_at IS NULL; diff --git a/sqlx/testcases/select/join/right_outer_join.sql b/sqlx/testcases/select/join/right_outer_join.sql new file mode 100644 index 0000000..d711254 --- /dev/null +++ b/sqlx/testcases/select/join/right_outer_join.sql @@ -0,0 +1 @@ +SELECT * FROM a RIGHT OUTER JOIN b ON a.id = b.id AND b.deleted_at IS NULL; diff --git a/sqlx/testcases/select/join/right_outer_join_pretty.sql b/sqlx/testcases/select/join/right_outer_join_pretty.sql new file mode 100644 index 0000000..8f0f716 --- /dev/null +++ b/sqlx/testcases/select/join/right_outer_join_pretty.sql @@ -0,0 +1,6 @@ +SELECT + * +FROM a +RIGHT OUTER JOIN b + ON a.id = b.id + AND b.deleted_at IS NULL;