summaryrefslogtreecommitdiff
path: root/vendor/github.com/Masterminds/squirrel/squirrel.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/Masterminds/squirrel/squirrel.go')
-rw-r--r--vendor/github.com/Masterminds/squirrel/squirrel.go183
1 files changed, 183 insertions, 0 deletions
diff --git a/vendor/github.com/Masterminds/squirrel/squirrel.go b/vendor/github.com/Masterminds/squirrel/squirrel.go
new file mode 100644
index 0000000..46d456e
--- /dev/null
+++ b/vendor/github.com/Masterminds/squirrel/squirrel.go
@@ -0,0 +1,183 @@
+// Package squirrel provides a fluent SQL generator.
+//
+// See https://github.com/Masterminds/squirrel for examples.
+package squirrel
+
+import (
+ "bytes"
+ "database/sql"
+ "fmt"
+ "strings"
+
+ "github.com/lann/builder"
+)
+
+// Sqlizer is the interface that wraps the ToSql method.
+//
+// ToSql returns a SQL representation of the Sqlizer, along with a slice of args
+// as passed to e.g. database/sql.Exec. It can also return an error.
+type Sqlizer interface {
+ ToSql() (string, []interface{}, error)
+}
+
+// rawSqlizer is expected to do what Sqlizer does, but without finalizing placeholders.
+// This is useful for nested queries.
+type rawSqlizer interface {
+ toSqlRaw() (string, []interface{}, error)
+}
+
+// Execer is the interface that wraps the Exec method.
+//
+// Exec executes the given query as implemented by database/sql.Exec.
+type Execer interface {
+ Exec(query string, args ...interface{}) (sql.Result, error)
+}
+
+// Queryer is the interface that wraps the Query method.
+//
+// Query executes the given query as implemented by database/sql.Query.
+type Queryer interface {
+ Query(query string, args ...interface{}) (*sql.Rows, error)
+}
+
+// QueryRower is the interface that wraps the QueryRow method.
+//
+// QueryRow executes the given query as implemented by database/sql.QueryRow.
+type QueryRower interface {
+ QueryRow(query string, args ...interface{}) RowScanner
+}
+
+// BaseRunner groups the Execer and Queryer interfaces.
+type BaseRunner interface {
+ Execer
+ Queryer
+}
+
+// Runner groups the Execer, Queryer, and QueryRower interfaces.
+type Runner interface {
+ Execer
+ Queryer
+ QueryRower
+}
+
+// WrapStdSql wraps a type implementing the standard SQL interface with methods that
+// squirrel expects.
+func WrapStdSql(stdSql StdSql) Runner {
+ return &stdsqlRunner{stdSql}
+}
+
+// StdSql encompasses the standard methods of the *sql.DB type, and other types that
+// wrap these methods.
+type StdSql interface {
+ Query(string, ...interface{}) (*sql.Rows, error)
+ QueryRow(string, ...interface{}) *sql.Row
+ Exec(string, ...interface{}) (sql.Result, error)
+}
+
+type stdsqlRunner struct {
+ StdSql
+}
+
+func (r *stdsqlRunner) QueryRow(query string, args ...interface{}) RowScanner {
+ return r.StdSql.QueryRow(query, args...)
+}
+
+func setRunWith(b interface{}, runner BaseRunner) interface{} {
+ switch r := runner.(type) {
+ case StdSqlCtx:
+ runner = WrapStdSqlCtx(r)
+ case StdSql:
+ runner = WrapStdSql(r)
+ }
+ return builder.Set(b, "RunWith", runner)
+}
+
+// RunnerNotSet is returned by methods that need a Runner if it isn't set.
+var RunnerNotSet = fmt.Errorf("cannot run; no Runner set (RunWith)")
+
+// RunnerNotQueryRunner is returned by QueryRow if the RunWith value doesn't implement QueryRower.
+var RunnerNotQueryRunner = fmt.Errorf("cannot QueryRow; Runner is not a QueryRower")
+
+// ExecWith Execs the SQL returned by s with db.
+func ExecWith(db Execer, s Sqlizer) (res sql.Result, err error) {
+ query, args, err := s.ToSql()
+ if err != nil {
+ return
+ }
+ return db.Exec(query, args...)
+}
+
+// QueryWith Querys the SQL returned by s with db.
+func QueryWith(db Queryer, s Sqlizer) (rows *sql.Rows, err error) {
+ query, args, err := s.ToSql()
+ if err != nil {
+ return
+ }
+ return db.Query(query, args...)
+}
+
+// QueryRowWith QueryRows the SQL returned by s with db.
+func QueryRowWith(db QueryRower, s Sqlizer) RowScanner {
+ query, args, err := s.ToSql()
+ return &Row{RowScanner: db.QueryRow(query, args...), err: err}
+}
+
+// DebugSqlizer calls ToSql on s and shows the approximate SQL to be executed
+//
+// If ToSql returns an error, the result of this method will look like:
+// "[ToSql error: %s]" or "[DebugSqlizer error: %s]"
+//
+// IMPORTANT: As its name suggests, this function should only be used for
+// debugging. While the string result *might* be valid SQL, this function does
+// not try very hard to ensure it. Additionally, executing the output of this
+// function with any untrusted user input is certainly insecure.
+func DebugSqlizer(s Sqlizer) string {
+ sql, args, err := s.ToSql()
+ if err != nil {
+ return fmt.Sprintf("[ToSql error: %s]", err)
+ }
+
+ var placeholder string
+ downCast, ok := s.(placeholderDebugger)
+ if !ok {
+ placeholder = "?"
+ } else {
+ placeholder = downCast.debugPlaceholder()
+ }
+ // TODO: dedupe this with placeholder.go
+ buf := &bytes.Buffer{}
+ i := 0
+ for {
+ p := strings.Index(sql, placeholder)
+ if p == -1 {
+ break
+ }
+ if len(sql[p:]) > 1 && sql[p:p+2] == "??" { // escape ?? => ?
+ buf.WriteString(sql[:p])
+ buf.WriteString("?")
+ if len(sql[p:]) == 1 {
+ break
+ }
+ sql = sql[p+2:]
+ } else {
+ if i+1 > len(args) {
+ return fmt.Sprintf(
+ "[DebugSqlizer error: too many placeholders in %#v for %d args]",
+ sql, len(args))
+ }
+ buf.WriteString(sql[:p])
+ fmt.Fprintf(buf, "'%v'", args[i])
+ // advance our sql string "cursor" beyond the arg we placed
+ sql = sql[p+1:]
+ i++
+ }
+ }
+ if i < len(args) {
+ return fmt.Sprintf(
+ "[DebugSqlizer error: not enough placeholders in %#v for %d args]",
+ sql, len(args))
+ }
+ // "append" any remaning sql that won't need interpolating
+ buf.WriteString(sql)
+ return buf.String()
+}