Mercurial > hg > orthanc-education
view Sources/Models/DocumentOrientedDatabase.cpp @ 77:80b663d5f8fe default tip
replaced boost::math::iround() by Orthanc::Math::llround()
| author | Sebastien Jodogne <s.jodogne@gmail.com> |
|---|---|
| date | Tue, 27 Jan 2026 17:05:03 +0100 |
| parents | 0f8c46d755e2 |
| children |
line wrap: on
line source
/** * SPDX-FileCopyrightText: 2024-2026 Sebastien Jodogne, EPL UCLouvain, Belgium * SPDX-License-Identifier: AGPL-3.0-or-later */ /** * Orthanc for Education * Copyright (C) 2024-2026 Sebastien Jodogne, EPL UCLouvain, Belgium * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Affero General Public License * as published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. **/ #include "DocumentOrientedDatabase.h" #include <Logging.h> #include <OrthancException.h> #include <OrthancPluginCppWrapper.h> #include <SerializationToolbox.h> #include <Toolbox.h> #include <cassert> void DocumentOrientedDatabase::Clear() { for (Documents::iterator it = documents_.begin(); it != documents_.end(); ++it) { assert(it->second != NULL); delete it->second; } documents_.clear(); } void DocumentOrientedDatabase::StoreInternal(const std::string& key, ISerializableDocument* value, const std::string& serialized) { // Mutex be locked in writer mode assert(value != NULL); std::unique_ptr<ISerializableDocument> protection(value); Documents::iterator found = documents_.find(key); if (found == documents_.end()) { documents_[key] = protection.release(); } else { assert(found->second != NULL); delete found->second; found->second = protection.release(); } { // Only modify the Orthanc database once we're sure the memory has been properly updated OrthancPlugins::KeyValueStore store(storeId_); store.Store(key, serialized); } } DocumentOrientedDatabase::DocumentOrientedDatabase(const std::string& storeId, IDocumentUnserializer* unserializer /* takes ownership */) : storeId_(storeId), unserializer_(unserializer) { if (unserializer == NULL) { throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); } } void DocumentOrientedDatabase::Load() { boost::unique_lock<boost::shared_mutex> lock(mutex_); Clear(); OrthancPlugins::KeyValueStore store(storeId_); std::unique_ptr<OrthancPlugins::KeyValueStore::Iterator> iterator(store.CreateIterator()); while (iterator->Next()) { if (documents_.find(iterator->GetKey()) != documents_.end()) { throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); } std::string serialized; iterator->GetValue(serialized); bool ok = false; Json::Value json; if (Orthanc::Toolbox::ReadJson(json, serialized)) { try { documents_[iterator->GetKey()] = unserializer_->Unserialize(json); ok = true; } catch (Orthanc::OrthancException& e) { } } if (!ok) { LOG(WARNING) << "Cannot unserialize document \"" << iterator->GetKey() << "\" from key-value store \"" << storeId_ << "\""; } } } void DocumentOrientedDatabase::Store(const std::string& key, ISerializableDocument* document /* takes ownership */) { std::unique_ptr<ISerializableDocument> protection(document); if (document == NULL) { throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); } Json::Value serialized; protection->Serialize(serialized); std::string value; Orthanc::Toolbox::WriteFastJson(value, serialized); { boost::unique_lock<boost::shared_mutex> lock(mutex_); StoreInternal(key, protection.release(), value); } } void DocumentOrientedDatabase::Remove(const std::string& key) { boost::unique_lock<boost::shared_mutex> lock(mutex_); Documents::iterator found = documents_.find(key); if (found != documents_.end()) { assert(found->second != NULL); delete found->second; documents_.erase(key); } { // Only modify the Orthanc database once we're sure the memory has been properly updated OrthancPlugins::KeyValueStore store(storeId_); store.DeleteKey(key); } } DocumentOrientedDatabase::Iterator::Iterator(DocumentOrientedDatabase& database) : lock_(database.mutex_), first_(true), current_(database.documents_.begin()), end_(database.documents_.end()) { } bool DocumentOrientedDatabase::Iterator::Next() { if (first_) { first_ = false; return (current_ != end_); } else if (current_ == end_) { throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } else { ++current_; return (current_ != end_); } } const std::string& DocumentOrientedDatabase::Iterator::GetKey() const { if (first_ || current_ == end_) { throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } else { return current_->first; } } const ISerializableDocument& DocumentOrientedDatabase::Iterator::GetDocument() const { if (first_ || current_ == end_) { throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } else { assert(current_->second != NULL); return *current_->second; } } DocumentOrientedDatabase::Reader::Reader(DocumentOrientedDatabase& database) : lock_(database.mutex_), database_(database) { } const ISerializableDocument& DocumentOrientedDatabase::Reader::GetDocument(const std::string& key) const { Documents::const_iterator found = database_.documents_.find(key); if (found == database_.documents_.end()) { throw Orthanc::OrthancException(Orthanc::ErrorCode_UnknownResource); } else { assert(found->second != NULL); return *found->second; } } const ISerializableDocument* DocumentOrientedDatabase::Reader::LookupDocument(const std::string& key) const { Documents::const_iterator found = database_.documents_.find(key); if (found == database_.documents_.end()) { return NULL; } else { assert(found->second != NULL); return found->second; } } ISerializableDocument* DocumentOrientedDatabase::CloneDocument(const std::string& key) { Reader reader(*this); const ISerializableDocument* document = reader.LookupDocument(key); if (document == NULL) { return NULL; } else { assert(document != NULL); return document->Clone(); } }
