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 }