549 lines
19 KiB
C++
549 lines
19 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 "../../../OrthancFramework/Sources/FileStorage/FileInfo.h"
|
|
#include "../../../OrthancFramework/Sources/FileStorage/IStorageArea.h"
|
|
#include "../ExportedResource.h"
|
|
#include "../Search/ISqlLookupFormatter.h"
|
|
#include "../ServerIndexChange.h"
|
|
#include "FindRequest.h"
|
|
#include "FindResponse.h"
|
|
#include "IDatabaseListener.h"
|
|
|
|
#include <list>
|
|
#include <boost/noncopyable.hpp>
|
|
#include <set>
|
|
|
|
namespace Orthanc
|
|
{
|
|
class DatabaseDicomTagConstraints;
|
|
class ResourcesContent;
|
|
|
|
class IDatabaseWrapper : public boost::noncopyable
|
|
{
|
|
public:
|
|
class Capabilities
|
|
{
|
|
private:
|
|
bool hasFlushToDisk_;
|
|
bool hasRevisionsSupport_;
|
|
bool hasLabelsSupport_;
|
|
bool hasAtomicIncrementGlobalProperty_;
|
|
bool hasUpdateAndGetStatistics_;
|
|
bool hasMeasureLatency_;
|
|
bool hasFindSupport_;
|
|
bool hasExtendedChanges_;
|
|
bool hasAttachmentCustomDataSupport_;
|
|
bool hasKeyValueStoresSupport_;
|
|
bool hasQueuesSupport_;
|
|
|
|
public:
|
|
Capabilities() :
|
|
hasFlushToDisk_(false),
|
|
hasRevisionsSupport_(false),
|
|
hasLabelsSupport_(false),
|
|
hasAtomicIncrementGlobalProperty_(false),
|
|
hasUpdateAndGetStatistics_(false),
|
|
hasMeasureLatency_(false),
|
|
hasFindSupport_(false),
|
|
hasExtendedChanges_(false),
|
|
hasAttachmentCustomDataSupport_(false),
|
|
hasKeyValueStoresSupport_(false),
|
|
hasQueuesSupport_(false)
|
|
{
|
|
}
|
|
|
|
void SetFlushToDisk(bool value)
|
|
{
|
|
hasFlushToDisk_ = value;
|
|
}
|
|
|
|
bool HasFlushToDisk() const
|
|
{
|
|
return hasFlushToDisk_;
|
|
}
|
|
|
|
void SetRevisionsSupport(bool value)
|
|
{
|
|
hasRevisionsSupport_ = value;
|
|
}
|
|
|
|
bool HasRevisionsSupport() const
|
|
{
|
|
return hasRevisionsSupport_;
|
|
}
|
|
|
|
void SetLabelsSupport(bool value)
|
|
{
|
|
hasLabelsSupport_ = value;
|
|
}
|
|
|
|
bool HasLabelsSupport() const
|
|
{
|
|
return hasLabelsSupport_;
|
|
}
|
|
|
|
void SetAttachmentCustomDataSupport(bool value)
|
|
{
|
|
hasAttachmentCustomDataSupport_ = value;
|
|
}
|
|
|
|
bool HasAttachmentCustomDataSupport() const
|
|
{
|
|
return hasAttachmentCustomDataSupport_;
|
|
}
|
|
|
|
void SetHasExtendedChanges(bool value)
|
|
{
|
|
hasExtendedChanges_ = value;
|
|
}
|
|
|
|
bool HasExtendedChanges() const
|
|
{
|
|
return hasExtendedChanges_;
|
|
}
|
|
|
|
void SetAtomicIncrementGlobalProperty(bool value)
|
|
{
|
|
hasAtomicIncrementGlobalProperty_ = value;
|
|
}
|
|
|
|
bool HasAtomicIncrementGlobalProperty() const
|
|
{
|
|
return hasAtomicIncrementGlobalProperty_;
|
|
}
|
|
|
|
void SetHasUpdateAndGetStatistics(bool value)
|
|
{
|
|
hasUpdateAndGetStatistics_ = value;
|
|
}
|
|
|
|
bool HasUpdateAndGetStatistics() const
|
|
{
|
|
return hasUpdateAndGetStatistics_;
|
|
}
|
|
|
|
void SetMeasureLatency(bool value)
|
|
{
|
|
hasMeasureLatency_ = value;
|
|
}
|
|
|
|
bool HasMeasureLatency() const
|
|
{
|
|
return hasMeasureLatency_;
|
|
}
|
|
|
|
void SetHasFindSupport(bool value)
|
|
{
|
|
hasFindSupport_ = value;
|
|
}
|
|
|
|
bool HasFindSupport() const
|
|
{
|
|
return hasFindSupport_;
|
|
}
|
|
|
|
void SetKeyValueStoresSupport(bool value)
|
|
{
|
|
hasKeyValueStoresSupport_ = value;
|
|
}
|
|
|
|
bool HasKeyValueStoresSupport() const
|
|
{
|
|
return hasKeyValueStoresSupport_;
|
|
}
|
|
|
|
void SetQueuesSupport(bool value)
|
|
{
|
|
hasQueuesSupport_ = value;
|
|
}
|
|
|
|
bool HasQueuesSupport() const
|
|
{
|
|
return hasQueuesSupport_;
|
|
}
|
|
};
|
|
|
|
|
|
struct CreateInstanceResult : public boost::noncopyable
|
|
{
|
|
bool isNewPatient_;
|
|
bool isNewStudy_;
|
|
bool isNewSeries_;
|
|
int64_t patientId_;
|
|
int64_t studyId_;
|
|
int64_t seriesId_;
|
|
};
|
|
|
|
|
|
class ITransaction : public boost::noncopyable
|
|
{
|
|
public:
|
|
virtual ~ITransaction()
|
|
{
|
|
}
|
|
|
|
virtual void Rollback() = 0;
|
|
|
|
// The "fileSizeDelta" is used for older database plugins that
|
|
// have no fast way to compute the size of all the stored
|
|
// attachments (cf. "fastGetTotalSize_")
|
|
virtual void Commit(int64_t fileSizeDelta) = 0;
|
|
|
|
// A call to "AddAttachment()" guarantees that this attachment
|
|
// is not already existing. This is different from
|
|
// "SetMetadata()" that might have to replace an older value.
|
|
virtual void AddAttachment(int64_t id,
|
|
const FileInfo& attachment,
|
|
int64_t revision) = 0;
|
|
|
|
virtual void ClearChanges() = 0;
|
|
|
|
virtual void ClearExportedResources() = 0;
|
|
|
|
virtual void DeleteAttachment(int64_t id,
|
|
FileContentType attachment) = 0;
|
|
|
|
virtual void DeleteMetadata(int64_t id,
|
|
MetadataType type) = 0;
|
|
|
|
virtual void DeleteResource(int64_t id) = 0;
|
|
|
|
virtual void GetAllMetadata(std::map<MetadataType, std::string>& target,
|
|
int64_t id) = 0;
|
|
|
|
virtual void GetAllPublicIds(std::list<std::string>& target,
|
|
ResourceType resourceType) = 0;
|
|
|
|
virtual void GetChanges(std::list<ServerIndexChange>& target /*out*/,
|
|
bool& done /*out*/,
|
|
int64_t since,
|
|
uint32_t limit) = 0;
|
|
|
|
virtual void GetChildrenInternalId(std::list<int64_t>& target,
|
|
int64_t id) = 0;
|
|
|
|
virtual void GetExportedResources(std::list<ExportedResource>& target /*out*/,
|
|
bool& done /*out*/,
|
|
int64_t since,
|
|
uint32_t limit) = 0;
|
|
|
|
virtual void GetLastChange(std::list<ServerIndexChange>& target /*out*/) = 0;
|
|
|
|
virtual void GetLastExportedResource(std::list<ExportedResource>& target /*out*/) = 0;
|
|
|
|
virtual void GetMainDicomTags(DicomMap& map,
|
|
int64_t id) = 0;
|
|
|
|
virtual std::string GetPublicId(int64_t resourceId) = 0;
|
|
|
|
virtual uint64_t GetResourcesCount(ResourceType resourceType) = 0;
|
|
|
|
virtual ResourceType GetResourceType(int64_t resourceId) = 0;
|
|
|
|
virtual uint64_t GetTotalCompressedSize() = 0;
|
|
|
|
virtual uint64_t GetTotalUncompressedSize() = 0;
|
|
|
|
virtual bool IsProtectedPatient(int64_t internalId) = 0;
|
|
|
|
virtual void ListAvailableAttachments(std::set<FileContentType>& target,
|
|
int64_t id) = 0;
|
|
|
|
virtual void LogChange(ChangeType changeType,
|
|
ResourceType resourceType,
|
|
int64_t internalId,
|
|
const std::string& publicId, /* only for compatibility with V1 and V2 plugins */
|
|
const std::string& date) = 0;
|
|
|
|
virtual void LogExportedResource(const ExportedResource& resource) = 0;
|
|
|
|
virtual bool LookupAttachment(FileInfo& attachment,
|
|
int64_t& revision,
|
|
int64_t id,
|
|
FileContentType contentType) = 0;
|
|
|
|
virtual void GetAttachmentCustomData(std::string& customData,
|
|
const std::string& attachmentUuid) = 0;
|
|
|
|
virtual void SetAttachmentCustomData(const std::string& attachmentUuid,
|
|
const void* customData,
|
|
size_t customDataSize) = 0;
|
|
|
|
/**
|
|
* If "shared" is "true", the property is shared by all the
|
|
* Orthanc servers that access the same database. If "shared" is
|
|
* "false", the property is private to the server (cf. the
|
|
* "DatabaseServerIdentifier" configuration option).
|
|
**/
|
|
virtual bool LookupGlobalProperty(std::string& target,
|
|
GlobalProperty property,
|
|
bool shared) = 0;
|
|
|
|
virtual bool LookupMetadata(std::string& target,
|
|
int64_t& revision,
|
|
int64_t id,
|
|
MetadataType type) = 0;
|
|
|
|
virtual bool LookupParent(int64_t& parentId,
|
|
int64_t resourceId) = 0;
|
|
|
|
virtual bool LookupResource(int64_t& id,
|
|
ResourceType& type,
|
|
const std::string& publicId) = 0;
|
|
|
|
virtual bool SelectPatientToRecycle(int64_t& internalId) = 0;
|
|
|
|
virtual bool SelectPatientToRecycle(int64_t& internalId,
|
|
int64_t patientIdToAvoid) = 0;
|
|
|
|
virtual void SetGlobalProperty(GlobalProperty property,
|
|
bool shared,
|
|
const std::string& value) = 0;
|
|
|
|
virtual void ClearMainDicomTags(int64_t id) = 0;
|
|
|
|
virtual void SetMetadata(int64_t id,
|
|
MetadataType type,
|
|
const std::string& value,
|
|
int64_t revision) = 0;
|
|
|
|
virtual void SetProtectedPatient(int64_t internalId,
|
|
bool isProtected) = 0;
|
|
|
|
|
|
/**
|
|
* Primitives introduced in Orthanc 1.5.2
|
|
**/
|
|
|
|
virtual bool IsDiskSizeAbove(uint64_t threshold) = 0;
|
|
|
|
|
|
// Returns "true" iff. the instance is new and has been inserted
|
|
// into the database. If "false" is returned, the content of
|
|
// "result" is undefined, but "instanceId" must be properly
|
|
// set. This method must also tag the parent patient as the most
|
|
// recent in the patient recycling order if it is not protected
|
|
// (so as to fix issue #58).
|
|
virtual bool CreateInstance(CreateInstanceResult& result, /* out */
|
|
int64_t& instanceId, /* out */
|
|
const std::string& patient,
|
|
const std::string& study,
|
|
const std::string& series,
|
|
const std::string& instance) = 0;
|
|
|
|
// It is guaranteed that the resources to be modified have no main
|
|
// DICOM tags, and no DICOM identifiers associated with
|
|
// them. However, some metadata might be already existing, and
|
|
// have to be overwritten.
|
|
virtual void SetResourcesContent(const ResourcesContent& content) = 0;
|
|
|
|
virtual void GetChildrenMetadata(std::list<std::string>& target,
|
|
int64_t resourceId,
|
|
MetadataType metadata) = 0;
|
|
|
|
virtual int64_t GetLastChangeIndex() = 0;
|
|
|
|
|
|
/**
|
|
* Primitives introduced in Orthanc 1.12.0
|
|
**/
|
|
|
|
virtual void AddLabel(int64_t resource,
|
|
const std::string& label) = 0;
|
|
|
|
virtual void RemoveLabel(int64_t resource,
|
|
const std::string& label) = 0;
|
|
|
|
// List all the labels that are present in any resource
|
|
virtual void ListAllLabels(std::set<std::string>& target) = 0;
|
|
|
|
virtual int64_t IncrementGlobalProperty(GlobalProperty property,
|
|
int64_t increment,
|
|
bool shared) = 0;
|
|
|
|
// New in Orthanc 1.12.3
|
|
virtual void UpdateAndGetStatistics(int64_t& patientsCount,
|
|
int64_t& studiesCount,
|
|
int64_t& seriesCount,
|
|
int64_t& instancesCount,
|
|
int64_t& compressedSize,
|
|
int64_t& uncompressedSize) = 0;
|
|
|
|
/**
|
|
* Primitives introduced in Orthanc 1.12.5
|
|
**/
|
|
|
|
// This is only implemented if "HasIntegratedFind()" is "true"
|
|
virtual void ExecuteCount(uint64_t& count,
|
|
const FindRequest& request,
|
|
const Capabilities& capabilities) = 0;
|
|
|
|
// This is only implemented if "HasIntegratedFind()" is "true"
|
|
virtual void ExecuteFind(FindResponse& response,
|
|
const FindRequest& request,
|
|
const Capabilities& capabilities) = 0;
|
|
|
|
// This is only implemented if "HasIntegratedFind()" is "false"
|
|
virtual void ExecuteFind(std::list<std::string>& identifiers,
|
|
const Capabilities& capabilities,
|
|
const FindRequest& request) = 0;
|
|
|
|
/**
|
|
* This is only implemented if "HasIntegratedFind()" is
|
|
* "false". In this flavor, the resource of interest might have
|
|
* been deleted, as the expansion is not done in the same
|
|
* transaction as the "ExecuteFind()". In such cases, the
|
|
* wrapper should not throw an exception, but simply ignore the
|
|
* request to expand the resource (i.e., "response" must not be
|
|
* modified).
|
|
**/
|
|
virtual void ExecuteExpand(FindResponse& response,
|
|
const Capabilities& capabilities,
|
|
const FindRequest& request,
|
|
const std::string& identifier) = 0;
|
|
|
|
// New in Orthanc 1.12.5
|
|
virtual void GetChangesExtended(std::list<ServerIndexChange>& target /*out*/,
|
|
bool& done /*out*/,
|
|
int64_t since,
|
|
int64_t to,
|
|
uint32_t limit,
|
|
const std::set<ChangeType>& filterType) = 0;
|
|
|
|
// New in Orthanc 1.12.8
|
|
virtual void StoreKeyValue(const std::string& storeId,
|
|
const std::string& key,
|
|
const void* value,
|
|
size_t valueSize) = 0;
|
|
|
|
// New in Orthanc 1.12.8
|
|
virtual void DeleteKeyValue(const std::string& storeId,
|
|
const std::string& key) = 0;
|
|
|
|
// New in Orthanc 1.12.8
|
|
virtual bool GetKeyValue(std::string& value,
|
|
const std::string& storeId,
|
|
const std::string& key) = 0;
|
|
|
|
// New in Orthanc 1.12.8
|
|
virtual void ListKeysValues(std::list<std::string>& keys /* out */,
|
|
std::list<std::string>& values /* out */,
|
|
const std::string& storeId,
|
|
bool first,
|
|
const std::string& from /* exclusive bound, only used if "first == false" */,
|
|
uint64_t limit /* maximum number of elements */) = 0;
|
|
|
|
// New in Orthanc 1.12.8
|
|
virtual void EnqueueValue(const std::string& queueId,
|
|
const void* value,
|
|
size_t valueSize) = 0;
|
|
|
|
// New in Orthanc 1.12.8
|
|
virtual bool DequeueValue(std::string& value,
|
|
const std::string& queueId,
|
|
QueueOrigin origin) = 0;
|
|
|
|
// New in Orthanc 1.12.8, for statistics only
|
|
virtual uint64_t GetQueueSize(const std::string& queueId) = 0;
|
|
};
|
|
|
|
|
|
// TODO-FIND: Could this interface be removed?
|
|
class ICompatibilityTransaction : public boost::noncopyable
|
|
{
|
|
public:
|
|
virtual ~ICompatibilityTransaction()
|
|
{
|
|
}
|
|
|
|
virtual void GetAllPublicIdsCompatibility(std::list<std::string>& target,
|
|
ResourceType resourceType,
|
|
int64_t since,
|
|
uint32_t limit) = 0;
|
|
|
|
virtual void GetChildrenPublicId(std::list<std::string>& target,
|
|
int64_t id) = 0;
|
|
|
|
/**
|
|
* Primitives introduced in Orthanc 1.5.2
|
|
**/
|
|
|
|
virtual void ApplyLookupResources(std::list<std::string>& resourcesId,
|
|
std::list<std::string>* instancesId, // Can be NULL if not needed
|
|
const DatabaseDicomTagConstraints& lookup,
|
|
ResourceType queryLevel,
|
|
const std::set<std::string>& labels,
|
|
LabelsConstraint labelsConstraint,
|
|
uint32_t limit) = 0;
|
|
|
|
/**
|
|
* Primitives introduced in Orthanc 1.5.4
|
|
**/
|
|
|
|
virtual bool LookupResourceAndParent(int64_t& id,
|
|
ResourceType& type,
|
|
std::string& parentPublicId,
|
|
const std::string& publicId) = 0;
|
|
|
|
/**
|
|
* Primitives introduced in Orthanc 1.12.0
|
|
**/
|
|
|
|
// List the labels of one single resource
|
|
virtual void ListLabels(std::set<std::string>& target,
|
|
int64_t resource) = 0;
|
|
};
|
|
|
|
|
|
virtual ~IDatabaseWrapper()
|
|
{
|
|
}
|
|
|
|
virtual void Open() = 0;
|
|
|
|
virtual void Close() = 0;
|
|
|
|
virtual void FlushToDisk() = 0;
|
|
|
|
virtual ITransaction* StartTransaction(TransactionType type,
|
|
IDatabaseListener& listener) = 0;
|
|
|
|
virtual unsigned int GetDatabaseVersion() = 0;
|
|
|
|
virtual void Upgrade(unsigned int targetVersion,
|
|
IPluginStorageArea& storageArea) = 0;
|
|
|
|
virtual const Capabilities GetDatabaseCapabilities() const = 0;
|
|
|
|
virtual uint64_t MeasureLatency() = 0;
|
|
|
|
// Returns "true" iff. the database engine supports the
|
|
// simultaneous find and expansion of resources.
|
|
virtual bool HasIntegratedFind() const = 0;
|
|
};
|
|
}
|