Browse Source

Merge pull request #415 from pieper/414-batch-insert-tags

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

Thanks for the reviews @nolden and @jcfr - I'm going to go ahead and do the merge (same tests fail as before ;( so no harm from this pull.
Steve Pieper 11 years ago
parent
commit
3b58045d9d
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: