changeset 255:d663d9e44f8d

reintroduction of IDatabaseFactory into DatabaseManager
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 14 Apr 2021 17:57:08 +0200
parents 8a4ce70f456a
children e184dcadf163
files Framework/Common/DatabaseManager.cpp Framework/Common/DatabaseManager.h Framework/Common/DatabasesEnumerations.h Framework/MySQL/MySQLDatabase.cpp Framework/MySQL/MySQLDatabase.h Framework/Plugins/DatabaseBackendAdapterV3.cpp Framework/Plugins/IDatabaseBackend.h Framework/Plugins/IndexBackend.cpp Framework/Plugins/StorageBackend.cpp Framework/Plugins/StorageBackend.h Framework/PostgreSQL/PostgreSQLDatabase.cpp Framework/PostgreSQL/PostgreSQLDatabase.h MySQL/Plugins/MySQLIndex.cpp MySQL/Plugins/MySQLIndex.h MySQL/Plugins/MySQLStorageArea.cpp MySQL/UnitTests/UnitTestsMain.cpp PostgreSQL/Plugins/PostgreSQLIndex.cpp PostgreSQL/Plugins/PostgreSQLIndex.h PostgreSQL/Plugins/PostgreSQLStorageArea.cpp PostgreSQL/UnitTests/PostgreSQLTests.cpp SQLite/Plugins/SQLiteIndex.cpp SQLite/Plugins/SQLiteIndex.h
diffstat 22 files changed, 186 insertions(+), 147 deletions(-) [+]
line wrap: on
line diff
--- a/Framework/Common/DatabaseManager.cpp	Wed Apr 14 15:33:57 2021 +0200
+++ b/Framework/Common/DatabaseManager.cpp	Wed Apr 14 17:57:08 2021 +0200
@@ -159,30 +159,54 @@
   }
 
     
-  DatabaseManager::DatabaseManager(IDatabase* database) :
-    database_(database)
+  DatabaseManager::DatabaseManager(IDatabaseFactory* factory) :
+    factory_(factory),
+    dialect_(Dialect_Unknown)
   {
-    if (database == NULL)
+    if (factory == NULL)
     {
       throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
     }
-
-    dialect_ = database->GetDialect();
   }
 
   
   IDatabase& DatabaseManager::GetDatabase()
   {
+    assert(factory_.get() != NULL);
+    
     if (database_.get() == NULL)
     {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_DatabaseUnavailable);
+      database_.reset(factory_->Open());
+
+      if (database_.get() == NULL)
+      {
+        throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
+      }
+
+      dialect_ = database_->GetDialect();
+      if (dialect_ == Dialect_Unknown)
+      {
+        throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
+      }
+    }
+
+    return *database_;
+  }
+
+
+  Dialect DatabaseManager::GetDialect() const
+  {
+    if (database_.get() == NULL)
+    {
+      throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
     }
     else
     {
-      return *database_;
+      assert(dialect_ != Dialect_Unknown);
+      return dialect_;
     }
   }
-
+  
 
   void DatabaseManager::StartTransaction(TransactionType type)
   {
--- a/Framework/Common/DatabaseManager.h	Wed Apr 14 15:33:57 2021 +0200
+++ b/Framework/Common/DatabaseManager.h	Wed Apr 14 17:57:08 2021 +0200
@@ -21,7 +21,7 @@
 
 #pragma once
 
-#include "IDatabase.h"
+#include "IDatabaseFactory.h"
 #include "StatementLocation.h"
 
 #include <Compatibility.h>  // For std::unique_ptr<>
@@ -39,12 +39,17 @@
    *
    * This class maintains a list of precompiled statements. At any
    * time, this class handles 0 or 1 active transaction.
+   *
+   * "DatabaseManager" takes a "IDatabaseFactory" as input, in order
+   * to be able to automatically re-open the database connection if
+   * the latter gets lost.
    **/
   class DatabaseManager : public boost::noncopyable
   {
   private:
     typedef std::map<StatementLocation, IPrecompiledStatement*>  CachedStatements;
 
+    std::unique_ptr<IDatabaseFactory>  factory_;
     std::unique_ptr<IDatabase>     database_;
     std::unique_ptr<ITransaction>  transaction_;
     CachedStatements               cachedStatements_;
@@ -62,7 +67,7 @@
     void ReleaseImplicitTransaction();
 
   public:
-    explicit DatabaseManager(IDatabase* database);  // Takes ownership
+    explicit DatabaseManager(IDatabaseFactory* factory);  // Takes ownership
     
     ~DatabaseManager()
     {
@@ -71,10 +76,7 @@
 
     IDatabase& GetDatabase();
 
-    Dialect GetDialect() const
-    {
-      return dialect_;
-    }
+    Dialect GetDialect() const;
 
     void Close();
     
--- a/Framework/Common/DatabasesEnumerations.h	Wed Apr 14 15:33:57 2021 +0200
+++ b/Framework/Common/DatabasesEnumerations.h	Wed Apr 14 17:57:08 2021 +0200
@@ -38,7 +38,8 @@
   {
     Dialect_MySQL,
     Dialect_PostgreSQL,
-    Dialect_SQLite
+    Dialect_SQLite,
+    Dialect_Unknown
   };
 
   enum TransactionType
--- a/Framework/MySQL/MySQLDatabase.cpp	Wed Apr 14 15:33:57 2021 +0200
+++ b/Framework/MySQL/MySQLDatabase.cpp	Wed Apr 14 17:57:08 2021 +0200
@@ -661,31 +661,38 @@
   }
 
   
-  MySQLDatabase* MySQLDatabase::OpenDatabaseConnection(const MySQLParameters& parameters)
+  class MySQLDatabase::Factory : public RetryDatabaseFactory
   {
-    class Factory : public RetryDatabaseFactory
-    {
-    private:
-      const MySQLParameters&  parameters_;
+  private:
+    MySQLParameters  parameters_;
 
-    protected:
-      virtual IDatabase* TryOpen()
-      {
-        std::unique_ptr<MySQLDatabase> db(new MySQLDatabase(parameters_));
-        db->Open();
-        db->ExecuteMultiLines("SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE", false);
-        return db.release();
-      }
+  protected:
+    virtual IDatabase* TryOpen()
+    {
+      std::unique_ptr<MySQLDatabase> db(new MySQLDatabase(parameters_));
+      db->Open();
+      db->ExecuteMultiLines("SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE", false);
+      return db.release();
+    }
       
-    public:
-      explicit Factory(const MySQLParameters& parameters) :
-        RetryDatabaseFactory(parameters.GetMaxConnectionRetries(),
-                             parameters.GetConnectionRetryInterval()),
-        parameters_(parameters)
-      {
-      }
-    };
+  public:
+    explicit Factory(const MySQLParameters& parameters) :
+      RetryDatabaseFactory(parameters.GetMaxConnectionRetries(),
+                           parameters.GetConnectionRetryInterval()),
+      parameters_(parameters)
+    {
+    }
+  };
 
+
+  IDatabaseFactory* MySQLDatabase::CreateDatabaseFactory(const MySQLParameters& parameters)
+  {
+    return new Factory(parameters);
+  }
+
+
+  MySQLDatabase* MySQLDatabase::CreateDatabaseConnection(const MySQLParameters& parameters)
+  {
     Factory factory(parameters);
     return dynamic_cast<MySQLDatabase*>(factory.Open());
   }
--- a/Framework/MySQL/MySQLDatabase.h	Wed Apr 14 15:33:57 2021 +0200
+++ b/Framework/MySQL/MySQLDatabase.h	Wed Apr 14 17:57:08 2021 +0200
@@ -25,7 +25,7 @@
 #  error MySQL support must be enabled to use this file
 #endif
 
-#include "../Common/IDatabase.h"
+#include "../Common/IDatabaseFactory.h"
 #include "MySQLParameters.h"
 
 #include <mysql.h>
@@ -37,6 +37,8 @@
   class MySQLDatabase : public IDatabase
   {
   private:
+    class Factory;
+    
     MySQLParameters  parameters_;
     MYSQL           *mysql_;
 
@@ -119,6 +121,8 @@
       ~TransientAdvisoryLock();
     };
 
-    static MySQLDatabase* OpenDatabaseConnection(const MySQLParameters& parameters);
+    static IDatabaseFactory* CreateDatabaseFactory(const MySQLParameters& parameters);
+
+    static MySQLDatabase* CreateDatabaseConnection(const MySQLParameters& parameters);
   };
 }
--- a/Framework/Plugins/DatabaseBackendAdapterV3.cpp	Wed Apr 14 15:33:57 2021 +0200
+++ b/Framework/Plugins/DatabaseBackendAdapterV3.cpp	Wed Apr 14 17:57:08 2021 +0200
@@ -154,14 +154,17 @@
         assert(backend_.get() != NULL);
 
         {
-          std::unique_ptr<DatabaseManager> manager(new DatabaseManager(backend_->OpenDatabaseConnection()));
+          std::unique_ptr<DatabaseManager> manager(new DatabaseManager(backend_->CreateDatabaseFactory()));
+          manager->GetDatabase();  // Make sure to open the database connection
+          
           backend_->ConfigureDatabase(*manager);
           connections_.push_back(manager.release());
         }
 
         for (size_t i = 1; i < countConnections_; i++)
         {
-          connections_.push_back(new DatabaseManager(backend_->OpenDatabaseConnection()));
+          connections_.push_back(new DatabaseManager(backend_->CreateDatabaseFactory()));
+          connections_.back()->GetDatabase();  // Make sure to open the database connection
         }
 
         for (std::list<DatabaseManager*>::iterator
--- a/Framework/Plugins/IDatabaseBackend.h	Wed Apr 14 15:33:57 2021 +0200
+++ b/Framework/Plugins/IDatabaseBackend.h	Wed Apr 14 17:57:08 2021 +0200
@@ -39,7 +39,7 @@
 
     virtual OrthancPluginContext* GetContext() = 0;
 
-    virtual IDatabase* OpenDatabaseConnection() = 0;
+    virtual IDatabaseFactory* CreateDatabaseFactory() = 0;
 
     // This function is invoked once, even if multiple connections are open
     virtual void ConfigureDatabase(DatabaseManager& database) = 0;
--- a/Framework/Plugins/IndexBackend.cpp	Wed Apr 14 15:33:57 2021 +0200
+++ b/Framework/Plugins/IndexBackend.cpp	Wed Apr 14 17:57:08 2021 +0200
@@ -2527,7 +2527,7 @@
 
   DatabaseManager* IndexBackend::CreateSingleDatabaseManager(IDatabaseBackend& backend)
   {
-    std::unique_ptr<DatabaseManager> manager(new DatabaseManager(backend.OpenDatabaseConnection()));
+    std::unique_ptr<DatabaseManager> manager(new DatabaseManager(backend.CreateDatabaseFactory()));
     backend.ConfigureDatabase(*manager);
     return manager.release();
   }
--- a/Framework/Plugins/StorageBackend.cpp	Wed Apr 14 15:33:57 2021 +0200
+++ b/Framework/Plugins/StorageBackend.cpp	Wed Apr 14 17:57:08 2021 +0200
@@ -56,36 +56,11 @@
 
 namespace OrthancDatabases
 {
-  void StorageBackend::SetDatabase(IDatabase* database)
+  StorageBackend::StorageBackend(IDatabaseFactory* factory) :
+    manager_(factory)
   {
-    if (database == NULL)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
-    }
-    else if (manager_.get() != NULL)
-    {
-      delete database;
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-    else
-    {
-      manager_.reset(new DatabaseManager(database));
-    }
   }
   
-  DatabaseManager& StorageBackend::GetManager()
-  {
-    if (manager_.get() == NULL)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-    else
-    {
-      return *manager_;
-    }
-  }
-    
-
   void StorageBackend::AccessorBase::Create(const std::string& uuid,
                                             const void* content,
                                             size_t size,
--- a/Framework/Plugins/StorageBackend.h	Wed Apr 14 15:33:57 2021 +0200
+++ b/Framework/Plugins/StorageBackend.h	Wed Apr 14 17:57:08 2021 +0200
@@ -74,11 +74,9 @@
   private:
     class StringVisitor;
     
-    boost::mutex                       mutex_;
-    std::unique_ptr<DatabaseManager>   manager_;
+    boost::mutex      mutex_;
+    DatabaseManager   manager_;
 
-    DatabaseManager& GetManager();
-    
   protected:
     class AccessorBase : public IAccessor
     {
@@ -89,7 +87,7 @@
     public:
       explicit AccessorBase(StorageBackend& backend) :
         lock_(backend.mutex_),
-        manager_(backend.GetManager())
+        manager_(backend.manager_)
       {
       }
 
@@ -117,11 +115,11 @@
                           OrthancPluginContentType type) ORTHANC_OVERRIDE;
     };
     
-    void SetDatabase(IDatabase* database);  // Takes ownership
-
     virtual bool HasReadRange() const = 0;
 
   public:
+    StorageBackend(IDatabaseFactory* factory);  // Takes ownership
+
     virtual ~StorageBackend()
     {
     }
--- a/Framework/PostgreSQL/PostgreSQLDatabase.cpp	Wed Apr 14 15:33:57 2021 +0200
+++ b/Framework/PostgreSQL/PostgreSQLDatabase.cpp	Wed Apr 14 17:57:08 2021 +0200
@@ -325,30 +325,37 @@
   }
 
 
-  PostgreSQLDatabase* PostgreSQLDatabase::OpenDatabaseConnection(const PostgreSQLParameters& parameters)
+  class PostgreSQLDatabase::Factory : public RetryDatabaseFactory
   {
-    class Factory : public RetryDatabaseFactory
+  private:
+    PostgreSQLParameters  parameters_;
+    
+  protected:
+    virtual IDatabase* TryOpen()
     {
-    private:
-      const PostgreSQLParameters&  parameters_;
+      std::unique_ptr<PostgreSQLDatabase> db(new PostgreSQLDatabase(parameters_));
+      db->Open();
+      return db.release();
+    }
+    
+  public:
+    explicit Factory(const PostgreSQLParameters& parameters) :
+      RetryDatabaseFactory(parameters.GetMaxConnectionRetries(),
+                           parameters.GetConnectionRetryInterval()),
+      parameters_(parameters)
+    {
+    }
+  };
 
-    protected:
-      virtual IDatabase* TryOpen()
-      {
-        std::unique_ptr<PostgreSQLDatabase> db(new PostgreSQLDatabase(parameters_));
-        db->Open();
-        return db.release();
-      }
-      
-    public:
-      explicit Factory(const PostgreSQLParameters& parameters) :
-        RetryDatabaseFactory(parameters.GetMaxConnectionRetries(),
-                             parameters.GetConnectionRetryInterval()),
-        parameters_(parameters)
-      {
-      }
-    };
 
+  IDatabaseFactory* PostgreSQLDatabase::CreateDatabaseFactory(const PostgreSQLParameters& parameters)
+  {
+    return new Factory(parameters);
+  }
+
+
+  PostgreSQLDatabase* PostgreSQLDatabase::CreateDatabaseConnection(const PostgreSQLParameters& parameters)
+  {
     Factory factory(parameters);
     return dynamic_cast<PostgreSQLDatabase*>(factory.Open());
   }
--- a/Framework/PostgreSQL/PostgreSQLDatabase.h	Wed Apr 14 15:33:57 2021 +0200
+++ b/Framework/PostgreSQL/PostgreSQLDatabase.h	Wed Apr 14 17:57:08 2021 +0200
@@ -26,7 +26,7 @@
 #endif
 
 #include "PostgreSQLParameters.h"
-#include "../Common/IDatabase.h"
+#include "../Common/IDatabaseFactory.h"
 
 namespace OrthancDatabases
 {
@@ -36,6 +36,8 @@
     friend class PostgreSQLStatement;
     friend class PostgreSQLLargeObject;
 
+    class Factory;
+
     PostgreSQLParameters  parameters_;
     void*                 pg_;   /* Object of type "PGconn*" */
 
@@ -90,6 +92,8 @@
       ~TransientAdvisoryLock();
     };
 
-    static PostgreSQLDatabase* OpenDatabaseConnection(const PostgreSQLParameters& parameters);
+    static IDatabaseFactory* CreateDatabaseFactory(const PostgreSQLParameters& parameters);
+
+    static PostgreSQLDatabase* CreateDatabaseConnection(const PostgreSQLParameters& parameters);
   };
 }
--- a/MySQL/Plugins/MySQLIndex.cpp	Wed Apr 14 15:33:57 2021 +0200
+++ b/MySQL/Plugins/MySQLIndex.cpp	Wed Apr 14 17:57:08 2021 +0200
@@ -45,9 +45,9 @@
   }
 
 
-  IDatabase* MySQLIndex::OpenDatabaseConnection()
+  IDatabaseFactory* MySQLIndex::CreateDatabaseFactory() 
   {
-    return MySQLDatabase::OpenDatabaseConnection(parameters_);
+    return MySQLDatabase::CreateDatabaseFactory(parameters_);
   }
 
 
--- a/MySQL/Plugins/MySQLIndex.h	Wed Apr 14 15:33:57 2021 +0200
+++ b/MySQL/Plugins/MySQLIndex.h	Wed Apr 14 17:57:08 2021 +0200
@@ -41,7 +41,7 @@
       clearAll_ = clear;
     }
 
-    virtual IDatabase* OpenDatabaseConnection() ORTHANC_OVERRIDE;
+    virtual IDatabaseFactory* CreateDatabaseFactory() ORTHANC_OVERRIDE;
 
     virtual void ConfigureDatabase(DatabaseManager& database) ORTHANC_OVERRIDE;
  
--- a/MySQL/Plugins/MySQLStorageArea.cpp	Wed Apr 14 15:33:57 2021 +0200
+++ b/MySQL/Plugins/MySQLStorageArea.cpp	Wed Apr 14 17:57:08 2021 +0200
@@ -87,17 +87,14 @@
 
 
   MySQLStorageArea::MySQLStorageArea(const MySQLParameters& parameters,
-                                     bool clearAll)
+                                     bool clearAll) :
+    StorageBackend(MySQLDatabase::CreateDatabaseFactory(parameters))
   {
-    std::unique_ptr<MySQLDatabase> database(MySQLDatabase::OpenDatabaseConnection(parameters));
-    
-    if (database.get() == NULL)
     {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
+      AccessorBase accessor(*this);
+      MySQLDatabase& database = dynamic_cast<MySQLDatabase&>(accessor.GetManager().GetDatabase());
+      ConfigureDatabase(database, parameters, clearAll);
     }
-    
-    ConfigureDatabase(*database, parameters, clearAll);
-    SetDatabase(database.release());
   }
 
 
--- a/MySQL/UnitTests/UnitTestsMain.cpp	Wed Apr 14 15:33:57 2021 +0200
+++ b/MySQL/UnitTests/UnitTestsMain.cpp	Wed Apr 14 17:57:08 2021 +0200
@@ -157,7 +157,7 @@
 TEST(MySQL, StorageArea)
 {
   std::unique_ptr<OrthancDatabases::MySQLDatabase> database(
-    OrthancDatabases::MySQLDatabase::OpenDatabaseConnection(globalParameters_));
+    OrthancDatabases::MySQLDatabase::CreateDatabaseConnection(globalParameters_));
   
   OrthancDatabases::MySQLStorageArea storageArea(globalParameters_, true /* clear database */);
 
@@ -214,7 +214,7 @@
 TEST(MySQL, StorageReadRange)
 {
   std::unique_ptr<OrthancDatabases::MySQLDatabase> database(
-    OrthancDatabases::MySQLDatabase::OpenDatabaseConnection(globalParameters_));
+    OrthancDatabases::MySQLDatabase::CreateDatabaseConnection(globalParameters_));
   
   OrthancDatabases::MySQLStorageArea storageArea(globalParameters_, true /* clear database */);
 
--- a/PostgreSQL/Plugins/PostgreSQLIndex.cpp	Wed Apr 14 15:33:57 2021 +0200
+++ b/PostgreSQL/Plugins/PostgreSQLIndex.cpp	Wed Apr 14 17:57:08 2021 +0200
@@ -54,9 +54,9 @@
   }
 
   
-  IDatabase* PostgreSQLIndex::OpenDatabaseConnection()
+  IDatabaseFactory* PostgreSQLIndex::CreateDatabaseFactory()
   {
-    return PostgreSQLDatabase::OpenDatabaseConnection(parameters_);
+    return PostgreSQLDatabase::CreateDatabaseFactory(parameters_);
   }
 
   
--- a/PostgreSQL/Plugins/PostgreSQLIndex.h	Wed Apr 14 15:33:57 2021 +0200
+++ b/PostgreSQL/Plugins/PostgreSQLIndex.h	Wed Apr 14 17:57:08 2021 +0200
@@ -41,7 +41,7 @@
       clearAll_ = clear;
     }
 
-    virtual IDatabase* OpenDatabaseConnection() ORTHANC_OVERRIDE;
+    virtual IDatabaseFactory* CreateDatabaseFactory() ORTHANC_OVERRIDE;
 
     virtual void ConfigureDatabase(DatabaseManager& manager) ORTHANC_OVERRIDE;
 
--- a/PostgreSQL/Plugins/PostgreSQLStorageArea.cpp	Wed Apr 14 15:33:57 2021 +0200
+++ b/PostgreSQL/Plugins/PostgreSQLStorageArea.cpp	Wed Apr 14 17:57:08 2021 +0200
@@ -70,16 +70,13 @@
 
 
   PostgreSQLStorageArea::PostgreSQLStorageArea(const PostgreSQLParameters& parameters,
-                                               bool clearAll)
+                                               bool clearAll) :
+    StorageBackend(PostgreSQLDatabase::CreateDatabaseFactory(parameters))
   {
-    std::unique_ptr<PostgreSQLDatabase> database(PostgreSQLDatabase::OpenDatabaseConnection(parameters));
-    
-    if (database.get() == NULL)
     {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
+      AccessorBase accessor(*this);
+      PostgreSQLDatabase& database = dynamic_cast<PostgreSQLDatabase&>(accessor.GetManager().GetDatabase());
+      ConfigureDatabase(database, parameters, clearAll);
     }
-    
-    ConfigureDatabase(*database, parameters, clearAll);
-    SetDatabase(database.release());
   }
 }
--- a/PostgreSQL/UnitTests/PostgreSQLTests.cpp	Wed Apr 14 15:33:57 2021 +0200
+++ b/PostgreSQL/UnitTests/PostgreSQLTests.cpp	Wed Apr 14 17:57:08 2021 +0200
@@ -358,7 +358,7 @@
 
 TEST(PostgreSQL, StorageArea)
 {
-  std::unique_ptr<PostgreSQLDatabase> database(PostgreSQLDatabase::OpenDatabaseConnection(globalParameters_));
+  std::unique_ptr<PostgreSQLDatabase> database(PostgreSQLDatabase::CreateDatabaseConnection(globalParameters_));
   
   PostgreSQLStorageArea storageArea(globalParameters_, true /* clear database */);
 
@@ -413,7 +413,7 @@
 TEST(PostgreSQL, StorageReadRange)
 {
   std::unique_ptr<OrthancDatabases::PostgreSQLDatabase> database(
-    OrthancDatabases::PostgreSQLDatabase::OpenDatabaseConnection(globalParameters_));
+    OrthancDatabases::PostgreSQLDatabase::CreateDatabaseConnection(globalParameters_));
   
   OrthancDatabases::PostgreSQLStorageArea storageArea(globalParameters_, true /* clear database */);
 
--- a/SQLite/Plugins/SQLiteIndex.cpp	Wed Apr 14 15:33:57 2021 +0200
+++ b/SQLite/Plugins/SQLiteIndex.cpp	Wed Apr 14 17:57:08 2021 +0200
@@ -34,33 +34,53 @@
 
 namespace OrthancDatabases
 {
-  IDatabase* SQLiteIndex::OpenDatabaseConnection()
+  IDatabaseFactory* SQLiteIndex::CreateDatabaseFactory()
   {
-    std::unique_ptr<SQLiteDatabase> db(new SQLiteDatabase);
-
-    if (path_.empty())
+    class Factory : public IDatabaseFactory
     {
-      db->OpenInMemory();
-    }
-    else
-    {
-      db->Open(path_);
-    }
+    private:
+      std::string  path_;
+      bool         fast_;
+      
+    public:
+      Factory(const std::string& path,
+              bool fast) :
+        path_(path),
+        fast_(fast)
+      {
+      }
+      
+      virtual IDatabase* Open() ORTHANC_OVERRIDE
+      {
+        std::unique_ptr<SQLiteDatabase> db(new SQLiteDatabase);
 
-    db->Execute("PRAGMA ENCODING=\"UTF-8\";");
+        if (path_.empty())
+        {
+          db->OpenInMemory();
+        }
+        else
+        {
+          db->Open(path_);
+        }
+
+        db->Execute("PRAGMA ENCODING=\"UTF-8\";");
 
-    if (fast_)
-    {
-      // Performance tuning of SQLite with PRAGMAs
-      // http://www.sqlite.org/pragma.html
-      db->Execute("PRAGMA SYNCHRONOUS=NORMAL;");
-      db->Execute("PRAGMA JOURNAL_MODE=WAL;");
-      db->Execute("PRAGMA LOCKING_MODE=EXCLUSIVE;");
-      db->Execute("PRAGMA WAL_AUTOCHECKPOINT=1000;");
-      //db->Execute("PRAGMA TEMP_STORE=memory");
-    }
+        if (fast_)
+        {
+          // Performance tuning of SQLite with PRAGMAs
+          // http://www.sqlite.org/pragma.html
+          db->Execute("PRAGMA SYNCHRONOUS=NORMAL;");
+          db->Execute("PRAGMA JOURNAL_MODE=WAL;");
+          db->Execute("PRAGMA LOCKING_MODE=EXCLUSIVE;");
+          db->Execute("PRAGMA WAL_AUTOCHECKPOINT=1000;");
+          //db->Execute("PRAGMA TEMP_STORE=memory");
+        }
 
-    return db.release();
+        return db.release();
+      }
+    };
+
+    return new Factory(path_, fast_);
   }
 
 
--- a/SQLite/Plugins/SQLiteIndex.h	Wed Apr 14 15:33:57 2021 +0200
+++ b/SQLite/Plugins/SQLiteIndex.h	Wed Apr 14 17:57:08 2021 +0200
@@ -42,7 +42,7 @@
       fast_ = fast;
     }
 
-    virtual IDatabase* OpenDatabaseConnection() ORTHANC_OVERRIDE;
+    virtual IDatabaseFactory* CreateDatabaseFactory() ORTHANC_OVERRIDE;
 
     virtual void ConfigureDatabase(DatabaseManager& manager) ORTHANC_OVERRIDE;