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