From 661fc8041e4483c6b7e135d7db5f4521edeee0ab Mon Sep 17 00:00:00 2001 From: laruh Date: Fri, 13 Sep 2024 13:22:23 +0700 Subject: [PATCH] use sql transaction to ensure atomicity in the nft history migration process --- mm2src/coins/nft/storage/sql_storage.rs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/mm2src/coins/nft/storage/sql_storage.rs b/mm2src/coins/nft/storage/sql_storage.rs index f6f1dd7bbb..c1192a445f 100644 --- a/mm2src/coins/nft/storage/sql_storage.rs +++ b/mm2src/coins/nft/storage/sql_storage.rs @@ -1409,41 +1409,46 @@ impl NftTransferHistoryStorageOps for AsyncMutexGuard<'_, AsyncConnection> { } fn migrate_tx_history_table_schema( - conn: &Connection, + conn: &mut Connection, history_table: SafeTableName, schema_table: SafeTableName, ) -> Result<(), AsyncConnError> { if has_primary_key_duplication(conn, &history_table)? { return Err(AsyncConnError::Internal(InternalError( - "Primary key duplication occurred in old tx history table".to_string(), + "Primary key duplication occurred in old nft tx history table".to_string(), ))); } + // Start a transaction to ensure all operations are atomic + let sql_tx = conn.transaction()?; + let temp_table_name = SafeTableName::new(format!("{}_temp", history_table.inner()).as_str())?; - conn.execute(&create_transfer_history_table_sql_custom_name(&temp_table_name)?, [])?; + sql_tx.execute(&create_transfer_history_table_sql_custom_name(&temp_table_name)?, [])?; let copy_data_sql = format!( "INSERT INTO {} SELECT * FROM {};", temp_table_name.inner(), history_table.inner() ); - conn.execute(©_data_sql, [])?; + sql_tx.execute(©_data_sql, [])?; let drop_old_table_sql = format!("DROP TABLE {};", history_table.inner()); - conn.execute(&drop_old_table_sql, [])?; + sql_tx.execute(&drop_old_table_sql, [])?; let rename_table_sql = format!( "ALTER TABLE {} RENAME TO {};", temp_table_name.inner(), history_table.inner() ); - conn.execute(&rename_table_sql, [])?; + sql_tx.execute(&rename_table_sql, [])?; - conn.execute(&update_schema_version_sql(&schema_table), [ + sql_tx.execute(&update_schema_version_sql(&schema_table), [ CURRENT_SCHEMA_VERSION_TX_HISTORY.to_string(), history_table.inner().to_string(), ])?; + sql_tx.commit()?; + Ok(()) }