OneToManyTableWithMap.h (6409B)
1 // Copyright (c) Microsoft Corporation. 2 // Licensed under the MIT License. 3 #pragma once 4 #include <winget/SQLiteWrapper.h> 5 #include <winget/SQLiteStatementBuilder.h> 6 #include <string> 7 #include <string_view> 8 #include <vector> 9 10 11 namespace AppInstaller::Repository::Microsoft::Schema::V2_0 12 { 13 // Allow the different schema version to indicate which they are. 14 enum class OneToManyTableSchema 15 { 16 // Uses a named unique index for data table. 17 // Map table has primary key and no rowid. 18 // Column order is consistent with primary key order. 19 Version_2_0, 20 }; 21 22 namespace details 23 { 24 // Returns the map table name for a given table. 25 std::string OneToManyTableGetMapTableName(std::string_view tableName); 26 27 // Returns the primary column name. 28 std::string_view OneToManyTableGetManifestColumnName(); 29 30 // Create the tables. 31 void CreateOneToManyTableWithMap(SQLite::Connection& connection, OneToManyTableSchema schemaVersion, std::string_view tableName, std::string_view valueName); 32 33 // Drops the tables. 34 void DropOneToManyTableWithMap(SQLite::Connection& connection, std::string_view tableName); 35 36 // Gets all values associated with the given primary id. 37 std::vector<std::string> OneToManyTableWithMapGetValuesByPrimaryId( 38 const SQLite::Connection& connection, 39 std::string_view tableName, 40 std::string_view valueName, 41 SQLite::rowid_t primaryId); 42 43 // Ensures that the value exists and inserts mapping entries. 44 void OneToManyTableWithMapEnsureExistsAndInsert(SQLite::Connection& connection, 45 std::string_view tableName, std::string_view valueName, 46 const std::vector<std::string>& values, SQLite::rowid_t primaryId); 47 48 // Removes data that is no longer needed for an index that is to be published. 49 void OneToManyTableWithMapPrepareForPackaging(SQLite::Connection& connection, std::string_view tableName); 50 51 // Checks the consistency of the index to ensure that every referenced row exists. 52 // Returns true if index is consistent; false if it is not. 53 bool OneToManyTableWithMapCheckConsistency(const SQLite::Connection& connection, std::string_view tableName, std::string_view valueName, bool log); 54 55 // Determines if the table is empty. 56 bool OneToManyTableWithMapIsEmpty(SQLite::Connection& connection, std::string_view tableName); 57 58 // Builds the search select statement base on the given value. 59 // The return value is the bind index of the value to match against. 60 int OneToManyTableWithMapBuildSearchStatement( 61 SQLite::Builder::StatementBuilder& builder, 62 std::string_view tableName, 63 std::string_view valueName, 64 std::string_view primaryAlias, 65 std::string_view valueAlias, 66 bool useLike); 67 } 68 69 // A table that represents a value that is 1:N with a primary entry. 70 template <typename TableInfo> 71 struct OneToManyTableWithMap 72 { 73 // The name of the table. 74 static constexpr std::string_view TableName() 75 { 76 return TableInfo::TableName(); 77 } 78 79 // The value name of the table. 80 static constexpr std::string_view ValueName() 81 { 82 return TableInfo::ValueName(); 83 } 84 85 // Creates the table with named indices. 86 static void Create(SQLite::Connection& connection, OneToManyTableSchema schemaVersion) 87 { 88 details::CreateOneToManyTableWithMap(connection, schemaVersion, TableInfo::TableName(), TableInfo::ValueName()); 89 } 90 91 // Drops the tables. 92 static void Drop(SQLite::Connection& connection) 93 { 94 details::DropOneToManyTableWithMap(connection, TableInfo::TableName()); 95 } 96 97 // Gets all values associated with the given primary id. 98 static std::vector<std::string> GetValuesByPrimaryId(const SQLite::Connection& connection, SQLite::rowid_t primaryId) 99 { 100 return details::OneToManyTableWithMapGetValuesByPrimaryId(connection, TableInfo::TableName(), TableInfo::ValueName(), primaryId); 101 } 102 103 // Ensures that all values exist in the data table, and inserts into the mapping table for the given primary id. 104 static void EnsureExistsAndInsert(SQLite::Connection& connection, const std::vector<std::string>& values, SQLite::rowid_t primaryId) 105 { 106 details::OneToManyTableWithMapEnsureExistsAndInsert(connection, TableInfo::TableName(), TableInfo::ValueName(), values, primaryId); 107 } 108 109 // Removes data that is no longer needed for an index that is to be published. 110 // Preserving the primary index will improve the efficiency of finding the values associated with a primary. 111 // Preserving the values index will improve searching when it is primarily done by equality. 112 static void PrepareForPackaging(SQLite::Connection& connection) 113 { 114 details::OneToManyTableWithMapPrepareForPackaging(connection, TableInfo::TableName()); 115 } 116 117 // Checks the consistency of the index to ensure that every referenced row exists. 118 // Returns true if index is consistent; false if it is not. 119 static bool CheckConsistency(const SQLite::Connection& connection, bool log) 120 { 121 return details::OneToManyTableWithMapCheckConsistency(connection, TableInfo::TableName(), TableInfo::ValueName(), log); 122 } 123 124 // Determines if the table is empty. 125 static bool IsEmpty(SQLite::Connection& connection) 126 { 127 return details::OneToManyTableWithMapIsEmpty(connection, TableInfo::TableName()); 128 } 129 130 // Builds the search select statement base on the given value. 131 // The return value is the bind index of the value to match against. 132 static int BuildSearchStatement(SQLite::Builder::StatementBuilder& builder, std::string_view primaryAlias, std::string_view valueAlias, bool useLike) 133 { 134 return details::OneToManyTableWithMapBuildSearchStatement(builder, TableInfo::TableName(), TableInfo::ValueName(), primaryAlias, valueAlias, useLike); 135 } 136 }; 137 }