comparison OrthancServer/Search/LookupResource.cpp @ 1753:faf2ecab3472 db-changes

fix
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 27 Oct 2015 20:31:34 +0100
parents fb569ee09a69
children 3a4f7dc00f49
comparison
equal deleted inserted replaced
1752:c3d8ec63a179 1753:faf2ecab3472
273 } 273 }
274 } 274 }
275 275
276 276
277 277
278 bool LookupResource::ApplyUnoptimizedConstraints(std::list<int64_t>& result, 278 bool LookupResource::IsMatch(const Json::Value& dicomAsJson) const
279 const std::list<int64_t>& candidates, 279 {
280 boost::mutex& databaseMutex, 280 for (Constraints::const_iterator it = unoptimizedConstraints_.begin();
281 IDatabaseWrapper& database, 281 it != unoptimizedConstraints_.end(); ++it)
282 IStorageArea& storageArea) const 282 {
283 { 283 std::string tag = (*it)->GetTag().Format();
284 assert(!unoptimizedConstraints_.empty()); 284 if (dicomAsJson.isMember(tag) &&
285 285 dicomAsJson[tag]["Type"] == "String")
286 StorageAccessor accessor(storageArea); 286 {
287 287 std::string value = dicomAsJson[tag]["Value"].asString();
288 for (std::list<int64_t>::const_iterator candidate = candidates.begin(); 288 if (!(*it)->Match(value))
289 candidate != candidates.end(); ++candidate) 289 {
290 { 290 return false;
291 if (maxResults_ != 0 && 291 }
292 result.size() >= maxResults_) 292 }
293 { 293 else
294 // We have enough results, not finished 294 {
295 return false; 295 return false;
296 } 296 }
297 297 }
298 int64_t instance; 298
299 FileInfo attachment; 299 return true;
300
301 {
302 boost::mutex::scoped_lock lock(databaseMutex);
303
304 if (!Toolbox::FindOneChildInstance(instance, database, *candidate, level_) ||
305 !database.LookupAttachment(attachment, instance, FileContentType_DicomAsJson))
306 {
307 continue;
308 }
309 }
310
311 Json::Value content;
312 accessor.Read(content, attachment);
313
314 bool match = true;
315
316 for (Constraints::const_iterator it = unoptimizedConstraints_.begin();
317 match && it != unoptimizedConstraints_.end(); ++it)
318 {
319 std::string tag = (*it)->GetTag().Format();
320 if (content.isMember(tag) &&
321 content[tag]["Type"] == "String")
322 {
323 std::string value = content[tag]["Value"].asString();
324 if (!(*it)->Match(value))
325 {
326 match = false;
327 }
328 }
329 else
330 {
331 match = false;
332 }
333 }
334
335 if (match)
336 {
337 result.push_back(*candidate);
338 }
339 }
340
341 return true; // Finished
342 } 300 }
343 301
344 302
345 void LookupResource::ApplyLevel(SetOfResources& candidates, 303 void LookupResource::ApplyLevel(SetOfResources& candidates,
346 ResourceType level, 304 ResourceType level,
352 it->second->Apply(candidates, database); 310 it->second->Apply(candidates, database);
353 } 311 }
354 } 312 }
355 313
356 314
357 bool LookupResource::Apply(std::list<int64_t>& result, 315 void LookupResource::FindCandidates(std::list<int64_t>& result,
358 boost::mutex& databaseMutex, 316 IDatabaseWrapper& database) const
359 IDatabaseWrapper& database, 317 {
360 IStorageArea& storageArea) const 318 SetOfResources candidates(database, level_);
361 { 319
362 std::list<int64_t> tmp; 320 switch (level_)
363 321 {
364 { 322 case ResourceType_Patient:
365 boost::mutex::scoped_lock lock(databaseMutex); 323 ApplyLevel(candidates, ResourceType_Patient, database);
366 SetOfResources candidates(database, level_); 324 break;
367 325
368 switch (level_) 326 case ResourceType_Study:
369 { 327 ApplyLevel(candidates, ResourceType_Study, database);
370 case ResourceType_Patient: 328 break;
371 ApplyLevel(candidates, ResourceType_Patient, database); 329
372 break; 330 case ResourceType_Series:
373 331 ApplyLevel(candidates, ResourceType_Study, database);
374 case ResourceType_Study: 332 candidates.GoDown();
375 ApplyLevel(candidates, ResourceType_Study, database); 333 ApplyLevel(candidates, ResourceType_Series, database);
376 break; 334 break;
377 335
378 case ResourceType_Series: 336 case ResourceType_Instance:
379 ApplyLevel(candidates, ResourceType_Study, database); 337 ApplyLevel(candidates, ResourceType_Study, database);
380 candidates.GoDown(); 338 candidates.GoDown();
381 ApplyLevel(candidates, ResourceType_Series, database); 339 ApplyLevel(candidates, ResourceType_Series, database);
382 break; 340 candidates.GoDown();
383 341 ApplyLevel(candidates, ResourceType_Instance, database);
384 case ResourceType_Instance: 342 break;
385 ApplyLevel(candidates, ResourceType_Study, database); 343
386 candidates.GoDown(); 344 default:
387 ApplyLevel(candidates, ResourceType_Series, database); 345 throw OrthancException(ErrorCode_InternalError);
388 candidates.GoDown(); 346 }
389 ApplyLevel(candidates, ResourceType_Instance, database); 347
390 break; 348 candidates.Flatten(result);
391
392 default:
393 throw OrthancException(ErrorCode_InternalError);
394 }
395
396 if (unoptimizedConstraints_.empty())
397 {
398 return candidates.Flatten(result, maxResults_);
399 }
400 else
401 {
402 candidates.Flatten(tmp);
403 }
404 }
405
406 return ApplyUnoptimizedConstraints(result, tmp, databaseMutex, database, storageArea);
407 }
408
409
410 bool LookupResource::Apply(std::list<std::string>& result,
411 boost::mutex& databaseMutex,
412 IDatabaseWrapper& database,
413 IStorageArea& storageArea) const
414 {
415
416 std::list<int64_t> tmp;
417 bool finished = Apply(tmp, databaseMutex, database, storageArea);
418
419 result.clear();
420
421 {
422 boost::mutex::scoped_lock lock(databaseMutex);
423
424 for (std::list<int64_t>::const_iterator
425 it = tmp.begin(); it != tmp.end(); ++it)
426 {
427 result.push_back(database.GetPublicId(*it));
428 }
429 }
430
431 return finished;
432 } 349 }
433 350
434 351
435 void LookupResource::Add(const DicomTag& tag, 352 void LookupResource::Add(const DicomTag& tag,
436 const std::string& dicomQuery, 353 const std::string& dicomQuery,