16 using namespace std::chrono_literals;
 
   25    bool database::debug = 
false;
 
   28    std::map<TString, KVSQLite::column_type::types> table::type_map;
 
   29    std::map<KVSQLite::column_type::types, TString> column::inv_type_map;
 
   45       TString _query = 
"SELECT " +  double_quote_all_tables_and_columns(columns) + 
" FROM " + double_quote_all_tables_and_columns(
table);
 
   46       if (condition != 
"") _query += 
" WHERE " + double_quote_all_tables_and_columns(condition);
 
   55    void database::read_table_infos()
 
   58       std::unique_ptr<TList> tl(fDBserv->GetTablesList());
 
   60       TIter it_tab(tl.get());
 
   61       while ((o = it_tab())) {
 
   65          std::unique_ptr<TSQLResult> columnRes(fDBserv->GetColumns(
"", o->
GetName()));
 
   66          if (!columnRes.get()) {
 
   67             Error(
"read_table_infos", 
"Cannot get information on columns for table %s", o->
GetName());
 
   70          std::unique_ptr<TSQLRow> columnRow(columnRes->Next());
 
   71          while ((columnRow.get()) != 
nullptr) {
 
   73             TString primary_key(columnRow->GetField(5));
 
   75             columnRow.reset(columnRes->Next());
 
   77          fTables.insert(std::pair<std::string, KVSQLite::table>(o->
GetName(), t));
 
   78          (*this)[t.
name()].fDB = 
this;
 
   81       for (
auto& 
p : fTables) {
 
   82          TString qry = 
Form(
"PRAGMA foreign_key_list('%s')", 
p.second.name());
 
   86          std::unique_ptr<TSQLRow> row(
result->Next());
 
   88             TString parent_table(row->GetField(2));
 
   89             TString child_key(row->GetField(3));
 
   90             TString parent_key(row->GetField(4));
 
   91             p.second.foreign_key(child_key, parent_table, parent_key);
 
   94          p.second.set_foreign_key_back_references();
 
  103    void database::show_tables()
 const 
  106       std::cout << 
"Tables in database:" << std::endl;
 
  107       for (
auto it = fTables.begin();
 
  108             it != fTables.end(); ++it) {
 
  109          std::cout << 
"\t" << it->first << std::endl;
 
  138          Error(
"open", 
"problem with SQLite database filename: %s", dbfile.
Data());
 
  142       TString uri = 
"sqlite://" + exp_path;
 
  143       fDBserv.reset(
new KVSQLiteServer(uri, 0, 0));
 
  145       if (!execute(
"pragma schema_version"))
 
  147          if(fDBserv->IsLocked())
 
  154                Info(
"open",
"Database is locked. Try again in 50ms...");
 
  155                std::this_thread::sleep_for(50ms);
 
  156                Info(
"open",
"Try number %d...",i);
 
  159             while(!execute(
"pragma schema_version") && fDBserv->IsLocked() && (i<6));
 
  160             if((i<6) && fDBserv->IsOK())
 
  162                Info(
"open",
"...database successfully opened");
 
  180    void database::PrintResults(
TSQLResult* tabent, 
int column_width)
 const 
  183       std::unique_ptr<TSQLRow> row(
nullptr);
 
  184       for (
int r = -1; 
true; ++
r) {
 
  186             row.reset(tabent->
Next());
 
  187             if (row.get() == 
nullptr) 
break;
 
  188             std::cout << std::setw(6) << 
r;
 
  190          for (
int f = 0; 
f < nfields; ++
f) {
 
  192                if (
f == 0) std::cout << std::setw(6) << 
"#";
 
  193                std::cout << 
"|" << std::setw(column_width) << tabent->
GetFieldName(
f) ;
 
  196                std::cout << 
"|" << std::setw(column_width) << row->GetField(
f) ;
 
  208    void database::Dump()
 const 
  212       std::cout << 
"Database : " << fDBserv->GetDB() << 
" [" << fDBserv->GetDBMS() << 
"]\n";
 
  213       std::unique_ptr<TList> tl(fDBserv->GetTablesList());
 
  215       TIter it_tab(tl.get());
 
  216       while ((o = it_tab())) {
 
  218          std::cout << 
"Table : " << o->
GetName() << 
"\n";
 
  219          std::unique_ptr<TSQLResult> tabent = SelectRowsFromTable(o->
GetName());
 
  220          PrintResults(tabent.get());
 
  222       std::cout << std::endl;
 
  233       std::unique_ptr<TSQLResult> tabent = SelectRowsFromTable(
table, columns, condition);
 
  234       PrintResults(tabent.get(), column_width);
 
  235       std::cout << std::endl;
 
  279          std::cout << command << std::endl;
 
  280       if (execute(command)) {
 
  281          fTables.insert(std::pair<std::string, KVSQLite::table>(t.
name(), t));
 
  282          (*this)[t.
name()].fDB = 
this;
 
  283          (*this)[t.
name()].set_foreign_key_back_references();
 
  285       return (*
this)[t.
name()];
 
  325       if(debug) 
Info(
"prepare_data_insertion",
"table=%s",
table.Data());
 
  328             Error(
"database::prepare_data_insertion",
 
  329                   "bulk insertion in progress for table %s; call database::commit() to terminate transaction",
 
  334             Error(
"database::prepare_data_insertion",
 
  335                   "bulk insertion in progress; call database::commit() to terminate transaction");
 
  340          Error(
"database::prepare_data_insertion",
 
  341                "data retrieval in progress; call get_next_result() until it returns false");
 
  345       fDBserv->StartTransaction();
 
  347       fBulkTable = &fTables[
table.Data()];
 
  348       TString com(fBulkTable->get_insert_command());
 
  349       int ncol = fBulkTable->number_of_columns();
 
  351       for (
int i = 0; i < ncol; ++i) {
 
  353          if (!(*fBulkTable)[i].rowid_alias()) {
 
  354             com += 
Form(
"\"%s\"", (*fBulkTable)[i].
name());;
 
  360       for (
int i = 0; i < ncol; ++i) {
 
  362          if (!(*fBulkTable)[i].rowid_alias()) {
 
  368       if(debug) std::cout << com << std::endl;
 
  369       return prepare_statement(com);
 
  399    bool database::prepare_data_insertion_selected_columns(
const TString& 
table)
 
  425       if(debug) 
Info(
"prepare_data_insertion_selected_columns",
"table=%s",
table.Data());
 
  428             Error(
"database::prepare_data_insertion",
 
  429                   "bulk insertion in progress for table %s; call database::commit() to terminate transaction",
 
  434             Error(
"database::prepare_data_insertion",
 
  435                   "bulk insertion in progress; call database::commit() to terminate transaction");
 
  440          Error(
"database::prepare_data_insertion",
 
  441                "data retrieval in progress; call get_next_result() until it returns false");
 
  445       fDBserv->StartTransaction();
 
  447       fBulkTable = &fTables[
table.Data()];
 
  448       TString com(fBulkTable->get_insert_command());
 
  449       int ncol = fBulkTable->number_of_columns();
 
  451       for (
int i = 0; i < ncol; ++i) {
 
  453          if (!(*fBulkTable)[i].rowid_alias() && (*fBulkTable)[i].has_data) {
 
  454             com += 
Form(
"\"%s\"", (*fBulkTable)[i].
name());;
 
  460       for (
int i = 0; i < ncol; ++i) {
 
  462          if (!(*fBulkTable)[i].rowid_alias() && (*fBulkTable)[i].has_data) {
 
  468       if(debug) std::cout << com << std::endl;
 
  469       return prepare_statement(com);
 
  476    const char* table::get_insert_command()
 const 
  480             return Form(
"INSERT OR FAIL INTO \"%s\"(", 
name());
 
  483             return Form(
"INSERT OR IGNORE INTO \"%s\"(", 
name());
 
  486             return Form(
"INSERT OR REPLACE INTO \"%s\"(", 
name());
 
  492       return Form(
"INSERT INTO \"%s\"(", 
name());
 
  511       decl.
Form(
"\"%s\" %s", 
name(), type_name());
 
  512       if (!fConstraint.IsNull()) {
 
  533    void database::insert_data_row()
 
  546       if (!fInserting || !fBulkTable) {
 
  547          Error(
"database::insert_data_row",
 
  548                "no transaction initialized; call prepare_data_insertion(name_table) before this method");
 
  552          Error(
"database::insert_data_row",
 
  553                "data retrieval in progress; call get_next_result() until it returns false, then call prepare_data_insertion(name_table) before this method");
 
  556       int ncol = fBulkTable->number_of_columns();
 
  557       fSQLstmt->NextIteration();
 
  559       for (
int i = 0; i < ncol; ++i) {
 
  560          if (!(*fBulkTable)[i].rowid_alias()) {
 
  561             (*fBulkTable)[i].set_data_in_statement(fSQLstmt.get(), idx);
 
  580    void database::insert_data_row_selected_columns()
 
  593       if (!fInserting || !fBulkTable) {
 
  594          Error(
"database::insert_data_row",
 
  595                "no transaction initialized; call prepare_data_insertion(name_table) before this method");
 
  599          Error(
"database::insert_data_row",
 
  600                "data retrieval in progress; call get_next_result() until it returns false, then call prepare_data_insertion(name_table) before this method");
 
  603       int ncol = fBulkTable->number_of_columns();
 
  604       fSQLstmt->NextIteration();
 
  606       for (
int i = 0; i < ncol; ++i) {
 
  607          if (!(*fBulkTable)[i].rowid_alias() && (*fBulkTable)[i].has_data) {
 
  608             (*fBulkTable)[i].set_data_in_statement(fSQLstmt.get(), idx);
 
  620    void database::end_data_insertion()
 
  625       if(debug) 
Info(
"end_data_insertion", 
"now");
 
  627          Error(
"database::end_data_insertion",
 
  628                "no transaction initialized; call prepare_data_insertion(name_table) first");
 
  632          Error(
"database::insert_data_row",
 
  633                "data retrieval in progress; call get_next_result() until it returns false, then call prepare_data_insertion(name_table) before this method");
 
  636       fBulkTable = 
nullptr;
 
  646    void database::print_selected_data(
const TString& tables, 
const TString& columns, 
const TString& selection, 
bool distinct, 
const TString& anything_else)
 
  650       if (select_data(tables, columns, selection, distinct, anything_else)) {
 
  652          std::vector<TString> col_titles;
 
  653          std::vector<int> col_width;
 
  654          std::for_each(std::begin(fSQLstmtCols), std::end(fSQLstmtCols),
 
  655                        [&col_titles, &col_width]
 
  662          using data_row = std::vector<TString>;
 
  663          std::vector<data_row> col_data;
 
  664          while (get_next_result()) {
 
  665             data_row current_data_row;
 
  667             std::for_each(std::begin(fSQLstmtCols), std::end(fSQLstmtCols),
 
  668                           [&col_index, &col_width, ¤t_data_row]
 
  671                col_width[col_index] = std::max(current_data_row[col_index].Length(), col_width[col_index]);
 
  675             col_data.push_back(current_data_row);
 
  677          auto print_line = [&col_width]() {
 
  678             for (
auto width : col_width) {
 
  680                for (
int i = 0; i <= 
width; ++i) std::cout << 
"-";
 
  684          auto print_column_item = [](
const TString & item, 
int width, 
bool end_line = 
false) {
 
  685             std::cout << 
"| " << item;
 
  686             for (
int i = 0; i <= 
width - item.Length(); ++i)
 
  691          auto print_column_data = [&col_width, &print_column_item](
const std::vector<TString>& cols) {
 
  693             int ncols = cols.size();
 
  694             for (
auto& col : cols) {
 
  695                print_column_item(col, col_width[col_index], (col_index == ncols - 1));
 
  698             std::cout << std::endl;
 
  701          print_column_data(col_titles);
 
  703          for (
auto& row : col_data) print_column_data(row);
 
  712    std::list<const table*> database::generate_table_selection_string(
const TString& tables, 
KVString& table_selection)
 const 
  714       std::list<const table*> table_list;
 
  719       std::unordered_map<std::string, int> table_names;
 
  720       while (!_tables.
End()) {
 
  722          table_list.push_back(& 
operator[](tabnam));
 
  724             table_selection += 
" INNER JOIN \"" + tabnam + 
"\"";
 
  726             auto this_table = table_list.back();
 
  727             if (this_table->has_foreign_keys(
false)) { 
 
  729                for (
auto& 
f : this_table->fForeignKeys) {
 
  731                   if (table_names[
f.parent_table.Data()]) {
 
  732                      table_selection += 
Form(
" %s %s.%s = %s.%s",
 
  734                                              this_table->name(), 
f.child_key.Data(),
 
  735                                              f.parent_table.Data(), 
f.parent_key.Data());
 
  742             table_selection += 
"\"" + tabnam + 
"\"";
 
  743          ++table_names[tabnam.
Data()];
 
  755        auto replacer = [&](
const KVString& repl)
 
  762               auto tok = repl.Next();
 
  763               if(replaced.
Length()) replaced+=
" ";
 
  764               bool stop_replacing=
false;
 
  765               for (
auto& tp : fTables)
 
  767                  TString table_name = tp.second.name();
 
  768                  if(tok == table_name)
 
  775                  for (
auto& 
c : tp.second.fColumns)
 
  778                     if(tok == column_name)
 
  786                  if(stop_replacing) 
break;
 
  799            auto part = _input.
Next();
 
  802                output += replacer(part);
 
  806                output += 
"'" + part + 
"'";
 
  808            in_quotes = !in_quotes;
 
  856       if(debug) 
Info(
"select_data",
"tables=%s columns=%s selection=%s anything_else=%s",
 
  859          Error(
"database::select_data",
 
  860                "data insertion in progress; call end_data_insertion() before retrieving data");
 
  864          Error(
"database::select_data",
 
  865                "data retrieval already in progress; call get_next_result() until it returns false before making new selection");
 
  869       fSQLstmtCols.clear();
 
  872       std::list<const table*> table_list = generate_table_selection_string(tables, table_selection);
 
  874       KVString column_selection(
""), _columns(columns);
 
  875       if (columns == 
"*") {
 
  876          column_selection = 
"*";
 
  880          for (
auto tabs : table_list) {
 
  881             for (
int i = 0; i < tabs->number_of_columns(); ++i) {
 
  882                fSQLstmtCols.push_back(&(*tabs)[i]);
 
  887          if (distinct) column_selection = 
"DISTINCT ";
 
  890          while (!_columns.
End()) {
 
  892             if (i) column_selection += 
", ";
 
  899                column_selection += 
Form(
"%s", colnam.
Data());
 
  900                fSQLstmtCols.push_back(&count_column);
 
  904                column_selection += 
Form(
"\"%s\"", colnam.
Data());
 
  905                for (
auto tabs : table_list)
 
  906                   if (tabs->has_column(colnam)) fSQLstmtCols.push_back(&(*tabs)[colnam]);
 
  911       TString cond = 
Form(
"SELECT %s FROM %s", column_selection.Data(), table_selection.
Data());
 
  912       if (selection != 
""){
 
  914           cond += 
" WHERE " + double_quote_all_tables_and_columns(selection);
 
  916       if (anything_else != 
"") {
 
  918          cond += 
" " + double_quote_all_tables_and_columns(anything_else);
 
  921          std::cout << cond << std::endl;
 
  922       prepare_statement(cond);
 
  923       if (fSQLstmt.get() == 
nullptr) {
 
  924          Error(
"database::select_data", 
"problem processing : %s", cond.
Data());
 
  926          fBulkTable = 
nullptr;
 
  929       fSQLstmt->EnableErrorOutput();
 
  930       if (fSQLstmt->Process()) {
 
  931          fSQLstmt->StoreResult();
 
  933          fEmptyResultSet = 
false;
 
  936       else if (!fSQLstmt->IsError()) {
 
  938          fSQLstmt->StoreResult();
 
  940          fEmptyResultSet = 
true;
 
  944       fBulkTable = 
nullptr;
 
  954    bool database::get_next_result()
 const 
  959       if(debug) 
Info(
"get_next_result",
"now");
 
  961          Error(
"database::get_next_result",
 
  962                "data insertion in progress; call end_data_insertion() then select_data() before this method");
 
  966          Error(
"database::get_next_result",
 
  967                "no data retrieval in progress; select_data() must be called and return true before calling this method");
 
  970       if (!fEmptyResultSet && fSQLstmt->NextResultRow()) {
 
  973          for (
auto col : fSQLstmtCols) {
 
  974             col->set_data_from_statement(fSQLstmt.get(), idx);
 
  979       fBulkTable = 
nullptr;
 
  996            Error(
"database::get_integer_list", 
"Only 1 column name at a time please!");
 
 1000       if (select_data(tables, 
column, selection, 
true, anything_else)) {
 
 1001           auto column_data = fSQLstmtCols.front();
 
 1002          while (get_next_result()) {
 
 1003             result.Add(column_data->get_data<
int>());
 
 1022        if(
column.Contains(
",")){
 
 1023            Error(
"database::get_string_list", 
"Only 1 column name at a time please!");
 
 1027       if (select_data(tables, 
column, selection, 
false, anything_else)) {
 
 1028           auto column_data = fSQLstmtCols.front();
 
 1029          while (get_next_result()) {
 
 1030             if (column_data->is_null()) 
continue;
 
 1052       if (select_data(tablename, 
Form(
"%s,%s", name_column.
Data(), value_column.
Data()), selection, 
false, anything_else)) {
 
 1053          auto it = fSQLstmtCols.begin();
 
 1056          while (get_next_result()) {
 
 1074       if (select_data(tablename, 
Form(
"%s,%s", Xcolumn.
Data(), Ycolumn.
Data()), selection)) {
 
 1077          auto it = fSQLstmtCols.begin();
 
 1080          while (get_next_result()) {
 
 1081             g->SetPoint(i++, Xcol->get_data<
double>(), Ycol->get_data<
double>());
 
 1148       if(debug) 
Info(
"count",
"tables=%s column=%s selection=%s anything_else=%s",
 
 1150       TString qry = 
"SELECT count(";
 
 1151       if(distinct && 
column!=
"*") qry += 
"DISTINCT ";
 
 1156       generate_table_selection_string(tables, table_selection);
 
 1157       qry += table_selection;
 
 1158       if (selection != 
"") {
 
 1159          qry += 
" WHERE " + double_quote_all_tables_and_columns(selection);
 
 1161       if (anything_else != 
"") {
 
 1162          qry += 
" " + double_quote_all_tables_and_columns(anything_else);
 
 1164       if(debug) std::cout << qry << std::endl;
 
 1165       auto result = query(qry);
 
 1166       std::unique_ptr<TSQLRow> row(
result->Next());
 
 1167       TString number = row->GetField(0);
 
 1168       return number.
Atoi();
 
 1192       if(debug) 
Info(
"update",
"table=%s columns=%s selection=%s",
table.Data(),columns.
Data(),selection.
Data());
 
 1194          Error(
"database::update",
 
 1195                "data insertion in progress; call end_data_insertion() before doing anything else");
 
 1199          Error(
"database::update",
 
 1200                "data retrieval in progress; call get_next_result() until it returns false before doing anything else");
 
 1204       fBulkTable = &fTables[
table.Data()];
 
 1206       int ncol = fBulkTable->number_of_columns();
 
 1208       for (
int i = 0; i < ncol; ++i) {
 
 1209          if (columns.
Contains((*fBulkTable)[i].name())) {
 
 1210             if (idx) query += 
",";
 
 1211             query += 
Form(
"\"%s\"", (*fBulkTable)[i].
name());
 
 1216       if (selection != 
"") query += 
" WHERE " + double_quote_all_tables_and_columns(selection);
 
 1217       if(debug) std::cout << query << std::endl;
 
 1218       if(!prepare_statement(query))
 
 1220       fSQLstmt->NextIteration();
 
 1222       for (
int i = 0; i < ncol; ++i) {
 
 1223          if (columns.
Contains((*fBulkTable)[i].name())) {
 
 1224             (*fBulkTable)[i].set_data_in_statement(fSQLstmt.get(), idx);
 
 1228       return (fSQLstmt->Process());
 
 1272       if(debug) 
Info(
"delete_data",
"table=%s selection=%s",
 
 1275       if (selection != 
"") query += 
" WHERE " + double_quote_all_tables_and_columns(selection);
 
 1306          Error(
"database::add_missing_columns",
 
 1307                "data insertion in progress; call end_data_insertion() before doing anything else");
 
 1311          Error(
"database::add_missing_columns",
 
 1312                "data retrieval in progress; call get_next_result() until it returns false before doing anything else");
 
 1315       int ipar = 
l.GetNpar();
 
 1316       table& tab = (*this)[_table_];
 
 1317       for (
int i = 0; i < ipar; ++i) {
 
 1343       if (COLUMNS != 
"*") {
 
 1347          _columns.
Begin(
",");
 
 1348          while (!_columns.
End()) {
 
 1349             if (COLUMNS != 
"") COLUMNS += 
", ";
 
 1353       TString query = 
Form(
"INSERT INTO \"%s\" SELECT %s FROM \"%s\"", destination.
Data(), COLUMNS.
Data(), source.
Data());
 
 1354       if (selection != 
"") query += 
" WHERE " + double_quote_all_tables_and_columns(selection);
 
 1362    void column::init_type_map()
 
 1377       return inv_type_map[fNameType.second];
 
 1386       fData.Set(
x.GetName(), 
x);
 
 1406       if (idx < 0) idx = 
index();
 
 1414             s->SetDouble(idx, fData.GetDouble());
 
 1417             s->SetInt(idx, fData.GetInt());
 
 1421             s->SetString(idx, fData.GetString(), -1);
 
 1424             s->SetBinary(idx, fBlob, fBlobSize);
 
 1455       if (idx < 0) idx = 
index();
 
 1456       fIsNull = s->IsNull(idx);
 
 1459             fData.Set(fIsNull ? 0.0 : s->GetDouble(idx));
 
 1462             fData.Set(fIsNull ? 0 : s->GetInt(idx));
 
 1466             fData.Set(fIsNull ? 
"" : s->GetString(idx));
 
 1473                if (!fBlob) fBlob = (
void*) 
new unsigned char[256];
 
 1474                s->GetBinary(idx, fBlob, fBlobSize);
 
 1494       if (fData.IsString()) {
 
 1495          auto r = fData.GetTString();
 
 1496          r.ReplaceAll(
"''", 
"~#%"); 
 
 1497          r.ReplaceAll(
"'", 
"''");
 
 1498          r.ReplaceAll(
"~#%", 
"''"); 
 
 1499          return Form(
"'%s'", 
r.Data());
 
 1501       return fData.GetTString();
 
 1508    void table::init_type_map()
 
 1525    void table::set_foreign_key_back_references()
 
 1532       for (
auto& 
f : fForeignKeys)
 
 1533          fDB->get_table(
f.parent_table).fForeignKeys.push_back({
f.parent_key, 
name(), 
f.child_key, 
true});
 
 1565       if (is_temporary()) command += 
"TEMPORARY ";
 
 1567       command += 
"TABLE ";
 
 1568       command += 
"\"" + fName + 
"\"";
 
 1570       for (
int i = 0; i < number_of_columns(); ++i) {
 
 1572          command += fColumns[i].get_declaration();
 
 1573          if (i < number_of_columns() - 1) command += 
",";
 
 1575       if (has_primary_key()) {
 
 1576          command += 
",\n   PRIMARY KEY(";
 
 1577          command += 
"\"" + fPrimaryKey + 
"\"";
 
 1580       if (has_foreign_keys()) {
 
 1582          for (
auto& fk : fForeignKeys) {
 
 1583             command += 
",\n   FOREIGN KEY(";
 
 1584             command += 
"\"" + fk.child_key + 
"\"";
 
 1585             command += 
") REFERENCES ";
 
 1586             command += 
"\"" + fk.parent_table + 
"\"";
 
 1587             if (!fk.parent_key.IsNull()) {
 
 1589                command += 
"\"" + fk.parent_key + 
"\"";
 
 1603    void table::show_columns()
 const 
 1606       std::cout << 
"Columns in table:" << std::endl;
 
 1608       for (
auto it = fColumns.begin(); it != fColumns.end(); ++it) {
 
 1610       for (std::vector<KVSQLite::column>::const_iterator it = fColumns.begin(); it != fColumns.end(); ++it) {
 
 1612          std::cout << 
"\t" << it->name() << 
" [" << it->type_name() << 
"]" << std::endl;
 
 1628       fColumns.push_back(
c);
 
 1629       fColMap[
c.name()] = 
c.index();
 
 1630       fColumns.back().set_table(
name());
 
 1631       return fColumns.back();
 
 1646       return add_column(
name, type_map[
type]);
 
 1698       KVString check_columns = child_key;
 
 1699       check_columns.
Begin(
",");
 
 1701       while (!check_columns.
End()) {
 
 1703          if (!has_column(nxt)) {
 
 1704             Error(
"table::foreign_key", 
"Child key \"%s\" has not being declared with add_column()", nxt.Data());
 
 1709       fForeignKeys.push_back({child_key, parent_table, parent_key});
 
 1724       int ipar = 
l.GetNpar();
 
 1725       for (
int i = 0; i < ipar; ++i) {
 
 1727          if (!has_column(par->
GetName())) ncols++;
 
 1749       for (
int i = 0; i < number_of_columns(); ++i) {
 
 1751          if (
p && !(null_value && 
p->HasSameValueAs(*null_value)))
 
 1752             (*
this)[i].set_data(*
p);
 
 1754             (*
this)[i].set_null();
 
 1763    void table::set_all_columns_null()
 
 1766       for (
int i = 0; i < number_of_columns(); ++i) {
 
 1767          (*this)[i].set_null();
 
 1788       for (
int i = 0; i < number_of_columns(); ++i) {
 
 1791          if (added) namelist += delim;
 
 1810    void table::prepare_insert_single_row()
 
 1821       for (
auto& col : fColumns) col.has_data = 
false;
 
 1829    void table::insert_single_row()
 
 1833       if(database::debug) 
Info(
"insert_single_row",
"table=%s",
name());
 
 1834       TString query = get_insert_command();
 
 1836       for (
auto& col : fColumns) {
 
 1838             if (ncols) query += 
",";
 
 1839             query += 
"\"" + col.Name() + 
"\"";
 
 1843       query += 
") VALUES (";
 
 1845       for (
auto& col : fColumns) {
 
 1847             if (ncols) query += 
",";
 
 1848             query += col.get_data_string_for_insert();
 
 1853       if(database::debug) std::cout << query << std::endl;
 
 1854       fDB->execute(query);
 
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void input
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t g
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
char * Form(const char *fmt,...)
R__EXTERN TSystem * gSystem
Handles lists of named parameters with different types, a list of KVNamedParameter objects.
A generic named parameter storing values of different types.
const Char_t * GetSQLType() const
TString GetTString() const
Strings used to represent a set of ranges of values.
const char * name() const
const KVNamedParameter & data() const
TString get_table() const
Interface to ROOT SQLite database backend.
KVString double_quote_all_tables_and_columns(const TString &) const
const char * name() const
void primary_key(const TString &cols)
column & add_column(const KVSQLite::column &c)
TString get_table_creation_command() const
bool has_column(const TString &name) const
Extension of ROOT TString class which allows backwards compatibility with ROOT v3....
void Begin(TString delim) const
KVString Next(Bool_t strip_whitespace=kFALSE) const
const char * GetName() const override
virtual const char * GetName() const
virtual const char * GetFieldName(Int_t field)=0
virtual TSQLRow * Next()=0
virtual Int_t GetFieldCount()=0
const char * Data() const
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
void Form(const char *fmt,...)
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
virtual char * ExpandPathName(const char *path)