diff --git a/util/sqlgen/default.go b/util/sqlgen/default.go index 778fab65e3137807804eb3b8b4452d9299840337..e67243c5a11ff70072937e1c64f320a6e39fd010 100644 --- a/util/sqlgen/default.go +++ b/util/sqlgen/default.go @@ -17,6 +17,8 @@ const ( defaultClauseOperator = ` {{.}} ` defaultColumnValue = `{{.Column}} {{.Operator}} {{.Value}}` + defaultTableAliasLayout = `{{.Name}}{{if .Alias}} AS {{.Alias}}{{end}}` + defaultSortByColumnLayout = `{{.Column}} {{.Sort}}` defaultOrderByLayout = ` diff --git a/util/sqlgen/layout.go b/util/sqlgen/layout.go index c4bc61599e229d7fbcd71a5e95c18e9755181717..ff8dc4217434517c187a1ec6382a4b54209d59f8 100644 --- a/util/sqlgen/layout.go +++ b/util/sqlgen/layout.go @@ -15,6 +15,7 @@ type layout struct { ClauseGroup string ClauseOperator string ColumnValue string + TableAliasLayout string SortByColumnLayout string WhereLayout string OrderByLayout string @@ -43,6 +44,7 @@ var Layout = layout{ defaultClauseGroup, defaultClauseOperator, defaultColumnValue, + defaultTableAliasLayout, defaultSortByColumnLayout, defaultWhereLayout, defaultOrderByLayout, diff --git a/util/sqlgen/main_test.go b/util/sqlgen/main_test.go index 4b26e860b4cf6d2f59d5c281112a45aa0a693fa5..835d200695c3acf5a0ba7f363098779175a8b966 100644 --- a/util/sqlgen/main_test.go +++ b/util/sqlgen/main_test.go @@ -127,6 +127,40 @@ func TestSelectStarFrom(t *testing.T) { } } +func TestSelectStarFromAlias(t *testing.T) { + var s, e string + var stmt Statement + + stmt = Statement{ + Type: SqlSelect, + Table: Table{"table.name AS foo"}, + } + + s = trim(stmt.Compile()) + e = `SELECT * FROM "table"."name" AS "foo"` + + if s != e { + t.Fatalf("Got: %s, Expecting: %s", s, e) + } +} + +func TestSelectStarFromMany(t *testing.T) { + var s, e string + var stmt Statement + + stmt = Statement{ + Type: SqlSelect, + Table: Table{"first.table AS foo, second.table as BAR, third.table aS baz"}, + } + + s = trim(stmt.Compile()) + e = `SELECT * FROM "first"."table" AS "foo", "second"."table" AS "BAR", "third"."table" AS "baz"` + + if s != e { + t.Fatalf("Got: %s, Expecting: %s", s, e) + } +} + func TestSelectArtistNameFrom(t *testing.T) { var s, e string var stmt Statement @@ -135,7 +169,7 @@ func TestSelectArtistNameFrom(t *testing.T) { Type: SqlSelect, Table: Table{"artist"}, Columns: Columns{ - Column{"artist.name"}, + {"artist.name"}, }, } diff --git a/util/sqlgen/table.go b/util/sqlgen/table.go index 71e540af8b2b4e966fab5d14939e22eb340c4b1e..1c2e3fb0aa4e73aba42c27a5c02875c9f577b16d 100644 --- a/util/sqlgen/table.go +++ b/util/sqlgen/table.go @@ -1,19 +1,59 @@ package sqlgen import ( + "regexp" "strings" ) +var ( + reTableSeparator = regexp.MustCompile(`\s*?,\s*?`) + reAliasSeparator = regexp.MustCompile(`(?i:AS)`) +) + +type table_t struct { + Name string + Alias string +} + type Table struct { - Value string + Name string +} + +func quotedTableName(input string) string { + input = strings.TrimSpace(input) + + chunks := reAliasSeparator.Split(input, 2) + + name := chunks[0] + + nameChunks := strings.SplitN(name, Layout.ColumnSeparator, 2) + + for i := range nameChunks { + nameChunks[i] = strings.TrimSpace(nameChunks[i]) + nameChunks[i] = mustParse(Layout.IdentifierQuote, Raw{nameChunks[i]}) + } + + name = strings.Join(nameChunks, Layout.ColumnSeparator) + + var alias string + + if len(chunks) > 1 { + alias = strings.TrimSpace(chunks[1]) + alias = mustParse(Layout.IdentifierQuote, Raw{alias}) + } + + return mustParse(Layout.TableAliasLayout, table_t{name, alias}) } func (self Table) String() string { - chunks := strings.Split(self.Value, Layout.ColumnSeparator) - for i := range chunks { - chunks[i] = mustParse(Layout.IdentifierQuote, Raw{chunks[i]}) + parts := reTableSeparator.Split(self.Name, -1) + + l := len(parts) + + for i := 0; i < l; i++ { + parts[i] = quotedTableName(parts[i]) } - return strings.Join(chunks, Layout.ColumnSeparator) + return strings.Join(parts, Layout.IdentifierSeparator) } diff --git a/util/sqlgen/table_test.go b/util/sqlgen/table_test.go new file mode 100644 index 0000000000000000000000000000000000000000..360d1141ef619d63b68454cac7792c31e5d333b6 --- /dev/null +++ b/util/sqlgen/table_test.go @@ -0,0 +1,75 @@ +package sqlgen + +import ( + "testing" +) + +func TestTableSimple(t *testing.T) { + var s, e string + var table Table + + table = Table{"artist"} + + s = trim(table.String()) + e = `"artist"` + + if s != e { + t.Fatalf("Got: %s, Expecting: %s", s, e) + } +} + +func TestTableCompound(t *testing.T) { + var s, e string + var table Table + + table = Table{"artist.foo"} + + s = trim(table.String()) + e = `"artist"."foo"` + + if s != e { + t.Fatalf("Got: %s, Expecting: %s", s, e) + } +} + +func TestTableCompoundAlias(t *testing.T) { + var s, e string + var table Table + + table = Table{"artist.foo AS baz"} + + s = trim(table.String()) + e = `"artist"."foo" AS "baz"` + + if s != e { + t.Fatalf("Got: %s, Expecting: %s", s, e) + } +} + +func TestTableMultiple(t *testing.T) { + var s, e string + var table Table + + table = Table{"artist.foo, artist.bar, artist.baz"} + + s = trim(table.String()) + e = `"artist"."foo", "artist"."bar", "artist"."baz"` + + if s != e { + t.Fatalf("Got: %s, Expecting: %s", s, e) + } +} + +func TestTableMultipleAlias(t *testing.T) { + var s, e string + var table Table + + table = Table{"artist.foo AS foo, artist.bar as bar, artist.baz As baz"} + + s = trim(table.String()) + e = `"artist"."foo" AS "foo", "artist"."bar" AS "bar", "artist"."baz" AS "baz"` + + if s != e { + t.Fatalf("Got: %s, Expecting: %s", s, e) + } +}