...

Source file src/github.com/doug-martin/goqu/v9/select_dataset.go

Documentation: github.com/doug-martin/goqu/v9

     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  // Dataset for creating and/or executing SELECT SQL statements.
    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  // used internally by database to create a database with a specific adapter
    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  // Sets the adapter used to serialize values and create the SQL statement
    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  // Set the parameter interpolation behavior. See examples
    51  //
    52  // prepared: If true the dataset WILL NOT interpolate the parameters.
    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  // Returns the current adapter on the dataset
    64  func (sd *SelectDataset) Dialect() SQLDialect {
    65  	return sd.dialect
    66  }
    67  
    68  // Returns the current adapter on the dataset
    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  // Clones the dataset
    80  func (sd *SelectDataset) Clone() exp.Expression {
    81  	return sd.copy(sd.clauses)
    82  }
    83  
    84  // Returns the current clauses on the dataset.
    85  func (sd *SelectDataset) GetClauses() exp.SelectClauses {
    86  	return sd.clauses
    87  }
    88  
    89  // used interally to copy the dataset
    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  // Creates a new UpdateDataset using the FROM of this dataset. This method will also copy over the `WITH`, `WHERE`,
   101  // `ORDER , and `LIMIT`
   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  // Creates a new InsertDataset using the FROM of this dataset. This method will also copy over the `WITH` clause to the
   128  // insert.
   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  // Creates a new DeleteDataset using the FROM of this dataset. This method will also copy over the `WITH`, `WHERE`,
   144  // `ORDER , and `LIMIT`
   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  // Creates a new TruncateDataset using the FROM of this dataset.
   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  // Creates a WITH clause for a common table expression (CTE).
   180  //
   181  // The name will be available to SELECT from in the associated query; and can optionally
   182  // contain a list of column names "name(col1, col2, col3)".
   183  //
   184  // The name will refer to the results of the specified subquery.
   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  // Creates a WITH RECURSIVE clause for a common table expression (CTE)
   190  //
   191  // The name will be available to SELECT from in the associated query; and must
   192  // contain a list of column names "name(col1, col2, col3)" for a recursive clause.
   193  //
   194  // The name will refer to the results of the specified subquery. The subquery for
   195  // a recursive query will always end with a UNION or UNION ALL with a clause that
   196  // refers to the CTE by name.
   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  // Adds columns to the SELECT clause. See examples
   202  // You can pass in the following.
   203  //   string: Will automatically be turned into an identifier
   204  //   Dataset: Will use the SQL generated from that Dataset. If the dataset is aliased it will use that alias as the
   205  //   column name.
   206  //   LiteralExpression: (See Literal) Will use the literal SQL
   207  //   SQLFunction: (See Func, MIN, MAX, COUNT....)
   208  //   Struct: If passing in an instance of a struct, we will parse the struct for the column names to select.
   209  //   See examples
   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  // Adds columns to the SELECT DISTINCT clause. See examples
   218  // You can pass in the following.
   219  //   string: Will automatically be turned into an identifier
   220  //   Dataset: Will use the SQL generated from that Dataset. If the dataset is aliased it will use that alias as the
   221  //   column name.
   222  //   LiteralExpression: (See Literal) Will use the literal SQL
   223  //   SQLFunction: (See Func, MIN, MAX, COUNT....)
   224  //   Struct: If passing in an instance of a struct, we will parse the struct for the column names to select.
   225  //   See examples
   226  // Deprecated: Use Distinct() instead.
   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  // Resets to SELECT *. If the SelectDistinct or Distinct was used the returned Dataset will have the the dataset set to SELECT *.
   236  // See examples.
   237  func (sd *SelectDataset) ClearSelect() *SelectDataset {
   238  	return sd.copy(sd.clauses.SetSelect(exp.NewColumnListExpression(exp.Star())).SetDistinct(nil))
   239  }
   240  
   241  // Adds columns to the SELECT clause. See examples
   242  // You can pass in the following.
   243  //   string: Will automatically be turned into an identifier
   244  //   Dataset: Will use the SQL generated from that Dataset. If the dataset is aliased it will use that alias as the
   245  //   column name.
   246  //   LiteralExpression: (See Literal) Will use the literal SQL
   247  //   SQLFunction: (See Func, MIN, MAX, COUNT....)
   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  // Adds a FROM clause. This return a new dataset with the original sources replaced. See examples.
   257  // You can pass in the following.
   258  //   string: Will automatically be turned into an identifier
   259  //   Dataset: Will be added as a sub select. If the Dataset is not aliased it will automatically be aliased
   260  //   LiteralExpression: (See Literal) Will use the literal SQL
   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  // Returns a new Dataset with the current one as an source. If the current Dataset is not aliased (See Dataset#As) then
   276  // it will automatically be aliased. See examples.
   277  func (sd *SelectDataset) FromSelf() *SelectDataset {
   278  	return sd.copy(exp.NewSelectClauses()).From(sd)
   279  }
   280  
   281  // Alias to InnerJoin. See examples.
   282  func (sd *SelectDataset) Join(table exp.Expression, condition exp.JoinCondition) *SelectDataset {
   283  	return sd.InnerJoin(table, condition)
   284  }
   285  
   286  // Adds an INNER JOIN clause. See examples.
   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  // Adds a FULL OUTER JOIN clause. See examples.
   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  // Adds a RIGHT OUTER JOIN clause. See examples.
   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  // Adds a LEFT OUTER JOIN clause. See examples.
   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  // Adds a FULL JOIN clause. See examples.
   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  // Adds a RIGHT JOIN clause. See examples.
   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  // Adds a LEFT JOIN clause. See examples.
   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  // Adds a NATURAL JOIN clause. See examples.
   322  func (sd *SelectDataset) NaturalJoin(table exp.Expression) *SelectDataset {
   323  	return sd.joinTable(exp.NewUnConditionedJoinExpression(exp.NaturalJoinType, table))
   324  }
   325  
   326  // Adds a NATURAL LEFT JOIN clause. See examples.
   327  func (sd *SelectDataset) NaturalLeftJoin(table exp.Expression) *SelectDataset {
   328  	return sd.joinTable(exp.NewUnConditionedJoinExpression(exp.NaturalLeftJoinType, table))
   329  }
   330  
   331  // Adds a NATURAL RIGHT JOIN clause. See examples.
   332  func (sd *SelectDataset) NaturalRightJoin(table exp.Expression) *SelectDataset {
   333  	return sd.joinTable(exp.NewUnConditionedJoinExpression(exp.NaturalRightJoinType, table))
   334  }
   335  
   336  // Adds a NATURAL FULL JOIN clause. See examples.
   337  func (sd *SelectDataset) NaturalFullJoin(table exp.Expression) *SelectDataset {
   338  	return sd.joinTable(exp.NewUnConditionedJoinExpression(exp.NaturalFullJoinType, table))
   339  }
   340  
   341  // Adds a CROSS JOIN clause. See examples.
   342  func (sd *SelectDataset) CrossJoin(table exp.Expression) *SelectDataset {
   343  	return sd.joinTable(exp.NewUnConditionedJoinExpression(exp.CrossJoinType, table))
   344  }
   345  
   346  // Joins this Datasets table with another
   347  func (sd *SelectDataset) joinTable(join exp.JoinExpression) *SelectDataset {
   348  	return sd.copy(sd.clauses.JoinsAppend(join))
   349  }
   350  
   351  // Adds a WHERE clause. See examples.
   352  func (sd *SelectDataset) Where(expressions ...exp.Expression) *SelectDataset {
   353  	return sd.copy(sd.clauses.WhereAppend(expressions...))
   354  }
   355  
   356  // Removes the WHERE clause. See examples.
   357  func (sd *SelectDataset) ClearWhere() *SelectDataset {
   358  	return sd.copy(sd.clauses.ClearWhere())
   359  }
   360  
   361  // Adds a FOR UPDATE clause. See examples.
   362  func (sd *SelectDataset) ForUpdate(waitOption exp.WaitOption, of ...exp.IdentifierExpression) *SelectDataset {
   363  	return sd.withLock(exp.ForUpdate, waitOption, of...)
   364  }
   365  
   366  // Adds a FOR NO KEY UPDATE clause. See examples.
   367  func (sd *SelectDataset) ForNoKeyUpdate(waitOption exp.WaitOption, of ...exp.IdentifierExpression) *SelectDataset {
   368  	return sd.withLock(exp.ForNoKeyUpdate, waitOption, of...)
   369  }
   370  
   371  // Adds a FOR KEY SHARE clause. See examples.
   372  func (sd *SelectDataset) ForKeyShare(waitOption exp.WaitOption, of ...exp.IdentifierExpression) *SelectDataset {
   373  	return sd.withLock(exp.ForKeyShare, waitOption, of...)
   374  }
   375  
   376  // Adds a FOR SHARE clause. See examples.
   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  // Adds a GROUP BY clause. See examples.
   386  func (sd *SelectDataset) GroupBy(groupBy ...interface{}) *SelectDataset {
   387  	return sd.copy(sd.clauses.SetGroupBy(exp.NewColumnListExpression(groupBy...)))
   388  }
   389  
   390  // Adds more columns to the current GROUP BY clause. See examples.
   391  func (sd *SelectDataset) GroupByAppend(groupBy ...interface{}) *SelectDataset {
   392  	return sd.copy(sd.clauses.GroupByAppend(exp.NewColumnListExpression(groupBy...)))
   393  }
   394  
   395  // Adds a HAVING clause. See examples.
   396  func (sd *SelectDataset) Having(expressions ...exp.Expression) *SelectDataset {
   397  	return sd.copy(sd.clauses.HavingAppend(expressions...))
   398  }
   399  
   400  // Adds a ORDER clause. If the ORDER is currently set it replaces it. See examples.
   401  func (sd *SelectDataset) Order(order ...exp.OrderedExpression) *SelectDataset {
   402  	return sd.copy(sd.clauses.SetOrder(order...))
   403  }
   404  
   405  // Adds a more columns to the current ORDER BY clause. If no order has be previously specified it is the same as
   406  // calling Order. See examples.
   407  func (sd *SelectDataset) OrderAppend(order ...exp.OrderedExpression) *SelectDataset {
   408  	return sd.copy(sd.clauses.OrderAppend(order...))
   409  }
   410  
   411  // Adds a more columns to the beginning of the current ORDER BY clause. If no order has be previously specified it is the same as
   412  // calling Order. See examples.
   413  func (sd *SelectDataset) OrderPrepend(order ...exp.OrderedExpression) *SelectDataset {
   414  	return sd.copy(sd.clauses.OrderPrepend(order...))
   415  }
   416  
   417  // Removes the ORDER BY clause. See examples.
   418  func (sd *SelectDataset) ClearOrder() *SelectDataset {
   419  	return sd.copy(sd.clauses.ClearOrder())
   420  }
   421  
   422  // Adds a LIMIT clause. If the LIMIT is currently set it replaces it. See examples.
   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  // Adds a LIMIT ALL clause. If the LIMIT is currently set it replaces it. See examples.
   431  func (sd *SelectDataset) LimitAll() *SelectDataset {
   432  	return sd.copy(sd.clauses.SetLimit(L("ALL")))
   433  }
   434  
   435  // Removes the LIMIT clause.
   436  func (sd *SelectDataset) ClearLimit() *SelectDataset {
   437  	return sd.copy(sd.clauses.ClearLimit())
   438  }
   439  
   440  // Adds an OFFSET clause. If the OFFSET is currently set it replaces it. See examples.
   441  func (sd *SelectDataset) Offset(offset uint) *SelectDataset {
   442  	return sd.copy(sd.clauses.SetOffset(offset))
   443  }
   444  
   445  // Removes the OFFSET clause from the Dataset
   446  func (sd *SelectDataset) ClearOffset() *SelectDataset {
   447  	return sd.copy(sd.clauses.ClearOffset())
   448  }
   449  
   450  // Creates an UNION statement with another dataset.
   451  // If this or the other dataset has a limit or offset it will use that dataset as a subselect in the FROM clause.
   452  // See examples.
   453  func (sd *SelectDataset) Union(other *SelectDataset) *SelectDataset {
   454  	return sd.withCompound(exp.UnionCompoundType, other.CompoundFromSelf())
   455  }
   456  
   457  // Creates an UNION ALL statement with another dataset.
   458  // If this or the other dataset has a limit or offset it will use that dataset as a subselect in the FROM clause.
   459  // See examples.
   460  func (sd *SelectDataset) UnionAll(other *SelectDataset) *SelectDataset {
   461  	return sd.withCompound(exp.UnionAllCompoundType, other.CompoundFromSelf())
   462  }
   463  
   464  // Creates an INTERSECT statement with another dataset.
   465  // If this or the other dataset has a limit or offset it will use that dataset as a subselect in the FROM clause.
   466  // See examples.
   467  func (sd *SelectDataset) Intersect(other *SelectDataset) *SelectDataset {
   468  	return sd.withCompound(exp.IntersectCompoundType, other.CompoundFromSelf())
   469  }
   470  
   471  // Creates an INTERSECT ALL statement with another dataset.
   472  // If this or the other dataset has a limit or offset it will use that dataset as a subselect in the FROM clause.
   473  // See examples.
   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  // Used internally to determine if the dataset needs to use iteself as a source.
   486  // If the dataset has an order or limit it will select from itself
   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  // Sets the alias for this dataset. This is typically used when using a Dataset as a subselect. See examples.
   495  func (sd *SelectDataset) As(alias string) *SelectDataset {
   496  	return sd.copy(sd.clauses.SetAlias(T(alias)))
   497  }
   498  
   499  // Returns the alias value as an identiier expression
   500  func (sd *SelectDataset) GetAs() exp.IdentifierExpression {
   501  	return sd.clauses.Alias()
   502  }
   503  
   504  // Sets the WINDOW clauses
   505  func (sd *SelectDataset) Window(ws ...exp.WindowExpression) *SelectDataset {
   506  	return sd.copy(sd.clauses.SetWindows(ws))
   507  }
   508  
   509  // Sets the WINDOW clauses
   510  func (sd *SelectDataset) WindowAppend(ws ...exp.WindowExpression) *SelectDataset {
   511  	return sd.copy(sd.clauses.WindowsAppend(ws...))
   512  }
   513  
   514  // Sets the WINDOW clauses
   515  func (sd *SelectDataset) ClearWindow() *SelectDataset {
   516  	return sd.copy(sd.clauses.ClearWindows())
   517  }
   518  
   519  // Get any error that has been set or nil if no error has been set.
   520  func (sd *SelectDataset) Error() error {
   521  	return sd.err
   522  }
   523  
   524  // Set an error on the dataset if one has not already been set. This error will be returned by a future call to Error
   525  // or as part of ToSQL. This can be used by end users to record errors while building up queries without having to
   526  // track those separately.
   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  // Generates a SELECT sql statement, if Prepared has been called with true then the parameters will not be interpolated.
   536  // See examples.
   537  //
   538  // Errors:
   539  //  * There is an error generating the SQL
   540  func (sd *SelectDataset) ToSQL() (sql string, params []interface{}, err error) {
   541  	return sd.selectSQLBuilder().ToSQL()
   542  }
   543  
   544  // Generates the SELECT sql, and returns an Exec struct with the sql set to the SELECT statement
   545  //    db.From("test").Select("col").Executor()
   546  //
   547  // See Dataset#ToUpdateSQL for arguments
   548  func (sd *SelectDataset) Executor() exec.QueryExecutor {
   549  	return sd.queryFactory.FromSQLBuilder(sd.selectSQLBuilder())
   550  }
   551  
   552  // Appends this Dataset's SELECT statement to the SQLBuilder
   553  // This is used internally for sub-selects by the dialect
   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  // Generates the SELECT sql for this dataset and uses Exec#ScanStructs to scan the results into a slice of structs.
   567  //
   568  // ScanStructs will only select the columns that can be scanned in to the struct unless you have explicitly selected
   569  // certain columns. See examples.
   570  //
   571  // i: A pointer to a slice of structs
   572  func (sd *SelectDataset) ScanStructs(i interface{}) error {
   573  	return sd.ScanStructsContext(context.Background(), i)
   574  }
   575  
   576  // Generates the SELECT sql for this dataset and uses Exec#ScanStructsContext to scan the results into a slice of
   577  // structs.
   578  //
   579  // ScanStructsContext will only select the columns that can be scanned in to the struct unless you have explicitly
   580  // selected certain columns. See examples.
   581  //
   582  // i: A pointer to a slice of structs
   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  // Generates the SELECT sql for this dataset and uses Exec#ScanStruct to scan the result into a slice of structs
   595  //
   596  // ScanStruct will only select the columns that can be scanned in to the struct unless you have explicitly selected
   597  // certain columns. See examples.
   598  //
   599  // i: A pointer to a structs
   600  func (sd *SelectDataset) ScanStruct(i interface{}) (bool, error) {
   601  	return sd.ScanStructContext(context.Background(), i)
   602  }
   603  
   604  // Generates the SELECT sql for this dataset and uses Exec#ScanStructContext to scan the result into a slice of structs
   605  //
   606  // ScanStructContext will only select the columns that can be scanned in to the struct unless you have explicitly
   607  // selected certain columns. See examples.
   608  //
   609  // i: A pointer to a structs
   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  // Generates the SELECT sql for this dataset and uses Exec#ScanVals to scan the results into a slice of primitive values
   622  //
   623  // i: A pointer to a slice of primitive values
   624  func (sd *SelectDataset) ScanVals(i interface{}) error {
   625  	return sd.ScanValsContext(context.Background(), i)
   626  }
   627  
   628  // Generates the SELECT sql for this dataset and uses Exec#ScanValsContext to scan the results into a slice of primitive
   629  // values
   630  //
   631  // i: A pointer to a slice of primitive values
   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  // Generates the SELECT sql for this dataset and uses Exec#ScanVal to scan the result into a primitive value
   640  //
   641  // i: A pointer to a primitive value
   642  func (sd *SelectDataset) ScanVal(i interface{}) (bool, error) {
   643  	return sd.ScanValContext(context.Background(), i)
   644  }
   645  
   646  // Generates the SELECT sql for this dataset and uses Exec#ScanValContext to scan the result into a primitive value
   647  //
   648  // i: A pointer to a primitive value
   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  // Generates the SELECT COUNT(*) sql for this dataset and uses Exec#ScanVal to scan the result into an int64.
   657  func (sd *SelectDataset) Count() (int64, error) {
   658  	return sd.CountContext(context.Background())
   659  }
   660  
   661  // Generates the SELECT COUNT(*) sql for this dataset and uses Exec#ScanValContext to scan the result into an int64.
   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  // Generates the SELECT sql only selecting the passed in column and uses Exec#ScanVals to scan the result into a slice
   669  // of primitive values.
   670  //
   671  // i: A slice of primitive values
   672  //
   673  // col: The column to select when generative the SQL
   674  func (sd *SelectDataset) Pluck(i interface{}, col string) error {
   675  	return sd.PluckContext(context.Background(), i, col)
   676  }
   677  
   678  // Generates the SELECT sql only selecting the passed in column and uses Exec#ScanValsContext to scan the result into a
   679  // slice of primitive values.
   680  //
   681  // i: A slice of primitive values
   682  //
   683  // col: The column to select when generative the SQL
   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