sql.cpp
Go to the documentation of this file.
1 // License: Apache 2.0. See LICENSE file in root directory.
2 // Copyright(c) 2019 Intel Corporation. All Rights Reserved.
3 #include "sql.h"
4 #include "../third-party/sqlite/sqlite3.h"
5 #include <stdexcept>
6 #include <cstring>
7 #include <thread>
8 
9 using namespace std;
10 
11 namespace sql
12 {
13  template<class T>
14  int do_with_retries(T action, int max_retries = 1000)
15  {
16  int result;
17  auto retries = 0;
18  do
19  {
20  result = action();
21  if (result == SQLITE_BUSY)
22  std::this_thread::sleep_for(std::chrono::milliseconds(100));
23  } while (result == SQLITE_BUSY && ++retries < max_retries);
24 
25  if (result == SQLITE_BUSY)
26  {
27  result = SQLITE_BUSY;
28  }
29 
30  return result;
31  }
32 
33  void connection_handle_traits::close(ptr value)
34  {
35  if (SQLITE_OK != do_with_retries([&]() { return sqlite3_close(value); }))
36  {
37  throw runtime_error(sqlite3_errmsg(value));
38  }
39  }
40 
41  void statement_handle_traits::close(ptr value)
42  {
43  if (SQLITE_OK != do_with_retries([&]() { return sqlite3_finalize(value); }))
44  {
45  throw runtime_error("cannot finalize statement");
46  }
47  }
48 
49  connection::connection(const char* filename)
50  {
52  auto const code = do_with_retries([&]() { return sqlite3_open(filename, handle.get_address()); });
53  if (SQLITE_OK != code)
54  {
55  throw runtime_error(sqlite3_errmsg(handle.get()));
56  }
57  m_handle = move(handle);
58  }
59 
60  void connection::execute(const char * command) const
61  {
62  auto const code = do_with_retries([&]() { return sqlite3_exec(m_handle.get(), command, nullptr, nullptr, nullptr); });
63  if (SQLITE_OK != code)
64  {
65  throw runtime_error(sqlite3_errmsg(m_handle.get()));
66  }
67  }
68 
69  bool connection::table_exists(const char* name) const
70  {
71  statement stmt(*this, "SELECT COUNT(name) FROM sqlite_master WHERE type=? AND name=?");
72  stmt.bind(1, "table");
73  stmt.bind(2, name);
74  return stmt()[0].get_bool();
75  }
76 
77  void connection::transaction(std::function<void()> transaction) const
78  {
79  char* errorMessage;
80  sqlite3_exec(m_handle.get(), "BEGIN TRANSACTION", NULL, NULL, &errorMessage);
81 
82  transaction();
83 
84  sqlite3_exec(m_handle.get(), "COMMIT TRANSACTION", NULL, NULL, &errorMessage);
85  }
86 
87  statement::statement(const connection& conn, const char * sql)
88  {
89  auto const code = do_with_retries([&]() {
90  return sqlite3_prepare_v2(conn.m_handle.get(), sql, static_cast<int>(strlen(sql)), m_handle.get_address(), nullptr);
91  });
92  if (SQLITE_OK != code)
93  {
94  throw runtime_error(sqlite3_errmsg(conn.m_handle.get()));
95  }
96  }
97 
98 
99 
100  bool statement::step() const
101  {
102  auto const code = do_with_retries([&]() { return sqlite3_step(m_handle.get()); });
103 
104  if (code == SQLITE_ROW) return true;
105  if (code == SQLITE_DONE) return false;
106 
107  throw runtime_error(sqlite3_errmsg(sqlite3_db_handle(m_handle.get())));
108  }
109 
110  int statement::get_int(int const column) const
111  {
112  return sqlite3_column_int(m_handle.get(), column);
113  }
114 
115  double statement::get_double(int const column) const
116  {
117  auto val = sqlite3_column_double(m_handle.get(), column);
118  return val;
119  }
120 
121  string statement::get_string(int const column) const
122  {
123  return reinterpret_cast<const char*>(sqlite3_column_text(m_handle.get(), column));
124  }
125 
126  vector<uint8_t> statement::get_blob(int column) const
127  {
128  auto size = sqlite3_column_bytes(m_handle.get(), column);
129  vector<uint8_t> result(size, 0);
130  auto blob = (unsigned char*)sqlite3_column_blob(m_handle.get(), column);
131  std::copy(blob, blob + size, result.data());
132 
133  return result;
134  }
135 
136  void statement::bind(int param, int value) const
137  {
138  sqlite3_bind_int(m_handle.get(), param, value);
139  }
140 
141  void statement::bind(int param, double value) const
142  {
143  sqlite3_bind_double(m_handle.get(), param, value);
144  }
145 
146  void statement::bind(int param, const char* value) const
147  {
148  sqlite3_bind_text(m_handle.get(), param, value, -1, SQLITE_STATIC);
149  }
150 
151  void statement::bind(int param, const std::vector<uint8_t>& value) const
152  {
153  sqlite3_bind_blob(m_handle.get(), param, value.data(), static_cast<int>(value.size()), SQLITE_STATIC);
154  }
155 
157  {
158  return row_value(m_owner, m_end);
159  }
160 
161  void statement::row_value::assert_good() const
162  {
163  if (m_bad)
164  throw runtime_error("query returned zero results");
165  }
166 }
167 
SQLITE_API int SQLITE_STDCALL sqlite3_column_int(sqlite3_stmt *, int iCol)
Definition: sqlite3.c:75502
int do_with_retries(T action, int max_retries=1000)
Definition: sql.cpp:14
const char * get_string(rs2_rs400_visual_preset value)
GLuint const GLchar * name
SQLITE_API double SQLITE_STDCALL sqlite3_column_double(sqlite3_stmt *, int iCol)
Definition: sqlite3.c:75497
SQLITE_API int SQLITE_STDCALL sqlite3_bind_text(sqlite3_stmt *, int, const char *, int, void(*)(void *))
Definition: sqlite3.c:75836
GLuint64 GLenum void * handle
Definition: glext.h:7785
SQLITE_API const char *SQLITE_STDCALL sqlite3_errmsg(sqlite3 *)
Definition: sqlite3.c:137767
GLfloat value
ImVec4 operator*(const ImVec4 &color, float t)
Definition: model-views.h:68
SQLITE_API int SQLITE_STDCALL sqlite3_step(sqlite3_stmt *)
Definition: sqlite3.c:75123
GLenum GLenum GLsizei void GLsizei void * column
sql::statement::iterator end(sql::statement &stmt)
Definition: sql.cpp:169
#define SQLITE_ROW
Definition: sqlite3.c:686
SQLITE_API int SQLITE_STDCALL sqlite3_bind_double(sqlite3_stmt *, int, double)
Definition: sqlite3.c:75804
#define SQLITE_DONE
Definition: sqlite3.c:687
GLuint GLfloat * val
SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob(sqlite3_stmt *, int, const void *, int n, void(*)(void *))
Definition: sqlite3.c:75778
SQLITE_API int SQLITE_STDCALL sqlite3_finalize(sqlite3_stmt *pStmt)
Definition: sqlite3.c:74571
GLsizeiptr size
T::ptr get() const
Definition: sql.h:53
#define SQLITE_BUSY
Definition: sqlite3.c:662
void bind(int param, int value) const
Definition: sql.cpp:136
T::ptr * get_address()
Definition: sql.h:54
iterator end()
Definition: sql.h:145
sql::statement::iterator begin(sql::statement &stmt)
Definition: sql.cpp:168
SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_column_text(sqlite3_stmt *, int iCol)
Definition: sqlite3.c:75512
iterator begin()
Definition: sql.h:144
action
Definition: enums.py:62
sqlite3_stmt * ptr
Definition: sql.h:26
Definition: sql.cpp:11
SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes(sqlite3_stmt *, int iCol)
Definition: sqlite3.c:75487
SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_db_handle(sqlite3_stmt *)
Definition: sqlite3.c:76027
SQLITE_API int SQLITE_STDCALL sqlite3_prepare_v2(sqlite3 *db, const char *zSql, int nByte, sqlite3_stmt **ppStmt, const char **pzTail)
Definition: sqlite3.c:112700
GLenum GLfloat param
SQLITE_API int SQLITE_STDCALL sqlite3_close(sqlite3 *)
Definition: sqlite3.c:136675
connection_handle m_handle
Definition: sql.h:152
typename::boost::move_detail::remove_reference< T >::type && move(T &&t) BOOST_NOEXCEPT
SQLITE_API int SQLITE_STDCALL sqlite3_exec(sqlite3 *, const char *sql, int(*callback)(void *, int, char **, char **), void *, char **errmsg)
Definition: sqlite3.c:108027
#define SQLITE_OK
Definition: sqlite3.c:656
#define NULL
Definition: tinycthread.c:47
SQLITE_API int SQLITE_STDCALL sqlite3_bind_int(sqlite3_stmt *, int, int)
Definition: sqlite3.c:75814
SQLITE_API const void *SQLITE_STDCALL sqlite3_column_blob(sqlite3_stmt *, int iCol)
Definition: sqlite3.c:75477
SQLITE_API int SQLITE_STDCALL sqlite3_open(const char *filename, sqlite3 **ppDb)
Definition: sqlite3.c:138639
GLuint64EXT * result
Definition: glext.h:10921
void copy(void *dst, void const *src, size_t size)
Definition: types.cpp:836
#define SQLITE_STATIC
Definition: sqlite3.c:4858


librealsense2
Author(s): Sergey Dorodnicov , Doron Hirshberg , Mark Horn , Reagan Lopez , Itay Carpis
autogenerated on Mon May 3 2021 02:47:41