github.com/Ali-iotechsys/sqlboiler/v4@v4.0.0-20221208124957-6aec9a5f1f71/queries/qm/query_mods.go (about)

     1  package qm
     2  
     3  import (
     4  	"strings"
     5  
     6  	"github.com/volatiletech/sqlboiler/v4/queries"
     7  	"github.com/volatiletech/sqlboiler/v4/queries/qmhelper"
     8  )
     9  
    10  // QueryMod modifies a query object.
    11  type QueryMod interface {
    12  	Apply(q *queries.Query)
    13  }
    14  
    15  // The QueryModFunc type is an adapter to allow the use
    16  // of ordinary functions for query modifying. If f is a
    17  // function with the appropriate signature,
    18  // QueryModFunc(f) is a QueryMod that calls f.
    19  type QueryModFunc func(q *queries.Query)
    20  
    21  // Apply calls f(q).
    22  func (f QueryModFunc) Apply(q *queries.Query) {
    23  	f(q)
    24  }
    25  
    26  type queryMods []QueryMod
    27  
    28  // Apply applies the query mods to a query, satisfying
    29  // the applicator interface in queries. This "clever"
    30  // inversion of dependency is because suddenly the
    31  // eager loading needs to be able to store query mods
    32  // in the query object, which before - never knew about
    33  // query mods.
    34  func (m queryMods) Apply(q *queries.Query) {
    35  	Apply(q, m...)
    36  }
    37  
    38  // Apply the query mods to the Query object
    39  func Apply(q *queries.Query, mods ...QueryMod) {
    40  	for _, mod := range mods {
    41  		mod.Apply(q)
    42  	}
    43  }
    44  
    45  type sqlQueryMod struct {
    46  	sql  string
    47  	args []interface{}
    48  }
    49  
    50  // Apply implements QueryMod.Apply.
    51  func (qm sqlQueryMod) Apply(q *queries.Query) {
    52  	queries.SetSQL(q, qm.sql, qm.args...)
    53  }
    54  
    55  // SQL allows you to execute a plain SQL statement
    56  func SQL(sql string, args ...interface{}) QueryMod {
    57  	return sqlQueryMod{
    58  		sql:  sql,
    59  		args: args,
    60  	}
    61  }
    62  
    63  type loadQueryMod struct {
    64  	relationship string
    65  	mods         []QueryMod
    66  }
    67  
    68  // Apply implements QueryMod.Apply.
    69  func (qm loadQueryMod) Apply(q *queries.Query) {
    70  	queries.AppendLoad(q, qm.relationship)
    71  
    72  	if len(qm.mods) != 0 {
    73  		queries.SetLoadMods(q, qm.relationship, queryMods(qm.mods))
    74  	}
    75  }
    76  
    77  // Load allows you to specify foreign key relationships to eager load
    78  // for your query. Passed in relationships need to be in the format
    79  // MyThing or MyThings.
    80  // Relationship name plurality is important, if your relationship is
    81  // singular, you need to specify the singular form and vice versa.
    82  //
    83  // In the following example we see how to eager load a users's videos
    84  // and the video's tags comments, and publisher during a query to find users.
    85  //
    86  //   models.Users(qm.Load("Videos.Tags"))
    87  //
    88  // In order to filter better on the query for the relationships you can additionally
    89  // supply query mods.
    90  //
    91  //   models.Users(qm.Load("Videos.Tags", Where("deleted = ?", isDeleted)))
    92  //
    93  // Keep in mind the above only sets the query mods for the query on the last specified
    94  // relationship. In this case, only Tags will get the query mod. If you want to do
    95  // intermediate relationships with query mods you must specify them separately:
    96  //
    97  //   models.Users(
    98  //     qm.Load("Videos", Where("deleted = false"))
    99  //     qm.Load("Videos.Tags", Where("deleted = ?", isDeleted))
   100  //   )
   101  func Load(relationship string, mods ...QueryMod) QueryMod {
   102  	return loadQueryMod{
   103  		relationship: relationship,
   104  		mods:         mods,
   105  	}
   106  }
   107  
   108  type innerJoinQueryMod struct {
   109  	clause string
   110  	args   []interface{}
   111  }
   112  
   113  // Apply implements QueryMod.Apply.
   114  func (qm innerJoinQueryMod) Apply(q *queries.Query) {
   115  	queries.AppendInnerJoin(q, qm.clause, qm.args...)
   116  }
   117  
   118  // InnerJoin on another table
   119  func InnerJoin(clause string, args ...interface{}) QueryMod {
   120  	return innerJoinQueryMod{
   121  		clause: clause,
   122  		args:   args,
   123  	}
   124  }
   125  
   126  type leftOuterJoinQueryMod struct {
   127  	clause string
   128  	args   []interface{}
   129  }
   130  
   131  // Apply implements QueryMod.Apply.
   132  func (qm leftOuterJoinQueryMod) Apply(q *queries.Query) {
   133  	queries.AppendLeftOuterJoin(q, qm.clause, qm.args...)
   134  }
   135  
   136  // LeftOuterJoin on another table
   137  func LeftOuterJoin(clause string, args ...interface{}) QueryMod {
   138  	return leftOuterJoinQueryMod{
   139  		clause: clause,
   140  		args:   args,
   141  	}
   142  }
   143  
   144  type rightOuterJoinQueryMod struct {
   145  	clause string
   146  	args   []interface{}
   147  }
   148  
   149  // Apply implements QueryMod.Apply.
   150  func (qm rightOuterJoinQueryMod) Apply(q *queries.Query) {
   151  	queries.AppendRightOuterJoin(q, qm.clause, qm.args...)
   152  }
   153  
   154  // RightOuterJoin on another table
   155  func RightOuterJoin(clause string, args ...interface{}) QueryMod {
   156  	return rightOuterJoinQueryMod{
   157  		clause: clause,
   158  		args:   args,
   159  	}
   160  }
   161  
   162  type fullOuterJoinQueryMod struct {
   163  	clause string
   164  	args   []interface{}
   165  }
   166  
   167  // Apply implements QueryMod.Apply.
   168  func (qm fullOuterJoinQueryMod) Apply(q *queries.Query) {
   169  	queries.AppendFullOuterJoin(q, qm.clause, qm.args...)
   170  }
   171  
   172  // FullOuterJoin on another table
   173  func FullOuterJoin(clause string, args ...interface{}) QueryMod {
   174  	return fullOuterJoinQueryMod{
   175  		clause: clause,
   176  		args:   args,
   177  	}
   178  }
   179  
   180  type distinctQueryMod struct {
   181  	clause string
   182  }
   183  
   184  // Apply implements QueryMod.Apply.
   185  func (qm distinctQueryMod) Apply(q *queries.Query) {
   186  	queries.SetDistinct(q, qm.clause)
   187  }
   188  
   189  // Distinct allows you to filter duplicates
   190  func Distinct(clause string) QueryMod {
   191  	return distinctQueryMod{
   192  		clause: clause,
   193  	}
   194  }
   195  
   196  type withQueryMod struct {
   197  	clause string
   198  	args   []interface{}
   199  }
   200  
   201  // Apply implements QueryMod.Apply.
   202  func (qm withQueryMod) Apply(q *queries.Query) {
   203  	queries.AppendWith(q, qm.clause, qm.args...)
   204  }
   205  
   206  // With allows you to pass in a Common Table Expression clause (and args)
   207  func With(clause string, args ...interface{}) QueryMod {
   208  	return withQueryMod{
   209  		clause: clause,
   210  		args:   args,
   211  	}
   212  }
   213  
   214  type selectQueryMod struct {
   215  	columns []string
   216  }
   217  
   218  // Apply implements QueryMod.Apply.
   219  func (qm selectQueryMod) Apply(q *queries.Query) {
   220  	queries.AppendSelect(q, qm.columns...)
   221  }
   222  
   223  // Select specific columns opposed to all columns
   224  func Select(columns ...string) QueryMod {
   225  	return selectQueryMod{
   226  		columns: columns,
   227  	}
   228  }
   229  
   230  // Where allows you to specify a where clause for your statement. If multiple
   231  // Where statements are used they are combined with 'and'
   232  func Where(clause string, args ...interface{}) QueryMod {
   233  	return qmhelper.WhereQueryMod{
   234  		Clause: clause,
   235  		Args:   args,
   236  	}
   237  }
   238  
   239  type andQueryMod struct {
   240  	clause string
   241  	args   []interface{}
   242  }
   243  
   244  // Apply implements QueryMod.Apply.
   245  func (qm andQueryMod) Apply(q *queries.Query) {
   246  	queries.AppendWhere(q, qm.clause, qm.args...)
   247  }
   248  
   249  // And allows you to specify a where clause separated by an AND for your statement
   250  // And is a duplicate of the Where function, but allows for more natural looking
   251  // query mod chains, for example: (Where("a=?"), And("b=?"), Or("c=?")))
   252  //
   253  // Because Where statements are by default combined with and, there's no reason
   254  // to call this method as it behaves the same as "Where"
   255  func And(clause string, args ...interface{}) QueryMod {
   256  	return andQueryMod{
   257  		clause: clause,
   258  		args:   args,
   259  	}
   260  }
   261  
   262  type orQueryMod struct {
   263  	clause string
   264  	args   []interface{}
   265  }
   266  
   267  // Apply implements QueryMod.Apply.
   268  func (qm orQueryMod) Apply(q *queries.Query) {
   269  	queries.AppendWhere(q, qm.clause, qm.args...)
   270  	queries.SetLastWhereAsOr(q)
   271  }
   272  
   273  // Or allows you to specify a where clause separated by an OR for your statement
   274  func Or(clause string, args ...interface{}) QueryMod {
   275  	return orQueryMod{
   276  		clause: clause,
   277  		args:   args,
   278  	}
   279  }
   280  
   281  // Or2 takes a Where query mod and turns it into an Or. It can be detrimental
   282  // if used on things that are not Where query mods as it will still modify the
   283  // last Where statement into an Or.
   284  func Or2(q QueryMod) QueryMod {
   285  	return or2QueryMod{inner: q}
   286  }
   287  
   288  type or2QueryMod struct {
   289  	inner QueryMod
   290  }
   291  
   292  func (qm or2QueryMod) Apply(q *queries.Query) {
   293  	qm.inner.Apply(q)
   294  	queries.SetLastWhereAsOr(q)
   295  }
   296  
   297  // Apply implements QueryMod.Apply.
   298  type whereInQueryMod struct {
   299  	clause string
   300  	args   []interface{}
   301  }
   302  
   303  func (qm whereInQueryMod) Apply(q *queries.Query) {
   304  	queries.AppendIn(q, qm.clause, qm.args...)
   305  }
   306  
   307  // WhereIn allows you to specify a "x IN (set)" clause for your where statement
   308  // Example clauses: "column in ?", "(column1,column2) in ?"
   309  func WhereIn(clause string, args ...interface{}) QueryMod {
   310  	return whereInQueryMod{
   311  		clause: clause,
   312  		args:   args,
   313  	}
   314  }
   315  
   316  type andInQueryMod struct {
   317  	clause string
   318  	args   []interface{}
   319  }
   320  
   321  // Apply implements QueryMod.Apply.
   322  func (qm andInQueryMod) Apply(q *queries.Query) {
   323  	queries.AppendIn(q, qm.clause, qm.args...)
   324  }
   325  
   326  // AndIn allows you to specify a "x IN (set)" clause separated by an AndIn
   327  // for your where statement. AndIn is a duplicate of the WhereIn function, but
   328  // allows for more natural looking query mod chains, for example:
   329  // (WhereIn("column1 in ?"), AndIn("column2 in ?"), OrIn("column3 in ?"))
   330  func AndIn(clause string, args ...interface{}) QueryMod {
   331  	return andInQueryMod{
   332  		clause: clause,
   333  		args:   args,
   334  	}
   335  }
   336  
   337  type orInQueryMod struct {
   338  	clause string
   339  	args   []interface{}
   340  }
   341  
   342  // Apply implements QueryMod.Apply.
   343  func (qm orInQueryMod) Apply(q *queries.Query) {
   344  	queries.AppendIn(q, qm.clause, qm.args...)
   345  	queries.SetLastInAsOr(q)
   346  }
   347  
   348  // OrIn allows you to specify an IN clause separated by
   349  // an OR for your where statement
   350  func OrIn(clause string, args ...interface{}) QueryMod {
   351  	return orInQueryMod{
   352  		clause: clause,
   353  		args:   args,
   354  	}
   355  }
   356  
   357  type whereNotInQueryMod struct {
   358  	clause string
   359  	args   []interface{}
   360  }
   361  
   362  // Apply implements QueryMod.Apply.
   363  func (qm whereNotInQueryMod) Apply(q *queries.Query) {
   364  	queries.AppendNotIn(q, qm.clause, qm.args...)
   365  }
   366  
   367  // WhereNotIn allows you to specify a "x NOT IN (set)" clause for your where
   368  // statement. Example clauses: "column not in ?",
   369  // "(column1,column2) not in ?"
   370  func WhereNotIn(clause string, args ...interface{}) QueryMod {
   371  	return whereNotInQueryMod{
   372  		clause: clause,
   373  		args:   args,
   374  	}
   375  }
   376  
   377  type andNotInQueryMod struct {
   378  	clause string
   379  	args   []interface{}
   380  }
   381  
   382  // Apply implements QueryMod.Apply.
   383  func (qm andNotInQueryMod) Apply(q *queries.Query) {
   384  	queries.AppendNotIn(q, qm.clause, qm.args...)
   385  }
   386  
   387  // AndNotIn allows you to specify a "x NOT IN (set)" clause separated by an
   388  // AndNotIn for your where statement. AndNotIn is a duplicate of the WhereNotIn
   389  // function, but allows for more natural looking query mod chains, for example:
   390  // (WhereNotIn("column1 not in ?"), AndIn("column2 not in ?"), OrIn("column3 not
   391  // in ?"))
   392  func AndNotIn(clause string, args ...interface{}) QueryMod {
   393  	return andNotInQueryMod{
   394  		clause: clause,
   395  		args:   args,
   396  	}
   397  }
   398  
   399  type orNotInQueryMod struct {
   400  	clause string
   401  	args   []interface{}
   402  }
   403  
   404  // Apply implements QueryMod.Apply.
   405  func (qm orNotInQueryMod) Apply(q *queries.Query) {
   406  	queries.AppendNotIn(q, qm.clause, qm.args...)
   407  	queries.SetLastInAsOr(q)
   408  }
   409  
   410  // OrNotIn allows you to specify a NOT IN clause separated by
   411  // an OR for your where statement
   412  func OrNotIn(clause string, args ...interface{}) QueryMod {
   413  	return orNotInQueryMod{
   414  		clause: clause,
   415  		args:   args,
   416  	}
   417  }
   418  
   419  // Expr groups where query mods. It's detrimental to use this with any other
   420  // type of Query Mod because the effects will always only affect where clauses.
   421  //
   422  // When Expr is used, the entire query will stop doing automatic paretheses
   423  // for the where statement and you must use Expr anywhere you would like them.
   424  //
   425  // Do NOT use with anything except where.
   426  func Expr(wheremods ...QueryMod) QueryMod {
   427  	return exprMod{mods: wheremods}
   428  }
   429  
   430  type exprMod struct {
   431  	mods []QueryMod
   432  }
   433  
   434  // Apply implements QueryMod.Apply
   435  func (qm exprMod) Apply(q *queries.Query) {
   436  	queries.AppendWhereLeftParen(q)
   437  	for _, mod := range qm.mods {
   438  		mod.Apply(q)
   439  	}
   440  	queries.AppendWhereRightParen(q)
   441  }
   442  
   443  type groupByQueryMod struct {
   444  	clause string
   445  }
   446  
   447  // Apply implements QueryMod.Apply.
   448  func (qm groupByQueryMod) Apply(q *queries.Query) {
   449  	queries.AppendGroupBy(q, qm.clause)
   450  }
   451  
   452  // GroupBy allows you to specify a group by clause for your statement
   453  func GroupBy(clause string) QueryMod {
   454  	return groupByQueryMod{
   455  		clause: clause,
   456  	}
   457  }
   458  
   459  type orderByQueryMod struct {
   460  	clause string
   461  	args   []interface{}
   462  }
   463  
   464  // Apply implements QueryMod.Apply.
   465  func (qm orderByQueryMod) Apply(q *queries.Query) {
   466  	queries.AppendOrderBy(q, qm.clause, qm.args...)
   467  }
   468  
   469  // OrderBy allows you to specify a order by clause for your statement
   470  func OrderBy(clause string, args ...interface{}) QueryMod {
   471  	return orderByQueryMod{
   472  		clause: clause,
   473  		args:   args,
   474  	}
   475  }
   476  
   477  type havingQueryMod struct {
   478  	clause string
   479  	args   []interface{}
   480  }
   481  
   482  // Apply implements QueryMod.Apply.
   483  func (qm havingQueryMod) Apply(q *queries.Query) {
   484  	queries.AppendHaving(q, qm.clause, qm.args...)
   485  }
   486  
   487  // Having allows you to specify a having clause for your statement
   488  func Having(clause string, args ...interface{}) QueryMod {
   489  	return havingQueryMod{
   490  		clause: clause,
   491  		args:   args,
   492  	}
   493  }
   494  
   495  type fromQueryMod struct {
   496  	from string
   497  }
   498  
   499  // Apply implements QueryMod.Apply.
   500  func (qm fromQueryMod) Apply(q *queries.Query) {
   501  	queries.AppendFrom(q, qm.from)
   502  }
   503  
   504  // From allows to specify the table for your statement
   505  func From(from string) QueryMod {
   506  	return fromQueryMod{
   507  		from: from,
   508  	}
   509  }
   510  
   511  type limitQueryMod struct {
   512  	limit int
   513  }
   514  
   515  // Apply implements QueryMod.Apply.
   516  func (qm limitQueryMod) Apply(q *queries.Query) {
   517  	queries.SetLimit(q, qm.limit)
   518  }
   519  
   520  // Limit the number of returned rows
   521  func Limit(limit int) QueryMod {
   522  	return limitQueryMod{
   523  		limit: limit,
   524  	}
   525  }
   526  
   527  type offsetQueryMod struct {
   528  	offset int
   529  }
   530  
   531  // Apply implements QueryMod.Apply.
   532  func (qm offsetQueryMod) Apply(q *queries.Query) {
   533  	queries.SetOffset(q, qm.offset)
   534  }
   535  
   536  // Offset into the results
   537  func Offset(offset int) QueryMod {
   538  	return offsetQueryMod{
   539  		offset: offset,
   540  	}
   541  }
   542  
   543  type forQueryMod struct {
   544  	clause string
   545  }
   546  
   547  // Apply implements QueryMod.Apply.
   548  func (qm forQueryMod) Apply(q *queries.Query) {
   549  	queries.SetFor(q, qm.clause)
   550  }
   551  
   552  // For inserts a concurrency locking clause at the end of your statement
   553  func For(clause string) QueryMod {
   554  	return forQueryMod{
   555  		clause: clause,
   556  	}
   557  }
   558  
   559  type commentQueryMod struct {
   560  	comment string
   561  }
   562  
   563  // Apply implements QueryMod.Apply.
   564  func (qm commentQueryMod) Apply(q *queries.Query) {
   565  	queries.SetComment(q, qm.comment)
   566  }
   567  
   568  // Comment inserts a custom comment at the begin of your query
   569  func Comment(comment string) QueryMod {
   570  	return commentQueryMod{
   571  		comment: comment,
   572  	}
   573  }
   574  
   575  // Rels is an alias for strings.Join to make it easier to use relationship name
   576  // constants in Load.
   577  func Rels(r ...string) string {
   578  	return strings.Join(r, ".")
   579  }
   580  
   581  // WithDeleted removes where clauses that sqlboiler soft-delete may have
   582  // placed in a query.
   583  func WithDeleted() QueryMod {
   584  	return removeDeletedQueryMod{}
   585  }
   586  
   587  type removeDeletedQueryMod struct{}
   588  
   589  func (removeDeletedQueryMod) Apply(q *queries.Query) {
   590  	queries.RemoveSoftDeleteWhere(q)
   591  }