Skip to content

Commit

Permalink
implement (WIP) rename column, datatype
Browse files Browse the repository at this point in the history
  • Loading branch information
lmcmicu committed Nov 1, 2024
1 parent 67ab925 commit 92ed973
Show file tree
Hide file tree
Showing 2 changed files with 198 additions and 4 deletions.
33 changes: 29 additions & 4 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,10 @@ enum RenameSubcommands {
#[arg(value_name = "NEW_NAME", action = ArgAction::Set,
help = "The desired new name for the column")]
new_name: String,

#[arg(value_name = "NEW_LABEL", action = ArgAction::Set,
help = "The desired new label for the column")]
new_label: Option<String>,
},
}

Expand Down Expand Up @@ -965,6 +969,7 @@ async fn main() -> Result<()> {
valve.ensure_all_tables_created().await?;
// TODO: Ask the user if they want to load the table now. If assume_yes
// is set to true, then load by default.
// Same goes when adding or removing a column from a table etc.
}
}
};
Expand Down Expand Up @@ -1467,11 +1472,31 @@ async fn main() -> Result<()> {
}
}
Commands::Rename { subcommand } => {
let _valve = build_valve(&cli.source, &cli.database).expect(BUILD_ERROR);
let mut valve = build_valve(&cli.source, &cli.database).expect(BUILD_ERROR);
match subcommand {
RenameSubcommands::Column { .. } => todo!(),
RenameSubcommands::Datatype { .. } => todo!(),
RenameSubcommands::Table { .. } => todo!(),
RenameSubcommands::Column {
table,
column,
new_name,
new_label,
} => {
valve
.rename_column(table, column, new_name, new_label)
.await
.expect("Error renaming column");
}
RenameSubcommands::Datatype { datatype, new_name } => {
valve
.rename_datatype(datatype, new_name)
.await
.expect("Error renaming datatype");
}
RenameSubcommands::Table { table, new_name } => {
valve
.rename_table(table, new_name)
.await
.expect("Error renaming table");
}
};
}
Commands::Save { save_dir, tables } => {
Expand Down
169 changes: 169 additions & 0 deletions src/valve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1032,6 +1032,7 @@ impl Valve {
}
}

// TODO: Why aren't we using the transaction here?
let (rn, ro) =
get_next_new_row_tx(&self.db_kind, &mut self.pool.begin().await?, "datatype").await?;
let sql = local_sql_syntax(
Expand Down Expand Up @@ -1070,6 +1071,138 @@ impl Valve {
self.rebuild()
}

/// TODO: Add docstring here
pub async fn rename_datatype(&mut self, datatype: &str, new_name: &str) -> Result<()> {
// TODO: Use the transaction.
let (rn, ro) =
get_next_new_row_tx(&self.db_kind, &mut self.pool.begin().await?, "datatype").await?;
let sql = local_sql_syntax(
&self.db_kind,
// TODO: Determine the columns from the column config
&format!(
r#"INSERT INTO "datatype" (
"row_number", "row_order", "datatype",
"parent", "condition", "description", "sql_type"
)
SELECT
{rn} AS row_number,
{ro} as row_order,
{SQL_PARAM} as "datatype",
t2.parent, t2.condition, t2.description, t2.sql_type
FROM "datatype" t2
WHERE t2."datatype" = {SQL_PARAM}"#
),
);
let query = sqlx_query(&sql).bind(new_name).bind(datatype);
query.execute(&self.pool).await?;

let sql = local_sql_syntax(
&self.db_kind,
&format!(
r#"UPDATE "column"
SET "datatype" = CASE
WHEN "datatype" = {SQL_PARAM} THEN {SQL_PARAM} ELSE "datatype"
END, "nulltype" = CASE
WHEN "nulltype" = {SQL_PARAM} THEN {SQL_PARAM} ELSE "nulltype"
END"#
),
);
let query = sqlx_query(&sql)
.bind(datatype)
.bind(new_name)
.bind(datatype)
.bind(new_name);
query.execute(&self.pool).await?;

let sql = local_sql_syntax(
&self.db_kind,
&format!(
r#"UPDATE "datatype"
SET "parent" =
CASE
WHEN "parent" = {SQL_PARAM} THEN {SQL_PARAM} ELSE "parent"
END"#
),
);
let query = sqlx_query(&sql).bind(datatype).bind(new_name);
query.execute(&self.pool).await?;

// TODO: We need to adjust any of the following that refer to the datatype:
// - datatype conditions (for list() types)
// - rule then and when conditions

let sql = local_sql_syntax(
&self.db_kind,
&format!(r#"DELETE FROM "datatype" WHERE "datatype" = {SQL_PARAM}"#),
);
let query = sqlx_query(&sql).bind(datatype);
query.execute(&self.pool).await?;

// Save the column table and the data table and then rebuild valve:
self.save_tables(&vec!["datatype"], &None).await?;
self.rebuild()?;

Ok(())
}

/// TODO: Add docstring here
pub async fn rename_table(&mut self, table: &str, new_name: &str) -> Result<()> {
let mut tx = self.pool.begin().await?;
let (rn, ro) = get_next_new_row_tx(&self.db_kind, &mut tx, "table").await?;
let sql = local_sql_syntax(
&self.db_kind,
&format!(
// TODO: Determine the columns from the column config
r#"INSERT INTO "table" (
"row_number", "row_order", "table",
"path", "type", "options", "description"
)
SELECT
{rn} AS row_number,
{ro} as row_order,
{SQL_PARAM} as "table",
t2.path, t2.type, t2.options, t2.description
FROM "table" t2
WHERE t2."table" = {SQL_PARAM}"#
),
);
let query = sqlx_query(&sql).bind(new_name).bind(table);
query.execute(&mut tx).await?;

for config_table in ["rule", "column"] {
let sql = local_sql_syntax(
&self.db_kind,
&format!(
r#"UPDATE "{config_table}"
SET "table" = {SQL_PARAM}
WHERE "table" = {SQL_PARAM}"#
),
);
let query = sqlx_query(&sql).bind(new_name).bind(table);
query.execute(&mut tx).await?;
}

let sql = local_sql_syntax(
&self.db_kind,
&format!(r#"DELETE FROM "table" WHERE "table" = {SQL_PARAM}"#),
);
let query = sqlx_query(&sql).bind(table);
query.execute(&mut tx).await?;

// Commit the transaction:
tx.commit().await?;

// TODO: We need to change the table name also in
// - The column table's structure" field.

// Save the column table and the data table and then rebuild valve:
self.save_tables(&vec!["table", "column", "rule"], &None)
.await?;
self.rebuild()?;

Ok(())
}

/// TODO: Add docstring here
pub async fn delete_table(&mut self, table: &str) -> Result<()> {
let mut tx = self.pool.begin().await?;
Expand Down Expand Up @@ -1220,6 +1353,42 @@ impl Valve {
Ok(())
}

/// TODO: Add docstring here
pub async fn rename_column(
&mut self,
table: &str,
column: &str,
new_name: &str,
new_label: &Option<String>,
) -> Result<()> {
let sql = local_sql_syntax(
&self.db_kind,
&format!(
r#"UPDATE "column"
SET "column" = {SQL_PARAM},
"label" = {SQL_PARAM}
WHERE "table" = {SQL_PARAM} AND "column" = {SQL_PARAM}"#
),
);

let query = sqlx_query(&sql)
.bind(new_name)
.bind(new_label)
.bind(table)
.bind(column);
query.execute(&self.pool).await?;

// TODO: We need to adjust any structures that refer to the old column name.

// Save the column table and the data table and then rebuild valve:
self.save_tables(&vec!["column", table], &None).await?;
self.rebuild()?;

// Load the newly modified table:
self.load_tables(&vec![table], true).await?;
Ok(())
}

/// (Private function.) Given a SQL string, execute it using the connection pool associated
/// with the Valve instance.
async fn execute_sql(&self, sql: &str) -> Result<()> {
Expand Down

0 comments on commit 92ed973

Please sign in to comment.