# HG changeset patch # User Sebastien Jodogne # Date 1446115942 -3600 # Node ID c16615029c9f28fdcad36cd35059d74d3bbe7b76 # Parent 8372e85618b85713731654c0f953ee438b70892e implementation of primitives LookupIdentifier and GetAllInternalIds diff -r 8372e85618b8 -r c16615029c9f IndexPlugin/PostgreSQLWrapper.cpp --- a/IndexPlugin/PostgreSQLWrapper.cpp Wed Oct 21 09:34:53 2015 +0200 +++ b/IndexPlugin/PostgreSQLWrapper.cpp Thu Oct 29 11:52:22 2015 +0100 @@ -110,7 +110,16 @@ void PostgreSQLWrapper::Prepare() { - uint32_t expectedVersion = OrthancPluginGetExpectedDatabaseVersion(context_); + uint32_t expectedVersion; + if (context_) + { + expectedVersion = OrthancPluginGetExpectedDatabaseVersion(context_); + } + else + { + // This case only occurs during unit testing + expectedVersion = 6; + } /* Check the expected version of the database */ if (expectedVersion != 5 && expectedVersion != 6) @@ -360,6 +369,30 @@ } + void PostgreSQLWrapper::GetAllInternalIds(std::list& target, + OrthancPluginResourceType resourceType) + { + if (getAllInternalIds_.get() == NULL) + { + getAllInternalIds_.reset + (new PostgreSQLStatement(*connection_, + "SELECT internalId FROM Resources WHERE resourceType=$1")); + getAllInternalIds_->DeclareInputInteger(0); + } + + getAllInternalIds_->BindInteger(0, static_cast(resourceType)); + PostgreSQLResult result(*getAllInternalIds_); + + target.clear(); + + while (!result.IsDone()) + { + target.push_back(result.GetInteger64(0)); + result.Step(); + } + } + + void PostgreSQLWrapper::GetAllPublicIds(std::list& target, OrthancPluginResourceType resourceType, uint64_t since, @@ -964,41 +997,124 @@ } + static std::string ConvertWildcardToLike(const std::string& query) + { + std::string s = query; + + for (size_t i = 0; i < s.size(); i++) + { + if (s[i] == '*') + { + s[i] = '%'; + } + else if (s[i] == '?') + { + s[i] = '_'; + } + } + + return s; + } + + // Used only if Orthanc >= 0.9.5 - void PostgreSQLWrapper::LookupIdentifierExact(std::list& target, - OrthancPluginResourceType level, - uint16_t group, - uint16_t element, - const char* value) + void PostgreSQLWrapper::LookupIdentifier(std::list& target, + OrthancPluginResourceType level, + uint16_t group, + uint16_t element, + OrthancPluginIdentifierConstraint constraint, + const char* value) { - if (lookupIdentifierExact_.get() == NULL) + if (lookupIdentifierEQ_.get() == NULL) { - lookupIdentifierExact_.reset + lookupIdentifierEQ_.reset (new PostgreSQLStatement (*connection_, "SELECT d.id FROM DicomIdentifiers AS d, Resources AS r WHERE " "d.id = r.internalId AND r.resourceType=$1 AND d.tagGroup=$2 AND d.tagElement=$3 AND d.value=$4")); - lookupIdentifierExact_->DeclareInputInteger(0); - lookupIdentifierExact_->DeclareInputInteger(1); - lookupIdentifierExact_->DeclareInputInteger(2); + lookupIdentifierEQ_->DeclareInputInteger(0); + lookupIdentifierEQ_->DeclareInputInteger(1); + lookupIdentifierEQ_->DeclareInputInteger(2); + lookupIdentifierEQ_->DeclareInputString(3); + } - if (version_ == 5) - { - lookupIdentifierExact_->DeclareInputBinary(3); - } - else - { - lookupIdentifierExact_->DeclareInputString(3); - } + if (lookupIdentifierLE_.get() == NULL) + { + lookupIdentifierLE_.reset + (new PostgreSQLStatement + (*connection_, + "SELECT d.id FROM DicomIdentifiers AS d, Resources AS r WHERE " + "d.id = r.internalId AND r.resourceType=$1 AND d.tagGroup=$2 AND d.tagElement=$3 AND d.value<=$4")); + lookupIdentifierLE_->DeclareInputInteger(0); + lookupIdentifierLE_->DeclareInputInteger(1); + lookupIdentifierLE_->DeclareInputInteger(2); + lookupIdentifierLE_->DeclareInputString(3); + } + + if (lookupIdentifierGE_.get() == NULL) + { + lookupIdentifierGE_.reset + (new PostgreSQLStatement + (*connection_, + "SELECT d.id FROM DicomIdentifiers AS d, Resources AS r WHERE " + "d.id = r.internalId AND r.resourceType=$1 AND d.tagGroup=$2 AND d.tagElement=$3 AND d.value>=$4")); + lookupIdentifierGE_->DeclareInputInteger(0); + lookupIdentifierGE_->DeclareInputInteger(1); + lookupIdentifierGE_->DeclareInputInteger(2); + lookupIdentifierGE_->DeclareInputString(3); } + if (lookupIdentifierWildcard_.get() == NULL) + { + lookupIdentifierWildcard_.reset + (new PostgreSQLStatement + (*connection_, + "SELECT d.id FROM DicomIdentifiers AS d, Resources AS r WHERE " + "d.id = r.internalId AND r.resourceType=$1 AND d.tagGroup=$2 AND d.tagElement=$3 AND d.value LIKE $4")); + lookupIdentifierWildcard_->DeclareInputInteger(0); + lookupIdentifierWildcard_->DeclareInputInteger(1); + lookupIdentifierWildcard_->DeclareInputInteger(2); + lookupIdentifierWildcard_->DeclareInputString(3); + } - lookupIdentifierExact_->BindInteger(0, level); - lookupIdentifierExact_->BindInteger(1, group); - lookupIdentifierExact_->BindInteger(2, element); - lookupIdentifierExact_->BindString(3, value); + PostgreSQLStatement* statement = NULL; + + switch (constraint) + { + case OrthancPluginIdentifierConstraint_Equal: + statement = lookupIdentifierEQ_.get(); + break; + + case OrthancPluginIdentifierConstraint_SmallerOrEqual: + statement = lookupIdentifierLE_.get(); + break; + + case OrthancPluginIdentifierConstraint_GreaterOrEqual: + statement = lookupIdentifierGE_.get(); + break; - PostgreSQLResult result(*lookupIdentifierExact_); + case OrthancPluginIdentifierConstraint_Wildcard: + statement = lookupIdentifierWildcard_.get(); + break; + + default: + throw PostgreSQLException(); + } + + assert(statement != NULL); + statement->BindInteger(0, level); + statement->BindInteger(1, group); + statement->BindInteger(2, element); + if (constraint == OrthancPluginIdentifierConstraint_Wildcard) + { + statement->BindString(3, ConvertWildcardToLike(value)); + } + else + { + statement->BindString(3, value); + } + + PostgreSQLResult result(*statement); target.clear(); while (!result.IsDone()) diff -r 8372e85618b8 -r c16615029c9f IndexPlugin/PostgreSQLWrapper.h --- a/IndexPlugin/PostgreSQLWrapper.h Wed Oct 21 09:34:53 2015 +0200 +++ b/IndexPlugin/PostgreSQLWrapper.h Thu Oct 29 11:52:22 2015 +0100 @@ -49,6 +49,7 @@ std::auto_ptr deleteMetadata_; std::auto_ptr deleteResource_; std::auto_ptr getAllMetadata_; + std::auto_ptr getAllInternalIds_; std::auto_ptr getAllPublicIds_; std::auto_ptr getAllPublicIdsWithLimit_; std::auto_ptr getChanges_; @@ -72,7 +73,10 @@ std::auto_ptr lookupAttachment_; std::auto_ptr lookupIdentifier1_; std::auto_ptr lookupIdentifier2_; - std::auto_ptr lookupIdentifierExact_; // New in Orthanc 0.9.5 + std::auto_ptr lookupIdentifierEQ_; // New in Orthanc 0.9.5 + std::auto_ptr lookupIdentifierLE_; // New in Orthanc 0.9.5 + std::auto_ptr lookupIdentifierGE_; // New in Orthanc 0.9.5 + std::auto_ptr lookupIdentifierWildcard_; // New in Orthanc 0.9.5 std::auto_ptr lookupMetadata_; std::auto_ptr lookupParent_; std::auto_ptr lookupResource_; @@ -154,6 +158,9 @@ virtual void DeleteResource(int64_t id); + virtual void GetAllInternalIds(std::list& target, + OrthancPluginResourceType resourceType); + virtual void GetAllPublicIds(std::list& target, OrthancPluginResourceType resourceType); @@ -226,11 +233,12 @@ const char* value); // Used only if Orthanc >= 0.9.5 - virtual void LookupIdentifierExact(std::list& result, - OrthancPluginResourceType level, - uint16_t group, - uint16_t element, - const char* value); + virtual void LookupIdentifier(std::list& result, + OrthancPluginResourceType level, + uint16_t group, + uint16_t element, + OrthancPluginIdentifierConstraint constraint, + const char* value); virtual bool LookupMetadata(std::string& target, int64_t id, diff -r 8372e85618b8 -r c16615029c9f NEWS --- a/NEWS Wed Oct 21 09:34:53 2015 +0200 +++ b/NEWS Thu Oct 29 11:52:22 2015 +0100 @@ -1,7 +1,7 @@ Pending changes in the mainline =============================== -* Support version 6 of the database schema +* Support version 6 of the database schema (for Orthanc >= 0.9.5) * The "value" column of tables "MainDicomTags" and "DicomIdentifiers" are now TEXT instead of BYTEA diff -r 8372e85618b8 -r c16615029c9f UnitTestsSources/PostgreSQLWrapperTests.cpp --- a/UnitTestsSources/PostgreSQLWrapperTests.cpp Wed Oct 21 09:34:53 2015 +0200 +++ b/UnitTestsSources/PostgreSQLWrapperTests.cpp Thu Oct 29 11:52:22 2015 +0100 @@ -159,7 +159,7 @@ std::string s; ASSERT_TRUE(db.LookupGlobalProperty(s, GlobalProperty_DatabaseSchemaVersion)); - ASSERT_EQ("5", s); + ASSERT_EQ("6", s); ASSERT_FALSE(db.LookupGlobalProperty(s, GlobalProperty_AnonymizationSequence)); db.SetGlobalProperty(GlobalProperty_AnonymizationSequence, "Hello");