ntuple_t.cc
Go to the documentation of this file.
1 // vim: set sw=2 expandtab :
2 
5 #include "cetlib/sqlite/Ntuple.h"
7 #include "cetlib/sqlite/select.h"
8 #include "hep_concurrency/simultaneous_function_spawner.h"
9 
10 #include "sqlite3.h"
11 
12 #include <assert.h>
13 #include <cstring>
14 #include <functional>
15 #include <iostream>
16 #include <vector>
17 
18 // We do not use Boost Unit Test here because we want the product into
19 // which this moves to be independent of Boost.
20 
21 using namespace cet::sqlite;
22 using namespace std;
23 
24 void
26 {
27  cout << "start test_with_new_database\n";
28  assert(c);
29  Ntuple<double, std::string> xx{c, "xx", {{"x", "txt"}}};
30  std::cout << "end test_with_new_database\n";
31 }
32 
33 void
35 {
36  cout << "start test_with_matching_table\n";
37  assert(c);
38  Ntuple<double, std::string> xx{c, "xx", {{"x", "txt"}}};
39  std::cout << "end test_with_matching_table\n";
40 }
41 
42 template <class... ARGS>
43 void
45  array<string, sizeof...(ARGS)> const& names)
46 {
47  cout << "start test_with_colliding_table\n";
48  assert(c);
49  try {
50  Ntuple<ARGS...> xx{c, "xx", names};
51  assert("Failed throw for mismatched table" == nullptr);
52  }
53  catch (Exception const& x) {
54  }
55  catch (...) {
56  assert("Threw wrong exception for mismatched table" == nullptr);
57  }
58  cout << "end test_with_colliding_table\n";
59 }
60 
61 int
62 count_rows(void* p, int nrows, char** results, char** cnames)
63 {
64  auto n = static_cast<int*>(p);
65  assert(nrows == 1);
66  assert(strcmp(cnames[0], "count(*)") == 0);
67  *n = stoi(results[0]);
68  return 0;
69 }
70 
71 void
73 {
74  cout << "start test_filling_table\n";
75  assert(c);
76  constexpr int nrows{903};
77  {
78  Ntuple<int, double> nt{c, "zz", {{"i", "x"}}, false, 100};
79  for (int i = 0; i < nrows; ++i) {
80  nt.insert(i, 1.5 * i);
81  }
82  }
83  query_result<int> nmatches;
84  nmatches << select("count(*)").from(c, "zz");
85  // Check that there are 'nrows' rows in the database.
86  assert(unique_value(nmatches) == nrows);
87  cout << "end test_filling_table\n";
88 }
89 
90 void
92 {
93  cout << "start test_parallel_filling_table\n";
94  assert(c);
95  constexpr int nrows_per_thread{100};
96  constexpr unsigned nthreads{10};
97  string const tablename{"zz"};
98  {
100  tablename,
101  {{"i", "x"}},
102  true,
103  60}; // Force flushing after 60 insertions.
104  std::vector<std::function<void()>> tasks;
105  for (unsigned i{}; i < nthreads; ++i) {
106  tasks.emplace_back([i, &nt] {
107  for (unsigned j{}; j < nrows_per_thread; ++j) {
108  auto const j1 = j + i * 100;
109  nt.insert(j1, 1.5 * j1);
110  }
111  });
112  }
113  hep::concurrency::simultaneous_function_spawner sfs{tasks};
114  }
115  query_result<int> nmatches;
116  nmatches << select("count(*)").from(c, tablename);
117  assert(unique_value(nmatches) == nrows_per_thread * nthreads);
118  cout << "end test_parallel_filling_table\n";
119 }
120 
121 void
123 {
124  cout << "start test_column_constraint\n";
125  assert(c);
126  Ntuple<column<int, primary_key>, double> nt{c, "u", {{"i", "x"}}};
127  auto const& ref = detail::create_table_ddl(
128  "u", column<int, primary_key>{"i"}, column<double>{"x"});
129  assert(hasTableWithSchema(c, "u", ref));
130  cout << "end test_column_constraint\n";
131 }
132 
133 void
135 {
136  string const filename{"myfile.db"};
137  remove(filename.c_str());
138  unique_ptr<Connection> c{cf.make_connection(filename)};
139  {
140  Ntuple<int, double, int> table{*c, "tab1", {{"i", "x", "k"}}, false, 5};
141  for (std::size_t i = 0; i < 103; ++i) {
142  table.insert(i, 0.5 * i, i * i);
143  }
144  }
145  query_result<int> cnt;
146  cnt << select("count(*)").from(*c, "tab1");
147  assert(unique_value(cnt) == 103);
148 }
149 
150 int
151 main() try {
152  const char* fname{"no_such_file.db"};
153  // If there is a database in the directory, delete it.
154  remove(fname);
155 
156  // Now make a database we are sure is empty.
158  auto c = cf.make_connection(fname);
159 
162  test_with_colliding_table<int, double>(*c, {{"y", "txt"}});
163  test_with_colliding_table<int, double>(*c, {{"x", "text"}});
164  test_with_colliding_table<int, int>(*c, {{"x", "txt"}});
165  test_with_colliding_table<int, double, int>(*c, {{"x", "txt", "z"}});
166  test_with_colliding_table<int>(*c, {{"x"}});
167  test_filling_table(*c);
170  test_file_create(cf);
171 }
172 catch (std::exception const& x) {
173  std::cout << x.what() << std::endl;
174  return 1;
175 }
176 catch (...) {
177  std::cout << "Unknown exception caught\n";
178  return 2;
179 }
void test_with_new_database(Connection &c)
Definition: ntuple_t.cc:25
bool hasTableWithSchema(sqlite3 *db, std::string const &tablename, std::string expectedSchema)
Definition: helpers.cc:29
T unique_value(query_result< T > const &r)
Definition: query_result.h:94
void test_with_matching_table(Connection &c)
Definition: ntuple_t.cc:34
void test_column_constraint(Connection &c)
Definition: ntuple_t.cc:122
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:27
STL namespace.
auto make_connection(std::string const &file_name, PolicyArgs &&...) -> Connection *
int main()
Definition: ntuple_t.cc:151
string filename
Definition: train.py:213
void test_file_create(ConnectionFactory &cf)
Definition: ntuple_t.cc:134
void test_parallel_filling_table(Connection &c)
Definition: ntuple_t.cc:91
std::void_t< T > n
p
Definition: test.py:223
std::string create_table_ddl(std::string const &tablename, Cols const &...cols)
Definition: create_table.h:96
int count_rows(void *p, int nrows, char **results, char **cnames)
Definition: ntuple_t.cc:62
auto select(T const &...t)
Definition: select.h:146
auto array(Array const &a)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:228
int strcmp(const String &s1, const String &s2)
Definition: relates.cpp:14
void test_filling_table(Connection &c)
Definition: ntuple_t.cc:72
list x
Definition: train.py:276
unsigned nrows(sqlite3 *db, std::string const &tablename)
Definition: helpers.cc:82
static std::vector< std::string > const names
Definition: FragmentType.hh:8
void test_with_colliding_table(Connection &c, array< string, sizeof...(ARGS)> const &names)
Definition: ntuple_t.cc:44
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
QTextStream & endl(QTextStream &s)