1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
use core::fmt;
/// Why [`SeedConfig`](crate::SeedConfig) could not build the statements
/// (returned by `try_generate` and `reset_plan`).
#[derive(Clone, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub enum SeedError {
/// The non-skipped `tables` have a foreign-key cycle, so there is no
/// parent-first order. A self-reference counts only when all of its
/// columns are `NOT NULL`.
CyclicForeignKeys { tables: Vec<String> },
/// A `NOT NULL` foreign key in `child` has no `parent` row to point at:
/// the seeded parent got zero rows, or the relation count is zero. (A
/// nullable foreign key is set to `NULL` instead.)
MissingParentRows { child: String, parent: String },
/// `reset_plan` would delete a parent's rows while a skipped table still
/// references it.
UnsafeResetSelection {
/// The table that would be emptied.
parent: String,
/// The skipped table that references it.
skipped_child: String,
},
/// A single row needs more bind parameters than the limit (`max_params`,
/// or the dialect's maximum).
ParameterLimitTooLow {
/// The table being seeded.
table: String,
/// Parameters one row needs.
required: usize,
/// The configured limit.
limit: usize,
},
/// A `*_by_name` setting names a table the schema does not have.
UnknownTable {
/// The name as given.
table: String,
/// The schema's tables.
known: Vec<String>,
},
/// A `*_by_name` setting names a table that exists in several
/// namespaces; qualify it as `schema.table`.
AmbiguousTable {
/// The name as given.
table: String,
/// The matching tables.
candidates: Vec<String>,
},
/// A `*_by_name` setting names a column the table does not have.
UnknownColumn {
/// The table.
table: String,
/// The column name as given.
column: String,
/// The table's columns.
known: Vec<String>,
},
/// `relation_by_name` was given a `child` with no foreign key to
/// `parent`.
NotRelated {
/// The parent table.
parent: String,
/// The child table.
child: String,
},
/// `Schema::from_snapshot` was given a snapshot for a dialect whose
/// feature (`sqlite`, `postgres` or `mysql`) is off.
DialectNotEnabled {
/// The snapshot's dialect.
dialect: String,
},
/// A value has no SQL literal form, so the statement cannot be written
/// with its values inline (`inline_sql`, `try_generate_script`).
NoLiteral {
/// What is wrong with the value.
reason: String,
},
/// A generated value cannot be stored in the column's SQL type.
InvalidValue {
/// The table being seeded.
table: String,
/// The column.
column: String,
/// What is wrong with the value.
reason: String,
},
}
impl fmt::Display for SeedError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::CyclicForeignKeys { tables } => write!(
formatter,
"cannot seed a foreign-key cycle in one portable pass: {}",
tables.join(", ")
),
Self::MissingParentRows { child, parent } => write!(
formatter,
"cannot seed {child}: referenced parent {parent} has no generated rows"
),
Self::UnsafeResetSelection {
parent,
skipped_child,
} => write!(
formatter,
"cannot reset {parent} while referenced table {skipped_child} is skipped"
),
Self::ParameterLimitTooLow {
table,
required,
limit,
} => write!(
formatter,
"cannot seed {table}: one row needs {required} bind parameters, above limit {limit}"
),
Self::UnknownTable { table, known } => write!(
formatter,
"no table `{table}` in the schema (tables: {})",
known.join(", ")
),
Self::AmbiguousTable { table, candidates } => write!(
formatter,
"table name `{table}` matches {}; qualify it as `schema.table`",
candidates.join(", ")
),
Self::UnknownColumn {
table,
column,
known,
} => write!(
formatter,
"table {table} has no column `{column}` (columns: {})",
known.join(", ")
),
Self::NotRelated { parent, child } => write!(
formatter,
"cannot set a relation count from {parent} to {child}: {child} has no foreign key to {parent}"
),
Self::DialectNotEnabled { dialect } => write!(
formatter,
"a {dialect} snapshot needs drizzle-seed's feature for that dialect"
),
Self::NoLiteral { reason } => {
write!(formatter, "cannot write a value inline: {reason}")
}
Self::InvalidValue {
table,
column,
reason,
} => write!(formatter, "cannot seed {table}.{column}: {reason}"),
}
}
}
impl std::error::Error for SeedError {}