insert.h
Go to the documentation of this file.
1 #ifndef cetlib_sqlite_insert_h
2 #define cetlib_sqlite_insert_h
3 
4 // ====================================================================
5 //
6 // The insert_into facility provides a means of ensuring, in a
7 // type-safe manner, the insertion of values into an already-existing
8 // database table.
9 //
10 // The encouraged usage pattern is:
11 //
12 // using namespace cet::sqlite;
13 // create_table(db, "workers", column<int>{"id"}, column<string>{"name"});
14 // insert_into(db, "workers").values(24, "Billy");
15 // insert_into(db, "workers").values(17, "Jenny");
16 //
17 // Extensive usage of insert_into(...) may be inefficient as each call
18 // prepares a statement, executes it, and then finalizes it. To
19 // support more efficient insertion, consider using the Ntuple
20 // facility.
21 //
22 // --------------------------------------------------------------------
23 //
24 // Technical considerations:
25 //
26 // - It is not difficult to expand the functionality of insert_into
27 // to support inserting into specific columns (as is supported with
28 // a bare SQLite insert statement), should it be requested.
29 // - It should be determined whether a simple-enough syntax can be
30 // developed to support insert statements with placeholders.
31 //
32 // ====================================================================
33 
34 #include <iomanip>
35 #include <iostream>
36 #include <ostream>
37 #include <sstream>
38 #include <string>
39 #include <vector>
40 
41 #include "cetlib/sqlite/exec.h"
42 #include "sqlite3.h"
43 
44 namespace cet::sqlite {
45  namespace detail {
46  inline std::string
48  {
49  return "\"" + s + "\"";
50  }
51 
52  inline std::string
53  maybe_quote(char const* s)
54  {
55  return maybe_quote(std::string{s});
56  }
57 
58  template <typename T>
59  T
60  maybe_quote(T const& t)
61  {
62  return t;
63  }
64 
65  inline void
66  values_str_impl(std::ostream&)
67  {}
68 
69  template <typename H, typename... T>
70  void
71  values_str_impl(std::ostream& os, H const& h, T const&... t)
72  {
73  if (sizeof...(T) != 0u) {
74  os << maybe_quote(h) << ',';
75  values_str_impl(os, t...);
76  } else
77  os << maybe_quote(h);
78  }
79 
80  template <typename... Args>
82  values_str(Args const&... args)
83  {
84  std::ostringstream oss;
85  values_str_impl(oss, args...);
86  return oss.str();
87  }
88  }
89 
91  IncompleteInsert(sqlite3* const db, std::string&& ddl)
92  : db_{db}, ddl_{std::move(ddl)}
93  {}
94 
95  template <typename... T>
96  void
97  values(T const&... t) &&
98  {
99  ddl_ += " values (";
100  ddl_ += detail::values_str(t...);
101  ddl_ += ");";
102  exec(db_, ddl_);
103  }
104 
105  sqlite3* const db_;
107  };
108 
109  inline auto
110  insert_into(sqlite3* const db, std::string const& tablename)
111  {
112  std::string result{"insert into " + tablename};
113  return IncompleteInsert{db, std::move(result)};
114  }
115 
116 } // cet::sqlite
117 
118 #endif /* cetlib_sqlite_insert_h */
119 
120 // Local variables:
121 // mode: c++
122 // End:
auto insert_into(sqlite3 *const db, std::string const &tablename)
Definition: insert.h:110
const XML_Char * s
Definition: expat.h:262
void values_str_impl(std::ostream &)
Definition: insert.h:66
IncompleteInsert(sqlite3 *const db, std::string &&ddl)
Definition: insert.h:91
void values(T const &...t)&&
Definition: insert.h:97
double T
Definition: Xdiff_gwt.C:5
void exec(sqlite3 *db, std::string const &ddl)
std::string values_str(Args const &...args)
Definition: insert.h:82
std::string maybe_quote(std::string const &s)
Definition: insert.h:47
enum BeamMode string