@@ -29,6 +29,7 @@ fn add_index() {
2929 table: "users".to_string(),
3030 name: "name_idx".to_string(),
3131 columns: vec!["name".to_string()],
32+ unique: false,
3233 });
3334
3435 let first_migrations = vec![create_table_migration.clone()];
@@ -47,7 +48,7 @@ fn add_index() {
4748 new_db.simple_query(&new_schema_query).unwrap();
4849
4950 // Ensure index is valid and ready
50− let result: Vec<(bool, bool)> = new_db
51+ let (is_ready, is_valid): (bool, bool) = new_db
5152 .query(
5253 "
5354 SELECT pg_index.indisready, pg_index.indisvalid
@@ -58,11 +59,87 @@ fn add_index() {
5859 &[],
5960 )
6061 .unwrap()
61− .iter()
62+ .first()
6263 .map(|row| (row.get("indisready"), row.get("indisvalid")))
63− .collect();
64+ .unwrap();
6465
65− assert_eq!(vec![(true, true)], result);
66+ assert!(is_ready, "expected index to be ready");
67+ assert!(is_valid, "expected index to be valid");
68+
69+ reshape.complete().unwrap();
70+ common::assert_cleaned_up(&mut new_db);
71+}
72+
73+#[test]
74+fn add_index_unique() {
75+ let (mut reshape, mut old_db, mut new_db) = common::setup();
76+
77+ let create_table_migration = Migration::new("create_user_table", None).with_action(
78+ CreateTableBuilder::default()
79+ .name("users")
80+ .primary_key(vec!["id".to_string()])
81+ .columns(vec![
82+ ColumnBuilder::default()
83+ .name("id")
84+ .data_type("INTEGER")
85+ .build()
86+ .unwrap(),
87+ ColumnBuilder::default()
88+ .name("name")
89+ .data_type("TEXT")
90+ .build()
91+ .unwrap(),
92+ ])
93+ .build()
94+ .unwrap(),
95+ );
96+ let add_index_migration = Migration::new("add_name_index", None).with_action(AddIndex {
97+ table: "users".to_string(),
98+ name: "name_idx".to_string(),
99+ columns: vec!["name".to_string()],
100+ unique: true,
101+ });
102+
103+ let first_migrations = vec![create_table_migration.clone()];
104+ let second_migrations = vec![create_table_migration.clone(), add_index_migration.clone()];
105+
106+ // Run migrations
107+ reshape.migrate(first_migrations.clone()).unwrap();
108+ reshape.migrate(second_migrations.clone()).unwrap();
109+
110+ // Update schemas of Postgres connections
111+ let old_schema_query =
112+ reshape::schema_query_for_migration(&first_migrations.last().unwrap().name);
113+ let new_schema_query =
114+ reshape::schema_query_for_migration(&second_migrations.last().unwrap().name);
115+ old_db.simple_query(&old_schema_query).unwrap();
116+ new_db.simple_query(&new_schema_query).unwrap();
117+
118+ // Ensure index is valid, ready and unique
119+ let (is_ready, is_valid, is_unique): (bool, bool, bool) = new_db
120+ .query(
121+ "
122+ SELECT pg_index.indisready, pg_index.indisvalid, pg_index.indisunique
123+ FROM pg_catalog.pg_index
124+ JOIN pg_catalog.pg_class ON pg_index.indexrelid = pg_class.oid
125+ WHERE pg_class.relname = 'name_idx'
126+ ",
127+ &[],
128+ )
129+ .unwrap()
130+ .first()
131+ .map(|row| {
132+ (
133+ row.get("indisready"),
134+ row.get("indisvalid"),
135+ row.get("indisunique"),
136+ )
137+ })
138+ .unwrap();
139+
140+ assert!(is_ready, "expected index to be ready");
141+ assert!(is_valid, "expected index to be valid");
142+ assert!(is_unique, "expected index to be unique");
66143
67144 reshape.complete().unwrap();
68145 common::assert_cleaned_up(&mut new_db);