comparison OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp @ 4591:ff8170d17d90 db-changes

moving all accesses to databases from IDatabaseWrapper to ITransaction
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 15 Mar 2021 15:30:42 +0100
parents bec74e29f86b
children d494b4f1103e
comparison
equal deleted inserted replaced
4590:4a0bf1019335 4591:ff8170d17d90
423 { 423 {
424 ServerIndexChange change(changeType, resourceType, publicId); 424 ServerIndexChange change(changeType, resourceType, publicId);
425 425
426 if (changeType <= ChangeType_INTERNAL_LastLogged) 426 if (changeType <= ChangeType_INTERNAL_LastLogged)
427 { 427 {
428 db_.LogChange(internalId, change); 428 transaction_.LogChange(internalId, change);
429 } 429 }
430 430
431 GetTransactionContext().SignalChange(change); 431 GetTransactionContext().SignalChange(change);
432 } 432 }
433 433
434 434
435 SeriesStatus StatelessDatabaseOperations::ReadOnlyTransaction::GetSeriesStatus(int64_t id, 435 SeriesStatus StatelessDatabaseOperations::ReadOnlyTransaction::GetSeriesStatus(int64_t id,
436 int64_t expectedNumberOfInstances) 436 int64_t expectedNumberOfInstances)
437 { 437 {
438 std::list<std::string> values; 438 std::list<std::string> values;
439 db_.GetChildrenMetadata(values, id, MetadataType_Instance_IndexInSeries); 439 transaction_.GetChildrenMetadata(values, id, MetadataType_Instance_IndexInSeries);
440 440
441 std::set<int64_t> instances; 441 std::set<int64_t> instances;
442 442
443 for (std::list<std::string>::const_iterator 443 for (std::list<std::string>::const_iterator
444 it = values.begin(); it != values.end(); ++it) 444 it = values.begin(); it != values.end(); ++it)
553 LOG(ERROR) << "Cannot rollback transaction: " << e.What(); 553 LOG(ERROR) << "Cannot rollback transaction: " << e.What();
554 } 554 }
555 } 555 }
556 } 556 }
557 557
558 IDatabaseWrapper::ITransaction& GetDatabaseTransaction()
559 {
560 assert(transaction_.get() != NULL);
561 return *transaction_;
562 }
563
558 void Commit() 564 void Commit()
559 { 565 {
560 if (isCommitted_) 566 if (isCommitted_)
561 { 567 {
562 throw OrthancException(ErrorCode_BadSequenceOfCalls); 568 throw OrthancException(ErrorCode_BadSequenceOfCalls);
609 * global mutex protecting the database. 615 * global mutex protecting the database.
610 **/ 616 **/
611 617
612 Transaction transaction(db_, *factory_, TransactionType_ReadOnly); // TODO - Only if not "TransactionType_Implicit" 618 Transaction transaction(db_, *factory_, TransactionType_ReadOnly); // TODO - Only if not "TransactionType_Implicit"
613 { 619 {
614 ReadOnlyTransaction t(db_, transaction.GetContext()); 620 ReadOnlyTransaction t(transaction.GetDatabaseTransaction(), transaction.GetContext());
615 readOperations->Apply(t); 621 readOperations->Apply(t);
616 } 622 }
617 transaction.Commit(); 623 transaction.Commit();
618 } 624 }
619 else 625 else
620 { 626 {
621 assert(writeOperations != NULL); 627 assert(writeOperations != NULL);
622 628
623 Transaction transaction(db_, *factory_, TransactionType_ReadWrite); 629 Transaction transaction(db_, *factory_, TransactionType_ReadWrite);
624 { 630 {
625 ReadWriteTransaction t(db_, transaction.GetContext()); 631 ReadWriteTransaction t(transaction.GetDatabaseTransaction(), transaction.GetContext());
626 writeOperations->Apply(t); 632 writeOperations->Apply(t);
627 } 633 }
628 transaction.Commit(); 634 transaction.Commit();
629 } 635 }
630 636
2499 std::unique_ptr<DicomInstanceHasher> hasher_; 2505 std::unique_ptr<DicomInstanceHasher> hasher_;
2500 bool hasTransferSyntax_; 2506 bool hasTransferSyntax_;
2501 DicomTransferSyntax transferSyntax_; 2507 DicomTransferSyntax transferSyntax_;
2502 2508
2503 public: 2509 public:
2504 Operations(const ParsedDicomFile& dicom) 2510 explicit Operations(const ParsedDicomFile& dicom)
2505 { 2511 {
2506 OrthancConfiguration::DefaultExtractDicomSummary(summary_, dicom); 2512 OrthancConfiguration::DefaultExtractDicomSummary(summary_, dicom);
2507 hasher_.reset(new DicomInstanceHasher(summary_)); 2513 hasher_.reset(new DicomInstanceHasher(summary_));
2508 hasTransferSyntax_ = dicom.LookupTransferSyntax(transferSyntax_); 2514 hasTransferSyntax_ = dicom.LookupTransferSyntax(transferSyntax_);
2509 } 2515 }
2561 Operations operations(dicom); 2567 Operations operations(dicom);
2562 Apply(operations); 2568 Apply(operations);
2563 } 2569 }
2564 2570
2565 2571
2566 static bool IsRecyclingNeeded(IDatabaseWrapper& db, 2572 static bool IsRecyclingNeeded(IDatabaseWrapper::ITransaction& transaction,
2567 uint64_t maximumStorageSize, 2573 uint64_t maximumStorageSize,
2568 unsigned int maximumPatients, 2574 unsigned int maximumPatients,
2569 uint64_t addedInstanceSize) 2575 uint64_t addedInstanceSize)
2570 { 2576 {
2571 if (maximumStorageSize != 0) 2577 if (maximumStorageSize != 0)
2576 boost::lexical_cast<std::string>(addedInstanceSize) + 2582 boost::lexical_cast<std::string>(addedInstanceSize) +
2577 " bytes in a storage area limited to " + 2583 " bytes in a storage area limited to " +
2578 boost::lexical_cast<std::string>(maximumStorageSize)); 2584 boost::lexical_cast<std::string>(maximumStorageSize));
2579 } 2585 }
2580 2586
2581 if (db.IsDiskSizeAbove(maximumStorageSize - addedInstanceSize)) 2587 if (transaction.IsDiskSizeAbove(maximumStorageSize - addedInstanceSize))
2582 { 2588 {
2583 return true; 2589 return true;
2584 } 2590 }
2585 } 2591 }
2586 2592
2587 if (maximumPatients != 0) 2593 if (maximumPatients != 0)
2588 { 2594 {
2589 uint64_t patientCount = db.GetResourceCount(ResourceType_Patient); 2595 uint64_t patientCount = transaction.GetResourceCount(ResourceType_Patient);
2590 if (patientCount > maximumPatients) 2596 if (patientCount > maximumPatients)
2591 { 2597 {
2592 return true; 2598 return true;
2593 } 2599 }
2594 } 2600 }
2602 uint64_t addedInstanceSize, 2608 uint64_t addedInstanceSize,
2603 const std::string& newPatientId) 2609 const std::string& newPatientId)
2604 { 2610 {
2605 // TODO - Performance: Avoid calls to "IsRecyclingNeeded()" 2611 // TODO - Performance: Avoid calls to "IsRecyclingNeeded()"
2606 2612
2607 if (IsRecyclingNeeded(db_, maximumStorageSize, maximumPatients, addedInstanceSize)) 2613 if (IsRecyclingNeeded(transaction_, maximumStorageSize, maximumPatients, addedInstanceSize))
2608 { 2614 {
2609 // Check whether other DICOM instances from this patient are 2615 // Check whether other DICOM instances from this patient are
2610 // already stored 2616 // already stored
2611 int64_t patientToAvoid; 2617 int64_t patientToAvoid;
2612 bool hasPatientToAvoid; 2618 bool hasPatientToAvoid;
2616 hasPatientToAvoid = false; 2622 hasPatientToAvoid = false;
2617 } 2623 }
2618 else 2624 else
2619 { 2625 {
2620 ResourceType type; 2626 ResourceType type;
2621 hasPatientToAvoid = db_.LookupResource(patientToAvoid, type, newPatientId); 2627 hasPatientToAvoid = transaction_.LookupResource(patientToAvoid, type, newPatientId);
2622 if (type != ResourceType_Patient) 2628 if (type != ResourceType_Patient)
2623 { 2629 {
2624 throw OrthancException(ErrorCode_InternalError); 2630 throw OrthancException(ErrorCode_InternalError);
2625 } 2631 }
2626 } 2632 }
2631 while (true) 2637 while (true)
2632 { 2638 {
2633 // If other instances of this patient are already in the store, 2639 // If other instances of this patient are already in the store,
2634 // we must avoid to recycle them 2640 // we must avoid to recycle them
2635 bool ok = (hasPatientToAvoid ? 2641 bool ok = (hasPatientToAvoid ?
2636 db_.SelectPatientToRecycle(patientToRecycle, patientToAvoid) : 2642 transaction_.SelectPatientToRecycle(patientToRecycle, patientToAvoid) :
2637 db_.SelectPatientToRecycle(patientToRecycle)); 2643 transaction_.SelectPatientToRecycle(patientToRecycle));
2638 2644
2639 if (!ok) 2645 if (!ok)
2640 { 2646 {
2641 throw OrthancException(ErrorCode_FullStorage); 2647 throw OrthancException(ErrorCode_FullStorage);
2642 } 2648 }
2643 2649
2644 LOG(TRACE) << "Recycling one patient"; 2650 LOG(TRACE) << "Recycling one patient";
2645 db_.DeleteResource(patientToRecycle); 2651 transaction_.DeleteResource(patientToRecycle);
2646 2652
2647 if (!IsRecyclingNeeded(db_, maximumStorageSize, maximumPatients, addedInstanceSize)) 2653 if (!IsRecyclingNeeded(transaction_, maximumStorageSize, maximumPatients, addedInstanceSize))
2648 { 2654 {
2649 // OK, we're done 2655 // OK, we're done
2650 return; 2656 return;
2651 } 2657 }
2652 } 2658 }