package orm
import (
)
type QueryOp string
const (
SelectOp QueryOp = "SELECT"
InsertOp QueryOp = "INSERT"
UpdateOp QueryOp = "UPDATE"
DeleteOp QueryOp = "DELETE"
CreateTableOp QueryOp = "CREATE TABLE"
DropTableOp QueryOp = "DROP TABLE"
CreateCompositeOp QueryOp = "CREATE COMPOSITE"
DropCompositeOp QueryOp = "DROP COMPOSITE"
)
type queryFlag uint8
const (
implicitModelFlag queryFlag = 1 << iota
deletedFlag
allWithDeletedFlag
)
type withQuery struct {
name string
query QueryAppender
}
type columnValue struct {
column string
value *SafeQueryAppender
}
type union struct {
expr string
query *Query
}
type Query struct {
ctx context.Context
db DB
stickyErr error
model Model
tableModel TableModel
flags queryFlag
with []withQuery
tables []QueryAppender
distinctOn []*SafeQueryAppender
columns []QueryAppender
set []QueryAppender
modelValues map[string]*SafeQueryAppender
extraValues []*columnValue
where []queryWithSepAppender
updWhere []queryWithSepAppender
group []QueryAppender
having []*SafeQueryAppender
union []*union
joins []QueryAppender
joinAppendOn func(app *condAppender)
order []QueryAppender
limit int
offset int
selFor *SafeQueryAppender
onConflict *SafeQueryAppender
returning []*SafeQueryAppender
}
func ( DB, ...interface{}) *Query {
:= context.Background()
if != nil {
= .Context()
}
:= &Query{ctx: }
return .DB().Model(...)
}
func ( context.Context, DB, ...interface{}) *Query {
return NewQuery(, ...).Context()
}
func ( *Query) () *Query {
:= &Query{
ctx: .ctx,
db: .db,
model: .model,
tableModel: cloneTableModelJoins(.tableModel),
flags: .flags,
}
return .withFlag(implicitModelFlag)
}
func ( *Query) () *Query {
var map[string]*SafeQueryAppender
if len(.modelValues) > 0 {
= make(map[string]*SafeQueryAppender, len(.modelValues))
for , := range .modelValues {
[] =
}
}
:= &Query{
ctx: .ctx,
db: .db,
stickyErr: .stickyErr,
model: .model,
tableModel: cloneTableModelJoins(.tableModel),
flags: .flags,
with: .with[:len(.with):len(.with)],
tables: .tables[:len(.tables):len(.tables)],
distinctOn: .distinctOn[:len(.distinctOn):len(.distinctOn)],
columns: .columns[:len(.columns):len(.columns)],
set: .set[:len(.set):len(.set)],
modelValues: ,
extraValues: .extraValues[:len(.extraValues):len(.extraValues)],
where: .where[:len(.where):len(.where)],
updWhere: .updWhere[:len(.updWhere):len(.updWhere)],
joins: .joins[:len(.joins):len(.joins)],
group: .group[:len(.group):len(.group)],
having: .having[:len(.having):len(.having)],
union: .union[:len(.union):len(.union)],
order: .order[:len(.order):len(.order)],
limit: .limit,
offset: .offset,
selFor: .selFor,
onConflict: .onConflict,
returning: .returning[:len(.returning):len(.returning)],
}
return
}
func ( TableModel) TableModel {
switch tm := .(type) {
case *structTableModel:
if len(.joins) == 0 {
return
}
:= *
.joins = .joins[:len(.joins):len(.joins)]
return &
case *sliceTableModel:
if len(.joins) == 0 {
return
}
:= *
.joins = .joins[:len(.joins):len(.joins)]
return &
}
return
}
func ( *Query) ( error) *Query {
if .stickyErr == nil {
.stickyErr =
}
return
}
func ( *Query) ( queryFlag) bool {
return hasFlag(.flags, )
}
func (, queryFlag) bool {
return & != 0
}
func ( *Query) ( queryFlag) *Query {
.flags |=
return
}
func ( *Query) ( queryFlag) *Query {
.flags &= ^
return
}
func ( *Query) ( context.Context) *Query {
.ctx =
return
}
func ( *Query) ( DB) *Query {
.db =
return
}
func ( *Query) ( ...interface{}) *Query {
var error
switch := len(); {
case == 0:
.model = nil
case == 1:
.model, = NewModel([0])
case > 1:
.model, = NewModel(&)
default:
panic("not reached")
}
if != nil {
= .err()
}
.tableModel, _ = .model.(TableModel)
return .withoutFlag(implicitModelFlag)
}
func ( *Query) () TableModel {
return .tableModel
}
func ( *Query) () bool {
if .tableModel != nil {
return .tableModel.Table().SoftDeleteField != nil && !.hasFlag(allWithDeletedFlag)
}
return false
}
func ( *Query) () *Query {
if .tableModel != nil {
if := .tableModel.Table().mustSoftDelete(); != nil {
return .err()
}
}
return .withFlag(deletedFlag).withoutFlag(allWithDeletedFlag)
}
func ( *Query) () *Query {
if .tableModel != nil {
if := .tableModel.Table().mustSoftDelete(); != nil {
return .err()
}
}
return .withFlag(allWithDeletedFlag).withoutFlag(deletedFlag)
}
func ( *Query) ( string, *Query) *Query {
return ._with(, NewSelectQuery())
}
func ( *Query) ( string, *Query) *Query {
return ._with(, NewInsertQuery())
}
func ( *Query) ( string, *Query) *Query {
return ._with(, NewUpdateQuery(, false))
}
func ( *Query) ( string, *Query) *Query {
return ._with(, NewDeleteQuery())
}
func ( *Query) ( string, QueryAppender) *Query {
.with = append(.with, withQuery{
name: ,
query: ,
})
return
}
func ( *Query) ( string) *Query {
:= .New()
.with = .with
.with = nil
= .With(, )
return
}
func ( *Query) ( ...string) *Query {
for , := range {
.tables = append(.tables, fieldAppender{})
}
return
}
func ( *Query) ( string, ...interface{}) *Query {
.tables = append(.tables, SafeQuery(, ...))
return
}
func ( *Query) () *Query {
.distinctOn = make([]*SafeQueryAppender, 0)
return
}
func ( *Query) ( string, ...interface{}) *Query {
.distinctOn = append(.distinctOn, SafeQuery(, ...))
return
}
func ( *Query) ( ...string) *Query {
for , := range {
if == "_" {
if .columns == nil {
.columns = make([]QueryAppender, 0)
}
continue
}
.columns = append(.columns, fieldAppender{})
}
return
}
func ( *Query) ( string, ...interface{}) *Query {
.columns = append(.columns, SafeQuery(, ...))
return
}
func ( *Query) ( ...string) *Query {
if .columns == nil {
for , := range .tableModel.Table().Fields {
.columns = append(.columns, fieldAppender{.SQLName})
}
}
for , := range {
if !.excludeColumn() {
return .err(fmt.Errorf("pg: can't find column=%q", ))
}
}
return
}
func ( *Query) ( string) bool {
for := 0; < len(.columns); ++ {
, := .columns[].(fieldAppender)
if && .field == {
.columns = append(.columns[:], .columns[+1:]...)
return true
}
}
return false
}
func ( *Query) () ([]*Field, error) {
return ._getFields(false)
}
func ( *Query) () ([]*Field, error) {
return ._getFields(true)
}
func ( *Query) ( bool) ([]*Field, error) {
:= .tableModel.Table()
:= make([]*Field, 0, len(.columns))
for , := range .columns {
, := .(fieldAppender)
if ! {
continue
}
, := .GetField(.field)
if != nil {
return nil,
}
if && .hasFlag(PrimaryKeyFlag) {
continue
}
= append(, )
}
return , nil
}
func ( *Query) ( string, ...func(*Query) (*Query, error)) *Query {
var func(*Query) (*Query, error)
if len() == 1 {
= [0]
} else if len() > 1 {
panic("only one apply function is supported")
}
:= .tableModel.Join(, )
if == nil {
return .err(fmt.Errorf("%s does not have relation=%q",
.tableModel.Table(), ))
}
if == nil {
return
}
switch .Rel.Type {
case HasOneRelation, BelongsToRelation:
.joinAppendOn = .AppendOn
return .Apply()
default:
.joinAppendOn = nil
return
}
}
func ( *Query) ( string, ...interface{}) *Query {
.set = append(.set, SafeQuery(, ...))
return
}
func ( *Query) ( string, string, ...interface{}) *Query {
if !.hasTableModel() {
.err(errModelNil)
return
}
:= .tableModel.Table()
if , := .FieldsMap[]; {
if .modelValues == nil {
.modelValues = make(map[string]*SafeQueryAppender)
}
.modelValues[] = SafeQuery(, ...)
} else {
.extraValues = append(.extraValues, &columnValue{
column: ,
value: SafeQuery(, ...),
})
}
return
}
func ( *Query) ( string, ...interface{}) *Query {
.addWhere(&condAppender{
sep: " AND ",
cond: ,
params: ,
})
return
}
func ( *Query) ( string, ...interface{}) *Query {
.addWhere(&condAppender{
sep: " OR ",
cond: ,
params: ,
})
return
}
func ( *Query) ( func(*Query) (*Query, error)) *Query {
return .whereGroup(" AND ", )
}
func ( *Query) ( func(*Query) (*Query, error)) *Query {
return .whereGroup(" AND NOT ", )
}
func ( *Query) ( func(*Query) (*Query, error)) *Query {
return .whereGroup(" OR ", )
}
func ( *Query) ( func(*Query) (*Query, error)) *Query {
return .whereGroup(" OR NOT ", )
}
func ( *Query) ( string, func(*Query) (*Query, error)) *Query {
:= .where
.where = nil
, := ()
if != nil {
.err()
return
}
if len(.where) == 0 {
.where =
return
}
:= &condGroupAppender{
sep: ,
cond: .where,
}
.where =
.addWhere()
return
}
func ( *Query) ( string, interface{}) *Query {
return .Where(, types.In())
}
func ( *Query) ( string, interface{}) *Query {
return .WhereOr(, types.In())
}
func ( *Query) ( string, ...interface{}) *Query {
return .Where(, types.InMulti(...))
}
func ( *Query) ( queryWithSepAppender) {
if .onConflictDoUpdate() {
.updWhere = append(.updWhere, )
} else {
.where = append(.where, )
}
}
func ( *Query) () *Query {
if !.hasTableModel() {
.err(errModelNil)
return
}
if := .tableModel.Table().checkPKs(); != nil {
.err()
return
}
switch .tableModel.Kind() {
case reflect.Struct:
.where = append(.where, wherePKStructQuery{})
return
case reflect.Slice:
.joins = append(.joins, joinPKSliceQuery{q: })
.where = append(.where, wherePKSliceQuery{q: })
= .OrderExpr(`"_data"."ordering" ASC`)
return
}
panic("not reached")
}
func ( *Query) ( string, ...interface{}) *Query {
:= &joinQuery{
join: SafeQuery(, ...),
}
.joins = append(.joins, )
.joinAppendOn = .AppendOn
return
}
func ( *Query) ( string, ...interface{}) *Query {
if .joinAppendOn == nil {
.err(errors.New("pg: no joins to apply JoinOn"))
return
}
.joinAppendOn(&condAppender{
sep: " AND ",
cond: ,
params: ,
})
return
}
func ( *Query) ( string, ...interface{}) *Query {
if .joinAppendOn == nil {
.err(errors.New("pg: no joins to apply JoinOn"))
return
}
.joinAppendOn(&condAppender{
sep: " OR ",
cond: ,
params: ,
})
return
}
func ( *Query) ( ...string) *Query {
for , := range {
.group = append(.group, fieldAppender{})
}
return
}
func ( *Query) ( string, ...interface{}) *Query {
.group = append(.group, SafeQuery(, ...))
return
}
func ( *Query) ( string, ...interface{}) *Query {
.having = append(.having, SafeQuery(, ...))
return
}
func ( *Query) ( *Query) *Query {
return .addUnion(" UNION ", )
}
func ( *Query) ( *Query) *Query {
return .addUnion(" UNION ALL ", )
}
func ( *Query) ( *Query) *Query {
return .addUnion(" INTERSECT ", )
}
func ( *Query) ( *Query) *Query {
return .addUnion(" INTERSECT ALL ", )
}
func ( *Query) ( *Query) *Query {
return .addUnion(" EXCEPT ", )
}
func ( *Query) ( *Query) *Query {
return .addUnion(" EXCEPT ALL ", )
}
func ( *Query) ( string, *Query) *Query {
.union = append(.union, &union{
expr: ,
query: ,
})
return
}
func ( *Query) ( ...string) *Query {
:
for , := range {
if == "" {
continue
}
:= strings.Index(, " ")
if != -1 {
:= [:]
:= [+1:]
switch internal.UpperString() {
case "ASC", "DESC", "ASC NULLS FIRST", "DESC NULLS FIRST",
"ASC NULLS LAST", "DESC NULLS LAST":
= .OrderExpr("? ?", types.Ident(), types.Safe())
continue
}
}
.order = append(.order, fieldAppender{})
}
return
}
func ( *Query) ( string, ...interface{}) *Query {
if != "" {
.order = append(.order, SafeQuery(, ...))
}
return
}
func ( *Query) ( int) *Query {
.limit =
return
}
func ( *Query) ( int) *Query {
.offset =
return
}
func ( *Query) ( string, ...interface{}) *Query {
.onConflict = SafeQuery(, ...)
return
}
func ( *Query) () bool {
return .onConflict != nil &&
strings.HasSuffix(internal.UpperString(.onConflict.query), "DO UPDATE")
}
func ( *Query) ( string, ...interface{}) *Query {
.returning = append(.returning, SafeQuery(, ...))
return
}
func ( *Query) ( string, ...interface{}) *Query {
.selFor = SafeQuery(, ...)
return
}
func ( *Query) ( func(*Query) (*Query, error)) *Query {
, := ()
if != nil {
.err()
return
}
return
}
func ( *Query) () (int, error) {
if .stickyErr != nil {
return 0, .stickyErr
}
var int
, := .db.QueryOneContext(
.ctx, Scan(&), .countSelectQuery("count(*)"), .tableModel)
return ,
}
func ( *Query) ( string) *SelectQuery {
return &SelectQuery{
q: ,
count: ,
}
}
func ( *Query) () error {
:= .tableModel.Table()
if := .checkPKs(); != nil {
return
}
:= appendColumns(nil, .Alias, .PKs)
return .OrderExpr(internal.BytesToString()).Limit(1).Select()
}
func ( *Query) () error {
:= .tableModel.Table()
if := .checkPKs(); != nil {
return
}
:= appendColumns(nil, .Alias, .PKs)
= append(, " DESC"...)
return .OrderExpr(internal.BytesToString()).Limit(1).Select()
}
func ( *Query) ( ...interface{}) error {
if .stickyErr != nil {
return .stickyErr
}
, := .newModel()
if != nil {
return
}
, := .query(.ctx, , NewSelectQuery())
if != nil {
return
}
if .RowsReturned() > 0 {
if .tableModel != nil {
if := .selectJoins(.tableModel.GetJoins()); != nil {
return
}
}
}
if := .AfterSelect(.ctx); != nil {
return
}
return nil
}
func ( *Query) ( []interface{}) (Model, error) {
if len() > 0 {
return newScanModel()
}
return .tableModel, nil
}
func ( *Query) ( context.Context, Model, interface{}) (Result, error) {
if , := .(useQueryOne); {
return .db.QueryOneContext(, , , .tableModel)
}
return .db.QueryContext(, , , .tableModel)
}
func ( *Query) ( ...interface{}) ( int, error) {
if .stickyErr != nil {
return 0, .stickyErr
}
var sync.WaitGroup
var sync.Mutex
if .limit >= 0 {
.Add(1)
go func() {
defer .Done()
:= .Select(...)
if != nil {
.Lock()
if == nil {
=
}
.Unlock()
}
}()
}
.Add(1)
go func() {
defer .Done()
var error
, = .Count()
if != nil {
.Lock()
if == nil {
=
}
.Unlock()
}
}()
.Wait()
return ,
}
func ( *Query) ( int, ...interface{}) ( int, error) {
if .stickyErr != nil {
return 0, .stickyErr
}
var sync.WaitGroup
var sync.Mutex
if .limit >= 0 {
.Add(1)
go func() {
defer .Done()
:= .Select(...)
if != nil {
.Lock()
if == nil {
=
}
.Unlock()
}
}()
}
.Add(1)
go func() {
defer .Done()
var error
, = .CountEstimate()
if != nil {
.Lock()
if == nil {
=
}
.Unlock()
}
}()
.Wait()
return ,
}
func ( *Query) ( interface{}) error {
:= newFuncModel()
return .Select()
}
func ( *Query) ( func(*join) error) error {
if .tableModel == nil {
return nil
}
return ._forEachHasOneJoin(, .tableModel.GetJoins())
}
func ( *Query) ( func(*join) error, []join) error {
for := range {
:= &[]
switch .Rel.Type {
case HasOneRelation, BelongsToRelation:
:= ()
if != nil {
return
}
= .(, .JoinModel.GetJoins())
if != nil {
return
}
}
}
return nil
}
func ( *Query) ( []join) error {
var error
for := range {
:= &[]
if .Rel.Type == HasOneRelation || .Rel.Type == BelongsToRelation {
= .(.JoinModel.GetJoins())
} else {
= .Select(.db.Formatter(), .New())
}
if != nil {
return
}
}
return nil
}
func ( *Query) ( ...interface{}) (Result, error) {
if .stickyErr != nil {
return nil, .stickyErr
}
, := .newModel()
if != nil {
return nil,
}
:= .ctx
if .tableModel != nil && .tableModel.Table().hasFlag(beforeInsertHookFlag) {
, = .tableModel.BeforeInsert()
if != nil {
return nil,
}
}
:= NewInsertQuery()
, := .returningQuery(, , )
if != nil {
return nil,
}
if .tableModel != nil {
if := .tableModel.AfterInsert(); != nil {
return nil,
}
}
return , nil
}
func ( *Query) ( ...interface{}) ( bool, error) {
if .stickyErr != nil {
return false, .stickyErr
}
var *Query
var error
for := 0; < 5; ++ {
if >= 2 {
:= internal.RetryBackoff(-2, 250*time.Millisecond, 5*time.Second)
if := internal.Sleep(.ctx, ); != nil {
return false,
}
}
:= .Select(...)
if == nil {
return false, nil
}
if != internal.ErrNoRows {
return false,
}
if == nil {
=
if len(.columns) > 0 {
= .Clone()
.columns = nil
}
}
, := .Insert(...)
if != nil {
=
if == internal.ErrNoRows {
continue
}
if , := .(internal.PGError); {
if .IntegrityViolation() {
continue
}
if .Field('C') == "55000" {
continue
}
}
return false,
}
if .RowsAffected() == 1 {
return true, nil
}
}
:= fmt.Errorf(
"pg: SelectOrInsert: select returns no rows (insert fails with err=%q)",
)
return false,
}
func ( *Query) ( ...interface{}) (Result, error) {
return .update(, false)
}
func ( *Query) ( ...interface{}) (Result, error) {
return .update(, true)
}
func ( *Query) ( []interface{}, bool) (Result, error) {
if .stickyErr != nil {
return nil, .stickyErr
}
, := .newModel()
if != nil {
return nil,
}
:= .ctx
if .tableModel != nil {
, = .tableModel.BeforeUpdate()
if != nil {
return nil,
}
}
:= NewUpdateQuery(, )
, := .returningQuery(, , )
if != nil {
return nil,
}
if .tableModel != nil {
= .tableModel.AfterUpdate()
if != nil {
return nil,
}
}
return , nil
}
func ( *Query) ( context.Context, Model, interface{}) (Result, error) {
if !.hasReturning() {
return .db.QueryContext(, , , .tableModel)
}
if , := .(useQueryOne); {
return .db.QueryOneContext(, , , .tableModel)
}
return .db.QueryContext(, , , .tableModel)
}
func ( *Query) ( ...interface{}) (Result, error) {
if .tableModel == nil {
return .ForceDelete(...)
}
:= .tableModel.Table()
if .SoftDeleteField == nil {
return .ForceDelete(...)
}
:= .Clone()
if .tableModel.IsNil() {
if .SoftDeleteField.SQLType == pgTypeBigint {
= .Set("? = ?", .SoftDeleteField.Column, time.Now().UnixNano())
} else {
= .Set("? = ?", .SoftDeleteField.Column, time.Now())
}
} else {
if := .tableModel.setSoftDeleteField(); != nil {
return nil,
}
= .Column(.SoftDeleteField.SQLName)
}
return .Update(...)
}
func ( *Query) ( ...interface{}) (Result, error) {
if .stickyErr != nil {
return nil, .stickyErr
}
if .tableModel == nil {
return nil, errModelNil
}
= .withFlag(deletedFlag)
, := .newModel()
if != nil {
return nil,
}
:= .ctx
if .tableModel != nil {
, = .tableModel.BeforeDelete()
if != nil {
return nil,
}
}
, := .returningQuery(, , NewDeleteQuery())
if != nil {
return nil,
}
if .tableModel != nil {
if := .tableModel.AfterDelete(); != nil {
return nil,
}
}
return , nil
}
func ( *Query) ( *CreateTableOptions) error {
, := .db.ExecContext(.ctx, NewCreateTableQuery(, ))
return
}
func ( *Query) ( *DropTableOptions) error {
, := .db.ExecContext(.ctx, NewDropTableQuery(, ))
return
}
func ( *Query) ( *CreateCompositeOptions) error {
, := .db.ExecContext(.ctx, NewCreateCompositeQuery(, ))
return
}
func ( *Query) ( *DropCompositeOptions) error {
, := .db.ExecContext(.ctx, NewDropCompositeQuery(, ))
return
}
func ( *Query) ( interface{}, ...interface{}) (Result, error) {
= append(, .tableModel)
return .db.ExecContext(.ctx, , ...)
}
func ( *Query) ( interface{}, ...interface{}) (Result, error) {
= append(, .tableModel)
return .db.ExecOneContext(.ctx, , ...)
}
func ( *Query) (, interface{}, ...interface{}) (Result, error) {
= append(, .tableModel)
return .db.QueryContext(.ctx, , , ...)
}
func ( *Query) (, interface{}, ...interface{}) (Result, error) {
= append(, .tableModel)
return .db.QueryOneContext(.ctx, , , ...)
}
func ( *Query) ( io.Reader, interface{}, ...interface{}) (Result, error) {
= append(, .tableModel)
return .db.CopyFrom(, , ...)
}
func ( *Query) ( io.Writer, interface{}, ...interface{}) (Result, error) {
= append(, .tableModel)
return .db.CopyTo(, , ...)
}
var _ QueryAppender = (*Query)(nil)
func ( *Query) ( QueryFormatter, []byte) ([]byte, error) {
return NewSelectQuery().AppendQuery(, )
}
func ( *Query) () (bool, error) {
= .Clone()
.columns = []QueryAppender{SafeQuery("1")}
.order = nil
.limit = 1
, := .db.ExecContext(.ctx, NewSelectQuery())
if != nil {
return false,
}
return .RowsAffected() > 0, nil
}
func ( *Query) () bool {
return .tableModel != nil && !.tableModel.IsNil()
}
func ( *Query) () bool {
return .tableModel != nil && !.hasFlag(implicitModelFlag)
}
func ( *Query) () bool {
return .hasExplicitTableModel() && .tableModel.Table().SQLName != ""
}
func ( *Query) () bool {
return .hasExplicitTableModel() && .tableModel.Table().Alias != ""
}
func ( *Query) () bool {
return .modelHasTableName() || len(.tables) > 0
}
func ( *Query) ( QueryFormatter, []byte) ([]byte, error) {
if .modelHasTableName() {
return .FormatQuery(, string(.tableModel.Table().SQLName)), nil
}
if len(.tables) > 0 {
return .tables[0].AppendQuery(, )
}
return , nil
}
func ( *Query) ( QueryFormatter, []byte) ( []byte, error) {
if .modelHasTableName() {
:= .tableModel.Table()
= .FormatQuery(, string(.SQLName))
if .Alias != .SQLName {
= append(, " AS "...)
= append(, .Alias...)
}
return , nil
}
if len(.tables) > 0 {
, = .tables[0].AppendQuery(, )
if != nil {
return nil,
}
if .modelHasTableAlias() {
:= .tableModel.Table()
if .Alias != .SQLName {
= append(, " AS "...)
= append(, .Alias...)
}
}
}
return , nil
}
func ( *Query) () bool {
if .modelHasTableName() {
return len(.tables) >= 1
}
return len(.tables) >= 2
}
func ( *Query) ( QueryFormatter, []byte) ( []byte, error) {
:= .tables
if !.modelHasTableName() {
= [1:]
}
for , := range {
if > 0 {
= append(, ", "...)
}
, = .AppendQuery(, )
if != nil {
return nil,
}
}
return , nil
}
func ( *Query) ( QueryFormatter, []byte) ( []byte, error) {
for , := range .columns {
if > 0 {
= append(, ", "...)
}
, = .AppendQuery(, )
if != nil {
return nil,
}
}
return , nil
}
func ( *Query) ( QueryFormatter, []byte) ([]byte, error) {
if len(.where) == 0 {
:= errors.New(
"pg: Update and Delete queries require Where clause (try WherePK)")
return nil,
}
return .appendWhere(, )
}
func ( *Query) ( QueryFormatter, []byte) ( []byte, error) {
:= .isSoftDelete()
if len(.where) > 0 {
if {
= append(, '(')
}
, = ._appendWhere(, , .where)
if != nil {
return nil,
}
if {
= append(, ')')
}
}
if {
if len(.where) > 0 {
= append(, " AND "...)
}
= append(, .tableModel.Table().Alias...)
= .appendSoftDelete()
}
return , nil
}
func ( *Query) ( []byte) []byte {
= append(, '.')
= append(, .tableModel.Table().SoftDeleteField.Column...)
if .hasFlag(deletedFlag) {
= append(, " IS NOT NULL"...)
} else {
= append(, " IS NULL"...)
}
return
}
func ( *Query) ( QueryFormatter, []byte) ([]byte, error) {
return ._appendWhere(, , .updWhere)
}
func ( *Query) (
QueryFormatter, []byte, []queryWithSepAppender,
) ( []byte, error) {
for , := range {
:= len()
if > 0 {
= .AppendSep()
}
:= len()
, = .AppendQuery(, )
if != nil {
return nil,
}
if len() == {
= [:]
}
}
return , nil
}
func ( *Query) ( QueryFormatter, []byte) ( []byte, error) {
= append(, " SET "...)
for , := range .set {
if > 0 {
= append(, ", "...)
}
, = .AppendQuery(, )
if != nil {
return nil,
}
}
return , nil
}
func ( *Query) () bool {
if len(.returning) == 0 {
return false
}
if len(.returning) == 1 {
switch .returning[0].query {
case "null", "NULL":
return false
}
}
return true
}
func ( *Query) ( QueryFormatter, []byte) ( []byte, error) {
if !.hasReturning() {
return , nil
}
= append(, " RETURNING "...)
for , := range .returning {
if > 0 {
= append(, ", "...)
}
, = .AppendQuery(, )
if != nil {
return nil,
}
}
return , nil
}
func ( *Query) ( QueryFormatter, []byte) ( []byte, error) {
= append(, "WITH "...)
for , := range .with {
if > 0 {
= append(, ", "...)
}
= types.AppendIdent(, .name, 1)
= append(, " AS ("...)
, = .query.AppendQuery(, )
if != nil {
return nil,
}
= append(, ')')
}
= append(, ' ')
return , nil
}
func ( *Query) () bool {
if !.hasTableModel() {
return false
}
, := .tableModel.(*sliceTableModel)
return && .sliceLen > 0
}
type wherePKStructQuery struct {
q *Query
}
var _ queryWithSepAppender = (*wherePKStructQuery)(nil)
func (wherePKStructQuery) ( []byte) []byte {
return append(, " AND "...)
}
func ( wherePKStructQuery) ( QueryFormatter, []byte) ([]byte, error) {
:= .q.tableModel.Table()
:= .q.tableModel.Value()
return appendColumnAndValue(, , , .Alias, .PKs), nil
}
func (
QueryFormatter, []byte, reflect.Value, types.Safe, []*Field,
) []byte {
:= isTemplateFormatter()
for , := range {
if > 0 {
= append(, " AND "...)
}
= append(, ...)
= append(, '.')
= append(, .Column...)
= append(, " = "...)
if {
= append(, '?')
} else {
= .AppendValue(, , 1)
}
}
return
}
type wherePKSliceQuery struct {
q *Query
}
var _ queryWithSepAppender = (*wherePKSliceQuery)(nil)
func (wherePKSliceQuery) ( []byte) []byte {
return append(, " AND "...)
}
func ( wherePKSliceQuery) ( QueryFormatter, []byte) ([]byte, error) {
:= .q.tableModel.Table()
for , := range .PKs {
if > 0 {
= append(, " AND "...)
}
= append(, .Alias...)
= append(, '.')
= append(, .Column...)
= append(, " = "...)
= append(, `"_data".`...)
= append(, .Column...)
}
return , nil
}
type joinPKSliceQuery struct {
q *Query
}
var _ QueryAppender = (*joinPKSliceQuery)(nil)
func ( joinPKSliceQuery) ( QueryFormatter, []byte) ([]byte, error) {
:= .q.tableModel.Table()
:= .q.tableModel.Value()
= append(, " JOIN (VALUES "...)
:= .Len()
for := 0; < ; ++ {
if > 0 {
= append(, ", "...)
}
:= indirect(.Index())
= append(, '(')
for , := range .PKs {
if > 0 {
= append(, ", "...)
}
= .AppendValue(, , 1)
if .UserSQLType != "" {
= append(, "::"...)
= append(, .SQLType...)
}
}
= append(, ", "...)
= strconv.AppendInt(, int64(), 10)
= append(, ')')
}
= append(, `) AS "_data" (`...)
for , := range .PKs {
if > 0 {
= append(, ", "...)
}
= append(, .Column...)
}
= append(, ", "...)
= append(, `"ordering"`...)
= append(, ") ON TRUE"...)
return , nil
}