123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- // Copyright 2018 Huan Du. All rights reserved.
- // Licensed under the MIT license that can be found in the LICENSE file.
- package sqlbuilder
- import (
- "fmt"
- )
- // Builder is a general SQL builder.
- // It's used by Args to create nested SQL like the `IN` expression in
- // `SELECT * FROM t1 WHERE id IN (SELECT id FROM t2)`.
- type Builder interface {
- Build() (sql string, args []interface{})
- BuildWithFlavor(flavor Flavor, initialArg ...interface{}) (sql string, args []interface{})
- }
- type compiledBuilder struct {
- args *Args
- format string
- }
- func (cb *compiledBuilder) Build() (sql string, args []interface{}) {
- return cb.args.Compile(cb.format)
- }
- func (cb *compiledBuilder) BuildWithFlavor(flavor Flavor, initialArg ...interface{}) (sql string, args []interface{}) {
- return cb.args.CompileWithFlavor(cb.format, flavor, initialArg...)
- }
- type flavoredBuilder struct {
- builder Builder
- flavor Flavor
- }
- func (fb *flavoredBuilder) Build() (sql string, args []interface{}) {
- return fb.builder.BuildWithFlavor(fb.flavor)
- }
- func (fb *flavoredBuilder) BuildWithFlavor(flavor Flavor, initialArg ...interface{}) (sql string, args []interface{}) {
- return fb.builder.BuildWithFlavor(flavor, initialArg...)
- }
- // WithFlavor creates a new Builder based on builder with a default flavor.
- func WithFlavor(builder Builder, flavor Flavor) Builder {
- return &flavoredBuilder{
- builder: builder,
- flavor: flavor,
- }
- }
- // Buildf creates a Builder from a format string using `fmt.Sprintf`-like syntax.
- // As all arguments will be converted to a string internally, e.g. "$0",
- // only `%v` and `%s` are valid.
- func Buildf(format string, arg ...interface{}) Builder {
- args := &Args{
- Flavor: DefaultFlavor,
- }
- vars := make([]interface{}, 0, len(arg))
- for _, a := range arg {
- vars = append(vars, args.Add(a))
- }
- return &compiledBuilder{
- args: args,
- format: fmt.Sprintf(Escape(format), vars...),
- }
- }
- // Build creates a Builder from a format string.
- // 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{
- Flavor: DefaultFlavor,
- }
- for _, a := range arg {
- args.Add(a)
- }
- return &compiledBuilder{
- args: args,
- format: format,
- }
- }
- // 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{
- Flavor: DefaultFlavor,
- onlyNamed: true,
- }
- for n, v := range named {
- args.Add(Named(n, v))
- }
- return &compiledBuilder{
- args: args,
- format: format,
- }
- }
|