winget-cli

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

ManifestMetadataTable.cpp (5940B)


      1 // Copyright (c) Microsoft Corporation.
      2 // Licensed under the MIT License.
      3 #include "pch.h"
      4 #include "ManifestMetadataTable.h"
      5 #include <winget/SQLiteStatementBuilder.h>
      6 
      7 
      8 namespace AppInstaller::Repository::Microsoft::Schema::V1_1
      9 {
     10     using namespace SQLite;
     11 
     12     static constexpr std::string_view s_ManifestMetadataTable_Table_Name = "manifest_metadata"sv;
     13     static constexpr std::string_view s_ManifestMetadataTable_PrimaryKeyIndex_Name = "manifest_metadata_pk"sv;
     14     static constexpr std::string_view s_ManifestMetadataTable_Manifest_Column = "manifest"sv;
     15     static constexpr std::string_view s_ManifestMetadataTable_Metadata_Column = "metadata"sv;
     16     static constexpr std::string_view s_ManifestMetadataTable_Value_Column = "value"sv;
     17 
     18     bool ManifestMetadataTable::Exists(const SQLite::Connection& connection)
     19     {
     20         Builder::StatementBuilder builder;
     21         builder.Select(Builder::RowCount).From(Builder::Schema::MainTable).
     22             Where(Builder::Schema::TypeColumn).Equals(Builder::Schema::Type_Table).And(Builder::Schema::NameColumn).Equals(s_ManifestMetadataTable_Table_Name);
     23 
     24         Statement statement = builder.Prepare(connection);
     25         THROW_HR_IF(E_UNEXPECTED, !statement.Step());
     26         return statement.GetColumn<int64_t>(0) != 0;
     27     }
     28 
     29     void ManifestMetadataTable::Create(SQLite::Connection& connection)
     30     {
     31         using namespace Builder;
     32 
     33         SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, "createmanifestmetadata_v1_1");
     34 
     35         StatementBuilder createTableBuilder;
     36         createTableBuilder.CreateTable(s_ManifestMetadataTable_Table_Name).Columns({
     37             ColumnBuilder(s_ManifestMetadataTable_Manifest_Column, Type::Int64).NotNull(),
     38             ColumnBuilder(s_ManifestMetadataTable_Metadata_Column, Type::Int64).NotNull(),
     39             ColumnBuilder(s_ManifestMetadataTable_Value_Column, Type::Text)
     40             });
     41 
     42         createTableBuilder.Execute(connection);
     43 
     44         StatementBuilder createPKIndexBuilder;
     45         createPKIndexBuilder.CreateUniqueIndex(s_ManifestMetadataTable_PrimaryKeyIndex_Name).On(s_ManifestMetadataTable_Table_Name).
     46             Columns({ s_ManifestMetadataTable_Manifest_Column, s_ManifestMetadataTable_Metadata_Column });
     47         createPKIndexBuilder.Execute(connection);
     48 
     49         savepoint.Commit();
     50     }
     51 
     52     void ManifestMetadataTable::Drop(SQLite::Connection& connection)
     53     {
     54         SQLite::Builder::StatementBuilder dropTableBuilder;
     55         dropTableBuilder.DropTableIfExists(s_ManifestMetadataTable_Table_Name);
     56 
     57         dropTableBuilder.Execute(connection);
     58     }
     59 
     60     ISQLiteIndex::MetadataResult ManifestMetadataTable::GetMetadataByManifestId(const SQLite::Connection& connection, SQLite::rowid_t manifestId)
     61     {
     62         using namespace Builder;
     63 
     64         StatementBuilder builder;
     65         builder.Select({ s_ManifestMetadataTable_Metadata_Column, s_ManifestMetadataTable_Value_Column }).From(s_ManifestMetadataTable_Table_Name).
     66             Where(s_ManifestMetadataTable_Manifest_Column).Equals(manifestId);
     67 
     68         Statement statement = builder.Prepare(connection);
     69 
     70         ISQLiteIndex::MetadataResult result;
     71         while (statement.Step())
     72         {
     73             result.emplace_back(std::make_pair(statement.GetColumn<PackageVersionMetadata>(0), statement.GetColumn<std::string>(1)));
     74         }
     75 
     76         return result;
     77     }
     78 
     79     std::optional<std::string> ManifestMetadataTable::GetMetadataByManifestIdAndMetadata(const SQLite::Connection& connection, SQLite::rowid_t manifestId, PackageVersionMetadata metadata)
     80     {
     81         using namespace Builder;
     82 
     83         StatementBuilder builder;
     84         builder.Select(s_ManifestMetadataTable_Value_Column).From(s_ManifestMetadataTable_Table_Name).
     85             Where(s_ManifestMetadataTable_Manifest_Column).Equals(manifestId).
     86             And(s_ManifestMetadataTable_Metadata_Column).Equals(metadata);
     87 
     88         Statement statement = builder.Prepare(connection);
     89 
     90         if (statement.Step())
     91         {
     92             return statement.GetColumn<std::string>(0);
     93         }
     94 
     95         return {};
     96     }
     97 
     98     void ManifestMetadataTable::SetMetadataByManifestId(SQLite::Connection& connection, SQLite::rowid_t manifestId, PackageVersionMetadata metadata, std::string_view value)
     99     {
    100         using namespace Builder;
    101 
    102         // First, we attempt to update an existing row. If not changes occurred, we then insert the new value.
    103         // UPSERT (aka ON CONFLICT) is not available to us, as it was only introduced in 3.24.0 (2018-06-04),
    104         // and we need to support Windows 10 (17763) which was released in 2017.
    105         StatementBuilder updateBuilder;
    106         updateBuilder.Update(s_ManifestMetadataTable_Table_Name).Set().Column(s_ManifestMetadataTable_Value_Column).Equals(value).
    107             Where(s_ManifestMetadataTable_Manifest_Column).Equals(manifestId).And(s_ManifestMetadataTable_Metadata_Column).Equals(metadata);
    108 
    109         updateBuilder.Execute(connection);
    110 
    111         // No changes means we need to insert the row
    112         if (connection.GetChanges() == 0)
    113         {
    114             StatementBuilder insertBuilder;
    115             insertBuilder.InsertInto(s_ManifestMetadataTable_Table_Name).
    116                 Columns({ s_ManifestMetadataTable_Manifest_Column, s_ManifestMetadataTable_Metadata_Column, s_ManifestMetadataTable_Value_Column })
    117                 .Values(manifestId, metadata, value);
    118 
    119             insertBuilder.Execute(connection);
    120         }
    121     }
    122 
    123     void ManifestMetadataTable::DeleteByManifestId(SQLite::Connection & connection, SQLite::rowid_t manifestId)
    124     {
    125         using namespace Builder;
    126 
    127         StatementBuilder builder;
    128         builder.DeleteFrom(s_ManifestMetadataTable_Table_Name).Where(s_ManifestMetadataTable_Manifest_Column).Equals(manifestId);
    129         builder.Execute(connection);
    130     }
    131 }