DYTSrouce/Tool/3rdParty_x64/include/dcmtk/dcmqrdb/dcmqrdbi.h
2024-11-22 23:19:31 +08:00

443 lines
18 KiB
C++

/*
*
* Copyright (C) 1993-2011, OFFIS e.V.
* All rights reserved. See COPYRIGHT file for details.
*
* This software and supporting documentation were developed by
*
* OFFIS e.V.
* R&D Division Health
* Escherweg 2
* D-26121 Oldenburg, Germany
*
*
* Module: dcmqrdb
*
* Author: Andrew Hewett, Marco Eichelberg
*
* Purpose: class DcmQueryRetrieveIndexDatabaseHandle
*
*/
#ifndef DCMQRDBI_H
#define DCMQRDBI_H
#include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */
#include "dcmtk/dcmqrdb/dcmqrdba.h" /* for class DcmQueryRetrieveDatabaseHandle */
#include "dcmtk/dcmnet/dicom.h"
#include "dcmtk/dcmnet/dimse.h"
#include "dcmtk/ofstd/offname.h"
struct StudyDescRecord;
struct DB_Private_Handle;
struct DB_SmallDcmElmt;
struct IdxRecord;
struct DB_ElementList;
class DcmQueryRetrieveConfig;
#define DBINDEXFILE "index.dat"
#ifndef _WIN32
/* we lock image files on all platforms except Win32 where it does not work
* due to the different semantics of LockFile/LockFileEx compared to flock.
*/
#define LOCK_IMAGE_FILES
#endif
/** enumeration describing the levels of the DICOM Q/R information model
*/
enum DB_LEVEL
{
/// DICOM Q/R patient level
PATIENT_LEVEL,
/// DICOM Q/R study level
STUDY_LEVEL,
/// DICOM Q/R series level
SERIE_LEVEL,
/// DICOM Q/R instance level
IMAGE_LEVEL
};
/** This enum describes the status of one entry in the database hierarchy. An
* entry can describe a study, a series or an instance. A study or series is
* new exactly if all subobjects (series and instances) are new. A study or
* series contains new subobjecs as long as any subobject (series or instance)
* has the status objectIsNew. Instances can never have the status
* DVIF_objectContainsNewSubobjects.
*/
enum DVIFhierarchyStatus
{
/// object (study, series or instance) in the database is not new
DVIF_objectIsNotNew,
/// object (study, series or instance) in the database is new
DVIF_objectIsNew,
/// object (study or series) in the database is not new but contains new subobjects
DVIF_objectContainsNewSubobjects
};
/// upper limit for the number of studies per storage area
#define DB_UpperMaxStudies 500
/// upper limit for the number bytes per study
#define DB_UpperMaxBytesPerStudy 0x40000000L
/** This class maintains database handles based on the classical "index.dat" file.
* A database handle maintains a connection to a database and encapsulates database support for
* store, find and move/get operations.
*/
class DCMTK_DCMQRDB_EXPORT DcmQueryRetrieveIndexDatabaseHandle: public DcmQueryRetrieveDatabaseHandle
{
private:
/// private undefined copy constructor
DcmQueryRetrieveIndexDatabaseHandle(const DcmQueryRetrieveIndexDatabaseHandle& other);
/// private undefined assignment operator
DcmQueryRetrieveIndexDatabaseHandle& operator=(const DcmQueryRetrieveIndexDatabaseHandle& other);
public:
/** Constructor. Creates and initializes a index file handle for the given
* database storage area (storageArea).
* @param storageArea name of storage area, must not be NULL
* @param maxStudiesPerStorageArea maximum number of studies for this storage area,
* needed to correctly parse the index file.
* @param maxBytesPerStudy maximum number of bytes per study, for quota mechanism
* @param result upon successful initialization of the database handle,
* EC_Normal is returned in this parameter, otherwise an error code is returned.
*/
DcmQueryRetrieveIndexDatabaseHandle(
const char *storageArea,
long maxStudiesPerStorageArea,
long maxBytesPerStudy,
OFCondition& result);
/** Destructor. Destroys handle, cancels any ongoing
* request if necessary, deletes temporary files used for C-STORE and
* sub-operations of C-MOVE.
*/
~DcmQueryRetrieveIndexDatabaseHandle();
/** Configure the DB module to perform (or not perform) checking
* of FIND and MOVE request identifiers. Default is no checking.
* @param checkFind checking for C-FIND parameters
* @param checkMove checking for C-MOVE parameters
*/
void setIdentifierChecking(OFBool checkFind, OFBool checkMove);
/** create a filename under which a DICOM object that is currently
* being received through a C-STORE operation can be stored.
* @param SOPClassUID SOP class UID of DICOM instance
* @param SOPInstanceUID SOP instance UID of DICOM instance
* @param newImageFileName file name is returned in this parameter.
* Memory must be provided by the caller and should be at least MAXPATHLEN+1
* characters. The file name generated should be an absolute file name.
* @return EC_Normal upon normal completion, or some other OFCondition code upon failure.
*/
OFCondition makeNewStoreFileName(
const char *SOPClassUID,
const char *SOPInstanceUID,
char *newImageFileName);
/** register the given DICOM object, which has been received through a C-STORE
* operation and stored in a file, in the database.
* @param SOPClassUID SOP class UID of DICOM instance
* @param SOPInstanceUID SOP instance UID of DICOM instance
* @param imageFileName file name (full path) of DICOM instance
* @param status pointer to DB status object in which a DIMSE status code
suitable for use with the C-STORE-RSP message is set.
* @param isNew if true, the instance is marked as "new" in the database,
* if such a flag is maintained in the database.
* @return EC_Normal upon normal completion, or some other OFCondition code upon failure.
*/
OFCondition storeRequest(
const char *SOPClassUID,
const char *SOPInstanceUID,
const char *imageFileName,
DcmQueryRetrieveDatabaseStatus *status,
OFBool isNew = OFTrue );
/** initiate FIND operation using the given SOP class UID (which identifies
* the query model) and DICOM dataset containing find request identifiers.
* @param SOPClassUID SOP class UID of query service, identifies Q/R model
* @param findRequestIdentifiers dataset containing request identifiers (i.e., the query)
* The caller retains responsibility for destroying the
* findRequestIdentifiers when no longer needed.
* @param status pointer to DB status object in which a DIMSE status code
* suitable for use with the C-FIND-RSP message is set. Status will be
* PENDING if any FIND responses will be generated or SUCCESS if no FIND responses will
* be generated (SUCCESS indicates the completion of a operation), or
* another status code upon failure.
* @return EC_Normal upon normal completion, or some other OFCondition code upon failure.
*/
OFCondition startFindRequest(
const char *SOPClassUID,
DcmDataset *findRequestIdentifiers,
DcmQueryRetrieveDatabaseStatus *status);
/** return the next available FIND response as a new DICOM dataset.
* @param findResponseIdentifiers DICOM dataset returned in this parameter.
* The caller is responsible for destroying the findResponseIdentifiers
* when no longer needed.
* @param status pointer to DB status object in which a DIMSE status code
* suitable for use with the C-FIND-RSP message is set. Status will be
* PENDING if more FIND responses will be generated or SUCCESS if no more
* FIND responses will be generated (SUCCESS indicates the completion of
* a operation), or another status code upon failure.
* @return EC_Normal upon normal completion, or some other OFCondition code upon failure.
*/
OFCondition nextFindResponse(
DcmDataset **findResponseIdentifiers,
DcmQueryRetrieveDatabaseStatus *status);
/** cancel the ongoing FIND request, stop and reset every running operation
* associated with this request, delete existing temporary files.
* @param status pointer to DB status object in which a DIMSE status code
* suitable for use with the C-FIND-RSP message is set.
* @return EC_Normal upon normal completion, or some other OFCondition code upon failure.
*/
OFCondition cancelFindRequest(DcmQueryRetrieveDatabaseStatus *status);
/** initiate MOVE operation using the given SOP class UID (which identifies
* the retrieve model) and DICOM dataset containing move request identifiers.
* @param SOPClassUID SOP class UID of retrieve service, identifies Q/R model
* @param moveRequestIdentifiers dataset containing request identifiers (i.e., the query)
* The caller retains responsibility for destroying the
* moveRequestIdentifiers when no longer needed.
* @param status pointer to DB status object in which a DIMSE status code
* suitable for use with the C-MOVE-RSP message is set. Status will be
* PENDING if any MOVE responses will be generated or SUCCESS if no MOVE responses will
* be generated (SUCCESS indicates the completion of a operation), or
* another status code upon failure.
* @return EC_Normal upon normal completion, or some other OFCondition code upon failure.
*/
OFCondition startMoveRequest(
const char *SOPClassUID,
DcmDataset *moveRequestIdentifiers,
DcmQueryRetrieveDatabaseStatus *status);
/** Constructs the information required for the next available C-MOVE
* sub-operation (the image SOP class UID, SOP Instance UID and an
* imageFileName containing the requested data).
* @param SOPClassUID pointer to string of at least 65 characters into
* which the SOP class UID for the next DICOM object to be transferred is copied.
* @param SOPInstanceUID pointer to string of at least 65 characters into
* which the SOP instance UID for the next DICOM object to be transferred is copied.
* @param imageFileName pointer to string of at least MAXPATHLEN+1 characters into
* which the file path for the next DICOM object to be transferred is copied.
* @param numberOfRemainingSubOperations On return, this parameter will contain
* the number of suboperations still remaining for the request
* (this number is needed by move responses with PENDING status).
* @param status pointer to DB status object in which a DIMSE status code
* suitable for use with the C-MOVE-RSP message is set. Status will be
* PENDING if more MOVE responses will be generated or SUCCESS if no more
* MOVE responses will be generated (SUCCESS indicates the completion of
* a operation), or another status code upon failure.
* @return EC_Normal upon normal completion, or some other OFCondition code upon failure.
*/
OFCondition nextMoveResponse(
char *SOPClassUID,
char *SOPInstanceUID,
char *imageFileName,
unsigned short *numberOfRemainingSubOperations,
DcmQueryRetrieveDatabaseStatus *status);
/** cancel the ongoing MOVE request, stop and reset every running operation
* associated with this request, delete existing temporary files.
* @param status pointer to DB status object in which a DIMSE status code
* suitable for use with the C-MOVE-RSP message is set.
* @return EC_Normal upon normal completion, or some other OFCondition code upon failure.
*/
OFCondition cancelMoveRequest(DcmQueryRetrieveDatabaseStatus *status);
/** Prune invalid records from the database.
* Records referring to non-existant image files are invalid.
*/
OFCondition pruneInvalidRecords();
// methods not inherited from the base class
/** enable/disable the DB quota system (default: enabled) which causes images
* to be deleted if certain boundaries (number of studies, bytes per study) are exceeded.
*/
void enableQuotaSystem(OFBool enable);
/** dump database index file to stdout.
* @param storeArea name of storage area, must not be NULL
*/
static void printIndexFile (char *storeArea);
/** search for a SOP class and SOP instance UIDs in index file.
* @param storeArea name of storage area, must not be NULL
* @param sopClassUID SOP Class UID to search for
* @param sopInstanceUID SOP Instance UID to search for
* @return OFTrue if SOP Class and SOP Instance UIDs are found. otherwise return OFFalse.
*/
OFBool findSOPInstance(const char *storeArea, const OFString &sopClassUID,const OFString &sopInstanceUID);
/** deletes the given file only if the quota mechanism is enabled.
* The image is not de-registered from the database by this routine.
* @param imgFile file name (path) to the file to be deleted.
* @return EC_Normal upon normal completion, or some other OFCondition code upon failure.
*/
OFCondition deleteImageFile(char* imgFile);
/** create lock on database
* @param exclusive exclusive/shared lock flag
* @return EC_Normal upon success, an error code otherwise
*/
OFCondition DB_lock(OFBool exclusive);
/** release lock on database
*/
OFCondition DB_unlock();
/** Get next Index record that is in use (i.e. references a non-empty a filename)
* @param idx pointer to index number, updated upon successful return
* @param idxRec pointer to index record structure
* @return EC_Normal upon success, an error code otherwise
*/
OFCondition DB_IdxGetNext(int *idx, IdxRecord *idxRec);
/** seek to beginning of image records in index file
* @param idx initialized to -1
* @return EC_Normal upon success, an error code otherwise
*/
OFCondition DB_IdxInitLoop(int *idx);
/** read index record at given index
* @param idx index
* @param idxRec pointer to index record
* @return EC_Normal upon success, an error code otherwise
*/
OFCondition DB_IdxRead(int idx, IdxRecord *idxRec);
/** get study descriptor record from start of index file
* @param pStudyDesc pointer to study record descriptor structure
* @return EC_Normal upon success, an error code otherwise
*/
OFCondition DB_GetStudyDesc(StudyDescRecord *pStudyDesc);
/** write study descriptor record to start of index file
* @param pStudyDesc pointer to study record descriptor structure
* @return EC_Normal upon success, an error code otherwise
*/
OFCondition DB_StudyDescChange(StudyDescRecord *pStudyDesc);
/** deactivate index record at given index by setting an empty filename
* @param idx index
* @return EC_Normal upon success, an error code otherwise
*/
OFCondition DB_IdxRemove(int idx);
/** clear the "is new" flag for the instance with the given index
* @param idx index
* @return EC_Normal upon success, an error code otherwise
*/
OFCondition instanceReviewed(int idx);
/// return name of storage area
const char *getStorageArea() const;
/// return path to index file
const char *getIndexFilename() const;
private:
OFCondition removeDuplicateImage(
const char *SOPInstanceUID, const char *StudyInstanceUID,
StudyDescRecord *pStudyDesc, const char *newImageFileName);
int deleteOldestStudy(StudyDescRecord *pStudyDesc);
OFCondition deleteOldestImages(StudyDescRecord *pStudyDesc, int StudyNum, char *StudyUID, long RequiredSize);
int matchDate (DB_SmallDcmElmt *mod, DB_SmallDcmElmt *elt);
int matchTime (DB_SmallDcmElmt *mod, DB_SmallDcmElmt *elt);
int matchUID (DB_SmallDcmElmt *mod, DB_SmallDcmElmt *elt);
int matchStrings (DB_SmallDcmElmt *mod, DB_SmallDcmElmt *elt);
int matchOther (DB_SmallDcmElmt *mod, DB_SmallDcmElmt *elt);
int dbmatch (DB_SmallDcmElmt *mod, DB_SmallDcmElmt *elt);
void makeResponseList(DB_Private_Handle *phandle, IdxRecord *idxRec);
int matchStudyUIDInStudyDesc (StudyDescRecord *pStudyDesc, char *StudyUID, int maxStudiesAllowed);
OFCondition checkupinStudyDesc(StudyDescRecord *pStudyDesc, char *StudyUID, long imageSize);
OFCondition hierarchicalCompare (
DB_Private_Handle *phandle,
IdxRecord *idxRec,
DB_LEVEL level,
DB_LEVEL infLevel,
int *match);
OFCondition testFindRequestList (
DB_ElementList *findRequestList,
DB_LEVEL queryLevel,
DB_LEVEL infLevel,
DB_LEVEL lowestLevel);
OFCondition testMoveRequestList (
DB_ElementList *findRequestList,
DB_LEVEL queryLevel,
DB_LEVEL infLevel,
DB_LEVEL lowestLevel);
/// database handle
DB_Private_Handle *handle_;
/// flag indicating whether or not the quota system is enabled
OFBool quotaSystemEnabled;
/// flag indicating whether or not the check function for FIND requests is enabled
OFBool doCheckFindIdentifier;
/// flag indicating whether or not the check function for MOVE requests is enabled
OFBool doCheckMoveIdentifier;
/// helper object for file name creation
OFFilenameCreator fnamecreator;
};
/** Index database factory class. Instances of this class are able to create database
* handles for a given called application entity title.
*/
class DCMTK_DCMQRDB_EXPORT DcmQueryRetrieveIndexDatabaseHandleFactory: public DcmQueryRetrieveDatabaseHandleFactory
{
private:
/// private undefined copy constructor
DcmQueryRetrieveIndexDatabaseHandleFactory(const DcmQueryRetrieveIndexDatabaseHandleFactory& other);
/// private undefined assignment operator
DcmQueryRetrieveIndexDatabaseHandleFactory& operator=(const DcmQueryRetrieveIndexDatabaseHandleFactory& other);
public:
/** constructor
* @param config system configuration object, must not be NULL.
*/
DcmQueryRetrieveIndexDatabaseHandleFactory(const DcmQueryRetrieveConfig *config);
/// destructor
virtual ~DcmQueryRetrieveIndexDatabaseHandleFactory();
/** this method creates a new database handle instance on the heap and returns
* a pointer to it, along with a result that indicates if the instance was
* successfully initialized, i.e. connected to the database
* @param callingAETitle calling aetitle
* @param calledAETitle called aetitle
* @param result result returned in this variable
* @return pointer to database object, must not be NULL if result is EC_Normal.
*/
virtual DcmQueryRetrieveDatabaseHandle *createDBHandle(
const char *callingAETitle,
const char *calledAETitle,
OFCondition& result) const;
private:
/// pointer to system configuration
const DcmQueryRetrieveConfig *config_;
};
#endif