[med-svn] [Git][med-team/orthanc][master] 4 commits: New upstream version 1.4.1+dfsg

Sebastien Jodogne gitlab at salsa.debian.org
Tue Jul 17 16:33:16 BST 2018


Sebastien Jodogne pushed to branch master at Debian Med / orthanc


Commits:
5ffa6e2a by jodogne-guest at 2018-07-17T16:52:37+02:00
New upstream version 1.4.1+dfsg
- - - - -
26dc1a35 by jodogne-guest at 2018-07-17T16:52:40+02:00
Update upstream source from tag 'upstream/1.4.1+dfsg'

Update to upstream version '1.4.1+dfsg'
with Debian dir 710f132b84880bd242c6d299cd05cee50478145d
- - - - -
a797267a by jodogne-guest at 2018-07-17T16:53:44+02:00
preparing for 1.4.1+dfsg-1

- - - - -
cb54d1f7 by jodogne-guest at 2018-07-17T17:21:57+02:00
update configuration files

- - - - -


25 changed files:

- .hg_archival.txt
- CMakeLists.txt
- Core/Images/ImageProcessing.h
- NEWS
- OrthancServer/DatabaseWrapper.cpp
- OrthancServer/DatabaseWrapper.h
- OrthancServer/IServerListener.h
- OrthancServer/LuaScripting.cpp
- OrthancServer/LuaScripting.h
- OrthancServer/ServerContext.cpp
- OrthancServer/ServerContext.h
- OrthancServer/ServerEnumerations.h
- OrthancServer/main.cpp
- Resources/CMake/OrthancFrameworkParameters.cmake
- Resources/Configuration.json
- Resources/DownloadOrthancFramework.cmake
- Plugins/Samples/DatabasePlugin/CMakeLists.txt → Resources/Graveyard/DatabasePluginSample/CMakeLists.txt
- Plugins/Samples/DatabasePlugin/Database.cpp → Resources/Graveyard/DatabasePluginSample/Database.cpp
- Plugins/Samples/DatabasePlugin/Database.h → Resources/Graveyard/DatabasePluginSample/Database.h
- OrthancServer/DatabaseWrapperBase.cpp → Resources/Graveyard/DatabasePluginSample/DatabaseWrapperBase.cpp
- OrthancServer/DatabaseWrapperBase.h → Resources/Graveyard/DatabasePluginSample/DatabaseWrapperBase.h
- Plugins/Samples/DatabasePlugin/Plugin.cpp → Resources/Graveyard/DatabasePluginSample/Plugin.cpp
- debian/changelog
- debian/docs/Orthanc.1
- debian/docs/OrthancRecoverCompressedFile.8


Changes:

=====================================
.hg_archival.txt
=====================================
--- a/.hg_archival.txt
+++ b/.hg_archival.txt
@@ -1,6 +1,6 @@
 repo: 3959d33612ccaadc0d4d707227fbed09ac35e5fe
-node: a2536c0d72deda960f2908e7bdcc56929837a0bf
-branch: Orthanc-1.4.0
+node: 218854b02a71c1ba79b446bf4273179b0098ae48
+branch: Orthanc-1.4.1
 latesttag: dcmtk-3.6.1
-latesttagdistance: 354
-changessincelatesttag: 396
+latesttagdistance: 366
+changessincelatesttag: 408


=====================================
CMakeLists.txt
=====================================
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -54,7 +54,6 @@ include(${CMAKE_SOURCE_DIR}/Resources/CMake/OrthancFrameworkConfiguration.cmake)
 
 set(ORTHANC_SERVER_SOURCES
   OrthancServer/DatabaseWrapper.cpp
-  OrthancServer/DatabaseWrapperBase.cpp
   OrthancServer/DicomInstanceOrigin.cpp
   OrthancServer/DicomInstanceToStore.cpp
   OrthancServer/ExportedResource.cpp


=====================================
Core/Images/ImageProcessing.h
=====================================
--- a/Core/Images/ImageProcessing.h
+++ b/Core/Images/ImageProcessing.h
@@ -99,5 +99,5 @@ namespace Orthanc
                          uint8_t green,
                          uint8_t blue,
                          uint8_t alpha);
-  };
+  }
 }


=====================================
NEWS
=====================================
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,13 @@ Pending changes in the mainline
 ===============================
 
 
+Version 1.4.1 (2018-07-17)
+==========================
+
+* Fix deadlock in Lua scripting
+* Simplification to the "DatabaseWrapper" class
+
+
 Version 1.4.0 (2018-07-13)
 ==========================
 
@@ -10,7 +17,7 @@ General
 
 * New advanced job engine
 * New configuration options:
-  - "ConcurrentJobs": Max number of jobs that are simultanously running
+  - "ConcurrentJobs": Max number of jobs that are simultaneously running
   - "SynchronousCMove": Whether to run DICOM C-Move operations synchronously
   - "JobsHistorySize": Max number of completed jobs that are kept in memory
 * New metadata automatically computed at the instance level: 


=====================================
OrthancServer/DatabaseWrapper.cpp
=====================================
--- a/OrthancServer/DatabaseWrapper.cpp
+++ b/OrthancServer/DatabaseWrapper.cpp
@@ -44,7 +44,6 @@
 
 namespace Orthanc
 {
-
   namespace Internals
   {
     class SignalFileDeleted : public SQLite::IScalarFunction
@@ -187,6 +186,59 @@ namespace Orthanc
   }
 
 
+  void DatabaseWrapper::GetChangesInternal(std::list<ServerIndexChange>& target,
+                                           bool& done,
+                                           SQLite::Statement& s,
+                                           uint32_t maxResults)
+  {
+    target.clear();
+
+    while (target.size() < maxResults && s.Step())
+    {
+      int64_t seq = s.ColumnInt64(0);
+      ChangeType changeType = static_cast<ChangeType>(s.ColumnInt(1));
+      ResourceType resourceType = static_cast<ResourceType>(s.ColumnInt(3));
+      const std::string& date = s.ColumnString(4);
+
+      int64_t internalId = s.ColumnInt64(2);
+      std::string publicId = GetPublicId(internalId);
+
+      target.push_back(ServerIndexChange(seq, changeType, resourceType, publicId, date));
+    }
+
+    done = !(target.size() == maxResults && s.Step());
+  }
+
+
+  void DatabaseWrapper::GetExportedResourcesInternal(std::list<ExportedResource>& target,
+                                                     bool& done,
+                                                     SQLite::Statement& s,
+                                                     uint32_t maxResults)
+  {
+    target.clear();
+
+    while (target.size() < maxResults && s.Step())
+    {
+      int64_t seq = s.ColumnInt64(0);
+      ResourceType resourceType = static_cast<ResourceType>(s.ColumnInt(1));
+      std::string publicId = s.ColumnString(2);
+
+      ExportedResource resource(seq, 
+                                resourceType,
+                                publicId,
+                                s.ColumnString(3),  // modality
+                                s.ColumnString(8),  // date
+                                s.ColumnString(4),  // patient ID
+                                s.ColumnString(5),  // study instance UID
+                                s.ColumnString(6),  // series instance UID
+                                s.ColumnString(7)); // sop instance UID
+
+      target.push_back(resource);
+    }
+
+    done = !(target.size() == maxResults && s.Step());
+  }
+
 
   void DatabaseWrapper::GetChildren(std::list<std::string>& childrenPublicIds,
                                     int64_t id)
@@ -258,22 +310,22 @@ namespace Orthanc
     
   DatabaseWrapper::DatabaseWrapper(const std::string& path) : 
     listener_(NULL), 
-    base_(db_),
     signalRemainingAncestor_(NULL),
     version_(0)
   {
     db_.Open(path);
   }
 
+
   DatabaseWrapper::DatabaseWrapper() : 
     listener_(NULL), 
-    base_(db_),
     signalRemainingAncestor_(NULL),
     version_(0)
   {
     db_.OpenInMemory();
   }
 
+
   void DatabaseWrapper::Open()
   {
     db_.Execute("PRAGMA ENCODING=\"UTF-8\";");
@@ -402,43 +454,53 @@ namespace Orthanc
   bool DatabaseWrapper::LookupParent(int64_t& parentId,
                                      int64_t resourceId)
   {
-    bool found;
-    ErrorCode error = base_.LookupParent(found, parentId, resourceId);
+    SQLite::Statement s(db_, SQLITE_FROM_HERE, 
+                        "SELECT parentId FROM Resources WHERE internalId=?");
+    s.BindInt64(0, resourceId);
 
-    if (error != ErrorCode_Success)
+    if (!s.Step())
+    {
+      throw OrthancException(ErrorCode_UnknownResource);
+    }
+
+    if (s.ColumnIsNull(0))
     {
-      throw OrthancException(error);
+      return false;
     }
     else
     {
-      return found;
+      parentId = s.ColumnInt(0);
+      return true;
     }
   }
 
 
   ResourceType DatabaseWrapper::GetResourceType(int64_t resourceId)
   {
-    ResourceType result;
-    ErrorCode code = base_.GetResourceType(result, resourceId);
-
-    if (code == ErrorCode_Success)
+    SQLite::Statement s(db_, SQLITE_FROM_HERE, 
+                        "SELECT resourceType FROM Resources WHERE internalId=?");
+    s.BindInt64(0, resourceId);
+    
+    if (s.Step())
     {
-      return result;
+      return static_cast<ResourceType>(s.ColumnInt(0));
     }
     else
-    {
-      throw OrthancException(code);
+    { 
+      throw OrthancException(ErrorCode_UnknownResource);
     }
   }
 
 
   std::string DatabaseWrapper::GetPublicId(int64_t resourceId)
   {
-    std::string id;
-
-    if (base_.GetPublicId(id, resourceId))
-    {
-      return id;
+    SQLite::Statement s(db_, SQLITE_FROM_HERE, 
+                        "SELECT publicId FROM Resources WHERE internalId=?");
+    s.BindInt64(0, resourceId);
+    
+    if (s.Step())
+    { 
+      return s.ColumnString(0);
     }
     else
     {
@@ -452,23 +514,18 @@ namespace Orthanc
                                    int64_t since,
                                    uint32_t maxResults)
   {
-    ErrorCode code = base_.GetChanges(target, done, since, maxResults);
-
-    if (code != ErrorCode_Success)
-    {
-      throw OrthancException(code);
-    }
+    SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT * FROM Changes WHERE seq>? ORDER BY seq LIMIT ?");
+    s.BindInt64(0, since);
+    s.BindInt(1, maxResults + 1);
+    GetChangesInternal(target, done, s, maxResults);
   }
 
 
   void DatabaseWrapper::GetLastChange(std::list<ServerIndexChange>& target /*out*/)
   {
-    ErrorCode code = base_.GetLastChange(target);
-
-    if (code != ErrorCode_Success)
-    {
-      throw OrthancException(code);
-    }
+    bool done;  // Ignored
+    SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT * FROM Changes ORDER BY seq DESC LIMIT 1");
+    GetChangesInternal(target, done, s, 1);
   }
 
 
@@ -487,4 +544,588 @@ namespace Orthanc
     }
   }
 
+
+  void DatabaseWrapper::SetGlobalProperty(GlobalProperty property,
+                                          const std::string& value)
+  {
+    SQLite::Statement s(db_, SQLITE_FROM_HERE, "INSERT OR REPLACE INTO GlobalProperties VALUES(?, ?)");
+    s.BindInt(0, property);
+    s.BindString(1, value);
+    s.Run();
+  }
+
+
+  bool DatabaseWrapper::LookupGlobalProperty(std::string& target,
+                                             GlobalProperty property)
+  {
+    SQLite::Statement s(db_, SQLITE_FROM_HERE, 
+                        "SELECT value FROM GlobalProperties WHERE property=?");
+    s.BindInt(0, property);
+
+    if (!s.Step())
+    {
+      return false;
+    }
+    else
+    {
+      target = s.ColumnString(0);
+      return true;
+    }
+  }
+
+
+  int64_t DatabaseWrapper::CreateResource(const std::string& publicId,
+                                          ResourceType type)
+  {
+    SQLite::Statement s(db_, SQLITE_FROM_HERE, "INSERT INTO Resources VALUES(NULL, ?, ?, NULL)");
+    s.BindInt(0, type);
+    s.BindString(1, publicId);
+    s.Run();
+    return db_.GetLastInsertRowId();
+  }
+
+
+  bool DatabaseWrapper::LookupResource(int64_t& id,
+                                       ResourceType& type,
+                                       const std::string& publicId)
+  {
+    SQLite::Statement s(db_, SQLITE_FROM_HERE, 
+                        "SELECT internalId, resourceType FROM Resources WHERE publicId=?");
+    s.BindString(0, publicId);
+
+    if (!s.Step())
+    {
+      return false;
+    }
+    else
+    {
+      id = s.ColumnInt(0);
+      type = static_cast<ResourceType>(s.ColumnInt(1));
+
+      // Check whether there is a single resource with this public id
+      assert(!s.Step());
+
+      return true;
+    }
+  }
+
+
+  void DatabaseWrapper::AttachChild(int64_t parent,
+                                    int64_t child)
+  {
+    SQLite::Statement s(db_, SQLITE_FROM_HERE, "UPDATE Resources SET parentId = ? WHERE internalId = ?");
+    s.BindInt64(0, parent);
+    s.BindInt64(1, child);
+    s.Run();
+  }
+
+
+  void DatabaseWrapper::SetMetadata(int64_t id,
+                                    MetadataType type,
+                                    const std::string& value)
+  {
+    SQLite::Statement s(db_, SQLITE_FROM_HERE, "INSERT OR REPLACE INTO Metadata VALUES(?, ?, ?)");
+    s.BindInt64(0, id);
+    s.BindInt(1, type);
+    s.BindString(2, value);
+    s.Run();
+  }
+
+
+  void DatabaseWrapper::DeleteMetadata(int64_t id,
+                                       MetadataType type)
+  {
+    SQLite::Statement s(db_, SQLITE_FROM_HERE, "DELETE FROM Metadata WHERE id=? and type=?");
+    s.BindInt64(0, id);
+    s.BindInt(1, type);
+    s.Run();
+  }
+
+
+  bool DatabaseWrapper::LookupMetadata(std::string& target,
+                                       int64_t id,
+                                       MetadataType type)
+  {
+    SQLite::Statement s(db_, SQLITE_FROM_HERE, 
+                        "SELECT value FROM Metadata WHERE id=? AND type=?");
+    s.BindInt64(0, id);
+    s.BindInt(1, type);
+
+    if (!s.Step())
+    {
+      return false;
+    }
+    else
+    {
+      target = s.ColumnString(0);
+      return true;
+    }
+  }
+
+
+  void DatabaseWrapper::ListAvailableMetadata(std::list<MetadataType>& target,
+                                              int64_t id)
+  {
+    target.clear();
+
+    SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT type FROM Metadata WHERE id=?");
+    s.BindInt64(0, id);
+
+    while (s.Step())
+    {
+      target.push_back(static_cast<MetadataType>(s.ColumnInt(0)));
+    }
+  }
+
+
+  void DatabaseWrapper::AddAttachment(int64_t id,
+                                      const FileInfo& attachment)
+  {
+    SQLite::Statement s(db_, SQLITE_FROM_HERE, "INSERT INTO AttachedFiles VALUES(?, ?, ?, ?, ?, ?, ?, ?)");
+    s.BindInt64(0, id);
+    s.BindInt(1, attachment.GetContentType());
+    s.BindString(2, attachment.GetUuid());
+    s.BindInt64(3, attachment.GetCompressedSize());
+    s.BindInt64(4, attachment.GetUncompressedSize());
+    s.BindInt(5, attachment.GetCompressionType());
+    s.BindString(6, attachment.GetUncompressedMD5());
+    s.BindString(7, attachment.GetCompressedMD5());
+    s.Run();
+  }
+
+
+  void DatabaseWrapper::DeleteAttachment(int64_t id,
+                                         FileContentType attachment)
+  {
+    SQLite::Statement s(db_, SQLITE_FROM_HERE, "DELETE FROM AttachedFiles WHERE id=? AND fileType=?");
+    s.BindInt64(0, id);
+    s.BindInt(1, attachment);
+    s.Run();
+  }
+
+
+  void DatabaseWrapper::ListAvailableAttachments(std::list<FileContentType>& target,
+                                                 int64_t id)
+  {
+    target.clear();
+
+    SQLite::Statement s(db_, SQLITE_FROM_HERE, 
+                        "SELECT fileType FROM AttachedFiles WHERE id=?");
+    s.BindInt64(0, id);
+
+    while (s.Step())
+    {
+      target.push_back(static_cast<FileContentType>(s.ColumnInt(0)));
+    }
+  }
+
+  bool DatabaseWrapper::LookupAttachment(FileInfo& attachment,
+                                         int64_t id,
+                                         FileContentType contentType)
+  {
+    SQLite::Statement s(db_, SQLITE_FROM_HERE, 
+                        "SELECT uuid, uncompressedSize, compressionType, compressedSize, "
+                        "uncompressedMD5, compressedMD5 FROM AttachedFiles WHERE id=? AND fileType=?");
+    s.BindInt64(0, id);
+    s.BindInt(1, contentType);
+
+    if (!s.Step())
+    {
+      return false;
+    }
+    else
+    {
+      attachment = FileInfo(s.ColumnString(0),
+                            contentType,
+                            s.ColumnInt64(1),
+                            s.ColumnString(4),
+                            static_cast<CompressionType>(s.ColumnInt(2)),
+                            s.ColumnInt64(3),
+                            s.ColumnString(5));
+      return true;
+    }
+  }
+
+
+  void DatabaseWrapper::ClearMainDicomTags(int64_t id)
+  {
+    {
+      SQLite::Statement s(db_, SQLITE_FROM_HERE, "DELETE FROM DicomIdentifiers WHERE id=?");
+      s.BindInt64(0, id);
+      s.Run();
+    }
+
+    {
+      SQLite::Statement s(db_, SQLITE_FROM_HERE, "DELETE FROM MainDicomTags WHERE id=?");
+      s.BindInt64(0, id);
+      s.Run();
+    }
+  }
+
+
+  void DatabaseWrapper::SetMainDicomTag(int64_t id,
+                                        const DicomTag& tag,
+                                        const std::string& value)
+  {
+    SQLite::Statement s(db_, SQLITE_FROM_HERE, "INSERT INTO MainDicomTags VALUES(?, ?, ?, ?)");
+    s.BindInt64(0, id);
+    s.BindInt(1, tag.GetGroup());
+    s.BindInt(2, tag.GetElement());
+    s.BindString(3, value);
+    s.Run();
+  }
+
+
+  void DatabaseWrapper::SetIdentifierTag(int64_t id,
+                                         const DicomTag& tag,
+                                         const std::string& value)
+  {
+    SQLite::Statement s(db_, SQLITE_FROM_HERE, "INSERT INTO DicomIdentifiers VALUES(?, ?, ?, ?)");
+    s.BindInt64(0, id);
+    s.BindInt(1, tag.GetGroup());
+    s.BindInt(2, tag.GetElement());
+    s.BindString(3, value);
+    s.Run();
+  }
+
+
+  void DatabaseWrapper::GetMainDicomTags(DicomMap& map,
+                                         int64_t id)
+  {
+    map.Clear();
+
+    SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT * FROM MainDicomTags WHERE id=?");
+    s.BindInt64(0, id);
+    while (s.Step())
+    {
+      map.SetValue(s.ColumnInt(1),
+                   s.ColumnInt(2),
+                   s.ColumnString(3), false);
+    }
+  }
+
+
+  void DatabaseWrapper::GetChildrenPublicId(std::list<std::string>& target,
+                                            int64_t id)
+  {
+    SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT a.publicId FROM Resources AS a, Resources AS b  "
+                        "WHERE a.parentId = b.internalId AND b.internalId = ?");     
+    s.BindInt64(0, id);
+
+    target.clear();
+
+    while (s.Step())
+    {
+      target.push_back(s.ColumnString(0));
+    }
+  }
+
+
+  void DatabaseWrapper::GetChildrenInternalId(std::list<int64_t>& target,
+                                              int64_t id)
+  {
+    SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT a.internalId FROM Resources AS a, Resources AS b  "
+                        "WHERE a.parentId = b.internalId AND b.internalId = ?");     
+    s.BindInt64(0, id);
+
+    target.clear();
+
+    while (s.Step())
+    {
+      target.push_back(s.ColumnInt64(0));
+    }
+  }
+
+
+  void DatabaseWrapper::LogChange(int64_t internalId,
+                                  const ServerIndexChange& change)
+  {
+    SQLite::Statement s(db_, SQLITE_FROM_HERE, "INSERT INTO Changes VALUES(NULL, ?, ?, ?, ?)");
+    s.BindInt(0, change.GetChangeType());
+    s.BindInt64(1, internalId);
+    s.BindInt(2, change.GetResourceType());
+    s.BindString(3, change.GetDate());
+    s.Run();
+  }
+
+
+  void DatabaseWrapper::LogExportedResource(const ExportedResource& resource)
+  {
+    SQLite::Statement s(db_, SQLITE_FROM_HERE, 
+                        "INSERT INTO ExportedResources VALUES(NULL, ?, ?, ?, ?, ?, ?, ?, ?)");
+
+    s.BindInt(0, resource.GetResourceType());
+    s.BindString(1, resource.GetPublicId());
+    s.BindString(2, resource.GetModality());
+    s.BindString(3, resource.GetPatientId());
+    s.BindString(4, resource.GetStudyInstanceUid());
+    s.BindString(5, resource.GetSeriesInstanceUid());
+    s.BindString(6, resource.GetSopInstanceUid());
+    s.BindString(7, resource.GetDate());
+    s.Run();      
+  }
+
+
+  void DatabaseWrapper::GetExportedResources(std::list<ExportedResource>& target,
+                                             bool& done,
+                                             int64_t since,
+                                             uint32_t maxResults)
+  {
+    SQLite::Statement s(db_, SQLITE_FROM_HERE, 
+                        "SELECT * FROM ExportedResources WHERE seq>? ORDER BY seq LIMIT ?");
+    s.BindInt64(0, since);
+    s.BindInt(1, maxResults + 1);
+    GetExportedResourcesInternal(target, done, s, maxResults);
+  }
+
+    
+  void DatabaseWrapper::GetLastExportedResource(std::list<ExportedResource>& target)
+  {
+    bool done;  // Ignored
+    SQLite::Statement s(db_, SQLITE_FROM_HERE, 
+                        "SELECT * FROM ExportedResources ORDER BY seq DESC LIMIT 1");
+    GetExportedResourcesInternal(target, done, s, 1);
+  }
+
+    
+  uint64_t DatabaseWrapper::GetTotalCompressedSize()
+  {
+    SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT SUM(compressedSize) FROM AttachedFiles");
+    s.Run();
+    return static_cast<uint64_t>(s.ColumnInt64(0));
+  }
+
+    
+  uint64_t DatabaseWrapper::GetTotalUncompressedSize()
+  {
+    SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT SUM(uncompressedSize) FROM AttachedFiles");
+    s.Run();
+    return static_cast<uint64_t>(s.ColumnInt64(0));
+  }
+
+
+  uint64_t DatabaseWrapper::GetResourceCount(ResourceType resourceType)
+  {
+    SQLite::Statement s(db_, SQLITE_FROM_HERE, 
+                        "SELECT COUNT(*) FROM Resources WHERE resourceType=?");
+    s.BindInt(0, resourceType);
+    
+    if (!s.Step())
+    {
+      return 0;
+    }
+    else
+    {
+      int64_t c = s.ColumnInt(0);
+      assert(!s.Step());
+      return c;
+    }
+  }
+
+
+  void DatabaseWrapper::GetAllInternalIds(std::list<int64_t>& target,
+                                          ResourceType resourceType)
+  {
+    SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT internalId FROM Resources WHERE resourceType=?");
+    s.BindInt(0, resourceType);
+
+    target.clear();
+    while (s.Step())
+    {
+      target.push_back(s.ColumnInt64(0));
+    }
+  }
+
+
+  void DatabaseWrapper::GetAllPublicIds(std::list<std::string>& target,
+                                        ResourceType resourceType)
+  {
+    SQLite::Statement s(db_, SQLITE_FROM_HERE, "SELECT publicId FROM Resources WHERE resourceType=?");
+    s.BindInt(0, resourceType);
+
+    target.clear();
+    while (s.Step())
+    {
+      target.push_back(s.ColumnString(0));
+    }
+  }
+
+
+  void DatabaseWrapper::GetAllPublicIds(std::list<std::string>& target,
+                                        ResourceType resourceType,
+                                        size_t since,
+                                        size_t limit)
+  {
+    if (limit == 0)
+    {
+      target.clear();
+      return;
+    }
+
+    SQLite::Statement s(db_, SQLITE_FROM_HERE,
+                        "SELECT publicId FROM Resources WHERE "
+                        "resourceType=? LIMIT ? OFFSET ?");
+    s.BindInt(0, resourceType);
+    s.BindInt64(1, limit);
+    s.BindInt64(2, since);
+
+    target.clear();
+    while (s.Step())
+    {
+      target.push_back(s.ColumnString(0));
+    }
+  }
+
+
+  bool DatabaseWrapper::SelectPatientToRecycle(int64_t& internalId)
+  {
+    SQLite::Statement s(db_, SQLITE_FROM_HERE,
+                        "SELECT patientId FROM PatientRecyclingOrder ORDER BY seq ASC LIMIT 1");
+   
+    if (!s.Step())
+    {
+      // No patient remaining or all the patients are protected
+      return false;
+    }
+    else
+    {
+      internalId = s.ColumnInt(0);
+      return true;
+    }    
+  }
+
+
+  bool DatabaseWrapper::SelectPatientToRecycle(int64_t& internalId,
+                                               int64_t patientIdToAvoid)
+  {
+    SQLite::Statement s(db_, SQLITE_FROM_HERE,
+                        "SELECT patientId FROM PatientRecyclingOrder "
+                        "WHERE patientId != ? ORDER BY seq ASC LIMIT 1");
+    s.BindInt64(0, patientIdToAvoid);
+
+    if (!s.Step())
+    {
+      // No patient remaining or all the patients are protected
+      return false;
+    }
+    else
+    {
+      internalId = s.ColumnInt(0);
+      return true;
+    }   
+  }
+
+
+  bool DatabaseWrapper::IsProtectedPatient(int64_t internalId)
+  {
+    SQLite::Statement s(db_, SQLITE_FROM_HERE,
+                        "SELECT * FROM PatientRecyclingOrder WHERE patientId = ?");
+    s.BindInt64(0, internalId);
+    return !s.Step();
+  }
+
+
+  void DatabaseWrapper::SetProtectedPatient(int64_t internalId, 
+                                            bool isProtected)
+  {
+    if (isProtected)
+    {
+      SQLite::Statement s(db_, SQLITE_FROM_HERE, "DELETE FROM PatientRecyclingOrder WHERE patientId=?");
+      s.BindInt64(0, internalId);
+      s.Run();
+    }
+    else if (IsProtectedPatient(internalId))
+    {
+      SQLite::Statement s(db_, SQLITE_FROM_HERE, "INSERT INTO PatientRecyclingOrder VALUES(NULL, ?)");
+      s.BindInt64(0, internalId);
+      s.Run();
+    }
+    else
+    {
+      // Nothing to do: The patient is already unprotected
+    }
+  }
+
+
+  bool DatabaseWrapper::IsExistingResource(int64_t internalId)
+  {
+    SQLite::Statement s(db_, SQLITE_FROM_HERE, 
+                        "SELECT * FROM Resources WHERE internalId=?");
+    s.BindInt64(0, internalId);
+    return s.Step();
+  }
+
+
+  void DatabaseWrapper::LookupIdentifier(std::list<int64_t>& target,
+                                         ResourceType level,
+                                         const DicomTag& tag,
+                                         IdentifierConstraintType type,
+                                         const std::string& value)
+  {
+    static const char* COMMON = ("SELECT d.id FROM DicomIdentifiers AS d, Resources AS r WHERE "
+                                 "d.id = r.internalId AND r.resourceType=? AND "
+                                 "d.tagGroup=? AND d.tagElement=? AND ");
+
+    std::auto_ptr<SQLite::Statement> s;
+
+    switch (type)
+    {
+      case IdentifierConstraintType_GreaterOrEqual:
+        s.reset(new SQLite::Statement(db_, std::string(COMMON) + "d.value>=?"));
+        break;
+
+      case IdentifierConstraintType_SmallerOrEqual:
+        s.reset(new SQLite::Statement(db_, std::string(COMMON) + "d.value<=?"));
+        break;
+
+      case IdentifierConstraintType_Wildcard:
+        s.reset(new SQLite::Statement(db_, std::string(COMMON) + "d.value GLOB ?"));
+        break;
+
+      case IdentifierConstraintType_Equal:
+      default:
+        s.reset(new SQLite::Statement(db_, std::string(COMMON) + "d.value=?"));
+        break;
+    }
+
+    assert(s.get() != NULL);
+
+    s->BindInt(0, level);
+    s->BindInt(1, tag.GetGroup());
+    s->BindInt(2, tag.GetElement());
+    s->BindString(3, value);
+
+    target.clear();
+
+    while (s->Step())
+    {
+      target.push_back(s->ColumnInt64(0));
+    }    
+  }
+
+
+  void DatabaseWrapper::LookupIdentifierRange(std::list<int64_t>& target,
+                                              ResourceType level,
+                                              const DicomTag& tag,
+                                              const std::string& start,
+                                              const std::string& end)
+  {
+    SQLite::Statement statement(db_, SQLITE_FROM_HERE,
+                                "SELECT d.id FROM DicomIdentifiers AS d, Resources AS r WHERE "
+                                "d.id = r.internalId AND r.resourceType=? AND "
+                                "d.tagGroup=? AND d.tagElement=? AND d.value>=? AND d.value<=?");
+
+    statement.BindInt(0, level);
+    statement.BindInt(1, tag.GetGroup());
+    statement.BindInt(2, tag.GetElement());
+    statement.BindString(3, start);
+    statement.BindString(4, end);
+
+    target.clear();
+
+    while (statement.Step())
+    {
+      target.push_back(statement.ColumnInt64(0));
+    }    
+  }
 }


=====================================
OrthancServer/DatabaseWrapper.h
=====================================
--- a/OrthancServer/DatabaseWrapper.h
+++ b/OrthancServer/DatabaseWrapper.h
@@ -37,7 +37,6 @@
 
 #include "../Core/SQLite/Connection.h"
 #include "../Core/SQLite/Transaction.h"
-#include "DatabaseWrapperBase.h"
 
 namespace Orthanc
 {
@@ -56,10 +55,19 @@ namespace Orthanc
   private:
     IDatabaseListener* listener_;
     SQLite::Connection db_;
-    DatabaseWrapperBase base_;
     Internals::SignalRemainingAncestor* signalRemainingAncestor_;
     unsigned int version_;
 
+    void GetChangesInternal(std::list<ServerIndexChange>& target,
+                            bool& done,
+                            SQLite::Statement& s,
+                            uint32_t maxResults);
+
+    void GetExportedResourcesInternal(std::list<ExportedResource>& target,
+                                      bool& done,
+                                      SQLite::Statement& s,
+                                      uint32_t maxResults);
+
     void ClearTable(const std::string& tableName);
 
   public:
@@ -76,301 +84,197 @@ namespace Orthanc
 
     virtual void SetListener(IDatabaseListener& listener);
 
-    virtual void SetGlobalProperty(GlobalProperty property,
-                                   const std::string& value)
+    virtual bool LookupParent(int64_t& parentId,
+                              int64_t resourceId);
+
+    virtual std::string GetPublicId(int64_t resourceId);
+
+    virtual ResourceType GetResourceType(int64_t resourceId);
+
+    virtual void DeleteResource(int64_t id);
+
+    virtual void GetChanges(std::list<ServerIndexChange>& target /*out*/,
+                            bool& done /*out*/,
+                            int64_t since,
+                            uint32_t maxResults);
+
+    virtual void GetLastChange(std::list<ServerIndexChange>& target /*out*/);
+
+    virtual SQLite::ITransaction* StartTransaction()
     {
-      base_.SetGlobalProperty(property, value);
+      return new SQLite::Transaction(db_);
     }
 
-    virtual bool LookupGlobalProperty(std::string& target,
-                                      GlobalProperty property)
+    virtual void FlushToDisk()
     {
-      return base_.LookupGlobalProperty(target, property);
+      db_.FlushToDisk();
     }
 
-    virtual int64_t CreateResource(const std::string& publicId,
-                                   ResourceType type)
+    virtual bool HasFlushToDisk() const
     {
-      return base_.CreateResource(publicId, type);
+      return true;
     }
 
-    virtual bool LookupResource(int64_t& id,
-                                ResourceType& type,
-                                const std::string& publicId)
+    virtual void ClearChanges()
     {
-      return base_.LookupResource(id, type, publicId);
+      ClearTable("Changes");
     }
 
-    virtual bool LookupParent(int64_t& parentId,
-                              int64_t resourceId);
+    virtual void ClearExportedResources()
+    {
+      ClearTable("ExportedResources");
+    }
 
-    virtual std::string GetPublicId(int64_t resourceId);
+    virtual void GetAllMetadata(std::map<MetadataType, std::string>& target,
+                                int64_t id);
 
-    virtual ResourceType GetResourceType(int64_t resourceId);
+    virtual unsigned int GetDatabaseVersion()
+    {
+      return version_;
+    }
 
-    virtual void AttachChild(int64_t parent,
-                             int64_t child)
+    virtual void Upgrade(unsigned int targetVersion,
+                         IStorageArea& storageArea);
+
+
+    /**
+     * The methods declared below are for unit testing only!
+     **/
+
+    const char* GetErrorMessage() const
     {
-      base_.AttachChild(parent, child);
+      return db_.GetErrorMessage();
     }
 
-    virtual void DeleteResource(int64_t id);
+    void GetChildren(std::list<std::string>& childrenPublicIds,
+                     int64_t id);
+
+    int64_t GetTableRecordCount(const std::string& table);
+    
+    bool GetParentPublicId(std::string& target,
+                           int64_t id);
+
+
+
+    /**
+     * Until Orthanc 1.4.0, the methods below were part of the
+     * "DatabaseWrapperBase" class, that is now placed in the
+     * graveyard.
+     **/
+
+    virtual void SetGlobalProperty(GlobalProperty property,
+                                   const std::string& value);
+
+    virtual bool LookupGlobalProperty(std::string& target,
+                                      GlobalProperty property);
+
+    virtual int64_t CreateResource(const std::string& publicId,
+                                   ResourceType type);
+
+    virtual bool LookupResource(int64_t& id,
+                                ResourceType& type,
+                                const std::string& publicId);
+
+    virtual void AttachChild(int64_t parent,
+                             int64_t child);
 
     virtual void SetMetadata(int64_t id,
                              MetadataType type,
-                             const std::string& value)
-    {
-      base_.SetMetadata(id, type, value);
-    }
+                             const std::string& value);
 
     virtual void DeleteMetadata(int64_t id,
-                                MetadataType type)
-    {
-      base_.DeleteMetadata(id, type);
-    }
+                                MetadataType type);
 
     virtual bool LookupMetadata(std::string& target,
                                 int64_t id,
-                                MetadataType type)
-    {
-      return base_.LookupMetadata(target, id, type);
-    }
+                                MetadataType type);
 
     virtual void ListAvailableMetadata(std::list<MetadataType>& target,
-                                       int64_t id)
-    {
-      base_.ListAvailableMetadata(target, id);
-    }
+                                       int64_t id);
 
     virtual void AddAttachment(int64_t id,
-                               const FileInfo& attachment)
-    {
-      base_.AddAttachment(id, attachment);
-    }
+                               const FileInfo& attachment);
 
     virtual void DeleteAttachment(int64_t id,
-                                  FileContentType attachment)
-    {
-      base_.DeleteAttachment(id, attachment);
-    }
+                                  FileContentType attachment);
 
     virtual void ListAvailableAttachments(std::list<FileContentType>& target,
-                                          int64_t id)
-    {
-      return base_.ListAvailableAttachments(target, id);
-    }
+                                          int64_t id);
 
     virtual bool LookupAttachment(FileInfo& attachment,
                                   int64_t id,
-                                  FileContentType contentType)
-    {
-      return base_.LookupAttachment(attachment, id, contentType);
-    }
+                                  FileContentType contentType);
 
-    virtual void ClearMainDicomTags(int64_t id)
-    {
-      base_.ClearMainDicomTags(id);
-    }
+    virtual void ClearMainDicomTags(int64_t id);
 
     virtual void SetMainDicomTag(int64_t id,
                                  const DicomTag& tag,
-                                 const std::string& value)
-    {
-      base_.SetMainDicomTag(id, tag, value);
-    }
+                                 const std::string& value);
 
     virtual void SetIdentifierTag(int64_t id,
-                                 const DicomTag& tag,
-                                 const std::string& value)
-    {
-      base_.SetIdentifierTag(id, tag, value);
-    }
+                                  const DicomTag& tag,
+                                  const std::string& value);
 
     virtual void GetMainDicomTags(DicomMap& map,
-                                  int64_t id)
-    {
-      base_.GetMainDicomTags(map, id);
-    }
+                                  int64_t id);
 
     virtual void GetChildrenPublicId(std::list<std::string>& target,
-                                     int64_t id)
-    {
-      base_.GetChildrenPublicId(target, id);
-    }
+                                     int64_t id);
 
     virtual void GetChildrenInternalId(std::list<int64_t>& target,
-                                       int64_t id)
-    {
-      base_.GetChildrenInternalId(target, id);
-    }
+                                       int64_t id);
 
     virtual void LogChange(int64_t internalId,
-                           const ServerIndexChange& change)
-    {
-      base_.LogChange(internalId, change);
-    }
+                           const ServerIndexChange& change);
 
-    virtual void GetChanges(std::list<ServerIndexChange>& target /*out*/,
-                            bool& done /*out*/,
-                            int64_t since,
-                            uint32_t maxResults);
-
-    virtual void GetLastChange(std::list<ServerIndexChange>& target /*out*/);
-
-    virtual void LogExportedResource(const ExportedResource& resource)
-    {
-      base_.LogExportedResource(resource);
-    }
+    virtual void LogExportedResource(const ExportedResource& resource);
     
     virtual void GetExportedResources(std::list<ExportedResource>& target /*out*/,
                                       bool& done /*out*/,
                                       int64_t since,
-                                      uint32_t maxResults)
-    {
-      base_.GetExportedResources(target, done, since, maxResults);
-    }
+                                      uint32_t maxResults);
 
-    virtual void GetLastExportedResource(std::list<ExportedResource>& target /*out*/)
-    {
-      base_.GetLastExportedResource(target);
-    }
+    virtual void GetLastExportedResource(std::list<ExportedResource>& target /*out*/);
 
-    virtual uint64_t GetTotalCompressedSize()
-    {
-      return base_.GetTotalCompressedSize();
-    }
+    virtual uint64_t GetTotalCompressedSize();
     
-    virtual uint64_t GetTotalUncompressedSize()
-    {
-      return base_.GetTotalUncompressedSize();
-    }
+    virtual uint64_t GetTotalUncompressedSize();
 
-    virtual uint64_t GetResourceCount(ResourceType resourceType)
-    {
-      return base_.GetResourceCount(resourceType);
-    }
+    virtual uint64_t GetResourceCount(ResourceType resourceType);
 
     virtual void GetAllInternalIds(std::list<int64_t>& target,
-                                   ResourceType resourceType)
-    {
-      base_.GetAllInternalIds(target, resourceType);
-    }
+                                   ResourceType resourceType);
 
     virtual void GetAllPublicIds(std::list<std::string>& target,
-                                 ResourceType resourceType)
-    {
-      base_.GetAllPublicIds(target, resourceType);
-    }
+                                 ResourceType resourceType);
 
     virtual void GetAllPublicIds(std::list<std::string>& target,
                                  ResourceType resourceType,
                                  size_t since,
-                                 size_t limit)
-    {
-      base_.GetAllPublicIds(target, resourceType, since, limit);
-    }
+                                 size_t limit);
 
-    virtual bool SelectPatientToRecycle(int64_t& internalId)
-    {
-      return base_.SelectPatientToRecycle(internalId);
-    }
+    virtual bool SelectPatientToRecycle(int64_t& internalId);
 
     virtual bool SelectPatientToRecycle(int64_t& internalId,
-                                        int64_t patientIdToAvoid)
-    {
-      return base_.SelectPatientToRecycle(internalId, patientIdToAvoid);
-    }
+                                        int64_t patientIdToAvoid);
 
-    virtual bool IsProtectedPatient(int64_t internalId)
-    {
-      return base_.IsProtectedPatient(internalId);
-    }
+    virtual bool IsProtectedPatient(int64_t internalId);
 
     virtual void SetProtectedPatient(int64_t internalId, 
-                                     bool isProtected)
-    {
-      base_.SetProtectedPatient(internalId, isProtected);
-    }
+                                     bool isProtected);
 
-    virtual SQLite::ITransaction* StartTransaction()
-    {
-      return new SQLite::Transaction(db_);
-    }
-
-    virtual void FlushToDisk()
-    {
-      db_.FlushToDisk();
-    }
-
-    virtual bool HasFlushToDisk() const
-    {
-      return true;
-    }
-
-    virtual void ClearChanges()
-    {
-      ClearTable("Changes");
-    }
-
-    virtual void ClearExportedResources()
-    {
-      ClearTable("ExportedResources");
-    }
-
-    virtual bool IsExistingResource(int64_t internalId)
-    {
-      return base_.IsExistingResource(internalId);
-    }
+    virtual bool IsExistingResource(int64_t internalId);
 
     virtual void LookupIdentifier(std::list<int64_t>& result,
                                   ResourceType level,
                                   const DicomTag& tag,
                                   IdentifierConstraintType type,
-                                  const std::string& value)
-    {
-      base_.LookupIdentifier(result, level, tag, type, value);
-    }
-
+                                  const std::string& value);
 
     virtual void LookupIdentifierRange(std::list<int64_t>& result,
                                        ResourceType level,
                                        const DicomTag& tag,
                                        const std::string& start,
-                                       const std::string& end)
-    {
-      base_.LookupIdentifierRange(result, level, tag, start, end);
-    }
-
-
-    virtual void GetAllMetadata(std::map<MetadataType, std::string>& target,
-                                int64_t id);
-
-    virtual unsigned int GetDatabaseVersion()
-    {
-      return version_;
-    }
-
-    virtual void Upgrade(unsigned int targetVersion,
-                         IStorageArea& storageArea);
-
-
-
-    /**
-     * The methods declared below are for unit testing only!
-     **/
-
-    const char* GetErrorMessage() const
-    {
-      return db_.GetErrorMessage();
-    }
-
-    void GetChildren(std::list<std::string>& childrenPublicIds,
-                     int64_t id);
-
-    int64_t GetTableRecordCount(const std::string& table);
-    
-    bool GetParentPublicId(std::string& target,
-                           int64_t id);
-
+                                       const std::string& end);
   };
 }


=====================================
OrthancServer/IServerListener.h
=====================================
--- a/OrthancServer/IServerListener.h
+++ b/OrthancServer/IServerListener.h
@@ -49,8 +49,8 @@ namespace Orthanc
 
     virtual void SignalStoredInstance(const std::string& publicId,
                                       DicomInstanceToStore& instance,
-                                      const Json::Value& simplifiedTags) = 0;                                      
-
+                                      const Json::Value& simplifiedTags) = 0;
+    
     virtual void SignalChange(const ServerIndexChange& change) = 0;
 
     virtual bool FilterIncomingInstance(const DicomInstanceToStore& instance,


=====================================
OrthancServer/LuaScripting.cpp
=====================================
--- a/OrthancServer/LuaScripting.cpp
+++ b/OrthancServer/LuaScripting.cpp
@@ -582,6 +582,9 @@ namespace Orthanc
     lua_.RegisterFunction("RestApiPut", RestApiPut);
     lua_.RegisterFunction("RestApiDelete", RestApiDelete);
     lua_.RegisterFunction("GetOrthancConfiguration", GetOrthancConfiguration);
+
+    LOG(INFO) << "Initializing Lua for the event handler";
+    LoadGlobalConfiguration();
   }
 
 


=====================================
OrthancServer/LuaScripting.h
=====================================
--- a/OrthancServer/LuaScripting.h
+++ b/OrthancServer/LuaScripting.h
@@ -33,8 +33,7 @@
 
 #pragma once
 
-#include "IServerListener.h"
-
+#include "DicomInstanceToStore.h"
 #include "ServerJobs/LuaJobManager.h"
 
 #include "../Core/MultiThreading/SharedMessageQueue.h"
@@ -44,7 +43,7 @@ namespace Orthanc
 {
   class ServerContext;
 
-  class LuaScripting : public IServerListener
+  class LuaScripting : public boost::noncopyable
   {
   private:
     enum State
@@ -88,6 +87,8 @@ namespace Orthanc
 
     static void EventThread(LuaScripting* that);
 
+    void LoadGlobalConfiguration();
+
   public:
     class Lock : public boost::noncopyable
     {
@@ -116,19 +117,17 @@ namespace Orthanc
 
     void Stop();
     
-    virtual void SignalStoredInstance(const std::string& publicId,
-                                      DicomInstanceToStore& instance,
-                                      const Json::Value& simplifiedTags);
+    void SignalStoredInstance(const std::string& publicId,
+                              DicomInstanceToStore& instance,
+                              const Json::Value& simplifiedTags);
 
-    virtual void SignalChange(const ServerIndexChange& change);
+    void SignalChange(const ServerIndexChange& change);
 
-    virtual bool FilterIncomingInstance(const DicomInstanceToStore& instance,
-                                        const Json::Value& simplifiedTags);
+    bool FilterIncomingInstance(const DicomInstanceToStore& instance,
+                                const Json::Value& simplifiedTags);
 
     void Execute(const std::string& command);
 
-    void LoadGlobalConfiguration();
-
     void SignalJobSubmitted(const std::string& jobId);
 
     void SignalJobSuccess(const std::string& jobId);


=====================================
OrthancServer/ServerContext.cpp
=====================================
--- a/OrthancServer/ServerContext.cpp
+++ b/OrthancServer/ServerContext.cpp
@@ -135,21 +135,21 @@ namespace Orthanc
   void ServerContext::SignalJobSubmitted(const std::string& jobId)
   {
     haveJobsChanged_ = true;
-    lua_.SignalJobSubmitted(jobId);
+    mainLua_.SignalJobSubmitted(jobId);
   }
   
 
   void ServerContext::SignalJobSuccess(const std::string& jobId)
   {
     haveJobsChanged_ = true;
-    lua_.SignalJobSuccess(jobId);
+    mainLua_.SignalJobSuccess(jobId);
   }
 
   
   void ServerContext::SignalJobFailure(const std::string& jobId)
   {
     haveJobsChanged_ = true;
-    lua_.SignalJobFailure(jobId);
+    mainLua_.SignalJobFailure(jobId);
   }
 
 
@@ -225,7 +225,9 @@ namespace Orthanc
     storeMD5_(true),
     provider_(*this),
     dicomCache_(provider_, DICOM_CACHE_SIZE),
-    lua_(*this),
+    mainLua_(*this),
+    filterLua_(*this),
+    luaListener_(*this),
 #if ORTHANC_ENABLE_PLUGINS == 1
     plugins_(NULL),
 #endif
@@ -234,7 +236,7 @@ namespace Orthanc
     queryRetrieveArchive_(Configuration::GetGlobalUnsignedIntegerParameter("QueryRetrieveSize", 10)),
     defaultLocalAet_(Configuration::GetGlobalStringParameter("DicomAet", "ORTHANC"))
   {
-    listeners_.push_back(ServerListener(lua_, "Lua"));
+    listeners_.push_back(ServerListener(luaListener_, "Lua"));
 
     SetupJobsEngine(unitTesting, loadJobsFromDatabase);
 
@@ -699,7 +701,7 @@ namespace Orthanc
 
     // TODO REFACTOR THIS
     listeners_.clear();
-    listeners_.push_back(ServerListener(lua_, "Lua"));
+    listeners_.push_back(ServerListener(luaListener_, "Lua"));
     listeners_.push_back(ServerListener(plugins, "plugin"));
   }
 
@@ -712,7 +714,7 @@ namespace Orthanc
 
     // TODO REFACTOR THIS
     listeners_.clear();
-    listeners_.push_back(ServerListener(lua_, "Lua"));
+    listeners_.push_back(ServerListener(luaListener_, "Lua"));
   }
 
 


=====================================
OrthancServer/ServerContext.h
=====================================
--- a/OrthancServer/ServerContext.h
+++ b/OrthancServer/ServerContext.h
@@ -63,6 +63,36 @@ namespace Orthanc
   class ServerContext : private JobsRegistry::IObserver
   {
   private:
+    class LuaServerListener : public IServerListener
+    {
+    private:
+      ServerContext& context_;
+
+    public:
+      LuaServerListener(ServerContext& context) :
+        context_(context)
+      {
+      }
+
+      virtual void SignalStoredInstance(const std::string& publicId,
+                                        DicomInstanceToStore& instance,
+                                        const Json::Value& simplifiedTags)
+      {
+        context_.mainLua_.SignalStoredInstance(publicId, instance, simplifiedTags);
+      }
+    
+      virtual void SignalChange(const ServerIndexChange& change)
+      {
+        context_.mainLua_.SignalChange(change);
+      }
+
+      virtual bool FilterIncomingInstance(const DicomInstanceToStore& instance,
+                                          const Json::Value& simplified)
+      {
+        return context_.filterLua_.FilterIncomingInstance(instance, simplified);
+      }
+    };
+    
     class DicomCacheProvider : public ICachePageProvider
     {
     private:
@@ -135,7 +165,9 @@ namespace Orthanc
     MemoryCache dicomCache_;
     JobsEngine jobsEngine_;
 
-    LuaScripting lua_;
+    LuaScripting mainLua_;
+    LuaScripting filterLua_;
+    LuaServerListener  luaListener_;
 
 #if ORTHANC_ENABLE_PLUGINS == 1
     OrthancPlugins* plugins_;
@@ -279,7 +311,7 @@ namespace Orthanc
 
     LuaScripting& GetLuaScripting()
     {
-      return lua_;
+      return mainLua_;
     }
 
     OrthancHttpHandler& GetHttpHandler()


=====================================
OrthancServer/ServerEnumerations.h
=====================================
--- a/OrthancServer/ServerEnumerations.h
+++ b/OrthancServer/ServerEnumerations.h
@@ -77,6 +77,8 @@ namespace Orthanc
     GlobalProperty_FlushSleep = 2,
     GlobalProperty_AnonymizationSequence = 3,
     GlobalProperty_JobsRegistry = 5,
+    GlobalProperty_TotalCompressedSize = 6,     // Reserved for Orthanc > 1.4.1
+    GlobalProperty_TotalUncompressedSize = 7,   // Reserved for Orthanc > 1.4.1
 
     // Reserved values for internal use by the database plugins
     GlobalProperty_DatabasePatchLevel = 4,


=====================================
OrthancServer/main.cpp
=====================================
--- a/OrthancServer/main.cpp
+++ b/OrthancServer/main.cpp
@@ -995,9 +995,6 @@ static bool ConfigureServerContext(IDatabaseWrapper& database,
     context.GetIndex().SetMaximumStorageSize(0);
   }
 
-  LOG(INFO) << "Initializing Lua for the event handler";
-  context.GetLuaScripting().LoadGlobalConfiguration();
-
   context.GetJobsEngine().GetRegistry().SetMaxCompletedJobs
     (Configuration::GetGlobalUnsignedIntegerParameter("JobsHistorySize", 10));
 


=====================================
Resources/CMake/OrthancFrameworkParameters.cmake
=====================================
--- a/Resources/CMake/OrthancFrameworkParameters.cmake
+++ b/Resources/CMake/OrthancFrameworkParameters.cmake
@@ -3,7 +3,7 @@
 #####################################################################
 
 # Version of the build, should always be "mainline" except in release branches
-set(ORTHANC_VERSION "1.4.0")
+set(ORTHANC_VERSION "1.4.1")
 
 # Version of the database schema. History:
 #   * Orthanc 0.1.0 -> Orthanc 0.3.0 = no versioning


=====================================
Resources/Configuration.json
=====================================
--- a/Resources/Configuration.json
+++ b/Resources/Configuration.json
@@ -43,7 +43,7 @@
   "Plugins" : [
   ],
 
-  // Maximum number of processing jobs that are simultanously running
+  // Maximum number of processing jobs that are simultaneously running
   // at any given time. A value of "0" indicates to use all the
   // available CPU logical cores. To emulate Orthanc <= 1.3.2, set
   // this value to "1".


=====================================
Resources/DownloadOrthancFramework.cmake
=====================================
--- a/Resources/DownloadOrthancFramework.cmake
+++ b/Resources/DownloadOrthancFramework.cmake
@@ -85,6 +85,8 @@ if (ORTHANC_FRAMEWORK_SOURCE STREQUAL "hg" OR
         set(ORTHANC_FRAMEWORK_MD5 "dac95bd6cf86fb19deaf4e612961f378")
       elseif (ORTHANC_FRAMEWORK_VERSION STREQUAL "1.3.2")
         set(ORTHANC_FRAMEWORK_MD5 "d0ccdf68e855d8224331f13774992750")
+      elseif (ORTHANC_FRAMEWORK_VERSION STREQUAL "1.4.0")
+        set(ORTHANC_FRAMEWORK_MD5 "81e15f34d97ac32bbd7d26e85698835a")
       endif()
     endif()
   endif()


=====================================
Plugins/Samples/DatabasePlugin/CMakeLists.txt → Resources/Graveyard/DatabasePluginSample/CMakeLists.txt
=====================================


=====================================
Plugins/Samples/DatabasePlugin/Database.cpp → Resources/Graveyard/DatabasePluginSample/Database.cpp
=====================================


=====================================
Plugins/Samples/DatabasePlugin/Database.h → Resources/Graveyard/DatabasePluginSample/Database.h
=====================================


=====================================
OrthancServer/DatabaseWrapperBase.cpp → Resources/Graveyard/DatabasePluginSample/DatabaseWrapperBase.cpp
=====================================


=====================================
OrthancServer/DatabaseWrapperBase.h → Resources/Graveyard/DatabasePluginSample/DatabaseWrapperBase.h
=====================================


=====================================
Plugins/Samples/DatabasePlugin/Plugin.cpp → Resources/Graveyard/DatabasePluginSample/Plugin.cpp
=====================================


=====================================
debian/changelog
=====================================
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+orthanc (1.4.1+dfsg-1) UNRELEASED; urgency=medium
+
+  * New upstream version
+
+ -- Sebastien Jodogne <s.jodogne at gmail.com>  Tue, 17 Jul 2018 16:52:47 +0200
+
 orthanc (1.4.0+dfsg-1) unstable; urgency=medium
 
   * New upstream version


=====================================
debian/docs/Orthanc.1
=====================================
--- a/debian/docs/Orthanc.1
+++ b/debian/docs/Orthanc.1
@@ -1,5 +1,5 @@
 .\" DO NOT MODIFY THIS FILE!  It was generated by help2man 1.47.6.
-.TH ORTHANC "1" "July 2018" "Orthanc 1.4.0" "User Commands"
+.TH ORTHANC "1" "July 2018" "Orthanc 1.4.1" "User Commands"
 .SH NAME
 Orthanc \- Lightweight, RESTful DICOM server for healthcare and medical research
 .SH SYNOPSIS


=====================================
debian/docs/OrthancRecoverCompressedFile.8
=====================================
--- a/debian/docs/OrthancRecoverCompressedFile.8
+++ b/debian/docs/OrthancRecoverCompressedFile.8
@@ -1,4 +1,4 @@
-.TH ORTHANC "8" "July 2018" "Orthanc 1.4.0" "System Administration tools and Deamons"
+.TH ORTHANC "8" "July 2018" "Orthanc 1.4.1" "System Administration tools and Deamons"
 .SH NAME
 Orthanc \- Lightweight, RESTful DICOM server for healthcare and medical research
 .SH SYNOPSIS



View it on GitLab: https://salsa.debian.org/med-team/orthanc/compare/91a7814bd3c618b1b58029155c25e169ac9ec334...cb54d1f71d1ecdc7a377117d1849365a3dc35bae

-- 
View it on GitLab: https://salsa.debian.org/med-team/orthanc/compare/91a7814bd3c618b1b58029155c25e169ac9ec334...cb54d1f71d1ecdc7a377117d1849365a3dc35bae
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/debian-med-commit/attachments/20180717/1a422beb/attachment-0001.html>


More information about the debian-med-commit mailing list