/*========================================================================= Program: GDCM (Grassroots DICOM). A DICOM library Copyright (c) 2006-2011 Mathieu Malaterre All rights reserved. See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ /* * Ref: * http://massmail.spl.harvard.edu/public-archives/slicer-devel/2010/004408.html * * Implementation details: * http://www.sqlite.org/c3ref/bind_blob.html * http://www.adp-gmbh.ch/sqlite/bind_insert.html */ #include "gdcmScanner.h" #include "gdcmDirectory.h" #include "gdcmTag.h" #include "gdcmTrace.h" #include "sqlite3.h" #include #include int main(int argc, char *argv[]) { if( argc < 2 ) { return 1; } time_t time_start = time(nullptr); gdcm::Trace::SetDebug( false ); gdcm::Trace::SetWarning( false ); const char *inputdirectory = argv[1]; gdcm::Directory d; unsigned int nfiles = d.Load( inputdirectory, true); gdcm::Scanner s; using gdcm::Tag; s.AddTag( Tag(0x20,0xd) ); // Study Instance UID s.AddTag( Tag(0x20,0xe) ); // Series Instance UID bool b0 = s.Scan( d.GetFilenames() ); if( !b0 ) return 1; time_t time_scanner = time(nullptr); std::cout << "Finished loading data from : " << nfiles << " files" << std::endl; // MappingType const &mappings = s.GetMappings(); sqlite3* db; sqlite3_open("./dicom.db", &db); if(db == nullptr) { std::cerr << "Could not open database." << std::endl; return 1; } const char sql_stmt[] = "create table browser (seriesuid, studyuid)"; int ret; char *errmsg; ret = sqlite3_exec(db, sql_stmt, nullptr, nullptr, &errmsg); if(ret != SQLITE_OK) { printf("Error in statement: %s [%s].\n", sql_stmt, errmsg); return 1; } using gdcm::Directory; using gdcm::Scanner; const Directory::FilenamesType& files = d.GetFilenames(); Directory::FilenamesType::const_iterator file = files.begin(); sqlite3_stmt *stmt; if ( sqlite3_prepare( db, "insert into browser values (?,?)", // stmt -1, // If than zero, then stmt is read up to the first nul terminator &stmt, nullptr // Pointer to unused portion of stmt ) != SQLITE_OK) { printf("\nCould not prepare statement."); return 1; } //printf("\nThe statement has %d wildcards\n", sqlite3_bind_parameter_count(stmt)); for(; file != files.end(); ++file) { const char *filename = file->c_str(); bool b = s.IsKey(filename); if( b ) { const Scanner::TagToValue &mapping = s.GetMapping(filename); Scanner::TagToValue::const_iterator it = mapping.begin(); sqlite3_reset(stmt); for( int index = 1; it != mapping.end(); ++it, ++index) { //const Tag & tag = it->first; const char *value = it->second; if (sqlite3_bind_text ( stmt, index, // Index of wildcard value, (int)strlen(value), // length of text SQLITE_STATIC // SQLite assumes that the information is in static ) != SQLITE_OK) { printf("\nCould not bind int.\n"); return 1; } } if (sqlite3_step(stmt) != SQLITE_DONE) { printf("\nCould not step (execute) stmt.\n"); return 1; } } } sqlite3_close(db); time_t time_sqlite = time(nullptr); std::cout << "Time to scan DICOM files: " << (time_scanner - time_start) << std::endl; std::cout << "Time to build SQLITE3: " << (time_sqlite - time_scanner) << std::endl; return 0; }