comparison OrthancServer/Sources/ServerIndex.cpp @ 4564:5a0adc1c19a9 db-changes

avoid copy of objects in ServerIndex
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 08 Mar 2021 11:08:03 +0100
parents bb1c365f9e44
children 3495a3d97ab6
comparison
equal deleted inserted replaced
4563:bb1c365f9e44 4564:5a0adc1c19a9
2049 2049
2050 bool ServerIndex::ExpandResource(Json::Value& target, 2050 bool ServerIndex::ExpandResource(Json::Value& target,
2051 const std::string& publicId, 2051 const std::string& publicId,
2052 ResourceType level) 2052 ResourceType level)
2053 { 2053 {
2054 class Operations : public ReadOnlyOperationsT4<bool*, Json::Value*, std::string, ResourceType> 2054 class Operations : public ReadOnlyOperationsT4<bool&, Json::Value&, const std::string&, ResourceType>
2055 { 2055 {
2056 private: 2056 private:
2057 ServerIndex& index_; 2057 ServerIndex& index_;
2058 2058
2059 public: 2059 public:
2070 ResourceType type; 2070 ResourceType type;
2071 std::string parent; 2071 std::string parent;
2072 if (!transaction.LookupResourceAndParent(internalId, type, parent, tuple.get<2>()) || 2072 if (!transaction.LookupResourceAndParent(internalId, type, parent, tuple.get<2>()) ||
2073 type != tuple.get<3>()) 2073 type != tuple.get<3>())
2074 { 2074 {
2075 *tuple.get<0>() = false; 2075 tuple.get<0>() = false;
2076 } 2076 }
2077 else 2077 else
2078 { 2078 {
2079 Json::Value& target = *tuple.get<1>(); 2079 Json::Value& target = tuple.get<1>();
2080 target = Json::objectValue; 2080 target = Json::objectValue;
2081 2081
2082 // Set information about the parent resource (if it exists) 2082 // Set information about the parent resource (if it exists)
2083 if (type == ResourceType_Patient) 2083 if (type == ResourceType_Patient)
2084 { 2084 {
2236 { 2236 {
2237 target["LastUpdate"] = tmp; 2237 target["LastUpdate"] = tmp;
2238 } 2238 }
2239 } 2239 }
2240 2240
2241 *tuple.get<0>() = true; 2241 tuple.get<0>() = true;
2242 } 2242 }
2243 } 2243 }
2244 }; 2244 };
2245 2245
2246 bool found; 2246 bool found;
2247 Operations operations(*this); 2247 Operations operations(*this);
2248 operations.Apply(*this, &found, &target, publicId, level); 2248 operations.Apply(*this, found, target, publicId, level);
2249 return found; 2249 return found;
2250 } 2250 }
2251 2251
2252 2252
2253 void ServerIndex::GetAllMetadata(std::map<MetadataType, std::string>& target, 2253 void ServerIndex::GetAllMetadata(std::map<MetadataType, std::string>& target,
2254 const std::string& publicId, 2254 const std::string& publicId,
2255 ResourceType level) 2255 ResourceType level)
2256 { 2256 {
2257 class Operations : public ReadOnlyOperationsT3<std::map<MetadataType, std::string>*, std::string, ResourceType> 2257 class Operations : public ReadOnlyOperationsT3<std::map<MetadataType, std::string>&, const std::string&, ResourceType>
2258 { 2258 {
2259 public: 2259 public:
2260 virtual void ApplyTuple(ReadOnlyTransaction& transaction, 2260 virtual void ApplyTuple(ReadOnlyTransaction& transaction,
2261 const Tuple& tuple) ORTHANC_OVERRIDE 2261 const Tuple& tuple) ORTHANC_OVERRIDE
2262 { 2262 {
2267 { 2267 {
2268 throw OrthancException(ErrorCode_UnknownResource); 2268 throw OrthancException(ErrorCode_UnknownResource);
2269 } 2269 }
2270 else 2270 else
2271 { 2271 {
2272 transaction.GetAllMetadata(*tuple.get<0>(), id); 2272 transaction.GetAllMetadata(tuple.get<0>(), id);
2273 } 2273 }
2274 } 2274 }
2275 }; 2275 };
2276 2276
2277 Operations operations; 2277 Operations operations;
2278 operations.Apply(*this, &target, publicId, level); 2278 operations.Apply(*this, target, publicId, level);
2279 } 2279 }
2280 2280
2281 2281
2282 bool ServerIndex::LookupAttachment(FileInfo& attachment, 2282 bool ServerIndex::LookupAttachment(FileInfo& attachment,
2283 const std::string& instancePublicId, 2283 const std::string& instancePublicId,
2284 FileContentType contentType) 2284 FileContentType contentType)
2285 { 2285 {
2286 class Operations : public ReadOnlyOperationsT4<bool*, FileInfo*, std::string, FileContentType> 2286 class Operations : public ReadOnlyOperationsT4<bool&, FileInfo&, const std::string&, FileContentType>
2287 { 2287 {
2288 public: 2288 public:
2289 virtual void ApplyTuple(ReadOnlyTransaction& transaction, 2289 virtual void ApplyTuple(ReadOnlyTransaction& transaction,
2290 const Tuple& tuple) ORTHANC_OVERRIDE 2290 const Tuple& tuple) ORTHANC_OVERRIDE
2291 { 2291 {
2293 ResourceType type; 2293 ResourceType type;
2294 if (!transaction.LookupResource(internalId, type, tuple.get<2>())) 2294 if (!transaction.LookupResource(internalId, type, tuple.get<2>()))
2295 { 2295 {
2296 throw OrthancException(ErrorCode_UnknownResource); 2296 throw OrthancException(ErrorCode_UnknownResource);
2297 } 2297 }
2298 else if (transaction.LookupAttachment(*tuple.get<1>(), internalId, tuple.get<3>())) 2298 else if (transaction.LookupAttachment(tuple.get<1>(), internalId, tuple.get<3>()))
2299 { 2299 {
2300 assert(tuple.get<1>()->GetContentType() == tuple.get<3>()); 2300 assert(tuple.get<1>().GetContentType() == tuple.get<3>());
2301 *tuple.get<0>() = true; 2301 tuple.get<0>() = true;
2302 } 2302 }
2303 else 2303 else
2304 { 2304 {
2305 *tuple.get<0>() = false; 2305 tuple.get<0>() = false;
2306 } 2306 }
2307 } 2307 }
2308 }; 2308 };
2309 2309
2310 bool found; 2310 bool found;
2311 Operations operations; 2311 Operations operations;
2312 operations.Apply(*this, &found, &attachment, instancePublicId, contentType); 2312 operations.Apply(*this, found, attachment, instancePublicId, contentType);
2313 return found; 2313 return found;
2314 } 2314 }
2315 2315
2316 2316
2317 void ServerIndex::GetAllUuids(std::list<std::string>& target, 2317 void ServerIndex::GetAllUuids(std::list<std::string>& target,
2318 ResourceType resourceType) 2318 ResourceType resourceType)
2319 { 2319 {
2320 class Operations : public ReadOnlyOperationsT2<std::list<std::string>*, ResourceType> 2320 class Operations : public ReadOnlyOperationsT2<std::list<std::string>&, ResourceType>
2321 { 2321 {
2322 public: 2322 public:
2323 virtual void ApplyTuple(ReadOnlyTransaction& transaction, 2323 virtual void ApplyTuple(ReadOnlyTransaction& transaction,
2324 const Tuple& tuple) ORTHANC_OVERRIDE 2324 const Tuple& tuple) ORTHANC_OVERRIDE
2325 { 2325 {
2326 // TODO - CANDIDATE FOR "TransactionType_SingleStatement" 2326 // TODO - CANDIDATE FOR "TransactionType_SingleStatement"
2327 transaction.GetAllPublicIds(*tuple.get<0>(), tuple.get<1>()); 2327 transaction.GetAllPublicIds(tuple.get<0>(), tuple.get<1>());
2328 } 2328 }
2329 }; 2329 };
2330 2330
2331 Operations operations; 2331 Operations operations;
2332 operations.Apply(*this, &target, resourceType); 2332 operations.Apply(*this, target, resourceType);
2333 } 2333 }
2334 2334
2335 2335
2336 void ServerIndex::GetAllUuids(std::list<std::string>& target, 2336 void ServerIndex::GetAllUuids(std::list<std::string>& target,
2337 ResourceType resourceType, 2337 ResourceType resourceType,
2342 { 2342 {
2343 target.clear(); 2343 target.clear();
2344 } 2344 }
2345 else 2345 else
2346 { 2346 {
2347 class Operations : public ReadOnlyOperationsT4<std::list<std::string>*, ResourceType, size_t, size_t> 2347 class Operations : public ReadOnlyOperationsT4<std::list<std::string>&, ResourceType, size_t, size_t>
2348 { 2348 {
2349 public: 2349 public:
2350 virtual void ApplyTuple(ReadOnlyTransaction& transaction, 2350 virtual void ApplyTuple(ReadOnlyTransaction& transaction,
2351 const Tuple& tuple) ORTHANC_OVERRIDE 2351 const Tuple& tuple) ORTHANC_OVERRIDE
2352 { 2352 {
2353 // TODO - CANDIDATE FOR "TransactionType_SingleStatement" 2353 // TODO - CANDIDATE FOR "TransactionType_SingleStatement"
2354 transaction.GetAllPublicIds(*tuple.get<0>(), tuple.get<1>(), tuple.get<2>(), tuple.get<3>()); 2354 transaction.GetAllPublicIds(tuple.get<0>(), tuple.get<1>(), tuple.get<2>(), tuple.get<3>());
2355 } 2355 }
2356 }; 2356 };
2357 2357
2358 Operations operations; 2358 Operations operations;
2359 operations.Apply(*this, &target, resourceType, since, limit); 2359 operations.Apply(*this, target, resourceType, since, limit);
2360 } 2360 }
2361 } 2361 }
2362 2362
2363 2363
2364 void ServerIndex::GetGlobalStatistics(/* out */ uint64_t& diskSize, 2364 void ServerIndex::GetGlobalStatistics(/* out */ uint64_t& diskSize,
2366 /* out */ uint64_t& countPatients, 2366 /* out */ uint64_t& countPatients,
2367 /* out */ uint64_t& countStudies, 2367 /* out */ uint64_t& countStudies,
2368 /* out */ uint64_t& countSeries, 2368 /* out */ uint64_t& countSeries,
2369 /* out */ uint64_t& countInstances) 2369 /* out */ uint64_t& countInstances)
2370 { 2370 {
2371 class Operations : public ReadOnlyOperationsT6<uint64_t*, uint64_t*, uint64_t*, uint64_t*, uint64_t*, uint64_t*> 2371 class Operations : public ReadOnlyOperationsT6<uint64_t&, uint64_t&, uint64_t&, uint64_t&, uint64_t&, uint64_t&>
2372 { 2372 {
2373 public: 2373 public:
2374 virtual void ApplyTuple(ReadOnlyTransaction& transaction, 2374 virtual void ApplyTuple(ReadOnlyTransaction& transaction,
2375 const Tuple& tuple) ORTHANC_OVERRIDE 2375 const Tuple& tuple) ORTHANC_OVERRIDE
2376 { 2376 {
2377 *tuple.get<0>() = transaction.GetTotalCompressedSize(); 2377 tuple.get<0>() = transaction.GetTotalCompressedSize();
2378 *tuple.get<1>() = transaction.GetTotalUncompressedSize(); 2378 tuple.get<1>() = transaction.GetTotalUncompressedSize();
2379 *tuple.get<2>() = transaction.GetResourceCount(ResourceType_Patient); 2379 tuple.get<2>() = transaction.GetResourceCount(ResourceType_Patient);
2380 *tuple.get<3>() = transaction.GetResourceCount(ResourceType_Study); 2380 tuple.get<3>() = transaction.GetResourceCount(ResourceType_Study);
2381 *tuple.get<4>() = transaction.GetResourceCount(ResourceType_Series); 2381 tuple.get<4>() = transaction.GetResourceCount(ResourceType_Series);
2382 *tuple.get<5>() = transaction.GetResourceCount(ResourceType_Instance); 2382 tuple.get<5>() = transaction.GetResourceCount(ResourceType_Instance);
2383 } 2383 }
2384 }; 2384 };
2385 2385
2386 Operations operations; 2386 Operations operations;
2387 operations.Apply(*this, &diskSize, &uncompressedSize, &countPatients, 2387 operations.Apply(*this, diskSize, uncompressedSize, countPatients,
2388 &countStudies, &countSeries, &countInstances); 2388 countStudies, countSeries, countInstances);
2389 } 2389 }
2390 2390
2391 2391
2392 void ServerIndex::GetChanges(Json::Value& target, 2392 void ServerIndex::GetChanges(Json::Value& target,
2393 int64_t since, 2393 int64_t since,
2394 unsigned int maxResults) 2394 unsigned int maxResults)
2395 { 2395 {
2396 class Operations : public ReadOnlyOperationsT3<Json::Value*, int64_t, unsigned int> 2396 class Operations : public ReadOnlyOperationsT3<Json::Value&, int64_t, unsigned int>
2397 { 2397 {
2398 public: 2398 public:
2399 virtual void ApplyTuple(ReadOnlyTransaction& transaction, 2399 virtual void ApplyTuple(ReadOnlyTransaction& transaction,
2400 const Tuple& tuple) ORTHANC_OVERRIDE 2400 const Tuple& tuple) ORTHANC_OVERRIDE
2401 { 2401 {
2412 { 2412 {
2413 last = transaction.GetLastChangeIndex(); 2413 last = transaction.GetLastChangeIndex();
2414 hasLast = true; 2414 hasLast = true;
2415 } 2415 }
2416 2416
2417 FormatLog(*tuple.get<0>(), changes, "Changes", done, tuple.get<1>(), hasLast, last); 2417 FormatLog(tuple.get<0>(), changes, "Changes", done, tuple.get<1>(), hasLast, last);
2418 } 2418 }
2419 }; 2419 };
2420 2420
2421 Operations operations; 2421 Operations operations;
2422 operations.Apply(*this, &target, since, maxResults); 2422 operations.Apply(*this, target, since, maxResults);
2423 } 2423 }
2424 2424
2425 2425
2426 void ServerIndex::GetLastChange(Json::Value& target) 2426 void ServerIndex::GetLastChange(Json::Value& target)
2427 { 2427 {
2428 class Operations : public ReadOnlyOperationsT1<Json::Value*> 2428 class Operations : public ReadOnlyOperationsT1<Json::Value&>
2429 { 2429 {
2430 public: 2430 public:
2431 virtual void ApplyTuple(ReadOnlyTransaction& transaction, 2431 virtual void ApplyTuple(ReadOnlyTransaction& transaction,
2432 const Tuple& tuple) ORTHANC_OVERRIDE 2432 const Tuple& tuple) ORTHANC_OVERRIDE
2433 { 2433 {
2443 { 2443 {
2444 last = transaction.GetLastChangeIndex(); 2444 last = transaction.GetLastChangeIndex();
2445 hasLast = true; 2445 hasLast = true;
2446 } 2446 }
2447 2447
2448 FormatLog(*tuple.get<0>(), changes, "Changes", true, 0, hasLast, last); 2448 FormatLog(tuple.get<0>(), changes, "Changes", true, 0, hasLast, last);
2449 } 2449 }
2450 }; 2450 };
2451 2451
2452 Operations operations; 2452 Operations operations;
2453 operations.Apply(*this, &target); 2453 operations.Apply(*this, target);
2454 } 2454 }
2455 2455
2456 2456
2457 void ServerIndex::GetExportedResources(Json::Value& target, 2457 void ServerIndex::GetExportedResources(Json::Value& target,
2458 int64_t since, 2458 int64_t since,
2459 unsigned int maxResults) 2459 unsigned int maxResults)
2460 { 2460 {
2461 class Operations : public ReadOnlyOperationsT3<Json::Value*, int64_t, unsigned int> 2461 class Operations : public ReadOnlyOperationsT3<Json::Value&, int64_t, unsigned int>
2462 { 2462 {
2463 public: 2463 public:
2464 virtual void ApplyTuple(ReadOnlyTransaction& transaction, 2464 virtual void ApplyTuple(ReadOnlyTransaction& transaction,
2465 const Tuple& tuple) ORTHANC_OVERRIDE 2465 const Tuple& tuple) ORTHANC_OVERRIDE
2466 { 2466 {
2467 // TODO - CANDIDATE FOR "TransactionType_SingleStatement" 2467 // TODO - CANDIDATE FOR "TransactionType_SingleStatement"
2468 2468
2469 std::list<ExportedResource> exported; 2469 std::list<ExportedResource> exported;
2470 bool done; 2470 bool done;
2471 transaction.GetExportedResources(exported, done, tuple.get<1>(), tuple.get<2>()); 2471 transaction.GetExportedResources(exported, done, tuple.get<1>(), tuple.get<2>());
2472 FormatLog(*tuple.get<0>(), exported, "Exports", done, tuple.get<1>(), false, -1); 2472 FormatLog(tuple.get<0>(), exported, "Exports", done, tuple.get<1>(), false, -1);
2473 } 2473 }
2474 }; 2474 };
2475 2475
2476 Operations operations; 2476 Operations operations;
2477 operations.Apply(*this, &target, since, maxResults); 2477 operations.Apply(*this, target, since, maxResults);
2478 } 2478 }
2479 2479
2480 2480
2481 void ServerIndex::GetLastExportedResource(Json::Value& target) 2481 void ServerIndex::GetLastExportedResource(Json::Value& target)
2482 { 2482 {
2483 class Operations : public ReadOnlyOperationsT1<Json::Value*> 2483 class Operations : public ReadOnlyOperationsT1<Json::Value&>
2484 { 2484 {
2485 public: 2485 public:
2486 virtual void ApplyTuple(ReadOnlyTransaction& transaction, 2486 virtual void ApplyTuple(ReadOnlyTransaction& transaction,
2487 const Tuple& tuple) ORTHANC_OVERRIDE 2487 const Tuple& tuple) ORTHANC_OVERRIDE
2488 { 2488 {
2489 // TODO - CANDIDATE FOR "TransactionType_SingleStatement" 2489 // TODO - CANDIDATE FOR "TransactionType_SingleStatement"
2490 2490
2491 std::list<ExportedResource> exported; 2491 std::list<ExportedResource> exported;
2492 transaction.GetLastExportedResource(exported); 2492 transaction.GetLastExportedResource(exported);
2493 FormatLog(*tuple.get<0>(), exported, "Exports", true, 0, false, -1); 2493 FormatLog(tuple.get<0>(), exported, "Exports", true, 0, false, -1);
2494 } 2494 }
2495 }; 2495 };
2496 2496
2497 Operations operations; 2497 Operations operations;
2498 operations.Apply(*this, &target); 2498 operations.Apply(*this, target);
2499 } 2499 }
2500 2500
2501 2501
2502 bool ServerIndex::IsProtectedPatient(const std::string& publicId) 2502 bool ServerIndex::IsProtectedPatient(const std::string& publicId)
2503 { 2503 {
2504 class Operations : public ReadOnlyOperationsT2<bool*, std::string> 2504 class Operations : public ReadOnlyOperationsT2<bool&, const std::string&>
2505 { 2505 {
2506 public: 2506 public:
2507 virtual void ApplyTuple(ReadOnlyTransaction& transaction, 2507 virtual void ApplyTuple(ReadOnlyTransaction& transaction,
2508 const Tuple& tuple) ORTHANC_OVERRIDE 2508 const Tuple& tuple) ORTHANC_OVERRIDE
2509 { 2509 {
2515 { 2515 {
2516 throw OrthancException(ErrorCode_ParameterOutOfRange); 2516 throw OrthancException(ErrorCode_ParameterOutOfRange);
2517 } 2517 }
2518 else 2518 else
2519 { 2519 {
2520 *tuple.get<0>() = transaction.IsProtectedPatient(id); 2520 tuple.get<0>() = transaction.IsProtectedPatient(id);
2521 } 2521 }
2522 } 2522 }
2523 }; 2523 };
2524 2524
2525 bool isProtected; 2525 bool isProtected;
2526 Operations operations; 2526 Operations operations;
2527 operations.Apply(*this, &isProtected, publicId); 2527 operations.Apply(*this, isProtected, publicId);
2528 return isProtected; 2528 return isProtected;
2529 } 2529 }
2530 2530
2531 2531
2532 void ServerIndex::GetChildren(std::list<std::string>& result, 2532 void ServerIndex::GetChildren(std::list<std::string>& result,
2533 const std::string& publicId) 2533 const std::string& publicId)
2534 { 2534 {
2535 class Operations : public ReadOnlyOperationsT2<std::list<std::string>*, std::string> 2535 class Operations : public ReadOnlyOperationsT2<std::list<std::string>&, const std::string&>
2536 { 2536 {
2537 public: 2537 public:
2538 virtual void ApplyTuple(ReadOnlyTransaction& transaction, 2538 virtual void ApplyTuple(ReadOnlyTransaction& transaction,
2539 const Tuple& tuple) ORTHANC_OVERRIDE 2539 const Tuple& tuple) ORTHANC_OVERRIDE
2540 { 2540 {
2552 else 2552 else
2553 { 2553 {
2554 std::list<int64_t> tmp; 2554 std::list<int64_t> tmp;
2555 transaction.GetChildrenInternalId(tmp, resource); 2555 transaction.GetChildrenInternalId(tmp, resource);
2556 2556
2557 tuple.get<0>()->clear(); 2557 tuple.get<0>().clear();
2558 2558
2559 for (std::list<int64_t>::const_iterator 2559 for (std::list<int64_t>::const_iterator
2560 it = tmp.begin(); it != tmp.end(); ++it) 2560 it = tmp.begin(); it != tmp.end(); ++it)
2561 { 2561 {
2562 tuple.get<0>()->push_back(transaction.GetPublicId(*it)); 2562 tuple.get<0>().push_back(transaction.GetPublicId(*it));
2563 } 2563 }
2564 } 2564 }
2565 } 2565 }
2566 }; 2566 };
2567 2567
2568 Operations operations; 2568 Operations operations;
2569 operations.Apply(*this, &result, publicId); 2569 operations.Apply(*this, result, publicId);
2570 } 2570 }
2571 2571
2572 2572
2573 void ServerIndex::GetChildInstances(std::list<std::string>& result, 2573 void ServerIndex::GetChildInstances(std::list<std::string>& result,
2574 const std::string& publicId) 2574 const std::string& publicId)
2575 { 2575 {
2576 class Operations : public ReadOnlyOperationsT2<std::list<std::string>*, std::string> 2576 class Operations : public ReadOnlyOperationsT2<std::list<std::string>&, const std::string&>
2577 { 2577 {
2578 public: 2578 public:
2579 virtual void ApplyTuple(ReadOnlyTransaction& transaction, 2579 virtual void ApplyTuple(ReadOnlyTransaction& transaction,
2580 const Tuple& tuple) ORTHANC_OVERRIDE 2580 const Tuple& tuple) ORTHANC_OVERRIDE
2581 { 2581 {
2582 tuple.get<0>()->clear(); 2582 tuple.get<0>().clear();
2583 2583
2584 ResourceType type; 2584 ResourceType type;
2585 int64_t top; 2585 int64_t top;
2586 if (!transaction.LookupResource(top, type, tuple.get<1>())) 2586 if (!transaction.LookupResource(top, type, tuple.get<1>()))
2587 { 2587 {
2588 throw OrthancException(ErrorCode_UnknownResource); 2588 throw OrthancException(ErrorCode_UnknownResource);
2589 } 2589 }
2590 else if (type == ResourceType_Instance) 2590 else if (type == ResourceType_Instance)
2591 { 2591 {
2592 // The resource is already an instance: Do not go down the hierarchy 2592 // The resource is already an instance: Do not go down the hierarchy
2593 tuple.get<0>()->push_back(tuple.get<1>()); 2593 tuple.get<0>().push_back(tuple.get<1>());
2594 } 2594 }
2595 else 2595 else
2596 { 2596 {
2597 std::stack<int64_t> toExplore; 2597 std::stack<int64_t> toExplore;
2598 toExplore.push(top); 2598 toExplore.push(top);
2607 // TODO - This could be optimized by seeing how many 2607 // TODO - This could be optimized by seeing how many
2608 // levels "type == transaction.GetResourceType(top)" is 2608 // levels "type == transaction.GetResourceType(top)" is
2609 // above the "instances level" 2609 // above the "instances level"
2610 if (transaction.GetResourceType(resource) == ResourceType_Instance) 2610 if (transaction.GetResourceType(resource) == ResourceType_Instance)
2611 { 2611 {
2612 tuple.get<0>()->push_back(transaction.GetPublicId(resource)); 2612 tuple.get<0>().push_back(transaction.GetPublicId(resource));
2613 } 2613 }
2614 else 2614 else
2615 { 2615 {
2616 // Tag all the children of this resource as to be explored 2616 // Tag all the children of this resource as to be explored
2617 transaction.GetChildrenInternalId(tmp, resource); 2617 transaction.GetChildrenInternalId(tmp, resource);
2625 } 2625 }
2626 } 2626 }
2627 }; 2627 };
2628 2628
2629 Operations operations; 2629 Operations operations;
2630 operations.Apply(*this, &result, publicId); 2630 operations.Apply(*this, result, publicId);
2631 } 2631 }
2632 2632
2633 2633
2634 bool ServerIndex::LookupMetadata(std::string& target, 2634 bool ServerIndex::LookupMetadata(std::string& target,
2635 const std::string& publicId, 2635 const std::string& publicId,
2636 ResourceType expectedType, 2636 ResourceType expectedType,
2637 MetadataType type) 2637 MetadataType type)
2638 { 2638 {
2639 class Operations : public ReadOnlyOperationsT5<bool*, std::string*, std::string, ResourceType, MetadataType> 2639 class Operations : public ReadOnlyOperationsT5<bool&, std::string&, const std::string&, ResourceType, MetadataType>
2640 { 2640 {
2641 public: 2641 public:
2642 virtual void ApplyTuple(ReadOnlyTransaction& transaction, 2642 virtual void ApplyTuple(ReadOnlyTransaction& transaction,
2643 const Tuple& tuple) ORTHANC_OVERRIDE 2643 const Tuple& tuple) ORTHANC_OVERRIDE
2644 { 2644 {
2649 { 2649 {
2650 throw OrthancException(ErrorCode_UnknownResource); 2650 throw OrthancException(ErrorCode_UnknownResource);
2651 } 2651 }
2652 else 2652 else
2653 { 2653 {
2654 *tuple.get<0>() = transaction.LookupMetadata(*tuple.get<1>(), id, tuple.get<4>()); 2654 tuple.get<0>() = transaction.LookupMetadata(tuple.get<1>(), id, tuple.get<4>());
2655 } 2655 }
2656 } 2656 }
2657 }; 2657 };
2658 2658
2659 bool found; 2659 bool found;
2660 Operations operations; 2660 Operations operations;
2661 operations.Apply(*this, &found, &target, publicId, expectedType, type); 2661 operations.Apply(*this, found, target, publicId, expectedType, type);
2662 return found; 2662 return found;
2663 } 2663 }
2664 2664
2665 2665
2666 void ServerIndex::ListAvailableAttachments(std::set<FileContentType>& target, 2666 void ServerIndex::ListAvailableAttachments(std::set<FileContentType>& target,
2667 const std::string& publicId, 2667 const std::string& publicId,
2668 ResourceType expectedType) 2668 ResourceType expectedType)
2669 { 2669 {
2670 class Operations : public ReadOnlyOperationsT3<std::set<FileContentType>*, std::string, ResourceType> 2670 class Operations : public ReadOnlyOperationsT3<std::set<FileContentType>&, const std::string&, ResourceType>
2671 { 2671 {
2672 public: 2672 public:
2673 virtual void ApplyTuple(ReadOnlyTransaction& transaction, 2673 virtual void ApplyTuple(ReadOnlyTransaction& transaction,
2674 const Tuple& tuple) ORTHANC_OVERRIDE 2674 const Tuple& tuple) ORTHANC_OVERRIDE
2675 { 2675 {
2680 { 2680 {
2681 throw OrthancException(ErrorCode_UnknownResource); 2681 throw OrthancException(ErrorCode_UnknownResource);
2682 } 2682 }
2683 else 2683 else
2684 { 2684 {
2685 transaction.ListAvailableAttachments(*tuple.get<0>(), id); 2685 transaction.ListAvailableAttachments(tuple.get<0>(), id);
2686 } 2686 }
2687 } 2687 }
2688 }; 2688 };
2689 2689
2690 Operations operations; 2690 Operations operations;
2691 operations.Apply(*this, &target, publicId, expectedType); 2691 operations.Apply(*this, target, publicId, expectedType);
2692 } 2692 }
2693 2693
2694 2694
2695 bool ServerIndex::LookupParent(std::string& target, 2695 bool ServerIndex::LookupParent(std::string& target,
2696 const std::string& publicId) 2696 const std::string& publicId)
2697 { 2697 {
2698 class Operations : public ReadOnlyOperationsT3<bool*, std::string*, std::string> 2698 class Operations : public ReadOnlyOperationsT3<bool&, std::string&, const std::string&>
2699 { 2699 {
2700 public: 2700 public:
2701 virtual void ApplyTuple(ReadOnlyTransaction& transaction, 2701 virtual void ApplyTuple(ReadOnlyTransaction& transaction,
2702 const Tuple& tuple) ORTHANC_OVERRIDE 2702 const Tuple& tuple) ORTHANC_OVERRIDE
2703 { 2703 {
2710 else 2710 else
2711 { 2711 {
2712 int64_t parentId; 2712 int64_t parentId;
2713 if (transaction.LookupParent(parentId, id)) 2713 if (transaction.LookupParent(parentId, id))
2714 { 2714 {
2715 *tuple.get<1>() = transaction.GetPublicId(parentId); 2715 tuple.get<1>() = transaction.GetPublicId(parentId);
2716 *tuple.get<0>() = true; 2716 tuple.get<0>() = true;
2717 } 2717 }
2718 else 2718 else
2719 { 2719 {
2720 *tuple.get<0>() = false; 2720 tuple.get<0>() = false;
2721 } 2721 }
2722 } 2722 }
2723 } 2723 }
2724 }; 2724 };
2725 2725
2726 bool found; 2726 bool found;
2727 Operations operations; 2727 Operations operations;
2728 operations.Apply(*this, &found, &target, publicId); 2728 operations.Apply(*this, found, target, publicId);
2729 return found; 2729 return found;
2730 } 2730 }
2731 2731
2732 2732
2733 void ServerIndex::GetResourceStatistics(/* out */ ResourceType& type, 2733 void ServerIndex::GetResourceStatistics(/* out */ ResourceType& type,
2924 2924
2925 2925
2926 bool ServerIndex::LookupGlobalProperty(std::string& value, 2926 bool ServerIndex::LookupGlobalProperty(std::string& value,
2927 GlobalProperty property) 2927 GlobalProperty property)
2928 { 2928 {
2929 class Operations : public ReadOnlyOperationsT3<bool*, std::string*, GlobalProperty> 2929 class Operations : public ReadOnlyOperationsT3<bool&, std::string&, GlobalProperty>
2930 { 2930 {
2931 public: 2931 public:
2932 virtual void ApplyTuple(ReadOnlyTransaction& transaction, 2932 virtual void ApplyTuple(ReadOnlyTransaction& transaction,
2933 const Tuple& tuple) ORTHANC_OVERRIDE 2933 const Tuple& tuple) ORTHANC_OVERRIDE
2934 { 2934 {
2935 // TODO - CANDIDATE FOR "TransactionType_SingleStatement" 2935 // TODO - CANDIDATE FOR "TransactionType_SingleStatement"
2936 *tuple.get<0>() = transaction.LookupGlobalProperty(*tuple.get<1>(), tuple.get<2>()); 2936 tuple.get<0>() = transaction.LookupGlobalProperty(tuple.get<1>(), tuple.get<2>());
2937 } 2937 }
2938 }; 2938 };
2939 2939
2940 bool found; 2940 bool found;
2941 Operations operations; 2941 Operations operations;
2942 operations.Apply(*this, &found, &value, property); 2942 operations.Apply(*this, found, value, property);
2943 return found; 2943 return found;
2944 } 2944 }
2945 2945
2946 2946
2947 std::string ServerIndex::GetGlobalProperty(GlobalProperty property, 2947 std::string ServerIndex::GetGlobalProperty(GlobalProperty property,
2973 { 2973 {
2974 throw OrthancException(ErrorCode_ParameterOutOfRange); 2974 throw OrthancException(ErrorCode_ParameterOutOfRange);
2975 } 2975 }
2976 2976
2977 2977
2978 class Operations : public ReadOnlyOperationsT5<bool*, DicomMap*, std::string, ResourceType, ResourceType> 2978 class Operations : public ReadOnlyOperationsT5<bool&, DicomMap&, const std::string&, ResourceType, ResourceType>
2979 { 2979 {
2980 public: 2980 public:
2981 virtual void ApplyTuple(ReadOnlyTransaction& transaction, 2981 virtual void ApplyTuple(ReadOnlyTransaction& transaction,
2982 const Tuple& tuple) ORTHANC_OVERRIDE 2982 const Tuple& tuple) ORTHANC_OVERRIDE
2983 { 2983 {
2985 int64_t id; 2985 int64_t id;
2986 ResourceType type; 2986 ResourceType type;
2987 if (!transaction.LookupResource(id, type, tuple.get<2>()) || 2987 if (!transaction.LookupResource(id, type, tuple.get<2>()) ||
2988 type != tuple.get<3>()) 2988 type != tuple.get<3>())
2989 { 2989 {
2990 *tuple.get<0>() = false; 2990 tuple.get<0>() = false;
2991 } 2991 }
2992 else if (type == ResourceType_Study) 2992 else if (type == ResourceType_Study)
2993 { 2993 {
2994 DicomMap tmp; 2994 DicomMap tmp;
2995 transaction.GetMainDicomTags(tmp, id); 2995 transaction.GetMainDicomTags(tmp, id);
2996 2996
2997 switch (tuple.get<4>()) 2997 switch (tuple.get<4>())
2998 { 2998 {
2999 case ResourceType_Patient: 2999 case ResourceType_Patient:
3000 tmp.ExtractPatientInformation(*tuple.get<1>()); 3000 tmp.ExtractPatientInformation(tuple.get<1>());
3001 *tuple.get<0>() = true; 3001 tuple.get<0>() = true;
3002 break; 3002 break;
3003 3003
3004 case ResourceType_Study: 3004 case ResourceType_Study:
3005 tmp.ExtractStudyInformation(*tuple.get<1>()); 3005 tmp.ExtractStudyInformation(tuple.get<1>());
3006 *tuple.get<0>() = true; 3006 tuple.get<0>() = true;
3007 break; 3007 break;
3008 3008
3009 default: 3009 default:
3010 throw OrthancException(ErrorCode_InternalError); 3010 throw OrthancException(ErrorCode_InternalError);
3011 } 3011 }
3012 } 3012 }
3013 else 3013 else
3014 { 3014 {
3015 transaction.GetMainDicomTags(*tuple.get<1>(), id); 3015 transaction.GetMainDicomTags(tuple.get<1>(), id);
3016 *tuple.get<0>() = true; 3016 tuple.get<0>() = true;
3017 } 3017 }
3018 } 3018 }
3019 }; 3019 };
3020 3020
3021 result.Clear(); 3021 result.Clear();
3022 3022
3023 bool found; 3023 bool found;
3024 Operations operations; 3024 Operations operations;
3025 operations.Apply(*this, &found, &result, publicId, expectedType, levelOfInterest); 3025 operations.Apply(*this, found, result, publicId, expectedType, levelOfInterest);
3026 return found; 3026 return found;
3027 } 3027 }
3028 3028
3029 3029
3030 bool ServerIndex::GetAllMainDicomTags(DicomMap& result, 3030 bool ServerIndex::GetAllMainDicomTags(DicomMap& result,
3031 const std::string& instancePublicId) 3031 const std::string& instancePublicId)
3032 { 3032 {
3033 class Operations : public ReadOnlyOperationsT3<bool*, DicomMap*, std::string> 3033 class Operations : public ReadOnlyOperationsT3<bool&, DicomMap&, const std::string&>
3034 { 3034 {
3035 public: 3035 public:
3036 virtual void ApplyTuple(ReadOnlyTransaction& transaction, 3036 virtual void ApplyTuple(ReadOnlyTransaction& transaction,
3037 const Tuple& tuple) ORTHANC_OVERRIDE 3037 const Tuple& tuple) ORTHANC_OVERRIDE
3038 { 3038 {
3040 int64_t instance; 3040 int64_t instance;
3041 ResourceType type; 3041 ResourceType type;
3042 if (!transaction.LookupResource(instance, type, tuple.get<2>()) || 3042 if (!transaction.LookupResource(instance, type, tuple.get<2>()) ||
3043 type != ResourceType_Instance) 3043 type != ResourceType_Instance)
3044 { 3044 {
3045 *tuple.get<0>() = false; 3045 tuple.get<0>() = false;
3046 } 3046 }
3047 else 3047 else
3048 { 3048 {
3049 DicomMap tmp; 3049 DicomMap tmp;
3050 3050
3051 transaction.GetMainDicomTags(tmp, instance); 3051 transaction.GetMainDicomTags(tmp, instance);
3052 tuple.get<1>()->Merge(tmp); 3052 tuple.get<1>().Merge(tmp);
3053 3053
3054 int64_t series; 3054 int64_t series;
3055 if (!transaction.LookupParent(series, instance)) 3055 if (!transaction.LookupParent(series, instance))
3056 { 3056 {
3057 throw OrthancException(ErrorCode_InternalError); 3057 throw OrthancException(ErrorCode_InternalError);
3058 } 3058 }
3059 3059
3060 tmp.Clear(); 3060 tmp.Clear();
3061 transaction.GetMainDicomTags(tmp, series); 3061 transaction.GetMainDicomTags(tmp, series);
3062 tuple.get<1>()->Merge(tmp); 3062 tuple.get<1>().Merge(tmp);
3063 3063
3064 int64_t study; 3064 int64_t study;
3065 if (!transaction.LookupParent(study, series)) 3065 if (!transaction.LookupParent(study, series))
3066 { 3066 {
3067 throw OrthancException(ErrorCode_InternalError); 3067 throw OrthancException(ErrorCode_InternalError);
3068 } 3068 }
3069 3069
3070 tmp.Clear(); 3070 tmp.Clear();
3071 transaction.GetMainDicomTags(tmp, study); 3071 transaction.GetMainDicomTags(tmp, study);
3072 tuple.get<1>()->Merge(tmp); 3072 tuple.get<1>().Merge(tmp);
3073 3073
3074 #ifndef NDEBUG 3074 #ifndef NDEBUG
3075 { 3075 {
3076 // Sanity test to check that all the main DICOM tags from the 3076 // Sanity test to check that all the main DICOM tags from the
3077 // patient level are copied at the study level 3077 // patient level are copied at the study level
3089 tmp.GetTags(patientTags); 3089 tmp.GetTags(patientTags);
3090 3090
3091 for (std::set<DicomTag>::const_iterator 3091 for (std::set<DicomTag>::const_iterator
3092 it = patientTags.begin(); it != patientTags.end(); ++it) 3092 it = patientTags.begin(); it != patientTags.end(); ++it)
3093 { 3093 {
3094 assert(tuple.get<1>()->HasTag(*it)); 3094 assert(tuple.get<1>().HasTag(*it));
3095 } 3095 }
3096 } 3096 }
3097 #endif 3097 #endif
3098 3098
3099 *tuple.get<0>() = true; 3099 tuple.get<0>() = true;
3100 } 3100 }
3101 } 3101 }
3102 }; 3102 };
3103 3103
3104 result.Clear(); 3104 result.Clear();
3105 3105
3106 bool found; 3106 bool found;
3107 Operations operations; 3107 Operations operations;
3108 operations.Apply(*this, &found, &result, instancePublicId); 3108 operations.Apply(*this, found, result, instancePublicId);
3109 return found; 3109 return found;
3110 } 3110 }
3111 3111
3112 3112
3113 bool ServerIndex::LookupResourceType(ResourceType& type, 3113 bool ServerIndex::LookupResourceType(ResourceType& type,
3114 const std::string& publicId) 3114 const std::string& publicId)
3115 { 3115 {
3116 class Operations : public ReadOnlyOperationsT3<bool*, ResourceType*, std::string> 3116 class Operations : public ReadOnlyOperationsT3<bool&, ResourceType&, const std::string&>
3117 { 3117 {
3118 public: 3118 public:
3119 virtual void ApplyTuple(ReadOnlyTransaction& transaction, 3119 virtual void ApplyTuple(ReadOnlyTransaction& transaction,
3120 const Tuple& tuple) ORTHANC_OVERRIDE 3120 const Tuple& tuple) ORTHANC_OVERRIDE
3121 { 3121 {
3122 // TODO - CANDIDATE FOR "TransactionType_SingleStatement" 3122 // TODO - CANDIDATE FOR "TransactionType_SingleStatement"
3123 int64_t id; 3123 int64_t id;
3124 *tuple.get<0>() = transaction.LookupResource(id, *tuple.get<1>(), tuple.get<2>()); 3124 tuple.get<0>() = transaction.LookupResource(id, tuple.get<1>(), tuple.get<2>());
3125 } 3125 }
3126 }; 3126 };
3127 3127
3128 bool found; 3128 bool found;
3129 Operations operations; 3129 Operations operations;
3130 operations.Apply(*this, &found, &type, publicId); 3130 operations.Apply(*this, found, type, publicId);
3131 return found; 3131 return found;
3132 } 3132 }
3133 3133
3134 3134
3135 unsigned int ServerIndex::GetDatabaseVersion() 3135 unsigned int ServerIndex::GetDatabaseVersion()
3136 { 3136 {
3137 class Operations : public ReadOnlyOperationsT1<unsigned int *> 3137 class Operations : public ReadOnlyOperationsT1<unsigned int&>
3138 { 3138 {
3139 public: 3139 public:
3140 virtual void ApplyTuple(ReadOnlyTransaction& transaction, 3140 virtual void ApplyTuple(ReadOnlyTransaction& transaction,
3141 const Tuple& tuple) ORTHANC_OVERRIDE 3141 const Tuple& tuple) ORTHANC_OVERRIDE
3142 { 3142 {
3143 // TODO - CANDIDATE FOR "TransactionType_SingleStatement" 3143 // TODO - CANDIDATE FOR "TransactionType_SingleStatement"
3144 *tuple.get<0>() = transaction.GetDatabaseVersion(); 3144 tuple.get<0>() = transaction.GetDatabaseVersion();
3145 } 3145 }
3146 }; 3146 };
3147 3147
3148 unsigned int version; 3148 unsigned int version;
3149 Operations operations; 3149 Operations operations;
3150 operations.Apply(*this, &version); 3150 operations.Apply(*this, version);
3151 return version; 3151 return version;
3152 } 3152 }
3153 3153
3154 3154
3155 bool ServerIndex::LookupParent(std::string& target, 3155 bool ServerIndex::LookupParent(std::string& target,
3156 const std::string& publicId, 3156 const std::string& publicId,
3157 ResourceType parentType) 3157 ResourceType parentType)
3158 { 3158 {
3159 class Operations : public ReadOnlyOperationsT4<bool*, std::string*, std::string, ResourceType> 3159 class Operations : public ReadOnlyOperationsT4<bool&, std::string&, const std::string&, ResourceType>
3160 { 3160 {
3161 public: 3161 public:
3162 virtual void ApplyTuple(ReadOnlyTransaction& transaction, 3162 virtual void ApplyTuple(ReadOnlyTransaction& transaction,
3163 const Tuple& tuple) ORTHANC_OVERRIDE 3163 const Tuple& tuple) ORTHANC_OVERRIDE
3164 { 3164 {
3174 int64_t parentId; 3174 int64_t parentId;
3175 3175
3176 if (type == ResourceType_Patient || // Cannot further go up in hierarchy 3176 if (type == ResourceType_Patient || // Cannot further go up in hierarchy
3177 !transaction.LookupParent(parentId, id)) 3177 !transaction.LookupParent(parentId, id))
3178 { 3178 {
3179 *tuple.get<0>() = false; 3179 tuple.get<0>() = false;
3180 return; 3180 return;
3181 } 3181 }
3182 3182
3183 id = parentId; 3183 id = parentId;
3184 type = GetParentResourceType(type); 3184 type = GetParentResourceType(type);
3185 } 3185 }
3186 3186
3187 *tuple.get<0>() = true; 3187 tuple.get<0>() = true;
3188 *tuple.get<1>() = transaction.GetPublicId(id); 3188 tuple.get<1>() = transaction.GetPublicId(id);
3189 } 3189 }
3190 }; 3190 };
3191 3191
3192 bool found; 3192 bool found;
3193 Operations operations; 3193 Operations operations;
3194 operations.Apply(*this, &found, &target, publicId, parentType); 3194 operations.Apply(*this, found, target, publicId, parentType);
3195 return found; 3195 return found;
3196 } 3196 }
3197 3197
3198 3198
3199 void ServerIndex::ApplyLookupResources(std::vector<std::string>& resourcesId, 3199 void ServerIndex::ApplyLookupResources(std::vector<std::string>& resourcesId,
3200 std::vector<std::string>* instancesId, 3200 std::vector<std::string>* instancesId,
3201 const DatabaseLookup& lookup, 3201 const DatabaseLookup& lookup,
3202 ResourceType queryLevel, 3202 ResourceType queryLevel,
3203 size_t limit) 3203 size_t limit)
3204 { 3204 {
3205 class Operations : public ReadOnlyOperationsT4<bool, std::vector<DatabaseConstraint>, ResourceType, size_t> 3205 class Operations : public ReadOnlyOperationsT4<bool, const std::vector<DatabaseConstraint>&, ResourceType, size_t>
3206 { 3206 {
3207 private: 3207 private:
3208 std::list<std::string> resourcesList_; 3208 std::list<std::string> resourcesList_;
3209 std::list<std::string> instancesList_; 3209 std::list<std::string> instancesList_;
3210 3210