toasty_driver_integration_suite/tests/
embed_enum_index.rs1use crate::prelude::*;
2
3#[driver_test]
6pub async fn embedded_enum_index_schema(test: &mut Test) {
7 #[derive(Debug, toasty::Embed)]
8 enum ContactInfo {
9 #[column(variant = 1)]
10 Email {
11 #[unique]
12 address: String,
13 },
14 #[column(variant = 2)]
15 Phone {
16 #[index]
17 number: String,
18 },
19 }
20
21 #[derive(Debug, toasty::Model)]
22 struct User {
23 #[key]
24 id: String,
25 name: String,
26 #[allow(dead_code)]
27 contact: ContactInfo,
28 }
29
30 let db = test.setup_db(models!(User)).await;
31 let schema = db.schema();
32
33 assert_struct!(schema.app.models, #{
35 ContactInfo::id(): toasty::schema::app::Model::EmbeddedEnum({
36 indices.len(): 2,
37 }),
38 ..
39 });
40
41 let table = &schema.db.tables[0];
46 let address_col = columns(&db, "users", &["contact_address"])[0];
47 let number_col = columns(&db, "users", &["contact_number"])[0];
48
49 assert_struct!(table.indices, [
50 { primary_key: true },
52 { unique: true, primary_key: false, columns: [{ column: == address_col }] },
54 { unique: false, primary_key: false, columns: [{ column: == number_col }] },
56 ]);
57}
58
59#[driver_test]
62pub async fn embedded_enum_unique_index_enforced(test: &mut Test) -> Result<()> {
63 #[derive(Debug, toasty::Embed)]
64 enum ContactInfo {
65 #[column(variant = 1)]
66 Email {
67 #[unique]
68 address: String,
69 },
70 #[column(variant = 2)]
71 Phone { number: String },
72 }
73
74 #[derive(Debug, toasty::Model)]
75 struct User {
76 #[key]
77 id: String,
78 name: String,
79 contact: ContactInfo,
80 }
81
82 let mut db = test.setup_db(models!(User)).await;
83
84 User::create()
86 .id("1")
87 .name("Alice")
88 .contact(ContactInfo::Email {
89 address: "alice@example.com".to_string(),
90 })
91 .exec(&mut db)
92 .await?;
93
94 assert_err!(
96 User::create()
97 .id("2")
98 .name("Bob")
99 .contact(ContactInfo::Email {
100 address: "alice@example.com".to_string(),
101 })
102 .exec(&mut db)
103 .await
104 );
105
106 User::create()
108 .id("3")
109 .name("Charlie")
110 .contact(ContactInfo::Email {
111 address: "charlie@example.com".to_string(),
112 })
113 .exec(&mut db)
114 .await?;
115
116 User::create()
118 .id("4")
119 .name("Dave")
120 .contact(ContactInfo::Phone {
121 number: "555-1234".to_string(),
122 })
123 .exec(&mut db)
124 .await?;
125
126 let users = User::filter(
128 User::fields()
129 .contact()
130 .email()
131 .matches(|e| e.address().eq("alice@example.com")),
132 )
133 .exec(&mut db)
134 .await?;
135
136 assert_struct!(users, [{ name: "Alice" }]);
137
138 Ok(())
139}
140
141#[driver_test]
147pub async fn unit_enum_field_index_schema(test: &mut Test) {
148 #[derive(Debug, toasty::Embed)]
149 enum EntityType {
150 Fund,
151 Account,
152 Department,
153 Program,
154 }
155
156 #[derive(Debug, toasty::Model)]
157 #[index(entity_type)]
158 struct Registry {
159 #[key]
160 id: String,
161 #[allow(dead_code)]
162 entity_type: EntityType,
163 }
164
165 let db = test.setup_db(models!(Registry)).await;
166 let schema = db.schema();
167
168 let table = &schema.db.tables[0];
171 let entity_type_col = table
172 .columns
173 .iter()
174 .find(|c| c.name == "entity_type")
175 .expect("entity_type discriminant column should exist");
176
177 assert_struct!(table.indices, [
179 { primary_key: true },
180 { unique: false, primary_key: false, columns: [{ column: == entity_type_col.id }] },
181 ]);
182}
183
184#[driver_test]
187pub async fn unit_enum_field_index_filter(test: &mut Test) -> Result<()> {
188 #[derive(Debug, PartialEq, toasty::Embed)]
189 enum EntityType {
190 Fund,
191 Account,
192 Department,
193 }
194
195 #[derive(Debug, toasty::Model)]
196 #[index(entity_type)]
197 struct Registry {
198 #[key]
199 id: String,
200 entity_type: EntityType,
201 }
202
203 let mut db = test.setup_db(models!(Registry)).await;
204
205 toasty::create!(Registry::[
206 { id: "1", entity_type: EntityType::Fund },
207 { id: "2", entity_type: EntityType::Account },
208 { id: "3", entity_type: EntityType::Fund },
209 { id: "4", entity_type: EntityType::Department },
210 ])
211 .exec(&mut db)
212 .await?;
213
214 let mut funds = Registry::filter(Registry::fields().entity_type().eq(EntityType::Fund))
215 .exec(&mut db)
216 .await?;
217 funds.sort_by(|a, b| a.id.cmp(&b.id));
218
219 assert_struct!(funds, [{ id: "1" }, { id: "3" }]);
220
221 Ok(())
222}
223
224#[driver_test(requires(sql))]
232pub async fn unit_enum_composite_unique_enforced(test: &mut Test) -> Result<()> {
233 #[derive(Debug, PartialEq, toasty::Embed)]
234 enum EntityType {
235 Fund,
236 Account,
237 }
238
239 #[derive(Debug, toasty::Model)]
240 #[unique(entity_type, entity_id)]
241 struct Registry {
242 #[key]
243 #[auto]
244 id: u64,
245 entity_type: EntityType,
246 entity_id: String,
247 }
248
249 let mut db = test.setup_db(models!(Registry)).await;
250
251 let index = db.schema().db.tables[0]
254 .indices
255 .iter()
256 .find(|i| !i.primary_key)
257 .expect("composite unique index");
258 assert!(index.unique);
259 assert_eq!(index.columns.len(), 2);
260
261 toasty::create!(Registry {
262 entity_type: EntityType::Fund,
263 entity_id: "x"
264 })
265 .exec(&mut db)
266 .await?;
267
268 assert_err!(
270 toasty::create!(Registry {
271 entity_type: EntityType::Fund,
272 entity_id: "x"
273 })
274 .exec(&mut db)
275 .await
276 );
277
278 toasty::create!(Registry {
280 entity_type: EntityType::Account,
281 entity_id: "x"
282 })
283 .exec(&mut db)
284 .await?;
285
286 toasty::create!(Registry {
287 entity_type: EntityType::Fund,
288 entity_id: "y"
289 })
290 .exec(&mut db)
291 .await?;
292
293 Ok(())
294}