Mercurial > hg > orthanc
comparison OrthancServer/Sources/Database/SQLiteDatabaseWrapper.cpp @ 5568:b0b5546f1b9f find-refactoring
find refactor: re-use existing code. /studies?expand is almost fully implemented with new code
author | Alain Mazy <am@orthanc.team> |
---|---|
date | Thu, 25 Apr 2024 09:22:07 +0200 |
parents | f3562c1a150d |
children | 5a13483d12c5 |
comparison
equal
deleted
inserted
replaced
5567:f3562c1a150d | 5568:b0b5546f1b9f |
---|---|
1139 } | 1139 } |
1140 } | 1140 } |
1141 | 1141 |
1142 | 1142 |
1143 virtual void ExecuteFind(FindResponse& response, | 1143 virtual void ExecuteFind(FindResponse& response, |
1144 const FindRequest& request) ORTHANC_OVERRIDE | 1144 const FindRequest& request, |
1145 { | 1145 const std::vector<DatabaseConstraint>& normalized) ORTHANC_OVERRIDE |
1146 #if 1 | 1146 { |
1147 #if 0 | |
1147 Compatibility::GenericFind find(*this); | 1148 Compatibility::GenericFind find(*this); |
1148 find.Execute(response, request); | 1149 find.Execute(response, request); |
1149 #else | 1150 #else |
1150 { | 1151 { |
1151 SQLite::Statement s(db_, SQLITE_FROM_HERE, "DROP TABLE IF EXISTS FilteredResourcesIds"); | 1152 SQLite::Statement s(db_, SQLITE_FROM_HERE, "DROP TABLE IF EXISTS FilteredResourcesIds"); |
1152 s.Run(); | 1153 s.Run(); |
1153 } | 1154 } |
1154 | 1155 |
1155 { | 1156 { |
1156 std::string sql; | 1157 |
1157 // sql = "CREATE TEMPORARY TABLE FilteredResourcesIds AS "; | 1158 LookupFormatter formatter; |
1158 sql = ".."; | 1159 |
1159 SQLite::Statement s(db_, SQLITE_FROM_HERE_DYNAMIC(sql), sql); | 1160 std::string sqlLookup; |
1160 } | 1161 LookupFormatter::Apply(sqlLookup, |
1162 formatter, | |
1163 normalized, | |
1164 request.GetLevel(), | |
1165 request.GetLabels(), | |
1166 request.GetLabelsConstraint(), | |
1167 (request.HasLimits() ? request.GetLimitsCount() : 0)); // TODO: handles since and count | |
1168 | |
1169 if (request.IsResponseIdentifiersOnly()) | |
1170 { | |
1171 SQLite::Statement statement(db_, SQLITE_FROM_HERE_DYNAMIC(sqlLookup), sqlLookup); | |
1172 formatter.Bind(statement); | |
1173 | |
1174 while (statement.Step()) | |
1175 { | |
1176 FindResponse::Item* item = new FindResponse::Item(request.GetResponseContent(), | |
1177 request.GetLevel(), | |
1178 statement.ColumnString(0)); | |
1179 response.Add(item); | |
1180 } | |
1181 } | |
1182 else | |
1183 { | |
1184 std::map<std::string, FindResponse::Item*> items; // cache to the response items | |
1185 | |
1186 {// first create a temporary table that with the filtered and ordered results | |
1187 sqlLookup = "CREATE TEMPORARY TABLE FilteredResourcesIds AS " + sqlLookup; | |
1188 | |
1189 SQLite::Statement statement(db_, SQLITE_FROM_HERE_DYNAMIC(sqlLookup), sqlLookup); | |
1190 formatter.Bind(statement); | |
1191 statement.Run(); | |
1192 } | |
1193 | |
1194 { | |
1195 // create the response item with the public ids only | |
1196 SQLite::Statement statement(db_, SQLITE_FROM_HERE, "SELECT publicId FROM FilteredResourcesIds"); | |
1197 formatter.Bind(statement); | |
1198 | |
1199 while (statement.Step()) | |
1200 { | |
1201 const std::string& resourceId = statement.ColumnString(0); | |
1202 FindResponse::Item* item = new FindResponse::Item(request.GetResponseContent(), | |
1203 request.GetLevel(), | |
1204 resourceId); | |
1205 items[resourceId] = item; | |
1206 response.Add(item); | |
1207 } | |
1208 } | |
1209 | |
1210 // request Each response content through INNER JOIN with the temporary table | |
1211 if (request.HasResponseContent(FindRequest::ResponseContent_MainDicomTags)) | |
1212 { | |
1213 // TODO-FIND: handle the case where we request tags from multiple levels | |
1214 SQLite::Statement statement(db_, SQLITE_FROM_HERE, | |
1215 "SELECT publicId, tagGroup, tagElement, value FROM MainDicomTags AS tags " | |
1216 " INNER JOIN FilteredResourcesIds ON tags.id = FilteredResourcesIds.internalId"); | |
1217 formatter.Bind(statement); | |
1218 | |
1219 while (statement.Step()) | |
1220 { | |
1221 const std::string& resourceId = statement.ColumnString(0); | |
1222 items[resourceId]->AddDicomTag(statement.ColumnInt(1), | |
1223 statement.ColumnInt(2), | |
1224 statement.ColumnString(3), false); | |
1225 } | |
1226 } | |
1227 | |
1228 if (request.HasResponseContent(FindRequest::ResponseContent_Children)) | |
1229 { | |
1230 SQLite::Statement statement(db_, SQLITE_FROM_HERE, | |
1231 "SELECT filtered.publicId, childLevel.publicId AS childPublicId " | |
1232 "FROM Resources as currentLevel " | |
1233 " INNER JOIN FilteredResourcesIds filtered ON filtered.internalId = currentLevel.internalId " | |
1234 " INNER JOIN Resources childLevel ON childLevel.parentId = currentLevel.internalId"); | |
1235 formatter.Bind(statement); | |
1236 | |
1237 while (statement.Step()) | |
1238 { | |
1239 const std::string& resourceId = statement.ColumnString(0); | |
1240 items[resourceId]->AddChild(statement.ColumnString(1)); | |
1241 } | |
1242 } | |
1243 | |
1244 if (request.HasResponseContent(FindRequest::ResponseContent_Parent)) | |
1245 { | |
1246 SQLite::Statement statement(db_, SQLITE_FROM_HERE, | |
1247 "SELECT filtered.publicId, parentLevel.publicId AS parentPublicId " | |
1248 "FROM Resources as currentLevel " | |
1249 " INNER JOIN FilteredResourcesIds filtered ON filtered.internalId = currentLevel.internalId " | |
1250 " INNER JOIN Resources parentLevel ON currentLevel.parentId = parentLevel.internalId"); | |
1251 | |
1252 while (statement.Step()) | |
1253 { | |
1254 const std::string& resourceId = statement.ColumnString(0); | |
1255 items[resourceId]->SetParent(statement.ColumnString(1)); | |
1256 } | |
1257 } | |
1258 | |
1259 if (request.HasResponseContent(FindRequest::ResponseContent_Metadata)) | |
1260 { | |
1261 SQLite::Statement statement(db_, SQLITE_FROM_HERE, | |
1262 "SELECT filtered.publicId, metadata.type, metadata.value " | |
1263 "FROM Metadata " | |
1264 " INNER JOIN FilteredResourcesIds filtered ON filtered.internalId = Metadata.id"); | |
1265 | |
1266 while (statement.Step()) | |
1267 { | |
1268 const std::string& resourceId = statement.ColumnString(0); | |
1269 items[resourceId]->AddMetadata(static_cast<MetadataType>(statement.ColumnInt(1)), | |
1270 statement.ColumnString(2)); | |
1271 } | |
1272 } | |
1273 | |
1274 if (request.HasResponseContent(FindRequest::ResponseContent_Labels)) | |
1275 { | |
1276 SQLite::Statement statement(db_, SQLITE_FROM_HERE, | |
1277 "SELECT filtered.publicId, label " | |
1278 "FROM Labels " | |
1279 " INNER JOIN FilteredResourcesIds filtered ON filtered.internalId = Labels.id"); | |
1280 | |
1281 while (statement.Step()) | |
1282 { | |
1283 const std::string& resourceId = statement.ColumnString(0); | |
1284 items[resourceId]->AddLabel(statement.ColumnString(1)); | |
1285 } | |
1286 } | |
1287 | |
1288 // TODO-FIND: implement other responseContent: ResponseContent_ChildInstanceId, ResponseContent_Attachments, (later: ResponseContent_IsStable) | |
1289 | |
1290 } | |
1291 } | |
1292 | |
1161 #endif | 1293 #endif |
1162 } | 1294 } |
1163 }; | 1295 }; |
1164 | 1296 |
1165 | 1297 |