diff --git a/util/sqlgen/column.go b/util/sqlgen/column.go index 4b3f972c2ff57c1e074d70a75dae2222ecae9774..a43ec871888369423acfeefac2530d7974fd67bd 100644 --- a/util/sqlgen/column.go +++ b/util/sqlgen/column.go @@ -14,7 +14,11 @@ type Column struct { Value interface{} } -func (self Column) Compile(layout *Template) string { +func (self Column) Compile(layout *Template) (compiled string) { + + if s, ok := layout.Cache(self); ok { + return s + } switch value := self.Value.(type) { case string: @@ -44,10 +48,14 @@ func (self Column) Compile(layout *Template) string { alias = mustParse(layout.IdentifierQuote, Raw{alias}) } - return mustParse(layout.ColumnAliasLayout, column_t{name, alias}) + compiled = mustParse(layout.ColumnAliasLayout, column_t{name, alias}) case Raw: - return value.String() + compiled = value.String() + default: + compiled = fmt.Sprintf("%v", self.Value) } - return fmt.Sprintf("%v", self.Value) + layout.SetCache(self, compiled) + + return compiled } diff --git a/util/sqlgen/column_value.go b/util/sqlgen/column_value.go index 897529720932e900295cf4e6a2eac6d4f347fd6f..2d8dfd1577b94e3ceb84ff30e978bf52c24adea5 100644 --- a/util/sqlgen/column_value.go +++ b/util/sqlgen/column_value.go @@ -16,18 +16,33 @@ type columnValue_s struct { Value string } -func (self ColumnValue) Compile(layout *Template) string { +func (self ColumnValue) Compile(layout *Template) (compiled string) { + + if s, ok := layout.Cache(self); ok { + return s + } + data := columnValue_s{ self.Column.Compile(layout), self.Operator, self.Value.Compile(layout), } - return mustParse(layout.ColumnValue, data) + + compiled = mustParse(layout.ColumnValue, data) + + return } type ColumnValues []ColumnValue -func (self ColumnValues) Compile(layout *Template) string { +func (self ColumnValues) Compile(layout *Template) (compiled string) { + + /* + if s, ok := layout.Cache(self); ok { + return s + } + */ + l := len(self) out := make([]string, l) @@ -36,5 +51,7 @@ func (self ColumnValues) Compile(layout *Template) string { out[i] = self[i].Compile(layout) } - return strings.Join(out, layout.IdentifierSeparator) + compiled = strings.Join(out, layout.IdentifierSeparator) + + return } diff --git a/util/sqlgen/default.go b/util/sqlgen/default.go index 81eb4a4b895610b8b169a78149a76a789b3bf1f6..0c855a6acb4ca5e742c1ba11d50f33c7874611dc 100644 --- a/util/sqlgen/default.go +++ b/util/sqlgen/default.go @@ -141,4 +141,5 @@ var defaultTemplate = &Template{ defaultDropTableLayout, defaultSelectCountLayout, defaultGroupByLayout, + nil, } diff --git a/util/sqlgen/main.go b/util/sqlgen/main.go index 41801bf95c747941810ab6282483c6bad45d8f86..098c113ced577d2df119eded5cd585b42ea513ce 100644 --- a/util/sqlgen/main.go +++ b/util/sqlgen/main.go @@ -24,14 +24,21 @@ type ( Extra string ) -func mustParse(text string, data interface{}) string { +var parsedTemplates = make(map[string]*template.Template) + +func mustParse(text string, data interface{}) (compiled string) { var b bytes.Buffer + var ok bool - t := template.Must(template.New("").Parse(text)) + if _, ok = parsedTemplates[text]; ok == false { + parsedTemplates[text] = template.Must(template.New("").Parse(text)) + } - if err := t.Execute(&b, data); err != nil { - panic("t.Execute: " + err.Error()) + if err := parsedTemplates[text].Execute(&b, data); err != nil { + panic("There was an error compiling the following template:\n" + text + "\nError was: " + err.Error()) } - return b.String() + compiled = b.String() + + return } diff --git a/util/sqlgen/statement.go b/util/sqlgen/statement.go index a7a8fea46b711df2db5108a01c70199e6148acbf..0efd906aad2518a82c5753959ce6914f77c6096c 100644 --- a/util/sqlgen/statement.go +++ b/util/sqlgen/statement.go @@ -29,7 +29,7 @@ type statement_s struct { Where string } -func (self *Statement) Compile(layout *Template) string { +func (self *Statement) Compile(layout *Template) (compiled string) { data := statement_s{ Table: self.Table.Compile(layout), @@ -47,21 +47,24 @@ func (self *Statement) Compile(layout *Template) string { switch self.Type { case SqlTruncate: - return mustParse(layout.TruncateLayout, data) + compiled = mustParse(layout.TruncateLayout, data) case SqlDropTable: - return mustParse(layout.DropTableLayout, data) + compiled = mustParse(layout.DropTableLayout, data) case SqlDropDatabase: - return mustParse(layout.DropDatabaseLayout, data) + compiled = mustParse(layout.DropDatabaseLayout, data) case SqlSelectCount: - return mustParse(layout.SelectCountLayout, data) + compiled = mustParse(layout.SelectCountLayout, data) case SqlSelect: - return mustParse(layout.SelectLayout, data) + compiled = mustParse(layout.SelectLayout, data) case SqlDelete: - return mustParse(layout.DeleteLayout, data) + compiled = mustParse(layout.DeleteLayout, data) case SqlUpdate: - return mustParse(layout.UpdateLayout, data) + compiled = mustParse(layout.UpdateLayout, data) case SqlInsert: - return mustParse(layout.InsertLayout, data) + compiled = mustParse(layout.InsertLayout, data) + default: + compiled = "" } - return "" + + return compiled } diff --git a/util/sqlgen/table.go b/util/sqlgen/table.go index 4802b892fd47571ba22ebabdc8f2029b078af923..50331770a9b0601e16c489f39fb3463e4a8dcf01 100644 --- a/util/sqlgen/table.go +++ b/util/sqlgen/table.go @@ -50,8 +50,13 @@ func quotedTableName(layout *Template, input string) string { return mustParse(layout.TableAliasLayout, table_t{name, alias}) } -func (self Table) Compile(layout *Template) string { +func (self Table) Hash() string { + return self.Name +} + +func (self Table) Compile(layout *Template) (compiled string) { + // Splitting tables by a comma parts := reTableSeparator.Split(self.Name, -1) l := len(parts) @@ -60,5 +65,7 @@ func (self Table) Compile(layout *Template) string { parts[i] = quotedTableName(layout, parts[i]) } - return strings.Join(parts, layout.IdentifierSeparator) + compiled = strings.Join(parts, layout.IdentifierSeparator) + + return compiled } diff --git a/util/sqlgen/template.go b/util/sqlgen/template.go index ada77c19bc1f2b9ffe029ca038ef99e6d86d7e69..ac399094ff8860fb0562651ea3d7566f3c783c7d 100644 --- a/util/sqlgen/template.go +++ b/util/sqlgen/template.go @@ -29,4 +29,21 @@ type Template struct { DropTableLayout string SelectCountLayout string GroupByLayout string + cache map[interface{}]string +} + +func (self *Template) SetCache(key interface{}, value string) { + if self.cache == nil { + self.cache = make(map[interface{}]string) + } + self.cache[key] = value +} + +func (self *Template) Cache(key interface{}) (string, bool) { + if self.cache != nil { + if s, ok := self.cache[key]; ok { + return s, true + } + } + return "", false }