Mercurial > hg > orthanc
comparison OrthancServer/SQLiteDatabaseWrapper.cpp @ 3025:039a9d262d64 db-changes
preparing to speed up find in databases
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 17 Dec 2018 17:05:28 +0100 |
parents | d207f6ac1f86 |
children | fd587cf51a89 |
comparison
equal
deleted
inserted
replaced
3024:ef17a587e10d | 3025:039a9d262d64 |
---|---|
52 private: | 52 private: |
53 IDatabaseListener& listener_; | 53 IDatabaseListener& listener_; |
54 | 54 |
55 public: | 55 public: |
56 SignalFileDeleted(IDatabaseListener& listener) : | 56 SignalFileDeleted(IDatabaseListener& listener) : |
57 listener_(listener) | 57 listener_(listener) |
58 { | 58 { |
59 } | 59 } |
60 | 60 |
61 virtual const char* GetName() const | 61 virtual const char* GetName() const |
62 { | 62 { |
99 private: | 99 private: |
100 IDatabaseListener& listener_; | 100 IDatabaseListener& listener_; |
101 | 101 |
102 public: | 102 public: |
103 SignalResourceDeleted(IDatabaseListener& listener) : | 103 SignalResourceDeleted(IDatabaseListener& listener) : |
104 listener_(listener) | 104 listener_(listener) |
105 { | 105 { |
106 } | 106 } |
107 | 107 |
108 virtual const char* GetName() const | 108 virtual const char* GetName() const |
109 { | 109 { |
1199 | 1199 |
1200 bool SQLiteDatabaseWrapper::IsDiskSizeAbove(uint64_t threshold) | 1200 bool SQLiteDatabaseWrapper::IsDiskSizeAbove(uint64_t threshold) |
1201 { | 1201 { |
1202 return GetTotalCompressedSize() > threshold; | 1202 return GetTotalCompressedSize() > threshold; |
1203 } | 1203 } |
1204 | |
1205 | |
1206 namespace | |
1207 { | |
1208 class MainDicomTagsRegistry : public boost::noncopyable | |
1209 { | |
1210 private: | |
1211 class TagInfo | |
1212 { | |
1213 private: | |
1214 ResourceType level_; | |
1215 DicomTagType type_; | |
1216 | |
1217 public: | |
1218 TagInfo() | |
1219 { | |
1220 } | |
1221 | |
1222 TagInfo(ResourceType level, | |
1223 DicomTagType type) : | |
1224 level_(level), | |
1225 type_(type) | |
1226 { | |
1227 } | |
1228 | |
1229 ResourceType GetLevel() const | |
1230 { | |
1231 return level_; | |
1232 } | |
1233 | |
1234 DicomTagType GetType() const | |
1235 { | |
1236 return type_; | |
1237 } | |
1238 }; | |
1239 | |
1240 typedef std::map<DicomTag, TagInfo> Registry; | |
1241 | |
1242 | |
1243 Registry registry_; | |
1244 | |
1245 void LoadTags(ResourceType level) | |
1246 { | |
1247 const DicomTag* tags = NULL; | |
1248 size_t size; | |
1249 | |
1250 ServerToolbox::LoadIdentifiers(tags, size, level); | |
1251 | |
1252 for (size_t i = 0; i < size; i++) | |
1253 { | |
1254 if (registry_.find(tags[i]) == registry_.end()) | |
1255 { | |
1256 registry_[tags[i]] = TagInfo(level, DicomTagType_Identifier); | |
1257 } | |
1258 else | |
1259 { | |
1260 // These patient-level tags are copied in the study level | |
1261 assert(level == ResourceType_Study && | |
1262 (tags[i] == DICOM_TAG_PATIENT_ID || | |
1263 tags[i] == DICOM_TAG_PATIENT_NAME || | |
1264 tags[i] == DICOM_TAG_PATIENT_BIRTH_DATE)); | |
1265 } | |
1266 } | |
1267 | |
1268 DicomMap::LoadMainDicomTags(tags, size, level); | |
1269 | |
1270 for (size_t i = 0; i < size; i++) | |
1271 { | |
1272 if (registry_.find(tags[i]) == registry_.end()) | |
1273 { | |
1274 registry_[tags[i]] = TagInfo(level, DicomTagType_Main); | |
1275 } | |
1276 } | |
1277 } | |
1278 | |
1279 public: | |
1280 MainDicomTagsRegistry() | |
1281 { | |
1282 LoadTags(ResourceType_Patient); | |
1283 LoadTags(ResourceType_Study); | |
1284 LoadTags(ResourceType_Series); | |
1285 LoadTags(ResourceType_Instance); | |
1286 } | |
1287 | |
1288 void LookupTag(ResourceType& level, | |
1289 DicomTagType& type, | |
1290 const DicomTag& tag) const | |
1291 { | |
1292 Registry::const_iterator it = registry_.find(tag); | |
1293 | |
1294 if (it == registry_.end()) | |
1295 { | |
1296 // Default values | |
1297 level = ResourceType_Instance; | |
1298 type = DicomTagType_Generic; | |
1299 } | |
1300 else | |
1301 { | |
1302 level = it->second.GetLevel(); | |
1303 type = it->second.GetType(); | |
1304 } | |
1305 } | |
1306 }; | |
1307 } | |
1308 | |
1309 | |
1310 void SQLiteDatabaseWrapper::FindOneChildInstance(std::vector<std::string>& instancesId, | |
1311 const std::vector<std::string>& resourcesId, | |
1312 ResourceType level) | |
1313 { | |
1314 printf("ICI 3\n"); | |
1315 | |
1316 throw OrthancException(ErrorCode_NotImplemented); | |
1317 } | |
1318 | |
1319 | |
1320 void SQLiteDatabaseWrapper::ApplyLookupPatients(std::vector<std::string>& patientsId, | |
1321 const DatabaseLookup& lookup, | |
1322 size_t limit) | |
1323 { | |
1324 static const MainDicomTagsRegistry registry; | |
1325 | |
1326 printf("ICI 1\n"); | |
1327 | |
1328 std::string heading = "SELECT patient.publicId FROM Resources AS patient "; | |
1329 std::string trailer; | |
1330 std::vector<std::string> parameters; | |
1331 | |
1332 for (size_t i = 0; i < lookup.GetConstraintsCount(); i++) | |
1333 { | |
1334 const DicomTagConstraint& constraint = lookup.GetConstraint(i); | |
1335 | |
1336 ResourceType level; | |
1337 DicomTagType type; | |
1338 registry.LookupTag(level, type, constraint.GetTag()); | |
1339 | |
1340 if (level != ResourceType_Patient) | |
1341 { | |
1342 throw OrthancException(ErrorCode_ParameterOutOfRange, | |
1343 "Not a patient-level tag: (" + | |
1344 lookup.GetConstraint(i).GetTag().Format() + ")"); | |
1345 } | |
1346 | |
1347 if (type == DicomTagType_Identifier || | |
1348 type == DicomTagType_Main) | |
1349 { | |
1350 std::string table = (type == DicomTagType_Identifier ? "DicomIdentifiers" : "MainDicomTags"); | |
1351 std::string tag = "t" + boost::lexical_cast<std::string>(i); | |
1352 | |
1353 char on[128]; | |
1354 sprintf(on, " %s ON %s.id = patient.internalId AND %s.tagGroup = 0x%04x AND %s.tagElement = 0x%04x ", | |
1355 tag.c_str(), tag.c_str(), tag.c_str(), constraint.GetTag().GetGroup(), | |
1356 tag.c_str(), constraint.GetTag().GetElement()); | |
1357 | |
1358 if (constraint.IsMandatory()) | |
1359 { | |
1360 heading += "INNER JOIN " + table + std::string(on); | |
1361 } | |
1362 else | |
1363 { | |
1364 heading += "LEFT JOIN " + table + std::string(on); | |
1365 } | |
1366 | |
1367 trailer += "AND ("; | |
1368 | |
1369 if (!constraint.IsMandatory()) | |
1370 { | |
1371 trailer += tag + ".value IS NULL OR "; | |
1372 } | |
1373 | |
1374 if (constraint.IsCaseSensitive()) | |
1375 { | |
1376 trailer += tag + ".value "; | |
1377 } | |
1378 else | |
1379 { | |
1380 trailer += "lower(" + tag + ".value) "; | |
1381 } | |
1382 | |
1383 switch (constraint.GetType()) | |
1384 { | |
1385 case ConstraintType_Equal: | |
1386 parameters.push_back(constraint.GetValue()); | |
1387 | |
1388 if (constraint.IsCaseSensitive()) | |
1389 { | |
1390 trailer += "= ?"; | |
1391 } | |
1392 else | |
1393 { | |
1394 trailer += "= lower(?)"; | |
1395 } | |
1396 | |
1397 break; | |
1398 | |
1399 default: | |
1400 throw OrthancException(ErrorCode_NotImplemented); | |
1401 } | |
1402 | |
1403 trailer += ") "; | |
1404 } | |
1405 } | |
1406 | |
1407 if (limit != 0) | |
1408 { | |
1409 trailer += " LIMIT " + boost::lexical_cast<std::string>(limit); | |
1410 } | |
1411 | |
1412 std::string sql = (heading + "WHERE patient.resourceType = " + | |
1413 boost::lexical_cast<std::string>(ResourceType_Patient) + " " + trailer); | |
1414 | |
1415 SQLite::Statement s(db_, sql); | |
1416 | |
1417 printf("[%s]\n", sql.c_str()); | |
1418 | |
1419 for (size_t i = 0; i < parameters.size(); i++) | |
1420 { | |
1421 printf(" %d = '%s'\n", i, parameters[i].c_str()); | |
1422 s.BindString(i, parameters[i]); | |
1423 } | |
1424 | |
1425 patientsId.clear(); | |
1426 | |
1427 while (s.Step()) | |
1428 { | |
1429 std::string publicId = s.ColumnString(0); | |
1430 patientsId.push_back(publicId); | |
1431 printf("** [%s]\n", publicId.c_str()); | |
1432 } | |
1433 | |
1434 throw OrthancException(ErrorCode_NotImplemented); | |
1435 } | |
1436 | |
1437 | |
1438 void SQLiteDatabaseWrapper::ApplyLookupResources(std::vector<std::string>& resourcesId, | |
1439 const DatabaseLookup& lookup, | |
1440 ResourceType queryLevel, | |
1441 size_t limit) | |
1442 { | |
1443 printf("ICI 2\n"); | |
1444 | |
1445 throw OrthancException(ErrorCode_NotImplemented); | |
1446 } | |
1204 } | 1447 } |