Add quote dialects
This commit is contained in:
parent
817189fbfd
commit
9e6a3d5ee3
9 changed files with 109 additions and 9 deletions
|
@ -123,3 +123,18 @@ func (m *MockDriver) Open() error { return nil }
|
|||
|
||||
// Close mimics a database close call
|
||||
func (m *MockDriver) Close() {}
|
||||
|
||||
// RightQuote is the quoting character for the right side of the identifier
|
||||
func (m *MockDriver) RightQuote() string {
|
||||
return "`"
|
||||
}
|
||||
|
||||
// LeftQuote is the quoting character for the left side of the identifier
|
||||
func (m *MockDriver) LeftQuote() string {
|
||||
return `"`
|
||||
}
|
||||
|
||||
// IndexPlaceholders returns true to indicate fake support of indexed placeholders
|
||||
func (m *MockDriver) IndexPlaceholders() bool {
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -318,3 +318,18 @@ func mySQLIsValidated(typ string) bool {
|
|||
|
||||
return false
|
||||
}
|
||||
|
||||
// RightQuote is the quoting character for the right side of the identifier
|
||||
func (m *MySQLDriver) RightQuote() string {
|
||||
return "`"
|
||||
}
|
||||
|
||||
// LeftQuote is the quoting character for the left side of the identifier
|
||||
func (m *MySQLDriver) LeftQuote() string {
|
||||
return "`"
|
||||
}
|
||||
|
||||
// IndexPlaceholders returns false to indicate MySQL doesnt support indexed placeholders
|
||||
func (m *MySQLDriver) IndexPlaceholders() bool {
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -340,3 +340,18 @@ func psqlIsValidated(typ string) bool {
|
|||
|
||||
return false
|
||||
}
|
||||
|
||||
// RightQuote is the quoting character for the right side of the identifier
|
||||
func (p *PostgresDriver) RightQuote() string {
|
||||
return `"`
|
||||
}
|
||||
|
||||
// LeftQuote is the quoting character for the left side of the identifier
|
||||
func (p *PostgresDriver) LeftQuote() string {
|
||||
return `"`
|
||||
}
|
||||
|
||||
// IndexPlaceholders returns true to indicate PSQL supports indexed placeholders
|
||||
func (p *PostgresDriver) IndexPlaceholders() bool {
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -22,6 +22,13 @@ type Interface interface {
|
|||
Open() error
|
||||
// Close the database connection
|
||||
Close()
|
||||
|
||||
// Dialect helpers, these provide the values that will go into
|
||||
// a boil.Dialect, so the query builder knows how to support
|
||||
// your database driver properly.
|
||||
LeftQuote() string
|
||||
RightQuote() string
|
||||
IndexPlaceholders() bool
|
||||
}
|
||||
|
||||
// Tables returns the metadata for all tables, minus the tables
|
||||
|
|
|
@ -19,6 +19,7 @@ const (
|
|||
// Query holds the state for the built up query
|
||||
type Query struct {
|
||||
executor Executor
|
||||
dialect *Dialect
|
||||
plainSQL plainSQL
|
||||
load []string
|
||||
delete bool
|
||||
|
@ -37,6 +38,20 @@ type Query struct {
|
|||
forlock string
|
||||
}
|
||||
|
||||
// Dialect holds values that direct the query builder
|
||||
// how to build compatible queries for each database.
|
||||
// Each database driver needs to implement functions
|
||||
// that provide these values.
|
||||
type Dialect struct {
|
||||
// The left quote character for SQL identifiers
|
||||
LQ string
|
||||
// The right quote character for SQL identifiers
|
||||
RQ string
|
||||
// Bool flag indicating whether indexed
|
||||
// placeholders ($1) are used, or ? placeholders.
|
||||
IndexPlaceholders bool
|
||||
}
|
||||
|
||||
type where struct {
|
||||
clause string
|
||||
orSeparator bool
|
||||
|
@ -121,6 +136,11 @@ func GetExecutor(q *Query) Executor {
|
|||
return q.executor
|
||||
}
|
||||
|
||||
// SetDialect on the query.
|
||||
func SetDialect(q *Query, dialect *Dialect) {
|
||||
q.dialect = dialect
|
||||
}
|
||||
|
||||
// SetSQL on the query.
|
||||
func SetSQL(q *Query, sql string, args ...interface{}) {
|
||||
q.plainSQL = plainSQL{sql: sql, args: args}
|
||||
|
|
|
@ -34,6 +34,7 @@ type State struct {
|
|||
|
||||
Driver bdb.Interface
|
||||
Tables []bdb.Table
|
||||
Dialect boil.Dialect
|
||||
|
||||
Templates *templateList
|
||||
TestTemplates *templateList
|
||||
|
@ -102,6 +103,7 @@ func (s *State) Run(includeTests bool) error {
|
|||
PkgName: s.Config.PkgName,
|
||||
NoHooks: s.Config.NoHooks,
|
||||
NoAutoTimestamps: s.Config.NoAutoTimestamps,
|
||||
Dialect: s.Dialect,
|
||||
|
||||
StringFuncs: templateStringMappers,
|
||||
}
|
||||
|
@ -135,6 +137,7 @@ func (s *State) Run(includeTests bool) error {
|
|||
NoHooks: s.Config.NoHooks,
|
||||
NoAutoTimestamps: s.Config.NoAutoTimestamps,
|
||||
Tags: s.Config.Tags,
|
||||
Dialect: s.Dialect,
|
||||
|
||||
StringFuncs: templateStringMappers,
|
||||
}
|
||||
|
@ -246,6 +249,10 @@ func (s *State) initDriver(driverName string) error {
|
|||
return errors.New("An invalid driver name was provided")
|
||||
}
|
||||
|
||||
s.Dialect.LQ = s.Driver.LeftQuote()
|
||||
s.Dialect.RQ = s.Driver.RightQuote()
|
||||
s.Dialect.IndexPlaceholders = s.Driver.IndexPlaceholders()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,18 @@ func SchemaTable(driver string, schema string, table string) string {
|
|||
return fmt.Sprintf(`"%s"`, table)
|
||||
}
|
||||
|
||||
// WrapQuote wraps a quote character in quotes.
|
||||
func WrapQuote(s string) string {
|
||||
if s == `"` {
|
||||
return "`\"`"
|
||||
}
|
||||
if s == "`" {
|
||||
return "\"`\""
|
||||
}
|
||||
|
||||
return fmt.Sprintf("`%s`", s)
|
||||
}
|
||||
|
||||
// IdentQuote attempts to quote simple identifiers in SQL tatements
|
||||
func IdentQuote(s string) string {
|
||||
if strings.ToLower(s) == "null" {
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"text/template"
|
||||
|
||||
"github.com/vattle/sqlboiler/bdb"
|
||||
"github.com/vattle/sqlboiler/boil"
|
||||
"github.com/vattle/sqlboiler/strmangle"
|
||||
)
|
||||
|
||||
|
@ -22,8 +23,8 @@ type templateData struct {
|
|||
NoHooks bool
|
||||
NoAutoTimestamps bool
|
||||
Tags []string
|
||||
|
||||
StringFuncs map[string]func(string) string
|
||||
Dialect boil.Dialect
|
||||
}
|
||||
|
||||
type templateList struct {
|
||||
|
@ -116,6 +117,7 @@ var templateFunctions = template.FuncMap{
|
|||
// String ops
|
||||
"quoteWrap": func(a string) string { return fmt.Sprintf(`"%s"`, a) },
|
||||
"id": strmangle.Identifier,
|
||||
"wrapQuote": strmangle.WrapQuote,
|
||||
|
||||
// Pluralization
|
||||
"singular": strmangle.Singular,
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
var dialect boil.Dialect = boil.Dialect{
|
||||
LQ: {{wrapQuote .Dialect.LQ}},
|
||||
RQ: {{wrapQuote .Dialect.RQ}},
|
||||
IndexPlaceholders: {{.Dialect.IndexPlaceholders}},
|
||||
}
|
||||
|
||||
// NewQueryG initializes a new Query using the passed in QueryMods
|
||||
func NewQueryG(mods ...qm.QueryMod) *boil.Query {
|
||||
return NewQuery(boil.GetDB(), mods...)
|
||||
|
@ -7,6 +13,7 @@ func NewQueryG(mods ...qm.QueryMod) *boil.Query {
|
|||
func NewQuery(exec boil.Executor, mods ...qm.QueryMod) *boil.Query {
|
||||
q := &boil.Query{}
|
||||
boil.SetExecutor(q, exec)
|
||||
boil.SetDialect(q, &dialect)
|
||||
qm.Apply(q, mods...)
|
||||
|
||||
return q
|
||||
|
|
Loading…
Reference in a new issue