on iko/quotes@origin help sign in
reshape/tests/add_column.rs
262 lines 6.8 kB history raw
1mod common;
2use common::Test;
4#[test]
5fn add_column() {
6 let mut test = Test::new("Add column");
8 test.first_migration(
9 r#"
10 name = "create_user_table"
12 [[actions]]
13 type = "create_table"
14 name = "users"
15 primary_key = ["id"]
17 [[actions.columns]]
18 name = "id"
19 type = "INTEGER"
21 [[actions.columns]]
22 name = "name"
23 type = "TEXT"
24 "#,
25 );
27 test.second_migration(
28 r#"
29 name = "add_first_and_last_name_columns"
31 [[actions]]
32 type = "add_column"
33 table = "users"
35 up = "(STRING_TO_ARRAY(name, ' '))[1]"
37 [actions.column]
38 name = "first"
39 type = "TEXT"
40 nullable = false
42 [[actions]]
43 type = "add_column"
44 table = "users"
46 up = "(STRING_TO_ARRAY(name, ' '))[2]"
48 [actions.column]
49 name = "last"
50 type = "TEXT"
51 nullable = false
52 "#,
53 );
55 test.after_first(|db| {
56 // Insert some test users
57 db.simple_query(
58 "
59 INSERT INTO users (id, name) VALUES
60 (1, 'John Doe'),
61 (2, 'Jane Doe');
62 ",
63 )
64 .unwrap();
65 });
67 test.intermediate(|old_db, new_db| {
68 // Check that the existing users have the new columns populated
69 let expected = vec![("John", "Doe"), ("Jane", "Doe")];
70 assert!(new_db
71 .query("SELECT first, last FROM users ORDER BY id", &[],)
72 .unwrap()
73 .iter()
74 .map(|row| (row.get("first"), row.get("last")))
75 .eq(expected));
77 // Insert data using old schema and make sure the new columns are populated
78 old_db
79 .simple_query("INSERT INTO users (id, name) VALUES (3, 'Test Testsson')")
80 .unwrap();
81 let (first_name, last_name): (String, String) = new_db
82 .query_one("SELECT first, last from users WHERE id = 3", &[])
83 .map(|row| (row.get("first"), row.get("last")))
84 .unwrap();
85 assert_eq!(
86 ("Test", "Testsson"),
87 (first_name.as_ref(), last_name.as_ref())
88 );
89 });
91 test.after_completion(|db| {
92 let expected = vec![("John", "Doe"), ("Jane", "Doe"), ("Test", "Testsson")];
93 assert!(db
94 .query("SELECT first, last FROM users ORDER BY id", &[],)
95 .unwrap()
96 .iter()
97 .map(|row| (row.get("first"), row.get("last")))
98 .eq(expected));
99 });
101 test.after_abort(|db| {
102 let expected = vec![("John Doe"), ("Jane Doe"), ("Test Testsson")];
103 assert!(db
104 .query("SELECT name FROM users ORDER BY id", &[],)
105 .unwrap()
106 .iter()
107 .map(|row| row.get::<'_, _, String>("name"))
108 .eq(expected));
109 });
111 test.run()
114#[test]
115fn add_column_nullable() {
116 let mut test = Test::new("Add nullable column");
118 test.first_migration(
119 r#"
120 name = "create_users_table"
122 [[actions]]
123 type = "create_table"
124 name = "users"
125 primary_key = ["id"]
127 [[actions.columns]]
128 name = "id"
129 type = "INTEGER"
130 "#,
131 );
133 test.second_migration(
134 r#"
135 name = "add_nullable_name_column"
137 [[actions]]
138 type = "add_column"
139 table = "users"
141 [actions.column]
142 name = "name"
143 type = "TEXT"
144 "#,
145 );
147 test.after_first(|db| {
148 // Insert some test values
149 db.simple_query(
150 "
151 INSERT INTO users (id) VALUES (1), (2);
152 ",
153 )
154 .unwrap();
155 });
157 test.intermediate(|old_db, new_db| {
158 // Ensure existing data got updated
159 let expected: Vec<Option<String>> = vec![None, None];
160 assert!(new_db
161 .query("SELECT name FROM users ORDER BY id", &[],)
162 .unwrap()
163 .iter()
164 .map(|row| row.get::<_, Option<String>>("name"))
165 .eq(expected));
167 // Insert data using old schema and ensure new column is NULL
168 old_db
169 .simple_query("INSERT INTO users (id) VALUES (3)")
170 .unwrap();
171 let name: Option<String> = new_db
172 .query_one("SELECT name from users WHERE id = 3", &[])
173 .map(|row| (row.get("name")))
174 .unwrap();
175 assert_eq!(None, name);
177 // Ensure data can be inserted against new schema
178 new_db
179 .simple_query("INSERT INTO users (id, name) VALUES (4, 'Test Testsson'), (5, NULL)")
180 .unwrap();
181 });
183 test.after_completion(|db| {
184 let expected: Vec<Option<String>> =
185 vec![None, None, None, Some("Test Testsson".to_string()), None];
186 let result: Vec<Option<String>> = db
187 .query("SELECT id, name FROM users ORDER BY id", &[])
188 .unwrap()
189 .iter()
190 .map(|row| row.get("name"))
191 .collect();
193 assert_eq!(result, expected);
194 });
196 test.run();
199#[test]
200fn add_column_with_default() {
201 let mut test = Test::new("Add column with default value");
203 test.first_migration(
204 r#"
205 name = "create_users_table"
207 [[actions]]
208 type = "create_table"
209 name = "users"
210 primary_key = ["id"]
212 [[actions.columns]]
213 name = "id"
214 type = "INTEGER"
215 "#,
216 );
218 test.second_migration(
219 r#"
220 name = "add_name_column_with_default"
222 [[actions]]
223 type = "add_column"
224 table = "users"
226 [actions.column]
227 name = "name"
228 type = "TEXT"
229 nullable = false
230 default = "'DEFAULT'"
231 "#,
232 );
234 test.after_first(|db| {
235 // Insert some test values
236 db.simple_query("INSERT INTO users (id) VALUES (1), (2)")
237 .unwrap();
238 });
240 test.intermediate(|old_db, new_db| {
241 // Ensure existing data got updated with defaults
242 let expected = vec!["DEFAULT".to_string(), "DEFAULT".to_string()];
243 assert!(new_db
244 .query("SELECT name FROM users ORDER BY id", &[],)
245 .unwrap()
246 .iter()
247 .map(|row| row.get::<_, String>("name"))
248 .eq(expected));
250 // Insert data using old schema and ensure new column gets the default value
251 old_db
252 .simple_query("INSERT INTO users (id) VALUES (3)")
253 .unwrap();
254 let name: String = new_db
255 .query_one("SELECT name from users WHERE id = 3", &[])
256 .map(|row| row.get("name"))
257 .unwrap();
258 assert_eq!("DEFAULT", name);
259 });
261 test.run();