1use crate::{
2 ColumnDef, ColumnType, DbBackend, EntityName, Iden, IdenStatic, IntoSimpleExpr, Iterable,
3};
4use sea_query::{
5 BinOper, DynIden, Expr, ExprTrait, IntoIden, IntoLikeExpr, SeaRc, SelectStatement, SimpleExpr,
6 Value,
7};
8use std::{borrow::Cow, str::FromStr};
9
10pub(crate) mod methods {
11 macro_rules! bind_oper {
12 ($vis:vis $op:ident, $bin_op:ident) => {
13 #[allow(missing_docs)]
14 $vis fn $op<V>(&self, v: V) -> SimpleExpr
15 where
16 V: Into<Value>,
17 {
18 let expr = self.save_as(Expr::val(v));
19 Expr::col(self.as_column_ref()).binary(BinOper::$bin_op, expr)
20 }
21 };
22 }
23
24 macro_rules! bind_func_no_params {
25 ($vis:vis $func:ident) => {
26 $vis fn $func(&self) -> SimpleExpr {
28 Expr::col(self.as_column_ref()).$func()
29 }
30 };
31 }
32
33 macro_rules! bind_vec_func {
34 ($vis:vis $func:ident) => {
35 #[allow(missing_docs)]
36 #[allow(clippy::wrong_self_convention)]
37 $vis fn $func<V, I>(&self, v: I) -> SimpleExpr
38 where
39 V: Into<Value>,
40 I: IntoIterator<Item = V>,
41 {
42 let v_with_enum_cast = v.into_iter().map(|v| self.save_as(Expr::val(v)));
43 Expr::col(self.as_column_ref()).$func(v_with_enum_cast)
44 }
45 };
46 }
47
48 macro_rules! bind_subquery_func {
49 ($vis:vis $func:ident) => {
50 #[allow(clippy::wrong_self_convention)]
51 #[allow(missing_docs)]
52 $vis fn $func(&self, s: SelectStatement) -> SimpleExpr {
53 Expr::col(self.as_column_ref()).$func(s)
54 }
55 };
56 }
57
58 pub(crate) use bind_func_no_params;
59 pub(crate) use bind_oper;
60 pub(crate) use bind_subquery_func;
61 pub(crate) use bind_vec_func;
62}
63
64use methods::*;
65
66pub trait ColumnTrait: IdenStatic + Iterable + FromStr {
69 #[allow(missing_docs)]
70 type EntityName: EntityName;
71
72 fn def(&self) -> ColumnDef;
74
75 fn enum_type_name(&self) -> Option<&'static str> {
77 None
78 }
79
80 fn entity_name(&self) -> DynIden {
82 SeaRc::new(Self::EntityName::default())
83 }
84
85 fn as_column_ref(&self) -> (DynIden, DynIden) {
87 (self.entity_name(), SeaRc::new(*self))
88 }
89
90 bind_oper!(eq, Equal);
91 bind_oper!(ne, NotEqual);
92 bind_oper!(gt, GreaterThan);
93 bind_oper!(gte, GreaterThanOrEqual);
94 bind_oper!(lt, SmallerThan);
95 bind_oper!(lte, SmallerThanOrEqual);
96
97 fn between<V>(&self, a: V, b: V) -> SimpleExpr
109 where
110 V: Into<Value>,
111 {
112 Expr::col(self.as_column_ref()).between(a, b)
113 }
114
115 fn not_between<V>(&self, a: V, b: V) -> SimpleExpr
127 where
128 V: Into<Value>,
129 {
130 Expr::col(self.as_column_ref()).not_between(a, b)
131 }
132
133 fn like<T>(&self, s: T) -> SimpleExpr
145 where
146 T: IntoLikeExpr,
147 {
148 Expr::col(self.as_column_ref()).like(s)
149 }
150
151 fn not_like<T>(&self, s: T) -> SimpleExpr
163 where
164 T: IntoLikeExpr,
165 {
166 Expr::col(self.as_column_ref()).not_like(s)
167 }
168
169 fn ilike<T>(&self, s: T) -> SimpleExpr
182 where
183 T: IntoLikeExpr,
184 {
185 use sea_query::extension::postgres::PgExpr;
186
187 Expr::col(self.as_column_ref()).ilike(s)
188 }
189
190 fn not_ilike<T>(&self, s: T) -> SimpleExpr
203 where
204 T: IntoLikeExpr,
205 {
206 use sea_query::extension::postgres::PgExpr;
207
208 Expr::col(self.as_column_ref()).not_ilike(s)
209 }
210
211 fn starts_with<T>(&self, s: T) -> SimpleExpr
228 where
229 T: Into<String>,
230 {
231 let pattern = format!("{}%", s.into());
232 Expr::col(self.as_column_ref()).like(pattern)
233 }
234
235 fn ends_with<T>(&self, s: T) -> SimpleExpr
252 where
253 T: Into<String>,
254 {
255 let pattern = format!("%{}", s.into());
256 Expr::col(self.as_column_ref()).like(pattern)
257 }
258
259 fn contains<T>(&self, s: T) -> SimpleExpr
276 where
277 T: Into<String>,
278 {
279 let pattern = format!("%{}%", s.into());
280 Expr::col(self.as_column_ref()).like(pattern)
281 }
282
283 bind_func_no_params!(max);
284 bind_func_no_params!(min);
285 bind_func_no_params!(sum);
286 bind_func_no_params!(count);
287 bind_func_no_params!(is_null);
288 bind_func_no_params!(is_not_null);
289
290 fn if_null<V>(&self, v: V) -> SimpleExpr
292 where
293 V: Into<Value>,
294 {
295 Expr::col(self.as_column_ref()).if_null(v)
296 }
297
298 bind_vec_func!(is_in);
299 bind_vec_func!(is_not_in);
300
301 #[cfg(feature = "postgres-array")]
314 fn eq_any<V, I>(&self, v: I) -> SimpleExpr
315 where
316 V: Into<Value> + sea_query::ValueType + sea_query::with_array::NotU8,
317 I: IntoIterator<Item = V>,
318 {
319 use sea_query::extension::postgres::PgFunc;
320
321 let vec: Vec<_> = v.into_iter().collect();
322 Expr::col(self.as_column_ref()).eq(PgFunc::any(vec))
323 }
324
325 bind_subquery_func!(in_subquery);
326 bind_subquery_func!(not_in_subquery);
327
328 fn into_expr(self) -> Expr {
330 self.into_simple_expr()
331 }
332
333 #[allow(clippy::match_single_binding)]
335 fn into_returning_expr(self, db_backend: DbBackend) -> Expr {
336 match db_backend {
337 _ => Expr::col(self),
338 }
339 }
340
341 fn select_as(&self, expr: Expr) -> SimpleExpr {
344 self.select_enum_as(expr)
345 }
346
347 fn select_enum_as(&self, expr: Expr) -> SimpleExpr {
349 cast_enum_as(expr, &self.def(), select_enum_as)
350 }
351
352 fn save_as(&self, val: Expr) -> SimpleExpr {
355 self.save_enum_as(val)
356 }
357
358 fn save_enum_as(&self, val: Expr) -> SimpleExpr {
360 cast_enum_as(val, &self.def(), save_enum_as)
361 }
362}
363
364pub trait ColumnTypeTrait {
366 fn def(self) -> ColumnDef;
368
369 fn get_enum_name(&self) -> Option<&DynIden>;
371}
372
373impl ColumnTypeTrait for ColumnType {
374 fn def(self) -> ColumnDef {
375 ColumnDef {
376 col_type: self,
377 null: false,
378 unique: false,
379 indexed: false,
380 default: None,
381 comment: None,
382 unique_key: None,
383 renamed_from: None,
384 seaography: Default::default(),
385 }
386 }
387
388 fn get_enum_name(&self) -> Option<&DynIden> {
389 enum_name(self)
390 }
391}
392
393impl ColumnTypeTrait for ColumnDef {
394 fn def(self) -> ColumnDef {
395 self
396 }
397
398 fn get_enum_name(&self) -> Option<&DynIden> {
399 enum_name(&self.col_type)
400 }
401}
402
403fn enum_name(col_type: &ColumnType) -> Option<&DynIden> {
404 match col_type {
405 ColumnType::Enum { name, .. } => Some(name),
406 ColumnType::Array(col_type) => enum_name(col_type),
407 _ => None,
408 }
409}
410
411struct Text;
412struct TextArray;
413
414impl Iden for Text {
415 fn quoted(&self) -> Cow<'static, str> {
416 Cow::Borrowed("text")
417 }
418
419 fn unquoted(&self) -> &str {
420 match self.quoted() {
421 Cow::Borrowed(s) => s,
422 _ => unreachable!(),
423 }
424 }
425}
426
427impl Iden for TextArray {
428 fn quoted(&self) -> Cow<'static, str> {
429 Cow::Borrowed("text[]")
431 }
432
433 fn unquoted(&self) -> &str {
434 match self.quoted() {
435 Cow::Borrowed(s) => s,
436 _ => unreachable!(),
437 }
438 }
439}
440
441pub(crate) fn select_enum_as(col: Expr, _: DynIden, col_type: &ColumnType) -> SimpleExpr {
442 let type_name = match col_type {
443 ColumnType::Array(_) => TextArray.into_iden(),
444 _ => Text.into_iden(),
445 };
446 col.as_enum(type_name)
447}
448
449pub(crate) fn save_enum_as(col: Expr, enum_name: DynIden, col_type: &ColumnType) -> SimpleExpr {
450 let type_name = match col_type {
451 ColumnType::Array(_) => format!("{enum_name}[]").into_iden(),
452 _ => enum_name,
453 };
454 col.as_enum(type_name)
455}
456
457pub(crate) fn cast_enum_as<F>(expr: Expr, col_def: &ColumnDef, f: F) -> SimpleExpr
458where
459 F: Fn(Expr, DynIden, &ColumnType) -> SimpleExpr,
460{
461 let col_type = col_def.get_column_type();
462
463 match col_type {
464 #[cfg(all(feature = "with-json", feature = "postgres-array"))]
465 ColumnType::Json | ColumnType::JsonBinary => {
466 use sea_query::ArrayType;
467 use serde_json::Value as Json;
468
469 match expr {
470 SimpleExpr::Value(Value::Array(ArrayType::Json, Some(json_vec))) => {
471 let json_vec: Vec<Json> = json_vec
473 .into_iter()
474 .filter_map(|val| match val {
475 Value::Json(Some(json)) => Some(json),
476 _ => None,
477 })
478 .collect();
479 SimpleExpr::Value(Value::Json(Some(json_vec.into())))
480 }
481 SimpleExpr::Value(Value::Array(ArrayType::Json, None)) => {
482 SimpleExpr::Value(Value::Json(None))
483 }
484 _ => expr,
485 }
486 }
487 _ => match col_type.get_enum_name() {
488 Some(enum_name) => f(expr, enum_name.clone(), col_type),
489 None => expr,
490 },
491 }
492}
493
494#[cfg(test)]
495mod tests {
496 use crate::{
497 ColumnTrait, Condition, DbBackend, EntityTrait, QueryFilter, QueryTrait, tests_cfg::*,
498 };
499 use sea_query::Query;
500
501 #[test]
502 fn test_in_subquery_1() {
503 assert_eq!(
504 cake::Entity::find()
505 .filter(
506 Condition::any().add(
507 cake::Column::Id.in_subquery(
508 Query::select()
509 .expr(cake::Column::Id.max())
510 .from(cake::Entity)
511 .to_owned()
512 )
513 )
514 )
515 .build(DbBackend::MySql)
516 .to_string(),
517 [
518 "SELECT `cake`.`id`, `cake`.`name` FROM `cake`",
519 "WHERE `cake`.`id` IN (SELECT MAX(`cake`.`id`) FROM `cake`)",
520 ]
521 .join(" ")
522 );
523 }
524
525 #[test]
526 fn test_in_subquery_2() {
527 assert_eq!(
528 cake::Entity::find()
529 .filter(
530 Condition::any().add(
531 cake::Column::Id.in_subquery(
532 Query::select()
533 .column(cake_filling::Column::CakeId)
534 .from(cake_filling::Entity)
535 .to_owned()
536 )
537 )
538 )
539 .build(DbBackend::MySql)
540 .to_string(),
541 [
542 "SELECT `cake`.`id`, `cake`.`name` FROM `cake`",
543 "WHERE `cake`.`id` IN (SELECT `cake_id` FROM `cake_filling`)",
544 ]
545 .join(" ")
546 );
547 }
548
549 #[test]
550 #[cfg(feature = "macros")]
551 fn select_as_1() {
552 use crate::{ActiveModelTrait, ActiveValue, Update};
553
554 mod hello_expanded {
555 use crate as sea_orm;
556 use crate::entity::prelude::*;
557 use crate::sea_query::{Expr, ExprTrait, SimpleExpr};
558
559 #[derive(Copy, Clone, Default, Debug, DeriveEntity)]
560 pub struct Entity;
561
562 impl EntityName for Entity {
563 fn table_name(&self) -> &'static str {
564 "hello"
565 }
566 }
567
568 #[derive(Clone, Debug, PartialEq, Eq, DeriveModel, DeriveActiveModel)]
569 pub struct Model {
570 pub id: i32,
571 #[sea_orm(enum_name = "One1")]
572 pub one: i32,
573 pub two: i32,
574 #[sea_orm(enum_name = "Three3")]
575 pub three: i32,
576 }
577
578 #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
579 pub enum Column {
580 Id,
581 One1,
582 Two,
583 Three3,
584 }
585
586 impl ColumnTrait for Column {
587 type EntityName = Entity;
588
589 fn def(&self) -> ColumnDef {
590 match self {
591 Column::Id => ColumnType::Integer.def(),
592 Column::One1 => ColumnType::Integer.def(),
593 Column::Two => ColumnType::Integer.def(),
594 Column::Three3 => ColumnType::Integer.def(),
595 }
596 }
597
598 fn select_as(&self, expr: Expr) -> SimpleExpr {
599 match self {
600 Self::Two => expr.cast_as("integer"),
601 _ => self.select_enum_as(expr),
602 }
603 }
604 }
605
606 #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]
607 pub enum PrimaryKey {
608 Id,
609 }
610
611 impl PrimaryKeyTrait for PrimaryKey {
612 type ValueType = i32;
613
614 fn auto_increment() -> bool {
615 true
616 }
617 }
618
619 #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
620 pub enum Relation {}
621
622 impl ActiveModelBehavior for ActiveModel {}
623 }
624
625 #[allow(clippy::enum_variant_names)]
626 mod hello_compact {
627 use crate as sea_orm;
628 use crate::entity::prelude::*;
629
630 #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
631 #[sea_orm(table_name = "hello")]
632 pub struct Model {
633 #[sea_orm(primary_key)]
634 pub id: i32,
635 #[sea_orm(enum_name = "One1")]
636 pub one: i32,
637 #[sea_orm(select_as = "integer")]
638 pub two: i32,
639 #[sea_orm(enum_name = "Three3")]
640 pub three: i32,
641 }
642
643 #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
644 pub enum Relation {}
645
646 impl ActiveModelBehavior for ActiveModel {}
647 }
648
649 fn assert_it<E, A>(active_model: A)
650 where
651 E: EntityTrait,
652 A: ActiveModelTrait<Entity = E>,
653 {
654 assert_eq!(
655 E::find().build(DbBackend::Postgres).to_string(),
656 r#"SELECT "hello"."id", "hello"."one1", CAST("hello"."two" AS integer), "hello"."three3" FROM "hello""#,
657 );
658 assert_eq!(
659 Update::one(active_model)
660 .validate()
661 .unwrap()
662 .build(DbBackend::Postgres)
663 .to_string(),
664 r#"UPDATE "hello" SET "one1" = 1, "two" = 2, "three3" = 3 WHERE "hello"."id" = 1"#,
665 );
666 }
667
668 assert_it(hello_expanded::ActiveModel {
669 id: ActiveValue::set(1),
670 one: ActiveValue::set(1),
671 two: ActiveValue::set(2),
672 three: ActiveValue::set(3),
673 });
674 assert_it(hello_compact::ActiveModel {
675 id: ActiveValue::set(1),
676 one: ActiveValue::set(1),
677 two: ActiveValue::set(2),
678 three: ActiveValue::set(3),
679 });
680 }
681
682 #[test]
683 #[cfg(feature = "macros")]
684 fn save_as_1() {
685 use crate::{ActiveModelTrait, ActiveValue, Update};
686
687 mod hello_expanded {
688 use crate as sea_orm;
689 use crate::entity::prelude::*;
690 use crate::sea_query::{Expr, ExprTrait, SimpleExpr};
691
692 #[derive(Copy, Clone, Default, Debug, DeriveEntity)]
693 pub struct Entity;
694
695 impl EntityName for Entity {
696 fn table_name(&self) -> &'static str {
697 "hello"
698 }
699 }
700
701 #[derive(Clone, Debug, PartialEq, Eq, DeriveModel, DeriveActiveModel)]
702 pub struct Model {
703 pub id: i32,
704 #[sea_orm(enum_name = "One1")]
705 pub one: i32,
706 pub two: i32,
707 #[sea_orm(enum_name = "Three3")]
708 pub three: i32,
709 }
710
711 #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
712 pub enum Column {
713 Id,
714 One1,
715 Two,
716 Three3,
717 }
718
719 impl ColumnTrait for Column {
720 type EntityName = Entity;
721
722 fn def(&self) -> ColumnDef {
723 match self {
724 Column::Id => ColumnType::Integer.def(),
725 Column::One1 => ColumnType::Integer.def(),
726 Column::Two => ColumnType::Integer.def(),
727 Column::Three3 => ColumnType::Integer.def(),
728 }
729 }
730
731 fn save_as(&self, val: Expr) -> SimpleExpr {
732 match self {
733 Self::Two => val.cast_as("text"),
734 _ => self.save_enum_as(val),
735 }
736 }
737 }
738
739 #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]
740 pub enum PrimaryKey {
741 Id,
742 }
743
744 impl PrimaryKeyTrait for PrimaryKey {
745 type ValueType = i32;
746
747 fn auto_increment() -> bool {
748 true
749 }
750 }
751
752 #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
753 pub enum Relation {}
754
755 impl ActiveModelBehavior for ActiveModel {}
756 }
757
758 #[allow(clippy::enum_variant_names)]
759 mod hello_compact {
760 use crate as sea_orm;
761 use crate::entity::prelude::*;
762
763 #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
764 #[sea_orm(table_name = "hello")]
765 pub struct Model {
766 #[sea_orm(primary_key)]
767 pub id: i32,
768 #[sea_orm(enum_name = "One1")]
769 pub one: i32,
770 #[sea_orm(save_as = "text")]
771 pub two: i32,
772 #[sea_orm(enum_name = "Three3")]
773 pub three: i32,
774 }
775
776 #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
777 pub enum Relation {}
778
779 impl ActiveModelBehavior for ActiveModel {}
780 }
781
782 fn assert_it<E, A>(active_model: A)
783 where
784 E: EntityTrait,
785 A: ActiveModelTrait<Entity = E>,
786 {
787 assert_eq!(
788 E::find().build(DbBackend::Postgres).to_string(),
789 r#"SELECT "hello"."id", "hello"."one1", "hello"."two", "hello"."three3" FROM "hello""#,
790 );
791 assert_eq!(
792 Update::one(active_model)
793 .validate()
794 .unwrap()
795 .build(DbBackend::Postgres)
796 .to_string(),
797 r#"UPDATE "hello" SET "one1" = 1, "two" = CAST(2 AS text), "three3" = 3 WHERE "hello"."id" = 1"#,
798 );
799 }
800
801 assert_it(hello_expanded::ActiveModel {
802 id: ActiveValue::set(1),
803 one: ActiveValue::set(1),
804 two: ActiveValue::set(2),
805 three: ActiveValue::set(3),
806 });
807 assert_it(hello_compact::ActiveModel {
808 id: ActiveValue::set(1),
809 one: ActiveValue::set(1),
810 two: ActiveValue::set(2),
811 three: ActiveValue::set(3),
812 });
813 }
814
815 #[test]
816 #[cfg(feature = "macros")]
817 fn select_as_and_value_1() {
818 use crate::{ActiveModelTrait, ActiveValue, Update};
819
820 mod hello_expanded {
821 use crate as sea_orm;
822 use crate::entity::prelude::*;
823 use crate::sea_query::{Expr, ExprTrait, SimpleExpr};
824
825 #[derive(Copy, Clone, Default, Debug, DeriveEntity)]
826 pub struct Entity;
827
828 impl EntityName for Entity {
829 fn table_name(&self) -> &'static str {
830 "hello"
831 }
832 }
833
834 #[derive(Clone, Debug, PartialEq, Eq, DeriveModel, DeriveActiveModel)]
835 pub struct Model {
836 pub id: i32,
837 #[sea_orm(enum_name = "One1")]
838 pub one: i32,
839 pub two: i32,
840 #[sea_orm(enum_name = "Three3")]
841 pub three: i32,
842 }
843
844 #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
845 pub enum Column {
846 Id,
847 One1,
848 Two,
849 Three3,
850 }
851
852 impl ColumnTrait for Column {
853 type EntityName = Entity;
854
855 fn def(&self) -> ColumnDef {
856 match self {
857 Column::Id => ColumnType::Integer.def(),
858 Column::One1 => ColumnType::Integer.def(),
859 Column::Two => ColumnType::Integer.def(),
860 Column::Three3 => ColumnType::Integer.def(),
861 }
862 }
863
864 fn select_as(&self, expr: Expr) -> SimpleExpr {
865 match self {
866 Self::Two => expr.cast_as("integer"),
867 _ => self.select_enum_as(expr),
868 }
869 }
870
871 fn save_as(&self, val: Expr) -> SimpleExpr {
872 match self {
873 Self::Two => val.cast_as("text"),
874 _ => self.save_enum_as(val),
875 }
876 }
877 }
878
879 #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]
880 pub enum PrimaryKey {
881 Id,
882 }
883
884 impl PrimaryKeyTrait for PrimaryKey {
885 type ValueType = i32;
886
887 fn auto_increment() -> bool {
888 true
889 }
890 }
891
892 #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
893 pub enum Relation {}
894
895 impl ActiveModelBehavior for ActiveModel {}
896 }
897
898 #[allow(clippy::enum_variant_names)]
899 mod hello_compact {
900 use crate as sea_orm;
901 use crate::entity::prelude::*;
902
903 #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
904 #[sea_orm(table_name = "hello")]
905 pub struct Model {
906 #[sea_orm(primary_key)]
907 pub id: i32,
908 #[sea_orm(enum_name = "One1")]
909 pub one: i32,
910 #[sea_orm(select_as = "integer", save_as = "text")]
911 pub two: i32,
912 #[sea_orm(enum_name = "Three3")]
913 pub three: i32,
914 }
915
916 #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
917 pub enum Relation {}
918
919 impl ActiveModelBehavior for ActiveModel {}
920 }
921
922 fn assert_it<E, A>(active_model: A)
923 where
924 E: EntityTrait,
925 A: ActiveModelTrait<Entity = E>,
926 {
927 assert_eq!(
928 E::find().build(DbBackend::Postgres).to_string(),
929 r#"SELECT "hello"."id", "hello"."one1", CAST("hello"."two" AS integer), "hello"."three3" FROM "hello""#,
930 );
931 assert_eq!(
932 Update::one(active_model)
933 .validate()
934 .unwrap()
935 .build(DbBackend::Postgres)
936 .to_string(),
937 r#"UPDATE "hello" SET "one1" = 1, "two" = CAST(2 AS text), "three3" = 3 WHERE "hello"."id" = 1"#,
938 );
939 }
940
941 assert_it(hello_expanded::ActiveModel {
942 id: ActiveValue::set(1),
943 one: ActiveValue::set(1),
944 two: ActiveValue::set(2),
945 three: ActiveValue::set(3),
946 });
947 assert_it(hello_compact::ActiveModel {
948 id: ActiveValue::set(1),
949 one: ActiveValue::set(1),
950 two: ActiveValue::set(2),
951 three: ActiveValue::set(3),
952 });
953 }
954}