mirror of
https://github.com/ilyakooo0/reshape.git
synced 2024-11-26 10:34:12 +03:00
Add remove_index action
This commit is contained in:
parent
8e08941007
commit
480bcf8af1
13
README.md
13
README.md
@ -26,6 +26,7 @@ Reshape is designed for Postgres 12 and later.
|
||||
- [Remove column](#remove-column)
|
||||
- [Indices](#indices)
|
||||
- [Add index](#add-index)
|
||||
- [Remove index](#remove-index)
|
||||
- [Commands and options](#commands-and-options)
|
||||
- [`reshape migrate`](#reshape-migrate)
|
||||
- [`reshape complete`](#reshape-complete)
|
||||
@ -391,6 +392,18 @@ name = "name_idx"
|
||||
columns = ["name"]
|
||||
```
|
||||
|
||||
#### Remove index
|
||||
|
||||
The `remove_index` action will remove an existing index. The index won't actually be removed until the migration is completed.
|
||||
|
||||
*Example: remove the `name_idx` index*
|
||||
|
||||
```toml
|
||||
[[actions]]
|
||||
type = "remove_index"
|
||||
index = "name_idx"
|
||||
```
|
||||
|
||||
## Commands and options
|
||||
|
||||
### `reshape migrate`
|
||||
|
@ -24,6 +24,9 @@ pub use remove_column::RemoveColumn;
|
||||
mod add_index;
|
||||
pub use add_index::AddIndex;
|
||||
|
||||
mod remove_index;
|
||||
pub use remove_index::RemoveIndex;
|
||||
|
||||
mod remove_table;
|
||||
pub use remove_table::RemoveTable;
|
||||
|
||||
|
51
src/migrations/remove_index.rs
Normal file
51
src/migrations/remove_index.rs
Normal file
@ -0,0 +1,51 @@
|
||||
use super::{Action, MigrationContext};
|
||||
use crate::{
|
||||
db::{Conn, Transaction},
|
||||
schema::Schema,
|
||||
};
|
||||
use anyhow::Context;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct RemoveIndex {
|
||||
pub index: String,
|
||||
}
|
||||
|
||||
#[typetag::serde(name = "remove_index")]
|
||||
impl Action for RemoveIndex {
|
||||
fn describe(&self) -> String {
|
||||
format!("Removing index \"{}\"", self.index)
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_ctx: &MigrationContext,
|
||||
_db: &mut dyn Conn,
|
||||
_schema: &Schema,
|
||||
) -> anyhow::Result<()> {
|
||||
// Do nothing, the index isn't removed until completion
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn complete<'a>(
|
||||
&self,
|
||||
_ctx: &MigrationContext,
|
||||
db: &'a mut dyn Conn,
|
||||
) -> anyhow::Result<Option<Transaction<'a>>> {
|
||||
db.run(&format!(
|
||||
"
|
||||
DROP INDEX CONCURRENTLY IF EXISTS {}
|
||||
",
|
||||
self.index
|
||||
))
|
||||
.context("failed to drop index")?;
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn update_schema(&self, _ctx: &MigrationContext, _schema: &mut Schema) {}
|
||||
|
||||
fn abort(&self, _ctx: &MigrationContext, _db: &mut dyn Conn) -> anyhow::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
109
tests/remove_index.rs
Normal file
109
tests/remove_index.rs
Normal file
@ -0,0 +1,109 @@
|
||||
use reshape::migrations::{AddIndex, ColumnBuilder, CreateTableBuilder, Migration, RemoveIndex};
|
||||
|
||||
mod common;
|
||||
|
||||
#[test]
|
||||
fn remove_index() {
|
||||
let (mut reshape, _, mut db) = common::setup();
|
||||
|
||||
let create_table_migration = Migration::new("create_user_table", None)
|
||||
.with_action(
|
||||
CreateTableBuilder::default()
|
||||
.name("users")
|
||||
.primary_key(vec!["id".to_string()])
|
||||
.columns(vec![
|
||||
ColumnBuilder::default()
|
||||
.name("id")
|
||||
.data_type("INTEGER")
|
||||
.build()
|
||||
.unwrap(),
|
||||
ColumnBuilder::default()
|
||||
.name("name")
|
||||
.data_type("TEXT")
|
||||
.build()
|
||||
.unwrap(),
|
||||
])
|
||||
.build()
|
||||
.unwrap(),
|
||||
)
|
||||
.with_action(AddIndex {
|
||||
table: "users".to_string(),
|
||||
name: "name_idx".to_string(),
|
||||
columns: vec!["name".to_string()],
|
||||
});
|
||||
|
||||
let remove_index_migration =
|
||||
Migration::new("remove_name_index", None).with_action(RemoveIndex {
|
||||
index: "name_idx".to_string(),
|
||||
});
|
||||
|
||||
let first_migrations = vec![create_table_migration.clone()];
|
||||
let second_migrations = vec![
|
||||
create_table_migration.clone(),
|
||||
remove_index_migration.clone(),
|
||||
];
|
||||
|
||||
// Run migrations
|
||||
reshape.migrate(first_migrations.clone()).unwrap();
|
||||
|
||||
// Ensure index is valid and ready
|
||||
let result: Vec<(bool, bool)> = db
|
||||
.query(
|
||||
"
|
||||
SELECT pg_index.indisready, pg_index.indisvalid
|
||||
FROM pg_catalog.pg_index
|
||||
JOIN pg_catalog.pg_class ON pg_index.indexrelid = pg_class.oid
|
||||
WHERE pg_class.relname = 'name_idx'
|
||||
",
|
||||
&[],
|
||||
)
|
||||
.unwrap()
|
||||
.iter()
|
||||
.map(|row| (row.get("indisready"), row.get("indisvalid")))
|
||||
.collect();
|
||||
|
||||
assert_eq!(vec![(true, true)], result);
|
||||
|
||||
// Run migration to remove index
|
||||
reshape.migrate(second_migrations.clone()).unwrap();
|
||||
|
||||
// Ensure index is still valid and ready during the migration
|
||||
let result: Vec<(bool, bool)> = db
|
||||
.query(
|
||||
"
|
||||
SELECT pg_index.indisready, pg_index.indisvalid
|
||||
FROM pg_catalog.pg_index
|
||||
JOIN pg_catalog.pg_class ON pg_index.indexrelid = pg_class.oid
|
||||
WHERE pg_class.relname = 'name_idx'
|
||||
",
|
||||
&[],
|
||||
)
|
||||
.unwrap()
|
||||
.iter()
|
||||
.map(|row| (row.get("indisready"), row.get("indisvalid")))
|
||||
.collect();
|
||||
|
||||
assert_eq!(vec![(true, true)], result);
|
||||
|
||||
reshape.complete_migration().unwrap();
|
||||
|
||||
// Ensure index has been removed after the migration is complete
|
||||
let count: i64 = db
|
||||
.query(
|
||||
"
|
||||
SELECT COUNT(*)
|
||||
FROM pg_catalog.pg_index
|
||||
JOIN pg_catalog.pg_class ON pg_index.indexrelid = pg_class.oid
|
||||
WHERE pg_class.relname = 'name_idx'
|
||||
",
|
||||
&[],
|
||||
)
|
||||
.unwrap()
|
||||
.first()
|
||||
.map(|row| row.get(0))
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(0, count, "expected index to not exist");
|
||||
|
||||
common::assert_cleaned_up(&mut db);
|
||||
}
|
Loading…
Reference in New Issue
Block a user