sea_orm_migration/
schema.rs

1//! > Adapted from https://github.com/loco-rs/loco/blob/master/src/schema.rs
2//!
3//! # Database Table Schema Helpers
4//!
5//! This module defines functions and helpers for creating database table
6//! schemas using the `sea-orm` and `sea-query` libraries.
7//!
8//! # Example
9//!
10//! The following example shows how the user migration file should be and using
11//! the schema helpers to create the Db fields.
12//!
13//! ```rust
14//! use sea_orm_migration::{prelude::*, schema::*};
15//!
16//! #[derive(DeriveMigrationName)]
17//! pub struct Migration;
18//!
19//! #[async_trait::async_trait]
20//! impl MigrationTrait for Migration {
21//!     async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
22//!         let table = table_auto(Users::Table)
23//!             .col(pk_auto(Users::Id))
24//!             .col(uuid(Users::Pid))
25//!             .col(string_uniq(Users::Email))
26//!             .col(string(Users::Password))
27//!             .col(string(Users::Name))
28//!             .col(string_null(Users::ResetToken))
29//!             .col(timestamp_null(Users::ResetSentAt))
30//!             .to_owned();
31//!         manager.create_table(table).await?;
32//!         Ok(())
33//!     }
34//!
35//!     async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
36//!         manager
37//!             .drop_table(Table::drop().table(Users::Table).to_owned())
38//!             .await
39//!     }
40//! }
41//!
42//! #[derive(Iden)]
43//! pub enum Users {
44//!     Table,
45//!     Id,
46//!     Pid,
47//!     Email,
48//!     Name,
49//!     Password,
50//!     ResetToken,
51//!     ResetSentAt,
52//! }
53//! ```
54
55use crate::{prelude::Iden, sea_query};
56use sea_orm::sea_query::{
57    Alias, ColumnDef, ColumnType, Expr, IntoIden, PgInterval, Table, TableCreateStatement,
58};
59
60#[derive(Iden)]
61enum GeneralIds {
62    CreatedAt,
63    UpdatedAt,
64}
65
66/// Wrapping table schema creation.
67pub fn table_auto<T: IntoIden + 'static>(name: T) -> TableCreateStatement {
68    timestamps(Table::create().table(name).if_not_exists().take())
69}
70
71/// Create a primary key column with auto-increment feature.
72pub fn pk_auto<T: IntoIden>(name: T) -> ColumnDef {
73    integer(name).auto_increment().primary_key().take()
74}
75
76/// Create a UUID primary key
77pub fn pk_uuid<T: IntoIden>(name: T) -> ColumnDef {
78    uuid(name).primary_key().take()
79}
80
81pub fn char_len<T: IntoIden>(col: T, length: u32) -> ColumnDef {
82    ColumnDef::new(col).char_len(length).not_null().take()
83}
84
85pub fn char_len_null<T: IntoIden>(col: T, length: u32) -> ColumnDef {
86    ColumnDef::new(col).char_len(length).null().take()
87}
88
89pub fn char_len_uniq<T: IntoIden>(col: T, length: u32) -> ColumnDef {
90    char_len(col, length).unique_key().take()
91}
92
93pub fn char<T: IntoIden>(col: T) -> ColumnDef {
94    ColumnDef::new(col).char().not_null().take()
95}
96
97pub fn char_null<T: IntoIden>(col: T) -> ColumnDef {
98    ColumnDef::new(col).char().null().take()
99}
100
101pub fn char_uniq<T: IntoIden>(col: T) -> ColumnDef {
102    char(col).unique_key().take()
103}
104
105pub fn string_len<T: IntoIden>(col: T, length: u32) -> ColumnDef {
106    ColumnDef::new(col).string_len(length).not_null().take()
107}
108
109pub fn string_len_null<T: IntoIden>(col: T, length: u32) -> ColumnDef {
110    ColumnDef::new(col).string_len(length).null().take()
111}
112
113pub fn string_len_uniq<T: IntoIden>(col: T, length: u32) -> ColumnDef {
114    string_len(col, length).unique_key().take()
115}
116
117pub fn string<T: IntoIden>(col: T) -> ColumnDef {
118    ColumnDef::new(col).string().not_null().take()
119}
120
121pub fn string_null<T: IntoIden>(col: T) -> ColumnDef {
122    ColumnDef::new(col).string().null().take()
123}
124
125pub fn string_uniq<T: IntoIden>(col: T) -> ColumnDef {
126    string(col).unique_key().take()
127}
128
129pub fn text<T: IntoIden>(col: T) -> ColumnDef {
130    ColumnDef::new(col).text().not_null().take()
131}
132
133pub fn text_null<T: IntoIden>(col: T) -> ColumnDef {
134    ColumnDef::new(col).text().null().take()
135}
136
137pub fn text_uniq<T: IntoIden>(col: T) -> ColumnDef {
138    text(col).unique_key().take()
139}
140
141pub fn tiny_integer<T: IntoIden>(col: T) -> ColumnDef {
142    ColumnDef::new(col).tiny_integer().not_null().take()
143}
144
145pub fn tiny_integer_null<T: IntoIden>(col: T) -> ColumnDef {
146    ColumnDef::new(col).tiny_integer().null().take()
147}
148
149pub fn tiny_integer_uniq<T: IntoIden>(col: T) -> ColumnDef {
150    tiny_integer(col).unique_key().take()
151}
152
153pub fn small_integer<T: IntoIden>(col: T) -> ColumnDef {
154    ColumnDef::new(col).small_integer().not_null().take()
155}
156
157pub fn small_integer_null<T: IntoIden>(col: T) -> ColumnDef {
158    ColumnDef::new(col).small_integer().null().take()
159}
160
161pub fn small_integer_uniq<T: IntoIden>(col: T) -> ColumnDef {
162    small_integer(col).unique_key().take()
163}
164
165pub fn integer<T: IntoIden>(col: T) -> ColumnDef {
166    ColumnDef::new(col).integer().not_null().take()
167}
168
169pub fn integer_null<T: IntoIden>(col: T) -> ColumnDef {
170    ColumnDef::new(col).integer().null().take()
171}
172
173pub fn integer_uniq<T: IntoIden>(col: T) -> ColumnDef {
174    integer(col).unique_key().take()
175}
176
177pub fn big_integer<T: IntoIden>(col: T) -> ColumnDef {
178    ColumnDef::new(col).big_integer().not_null().take()
179}
180
181pub fn big_integer_null<T: IntoIden>(col: T) -> ColumnDef {
182    ColumnDef::new(col).big_integer().null().take()
183}
184
185pub fn big_integer_uniq<T: IntoIden>(col: T) -> ColumnDef {
186    big_integer(col).unique_key().take()
187}
188
189pub fn tiny_unsigned<T: IntoIden>(col: T) -> ColumnDef {
190    ColumnDef::new(col).tiny_unsigned().not_null().take()
191}
192
193pub fn tiny_unsigned_null<T: IntoIden>(col: T) -> ColumnDef {
194    ColumnDef::new(col).tiny_unsigned().null().take()
195}
196
197pub fn tiny_unsigned_uniq<T: IntoIden>(col: T) -> ColumnDef {
198    tiny_unsigned(col).unique_key().take()
199}
200
201pub fn small_unsigned<T: IntoIden>(col: T) -> ColumnDef {
202    ColumnDef::new(col).small_unsigned().not_null().take()
203}
204
205pub fn small_unsigned_null<T: IntoIden>(col: T) -> ColumnDef {
206    ColumnDef::new(col).small_unsigned().null().take()
207}
208
209pub fn small_unsigned_uniq<T: IntoIden>(col: T) -> ColumnDef {
210    small_unsigned(col).unique_key().take()
211}
212
213pub fn unsigned<T: IntoIden>(col: T) -> ColumnDef {
214    ColumnDef::new(col).unsigned().not_null().take()
215}
216
217pub fn unsigned_null<T: IntoIden>(col: T) -> ColumnDef {
218    ColumnDef::new(col).unsigned().null().take()
219}
220
221pub fn unsigned_uniq<T: IntoIden>(col: T) -> ColumnDef {
222    unsigned(col).unique_key().take()
223}
224
225pub fn big_unsigned<T: IntoIden>(col: T) -> ColumnDef {
226    ColumnDef::new(col).big_unsigned().not_null().take()
227}
228
229pub fn big_unsigned_null<T: IntoIden>(col: T) -> ColumnDef {
230    ColumnDef::new(col).big_unsigned().null().take()
231}
232
233pub fn big_unsigned_uniq<T: IntoIden>(col: T) -> ColumnDef {
234    big_unsigned(col).unique_key().take()
235}
236
237pub fn float<T: IntoIden>(col: T) -> ColumnDef {
238    ColumnDef::new(col).float().not_null().take()
239}
240
241pub fn float_null<T: IntoIden>(col: T) -> ColumnDef {
242    ColumnDef::new(col).float().null().take()
243}
244
245pub fn float_uniq<T: IntoIden>(col: T) -> ColumnDef {
246    float(col).unique_key().take()
247}
248
249pub fn double<T: IntoIden>(col: T) -> ColumnDef {
250    ColumnDef::new(col).double().not_null().take()
251}
252
253pub fn double_null<T: IntoIden>(col: T) -> ColumnDef {
254    ColumnDef::new(col).double().null().take()
255}
256
257pub fn double_uniq<T: IntoIden>(col: T) -> ColumnDef {
258    double(col).unique_key().take()
259}
260
261pub fn decimal_len<T: IntoIden>(col: T, precision: u32, scale: u32) -> ColumnDef {
262    ColumnDef::new(col)
263        .decimal_len(precision, scale)
264        .not_null()
265        .take()
266}
267
268pub fn decimal_len_null<T: IntoIden>(col: T, precision: u32, scale: u32) -> ColumnDef {
269    ColumnDef::new(col)
270        .decimal_len(precision, scale)
271        .null()
272        .take()
273}
274
275pub fn decimal_len_uniq<T: IntoIden>(col: T, precision: u32, scale: u32) -> ColumnDef {
276    decimal_len(col, precision, scale).unique_key().take()
277}
278
279pub fn decimal<T: IntoIden>(col: T) -> ColumnDef {
280    ColumnDef::new(col).decimal().not_null().take()
281}
282
283pub fn decimal_null<T: IntoIden>(col: T) -> ColumnDef {
284    ColumnDef::new(col).decimal().null().take()
285}
286
287pub fn decimal_uniq<T: IntoIden>(col: T) -> ColumnDef {
288    decimal(col).unique_key().take()
289}
290
291pub fn date_time<T: IntoIden>(col: T) -> ColumnDef {
292    ColumnDef::new(col).date_time().not_null().take()
293}
294
295pub fn date_time_null<T: IntoIden>(col: T) -> ColumnDef {
296    ColumnDef::new(col).date_time().null().take()
297}
298
299pub fn date_time_uniq<T: IntoIden>(col: T) -> ColumnDef {
300    date_time(col).unique_key().take()
301}
302
303pub fn interval<T: IntoIden>(
304    col: T,
305    fields: Option<PgInterval>,
306    precision: Option<u32>,
307) -> ColumnDef {
308    ColumnDef::new(col)
309        .interval(fields, precision)
310        .not_null()
311        .take()
312}
313
314pub fn interval_null<T: IntoIden>(
315    col: T,
316    fields: Option<PgInterval>,
317    precision: Option<u32>,
318) -> ColumnDef {
319    ColumnDef::new(col)
320        .interval(fields, precision)
321        .null()
322        .take()
323}
324
325pub fn interval_uniq<T: IntoIden>(
326    col: T,
327    fields: Option<PgInterval>,
328    precision: Option<u32>,
329) -> ColumnDef {
330    interval(col, fields, precision).unique_key().take()
331}
332
333pub fn timestamp<T: IntoIden>(col: T) -> ColumnDef {
334    ColumnDef::new(col).timestamp().not_null().take()
335}
336
337pub fn timestamp_null<T: IntoIden>(col: T) -> ColumnDef {
338    ColumnDef::new(col).timestamp().null().take()
339}
340
341pub fn timestamp_uniq<T: IntoIden>(col: T) -> ColumnDef {
342    timestamp(col).unique_key().take()
343}
344
345pub fn timestamp_with_time_zone<T: IntoIden>(col: T) -> ColumnDef {
346    ColumnDef::new(col)
347        .timestamp_with_time_zone()
348        .not_null()
349        .take()
350}
351
352pub fn timestamp_with_time_zone_null<T: IntoIden>(col: T) -> ColumnDef {
353    ColumnDef::new(col).timestamp_with_time_zone().null().take()
354}
355
356pub fn timestamp_with_time_zone_uniq<T: IntoIden>(col: T) -> ColumnDef {
357    timestamp_with_time_zone(col).unique_key().take()
358}
359
360pub fn time<T: IntoIden>(col: T) -> ColumnDef {
361    ColumnDef::new(col).time().not_null().take()
362}
363
364pub fn time_null<T: IntoIden>(col: T) -> ColumnDef {
365    ColumnDef::new(col).time().null().take()
366}
367
368pub fn time_uniq<T: IntoIden>(col: T) -> ColumnDef {
369    time(col).unique_key().take()
370}
371
372pub fn date<T: IntoIden>(col: T) -> ColumnDef {
373    ColumnDef::new(col).date().not_null().take()
374}
375
376pub fn date_null<T: IntoIden>(col: T) -> ColumnDef {
377    ColumnDef::new(col).date().null().take()
378}
379
380pub fn date_uniq<T: IntoIden>(col: T) -> ColumnDef {
381    date(col).unique_key().take()
382}
383
384pub fn year<T: IntoIden>(col: T) -> ColumnDef {
385    ColumnDef::new(col).year().not_null().take()
386}
387
388pub fn year_null<T: IntoIden>(col: T) -> ColumnDef {
389    ColumnDef::new(col).year().null().take()
390}
391
392pub fn year_uniq<T: IntoIden>(col: T) -> ColumnDef {
393    year(col).unique_key().take()
394}
395
396pub fn binary_len<T: IntoIden>(col: T, length: u32) -> ColumnDef {
397    ColumnDef::new(col).binary_len(length).not_null().take()
398}
399
400pub fn binary_len_null<T: IntoIden>(col: T, length: u32) -> ColumnDef {
401    ColumnDef::new(col).binary_len(length).null().take()
402}
403
404pub fn binary_len_uniq<T: IntoIden>(col: T, length: u32) -> ColumnDef {
405    binary_len(col, length).unique_key().take()
406}
407
408pub fn binary<T: IntoIden>(col: T) -> ColumnDef {
409    ColumnDef::new(col).binary().not_null().take()
410}
411
412pub fn binary_null<T: IntoIden>(col: T) -> ColumnDef {
413    ColumnDef::new(col).binary().null().take()
414}
415
416pub fn binary_uniq<T: IntoIden>(col: T) -> ColumnDef {
417    binary(col).unique_key().take()
418}
419
420pub fn var_binary<T: IntoIden>(col: T, length: u32) -> ColumnDef {
421    ColumnDef::new(col).var_binary(length).not_null().take()
422}
423
424pub fn var_binary_null<T: IntoIden>(col: T, length: u32) -> ColumnDef {
425    ColumnDef::new(col).var_binary(length).null().take()
426}
427
428pub fn var_binary_uniq<T: IntoIden>(col: T, length: u32) -> ColumnDef {
429    var_binary(col, length).unique_key().take()
430}
431
432pub fn bit<T: IntoIden>(col: T, length: Option<u32>) -> ColumnDef {
433    ColumnDef::new(col).bit(length).not_null().take()
434}
435
436pub fn bit_null<T: IntoIden>(col: T, length: Option<u32>) -> ColumnDef {
437    ColumnDef::new(col).bit(length).null().take()
438}
439
440pub fn bit_uniq<T: IntoIden>(col: T, length: Option<u32>) -> ColumnDef {
441    bit(col, length).unique_key().take()
442}
443
444pub fn varbit<T: IntoIden>(col: T, length: u32) -> ColumnDef {
445    ColumnDef::new(col).varbit(length).not_null().take()
446}
447
448pub fn varbit_null<T: IntoIden>(col: T, length: u32) -> ColumnDef {
449    ColumnDef::new(col).varbit(length).null().take()
450}
451
452pub fn varbit_uniq<T: IntoIden>(col: T, length: u32) -> ColumnDef {
453    varbit(col, length).unique_key().take()
454}
455
456pub fn blob<T: IntoIden>(col: T) -> ColumnDef {
457    ColumnDef::new(col).blob().not_null().take()
458}
459
460pub fn blob_null<T: IntoIden>(col: T) -> ColumnDef {
461    ColumnDef::new(col).blob().null().take()
462}
463
464pub fn blob_uniq<T: IntoIden>(col: T) -> ColumnDef {
465    blob(col).unique_key().take()
466}
467
468pub fn boolean<T: IntoIden>(col: T) -> ColumnDef {
469    ColumnDef::new(col).boolean().not_null().take()
470}
471
472pub fn boolean_null<T: IntoIden>(col: T) -> ColumnDef {
473    ColumnDef::new(col).boolean().null().take()
474}
475
476pub fn boolean_uniq<T: IntoIden>(col: T) -> ColumnDef {
477    boolean(col).unique_key().take()
478}
479
480pub fn money_len<T: IntoIden>(col: T, precision: u32, scale: u32) -> ColumnDef {
481    ColumnDef::new(col)
482        .money_len(precision, scale)
483        .not_null()
484        .take()
485}
486
487pub fn money_len_null<T: IntoIden>(col: T, precision: u32, scale: u32) -> ColumnDef {
488    ColumnDef::new(col)
489        .money_len(precision, scale)
490        .null()
491        .take()
492}
493
494pub fn money_len_uniq<T: IntoIden>(col: T, precision: u32, scale: u32) -> ColumnDef {
495    money_len(col, precision, scale).unique_key().take()
496}
497
498pub fn money<T: IntoIden>(col: T) -> ColumnDef {
499    ColumnDef::new(col).money().not_null().take()
500}
501
502pub fn money_null<T: IntoIden>(col: T) -> ColumnDef {
503    ColumnDef::new(col).money().null().take()
504}
505
506pub fn money_uniq<T: IntoIden>(col: T) -> ColumnDef {
507    money(col).unique_key().take()
508}
509
510pub fn json<T: IntoIden>(col: T) -> ColumnDef {
511    ColumnDef::new(col).json().not_null().take()
512}
513
514pub fn json_null<T: IntoIden>(col: T) -> ColumnDef {
515    ColumnDef::new(col).json().null().take()
516}
517
518pub fn json_uniq<T: IntoIden>(col: T) -> ColumnDef {
519    json(col).unique_key().take()
520}
521
522pub fn json_binary<T: IntoIden>(col: T) -> ColumnDef {
523    ColumnDef::new(col).json_binary().not_null().take()
524}
525
526pub fn json_binary_null<T: IntoIden>(col: T) -> ColumnDef {
527    ColumnDef::new(col).json_binary().null().take()
528}
529
530pub fn json_binary_uniq<T: IntoIden>(col: T) -> ColumnDef {
531    json_binary(col).unique_key().take()
532}
533
534pub fn uuid<T: IntoIden>(col: T) -> ColumnDef {
535    ColumnDef::new(col).uuid().not_null().take()
536}
537
538pub fn uuid_null<T: IntoIden>(col: T) -> ColumnDef {
539    ColumnDef::new(col).uuid().null().take()
540}
541
542pub fn uuid_uniq<T: IntoIden>(col: T) -> ColumnDef {
543    uuid(col).unique_key().take()
544}
545
546pub fn custom<T: IntoIden, N: IntoIden>(col: T, name: N) -> ColumnDef {
547    ColumnDef::new(col).custom(name).not_null().take()
548}
549
550pub fn custom_null<T: IntoIden, N: IntoIden>(col: T, name: N) -> ColumnDef {
551    ColumnDef::new(col).custom(name).null().take()
552}
553
554pub fn enumeration<T, N, S, V>(col: T, name: N, variants: V) -> ColumnDef
555where
556    T: IntoIden,
557    N: IntoIden,
558    S: IntoIden,
559    V: IntoIterator<Item = S>,
560{
561    ColumnDef::new(col)
562        .enumeration(name, variants)
563        .not_null()
564        .take()
565}
566
567pub fn enumeration_null<T, N, S, V>(col: T, name: N, variants: V) -> ColumnDef
568where
569    T: IntoIden,
570    N: IntoIden,
571    S: IntoIden,
572    V: IntoIterator<Item = S>,
573{
574    ColumnDef::new(col)
575        .enumeration(name, variants)
576        .null()
577        .take()
578}
579
580pub fn enumeration_uniq<T, N, S, V>(col: T, name: N, variants: V) -> ColumnDef
581where
582    T: IntoIden,
583    N: IntoIden,
584    S: IntoIden,
585    V: IntoIterator<Item = S>,
586{
587    enumeration(col, name, variants).unique_key().take()
588}
589
590pub fn array<T: IntoIden>(col: T, elem_type: ColumnType) -> ColumnDef {
591    ColumnDef::new(col).array(elem_type).not_null().take()
592}
593
594pub fn array_null<T: IntoIden>(col: T, elem_type: ColumnType) -> ColumnDef {
595    ColumnDef::new(col).array(elem_type).null().take()
596}
597
598pub fn array_uniq<T: IntoIden>(col: T, elem_type: ColumnType) -> ColumnDef {
599    array(col, elem_type).unique_key().take()
600}
601
602/// Add timestamp columns (`CreatedAt` and `UpdatedAt`) to an existing table.
603pub fn timestamps(t: TableCreateStatement) -> TableCreateStatement {
604    let mut t = t;
605    t.col(timestamp(GeneralIds::CreatedAt).default(Expr::current_timestamp()))
606        .col(timestamp(GeneralIds::UpdatedAt).default(Expr::current_timestamp()))
607        .take()
608}
609
610/// Create an Alias.
611pub fn name<T: Into<String>>(name: T) -> Alias {
612    Alias::new(name)
613}