Skip to main content

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
296/// A date time column with a server-side default of 'now'.
297pub fn date_time_default_now<T: IntoIden>(col: T) -> ColumnDef {
298    date_time(col).default(Expr::current_timestamp()).take()
299}
300
301pub fn interval<T: IntoIden>(
302    col: T,
303    fields: Option<PgInterval>,
304    precision: Option<u32>,
305) -> ColumnDef {
306    ColumnDef::new(col)
307        .interval(fields, precision)
308        .not_null()
309        .take()
310}
311
312pub fn interval_null<T: IntoIden>(
313    col: T,
314    fields: Option<PgInterval>,
315    precision: Option<u32>,
316) -> ColumnDef {
317    ColumnDef::new(col)
318        .interval(fields, precision)
319        .null()
320        .take()
321}
322
323pub fn interval_uniq<T: IntoIden>(
324    col: T,
325    fields: Option<PgInterval>,
326    precision: Option<u32>,
327) -> ColumnDef {
328    interval(col, fields, precision).unique_key().take()
329}
330
331pub fn timestamp<T: IntoIden>(col: T) -> ColumnDef {
332    ColumnDef::new(col).timestamp().not_null().take()
333}
334
335pub fn timestamp_null<T: IntoIden>(col: T) -> ColumnDef {
336    ColumnDef::new(col).timestamp().null().take()
337}
338
339pub fn timestamp_uniq<T: IntoIden>(col: T) -> ColumnDef {
340    timestamp(col).unique_key().take()
341}
342
343/// A timestamp column with a server-side default of 'now'.
344pub fn timestamp_default_now<T: IntoIden>(col: T) -> ColumnDef {
345    timestamp(col).default(Expr::current_timestamp()).take()
346}
347
348pub fn timestamp_with_time_zone<T: IntoIden>(col: T) -> ColumnDef {
349    ColumnDef::new(col)
350        .timestamp_with_time_zone()
351        .not_null()
352        .take()
353}
354
355pub fn timestamp_with_time_zone_null<T: IntoIden>(col: T) -> ColumnDef {
356    ColumnDef::new(col).timestamp_with_time_zone().null().take()
357}
358
359pub fn timestamp_with_time_zone_uniq<T: IntoIden>(col: T) -> ColumnDef {
360    timestamp_with_time_zone(col).unique_key().take()
361}
362
363/// A timestamp with time zone column with a server-side default of 'now'.
364pub fn timestamp_with_time_zone_default_now<T: IntoIden>(col: T) -> ColumnDef {
365    timestamp_with_time_zone(col)
366        .default(Expr::current_timestamp())
367        .take()
368}
369
370pub fn time<T: IntoIden>(col: T) -> ColumnDef {
371    ColumnDef::new(col).time().not_null().take()
372}
373
374pub fn time_null<T: IntoIden>(col: T) -> ColumnDef {
375    ColumnDef::new(col).time().null().take()
376}
377
378pub fn time_uniq<T: IntoIden>(col: T) -> ColumnDef {
379    time(col).unique_key().take()
380}
381
382pub fn date<T: IntoIden>(col: T) -> ColumnDef {
383    ColumnDef::new(col).date().not_null().take()
384}
385
386pub fn date_null<T: IntoIden>(col: T) -> ColumnDef {
387    ColumnDef::new(col).date().null().take()
388}
389
390pub fn date_uniq<T: IntoIden>(col: T) -> ColumnDef {
391    date(col).unique_key().take()
392}
393
394pub fn year<T: IntoIden>(col: T) -> ColumnDef {
395    ColumnDef::new(col).year().not_null().take()
396}
397
398pub fn year_null<T: IntoIden>(col: T) -> ColumnDef {
399    ColumnDef::new(col).year().null().take()
400}
401
402pub fn year_uniq<T: IntoIden>(col: T) -> ColumnDef {
403    year(col).unique_key().take()
404}
405
406pub fn binary_len<T: IntoIden>(col: T, length: u32) -> ColumnDef {
407    ColumnDef::new(col).binary_len(length).not_null().take()
408}
409
410pub fn binary_len_null<T: IntoIden>(col: T, length: u32) -> ColumnDef {
411    ColumnDef::new(col).binary_len(length).null().take()
412}
413
414pub fn binary_len_uniq<T: IntoIden>(col: T, length: u32) -> ColumnDef {
415    binary_len(col, length).unique_key().take()
416}
417
418pub fn binary<T: IntoIden>(col: T) -> ColumnDef {
419    ColumnDef::new(col).binary().not_null().take()
420}
421
422pub fn binary_null<T: IntoIden>(col: T) -> ColumnDef {
423    ColumnDef::new(col).binary().null().take()
424}
425
426pub fn binary_uniq<T: IntoIden>(col: T) -> ColumnDef {
427    binary(col).unique_key().take()
428}
429
430pub fn var_binary<T: IntoIden>(col: T, length: u32) -> ColumnDef {
431    ColumnDef::new(col).var_binary(length).not_null().take()
432}
433
434pub fn var_binary_null<T: IntoIden>(col: T, length: u32) -> ColumnDef {
435    ColumnDef::new(col).var_binary(length).null().take()
436}
437
438pub fn var_binary_uniq<T: IntoIden>(col: T, length: u32) -> ColumnDef {
439    var_binary(col, length).unique_key().take()
440}
441
442pub fn bit<T: IntoIden>(col: T, length: Option<u32>) -> ColumnDef {
443    ColumnDef::new(col).bit(length).not_null().take()
444}
445
446pub fn bit_null<T: IntoIden>(col: T, length: Option<u32>) -> ColumnDef {
447    ColumnDef::new(col).bit(length).null().take()
448}
449
450pub fn bit_uniq<T: IntoIden>(col: T, length: Option<u32>) -> ColumnDef {
451    bit(col, length).unique_key().take()
452}
453
454pub fn varbit<T: IntoIden>(col: T, length: u32) -> ColumnDef {
455    ColumnDef::new(col).varbit(length).not_null().take()
456}
457
458pub fn varbit_null<T: IntoIden>(col: T, length: u32) -> ColumnDef {
459    ColumnDef::new(col).varbit(length).null().take()
460}
461
462pub fn varbit_uniq<T: IntoIden>(col: T, length: u32) -> ColumnDef {
463    varbit(col, length).unique_key().take()
464}
465
466pub fn blob<T: IntoIden>(col: T) -> ColumnDef {
467    ColumnDef::new(col).blob().not_null().take()
468}
469
470pub fn blob_null<T: IntoIden>(col: T) -> ColumnDef {
471    ColumnDef::new(col).blob().null().take()
472}
473
474pub fn blob_uniq<T: IntoIden>(col: T) -> ColumnDef {
475    blob(col).unique_key().take()
476}
477
478pub fn boolean<T: IntoIden>(col: T) -> ColumnDef {
479    ColumnDef::new(col).boolean().not_null().take()
480}
481
482pub fn boolean_null<T: IntoIden>(col: T) -> ColumnDef {
483    ColumnDef::new(col).boolean().null().take()
484}
485
486pub fn boolean_uniq<T: IntoIden>(col: T) -> ColumnDef {
487    boolean(col).unique_key().take()
488}
489
490pub fn money_len<T: IntoIden>(col: T, precision: u32, scale: u32) -> ColumnDef {
491    ColumnDef::new(col)
492        .money_len(precision, scale)
493        .not_null()
494        .take()
495}
496
497pub fn money_len_null<T: IntoIden>(col: T, precision: u32, scale: u32) -> ColumnDef {
498    ColumnDef::new(col)
499        .money_len(precision, scale)
500        .null()
501        .take()
502}
503
504pub fn money_len_uniq<T: IntoIden>(col: T, precision: u32, scale: u32) -> ColumnDef {
505    money_len(col, precision, scale).unique_key().take()
506}
507
508pub fn money<T: IntoIden>(col: T) -> ColumnDef {
509    ColumnDef::new(col).money().not_null().take()
510}
511
512pub fn money_null<T: IntoIden>(col: T) -> ColumnDef {
513    ColumnDef::new(col).money().null().take()
514}
515
516pub fn money_uniq<T: IntoIden>(col: T) -> ColumnDef {
517    money(col).unique_key().take()
518}
519
520pub fn json<T: IntoIden>(col: T) -> ColumnDef {
521    ColumnDef::new(col).json().not_null().take()
522}
523
524pub fn json_null<T: IntoIden>(col: T) -> ColumnDef {
525    ColumnDef::new(col).json().null().take()
526}
527
528pub fn json_uniq<T: IntoIden>(col: T) -> ColumnDef {
529    json(col).unique_key().take()
530}
531
532pub fn json_binary<T: IntoIden>(col: T) -> ColumnDef {
533    ColumnDef::new(col).json_binary().not_null().take()
534}
535
536pub fn json_binary_null<T: IntoIden>(col: T) -> ColumnDef {
537    ColumnDef::new(col).json_binary().null().take()
538}
539
540pub fn json_binary_uniq<T: IntoIden>(col: T) -> ColumnDef {
541    json_binary(col).unique_key().take()
542}
543
544pub fn uuid<T: IntoIden>(col: T) -> ColumnDef {
545    ColumnDef::new(col).uuid().not_null().take()
546}
547
548pub fn uuid_null<T: IntoIden>(col: T) -> ColumnDef {
549    ColumnDef::new(col).uuid().null().take()
550}
551
552pub fn uuid_uniq<T: IntoIden>(col: T) -> ColumnDef {
553    uuid(col).unique_key().take()
554}
555
556pub fn custom<T: IntoIden, N: IntoIden>(col: T, name: N) -> ColumnDef {
557    ColumnDef::new(col).custom(name).not_null().take()
558}
559
560pub fn custom_null<T: IntoIden, N: IntoIden>(col: T, name: N) -> ColumnDef {
561    ColumnDef::new(col).custom(name).null().take()
562}
563
564pub fn enumeration<T, N, S, V>(col: T, name: N, variants: V) -> ColumnDef
565where
566    T: IntoIden,
567    N: IntoIden,
568    S: IntoIden,
569    V: IntoIterator<Item = S>,
570{
571    ColumnDef::new(col)
572        .enumeration(name, variants)
573        .not_null()
574        .take()
575}
576
577pub fn enumeration_null<T, N, S, V>(col: T, name: N, variants: V) -> ColumnDef
578where
579    T: IntoIden,
580    N: IntoIden,
581    S: IntoIden,
582    V: IntoIterator<Item = S>,
583{
584    ColumnDef::new(col)
585        .enumeration(name, variants)
586        .null()
587        .take()
588}
589
590pub fn enumeration_uniq<T, N, S, V>(col: T, name: N, variants: V) -> ColumnDef
591where
592    T: IntoIden,
593    N: IntoIden,
594    S: IntoIden,
595    V: IntoIterator<Item = S>,
596{
597    enumeration(col, name, variants).unique_key().take()
598}
599
600pub fn array<T: IntoIden>(col: T, elem_type: ColumnType) -> ColumnDef {
601    ColumnDef::new(col).array(elem_type).not_null().take()
602}
603
604pub fn array_null<T: IntoIden>(col: T, elem_type: ColumnType) -> ColumnDef {
605    ColumnDef::new(col).array(elem_type).null().take()
606}
607
608pub fn array_uniq<T: IntoIden>(col: T, elem_type: ColumnType) -> ColumnDef {
609    array(col, elem_type).unique_key().take()
610}
611
612/// Add timestamp columns (`CreatedAt` and `UpdatedAt`) to an existing table.
613pub fn timestamps(t: TableCreateStatement) -> TableCreateStatement {
614    let mut t = t;
615    t.col(timestamp(GeneralIds::CreatedAt).default(Expr::current_timestamp()))
616        .col(timestamp(GeneralIds::UpdatedAt).default(Expr::current_timestamp()))
617        .take()
618}
619
620/// Create an Alias.
621pub fn name<T: Into<String>>(name: T) -> Alias {
622    Alias::new(name)
623}