diff --git a/GeoModelDBManager/GeoModelDBManager/GMDBManager.h b/GeoModelDBManager/GeoModelDBManager/GMDBManager.h
index 06dbf03af328c29c376297ef861df960e8866f76..aa864bd642c60bffadd64b88ad3032097e612381 100644
--- a/GeoModelDBManager/GeoModelDBManager/GMDBManager.h
+++ b/GeoModelDBManager/GeoModelDBManager/GMDBManager.h
@@ -55,7 +55,8 @@ public:
 	/**
 	 * @brief Returns true if the DB is correctly open
 	 */
-  bool isOpen() const;
+//  bool isOpen() const;
+  bool checkIsDBOpen() const;
 
 	/**
 	 * @brief Print names of all GeoPhysVol objects in db
@@ -137,14 +138,13 @@ public:
 	 * @brief Print the current version number of the DB schema
 	 */
 	void printDBVersion() const;
-  
-  
+
   
   void printAllDBTables();
+  void getAllDBTables();
   int execQuery(std::string queryStr);
 
 
-
 	// ADD methods
   /* single-item adders are not efficient, so they are not used at the moment. We might want to enable them again later if we'll have specific use-cases.
 	QVariant addShape(const QString &type, const QString &parameters);
@@ -165,29 +165,25 @@ public:
   bool addListOfRecords(const std::string geoType, const std::vector<std::vector<std::string>> records);
   
 //  bool addListOfRecordsToTable(const QString tableName, const std::vector<QStringList> records);
-  bool addListOfRecordsToTableStd(const std::string tableName, const std::vector<std::vector<std::string>> records);
+//  bool addListOfRecordsToTableStd(const std::string tableName, const std::vector<std::vector<std::string>> records);
   bool addListOfRecordsToTable(const std::string tableName, const std::vector<std::vector<std::string>> records);
   
 //  bool addListOfRecordsToTableOld(const QString tableName, const std::vector<QStringList> records); // for the old SQlite only
   bool addListOfChildrenPositions(const std::vector<std::vector<std::string>> &records);
 
 	bool addRootVolume(const std::vector<std::string> &values);
-  void addChildPosition(const unsigned int &parentId, const std::string &parentType, const unsigned int &childId, const unsigned int &parentCopyNumber, const unsigned int &childPos, const std::string &childType, const unsigned int &childCopyN);
+//  void addChildPosition(const unsigned int &parentId, const std::string &parentType, const unsigned int &childId, const unsigned int &parentCopyNumber, const unsigned int &childPos, const std::string &childType, const unsigned int &childCopyN);
 
   
-	void addDBversion(const QString);
-  void addDBversion(std::string version);
-
-
 	// GET methods
 
   std::string getDBFilePath();
 
   std::vector<std::string> getRootPhysVol();
 
-  std::vector<std::string> getItem(std::string geoType, unsigned int id);
-  std::vector<std::string> getItem(unsigned int tableId, unsigned int id);
-  
+//  std::vector<std::string> getItem(std::string geoType, unsigned int id);
+//  std::vector<std::string> getItem(unsigned int tableId, unsigned int id);
+//
 	
   std::vector<std::string> getItemFromTableName(std::string tableName, unsigned int id);
   
@@ -195,11 +191,11 @@ public:
 
   std::string getNodeTypeFromTableId(unsigned int id);
 
-  QMap<unsigned int, QStringList> getVPhysVolChildren(const unsigned int &id, const std::string &nodeType, const unsigned int &copyN);
+//  QMap<unsigned int, QStringList> getVPhysVolChildren(const unsigned int &id, const std::string &nodeType, const unsigned int &copyN);
 
 	/// methods to dump the DB
-	QHash<QString, QMap<unsigned int, QStringList>> getChildrenTable();
-  std::vector<std::vector<std::string>> getChildrenTableStd();
+//  QHash<QString, QMap<unsigned int, QStringList>> getChildrenTable();
+  std::vector<std::vector<std::string>> getChildrenTable();
 
 //  QHash<unsigned int, QStringList> getTableFromNodeType(QString nodeType);
   std::vector<std::vector<std::string>> getTableFromNodeType(std::string nodeType);
@@ -207,31 +203,37 @@ public:
   std::unordered_map<unsigned int, std::string> getAll_TableIDsNodeTypes();
   std::unordered_map<std::string, unsigned int> getAll_NodeTypesTableIDs();
   
+  std::vector<std::vector<std::string>> getTableRecords(std::string tableName) const; // TODO: should be private?
+
 
 private:
 
 	bool initDB();
 	bool createTables();
-  bool createTablesStd();
   
-  void checkIsDBOpen();
+
+  void addDBversion(std::string version);
+  
 
 
 //  void loadTestData(); // for debug only
 
-	void loadTableNamesFromDB();
-  std::vector<std::string> getTableColNamesFromDB(std::string tableName) const;
+//  void loadTableNamesFromDB();
+//  std::vector<std::string> getTableColNamesFromDB(std::string tableName) const;
+
+  int loadGeoNodeTypesAndBuildCache();
 
   std::string getTableNameFromTableId(unsigned int tabId);
   
   unsigned int getTableIdFromNodeType(const std::string &nodeType);
   void storeNodeType(std::string nodeType, std::string tableName);
 	
-  QString getTableNameFromNodeType(QString nodeType); // TODO: to be removed
-  std::string getTableNameFromNodeType(std::string nodeType);
+//  QString getTableNameFromNodeType(QString nodeType); // TODO: to be removed
+  std::string getTableNameFromNodeType(const std::string &nodeType);
 
-  QSqlQuery selectAllFromTable(std::string tableName) const;
-  QSqlQuery selectAllFromTableSortBy(std::string tableName, std::string sortColumn="") const;
+  sqlite3_stmt* selectAllFromTable(std::string tableName) const;
+  sqlite3_stmt* selectAllFromTableSortBy(std::string tableName, std::string sortColumn="") const;
+  sqlite3_stmt* selectAllFromTableChildrenPositions() const;
 
   void storeTableColumnNames(std::vector<std::string> input);
   
@@ -248,7 +250,7 @@ private:
 
   std::string m_dbpath;
 	
-  QSqlDatabase m_db;
+//  QSqlDatabase m_db;
   /// Pointer to SQLite connection
   sqlite3* m_dbSqlite;
   /// Variable to store error messages from SQLite
@@ -257,10 +259,16 @@ private:
   
 	bool m_dbIsOK;
 
-	bool m_deepDebug;
+	bool m_debug;
 
   std::unordered_map<std::string, std::vector<std::string>> m_tableNames; /// stores the column names for each table
   std::unordered_map<std::string, std::string> m_childType_tableName;
+  
+  std::vector<std::string> m_cache_tables; /// cache for the list of tables in the DB
+  std::unordered_map<unsigned int, std::string> m_cache_tableId_tableName; /// cache for tableID-->tableName
+  std::unordered_map<unsigned int, std::string> m_cache_tableId_nodeType; /// cache for tableID-->nodeType
+  std::unordered_map<std::string, std::string> m_cache_nodeType_tableName; /// cache for nodeType-->tableName
+  std::unordered_map<std::string, unsigned int> m_cache_nodeType_tableID; /// cache for nodeType-->tableID
 };
 
 #endif // GMDBManager_H
diff --git a/GeoModelDBManager/src/GMDBManager.cpp b/GeoModelDBManager/src/GMDBManager.cpp
index aae007db769a64eda3d0af655aa0ba7a2efa2464..d6fa34244f609c81817ff20e0fa9643aa94d58bd 100644
--- a/GeoModelDBManager/src/GMDBManager.cpp
+++ b/GeoModelDBManager/src/GMDBManager.cpp
@@ -1,6 +1,10 @@
 
-// author: Riccardo.Maria.Bianchi@cern.ch - 2017
-// major updates: Aug 2018
+/*
+* author: Riccardo.Maria.Bianchi@cern.ch - 2017
+* major updates:
+*  - Aug 2018, R.M.Bianchi
+*  - May 2020, R.M.Bianchi
+*/
 
 #include <GeoModelDBManager/GMDBManager.h>
 
@@ -51,30 +55,77 @@ std::string joinVectorStrings(std::vector<std::string> vec, std::string sep="")
 
 
 
-GMDBManager::GMDBManager(const std::string &path) : m_dbpath(path), m_SQLiteErrMsg(0), m_dbIsOK(false), m_deepDebug(false)
+//GMDBManager::GMDBManager(const std::string &path) : m_dbpath(path), m_SQLiteErrMsg(0), m_dbIsOK(false), m_debug(false)
+//{
+//  // TODO: move to a more organic way
+//  #ifdef GEOREAD_DEEP_DEBUG
+//    m_debug = true;
+//   #endif
+//
+//  m_dbIsOK = false;
+//
+//  m_db = QSqlDatabase::addDatabase("QSQLITE");
+//  m_db.setDatabaseName( QString::fromStdString(path));
+//
+//  if (!m_db.open())
+//  {
+//    std::cout << "Error: connection with database failed!\n";
+//    showError( m_db.lastError() );
+//    m_dbIsOK = false;
+//  }
+//  else
+//  {
+//    m_dbIsOK = true;
+//  }
+//
+////  // check if DB has tables, if not create them
+//  if (m_dbIsOK) {
+//    if ( ! (initDB()) ) {
+//      std::cout << "Error: database initialization failed" << std::endl;
+//      m_dbIsOK = false;
+//    }
+//  }
+//
+//  // populate DB with fake data, only for debug
+//  //loadTestData(); // TODO: we should move initDB() here, only for debug and Write
+//}
+
+//GMDBManager::~GMDBManager()
+//{
+//  m_db.close();
+//}
+
+
+//bool GMDBManager::isOpen() const
+//{
+//  if (! m_dbIsOK )
+//    return false;
+//  return m_db.isOpen();
+//}
+
+GMDBManager::GMDBManager(const std::string &path) : m_dbpath(path), m_dbSqlite(nullptr), m_SQLiteErrMsg(0), m_dbIsOK(false), m_debug(false)
 {
-  // TODO: move to a more organic way
-	#ifdef GEOREAD_DEEP_DEBUG
-	  m_deepDebug = true;
- 	#endif
+  // Check if the user asked for running in serial or multi-threading mode
+  if ( "" != getEnvVar("GEOMODEL_ENV_IO_DBMANAGER_DEBUG")) {
+    m_debug = true;
+    std::cout << "You defined the GEOMODEL_IO_DEBUG variable, so you will see a verbose output." << std::endl;
+  }
 
   m_dbIsOK = false;
 
-  m_db = QSqlDatabase::addDatabase("QSQLITE");
-  m_db.setDatabaseName( QString::fromStdString(path));
+  // FIXME: TODO: we should check the existence of the file, otherwise SQLite will create a new file from scratch
+  // Save the connection result
+  int exit = sqlite3_open(path.c_str(), &m_dbSqlite);
 
-  if (!m_db.open())
-  {
-    std::cout << "Error: connection with database failed!\n";
-    showError( m_db.lastError() );
-    m_dbIsOK = false;
-  }
-  else
-  {
+  // Test if there was an error
+  if (exit == SQLITE_OK) {
+    std::cout << "The Geometry Database '"<< path << "' has been opened successfully!" << std::endl;
     m_dbIsOK = true;
+  } else {
+    std::cout << "DB Open Error: " << sqlite3_errmsg(m_dbSqlite) << std::endl;
+    m_dbIsOK = false;
   }
 
-//  // check if DB has tables, if not create them
   if (m_dbIsOK) {
     if ( ! (initDB()) ) {
       std::cout << "Error: database initialization failed" << std::endl;
@@ -82,53 +133,14 @@ GMDBManager::GMDBManager(const std::string &path) : m_dbpath(path), m_SQLiteErrM
     }
   }
 
-	// populate DB with fake data, only for debug
+  // populate DB with fake data, only for debug
   //loadTestData(); // TODO: we should move initDB() here, only for debug and Write
 }
 
-GMDBManager::~GMDBManager()
-{
-  m_db.close();
-}
-
-
-bool GMDBManager::isOpen() const
-{
-  if (! m_dbIsOK )
-    return false;
-  return m_db.isOpen();
-}
-
-//GMDBManager::GMDBManager(const std::string &path) : m_dbpath(path), m_dbSqlite(nullptr), m_SQLiteErrMsg(0), m_dbIsOK(false), m_deepDebug(false)
-//{
-//  // TODO: move to a more organic way
-//#ifdef GEOREAD_DEEP_DEBUG
-//  m_deepDebug = true;
-//#endif
-//
-//  m_dbIsOK = false;
-//
-//  // FIXME: TODO: we should check the existence of the file, otherwise SQLite will create a new file from scratch
-//  // Save the connection result
-//  int exit = sqlite3_open(path.c_str(), &m_dbSqlite);
-//
-//  // Test if there was an error
-//  if (exit == SQLITE_OK) {
-//    std::cout << "The Geometry Database '"<< path << "' has been opened successfully!" << std::endl;
-//    m_dbIsOK = true;
-//  } else {
-//    std::cout << "DB Open Error: " << sqlite3_errmsg(m_dbSqlite) << std::endl;
-//    m_dbIsOK = false;
-//  }
-//
-//  // populate DB with fake data, only for debug
-//  //loadTestData(); // TODO: we should move initDB() here, only for debug and Write
-//}
-
 
-void GMDBManager::DestructorGMDBManagerStd()
+GMDBManager::~GMDBManager()
 {
-//  sqlite3_close(m_dbSqlite);
+  sqlite3_close(m_dbSqlite);
   m_dbSqlite = nullptr;
 }
 
@@ -206,86 +218,102 @@ void GMDBManager::printDBVersion() const
 
 void GMDBManager::printAllRecords(const std::string &tableName) const
 {
-	std::cout << tableName << " in db:" << std::endl;
+  // --- print table name
+  std::cout << tableName << " in db:" << std::endl;
+  // --- print table column names
+  std::cout << "- " <<  joinVectorStrings(m_tableNames.at(tableName), ", ") << std::endl;
+  // --- print records
+  std::vector<std::vector<std::string>> records;
+//  std::vector<std::string> nodeParams;
+  records = getTableRecords(tableName);
+  for( auto& row : records) {
+    std::cout << "* ";
+    for( auto& item : row) {
+      std::cout << item << ", ";
+    }
+    std::cout << std::endl;
+  }
+  std::cout << "---" << endl;
+	// TODO: I want to have a symbol like '---' to mean empty line when query gives 0 results.
+}
 
-	// QSqlQuery query("SELECT * FROM " + tableName);
-  QSqlQuery query = selectAllFromTable(tableName);
 
-	int nCols = (m_tableNames.at(tableName)).size();
+// FIXME: TODO: we now return all records as text, but should we get double/int instead when appropriate? In that case, we should create dedicated methods for all tables, I guess.
+// TODO: fill a cache and returns that if asked a second time
+std::vector<std::vector<std::string>> GMDBManager::getTableRecords(std::string tableName) const
+{
+  // container to be returned
+  std::vector<std::vector<std::string>> records;
+  // get the query statetement ready to be executed
+  sqlite3_stmt* stmt = nullptr;
+  if ("ChildrenPositions" == tableName) {
+    stmt = selectAllFromTableChildrenPositions();
+  }
+  else {
+    stmt = selectAllFromTable(tableName);
+  }
+  // execute the query and loop over all rows and all columuns
+  if ( stmt )
+  {
+    int ctotal = sqlite3_column_count(stmt); // Count the Number of Columns in the Table
+    int res = 0;
+    while ( 1 )
+    {
+      res = sqlite3_step(stmt); // Execute SQL Statement.
+      if ( res == SQLITE_ROW )
+      {
+        std::vector<std::string> nodeParams; // stores the data items contained in a single row
+        for ( int i = 0; i < ctotal; i++ )  // Loop times the number of columns in the table
+        {
+          std::string s = (char*)sqlite3_column_text(stmt, i);  // Read each Column in the row as text FIXME: is there a method to get the right type, e.g. double, instead of text?
+          nodeParams.push_back( s );
+        }
+        records.push_back(nodeParams);
+      }
+      
+      if ( res == SQLITE_DONE || res==SQLITE_ERROR)
+      {
+        if (res == SQLITE_ERROR) {
+          std::string errmsg(sqlite3_errmsg(m_dbSqlite));
+          sqlite3_finalize(stmt);
+          throw errmsg;
+        }
+        break;
+      }
+    }
+  }
+  // finalize
+  sqlite3_finalize(stmt);
+  return records;
+}
 
-	// print table column names
-	std::cout << "- " <<  joinVectorStrings(m_tableNames.at(tableName), ", ") << std::endl;
-	while (query.next())
-	{
-		std::cout << "* "; // TODO: move to a osstream: it's cleaner
-		for( int ii=0; ii<nCols; ++ii)
-		{
-			if (! (ii==0) )
-				std::cout << ", ";
-			std::string valueStr = query.value(ii).toString().toStdString();
-			// if (valueStr == "")
-			// 	std::cout << "NULL"; // removed because we want to save the NULL to the DB, for consistency
-			// else
-				std::cout << valueStr;
-		}
-		std::cout << std::endl;
-	}
 
-	// TODO: I want to have a symbol like '---' to mean empty line when query gives 0 results.
-	// but I guess query.size() is not the right method...
-	//	qDebug() << "query size: " << query.size();
-	//	if (query.size() == 0 || query.size() == -1)
-	//		std::cout << "---" << std::endl;
+std::vector<std::vector<std::string>> GMDBManager::getTableFromNodeType(std::string nodeType)
+{
 
-}
-//QHash<unsigned int, QStringList> GMDBManager::getTableFromNodeType(QString nodeType)
-//{
-//
-//  QString tableName = getTableNameFromNodeType(nodeType);
-//
-//  QHash<unsigned int, QStringList> records;
-//  QStringList nodeParams;
+  std::string tableName = getTableNameFromNodeType(nodeType);
+  return getTableRecords(tableName);
+  
+//  // QHash<unsigned int, QStringList> records;
+//  // QStringList nodeParams;
+//  std::vector<std::vector<std::string>> records;
+//  std::vector<std::string> nodeParams;
 //
-//  int nCols = (m_tableNames.at(tableName.toStdString())).size();
+//  int nCols = (m_tableNames.at(tableName)).size();
 //
-//  QSqlQuery query = selectAllFromTable(tableName.toStdString());
+//  QSqlQuery query = selectAllFromTable(tableName); // sorted by ID
 //  while (query.next()) {
 //    nodeParams.clear();
-//    unsigned int nodeId = query.value(0).toUInt();
+////    unsigned int nodeId = query.value(0).toUInt();
 //
 //    for( int ii=0; ii<nCols; ++ii) {
-//      nodeParams << query.value(ii).toString();
+//      // nodeParams << query.value(ii).toString();
+//      nodeParams.push_back( query.value(ii).toString().toStdString() );
 //    }
-//    records[nodeId] = nodeParams;
+//    // records[nodeId] = nodeParams;
+//    records.push_back(nodeParams);
 //  }
 //return records;
-//}
-
-std::vector<std::vector<std::string>> GMDBManager::getTableFromNodeType(std::string nodeType)
-{
-
-  std::string tableName = getTableNameFromNodeType(nodeType);
-
-	// QHash<unsigned int, QStringList> records;
-	// QStringList nodeParams;
-  std::vector<std::vector<std::string>> records;
-  std::vector<std::string> nodeParams;
-
-	int nCols = (m_tableNames.at(tableName)).size();
-
-	QSqlQuery query = selectAllFromTable(tableName); // sorted by ID
-	while (query.next()) {
-		nodeParams.clear();
-//    unsigned int nodeId = query.value(0).toUInt();
-
-		for( int ii=0; ii<nCols; ++ii) {
-			// nodeParams << query.value(ii).toString();
-			nodeParams.push_back( query.value(ii).toString().toStdString() );
-		}
-		// records[nodeId] = nodeParams;
-    records.push_back(nodeParams);
-	}
-return records;
 }
 
 
@@ -296,7 +324,7 @@ void GMDBManager::showError(const QSqlError &err) const
 
 //QVariant GMDBManager::addPhysVol(const QVariant &logVolId, const QVariant &parentPhysVolId, bool isRootVolume)
 //{
-//  if (m_deepDebug) std::cout << "GMDBManager::addPhysVol() - is root?" << isRootVolume << std::endl;
+//  if (m_debug) std::cout << "GMDBManager::addPhysVol() - is root?" << isRootVolume << std::endl;
 //
 //  QSqlQuery q;
 //  if (!q.prepare(QLatin1String("insert into PhysVols(logvol, parent) values(?, ?)"))) {
@@ -320,7 +348,7 @@ void GMDBManager::showError(const QSqlError &err) const
 
 //QVariant GMDBManager::addFullPhysVol(const QVariant &logVolId, const QVariant &parentPhysVolId, bool isRootVolume)
 //{
-//  if (m_deepDebug) std::cout << "GMDBManager::addFullPhysVol() - is root?" << isRootVolume << std::endl;
+//  if (m_debug) std::cout << "GMDBManager::addFullPhysVol() - is root?" << isRootVolume << std::endl;
 //
 //  QSqlQuery q;
 //  if (!q.prepare(QLatin1String("insert into FullPhysVols(logvol, parent) values(?, ?)"))) {
@@ -346,7 +374,7 @@ void GMDBManager::showError(const QSqlError &err) const
 
 //QVariant GMDBManager::addLogVol(const QString &name, const QVariant &shapeId, const QVariant &materialId)
 //{
-////  if (m_deepDebug) qDebug() << "GMDBManager::addLogVol()";
+////  if (m_debug) qDebug() << "GMDBManager::addLogVol()";
 //
 //  QSqlQuery q;
 //  if (!q.prepare(QLatin1String("insert into LogVols(name, shape, material) values(?, ?, ?)"))) {
@@ -363,7 +391,7 @@ void GMDBManager::showError(const QSqlError &err) const
 
 //QVariant GMDBManager::addMaterial(const QString &name, const QString &density, const QString &elements)
 //{
-////  if (m_deepDebug) qDebug() << "GMDBManager::addMaterial()";
+////  if (m_debug) qDebug() << "GMDBManager::addMaterial()";
 //
 //  QSqlQuery q;
 //  if (!q.prepare(QLatin1String("insert into Materials(name, density, elements) values(?, ?, ?)"))) {
@@ -380,7 +408,7 @@ void GMDBManager::showError(const QSqlError &err) const
 
 //QVariant GMDBManager::addElement(const QString &name, const QString &symbol, const QString &elZ, const QString &elA)
 //{
-////  if (m_deepDebug) qDebug() << "GMDBManager::addElement()";
+////  if (m_debug) qDebug() << "GMDBManager::addElement()";
 //
 //  QSqlQuery q;
 //  if (!q.prepare(QLatin1String("insert into Elements(name, symbol, Z, A) values(?, ?, ?, ?)"))) {
@@ -395,45 +423,25 @@ void GMDBManager::showError(const QSqlError &err) const
 //  return q.lastInsertId();
 //}
 
+
 bool GMDBManager::addListOfChildrenPositions(const std::vector<std::vector<std::string>> &records)
 {
     // NOTE: Choose the right function for your version of SQLite!!
-	return addListOfRecordsToTable("ChildrenPositions", records); // newest SQLite versions
+	return addListOfRecordsToTable("ChildrenPositions", records); // needs SQLite >= 3.7.11
 	//return addListOfRecordsToTableOld("ChildrenPositions", records); // old SQLite versions
 }
 
-//bool GMDBManager::addListOfRecords(const QString geoType, const std::vector<QStringList> records)
-//{
-////  if (m_deepDebug) qDebug() << "GMDBManager::addListOfRecords():" << geoType;
-//
-//  QString tableName = QString::fromStdString(m_childType_tableName[geoType.toStdString()]);
-//
-//  if (tableName.isEmpty()) {
-//        //qWarning() << "m_childType_tableName:" << m_childType_tableName;
-//    qWarning() << "ERROR!! could not retrieve tableName for node type " << geoType << "!! Aborting...";
-//    exit(1);
-//  }
-//
-//  if (records.size() > 0 ) {
-//        // NOTE: Choose the right function!!
-//    return addListOfRecordsToTable(tableName, records); // newest SQLite versions
-//    //return addListOfRecordsToTableOld(tableName, records); // old SQLite versions
-//  }
-//  else
-//    qWarning() << "Info: no records to save for geoType '" << geoType << "'. Skipping...";
-//  return true;
-//}
 
 
 bool GMDBManager::addListOfRecords(const std::string geoType, const std::vector<std::vector<std::string>> records)
 {
-//  if (m_deepDebug) qDebug() << "GMDBManager::addListOfRecords():" << geoType;
+//  if (m_debug) qDebug() << "GMDBManager::addListOfRecords():" << geoType;
 
   std::string tableName = m_childType_tableName[geoType];
 
   if (tableName.size() == 0) {
     //qWarning() << "m_childType_tableName:" << m_childType_tableName;
-    std::cout << "ERROR!! could not retrieve tableName for node type '" << geoType << "'!! Aborting...";
+    std::cout << "ERROR!! could not retrieve tableName for node type '" << geoType << "'!! Aborting..." << std::endl;
     exit(EXIT_FAILURE);
   }
 
@@ -449,66 +457,14 @@ bool GMDBManager::addListOfRecords(const std::string geoType, const std::vector<
 
 
 
-
-// ***Note***
-// the syntax built here below is more convenient
-// but it is supported only in SQLite >= 3.7.11
-// ...but SLC6 only has 3.7.9!
-// here we build a query like this:
-// queryStr = QString("INSERT INTO Materials (id, name) VALUES  (1,'Air'), (2,'Silicon'), (368,'ShieldSteel');");
-//
-//bool GMDBManager::addListOfRecordsToTable(const QString tableName, const std::vector<QStringList> records)
-//{
-//  // get table columns and format them for query
-//  QString tableColString = "(" + QString::fromStdString(joinVectorStrings(m_tableNames.at(tableName.toStdString()), ", ")) + ")";
-//
-//    unsigned int nRecords = records.size();
-//    qInfo() << "number of " << tableName << "records to insert into the DB:" << nRecords;
-//
-//  // preparing the SQL query
-//  QString queryStr("INSERT INTO %1 %2 VALUES ");
-//  queryStr = queryStr.arg(tableName); // insert table name
-//  queryStr = queryStr.arg(tableColString); // insert table columns
-//
-//  unsigned int nMat = nRecords;
-//  unsigned int id = 0;
-//  foreach(QStringList rec, records) {
-//        //qDebug() << "rec:" << rec;
-//
-//    ++id;
-//    QStringList items;
-//
-//    foreach (QString item, rec) {
-//      items << '"' + item + '"';
-//    }
-//    QString values = items.join(",");
-//    queryStr += " (" + QString::number(id) + "," + values + ")";
-//    if (id != nMat)
-//      queryStr += ",";
-//    else
-//      queryStr += ";";
-//
-//        }
-//
-//  // executing the SQL query
-//  QSqlQuery q;
-//  if (!q.exec(queryStr)) {
-//        qWarning() << "ERROR!!! SQL error:";
-//    showError(q.lastError());
-//    return false;
-//  }
-//
-//  return true;
-//}
-
-
 // ***Note***
 // the syntax built here below is more convenient
 // but it is supported only in SQLite >= 3.7.11
-// ...but SLC6 only has 3.7.9!
+// (Note: old SLC6-based Athena releases uses SQLite 3.7.9 from LCG!
 // here we build a query like this:
 // queryStr = QString("INSERT INTO Materials (id, name) VALUES  (1,'Air'), (2,'Silicon'), (368,'ShieldSteel');");
 //
+/*
 bool GMDBManager::addListOfRecordsToTable(const std::string tableName, const std::vector<std::vector<std::string>> records)
 //bool addListOfRecordsToTable(const std::string tableName, const std::vector<std::vector<std::string>> records)
 {
@@ -560,23 +516,52 @@ bool GMDBManager::addListOfRecordsToTable(const std::string tableName, const std
 
   return true;
 }
+*/
 
 
-bool GMDBManager::addListOfRecordsToTableStd(const std::string tableName, const std::vector<std::vector<std::string>> records)
+
+// ***Note***
+// The syntax built here below is more convenient
+// but it is supported only in SQLite >= 3.7.11
+// (Note: old SLC6-based Athena releases uses SQLite 3.7.9 from LCG)
+//
+// Here we build a query like this:
+// queryStr = QString("INSERT INTO Materials (id, name) VALUES  (1,'Air'), (2,'Silicon'), (368,'ShieldSteel');");
+//
+bool GMDBManager::addListOfRecordsToTable(const std::string tableName, const std::vector<std::vector<std::string>> records)
 {
   // get table columns and format them for query
   std::string tableColString = "(" + joinVectorStrings(m_tableNames.at(tableName), ", ") + ")";
-
-  std::cout << "tableColString:" << tableColString << std::endl;
+  //std::cout << "tableColString:" << tableColString << std::endl; // debug
 
   unsigned int nRecords = records.size();
-  std::cout << "number of " << tableName << " records to insert into the DB:" << nRecords << std::endl;
-
-//  // preparing the SQL query
-//  QString queryStr("INSERT INTO %1 %2 VALUES ");
-//  queryStr = queryStr.arg(QString::fromStdString(tableName)); // insert table name
-//  queryStr = queryStr.arg(QString::fromStdString(tableColString)); // insert table columns
+  std::cout << "Info: number of " << tableName << " records to dump into the DB:" << nRecords << std::endl;
 
+  // preparing the SQL query
+  std::string sql = fmt::format("INSERT INTO {0} {1} VALUES ", tableName, tableColString);
+  unsigned int id = 0;
+  for( const std::vector<std::string>& rec : records) {
+    ++id;
+    std::vector<std::string> items;
+    for ( const std::string& item : rec) {
+      items.push_back("'" + item + "'");
+    }
+    std::string values = joinVectorStrings(items, ",");
+    sql += " (" + std::to_string(id) + "," + values + ")";
+    if (id != nRecords) {
+      sql += ",";
+    } else {
+      sql += ";";
+    }
+    
+  }
+  if(m_debug) std::cout << "Query string:" << sql << std::endl; // debug
+  
+  // executing the SQL query
+  if ( ! (execQuery(sql)) ) {
+    return false;
+  }
+  return true;
 }
 
 
@@ -629,14 +614,14 @@ bool GMDBManager::addListOfRecordsToTableOld(const QString tableName, const std:
 
         std::vector<QStringList> recordsBunch( first, last ); // we take the first 500 records
         recordsCopy.erase( first, last ); // we delete the first 500 records
-        if (m_deepDebug) qDebug() << "start:" << start << "recordsBunch size:" << recordsBunch.size() << "- recordsCopy size after removal:" << recordsCopy.size();
+        if (m_debug) qDebug() << "start:" << start << "recordsBunch size:" << recordsBunch.size() << "- recordsCopy size after removal:" << recordsCopy.size();
 
 	    // --- first record
         // outcome should be like: " 1 as id, 'Air' as name "
         unsigned int id = start+1; // set the first ID as 'start'
         QStringList recFirst = recordsBunch.front(); // access first record from vector
         recordsBunch.erase( recordsBunch.begin() ); // delete first record
-        if (m_deepDebug) qDebug() << "after taking first record - recordsBunch size:" << recordsBunch.size();
+        if (m_debug) qDebug() << "after taking first record - recordsBunch size:" << recordsBunch.size();
 
         // first item in the first record (it is the ID)
         QString firstCol = colNames[0];
@@ -653,7 +638,7 @@ bool GMDBManager::addListOfRecordsToTableOld(const QString tableName, const std:
             //qDebug() << "first element:" << ii << nRecs << queryStr;
             ++ii;
         }
-        if (m_deepDebug) qDebug() << "first element query:" << queryStr;
+        if (m_debug) qDebug() << "first element query:" << queryStr;
         // --- other records
         // outcome should be: " UNION ALL SELECT 2,'Silicon' "
 
@@ -768,7 +753,7 @@ bool GMDBManager::addListOfRecordsToTableOld(const QString tableName, const std:
 
 //QVariant GMDBManager::addShape(const QString &type, const QString &parameters)
 //{
-////  if (m_deepDebug) qDebug() << "GMDBManager::addShape()";
+////  if (m_debug) qDebug() << "GMDBManager::addShape()";
 //
 //  QSqlQuery q;
 //  if (!q.prepare(QLatin1String("insert into Shapes(type, parameters) values(?, ?)"))) {
@@ -784,7 +769,7 @@ bool GMDBManager::addListOfRecordsToTableOld(const QString tableName, const std:
 //
 //QVariant GMDBManager::addSerialDenominator(const QString &baseName)
 //{
-////  if (m_deepDebug) qDebug() << "GMDBManager::addSerialDenominator("+baseName+")";
+////  if (m_debug) qDebug() << "GMDBManager::addSerialDenominator("+baseName+")";
 //
 //  QSqlQuery q;
 //  if (!q.prepare(QLatin1String("insert into SerialDenominators(baseName) values(?)"))) {
@@ -799,7 +784,7 @@ bool GMDBManager::addListOfRecordsToTableOld(const QString tableName, const std:
 
 //QVariant GMDBManager::addNameTag(const QString &name)
 //{
-////  if (m_deepDebug) qDebug() << "GMDBManager::addNameTag("+name+")";
+////  if (m_debug) qDebug() << "GMDBManager::addNameTag("+name+")";
 //
 //  QSqlQuery q;
 //  if (!q.prepare(QLatin1String("insert into NameTags(name) values(?)"))) {
@@ -813,7 +798,7 @@ bool GMDBManager::addListOfRecordsToTableOld(const QString tableName, const std:
 //
 //QVariant GMDBManager::addFunction(const QString expression)
 //{
-////  if (m_deepDebug) qDebug() << "GMDBManager::addFunction()";
+////  if (m_debug) qDebug() << "GMDBManager::addFunction()";
 //
 //  // TEST
 //  std::cout << "Function - expression string len: " << expression.length();
@@ -835,7 +820,7 @@ bool GMDBManager::addListOfRecordsToTableOld(const QString tableName, const std:
 
 //QVariant GMDBManager::addSerialTransformer(const unsigned int &funcId, const unsigned int &physvolId, const std::string &physvolType, const unsigned int &copies)
 //{
-////  if (m_deepDebug) qDebug() << "GMDBManager::addSerialTransformer()" << funcId << physvolId << copies;
+////  if (m_debug) qDebug() << "GMDBManager::addSerialTransformer()" << funcId << physvolId << copies;
 //
 //  const unsigned int volTableId = getTableIdFromNodeType(physvolType);
 //
@@ -855,7 +840,7 @@ bool GMDBManager::addListOfRecordsToTableOld(const QString tableName, const std:
 
 //QVariant GMDBManager::addTransform(QVector<double> params)
 //{
-////  if (m_deepDebug) qDebug() << "GMDBManager::addTransform()";
+////  if (m_debug) qDebug() << "GMDBManager::addTransform()";
 //
 //  // get the 12 matrix elements
 //  double xx = params[0];
@@ -899,7 +884,7 @@ bool GMDBManager::addListOfRecordsToTableOld(const QString tableName, const std:
 //
 //QVariant GMDBManager::addAlignableTransform(QVector<double> params)
 //{
-////  if (m_deepDebug) qDebug() << "GMDBManager::addAlignableTransform()";
+////  if (m_debug) qDebug() << "GMDBManager::addAlignableTransform()";
 //
 //  // get the 12 matrix elements
 //  double xx = params[0];
@@ -953,10 +938,11 @@ bool GMDBManager::addRootVolume(const std::vector<std::string> &values)
 	return false;
 }
 
+/*
 // insert a single parent-child relationship for a given parent volume
 void GMDBManager::addChildPosition(const unsigned int &parentId, const std::string &parentType, const unsigned int &childId, const unsigned int &parentCopyNumber, const unsigned int &childPos, const std::string &childType, const unsigned int &childCopyN)
 {
-//  if (m_deepDebug) qDebug() << "GMDBManager::addChildPosition(" << parentId << "," << parentType << "," << QString::number(parentCopyNumber) << "," <<childPos << "," << childType << ", " << childId << ", " << QString::number(childCopyN) << ")";
+//  if (m_debug) qDebug() << "GMDBManager::addChildPosition(" << parentId << "," << parentType << "," << QString::number(parentCopyNumber) << "," <<childPos << "," << childType << ", " << childId << ", " << QString::number(childCopyN) << ")";
 
 	// get table name -- which the child ID refers to -- based on the child type
 	const unsigned int parentTableId = getTableIdFromNodeType(parentType);
@@ -970,7 +956,7 @@ void GMDBManager::addChildPosition(const unsigned int &parentId, const std::stri
 		if (i != 0) // skip the "id" column
 			queryStr = queryStr.arg( QString::fromStdString( cols.at(i)) );
 	}
-//  if (m_deepDebug) qDebug() << "queryStr:" << queryStr;
+//  if (m_debug) qDebug() << "queryStr:" << queryStr;
 	QSqlQuery q;
 	if (!q.prepare(queryStr)) {
 		showError(q.lastError());
@@ -986,26 +972,26 @@ void GMDBManager::addChildPosition(const unsigned int &parentId, const std::stri
 	q.exec();
 	return;
 }
+*/
 
-void GMDBManager::addDBversion(const QString version)
-{
-	QSqlQuery q;
-	if (!q.prepare(QLatin1String("insert into dbversion(version) values(?)"))) {
-		showError(q.lastError());
-		return;
-	}
-	q.addBindValue(version);
-	q.exec();
-	return;
-}
+//void GMDBManager::addDBversion(const QString version)
+//{
+//  QSqlQuery q;
+//  if (!q.prepare(QLatin1String("insert into dbversion(version) values(?)"))) {
+//    showError(q.lastError());
+//    return;
+//  }
+//  q.addBindValue(version);
+//  q.exec();
+//  return;
+//}
 void GMDBManager::addDBversion(std::string version)
 {
   checkIsDBOpen();
-  std::string queryStr;
   sqlite3_stmt * st = nullptr;
   int rc = -1;
   std::string sql = "INSERT INTO dbversion(version) VALUES(?)";
-  rc = sqlite3_prepare( m_dbSqlite, sql.c_str(), -1, &st, NULL);
+  rc = sqlite3_prepare_v2( m_dbSqlite, sql.c_str(), -1, &st, NULL);
   if (rc != SQLITE_OK) {
     printf( "[SQLite ERR] : Error msg: %s\n", sqlite3_errmsg(m_dbSqlite) );
     exit(EXIT_FAILURE);
@@ -1016,13 +1002,15 @@ void GMDBManager::addDBversion(std::string version)
     printf( "[SQLite ERR] : Error msg: %s\n", sqlite3_errmsg(m_dbSqlite) );
     exit(EXIT_FAILURE);
   }
+  // finalize
+  sqlite3_finalize(st);
   return;
 }
 
-void GMDBManager::checkIsDBOpen()
+bool GMDBManager::checkIsDBOpen() const
 {
   if(m_dbSqlite != nullptr) {
-    return;
+    return true;
   } else {
     std::cout << "ERROR! The SQLite DB is not accessible! Exiting..." << std::endl;
     exit(EXIT_FAILURE);
@@ -1030,43 +1018,8 @@ void GMDBManager::checkIsDBOpen()
 }
 
 
-std::vector<std::string> GMDBManager::getItem(std::string geoType, unsigned int id)
-{
-//  if (m_deepDebug) qDebug() << "GMDBManager::getItem(geoType, id)"<< geoType << QString::number(id);
-
-	/* Get the right DB table */
-  std::string tableName = getTableNameFromNodeType(geoType);
-	return getItemFromTableName(tableName, id);
-}
-
-
-std::vector<std::string> GMDBManager::getItem(unsigned int tableId, unsigned int id)
-{
-//  if (m_deepDebug) qDebug() << "GMDBManager::getItem(tableId, id)"<< QString::number(tableId) << QString::number(id);
-	/* Get the right DB table */
-  std::string tableName = getTableNameFromTableId(tableId);
-	return getItemFromTableName(tableName, id);
-
-}
-
-/*
-QStringList GMDBManager::getItemAndType(unsigned int tableId, unsigned int id)
-{
-	if (m_deepDebug) qDebug() << "GMDBManager::getItemAndType(tableId, id)"<< QString::number(tableId) << QString::number(id);
-	// Get the right DB table
-  std::string tableName = getTableNameFromTableId(tableId);
-
-  std::string nodeType = getNodeTypeFromTableId(tableId);
-
-	QStringList results;
-  std::vector<std::string> item =  getItemFromTableName(tableName, id);
 
-	results << nodeType << item;
 
-	return results;
-
-}
-*/
 std::vector<std::string> GMDBManager::getItemAndType(unsigned int tableId, unsigned int id)
 {
   std::vector<std::string> results;
@@ -1084,48 +1037,68 @@ std::vector<std::string> GMDBManager::getItemAndType(unsigned int tableId, unsig
 
 }
 
-/*
-QStringList GMDBManager::getItemFromTableName(std::string tableName, unsigned int id)
-{
-	if (m_deepDebug) qDebug() << "GMDBManager::getItemFromTableName(tableName, id)"<< tableName << QString::number(id);
-
-	 // 2. Get the object from DB
-
-	// prepare a SQL string with the right table name
-	QString queryStr = QString("SELECT * FROM %1 WHERE id = (?)").arg(tableName);
-	// prepare the query
-	QSqlQuery q;
-	if (!q.prepare( queryStr )) {
-		showError(q.lastError());
-		return QStringList();
-	}
-	q.addBindValue(id);
-	q.exec();
-
-	QStringList params;
-
-	// get the number of columns of the DB table
-	int nCols = (m_tableNames.at(tableName.toStdString())).size();
-
-	while (q.next()) {
-
-		for( int ii=0; ii<nCols; ++ii)
-			params << q.value(ii).toString();
-	}
-	if (params.length()==0) {
-		qWarning() << "WARNING!!" << "Item" << id << "does not exist in table" << tableName << "!!";
-	}
-	return params;
-}
-    */
 
 std::vector<std::string> GMDBManager::getItemFromTableName(std::string tableName, unsigned int id)
 {
-//  if (m_deepDebug) qDebug() << "GMDBManager::getItemFromTableName(tableName, id)"<< tableName << QString::number(id);
+  // FIXME: when you create caches for all tables, replace this method with a lookup action in the cache.
   /*
-   * 2. Get the object from DB
+   * Get the object from DB.
    */
-  // prepare a SQL string with the right table name
+  std::vector<std::string> item;
+  // set a SQL command string with the right table name
+  std::string sql = fmt::format("SELECT * FROM {0} WHERE id = (?)", tableName);
+  // prepare the query
+  sqlite3_stmt * stmt = nullptr;
+  int rc = -1;
+  rc = sqlite3_prepare_v2( m_dbSqlite, sql.c_str(), -1, &stmt, NULL);
+  if (rc != SQLITE_OK) {
+    printf( "[SQLite ERR] (%s) : Error msg: %s\n", __func__, sqlite3_errmsg(m_dbSqlite) );
+    exit(EXIT_FAILURE);
+  }
+  // bind the parameters
+  rc = sqlite3_bind_int(stmt, 1, id);
+  // execute the query and loop over all rows and all columuns
+  if ( stmt )
+  {
+    int ctotal = sqlite3_column_count(stmt); // Count the Number of Columns in the Table
+    int res = 0;
+    while ( 1 )
+    {
+      res = sqlite3_step(stmt); // Execute SQL Statement.
+      if ( res == SQLITE_ROW )
+      {
+        for ( int i = 0; i < ctotal; i++ )  // Loop times the number of columns in the table
+        {
+          std::string s = (char*)sqlite3_column_text(stmt, i);  // Read each Column in the row as text FIXME: is there a method to get the right type, e.g. double, instead of text?
+          item.push_back( s );
+        }
+      }
+      if ( res == SQLITE_DONE || res==SQLITE_ERROR)
+      {
+        if (res == SQLITE_ERROR) {
+          std::string errmsg(sqlite3_errmsg(m_dbSqlite));
+          sqlite3_finalize(stmt);
+          throw errmsg;
+        }
+        break;
+      }
+    }
+  }
+  if (rc != SQLITE_DONE) {
+    printf( "[SQLite ERR] (%s) : Error msg: %s\n", __func__, sqlite3_errmsg(m_dbSqlite) );
+    exit(EXIT_FAILURE);
+  }
+  // finalize
+  sqlite3_finalize(stmt);
+    
+  if (item.size()==0) {
+    std::cout << "ERROR!!" << "Item with ID:'" << id << "' does not exist in table" << tableName << "! Exiting...";
+    exit(EXIT_FAILURE);
+  }
+    
+  return item;
+  
+    /*
   QString queryStr = QString("SELECT * FROM %1 WHERE id = (?)").arg(QString::fromStdString(tableName));
   // prepare the query
   QSqlQuery q;
@@ -1151,13 +1124,14 @@ std::vector<std::string> GMDBManager::getItemFromTableName(std::string tableName
     std::cout << "WARNING!!" << "Item" << id << "does not exist in table" << tableName << "!!";
   }
   return params;
+    */
 }
 
-
+/*
 // get the list of children for a single GeoVPhysVol (i.e., GeoPhysVol or GeoFullPhysVol)
 QMap<unsigned int, QStringList> GMDBManager::getVPhysVolChildren(const unsigned int &id, const std::string &nodeType, const unsigned int &parentCopyNumber)
 {
-  if (m_deepDebug) std::cout << "GMDBManager::getVPhysVolChildren() - id:" << id << "- type:" << nodeType << "- copyN:" << parentCopyNumber;
+  if (m_debug) std::cout << "GMDBManager::getVPhysVolChildren() - id:" << id << "- type:" << nodeType << "- copyN:" << parentCopyNumber;
 
 	const unsigned int tableId = getTableIdFromNodeType(nodeType);
 
@@ -1192,8 +1166,10 @@ QMap<unsigned int, QStringList> GMDBManager::getVPhysVolChildren(const unsigned
 
 	return children;
 }
+ */
 
 
+/*
 // Get all parent-children data from the database in one go
 QHash<QString, QMap<unsigned int, QStringList>> GMDBManager::getChildrenTable()
 {
@@ -1226,12 +1202,14 @@ QHash<QString, QMap<unsigned int, QStringList>> GMDBManager::getChildrenTable()
 	}
 	return all_children;
 }
+*/
 
 // Get all parent-children data from the database in one go
-std::vector<std::vector<std::string>> GMDBManager::getChildrenTableStd()
+std::vector<std::vector<std::string>> GMDBManager::getChildrenTable()
 {
-//  std::cout << "GMDBManager::getChildrenTableStd()\n"; // debug
-
+  return getTableRecords("ChildrenPositions");
+  
+  /*
   QSqlQuery q;
   QString queryStr = QString("SELECT * FROM ChildrenPositions ORDER BY parentTable, parentId, parentCopyNumber, position");
   if (!q.prepare(queryStr)) {
@@ -1262,12 +1240,16 @@ std::vector<std::vector<std::string>> GMDBManager::getChildrenTableStd()
     all_children.push_back(childParams);
   }
   return all_children;
+  */
 }
 
 
 
 unsigned int GMDBManager::getTableIdFromNodeType(const std::string &nodeType)
 {
+  return m_cache_nodeType_tableID[nodeType];
+  
+  /*
 	QSqlQuery q;
 	if (!q.prepare(QLatin1String("SELECT id FROM GeoNodesTypes WHERE nodeType = (?)"))) {
 		showError(q.lastError());
@@ -1282,48 +1264,17 @@ unsigned int GMDBManager::getTableIdFromNodeType(const std::string &nodeType)
 	}
 
 	return id.toUInt();
+  */
 }
 
-QString GMDBManager::getTableNameFromNodeType(QString nodeType)
-{
-	QSqlQuery q;
-	if (!q.prepare(QLatin1String("SELECT tableName FROM GeoNodesTypes WHERE nodeType = (?)"))) {
-		showError(q.lastError());
-		return QString();
-	}
-	q.addBindValue(nodeType);
-	q.exec();
-
-	QString tableName;
-	while (q.next()) {
-		tableName = q.value(0).toString();
-	}
 
-	return tableName;
+std::string GMDBManager::getTableNameFromNodeType(const std::string &nodeType)
+{
+  return m_cache_nodeType_tableName.at(nodeType);
 }
 
-      std::string GMDBManager::getTableNameFromNodeType(std::string nodeType)
-      {
-        QSqlQuery q;
-        if (!q.prepare(QLatin1String("SELECT tableName FROM GeoNodesTypes WHERE nodeType = (?)"))) {
-          showError(q.lastError());
-//          return QString();
-          exit(EXIT_FAILURE);
-        }
-        q.addBindValue(QString::fromStdString(nodeType));
-        q.exec();
-
-        std::string tableName;
-        while (q.next()) {
-          tableName = q.value(0).toString().toStdString();
-        }
-
-        return tableName;
-      }
-
 
 
-// TODO: this and other methods could take data from in-memory maps, without asking to the DB all the times
 /*
 QString GMDBManager::getTableNameFromTableId(unsigned int tabId)
 {
@@ -1344,276 +1295,208 @@ QString GMDBManager::getTableNameFromTableId(unsigned int tabId)
 }
  */
 
+// build the GeoNodeTypes cache
+int GMDBManager::loadGeoNodeTypesAndBuildCache()
+{
+    checkIsDBOpen();
+    std::string queryStr;
+    sqlite3_stmt * st = nullptr;
+    int rc = -1;
+    //set the SQL query string
+    std::string sql = "SELECT * FROM GeoNodesTypes";
+    // declare the data we want to fetch
+    unsigned int id = 0;
+    std::string nodeType = "";
+    std::string tableName = "";
+    // prepare the query
+    rc = sqlite3_prepare_v2( m_dbSqlite, sql.c_str(), -1, &st, NULL);
+    if (rc != SQLITE_OK) {
+      printf( "[SQLite ERR] : Error msg: %s\n", sqlite3_errmsg(m_dbSqlite) );
+      exit(EXIT_FAILURE);
+    }
+    // execute the statement until all selected records are processed
+    while ((rc = sqlite3_step(st)) == SQLITE_ROW) {
+      // get the data
+      id = sqlite3_column_int(st, 0);
+      nodeType = std::string(reinterpret_cast<const char*>(sqlite3_column_text(st, 1)));
+      tableName = std::string(reinterpret_cast<const char*>(sqlite3_column_text(st, 2)));
+//      std::cout << "row: " << id << "," << nodeType << "," << tableName << std::endl; // debug
+      // fill the caches
+      m_cache_tableId_tableName.insert( std::pair<unsigned int, std::string>(id, tableName));
+      m_cache_tableId_nodeType.insert( std::pair<unsigned int, std::string>(id, nodeType));
+      m_cache_nodeType_tableName.insert( std::pair<std::string, std::string>(nodeType, tableName));
+      m_cache_nodeType_tableID.insert( std::pair<std::string, unsigned int>(nodeType, id));
+    }
+    if (rc != SQLITE_DONE) {
+      std::string errmsg(sqlite3_errmsg(m_dbSqlite));
+      sqlite3_finalize(st);
+      throw errmsg;
+    }
+    // finalize
+    sqlite3_finalize(st);
+  return rc;
+}
 
 std::string GMDBManager::getTableNameFromTableId(unsigned int tabId)
 {
-  QSqlQuery q;
-  if (!q.prepare(QLatin1String("SELECT tableName FROM GeoNodesTypes WHERE id = (?)"))) {
-    showError(q.lastError());
-//    return QString();
-    exit(EXIT_FAILURE);
-  }
-  q.addBindValue(tabId);
-  q.exec();
-
-  std::string tableName;
-  while (q.next()) {
-    tableName = q.value(0).toString().toStdString();
-  }
-
-  return tableName;
+  return m_cache_tableId_tableName[tabId];
 }
-/*
-QString GMDBManager::getNodeTypeFromTableId(unsigned int tabId)
-{
-	QSqlQuery q;
-	if (!q.prepare(QLatin1String("SELECT nodeType FROM GeoNodesTypes WHERE id = (?)"))) {
-		showError(q.lastError());
-		return QString();
-	}
-	q.addBindValue(tabId);
-	q.exec();
 
-	QString nodeType;
-	while (q.next()) {
-		nodeType = q.value(0).toString();
-	}
-
-	return nodeType;
-}
- */
 std::string GMDBManager::getNodeTypeFromTableId(unsigned int tabId)
 {
-  QSqlQuery q;
-  if (!q.prepare(QLatin1String("SELECT nodeType FROM GeoNodesTypes WHERE id = (?)"))) {
-    showError(q.lastError());
-    // return QString();
-    exit(EXIT_FAILURE);
-  }
-  q.addBindValue(tabId);
-  q.exec();
-
-  std::string nodeType;
-  while (q.next()) {
-    nodeType = q.value(0).toString().toStdString();
-  }
-
-  return nodeType;
+  return m_cache_tableId_nodeType[tabId];
 }
-/*
-QHash<unsigned int, QString> GMDBManager::getAll_TableIDsNodeTypes()
-{
 
-	QHash<unsigned int, QString> output;
-
-	QSqlQuery q = selectAllFromTable("GeoNodesTypes");
-
-	unsigned int id;
-	QString nodeType;
-	// QString tableName;
-	while (q.next()) {
-		id = q.value(0).toUInt();
-		nodeType = q.value(1).toString();
-		output[id] = nodeType;
-	}
-	return output;
-}
-*/
 std::unordered_map<unsigned int, std::string> GMDBManager::getAll_TableIDsNodeTypes()
 {
-  std::unordered_map<unsigned int, std::string> output;
-  QSqlQuery q = selectAllFromTable("GeoNodesTypes");
-
-  unsigned int id;
-  QString nodeType;
-  // QString tableName;
-  while (q.next()) {
-    id = q.value(0).toUInt();
-    nodeType = q.value(1).toString();
-    output[id] = nodeType.toStdString();
-  }
-  return output;
-}
-
-/*
-QHash<QString, unsigned int> GMDBManager::getAll_NodeTypesTableIDs()
-{
-	QHash<QString, unsigned int> output;
-
-	QSqlQuery q = selectAllFromTable("GeoNodesTypes");
-
-	unsigned int id;
-	QString nodeType;
-	// QString tableName;
-	while (q.next()) {
-		id = q.value(0).toUInt();
-		nodeType = q.value(1).toString();
-		output[nodeType] = id;
-	}
-	return output;
+  return m_cache_tableId_nodeType;
 }
-*/
 
 std::unordered_map<std::string, unsigned int> GMDBManager::getAll_NodeTypesTableIDs()
 {
-  std::unordered_map<std::string, unsigned int> output;
-  QSqlQuery q = selectAllFromTable("GeoNodesTypes");
-
-  unsigned int id;
-  QString nodeType;
-  // QString tableName;
-  while (q.next()) {
-    id = q.value(0).toUInt();
-    nodeType = q.value(1).toString();
-    output[nodeType.toStdString()] = id;
-  }
-  return output;
+  return m_cache_nodeType_tableID;
 }
 
 
-//QSqlQuery GMDBManager::selectAllFromTable(QString tableName) const
-//{
-////  QSqlQuery q;
-////
-////  QString queryStr = QString("SELECT * FROM %1 ORDER BY id");
-////  queryStr = queryStr.arg(tableName);
-////
-////  if (!q.prepare(queryStr)) {
-////    showError(q.lastError());
-////    return QSqlQuery();
-////  }
-////  q.exec();
-////  return q;
-//
-//  return selectAllFromTableSortBy(tableName.toStdString(), "id");
-//}
 
-QSqlQuery GMDBManager::selectAllFromTable(std::string tableName) const
+sqlite3_stmt* GMDBManager::selectAllFromTable(std::string tableName) const
 {
   return selectAllFromTableSortBy(tableName, "id");
 }
 
 
-
-      QSqlQuery GMDBManager::selectAllFromTableSortBy(std::string tableName, std::string sortColumn) const
+sqlite3_stmt* GMDBManager::selectAllFromTableSortBy(std::string tableName, std::string sortColumn) const
 {
-  QSqlQuery q;
-
+  checkIsDBOpen();
+  
   if ("" == sortColumn || 0 == sortColumn.size()) {
     sortColumn = "id";
   }
-  QString qsortColumn = QString::fromStdString(sortColumn);
-
-  QStringList args;
-  args << QString::fromStdString(tableName) << qsortColumn;
-
-  QString queryStr = QString("SELECT * FROM %1 ORDER BY %2");
-//  queryStr = queryStr.arg(tableName);
-  for (int i=0; i < args.size(); ++i) {
-    queryStr = queryStr.arg( args.at(i) );
+  
+  sqlite3_stmt * st = nullptr;
+  int rc = -1;
+  //set the SQL query string
+  std::string sql = fmt::format("SELECT * FROM {0} ORDER BY {1}", tableName, sortColumn);
+  // prepare the query
+  rc = sqlite3_prepare_v2( m_dbSqlite, sql.c_str(), -1, &st, NULL);
+  if (rc != SQLITE_OK) {
+    printf( "[SQLite ERR] : Error msg: %s\n", sqlite3_errmsg(m_dbSqlite) );
+    exit(EXIT_FAILURE);
   }
+  return st;
+  
+//  QSqlQuery q;
+//
+//  if ("" == sortColumn || 0 == sortColumn.size()) {
+//    sortColumn = "id";
+//  }
+//  QString qsortColumn = QString::fromStdString(sortColumn);
+//
+//  QStringList args;
+//  args << QString::fromStdString(tableName) << qsortColumn;
+//
+//  QString queryStr = QString("SELECT * FROM %1 ORDER BY %2");
+////  queryStr = queryStr.arg(tableName);
+//  for (int i=0; i < args.size(); ++i) {
+//    queryStr = queryStr.arg( args.at(i) );
+//  }
+//
+//  if (!q.prepare(queryStr)) {
+//    showError(q.lastError());
+//    return QSqlQuery();
+//  }
+//  q.exec();
+//  return q;
+}
 
-  if (!q.prepare(queryStr)) {
-    showError(q.lastError());
-    return QSqlQuery();
+
+sqlite3_stmt* GMDBManager::selectAllFromTableChildrenPositions() const
+{
+  checkIsDBOpen();
+  sqlite3_stmt * st = nullptr;
+  int rc = -1;
+  //set the SQL query string
+  std::string sql = "SELECT * FROM ChildrenPositions ORDER BY parentTable, parentId, parentCopyNumber, position";
+  // prepare the query
+  rc = sqlite3_prepare_v2( m_dbSqlite, sql.c_str(), -1, &st, NULL);
+  if (rc != SQLITE_OK) {
+    printf( "[SQLite ERR] : Error msg: %s\n", sqlite3_errmsg(m_dbSqlite) );
+    exit(EXIT_FAILURE);
   }
-  q.exec();
-  return q;
+  return st;
 }
 
 
-
 bool GMDBManager::initDB()
 {
-	// check if DB is empty
-	QSqlDatabase db = QSqlDatabase::database();
-	QStringList tables = db.tables();
-	if (   tables.contains("LogVols",   Qt::CaseInsensitive)
-			|| tables.contains("PhysVols",  Qt::CaseInsensitive)
-			|| tables.contains("Materials", Qt::CaseInsensitive)
-			|| tables.contains("Elements",  Qt::CaseInsensitive)
-			|| tables.contains("Shapes",    Qt::CaseInsensitive)
-	) {
-		loadTableNamesFromDB();
-		return true;
-	}
-
-  // TODO: we should check if all needed tables are present; if not throw an error message and exit.
-
-  // TODO: we should create tables only if the DB is really completely empty!
-	// if DB is empty, then create tables
-	bool tablesOK = createTables();
-  
+  // create tables
+  bool tablesOK = createTables();
 	// store DB version
-	addDBversion(QString::fromStdString(dbversion));
-
-  
-  
-  // SQLITE test
-  createTablesStd();
   addDBversion(dbversion);
-  
-  
-  
+  // build caches
+  loadGeoNodeTypesAndBuildCache();
 	return tablesOK;
 
 }
 
 
 
-
 void GMDBManager::printAllDBTables()
 {
-  // declare a statement
-  sqlite3_stmt *stmt;
+  if(m_cache_tables.size() == 0)
+    getAllDBTables();
   
+  for( auto& str : m_cache_tables )
+    std::cout << str << std::endl;
+}
+
+
+void GMDBManager::getAllDBTables()
+{
   std::string tableName;
-  
+  std::vector<std::string> tables;
   // define a query string containing the necessary SQL instructions
   std::string queryStr = "SELECT name FROM sqlite_master WHERE type ='table' AND name NOT LIKE 'sqlite_%';";
-  
-  // prepare the statement with the query string
-//  int rc = sqlite3_prepare_v2(m_dbSqlite, queryStr.c_str(), -1, &stmt, NULL); // new SQlite required!!!
-  int rc = sqlite3_prepare(m_dbSqlite, queryStr.c_str(), -1, &stmt, NULL);
-  if (rc != SQLITE_OK)
-  throw std::string(sqlite3_errmsg(m_dbSqlite));
-  
-  // execute the statement unti all selected records are processed
+  // prepare the query with the query string
+  sqlite3_stmt *stmt;
+  int rc = sqlite3_prepare_v2(m_dbSqlite, queryStr.c_str(), -1, &stmt, NULL);
+  if (rc != SQLITE_OK) {
+    throw std::string(sqlite3_errmsg(m_dbSqlite));
+  }
+  // execute the statement until all selected records are processed
   while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
     tableName = std::string(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)));
-    std::cout << "tableName: " << tableName << std::endl;
+    //std::cout << "tableName: " << tableName << std::endl; // debug
+    tables.push_back(tableName);
   }
   if (rc != SQLITE_DONE) {
     std::string errmsg(sqlite3_errmsg(m_dbSqlite));
     sqlite3_finalize(stmt);
     throw errmsg;
   }
-  
   // finalize
   sqlite3_finalize(stmt);
+  
+  m_cache_tables = tables;
 }
 
-bool GMDBManager::createTablesStd()
+bool GMDBManager::createTables()
 {
-  //-----------------------------------------------
-  //FIXME: move to constructor or initDB()!
-  std::string path = "geometry_v2.db";
-  int rc = sqlite3_open(path.c_str(), &m_dbSqlite);
-  //-----------------------------------------------
+  checkIsDBOpen();
   
+  int rc = -1; // sqlite return code
   std::string queryStr;
 
   std::string geoNode;
   std::string tableName;
   std::vector<std::string> tab;
 
-  checkIsDBOpen();
   // create a table to store the relation between the types of GeoNodes and the name of the table
   tableName = "dbversion";
   tab.insert(tab.begin(), {tableName, "id", "version"});
   storeTableColumnNames(tab);
   queryStr = fmt::format("create table {0} ({1} integer primary key, {2} integer)", tab[0], tab[1], tab[2]);
-  execQuery(queryStr);
+  rc = execQuery(queryStr);
   tab.clear();
   
   // create a table to store the relation between the types of GeoNodes and the name of the table
@@ -1621,12 +1504,11 @@ bool GMDBManager::createTablesStd()
   tab.insert(tab.begin(), {tableName, "id", "nodeType", "tableName"});
   storeTableColumnNames(tab);
   queryStr = fmt::format("create table {0}({1} integer primary key, {2} varchar, {3} varchar)", tab[0], tab[1], tab[2], tab[3]);
-  execQuery(queryStr);
+  rc = execQuery(queryStr);
   tab.clear();
   
   // create a table to store the mother-daughter relationships between nodes (notably, between the [Full]PhysVols as the parents and their children)
   tableName = "ChildrenPositions";
-  //  tab << tableName << "id" << "parentId" << "parentTable" << "parentCopyNumber" << "position" << "childTable" << "childId" << "childCopyNumber";
   tab.push_back(tableName);
   tab.push_back("id");
   tab.push_back("parentId");
@@ -1638,7 +1520,7 @@ bool GMDBManager::createTablesStd()
   tab.push_back("childCopyNumber");
   storeTableColumnNames(tab);
   queryStr = fmt::format("create table {0}({1} integer primary key, {2} integer, {3} integer not null REFERENCES GeoNodesTypes(id), {4} integer, {5} integer, {6} integer not null REFERENCES GeoNodesTypes(id), {7} integer not null, {8} integer not null)", tab[0], tab[1], tab[2], tab[3], tab[4], tab[5], tab[6], tab[7], tab[8]);
-  execQuery(queryStr);
+  rc = execQuery(queryStr);
   tab.clear();
 
   // create a table to store information about the 'root' volume (also known as the 'world' volume)
@@ -1649,7 +1531,7 @@ bool GMDBManager::createTablesStd()
   tab.push_back("volTable");
   storeTableColumnNames(tab);
   queryStr = fmt::format("create table {0}({1} integer primary key, {2} integer not null, {3} integer not null REFERENCES GeoNodesTypes(id))", tab[0], tab[1], tab[2], tab[3]);
-  execQuery(queryStr);
+  rc = execQuery(queryStr);
   tab.clear();
   
   // PhysVols table
@@ -1661,7 +1543,7 @@ bool GMDBManager::createTablesStd()
   tab.push_back("logvol");
   storeTableColumnNames(tab);
   queryStr = fmt::format("create table {0}({1} integer primary key, {2} integer not null)", tab[0], tab[1], tab[2]);
-  if (execQuery(queryStr)) {
+  if ( 0==(rc = execQuery(queryStr)) ) {
     storeNodeType(geoNode, tableName); }
   tab.clear();
   
@@ -1674,7 +1556,7 @@ bool GMDBManager::createTablesStd()
   tab.push_back("logvol");
   storeTableColumnNames(tab);
   queryStr = fmt::format("create table {0}({1} integer primary key, {2} integer not null)", tab[0], tab[1], tab[2]);
-  if (execQuery(queryStr)) {
+  if ( 0==(rc = execQuery(queryStr))) {
     storeNodeType(geoNode, tableName); }
   tab.clear();
   
@@ -1689,7 +1571,7 @@ bool GMDBManager::createTablesStd()
   tab.push_back("material");
   storeTableColumnNames(tab);
   queryStr = fmt::format("create table {0}({1} integer primary key, {2} varchar, {3} integer not null, {4} integer not null)", tab[0], tab[1], tab[2], tab[3], tab[4]);
-  if (execQuery(queryStr)) {
+  if ( 0==(rc = execQuery(queryStr))) {
     storeNodeType(geoNode, tableName); }
   tab.clear();
   
@@ -1704,7 +1586,7 @@ bool GMDBManager::createTablesStd()
   tab.push_back("elements");
   storeTableColumnNames(tab);
   queryStr = fmt::format("create table {0}({1} integer primary key, {2} varchar, {3} varchar, {4} varchar)", tab[0], tab[1], tab[2], tab[3], tab[4]);
-  if (execQuery(queryStr)) {
+  if ( 0==(rc = execQuery(queryStr))) {
     storeNodeType(geoNode, tableName); }
   tab.clear();
   
@@ -1720,7 +1602,7 @@ bool GMDBManager::createTablesStd()
   tab.push_back("A");
   storeTableColumnNames(tab);
   queryStr = fmt::format("create table {0}({1} integer primary key, {2} varchar, {3} varchar, {4} varchar, {5} varchar)", tab[0], tab[1], tab[2], tab[3], tab[4], tab[5]);
-  if (execQuery(queryStr)) {
+  if ( 0==(rc = execQuery(queryStr))) {
     storeNodeType(geoNode, tableName); }
   tab.clear();
   
@@ -1734,7 +1616,7 @@ bool GMDBManager::createTablesStd()
   tab.push_back("parameters");
   storeTableColumnNames(tab);
   queryStr = fmt::format("create table {0}({1} integer primary key, {2} varchar, {3} varchar)", tab[0], tab[1], tab[2], tab[3]);
-  if (execQuery(queryStr)) {
+  if ( 0==(rc = execQuery(queryStr))) {
     storeNodeType(geoNode, tableName); }
   tab.clear();
   
@@ -1747,7 +1629,7 @@ bool GMDBManager::createTablesStd()
   tab.push_back("baseName");
   storeTableColumnNames(tab);
   queryStr = fmt::format("create table {0}({1} integer primary key, {2} varchar)", tab[0], tab[1], tab[2]);
-  if (execQuery(queryStr)) {
+  if ( 0==(rc = execQuery(queryStr))) {
     storeNodeType(geoNode, tableName); }
   tab.clear();
 
@@ -1760,7 +1642,7 @@ bool GMDBManager::createTablesStd()
   tab.push_back("expression");
   storeTableColumnNames(tab);
   queryStr = fmt::format("create table {0}({1} integer primary key, {2} varchar)", tab[0], tab[1], tab[2]);
-  if (execQuery(queryStr)) {
+  if ( 0==(rc = execQuery(queryStr))) {
     storeNodeType(geoNode, tableName); }
   tab.clear();
   
@@ -1776,7 +1658,7 @@ bool GMDBManager::createTablesStd()
   tab.push_back("copies");
   storeTableColumnNames(tab);
   queryStr = fmt::format("create table {0}({1} integer primary key, {2} integer not null REFERENCES Functions(id), {3} integer not null, {4} integer not null REFERENCES GeoNodesTypes(id), {5} integer)", tab[0], tab[1], tab[2], tab[3], tab[4], tab[5]);
-  if (execQuery(queryStr)) {
+  if ( 0==(rc = execQuery(queryStr))) {
     storeNodeType(geoNode, tableName); }
   tab.clear();
   
@@ -1800,7 +1682,7 @@ bool GMDBManager::createTablesStd()
   tab.push_back("dz");
   storeTableColumnNames(tab);
   queryStr = fmt::format("create table {0}({1} integer primary key, {2} real, {3} real, {4} real, {5} real, {6} real, {7} real, {8} real, {9} real, {10} real, {11} real, {12} real, {13} real)", tab[0], tab[1], tab[2], tab[3], tab[4], tab[5], tab[6], tab[7], tab[8], tab[9], tab[10], tab[11], tab[12], tab[13]);
-  if (execQuery(queryStr)) {
+  if ( 0==(rc = execQuery(queryStr))) {
     storeNodeType(geoNode, tableName); }
   tab.clear();
   
@@ -1824,7 +1706,7 @@ bool GMDBManager::createTablesStd()
   tab.push_back("dz");
   storeTableColumnNames(tab);
   queryStr = fmt::format("create table {0}({1} integer primary key, {2} real, {3} real, {4} real, {5} real, {6} real, {7} real, {8} real, {9} real, {10} real, {11} real, {12} real, {13} real)", tab[0], tab[1], tab[2], tab[3], tab[4], tab[5], tab[6], tab[7], tab[8], tab[9], tab[10], tab[11], tab[12], tab[13]);
-  if (execQuery(queryStr)) {
+  if ( 0==(rc = execQuery(queryStr))) {
     storeNodeType(geoNode, tableName); }
   tab.clear();
   
@@ -1837,19 +1719,25 @@ bool GMDBManager::createTablesStd()
   tab.push_back("name");
   storeTableColumnNames(tab);
   queryStr = fmt::format("create table {0}({1} integer primary key, {2} varchar)", tab[0], tab[1], tab[2]);
-  if (execQuery(queryStr)) {
+  if ( 0==(rc = execQuery(queryStr))) {
     storeNodeType(geoNode, tableName); }
   tab.clear();
   
-  std::cout << "All these tables have been successfully created:" << std::endl;
-  printAllDBTables();
-  return rc;
+  if(m_debug) {
+    std::cout << "All these tables have been successfully created:" << std::endl; // debug
+    printAllDBTables();
+  }
+
+  if(rc==0) {
+    return true;
+  }
+  return false;
 }
 
 
 int GMDBManager::execQuery(std::string queryStr)
 {
-  //  std::cout << "queryStr to execute: " << queryStr << std::endl; // debug
+  if(m_debug) std::cout << "queryStr to execute: " << queryStr << std::endl; // debug
   checkIsDBOpen();
   int result = -1;
   if( (result = sqlite3_exec(m_dbSqlite, queryStr.c_str(), NULL, 0, &m_SQLiteErrMsg)) )
@@ -1865,369 +1753,8 @@ int GMDBManager::execQuery(std::string queryStr)
 }
 
 
-bool GMDBManager::createTables()
-{
-//  QStringList tab;
-  QSqlQuery q;
-  QString queryStr;
-
-
-  std::string geoNode;
-  std::string tableName;
-  std::vector<std::string> tab;
-//  std::vector<std::string>::iterator it;
-
-  // create a table to store the relation between the types of GeoNodes and the name of the table
-	tableName = "dbversion";
-//  tab << tableName << "id" << "version";
-  tab.push_back(tableName); // TODO: find a nicer and faster way compared to this chain of push_back()...
-  tab.push_back("id");
-  tab.push_back("version" );
-	queryStr = QString("create table %1(%2 integer primary key, %3 integer)");
-	for (int i=0; i < tab.size(); ++i) {
-    queryStr = queryStr.arg( QString::fromStdString(tab.at(i)) );
-	}
-	if (!q.exec(queryStr)) {
-		showError(q.lastError());
-		return false;
-	}
-	storeTableColumnNames(tab);
-	tab.clear();
-
-	// create a table to store the relation between the types of GeoNodes and the name of the table
-	tableName = "GeoNodesTypes";
-//  tab << tableName << "id" << "nodeType" << "tableName";
-  tab.push_back(tableName);
-  tab.push_back("id");
-  tab.push_back("nodeType");
-  tab.push_back("tableName");
-	storeTableColumnNames(tab);
-	tab.clear();
-	if (!q.exec(QLatin1String("create table GeoNodesTypes(id integer primary key, nodeType varchar, tableName varchar)"))) {
-		showError(q.lastError());
-		return false;
-	}
-
-	// ChildrenPositions table
-	tableName = "ChildrenPositions";
-//  tab << tableName << "id" << "parentId" << "parentTable" << "parentCopyNumber" << "position" << "childTable" << "childId" << "childCopyNumber";
-  tab.push_back(tableName);
-  tab.push_back("id");
-  tab.push_back("parentId");
-  tab.push_back("parentTable");
-  tab.push_back("parentCopyNumber");
-  tab.push_back("position");
-  tab.push_back("childTable");
-  tab.push_back("childId");
-  tab.push_back("childCopyNumber");
-	queryStr = QString("create table %1(%2 integer primary key, %3 integer, %4 integer not null REFERENCES GeoNodesTypes(id), %5 integer, %6 integer, %7 integer not null REFERENCES GeoNodesTypes(id), %8 integer not null, %9 integer)"); // FIXME: add "NOT NULL" to copy numbers
-	for (int i=0; i < tab.size(); ++i) {
-		queryStr = queryStr.arg( QString::fromStdString(tab.at(i)) );
-	}
-	if (!q.exec(queryStr)) {
-		showError(q.lastError());
-		return false;
-	}
-	storeTableColumnNames(tab);
-	tab.clear();
 
 
-	// RootVolume table
-	tableName = "RootVolume";
-//  tab << tableName << "id" << "volId" << "volTable";
-  tab.push_back(tableName);
-  tab.push_back("id");
-  tab.push_back("volId");
-  tab.push_back("volTable");
-	queryStr = QString("create table %1(%2 integer primary key, %3 integer not null, %4 integer not null REFERENCES GeoNodesTypes(id))");
-	for (int i=0; i < tab.size(); ++i) {
-		queryStr = queryStr.arg( QString::fromStdString(tab.at(i)) );
-	}
-	//qDebug() << "query:" << queryStr;
-	if (!q.exec(queryStr)) {
-		showError(q.lastError());
-		return false;
-	}
-	storeTableColumnNames(tab);
-	tab.clear();
-
-
-	// PhysVols table
-	geoNode = "GeoPhysVol";
-	tableName = "PhysVols";
-  m_childType_tableName[geoNode] = tableName; // store type-table relation
-//  tab << tableName << "id" << "logvol" << "parent"; // FIXME: remove "parent" field, it is not used anymore and it's not reliable since it's not using the tableID.
-  tab.push_back(tableName);
-  tab.push_back("id");
-  tab.push_back("logvol");
-  //tab.push_back("parent");
-	storeTableColumnNames(tab);
-	tab.clear();
-//  if (!q.exec(QLatin1String("create table PhysVols(id integer primary key, logvol integer not null, parent integer)"))) {
-  if (!q.exec(QLatin1String("create table PhysVols(id integer primary key, logvol integer not null)"))) {
-		showError(q.lastError());
-		return false;
-	} else {
-		storeNodeType(geoNode, tableName);
-	}
-
-	// FullPhysVols table
-	geoNode = "GeoFullPhysVol";
-	tableName = "FullPhysVols";
-  m_childType_tableName[geoNode] = tableName; // store type-table relation
-//  tab << tableName << "id" << "logvol" << "parent";
-  tab.push_back(tableName);
-  tab.push_back("id");
-  tab.push_back("logvol");
-//  tab.push_back("parent");
-	storeTableColumnNames(tab);
-	tab.clear();
-//  if (!q.exec(QLatin1String("create table FullPhysVols(id integer primary key, logvol integer not null, parent integer)"))) {
-  if (!q.exec(QLatin1String("create table FullPhysVols(id integer primary key, logvol integer not null)"))) {
-		showError(q.lastError());
-		return false;
-	} else {
-		storeNodeType(geoNode, tableName);
-	}
-
-	// LogVols table
-	geoNode = "GeoLogVol";
-	tableName = "LogVols";
-  m_childType_tableName[geoNode] = tableName; // store type-table relation
-//  tab << tableName << "id" << "name" << "shape" << "material";
-  tab.push_back(tableName);
-  tab.push_back("id");
-  tab.push_back("name");
-  tab.push_back("shape");
-  tab.push_back("material");
-	storeTableColumnNames(tab);
-	tab.clear();
-	if (!q.exec(QLatin1String("create table LogVols(id integer primary key, name varchar, shape integer not null, material integer not null)"))) {
-		showError(q.lastError());
-		return false;
-	} else {
-		storeNodeType(geoNode, tableName);
-	}
-
-	// Materials table
-	geoNode = "GeoMaterial";
-	tableName = "Materials";
-  m_childType_tableName[geoNode] = tableName; // store type-table relation
-//  tab << tableName << "id" << "name" << "density" << "elements";
-  tab.push_back(tableName);
-  tab.push_back("id");
-  tab.push_back("name");
-  tab.push_back("density");
-  tab.push_back("elements");
-	storeTableColumnNames(tab);
-	tab.clear();
-	if (!q.exec(QLatin1String("create table Materials(id integer primary key, name varchar, density varchar, elements varchar)"))) {
-		showError(q.lastError());
-		return false;
-	} else {
-		storeNodeType(geoNode, tableName);
-	}
-
-	// Elements table
-	geoNode = "GeoElement";
-	tableName = "Elements";
-  m_childType_tableName[geoNode] = tableName; // store type-table relation
-//  tab << tableName << "id" << "name" << "symbol" << "Z" << "A";
-  tab.push_back(tableName);
-  tab.push_back("id");
-  tab.push_back("name");
-  tab.push_back("symbol");
-  tab.push_back("Z");
-  tab.push_back("A");
-	storeTableColumnNames(tab);
-	tab.clear();
-	if (!q.exec(QLatin1String("create table Elements(id integer primary key, name varchar, symbol varchar, Z varchar, A varchar)"))) {
-		showError(q.lastError());
-		return false;
-	} else {
-		storeNodeType(geoNode, tableName);
-	}
-
-	// Shapes table
-	geoNode = "GeoShape";
-	tableName = "Shapes";
-  m_childType_tableName[geoNode] = tableName; // store type-table relation
-//  tab << tableName << "id" << "type" << "parameters";
-  tab.push_back(tableName);
-  tab.push_back("id");
-  tab.push_back("type");
-  tab.push_back("parameters");
-	storeTableColumnNames(tab);
-	tab.clear();
-	if (!q.exec(QLatin1String("create table Shapes(id integer primary key, type varchar, parameters varchar)"))) {
-		showError(q.lastError());
-		return false;
-	} else {
-		storeNodeType(geoNode, tableName);
-	}
-
-	// SerialDenominators table
-	geoNode = "GeoSerialDenominator";
-	tableName = "SerialDenominators";
-  m_childType_tableName[geoNode] = tableName; // store type-table relation
-//  tab << tableName << "id" << "baseName";
-  tab.push_back(tableName);
-  tab.push_back("id");
-  tab.push_back("baseName");
-	storeTableColumnNames(tab);
-	tab.clear();
-	if (!q.exec(QLatin1String("create table SerialDenominators(id integer primary key, baseName varchar)"))) {
-		showError(q.lastError());
-		return false;
-	} else {
-		storeNodeType(geoNode, tableName);
-	}
-
-	// Functions table
-	geoNode = "Function";
-	tableName = "Functions";
-  m_childType_tableName[geoNode] = tableName; // store type-table relation
-//  tab << tableName << "id" << "expression";
-  tab.push_back(tableName);
-  tab.push_back("id");
-  tab.push_back("expression");
-	storeTableColumnNames(tab);
-	tab.clear();
-	if (!q.exec(QLatin1String("create table Functions(id integer primary key, expression varchar)"))) {
-		showError(q.lastError());
-		return false;
-	} else {
-		storeNodeType(geoNode, tableName);
-	}
-
-	// SerialDenominators table
-	geoNode = "GeoSerialTransformer";
-	tableName = "SerialTransformers";
-	m_childType_tableName[geoNode] = tableName; // store type-table relation
-//  tab << tableName << "id" << "funcId" << "volId" << "volTable" << "copies";
-  tab.push_back(tableName);
-  tab.push_back("id");
-  tab.push_back("funcId");
-  tab.push_back("volId");
-  tab.push_back("volTable");
-  tab.push_back("copies");
-	storeTableColumnNames(tab);
-	queryStr = QString("create table %1(%2 integer primary key, %3 integer not null REFERENCES Functions(id), %4 integer not null, %5 integer not null REFERENCES GeoNodesTypes(id), %6 integer)");
-	for (int i=0; i < tab.size(); ++i) {
-		queryStr = queryStr.arg( QString::fromStdString(tab.at(i)) );
-	}
-	tab.clear();
-	// qDebug() << "query:" << queryStr;
-	if (!q.exec(queryStr)) {
-		showError(q.lastError());
-		return false;
-	} else {
-		storeNodeType(geoNode, tableName);
-	}
-
-
-	// Transforms table
-	geoNode = "GeoTransform";
-	tableName = "Transforms";
-  m_childType_tableName[geoNode] = tableName; // store type-table relation
-//  tab << tableName << "id" << "xx" << "xy" << "xz" << "yx" << "yy" << "yz" << "zx" << "zy" << "zz" << "dx" << "dy" << "dz";
-  tab.push_back(tableName);
-  tab.push_back("id");
-  tab.push_back("xx");
-  tab.push_back("xy");
-  tab.push_back("xz");
-  tab.push_back("yx");
-  tab.push_back("yy");
-  tab.push_back("yz");
-  tab.push_back("zx");
-  tab.push_back("zy");
-  tab.push_back("zz");
-  tab.push_back("dx");
-  tab.push_back("dy");
-  tab.push_back("dz");
-	storeTableColumnNames(tab);
-	tab.clear();
-	if (!q.exec(QLatin1String("create table Transforms(id integer primary key, xx real, xy real, xz real, yx real, yy real, yz real, zx real, zy real, zz real, dx real, dy real, dz real)"))) {
-		showError(q.lastError());
-		return false;
-	} else {
-		storeNodeType(geoNode, tableName);
-	}
-
-	// AlignableTransforms table
-	geoNode = "GeoAlignableTransform";
-	tableName = "AlignableTransforms";
-  m_childType_tableName[geoNode] = tableName; // store type-table relation
-//  tab << tableName << "id" << "xx" << "xy" << "xz" << "yx" << "yy" << "yz" << "zx" << "zy" << "zz" << "dx" << "dy" << "dz";
-  tab.push_back(tableName);
-  tab.push_back("id");
-  tab.push_back("xx");
-  tab.push_back("xy");
-  tab.push_back("xz");
-  tab.push_back("yx");
-  tab.push_back("yy");
-  tab.push_back("yz");
-  tab.push_back("zx");
-  tab.push_back("zy");
-  tab.push_back("zz");
-  tab.push_back("dx");
-  tab.push_back("dy");
-  tab.push_back("dz");
-	storeTableColumnNames(tab);
-	tab.clear();
-	if (!q.exec(QLatin1String("create table AlignableTransforms(id integer primary key, xx real, xy real, xz real, yx real, yy real, yz real, zx real, zy real, zz real, dx real, dy real, dz real)"))) {
-		showError(q.lastError());
-		return false;
-	} else {
-		storeNodeType(geoNode, tableName);
-	}
-
-	// NameTags table
-	geoNode = "GeoNameTag";
-	tableName = "NameTags";
-	m_childType_tableName[geoNode] = tableName; // store type-table relation
-//  tab << tableName << "id" << "name";
-  tab.push_back(tableName);
-  tab.push_back("id");
-  tab.push_back("name");
-	storeTableColumnNames(tab);
-	queryStr = QString("create table %1(%2 integer primary key, %3 varchar)");
-	for (int i=0; i < tab.size(); ++i) {
-		queryStr = queryStr.arg( QString::fromStdString(tab.at(i)) );
-	}
-	tab.clear();
-	// qDebug() << "query:" << queryStr;
-	if (!q.exec(queryStr)) {
-		showError(q.lastError());
-		return false;
-	} else {
-		storeNodeType(geoNode, tableName);
-	}
-
-	return true;
-
-}
-
-void GMDBManager::loadTableNamesFromDB()
-{
-	QSqlDatabase db = QSqlDatabase::database();
-	QStringList qtables = db.tables();
-  std::vector<std::string> tables = toStdVectorStrings(qtables);
-  for ( auto& tab : tables) {
-    std::vector<std::string> tabColNames = getTableColNamesFromDB(tab);
-		storeTableColumnNames(tabColNames);
-	}
-}
-
-//void GMDBManager::storeTableColumnNames(QStringList input)
-//{
-//  //  qDebug() << "GMDBManager::storeTableColumnNames()";
-//  if (! (input.isEmpty()) ) {
-//    QString tabName = input.takeFirst();
-//    m_tableNames[tabName] = input;
-//  }
-//}
-
 void GMDBManager::storeTableColumnNames(std::vector<std::string> input)
 {
   if (! (input.size() == 0) ) {
@@ -2246,8 +1773,32 @@ std::vector<std::string> GMDBManager::getTableColumnNames(const std::string &tab
 
 void GMDBManager::storeNodeType(std::string nodeType, std::string tableName)
 {
-	// JFB commented: qDebug() << "GMDBManager::storeNodeType()";
-
+  checkIsDBOpen();
+  std::string queryStr;
+  sqlite3_stmt * st = nullptr;
+  int rc = -1;
+  // preparing the SQL query
+  std::string sql = "INSERT INTO GeoNodesTypes(nodeType, tableName) VALUES(?, ?)";
+  rc = sqlite3_prepare_v2( m_dbSqlite, sql.c_str(), -1, &st, NULL);
+  if (rc != SQLITE_OK) {
+    printf( "[SQLite ERR] (%s) : Error msg: %s\n", __func__, sqlite3_errmsg(m_dbSqlite) ); // TODO: add __func__ to all error messages, as I did here
+    exit(EXIT_FAILURE);
+  }
+  if(m_debug) std::cout << "storeNodeType - Query string:" << sql << std::endl; // debug
+  // bind the parameters
+  rc = sqlite3_bind_text(st, 1, nodeType.c_str(), nodeType.length(), SQLITE_TRANSIENT);
+  rc = sqlite3_bind_text(st, 2, tableName.c_str(), tableName.length(), SQLITE_TRANSIENT);
+  // execute the query
+  rc = sqlite3_step( st );
+  if (rc != SQLITE_DONE) {
+    printf( "[SQLite ERR] : Error msg: %s\n", sqlite3_errmsg(m_dbSqlite) );
+    exit(EXIT_FAILURE);
+  }
+  // finalize
+  sqlite3_finalize(st);
+  return;
+  
+  /*
 	QSqlQuery q;
 	if (!q.prepare(QLatin1String("insert into GeoNodesTypes(nodeType, tableName) values(?, ?)"))) {
 		showError(q.lastError());
@@ -2258,6 +1809,7 @@ void GMDBManager::storeNodeType(std::string nodeType, std::string tableName)
   q.addBindValue(QString::fromStdString(tableName));
 	q.exec();
 	return;
+  */
 }
 
 
@@ -2290,19 +1842,19 @@ void GMDBManager::storeNodeType(std::string nodeType, std::string tableName)
 //}
 
 
-std::vector<std::string> GMDBManager::getTableColNamesFromDB(std::string tableName) const
-{
-  std::vector<std::string> colNames;
-	colNames. push_back( tableName );
-
-	// fetch the driver
-	QSqlDriver* driver = m_db.driver();
-  QSqlRecord record = driver->record(QString::fromStdString(tableName));
-	unsigned int colN = record.count();
-	for (unsigned int i = 0; i < colN; ++i)
-		colNames.push_back( record.fieldName(i).toStdString() );
-	return colNames;
-}
+//std::vector<std::string> GMDBManager::getTableColNamesFromDB(std::string tableName) const
+//{
+//  std::vector<std::string> colNames;
+//  colNames. push_back( tableName );
+//
+//  // fetch the driver
+//  QSqlDriver* driver = m_db.driver();
+//  QSqlRecord record = driver->record(QString::fromStdString(tableName));
+//  unsigned int colN = record.count();
+//  for (unsigned int i = 0; i < colN; ++i)
+//    colNames.push_back( record.fieldName(i).toStdString() );
+//  return colNames;
+//}
 
 
 
@@ -2318,11 +1870,37 @@ std::vector<std::string> GMDBManager::getTableColNamesFromDB(std::string tableNa
 
 bool GMDBManager::storeRootVolume(const unsigned int &id, const std::string &nodeType)
 {
-	const unsigned int typeId = getTableIdFromNodeType(nodeType);
-
+  checkIsDBOpen();
+  
   std::string tableName = "RootVolume";
+	const unsigned int typeId = getTableIdFromNodeType(nodeType);
   std::vector<std::string> cols = getTableColumnNames(tableName);
 
+  // set the SQL query
+  std::string queryStr;
+  std::string sql = fmt::format("INSERT INTO {0} ({1}, {2}) VALUES (?, ?)", tableName, cols[1], cols[2]);
+  // preparing the SQL query
+  sqlite3_stmt * st = nullptr;
+  int rc = -1;
+  rc = sqlite3_prepare_v2( m_dbSqlite, sql.c_str(), -1, &st, NULL);
+  if (rc != SQLITE_OK) {
+    printf( "[SQLite ERR] (%s) : Error msg: %s\n", __func__, sqlite3_errmsg(m_dbSqlite) ); // TODO: add __func__ to all error messages, as I did here
+    exit(EXIT_FAILURE);
+  }
+  if(m_debug) std::cout << "Query string:" << sql << std::endl; // debug
+  // bind the parameters
+  rc = sqlite3_bind_int(st, 1, id);
+  rc = sqlite3_bind_int(st, 2, typeId);
+  // execute the query
+  rc = sqlite3_step( st );
+  if (rc != SQLITE_DONE) {
+    printf( "[SQLite ERR] (%s) : Error msg: %s\n", __func__, sqlite3_errmsg(m_dbSqlite) );
+    exit(EXIT_FAILURE);
+  }
+  // finalize
+  sqlite3_finalize(st);
+  
+  /*
 	// prepare the query string
 	QString queryStr = QString("insert into %1(%2, %3) values(?, ?)").arg( QString::fromStdString(tableName) );
 	for (int i=0; i < cols.size(); ++i) {
@@ -2340,6 +1918,8 @@ bool GMDBManager::storeRootVolume(const unsigned int &id, const std::string &nod
 	q.addBindValue(typeId);
 	// run the query
 	q.exec();
+  */
+  
 	return true;
 }
 
@@ -2363,14 +1943,26 @@ std::vector<std::string> GMDBManager::getRootPhysVol()
 std::vector<std::string> GMDBManager::getRootPhysVol()
 {
   // get the ID of the ROOT vol from the table "RootVolume"
-  QSqlQuery query = selectAllFromTable("RootVolume");
-
+  sqlite3_stmt* stmt = selectAllFromTable("RootVolume");
+  // declare the data we want to fetch
   unsigned int id;
   unsigned int typeId;
-  while (query.next()) {
-    id = query.value(1).toUInt();
-    typeId = query.value(2).toUInt();
+  // execute the statement on all rows
+  int rc = -1;
+  while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
+    // get the data
+    id = sqlite3_column_int(stmt, 0);
+    typeId = sqlite3_column_int(stmt, 1);
+    // TODO: fill a cache
+  }
+  if (rc != SQLITE_DONE) {
+    std::string errmsg(sqlite3_errmsg(m_dbSqlite));
+    sqlite3_finalize(stmt);
+    throw errmsg;
   }
+  // finalize
+  sqlite3_finalize(stmt);
+  
   return getItemAndType(typeId, id);
 }
 
diff --git a/GeoModelRead/src/ReadGeoModel.cpp b/GeoModelRead/src/ReadGeoModel.cpp
index ad7dd8cf80b4099c2ee1f7b27973d7aed9c3ecae..1ef613cb69913d22c51f4e84a82e40c85628d423 100644
--- a/GeoModelRead/src/ReadGeoModel.cpp
+++ b/GeoModelRead/src/ReadGeoModel.cpp
@@ -92,20 +92,20 @@ ReadGeoModel::ReadGeoModel(GMDBManager* db, unsigned long* progress) : m_deepDeb
   m_debug(false), m_timing(false), m_runMultithreaded(false),
   m_runMultithreaded_nThreads(0), m_progress(nullptr)
 {
-  // Check if the user asked for running in serial or multi-threading mode
-  if ( "" != getEnvVar("GEOMODEL_ENV_IO_DEBUG")) {
+  // Check if the user asked for debug messages
+  if ( "" != getEnvVar("GEOMODEL_ENV_IO_READ_DEBUG")) {
     m_debug = true;
     std::cout << "You defined the GEOMODEL_IO_DEBUG variable, so you will see a verbose output." << std::endl;
   }
-  // Check if the user asked for running in serial or multi-threading mode
+  // Check if the user asked for verbose debug messages
   if ( "" != getEnvVar("GEOMODEL_ENV_IO_DEBUG_VERBOSE")) {
     m_deepDebug = true;
-    std::cout << "You defined the GEOMODEL_IO_DEBUG_VERBOSE variable, so you will see a verbose output." << std::endl;
+    std::cout << "You defined the GEOMODEL_IO_READ_DEBUG_VERBOSE variable, so you will see a verbose output." << std::endl;
   }
-  // Check if the user asked for running in serial or multi-threading mode
+  // Check if the user asked for timing output
   if ( "" != getEnvVar("GEOMODEL_ENV_IO_TIMING")) {
     m_timing = true;
-    std::cout << "You defined the GEOMODEL_IO_TIMING variable, so you will see a timing measurement in the output." << std::endl;
+    std::cout << "You defined the GEOMODEL_IO_READ_TIMING variable, so you will see a timing measurement in the output." << std::endl;
   }
 
 	if ( progress != nullptr) {
@@ -182,18 +182,18 @@ GeoPhysVol* ReadGeoModel::buildGeoModelPrivate()
   // *** get all data from the DB ***
 
 	// get all GeoModel nodes from the DB
-	m_logVols = m_dbManager->getTableFromNodeTypeStd("GeoLogVol");
-	m_shapes = m_dbManager->getTableFromNodeTypeStd("GeoShape");
-	m_materials = m_dbManager->getTableFromNodeTypeStd("GeoMaterial");
-	m_elements = m_dbManager->getTableFromNodeTypeStd("GeoElement");
-	m_functions = m_dbManager->getTableFromNodeTypeStd("Function");
-  m_physVols = m_dbManager->getTableFromNodeTypeStd("GeoPhysVol");
-  m_fullPhysVols = m_dbManager->getTableFromNodeTypeStd("GeoFullPhysVol");
-  m_transforms = m_dbManager->getTableFromNodeTypeStd("GeoTransform");
-  m_alignableTransforms = m_dbManager->getTableFromNodeTypeStd("GeoAlignableTransform");
-  m_serialDenominators = m_dbManager->getTableFromNodeTypeStd("GeoSerialDenominator");
-  m_serialTransformers = m_dbManager->getTableFromNodeTypeStd("GeoSerialTransformer");
-  m_nameTags = m_dbManager->getTableFromNodeTypeStd("GeoNameTag");
+	m_logVols = m_dbManager->getTableFromNodeType("GeoLogVol");
+	m_shapes = m_dbManager->getTableFromNodeType("GeoShape");
+	m_materials = m_dbManager->getTableFromNodeType("GeoMaterial");
+	m_elements = m_dbManager->getTableFromNodeType("GeoElement");
+	m_functions = m_dbManager->getTableFromNodeType("Function");
+  m_physVols = m_dbManager->getTableFromNodeType("GeoPhysVol");
+  m_fullPhysVols = m_dbManager->getTableFromNodeType("GeoFullPhysVol");
+  m_transforms = m_dbManager->getTableFromNodeType("GeoTransform");
+  m_alignableTransforms = m_dbManager->getTableFromNodeType("GeoAlignableTransform");
+  m_serialDenominators = m_dbManager->getTableFromNodeType("GeoSerialDenominator");
+  m_serialTransformers = m_dbManager->getTableFromNodeType("GeoSerialTransformer");
+  m_nameTags = m_dbManager->getTableFromNodeType("GeoNameTag");
   
   // get the children table from DB
   m_allchildren = m_dbManager->getChildrenTableStd();
diff --git a/GeoModelWrite/GeoModelWrite/WriteGeoModel.h b/GeoModelWrite/GeoModelWrite/WriteGeoModel.h
index bb882c500f63c3fb77b81d31e9036d9966bdf56a..5f0d7f411ebb2efd767f6fb18a6027e41bf717c5 100644
--- a/GeoModelWrite/GeoModelWrite/WriteGeoModel.h
+++ b/GeoModelWrite/GeoModelWrite/WriteGeoModel.h
@@ -22,7 +22,7 @@
 #include "GeoModelKernel/GeoLogVol.h"
 #include "GeoModelKernel/GeoXF.h"
 #include "GeoModelKernel/GeoAlignableTransform.h"
-#include "GeoModelKernel/GeoDefinitions.h"
+#include "GeoModelKernel/GeoDefinitions.h" 
 
 // C++ includes
 #include <vector>
diff --git a/GeoModelWrite/src/WriteGeoModel.cpp b/GeoModelWrite/src/WriteGeoModel.cpp
index ef9b992e09bafd10cd504bc6a66a312cf9ea50c6..64c60b062a33a65a460ce691610a01c722ba1d4c 100644
--- a/GeoModelWrite/src/WriteGeoModel.cpp
+++ b/GeoModelWrite/src/WriteGeoModel.cpp
@@ -1124,7 +1124,7 @@ WriteGeoModel::WriteGeoModel(GMDBManager &db)
 
 	// init anche check the database handle
 	m_dbManager = &db;
-	if (m_dbManager->isOpen()) {
+	if (m_dbManager->checkIsDBOpen()) { 
 		//JFB Commented out: qDebug() << "OK! Database is open!";
 	}
 	else {