winget-cli

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

PinTable.cpp (7499B)


      1 // Copyright (c) Microsoft Corporation.
      2 // Licensed under the MIT License.
      3 #include "pch.h"
      4 #include "PinTable.h"
      5 #include <winget/SQLiteStatementBuilder.h>
      6 #include "Microsoft/Schema/IPinningIndex.h"
      7 
      8 namespace AppInstaller::Repository::Microsoft::Schema::Pinning_V1_0
      9 {
     10     namespace
     11     {
     12         std::optional<Pinning::Pin> GetPinFromRow(
     13             std::string_view packageId,
     14             std::string_view sourceId,
     15             Pinning::PinType type,
     16             std::string_view version)
     17 
     18         {
     19             switch (type)
     20             {
     21             case Pinning::PinType::Blocking:
     22                 return Pinning::Pin::CreateBlockingPin({ packageId, sourceId });
     23             case Pinning::PinType::Pinning:
     24                 return Pinning::Pin::CreatePinningPin({ packageId, sourceId });
     25             case Pinning::PinType::Gating:
     26                 return Pinning::Pin::CreateGatingPin({ packageId, sourceId }, Utility::GatedVersion{ version });
     27             default:
     28                 return {};
     29             }
     30         }
     31     }
     32 
     33     using namespace std::string_view_literals;
     34     static constexpr std::string_view s_PinTable_Table_Name = "pin"sv;
     35     static constexpr std::string_view s_PinTable_PackageId_Column = "package_id"sv;
     36     static constexpr std::string_view s_PinTable_SourceId_Column = "source_id"sv;
     37     static constexpr std::string_view s_PinTable_Type_Column = "type"sv;
     38     static constexpr std::string_view s_PinTable_Version_Column = "version"sv;
     39     static constexpr std::string_view s_PinTable_Index = "pin_index"sv;
     40 
     41     std::string_view PinTable::TableName()
     42     {
     43         return s_PinTable_Table_Name;
     44     }
     45 
     46     void PinTable::Create(SQLite::Connection& connection)
     47     {
     48         using namespace SQLite::Builder;
     49 
     50         SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, "createpintable_v1_0");
     51 
     52         StatementBuilder createTableBuilder;
     53         createTableBuilder.CreateTable(s_PinTable_Table_Name).BeginColumns();
     54 
     55         createTableBuilder.Column(ColumnBuilder(s_PinTable_PackageId_Column, Type::Text).NotNull());
     56         createTableBuilder.Column(ColumnBuilder(s_PinTable_SourceId_Column, Type::Text).NotNull());
     57         createTableBuilder.Column(ColumnBuilder(s_PinTable_Type_Column, Type::Int64).NotNull());
     58         createTableBuilder.Column(ColumnBuilder(s_PinTable_Version_Column, Type::Text).NotNull());
     59 
     60         createTableBuilder.EndColumns();
     61         createTableBuilder.Execute(connection);
     62 
     63         // Create an index over the pairs package,source
     64         StatementBuilder createIndexBuilder;
     65         createIndexBuilder.CreateUniqueIndex(s_PinTable_Index).On(s_PinTable_Table_Name)
     66             .Columns({ s_PinTable_PackageId_Column, s_PinTable_SourceId_Column });
     67         createIndexBuilder.Execute(connection);
     68 
     69         savepoint.Commit();
     70     }
     71 
     72     std::optional<SQLite::rowid_t> PinTable::GetIdByPinKey(SQLite::Connection& connection, const Pinning::PinKey& pinKey)
     73     {
     74         SQLite::Builder::StatementBuilder builder;
     75         builder.Select(SQLite::RowIDName).From(s_PinTable_Table_Name)
     76             .Where(s_PinTable_PackageId_Column).Equals((std::string_view)pinKey.PackageId)
     77             .And(s_PinTable_SourceId_Column).Equals((std::string_view)pinKey.SourceId);
     78 
     79         SQLite::Statement select = builder.Prepare(connection);
     80 
     81         if (select.Step())
     82         {
     83             return select.GetColumn<SQLite::rowid_t>(0);
     84         }
     85         else
     86         {
     87             return {};
     88         }
     89     }
     90 
     91     SQLite::rowid_t PinTable::AddPin(SQLite::Connection& connection, const Pinning::Pin& pin)
     92     {
     93         SQLite::Builder::StatementBuilder builder;
     94         const auto& pinKey = pin.GetKey();
     95         builder.InsertInto(s_PinTable_Table_Name)
     96             .Columns({
     97                 s_PinTable_PackageId_Column,
     98                 s_PinTable_SourceId_Column,
     99                 s_PinTable_Type_Column,
    100                 s_PinTable_Version_Column })
    101             .Values(
    102                 (std::string_view)pinKey.PackageId,
    103                 pinKey.SourceId,
    104                 pin.GetType(),
    105                 pin.GetGatedVersion().ToString());
    106 
    107         builder.Execute(connection);
    108         return connection.GetLastInsertRowID();
    109     }
    110 
    111     bool PinTable::UpdatePinById(SQLite::Connection& connection, SQLite::rowid_t pinId, const Pinning::Pin& pin)
    112     {
    113         SQLite::Builder::StatementBuilder builder;
    114         const auto& pinKey = pin.GetKey();
    115         builder.Update(s_PinTable_Table_Name).Set()
    116             .Column(s_PinTable_PackageId_Column).Equals((std::string_view)pinKey.PackageId)
    117             .Column(s_PinTable_SourceId_Column).Equals(pinKey.SourceId)
    118             .Column(s_PinTable_Type_Column).Equals(pin.GetType())
    119             .Column(s_PinTable_Version_Column).Equals(pin.GetGatedVersion().ToString())
    120             .Where(SQLite::RowIDName).Equals(pinId);
    121 
    122         builder.Execute(connection);
    123         return connection.GetChanges() != 0;
    124     }
    125 
    126     void PinTable::RemovePinById(SQLite::Connection& connection, SQLite::rowid_t pinId)
    127     {
    128         SQLite::Builder::StatementBuilder builder;
    129         builder.DeleteFrom(s_PinTable_Table_Name).Where(SQLite::RowIDName).Equals(pinId);
    130         builder.Execute(connection);
    131     }
    132 
    133     std::optional<Pinning::Pin> PinTable::GetPinById(SQLite::Connection& connection, const SQLite::rowid_t pinId)
    134     {
    135         SQLite::Builder::StatementBuilder builder;
    136         builder.Select({
    137             s_PinTable_PackageId_Column,
    138             s_PinTable_SourceId_Column,
    139             s_PinTable_Type_Column,
    140             s_PinTable_Version_Column })
    141             .From(s_PinTable_Table_Name).Where(SQLite::RowIDName).Equals(pinId);
    142 
    143         SQLite::Statement select = builder.Prepare(connection);
    144 
    145         if (!select.Step())
    146         {
    147             return {};
    148         }
    149 
    150         auto [packageId, sourceId, pinType, gatedVersion] =
    151             select.GetRow<std::string, std::string, Pinning::PinType, std::string>();
    152         return GetPinFromRow(packageId, sourceId, pinType, gatedVersion);
    153     }
    154 
    155     std::vector<Pinning::Pin> PinTable::GetAllPins(SQLite::Connection& connection)
    156     {
    157         SQLite::Builder::StatementBuilder builder;
    158         builder.Select({
    159             s_PinTable_PackageId_Column,
    160             s_PinTable_SourceId_Column,
    161             s_PinTable_Type_Column,
    162             s_PinTable_Version_Column })
    163             .From(s_PinTable_Table_Name);
    164 
    165         SQLite::Statement select = builder.Prepare(connection);
    166 
    167         std::vector<Pinning::Pin> pins;
    168         while (select.Step())
    169         {
    170             auto [packageId, sourceId, pinType, gatedVersion] =
    171                 select.GetRow<std::string, std::string, Pinning::PinType, std::string>();
    172             auto pin = GetPinFromRow(packageId, sourceId, pinType, gatedVersion);
    173             if (pin)
    174             {
    175                 pins.push_back(std::move(pin.value()));
    176             }
    177         }
    178 
    179         return pins;
    180     }
    181 
    182     bool PinTable::ResetAllPins(SQLite::Connection& connection, std::string_view sourceId)
    183     {
    184         SQLite::Builder::StatementBuilder builder;
    185         builder.DeleteFrom(s_PinTable_Table_Name);
    186 
    187         if (!sourceId.empty())
    188         {
    189             builder.Where(s_PinTable_SourceId_Column).Equals(sourceId);
    190         }
    191 
    192         builder.Execute(connection);
    193 
    194         return connection.GetChanges() != 0;
    195     }
    196 }