Functions
connection_t.cc File Reference
#include "boost/filesystem.hpp"
#include "cetlib/sqlite/ConnectionFactory.h"
#include "cetlib/sqlite/Ntuple.h"
#include "cetlib/sqlite/create_table.h"
#include "hep_concurrency/simultaneous_function_spawner.h"
#include <cassert>
#include <iostream>
#include <memory>
#include <string>
#include <vector>

Go to the source code of this file.

Functions

int main ()
 

Function Documentation

int main ( void  )

Definition at line 21 of file connection_t.cc.

22 {
23  try {
25  // Simple connection to "a.db"
26  {
27  string const f{"a.db"};
28  unique_ptr<Connection> c{cf.make_connection(f)};
29  create_table(*c, "onlyOne", column<int>{"numbers"});
30  bfs::path const p{f};
31  assert(bfs::exists(p));
32  }
33  // Simple connection to in-memory database
34  {
35  unique_ptr<Connection> c{cf.make_connection(":memory:")};
36  create_table(*c, "onlyOne", column<int>{"numbers"});
38  r << select("*").from(*c, "onlyOne");
39  assert(r.empty());
40  }
41  // Separate connections to "b.db" and "c.db"
42  {
43  string const f1{"b.db"};
44  string const f2{"c.db"};
45  unique_ptr<Connection> c1{cf.make_connection(f1)};
46  unique_ptr<Connection> c2{cf.make_connection(f2)};
47  create_table(*c1, "separate", column<int>{"numbers"});
48  create_table(*c2, "separate", column<int>{"numbers"});
49  bfs::path const p1{f1};
50  bfs::path const p2{f2};
51  assert(bfs::exists(p1));
52  assert(bfs::exists(p2));
53  }
54  auto test_colliding_tables = [&cf](string const& dbname) {
55  unique_ptr<Connection> c1{cf.make_connection(dbname)};
56  unique_ptr<Connection> c2{cf.make_connection(dbname)};
57  create_table(*c1, "colliding", column<int>{"numbers"});
58  try {
59  create_table(*c2, "colliding", column<int>{"numbers"});
60  }
61  catch (Exception const& e) {
62  assert(e.categoryCode() == errors::SQLExecutionError);
63  assert(string{e.what()}.find("table colliding already exists") !=
64  string::npos);
65  }
66  };
67  // Separate connections to same database "d.db"
68  {
69  string const f{"d.db"};
70  test_colliding_tables(f);
71  bfs::path const p{f};
72  assert(bfs::exists(p));
73  }
74  // Separate connections to same database in-memory database
75  test_colliding_tables(":memory:");
76  // Test concurrent creation of connections to the same database.
77  {
78  ConnectionFactory sharedFactory;
79  string const f{"e.db"};
80  auto makeConnection = [&sharedFactory, &f] {
81  sharedFactory.make_connection(f);
82  };
83  simultaneous_function_spawner launch{repeated_task(10u, makeConnection)};
84  bfs::path const p{f};
85  assert(bfs::exists(p));
86  }
87  // Test concurrent insertion into different tables, using
88  // different connections that refer to the same database.
89  // - Force flush after each insertion to test thread-safety of
90  // concurrent writes to the same database.
91  {
92  std::string const f{"f.db"};
93  auto c1 = cf.make_connection(f);
94  auto c2 = cf.make_connection(f);
95  Ntuple<int> n1{*c1, "Odds", {{"Number"}}};
96  Ntuple<int> n2{*c2, "Evens", {{"Number"}}};
97  std::vector<std::function<void()>> tasks;
98  for (unsigned i{1}; i < 6u; ++i) {
99  tasks.push_back([&n1, i] {
100  n1.insert(2 * i - 1);
101  n1.flush();
102  });
103  tasks.push_back([&n2, i] {
104  n2.insert(2 * i);
105  n2.flush();
106  });
107  }
108  simultaneous_function_spawner launch{tasks};
109  query_result<int> sum_odds;
110  sum_odds << select("sum(Number)").from(*c1, "Odds");
111  query_result<int> sum_evens;
112  sum_evens << select("sum(Number)").from(*c2, "Evens");
113  assert(unique_value(sum_odds) == 25);
114  assert(unique_value(sum_evens) == 30);
115  }
116  }
117  catch (exception const& e) {
118  cerr << e.what() << '\n';
119  return 1;
120  }
121  catch (...) {
122  cerr << "Caught unknown exception.\n";
123  return 2;
124  }
125 }
T unique_value(query_result< T > const &r)
Definition: query_result.h:94
std::string string
Definition: nybbler.cc:12
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:27
auto make_connection(std::string const &file_name, PolicyArgs &&...) -> Connection *
bool exists(std::string path)
const double e
void create_table(sqlite3 *const db, std::string const &tablename, Cols const &...cols)
Definition: create_table.h:118
p
Definition: test.py:223
auto select(T const &...t)
Definition: select.h:146
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33