changeset 1748:92203f713205 db-changes

IFindConstraint
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 26 Oct 2015 17:33:55 +0100
parents ca69082ab200
children 99f4a05f39fa
files OrthancServer/Search/IFindConstraint.h OrthancServer/Search/LookupIdentifierQuery.cpp OrthancServer/Search/LookupIdentifierQuery.h
diffstat 3 files changed, 145 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OrthancServer/Search/IFindConstraint.h	Mon Oct 26 17:33:55 2015 +0100
@@ -0,0 +1,50 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2015 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, 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.
+ *
+ * In addition, as a special exception, the copyright holders of this
+ * program give permission to link the code of its release with the
+ * OpenSSL project's "OpenSSL" library (or with modified versions of it
+ * that use the same license as the "OpenSSL" library), and distribute
+ * the linked executables. You must obey the GNU General Public License
+ * in all respects for all of the code used other than "OpenSSL". If you
+ * modify file(s) with this exception, you may extend this exception to
+ * your version of the file(s), but you are not obligated to do so. If
+ * you do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source files
+ * in the program, then also delete it here.
+ * 
+ * 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 "LookupIdentifierQuery.h"
+
+namespace Orthanc
+{
+  class IFindConstraint : public boost::noncopyable
+  {
+  public:
+    virtual ~IFindConstraint()
+    {
+    }
+
+    virtual void Setup(LookupIdentifierQuery& lookup) const = 0;
+
+    virtual bool Match(const std::string& value) const = 0;
+  };
+}
--- a/OrthancServer/Search/LookupIdentifierQuery.cpp	Mon Oct 26 16:58:11 2015 +0100
+++ b/OrthancServer/Search/LookupIdentifierQuery.cpp	Mon Oct 26 17:33:55 2015 +0100
@@ -102,6 +102,20 @@
   }
 
 
+  LookupIdentifierQuery::Union::~Union()
+  {
+    for (size_t i = 0; i < union_.size(); i++)
+    {
+      delete union_[i];
+    }
+  }
+
+
+  void LookupIdentifierQuery::Union::Add(const Constraint& constraint)
+  {
+    union_.push_back(new Constraint(constraint));
+  }
+
 
   LookupIdentifierQuery::~LookupIdentifierQuery()
   {
@@ -114,21 +128,13 @@
 
 
 
-  void  LookupIdentifierQuery::CheckIndex(size_t index) const
-  {
-    if (index >= constraints_.size())
-    {
-      throw OrthancException(ErrorCode_ParameterOutOfRange);
-    }
-  }
-
-
-  bool LookupIdentifierQuery::IsIdentifier(const DicomTag& tag) const
+  bool LookupIdentifierQuery::IsIdentifier(const DicomTag& tag,
+                                           ResourceType level)
   {
     const DicomTag* tags;
     size_t size;
 
-    LoadIdentifiers(tags, size, level_);
+    LoadIdentifiers(tags, size, level);
 
     for (size_t i = 0; i < size; i++)
     {
@@ -147,28 +153,23 @@
                                             const std::string& value)
   {
     assert(IsIdentifier(tag));
-    constraints_.push_back(new Constraint(tag, type, NormalizeIdentifier(value)));
-  }
 
-
-  const DicomTag& LookupIdentifierQuery::GetTag(size_t index) const
-  {
-    CheckIndex(index);
-    return constraints_[index]->tag_;
+    Constraint constraint(tag, type, NormalizeIdentifier(value));
+    constraints_.push_back(new Union);
+    constraints_.back()->Add(constraint);
   }
 
 
-  IdentifierConstraintType  LookupIdentifierQuery::GetType(size_t index) const
+  void LookupIdentifierQuery::AddDisjunction(const std::list<Constraint>& constraints)
   {
-    CheckIndex(index);
-    return constraints_[index]->type_;
-  }
+    constraints_.push_back(new Union);
 
-
-  const std::string& LookupIdentifierQuery::GetValue(size_t index) const
-  {
-    CheckIndex(index);
-    return constraints_[index]->value_;
+    for (std::list<Constraint>::const_iterator
+           it = constraints.begin(); it != constraints.end(); ++it)
+    {
+      assert(IsIdentifier(it->GetTag()));
+      constraints_.back()->Add(*it);
+    }
   }
 
 
@@ -211,9 +212,18 @@
     
     for (size_t i = 0; i < GetSize(); i++)
     {
-      std::list<int64_t> tmp;
-      database.LookupIdentifier(tmp, level_, GetTag(i), GetType(i), GetValue(i));
-      resources.Intersect(tmp);
+      std::list<int64_t> a;
+
+      for (size_t j = 0; j < constraints_[i]->GetSize(); j++)
+      {
+        const Constraint& constraint = constraints_[i]->GetConstraint(j);
+        std::list<int64_t> b;
+        database.LookupIdentifier(b, level_, constraint.GetTag(), constraint.GetType(), constraint.GetValue());
+
+        a.splice(a.end(), b);
+      }
+
+      resources.Intersect(a);
     }
 
     resources.Flatten(result);
--- a/OrthancServer/Search/LookupIdentifierQuery.h	Mon Oct 26 16:58:11 2015 +0100
+++ b/OrthancServer/Search/LookupIdentifierQuery.h	Mon Oct 26 17:33:55 2015 +0100
@@ -62,13 +62,15 @@
 
   class LookupIdentifierQuery : public boost::noncopyable
   {
-  private:
-    struct Constraint
+  public:
+    class Constraint
     {
+    private:
       DicomTag                  tag_;
       IdentifierConstraintType  type_;
       std::string               value_;
 
+    public:
       Constraint(const DicomTag& tag,
                  IdentifierConstraintType type,
                  const std::string& value) : 
@@ -77,15 +79,52 @@
         value_(value)
       {
       }
+
+      const DicomTag& GetTag() const
+      {
+        return tag_;
+      }
+
+      IdentifierConstraintType GetType() const
+      {
+        return type_;
+      }
+      
+      const std::string& GetValue() const
+      {
+        return value_;
+      }
     };
 
-    typedef std::vector<Constraint*>  Constraints;
+
+  private:
+    class Union
+    {
+    private:
+      std::vector<Constraint*>  union_;
+
+    public:
+      ~Union();
+
+      void Add(const Constraint& constraint);
+
+      size_t GetSize() const
+      {
+        return union_.size();
+      }
+
+      const Constraint&  GetConstraint(size_t i) const
+      {
+        return *union_[i];
+      }
+    };
+
+
+    typedef std::vector<Union*>  Constraints;
 
     ResourceType  level_;
     Constraints   constraints_;
 
-    void CheckIndex(size_t index) const;
-
     static std::string NormalizeIdentifier(const std::string& value);
 
   public:
@@ -95,12 +134,17 @@
 
     ~LookupIdentifierQuery();
 
-    bool IsIdentifier(const DicomTag& tag) const;
+    bool IsIdentifier(const DicomTag& tag)
+    {
+      return IsIdentifier(tag, level_);
+    }
 
     void AddConstraint(DicomTag tag,
                        IdentifierConstraintType type,
                        const std::string& value);
 
+    void AddDisjunction(const std::list<Constraint>& constraints);
+
     ResourceType GetLevel() const
     {
       return level_;
@@ -111,19 +155,16 @@
       return constraints_.size();
     }
 
-    const DicomTag& GetTag(size_t index) const;
+    // The database must be locked
+    void Apply(std::list<std::string>& result,
+               IDatabaseWrapper& database);
 
-    IdentifierConstraintType  GetType(size_t index) const;
-
-    const std::string& GetValue(size_t index) const;
+    static bool IsIdentifier(const DicomTag& tag,
+                             ResourceType level);
 
     static void StoreIdentifiers(IDatabaseWrapper& database,
                                  int64_t resource,
                                  ResourceType level,
                                  const DicomMap& map);
-
-    // The database must be locked
-    void Apply(std::list<std::string>& result,
-               IDatabaseWrapper& database);
   };
 }