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 <iostream>
35 #include <ostream>
36 #include <sstream>
37 #include <string>
38 #include <vector>
39 
40 #include "cetlib/sqlite/exec.h"
41 #include "sqlite3.h"
42 
43 namespace cet {
44  namespace sqlite {
45  namespace detail {
46 
47  inline std::string
48  maybe_quote(char const* s)
49  {
50  return "\"" + std::string{s} + "\"";
51  }
52 
53  inline std::string
55  {
56  return "\"" + s + "\"";
57  }
58 
59  template <typename T>
60  T
61  maybe_quote(T const& t)
62  {
63  return t;
64  }
65 
66  inline void
67  values_str_impl(std::ostream&)
68  {}
69 
70  template <typename H, typename... T>
71  void
72  values_str_impl(std::ostream& os, H const& h, T const&... t)
73  {
74  if (sizeof...(T) != 0u) {
75  os << maybe_quote(h) << ',';
76  values_str_impl(os, t...);
77  } else
78  os << maybe_quote(h);
79  }
80 
81  template <typename... Args>
83  values_str(Args const&... args)
84  {
85  std::ostringstream oss;
86  values_str_impl(oss, args...);
87  return oss.str();
88  }
89  }
90 
92 
93  IncompleteInsert(sqlite3* const db, std::string&& ddl)
94  : db_{db}, ddl_{std::move(ddl)}
95  {}
96 
97  template <typename... T>
98  void
99  values(T const&... t) &&
100  {
101  ddl_ += " values (";
102  ddl_ += detail::values_str(t...);
103  ddl_ += ");";
104  exec(db_, ddl_);
105  }
106 
107  sqlite3* const db_;
109  };
110 
111  inline auto
112  insert_into(sqlite3* const db, std::string const& tablename)
113  {
114  std::string result{"insert into " + tablename};
115  return IncompleteInsert{db, std::move(result)};
116  }
117 
118  } // sqlite
119 } // cet
120 
121 #endif /* cetlib_sqlite_insert_h */
122 
123 // Local variables:
124 // mode: c++
125 // End:
auto insert_into(sqlite3 *const db, std::string const &tablename)
Definition: insert.h:112
const XML_Char * s
Definition: expat.h:262
void values_str_impl(std::ostream &)
Definition: insert.h:67
std::string maybe_quote(char const *s)
Definition: insert.h:48
IncompleteInsert(sqlite3 *const db, std::string &&ddl)
Definition: insert.h:93
void values(T const &...t)&&
Definition: insert.h:99
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:83
enum BeamMode string