CernVM-FS  2.13.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
sql.h
Go to the documentation of this file.
1 
5 #ifndef CVMFS_SQL_H_
6 #define CVMFS_SQL_H_
7 
8 #include <cassert>
9 #include <string>
10 
11 #include "duplex_sqlite3.h"
12 #include "util/file_guard.h"
13 #include "util/pointer.h"
14 
15 namespace sqlite {
16 
17 struct MemStatistics {
21  , lookaside_hit(-1)
24  , page_cache_used(-1)
25  , page_cache_hit(-1)
26  , page_cache_miss(-1)
27  , schema_used(-1)
28  , stmt_used(-1) { }
38  int stmt_used;
39 };
40 
41 class Sql;
42 
96 template<class DerivedT>
98  public:
99  enum OpenMode {
102  };
103 
104  static const float kSchemaEpsilon; // floats get imprecise in SQlite
105 
114  static DerivedT *Create(const std::string &filename);
115 
127  static DerivedT *Open(const std::string &filename, const OpenMode open_mode);
128 
129  bool IsEqualSchema(const float value, const float compare) const {
130  return (value > compare - kSchemaEpsilon
131  && value < compare + kSchemaEpsilon);
132  }
133 
134  bool BeginTransaction() const;
135  bool CommitTransaction() const;
136 
137  template<typename T>
138  T GetProperty(const std::string &key) const;
139  template<typename T>
140  T GetPropertyDefault(const std::string &key, const T default_value) const;
141  template<typename T>
142  bool SetProperty(const std::string &key, const T value);
143  bool HasProperty(const std::string &key) const;
144 
145  sqlite3 *sqlite_db() const { return database_.database(); }
146  const std::string &filename() const { return database_.filename(); }
147  float schema_version() const { return schema_version_; }
148  unsigned schema_revision() const { return schema_revision_; }
149  bool read_write() const { return read_write_; }
150 
156  unsigned GetModifiedRowCount() const;
157 
165  double GetFreePageRatio() const;
166 
170  void GetMemStatistics(MemStatistics *stats) const;
171 
179  bool Vacuum() const;
180 
186  void PrintSqlError(const std::string &error_msg);
187 
195  std::string GetLastErrorMsg() const;
196 
197 
203  void TakeFileOwnership();
204 
210  void DropFileOwnership();
211 
219  bool OwnsFile() const { return database_.OwnsFile(); }
220 
225  void EnforceSchema(float version, unsigned revision) {
226  schema_version_ = version;
227  schema_revision_ = revision;
228  }
229 
230  protected:
235  Database(const std::string &filename, const OpenMode open_mode);
236 
237  bool Initialize();
238 
239  bool CreatePropertiesTable();
240  bool PrepareCommonQueries();
241 
242  bool OpenDatabase(const int sqlite_open_flags);
243  bool Configure();
244  bool FileReadAhead();
245 
246  void ReadSchemaRevision();
247  bool StoreSchemaRevision();
248 
249  void set_schema_version(const float ver) { schema_version_ = ver; }
250  void set_schema_revision(const unsigned rev) { schema_revision_ = rev; }
251 
252  private:
259  DatabaseRaiiWrapper(const std::string &filename,
260  Database<DerivedT> *delegate)
261  : sqlite_db(NULL)
262  , lookaside_buffer(NULL)
263  , db_file_guard(filename, UnlinkGuard::kDisabled)
264  , delegate_(delegate) { }
266 
267  sqlite3 *database() const { return sqlite_db; }
268  const std::string &filename() const { return db_file_guard.path(); }
269 
270  bool Close();
271 
274  bool OwnsFile() const { return db_file_guard.IsEnabled(); }
275 
276  sqlite3 *sqlite_db;
280  };
281 
282  static const char *kSchemaVersionKey;
283  static const char *kSchemaRevisionKey;
284 
285  DatabaseRaiiWrapper database_;
286 
287  const bool read_write_;
290 
293 
297 };
298 
299 
300 //
301 // # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
302 //
303 
304 
326 class Sql {
327  public:
333  Sql(sqlite3 *sqlite_db, const std::string &statement);
334  virtual ~Sql();
335 
336  bool Execute();
337  bool FetchRow();
338  std::string DebugResultTable();
339  bool Reset();
340  inline int GetLastError() const { return last_error_code_; }
341 
350  std::string GetLastErrorMsg() const;
351 
352  bool BindBlob(const int index, const void *value, const unsigned size) {
353  LazyInit();
354  last_error_code_ = sqlite3_bind_blob(statement_, index, value,
355  static_cast<int>(size), SQLITE_STATIC);
356  return Successful();
357  }
358  bool BindBlobTransient(const int index, const void *value,
359  const unsigned size) {
360  LazyInit();
361  last_error_code_ = sqlite3_bind_blob(statement_, index, value,
362  static_cast<int>(size),
363  SQLITE_TRANSIENT); // NOLINT
364  return Successful();
365  }
366  bool BindDouble(const int index, const double value) {
367  LazyInit();
368  last_error_code_ = sqlite3_bind_double(statement_, index, value);
369  return Successful();
370  }
371  bool BindInt(const int index, const int value) {
372  LazyInit();
373  last_error_code_ = sqlite3_bind_int(statement_, index, value);
374  return Successful();
375  }
376  bool BindInt64(const int index, const sqlite3_int64 value) {
377  LazyInit();
378  last_error_code_ = sqlite3_bind_int64(statement_, index, value);
379  return Successful();
380  }
381  bool BindNull(const int index) {
382  LazyInit();
383  last_error_code_ = sqlite3_bind_null(statement_, index);
384  return Successful();
385  }
386  bool BindTextTransient(const int index, const std::string &value) {
387  return BindTextTransient(index, value.data(),
388  static_cast<int>(value.length()));
389  }
390  bool BindTextTransient(const int index, const char *value, const int size) {
391  // NOLINTNEXTLINE(performance-no-int-to-ptr)
392  return BindText(index, value, size, SQLITE_TRANSIENT);
393  }
394  bool BindText(const int index, const std::string &value) {
395  return BindText(index, value.data(), static_cast<int>(value.length()),
396  SQLITE_STATIC);
397  }
398  bool BindText(const int index,
399  const char *value,
400  const int size,
401  void (*dtor)(void *) = SQLITE_STATIC) {
402  LazyInit();
403  last_error_code_ = sqlite3_bind_text(statement_, index, value, size, dtor);
404  return Successful();
405  }
406 
412  template<typename T>
413  inline bool Bind(const int index, const T &value);
414 
415 
416  int RetrieveType(const int idx_column) const {
417  return sqlite3_column_type(statement_, idx_column);
418  }
419 
428  int RetrieveBytes(const int idx_column) const {
429  return sqlite3_column_bytes(statement_, idx_column);
430  }
431  const void *RetrieveBlob(const int idx_column) const {
432  return sqlite3_column_blob(statement_, idx_column);
433  }
434  double RetrieveDouble(const int idx_column) const {
435  return sqlite3_column_double(statement_, idx_column);
436  }
437  int RetrieveNullableInt(const int idx_column, const int val_null) const {
438  if (sqlite3_column_type(statement_, idx_column) == SQLITE_NULL)
439  return val_null;
440  return sqlite3_column_int(statement_, idx_column);
441  }
442  int RetrieveInt(const int idx_column) const {
443  return sqlite3_column_int(statement_, idx_column);
444  }
445  sqlite3_int64 RetrieveInt64(const int idx_column) const {
446  return sqlite3_column_int64(statement_, idx_column);
447  }
448  const unsigned char *RetrieveText(const int idx_column) const {
449  return sqlite3_column_text(statement_, idx_column);
450  }
451  std::string RetrieveString(const int idx_column) const {
452  return reinterpret_cast<const char *>(RetrieveText(idx_column));
453  }
454  template<typename T>
455  inline T Retrieve(const int index);
456 
457  protected:
458  Sql()
459  : database_(NULL)
460  , statement_(NULL)
461  , query_string_(NULL)
462  , last_error_code_(0) { }
463 
464  bool IsInitialized() const { return statement_ != NULL; }
465 
473  bool Init(const sqlite3 *database, const std::string &statement);
474 
483  void DeferredInit(const sqlite3 *database, const char *statement);
484 
489  inline bool Successful() const {
490  return SQLITE_OK == last_error_code_ || SQLITE_ROW == last_error_code_
491  || SQLITE_DONE == last_error_code_;
492  }
493 
494  private:
495  bool Init(const char *statement);
496  void LazyInit() {
497  if (!IsInitialized()) {
498  assert(NULL != database_);
499  assert(NULL != query_string_);
500  const bool success = Init(query_string_);
501  assert(success);
502  }
503  }
504 
505  sqlite3 *database_;
506  sqlite3_stmt *statement_;
507  const char *query_string_;
509 };
510 
511 } // namespace sqlite
512 
513 #include "sql_impl.h"
514 
515 #endif // CVMFS_SQL_H_
const char * query_string_
Definition: sql.h:507
void LazyInit()
Definition: sql.h:496
std::string GetLastErrorMsg() const
Definition: sql.cc:165
bool Bind(const int index, const T &value)
void DropFileOwnership()
Definition: sql_impl.h:342
const std::string & filename() const
Definition: sql.h:268
std::string GetLastErrorMsg() const
Definition: sql_impl.h:327
bool IsInitialized() const
Definition: sql.h:464
bool BindTextTransient(const int index, const std::string &value)
Definition: sql.h:386
bool Execute()
Definition: sql.cc:41
bool Reset()
Definition: sql.cc:127
void EnforceSchema(float version, unsigned revision)
Definition: sql.h:225
double GetFreePageRatio() const
Definition: sql_impl.h:398
int page_cache_used
Bytes used for caching pages.
Definition: sql.h:34
bool BindText(const int index, const std::string &value)
Definition: sql.h:394
bool FetchRow()
Definition: sql.cc:61
const std::string & filename() const
Definition: sql.h:146
bool Init(const sqlite3 *database, const std::string &statement)
Definition: sql.cc:133
bool PrepareCommonQueries()
Definition: sql_impl.h:233
const void * RetrieveBlob(const int idx_column) const
Definition: sql.h:431
double RetrieveDouble(const int idx_column) const
Definition: sql.h:434
bool read_write() const
Definition: sql.h:149
void TakeFileOwnership()
Definition: sql_impl.h:334
int lookaside_miss_size
Definition: sql.h:32
bool Initialize()
Definition: sql_impl.h:93
int last_error_code_
Definition: sql.h:508
float schema_version_
Definition: sql.h:288
bool BeginTransaction() const
Definition: sql_impl.h:268
void ReadSchemaRevision()
Definition: sql_impl.h:250
bool BindBlobTransient(const int index, const void *value, const unsigned size)
Definition: sql.h:358
int lookaside_slots_used
Definition: sql.h:29
Database(const std::string &filename, const OpenMode open_mode)
Definition: sql_impl.h:21
void set_schema_version(const float ver)
Definition: sql.h:249
assert((mem||(size==0))&&"Out Of Memory")
std::string DebugResultTable()
Definition: sql.cc:68
int RetrieveNullableInt(const int idx_column, const int val_null) const
Definition: sql.h:437
float schema_version() const
Definition: sql.h:147
int stmt_used
Bytes used for prepared statmements (lookaside + heap)
Definition: sql.h:38
void set_schema_revision(const unsigned rev)
Definition: sql.h:250
bool Configure()
Definition: sql_impl.h:180
static DerivedT * Open(const std::string &filename, const OpenMode open_mode)
Definition: sql_impl.h:73
sqlite3 * database() const
Definition: sql.h:267
bool CreatePropertiesTable()
Definition: sql_impl.h:280
Sql()
Definition: sql.h:458
T GetProperty(const std::string &key) const
Definition: sql_impl.h:301
unsigned schema_revision() const
Definition: sql.h:148
T GetPropertyDefault(const std::string &key, const T default_value) const
Definition: sql_impl.h:313
void DeferredInit(const sqlite3 *database, const char *statement)
Definition: sql.cc:159
int GetLastError() const
Definition: sql.h:340
bool BindDouble(const int index, const double value)
Definition: sql.h:366
UniquePtr< Sql > set_property_
Definition: sql.h:295
unsigned GetModifiedRowCount() const
Definition: sql_impl.h:350
static const float kSchemaEpsilon
Definition: sql.h:104
sqlite3 * database_
Definition: sql.h:505
const bool read_write_
Definition: sql.h:287
bool Vacuum() const
Definition: sql_impl.h:415
sqlite3_int64 RetrieveInt64(const int idx_column) const
Definition: sql.h:445
bool BindBlob(const int index, const void *value, const unsigned size)
Definition: sql.h:352
bool BindInt(const int index, const int value)
Definition: sql.h:371
DatabaseRaiiWrapper(const std::string &filename, Database< DerivedT > *delegate)
Definition: sql.h:259
T Retrieve(const int index)
UniquePtr< Sql > commit_transaction_
Definition: sql.h:292
UniquePtr< Sql > has_property_
Definition: sql.h:294
bool BindTextTransient(const int index, const char *value, const int size)
Definition: sql.h:390
sqlite3 * sqlite_db() const
Definition: sql.h:145
bool CommitTransaction() const
Definition: sql_impl.h:274
sqlite3_stmt * statement_
Definition: sql.h:506
int page_cache_miss
Definition: sql.h:36
bool BindInt64(const int index, const sqlite3_int64 value)
Definition: sql.h:376
bool SetProperty(const std::string &key, const T value)
Definition: sql_impl.h:320
virtual ~Sql()
Definition: sql.cc:25
bool OpenDatabase(const int sqlite_open_flags)
Definition: sql_impl.h:128
bool OwnsFile() const
Definition: sql.h:219
bool HasProperty(const std::string &key) const
Definition: sql_impl.h:289
bool IsEqualSchema(const float value, const float compare) const
Definition: sql.h:129
std::string RetrieveString(const int idx_column) const
Definition: sql.h:451
const unsigned char * RetrieveText(const int idx_column) const
Definition: sql.h:448
static const char * kSchemaRevisionKey
Definition: sql.h:283
unsigned schema_revision_
Definition: sql.h:289
bool FileReadAhead()
Definition: sql_impl.h:199
int RetrieveType(const int idx_column) const
Definition: sql.h:416
int schema_used
Bytes used to store db schema.
Definition: sql.h:37
bool BindText(const int index, const char *value, const int size, void(*dtor)(void *)=SQLITE_STATIC)
Definition: sql.h:398
int lookaside_miss_full
Definition: sql.h:33
int page_cache_hit
Definition: sql.h:35
int lookaside_slots_max
Definition: sql.h:30
Database< DerivedT > * delegate_
Definition: sql.h:279
void GetMemStatistics(MemStatistics *stats) const
Definition: sql_impl.h:360
bool Successful() const
Definition: sql.h:489
void PrintSqlError(const std::string &error_msg)
Definition: sql_impl.h:423
DatabaseRaiiWrapper database_
Definition: sql.h:285
static const char * kSchemaVersionKey
Definition: sql.h:282
int RetrieveInt(const int idx_column) const
Definition: sql.h:442
UniquePtr< Sql > get_property_
Definition: sql.h:296
bool BindNull(const int index)
Definition: sql.h:381
static void size_t size
Definition: smalloc.h:54
bool StoreSchemaRevision()
Definition: sql_impl.h:261
UniquePtr< Sql > begin_transaction_
Definition: sql.h:291
static DerivedT * Create(const std::string &filename)
Definition: sql_impl.h:30
int RetrieveBytes(const int idx_column) const
Definition: sql.h:428