package orm
import (
)
type SelectQuery struct {
q *Query
count string
}
var (
_ QueryAppender = (*SelectQuery)(nil)
_ QueryCommand = (*SelectQuery)(nil)
)
func ( *Query) *SelectQuery {
return &SelectQuery{
q: ,
}
}
func ( *SelectQuery) () string {
, := .AppendQuery(defaultFmter, nil)
if != nil {
panic()
}
return string()
}
func ( *SelectQuery) () QueryOp {
return SelectOp
}
func ( *SelectQuery) () QueryCommand {
return &SelectQuery{
q: .q.Clone(),
count: .count,
}
}
func ( *SelectQuery) () *Query {
return .q
}
func ( *SelectQuery) ( []byte) ([]byte, error) {
return .AppendQuery(dummyFormatter{}, )
}
func ( *SelectQuery) ( QueryFormatter, []byte) ( []byte, error) {
if .q.stickyErr != nil {
return nil, .q.stickyErr
}
:= .count != "" && (len(.q.group) > 0 || .isDistinct())
if {
= append(, `WITH "_count_wrapper" AS (`...)
}
if len(.q.with) > 0 {
, = .q.appendWith(, )
if != nil {
return nil,
}
}
if len(.q.union) > 0 {
= append(, '(')
}
= append(, "SELECT "...)
if len(.q.distinctOn) > 0 {
= append(, "DISTINCT ON ("...)
for , := range .q.distinctOn {
if > 0 {
= append(, ", "...)
}
, = .AppendQuery(, )
}
= append(, ") "...)
} else if .q.distinctOn != nil {
= append(, "DISTINCT "...)
}
if .count != "" && ! {
= append(, .count...)
} else {
, = .appendColumns(, )
if != nil {
return nil,
}
}
if .q.hasTables() {
= append(, " FROM "...)
, = .appendTables(, )
if != nil {
return nil,
}
}
= .q.forEachHasOneJoin(func( *join) error {
= append(, ' ')
, = .appendHasOneJoin(, , .q)
return
})
if != nil {
return nil,
}
for , := range .q.joins {
, = .AppendQuery(, )
if != nil {
return nil,
}
}
if len(.q.where) > 0 || .q.isSoftDelete() {
= append(, " WHERE "...)
, = .q.appendWhere(, )
if != nil {
return nil,
}
}
if len(.q.group) > 0 {
= append(, " GROUP BY "...)
for , := range .q.group {
if > 0 {
= append(, ", "...)
}
, = .AppendQuery(, )
if != nil {
return nil,
}
}
}
if len(.q.having) > 0 {
= append(, " HAVING "...)
for , := range .q.having {
if > 0 {
= append(, " AND "...)
}
= append(, '(')
, = .AppendQuery(, )
if != nil {
return nil,
}
= append(, ')')
}
}
if .count == "" {
if len(.q.order) > 0 {
= append(, " ORDER BY "...)
for , := range .q.order {
if > 0 {
= append(, ", "...)
}
, = .AppendQuery(, )
if != nil {
return nil,
}
}
}
if .q.limit != 0 {
= append(, " LIMIT "...)
= strconv.AppendInt(, int64(.q.limit), 10)
}
if .q.offset != 0 {
= append(, " OFFSET "...)
= strconv.AppendInt(, int64(.q.offset), 10)
}
if .q.selFor != nil {
= append(, " FOR "...)
, = .q.selFor.AppendQuery(, )
if != nil {
return nil,
}
}
} else if {
= append(, `) SELECT `...)
= append(, .count...)
= append(, ` FROM "_count_wrapper"`...)
}
if len(.q.union) > 0 {
= append(, ")"...)
for , := range .q.union {
= append(, .expr...)
= append(, '(')
, = .query.AppendQuery(, )
if != nil {
return nil,
}
= append(, ")"...)
}
}
return , .q.stickyErr
}
func ( SelectQuery) ( QueryFormatter, []byte) ( []byte, error) {
:= len()
switch {
case .q.columns != nil:
, = .q.appendColumns(, )
if != nil {
return nil,
}
case .q.hasExplicitTableModel():
:= .q.tableModel.Table()
if len(.Fields) > 10 && isTemplateFormatter() {
= append(, .Alias...)
= append(, '.')
= types.AppendString(, fmt.Sprintf("%d columns", len(.Fields)), 2)
} else {
= appendColumns(, .Alias, .Fields)
}
default:
= append(, '*')
}
= .q.forEachHasOneJoin(func( *join) error {
if len() != {
= append(, ", "...)
= len()
}
= .appendHasOneColumns()
return nil
})
if != nil {
return nil,
}
= bytes.TrimSuffix(, []byte(", "))
return , nil
}
func ( *SelectQuery) () bool {
if .q.distinctOn != nil {
return true
}
for , := range .q.columns {
, := .(*SafeQueryAppender)
if {
if strings.Contains(.query, "DISTINCT") ||
strings.Contains(.query, "distinct") {
return true
}
}
}
return false
}
func ( *SelectQuery) ( QueryFormatter, []byte) ( []byte, error) {
:= .q.tables
if .q.modelHasTableName() {
:= .q.tableModel.Table()
= .FormatQuery(, string(.SQLNameForSelects))
if .Alias != "" {
= append(, " AS "...)
= append(, .Alias...)
}
if len() > 0 {
= append(, ", "...)
}
} else if len() > 0 {
, = [0].AppendQuery(, )
if != nil {
return nil,
}
if .q.modelHasTableAlias() {
= append(, " AS "...)
= append(, .q.tableModel.Table().Alias...)
}
= [1:]
if len() > 0 {
= append(, ", "...)
}
}
for , := range {
if > 0 {
= append(, ", "...)
}
, = .AppendQuery(, )
if != nil {
return nil,
}
}
return , nil
}
type joinQuery struct {
join *SafeQueryAppender
on []*condAppender
}
func ( *joinQuery) ( *condAppender) {
.on = append(.on, )
}
func ( *joinQuery) ( QueryFormatter, []byte) ( []byte, error) {
= append(, ' ')
, = .join.AppendQuery(, )
if != nil {
return nil,
}
if len(.on) > 0 {
= append(, " ON "...)
for , := range .on {
if > 0 {
= .AppendSep()
}
, = .AppendQuery(, )
if != nil {
return nil,
}
}
}
return , nil
}