diff --git a/postgresql/database.go b/postgresql/database.go index 360611a1417f899e84ca8636d08ba2548b3c3172..44912553ac95df658205634746f577cc74eb0857 100644 --- a/postgresql/database.go +++ b/postgresql/database.go @@ -69,6 +69,37 @@ func debugEnabled() bool { } func init() { + + sqlgen.SetTemplate(sqlgen.Template{ + pgsqlColumnSeparator, + pgsqlIdentifierSeparator, + pgsqlIdentifierQuote, + pgsqlValueSeparator, + pgsqlValueQuote, + pgsqlAndKeyword, + pgsqlOrKeyword, + pgsqlNotKeyword, + pgsqlDescKeyword, + pgsqlAscKeyword, + pgsqlDefaultOperator, + pgsqlClauseGroup, + pgsqlClauseOperator, + pgsqlColumnValue, + pgsqlTableAliasLayout, + pgsqlColumnAliasLayout, + pgsqlSortByColumnLayout, + pgsqlWhereLayout, + pgsqlOrderByLayout, + pgsqlInsertLayout, + pgsqlSelectLayout, + pgsqlUpdateLayout, + pgsqlDeleteLayout, + pgsqlTruncateLayout, + pgsqlDropDatabaseLayout, + pgsqlDropTableLayout, + pgsqlSelectCountLayout, + }) + db.Register(Driver, &Source{}) } diff --git a/postgresql/layout.go b/postgresql/layout.go new file mode 100644 index 0000000000000000000000000000000000000000..5d3d517c1e8f7524fe93538377cdfa4d9e4f708a --- /dev/null +++ b/postgresql/layout.go @@ -0,0 +1,124 @@ +// Copyright (c) 2012-2014 José Carlos Nieto, https://menteslibres.net/xiam +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +package postgresql + +const ( + pgsqlColumnSeparator = `.` + pgsqlIdentifierSeparator = `, ` + pgsqlIdentifierQuote = `"{{.Raw}}"` + pgsqlValueSeparator = `, ` + pgsqlValueQuote = `'{{.}}'` + pgsqlAndKeyword = `AND` + pgsqlOrKeyword = `OR` + pgsqlNotKeyword = `NOT` + pgsqlDescKeyword = `DESC` + pgsqlAscKeyword = `ASC` + pgsqlDefaultOperator = `=` + pgsqlClauseGroup = `({{.}})` + pgsqlClauseOperator = ` {{.}} ` + pgsqlColumnValue = `{{.Column}} {{.Operator}} {{.Value}}` + pgsqlTableAliasLayout = `{{.Name}}{{if .Alias}} AS {{.Alias}}{{end}}` + pgsqlColumnAliasLayout = `{{.Name}}{{if .Alias}} AS {{.Alias}}{{end}}` + pgsqlSortByColumnLayout = `{{.Column}} {{.Sort}}` + + pgsqlOrderByLayout = ` + {{if .SortColumns}} + ORDER BY {{.SortColumns}} + {{end}} + ` + + pgsqlWhereLayout = ` + {{if .Conds}} + WHERE {{.Conds}} + {{end}} + ` + + pgsqlSelectLayout = ` + SELECT + + {{if .Columns}} + {{.Columns}} + {{else}} + * + {{end}} + + FROM {{.Table}} + + {{.Where}} + + {{.OrderBy}} + + {{if .Limit}} + LIMIT {{.Limit}} + {{end}} + + {{if .Offset}} + OFFSET {{.Offset}} + {{end}} + ` + pgsqlDeleteLayout = ` + DELETE + FROM {{.Table}} + {{.Where}} + ` + pgsqlUpdateLayout = ` + UPDATE + {{.Table}} + SET {{.ColumnValues}} + {{ .Where }} + ` + + pgsqlSelectCountLayout = ` + SELECT + COUNT(1) AS _t + FROM {{.Table}} + {{.Where}} + + {{if .Limit}} + LIMIT {{.Limit}} + {{end}} + + {{if .Offset}} + OFFSET {{.Offset}} + {{end}} + ` + + pgsqlInsertLayout = ` + INSERT INTO {{.Table}} + ({{.Columns}}) + VALUES + ({{.Values}}) + {{.Extra}} + ` + + pgsqlTruncateLayout = ` + TRUNCATE TABLE {{.Table}} + ` + + pgsqlDropDatabaseLayout = ` + DROP DATABASE {{.Database}} + ` + + pgsqlDropTableLayout = ` + DROP TABLE {{.Table}} + ` +) diff --git a/util/sqlgen/column.go b/util/sqlgen/column.go index 3314c788e3f76b8a5a8c21d06f7f86420866a42f..34a6e31ecb9b5768b8aa5cdf156251d328fb9c40 100644 --- a/util/sqlgen/column.go +++ b/util/sqlgen/column.go @@ -20,21 +20,21 @@ func (self Column) String() string { name := chunks[0] - nameChunks := strings.SplitN(name, Layout.ColumnSeparator, 2) + 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]}) + nameChunks[i] = mustParse(layout.IdentifierQuote, Raw{nameChunks[i]}) } - name = strings.Join(nameChunks, Layout.ColumnSeparator) + name = strings.Join(nameChunks, layout.ColumnSeparator) var alias string if len(chunks) > 1 { alias = strings.TrimSpace(chunks[1]) - alias = mustParse(Layout.IdentifierQuote, Raw{alias}) + alias = mustParse(layout.IdentifierQuote, Raw{alias}) } - return mustParse(Layout.ColumnAliasLayout, column_t{name, alias}) + return mustParse(layout.ColumnAliasLayout, column_t{name, alias}) } diff --git a/util/sqlgen/column_value.go b/util/sqlgen/column_value.go index a94217528db019cb0a7b0149885e9e3cb748bdc3..8e6d5ad67b1367a30b55413dcd7efb5d906c21d6 100644 --- a/util/sqlgen/column_value.go +++ b/util/sqlgen/column_value.go @@ -11,7 +11,7 @@ type ColumnValue struct { } func (self ColumnValue) String() string { - return mustParse(Layout.ColumnValue, self) + return mustParse(layout.ColumnValue, self) } type ColumnValues []ColumnValue @@ -25,5 +25,5 @@ func (self ColumnValues) String() string { out[i] = self[i].String() } - return strings.Join(out, Layout.IdentifierSeparator) + return strings.Join(out, layout.IdentifierSeparator) } diff --git a/util/sqlgen/columns.go b/util/sqlgen/columns.go index fc076b81dd7d2cf7f11e88b376c6e6fcadf4a741..45eaa6f897e2d3703c8a072a8410e238b1842aca 100644 --- a/util/sqlgen/columns.go +++ b/util/sqlgen/columns.go @@ -16,7 +16,7 @@ func (self Columns) String() string { out[i] = self[i].String() } - return strings.Join(out, Layout.IdentifierSeparator) + return strings.Join(out, layout.IdentifierSeparator) } return "" } diff --git a/util/sqlgen/database.go b/util/sqlgen/database.go index e61f1f364651d88f2fc6104444e9e420574ee06e..c8949108f09b3e20e7bea2d0a259217b5f5a92b7 100644 --- a/util/sqlgen/database.go +++ b/util/sqlgen/database.go @@ -9,5 +9,5 @@ type Database struct { } func (self Database) String() string { - return mustParse(Layout.IdentifierQuote, Raw{fmt.Sprintf(`%v`, self.Value)}) + return mustParse(layout.IdentifierQuote, Raw{fmt.Sprintf(`%v`, self.Value)}) } diff --git a/util/sqlgen/layout.go b/util/sqlgen/layout.go index fe0c597779b268f9104ee0a93dc8c8fd55824b81..c9b5f356639d72c3baa7b269faf3114d04b6a869 100644 --- a/util/sqlgen/layout.go +++ b/util/sqlgen/layout.go @@ -1,6 +1,6 @@ package sqlgen -type layout struct { +type Template struct { ColumnSeparator string IdentifierSeparator string IdentifierQuote string @@ -30,7 +30,7 @@ type layout struct { SelectCountLayout string } -var Layout = layout{ +var layout = Template{ defaultColumnSeparator, defaultIdentifierSeparator, defaultIdentifierQuote, diff --git a/util/sqlgen/main.go b/util/sqlgen/main.go index 35c6109430a1f7b19d32f3a24c86ba3a15b7e23e..ee10860eb3f508d11c321de36521b95833416ac2 100644 --- a/util/sqlgen/main.go +++ b/util/sqlgen/main.go @@ -53,21 +53,25 @@ type Statement struct { func (self *Statement) Compile() string { switch self.Type { case SqlTruncate: - return mustParse(Layout.TruncateLayout, self) + return mustParse(layout.TruncateLayout, self) case SqlDropTable: - return mustParse(Layout.DropTableLayout, self) + return mustParse(layout.DropTableLayout, self) case SqlDropDatabase: - return mustParse(Layout.DropDatabaseLayout, self) + return mustParse(layout.DropDatabaseLayout, self) case SqlSelectCount: - return mustParse(Layout.SelectCountLayout, self) + return mustParse(layout.SelectCountLayout, self) case SqlSelect: - return mustParse(Layout.SelectLayout, self) + return mustParse(layout.SelectLayout, self) case SqlDelete: - return mustParse(Layout.DeleteLayout, self) + return mustParse(layout.DeleteLayout, self) case SqlUpdate: - return mustParse(Layout.UpdateLayout, self) + return mustParse(layout.UpdateLayout, self) case SqlInsert: - return mustParse(Layout.InsertLayout, self) + return mustParse(layout.InsertLayout, self) } return "" } + +func SetTemplate(tpl Template) { + layout = tpl +} diff --git a/util/sqlgen/order_by.go b/util/sqlgen/order_by.go index c2131d7009b8f7a7f49ab05cb6c00bb6916ac658..94b786180253f8a2f2b4e291ea240382e270b4d3 100644 --- a/util/sqlgen/order_by.go +++ b/util/sqlgen/order_by.go @@ -15,11 +15,11 @@ func (self SortColumns) String() string { for i := 0; i < l; i++ { s = append(s, self[i].String()) } - return strings.Join(s, Layout.IdentifierSeparator) + return strings.Join(s, layout.IdentifierSeparator) } func (self SortColumn) String() string { - return mustParse(Layout.SortByColumnLayout, self) + return mustParse(layout.SortByColumnLayout, self) } type OrderBy struct { @@ -28,7 +28,7 @@ type OrderBy struct { func (self OrderBy) String() string { if len(self.SortColumns) > 0 { - return mustParse(Layout.OrderByLayout, self) + return mustParse(layout.OrderByLayout, self) } return "" } @@ -44,9 +44,9 @@ const ( func (self Sort) String() string { switch self { case SqlSortAsc: - return Layout.AscKeyword + return layout.AscKeyword case SqlSortDesc: - return Layout.DescKeyword + return layout.DescKeyword } return "" } diff --git a/util/sqlgen/table.go b/util/sqlgen/table.go index 631ea4165627c4c0412f8c167c6cd82f574d37e7..c865150130cfee4b3fd0b2abcf49a41a7959b627 100644 --- a/util/sqlgen/table.go +++ b/util/sqlgen/table.go @@ -26,23 +26,23 @@ func quotedTableName(input string) string { name := chunks[0] - nameChunks := strings.SplitN(name, Layout.ColumnSeparator, 2) + 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]}) + nameChunks[i] = mustParse(layout.IdentifierQuote, Raw{nameChunks[i]}) } - name = strings.Join(nameChunks, Layout.ColumnSeparator) + name = strings.Join(nameChunks, layout.ColumnSeparator) var alias string if len(chunks) > 1 { alias = strings.TrimSpace(chunks[1]) - alias = mustParse(Layout.IdentifierQuote, Raw{alias}) + alias = mustParse(layout.IdentifierQuote, Raw{alias}) } - return mustParse(Layout.TableAliasLayout, table_t{name, alias}) + return mustParse(layout.TableAliasLayout, table_t{name, alias}) } func (self Table) String() string { @@ -55,5 +55,5 @@ func (self Table) String() string { parts[i] = quotedTableName(parts[i]) } - return strings.Join(parts, Layout.IdentifierSeparator) + return strings.Join(parts, layout.IdentifierSeparator) } diff --git a/util/sqlgen/value.go b/util/sqlgen/value.go index 2f77a7c6b953741f211ad7574a6b65cf509d6410..44cb6c501e98bf1a369a91b470012a76252745c5 100644 --- a/util/sqlgen/value.go +++ b/util/sqlgen/value.go @@ -15,7 +15,7 @@ func (self Value) String() string { if raw, ok := self.Value.(Raw); ok { return raw.Raw } - return mustParse(Layout.ValueQuote, Raw{fmt.Sprintf(`%v`, self.Value)}) + return mustParse(layout.ValueQuote, Raw{fmt.Sprintf(`%v`, self.Value)}) } func (self Values) String() string { @@ -28,7 +28,7 @@ func (self Values) String() string { chunks = append(chunks, self[i].String()) } - return strings.Join(chunks, Layout.ValueSeparator) + return strings.Join(chunks, layout.ValueSeparator) } return "" diff --git a/util/sqlgen/where.go b/util/sqlgen/where.go index 5673923a09f034a6f9301af9302cc07b8dec0ef3..be0dafa736302451c1dde3f5637acbd1542f1d72 100644 --- a/util/sqlgen/where.go +++ b/util/sqlgen/where.go @@ -15,17 +15,17 @@ type conds struct { } func (self Or) String() string { - return groupCondition(self, mustParse(Layout.ClauseOperator, Layout.OrKeyword)) + return groupCondition(self, mustParse(layout.ClauseOperator, layout.OrKeyword)) } func (self And) String() string { - return groupCondition(self, mustParse(Layout.ClauseOperator, Layout.AndKeyword)) + return groupCondition(self, mustParse(layout.ClauseOperator, layout.AndKeyword)) } func (self Where) String() string { - grouped := groupCondition(self, mustParse(Layout.ClauseOperator, Layout.AndKeyword)) + grouped := groupCondition(self, mustParse(layout.ClauseOperator, layout.AndKeyword)) if grouped != "" { - return mustParse(Layout.WhereLayout, conds{grouped}) + return mustParse(layout.WhereLayout, conds{grouped}) } return "" } @@ -52,7 +52,7 @@ func groupCondition(terms []interface{}, joinKeyword string) string { } if len(chunks) > 0 { - return mustParse(Layout.ClauseGroup, strings.Join(chunks, joinKeyword)) + return mustParse(layout.ClauseGroup, strings.Join(chunks, joinKeyword)) } return ""