package orm
import (
)
var defaultFmter = NewFormatter()
type queryWithSepAppender interface {
QueryAppender
AppendSep([]byte) []byte
}
type SafeQueryAppender struct {
query string
params []interface{}
}
var (
_ QueryAppender = (*SafeQueryAppender)(nil)
_ types.ValueAppender = (*SafeQueryAppender)(nil)
)
func ( string, ...interface{}) *SafeQueryAppender {
return &SafeQueryAppender{, }
}
func ( *SafeQueryAppender) ( QueryFormatter, []byte) ([]byte, error) {
return .FormatQuery(, .query, .params...), nil
}
func ( *SafeQueryAppender) ( []byte, int) ([]byte, error) {
return .AppendQuery(defaultFmter, )
}
func ( *SafeQueryAppender) () types.Safe {
, := .AppendValue(nil, 1)
if != nil {
return types.Safe(.Error())
}
return types.Safe(internal.BytesToString())
}
type condGroupAppender struct {
sep string
cond []queryWithSepAppender
}
var (
_ QueryAppender = (*condAppender)(nil)
_ queryWithSepAppender = (*condAppender)(nil)
)
func ( *condGroupAppender) ( []byte) []byte {
return append(, .sep...)
}
func ( *condGroupAppender) ( QueryFormatter, []byte) ( []byte, error) {
= append(, '(')
for , := range .cond {
if > 0 {
= .AppendSep()
}
, = .AppendQuery(, )
if != nil {
return nil,
}
}
= append(, ')')
return , nil
}
type condAppender struct {
sep string
cond string
params []interface{}
}
var (
_ QueryAppender = (*condAppender)(nil)
_ queryWithSepAppender = (*condAppender)(nil)
)
func ( *condAppender) ( []byte) []byte {
return append(, .sep...)
}
func ( *condAppender) ( QueryFormatter, []byte) ([]byte, error) {
= append(, '(')
= .FormatQuery(, .cond, .params...)
= append(, ')')
return , nil
}
type fieldAppender struct {
field string
}
var _ QueryAppender = (*fieldAppender)(nil)
func ( fieldAppender) ( QueryFormatter, []byte) ([]byte, error) {
return types.AppendIdent(, .field, 1), nil
}
type dummyFormatter struct{}
func ( dummyFormatter) ( []byte, string, ...interface{}) []byte {
return append(, ...)
}
func ( QueryFormatter) bool {
, := .(dummyFormatter)
return
}
type QueryFormatter interface {
FormatQuery(b []byte, query string, params ...interface{}) []byte
}
type Formatter struct {
namedParams map[string]interface{}
model TableModel
}
var _ QueryFormatter = (*Formatter)(nil)
func () *Formatter {
return new(Formatter)
}
func ( *Formatter) () string {
if len(.namedParams) == 0 {
return ""
}
:= make([]string, len(.namedParams))
:= 0
for := range .namedParams {
[] =
++
}
sort.Strings()
:= make([]string, len())
for , := range {
[] = fmt.Sprintf("%s=%v", , .namedParams[])
}
return " " + strings.Join(, " ")
}
func ( *Formatter) () *Formatter {
:= NewFormatter()
.model = .model
if len(.namedParams) > 0 {
.namedParams = make(map[string]interface{}, len(.namedParams))
}
for , := range .namedParams {
.setParam(, )
}
return
}
func ( *Formatter) ( TableModel) *Formatter {
:= .clone()
.model =
return
}
func ( *Formatter) ( interface{}) *Formatter {
switch model := .(type) {
case TableModel:
return .WithTableModel()
case *Query:
return .WithTableModel(.tableModel)
case QueryCommand:
return .WithTableModel(.Query().tableModel)
default:
panic(fmt.Errorf("pg: unsupported model %T", ))
}
}
func ( *Formatter) ( string, interface{}) {
if .namedParams == nil {
.namedParams = make(map[string]interface{})
}
.namedParams[] =
}
func ( *Formatter) ( string, interface{}) *Formatter {
:= .clone()
.setParam(, )
return
}
func ( *Formatter) ( string) interface{} {
return .namedParams[]
}
func ( *Formatter) () bool {
return len(.namedParams) > 0 || .model != nil
}
func ( *Formatter) (, []byte, ...interface{}) []byte {
if ( == nil && !.hasParams()) || bytes.IndexByte(, '?') == -1 {
return append(, ...)
}
return .append(, parser.New(), )
}
func ( *Formatter) ( []byte, string, ...interface{}) []byte {
if ( == nil && !.hasParams()) || strings.IndexByte(, '?') == -1 {
return append(, ...)
}
return .append(, parser.NewString(), )
}
func ( *Formatter) ( []byte, *parser.Parser, []interface{}) []byte {
var int
var bool
var *tableParams
for .Valid() {
, := .ReadSep('?')
if ! {
= append(, ...)
continue
}
if len() > 0 && [len()-1] == '\\' {
= append(, [:len()-1]...)
= append(, '?')
continue
}
= append(, ...)
, := .ReadIdentifier()
if != "" {
if {
, := strconv.Atoi()
if != nil {
goto
}
if >= len() {
goto
}
= .appendParam(, [])
continue
}
if .namedParams != nil {
, := .namedParams[]
if {
= .appendParam(, )
continue
}
}
if ! && len() > 0 {
= true
, _ = newTableParams([len()-1])
}
if != nil {
, = .AppendParam(, , )
if {
continue
}
}
if .model != nil {
, = .model.AppendParam(, , )
if {
continue
}
}
:
= append(, '?')
= append(, ...)
continue
}
if >= len() {
= append(, '?')
continue
}
:= []
++
= .appendParam(, )
}
return
}
func ( *Formatter) ( []byte, interface{}) []byte {
switch param := .(type) {
case QueryAppender:
, := .AppendQuery(, )
if != nil {
return types.AppendError(, )
}
return
default:
return types.Append(, , 1)
}
}