add BuildNamed

This commit is contained in:
Huan Du
2017-12-31 20:31:07 +08:00
parent ff11beaf50
commit eef30ff185
4 changed files with 42 additions and 3 deletions
+1
View File
@@ -44,6 +44,7 @@ Following builders are implemented right now. API document and examples are prov
* [DeleteBuilder](https://godoc.org/github.com/huandu/go-sqlbuilder#DeleteBuilder): Builder for DELETE.
* [Buildf](https://godoc.org/github.com/huandu/go-sqlbuilder#Buildf): Freestyle builder using `fmt.Sprintf`-like syntax.
* [Build](https://godoc.org/github.com/huandu/go-sqlbuilder#Build): Advanced freestyle builder using special syntax defined in [Args#Compile](https://godoc.org/github.com/huandu/go-sqlbuilder#Args.Compile).
* [BuildNamed](https://godoc.org/github.com/huandu/go-sqlbuilder#BuildNamed): Advanced freestyle builder using `${key}` to refer the value of a map by key.
### Using `Struct` as a light weight ORM ###
+3 -2
View File
@@ -17,6 +17,7 @@ type Args struct {
args []interface{}
namedArgs map[string]int
sqlNamedArgs map[string]int
onlyNamed bool
}
// Add adds an arg to Args and returns a placeholder.
@@ -89,9 +90,9 @@ func (args *Args) Compile(format string) (query string, values []interface{}) {
format = format[1:]
} else if format[0] == '{' {
format, values = args.compileNamed(buf, format, values)
} else if '0' <= format[0] && format[0] <= '9' {
} else if !args.onlyNamed && '0' <= format[0] && format[0] <= '9' {
format, values, offset = args.compileDigits(buf, format, values, offset)
} else if format[0] == '?' {
} else if !args.onlyNamed && format[0] == '?' {
format, values, offset = args.compileSuccessive(buf, format[1:], values, offset)
}
+19 -1
View File
@@ -44,7 +44,7 @@ func Buildf(format string, arg ...interface{}) Builder {
}
// Build creates a Builder from a format string.
// The format string uses a special syntax to represent arguments.
// The format string uses special syntax to represent arguments.
// See doc in `Args#Compile` for syntax details.
func Build(format string, arg ...interface{}) Builder {
args := &Args{}
@@ -59,3 +59,21 @@ func Build(format string, arg ...interface{}) Builder {
args: values,
}
}
// BuildNamed creates a Builder from a format string.
// The format string uses `${key}` to refer the value of named by key.
func BuildNamed(format string, named map[string]interface{}) Builder {
args := &Args{
onlyNamed: true,
}
for n, v := range named {
args.Add(Named(n, v))
}
sql, values := args.Compile(format)
return &compiledBuilder{
sql: sql,
args: values,
}
}
+19
View File
@@ -4,6 +4,7 @@
package sqlbuilder
import (
"database/sql"
"fmt"
)
@@ -36,3 +37,21 @@ func ExampleBuild() {
// EXPLAIN SELECT id FROM user WHERE status IN (?, ?) LEFT JOIN SELECT * FROM banned WHERE created_at > ? AND state IN (?, ?, ?) AND modified_at BETWEEN ? AND ?
// [1 2 1514458225 3 4 5 1514458225 1514544625]
}
func ExampleBuildNamed() {
b := BuildNamed("SELECT * FROM ${table} WHERE status IN (${status}) AND name LIKE ${name} AND created_at > ${time} AND modified_at < ${time} + 86400",
map[string]interface{}{
"time": sql.Named("start", 1234567890),
"status": List([]int{1, 2, 5}),
"name": "Huan%",
"table": Raw("user"),
})
sql, args := b.Build()
fmt.Println(sql)
fmt.Println(args)
// Output:
// SELECT * FROM user WHERE status IN (?, ?, ?) AND name LIKE ? AND created_at > @start AND modified_at < @start + 86400
// [1 2 5 Huan% {{} start 1234567890}]
}