Audacity 3.2.0
Public Member Functions | Static Public Member Functions | Private Member Functions | Private Attributes | List of all members
audacity::cloud::audiocom::sync::CloudProjectsDatabase Class Referencefinal

#include <CloudProjectsDatabase.h>

Collaboration diagram for audacity::cloud::audiocom::sync::CloudProjectsDatabase:
[legend]

Public Member Functions

sqlite::SafeConnection::Lock GetConnection ()
 
const sqlite::SafeConnection::Lock GetConnection () const
 
std::optional< DBProjectDataGetProjectData (std::string_view projectId) const
 
std::optional< DBProjectDataGetProjectDataForPath (const std::string &projectPath) const
 
std::vector< DBProjectDataGetCloudProjects () const
 
void DeleteProject (std::string_view projectId)
 
bool MarkProjectAsSynced (std::string_view projectId, std::string_view snapshotId)
 
void UpdateProjectBlockList (std::string_view projectId, const SampleBlockIDSet &blockSet)
 
std::optional< std::string > GetBlockHash (std::string_view projectId, int64_t blockId) const
 
void UpdateBlockHashes (std::string_view projectId, const std::vector< std::pair< int64_t, std::string > > &hashes)
 
bool UpdateProjectData (const DBProjectData &projectData)
 
bool IsFirstSyncDialogShown (std::string_view projectId) const
 
void SetFirstSyncDialogShown (std::string_view projectId, bool shown=true)
 
std::string GetProjectUserSlug (std::string_view projectId)
 
void SetProjectUserSlug (std::string_view projectId, std::string_view slug)
 
bool IsProjectBlockLocked (std::string_view projectId, int64_t blockId) const
 
void AddPendingSnapshot (const PendingSnapshotData &snapshotData)
 
void RemovePendingSnapshot (std::string_view projectId, std::string_view snapshotId)
 
std::vector< PendingSnapshotDataGetPendingSnapshots (std::string_view projectId) const
 
void AddPendingProjectBlob (const PendingProjectBlobData &blobData)
 
void RemovePendingProjectBlob (std::string_view projectId, std::string_view snapshotId)
 
std::optional< PendingProjectBlobDataGetPendingProjectBlob (std::string_view projectId, std::string_view snapshotId) const
 
void AddPendingProjectBlocks (const std::vector< PendingProjectBlockData > &blockData)
 
void RemovePendingProjectBlock (std::string_view projectId, int64_t blockId)
 
void RemovePendingProjectBlocks (std::string_view projectId, std::string_view snapshotId)
 
std::vector< PendingProjectBlockDataGetPendingProjectBlocks (std::string_view projectId, std::string_view snapshotId)
 

Static Public Member Functions

static CloudProjectsDatabaseGet ()
 

Private Member Functions

 CloudProjectsDatabase ()=default
 
 ~CloudProjectsDatabase ()=default
 
std::optional< DBProjectDataDoGetProjectData (const sqlite::Row &result) const
 
std::optional< DBProjectDataDoGetProjectData (sqlite::RunResult result) const
 
bool OpenConnection ()
 
bool RunMigrations ()
 
bool DeleteProject (sqlite::SafeConnection::Lock &connection, std::string_view projectId)
 

Private Attributes

std::mutex mConnectionMutex
 
std::shared_ptr< sqlite::SafeConnectionmConnection
 

Detailed Description

Definition at line 78 of file CloudProjectsDatabase.h.

Constructor & Destructor Documentation

◆ CloudProjectsDatabase()

audacity::cloud::audiocom::sync::CloudProjectsDatabase::CloudProjectsDatabase ( )
privatedefault

◆ ~CloudProjectsDatabase()

audacity::cloud::audiocom::sync::CloudProjectsDatabase::~CloudProjectsDatabase ( )
privatedefault

Member Function Documentation

◆ AddPendingProjectBlob()

void audacity::cloud::audiocom::sync::CloudProjectsDatabase::AddPendingProjectBlob ( const PendingProjectBlobData blobData)

Definition at line 561 of file CloudProjectsDatabase.cpp.

563{
564 auto connection = GetConnection();
565
566 if (!connection)
567 return;
568
569 auto statement = connection->CreateStatement(
570 "INSERT OR REPLACE INTO pending_project_blobs (project_id, snapshot_id, upload_url, confirm_url, fail_url, blob) VALUES (?, ?, ?, ?, ?, ?)");
571
572 if (!statement)
573 return;
574
575 statement->Prepare()
576 .Bind(1, blobData.ProjectId)
577 .Bind(2, blobData.SnapshotId)
578 .Bind(3, blobData.UploadUrl)
579 .Bind(4, blobData.ConfirmUrl)
580 .Bind(5, blobData.FailUrl)
581 .Bind(6, blobData.BlobData.data(), blobData.BlobData.size(), false)
582 .Run();
583}

References audacity::cloud::audiocom::sync::PendingProjectBlobData::BlobData, audacity::cloud::audiocom::sync::PendingProjectBlobData::ConfirmUrl, audacity::cloud::audiocom::sync::PendingProjectBlobData::FailUrl, GetConnection(), audacity::cloud::audiocom::sync::PendingProjectBlobData::ProjectId, audacity::cloud::audiocom::sync::PendingProjectBlobData::SnapshotId, and audacity::cloud::audiocom::sync::PendingProjectBlobData::UploadUrl.

Referenced by audacity::cloud::audiocom::sync::LocalProjectSnapshot::StorePendingSnapshot().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ AddPendingProjectBlocks()

void audacity::cloud::audiocom::sync::CloudProjectsDatabase::AddPendingProjectBlocks ( const std::vector< PendingProjectBlockData > &  blockData)

Definition at line 650 of file CloudProjectsDatabase.cpp.

652{
653 auto connection = GetConnection();
654
655 if (!connection)
656 return;
657
658 auto tx = connection->BeginTransaction("AddPendingProjectBlocks");
659
660 auto statement = connection->CreateStatement(
661 "INSERT OR REPLACE INTO pending_project_blocks (project_id, snapshot_id, upload_url, confirm_url, fail_url, block_id, block_sample_format, block_hash) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
662
663 if (!statement)
664 return;
665
666 for (const auto& data : blockData)
667 statement->Prepare()
668 .Bind(1, data.ProjectId)
669 .Bind(2, data.SnapshotId)
670 .Bind(3, data.UploadUrl)
671 .Bind(4, data.ConfirmUrl)
672 .Bind(5, data.FailUrl)
673 .Bind(6, data.BlockId)
674 .Bind(7, data.BlockSampleFormat)
675 .Bind(8, data.BlockHash)
676 .Run();
677
678 tx.Commit();
679}

References GetConnection().

Referenced by audacity::cloud::audiocom::sync::LocalProjectSnapshot::StorePendingSnapshot().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ AddPendingSnapshot()

void audacity::cloud::audiocom::sync::CloudProjectsDatabase::AddPendingSnapshot ( const PendingSnapshotData snapshotData)

Definition at line 473 of file CloudProjectsDatabase.cpp.

475{
476 auto connection = GetConnection();
477
478 if (!connection)
479 return;
480
481 auto statement = connection->CreateStatement(
482 "INSERT OR REPLACE INTO pending_snapshots (project_id, snapshot_id, confirm_url) VALUES (?, ?, ?)");
483
484 if (!statement)
485 return;
486
487 statement
488 ->Prepare(
489 snapshotData.ProjectId, snapshotData.SnapshotId,
490 snapshotData.ConfirmUrl)
491 .Run();
492}

References audacity::cloud::audiocom::sync::PendingSnapshotData::ConfirmUrl, GetConnection(), audacity::cloud::audiocom::sync::PendingSnapshotData::ProjectId, and audacity::cloud::audiocom::sync::PendingSnapshotData::SnapshotId.

Referenced by audacity::cloud::audiocom::sync::LocalProjectSnapshot::StorePendingSnapshot().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ DeleteProject() [1/2]

bool audacity::cloud::audiocom::sync::CloudProjectsDatabase::DeleteProject ( sqlite::SafeConnection::Lock connection,
std::string_view  projectId 
)
private

Definition at line 896 of file CloudProjectsDatabase.cpp.

898{
899 static const char* queries[] = {
900 "DELETE FROM projects WHERE project_id = ?",
901 "DELETE FROM block_hashes WHERE project_id = ?",
902 "DELETE FROM pending_snapshots WHERE project_id = ?",
903 "DELETE FROM pending_project_blobs WHERE project_id = ?",
904 "DELETE FROM pending_project_blocks WHERE project_id = ?",
905 "DELETE FROM project_users WHERE project_id = ?",
906 };
907
908 for (auto query : queries)
909 {
910 auto statement = connection->CreateStatement(query);
911
912 if (!statement)
913 return false;
914
915 if (!statement->Prepare(projectId).Run().IsOk())
916 return false;
917 }
918
919 return true;
920}

References audacity::sqlite::Connection::CreateStatement().

Here is the call graph for this function:

◆ DeleteProject() [2/2]

void audacity::cloud::audiocom::sync::CloudProjectsDatabase::DeleteProject ( std::string_view  projectId)

Definition at line 195 of file CloudProjectsDatabase.cpp.

197{
198 auto connection = GetConnection();
199
200 if (!connection)
201 return;
202
203 auto tx = connection->BeginTransaction("DeleteProject");
204 if (DeleteProject(connection, projectId))
205 tx.Commit();
206}

Referenced by UpdateProjectData().

Here is the caller graph for this function:

◆ DoGetProjectData() [1/2]

std::optional< DBProjectData > audacity::cloud::audiocom::sync::CloudProjectsDatabase::DoGetProjectData ( const sqlite::Row result) const
private

Definition at line 769 of file CloudProjectsDatabase.cpp.

770{
771 DBProjectData data;
772
773 if (!row.Get(0, data.ProjectId))
774 return {};
775
776 if (!row.Get(1, data.SnapshotId))
777 return {};
778
779 if (!row.Get(2, data.SavesCount))
780 return {};
781
782 if (!row.Get(3, data.LastAudioPreview))
783 return {};
784
785 if (!row.Get(4, data.LocalPath))
786 return {};
787
788 if (!row.Get(5, data.LastModified))
789 return {};
790
791 if (!row.Get(6, data.LastRead))
792 return {};
793
794 int status;
795 if (!row.Get(7, status))
796 return {};
797
798 data.SyncStatus = static_cast<DBProjectData::SyncStatusType>(status);
799
800 if (!row.Get(8, data.FirstSyncDialogShown))
801 return {};
802
803 return data;
804}

References audacity::cloud::audiocom::sync::DBProjectData::FirstSyncDialogShown, audacity::sqlite::Row::Get(), audacity::cloud::audiocom::sync::DBProjectData::LastAudioPreview, audacity::cloud::audiocom::sync::DBProjectData::LastModified, audacity::cloud::audiocom::sync::DBProjectData::LastRead, audacity::cloud::audiocom::sync::DBProjectData::LocalPath, audacity::cloud::audiocom::sync::DBProjectData::ProjectId, audacity::cloud::audiocom::sync::DBProjectData::SavesCount, audacity::cloud::audiocom::sync::DBProjectData::SnapshotId, and audacity::cloud::audiocom::sync::DBProjectData::SyncStatus.

Referenced by GetProjectData(), and GetProjectDataForPath().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ DoGetProjectData() [2/2]

std::optional< DBProjectData > audacity::cloud::audiocom::sync::CloudProjectsDatabase::DoGetProjectData ( sqlite::RunResult  result) const
private

Definition at line 807 of file CloudProjectsDatabase.cpp.

809{
810 for (auto row : result)
811 {
812 if (auto data = DoGetProjectData(row))
813 return data;
814 }
815
816 return {};
817}
std::optional< DBProjectData > DoGetProjectData(const sqlite::Row &result) const

◆ Get()

CloudProjectsDatabase & audacity::cloud::audiocom::sync::CloudProjectsDatabase::Get ( )
static

Definition at line 110 of file CloudProjectsDatabase.cpp.

111{
112 static CloudProjectsDatabase instance;
113 return instance;
114}

Referenced by audacity::cloud::audiocom::sync::RemoteProjectSnapshot::AttachOriginalDB(), audacity::cloud::audiocom::sync::RemoteProjectSnapshot::CalculateKnownBlocks(), audacity::cloud::audiocom::sync::LocalProjectSnapshot::DeleteSnapshot(), audacity::cloud::audiocom::sync::LocalProjectSnapshot::ProjectBlocksLock::GetHash(), audacity::cloud::audiocom::sync::anonymous_namespace{RemoteProjectSnapshot.cpp}::ListAttachedDatabases(), audacity::cloud::audiocom::sync::LocalProjectSnapshot::MarkSnapshotSynced(), audacity::cloud::audiocom::sync::anonymous_namespace{ResumedSnaphotUploadOperation.cpp}::ResumedSnaphotUploadOperation::MarkSnapshotSynced(), audacity::cloud::audiocom::sync::anonymous_namespace{CloudSyncHousekeeper.cpp}::Housekeeper::OnAppClosing(), audacity::cloud::audiocom::sync::LocalProjectSnapshot::OnSnapshotCreated(), audacity::cloud::audiocom::sync::anonymous_namespace{ResumedSnaphotUploadOperation.cpp}::ResumedSnaphotUploadOperation::Perform(), audacity::cloud::audiocom::sync::anonymous_namespace{CloudSyncHousekeeper.cpp}::Housekeeper::PerformHousekeeping(), audacity::cloud::audiocom::sync::LocalProjectSnapshot::ProjectBlocksLock::ProjectBlocksLock(), audacity::cloud::audiocom::sync::RemoteProjectSnapshot::RemoteProjectSnapshot(), audacity::cloud::audiocom::sync::ResumeProjectUpload(), audacity::cloud::audiocom::sync::RemoteProjectSnapshot::SetupBlocksCopy(), audacity::cloud::audiocom::sync::LocalProjectSnapshot::StorePendingSnapshot(), audacity::cloud::audiocom::sync::LocalProjectSnapshot::ProjectBlocksLock::UpdateProjectHashesInCache(), audacity::cloud::audiocom::sync::anonymous_namespace{ResumedSnaphotUploadOperation.cpp}::ResumedSnaphotUploadOperation::UpdateUrls(), audacity::cloud::audiocom::sync::anonymous_namespace{ResumedSnaphotUploadOperation.cpp}::ResumedSnaphotUploadOperation::UploadBlocks(), audacity::cloud::audiocom::sync::anonymous_namespace{ResumedSnaphotUploadOperation.cpp}::ResumedSnaphotUploadOperation::UploadSnapshot(), and audacity::cloud::audiocom::sync::RemoteProjectSnapshot::~RemoteProjectSnapshot().

Here is the caller graph for this function:

◆ GetBlockHash()

std::optional< std::string > audacity::cloud::audiocom::sync::CloudProjectsDatabase::GetBlockHash ( std::string_view  projectId,
int64_t  blockId 
) const

Definition at line 257 of file CloudProjectsDatabase.cpp.

259{
260 auto connection = GetConnection();
261
262 if (!connection)
263 return {};
264
265 auto statement = connection->CreateStatement(
266 "SELECT hash FROM block_hashes WHERE project_id = ? AND block_id = ? LIMIT 1");
267
268 if (!statement)
269 return {};
270
271 auto result = statement->Prepare(projectId, blockId).Run();
272
273 for (auto row : result)
274 {
275 std::string hash;
276
277 if (!row.Get(0, hash))
278 return {};
279
280 return hash;
281 }
282
283 return {};
284}

References GetConnection().

Referenced by audacity::cloud::audiocom::sync::LocalProjectSnapshot::ProjectBlocksLock::GetHash().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetCloudProjects()

std::vector< DBProjectData > audacity::cloud::audiocom::sync::CloudProjectsDatabase::GetCloudProjects ( ) const

Definition at line 167 of file CloudProjectsDatabase.cpp.

168{
169 std::vector<DBProjectData> result;
170
171 auto connection = GetConnection();
172
173 if (!connection)
174 return result;
175
176 auto statement = connection->CreateStatement(
177 "SELECT project_id, snapshot_id, saves_count, last_audio_preview_save, local_path, last_modified, last_read, sync_status, synced_dialog_shown FROM projects");
178
179 if (!statement)
180 return result;
181
182 auto runResult = statement->Prepare().Run();
183
184 for (auto row : runResult)
185 {
186 auto data = DoGetProjectData(row);
187
188 if (data)
189 result.push_back(*data);
190 }
191
192 return result;
193}

◆ GetConnection() [1/2]

sqlite::SafeConnection::Lock audacity::cloud::audiocom::sync::CloudProjectsDatabase::GetConnection ( )

Definition at line 116 of file CloudProjectsDatabase.cpp.

117{
118 auto lock = std::lock_guard { mConnectionMutex };
119
120 if (!mConnection)
122
123 // It is safe to call lock on a null connection
124 return sqlite::SafeConnection::Lock { mConnection };
125}
std::shared_ptr< sqlite::SafeConnection > mConnection

References mConnection, mConnectionMutex, and OpenConnection().

Referenced by AddPendingProjectBlob(), AddPendingProjectBlocks(), AddPendingSnapshot(), audacity::cloud::audiocom::sync::RemoteProjectSnapshot::AttachOriginalDB(), audacity::cloud::audiocom::sync::RemoteProjectSnapshot::CalculateKnownBlocks(), GetBlockHash(), GetConnection(), GetPendingProjectBlob(), GetPendingProjectBlocks(), GetPendingSnapshots(), GetProjectData(), GetProjectDataForPath(), GetProjectUserSlug(), IsProjectBlockLocked(), audacity::cloud::audiocom::sync::anonymous_namespace{RemoteProjectSnapshot.cpp}::ListAttachedDatabases(), MarkProjectAsSynced(), audacity::cloud::audiocom::sync::RemoteProjectSnapshot::RemoteProjectSnapshot(), RemovePendingProjectBlob(), RemovePendingProjectBlock(), RemovePendingProjectBlocks(), RemovePendingSnapshot(), SetProjectUserSlug(), audacity::cloud::audiocom::sync::RemoteProjectSnapshot::SetupBlocksCopy(), UpdateBlockHashes(), UpdateProjectBlockList(), UpdateProjectData(), and audacity::cloud::audiocom::sync::RemoteProjectSnapshot::~RemoteProjectSnapshot().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetConnection() [2/2]

const sqlite::SafeConnection::Lock audacity::cloud::audiocom::sync::CloudProjectsDatabase::GetConnection ( ) const

Definition at line 127 of file CloudProjectsDatabase.cpp.

128{
129 return const_cast<CloudProjectsDatabase*>(this)->GetConnection();
130}

References GetConnection().

Here is the call graph for this function:

◆ GetPendingProjectBlob()

std::optional< PendingProjectBlobData > audacity::cloud::audiocom::sync::CloudProjectsDatabase::GetPendingProjectBlob ( std::string_view  projectId,
std::string_view  snapshotId 
) const

Definition at line 603 of file CloudProjectsDatabase.cpp.

605{
606 auto connection = GetConnection();
607
608 if (!connection)
609 return {};
610
611 auto statement = connection->CreateStatement(
612 "SELECT project_id, snapshot_id, upload_url, confirm_url, fail_url, blob FROM pending_project_blobs WHERE project_id = ? AND snapshot_id = ?");
613
614 if (!statement)
615 return {};
616
617 auto result = statement->Prepare(projectId, snapshotId).Run();
618
619 for (auto row : result)
620 {
621 PendingProjectBlobData data;
622
623 if (!row.Get(0, data.ProjectId))
624 return {};
625
626 if (!row.Get(1, data.SnapshotId))
627 return {};
628
629 if (!row.Get(2, data.UploadUrl))
630 return {};
631
632 if (!row.Get(3, data.ConfirmUrl))
633 return {};
634
635 if (!row.Get(4, data.FailUrl))
636 return {};
637
638 const auto size = row.GetColumnBytes(6);
639 data.BlobData.resize(size);
640
641 if (size != row.ReadData(6, data.BlobData.data(), size))
642 return {};
643
644 return data;
645 }
646
647 return {};
648}

References audacity::cloud::audiocom::sync::PendingProjectBlobData::BlobData, audacity::cloud::audiocom::sync::PendingProjectBlobData::ConfirmUrl, audacity::cloud::audiocom::sync::PendingProjectBlobData::FailUrl, GetConnection(), audacity::cloud::audiocom::sync::PendingProjectBlobData::ProjectId, size, audacity::cloud::audiocom::sync::PendingProjectBlobData::SnapshotId, and audacity::cloud::audiocom::sync::PendingProjectBlobData::UploadUrl.

Here is the call graph for this function:

◆ GetPendingProjectBlocks()

std::vector< PendingProjectBlockData > audacity::cloud::audiocom::sync::CloudProjectsDatabase::GetPendingProjectBlocks ( std::string_view  projectId,
std::string_view  snapshotId 
)

Definition at line 716 of file CloudProjectsDatabase.cpp.

718{
719 auto connection = GetConnection();
720
721 if (!connection)
722 return {};
723
724 auto statement = connection->CreateStatement(
725 "SELECT project_id, snapshot_id, upload_url, confirm_url, fail_url, block_id, block_sample_format, block_hash FROM pending_project_blocks WHERE project_id = ? AND snapshot_id = ?");
726
727 if (!statement)
728 return {};
729
730 auto result = statement->Prepare(projectId, snapshotId).Run();
731
732 std::vector<PendingProjectBlockData> blocks;
733
734 for (auto row : result)
735 {
736 PendingProjectBlockData data;
737
738 if (!row.Get(0, data.ProjectId))
739 return {};
740
741 if (!row.Get(1, data.SnapshotId))
742 return {};
743
744 if (!row.Get(2, data.UploadUrl))
745 return {};
746
747 if (!row.Get(3, data.ConfirmUrl))
748 return {};
749
750 if (!row.Get(4, data.FailUrl))
751 return {};
752
753 if (!row.Get(5, data.BlockId))
754 return {};
755
756 if (!row.Get(6, data.BlockSampleFormat))
757 return {};
758
759 if (!row.Get(7, data.BlockHash))
760 return {};
761
762 blocks.push_back(data);
763 }
764
765 return blocks;
766}

References audacity::cloud::audiocom::sync::PendingProjectBlockData::BlockHash, audacity::cloud::audiocom::sync::PendingProjectBlockData::BlockId, audacity::cloud::audiocom::sync::PendingProjectBlockData::BlockSampleFormat, audacity::cloud::audiocom::sync::PendingProjectBlockData::ConfirmUrl, audacity::cloud::audiocom::sync::PendingProjectBlockData::FailUrl, GetConnection(), audacity::cloud::audiocom::sync::PendingProjectBlockData::ProjectId, audacity::cloud::audiocom::sync::PendingProjectBlockData::SnapshotId, and audacity::cloud::audiocom::sync::PendingProjectBlockData::UploadUrl.

Here is the call graph for this function:

◆ GetPendingSnapshots()

std::vector< PendingSnapshotData > audacity::cloud::audiocom::sync::CloudProjectsDatabase::GetPendingSnapshots ( std::string_view  projectId) const

Definition at line 525 of file CloudProjectsDatabase.cpp.

526{
527 auto connection = GetConnection();
528
529 if (!connection)
530 return {};
531
532 auto statement = connection->CreateStatement(
533 "SELECT project_id, snapshot_id, confirm_url FROM pending_snapshots WHERE project_id = ?");
534
535 if (!statement)
536 return {};
537
538 auto result = statement->Prepare(projectId).Run();
539
540 std::vector<PendingSnapshotData> snapshots;
541
542 for (auto row : result)
543 {
544 PendingSnapshotData data;
545
546 if (!row.Get(0, data.ProjectId))
547 return {};
548
549 if (!row.Get(1, data.SnapshotId))
550 return {};
551
552 if (!row.Get(2, data.ConfirmUrl))
553 return {};
554
555 snapshots.push_back(data);
556 }
557
558 return snapshots;
559}

References audacity::cloud::audiocom::sync::PendingSnapshotData::ConfirmUrl, GetConnection(), audacity::cloud::audiocom::sync::PendingSnapshotData::ProjectId, and audacity::cloud::audiocom::sync::PendingSnapshotData::SnapshotId.

Here is the call graph for this function:

◆ GetProjectData()

std::optional< DBProjectData > audacity::cloud::audiocom::sync::CloudProjectsDatabase::GetProjectData ( std::string_view  projectId) const

Definition at line 133 of file CloudProjectsDatabase.cpp.

134{
135 auto connection = GetConnection();
136
137 if (!connection)
138 return {};
139
140 auto statement = connection->CreateStatement(
141 "SELECT project_id, snapshot_id, saves_count, last_audio_preview_save, local_path, last_modified, last_read, sync_status, synced_dialog_shown FROM projects WHERE project_id = ? LIMIT 1");
142
143 if (!statement)
144 return {};
145
146 return DoGetProjectData(statement->Prepare(projectId).Run());
147}

References DoGetProjectData(), and GetConnection().

Referenced by audacity::cloud::audiocom::sync::RemoteProjectSnapshot::AttachOriginalDB(), and audacity::cloud::audiocom::sync::RemoteProjectSnapshot::RemoteProjectSnapshot().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetProjectDataForPath()

std::optional< DBProjectData > audacity::cloud::audiocom::sync::CloudProjectsDatabase::GetProjectDataForPath ( const std::string &  projectPath) const

Definition at line 149 of file CloudProjectsDatabase.cpp.

151{
152 auto connection = GetConnection();
153
154 if (!connection)
155 return {};
156
157 auto statement = connection->CreateStatement(
158 "SELECT project_id, snapshot_id, saves_count, last_audio_preview_save, local_path, last_modified, last_read, sync_status, synced_dialog_shown FROM projects WHERE local_path = ? LIMIT 1");
159
160 if (!statement)
161 return {};
162
163 return DoGetProjectData(statement->Prepare(projectFilePath).Run());
164}

References DoGetProjectData(), and GetConnection().

Here is the call graph for this function:

◆ GetProjectUserSlug()

std::string audacity::cloud::audiocom::sync::CloudProjectsDatabase::GetProjectUserSlug ( std::string_view  projectId)

Definition at line 406 of file CloudProjectsDatabase.cpp.

407{
408 auto connection = GetConnection();
409
410 if (!connection)
411 return {};
412
413 auto statement = connection->CreateStatement(
414 "SELECT user_name FROM project_users WHERE project_id = ? LIMIT 1");
415
416 if (!statement)
417 return {};
418
419 auto result = statement->Prepare(projectId).Run();
420
421 for (auto row : result)
422 {
423 std::string slug;
424
425 if (!row.Get(0, slug))
426 return {};
427
428 return slug;
429 }
430
431 return {};
432}

References GetConnection().

Here is the call graph for this function:

◆ IsFirstSyncDialogShown()

bool audacity::cloud::audiocom::sync::CloudProjectsDatabase::IsFirstSyncDialogShown ( std::string_view  projectId) const

Definition at line 359 of file CloudProjectsDatabase.cpp.

361{
362 auto connection = GetConnection();
363
364 if (!connection)
365 return false;
366
367 auto statement = connection->CreateStatement (
368 "SELECT synced_dialog_shown FROM projects WHERE project_id = ? LIMIT 1");
369
370 if (!statement)
371 return false;
372
373 auto result = statement->Prepare(projectId).Run();
374
375 for (auto row : result)
376 {
377 bool shown;
378
379 if (!row.Get(0, shown))
380 return false;
381
382 return shown;
383 }
384
385 return false;
386}

◆ IsProjectBlockLocked()

bool audacity::cloud::audiocom::sync::CloudProjectsDatabase::IsProjectBlockLocked ( std::string_view  projectId,
int64_t  blockId 
) const

Definition at line 451 of file CloudProjectsDatabase.cpp.

453{
454 auto connection = GetConnection();
455
456 if (!connection)
457 return false;
458
459 auto statement = connection->CreateStatement(
460 "SELECT 1 FROM pending_project_blocks WHERE project_id = ? AND block_id = ? LIMIT 1");
461
462 if (!statement)
463 return false;
464
465 auto result = statement->Prepare(projectId, blockId).Run();
466
467 for (auto row : result)
468 return true;
469
470 return false;
471}

References GetConnection().

Here is the call graph for this function:

◆ MarkProjectAsSynced()

bool audacity::cloud::audiocom::sync::CloudProjectsDatabase::MarkProjectAsSynced ( std::string_view  projectId,
std::string_view  snapshotId 
)

Definition at line 208 of file CloudProjectsDatabase.cpp.

210{
211 auto connection = GetConnection();
212
213 if (!connection)
214 return false;
215
216 auto statement = connection->CreateStatement(
217 "UPDATE projects SET sync_status = ? WHERE project_id = ? AND snapshot_id = ?");
218
219 if (!statement)
220 return false;
221
222 auto result = statement
223 ->Prepare(
224 static_cast<int>(DBProjectData::SyncStatusSynced),
225 projectId, snapshotId)
226 .Run();
227
228 if (!result.IsOk())
229 return false;
230
231 return result.GetModifiedRowsCount() > 0;
232}

References GetConnection(), and audacity::cloud::audiocom::sync::DBProjectData::SyncStatusSynced.

Here is the call graph for this function:

◆ OpenConnection()

bool audacity::cloud::audiocom::sync::CloudProjectsDatabase::OpenConnection ( )
private

Definition at line 819 of file CloudProjectsDatabase.cpp.

820{
821 if (mConnection)
822 return true;
823
824 const auto configDir = FileNames::ConfigDir();
825 const auto configPath = configDir + "/audiocom_sync.db";
826
828
829 if (!mConnection)
830 return false;
831
832 auto connection = mConnection->Acquire();
833
834 auto result = connection->Execute(createTableQuery);
835
836 if (!result)
837 {
838 mConnection = {};
839 return false;
840 }
841
842 return RunMigrations();
843}
static std::shared_ptr< SafeConnection > Open(std::string_view path, OpenMode mode=OpenMode::ReadWriteCreate, ThreadMode threadMode=ThreadMode::Serialized, Error *openError=nullptr)
FILES_API FilePath ConfigDir()
Audacity user config directory.
std::string ToUTF8(const std::wstring &wstr)

References FileNames::ConfigDir(), audacity::cloud::audiocom::sync::anonymous_namespace{CloudProjectsDatabase.cpp}::createTableQuery, mConnection, audacity::sqlite::SafeConnection::Open(), RunMigrations(), and audacity::ToUTF8().

Referenced by GetConnection().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ RemovePendingProjectBlob()

void audacity::cloud::audiocom::sync::CloudProjectsDatabase::RemovePendingProjectBlob ( std::string_view  projectId,
std::string_view  snapshotId 
)

Definition at line 585 of file CloudProjectsDatabase.cpp.

587{
588 auto connection = GetConnection();
589
590 if (!connection)
591 return;
592
593 auto statement = connection->CreateStatement(
594 "DELETE FROM pending_project_blobs WHERE project_id = ? AND snapshot_id = ?");
595
596 if (!statement)
597 return;
598
599 statement->Prepare(projectId, snapshotId).Run();
600}

References GetConnection().

Referenced by audacity::cloud::audiocom::sync::anonymous_namespace{ResumedSnaphotUploadOperation.cpp}::ResumedSnaphotUploadOperation::UpdateUrls(), and audacity::cloud::audiocom::sync::anonymous_namespace{ResumedSnaphotUploadOperation.cpp}::ResumedSnaphotUploadOperation::UploadSnapshot().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ RemovePendingProjectBlock()

void audacity::cloud::audiocom::sync::CloudProjectsDatabase::RemovePendingProjectBlock ( std::string_view  projectId,
int64_t  blockId 
)

Definition at line 681 of file CloudProjectsDatabase.cpp.

683{
684 auto connection = GetConnection();
685
686 if (!connection)
687 return;
688
689 auto statement = connection->CreateStatement(
690 "DELETE FROM pending_project_blocks WHERE project_id = ? AND block_id = ?");
691
692 if (!statement)
693 return;
694
695 statement->Prepare(projectId, blockId).Run();
696}

References GetConnection().

Referenced by audacity::cloud::audiocom::sync::LocalProjectSnapshot::OnSnapshotCreated(), audacity::cloud::audiocom::sync::anonymous_namespace{ResumedSnaphotUploadOperation.cpp}::ResumedSnaphotUploadOperation::UpdateUrls(), and audacity::cloud::audiocom::sync::anonymous_namespace{ResumedSnaphotUploadOperation.cpp}::ResumedSnaphotUploadOperation::UploadBlocks().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ RemovePendingProjectBlocks()

void audacity::cloud::audiocom::sync::CloudProjectsDatabase::RemovePendingProjectBlocks ( std::string_view  projectId,
std::string_view  snapshotId 
)

Definition at line 698 of file CloudProjectsDatabase.cpp.

700{
701 auto connection = GetConnection();
702
703 if (!connection)
704 return;
705
706 auto statement = connection->CreateStatement(
707 "DELETE FROM pending_project_blocks WHERE project_id = ? AND snapshot_id = ?");
708
709 if (!statement)
710 return;
711
712 statement->Prepare(projectId, snapshotId).Run();
713}

References GetConnection().

Here is the call graph for this function:

◆ RemovePendingSnapshot()

void audacity::cloud::audiocom::sync::CloudProjectsDatabase::RemovePendingSnapshot ( std::string_view  projectId,
std::string_view  snapshotId 
)

Definition at line 494 of file CloudProjectsDatabase.cpp.

496{
497 auto connection = GetConnection();
498
499 if (!connection)
500 return;
501
502 static const char* queries[] = {
503 "DELETE FROM pending_snapshots WHERE project_id = ? AND snapshot_id = ?",
504 "DELETE FROM pending_project_blobs WHERE project_id = ? AND snapshot_id = ?",
505 "DELETE FROM pending_project_blocks WHERE project_id = ? AND snapshot_id = ?",
506 };
507
508 auto tx = connection->BeginTransaction("RemovePendingSnapshot");
509
510 for (auto query : queries)
511 {
512 auto statement = connection->CreateStatement(query);
513
514 if (!statement)
515 return;
516
517 if (!statement->Prepare(projectId, snapshotId).Run().IsOk())
518 return;
519 }
520
521 tx.Commit();
522}

References GetConnection().

Referenced by audacity::cloud::audiocom::sync::LocalProjectSnapshot::DeleteSnapshot(), audacity::cloud::audiocom::sync::LocalProjectSnapshot::MarkSnapshotSynced(), audacity::cloud::audiocom::sync::anonymous_namespace{ResumedSnaphotUploadOperation.cpp}::ResumedSnaphotUploadOperation::MarkSnapshotSynced(), and audacity::cloud::audiocom::sync::anonymous_namespace{ResumedSnaphotUploadOperation.cpp}::ResumedSnaphotUploadOperation::UploadBlocks().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ RunMigrations()

bool audacity::cloud::audiocom::sync::CloudProjectsDatabase::RunMigrations ( )
private

Definition at line 845 of file CloudProjectsDatabase.cpp.

846{
847 auto connection = mConnection->Acquire();
848
849 auto getMigrationVersion =
850 connection->CreateStatement("SELECT version FROM migration LIMIT 1");
851
852 if (!getMigrationVersion)
853 return false;
854
855 auto versionResult = getMigrationVersion->Prepare().Run();
856
857 if (!versionResult.IsOk())
858 return false;
859
860 int version = 0;
861
862 for (auto row : versionResult)
863 {
864 if (!row.Get(0, version))
865 return false;
866 break;
867 }
868
869 const auto migrationsCount = std::size(migrations);
870
871 if (version >= migrationsCount)
872 return true;
873
874 auto tx = connection->BeginTransaction("RunMigrations");
875
876 for (int i = version; i < migrationsCount; ++i)
877 {
878 auto result = connection->Execute(migrations[i]);
879
880 if (!result)
881 return false;
882 }
883
884 auto updateVersion =
885 connection->CreateStatement("UPDATE migration SET version = ?");
886
887 if (!updateVersion)
888 return false;
889
890 if (!updateVersion->Prepare(migrationsCount).Run().IsOk())
891 return false;
892
893 return tx.Commit().IsOk();
894}

References mConnection, audacity::cloud::audiocom::sync::anonymous_namespace{CloudProjectsDatabase.cpp}::migrations, and size.

Referenced by OpenConnection().

Here is the caller graph for this function:

◆ SetFirstSyncDialogShown()

void audacity::cloud::audiocom::sync::CloudProjectsDatabase::SetFirstSyncDialogShown ( std::string_view  projectId,
bool  shown = true 
)

Definition at line 388 of file CloudProjectsDatabase.cpp.

390{
391 auto connection = GetConnection();
392
393 if (!connection)
394 return;
395
396 auto statement = connection->CreateStatement (
397 "UPDATE projects SET synced_dialog_shown = ? WHERE project_id = ?");
398
399 if (!statement)
400 return;
401
402 statement->Prepare(shown, projectId).Run();
403}

◆ SetProjectUserSlug()

void audacity::cloud::audiocom::sync::CloudProjectsDatabase::SetProjectUserSlug ( std::string_view  projectId,
std::string_view  slug 
)

Definition at line 434 of file CloudProjectsDatabase.cpp.

436{
437 auto connection = GetConnection();
438
439 if (!connection)
440 return;
441
442 auto statement = connection->CreateStatement(
443 "INSERT OR REPLACE INTO project_users (project_id, user_name) VALUES (?, ?)");
444
445 if (!statement)
446 return;
447
448 statement->Prepare(projectId, slug).Run();
449}

References GetConnection().

Here is the call graph for this function:

◆ UpdateBlockHashes()

void audacity::cloud::audiocom::sync::CloudProjectsDatabase::UpdateBlockHashes ( std::string_view  projectId,
const std::vector< std::pair< int64_t, std::string > > &  hashes 
)

Definition at line 286 of file CloudProjectsDatabase.cpp.

289{
290 auto connection = GetConnection();
291
292 if (!connection)
293 return;
294
295 const int localVar {};
296 auto transaction = connection->BeginTransaction(
297 std::string("UpdateBlockHashes_") +
298 std::to_string(reinterpret_cast<size_t>(&localVar)));
299
300 auto statement = connection->CreateStatement(
301 "INSERT OR REPLACE INTO block_hashes (project_id, block_id, hash) VALUES (?, ?, ?)");
302
303 for (const auto& [blockId, hash] : hashes)
304 statement->Prepare(projectId, blockId, hash).Run();
305
306 transaction.Commit();
307}

References GetConnection().

Referenced by audacity::cloud::audiocom::sync::LocalProjectSnapshot::ProjectBlocksLock::UpdateProjectHashesInCache().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ UpdateProjectBlockList()

void audacity::cloud::audiocom::sync::CloudProjectsDatabase::UpdateProjectBlockList ( std::string_view  projectId,
const SampleBlockIDSet blockSet 
)

Definition at line 234 of file CloudProjectsDatabase.cpp.

236{
237 auto connection = GetConnection();
238
239 if (!connection)
240 return;
241
242 auto inProjectSet = connection->CreateScalarFunction(
243 "inProjectSet", [&blockSet](int64_t blockIndex)
244 { return blockSet.find(blockIndex) != blockSet.end(); });
245
246 auto statement = connection->CreateStatement(
247 "DELETE FROM block_hashes WHERE project_id = ? AND NOT inProjectSet(block_id)");
248
249 auto result = statement->Prepare(projectId).Run();
250
251 if (!result.IsOk())
252 {
253 assert(false);
254 }
255}

References GetConnection().

Referenced by audacity::cloud::audiocom::sync::LocalProjectSnapshot::ProjectBlocksLock::ProjectBlocksLock().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ UpdateProjectData()

bool audacity::cloud::audiocom::sync::CloudProjectsDatabase::UpdateProjectData ( const DBProjectData projectData)

Definition at line 309 of file CloudProjectsDatabase.cpp.

310{
311 auto connection = GetConnection();
312
313 if (!connection)
314 return false;
315
316 auto tx = connection->BeginTransaction("UpdateProjectData");
317
318 auto updateProjectData = connection->CreateStatement(
319 "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 (?, ?, ?, ?, ?, ?, ?, ?, ?)");
320
321 if (!updateProjectData)
322 return false;
323
324 auto result = updateProjectData
325 ->Prepare(
326 projectData.ProjectId, projectData.SnapshotId,
327 projectData.SavesCount, projectData.LastAudioPreview,
328 projectData.LocalPath, projectData.LastModified,
329 projectData.LastRead, projectData.SyncStatus,
330 projectData.FirstSyncDialogShown)
331 .Run();
332
333 if (!result.IsOk())
334 return false;
335
336 auto listMissingProjects = connection->CreateStatement (
337 "SELECT project_id FROM projects WHERE project_id != ? AND local_path = ?");
338
339 if (!listMissingProjects)
340 return false;
341
342 auto missingProjects = listMissingProjects->Prepare(
343 projectData.ProjectId, projectData.LocalPath).Run();
344
345 for (auto row : missingProjects)
346 {
347 std::string missingProjectId;
348
349 if (!row.Get(0, missingProjectId))
350 return false;
351
352 if (!DeleteProject(connection, missingProjectId))
353 return false;
354 }
355
356 return tx.Commit().IsOk();
357}

References DeleteProject(), audacity::cloud::audiocom::sync::DBProjectData::FirstSyncDialogShown, GetConnection(), audacity::cloud::audiocom::sync::DBProjectData::LastAudioPreview, audacity::cloud::audiocom::sync::DBProjectData::LastModified, audacity::cloud::audiocom::sync::DBProjectData::LastRead, audacity::cloud::audiocom::sync::DBProjectData::LocalPath, audacity::cloud::audiocom::sync::DBProjectData::ProjectId, audacity::cloud::audiocom::sync::DBProjectData::SavesCount, audacity::cloud::audiocom::sync::DBProjectData::SnapshotId, and audacity::cloud::audiocom::sync::DBProjectData::SyncStatus.

Here is the call graph for this function:

Member Data Documentation

◆ mConnection

std::shared_ptr<sqlite::SafeConnection> audacity::cloud::audiocom::sync::CloudProjectsDatabase::mConnection
private

Definition at line 155 of file CloudProjectsDatabase.h.

Referenced by GetConnection(), OpenConnection(), and RunMigrations().

◆ mConnectionMutex

std::mutex audacity::cloud::audiocom::sync::CloudProjectsDatabase::mConnectionMutex
private

Definition at line 154 of file CloudProjectsDatabase.h.

Referenced by GetConnection().


The documentation for this class was generated from the following files: