mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
* add query builder to facilitate dynamic SQL construction * leverage query builder to refactor user store This is partially setup work for MM-13120, but merged to master to avoid further conflicts. * fix unrelated unit test breakage * documentation tweaks * Apply suggestions from code review Co-Authored-By: lieut-data <jesse.hallam@gmail.com> * prefer comma separated case options to fallthrough * vendor github.com/Masterminds/squirrel and deps * switch to using github.com/Masterminds/squirrel * rm querybuilder
85 lines
1.9 KiB
Go
85 lines
1.9 KiB
Go
package squirrel
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
// PlaceholderFormat is the interface that wraps the ReplacePlaceholders method.
|
|
//
|
|
// ReplacePlaceholders takes a SQL statement and replaces each question mark
|
|
// placeholder with a (possibly different) SQL placeholder.
|
|
type PlaceholderFormat interface {
|
|
ReplacePlaceholders(sql string) (string, error)
|
|
}
|
|
|
|
var (
|
|
// Question is a PlaceholderFormat instance that leaves placeholders as
|
|
// question marks.
|
|
Question = questionFormat{}
|
|
|
|
// Dollar is a PlaceholderFormat instance that replaces placeholders with
|
|
// dollar-prefixed positional placeholders (e.g. $1, $2, $3).
|
|
Dollar = dollarFormat{}
|
|
|
|
// Colon is a PlaceholderFormat instance that replaces placeholders with
|
|
// colon-prefixed positional placeholders (e.g. :1, :2, :3).
|
|
Colon = colonFormat{}
|
|
)
|
|
|
|
type questionFormat struct{}
|
|
|
|
func (questionFormat) ReplacePlaceholders(sql string) (string, error) {
|
|
return sql, nil
|
|
}
|
|
|
|
type dollarFormat struct{}
|
|
|
|
func (dollarFormat) ReplacePlaceholders(sql string) (string, error) {
|
|
return replacePositionalPlaceholders(sql, "$")
|
|
}
|
|
|
|
type colonFormat struct{}
|
|
|
|
func (colonFormat) ReplacePlaceholders(sql string) (string, error) {
|
|
return replacePositionalPlaceholders(sql, ":")
|
|
}
|
|
|
|
// Placeholders returns a string with count ? placeholders joined with commas.
|
|
func Placeholders(count int) string {
|
|
if count < 1 {
|
|
return ""
|
|
}
|
|
|
|
return strings.Repeat(",?", count)[1:]
|
|
}
|
|
|
|
func replacePositionalPlaceholders(sql, prefix string) (string, error) {
|
|
buf := &bytes.Buffer{}
|
|
i := 0
|
|
for {
|
|
p := strings.Index(sql, "?")
|
|
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 {
|
|
i++
|
|
buf.WriteString(sql[:p])
|
|
fmt.Fprintf(buf, "%s%d", prefix, i)
|
|
sql = sql[p+1:]
|
|
}
|
|
}
|
|
|
|
buf.WriteString(sql)
|
|
return buf.String(), nil
|
|
}
|