winget-cli

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

OneToManyTable.h (8189B)


      1 // Copyright (c) Microsoft Corporation.
      2 // Licensed under the MIT License.
      3 #pragma once
      4 #include <winget/SQLiteWrapper.h>
      5 #include <string>
      6 #include <string_view>
      7 #include <vector>
      8 
      9 
     10 namespace AppInstaller::Repository::Microsoft::Schema::V1_0
     11 {
     12     // Allow the different schema version to indicate which they are.
     13     enum class OneToManyTableSchema
     14     {
     15         // Does not used a named unique index for either table.
     16         // Map table has primary key and rowid.
     17         Version_1_0,
     18         // Uses a named unique index for both tables.
     19         // Map table has rowid.
     20         Version_1_1,
     21         // Uses a named unique index for data table. (No change from 1.1)
     22         // Map table has primary key and no rowid.
     23         Version_1_7,
     24     };
     25 
     26     namespace details
     27     {
     28         // Returns the map table name for a given table.
     29         std::string OneToManyTableGetMapTableName(std::string_view tableName);
     30 
     31         // Returns the manifest column name.
     32         std::string_view OneToManyTableGetManifestColumnName();
     33 
     34         // Create the tables.
     35         void CreateOneToManyTable(SQLite::Connection& connection, OneToManyTableSchema schemaVersion, std::string_view tableName, std::string_view valueName);
     36 
     37         // Drop the tables.
     38         void DropOneToManyTable(SQLite::Connection& connection, std::string_view tableName);
     39 
     40         // Gets all values associated with the given manifest id.
     41         std::vector<std::string> OneToManyTableGetValuesByManifestId(
     42             const SQLite::Connection& connection,
     43             std::string_view tableName,
     44             std::string_view valueName,
     45             SQLite::rowid_t manifestId);
     46 
     47         // Ensures that the value exists and inserts mapping entries.
     48         void OneToManyTableEnsureExistsAndInsert(SQLite::Connection& connection,
     49             std::string_view tableName, std::string_view valueName, 
     50             const std::vector<Utility::NormalizedString>& values, SQLite::rowid_t manifestId);
     51 
     52         // Updates the mapping table to represent the given values for the manifest.
     53         bool OneToManyTableUpdateIfNeededByManifestId(SQLite::Connection& connection,
     54             std::string_view tableName, std::string_view valueName,
     55             const std::vector<Utility::NormalizedString>& values, SQLite::rowid_t manifestId);
     56 
     57         // Deletes the mapping rows for the given manifest, then removes any unused data rows.
     58         void OneToManyTableDeleteIfNotNeededByManifestId(SQLite::Connection& connection, std::string_view tableName, std::string_view valueName, SQLite::rowid_t manifestId);
     59 
     60         // Removes data that is no longer needed for an index that is to be published.
     61         void OneToManyTablePrepareForPackaging(SQLite::Connection& connection, std::string_view tableName, OneToManyTableSchema schemaVersion, bool preserveManifestIndex, bool preserveValuesIndex);
     62 
     63         // Checks the consistency of the index to ensure that every referenced row exists.
     64         // Returns true if index is consistent; false if it is not.
     65          bool OneToManyTableCheckConsistency(const SQLite::Connection& connection, std::string_view tableName, std::string_view valueName, bool log);
     66 
     67         // Determines if the table is empty.
     68         bool OneToManyTableIsEmpty(SQLite::Connection& connection, std::string_view tableName);
     69 
     70         // Prepares a statement for replacing all of the map data to point to a single manifest for a given id.
     71         SQLite::Statement OneToManyTablePrepareMapDataFoldingStatement(const SQLite::Connection& connection, std::string_view tableName);
     72     }
     73 
     74     // Gets the manifest id that the PrepareMapDataFoldingStatement will fold to for the given manifest id.
     75     std::optional<SQLite::rowid_t> OneToManyTableGetMapDataFoldingManifestTargetId(const SQLite::Connection& connection, SQLite::rowid_t manifestId);
     76 
     77     // A table that represents a value that is 1:N with a primary entry.
     78     template <typename TableInfo>
     79     struct OneToManyTable
     80     {
     81         // The name of the table.
     82         static constexpr std::string_view TableName()
     83         {
     84             return TableInfo::TableName();
     85         }
     86 
     87         // The value name of the table.
     88         static constexpr std::string_view ValueName()
     89         {
     90             return TableInfo::ValueName();
     91         }
     92 
     93         // Value indicating type.
     94         static constexpr bool IsOneToOne()
     95         {
     96             return false;
     97         }
     98 
     99         // Creates the table with named indices.
    100         static void Create(SQLite::Connection& connection, OneToManyTableSchema schemaVersion)
    101         {
    102             details::CreateOneToManyTable(connection, schemaVersion, TableInfo::TableName(), TableInfo::ValueName());
    103         }
    104 
    105         // Drops the table.
    106         static void Drop(SQLite::Connection& connection)
    107         {
    108             details::DropOneToManyTable(connection, TableInfo::TableName());
    109         }
    110 
    111         // Gets all values associated with the given manifest id.
    112         static std::vector<std::string> GetValuesByManifestId(const SQLite::Connection& connection, SQLite::rowid_t manifestId)
    113         {
    114             return details::OneToManyTableGetValuesByManifestId(connection, TableInfo::TableName(), TableInfo::ValueName(), manifestId);
    115         }
    116 
    117         // Ensures that all values exist in the data table, and inserts into the mapping table for the given manifest id.
    118         static void EnsureExistsAndInsert(SQLite::Connection& connection, const std::vector<Utility::NormalizedString>& values, SQLite::rowid_t manifestId)
    119         {
    120             details::OneToManyTableEnsureExistsAndInsert(connection, TableInfo::TableName(), TableInfo::ValueName(), values, manifestId);
    121         }
    122 
    123         // Updates the mapping table to represent the given values for the manifest.
    124         static bool UpdateIfNeededByManifestId(SQLite::Connection& connection, const std::vector<Utility::NormalizedString>& values, SQLite::rowid_t manifestId)
    125         {
    126             return details::OneToManyTableUpdateIfNeededByManifestId(connection, TableInfo::TableName(), TableInfo::ValueName(), values, manifestId);
    127         }
    128 
    129         // Deletes the mapping rows for the given manifest, then removes any unused data rows.
    130         static void DeleteIfNotNeededByManifestId(SQLite::Connection& connection, SQLite::rowid_t manifestId)
    131         {
    132             details::OneToManyTableDeleteIfNotNeededByManifestId(connection, TableInfo::TableName(), TableInfo::ValueName(), manifestId);
    133         }
    134 
    135         // Removes data that is no longer needed for an index that is to be published.
    136         // Preserving the manifest index will improve the efficiency of finding the values associated with a manifest.
    137         // Preserving the values index will improve searching when it is primarily done by equality.
    138         static void PrepareForPackaging(SQLite::Connection& connection, OneToManyTableSchema schemaVersion, bool preserveManifestIndex, bool preserveValuesIndex)
    139         {
    140             details::OneToManyTablePrepareForPackaging(connection, TableInfo::TableName(), schemaVersion, preserveManifestIndex, preserveValuesIndex);
    141         }
    142 
    143         // Checks the consistency of the index to ensure that every referenced row exists.
    144         // Returns true if index is consistent; false if it is not.
    145         static bool CheckConsistency(const SQLite::Connection& connection, bool log)
    146         {
    147             return details::OneToManyTableCheckConsistency(connection, TableInfo::TableName(), TableInfo::ValueName(), log);
    148         }
    149 
    150         // Determines if the table is empty.
    151         static bool IsEmpty(SQLite::Connection& connection)
    152         {
    153             return details::OneToManyTableIsEmpty(connection, TableInfo::TableName());
    154         }
    155 
    156         // Prepares a statement for replacing all of the map data to point to a single manifest for a given id.
    157         static SQLite::Statement PrepareMapDataFoldingStatement(const SQLite::Connection& connection)
    158         {
    159             return details::OneToManyTablePrepareMapDataFoldingStatement(connection, TableInfo::TableName());
    160         }
    161     };
    162 }