Skip to content

Commit

Permalink
Merge pull request #115 from ulule/feat/multiple-from
Browse files Browse the repository at this point in the history
feat: allow multiple from
  • Loading branch information
thoas authored May 17, 2021
2 parents f297dd1 + 16e4ef5 commit 4790f61
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 39 deletions.
26 changes: 16 additions & 10 deletions builder/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,20 +199,26 @@ func ToTables(values []interface{}) []stmt.Table {
}

// ToFrom takes an empty interfaces and returns a From instance.
func ToFrom(arg interface{}) stmt.From {
func ToFrom(args ...interface{}) stmt.From {
from := stmt.From{}

switch value := arg.(type) {
case string:
from = stmt.NewFrom(stmt.NewTable(value), false)
case stmt.From:
from = value
case stmt.Table:
from = stmt.NewFrom(value, false)
default:
panic(fmt.Sprintf("loukoum: cannot use %T as from clause", arg))
tables := make([]stmt.Statement, len(args))
for i := range args {
switch value := args[i].(type) {
case string:
tables[i] = stmt.NewTable(value)
case stmt.From:
from = value
case stmt.Table:
tables[i] = value
case stmt.Raw:
tables[i] = value
default:
panic(fmt.Sprintf("loukoum: cannot use %T as from clause", args[i]))
}
}

from = stmt.NewFrom(tables)
if from.IsEmpty() {
panic("loukoum: given from clause is undefined")
}
Expand Down
14 changes: 2 additions & 12 deletions builder/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,13 @@ func NewDelete() Delete {
}

// From sets the FROM clause of the query.
func (b Delete) From(arg interface{}) Delete {
func (b Delete) From(arg ...interface{}) Delete {
if !b.query.From.IsEmpty() {
panic("loukoum: delete builder has from clause already defined")
}

only := b.query.From.Only
b.query.From = ToFrom(arg)
if only {
b.query.From.Only = only
}

return b
}
b.query.From = ToFrom(arg...)

// Only adds a ONLY clause to the query.
func (b Delete) Only() Delete {
b.query.From.Only = true
return b
}

Expand Down
5 changes: 2 additions & 3 deletions builder/delete_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ func TestDelete(t *testing.T) {
{
Name: "Only",
Builders: []builder.Builder{
loukoum.Delete("table").Only(),
loukoum.Delete(loukoum.Table("table")).Only(),
loukoum.Delete(loukoum.Table("table").Only()),
},
SameQuery: "DELETE FROM ONLY \"table\"",
},
Expand All @@ -33,7 +32,7 @@ func TestDelete(t *testing.T) {
},
{
Name: "As only",
Builder: loukoum.Delete(loukoum.Table("table").As("foobar")).Only(),
Builder: loukoum.Delete(loukoum.Table("table").As("foobar").Only()),
SameQuery: "DELETE FROM ONLY \"table\" AS \"foobar\"",
},
})
Expand Down
4 changes: 2 additions & 2 deletions builder/select.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,12 @@ func (b Select) Columns(args ...interface{}) Select {
}

// From sets the FROM clause of the query.
func (b Select) From(arg interface{}) Select {
func (b Select) From(arg ...interface{}) Select {
if !b.query.From.IsEmpty() {
panic("loukoum: select builder has from clause already defined")
}

b.query.From = ToFrom(arg)
b.query.From = ToFrom(arg...)

return b
}
Expand Down
20 changes: 20 additions & 0 deletions builder/select_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,26 @@ func TestSelect_From(t *testing.T) {
Builder: loukoum.Select("a").From(loukoum.Table("foobar").As("example")),
SameQuery: "SELECT \"a\" FROM \"foobar\" AS \"example\"",
},
{
Name: "Multiple",
Builder: loukoum.Select("a").From(loukoum.Table("foobar").As("example"), loukoum.Table("foobar").As("example2")),
SameQuery: "SELECT \"a\" FROM \"foobar\" AS \"example\", \"foobar\" AS \"example2\"",
},
{
Name: "Multiple strings",
Builder: loukoum.Select("a").From("example", "example2"),
SameQuery: "SELECT \"a\" FROM \"example\", \"example2\"",
},
{
Name: "Multiple raws",
Builder: loukoum.Select("a").From(loukoum.Raw("example1 ex1"), loukoum.Raw("example2 ex2")),
SameQuery: "SELECT \"a\" FROM example1 ex1, example2 ex2",
},
{
Name: "Multiple raw",
Builder: loukoum.Select("a").From(loukoum.Raw("example1 ex1, example2 ex2")),
SameQuery: "SELECT \"a\" FROM example1 ex1, example2 ex2",
},
})
}

Expand Down
23 changes: 12 additions & 11 deletions stmt/from.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,33 @@ import (

// From is a FROM clause.
type From struct {
Only bool
Table Table
Tables []Statement
}

// NewFrom returns a new From instance.
func NewFrom(table Table, only bool) From {
func NewFrom(tables []Statement) From {
return From{
Only: only,
Table: table,
Tables: tables,
}
}

// Write exposes statement as a SQL query.
func (from From) Write(ctx types.Context) {
ctx.Write(token.From.String())
if from.Only {
ctx.Write(" ")
ctx.Write(token.Only.String())
}
ctx.Write(" ")
from.Table.Write(ctx)

for i := range from.Tables {
from.Tables[i].Write(ctx)

if i != len(from.Tables)-1 {
ctx.Write(", ")
}
}
}

// IsEmpty returns true if statement is undefined.
func (from From) IsEmpty() bool {
return from.Table.IsEmpty()
return len(from.Tables) == 0
}

// Ensure that From is a Statement
Expand Down
13 changes: 12 additions & 1 deletion stmt/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,22 @@ import (

// Table is a table identifier.
type Table struct {
Name string
Alias string
Name string
only bool
}

// NewTable returns a new Table instance.
func NewTable(name string) Table {
return NewTableAlias(name, "")
}

// Only sets ONLY clause to the table.
func (table Table) Only() Table {
table.only = true
return table
}

// NewTableAlias returns a new Table instance with an alias.
func NewTableAlias(name, alias string) Table {
return Table{
Expand All @@ -32,6 +39,10 @@ func (table Table) As(alias string) Table {

// Write exposes statement as a SQL query.
func (table Table) Write(ctx types.Context) {
if table.only {
ctx.Write(token.Only.String())
ctx.Write(" ")
}
ctx.Write(quote(table.Name))
if table.Alias != "" {
ctx.Write(" ")
Expand Down

0 comments on commit 4790f61

Please sign in to comment.