Connection.h
Go to the documentation of this file.
1 #ifndef cetlib_sqlite_Connection_h
2 #define cetlib_sqlite_Connection_h
3 
4 // ====================================================================
5 // A Connection is an RAII-motivated class that automatically handles
6 // opening and closing of the database handle.
7 //
8 // It receives a template argument that specifies the database-opening
9 // policy. The database closing policy is sqlite3_close(db).
10 //
11 // Note that whenever a Connection object is created, database locking
12 // is automatically disabled to accommodate operations on NFS systems.
13 // The Connection is created by the ConnectionFactory, which
14 // constructs a Connection in a thread-safe way. However, when using
15 // a connection, the user must ensure that updates to the same
16 // database via Connection objects is serialized.
17 // ====================================================================
18 
21 #include "sqlite3.h"
22 
23 #include <memory>
24 #include <mutex>
25 #include <string>
26 #include <vector>
27 
28 namespace cet {
29  namespace sqlite {
30 
31  class Connection {
32  public:
33  // It is permitted to create an invalid Connection object
34  // through default construction. However, any connections to an
35  // SQLite database must be retrieved through the
36  // ConnectionFactory.
37  explicit Connection() = default;
38  ~Connection() noexcept;
39 
40  sqlite3*
41  get() const
42  {
43  return db_;
44  }
45  operator sqlite3*() { return db_; }
46 
47  template <std::size_t NColumns, typename Row>
48  int flush_no_throw(std::vector<Row> const& buffer,
49  sqlite3_stmt*& insertStmt);
50 
51  // Non-copyable
52  Connection(Connection const&) = delete;
53  Connection& operator=(Connection const&) = delete;
54 
55  Connection(Connection&&) noexcept;
56  Connection& operator=(Connection&&) noexcept;
57 
58  private:
59  template <typename DatabaseOpenPolicy>
60  explicit Connection(std::string const& file_name,
61  std::shared_ptr<std::mutex> m,
62  DatabaseOpenPolicy);
63  friend class ConnectionFactory;
64 
65  sqlite3* db_{nullptr};
66  std::shared_ptr<std::mutex> m_{
67  nullptr}; // Shared with other connections to the same database
68  };
69 
70  } // namespace sqlite
71 } // cet
72 
73 template <typename DatabaseOpenPolicy>
75  std::shared_ptr<std::mutex> m,
76  DatabaseOpenPolicy policy)
77  : m_{m}
78 {
79  // No lock necessary since the c'tor is called in a protected
80  // environment.
81  db_ = policy.open(file_name);
82 }
83 
84 template <std::size_t NColumns, typename Row>
85 int
87  sqlite3_stmt*& insertStmt)
88 {
89  // Guard against concurrent updates to the same database.
90  std::lock_guard<decltype((*m_))> hold{*m_};
92  for (auto const& r : buffer) {
94  int const rc{sqlite3_step(insertStmt)};
95  if (rc != SQLITE_DONE) {
96  return rc;
97  }
98  sqlite3_reset(insertStmt);
99  }
100  txn.commit();
101  return SQLITE_DONE;
102 }
103 
104 #endif /* cetlib_sqlite_Connection_h */
105 
106 // Local Variables:
107 // mode: c++
108 // End:
::xsd::cxx::tree::buffer< char > buffer
Definition: Database.h:179
::xsd::cxx::tree::string< char, simple_type > string
Definition: Database.h:154
int flush_no_throw(std::vector< Row > const &buffer, sqlite3_stmt *&insertStmt)
Definition: Connection.h:86
TRandom3 r(0)
std::shared_ptr< std::mutex > m_
Definition: Connection.h:66
static void bind(sqlite3_stmt *s, TUP const &t)
Connection & operator=(Connection const &)=delete