CheckpointDataTable.cpp (9107B)
1 // Copyright (c) Microsoft Corporation. 2 // Licensed under the MIT License. 3 #include "pch.h" 4 #include "CheckpointDataTable.h" 5 #include <winget/SQLiteStatementBuilder.h> 6 7 namespace AppInstaller::Repository::Microsoft::Schema::Checkpoint_V1_0 8 { 9 using namespace SQLite; 10 using namespace std::string_view_literals; 11 static constexpr std::string_view s_CheckpointDataTable_Table_Name = "CheckpointData"sv; 12 static constexpr std::string_view s_CheckpointDataTable_CheckpointId_Column = "CheckpointId"sv; 13 static constexpr std::string_view s_CheckpointDataTable_ContextData_Column = "ContextData"sv; 14 static constexpr std::string_view s_CheckpointDataTable_Name_Column = "Name"sv; 15 static constexpr std::string_view s_CheckpointDataTable_Value_Column = "Value"sv; 16 static constexpr std::string_view s_CheckpointDataTable_Index_Column = "Index"sv; 17 18 namespace 19 { 20 SQLite::rowid_t SetNamedValue(SQLite::Connection& connection, std::string_view name, std::string_view value) 21 { 22 SQLite::Builder::StatementBuilder builder; 23 builder.InsertInto(s_CheckpointDataTable_Table_Name) 24 .Columns({ s_CheckpointDataTable_CheckpointId_Column, 25 s_CheckpointDataTable_ContextData_Column, 26 s_CheckpointDataTable_Name_Column, 27 s_CheckpointDataTable_Value_Column, 28 s_CheckpointDataTable_Index_Column}) 29 .Values(name, value); 30 31 builder.Execute(connection); 32 return connection.GetLastInsertRowID(); 33 } 34 35 std::string GetNamedValue(SQLite::Connection& connection, std::string_view name) 36 { 37 SQLite::Builder::StatementBuilder builder; 38 builder.Select({ s_CheckpointDataTable_Value_Column }) 39 .From(s_CheckpointDataTable_Table_Name).Where(s_CheckpointDataTable_Name_Column).Equals(name); 40 41 SQLite::Statement statement = builder.Prepare(connection); 42 THROW_HR_IF(E_NOT_SET, !statement.Step()); 43 return statement.GetColumn<std::string>(0); 44 } 45 } 46 47 std::string_view CheckpointDataTable::TableName() 48 { 49 return s_CheckpointDataTable_Table_Name; 50 } 51 52 void CheckpointDataTable::Create(SQLite::Connection& connection) 53 { 54 using namespace SQLite::Builder; 55 56 SQLite::Savepoint savepoint = SQLite::Savepoint::Create(connection, "createCheckpointDataTable_v1_0"); 57 58 StatementBuilder createTableBuilder; 59 createTableBuilder.CreateTable(s_CheckpointDataTable_Table_Name).BeginColumns(); 60 createTableBuilder.Column(ColumnBuilder(s_CheckpointDataTable_CheckpointId_Column, Type::Int).NotNull()); 61 createTableBuilder.Column(ColumnBuilder(s_CheckpointDataTable_ContextData_Column, Type::Int).NotNull()); 62 createTableBuilder.Column(ColumnBuilder(s_CheckpointDataTable_Name_Column, Type::Text).NotNull()); 63 createTableBuilder.Column(ColumnBuilder(s_CheckpointDataTable_Value_Column, Type::Text)); 64 createTableBuilder.Column(ColumnBuilder(s_CheckpointDataTable_Index_Column, Type::Int).NotNull()); 65 66 PrimaryKeyBuilder pkBuilder; 67 pkBuilder.Column(s_CheckpointDataTable_CheckpointId_Column); 68 pkBuilder.Column(s_CheckpointDataTable_ContextData_Column); 69 pkBuilder.Column(s_CheckpointDataTable_Name_Column); 70 pkBuilder.Column(s_CheckpointDataTable_Index_Column); 71 72 createTableBuilder.Column(pkBuilder).EndColumns(); 73 createTableBuilder.Execute(connection); 74 savepoint.Commit(); 75 } 76 77 bool CheckpointDataTable::IsEmpty(SQLite::Connection& connection) 78 { 79 SQLite::Builder::StatementBuilder builder; 80 builder.Select(SQLite::Builder::RowCount).From(s_CheckpointDataTable_Table_Name); 81 82 SQLite::Statement countStatement = builder.Prepare(connection); 83 84 THROW_HR_IF(E_UNEXPECTED, !countStatement.Step()); 85 86 return (countStatement.GetColumn<int>(0) == 0); 87 } 88 89 std::vector<int> CheckpointDataTable::GetAvailableData(SQLite::Connection& connection, SQLite::rowid_t checkpointId) 90 { 91 SQLite::Builder::StatementBuilder builder; 92 builder.Select(s_CheckpointDataTable_ContextData_Column).From(s_CheckpointDataTable_Table_Name).Where(s_CheckpointDataTable_CheckpointId_Column); 93 builder.Equals(checkpointId); 94 95 SQLite::Statement select = builder.Prepare(connection); 96 97 std::vector<int> availableData; 98 99 while (select.Step()) 100 { 101 availableData.emplace_back(select.GetColumn<int>(0)); 102 } 103 104 return availableData; 105 } 106 107 SQLite::rowid_t CheckpointDataTable::AddCheckpointData(SQLite::Connection& connection, SQLite::rowid_t checkpointId, int contextData, std::string_view name, std::string_view value, int index) 108 { 109 SQLite::Builder::StatementBuilder builder; 110 111 if (value.empty()) 112 { 113 builder.InsertInto(s_CheckpointDataTable_Table_Name) 114 .Columns({ s_CheckpointDataTable_CheckpointId_Column, 115 s_CheckpointDataTable_ContextData_Column, 116 s_CheckpointDataTable_Name_Column, 117 s_CheckpointDataTable_Index_Column }) 118 .Values(checkpointId, contextData, name, index); 119 } 120 else 121 { 122 builder.InsertInto(s_CheckpointDataTable_Table_Name) 123 .Columns({ s_CheckpointDataTable_CheckpointId_Column, 124 s_CheckpointDataTable_ContextData_Column, 125 s_CheckpointDataTable_Name_Column, 126 s_CheckpointDataTable_Value_Column, 127 s_CheckpointDataTable_Index_Column }) 128 .Values(checkpointId, contextData, name, value, index); 129 } 130 131 builder.Execute(connection); 132 return connection.GetLastInsertRowID(); 133 } 134 135 bool CheckpointDataTable::HasDataField(SQLite::Connection& connection, SQLite::rowid_t checkpointId, int type, std::string_view name) 136 { 137 SQLite::Builder::StatementBuilder builder; 138 builder.Select(SQLite::Builder::RowCount).From(s_CheckpointDataTable_Table_Name).Where(s_CheckpointDataTable_CheckpointId_Column); 139 builder.Equals(checkpointId).And(s_CheckpointDataTable_ContextData_Column).Equals(type).And(s_CheckpointDataTable_Name_Column).Equals(name); 140 141 SQLite::Statement countStatement = builder.Prepare(connection); 142 143 THROW_HR_IF(E_UNEXPECTED, !countStatement.Step()); 144 145 return (countStatement.GetColumn<int>(0) == 0); 146 } 147 148 std::vector<std::string> CheckpointDataTable::GetDataFields(SQLite::Connection& connection, SQLite::rowid_t checkpointId, int type) 149 { 150 SQLite::Builder::StatementBuilder builder; 151 builder.Select(s_CheckpointDataTable_Name_Column).From(s_CheckpointDataTable_Table_Name).Where(s_CheckpointDataTable_CheckpointId_Column); 152 builder.Equals(checkpointId).And(s_CheckpointDataTable_ContextData_Column).Equals(type); 153 154 SQLite::Statement select = builder.Prepare(connection); 155 156 std::vector<std::string> fields; 157 158 while (select.Step()) 159 { 160 fields.emplace_back(select.GetColumn<std::string>(0)); 161 } 162 163 return fields; 164 } 165 166 std::vector<std::string> CheckpointDataTable::GetDataValuesByFieldName(SQLite::Connection& connection, SQLite::rowid_t checkpointId, int contextData, std::string_view name) 167 { 168 SQLite::Builder::StatementBuilder builder; 169 builder.Select(s_CheckpointDataTable_Value_Column).From(s_CheckpointDataTable_Table_Name).Where(s_CheckpointDataTable_CheckpointId_Column); 170 builder.Equals(checkpointId).And(s_CheckpointDataTable_ContextData_Column).Equals(contextData).And(s_CheckpointDataTable_Name_Column).Equals(name); 171 172 SQLite::Statement select = builder.Prepare(connection); 173 174 std::vector<std::string> values; 175 176 while (select.Step()) 177 { 178 values.emplace_back(select.GetColumn<std::string>(0)); 179 } 180 181 return values; 182 } 183 184 std::string CheckpointDataTable::GetDataValue(SQLite::Connection& connection, SQLite::rowid_t checkpointId, int type) 185 { 186 SQLite::Builder::StatementBuilder builder; 187 builder.Select(s_CheckpointDataTable_Value_Column).From(s_CheckpointDataTable_Table_Name).Where(s_CheckpointDataTable_CheckpointId_Column); 188 builder.Equals(checkpointId).And(s_CheckpointDataTable_ContextData_Column).Equals(type); 189 190 SQLite::Statement select = builder.Prepare(connection); 191 192 if (select.Step()) 193 { 194 return select.GetColumn<std::string>(0); 195 } 196 else 197 { 198 return {}; 199 } 200 } 201 202 void CheckpointDataTable::RemoveDataType(SQLite::Connection& connection, SQLite::rowid_t checkpointId, int contextData) 203 { 204 SQLite::Builder::StatementBuilder builder; 205 builder.DeleteFrom(s_CheckpointDataTable_Table_Name).Where(s_CheckpointDataTable_CheckpointId_Column).Equals(checkpointId) 206 .And(s_CheckpointDataTable_ContextData_Column).Equals(contextData); 207 builder.Execute(connection); 208 } 209 }