changeset 79:c16615029c9f

implementation of primitives LookupIdentifier and GetAllInternalIds
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 29 Oct 2015 11:52:22 +0100
parents 8372e85618b8
children 2605ebf75cf8
files IndexPlugin/PostgreSQLWrapper.cpp IndexPlugin/PostgreSQLWrapper.h NEWS UnitTestsSources/PostgreSQLWrapperTests.cpp
diffstat 4 files changed, 156 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- 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<int64_t>& 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<int>(resourceType));
+    PostgreSQLResult result(*getAllInternalIds_);
+
+    target.clear();
+
+    while (!result.IsDone())
+    {
+      target.push_back(result.GetInteger64(0));
+      result.Step();
+    }
+  }
+
+
   void PostgreSQLWrapper::GetAllPublicIds(std::list<std::string>& 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<int64_t>& target,
-                                                OrthancPluginResourceType level,
-                                                uint16_t group,
-                                                uint16_t element,
-                                                const char* value)
+  void PostgreSQLWrapper::LookupIdentifier(std::list<int64_t>& 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())
--- 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<PostgreSQLStatement> deleteMetadata_;
     std::auto_ptr<PostgreSQLStatement> deleteResource_;
     std::auto_ptr<PostgreSQLStatement> getAllMetadata_;
+    std::auto_ptr<PostgreSQLStatement> getAllInternalIds_;
     std::auto_ptr<PostgreSQLStatement> getAllPublicIds_;
     std::auto_ptr<PostgreSQLStatement> getAllPublicIdsWithLimit_;
     std::auto_ptr<PostgreSQLStatement> getChanges_;
@@ -72,7 +73,10 @@
     std::auto_ptr<PostgreSQLStatement> lookupAttachment_;
     std::auto_ptr<PostgreSQLStatement> lookupIdentifier1_;
     std::auto_ptr<PostgreSQLStatement> lookupIdentifier2_;
-    std::auto_ptr<PostgreSQLStatement> lookupIdentifierExact_;  // New in Orthanc 0.9.5
+    std::auto_ptr<PostgreSQLStatement> lookupIdentifierEQ_;  // New in Orthanc 0.9.5
+    std::auto_ptr<PostgreSQLStatement> lookupIdentifierLE_;  // New in Orthanc 0.9.5
+    std::auto_ptr<PostgreSQLStatement> lookupIdentifierGE_;  // New in Orthanc 0.9.5
+    std::auto_ptr<PostgreSQLStatement> lookupIdentifierWildcard_;  // New in Orthanc 0.9.5
     std::auto_ptr<PostgreSQLStatement> lookupMetadata_;
     std::auto_ptr<PostgreSQLStatement> lookupParent_;
     std::auto_ptr<PostgreSQLStatement> lookupResource_;
@@ -154,6 +158,9 @@
 
     virtual void DeleteResource(int64_t id);
 
+    virtual void GetAllInternalIds(std::list<int64_t>& target,
+                                   OrthancPluginResourceType resourceType);
+
     virtual void GetAllPublicIds(std::list<std::string>& target,
                                  OrthancPluginResourceType resourceType);
 
@@ -226,11 +233,12 @@
                                   const char* value);
 
     // Used only if Orthanc >= 0.9.5
-    virtual void LookupIdentifierExact(std::list<int64_t>& result,
-                                       OrthancPluginResourceType level,
-                                       uint16_t group,
-                                       uint16_t element,
-                                       const char* value);
+    virtual void LookupIdentifier(std::list<int64_t>& result,
+                                  OrthancPluginResourceType level,
+                                  uint16_t group,
+                                  uint16_t element,
+                                  OrthancPluginIdentifierConstraint constraint,
+                                  const char* value);
 
     virtual bool LookupMetadata(std::string& target,
                                 int64_t id,
--- 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
 
 
--- 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");