Skip to content

Instantly share code, notes, and snippets.

@bbq-all-stars
Last active December 26, 2018 11:34
Show Gist options
  • Save bbq-all-stars/bb056fbc2a87f4d90fd2cfd12784f44f to your computer and use it in GitHub Desktop.
Save bbq-all-stars/bb056fbc2a87f4d90fd2cfd12784f44f to your computer and use it in GitHub Desktop.
Goで柔軟なQuery Builder的なもの
package main
import "fmt"
func main() {
query := Query{
SingleQuery{
And: []QueryInterface{
ComparisonFormula{
Eq: []ValueInterface{
AdminCreateTime, ValueInt(1),
},
},
},
},
SingleQuery{
And: []QueryInterface{
ComparisonFormula{
Eq: []ValueInterface{
AdminId, ValueInt(10),
},
},
},
},
SingleQuery{
And: []QueryInterface{
SingleQuery{
And: []QueryInterface{
ComparisonFormula{
Eq: []ValueInterface{
AdminId, ValueInt(10),
},
},
},
},
SingleQuery{
Or: []QueryInterface{
ComparisonFormula{
Eq: []ValueInterface{
AdminId, ValueInt(10),
},
},
},
},
},
},
}
println(query.Build())
}
// generated
type AdminColumn string
const (
AdminCreateTime AdminColumn = "create_time"
AdminId AdminColumn = "id"
)
func (a AdminColumn) Value() string {
return string(a)
}
// common
type ComparisonOperator string
const (
Eq ComparisonOperator = "="
NotEq ComparisonOperator = "!="
)
type LogicalOperator string
const (
And LogicalOperator = "AND"
Or LogicalOperator = "OR"
)
type QueryInterface interface {
Build() string
}
type Query []SingleQuery
func (q Query) Build() string {
rawQuery := ""
for _, singleQuery := range q {
rawQuery += singleQuery.Build() + " "
}
return rawQuery
}
type SingleQuery map[LogicalOperator][]QueryInterface
func (q SingleQuery) Build() string {
var queries []QueryInterface
rawQuery := ""
if andQueries, ok := q[And]; ok {
rawQuery += " " + string(And)+ " "
queries = andQueries
}
if orQueries, ok := q[Or]; ok {
rawQuery += " " + string(Or)+ " "
queries = orQueries
}
for _, query := range queries {
if singleQuery, ok := query.(SingleQuery); ok {
rawQuery += "(" + singleQuery.Build() +")"
} else {
rawQuery += " " + query.Build() + " "
}
}
return rawQuery
}
type ComparisonFormula map[ComparisonOperator][]ValueInterface
func (c ComparisonFormula) Build() string {
operator := ""
var values []ValueInterface
if eqValue, ok := c[Eq]; ok {
operator = string(Eq)
values = eqValue
}
if eqValue, ok := c[NotEq]; ok {
operator = string(NotEq)
values = eqValue
}
return values[0].Value() + " " + operator + " " + values[1].Value()
}
type ValueInterface interface {
Value() string
}
type ValueInt int
func (i ValueInt) Value() string {
return fmt.Sprintf("%d", i)
}
type ValueString string
func (s ValueString) Value() string {
return `"` + string(s) + `"`
}
@bbq-all-stars
Copy link
Author

 AND  create_time = 1   AND  id = 10   AND ( AND  id = 10 )( OR  id = 10 ) 

なおうまく動かない模様

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment