Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 34 additions & 22 deletions CommonData/databaseinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down Expand Up @@ -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
Expand All @@ -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()
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -2294,7 +2306,7 @@ void DatabaseInterface::transactionWriteEnd(bool rollback)
}
else if(_transactionWriteDepth == 0 || --_transactionWriteDepth == 0)
runStatements("COMMIT", true);

}

void DatabaseInterface::transactionReadEnd()
Expand Down
9 changes: 2 additions & 7 deletions CommonData/databaseinterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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<std::thread::id, sqlite3*> _dbs;
std::thread::id _dbCreator;
sqlite3* _dbCreated = nullptr;
Expand Down
2 changes: 0 additions & 2 deletions Desktop/data/datasetloader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,6 @@ void DataSetLoader::loadPackage(const string &locator, const string &extension,

void DataSetLoader::syncPackage(const string &locator, const string &extension, std::function<void(int)> progress)
{
Utils::sleep(100); // :'(

Importer* importer = getImporter(locator, extension);

if (importer)
Expand Down
Loading