DBDriverSqlite3.cpp
Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without
00006 modification, are permitted provided that the following conditions are met:
00007     * Redistributions of source code must retain the above copyright
00008       notice, this list of conditions and the following disclaimer.
00009     * Redistributions in binary form must reproduce the above copyright
00010       notice, this list of conditions and the following disclaimer in the
00011       documentation and/or other materials provided with the distribution.
00012     * Neither the name of the Universite de Sherbrooke nor the
00013       names of its contributors may be used to endorse or promote products
00014       derived from this software without specific prior written permission.
00015 
00016 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00017 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00018 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00019 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
00020 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00021 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00022 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00023 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00024 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00025 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026 */
00027 
00028 #include "DBDriverSqlite3.h"
00029 
00030 #include "rtabmap/core/Signature.h"
00031 #include "VisualWord.h"
00032 #include "rtabmap/core/VWDictionary.h"
00033 #include "rtabmap/core/util3d.h"
00034 #include "DatabaseSchema_sql.h"
00035 #include <set>
00036 
00037 #include "rtabmap/utilite/UtiLite.h"
00038 
00039 namespace rtabmap {
00040 
00041 DBDriverSqlite3::DBDriverSqlite3(const ParametersMap & parameters) :
00042         DBDriver(parameters),
00043         _ppDb(0),
00044         _version("0.0.0"),
00045         _dbInMemory(Parameters::defaultDbSqlite3InMemory()),
00046         _cacheSize(Parameters::defaultDbSqlite3CacheSize()),
00047         _journalMode(Parameters::defaultDbSqlite3JournalMode()),
00048         _synchronous(Parameters::defaultDbSqlite3Synchronous()),
00049         _tempStore(Parameters::defaultDbSqlite3TempStore())
00050 {
00051         ULOGGER_DEBUG("treadSafe=%d", sqlite3_threadsafe());
00052         this->parseParameters(parameters);
00053 }
00054 
00055 DBDriverSqlite3::~DBDriverSqlite3()
00056 {
00057         this->closeConnection();
00058 }
00059 
00060 void DBDriverSqlite3::parseParameters(const ParametersMap & parameters)
00061 {
00062         ParametersMap::const_iterator iter;
00063         if((iter=parameters.find(Parameters::kDbSqlite3CacheSize())) != parameters.end())
00064         {
00065                 this->setCacheSize(std::atoi((*iter).second.c_str()));
00066         }
00067         if((iter=parameters.find(Parameters::kDbSqlite3JournalMode())) != parameters.end())
00068         {
00069                 this->setJournalMode(std::atoi((*iter).second.c_str()));
00070         }
00071         if((iter=parameters.find(Parameters::kDbSqlite3Synchronous())) != parameters.end())
00072         {
00073                 this->setSynchronous(std::atoi((*iter).second.c_str()));
00074         }
00075         if((iter=parameters.find(Parameters::kDbSqlite3TempStore())) != parameters.end())
00076         {
00077                 this->setTempStore(std::atoi((*iter).second.c_str()));
00078         }
00079         if((iter=parameters.find(Parameters::kDbSqlite3InMemory())) != parameters.end())
00080         {
00081                 this->setDbInMemory(uStr2Bool((*iter).second.c_str()));
00082         }
00083         DBDriver::parseParameters(parameters);
00084 }
00085 
00086 void DBDriverSqlite3::setCacheSize(unsigned int cacheSize)
00087 {
00088         if(this->isConnected())
00089         {
00090                 _cacheSize = cacheSize;
00091                 std::string query = "PRAGMA cache_size = ";
00092                 query += uNumber2Str(_cacheSize) + ";";
00093                 this->executeNoResultQuery(query.c_str());
00094         }
00095 }
00096 
00097 void DBDriverSqlite3::setJournalMode(int journalMode)
00098 {
00099         if(journalMode >= 0 && journalMode < 5)
00100         {
00101                 _journalMode = journalMode;
00102                 if(this->isConnected())
00103                 {
00104                         switch(_journalMode)
00105                         {
00106                         case 4:
00107                                 this->executeNoResultQuery("PRAGMA journal_mode = OFF;");
00108                                 break;
00109                         case 3:
00110                                 this->executeNoResultQuery("PRAGMA journal_mode = MEMORY;");
00111                                 break;
00112                         case 2:
00113                                 this->executeNoResultQuery("PRAGMA journal_mode = PERSIST;");
00114                                 break;
00115                         case 1:
00116                                 this->executeNoResultQuery("PRAGMA journal_mode = TRUNCATE;");
00117                                 break;
00118                         case 0:
00119                         default:
00120                                 this->executeNoResultQuery("PRAGMA journal_mode = DELETE;");
00121                                 break;
00122                         }
00123                 }
00124         }
00125         else
00126         {
00127                 ULOGGER_ERROR("Wrong journal mode (%d)", journalMode);
00128         }
00129 }
00130 
00131 void DBDriverSqlite3::setSynchronous(int synchronous)
00132 {
00133         if(synchronous >= 0 && synchronous < 3)
00134         {
00135                 _synchronous = synchronous;
00136                 if(this->isConnected())
00137                 {
00138                         switch(_synchronous)
00139                         {
00140                         case 0:
00141                                 this->executeNoResultQuery("PRAGMA synchronous = OFF;");
00142                                 break;
00143                         case 1:
00144                                 this->executeNoResultQuery("PRAGMA synchronous = NORMAL;");
00145                                 break;
00146                         case 2:
00147                         default:
00148                                 this->executeNoResultQuery("PRAGMA synchronous = FULL;");
00149                                 break;
00150                         }
00151                 }
00152         }
00153         else
00154         {
00155                 ULOGGER_ERROR("Wrong synchronous value (%d)", synchronous);
00156         }
00157 }
00158 
00159 void DBDriverSqlite3::setTempStore(int tempStore)
00160 {
00161         if(tempStore >= 0 && tempStore < 3)
00162         {
00163                 _tempStore = tempStore;
00164                 if(this->isConnected())
00165                 {
00166                         switch(_tempStore)
00167                         {
00168                         case 2:
00169                                 this->executeNoResultQuery("PRAGMA temp_store = MEMORY;");
00170                                 break;
00171                         case 1:
00172                                 this->executeNoResultQuery("PRAGMA temp_store = FILE;");
00173                                 break;
00174                         case 0:
00175                         default:
00176                                 this->executeNoResultQuery("PRAGMA temp_store = DEFAULT;");
00177                                 break;
00178                         }
00179                 }
00180         }
00181         else
00182         {
00183                 ULOGGER_ERROR("Wrong tempStore value (%d)", tempStore);
00184         }
00185 }
00186 
00187 void DBDriverSqlite3::setDbInMemory(bool dbInMemory)
00188 {
00189         if(dbInMemory != _dbInMemory)
00190         {
00191                 if(this->isConnected())
00192                 {
00193                         // Hard reset...
00194                         join(true);
00195                         this->emptyTrashes();
00196                         this->closeConnection();
00197                         _dbInMemory = dbInMemory;
00198                         this->openConnection(this->getUrl());
00199                 }
00200                 else
00201                 {
00202                         _dbInMemory = dbInMemory;
00203                 }
00204         }
00205 }
00206 
00207 /*
00208 ** This function is used to load the contents of a database file on disk
00209 ** into the "main" database of open database connection pInMemory, or
00210 ** to save the current contents of the database opened by pInMemory into
00211 ** a database file on disk. pInMemory is probably an in-memory database,
00212 ** but this function will also work fine if it is not.
00213 **
00214 ** Parameter zFilename points to a nul-terminated string containing the
00215 ** name of the database file on disk to load from or save to. If parameter
00216 ** isSave is non-zero, then the contents of the file zFilename are
00217 ** overwritten with the contents of the database opened by pInMemory. If
00218 ** parameter isSave is zero, then the contents of the database opened by
00219 ** pInMemory are replaced by data loaded from the file zFilename.
00220 **
00221 ** If the operation is successful, SQLITE_OK is returned. Otherwise, if
00222 ** an error occurs, an SQLite error code is returned.
00223 */
00224 int DBDriverSqlite3::loadOrSaveDb(sqlite3 *pInMemory, const std::string & fileName, int isSave) const
00225 {
00226   int rc;                   /* Function return code */
00227   sqlite3 *pFile = 0;           /* Database connection opened on zFilename */
00228   sqlite3_backup *pBackup = 0;  /* Backup object used to copy data */
00229   sqlite3 *pTo = 0;             /* Database to copy to (pFile or pInMemory) */
00230   sqlite3 *pFrom = 0;           /* Database to copy from (pFile or pInMemory) */
00231 
00232   /* Open the database file identified by zFilename. Exit early if this fails
00233   ** for any reason. */
00234   rc = sqlite3_open(fileName.c_str(), &pFile);
00235   if( rc==SQLITE_OK ){
00236 
00237     /* If this is a 'load' operation (isSave==0), then data is copied
00238     ** from the database file just opened to database pInMemory.
00239     ** Otherwise, if this is a 'save' operation (isSave==1), then data
00240     ** is copied from pInMemory to pFile.  Set the variables pFrom and
00241     ** pTo accordingly. */
00242     pFrom = (isSave ? pInMemory : pFile);
00243     pTo   = (isSave ? pFile     : pInMemory);
00244 
00245     /* Set up the backup procedure to copy from the "main" database of
00246     ** connection pFile to the main database of connection pInMemory.
00247     ** If something goes wrong, pBackup will be set to NULL and an error
00248     ** code and  message left in connection pTo.
00249     **
00250     ** If the backup object is successfully created, call backup_step()
00251     ** to copy data from pFile to pInMemory. Then call backup_finish()
00252     ** to release resources associated with the pBackup object.  If an
00253     ** error occurred, then  an error code and message will be left in
00254     ** connection pTo. If no error occurred, then the error code belonging
00255     ** to pTo is set to SQLITE_OK.
00256     */
00257     pBackup = sqlite3_backup_init(pTo, "main", pFrom, "main");
00258     if( pBackup ){
00259       (void)sqlite3_backup_step(pBackup, -1);
00260       (void)sqlite3_backup_finish(pBackup);
00261     }
00262     rc = sqlite3_errcode(pTo);
00263   }
00264 
00265   /* Close the database connection opened on database file zFilename
00266   ** and return the result of this function. */
00267   (void)sqlite3_close(pFile);
00268   return rc;
00269 }
00270 
00271 bool DBDriverSqlite3::getVersion(std::string & version) const
00272 {
00273         version = "0.0.0";
00274         if(_ppDb)
00275         {
00276                 UTimer timer;
00277                 timer.start();
00278                 int rc = SQLITE_OK;
00279                 sqlite3_stmt * ppStmt = 0;
00280                 std::stringstream query;
00281 
00282                 query << "SELECT version FROM Admin;";
00283 
00284                 rc = sqlite3_prepare_v2(_ppDb, query.str().c_str(), -1, &ppStmt, 0);
00285                 if(rc == SQLITE_OK)
00286                 {
00287                         // Process the result if one
00288                         rc = sqlite3_step(ppStmt);
00289                         if(rc == SQLITE_ROW)
00290                         {
00291                                 version = reinterpret_cast<const char*>(sqlite3_column_text(ppStmt, 0));
00292                                 rc = sqlite3_step(ppStmt);
00293                         }
00294                         UASSERT_MSG(rc == SQLITE_DONE, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
00295 
00296                         // Finalize (delete) the statement
00297                         rc = sqlite3_finalize(ppStmt);
00298                         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
00299                 }
00300                 //else
00301                 //{
00302                         // old version detected
00303                 //}
00304                 return true;
00305         }
00306         return false;
00307 }
00308 
00309 
00310 bool DBDriverSqlite3::connectDatabaseQuery(const std::string & url, bool overwritten)
00311 {
00312         this->disconnectDatabaseQuery();
00313         // Open a database connection
00314         _ppDb = 0;
00315 
00316         if(url.empty())
00317         {
00318                 UERROR("url is empty...");
00319                 return false;
00320         }
00321 
00322         int rc = SQLITE_OK;
00323         bool dbFileExist = UFile::exists(url.c_str());
00324         if(dbFileExist && overwritten)
00325         {
00326                 UINFO("Deleting database %s...", url.c_str());
00327                 UASSERT(UFile::erase(url.c_str()) == 0);
00328                 dbFileExist = false;
00329         }
00330 
00331         if(_dbInMemory)
00332         {
00333                 ULOGGER_INFO("Using database \"%s\" in the memory.", url.c_str());
00334                 rc = sqlite3_open_v2(":memory:", &_ppDb, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
00335         }
00336         else
00337         {
00338                 ULOGGER_INFO("Using database \"%s\" from the hard drive.", url.c_str());
00339                 rc = sqlite3_open_v2(url.c_str(), &_ppDb, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
00340         }
00341         if(rc != SQLITE_OK)
00342         {
00343                 UFATAL("DB error : %s (path=\"%s\")", sqlite3_errmsg(_ppDb), url.c_str());
00344                 _ppDb = 0;
00345                 return false;
00346         }
00347 
00348         if(_dbInMemory && dbFileExist)
00349         {
00350                 UTimer timer;
00351                 timer.start();
00352                 ULOGGER_DEBUG("Loading DB ...");
00353                 rc = loadOrSaveDb(_ppDb, url, 0); // Load memory from file
00354                 ULOGGER_INFO("Loading DB time = %fs, (%s)", timer.ticks(), url.c_str());
00355                 if(rc != SQLITE_OK)
00356                 {
00357                         UFATAL("DB error 2 : %s", sqlite3_errmsg(_ppDb));
00358                         sqlite3_close(_ppDb);
00359                         _ppDb = 0;
00360                         return false;
00361                 }
00362         }
00363 
00364         if(!dbFileExist)
00365         {
00366                 ULOGGER_INFO("Database \"%s\" doesn't exist, creating a new one...", url.c_str());
00367                 // Create the database
00368                 std::string schema = DATABASESCHEMA_SQL;
00369                 schema = uHex2Str(schema);
00370                 this->executeNoResultQuery(schema.c_str());
00371         }
00372         UASSERT(this->getVersion(_version)); // must be true!
00373         UINFO("Database version = %s", _version.c_str());
00374 
00375         //Set database optimizations
00376         this->setCacheSize(_cacheSize); // this will call the SQL
00377         this->setJournalMode(_journalMode); // this will call the SQL
00378         this->setSynchronous(_synchronous); // this will call the SQL
00379         this->setTempStore(_tempStore); // this will call the SQL
00380 
00381         return true;
00382 }
00383 void DBDriverSqlite3::disconnectDatabaseQuery()
00384 {
00385         UDEBUG("");
00386         if(_ppDb)
00387         {
00388                 int rc = SQLITE_OK;
00389                 // make sure that all statements are finalized
00390                 sqlite3_stmt * pStmt;
00391                 while( (pStmt = sqlite3_next_stmt(_ppDb, 0))!=0 )
00392                 {
00393                         rc = sqlite3_finalize(pStmt);
00394                         if(rc != SQLITE_OK)
00395                         {
00396                                 UERROR("");
00397                         }
00398                 }
00399 
00400                 if(_dbInMemory)
00401                 {
00402                         UTimer timer;
00403                         timer.start();
00404                         UINFO("Saving database to %s ...",  this->getUrl().c_str());
00405                         rc = loadOrSaveDb(_ppDb, this->getUrl(), 1); // Save memory to file
00406                         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
00407                         ULOGGER_DEBUG("Saving DB time = %fs", timer.ticks());
00408                 }
00409 
00410                 // Then close (delete) the database connection
00411                 UINFO("Disconnecting database %s...", this->getUrl().c_str());
00412                 sqlite3_close(_ppDb);
00413                 _ppDb = 0;
00414         }
00415 }
00416 
00417 bool DBDriverSqlite3::isConnectedQuery() const
00418 {
00419         return _ppDb != 0;
00420 }
00421 
00422 // In bytes
00423 void DBDriverSqlite3::executeNoResultQuery(const std::string & sql) const
00424 {
00425         if(_ppDb)
00426         {
00427                 UTimer timer;
00428                 timer.start();
00429                 int rc;
00430                 rc = sqlite3_exec(_ppDb, sql.c_str(), 0, 0, 0);
00431                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s, the query is %s", sqlite3_errmsg(_ppDb), sql.c_str()).c_str());
00432                 UDEBUG("Time=%fs", timer.ticks());
00433         }
00434 }
00435 
00436 long DBDriverSqlite3::getMemoryUsedQuery() const
00437 {
00438         if(_dbInMemory)
00439         {
00440                 return sqlite3_memory_used();
00441         }
00442         else
00443         {
00444                 return UFile::length(this->getUrl());
00445         }
00446 }
00447 
00448 void DBDriverSqlite3::loadNodeDataQuery(std::list<Signature *> & signatures, bool loadMetricData) const
00449 {
00450         UDEBUG("load data (metric=%s) for %d signatures", loadMetricData?"true":"false", (int)signatures.size());
00451         if(_ppDb)
00452         {
00453                 UTimer timer;
00454                 timer.start();
00455                 int rc = SQLITE_OK;
00456                 sqlite3_stmt * ppStmt = 0;
00457                 std::stringstream query;
00458 
00459                 if(loadMetricData)
00460                 {
00461                         if(uStrNumCmp(_version, "0.8.11") >= 0)
00462                         {
00463                                 query << "SELECT Image.data, "
00464                                                  "Depth.data, Depth.fx, Depth.fy, Depth.cx, Depth.cy, Depth.local_transform, Depth.data2d_max_pts, Depth.data2d "
00465                                           << "FROM Image "
00466                                           << "LEFT OUTER JOIN Depth " // returns all images even if there are no metric data
00467                                           << "ON Image.id = Depth.id "
00468                                           << "WHERE Image.id = ?"
00469                                           <<";";
00470                         }
00471                         else if(uStrNumCmp(_version, "0.7.0") >= 0)
00472                         {
00473                                 query << "SELECT Image.data, "
00474                                                  "Depth.data, Depth.fx, Depth.fy, Depth.cx, Depth.cy, Depth.local_transform, Depth.data2d "
00475                                           << "FROM Image "
00476                                           << "LEFT OUTER JOIN Depth " // returns all images even if there are no metric data
00477                                           << "ON Image.id = Depth.id "
00478                                           << "WHERE Image.id = ?"
00479                                           <<";";
00480                         }
00481                         else
00482                         {
00483                                 query << "SELECT Image.data, "
00484                                                  "Depth.data, Depth.constant, Depth.local_transform, Depth.data2d "
00485                                           << "FROM Image "
00486                                           << "LEFT OUTER JOIN Depth " // returns all images even if there are no metric data
00487                                           << "ON Image.id = Depth.id "
00488                                           << "WHERE Image.id = ?"
00489                                           <<";";
00490                         }
00491                 }
00492                 else
00493                 {
00494                         query << "SELECT data "
00495                                   << "FROM Image "
00496                                   << "WHERE id = ?"
00497                                   <<";";
00498                 }
00499 
00500                 rc = sqlite3_prepare_v2(_ppDb, query.str().c_str(), -1, &ppStmt, 0);
00501                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
00502 
00503                 const void * data = 0;
00504                 int dataSize = 0;
00505                 int index = 0;
00506 
00507                 for(std::list<Signature*>::iterator iter = signatures.begin(); iter!=signatures.end(); ++iter)
00508                 {
00509                         UASSERT(*iter != 0);
00510 
00511                         ULOGGER_DEBUG("Loading data for %d...", (*iter)->id());
00512                         // bind id
00513                         rc = sqlite3_bind_int(ppStmt, 1, (*iter)->id());
00514                         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
00515 
00516                         // Process the result if one
00517                         rc = sqlite3_step(ppStmt);
00518                         if(rc == SQLITE_ROW)
00519                         {
00520                                 index = 0;
00521 
00522                                 data = sqlite3_column_blob(ppStmt, index);
00523                                 dataSize = sqlite3_column_bytes(ppStmt, index++);
00524 
00525                                 //Create the image
00526                                 if(dataSize>4 && data)
00527                                 {
00528                                         (*iter)->setImageCompressed(cv::Mat(1, dataSize, CV_8UC1, (void *)data).clone());
00529                                 }
00530 
00531                                 if(loadMetricData)
00532                                 {
00533                                         data = sqlite3_column_blob(ppStmt, index);
00534                                         dataSize = sqlite3_column_bytes(ppStmt, index++);
00535 
00536                                         //Create the depth image
00537                                         cv::Mat depthCompressed;
00538                                         if(dataSize>4 && data)
00539                                         {
00540                                                 depthCompressed = cv::Mat(1, dataSize, CV_8UC1, (void *)data).clone();
00541                                         }
00542 
00543                                         if(uStrNumCmp(_version, "0.7.0") < 0)
00544                                         {
00545                                                 float depthConstant = sqlite3_column_double(ppStmt, index++);
00546                                                 (*iter)->setDepthCompressed(depthCompressed, 1.0f/depthConstant, 1.0f/depthConstant, 0, 0);
00547                                         }
00548                                         else
00549                                         {
00550                                                 float fx = sqlite3_column_double(ppStmt, index++);
00551                                                 float fy = sqlite3_column_double(ppStmt, index++);
00552                                                 float cx = sqlite3_column_double(ppStmt, index++);
00553                                                 float cy = sqlite3_column_double(ppStmt, index++);
00554                                                 (*iter)->setDepthCompressed(depthCompressed, fx, fy, cx, cy);
00555                                         }
00556 
00557                                         data = sqlite3_column_blob(ppStmt, index); // local transform
00558                                         dataSize = sqlite3_column_bytes(ppStmt, index++);
00559                                         Transform localTransform;
00560                                         if((unsigned int)dataSize == localTransform.size()*sizeof(float) && data)
00561                                         {
00562                                                 memcpy(localTransform.data(), data, dataSize);
00563                                         }
00564                                         (*iter)->setLocalTransform(localTransform);
00565 
00566                                         int laserScanMaxPts = 0;
00567                                         if(uStrNumCmp(_version, "0.8.11") >= 0)
00568                                         {
00569                                                 laserScanMaxPts = sqlite3_column_int(ppStmt, index++);
00570                                         }
00571 
00572                                         data = sqlite3_column_blob(ppStmt, index);
00573                                         dataSize = sqlite3_column_bytes(ppStmt, index++);
00574                                         //Create the laserScan
00575                                         if(dataSize>4 && data)
00576                                         {
00577                                                 (*iter)->setLaserScanCompressed(cv::Mat(1, dataSize, CV_8UC1, (void *)data).clone(), laserScanMaxPts); // depth2d
00578                                         }
00579                                 }
00580 
00581                                 rc = sqlite3_step(ppStmt); // next result...
00582                         }
00583                         UASSERT_MSG(rc == SQLITE_DONE, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
00584 
00585                         //reset
00586                         rc = sqlite3_reset(ppStmt);
00587                         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
00588                 }
00589 
00590                 // Finalize (delete) the statement
00591                 rc = sqlite3_finalize(ppStmt);
00592                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
00593                 ULOGGER_DEBUG("Time=%fs", timer.ticks());
00594         }
00595 }
00596 
00597 void DBDriverSqlite3::getNodeDataQuery(
00598                 int signatureId,
00599                 cv::Mat & imageCompressed,
00600                 cv::Mat & depthCompressed,
00601                 cv::Mat & laserScanCompressed,
00602                 float & fx,
00603                 float & fy,
00604                 float & cx,
00605                 float & cy,
00606                 Transform & localTransform,
00607                 int & laserScanMaxPts) const
00608 {
00609         if(_ppDb)
00610         {
00611                 UTimer timer;
00612                 timer.start();
00613                 int rc = SQLITE_OK;
00614                 sqlite3_stmt * ppStmt = 0;
00615                 std::stringstream query;
00616 
00617                 if(uStrNumCmp(_version, "0.8.11") >= 0)
00618                 {
00619                         query << "SELECT Image.data, "
00620                                          "Depth.data, Depth.fx, Depth.fy, Depth.cx, Depth.cy, Depth.local_transform, Depth.data2d_max_pts, Depth.data2d "
00621                                   << "FROM Image "
00622                                   << "LEFT OUTER JOIN Depth " // returns all images even if there are no metric data
00623                                   << "ON Image.id = Depth.id "
00624                                   << "WHERE Image.id = " << signatureId
00625                                   <<";";
00626                 }
00627                 else if(uStrNumCmp(_version, "0.7.0") >= 0)
00628                 {
00629                         query << "SELECT Image.data, "
00630                                          "Depth.data, Depth.fx, Depth.fy, Depth.cx, Depth.cy, Depth.local_transform, Depth.data2d "
00631                                   << "FROM Image "
00632                                   << "LEFT OUTER JOIN Depth " // returns all images even if there are no metric data
00633                                   << "ON Image.id = Depth.id "
00634                                   << "WHERE Image.id = " << signatureId
00635                                   <<";";
00636                 }
00637                 else
00638                 {
00639                         query << "SELECT Image.data, "
00640                                          "Depth.data, Depth.constant, Depth.local_transform, Depth.data2d "
00641                                   << "FROM Image "
00642                                   << "LEFT OUTER JOIN Depth " // returns all images even if there are no metric data
00643                                   << "ON Image.id = Depth.id "
00644                                   << "WHERE Image.id = " << signatureId
00645                                   <<";";
00646                 }
00647 
00648                 rc = sqlite3_prepare_v2(_ppDb, query.str().c_str(), -1, &ppStmt, 0);
00649                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
00650 
00651                 const void * data = 0;
00652                 int dataSize = 0;
00653                 int index = 0;;
00654 
00655                 ULOGGER_DEBUG("Loading data for %d...", signatureId);
00656 
00657                 // Process the result if one
00658                 rc = sqlite3_step(ppStmt);
00659                 if(rc == SQLITE_ROW)
00660                 {
00661                         index = 0;
00662 
00663                         data = sqlite3_column_blob(ppStmt, index);
00664                         dataSize = sqlite3_column_bytes(ppStmt, index++);
00665 
00666                         //Create the image
00667                         if(dataSize>4 && data)
00668                         {
00669                                 imageCompressed = cv::Mat(1, dataSize, CV_8UC1, (void *)data).clone();
00670                         }
00671 
00672                         data = sqlite3_column_blob(ppStmt, index);
00673                         dataSize = sqlite3_column_bytes(ppStmt, index++);
00674 
00675                         //Create the depth image
00676                         if(dataSize>4 && data)
00677                         {
00678                                 depthCompressed = cv::Mat(1, dataSize, CV_8UC1, (void *)data).clone();
00679                         }
00680 
00681                         if(uStrNumCmp(_version, "0.7.0") < 0)
00682                         {
00683                                 float depthConstant = sqlite3_column_double(ppStmt, index++);
00684                                 fx = 1.0f/depthConstant;
00685                                 fy = 1.0f/depthConstant;
00686                                 cx = 0.0f;
00687                                 cy = 0.0f;
00688                         }
00689                         else
00690                         {
00691                                 fx = sqlite3_column_double(ppStmt, index++);
00692                                 fy = sqlite3_column_double(ppStmt, index++);
00693                                 cx = sqlite3_column_double(ppStmt, index++);
00694                                 cy = sqlite3_column_double(ppStmt, index++);
00695                         }
00696 
00697                         data = sqlite3_column_blob(ppStmt, index); // local transform
00698                         dataSize = sqlite3_column_bytes(ppStmt, index++);
00699                         if((unsigned int)dataSize == localTransform.size()*sizeof(float) && data)
00700                         {
00701                                 memcpy(localTransform.data(), data, dataSize);
00702                         }
00703 
00704                         laserScanMaxPts = 0;
00705                         if(uStrNumCmp(_version, "0.8.11") >= 0)
00706                         {
00707                                 laserScanMaxPts = sqlite3_column_int(ppStmt, index++);
00708                         }
00709 
00710                         data = sqlite3_column_blob(ppStmt, index); // depth2d
00711                         dataSize = sqlite3_column_bytes(ppStmt, index++);
00712                         //Create the depth2d
00713                         if(dataSize>4 && data)
00714                         {
00715                                 laserScanCompressed = cv::Mat(1, dataSize, CV_8UC1, (void *)data).clone();
00716                         }
00717 
00718                         if(depthCompressed.empty() || fx <= 0 || fy <= 0 || cx < 0 || cy < 0)
00719                         {
00720                                 UWARN("No metric data loaded!? Consider using getNodeDataQuery() with image only.");
00721                         }
00722 
00723                         rc = sqlite3_step(ppStmt); // next result...
00724                 }
00725                 UASSERT_MSG(rc == SQLITE_DONE, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
00726 
00727 
00728                 // Finalize (delete) the statement
00729                 rc = sqlite3_finalize(ppStmt);
00730                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
00731                 ULOGGER_DEBUG("Time=%fs", timer.ticks());
00732         }
00733 }
00734 
00735 void DBDriverSqlite3::getNodeDataQuery(int signatureId, cv::Mat & imageCompressed) const
00736 {
00737         if(_ppDb)
00738         {
00739                 UTimer timer;
00740                 timer.start();
00741                 int rc = SQLITE_OK;
00742                 sqlite3_stmt * ppStmt = 0;
00743                 std::stringstream query;
00744 
00745                 query << "SELECT data "
00746                           << "FROM Image "
00747                           << "WHERE id = " << signatureId
00748                           <<";";
00749 
00750                 rc = sqlite3_prepare_v2(_ppDb, query.str().c_str(), -1, &ppStmt, 0);
00751                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
00752 
00753                 const void * data = 0;
00754                 int dataSize = 0;
00755                 int index = 0;;
00756 
00757                 ULOGGER_DEBUG("Loading data for %d...", signatureId);
00758 
00759                 // Process the result if one
00760                 rc = sqlite3_step(ppStmt);
00761                 if(rc == SQLITE_ROW)
00762                 {
00763                         index = 0;
00764 
00765                         data = sqlite3_column_blob(ppStmt, index);
00766                         dataSize = sqlite3_column_bytes(ppStmt, index++);
00767 
00768                         //Create the image
00769                         if(dataSize>4 && data)
00770                         {
00771                                 imageCompressed = cv::Mat(1, dataSize, CV_8UC1, (void *)data).clone();
00772                         }
00773 
00774                         rc = sqlite3_step(ppStmt); // next result...
00775                 }
00776                 UASSERT_MSG(rc == SQLITE_DONE, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
00777 
00778 
00779                 // Finalize (delete) the statement
00780                 rc = sqlite3_finalize(ppStmt);
00781                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
00782                 ULOGGER_DEBUG("Time=%fs", timer.ticks());
00783         }
00784 }
00785 
00786 bool DBDriverSqlite3::getNodeInfoQuery(int signatureId,
00787                 Transform & pose,
00788                 int & mapId,
00789                 int & weight,
00790                 std::string & label,
00791                 double & stamp,
00792                 std::vector<unsigned char> & userData) const
00793 {
00794         bool found = false;
00795         if(_ppDb && signatureId)
00796         {
00797                 int rc = SQLITE_OK;
00798                 sqlite3_stmt * ppStmt = 0;
00799                 std::stringstream query;
00800 
00801                 // Prepare the query... Get the map from signature and visual words
00802                 if(uStrNumCmp(_version, "0.8.8") >= 0)
00803                 {
00804                         query << "SELECT pose, map_id, weight, label, stamp, user_data "
00805                                          "FROM Node "
00806                                          "WHERE id = " << signatureId <<
00807                                          ";";
00808                 }
00809                 else if(uStrNumCmp(_version, "0.8.5") >= 0)
00810                 {
00811                         query << "SELECT pose, map_id, weight, label, stamp "
00812                                          "FROM Node "
00813                                          "WHERE id = " << signatureId <<
00814                                          ";";
00815                 }
00816                 else
00817                 {
00818                         query << "SELECT pose, map_id, weight "
00819                                          "FROM Node "
00820                                          "WHERE id = " << signatureId <<
00821                                          ";";
00822                 }
00823 
00824                 rc = sqlite3_prepare_v2(_ppDb, query.str().c_str(), -1, &ppStmt, 0);
00825                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
00826 
00827                 const void * data = 0;
00828                 int dataSize = 0;
00829 
00830                 // Process the result if one
00831                 rc = sqlite3_step(ppStmt);
00832                 if(rc == SQLITE_ROW)
00833                 {
00834                         found = true;
00835                         int index = 0;
00836                         data = sqlite3_column_blob(ppStmt, index); // pose
00837                         dataSize = sqlite3_column_bytes(ppStmt, index++);
00838                         if((unsigned int)dataSize == pose.size()*sizeof(float) && data)
00839                         {
00840                                 memcpy(pose.data(), data, dataSize);
00841                         }
00842 
00843                         mapId = sqlite3_column_int(ppStmt, index++); // map id
00844                         weight = sqlite3_column_int(ppStmt, index++); // weight
00845 
00846                         if(uStrNumCmp(_version, "0.8.5") >= 0)
00847                         {
00848                                 const unsigned char * p = sqlite3_column_text(ppStmt, index++);
00849                                 if(p)
00850                                 {
00851                                         label = reinterpret_cast<const char*>(p); // label
00852                                 }
00853                                 stamp = sqlite3_column_double(ppStmt, index++); // stamp
00854                         }
00855 
00856                         if(uStrNumCmp(_version, "0.8.8") >= 0)
00857                         {
00858                                 data = sqlite3_column_blob(ppStmt, index);
00859                                 dataSize = sqlite3_column_bytes(ppStmt, index++); // user_data
00860 
00861                                 if(dataSize && data)
00862                                 {
00863                                         userData.resize(dataSize);
00864                                         memcpy(userData.data(), data, dataSize);
00865                                 }
00866                         }
00867 
00868                         rc = sqlite3_step(ppStmt); // next result...
00869                 }
00870                 UASSERT_MSG(rc == SQLITE_DONE, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
00871 
00872                 // Finalize (delete) the statement
00873                 rc = sqlite3_finalize(ppStmt);
00874                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
00875         }
00876         return found;
00877 }
00878 
00879 
00880 void DBDriverSqlite3::getAllNodeIdsQuery(std::set<int> & ids, bool ignoreChildren) const
00881 {
00882         if(_ppDb)
00883         {
00884                 UTimer timer;
00885                 timer.start();
00886                 int rc = SQLITE_OK;
00887                 sqlite3_stmt * ppStmt = 0;
00888                 std::stringstream query;
00889 
00890                 if(!ignoreChildren)
00891                 {
00892                         query << "SELECT id "
00893                                   << "FROM Node "
00894                                   << "ORDER BY id";
00895                 }
00896                 else
00897                 {
00898                         query << "SELECT id "
00899                                   << "FROM Node "
00900                                   << "INNER JOIN Link "
00901                                   << "ON id = to_id " // use to_id tp ignore all children (which don't have link pointing on them)
00902                                   << "ORDER BY id";
00903                 }
00904 
00905                 rc = sqlite3_prepare_v2(_ppDb, query.str().c_str(), -1, &ppStmt, 0);
00906                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
00907 
00908 
00909                 // Process the result if one
00910                 rc = sqlite3_step(ppStmt);
00911                 while(rc == SQLITE_ROW)
00912                 {
00913                         ids.insert(ids.end(), sqlite3_column_int(ppStmt, 0)); // Signature Id
00914                         rc = sqlite3_step(ppStmt);
00915                 }
00916                 UASSERT_MSG(rc == SQLITE_DONE, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
00917 
00918                 // Finalize (delete) the statement
00919                 rc = sqlite3_finalize(ppStmt);
00920                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
00921                 ULOGGER_DEBUG("Time=%f ids=%d", timer.ticks(), (int)ids.size());
00922         }
00923 }
00924 
00925 void DBDriverSqlite3::getLastIdQuery(const std::string & tableName, int & id) const
00926 {
00927         if(_ppDb)
00928         {
00929                 UDEBUG("get last id from table \"%s\"", tableName.c_str());
00930                 UTimer timer;
00931                 timer.start();
00932                 int rc = SQLITE_OK;
00933                 sqlite3_stmt * ppStmt = 0;
00934                 std::stringstream query;
00935 
00936                 query << "SELECT max(id) "
00937                           << "FROM " << tableName
00938                           << ";";
00939 
00940                 rc = sqlite3_prepare_v2(_ppDb, query.str().c_str(), -1, &ppStmt, 0);
00941                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
00942 
00943 
00944                 // Process the result if one
00945                 rc = sqlite3_step(ppStmt);
00946                 if(rc == SQLITE_ROW)
00947                 {
00948                         id = sqlite3_column_int(ppStmt, 0); // Signature Id
00949                         rc = sqlite3_step(ppStmt);
00950                         UASSERT_MSG(rc == SQLITE_DONE, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
00951                 }
00952                 else
00953                 {
00954                         ULOGGER_ERROR("No result !?! from the DB");
00955                 }
00956 
00957                 // Finalize (delete) the statement
00958                 rc = sqlite3_finalize(ppStmt);
00959                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
00960                 ULOGGER_DEBUG("Time=%fs", timer.ticks());
00961         }
00962 }
00963 
00964 void DBDriverSqlite3::getInvertedIndexNiQuery(int nodeId, int & ni) const
00965 {
00966         ni = 0;
00967         if(_ppDb)
00968         {
00969                 UTimer timer;
00970                 timer.start();
00971                 int rc = SQLITE_OK;
00972                 sqlite3_stmt * ppStmt = 0;
00973                 std::stringstream query;
00974 
00975                 // Create a new entry in table Signature
00976                 query << "SELECT count(word_id) "
00977                           << "FROM Map_Node_Word "
00978                           << "WHERE node_id=" << nodeId << ";";
00979 
00980                 //query.append("COMMIT;");
00981 
00982                 //ULOGGER_DEBUG("DBDriverSqlite3::getSurfNi() Execute query : %s", query.toStdString().c_str());
00983 
00984                 rc = sqlite3_prepare_v2(_ppDb, query.str().c_str(), -1, &ppStmt, 0);
00985                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
00986 
00987 
00988                 // Process the result if one
00989                 rc = sqlite3_step(ppStmt);
00990                 if(rc == SQLITE_ROW)
00991                 {
00992                         ni = sqlite3_column_int(ppStmt, 0);
00993                         rc = sqlite3_step(ppStmt);
00994                         UASSERT_MSG(rc == SQLITE_DONE, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
00995                 }
00996                 else
00997                 {
00998                         ULOGGER_ERROR("No result !?! from the DB, node=%d",nodeId);
00999                 }
01000 
01001 
01002                 // Finalize (delete) the statement
01003                 rc = sqlite3_finalize(ppStmt);
01004                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01005                 ULOGGER_DEBUG("Time=%fs", timer.ticks());
01006         }
01007 }
01008 
01009 void DBDriverSqlite3::getNodeIdByLabelQuery(const std::string & label, int & id) const
01010 {
01011         if(_ppDb && !label.empty() && uStrNumCmp(_version, "0.8.5") >= 0)
01012         {
01013                 UTimer timer;
01014                 timer.start();
01015                 int rc = SQLITE_OK;
01016                 sqlite3_stmt * ppStmt = 0;
01017                 std::stringstream query;
01018                 query << "SELECT id FROM Node WHERE label='" << label <<"'";
01019 
01020                 rc = sqlite3_prepare_v2(_ppDb, query.str().c_str(), -1, &ppStmt, 0);
01021                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01022 
01023                 // Process the result if one
01024                 rc = sqlite3_step(ppStmt);
01025                 if(rc == SQLITE_ROW)
01026                 {
01027                         id = sqlite3_column_int(ppStmt, 0);
01028                         rc = sqlite3_step(ppStmt);
01029                 }
01030                 UASSERT_MSG(rc == SQLITE_DONE, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01031 
01032                 // Finalize (delete) the statement
01033                 rc = sqlite3_finalize(ppStmt);
01034                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01035                 ULOGGER_DEBUG("Time=%f", timer.ticks());
01036         }
01037 }
01038 
01039 void DBDriverSqlite3::getAllLabelsQuery(std::map<int, std::string> & labels) const
01040 {
01041         if(_ppDb && uStrNumCmp(_version, "0.8.5") >= 0)
01042         {
01043                 UTimer timer;
01044                 timer.start();
01045                 int rc = SQLITE_OK;
01046                 sqlite3_stmt * ppStmt = 0;
01047                 std::stringstream query;
01048                 query << "SELECT id,label FROM Node WHERE label IS NOT NULL";
01049 
01050                 rc = sqlite3_prepare_v2(_ppDb, query.str().c_str(), -1, &ppStmt, 0);
01051                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01052 
01053                 // Process the result if one
01054                 rc = sqlite3_step(ppStmt);
01055                 while(rc == SQLITE_ROW)
01056                 {
01057                         int index = 0;
01058                         int id = sqlite3_column_int(ppStmt, index++);
01059                         const unsigned char * p = sqlite3_column_text(ppStmt, index++);
01060                         if(p)
01061                         {
01062                                 std::string label = reinterpret_cast<const char*>(p);
01063                                 if(!label.empty())
01064                                 {
01065                                         labels.insert(std::make_pair(id, label));
01066                                 }
01067                         }
01068                         rc = sqlite3_step(ppStmt);
01069                 }
01070                 UASSERT_MSG(rc == SQLITE_DONE, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01071 
01072                 // Finalize (delete) the statement
01073                 rc = sqlite3_finalize(ppStmt);
01074                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01075                 ULOGGER_DEBUG("Time=%f", timer.ticks());
01076         }
01077 }
01078 
01079 void DBDriverSqlite3::getWeightQuery(int nodeId, int & weight) const
01080 {
01081         weight = 0;
01082         if(_ppDb)
01083         {
01084                 UTimer timer;
01085                 timer.start();
01086                 int rc = SQLITE_OK;
01087                 sqlite3_stmt * ppStmt = 0;
01088                 std::stringstream query;
01089 
01090                 query << "SELECT weight FROM node WHERE id =  "
01091                           << nodeId
01092                           << ";";
01093 
01094                 rc = sqlite3_prepare_v2(_ppDb, query.str().c_str(), -1, &ppStmt, 0);
01095                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01096 
01097 
01098                 // Process the result if one
01099                 rc = sqlite3_step(ppStmt);
01100                 if(rc == SQLITE_ROW)
01101                 {
01102                         weight= sqlite3_column_int(ppStmt, 0); // weight
01103                         rc = sqlite3_step(ppStmt);
01104                 }
01105                 UASSERT_MSG(rc == SQLITE_DONE, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01106 
01107                 // Finalize (delete) the statement
01108                 rc = sqlite3_finalize(ppStmt);
01109                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01110         }
01111 }
01112 
01113 //may be slower than the previous version but don't have a limit of words that can be loaded at the same time
01114 void DBDriverSqlite3::loadSignaturesQuery(const std::list<int> & ids, std::list<Signature *> & nodes) const
01115 {
01116         ULOGGER_DEBUG("count=%d", (int)ids.size());
01117         if(_ppDb && ids.size())
01118         {
01119                 std::string type;
01120                 UTimer timer;
01121                 timer.start();
01122                 int rc = SQLITE_OK;
01123                 sqlite3_stmt * ppStmt = 0;
01124                 std::stringstream query;
01125                 unsigned int loaded = 0;
01126 
01127                 // Load nodes information
01128                 if(uStrNumCmp(_version, "0.8.8") >= 0)
01129                 {
01130                         query << "SELECT id, map_id, weight, pose, stamp, label, user_data "
01131                                   << "FROM Node "
01132                                   << "WHERE id=?;";
01133                 }
01134                 else if(uStrNumCmp(_version, "0.8.5") >= 0)
01135                 {
01136                         query << "SELECT id, map_id, weight, pose, stamp, label "
01137                                   << "FROM Node "
01138                                   << "WHERE id=?;";
01139                 }
01140                 else
01141                 {
01142                         query << "SELECT id, map_id, weight, pose "
01143                                   << "FROM Node "
01144                                   << "WHERE id=?;";
01145                 }
01146 
01147                 rc = sqlite3_prepare_v2(_ppDb, query.str().c_str(), -1, &ppStmt, 0);
01148                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01149 
01150                 for(std::list<int>::const_iterator iter=ids.begin(); iter!=ids.end(); ++iter)
01151                 {
01152                         //ULOGGER_DEBUG("Loading node %d...", *iter);
01153                         // bind id
01154                         rc = sqlite3_bind_int(ppStmt, 1, *iter);
01155                         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01156 
01157                         int id = 0;
01158                         int mapId = 0;
01159                         double stamp = 0.0;
01160                         int weight = 0;
01161                         Transform pose;
01162                         const void * data = 0;
01163                         int dataSize = 0;
01164                         std::string label;
01165                         std::vector<unsigned char> userData;
01166 
01167                         // Process the result if one
01168                         rc = sqlite3_step(ppStmt);
01169                         if(rc == SQLITE_ROW)
01170                         {
01171                                 int index = 0;
01172                                 id = sqlite3_column_int(ppStmt, index++); // Signature Id
01173                                 mapId = sqlite3_column_int(ppStmt, index++); // Map Id
01174                                 weight = sqlite3_column_int(ppStmt, index++); // weight
01175 
01176                                 data = sqlite3_column_blob(ppStmt, index); // pose
01177                                 dataSize = sqlite3_column_bytes(ppStmt, index++);
01178                                 if((unsigned int)dataSize == pose.size()*sizeof(float) && data)
01179                                 {
01180                                         memcpy(pose.data(), data, dataSize);
01181                                 }
01182 
01183                                 if(uStrNumCmp(_version, "0.8.5") >= 0)
01184                                 {
01185                                         stamp = sqlite3_column_double(ppStmt, index++); // stamp
01186                                         const unsigned char * p = sqlite3_column_text(ppStmt, index++); // label
01187                                         if(p)
01188                                         {
01189                                                 label = reinterpret_cast<const char*>(p);
01190                                         }
01191                                 }
01192 
01193                                 if(uStrNumCmp(_version, "0.8.8") >= 0)
01194                                 {
01195                                         data = sqlite3_column_blob(ppStmt, index);
01196                                         dataSize = sqlite3_column_bytes(ppStmt, index++); // user_data
01197 
01198                                         if(dataSize && data)
01199                                         {
01200                                                 userData.resize(dataSize);
01201                                                 memcpy(userData.data(), data, dataSize);
01202                                         }
01203                                 }
01204 
01205                                 rc = sqlite3_step(ppStmt);
01206                         }
01207                         UASSERT_MSG(rc == SQLITE_DONE, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01208 
01209                         // create the node
01210                         if(id)
01211                         {
01212                                 ULOGGER_DEBUG("Creating %d (map=%d, pose=%s)", *iter, mapId, pose.prettyPrint().c_str());
01213                                 Signature * s = new Signature(
01214                                                 id,
01215                                                 mapId,
01216                                                 weight,
01217                                                 stamp,
01218                                                 label,
01219                                                 std::multimap<int, cv::KeyPoint>(),
01220                                                 std::multimap<int, pcl::PointXYZ>(),
01221                                                 pose,
01222                                                 userData);
01223                                 s->setSaved(true);
01224                                 nodes.push_back(s);
01225                                 ++loaded;
01226                         }
01227                         else
01228                         {
01229                                 UERROR("Signature %d not found in database!", *iter);
01230                         }
01231 
01232                         //reset
01233                         rc = sqlite3_reset(ppStmt);
01234                         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01235                 }
01236 
01237                 // Finalize (delete) the statement
01238                 rc = sqlite3_finalize(ppStmt);
01239                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01240 
01241                 ULOGGER_DEBUG("Time=%fs", timer.ticks());
01242 
01243                 // Prepare the query... Get the map from signature and visual words
01244                 std::stringstream query2;
01245                 query2 << "SELECT word_id, pos_x, pos_y, size, dir, response, depth_x, depth_y, depth_z "
01246                                  "FROM Map_Node_Word "
01247                                  "WHERE node_id = ? ";
01248 
01249                 query2 << " ORDER BY word_id"; // Needed for fast insertion below
01250                 query2 << ";";
01251 
01252                 rc = sqlite3_prepare_v2(_ppDb, query2.str().c_str(), -1, &ppStmt, 0);
01253                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01254 
01255                 for(std::list<Signature*>::const_iterator iter=nodes.begin(); iter!=nodes.end(); ++iter)
01256                 {
01257                         //ULOGGER_DEBUG("Loading words of %d...", (*iter)->id());
01258                         // bind id
01259                         rc = sqlite3_bind_int(ppStmt, 1, (*iter)->id());
01260                         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01261 
01262                         int visualWordId = 0;
01263                         cv::KeyPoint kpt;
01264                         std::multimap<int, cv::KeyPoint> visualWords;
01265                         std::multimap<int, pcl::PointXYZ> visualWords3;
01266                         pcl::PointXYZ depth(0,0,0);
01267 
01268                         // Process the result if one
01269                         rc = sqlite3_step(ppStmt);
01270                         while(rc == SQLITE_ROW)
01271                         {
01272                                 int index = 0;
01273                                 visualWordId = sqlite3_column_int(ppStmt, index++);
01274                                 kpt.pt.x = sqlite3_column_double(ppStmt, index++);
01275                                 kpt.pt.y = sqlite3_column_double(ppStmt, index++);
01276                                 kpt.size = sqlite3_column_int(ppStmt, index++);
01277                                 kpt.angle = sqlite3_column_double(ppStmt, index++);
01278                                 kpt.response = sqlite3_column_double(ppStmt, index++);
01279                                 depth.x = sqlite3_column_double(ppStmt, index++);
01280                                 depth.y = sqlite3_column_double(ppStmt, index++);
01281                                 depth.z = sqlite3_column_double(ppStmt, index++);
01282                                 visualWords.insert(visualWords.end(), std::make_pair(visualWordId, kpt));
01283                                 visualWords3.insert(visualWords3.end(), std::make_pair(visualWordId, depth));
01284                                 rc = sqlite3_step(ppStmt);
01285                         }
01286                         UASSERT_MSG(rc == SQLITE_DONE, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01287 
01288                         if(visualWords.size()==0)
01289                         {
01290                                 UDEBUG("Empty signature detected! (id=%d)", (*iter)->id());
01291                         }
01292                         else
01293                         {
01294                                 (*iter)->setWords(visualWords);
01295                                 (*iter)->setWords3(visualWords3);
01296                                 ULOGGER_DEBUG("Add %d keypoints and %d 3d points to node %d", visualWords.size(), visualWords3.size(), (*iter)->id());
01297                         }
01298 
01299                         //reset
01300                         rc = sqlite3_reset(ppStmt);
01301                         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01302                 }
01303 
01304                 // Finalize (delete) the statement
01305                 rc = sqlite3_finalize(ppStmt);
01306                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01307 
01308                 ULOGGER_DEBUG("Time=%fs", timer.ticks());
01309 
01310                 this->loadLinksQuery(nodes);
01311                 for(std::list<Signature*>::iterator iter = nodes.begin(); iter!=nodes.end(); ++iter)
01312                 {
01313                         (*iter)->setModified(false);
01314                 }
01315                 ULOGGER_DEBUG("Time load links=%fs", timer.ticks());
01316 
01317                 if(ids.size() != loaded)
01318                 {
01319                         UERROR("Some signatures not found in database");
01320                 }
01321         }
01322 }
01323 
01324 void DBDriverSqlite3::loadLastNodesQuery(std::list<Signature *> & nodes) const
01325 {
01326         ULOGGER_DEBUG("");
01327         if(_ppDb)
01328         {
01329                 std::string type;
01330                 UTimer timer;
01331                 timer.start();
01332                 int rc = SQLITE_OK;
01333                 sqlite3_stmt * ppStmt = 0;
01334                 std::string query;
01335                 std::list<int> ids;
01336 
01337                 query = "SELECT n.id "
01338                                  "FROM Node AS n "
01339                                  "WHERE n.time_enter >= (SELECT MAX(time_enter) FROM Statistics) "
01340                                  "ORDER BY n.id;";
01341 
01342                 rc = sqlite3_prepare_v2(_ppDb, query.c_str(), -1, &ppStmt, 0);
01343                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01344 
01345                 // Process the result if one
01346                 rc = sqlite3_step(ppStmt);
01347                 while(rc == SQLITE_ROW)
01348                 {
01349                         ids.push_back(sqlite3_column_int(ppStmt, 0));   // Signature id
01350                         rc = sqlite3_step(ppStmt); // next result...
01351                 }
01352 
01353                 UASSERT_MSG(rc == SQLITE_DONE, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01354 
01355                 // Finalize (delete) the statement
01356                 rc = sqlite3_finalize(ppStmt);
01357                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01358 
01359                 ULOGGER_DEBUG("Loading %d signatures...", ids.size());
01360                 this->loadSignaturesQuery(ids, nodes);
01361                 ULOGGER_DEBUG("loaded=%d, Time=%fs", nodes.size(), timer.ticks());
01362         }
01363 }
01364 
01365 void DBDriverSqlite3::loadQuery(VWDictionary * dictionary) const
01366 {
01367         ULOGGER_DEBUG("");
01368         if(_ppDb && dictionary)
01369         {
01370                 std::string type;
01371                 UTimer timer;
01372                 timer.start();
01373                 int rc = SQLITE_OK;
01374                 sqlite3_stmt * ppStmt = 0;
01375                 std::string query;
01376                 std::list<VisualWord *> visualWords;
01377 
01378                 // Get the visual words
01379                 query = "SELECT id, descriptor_size, descriptor "
01380                                 "FROM Word "
01381                                 "WHERE time_enter >= (SELECT MAX(time_enter) FROM Statistics) "
01382                                 "ORDER BY id;";
01383 
01384                 rc = sqlite3_prepare_v2(_ppDb, query.c_str(), -1, &ppStmt, 0);
01385                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01386 
01387                 // Process the result if one
01388                 int id = 0;
01389                 int descriptorSize = 0;
01390                 const void * descriptor = 0;
01391                 int dRealSize = 0;
01392                 rc = sqlite3_step(ppStmt);
01393                 int count = 0;
01394                 while(rc == SQLITE_ROW)
01395                 {
01396                         int index=0;
01397                         id = sqlite3_column_int(ppStmt, index++);                       // VisualWord Id
01398                         if(id>0)
01399                         {
01400                                 descriptorSize = sqlite3_column_int(ppStmt, index++); // VisualWord descriptor size
01401                                 descriptor = sqlite3_column_blob(ppStmt, index);        // VisualWord descriptor array
01402                                 dRealSize = sqlite3_column_bytes(ppStmt, index++);
01403 
01404                                 cv::Mat d;
01405                                 if(dRealSize == descriptorSize)
01406                                 {
01407                                         // CV_8U binary descriptors
01408                                         d = cv::Mat(1, descriptorSize, CV_8U);
01409                                 }
01410                                 else if(dRealSize/int(sizeof(float)) == descriptorSize)
01411                                 {
01412                                         // CV_32F
01413                                         d = cv::Mat(1, descriptorSize, CV_32F);
01414                                 }
01415                                 else
01416                                 {
01417                                         UFATAL("Saved buffer size (%d bytes) is not the same as descriptor size (%d)", dRealSize, descriptorSize);
01418                                 }
01419 
01420                                 memcpy(d.data, descriptor, dRealSize);
01421                                 VisualWord * vw = new VisualWord(id, d);
01422                                 vw->setSaved(true);
01423                                 dictionary->addWord(vw);
01424                         }
01425                         else
01426                         {
01427                                 ULOGGER_ERROR("Wrong word id ?!? (%d)", id);
01428                         }
01429                         if(++count % 5000 == 0)
01430                         {
01431                                 ULOGGER_DEBUG("Loaded %d words...", count);
01432                         }
01433                         rc = sqlite3_step(ppStmt); // next result...
01434                 }
01435                 UASSERT_MSG(rc == SQLITE_DONE, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01436                 // Finalize (delete) the statement
01437                 rc = sqlite3_finalize(ppStmt);
01438                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01439 
01440                 // Get Last word id
01441                 getLastWordId(id);
01442                 dictionary->setLastWordId(id);
01443 
01444                 ULOGGER_DEBUG("Time=%fs", timer.ticks());
01445         }
01446 }
01447 
01448 //may be slower than the previous version but don't have a limit of words that can be loaded at the same time
01449 void DBDriverSqlite3::loadWordsQuery(const std::set<int> & wordIds, std::list<VisualWord *> & vws) const
01450 {
01451         ULOGGER_DEBUG("size=%d", wordIds.size());
01452         if(_ppDb && wordIds.size())
01453         {
01454                 std::string type;
01455                 UTimer timer;
01456                 timer.start();
01457                 int rc = SQLITE_OK;
01458                 sqlite3_stmt * ppStmt = 0;
01459                 std::stringstream query;
01460                 std::set<int> loaded;
01461 
01462                 // Get the map from signature and visual words
01463                 query << "SELECT vw.descriptor_size, vw.descriptor "
01464                                  "FROM Word as vw "
01465                                  "WHERE vw.id = ?;";
01466 
01467                 rc = sqlite3_prepare_v2(_ppDb, query.str().c_str(), -1, &ppStmt, 0);
01468                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01469 
01470                 int descriptorSize;
01471                 const void * descriptor;
01472                 int dRealSize;
01473                 for(std::set<int>::const_iterator iter=wordIds.begin(); iter!=wordIds.end(); ++iter)
01474                 {
01475                         // bind id
01476                         rc = sqlite3_bind_int(ppStmt, 1, *iter);
01477                         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01478 
01479                         // Process the result if one
01480                         rc = sqlite3_step(ppStmt);
01481                         if(rc == SQLITE_ROW)
01482                         {
01483                                 int index = 0;
01484                                 descriptorSize = sqlite3_column_int(ppStmt, index++); // VisualWord descriptor size
01485                                 descriptor = sqlite3_column_blob(ppStmt, index);        // VisualWord descriptor array
01486                                 dRealSize = sqlite3_column_bytes(ppStmt, index++);
01487 
01488                                 cv::Mat d;
01489                                 if(dRealSize == descriptorSize)
01490                                 {
01491                                         // CV_8U binary descriptors
01492                                         d = cv::Mat(1, descriptorSize, CV_8U);
01493                                 }
01494                                 else if(dRealSize/int(sizeof(float)) == descriptorSize)
01495                                 {
01496                                         // CV_32F
01497                                         d = cv::Mat(1, descriptorSize, CV_32F);
01498                                 }
01499                                 else
01500                                 {
01501                                         UFATAL("Saved buffer size (%d bytes) is not the same as descriptor size (%d)", dRealSize, descriptorSize);
01502                                 }
01503 
01504                                 memcpy(d.data, descriptor, dRealSize);
01505                                 VisualWord * vw = new VisualWord(*iter, d);
01506                                 if(vw)
01507                                 {
01508                                         vw->setSaved(true);
01509                                 }
01510                                 vws.push_back(vw);
01511                                 loaded.insert(loaded.end(), *iter);
01512 
01513                                 rc = sqlite3_step(ppStmt);
01514                         }
01515 
01516                         UASSERT_MSG(rc == SQLITE_DONE, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01517 
01518                         rc = sqlite3_reset(ppStmt);
01519                         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01520                 }
01521 
01522                 // Finalize (delete) the statement
01523                 rc = sqlite3_finalize(ppStmt);
01524                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01525 
01526                 ULOGGER_DEBUG("Time=%fs", timer.ticks());
01527 
01528                 if(wordIds.size() != loaded.size())
01529                 {
01530                         for(std::set<int>::const_iterator iter = wordIds.begin(); iter!=wordIds.end(); ++iter)
01531                         {
01532                                 if(loaded.find(*iter) == loaded.end())
01533                                 {
01534                                         UDEBUG("Not found word %d", *iter);
01535                                 }
01536                         }
01537                         UERROR("Query (%d) doesn't match loaded words (%d)", wordIds.size(), loaded.size());
01538                 }
01539         }
01540 }
01541 
01542 void DBDriverSqlite3::loadLinksQuery(
01543                 int signatureId,
01544                 std::map<int, Link> & neighbors,
01545                 Link::Type typeIn) const
01546 {
01547         neighbors.clear();
01548         if(_ppDb)
01549         {
01550                 UTimer timer;
01551                 timer.start();
01552                 int rc = SQLITE_OK;
01553                 sqlite3_stmt * ppStmt = 0;
01554                 std::stringstream query;
01555 
01556                 if(uStrNumCmp(_version, "0.8.4") >= 0)
01557                 {
01558                         query << "SELECT to_id, type, transform, rot_variance, trans_variance FROM Link ";
01559                 }
01560                 else if(uStrNumCmp(_version, "0.7.4") >= 0)
01561                 {
01562                         query << "SELECT to_id, type, transform, variance FROM Link ";
01563                 }
01564                 else
01565                 {
01566                         query << "SELECT to_id, type, transform FROM Link ";
01567                 }
01568                 query << "WHERE from_id = " << signatureId;
01569                 if(typeIn != Link::kUndef)
01570                 {
01571                         if(uStrNumCmp(_version, "0.7.4") >= 0)
01572                         {
01573                                 query << " AND type = " << typeIn;
01574                         }
01575                         else if(typeIn == Link::kNeighbor)
01576                         {
01577                                 query << " AND type = 0";
01578                         }
01579                         else if(typeIn > Link::kNeighbor)
01580                         {
01581                                 query << " AND type > 0";
01582                         }
01583                 }
01584                 query << " ORDER BY to_id";
01585 
01586                 rc = sqlite3_prepare_v2(_ppDb, query.str().c_str(), -1, &ppStmt, 0);
01587                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01588 
01589                 int toId = -1;
01590                 int type = Link::kUndef;
01591                 float rotVariance = 1.0f;
01592                 float transVariance = 1.0f;
01593                 const void * data = 0;
01594                 int dataSize = 0;
01595 
01596                 // Process the result if one
01597                 rc = sqlite3_step(ppStmt);
01598                 while(rc == SQLITE_ROW)
01599                 {
01600                         int index = 0;
01601 
01602                         toId = sqlite3_column_int(ppStmt, index++);
01603                         type = sqlite3_column_int(ppStmt, index++);
01604 
01605                         data = sqlite3_column_blob(ppStmt, index);
01606                         dataSize = sqlite3_column_bytes(ppStmt, index++);
01607 
01608                         Transform transform;
01609                         if((unsigned int)dataSize == transform.size()*sizeof(float) && data)
01610                         {
01611                                 memcpy(transform.data(), data, dataSize);
01612                         }
01613                         else if(dataSize)
01614                         {
01615                                 UERROR("Error while loading link transform from %d to %d! Setting to null...", signatureId, toId);
01616                         }
01617 
01618                         if(uStrNumCmp(_version, "0.8.4") >= 0)
01619                         {
01620                                 rotVariance = sqlite3_column_double(ppStmt, index++);
01621                                 transVariance = sqlite3_column_double(ppStmt, index++);
01622                                 neighbors.insert(neighbors.end(), std::make_pair(toId, Link(signatureId, toId, (Link::Type)type, transform, rotVariance, transVariance)));
01623                         }
01624                         else if(uStrNumCmp(_version, "0.7.4") >= 0)
01625                         {
01626                                 rotVariance = transVariance = sqlite3_column_double(ppStmt, index++);
01627                                 neighbors.insert(neighbors.end(), std::make_pair(toId, Link(signatureId, toId, (Link::Type)type, transform, rotVariance, transVariance)));
01628                         }
01629                         else
01630                         {
01631                                 // neighbor is 0, loop closures are 1 and 2 (child)
01632                                 neighbors.insert(neighbors.end(), std::make_pair(toId, Link(signatureId, toId, type==0?Link::kNeighbor:Link::kGlobalClosure, transform, rotVariance, transVariance)));
01633                         }
01634 
01635                         rc = sqlite3_step(ppStmt);
01636                 }
01637 
01638                 UASSERT_MSG(rc == SQLITE_DONE, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01639 
01640                 // Finalize (delete) the statement
01641                 rc = sqlite3_finalize(ppStmt);
01642                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01643 
01644                 if(neighbors.size() == 0)
01645                 {
01646                         //UERROR("No neighbors loaded from signature %d", signatureId);
01647                 }
01648         }
01649 }
01650 
01651 void DBDriverSqlite3::loadLinksQuery(std::list<Signature *> & signatures) const
01652 {
01653         if(_ppDb)
01654         {
01655                 UTimer timer;
01656                 timer.start();
01657                 int rc = SQLITE_OK;
01658                 sqlite3_stmt * ppStmt = 0;
01659                 std::stringstream query;
01660                 int totalLinksLoaded = 0;
01661 
01662                 if(uStrNumCmp(_version, "0.8.4") >= 0)
01663                 {
01664                         query << "SELECT to_id, type, rot_variance, trans_variance, transform FROM Link "
01665                                   << "WHERE from_id = ? "
01666                                   << "ORDER BY to_id";
01667                 }
01668                 else if(uStrNumCmp(_version, "0.7.4") >= 0)
01669                 {
01670                         query << "SELECT to_id, type, variance, transform FROM Link "
01671                                   << "WHERE from_id = ? "
01672                                   << "ORDER BY to_id";
01673                 }
01674                 else
01675                 {
01676                         query << "SELECT to_id, type, transform FROM Link "
01677                                   << "WHERE from_id = ? "
01678                                   << "ORDER BY to_id";
01679                 }
01680 
01681                 rc = sqlite3_prepare_v2(_ppDb, query.str().c_str(), -1, &ppStmt, 0);
01682                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01683 
01684                 for(std::list<Signature*>::iterator iter=signatures.begin(); iter!=signatures.end(); ++iter)
01685                 {
01686                         // bind id
01687                         rc = sqlite3_bind_int(ppStmt, 1, (*iter)->id());
01688                         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01689 
01690                         int toId = -1;
01691                         int linkType = -1;
01692                         float rotVariance = 1.0f;
01693                         float transVariance = 1.0f;
01694                         std::list<Link> links;
01695                         const void * data = 0;
01696                         int dataSize = 0;
01697 
01698                         // Process the result if one
01699                         rc = sqlite3_step(ppStmt);
01700                         while(rc == SQLITE_ROW)
01701                         {
01702                                 int index = 0;
01703 
01704                                 toId = sqlite3_column_int(ppStmt, index++);
01705                                 linkType = sqlite3_column_int(ppStmt, index++);
01706                                 if(uStrNumCmp(_version, "0.8.4") >= 0)
01707                                 {
01708                                         rotVariance = sqlite3_column_double(ppStmt, index++);
01709                                         transVariance = sqlite3_column_double(ppStmt, index++);
01710                                 }
01711                                 else if(uStrNumCmp(_version, "0.7.4") >= 0)
01712                                 {
01713                                         rotVariance = transVariance = sqlite3_column_double(ppStmt, index++);
01714                                 }
01715 
01716                                 //transform
01717                                 data = sqlite3_column_blob(ppStmt, index);
01718                                 dataSize = sqlite3_column_bytes(ppStmt, index++);
01719                                 Transform transform;
01720                                 if((unsigned int)dataSize == transform.size()*sizeof(float) && data)
01721                                 {
01722                                         memcpy(transform.data(), data, dataSize);
01723                                 }
01724                                 else if(dataSize)
01725                                 {
01726                                         UERROR("Error while loading link transform from %d to %d! Setting to null...", (*iter)->id(), toId);
01727                                 }
01728 
01729                                 if(linkType >= 0 && linkType != Link::kUndef)
01730                                 {
01731                                         if(uStrNumCmp(_version, "0.7.4") >= 0)
01732                                         {
01733                                                 links.push_back(Link((*iter)->id(), toId, (Link::Type)linkType, transform, rotVariance, transVariance));
01734                                         }
01735                                         else // neighbor is 0, loop closures are 1 and 2 (child)
01736                                         {
01737                                                 links.push_back(Link((*iter)->id(), toId, linkType == 0?Link::kNeighbor:Link::kGlobalClosure, transform, rotVariance, transVariance));
01738                                         }
01739                                 }
01740                                 else
01741                                 {
01742                                         UFATAL("Not supported link type %d ! (fromId=%d, toId=%d)",
01743                                                         linkType, (*iter)->id(), toId);
01744                                 }
01745 
01746                                 ++totalLinksLoaded;
01747                                 rc = sqlite3_step(ppStmt);
01748                         }
01749                         UASSERT_MSG(rc == SQLITE_DONE, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01750 
01751                         // add links
01752                         (*iter)->addLinks(links);
01753 
01754                         //reset
01755                         rc = sqlite3_reset(ppStmt);
01756                         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01757                         UDEBUG("time=%fs, node=%d, links.size=%d", timer.ticks(), (*iter)->id(), links.size());
01758                 }
01759 
01760                 // Finalize (delete) the statement
01761                 rc = sqlite3_finalize(ppStmt);
01762                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01763         }
01764 }
01765 
01766 
01767 void DBDriverSqlite3::updateQuery(const std::list<Signature *> & nodes, bool updateTimestamp) const
01768 {
01769         UDEBUG("nodes = %d", nodes.size());
01770         if(_ppDb && nodes.size())
01771         {
01772                 UTimer timer;
01773                 timer.start();
01774                 int rc = SQLITE_OK;
01775                 sqlite3_stmt * ppStmt = 0;
01776                 Signature * s = 0;
01777 
01778                 std::string query;
01779                 if(uStrNumCmp(_version, "0.8.8") >= 0)
01780                 {
01781                         if(updateTimestamp)
01782                         {
01783                                 query = "UPDATE Node SET weight=?, label=?, user_data=?, time_enter = DATETIME('NOW') WHERE id=?;";
01784                         }
01785                         else
01786                         {
01787                                 query = "UPDATE Node SET weight=?, label=?, user_data=? WHERE id=?;";
01788                         }
01789                 }
01790                 else if(uStrNumCmp(_version, "0.8.5") >= 0)
01791                 {
01792                         if(updateTimestamp)
01793                         {
01794                                 query = "UPDATE Node SET weight=?, label=?, time_enter = DATETIME('NOW') WHERE id=?;";
01795                         }
01796                         else
01797                         {
01798                                 query = "UPDATE Node SET weight=?, label=? WHERE id=?;";
01799                         }
01800                 }
01801                 else
01802                 {
01803                         if(updateTimestamp)
01804                         {
01805                                 query = "UPDATE Node SET weight=?, time_enter = DATETIME('NOW') WHERE id=?;";
01806                         }
01807                         else
01808                         {
01809                                 query = "UPDATE Node SET weight=? WHERE id=?;";
01810                         }
01811                 }
01812                 rc = sqlite3_prepare_v2(_ppDb, query.c_str(), -1, &ppStmt, 0);
01813                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01814 
01815                 for(std::list<Signature *>::const_iterator i=nodes.begin(); i!=nodes.end(); ++i)
01816                 {
01817                         s = *i;
01818                         int index = 1;
01819                         if(s)
01820                         {
01821                                 rc = sqlite3_bind_int(ppStmt, index++, s->getWeight());
01822                                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01823 
01824                                 if(uStrNumCmp(_version, "0.8.5") >= 0)
01825                                 {
01826                                         if(s->getLabel().empty())
01827                                         {
01828                                                 rc = sqlite3_bind_null(ppStmt, index++);
01829                                                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01830                                         }
01831                                         else
01832                                         {
01833                                                 rc = sqlite3_bind_text(ppStmt, index++, s->getLabel().c_str(), -1, SQLITE_STATIC);
01834                                                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01835                                         }
01836                                 }
01837 
01838                                 if(uStrNumCmp(_version, "0.8.8") >= 0)
01839                                 {
01840                                         if(s->getUserData().empty())
01841                                         {
01842                                                 rc = sqlite3_bind_null(ppStmt, index++);
01843                                                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01844                                         }
01845                                         else
01846                                         {
01847                                                 rc = sqlite3_bind_blob(ppStmt, index++, s->getUserData().data(), (int)s->getUserData().size(), SQLITE_STATIC);
01848                                                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01849                                         }
01850                                 }
01851 
01852                                 rc = sqlite3_bind_int(ppStmt, index++, s->id());
01853                                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01854 
01855                                 //step
01856                                 rc=sqlite3_step(ppStmt);
01857                                 UASSERT_MSG(rc == SQLITE_DONE, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01858 
01859                                 rc = sqlite3_reset(ppStmt);
01860                                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01861                         }
01862                 }
01863                 // Finalize (delete) the statement
01864                 rc = sqlite3_finalize(ppStmt);
01865                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01866 
01867                 ULOGGER_DEBUG("Update Node table, Time=%fs", timer.ticks());
01868 
01869                 // Update links part1
01870                 query = "DELETE FROM Link WHERE from_id=?;";
01871                 rc = sqlite3_prepare_v2(_ppDb, query.c_str(), -1, &ppStmt, 0);
01872                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01873                 for(std::list<Signature *>::const_iterator j=nodes.begin(); j!=nodes.end(); ++j)
01874                 {
01875                         if((*j)->isLinksModified())
01876                         {
01877                                 rc = sqlite3_bind_int(ppStmt, 1, (*j)->id());
01878                                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01879 
01880                                 rc=sqlite3_step(ppStmt);
01881                                 UASSERT_MSG(rc == SQLITE_DONE, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01882 
01883                                 rc = sqlite3_reset(ppStmt);
01884                                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01885                         }
01886                 }
01887                 // Finalize (delete) the statement
01888                 rc = sqlite3_finalize(ppStmt);
01889                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01890 
01891                 // Update links part2
01892                 query = queryStepLink();
01893                 rc = sqlite3_prepare_v2(_ppDb, query.c_str(), -1, &ppStmt, 0);
01894                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01895                 for(std::list<Signature *>::const_iterator j=nodes.begin(); j!=nodes.end(); ++j)
01896                 {
01897                         if((*j)->isLinksModified())
01898                         {
01899                                 // Save links
01900                                 const std::map<int, Link> & links = (*j)->getLinks();
01901                                 for(std::map<int, Link>::const_iterator i=links.begin(); i!=links.end(); ++i)
01902                                 {
01903                                         stepLink(ppStmt, (*j)->id(), i->first, i->second.type(), i->second.rotVariance(), i->second.transVariance(), i->second.transform());
01904                                 }
01905                         }
01906                 }
01907                 // Finalize (delete) the statement
01908                 rc = sqlite3_finalize(ppStmt);
01909                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01910                 ULOGGER_DEBUG("Update Neighbors Time=%fs", timer.ticks());
01911 
01912                 // Update word references
01913                 query = queryStepWordsChanged();
01914                 rc = sqlite3_prepare_v2(_ppDb, query.c_str(), -1, &ppStmt, 0);
01915                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01916                 for(std::list<Signature *>::const_iterator j=nodes.begin(); j!=nodes.end(); ++j)
01917                 {
01918                         if((*j)->getWordsChanged().size())
01919                         {
01920                                 const std::map<int, int> & wordsChanged = (*j)->getWordsChanged();
01921                                 for(std::map<int, int>::const_iterator iter=wordsChanged.begin(); iter!=wordsChanged.end(); ++iter)
01922                                 {
01923                                         stepWordsChanged(ppStmt, (*j)->id(), iter->first, iter->second);
01924                                 }
01925                         }
01926                 }
01927                 // Finalize (delete) the statement
01928                 rc = sqlite3_finalize(ppStmt);
01929                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01930 
01931                 ULOGGER_DEBUG("signatures update=%fs", timer.ticks());
01932         }
01933 }
01934 
01935 void DBDriverSqlite3::updateQuery(const std::list<VisualWord *> & words, bool updateTimestamp) const
01936 {
01937         if(_ppDb && words.size() && updateTimestamp)
01938         {
01939                 // Only timestamp update is done here, so don't enter this if at all if false
01940                 UTimer timer;
01941                 timer.start();
01942                 int rc = SQLITE_OK;
01943                 sqlite3_stmt * ppStmt = 0;
01944                 VisualWord * w = 0;
01945 
01946                 std::string query = "UPDATE Word SET time_enter = DATETIME('NOW') WHERE id=?;";
01947                 rc = sqlite3_prepare_v2(_ppDb, query.c_str(), -1, &ppStmt, 0);
01948                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01949 
01950                 for(std::list<VisualWord *>::const_iterator i=words.begin(); i!=words.end(); ++i)
01951                 {
01952                         w = *i;
01953                         int index = 1;
01954                         if(w)
01955                         {
01956                                 rc = sqlite3_bind_int(ppStmt, index++, w->id());
01957                                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01958 
01959                                 //step
01960                                 rc=sqlite3_step(ppStmt);
01961                                 UASSERT_MSG(rc == SQLITE_DONE, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01962 
01963                                 rc = sqlite3_reset(ppStmt);
01964                                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01965                         }
01966                 }
01967                 // Finalize (delete) the statement
01968                 rc = sqlite3_finalize(ppStmt);
01969                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01970 
01971                 ULOGGER_DEBUG("Update Word table, Time=%fs", timer.ticks());
01972         }
01973 }
01974 
01975 void DBDriverSqlite3::saveQuery(const std::list<Signature *> & signatures) const
01976 {
01977         UDEBUG("");
01978         if(_ppDb && signatures.size())
01979         {
01980                 std::string type;
01981                 UTimer timer;
01982                 timer.start();
01983                 int rc = SQLITE_OK;
01984                 sqlite3_stmt * ppStmt = 0;
01985 
01986                 // Signature table
01987                 std::string query = queryStepNode();
01988                 rc = sqlite3_prepare_v2(_ppDb, query.c_str(), -1, &ppStmt, 0);
01989                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01990 
01991                 for(std::list<Signature *>::const_iterator i=signatures.begin(); i!=signatures.end(); ++i)
01992                 {
01993                         stepNode(ppStmt, *i);
01994                 }
01995                 // Finalize (delete) the statement
01996                 rc = sqlite3_finalize(ppStmt);
01997                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
01998 
01999                 UDEBUG("Time=%fs", timer.ticks());
02000 
02001                 // Create new entries in table Link
02002                 query = queryStepLink();
02003                 rc = sqlite3_prepare_v2(_ppDb, query.c_str(), -1, &ppStmt, 0);
02004                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02005                 for(std::list<Signature *>::const_iterator jter=signatures.begin(); jter!=signatures.end(); ++jter)
02006                 {
02007                         // Save links
02008                         const std::map<int, Link> & links = (*jter)->getLinks();
02009                         for(std::map<int, Link>::const_iterator i=links.begin(); i!=links.end(); ++i)
02010                         {
02011                                 stepLink(ppStmt, (*jter)->id(), i->first, i->second.type(), i->second.rotVariance(), i->second.transVariance(), i->second.transform());
02012                         }
02013                 }
02014                 // Finalize (delete) the statement
02015                 rc = sqlite3_finalize(ppStmt);
02016                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02017 
02018                 UDEBUG("Time=%fs", timer.ticks());
02019 
02020 
02021                 // Create new entries in table Map_Word_Node
02022                 query = queryStepKeypoint();
02023                 rc = sqlite3_prepare_v2(_ppDb, query.c_str(), -1, &ppStmt, 0);
02024                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02025                 for(std::list<Signature *>::const_iterator i=signatures.begin(); i!=signatures.end(); ++i)
02026                 {
02027                         UASSERT((*i)->getWords3().empty() || (*i)->getWords().size() == (*i)->getWords3().size());
02028                         if((*i)->getWords3().size())
02029                         {
02030                                 std::multimap<int, cv::KeyPoint>::const_iterator w=(*i)->getWords().begin();
02031                                 std::multimap<int, pcl::PointXYZ>::const_iterator p=(*i)->getWords3().begin();
02032                                 for(; w!=(*i)->getWords().end(); ++w, ++p)
02033                                 {
02034                                         UASSERT(w->first == p->first); // must be same id!
02035                                         stepKeypoint(ppStmt, (*i)->id(), w->first, w->second, p->second);
02036                                 }
02037                         }
02038                         else
02039                         {
02040                                 for(std::multimap<int, cv::KeyPoint>::const_iterator w=(*i)->getWords().begin(); w!=(*i)->getWords().end(); ++w)
02041                                 {
02042                                         stepKeypoint(ppStmt, (*i)->id(), w->first, w->second, pcl::PointXYZ(0,0,0));
02043                                 }
02044                         }
02045                 }
02046                 // Finalize (delete) the statement
02047                 rc = sqlite3_finalize(ppStmt);
02048                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02049                 UDEBUG("Time=%fs", timer.ticks());
02050 
02051                 // Add images
02052                 query = queryStepImage();
02053                 rc = sqlite3_prepare_v2(_ppDb, query.c_str(), -1, &ppStmt, 0);
02054                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02055                 UDEBUG("Saving %d images", signatures.size());
02056 
02057                 for(std::list<Signature *>::const_iterator i=signatures.begin(); i!=signatures.end(); ++i)
02058                 {
02059                         if(!(*i)->getImageCompressed().empty())
02060                         {
02061                                 stepImage(ppStmt, (*i)->id(), (*i)->getImageCompressed());
02062                         }
02063                 }
02064 
02065                 // Finalize (delete) the statement
02066                 rc = sqlite3_finalize(ppStmt);
02067                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02068                 UDEBUG("Time=%fs", timer.ticks());
02069 
02070                 // Add depths
02071                 query = queryStepDepth();
02072                 rc = sqlite3_prepare_v2(_ppDb, query.c_str(), -1, &ppStmt, 0);
02073                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02074                 for(std::list<Signature *>::const_iterator i=signatures.begin(); i!=signatures.end(); ++i)
02075                 {
02076                         //metric
02077                         if(!(*i)->getDepthCompressed().empty() || !(*i)->getLaserScanCompressed().empty())
02078                         {
02079                                 stepDepth(ppStmt, (*i)->id(), (*i)->getDepthCompressed(), (*i)->getLaserScanCompressed(), (*i)->getFx(), (*i)->getFy(), (*i)->getCx(), (*i)->getCy(), (*i)->getLocalTransform(), (*i)->getLaserScanMaxPts());
02080                         }
02081                 }
02082                 // Finalize (delete) the statement
02083                 rc = sqlite3_finalize(ppStmt);
02084                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02085 
02086                 UDEBUG("Time=%fs", timer.ticks());
02087         }
02088 }
02089 
02090 void DBDriverSqlite3::saveQuery(const std::list<VisualWord *> & words) const
02091 {
02092         UDEBUG("visualWords size=%d", words.size());
02093         if(_ppDb)
02094         {
02095                 std::string type;
02096                 UTimer timer;
02097                 timer.start();
02098                 int rc = SQLITE_OK;
02099                 sqlite3_stmt * ppStmt = 0;
02100                 std::string query;
02101 
02102                 // Create new entries in table Map_SS_VW
02103                 if(words.size()>0)
02104                 {
02105                         query = std::string("INSERT INTO Word(id, descriptor_size, descriptor) VALUES(?,?,?);");
02106                         rc = sqlite3_prepare_v2(_ppDb, query.c_str(), -1, &ppStmt, 0);
02107                         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02108                         for(std::list<VisualWord *>::const_iterator iter=words.begin(); iter!=words.end(); ++iter)
02109                         {
02110                                 const VisualWord * w = *iter;
02111                                 if(w && !w->isSaved())
02112                                 {
02113                                         rc = sqlite3_bind_int(ppStmt, 1, w->id());
02114                                         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02115                                         rc = sqlite3_bind_int(ppStmt, 2, w->getDescriptor().cols);
02116                                         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02117                                         UASSERT(w->getDescriptor().type() == CV_32F || w->getDescriptor().type() == CV_8U);
02118                                         if(w->getDescriptor().type() == CV_32F)
02119                                         {
02120                                                 // CV_32F
02121                                                 rc = sqlite3_bind_blob(ppStmt, 3, w->getDescriptor().data, w->getDescriptor().cols*sizeof(float), SQLITE_STATIC);
02122                                         }
02123                                         else
02124                                         {
02125                                                 // CV_8U
02126                                                 rc = sqlite3_bind_blob(ppStmt, 3, w->getDescriptor().data, w->getDescriptor().cols*sizeof(char), SQLITE_STATIC);
02127                                         }
02128                                         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02129 
02130                                         //execute query
02131                                         rc=sqlite3_step(ppStmt);
02132                                         UASSERT_MSG(rc == SQLITE_DONE, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02133 
02134                                         rc = sqlite3_reset(ppStmt);
02135                                         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02136                                 }
02137                         }
02138                         // Finalize (delete) the statement
02139                         rc = sqlite3_finalize(ppStmt);
02140                         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02141                 }
02142 
02143                 UDEBUG("Time=%fs", timer.ticks());
02144         }
02145 }
02146 
02147 std::string DBDriverSqlite3::queryStepNode() const
02148 {
02149         if(uStrNumCmp(_version, "0.8.8") >= 0)
02150         {
02151                 return "INSERT INTO Node(id, map_id, weight, pose, stamp, label, user_data) VALUES(?,?,?,?,?,?,?);";
02152         }
02153         else if(uStrNumCmp(_version, "0.8.5") >= 0)
02154         {
02155                 return "INSERT INTO Node(id, map_id, weight, pose, stamp, label) VALUES(?,?,?,?,?,?);";
02156         }
02157         return "INSERT INTO Node(id, map_id, weight, pose) VALUES(?,?,?,?);";
02158 }
02159 void DBDriverSqlite3::stepNode(sqlite3_stmt * ppStmt, const Signature * s) const
02160 {
02161         UDEBUG("Save node %d", s->id());
02162         if(!ppStmt || !s)
02163         {
02164                 UFATAL("");
02165         }
02166         int rc = SQLITE_OK;
02167 
02168         int index = 1;
02169         rc = sqlite3_bind_int(ppStmt, index++, s->id());
02170         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02171         rc = sqlite3_bind_int(ppStmt, index++, s->mapId());
02172         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02173         rc = sqlite3_bind_int(ppStmt, index++, s->getWeight());
02174         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02175         rc = sqlite3_bind_blob(ppStmt, index++, s->getPose().data(), s->getPose().size()*sizeof(float), SQLITE_STATIC);
02176         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02177 
02178         if(uStrNumCmp(_version, "0.8.5") >= 0)
02179         {
02180                 rc = sqlite3_bind_double(ppStmt, index++, s->getStamp());
02181                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02182 
02183                 if(s->getLabel().empty())
02184                 {
02185                         rc = sqlite3_bind_null(ppStmt, index++);
02186                         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02187                 }
02188                 else
02189                 {
02190                         rc = sqlite3_bind_text(ppStmt, index++, s->getLabel().c_str(), -1, SQLITE_STATIC);
02191                         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02192                 }
02193         }
02194 
02195         if(uStrNumCmp(_version, "0.8.8") >= 0)
02196         {
02197                 if(s->getUserData().empty())
02198                 {
02199                         rc = sqlite3_bind_null(ppStmt, index++);
02200                         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02201                 }
02202                 else
02203                 {
02204                         rc = sqlite3_bind_blob(ppStmt, index++, s->getUserData().data(), (int)s->getUserData().size(), SQLITE_STATIC);
02205                         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02206                 }
02207         }
02208 
02209         //step
02210         rc=sqlite3_step(ppStmt);
02211         UASSERT_MSG(rc == SQLITE_DONE, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02212 
02213         rc = sqlite3_reset(ppStmt);
02214         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02215 }
02216 
02217 std::string DBDriverSqlite3::queryStepImage() const
02218 {
02219         return "INSERT INTO Image(id, data) VALUES(?,?);";
02220 }
02221 void DBDriverSqlite3::stepImage(sqlite3_stmt * ppStmt,
02222                 int id,
02223                 const cv::Mat & imageBytes) const
02224 {
02225         UDEBUG("Save image %d (size=%d)", id, (int)imageBytes.cols);
02226         if(!ppStmt)
02227         {
02228                 UFATAL("");
02229         }
02230 
02231         int rc = SQLITE_OK;
02232         int index = 1;
02233 
02234         rc = sqlite3_bind_int(ppStmt, index++, id);
02235         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02236 
02237         if(!imageBytes.empty())
02238         {
02239                 rc = sqlite3_bind_blob(ppStmt, index++, imageBytes.data, (int)imageBytes.cols, SQLITE_STATIC);
02240         }
02241         else
02242         {
02243                 rc = sqlite3_bind_zeroblob(ppStmt, index++, 4);
02244         }
02245         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02246 
02247         //step
02248         rc=sqlite3_step(ppStmt);
02249         UASSERT_MSG(rc == SQLITE_DONE, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02250 
02251         rc = sqlite3_reset(ppStmt);
02252         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02253 }
02254 
02255 std::string DBDriverSqlite3::queryStepDepth() const
02256 {
02257         if(uStrNumCmp(_version, "0.8.11") >= 0)
02258         {
02259                 return "INSERT INTO Depth(id, data, fx, fy, cx, cy, local_transform, data2d, data2d_max_pts) VALUES(?,?,?,?,?,?,?,?,?);";
02260         }
02261         else if(uStrNumCmp(_version, "0.7.0") >= 0)
02262         {
02263                 return "INSERT INTO Depth(id, data, fx, fy, cx, cy, local_transform, data2d) VALUES(?,?,?,?,?,?,?,?);";
02264         }
02265         else
02266         {
02267                 return "INSERT INTO Depth(id, data, constant, local_transform, data2d) VALUES(?,?,?,?,?);";
02268         }
02269 }
02270 void DBDriverSqlite3::stepDepth(sqlite3_stmt * ppStmt,
02271                 int id,
02272                 const cv::Mat & depthBytes,
02273                 const cv::Mat & depth2dBytes,
02274                 float fx,
02275                 float fy,
02276                 float cx,
02277                 float cy,
02278                 const Transform & localTransform,
02279                 int depth2dMaxPts) const
02280 {
02281         UDEBUG("Save depth %d (size=%d) depth2d = %d", id, (int)depthBytes.cols, (int)depth2dBytes.cols);
02282         if(!ppStmt)
02283         {
02284                 UFATAL("");
02285         }
02286 
02287         int rc = SQLITE_OK;
02288         int index = 1;
02289 
02290         rc = sqlite3_bind_int(ppStmt, index++, id);
02291         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02292 
02293         if(!depthBytes.empty())
02294         {
02295                 rc = sqlite3_bind_blob(ppStmt, index++, depthBytes.data, (int)depthBytes.cols, SQLITE_STATIC);
02296         }
02297         else
02298         {
02299                 rc = sqlite3_bind_zeroblob(ppStmt, index++, 4);
02300         }
02301         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02302 
02303         if(uStrNumCmp(_version, "0.7.0") >= 0)
02304         {
02305                 rc = sqlite3_bind_double(ppStmt, index++, fx);
02306                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02307                 rc = sqlite3_bind_double(ppStmt, index++, fy);
02308                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02309                 rc = sqlite3_bind_double(ppStmt, index++, cx);
02310                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02311                 rc = sqlite3_bind_double(ppStmt, index++, cy);
02312                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02313         }
02314         else
02315         {
02316                 rc = sqlite3_bind_double(ppStmt, index++, 1.0f/fx);
02317                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02318         }
02319 
02320         rc = sqlite3_bind_blob(ppStmt, index++, localTransform.data(), localTransform.size()*sizeof(float), SQLITE_STATIC);
02321         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02322 
02323         if(!depth2dBytes.empty())
02324         {
02325                 rc = sqlite3_bind_blob(ppStmt, index++, depth2dBytes.data, (int)depth2dBytes.cols, SQLITE_STATIC);
02326         }
02327         else
02328         {
02329                 rc = sqlite3_bind_zeroblob(ppStmt, index++, 4);
02330         }
02331         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02332 
02333         if(uStrNumCmp(_version, "0.8.11") >= 0)
02334         {
02335                 rc = sqlite3_bind_int(ppStmt, index++, depth2dMaxPts);
02336                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02337         }
02338 
02339         //step
02340         rc=sqlite3_step(ppStmt);
02341         UASSERT_MSG(rc == SQLITE_DONE, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02342 
02343         rc = sqlite3_reset(ppStmt);
02344         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02345 }
02346 
02347 std::string DBDriverSqlite3::queryStepLink() const
02348 {
02349         if(uStrNumCmp(_version, "0.8.4") >= 0)
02350         {
02351                 return "INSERT INTO Link(from_id, to_id, type, rot_variance, trans_variance, transform) VALUES(?,?,?,?,?,?);";
02352         }
02353         else if(uStrNumCmp(_version, "0.7.4") >= 0)
02354         {
02355                 return "INSERT INTO Link(from_id, to_id, type, variance, transform) VALUES(?,?,?,?,?);";
02356         }
02357         else
02358         {
02359                 return "INSERT INTO Link(from_id, to_id, type, transform) VALUES(?,?,?,?);";
02360         }
02361 }
02362 void DBDriverSqlite3::stepLink(
02363                 sqlite3_stmt * ppStmt,
02364                 int fromId,
02365                 int toId,
02366                 Link::Type type,
02367                 float rotVariance,
02368                 float transVariance,
02369                 const Transform & transform) const
02370 {
02371         if(!ppStmt)
02372         {
02373                 UFATAL("");
02374         }
02375         UDEBUG("Save link from %d to %d, type=%d", fromId, toId, type);
02376 
02377         // Don't save virtual links
02378         if(type==Link::kVirtualClosure)
02379         {
02380                 UDEBUG("Virtual link ignored....");
02381                 return;
02382         }
02383 
02384         int rc = SQLITE_OK;
02385         int index = 1;
02386         rc = sqlite3_bind_int(ppStmt, index++, fromId);
02387         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02388         rc = sqlite3_bind_int(ppStmt, index++, toId);
02389         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02390         rc = sqlite3_bind_int(ppStmt, index++, type);
02391         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02392 
02393         if(uStrNumCmp(_version, "0.8.4") >= 0)
02394         {
02395                 rc = sqlite3_bind_double(ppStmt, index++, rotVariance);
02396                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02397                 rc = sqlite3_bind_double(ppStmt, index++, transVariance);
02398                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02399         }
02400         else if(uStrNumCmp(_version, "0.7.4") >= 0)
02401         {
02402                 rc = sqlite3_bind_double(ppStmt, index++, rotVariance<transVariance?rotVariance:transVariance);
02403                 UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02404         }
02405 
02406         rc = sqlite3_bind_blob(ppStmt, index++, transform.data(), transform.size()*sizeof(float), SQLITE_STATIC);
02407         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02408 
02409         rc=sqlite3_step(ppStmt);
02410         UASSERT_MSG(rc == SQLITE_DONE, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02411 
02412         rc=sqlite3_reset(ppStmt);
02413         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02414 }
02415 
02416 std::string DBDriverSqlite3::queryStepWordsChanged() const
02417 {
02418         return "UPDATE Map_Node_Word SET word_id = ? WHERE word_id = ? AND node_id = ?;";
02419 }
02420 void DBDriverSqlite3::stepWordsChanged(sqlite3_stmt * ppStmt, int nodeId, int oldWordId, int newWordId) const
02421 {
02422         if(!ppStmt)
02423         {
02424                 UFATAL("");
02425         }
02426         int rc = SQLITE_OK;
02427         int index = 1;
02428         rc = sqlite3_bind_int(ppStmt, index++, newWordId);
02429         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02430         rc = sqlite3_bind_int(ppStmt, index++, oldWordId);
02431         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02432         rc = sqlite3_bind_int(ppStmt, index++, nodeId);
02433         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02434 
02435         rc=sqlite3_step(ppStmt);
02436         UASSERT_MSG(rc == SQLITE_DONE, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02437 
02438         rc=sqlite3_reset(ppStmt);
02439         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02440 }
02441 
02442 std::string DBDriverSqlite3::queryStepKeypoint() const
02443 {
02444         return "INSERT INTO Map_Node_Word(node_id, word_id, pos_x, pos_y, size, dir, response, depth_x, depth_y, depth_z) VALUES(?,?,?,?,?,?,?,?,?,?);";
02445 }
02446 void DBDriverSqlite3::stepKeypoint(sqlite3_stmt * ppStmt, int nodeId, int wordId, const cv::KeyPoint & kp, const pcl::PointXYZ & pt) const
02447 {
02448         if(!ppStmt)
02449         {
02450                 UFATAL("");
02451         }
02452         int rc = SQLITE_OK;
02453         int index = 1;
02454         rc = sqlite3_bind_int(ppStmt, index++, nodeId);
02455         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02456         rc = sqlite3_bind_int(ppStmt, index++, wordId);
02457         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02458         rc = sqlite3_bind_double(ppStmt, index++, kp.pt.x);
02459         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02460         rc = sqlite3_bind_double(ppStmt, index++, kp.pt.y);
02461         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02462         rc = sqlite3_bind_int(ppStmt, index++, kp.size);
02463         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02464         rc = sqlite3_bind_double(ppStmt, index++, kp.angle);
02465         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02466         rc = sqlite3_bind_double(ppStmt, index++, kp.response);
02467         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02468         rc = sqlite3_bind_double(ppStmt, index++, pt.x);
02469         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02470         rc = sqlite3_bind_double(ppStmt, index++, pt.y);
02471         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02472         rc = sqlite3_bind_double(ppStmt, index++, pt.z);
02473         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02474 
02475         rc=sqlite3_step(ppStmt);
02476         UASSERT_MSG(rc == SQLITE_DONE, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02477 
02478         rc = sqlite3_reset(ppStmt);
02479         UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
02480 }
02481 
02482 } // namespace rtabmap


rtabmap
Author(s): Mathieu Labbe
autogenerated on Fri Aug 28 2015 12:51:31