37 int MDSql::table_counter = 0;
41 const char *MDSql::zLeftover;
45 std::stringstream MDSql::preparedStream;
46 sqlite3_stmt * MDSql::preparedStmt;
48 void sqlite_regexp(sqlite3_context* context,
int argc, sqlite3_value** values) {
51 char* reg = (
char*)sqlite3_value_text(values[0]);
52 char* text = (
char*)sqlite3_value_text(values[1]);
54 if ( argc != 2 || reg == 0 || text == 0) {
55 sqlite3_result_error(context,
"SQL function regexp() called with invalid arguments.\n", -1);
59 ret = regcomp(®ex, reg, REG_EXTENDED | REG_NOSUB);
61 sqlite3_result_error(context,
"error compiling regular expression", -1);
65 ret = regexec(®ex, text , 0, NULL, 0);
68 sqlite3_result_int(context, (ret != REG_NOMATCH));
81 if ((rc=sqlite3_open(inFile.c_str(), &db1)))
83 if ((rc=sqlite3_get_table (db1, sql.c_str(), &results, &rows, &columns, NULL)) != SQLITE_OK)
90 std::cerr <<
"Empty Metadata" <<std::endl;
95 for (
int i = 1;
i <= rows;
i++)
97 blockList.push_back((
String)results[
i]);
100 sqlite3_free_table (results);
106 int MDSql::getUniqueId()
110 return ++table_counter;
116 tableId = getUniqueId();
121 beThreadSafe =
false;
130 bool MDSql::createMd()
141 bool MDSql::clearMd()
146 bool result = dropTable();
153 size_t MDSql::getObjId()
158 id = sqlite3_last_insert_rowid(db);
163 size_t MDSql::addRow()
171 std::stringstream ss;
172 ss <<
"INSERT INTO " << tableName(tableId) <<
" DEFAULT VALUES;";
173 sqlite3_prepare_v2(db, ss.str().c_str(), -1, &stmt, &zLeftover);
176 std::cerr <<
"DEBUG_JM: addRow: " << ss.str() <<std::endl;
182 if (execSingleStmt(stmt))
183 id = sqlite3_last_insert_rowid(db);
190 bool MDSql::addColumn(
MDLabel column)
192 std::stringstream ss;
193 ss <<
"ALTER TABLE " << tableName(tableId)
195 return execSingleStmt(ss);
200 const char* lib =
"libXmippCore.so";
201 sqlite3_enable_load_extension(db, 1);
202 if( sqlite3_load_extension(db, lib, 0, 0)!= SQLITE_OK)
210 if( sqlite3_create_function(db,
"regexp", 2, SQLITE_ANY,0, &
sqlite_regexp,0,0)!= SQLITE_OK)
218 beThreadSafe =
false;
219 return ( sqlite3_config(SQLITE_CONFIG_MULTITHREAD) == SQLITE_OK);
224 return ( sqlite3_config(SQLITE_CONFIG_SERIALIZED) == SQLITE_OK);
228 bool MDSql::renameColumn(
const std::vector<MDLabel> &oldLabel,
const std::vector<MDLabel> &newlabel)
234 std::vector<MDLabel>::const_iterator itOld;
235 std::vector<MDLabel>::const_iterator itNew;
236 for( itOld = oldLabel.begin(), itNew = newlabel.begin();
237 itOld < oldLabel.end();
239 std::replace(v1.begin(), v1.end(), *itOld, *itNew);
241 int oldTableId = tableId;
243 tableId = getUniqueId();
247 String oldLabelString=
" objID";
248 String newLabelString=
" objID";
249 for(std::vector<MDLabel>::const_iterator it = (myMd->
_activeLabels)
254 for(std::vector<MDLabel>
259 std::stringstream sqlCommand;
260 sqlCommand <<
" INSERT INTO " + tableName(tableId)
261 <<
" ("+ newLabelString +
") " 262 <<
" SELECT " + oldLabelString
263 <<
" FROM " + tableName(oldTableId) ;
264 execSingleStmt(sqlCommand);
266 sqlCommand.str(std::string());
267 sqlCommand <<
"DROP TABLE " << tableName(oldTableId);
268 execSingleStmt(sqlCommand);
270 sqlCommand.str(std::string());
271 sqlCommand <<
" ALTER TABLE " << tableName(tableId)
272 <<
" RENAME TO " << tableName(oldTableId);
273 result = execSingleStmt(sqlCommand);
279 size_t MDSql::size(
void)
281 std::stringstream ss;
282 ss <<
"SELECT COUNT(*) FROM "<< tableName(tableId) <<
";";
283 return execSingleIntStmt(ss);
286 template bool MDSql::setObjectValues(
int id,
const std::vector<MDObject*> &columnValues,
const std::vector<MDLabel> *desiredLabels);
287 template bool MDSql::setObjectValues(
int id,
const std::vector<const MDObject*> &columnValues,
const std::vector<MDLabel> *desiredLabels);
289 template <
typename T>
290 bool MDSql::setObjectValues(
int id,
const std::vector<T> &columnValues,
const std::vector<MDLabel> *desiredLabels)
294 size_t columnCount = 0;
297 if (desiredLabels ==
nullptr)
299 bindValue(this->preparedStmt, 1, *(columnValues[0]));
300 for (
size_t i=1;
i<columnValues.size() ;
i++)
301 bindValue(this->preparedStmt,
i+1, *(columnValues[
i]));
302 columnCount = columnValues.size();
307 for (
size_t i=0;
i<desiredLabels->size() ;
i++)
309 for (
size_t j=0;
j<columnValues.size() ;
j++)
311 if (columnValues[
j]->label == (*desiredLabels)[
i])
313 bindValue(this->preparedStmt,
i+1, *(columnValues[
j]));
318 columnCount = desiredLabels->size();
323 sqlite3_bind_int(this->preparedStmt, columnCount,
id);
326 rc = sqlite3_step( this->preparedStmt);
327 if (rc != SQLITE_OK && rc != SQLITE_ROW && rc != SQLITE_DONE)
329 std::cerr <<
"MDSql::setObjectValue(MDObject): " << std::endl
330 <<
" " << this->preparedStream.str() << std::endl
331 <<
" code: " << rc <<
" error: " << sqlite3_errmsg(db) << std::endl;
336 sqlite3_clear_bindings(this->preparedStmt);
337 sqlite3_reset(this->preparedStmt);
342 void MDSql::finalizePreparedStmt(
void)
344 if (this->preparedStmt != NULL)
346 sqlite3_finalize( this->preparedStmt);
347 this->preparedStmt = NULL;
352 bool MDSql::setObjectValue(
const MDObject &value)
357 std::stringstream ss;
359 ss <<
"UPDATE " << tableName(tableId)
361 rc = sqlite3_prepare_v2(db, ss.str().c_str(), -1, &stmt, &zLeftover);
362 bindValue(stmt, 1, value);
363 rc = sqlite3_step(stmt);
364 if (rc != SQLITE_OK && rc != SQLITE_ROW && rc != SQLITE_DONE)
366 std::cerr <<
"MDSql::setObjectValue(MDObject): " << std::endl
367 <<
" " << ss.str() << std::endl
368 <<
" code: " << rc <<
" error: " << sqlite3_errmsg(db) << std::endl;
371 sqlite3_finalize(stmt);
375 bool MDSql::setObjectValue(
const int objId,
const MDObject &value)
380 std::stringstream ss;
387 ss <<
"UPDATE " << tableName(tableId)
391 std::cerr <<
"DEBUG_JM: setObjectValue: " << ss.str() << std::endl;
395 sqlite3_prepare_v2(db, ss.str().c_str(), -1, &stmt, &zLeftover);
398 bindValue(stmt, 1, value);
399 sqlite3_bind_int(stmt, 2, objId);
400 rc = sqlite3_step(stmt);
401 if (rc != SQLITE_OK && rc != SQLITE_ROW && rc != SQLITE_DONE)
403 std::cerr <<
"MDSql::setObjectValue: " << std::endl
404 <<
" " << ss.str() << std::endl
405 <<
" code: " << rc <<
" error: " << sqlite3_errmsg(db) << std::endl;
412 bool MDSql::initializeSelect(
bool addWhereObjId,
const std::vector<MDLabel> &labels)
415 std::stringstream ss;
421 if (labels.size() > 0)
425 for (
size_t i=1;
i<labels.size() ;
i++)
440 ss <<
" FROM " << tableName(tableId);
445 ss <<
" WHERE objID=?";
448 if (sqlite3_prepare_v2(db, ss.str().c_str(), -1, &this->preparedStmt, &zLeftover) != SQLITE_OK)
451 printf(
"could not prepare statement: %s\n", sqlite3_errmsg(db) );
452 this->preparedStmt = NULL;
458 bool MDSql::initializeInsert(
const std::vector<MDLabel> *labels,
const std::vector<MDObject*> &values)
465 this->preparedStream.str(std::string());
468 this->preparedStream <<
"INSERT INTO " << tableName(tableId);
471 this->preparedStream <<
" (";
476 length = labels->size();
484 else if ((length = values.size()) > 0)
494 this->preparedStream <<
") VALUES (?";
497 this->preparedStream <<
",?";
499 this->preparedStream <<
");";
502 if (sqlite3_prepare_v2(db, this->preparedStream.str().c_str(), -1, &this->preparedStmt, &zLeftover) != SQLITE_OK)
504 printf(
"initializeInsert: could not prepare statement: %s\n", sqlite3_errmsg(db) );
505 this->preparedStmt = NULL;
512 bool MDSql::getObjectsValues(
const std::vector<MDLabel> &labels, std::vector<MDObject> &values)
517 if (sqlite3_step(this->preparedStmt) == SQLITE_ROW)
519 const auto noOfLabels = labels.size();
520 for (
size_t i=0;
i < noOfLabels;
i++)
524 values.emplace_back(labels[
i]);
525 auto &value = values.back();
526 extractValue(this->preparedStmt, i, value);
539 bool MDSql::getObjectValue(
const int objId,
MDObject &value)
541 if (beThreadSafe) { sqlMutex.
lock(); }
542 std::stringstream ss;
550 <<
" FROM " << tableName(tableId)
552 sqlite3_prepare_v2(db, ss.str().c_str(), -1, &stmt, &zLeftover);
558 std::cerr <<
"getObjectValue: " << ss.str() <<std::endl;
562 sqlite3_bind_int(stmt, 1, objId);
564 bool wasSuccess = (sqlite3_step(stmt) == SQLITE_ROW);
568 extractValue(stmt, 0, value);
571 if (beThreadSafe) { sqlMutex.
unlock(); }
576 void MDSql::selectObjects(std::vector<size_t> &objectsOut,
const MDQuery *queryPtr)
578 std::stringstream ss;
582 ss <<
"SELECT objID FROM " << tableName(tableId);
583 if (queryPtr != NULL)
589 sqlite3_prepare_v2(db, ss.str().c_str(), -1, &stmt, &zLeftover);
592 std::cerr <<
"selectObjects: " << ss.str() <<std::endl;
595 while (sqlite3_step(stmt) == SQLITE_ROW)
597 objectsOut.emplace_back(sqlite3_column_int(stmt, 0));
599 sqlite3_finalize(stmt);
602 size_t MDSql::deleteObjects(
const MDQuery *queryPtr)
604 std::stringstream ss;
605 ss <<
"DELETE FROM " << tableName(tableId);
606 if (queryPtr != NULL)
609 if (execSingleStmt(ss))
611 return sqlite3_changes(db);
619 return copyObjects(mdPtrOut->
myMDSql, queryPtr);
622 size_t MDSql::copyObjects(
MDSql * sqlOut,
const MDQuery *queryPtr)
const 627 std::stringstream ss, ss2;
628 ss <<
"INSERT INTO " << tableName(sqlOut->tableId);
631 std::string sep =
" ";
639 ss <<
"(" << ss2.str() <<
") SELECT " << ss2.str();
640 ss <<
" FROM " << tableName(tableId);
641 if (queryPtr != NULL)
647 if (sqlOut->execSingleStmt(ss))
649 return sqlite3_changes(db);
655 const std::vector<AggregateOperation> &operations,
656 const std::vector<MDLabel> &operateLabel)
658 std::stringstream ss;
659 std::stringstream ss2;
661 ss <<
"INSERT INTO " << tableName(mdPtrOut->
myMDSql->tableId)
662 <<
"(" << aggregateStr;
666 for (
size_t i = 0;
i < operations.size();
i++)
670 switch (operations[
i])
693 ss <<
") SELECT " << ss2.str();
694 ss <<
" FROM " << tableName(tableId);
695 ss <<
" GROUP BY " << aggregateStr;
696 ss <<
" ORDER BY " << aggregateStr <<
";";
702 void MDSql::aggregateMdGroupBy(
MetaDataDb *mdPtrOut,
704 const std::vector<MDLabel> &groupByLabels ,
708 std::stringstream ss;
709 std::stringstream ss2;
710 std::stringstream groupByStr;
713 for (
size_t i = 1;
i < groupByLabels.size();
i++)
714 groupByStr <<
", " << MDL::label2StrSql(groupByLabels[
i]);
716 ss <<
"INSERT INTO " << tableName(mdPtrOut->
myMDSql->tableId) <<
"(" 719 ss2 << groupByStr.str() <<
", ";
743 ss <<
" SELECT " << ss2.str();
744 ss <<
" FROM " << tableName(tableId);
745 ss <<
" GROUP BY " << groupByStr.str();
746 ss <<
" ORDER BY " << groupByStr.str() <<
";";
756 std::stringstream ss;
781 ss <<
" FROM " << tableName(tableId);
782 return (execSingleDoubleStmt(ss));
788 std::stringstream ss;
813 ss <<
" FROM " << tableName(tableId);
814 return (execSingleIntStmt(ss));
817 void MDSql::indexModify(
const std::vector<MDLabel> &columns,
bool create)
819 std::stringstream ss,index_name,index_column;
820 std::string sep1=
" ";
821 std::string sep2=
" ";
822 for (
size_t i = 0;
i < columns.size();
i++)
824 index_name << sep1 << tableName(tableId) <<
"_" 833 ss <<
"CREATE INDEX IF NOT EXISTS " << index_name.str() <<
"_INDEX " 834 <<
" ON " << tableName(tableId) <<
" (" << index_column.str() <<
")";
838 ss <<
"DROP INDEX IF EXISTS " << index_name.str() <<
"_INDEX ";
843 size_t MDSql::firstRow()
845 std::stringstream ss;
846 ss <<
"SELECT COALESCE(MIN(objID), -1) AS MDSQL_FIRST_ID FROM " 847 << tableName(tableId) <<
";";
848 return execSingleIntStmt(ss);
851 size_t MDSql::lastRow()
853 std::stringstream ss;
854 ss <<
"SELECT COALESCE(MAX(objID), -1) AS MDSQL_LAST_ID FROM " 855 << tableName(tableId) <<
";";
856 return execSingleIntStmt(ss);
859 size_t MDSql::nextRow(
size_t currentRow)
861 std::stringstream ss;
862 ss <<
"SELECT COALESCE(MIN(objID), -1) AS MDSQL_NEXT_ID FROM " 863 << tableName(tableId)
864 <<
" WHERE objID>" << currentRow <<
";";
865 return execSingleIntStmt(ss);
868 size_t MDSql::previousRow(
size_t currentRow)
870 std::stringstream ss;
871 ss <<
"SELECT COALESCE(MAX(objID), -1) AS MDSQL_PREV_ID FROM " 872 << tableName(tableId)
873 <<
" WHERE objID<" << currentRow <<
";";
874 return execSingleIntStmt(ss);
877 int MDSql::columnMaxLength(
MDLabel column)
879 std::stringstream ss;
881 <<
"), -1)) AS MDSQL_STRING_LENGTH FROM " 882 << tableName(tableId) <<
";";
883 return execSingleIntStmt(ss);
888 std::stringstream ss, ss2;
889 bool execStmt =
true;
891 std::string sep =
" ";
892 std::vector<MDLabel> * labelVector;
897 copyObjects(mdPtrOut->
myMDSql);
910 ss <<
"INSERT INTO " << tableName(mdPtrOut->
myMDSql->tableId)
911 <<
" (" << ss2.str() <<
")" 912 <<
" SELECT " << ss2.str()
913 <<
" FROM " << tableName(tableId)
915 for (
size_t j=0;
j<columns.size(); ++
j)
921 <<
" FROM " << tableName(mdPtrOut->
myMDSql->tableId) <<
") ";
939 ss <<
"INSERT INTO " << tableName(mdPtrOut->
myMDSql->tableId)
940 <<
" (" << ss2.str() <<
")" 941 <<
" SELECT DISTINCT " << ss2.str()
942 <<
" FROM " << tableName(tableId) <<
";";
949 ss <<
"INSERT INTO " << tableName(mdPtrOut->
myMDSql->tableId)
950 <<
" (ObjId," << ss2.str() <<
")" 951 <<
" SELECT M.* FROM (SELECT " <<
MDL::label2StrSql(columns[0]) <<
", MIN(ObjId) AS first " 952 <<
" FROM " << tableName(tableId) <<
" GROUP BY " <<
MDL::label2StrSql(columns[0])
953 <<
" ) foo JOIN " << tableName(tableId) <<
" M ON foo.first = M.ObjId;";
959 ss <<
"DELETE FROM " << tableName(mdPtrOut->
myMDSql->tableId)
961 for (
size_t j=0;
j<columns.size(); ++
j)
969 <<
" FROM " << tableName(tableId) <<
") ";
981 bool MDSql::equals(
const MDSql &op)
990 std::stringstream sqlQuery,ss2,ss2Group;
1012 <<
"SELECT count(*) FROM (" 1013 <<
"SELECT count(*) as result\ 1016 SELECT " << ss2.str() <<
"\ 1017 FROM " << tableName(tableId)
1019 SELECT " << ss2.str() <<
"\ 1020 FROM " << tableName(op.tableId)
1022 <<
" GROUP BY " << ss2Group.str()
1023 <<
" HAVING COUNT(*) <> 2" 1025 return (execSingleIntStmt(sqlQuery)==0);
1028 void MDSql::setOperate(
const MetaDataDb *mdInLeft,
1030 const std::vector<MDLabel> &columnsLeft,
1031 const std::vector<MDLabel> &columnsRight,
1034 std::stringstream ss, ss2, ss3;
1036 std::string join_type =
"", sep =
"";
1040 join_type =
" INNER ";
1043 join_type =
" LEFT OUTER ";
1046 join_type =
" OUTER ";
1050 join_type =
" INNER ";
1057 std::vector<MDLabel> intersectLabels;
1058 std::vector<MDLabel>::const_iterator left, right;
1066 if (*left == *right)
1069 intersectLabels.push_back(*left);
1072 if (0 == intersectLabels.size()) {
1075 mdInRight->
addIndex(intersectLabels);
1076 mdInLeft->
addIndex(intersectLabels);
1080 if (columnsRight.size()==1)
1082 mdInRight->
addIndex(columnsRight[0]);
1083 mdInLeft->
addIndex(columnsLeft[0]);
1089 for (
size_t i = 0;
i <
size;
i++)
1093 if (i < sizeLeft && mdInLeft->_activeLabels[
i] == myMd->
_activeLabels[
i])
1094 ss3 << tableName(mdInLeft->
myMDSql->tableId) <<
".";
1096 ss3 << tableName(mdInRight->
myMDSql->tableId) <<
".";
1100 ss <<
"INSERT INTO " << tableName(tableId)
1101 <<
" (" << ss2.str() <<
")" 1102 <<
" SELECT " << ss3.str()
1103 <<
" FROM " << tableName(mdInLeft->
myMDSql->tableId)
1104 << join_type <<
" JOIN " << tableName(mdInRight->
myMDSql->tableId);
1109 for (
size_t j=0;
j<columnsLeft.size(); ++
j)
1123 for (
size_t j = 0;
j < sizeLeft;
j++)
1128 << tableName(mdInRight->
myMDSql->tableId) <<
"." 1131 << tableName(mdInLeft->
myMDSql->tableId) <<
"." 1149 bool MDSql::operate(
const String &expression)
1151 std::stringstream ss;
1152 ss <<
"UPDATE " << tableName(tableId) <<
" SET " << expression;
1154 return execSingleStmt(ss);
1160 sqlite3_backup *pBackup;
1163 rc = sqlite3_open(fileName.c_str(), &pTo);
1166 pBackup = sqlite3_backup_init(pTo,
"main", db,
"main");
1169 sqlite3_backup_step(pBackup, -1);
1170 sqlite3_backup_finish(pBackup);
1172 rc = sqlite3_errcode(pTo);
1180 void MDSql::copyTableFromFileDB(
const FileName blockname,
1182 const std::vector<MDLabel> *desiredLabels,
1183 const size_t maxRows
1193 if (sqlite3_open(filename.c_str(), &db1))
1197 if(blockname.empty())
1199 sql = (
String)
"SELECT name FROM sqlite_master\ 1200 WHERE type='table' LIMIT 1;";
1201 if ((rc=sqlite3_get_table (db1, sql.c_str(), &results, &rows, &columns, NULL)) != SQLITE_OK)
1204 _blockname=(
String)results[1];
1207 _blockname=blockname;
1208 sql = (
String)
"PRAGMA table_info(" + _blockname +
")";
1209 if (sqlite3_get_table (db1, sql.c_str(), &results, &rows, &columns, NULL) != SQLITE_OK)
1218 std::cerr <<
"Empty Metadata" <<std::endl;
1219 else if (desiredLabels != NULL)
1223 for(std::vector<MDLabel>::const_iterator it = desiredLabels->
1225 it != desiredLabels->end();
1228 activeLabel += *it +
" ,";
1235 for (
int i = 1;
i <= rows;
i++)
1237 Labels = results[(
i * columns) + 1];
1242 if(strcmp(Labels,
"objID"))
1243 std::cerr << (
String)
"WARNING: Ignoring unknown column: " + Labels << std::endl;
1251 sqlite3_free_table (results);
1262 if (sqlite3_exec(db, sqlCommand.c_str(), NULL, NULL, &errmsg) != SQLITE_OK)
1264 std::cerr <<
"Couldn't attach or create table: " << errmsg << std::endl;
1267 String selectCmd =
formatString(
"SELECT %s FROM load.%s", activeLabel.c_str(), _blockname.c_str());
1268 sqlCommand =
formatString(
"INSERT INTO %s %s", tableName(tableId).c_str(), selectCmd.c_str());
1272 std::stringstream ss;
1273 ss <<
"SELECT COUNT(objId) FROM load." << _blockname;
1280 if (sqlite3_exec(db, sqlCommand.c_str(),NULL,NULL,&errmsg) != SQLITE_OK)
1282 std::cerr << (
String)
"Couldn't write table: " << tableName(tableId)
1283 <<
" " << errmsg << std::endl
1284 <<
"sqlcommand " << sqlCommand << std::endl;
1287 sqlite3_exec(db,
"DETACH load",NULL,NULL,&errmsg);
1291 void MDSql::copyTableToFileDB(
const FileName blockname,
const FileName &fileName)
1295 if(blockname.empty())
1298 _blockname=blockname;
1299 String sqlCommand = (
String)
"ATTACH database '" + fileName+
"' as save";
1300 sqlCommand += (
String)
";drop table if exists save." + blockname;
1301 if (sqlite3_exec(db, sqlCommand.c_str(),NULL,NULL,&errmsg) != SQLITE_OK)
1303 std::cerr <<
"Couldn't attach or create table: " << errmsg << std::endl;
1307 sqlCommand = (
String)
"create table save." +blockname
1308 +
" as select * from main."+tableName(tableId);
1312 if (sqlite3_exec(db, sqlCommand.c_str(),NULL,NULL,&errmsg) != SQLITE_OK)
1314 std::cerr << (
String)
"Couldn't write table: " << blockname
1315 <<
" " << errmsg << std::endl;
1318 sqlite3_exec(db,
"DETACH save",NULL,NULL,&errmsg);
1322 bool MDSql::sqlBegin()
1324 if (table_counter > 0)
1327 rc = sqlite3_open(
"", &db);
1329 sqlite3_exec(db,
"PRAGMA temp_store=MEMORY",NULL, NULL, &errmsg);
1330 sqlite3_exec(db,
"PRAGMA synchronous=OFF",NULL, NULL, &errmsg);
1331 sqlite3_exec(db,
"PRAGMA count_changes=OFF",NULL, NULL, &errmsg);
1332 sqlite3_exec(db,
"PRAGMA page_size=4092",NULL, NULL, &errmsg);
1334 return sqlBeginTrans();
1339 if (sqlite3_busy_timeout(db, miliseconds) != SQLITE_OK)
1341 std::cerr <<
"Couldn't not set timeOut: " << std::endl;
1348 void MDSql::sqlEnd()
1355 bool MDSql::sqlBeginTrans()
1357 if (sqlite3_exec(db,
"BEGIN TRANSACTION", NULL, NULL, &errmsg) != SQLITE_OK)
1359 std::cerr <<
"Couldn't begin transaction: " << errmsg << std::endl;
1365 bool MDSql::sqlCommitTrans()
1369 if (sqlite3_exec(db,
"COMMIT TRANSACTION", NULL, NULL, &errmsg) != SQLITE_OK)
1371 std::cerr <<
"Couldn't commit transaction: " << errmsg << std::endl;
1377 bool MDSql::dropTable()
1379 std::stringstream ss;
1380 ss <<
"DROP TABLE IF EXISTS " << tableName(tableId) <<
";";
1381 return execSingleStmt(ss);
1384 bool MDSql::createTable(
const std::vector<MDLabel> * labelsVector,
bool withObjID)
1386 std::stringstream ss;
1387 ss <<
"CREATE TABLE " << tableName(tableId) <<
"(";
1388 std::string sep =
"";
1391 ss <<
"objID INTEGER PRIMARY KEY ASC AUTOINCREMENT";
1394 if (labelsVector != NULL)
1396 for (
size_t i = 0;
i < labelsVector->size();
i++)
1403 return execSingleStmt(ss);
1406 void MDSql::prepareStmt(
const std::stringstream &ss, sqlite3_stmt *stmt)
1408 const char * zLeftover;
1409 sqlite3_prepare_v2(db, ss.str().c_str(), -1, &stmt, &zLeftover);
1412 bool MDSql::execSingleStmt(
const std::stringstream &ss)
1415 sqlite3_stmt * stmt;
1416 sqlite3_prepare_v2(db, ss.str().c_str(), -1, &stmt, &zLeftover);
1421 std::cerr <<
"execSingleStmt, stmt: '" << ss.str() <<
"'" <<std::endl;
1425 bool r = execSingleStmt(stmt, &ss);
1426 sqlite3_finalize(stmt);
1430 bool MDSql::execSingleStmt(sqlite3_stmt * &stmt,
const std::stringstream *ss)
1433 rc = sqlite3_step(stmt);
1434 if (rc != SQLITE_OK && rc != SQLITE_ROW && rc != SQLITE_DONE)
1439 size_t MDSql::execSingleIntStmt(
const std::stringstream &ss)
1442 sqlite3_stmt * stmt;
1443 sqlite3_prepare_v2(db, ss.str().c_str(), -1, &stmt, &zLeftover);
1444 rc = sqlite3_step(stmt);
1445 size_t result = sqlite3_column_int(stmt, 0);
1447 if (rc != SQLITE_OK && rc != SQLITE_ROW && rc != SQLITE_DONE)
1449 std::cerr <<
"MDSql::execSingleIntStmt: error executing statement, code " << rc <<std::endl;
1452 sqlite3_finalize(stmt);
1456 double MDSql::execSingleDoubleStmt(
const std::stringstream &ss)
1459 sqlite3_stmt * stmt;
1460 sqlite3_prepare_v2(db, ss.str().c_str(), -1, &stmt, &zLeftover);
1461 rc = sqlite3_step(stmt);
1462 double result = sqlite3_column_double(stmt, 0);
1464 if (rc != SQLITE_OK && rc != SQLITE_ROW && rc != SQLITE_DONE)
1466 std::cerr <<
"MDSql::execSingleDoubleStmt: error executing statement, code " << rc <<std::endl;
1469 sqlite3_finalize(stmt);
1472 std::string MDSql::tableName(
const int tableId)
const 1474 std::stringstream ss;
1475 ss <<
"MDTable_" << tableId;
1479 bool MDSql::bindStatement(
size_t id)
1484 sqlite3_clear_bindings(this->preparedStmt);
1485 sqlite3_reset(this->preparedStmt);
1488 if (sqlite3_bind_int(this->preparedStmt, 1,
id) != SQLITE_OK)
1496 int MDSql::bindValue(sqlite3_stmt *stmt,
const int position,
const MDObject &valueIn)
1504 std::cerr <<
"WARNING!!! valueIn.failed = True, binding NULL" << std::endl;
1506 return sqlite3_bind_null(stmt, position);
1510 switch (valueIn.
type)
1513 return sqlite3_bind_int(stmt, position, valueIn.
data.
boolValue ? 1 : 0);
1515 return sqlite3_bind_int(stmt, position, valueIn.
data.
intValue);
1521 return sqlite3_bind_text(stmt, position, valueIn.
data.
stringValue->c_str(), -1, SQLITE_TRANSIENT);
1524 return sqlite3_bind_text(stmt, position, valueIn.
toString(
false,
true).c_str(), -1, SQLITE_TRANSIENT);
1531 void MDSql::extractValue(sqlite3_stmt *stmt,
const int position,
MDObject &valueOut)
1533 switch (valueOut.
type)
1536 valueOut.
data.
boolValue = sqlite3_column_int(stmt, position) == 1;
1539 valueOut.
data.
intValue = sqlite3_column_int(stmt, position);
1549 std::stringstream ss;
1550 ss << sqlite3_column_text(stmt, position);
1558 std::stringstream ss;
1559 ss << sqlite3_column_text(stmt, position);
1570 this->addRowStmt = NULL;
1571 this->iterStmt = NULL;
1582 std::map<MDLabel, sqlite3_stmt*>::iterator it;
1584 for (it = setValueCache.begin(); it != setValueCache.end(); it++)
1585 sqlite3_finalize(it->second);
1586 setValueCache.clear();
1588 for (it = getValueCache.begin(); it != getValueCache.end(); it++)
1589 sqlite3_finalize(it->second);
1590 getValueCache.clear();
1592 if (iterStmt != NULL)
1594 sqlite3_finalize(iterStmt);
1598 if (addRowStmt != NULL)
1600 sqlite3_finalize(addRowStmt);
String whereString() const
static MDLabel str2Label(const String &labelName)
#define REPORT_ERROR(nerr, ErrormMsg)
static bool isVector(const MDLabel label)
static String label2StrSql(const MDLabel label)
std::vector< String > StringVector
Error in SQL of MetaData operations.
bool fromStream(std::istream &is, bool fromString=false)
String orderByString() const
Incorrect argument received.
__host__ __device__ float length(float2 v)
void sort(struct DCEL_T *dcel)
String limitString() const
String toString(bool withFormat=false, bool isSql=false) const
static bool isString(const MDLabel label)
static String label2SqlColumn(const MDLabel label)
static bool isDouble(const MDLabel label)
String formatString(const char *format,...)
static String label2Str(const MDLabel &label)