From 3cd47003329c57eb9b1bf5798338c2796f77973b Mon Sep 17 00:00:00 2001 From: Dmitry Vedenko Date: Wed, 17 Apr 2024 18:38:10 +0300 Subject: [PATCH] Force local_path uniqueness --- .../sync/CloudProjectsDatabase.cpp | 83 +++++++++++++------ .../sync/CloudProjectsDatabase.h | 2 + 2 files changed, 59 insertions(+), 26 deletions(-) diff --git a/libraries/lib-cloud-audiocom/sync/CloudProjectsDatabase.cpp b/libraries/lib-cloud-audiocom/sync/CloudProjectsDatabase.cpp index 881a0059132b..2becdab4d6aa 100644 --- a/libraries/lib-cloud-audiocom/sync/CloudProjectsDatabase.cpp +++ b/libraries/lib-cloud-audiocom/sync/CloudProjectsDatabase.cpp @@ -198,29 +198,9 @@ void cloud::audiocom::sync::CloudProjectsDatabase::DeleteProject( if (!connection) return; - static const char* queries[] = { - "DELETE FROM projects WHERE project_id = ?", - "DELETE FROM block_hashes WHERE project_id = ?", - "DELETE FROM pending_snapshots WHERE project_id = ?", - "DELETE FROM pending_project_blobs WHERE project_id = ?", - "DELETE FROM pending_project_blocks WHERE project_id = ?", - "DELETE FROM project_users WHERE project_id = ?", - }; - auto tx = connection->BeginTransaction("DeleteProject"); - - for (auto query : queries) - { - auto statement = connection->CreateStatement(query); - - if (!statement) - return; - - if (!statement->Prepare(projectId).Run().IsOk()) - return; - } - - tx.Commit(); + if (DeleteProject(connection, projectId)) + tx.Commit(); } bool CloudProjectsDatabase::MarkProjectAsSynced( @@ -331,13 +311,15 @@ bool CloudProjectsDatabase::UpdateProjectData(const DBProjectData& projectData) if (!connection) return false; - auto statement = connection->CreateStatement( + auto tx = connection->BeginTransaction("UpdateProjectData"); + + auto updateProjectData = connection->CreateStatement( "INSERT OR REPLACE INTO projects (project_id, snapshot_id, saves_count, last_audio_preview_save, local_path, last_modified, last_read, sync_status, synced_dialog_shown) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"); - if (!statement) + if (!updateProjectData) return false; - auto result = statement + auto result = updateProjectData ->Prepare( projectData.ProjectId, projectData.SnapshotId, projectData.SavesCount, projectData.LastAudioPreview, @@ -346,7 +328,30 @@ bool CloudProjectsDatabase::UpdateProjectData(const DBProjectData& projectData) projectData.FirstSyncDialogShown) .Run(); - return result.IsOk(); + if (!result.IsOk()) + return false; + + auto listMissingProjects = connection->CreateStatement ( + "SELECT project_id FROM projects WHERE project_id != ? AND local_path = ?"); + + if (!listMissingProjects) + return false; + + auto missingProjects = listMissingProjects->Prepare( + projectData.ProjectId, projectData.LocalPath).Run(); + + for (auto row : missingProjects) + { + std::string missingProjectId; + + if (!row.Get(0, missingProjectId)) + return false; + + if (!DeleteProject(connection, missingProjectId)) + return false; + } + + return tx.Commit().IsOk(); } bool cloud::audiocom::sync::CloudProjectsDatabase::IsFirstSyncDialogShown( @@ -886,4 +891,30 @@ bool CloudProjectsDatabase::RunMigrations() return tx.Commit().IsOk(); } +bool cloud::audiocom::sync::CloudProjectsDatabase::DeleteProject( + sqlite::SafeConnection::Lock& connection, std::string_view projectId) +{ + static const char* queries[] = { + "DELETE FROM projects WHERE project_id = ?", + "DELETE FROM block_hashes WHERE project_id = ?", + "DELETE FROM pending_snapshots WHERE project_id = ?", + "DELETE FROM pending_project_blobs WHERE project_id = ?", + "DELETE FROM pending_project_blocks WHERE project_id = ?", + "DELETE FROM project_users WHERE project_id = ?", + }; + + for (auto query : queries) + { + auto statement = connection->CreateStatement(query); + + if (!statement) + return false; + + if (!statement->Prepare(projectId).Run().IsOk()) + return false; + } + + return true; +} + } // namespace audacity::cloud::audiocom::sync diff --git a/libraries/lib-cloud-audiocom/sync/CloudProjectsDatabase.h b/libraries/lib-cloud-audiocom/sync/CloudProjectsDatabase.h index cdd923f46db6..2800b1229985 100644 --- a/libraries/lib-cloud-audiocom/sync/CloudProjectsDatabase.h +++ b/libraries/lib-cloud-audiocom/sync/CloudProjectsDatabase.h @@ -149,6 +149,8 @@ class CloudProjectsDatabase final bool OpenConnection(); bool RunMigrations(); + bool DeleteProject(sqlite::SafeConnection::Lock& connection, std::string_view projectId); + std::mutex mConnectionMutex; std::shared_ptr mConnection; };