diff --git a/CommonData/databaseinterface.cpp b/CommonData/databaseinterface.cpp index 7e4108b5db..ae29690c20 100644 --- a/CommonData/databaseinterface.cpp +++ b/CommonData/databaseinterface.cpp @@ -12,6 +12,10 @@ DatabaseInterface * DatabaseInterface::_singleton = nullptr; +thread_local int _transactionWriteDepth = 0, + _transactionReadDepth = 0; + + //#define SIR_LOG_A_LOT const std::string DatabaseInterface::_dbConstructionSql = @@ -2135,37 +2139,38 @@ void DatabaseInterface::preloadInterfaceForThread() void DatabaseInterface::load() { JASPTIMER_SCOPE(DatabaseInterface::load); - assert(!_dbCreated || std::this_thread::get_id() != _dbCreator); + assert(!_dbCreated || std::this_thread::get_id() != _dbCreator); _loadMutex.lock(); if(_dbs.count(std::this_thread::get_id())) { + sqlite3* connection = _dbs.at(std::this_thread::get_id()); _loadMutex.unlock(); - return; + return; } - - if(!std::filesystem::exists(dbFile())) - throw std::runtime_error("Trying to load '" + dbFile() + "' but it doesn't exist!"); + if(!std::filesystem::exists(dbFile())) + throw std::runtime_error("Trying to load '" + dbFile() + "' but it doesn't exist!"); bool loadingWorked = false; size_t loadingAttempt = 0; sqlite3 * db = nullptr; - for(bool loadingWorked = false; !loadingWorked; ) - { - int ret = sqlite3_open_v2(dbFile().c_str(), &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_NOMUTEX, NULL); + int ret = sqlite3_open_v2(dbFile().c_str(), &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_NOMUTEX, NULL); - if(ret != SQLITE_OK) - { - Log::log() << "Couldnt open sqlite internal db, because of: " << (db ? sqlite3_errmsg(db) : "not even a broken sqlite3 obj was returned..." ) << std::endl; - throw std::runtime_error("JASP cannot run without an internal database and it cannot be created. Contact the JASP team for help."); - } - else - Log::log() << "Opened internal sqlite database for loading at '" << dbFile() << "'. This is for thread " << std::this_thread::get_id() << std::endl; + if(ret != SQLITE_OK) + { + Log::log() << "Couldnt open sqlite internal db, because of: " << (db ? sqlite3_errmsg(db) : "not even a broken sqlite3 obj was returned..." ) << std::endl; + throw std::runtime_error("JASP cannot run without an internal database and it cannot be created. Contact the JASP team for help."); + } + else + Log::log() << "Opened internal sqlite database for loading at '" << dbFile() << "'. This is for thread " << std::this_thread::get_id() << std::endl; - _dbs[std::this_thread::get_id()] = db; - + _dbs[std::this_thread::get_id()] = db; + _loadMutex.unlock(); + + for(bool loadingWorked = false; !loadingWorked; ) + { sqlite3_busy_timeout(db, 100); try @@ -2187,17 +2192,14 @@ void DatabaseInterface::load() if(!loadingWorked) { if(loadingAttempt > 10 * 60) //Timeout is 0.1 sec, so this lets the db try for 1 minute to connect... - { - _loadMutex.unlock(); throw dbMalformedException(); - } Log::log() << "There was a problem loading the database, retrying for the #" << loadingAttempt << " time" << std::endl; std::this_thread::sleep_for(std::chrono::nanoseconds(100000000)); } } - _loadMutex.unlock(); + return; } void DatabaseInterface::close() @@ -2254,6 +2256,16 @@ bool DatabaseInterface::tableExists(const std::string &name) return runStatementsId("SELECT COUNT(name) FROM sqlite_master WHERE type='table' AND name='" + name + "';") > 0; } +int DatabaseInterface::transactionWriteDepth() +{ + return _transactionWriteDepth; +} + +int DatabaseInterface::transactionReadDepth() +{ + return _transactionReadDepth; +} + void DatabaseInterface::transactionWriteBegin() { JASPTIMER_SCOPE(DatabaseInterface::transactionWriteBegin); @@ -2294,7 +2306,7 @@ void DatabaseInterface::transactionWriteEnd(bool rollback) } else if(_transactionWriteDepth == 0 || --_transactionWriteDepth == 0) runStatements("COMMIT", true); - + } void DatabaseInterface::transactionReadEnd() diff --git a/CommonData/databaseinterface.h b/CommonData/databaseinterface.h index a1731008b9..ba950c2008 100644 --- a/CommonData/databaseinterface.h +++ b/CommonData/databaseinterface.h @@ -183,8 +183,8 @@ class DatabaseInterface void truncateAllTables(); bool tableHasColumn(const std::string & tableName, const std::string & columnName); bool tableExists(const std::string & name); - int transactionWriteDepth() { return _transactionWriteDepth; } - int transactionReadDepth() { return _transactionReadDepth; } + int transactionWriteDepth(); + int transactionReadDepth(); void preloadInterfaceForThread(); void close(); ///< Closes the loaded database and disconnects @@ -199,11 +199,6 @@ class DatabaseInterface void create(); ///< Creates a new sqlite database in sessiondir and loads it void load(); ///< Loads a sqlite database from sessiondir (after loading a jaspfile) - - - int _transactionWriteDepth = 0, - _transactionReadDepth = 0; - std::map _dbs; std::thread::id _dbCreator; sqlite3* _dbCreated = nullptr; diff --git a/Desktop/data/datasetloader.cpp b/Desktop/data/datasetloader.cpp index eeecd6f770..7893c08f70 100644 --- a/Desktop/data/datasetloader.cpp +++ b/Desktop/data/datasetloader.cpp @@ -89,8 +89,6 @@ void DataSetLoader::loadPackage(const string &locator, const string &extension, void DataSetLoader::syncPackage(const string &locator, const string &extension, std::function progress) { - Utils::sleep(100); // :'( - Importer* importer = getImporter(locator, extension); if (importer)