1use crate::{
2 ColumnTrait, EntityTrait, IdenStatic, Iterable, Linked, QueryFilter, QuerySelect, QueryTrait,
3 Related, Select, SelectA, SelectB, SelectThree, SelectTwo, SelectTwoMany, SelectTwoRequired,
4 TopologyChain, TopologyStar, find_linked_recursive, join_tbl_on_condition,
5};
6pub use sea_query::JoinType;
7use sea_query::{Condition, Expr, IntoCondition, IntoIden, SelectExpr};
8
9impl<E> Select<E>
10where
11 E: EntityTrait,
12{
13 pub fn left_join<R>(self, _: R) -> Self
15 where
16 R: EntityTrait,
17 E: Related<R>,
18 {
19 self.join_join(JoinType::LeftJoin, E::to(), E::via())
20 }
21
22 pub fn right_join<R>(self, _: R) -> Self
24 where
25 R: EntityTrait,
26 E: Related<R>,
27 {
28 self.join_join(JoinType::RightJoin, E::to(), E::via())
29 }
30
31 pub fn inner_join<R>(self, _: R) -> Self
33 where
34 R: EntityTrait,
35 E: Related<R>,
36 {
37 self.join_join(JoinType::InnerJoin, E::to(), E::via())
38 }
39
40 pub fn reverse_join<R>(self, _: R) -> Self
42 where
43 R: EntityTrait + Related<E>,
44 {
45 self.join_rev(JoinType::InnerJoin, R::to())
46 }
47
48 pub fn find_also<R>(self, _: E, r: R) -> SelectTwo<E, R>
50 where
51 R: EntityTrait,
52 E: Related<R>,
53 {
54 self.left_join(r).select_also(r)
55 }
56
57 pub fn find_also_related<R>(self, r: R) -> SelectTwo<E, R>
59 where
60 R: EntityTrait,
61 E: Related<R>,
62 {
63 self.left_join(r).select_also(r)
64 }
65
66 pub fn find_both_related<R>(self, r: R) -> SelectTwoRequired<E, R>
68 where
69 R: EntityTrait,
70 E: Related<R>,
71 {
72 self.inner_join(r).select_two_required(r)
73 }
74
75 pub fn find_with_related<R>(self, r: R) -> SelectTwoMany<E, R>
77 where
78 R: EntityTrait,
79 E: Related<R>,
80 {
81 self.left_join(r).select_with(r)
82 }
83
84 pub fn find_also_linked<L, T>(self, l: L) -> SelectTwo<E, T>
86 where
87 L: Linked<FromEntity = E, ToEntity = T>,
88 T: EntityTrait,
89 {
90 SelectTwo::new_without_prepare(self.left_join_linked(l).into_query())
91 }
92
93 pub fn find_with_linked<L, T>(self, l: L) -> SelectTwoMany<E, T>
95 where
96 L: Linked<FromEntity = E, ToEntity = T>,
97 T: EntityTrait,
98 {
99 SelectTwoMany::new_without_prepare(self.left_join_linked(l).into_query())
100 }
101
102 pub fn left_join_linked<L, T>(mut self, l: L) -> Self
104 where
105 L: Linked<FromEntity = E, ToEntity = T>,
106 T: EntityTrait,
107 {
108 for (i, mut rel) in l.link().into_iter().enumerate() {
109 let r = self.linked_index;
110 self.linked_index += 1;
111 let to_tbl = format!("r{r}").into_iden();
112 let from_tbl = if i > 0 {
113 format!("r{}", i - 1).into_iden()
114 } else {
115 rel.from_tbl.sea_orm_table().clone()
116 };
117 let table_ref = rel.to_tbl;
118
119 let mut condition = Condition::all().add(join_tbl_on_condition(
120 from_tbl.clone(),
121 to_tbl.clone(),
122 rel.from_col,
123 rel.to_col,
124 ));
125 if let Some(f) = rel.on_condition.take() {
126 condition = condition.add(f(from_tbl.clone(), to_tbl.clone()));
127 }
128
129 self.query
130 .join_as(JoinType::LeftJoin, table_ref, to_tbl, condition);
131 }
132 self = self.apply_alias(SelectA.as_str());
133 for col in <T::Column as Iterable>::iter() {
134 let alias = format!("{}{}", SelectB.as_str(), col.as_str());
135 let expr = Expr::col((
136 format!("r{}", self.linked_index - 1).into_iden(),
137 col.into_iden(),
138 ));
139 self.query.expr(SelectExpr {
140 expr: col.select_as(expr),
141 alias: Some(alias.into_iden()),
142 window: None,
143 });
144 }
145 self
146 }
147
148 pub fn has_related<R, C>(mut self, _: R, condition: C) -> Self
181 where
182 R: EntityTrait,
183 E: Related<R>,
184 C: IntoCondition,
185 {
186 let mut to = None;
187 let mut condition = condition.into_condition();
188 condition = condition.add(if let Some(via) = E::via() {
189 to = Some(E::to());
190 via
191 } else {
192 E::to()
193 });
194 let mut subquery = R::find()
195 .select_only()
196 .expr(Expr::cust("1"))
197 .filter(condition)
198 .into_query();
199 if let Some(to) = to {
200 subquery.inner_join(to.from_tbl.clone(), to);
202 }
203 self.query.cond_where(Expr::exists(subquery));
204 self
205 }
206
207 #[doc(hidden)]
208 pub fn find_with_linked_recursive<L>(self, l: L) -> Select<E>
210 where
211 L: Linked<FromEntity = E, ToEntity = E>,
212 {
213 find_linked_recursive(self, l.link())
214 }
215}
216
217impl<E, F> SelectTwo<E, F>
218where
219 E: EntityTrait,
220 F: EntityTrait,
221{
222 #[doc(hidden)]
224 pub fn select_also_fake<R>(self, _: R) -> SelectThree<E, F, R, TopologyStar>
225 where
226 R: EntityTrait,
227 {
228 SelectThree::new_without_prepare(self.into_query())
230 }
231
232 pub fn find_also<G, R>(self, _: G, _: R) -> SelectThree<E, F, R, TopologyStar>
234 where
235 R: EntityTrait,
236 G: EntityTrait + Related<R>,
237 {
238 SelectThree::new(
239 self.join_join(JoinType::LeftJoin, G::to(), G::via())
240 .into_query(),
241 )
242 }
243
244 pub fn find_also_related<R>(self, _: R) -> SelectThree<E, F, R, TopologyStar>
246 where
247 R: EntityTrait,
248 E: Related<R>,
249 {
250 SelectThree::new(
251 self.join_join(JoinType::LeftJoin, E::to(), E::via())
252 .into_query(),
253 )
254 }
255
256 pub fn and_also_related<R>(self, _: R) -> SelectThree<E, F, R, TopologyChain>
258 where
259 R: EntityTrait,
260 F: Related<R>,
261 {
262 SelectThree::new(
263 self.join_join(JoinType::LeftJoin, F::to(), F::via())
264 .into_query(),
265 )
266 }
267}
268
269#[cfg(test)]
270mod tests {
271 use crate::tests_cfg::{
272 cake, cake_compact, cake_filling, cake_filling_price, entity_linked, filling, fruit,
273 };
274 use crate::{
275 ColumnTrait, DbBackend, EntityTrait, ModelTrait, QueryFilter, QuerySelect, QueryTrait,
276 RelationTrait,
277 };
278 use pretty_assertions::assert_eq;
279 use sea_query::{ConditionType, Expr, ExprTrait, IntoCondition, JoinType};
280
281 #[test]
282 fn join_1() {
283 assert_eq!(
284 cake::Entity::find()
285 .left_join(fruit::Entity)
286 .build(DbBackend::MySql)
287 .to_string(),
288 [
289 "SELECT `cake`.`id`, `cake`.`name` FROM `cake`",
290 "LEFT JOIN `fruit` ON `cake`.`id` = `fruit`.`cake_id`",
291 ]
292 .join(" ")
293 );
294 }
295
296 #[test]
297 fn join_2() {
298 assert_eq!(
299 cake::Entity::find()
300 .inner_join(fruit::Entity)
301 .filter(fruit::Column::Name.contains("cherry"))
302 .build(DbBackend::MySql)
303 .to_string(),
304 [
305 "SELECT `cake`.`id`, `cake`.`name` FROM `cake`",
306 "INNER JOIN `fruit` ON `cake`.`id` = `fruit`.`cake_id`",
307 "WHERE `fruit`.`name` LIKE \'%cherry%\'"
308 ]
309 .join(" ")
310 );
311 }
312
313 #[test]
314 fn join_3() {
315 assert_eq!(
316 fruit::Entity::find()
317 .reverse_join(cake::Entity)
318 .build(DbBackend::MySql)
319 .to_string(),
320 [
321 "SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit`",
322 "INNER JOIN `cake` ON `cake`.`id` = `fruit`.`cake_id`",
323 ]
324 .join(" ")
325 );
326 }
327
328 #[test]
329 fn join_4() {
330 use crate::{Related, Select};
331
332 let find_fruit: Select<fruit::Entity> = cake::Entity::find_related();
333 assert_eq!(
334 find_fruit
335 .filter(cake::Column::Id.eq(11))
336 .build(DbBackend::MySql)
337 .to_string(),
338 [
339 "SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit`",
340 "INNER JOIN `cake` ON `cake`.`id` = `fruit`.`cake_id`",
341 "WHERE `cake`.`id` = 11",
342 ]
343 .join(" ")
344 );
345
346 let find_fruit: Select<fruit::Entity> = cake::Entity::find_related_rev();
347 assert_eq!(
348 find_fruit
349 .filter(cake::Column::Id.eq(11))
350 .build(DbBackend::MySql)
351 .to_string(),
352 [
353 "SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit`",
354 "INNER JOIN `cake` ON `fruit`.`cake_id` = `cake`.`id`",
355 "WHERE `cake`.`id` = 11",
356 ]
357 .join(" ")
358 );
359 }
360
361 #[test]
362 fn join_5() {
363 let cake_model = cake::Model {
364 id: 12,
365 name: "".to_owned(),
366 };
367
368 assert_eq!(
369 cake_model
370 .find_related(fruit::Entity)
371 .build(DbBackend::MySql)
372 .to_string(),
373 [
374 "SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit`",
375 "INNER JOIN `cake` ON `cake`.`id` = `fruit`.`cake_id`",
376 "WHERE `cake`.`id` = 12",
377 ]
378 .join(" ")
379 );
380 }
381
382 #[test]
383 fn join_6() {
384 assert_eq!(
385 cake::Entity::find()
386 .left_join(filling::Entity)
387 .build(DbBackend::MySql)
388 .to_string(),
389 [
390 "SELECT `cake`.`id`, `cake`.`name` FROM `cake`",
391 "LEFT JOIN `cake_filling` ON `cake`.`id` = `cake_filling`.`cake_id`",
392 "LEFT JOIN `filling` ON `cake_filling`.`filling_id` = `filling`.`id`",
393 ]
394 .join(" ")
395 );
396 }
397
398 #[test]
399 fn join_7() {
400 use crate::{Related, Select};
401
402 let find_filling: Select<filling::Entity> = cake::Entity::find_related();
403 assert_eq!(
404 find_filling.build(DbBackend::MySql).to_string(),
405 [
406 "SELECT `filling`.`id`, `filling`.`name`, `filling`.`vendor_id` FROM `filling`",
407 "INNER JOIN `cake_filling` ON `cake_filling`.`filling_id` = `filling`.`id`",
408 "INNER JOIN `cake` ON `cake`.`id` = `cake_filling`.`cake_id`",
409 ]
410 .join(" ")
411 );
412
413 let find_filling: Select<filling::Entity> = cake::Entity::find_related_rev();
414 assert_eq!(
415 find_filling.build(DbBackend::MySql).to_string(),
416 [
417 "SELECT `filling`.`id`, `filling`.`name`, `filling`.`vendor_id` FROM `filling`",
418 "INNER JOIN `cake_filling` ON `filling`.`id` = `cake_filling`.`filling_id`",
419 "INNER JOIN `cake` ON `cake_filling`.`cake_id` = `cake`.`id`",
420 ]
421 .join(" ")
422 );
423 }
424
425 #[test]
426 fn join_8() {
427 use crate::{Related, Select};
428
429 let find_cake_filling_price: Select<cake_filling_price::Entity> =
430 cake_filling::Entity::find_related();
431 assert_eq!(
432 find_cake_filling_price.build(DbBackend::Postgres).to_string(),
433 [
434 r#"SELECT "cake_filling_price"."cake_id", "cake_filling_price"."filling_id", "cake_filling_price"."price""#,
435 r#"FROM "public"."cake_filling_price""#,
436 r#"INNER JOIN "cake_filling" ON"#,
437 r#""cake_filling"."cake_id" = "cake_filling_price"."cake_id" AND"#,
438 r#""cake_filling"."filling_id" = "cake_filling_price"."filling_id""#,
439 ]
440 .join(" ")
441 );
442 }
443
444 #[test]
445 fn join_9() {
446 use crate::{Related, Select};
447
448 let find_cake_filling: Select<cake_filling::Entity> =
449 cake_filling_price::Entity::find_related();
450 assert_eq!(
451 find_cake_filling.build(DbBackend::Postgres).to_string(),
452 [
453 r#"SELECT "cake_filling"."cake_id", "cake_filling"."filling_id""#,
454 r#"FROM "cake_filling""#,
455 r#"INNER JOIN "public"."cake_filling_price" ON"#,
456 r#""cake_filling_price"."cake_id" = "cake_filling"."cake_id" AND"#,
457 r#""cake_filling_price"."filling_id" = "cake_filling"."filling_id""#,
458 ]
459 .join(" ")
460 );
461 }
462
463 #[test]
464 fn join_10() {
465 let cake_model = cake::Model {
466 id: 12,
467 name: "".to_owned(),
468 };
469
470 assert_eq!(
471 cake_model
472 .find_linked(entity_linked::CakeToFilling)
473 .build(DbBackend::MySql)
474 .to_string(),
475 [
476 r"SELECT `filling`.`id`, `filling`.`name`, `filling`.`vendor_id`",
477 r"FROM `filling`",
478 r"INNER JOIN `cake_filling` AS `r0` ON `r0`.`filling_id` = `filling`.`id`",
479 r"INNER JOIN `cake` AS `r1` ON `r1`.`id` = `r0`.`cake_id`",
480 r"WHERE `r1`.`id` = 12",
481 ]
482 .join(" ")
483 );
484 }
485
486 #[test]
487 fn join_11() {
488 let cake_model = cake::Model {
489 id: 18,
490 name: "".to_owned(),
491 };
492
493 assert_eq!(
494 cake_model
495 .find_linked(entity_linked::CakeToFillingVendor)
496 .build(DbBackend::MySql)
497 .to_string(),
498 [
499 r"SELECT `vendor`.`id`, `vendor`.`name`",
500 r"FROM `vendor`",
501 r"INNER JOIN `filling` AS `r0` ON `r0`.`vendor_id` = `vendor`.`id`",
502 r"INNER JOIN `cake_filling` AS `r1` ON `r1`.`filling_id` = `r0`.`id`",
503 r"INNER JOIN `cake` AS `r2` ON `r2`.`id` = `r1`.`cake_id`",
504 r"WHERE `r2`.`id` = 18",
505 ]
506 .join(" ")
507 );
508 }
509
510 #[test]
511 fn join_12() {
512 assert_eq!(
513 cake::Entity::find()
514 .find_also_linked(entity_linked::CakeToFilling)
515 .build(DbBackend::MySql)
516 .to_string(),
517 [
518 r"SELECT `cake`.`id` AS `A_id`, `cake`.`name` AS `A_name`,",
519 r"`r1`.`id` AS `B_id`, `r1`.`name` AS `B_name`, `r1`.`vendor_id` AS `B_vendor_id`",
520 r"FROM `cake`",
521 r"LEFT JOIN `cake_filling` AS `r0` ON `cake`.`id` = `r0`.`cake_id`",
522 r"LEFT JOIN `filling` AS `r1` ON `r0`.`filling_id` = `r1`.`id`",
523 ]
524 .join(" ")
525 );
526 }
527
528 #[test]
529 fn join_13() {
530 assert_eq!(
531 cake::Entity::find()
532 .find_also_linked(entity_linked::CakeToFillingVendor)
533 .build(DbBackend::MySql)
534 .to_string(),
535 [
536 r"SELECT `cake`.`id` AS `A_id`, `cake`.`name` AS `A_name`,",
537 r"`r2`.`id` AS `B_id`, `r2`.`name` AS `B_name`",
538 r"FROM `cake`",
539 r"LEFT JOIN `cake_filling` AS `r0` ON `cake`.`id` = `r0`.`cake_id`",
540 r"LEFT JOIN `filling` AS `r1` ON `r0`.`filling_id` = `r1`.`id`",
541 r"LEFT JOIN `vendor` AS `r2` ON `r1`.`vendor_id` = `r2`.`id`",
542 ]
543 .join(" ")
544 );
545 }
546
547 #[test]
548 fn join_14() {
549 assert_eq!(
550 cake_compact::Entity::find()
551 .join(JoinType::LeftJoin, cake_compact::Relation::TropicalFruit.def())
552 .build(DbBackend::MySql)
553 .to_string(),
554 [
555 "SELECT `cake`.`id`, `cake`.`name` FROM `cake`",
556 "LEFT JOIN `fruit` ON `cake`.`id` = `fruit`.`cake_id` AND `fruit`.`name` LIKE '%tropical%'",
557 ]
558 .join(" ")
559 );
560 }
561
562 #[test]
563 fn join_15() {
564 let cake_model = cake::Model {
565 id: 18,
566 name: "".to_owned(),
567 };
568
569 assert_eq!(
570 cake_model
571 .find_linked(entity_linked::CheeseCakeToFillingVendor)
572 .build(DbBackend::MySql)
573 .to_string(),
574 [
575 r"SELECT `vendor`.`id`, `vendor`.`name`",
576 r"FROM `vendor`",
577 r"INNER JOIN `filling` AS `r0` ON `r0`.`vendor_id` = `vendor`.`id`",
578 r"INNER JOIN `cake_filling` AS `r1` ON `r1`.`filling_id` = `r0`.`id`",
579 r"INNER JOIN `cake` AS `r2` ON `r2`.`id` = `r1`.`cake_id` AND `r2`.`name` LIKE '%cheese%'",
580 r"WHERE `r2`.`id` = 18",
581 ]
582 .join(" ")
583 );
584 }
585
586 #[test]
587 fn join_16() {
588 }
590
591 #[test]
592 fn join_17() {
593 assert_eq!(
594 cake::Entity::find()
595 .find_also_linked(entity_linked::CheeseCakeToFillingVendor)
596 .build(DbBackend::MySql)
597 .to_string(),
598 [
599 r"SELECT `cake`.`id` AS `A_id`, `cake`.`name` AS `A_name`,",
600 r"`r2`.`id` AS `B_id`, `r2`.`name` AS `B_name`",
601 r"FROM `cake`",
602 r"LEFT JOIN `cake_filling` AS `r0` ON `cake`.`id` = `r0`.`cake_id` AND `cake`.`name` LIKE '%cheese%'",
603 r"LEFT JOIN `filling` AS `r1` ON `r0`.`filling_id` = `r1`.`id`",
604 r"LEFT JOIN `vendor` AS `r2` ON `r1`.`vendor_id` = `r2`.`id`",
605 ]
606 .join(" ")
607 );
608 }
609
610 #[test]
611 fn join_18() {
612 }
614
615 #[test]
616 fn join_19() {
617 assert_eq!(
618 cake_compact::Entity::find()
619 .join(JoinType::LeftJoin, cake_compact::Relation::TropicalFruit.def())
620 .join(
621 JoinType::LeftJoin,
622 cake_filling::Relation::Cake
623 .def()
624 .rev()
625 .on_condition(|_left, right| {
626 Expr::col((right, cake_filling::Column::CakeId))
627 .gt(10)
628 .into_condition()
629 })
630 )
631 .join(
632 JoinType::LeftJoin,
633 cake_filling::Relation::Filling
634 .def()
635 .on_condition(|_left, right| {
636 Expr::col((right, filling::Column::Name))
637 .like("%lemon%")
638 .into_condition()
639 })
640 )
641 .join(JoinType::LeftJoin, filling::Relation::Vendor.def())
642 .build(DbBackend::MySql)
643 .to_string(),
644 [
645 "SELECT `cake`.`id`, `cake`.`name` FROM `cake`",
646 "LEFT JOIN `fruit` ON `cake`.`id` = `fruit`.`cake_id` AND `fruit`.`name` LIKE '%tropical%'",
647 "LEFT JOIN `cake_filling` ON `cake`.`id` = `cake_filling`.`cake_id` AND `cake_filling`.`cake_id` > 10",
648 "LEFT JOIN `filling` ON `cake_filling`.`filling_id` = `filling`.`id` AND `filling`.`name` LIKE '%lemon%'",
649 "LEFT JOIN `vendor` ON `filling`.`vendor_id` = `vendor`.`id`",
650 ]
651 .join(" ")
652 );
653 }
654
655 #[test]
656 fn join_20() {
657 assert_eq!(
658 cake::Entity::find()
659 .column_as(
660 Expr::col(("fruit_alias", fruit::Column::Name)),
661 "fruit_name"
662 )
663 .join_as(
664 JoinType::LeftJoin,
665 cake::Relation::Fruit
666 .def()
667 .on_condition(|_left, right| {
668 Expr::col((right, fruit::Column::Name))
669 .like("%tropical%")
670 .into_condition()
671 }),
672 "fruit_alias"
673 )
674 .build(DbBackend::MySql)
675 .to_string(),
676 [
677 "SELECT `cake`.`id`, `cake`.`name`, `fruit_alias`.`name` AS `fruit_name` FROM `cake`",
678 "LEFT JOIN `fruit` AS `fruit_alias` ON `cake`.`id` = `fruit_alias`.`cake_id` AND `fruit_alias`.`name` LIKE '%tropical%'",
679 ]
680 .join(" ")
681 );
682 }
683
684 #[test]
685 fn join_21() {
686 assert_eq!(
687 cake_compact::Entity::find()
688 .column_as(
689 Expr::col(("cake_filling_alias", cake_filling::Column::CakeId)),
690 "cake_filling_cake_id"
691 )
692 .join(JoinType::LeftJoin, cake_compact::Relation::TropicalFruit.def())
693 .join_as_rev(
694 JoinType::LeftJoin,
695 cake_filling::Relation::Cake
696 .def()
697 .on_condition(|left, _right| {
698 Expr::col((left, cake_filling::Column::CakeId))
699 .gt(10)
700 .into_condition()
701 }),
702 "cake_filling_alias"
703 )
704 .build(DbBackend::MySql)
705 .to_string(),
706 [
707 "SELECT `cake`.`id`, `cake`.`name`, `cake_filling_alias`.`cake_id` AS `cake_filling_cake_id` FROM `cake`",
708 "LEFT JOIN `fruit` ON `cake`.`id` = `fruit`.`cake_id` AND `fruit`.`name` LIKE '%tropical%'",
709 "LEFT JOIN `cake_filling` AS `cake_filling_alias` ON `cake_filling_alias`.`cake_id` = `cake`.`id` AND `cake_filling_alias`.`cake_id` > 10",
710 ]
711 .join(" ")
712 );
713 }
714
715 #[test]
716 fn join_22() {
717 assert_eq!(
718 cake_compact::Entity::find()
719 .column_as(
720 Expr::col(("cake_filling_alias", cake_filling::Column::CakeId)),
721 "cake_filling_cake_id"
722 )
723 .join(JoinType::LeftJoin, cake_compact::Relation::OrTropicalFruit.def())
724 .join_as_rev(
725 JoinType::LeftJoin,
726 cake_filling::Relation::Cake
727 .def()
728 .condition_type(ConditionType::Any)
729 .on_condition(|left, _right| {
730 Expr::col((left, cake_filling::Column::CakeId))
731 .gt(10)
732 .into_condition()
733 }),
734 "cake_filling_alias"
735 )
736 .build(DbBackend::MySql)
737 .to_string(),
738 [
739 "SELECT `cake`.`id`, `cake`.`name`, `cake_filling_alias`.`cake_id` AS `cake_filling_cake_id` FROM `cake`",
740 "LEFT JOIN `fruit` ON `cake`.`id` = `fruit`.`cake_id` OR `fruit`.`name` LIKE '%tropical%'",
741 "LEFT JOIN `cake_filling` AS `cake_filling_alias` ON `cake_filling_alias`.`cake_id` = `cake`.`id` OR `cake_filling_alias`.`cake_id` > 10",
742 ]
743 .join(" ")
744 );
745 }
746
747 #[test]
748 fn join_23() {
749 let cake_model = cake::Model {
750 id: 18,
751 name: "".to_owned(),
752 };
753
754 assert_eq!(
755 cake_model
756 .find_linked(entity_linked::CakeToCakeViaFilling)
757 .build(DbBackend::MySql)
758 .to_string(),
759 [
760 "SELECT `cake`.`id`, `cake`.`name` FROM `cake`",
761 "INNER JOIN `cake_filling` AS `r0` ON `r0`.`cake_id` = `cake`.`id`",
762 "INNER JOIN `filling` AS `r1` ON `r1`.`id` = `r0`.`filling_id`",
763 "INNER JOIN `cake_filling` AS `r2` ON `r2`.`filling_id` = `r1`.`id`",
764 "INNER JOIN `cake` AS `r3` ON `r3`.`id` = `r2`.`cake_id`",
765 "WHERE `r3`.`id` = 18",
766 ]
767 .join(" ")
768 );
769 }
770
771 #[test]
772 fn join_24() {
773 let cake_model = cake::Model {
774 id: 12,
775 name: "".to_owned(),
776 };
777
778 assert_eq!(
779 cake_model
780 .find_linked_recursive(entity_linked::CakeToCakeViaFilling)
781 .build(DbBackend::MySql)
782 .to_string(),
783 [
784 "WITH `cte` AS (SELECT `cake`.`id`, `cake`.`name` FROM `cake`",
785 "INNER JOIN `cake_filling` AS `r0` ON `r0`.`cake_id` = `cake`.`id`",
786 "INNER JOIN `filling` AS `r1` ON `r1`.`id` = `r0`.`filling_id`",
787 "INNER JOIN `cake_filling` AS `r2` ON `r2`.`filling_id` = `r1`.`id`",
788 "INNER JOIN `cake` AS `r3` ON `r3`.`id` = `r2`.`cake_id`",
789 "WHERE `r3`.`id` = 12",
790 "UNION ALL (SELECT `cake`.`id`, `cake`.`name` FROM `cake`",
791 "INNER JOIN `cake_filling` AS `r0` ON `r0`.`cake_id` = `cake`.`id`",
792 "INNER JOIN `filling` AS `r1` ON `r1`.`id` = `r0`.`filling_id`",
793 "INNER JOIN `cake_filling` AS `r2` ON `r2`.`filling_id` = `r1`.`id`",
794 "INNER JOIN `cte` AS `r3` ON `r3`.`id` = `r2`.`cake_id`))",
795 "SELECT `cake`.`id`, `cake`.`name` FROM `cte` AS `cake`",
796 ]
797 .join(" ")
798 );
799 }
800
801 #[test]
802 fn join_25() {
803 assert_eq!(
804 cake::Entity::find()
805 .find_with_linked_recursive(entity_linked::CakeToCakeViaFilling)
806 .build(DbBackend::MySql)
807 .to_string(),
808 [
809 "WITH `cte` AS (SELECT `cake`.`id`, `cake`.`name` FROM `cake`",
810 "UNION ALL (SELECT `cake`.`id`, `cake`.`name` FROM `cake`",
811 "INNER JOIN `cake_filling` AS `r0` ON `r0`.`cake_id` = `cake`.`id`",
812 "INNER JOIN `filling` AS `r1` ON `r1`.`id` = `r0`.`filling_id`",
813 "INNER JOIN `cake_filling` AS `r2` ON `r2`.`filling_id` = `r1`.`id`",
814 "INNER JOIN `cte` AS `r3` ON `r3`.`id` = `r2`.`cake_id`))",
815 "SELECT `cake`.`id`, `cake`.`name` FROM `cte` AS `cake`",
816 ]
817 .join(" ")
818 );
819 }
820}