880 lines
29 KiB
C++
880 lines
29 KiB
C++
/**
|
|
* Orthanc - A Lightweight, RESTful DICOM Store
|
|
* Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
|
|
* Department, University Hospital of Liege, Belgium
|
|
* Copyright (C) 2017-2023 Osimis S.A., Belgium
|
|
* Copyright (C) 2024-2025 Orthanc Team SRL, Belgium
|
|
* Copyright (C) 2021-2025 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
|
|
*
|
|
* This program is free software: you can redistribute it and/or
|
|
* modify it under the terms of the GNU 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
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
**/
|
|
|
|
|
|
#pragma once
|
|
|
|
#include "../../../OrthancFramework/Sources/DicomFormat/DicomMap.h"
|
|
|
|
#include "../DicomInstanceOrigin.h"
|
|
#include "IDatabaseWrapper.h"
|
|
#include "MainDicomTagsRegistry.h"
|
|
|
|
#include <boost/shared_ptr.hpp>
|
|
#include <boost/thread/shared_mutex.hpp>
|
|
|
|
|
|
namespace Orthanc
|
|
{
|
|
class DatabaseLookup;
|
|
class ParsedDicomFile;
|
|
struct ServerIndexChange;
|
|
|
|
class StatelessDatabaseOperations : public boost::noncopyable
|
|
{
|
|
public:
|
|
typedef std::list<FileInfo> Attachments;
|
|
typedef std::map<std::pair<ResourceType, MetadataType>, std::string> MetadataMap;
|
|
|
|
enum LabelOperation
|
|
{
|
|
LabelOperation_Add,
|
|
LabelOperation_Remove
|
|
};
|
|
|
|
class ITransactionContext : public IDatabaseListener
|
|
{
|
|
public:
|
|
virtual ~ITransactionContext()
|
|
{
|
|
}
|
|
|
|
virtual void Commit() = 0;
|
|
|
|
virtual int64_t GetCompressedSizeDelta() = 0;
|
|
|
|
virtual bool IsUnstableResource(Orthanc::ResourceType type,
|
|
int64_t id) = 0;
|
|
|
|
virtual bool LookupRemainingLevel(std::string& remainingPublicId /* out */,
|
|
ResourceType& remainingLevel /* out */) = 0;
|
|
|
|
virtual void MarkAsUnstable(Orthanc::ResourceType type,
|
|
int64_t id,
|
|
const std::string& publicId) = 0;
|
|
|
|
virtual void SignalAttachmentsAdded(uint64_t compressedSize) = 0;
|
|
|
|
virtual void SignalChange(const ServerIndexChange& change) = 0;
|
|
};
|
|
|
|
|
|
class ITransactionContextFactory : public boost::noncopyable
|
|
{
|
|
public:
|
|
virtual ~ITransactionContextFactory()
|
|
{
|
|
}
|
|
|
|
// WARNING: This method can be invoked from several threads concurrently
|
|
virtual ITransactionContext* Create() = 0;
|
|
};
|
|
|
|
|
|
class ReadOnlyTransaction : public boost::noncopyable
|
|
{
|
|
private:
|
|
ITransactionContext& context_;
|
|
|
|
protected:
|
|
IDatabaseWrapper::ITransaction& transaction_;
|
|
|
|
public:
|
|
explicit ReadOnlyTransaction(IDatabaseWrapper::ITransaction& transaction,
|
|
ITransactionContext& context) :
|
|
context_(context),
|
|
transaction_(transaction)
|
|
{
|
|
}
|
|
|
|
ITransactionContext& GetTransactionContext()
|
|
{
|
|
return context_;
|
|
}
|
|
|
|
/**
|
|
* Higher-level constructions
|
|
**/
|
|
|
|
SeriesStatus GetSeriesStatus(int64_t id,
|
|
int64_t expectedNumberOfInstances);
|
|
|
|
|
|
/**
|
|
* Read-only methods from "IDatabaseWrapper"
|
|
**/
|
|
|
|
void GetAllMetadata(std::map<MetadataType, std::string>& target,
|
|
int64_t id)
|
|
{
|
|
transaction_.GetAllMetadata(target, id);
|
|
}
|
|
|
|
void GetChanges(std::list<ServerIndexChange>& target /*out*/,
|
|
bool& done /*out*/,
|
|
int64_t since,
|
|
uint32_t limit)
|
|
{
|
|
transaction_.GetChanges(target, done, since, limit);
|
|
}
|
|
|
|
void GetChangesExtended(std::list<ServerIndexChange>& target /*out*/,
|
|
bool& done /*out*/,
|
|
int64_t since,
|
|
int64_t to,
|
|
uint32_t limit,
|
|
const std::set<ChangeType>& filterType)
|
|
{
|
|
transaction_.GetChangesExtended(target, done, since, to, limit, filterType);
|
|
}
|
|
|
|
void GetChildrenInternalId(std::list<int64_t>& target,
|
|
int64_t id)
|
|
{
|
|
transaction_.GetChildrenInternalId(target, id);
|
|
}
|
|
|
|
void GetExportedResources(std::list<ExportedResource>& target /*out*/,
|
|
bool& done /*out*/,
|
|
int64_t since,
|
|
uint32_t limit)
|
|
{
|
|
return transaction_.GetExportedResources(target, done, since, limit);
|
|
}
|
|
|
|
void GetLastChange(std::list<ServerIndexChange>& target /*out*/)
|
|
{
|
|
transaction_.GetLastChange(target);
|
|
}
|
|
|
|
void GetLastExportedResource(std::list<ExportedResource>& target /*out*/)
|
|
{
|
|
return transaction_.GetLastExportedResource(target);
|
|
}
|
|
|
|
int64_t GetLastChangeIndex()
|
|
{
|
|
return transaction_.GetLastChangeIndex();
|
|
}
|
|
|
|
void GetMainDicomTags(DicomMap& map,
|
|
int64_t id)
|
|
{
|
|
transaction_.GetMainDicomTags(map, id);
|
|
}
|
|
|
|
std::string GetPublicId(int64_t resourceId)
|
|
{
|
|
return transaction_.GetPublicId(resourceId);
|
|
}
|
|
|
|
uint64_t GetResourcesCount(ResourceType resourceType)
|
|
{
|
|
return transaction_.GetResourcesCount(resourceType);
|
|
}
|
|
|
|
ResourceType GetResourceType(int64_t resourceId)
|
|
{
|
|
return transaction_.GetResourceType(resourceId);
|
|
}
|
|
|
|
uint64_t GetTotalCompressedSize()
|
|
{
|
|
return transaction_.GetTotalCompressedSize();
|
|
}
|
|
|
|
uint64_t GetTotalUncompressedSize()
|
|
{
|
|
return transaction_.GetTotalUncompressedSize();
|
|
}
|
|
|
|
bool IsProtectedPatient(int64_t internalId)
|
|
{
|
|
return transaction_.IsProtectedPatient(internalId);
|
|
}
|
|
|
|
void ListAvailableAttachments(std::set<FileContentType>& target,
|
|
int64_t id)
|
|
{
|
|
transaction_.ListAvailableAttachments(target, id);
|
|
}
|
|
|
|
bool LookupAttachment(FileInfo& attachment,
|
|
int64_t& revision,
|
|
int64_t id,
|
|
FileContentType contentType)
|
|
{
|
|
return transaction_.LookupAttachment(attachment, revision, id, contentType);
|
|
}
|
|
|
|
void GetAttachmentCustomData(std::string& customData,
|
|
const std::string& attachmentUuid)
|
|
{
|
|
return transaction_.GetAttachmentCustomData(customData, attachmentUuid);
|
|
}
|
|
|
|
bool LookupGlobalProperty(std::string& target,
|
|
GlobalProperty property,
|
|
bool shared)
|
|
{
|
|
return transaction_.LookupGlobalProperty(target, property, shared);
|
|
}
|
|
|
|
bool LookupMetadata(std::string& target,
|
|
int64_t& revision,
|
|
int64_t id,
|
|
MetadataType type)
|
|
{
|
|
return transaction_.LookupMetadata(target, revision, id, type);
|
|
}
|
|
|
|
bool LookupParent(int64_t& parentId,
|
|
int64_t resourceId)
|
|
{
|
|
return transaction_.LookupParent(parentId, resourceId);
|
|
}
|
|
|
|
bool LookupResource(int64_t& id,
|
|
ResourceType& type,
|
|
const std::string& publicId)
|
|
{
|
|
return transaction_.LookupResource(id, type, publicId);
|
|
}
|
|
|
|
void ListAllLabels(std::set<std::string>& target)
|
|
{
|
|
transaction_.ListAllLabels(target);
|
|
}
|
|
|
|
bool HasReachedMaxStorageSize(uint64_t maximumStorageSize,
|
|
uint64_t addedInstanceSize);
|
|
|
|
bool HasReachedMaxPatientCount(unsigned int maximumPatientCount,
|
|
const std::string& patientId);
|
|
|
|
void ExecuteCount(uint64_t& count,
|
|
const FindRequest& request,
|
|
const IDatabaseWrapper::Capabilities& capabilities)
|
|
{
|
|
transaction_.ExecuteCount(count, request, capabilities);
|
|
}
|
|
|
|
void ExecuteFind(FindResponse& response,
|
|
const FindRequest& request,
|
|
const IDatabaseWrapper::Capabilities& capabilities)
|
|
{
|
|
transaction_.ExecuteFind(response, request, capabilities);
|
|
}
|
|
|
|
void ExecuteFind(std::list<std::string>& identifiers,
|
|
const IDatabaseWrapper::Capabilities& capabilities,
|
|
const FindRequest& request)
|
|
{
|
|
transaction_.ExecuteFind(identifiers, capabilities, request);
|
|
}
|
|
|
|
void ExecuteExpand(FindResponse& response,
|
|
const IDatabaseWrapper::Capabilities& capabilities,
|
|
const FindRequest& request,
|
|
const std::string& identifier)
|
|
{
|
|
transaction_.ExecuteExpand(response, capabilities, request, identifier);
|
|
}
|
|
|
|
bool GetKeyValue(std::string& value,
|
|
const std::string& storeId,
|
|
const std::string& key)
|
|
{
|
|
return transaction_.GetKeyValue(value, storeId, key);
|
|
}
|
|
|
|
uint64_t GetQueueSize(const std::string& queueId)
|
|
{
|
|
return transaction_.GetQueueSize(queueId);
|
|
}
|
|
|
|
void ListKeysValues(std::list<std::string>& keys,
|
|
std::list<std::string>& values,
|
|
const std::string& storeId,
|
|
bool first,
|
|
const std::string& from,
|
|
uint64_t limit)
|
|
{
|
|
return transaction_.ListKeysValues(keys, values, storeId, first, from, limit);
|
|
}
|
|
};
|
|
|
|
|
|
class ReadWriteTransaction : public ReadOnlyTransaction
|
|
{
|
|
public:
|
|
ReadWriteTransaction(IDatabaseWrapper::ITransaction& transaction,
|
|
ITransactionContext& context) :
|
|
ReadOnlyTransaction(transaction, context)
|
|
{
|
|
}
|
|
|
|
void AddAttachment(int64_t id,
|
|
const FileInfo& attachment,
|
|
int64_t revision)
|
|
{
|
|
transaction_.AddAttachment(id, attachment, revision);
|
|
}
|
|
|
|
void ClearChanges()
|
|
{
|
|
transaction_.ClearChanges();
|
|
}
|
|
|
|
void ClearExportedResources()
|
|
{
|
|
transaction_.ClearExportedResources();
|
|
}
|
|
|
|
void ClearMainDicomTags(int64_t id)
|
|
{
|
|
return transaction_.ClearMainDicomTags(id);
|
|
}
|
|
|
|
bool CreateInstance(IDatabaseWrapper::CreateInstanceResult& result, /* out */
|
|
int64_t& instanceId, /* out */
|
|
const std::string& patient,
|
|
const std::string& study,
|
|
const std::string& series,
|
|
const std::string& instance)
|
|
{
|
|
return transaction_.CreateInstance(result, instanceId, patient, study, series, instance);
|
|
}
|
|
|
|
void DeleteAttachment(int64_t id,
|
|
FileContentType attachment)
|
|
{
|
|
return transaction_.DeleteAttachment(id, attachment);
|
|
}
|
|
|
|
void DeleteMetadata(int64_t id,
|
|
MetadataType type)
|
|
{
|
|
transaction_.DeleteMetadata(id, type);
|
|
}
|
|
|
|
void DeleteResource(int64_t id)
|
|
{
|
|
transaction_.DeleteResource(id);
|
|
}
|
|
|
|
void LogChange(int64_t internalId,
|
|
ChangeType changeType,
|
|
ResourceType resourceType,
|
|
const std::string& publicId);
|
|
|
|
void LogExportedResource(const ExportedResource& resource)
|
|
{
|
|
transaction_.LogExportedResource(resource);
|
|
}
|
|
|
|
void SetGlobalProperty(GlobalProperty property,
|
|
bool shared,
|
|
const std::string& value)
|
|
{
|
|
transaction_.SetGlobalProperty(property, shared, value);
|
|
}
|
|
|
|
int64_t IncrementGlobalProperty(GlobalProperty sequence,
|
|
bool shared,
|
|
int64_t increment)
|
|
{
|
|
return transaction_.IncrementGlobalProperty(sequence, shared, increment);
|
|
}
|
|
|
|
void UpdateAndGetStatistics(int64_t& patientsCount,
|
|
int64_t& studiesCount,
|
|
int64_t& seriesCount,
|
|
int64_t& instancesCount,
|
|
int64_t& compressedSize,
|
|
int64_t& uncompressedSize)
|
|
{
|
|
return transaction_.UpdateAndGetStatistics(patientsCount, studiesCount, seriesCount, instancesCount, compressedSize, uncompressedSize);
|
|
}
|
|
|
|
void SetMetadata(int64_t id,
|
|
MetadataType type,
|
|
const std::string& value,
|
|
int64_t revision)
|
|
{
|
|
return transaction_.SetMetadata(id, type, value, revision);
|
|
}
|
|
|
|
void SetProtectedPatient(int64_t internalId,
|
|
bool isProtected)
|
|
{
|
|
transaction_.SetProtectedPatient(internalId, isProtected);
|
|
}
|
|
|
|
void SetResourcesContent(const ResourcesContent& content)
|
|
{
|
|
transaction_.SetResourcesContent(content);
|
|
}
|
|
|
|
void Recycle(uint64_t maximumStorageSize,
|
|
unsigned int maximumPatients,
|
|
uint64_t addedInstanceSize,
|
|
const std::string& newPatientId);
|
|
|
|
bool IsRecyclingNeeded(uint64_t maximumStorageSize,
|
|
unsigned int maximumPatients,
|
|
uint64_t addedInstanceSize,
|
|
const std::string& newPatientId);
|
|
|
|
void AddLabel(int64_t id,
|
|
const std::string& label)
|
|
{
|
|
transaction_.AddLabel(id, label);
|
|
}
|
|
|
|
void RemoveLabel(int64_t id,
|
|
const std::string& label)
|
|
{
|
|
transaction_.RemoveLabel(id, label);
|
|
}
|
|
|
|
void StoreKeyValue(const std::string& storeId,
|
|
const std::string& key,
|
|
const void* value,
|
|
size_t valueSize)
|
|
{
|
|
transaction_.StoreKeyValue(storeId, key, value, valueSize);
|
|
}
|
|
|
|
void DeleteKeyValue(const std::string& storeId,
|
|
const std::string& key)
|
|
{
|
|
transaction_.DeleteKeyValue(storeId, key);
|
|
}
|
|
|
|
void EnqueueValue(const std::string& queueId,
|
|
const void* value,
|
|
size_t valueSize)
|
|
{
|
|
transaction_.EnqueueValue(queueId, value, valueSize);
|
|
}
|
|
|
|
bool DequeueValue(std::string& value,
|
|
const std::string& queueId,
|
|
QueueOrigin origin)
|
|
{
|
|
return transaction_.DequeueValue(value, queueId, origin);
|
|
}
|
|
|
|
void SetAttachmentCustomData(const std::string& attachmentUuid,
|
|
const void* customData,
|
|
size_t customDataSize)
|
|
{
|
|
return transaction_.SetAttachmentCustomData(attachmentUuid, customData, customDataSize);
|
|
}
|
|
};
|
|
|
|
|
|
class IReadOnlyOperations : public boost::noncopyable
|
|
{
|
|
public:
|
|
virtual ~IReadOnlyOperations()
|
|
{
|
|
}
|
|
|
|
virtual void Apply(ReadOnlyTransaction& transaction) = 0;
|
|
};
|
|
|
|
|
|
class IReadWriteOperations : public boost::noncopyable
|
|
{
|
|
public:
|
|
virtual ~IReadWriteOperations()
|
|
{
|
|
}
|
|
|
|
virtual void Apply(ReadWriteTransaction& transaction) = 0;
|
|
};
|
|
|
|
|
|
private:
|
|
class Transaction;
|
|
|
|
IDatabaseWrapper& db_;
|
|
boost::shared_ptr<MainDicomTagsRegistry> mainDicomTagsRegistry_; // "shared_ptr" because of PImpl
|
|
|
|
// Mutex to protect the configuration options
|
|
boost::shared_mutex mutex_;
|
|
std::unique_ptr<ITransactionContextFactory> factory_;
|
|
unsigned int maxRetries_;
|
|
bool readOnly_;
|
|
|
|
void ApplyInternal(IReadOnlyOperations* readOperations,
|
|
IReadWriteOperations* writeOperations);
|
|
|
|
const FindResponse::Resource &ExecuteSingleResource(FindResponse &response,
|
|
const FindRequest &request);
|
|
|
|
protected:
|
|
void StandaloneRecycling(MaxStorageMode maximumStorageMode,
|
|
uint64_t maximumStorageSize,
|
|
unsigned int maximumPatientCount);
|
|
|
|
bool IsReadOnly()
|
|
{
|
|
return readOnly_;
|
|
}
|
|
|
|
public:
|
|
explicit StatelessDatabaseOperations(IDatabaseWrapper& database, bool readOnly);
|
|
|
|
void SetTransactionContextFactory(ITransactionContextFactory* factory /* takes ownership */);
|
|
|
|
// Only used to handle "ErrorCode_DatabaseCannotSerialize" in the
|
|
// case of collision between multiple writers
|
|
void SetMaxDatabaseRetries(unsigned int maxRetries);
|
|
|
|
// It is assumed that "GetDatabaseVersion()" can run out of a
|
|
// database transaction
|
|
unsigned int GetDatabaseVersion()
|
|
{
|
|
return db_.GetDatabaseVersion();
|
|
}
|
|
|
|
const IDatabaseWrapper::Capabilities GetDatabaseCapabilities() const
|
|
{
|
|
return db_.GetDatabaseCapabilities();
|
|
}
|
|
|
|
void FlushToDisk();
|
|
|
|
|
|
void Apply(IReadOnlyOperations& operations);
|
|
|
|
void Apply(IReadWriteOperations& operations);
|
|
|
|
void GetAllMetadata(std::map<MetadataType, std::string>& target,
|
|
const std::string& publicId,
|
|
ResourceType level);
|
|
|
|
void GetAllUuids(std::list<std::string>& target,
|
|
ResourceType resourceType);
|
|
|
|
void GetGlobalStatistics(/* out */ uint64_t& diskSize,
|
|
/* out */ uint64_t& uncompressedSize,
|
|
/* out */ uint64_t& countPatients,
|
|
/* out */ uint64_t& countStudies,
|
|
/* out */ uint64_t& countSeries,
|
|
/* out */ uint64_t& countInstances);
|
|
|
|
void GetAttachmentCustomData(std::string& customData,
|
|
const std::string& attachmentUuid);
|
|
|
|
void SetAttachmentCustomData(const std::string& attachmentUuid,
|
|
const void* customData,
|
|
size_t customDataSize);
|
|
|
|
bool LookupAttachment(FileInfo& attachment,
|
|
int64_t& revision,
|
|
ResourceType level,
|
|
const std::string& publicId,
|
|
FileContentType contentType);
|
|
|
|
void GetChanges(Json::Value& target,
|
|
int64_t since,
|
|
uint32_t limit);
|
|
|
|
void GetChangesExtended(Json::Value& target,
|
|
int64_t since,
|
|
int64_t to,
|
|
uint32_t limit,
|
|
const std::set<ChangeType>& filterType);
|
|
|
|
void GetLastChange(Json::Value& target);
|
|
|
|
bool HasExtendedChanges();
|
|
|
|
bool HasFindSupport();
|
|
|
|
bool HasAttachmentCustomDataSupport();
|
|
|
|
bool HasKeyValueStoresSupport();
|
|
|
|
bool HasQueuesSupport();
|
|
|
|
void GetExportedResources(Json::Value& target,
|
|
int64_t since,
|
|
uint32_t limit);
|
|
|
|
void GetLastExportedResource(Json::Value& target);
|
|
|
|
bool IsProtectedPatient(const std::string& publicId);
|
|
|
|
void GetChildren(std::list<std::string>& result,
|
|
ResourceType level,
|
|
const std::string& publicId);
|
|
|
|
// Always prefer this flavor, which is more efficient than the flavor without "level"
|
|
void GetChildInstances(std::list<std::string>& result,
|
|
const std::string& publicId,
|
|
ResourceType level);
|
|
|
|
void GetChildInstances(std::list<std::string>& result,
|
|
const std::string& publicId);
|
|
|
|
bool LookupMetadata(std::string& target,
|
|
const std::string& publicId,
|
|
ResourceType expectedType,
|
|
MetadataType type);
|
|
|
|
bool LookupMetadata(std::string& target,
|
|
int64_t& revision,
|
|
const std::string& publicId,
|
|
ResourceType expectedType,
|
|
MetadataType type);
|
|
|
|
void ListAvailableAttachments(std::set<FileContentType>& target,
|
|
const std::string& publicId,
|
|
ResourceType expectedType);
|
|
|
|
bool LookupParent(std::string& target,
|
|
const std::string& publicId);
|
|
|
|
void GetResourceStatistics(/* out */ ResourceType& type,
|
|
/* out */ uint64_t& diskSize,
|
|
/* out */ uint64_t& uncompressedSize,
|
|
/* out */ unsigned int& countStudies,
|
|
/* out */ unsigned int& countSeries,
|
|
/* out */ unsigned int& countInstances,
|
|
/* out */ uint64_t& dicomDiskSize,
|
|
/* out */ uint64_t& dicomUncompressedSize,
|
|
const std::string& publicId);
|
|
|
|
void LookupIdentifierExact(std::vector<std::string>& result,
|
|
ResourceType level,
|
|
const DicomTag& tag,
|
|
const std::string& value);
|
|
|
|
bool LookupGlobalProperty(std::string& value,
|
|
GlobalProperty property,
|
|
bool shared);
|
|
|
|
std::string GetGlobalProperty(GlobalProperty property,
|
|
bool shared,
|
|
const std::string& defaultValue);
|
|
|
|
bool GetMainDicomTags(DicomMap& result,
|
|
const std::string& publicId,
|
|
ResourceType expectedType,
|
|
ResourceType levelOfInterest);
|
|
|
|
// Only applicable at the instance level, retrieves tags from patient/study/series levels
|
|
bool GetAllMainDicomTags(DicomMap& result,
|
|
const std::string& instancePublicId);
|
|
|
|
bool LookupResourceType(ResourceType& type,
|
|
const std::string& publicId);
|
|
|
|
bool LookupParent(std::string& target,
|
|
const std::string& publicId,
|
|
ResourceType parentType);
|
|
|
|
bool DeleteResource(Json::Value& remainingAncestor /* out */,
|
|
const std::string& uuid,
|
|
ResourceType expectedType);
|
|
|
|
void LogExportedResource(const std::string& publicId,
|
|
const std::string& remoteModality);
|
|
|
|
void SetProtectedPatient(const std::string& publicId,
|
|
bool isProtected);
|
|
|
|
void SetMetadata(int64_t& newRevision /*out*/,
|
|
const std::string& publicId,
|
|
MetadataType type,
|
|
const std::string& value,
|
|
bool hasOldRevision,
|
|
int64_t oldRevision,
|
|
const std::string& oldMD5);
|
|
|
|
// Same as "SetMetadata()", but doesn't care about revisions
|
|
void OverwriteMetadata(const std::string& publicId,
|
|
MetadataType type,
|
|
const std::string& value);
|
|
|
|
bool DeleteMetadata(const std::string& publicId,
|
|
MetadataType type,
|
|
bool hasRevision,
|
|
int64_t revision,
|
|
const std::string& md5);
|
|
|
|
uint64_t IncrementGlobalSequence(GlobalProperty sequence,
|
|
bool shared);
|
|
|
|
void DeleteChanges();
|
|
|
|
void DeleteExportedResources();
|
|
|
|
void SetGlobalProperty(GlobalProperty property,
|
|
bool shared,
|
|
const std::string& value);
|
|
|
|
bool DeleteAttachment(const std::string& publicId,
|
|
FileContentType type,
|
|
bool hasRevision,
|
|
int64_t revision,
|
|
const std::string& md5);
|
|
|
|
void LogChange(int64_t internalId,
|
|
ChangeType changeType,
|
|
const std::string& publicId,
|
|
ResourceType level);
|
|
|
|
void ReconstructInstance(const ParsedDicomFile& dicom,
|
|
bool limitToThisLevelDicomTags,
|
|
ResourceType limitToLevel_);
|
|
|
|
StoreStatus Store(std::map<MetadataType, std::string>& instanceMetadata,
|
|
const DicomMap& dicomSummary,
|
|
const Attachments& attachments,
|
|
const MetadataMap& metadata,
|
|
const DicomInstanceOrigin& origin,
|
|
bool overwrite,
|
|
bool hasTransferSyntax,
|
|
DicomTransferSyntax transferSyntax,
|
|
bool hasPixelDataOffset,
|
|
uint64_t pixelDataOffset,
|
|
ValueRepresentation pixelDataVR,
|
|
MaxStorageMode maximumStorageMode,
|
|
uint64_t maximumStorageSize,
|
|
unsigned int maximumPatients,
|
|
bool isReconstruct);
|
|
|
|
StoreStatus AddAttachment(int64_t& newRevision /*out*/,
|
|
const FileInfo& attachment,
|
|
const std::string& publicId,
|
|
uint64_t maximumStorageSize,
|
|
unsigned int maximumPatients,
|
|
bool hasOldRevision,
|
|
int64_t oldRevision,
|
|
const std::string& oldMd5);
|
|
|
|
void ListLabels(std::set<std::string>& target,
|
|
const std::string& publicId,
|
|
ResourceType level);
|
|
|
|
void ListAllLabels(std::set<std::string>& target);
|
|
|
|
void ModifyLabel(const std::string& publicId,
|
|
ResourceType level,
|
|
const std::string& label,
|
|
LabelOperation operation);
|
|
|
|
void AddLabels(const std::string& publicId,
|
|
ResourceType level,
|
|
const std::set<std::string>& labels);
|
|
|
|
bool HasLabelsSupport();
|
|
|
|
void ExecuteFind(FindResponse& response,
|
|
const FindRequest& request);
|
|
|
|
void ExecuteCount(uint64_t& count,
|
|
const FindRequest& request);
|
|
|
|
void StoreKeyValue(const std::string& storeId,
|
|
const std::string& key,
|
|
const void* value,
|
|
size_t valueSize);
|
|
|
|
void StoreKeyValue(const std::string& storeId,
|
|
const std::string& key,
|
|
const std::string& value)
|
|
{
|
|
StoreKeyValue(storeId, key, value.empty() ? NULL : value.c_str(), value.size());
|
|
}
|
|
|
|
void DeleteKeyValue(const std::string& storeId,
|
|
const std::string& key);
|
|
|
|
bool GetKeyValue(std::string& value,
|
|
const std::string& storeId,
|
|
const std::string& key);
|
|
|
|
void EnqueueValue(const std::string& queueId,
|
|
const void* value,
|
|
size_t valueSize);
|
|
|
|
void EnqueueValue(const std::string& queueId,
|
|
const std::string& value)
|
|
{
|
|
EnqueueValue(queueId, value.empty() ? NULL : value.c_str(), value.size());
|
|
}
|
|
|
|
bool DequeueValue(std::string& value,
|
|
const std::string& queueId,
|
|
QueueOrigin origin);
|
|
|
|
uint64_t GetQueueSize(const std::string& queueId);
|
|
|
|
class KeysValuesIterator : public boost::noncopyable
|
|
{
|
|
private:
|
|
enum State
|
|
{
|
|
State_Waiting,
|
|
State_Available,
|
|
State_Done
|
|
};
|
|
|
|
StatelessDatabaseOperations& db_;
|
|
State state_;
|
|
std::string storeId_;
|
|
uint64_t limit_;
|
|
std::list<std::string> keys_;
|
|
std::list<std::string> values_;
|
|
std::list<std::string>::const_iterator currentKey_;
|
|
std::list<std::string>::const_iterator currentValue_;
|
|
|
|
public:
|
|
KeysValuesIterator(StatelessDatabaseOperations& db,
|
|
const std::string& storeId);
|
|
|
|
void SetLimit(uint64_t limit)
|
|
{
|
|
limit_ = limit;
|
|
}
|
|
|
|
uint64_t GetLimit() const
|
|
{
|
|
return limit_;
|
|
}
|
|
|
|
bool Next();
|
|
|
|
const std::string& GetKey() const;
|
|
|
|
const std::string& GetValue() const;
|
|
};
|
|
};
|
|
}
|