1 package goqu
2
3 import (
4 "context"
5 "fmt"
6
7 "github.com/doug-martin/goqu/v9/exec"
8 "github.com/doug-martin/goqu/v9/exp"
9 "github.com/doug-martin/goqu/v9/internal/errors"
10 "github.com/doug-martin/goqu/v9/internal/sb"
11 )
12
13
14 type SelectDataset struct {
15 dialect SQLDialect
16 clauses exp.SelectClauses
17 isPrepared prepared
18 queryFactory exec.QueryFactory
19 err error
20 }
21
22 var ErrQueryFactoryNotFoundError = errors.New(
23 "unable to execute query did you use goqu.Database#From to create the dataset",
24 )
25
26
27 func newDataset(d string, queryFactory exec.QueryFactory) *SelectDataset {
28 return &SelectDataset{
29 clauses: exp.NewSelectClauses(),
30 dialect: GetDialect(d),
31 queryFactory: queryFactory,
32 }
33 }
34
35 func From(table ...interface{}) *SelectDataset {
36 return newDataset("default", nil).From(table...)
37 }
38
39 func Select(cols ...interface{}) *SelectDataset {
40 return newDataset("default", nil).Select(cols...)
41 }
42
43
44 func (sd *SelectDataset) WithDialect(dl string) *SelectDataset {
45 ds := sd.copy(sd.GetClauses())
46 ds.dialect = GetDialect(dl)
47 return ds
48 }
49
50
51
52
53 func (sd *SelectDataset) Prepared(prepared bool) *SelectDataset {
54 ret := sd.copy(sd.clauses)
55 ret.isPrepared = preparedFromBool(prepared)
56 return ret
57 }
58
59 func (sd *SelectDataset) IsPrepared() bool {
60 return sd.isPrepared.Bool()
61 }
62
63
64 func (sd *SelectDataset) Dialect() SQLDialect {
65 return sd.dialect
66 }
67
68
69 func (sd *SelectDataset) SetDialect(dialect SQLDialect) *SelectDataset {
70 cd := sd.copy(sd.GetClauses())
71 cd.dialect = dialect
72 return cd
73 }
74
75 func (sd *SelectDataset) Expression() exp.Expression {
76 return sd
77 }
78
79
80 func (sd *SelectDataset) Clone() exp.Expression {
81 return sd.copy(sd.clauses)
82 }
83
84
85 func (sd *SelectDataset) GetClauses() exp.SelectClauses {
86 return sd.clauses
87 }
88
89
90 func (sd *SelectDataset) copy(clauses exp.SelectClauses) *SelectDataset {
91 return &SelectDataset{
92 dialect: sd.dialect,
93 clauses: clauses,
94 isPrepared: sd.isPrepared,
95 queryFactory: sd.queryFactory,
96 err: sd.err,
97 }
98 }
99
100
101
102 func (sd *SelectDataset) Update() *UpdateDataset {
103 u := newUpdateDataset(sd.dialect.Dialect(), sd.queryFactory).
104 Prepared(sd.isPrepared.Bool())
105 if sd.clauses.HasSources() {
106 u = u.Table(sd.GetClauses().From().Columns()[0])
107 }
108 c := u.clauses
109 for _, ce := range sd.clauses.CommonTables() {
110 c = c.CommonTablesAppend(ce)
111 }
112 if sd.clauses.Where() != nil {
113 c = c.WhereAppend(sd.clauses.Where())
114 }
115 if sd.clauses.HasLimit() {
116 c = c.SetLimit(sd.clauses.Limit())
117 }
118 if sd.clauses.HasOrder() {
119 for _, oe := range sd.clauses.Order().Columns() {
120 c = c.OrderAppend(oe.(exp.OrderedExpression))
121 }
122 }
123 u.clauses = c
124 return u
125 }
126
127
128
129 func (sd *SelectDataset) Insert() *InsertDataset {
130 i := newInsertDataset(sd.dialect.Dialect(), sd.queryFactory).
131 Prepared(sd.isPrepared.Bool())
132 if sd.clauses.HasSources() {
133 i = i.Into(sd.GetClauses().From().Columns()[0])
134 }
135 c := i.clauses
136 for _, ce := range sd.clauses.CommonTables() {
137 c = c.CommonTablesAppend(ce)
138 }
139 i.clauses = c
140 return i
141 }
142
143
144
145 func (sd *SelectDataset) Delete() *DeleteDataset {
146 d := newDeleteDataset(sd.dialect.Dialect(), sd.queryFactory).
147 Prepared(sd.isPrepared.Bool())
148 if sd.clauses.HasSources() {
149 d = d.From(sd.clauses.From().Columns()[0])
150 }
151 c := d.clauses
152 for _, ce := range sd.clauses.CommonTables() {
153 c = c.CommonTablesAppend(ce)
154 }
155 if sd.clauses.Where() != nil {
156 c = c.WhereAppend(sd.clauses.Where())
157 }
158 if sd.clauses.HasLimit() {
159 c = c.SetLimit(sd.clauses.Limit())
160 }
161 if sd.clauses.HasOrder() {
162 for _, oe := range sd.clauses.Order().Columns() {
163 c = c.OrderAppend(oe.(exp.OrderedExpression))
164 }
165 }
166 d.clauses = c
167 return d
168 }
169
170
171 func (sd *SelectDataset) Truncate() *TruncateDataset {
172 td := newTruncateDataset(sd.dialect.Dialect(), sd.queryFactory)
173 if sd.clauses.HasSources() {
174 td = td.Table(sd.clauses.From())
175 }
176 return td
177 }
178
179
180
181
182
183
184
185 func (sd *SelectDataset) With(name string, subquery exp.Expression) *SelectDataset {
186 return sd.copy(sd.clauses.CommonTablesAppend(exp.NewCommonTableExpression(false, name, subquery)))
187 }
188
189
190
191
192
193
194
195
196
197 func (sd *SelectDataset) WithRecursive(name string, subquery exp.Expression) *SelectDataset {
198 return sd.copy(sd.clauses.CommonTablesAppend(exp.NewCommonTableExpression(true, name, subquery)))
199 }
200
201
202
203
204
205
206
207
208
209
210 func (sd *SelectDataset) Select(selects ...interface{}) *SelectDataset {
211 if len(selects) == 0 {
212 return sd.ClearSelect()
213 }
214 return sd.copy(sd.clauses.SetSelect(exp.NewColumnListExpression(selects...)))
215 }
216
217
218
219
220
221
222
223
224
225
226
227 func (sd *SelectDataset) SelectDistinct(selects ...interface{}) *SelectDataset {
228 if len(selects) == 0 {
229 cleared := sd.ClearSelect()
230 return cleared.copy(cleared.clauses.SetDistinct(nil))
231 }
232 return sd.copy(sd.clauses.SetSelect(exp.NewColumnListExpression(selects...)).SetDistinct(exp.NewColumnListExpression()))
233 }
234
235
236
237 func (sd *SelectDataset) ClearSelect() *SelectDataset {
238 return sd.copy(sd.clauses.SetSelect(exp.NewColumnListExpression(exp.Star())).SetDistinct(nil))
239 }
240
241
242
243
244
245
246
247
248 func (sd *SelectDataset) SelectAppend(selects ...interface{}) *SelectDataset {
249 return sd.copy(sd.clauses.SelectAppend(exp.NewColumnListExpression(selects...)))
250 }
251
252 func (sd *SelectDataset) Distinct(on ...interface{}) *SelectDataset {
253 return sd.copy(sd.clauses.SetDistinct(exp.NewColumnListExpression(on...)))
254 }
255
256
257
258
259
260
261 func (sd *SelectDataset) From(from ...interface{}) *SelectDataset {
262 var sources []interface{}
263 numSources := 0
264 for _, source := range from {
265 if ds, ok := source.(*SelectDataset); ok && !ds.clauses.HasAlias() {
266 numSources++
267 sources = append(sources, ds.As(fmt.Sprintf("t%d", numSources)))
268 } else {
269 sources = append(sources, source)
270 }
271 }
272 return sd.copy(sd.clauses.SetFrom(exp.NewColumnListExpression(sources...)))
273 }
274
275
276
277 func (sd *SelectDataset) FromSelf() *SelectDataset {
278 return sd.copy(exp.NewSelectClauses()).From(sd)
279 }
280
281
282 func (sd *SelectDataset) Join(table exp.Expression, condition exp.JoinCondition) *SelectDataset {
283 return sd.InnerJoin(table, condition)
284 }
285
286
287 func (sd *SelectDataset) InnerJoin(table exp.Expression, condition exp.JoinCondition) *SelectDataset {
288 return sd.joinTable(exp.NewConditionedJoinExpression(exp.InnerJoinType, table, condition))
289 }
290
291
292 func (sd *SelectDataset) FullOuterJoin(table exp.Expression, condition exp.JoinCondition) *SelectDataset {
293 return sd.joinTable(exp.NewConditionedJoinExpression(exp.FullOuterJoinType, table, condition))
294 }
295
296
297 func (sd *SelectDataset) RightOuterJoin(table exp.Expression, condition exp.JoinCondition) *SelectDataset {
298 return sd.joinTable(exp.NewConditionedJoinExpression(exp.RightOuterJoinType, table, condition))
299 }
300
301
302 func (sd *SelectDataset) LeftOuterJoin(table exp.Expression, condition exp.JoinCondition) *SelectDataset {
303 return sd.joinTable(exp.NewConditionedJoinExpression(exp.LeftOuterJoinType, table, condition))
304 }
305
306
307 func (sd *SelectDataset) FullJoin(table exp.Expression, condition exp.JoinCondition) *SelectDataset {
308 return sd.joinTable(exp.NewConditionedJoinExpression(exp.FullJoinType, table, condition))
309 }
310
311
312 func (sd *SelectDataset) RightJoin(table exp.Expression, condition exp.JoinCondition) *SelectDataset {
313 return sd.joinTable(exp.NewConditionedJoinExpression(exp.RightJoinType, table, condition))
314 }
315
316
317 func (sd *SelectDataset) LeftJoin(table exp.Expression, condition exp.JoinCondition) *SelectDataset {
318 return sd.joinTable(exp.NewConditionedJoinExpression(exp.LeftJoinType, table, condition))
319 }
320
321
322 func (sd *SelectDataset) NaturalJoin(table exp.Expression) *SelectDataset {
323 return sd.joinTable(exp.NewUnConditionedJoinExpression(exp.NaturalJoinType, table))
324 }
325
326
327 func (sd *SelectDataset) NaturalLeftJoin(table exp.Expression) *SelectDataset {
328 return sd.joinTable(exp.NewUnConditionedJoinExpression(exp.NaturalLeftJoinType, table))
329 }
330
331
332 func (sd *SelectDataset) NaturalRightJoin(table exp.Expression) *SelectDataset {
333 return sd.joinTable(exp.NewUnConditionedJoinExpression(exp.NaturalRightJoinType, table))
334 }
335
336
337 func (sd *SelectDataset) NaturalFullJoin(table exp.Expression) *SelectDataset {
338 return sd.joinTable(exp.NewUnConditionedJoinExpression(exp.NaturalFullJoinType, table))
339 }
340
341
342 func (sd *SelectDataset) CrossJoin(table exp.Expression) *SelectDataset {
343 return sd.joinTable(exp.NewUnConditionedJoinExpression(exp.CrossJoinType, table))
344 }
345
346
347 func (sd *SelectDataset) joinTable(join exp.JoinExpression) *SelectDataset {
348 return sd.copy(sd.clauses.JoinsAppend(join))
349 }
350
351
352 func (sd *SelectDataset) Where(expressions ...exp.Expression) *SelectDataset {
353 return sd.copy(sd.clauses.WhereAppend(expressions...))
354 }
355
356
357 func (sd *SelectDataset) ClearWhere() *SelectDataset {
358 return sd.copy(sd.clauses.ClearWhere())
359 }
360
361
362 func (sd *SelectDataset) ForUpdate(waitOption exp.WaitOption, of ...exp.IdentifierExpression) *SelectDataset {
363 return sd.withLock(exp.ForUpdate, waitOption, of...)
364 }
365
366
367 func (sd *SelectDataset) ForNoKeyUpdate(waitOption exp.WaitOption, of ...exp.IdentifierExpression) *SelectDataset {
368 return sd.withLock(exp.ForNoKeyUpdate, waitOption, of...)
369 }
370
371
372 func (sd *SelectDataset) ForKeyShare(waitOption exp.WaitOption, of ...exp.IdentifierExpression) *SelectDataset {
373 return sd.withLock(exp.ForKeyShare, waitOption, of...)
374 }
375
376
377 func (sd *SelectDataset) ForShare(waitOption exp.WaitOption, of ...exp.IdentifierExpression) *SelectDataset {
378 return sd.withLock(exp.ForShare, waitOption, of...)
379 }
380
381 func (sd *SelectDataset) withLock(strength exp.LockStrength, option exp.WaitOption, of ...exp.IdentifierExpression) *SelectDataset {
382 return sd.copy(sd.clauses.SetLock(exp.NewLock(strength, option, of...)))
383 }
384
385
386 func (sd *SelectDataset) GroupBy(groupBy ...interface{}) *SelectDataset {
387 return sd.copy(sd.clauses.SetGroupBy(exp.NewColumnListExpression(groupBy...)))
388 }
389
390
391 func (sd *SelectDataset) GroupByAppend(groupBy ...interface{}) *SelectDataset {
392 return sd.copy(sd.clauses.GroupByAppend(exp.NewColumnListExpression(groupBy...)))
393 }
394
395
396 func (sd *SelectDataset) Having(expressions ...exp.Expression) *SelectDataset {
397 return sd.copy(sd.clauses.HavingAppend(expressions...))
398 }
399
400
401 func (sd *SelectDataset) Order(order ...exp.OrderedExpression) *SelectDataset {
402 return sd.copy(sd.clauses.SetOrder(order...))
403 }
404
405
406
407 func (sd *SelectDataset) OrderAppend(order ...exp.OrderedExpression) *SelectDataset {
408 return sd.copy(sd.clauses.OrderAppend(order...))
409 }
410
411
412
413 func (sd *SelectDataset) OrderPrepend(order ...exp.OrderedExpression) *SelectDataset {
414 return sd.copy(sd.clauses.OrderPrepend(order...))
415 }
416
417
418 func (sd *SelectDataset) ClearOrder() *SelectDataset {
419 return sd.copy(sd.clauses.ClearOrder())
420 }
421
422
423 func (sd *SelectDataset) Limit(limit uint) *SelectDataset {
424 if limit > 0 {
425 return sd.copy(sd.clauses.SetLimit(limit))
426 }
427 return sd.copy(sd.clauses.ClearLimit())
428 }
429
430
431 func (sd *SelectDataset) LimitAll() *SelectDataset {
432 return sd.copy(sd.clauses.SetLimit(L("ALL")))
433 }
434
435
436 func (sd *SelectDataset) ClearLimit() *SelectDataset {
437 return sd.copy(sd.clauses.ClearLimit())
438 }
439
440
441 func (sd *SelectDataset) Offset(offset uint) *SelectDataset {
442 return sd.copy(sd.clauses.SetOffset(offset))
443 }
444
445
446 func (sd *SelectDataset) ClearOffset() *SelectDataset {
447 return sd.copy(sd.clauses.ClearOffset())
448 }
449
450
451
452
453 func (sd *SelectDataset) Union(other *SelectDataset) *SelectDataset {
454 return sd.withCompound(exp.UnionCompoundType, other.CompoundFromSelf())
455 }
456
457
458
459
460 func (sd *SelectDataset) UnionAll(other *SelectDataset) *SelectDataset {
461 return sd.withCompound(exp.UnionAllCompoundType, other.CompoundFromSelf())
462 }
463
464
465
466
467 func (sd *SelectDataset) Intersect(other *SelectDataset) *SelectDataset {
468 return sd.withCompound(exp.IntersectCompoundType, other.CompoundFromSelf())
469 }
470
471
472
473
474 func (sd *SelectDataset) IntersectAll(other *SelectDataset) *SelectDataset {
475 return sd.withCompound(exp.IntersectAllCompoundType, other.CompoundFromSelf())
476 }
477
478 func (sd *SelectDataset) withCompound(ct exp.CompoundType, other exp.AppendableExpression) *SelectDataset {
479 ce := exp.NewCompoundExpression(ct, other)
480 ret := sd.CompoundFromSelf()
481 ret.clauses = ret.clauses.CompoundsAppend(ce)
482 return ret
483 }
484
485
486
487 func (sd *SelectDataset) CompoundFromSelf() *SelectDataset {
488 if sd.clauses.HasOrder() || sd.clauses.HasLimit() {
489 return sd.FromSelf()
490 }
491 return sd.copy(sd.clauses)
492 }
493
494
495 func (sd *SelectDataset) As(alias string) *SelectDataset {
496 return sd.copy(sd.clauses.SetAlias(T(alias)))
497 }
498
499
500 func (sd *SelectDataset) GetAs() exp.IdentifierExpression {
501 return sd.clauses.Alias()
502 }
503
504
505 func (sd *SelectDataset) Window(ws ...exp.WindowExpression) *SelectDataset {
506 return sd.copy(sd.clauses.SetWindows(ws))
507 }
508
509
510 func (sd *SelectDataset) WindowAppend(ws ...exp.WindowExpression) *SelectDataset {
511 return sd.copy(sd.clauses.WindowsAppend(ws...))
512 }
513
514
515 func (sd *SelectDataset) ClearWindow() *SelectDataset {
516 return sd.copy(sd.clauses.ClearWindows())
517 }
518
519
520 func (sd *SelectDataset) Error() error {
521 return sd.err
522 }
523
524
525
526
527 func (sd *SelectDataset) SetError(err error) *SelectDataset {
528 if sd.err == nil {
529 sd.err = err
530 }
531
532 return sd
533 }
534
535
536
537
538
539
540 func (sd *SelectDataset) ToSQL() (sql string, params []interface{}, err error) {
541 return sd.selectSQLBuilder().ToSQL()
542 }
543
544
545
546
547
548 func (sd *SelectDataset) Executor() exec.QueryExecutor {
549 return sd.queryFactory.FromSQLBuilder(sd.selectSQLBuilder())
550 }
551
552
553
554 func (sd *SelectDataset) AppendSQL(b sb.SQLBuilder) {
555 if sd.err != nil {
556 b.SetError(sd.err)
557 return
558 }
559 sd.dialect.ToSelectSQL(b, sd.GetClauses())
560 }
561
562 func (sd *SelectDataset) ReturnsColumns() bool {
563 return true
564 }
565
566
567
568
569
570
571
572 func (sd *SelectDataset) ScanStructs(i interface{}) error {
573 return sd.ScanStructsContext(context.Background(), i)
574 }
575
576
577
578
579
580
581
582
583 func (sd *SelectDataset) ScanStructsContext(ctx context.Context, i interface{}) error {
584 if sd.queryFactory == nil {
585 return ErrQueryFactoryNotFoundError
586 }
587 ds := sd
588 if sd.GetClauses().IsDefaultSelect() {
589 ds = sd.Select(i)
590 }
591 return ds.Executor().ScanStructsContext(ctx, i)
592 }
593
594
595
596
597
598
599
600 func (sd *SelectDataset) ScanStruct(i interface{}) (bool, error) {
601 return sd.ScanStructContext(context.Background(), i)
602 }
603
604
605
606
607
608
609
610 func (sd *SelectDataset) ScanStructContext(ctx context.Context, i interface{}) (bool, error) {
611 if sd.queryFactory == nil {
612 return false, ErrQueryFactoryNotFoundError
613 }
614 ds := sd
615 if sd.GetClauses().IsDefaultSelect() {
616 ds = sd.Select(i)
617 }
618 return ds.Limit(1).Executor().ScanStructContext(ctx, i)
619 }
620
621
622
623
624 func (sd *SelectDataset) ScanVals(i interface{}) error {
625 return sd.ScanValsContext(context.Background(), i)
626 }
627
628
629
630
631
632 func (sd *SelectDataset) ScanValsContext(ctx context.Context, i interface{}) error {
633 if sd.queryFactory == nil {
634 return ErrQueryFactoryNotFoundError
635 }
636 return sd.Executor().ScanValsContext(ctx, i)
637 }
638
639
640
641
642 func (sd *SelectDataset) ScanVal(i interface{}) (bool, error) {
643 return sd.ScanValContext(context.Background(), i)
644 }
645
646
647
648
649 func (sd *SelectDataset) ScanValContext(ctx context.Context, i interface{}) (bool, error) {
650 if sd.queryFactory == nil {
651 return false, ErrQueryFactoryNotFoundError
652 }
653 return sd.Limit(1).Executor().ScanValContext(ctx, i)
654 }
655
656
657 func (sd *SelectDataset) Count() (int64, error) {
658 return sd.CountContext(context.Background())
659 }
660
661
662 func (sd *SelectDataset) CountContext(ctx context.Context) (int64, error) {
663 var count int64
664 _, err := sd.Select(COUNT(Star()).As("count")).ScanValContext(ctx, &count)
665 return count, err
666 }
667
668
669
670
671
672
673
674 func (sd *SelectDataset) Pluck(i interface{}, col string) error {
675 return sd.PluckContext(context.Background(), i, col)
676 }
677
678
679
680
681
682
683
684 func (sd *SelectDataset) PluckContext(ctx context.Context, i interface{}, col string) error {
685 return sd.Select(col).ScanValsContext(ctx, i)
686 }
687
688 func (sd *SelectDataset) selectSQLBuilder() sb.SQLBuilder {
689 buf := sb.NewSQLBuilder(sd.isPrepared.Bool())
690 if sd.err != nil {
691 return buf.SetError(sd.err)
692 }
693 sd.dialect.ToSelectSQL(buf, sd.GetClauses())
694 return buf
695 }
696
View as plain text