Browse Source

Put all tags for a given instance into a list for a single batch insert

Addresses #414 by using the execBatch feature of QSQLQuery.

Might still be improved if we can do other operations as batch inserts
as well.
Steve Pieper 11 years ago
parent
commit
faed95e136
2 changed files with 55 additions and 11 deletions
  1. 53 11
      Libs/DICOM/Core/ctkDICOMDatabase.cpp
  2. 2 0
      Libs/DICOM/Core/ctkDICOMDatabase.h

+ 53 - 11
Libs/DICOM/Core/ctkDICOMDatabase.cpp

@@ -85,6 +85,7 @@ public:
   ///
   bool loggedExec(QSqlQuery& query);
   bool loggedExec(QSqlQuery& query, const QString& queryString);
+  bool loggedExecBatch(QSqlQuery& query);
   bool LoggedExecVerbose;
 
   ///
@@ -234,6 +235,27 @@ bool ctkDICOMDatabasePrivate::loggedExec(QSqlQuery& query, const QString& queryS
 }
 
 //------------------------------------------------------------------------------
+bool ctkDICOMDatabasePrivate::loggedExecBatch(QSqlQuery& query)
+{
+  bool success;
+  success = query.execBatch();
+  if (!success)
+    {
+      QSqlError sqlError = query.lastError();
+      logger.debug( "SQL failed\n Bad SQL: " + query.lastQuery());
+      logger.debug( "Error text: " + sqlError.text());
+    }
+  else
+    {
+      if (LoggedExecVerbose)
+      {
+      logger.debug( "SQL worked!\n SQL: " + query.lastQuery());
+      }
+    }
+  return (success);
+}
+
+//------------------------------------------------------------------------------
 void ctkDICOMDatabasePrivate::beginTransaction()
 {
   QSqlQuery transaction( this->Database );
@@ -1082,17 +1104,21 @@ void ctkDICOMDatabasePrivate::precacheTags( const QString sopInstanceUID )
   QString fileName = q->fileForInstance(sopInstanceUID);
   dataset.InitializeFromFile(fileName);
 
-  this->beginTransaction();
 
+  QStringList sopInstanceUIDs, tags, values;
   foreach (const QString &tag, this->TagsToPrecache)
     {
     unsigned short group, element;
     q->tagToGroupElement(tag, group, element);
     DcmTagKey tagKey(group, element);
     QString value = dataset.GetAllElementValuesAsString(tagKey);
-    q->cacheTag(sopInstanceUID, tag, value);
+    sopInstanceUIDs << sopInstanceUID;
+    tags << tag;
+    values << value;
     }
 
+  this->beginTransaction();
+  q->cacheTags(sopInstanceUIDs, tags, values);
   this->endTransaction();
 }
 
@@ -1611,6 +1637,16 @@ QString ctkDICOMDatabase::cachedTag(const QString sopInstanceUID, const QString
 //------------------------------------------------------------------------------
 bool ctkDICOMDatabase::cacheTag(const QString sopInstanceUID, const QString tag, const QString value)
 {
+  QStringList sopInstanceUIDs, tags, values;
+  sopInstanceUIDs << sopInstanceUID;
+  tags << tag;
+  values << value;
+  return this->cacheTags(sopInstanceUIDs, tags, values);
+}
+
+//------------------------------------------------------------------------------
+bool ctkDICOMDatabase::cacheTags(const QStringList sopInstanceUIDs, const QStringList tags, QStringList values)
+{
   Q_D(ctkDICOMDatabase);
   if ( !this->tagCacheExists() )
     {
@@ -1619,15 +1655,21 @@ bool ctkDICOMDatabase::cacheTag(const QString sopInstanceUID, const QString tag,
       return false;
       }
     }
-  QString valueToInsert(value);
-  if (valueToInsert == "")
+
+  // replace empty strings with special flag string
+  QStringList::iterator i;
+  for (i = values.begin(); i != values.end(); ++i)
     {
-    valueToInsert = TagNotInInstance;
+    if (*i == "")
+      {
+      *i = TagNotInInstance;
+      }
     }
-  QSqlQuery insertTag( d->TagCacheDatabase );
-  insertTag.prepare( "INSERT OR REPLACE INTO TagCache VALUES(:sopInstanceUID, :tag, :value)" );
-  insertTag.bindValue(":sopInstanceUID",sopInstanceUID);
-  insertTag.bindValue(":tag",tag);
-  insertTag.bindValue(":value",valueToInsert);
-  return d->loggedExec(insertTag);
+
+  QSqlQuery insertTags( d->TagCacheDatabase );
+  insertTags.prepare( "INSERT OR REPLACE INTO TagCache VALUES(?,?,?)" );
+  insertTags.addBindValue(sopInstanceUIDs);
+  insertTags.addBindValue(tags);
+  insertTags.addBindValue(values);
+  return d->loggedExecBatch(insertTags);
 }

+ 2 - 0
Libs/DICOM/Core/ctkDICOMDatabase.h

@@ -230,6 +230,8 @@ public:
   Q_INVOKABLE QString cachedTag (const QString sopInstanceUID, const QString tag);
   /// Insert an instance tag's value into to the cache
   Q_INVOKABLE bool cacheTag (const QString sopInstanceUID, const QString tag, const QString value);
+  /// Insert lists of tags into the cache as a batch query operation
+  Q_INVOKABLE bool cacheTags (const QStringList sopInstanceUIDs, const QStringList tags, const QStringList values);
 
 
 Q_SIGNALS: