|
@@ -21,19 +21,19 @@
|
|
|
#include <stdexcept>
|
|
|
|
|
|
// Qt includes
|
|
|
-#include <QSqlQuery>
|
|
|
-#include <QSqlRecord>
|
|
|
-#include <QSqlError>
|
|
|
-#include <QVariant>
|
|
|
#include <QDate>
|
|
|
-#include <QStringList>
|
|
|
-#include <QSet>
|
|
|
-#include <QFile>
|
|
|
+#include <QDebug>
|
|
|
#include <QDirIterator>
|
|
|
+#include <QFile>
|
|
|
#include <QFileInfo>
|
|
|
-#include <QDebug>
|
|
|
#include <QFileSystemWatcher>
|
|
|
#include <QMutexLocker>
|
|
|
+#include <QSet>
|
|
|
+#include <QSqlError>
|
|
|
+#include <QSqlQuery>
|
|
|
+#include <QSqlRecord>
|
|
|
+#include <QStringList>
|
|
|
+#include <QVariant>
|
|
|
|
|
|
// ctkDICOM includes
|
|
|
#include "ctkDICOMDatabase.h"
|
|
@@ -109,6 +109,11 @@ public:
|
|
|
|
|
|
/// tagCache table has been checked to exist
|
|
|
bool TagCacheVerified;
|
|
|
+ /// tag cache has independent database to avoid locking issue
|
|
|
+ /// with other access to the database which need to be
|
|
|
+ /// reading while the tag cache is writing
|
|
|
+ QSqlDatabase TagCacheDatabase;
|
|
|
+ QString TagCacheDatabaseFilename;
|
|
|
|
|
|
int insertPatient(const ctkDICOMDataset& ctkDataset);
|
|
|
void insertStudy(const ctkDICOMDataset& ctkDataset, int dbPatientID);
|
|
@@ -133,6 +138,7 @@ void ctkDICOMDatabasePrivate::init(QString databaseFilename)
|
|
|
Q_Q(ctkDICOMDatabase);
|
|
|
|
|
|
q->openDatabase(databaseFilename);
|
|
|
+
|
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
@@ -214,6 +220,11 @@ void ctkDICOMDatabase::openDatabase(const QString databaseFile, const QString& c
|
|
|
QFileSystemWatcher* watcher = new QFileSystemWatcher(QStringList(databaseFile),this);
|
|
|
connect(watcher, SIGNAL(fileChanged(QString)),this, SIGNAL (databaseChanged()) );
|
|
|
}
|
|
|
+
|
|
|
+ // set up the tag cache for use later
|
|
|
+ QFileInfo fileInfo(d->DatabaseFileName);
|
|
|
+ d->TagCacheDatabaseFilename = QString( fileInfo.dir().path() + "/ctkDICOMTagCache.sql" );
|
|
|
+ d->TagCacheVerified = false;
|
|
|
}
|
|
|
|
|
|
|
|
@@ -333,6 +344,7 @@ void ctkDICOMDatabase::closeDatabase()
|
|
|
{
|
|
|
Q_D(ctkDICOMDatabase);
|
|
|
d->Database.close();
|
|
|
+ d->TagCacheDatabase.close();
|
|
|
}
|
|
|
|
|
|
//
|
|
@@ -1196,13 +1208,32 @@ bool ctkDICOMDatabase::tagCacheExists()
|
|
|
{
|
|
|
return true;
|
|
|
}
|
|
|
- QSqlQuery cacheExists( d->Database );
|
|
|
+
|
|
|
+ // try to open the database if it's not already open
|
|
|
+ if ( !(d->TagCacheDatabase.isOpen()) )
|
|
|
+ {
|
|
|
+ qDebug() << "TagCacheDatabase not open\n";
|
|
|
+ d->TagCacheDatabase = QSqlDatabase::addDatabase("QSQLITE", "TagCache");
|
|
|
+ d->TagCacheDatabase.setDatabaseName(d->TagCacheDatabaseFilename);
|
|
|
+ if ( !(d->TagCacheDatabase.open()) )
|
|
|
+ {
|
|
|
+ qDebug() << "TagCacheDatabase would not open!\n";
|
|
|
+ qDebug() << "TagCacheDatabaseFilename is: " << d->TagCacheDatabaseFilename << "\n";
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // check that the table exists
|
|
|
+ QSqlQuery cacheExists( d->TagCacheDatabase );
|
|
|
cacheExists.prepare("SELECT * FROM TagCache LIMIT 1");
|
|
|
bool success = d->loggedExec(cacheExists);
|
|
|
if (success)
|
|
|
{
|
|
|
+ qDebug() << "TagCacheDatabase verified!\n";
|
|
|
d->TagCacheVerified = true;
|
|
|
+ return true;
|
|
|
}
|
|
|
+ qDebug() << "TagCacheDatabase NOT verified based on table check!\n";
|
|
|
return false;
|
|
|
}
|
|
|
|
|
@@ -1214,13 +1245,15 @@ bool ctkDICOMDatabase::initializeTagCache()
|
|
|
// First, drop any existing table
|
|
|
if ( this->tagCacheExists() )
|
|
|
{
|
|
|
- QSqlQuery dropCacheTable( d->Database );
|
|
|
+ qDebug() << "TagCacheDatabase drop existing table\n";
|
|
|
+ QSqlQuery dropCacheTable( d->TagCacheDatabase );
|
|
|
dropCacheTable.prepare( "DROP TABLE TagCache" );
|
|
|
d->loggedExec(dropCacheTable);
|
|
|
}
|
|
|
|
|
|
// now create a table
|
|
|
- QSqlQuery createCacheTable( d->Database );
|
|
|
+ qDebug() << "TagCacheDatabase adding table\n";
|
|
|
+ QSqlQuery createCacheTable( d->TagCacheDatabase );
|
|
|
createCacheTable.prepare(
|
|
|
"CREATE TABLE TagCache (SOPInstanceUID, Tag, Value, PRIMARY KEY (SOPInstanceUID, Tag))" );
|
|
|
bool success = d->loggedExec(createCacheTable);
|
|
@@ -1238,9 +1271,12 @@ QString ctkDICOMDatabase::cachedTag(const QString sopInstanceUID, const QString
|
|
|
Q_D(ctkDICOMDatabase);
|
|
|
if ( !this->tagCacheExists() )
|
|
|
{
|
|
|
- this->initializeTagCache();
|
|
|
+ if ( !this->initializeTagCache() )
|
|
|
+ {
|
|
|
+ return( "" );
|
|
|
+ }
|
|
|
}
|
|
|
- QSqlQuery selectValue( d->Database );
|
|
|
+ QSqlQuery selectValue( d->TagCacheDatabase );
|
|
|
selectValue.prepare( "SELECT Value FROM TagCache WHERE SOPInstanceUID = :sopInstanceUID AND Tag = :tag" );
|
|
|
selectValue.bindValue(":sopInstanceUID",sopInstanceUID);
|
|
|
selectValue.bindValue(":tag",tag);
|
|
@@ -1259,9 +1295,12 @@ bool ctkDICOMDatabase::cacheTag(const QString sopInstanceUID, const QString tag,
|
|
|
Q_D(ctkDICOMDatabase);
|
|
|
if ( !this->tagCacheExists() )
|
|
|
{
|
|
|
- this->initializeTagCache();
|
|
|
+ if ( !this->initializeTagCache() )
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
}
|
|
|
- QSqlQuery insertTag( d->Database );
|
|
|
+ QSqlQuery insertTag( d->TagCacheDatabase );
|
|
|
insertTag.prepare( "INSERT OR REPLACE INTO TagCache VALUES(:sopInstanceUID, :tag, :value)" );
|
|
|
insertTag.bindValue(":sopInstanceUID",sopInstanceUID);
|
|
|
insertTag.bindValue(":tag",tag);
|