winget-cli

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

CheckpointDatabase.cpp (6857B)


      1 // Copyright (c) Microsoft Corporation.
      2 // Licensed under the MIT License.
      3 #include "pch.h"
      4 #include "Public/winget/CheckpointDatabase.h"
      5 #include "Microsoft/Schema/ICheckpointDatabase.h"
      6 #include "Microsoft/Schema/Checkpoint_1_0/CheckpointDatabaseInterface.h"
      7 
      8 namespace AppInstaller::Repository::Microsoft
      9 {
     10     namespace
     11     {
     12         // Creates the ICheckpointDatabase interface object for the given version.
     13         std::unique_ptr<Schema::ICheckpointDatabase> CreateICheckpointDatabase(const SQLite::Version& version)
     14         {
     15             if (version == SQLite::Version{ 1, 0 } ||
     16                 version.MajorVersion == 1 ||
     17                 version.IsLatest())
     18             {
     19                 return std::make_unique<Schema::Checkpoint_V1_0::CheckpointDatabaseInterface>();
     20             }
     21 
     22             THROW_HR(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED));
     23         }
     24     }
     25 
     26     CheckpointDatabase::CheckpointDatabase(CheckpointDatabase&&) = default;
     27     CheckpointDatabase& CheckpointDatabase::operator=(CheckpointDatabase&&) = default;
     28 
     29     std::shared_ptr<CheckpointDatabase> CheckpointDatabase::CreateNew(const std::string& filePath, SQLite::Version version)
     30     {
     31         AICLI_LOG(Repo, Info, << "Creating new Checkpoint database with version [" << version << "] at '" << filePath << "'");
     32         CheckpointDatabase result{ filePath, version };
     33 
     34         SQLite::Savepoint savepoint = SQLite::Savepoint::Create(result.m_dbconn, "CheckpointDatabase_CreateNew");
     35 
     36         // Use calculated version, as incoming version could be 'latest'
     37         result.m_version.SetSchemaVersion(result.m_dbconn);
     38 
     39         result.m_interface->CreateTables(result.m_dbconn);
     40 
     41         result.SetLastWriteTime();
     42 
     43         savepoint.Commit();
     44 
     45         return std::make_shared<CheckpointDatabase>(std::move(result));
     46     }
     47 
     48     std::shared_ptr<CheckpointDatabase> CheckpointDatabase::Open(const std::string& filePath, SQLite::SQLiteStorageBase::OpenDisposition disposition, Utility::ManagedFile&& indexFile)
     49     {
     50         return std::make_shared<CheckpointDatabase>(CheckpointDatabase{ filePath, disposition, std::move(indexFile) });
     51     }
     52 
     53     bool CheckpointDatabase::IsEmpty()
     54     {
     55         return m_interface->IsEmpty(m_dbconn);
     56     }
     57 
     58     CheckpointDatabase::IdType CheckpointDatabase::AddCheckpoint(std::string_view checkpointName)
     59     {
     60         std::lock_guard<std::mutex> lockInterface{ *m_interfaceLock };
     61         AICLI_LOG(Repo, Verbose, << "Adding checkpoint [" << checkpointName << "]");
     62 
     63         SQLite::Savepoint savepoint = SQLite::Savepoint::Create(m_dbconn, "CheckpointDatabase_addCheckpoint");
     64 
     65         IdType result = m_interface->AddCheckpoint(m_dbconn, checkpointName);
     66 
     67         SetLastWriteTime();
     68         savepoint.Commit();
     69         return result;
     70     }
     71 
     72     std::vector<CheckpointDatabase::IdType> CheckpointDatabase::GetCheckpointIds()
     73     {
     74         return m_interface->GetCheckpointIds(m_dbconn);
     75     }
     76 
     77     bool CheckpointDatabase::HasDataField(IdType checkpointId, int type, const std::string& name)
     78     {
     79         return m_interface->GetCheckpointDataFieldValues(m_dbconn, checkpointId, type, name).has_value();
     80     }
     81 
     82     std::vector<int> CheckpointDatabase::GetDataTypes(IdType checkpointId)
     83     {
     84         return m_interface->GetCheckpointDataTypes(m_dbconn, checkpointId);
     85     }
     86 
     87     std::vector<std::string> CheckpointDatabase::GetDataFieldNames(IdType checkpointId, int dataType)
     88     {
     89         return m_interface->GetCheckpointDataFields(m_dbconn, checkpointId, dataType);
     90     }
     91 
     92     void CheckpointDatabase::SetDataValue(IdType checkpointId, int dataType, const std::string& field, const std::vector<std::string>& values)
     93     {
     94         std::lock_guard<std::mutex> lockInterface{ *m_interfaceLock };
     95         AICLI_LOG(Repo, Verbose, << "Setting checkpoint data [" << dataType << "]");
     96 
     97         SQLite::Savepoint savepoint = SQLite::Savepoint::Create(m_dbconn, "CheckpointDatabase_setDataValue");
     98 
     99         m_interface->SetCheckpointDataValues(m_dbconn, checkpointId, dataType, field, values);
    100 
    101         SetLastWriteTime();
    102         savepoint.Commit();
    103     }
    104 
    105     void CheckpointDatabase::UpdateDataValue(IdType checkpointId, int dataType, const std::string& field, const std::vector<std::string>& values)
    106     {
    107         std::lock_guard<std::mutex> lockInterface{ *m_interfaceLock };
    108         AICLI_LOG(Repo, Verbose, << "Updating checkpoint data [" << dataType << "]");
    109 
    110         SQLite::Savepoint savepoint = SQLite::Savepoint::Create(m_dbconn, "CheckpointDatabase_updateDataValue");
    111 
    112         m_interface->RemoveCheckpointDataType(m_dbconn, checkpointId, dataType);
    113         m_interface->SetCheckpointDataValues(m_dbconn, checkpointId, dataType, field, values);
    114 
    115         SetLastWriteTime();
    116         savepoint.Commit();
    117     }
    118 
    119     void CheckpointDatabase::RemoveDataType(IdType checkpointId, int dataType)
    120     {
    121         std::lock_guard<std::mutex> lockInterface{ *m_interfaceLock };
    122         AICLI_LOG(Repo, Verbose, << "Removing checkpoint data [" << dataType << "]");
    123 
    124         SQLite::Savepoint savepoint = SQLite::Savepoint::Create(m_dbconn, "CheckpointDatabase_removeDataValue");
    125 
    126         m_interface->RemoveCheckpointDataType(m_dbconn, checkpointId, dataType);
    127 
    128         SetLastWriteTime();
    129         savepoint.Commit();
    130     }
    131 
    132     std::string CheckpointDatabase::GetDataFieldSingleValue(IdType checkpointId, int dataType, const std::string& field)
    133     {
    134         const auto& values = m_interface->GetCheckpointDataFieldValues(m_dbconn, checkpointId, dataType, field);
    135 
    136         if (!values.has_value())
    137         {
    138             THROW_HR(E_UNEXPECTED);
    139         }
    140 
    141         return values.value()[0];
    142     }
    143 
    144     std::vector<std::string> CheckpointDatabase::GetDataFieldMultiValue(IdType checkpointId, int dataType, const std::string& field)
    145     {
    146         const auto& values = m_interface->GetCheckpointDataFieldValues(m_dbconn, checkpointId, dataType, field);
    147 
    148         if (!values.has_value())
    149         {
    150             THROW_HR(E_UNEXPECTED);
    151         }
    152 
    153         return values.value();
    154     }
    155 
    156 
    157     CheckpointDatabase::CheckpointDatabase(const std::string& target, SQLiteStorageBase::OpenDisposition disposition, Utility::ManagedFile&& indexFile) :
    158         SQLiteStorageBase(target, disposition, std::move(indexFile))
    159     {
    160         AICLI_LOG(Repo, Info, << "Opened Checkpoint Index with version [" << m_version << "], last write [" << GetLastWriteTime() << "]");
    161         m_interface = CreateICheckpointDatabase(m_version);
    162         THROW_HR_IF(APPINSTALLER_CLI_ERROR_CANNOT_WRITE_TO_UPLEVEL_INDEX, disposition == SQLiteStorageBase::OpenDisposition::ReadWrite && m_version != m_interface->GetVersion());
    163     }
    164 
    165     CheckpointDatabase::CheckpointDatabase(const std::string& target, SQLite::Version version) : SQLiteStorageBase(target, version)
    166     {
    167         m_interface = CreateICheckpointDatabase(m_version);
    168         m_version = m_interface->GetVersion();
    169     }
    170 }