5 #ifndef CVMFS_SQL_IMPL_H_
6 #define CVMFS_SQL_IMPL_H_
20 template<
class DerivedT>
23 : database_(filename, this)
24 , read_write_(kOpenReadWrite == open_mode)
25 , schema_version_(0.0f)
26 , schema_revision_(0) { }
29 template<
class DerivedT>
38 database->set_schema_version(DerivedT::kLatestSchema);
39 database->set_schema_revision(DerivedT::kLatestSchemaRevision);
41 const int open_flags = SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_READWRITE
43 if (!database->OpenDatabase(open_flags)) {
48 if (!database->CreatePropertiesTable()) {
49 database->PrintSqlError(
"Failed to create common properties table");
53 if (!database->CreateEmptyDatabase()) {
54 database->PrintSqlError(
"Failed to create empty database");
58 if (!database->PrepareCommonQueries()) {
59 database->PrintSqlError(
"Failed to initialize properties queries");
63 if (!database->StoreSchemaRevision()) {
64 database->PrintSqlError(
"Failed to store initial schema revision");
72 template<
class DerivedT>
79 "Failed to open database file '%s' - errno: %d", filename.c_str(),
84 if (!database->Initialize()) {
92 template<
class DerivedT>
94 const int flags = (read_write_) ? SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_READWRITE
95 : SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_READONLY;
97 bool successful = OpenDatabase(flags) && Configure() && FileReadAhead()
98 && PrepareCommonQueries();
105 ReadSchemaRevision();
107 "opened database with schema version %f "
109 schema_version_, schema_revision_);
111 if (!static_cast<DerivedT *>(
this)->CheckSchemaCompatibility()) {
113 schema_version_, filename().c_str());
118 && !static_cast<DerivedT *>(
this)->LiveSchemaUpgradeIfNecessary()) {
127 template<
class DerivedT>
131 int retval = sqlite3_open_v2(filename().c_str(),
132 &database_.sqlite_db,
133 flags | SQLITE_OPEN_EXRESCODE,
135 if (retval != SQLITE_OK) {
137 filename().c_str(), retval, errno);
145 template<
class DerivedT>
148 const bool close_successful =
Close();
154 template<
class DerivedT>
159 filename().c_str(), (db_file_guard.IsEnabled() ?
"yes" :
"no"));
160 const int result = sqlite3_close(
sqlite_db);
162 if (result != SQLITE_OK) {
164 "failed to close SQLite database '%s' (%d - %s)",
165 filename().c_str(), result, delegate_->GetLastErrorMsg().c_str());
170 if (lookaside_buffer != NULL) {
173 lookaside_buffer = NULL;
179 template<
class DerivedT>
198 template<
class DerivedT>
205 fd_readahead = open(
filename().c_str(), O_RDONLY);
206 if (fd_readahead < 0) {
219 if (retval != 0 && errno != EINVAL && errno != ENOSYS) {
221 "failed to read-ahead %s: invalid file descrp. or not open for "
232 template<
class DerivedT>
238 "WHERE key = :key;");
240 "WHERE key = :key;");
242 "(key, value) VALUES (:key, :value);");
249 template<
class DerivedT>
260 template<
class DerivedT>
267 template<
class DerivedT>
273 template<
class DerivedT>
279 template<
class DerivedT>
282 "CREATE TABLE properties (key TEXT, value TEXT, "
283 "CONSTRAINT pk_properties PRIMARY KEY (key));")
288 template<
class DerivedT>
299 template<
class DerivedT>
311 template<
class DerivedT>
314 const T default_value)
const {
315 return (
HasProperty(key)) ? GetProperty<T>(key) : default_value;
318 template<
class DerivedT>
326 template<
class DerivedT>
328 std::string msg = sqlite3_errmsg(
sqlite_db());
333 template<
class DerivedT>
341 template<
class DerivedT>
349 template<
class DerivedT>
351 const int modified_rows = sqlite3_total_changes(
sqlite_db());
352 assert(modified_rows >= 0);
353 return static_cast<unsigned>(modified_rows);
359 template<
class DerivedT>
364 int retval = SQLITE_OK;
365 retval |= sqlite3_db_status(
sqlite_db(), SQLITE_DBSTATUS_LOOKASIDE_USED,
366 ¤t, &highwater, reset);
369 retval |= sqlite3_db_status(
sqlite_db(), SQLITE_DBSTATUS_LOOKASIDE_HIT,
370 ¤t, &highwater, reset);
372 retval |= sqlite3_db_status(
sqlite_db(), SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE,
373 ¤t, &highwater, reset);
375 retval |= sqlite3_db_status(
sqlite_db(), SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL,
376 ¤t, &highwater, reset);
378 retval |= sqlite3_db_status(
sqlite_db(), SQLITE_DBSTATUS_CACHE_USED, ¤t,
381 retval |= sqlite3_db_status(
sqlite_db(), SQLITE_DBSTATUS_CACHE_HIT, ¤t,
384 retval |= sqlite3_db_status(
sqlite_db(), SQLITE_DBSTATUS_CACHE_MISS, ¤t,
387 retval |= sqlite3_db_status(
sqlite_db(), SQLITE_DBSTATUS_SCHEMA_USED,
388 ¤t, &highwater, reset);
390 retval |= sqlite3_db_status(
sqlite_db(), SQLITE_DBSTATUS_STMT_USED, ¤t,
393 assert(retval == SQLITE_OK);
397 template<
class DerivedT>
399 Sql free_page_count_query(this->
sqlite_db(),
"PRAGMA freelist_count;");
400 Sql page_count_query(this->
sqlite_db(),
"PRAGMA page_count;");
402 const bool retval = page_count_query.
FetchRow()
403 && free_page_count_query.
FetchRow();
410 return (static_cast<double>(free_pages) / static_cast<double>(pages));
414 template<
class DerivedT>
417 return static_cast<const DerivedT *
>(
this)->CompactDatabase()
422 template<
class DerivedT>
428 template<
class DerivedT>
430 template<
class DerivedT>
432 template<
class DerivedT>
442 inline bool Sql::Bind(
const int index,
const int &value) {
443 return this->BindInt64(index, value);
447 inline bool Sql::Bind(
const int index,
const unsigned int &value) {
448 return this->BindInt64(index, static_cast<int>(value));
452 inline bool Sql::Bind(
const int index,
const uint64_t &value) {
453 return this->BindInt64(index, static_cast<int64_t>(value));
457 inline bool Sql::Bind(
const int index,
const sqlite3_int64 &value) {
458 return this->BindInt64(index, value);
462 inline bool Sql::Bind(
const int index,
const std::string &value) {
463 return this->BindTextTransient(index, value);
467 inline bool Sql::Bind(
const int index,
const float &value) {
468 return this->BindDouble(index, value);
472 inline bool Sql::Bind(
const int index,
const double &value) {
473 return this->BindDouble(index, value);
479 return static_cast<int>(this->RetrieveInt64(index));
484 return static_cast<bool>(this->RetrieveInt(index));
489 return this->RetrieveInt64(index);
494 return static_cast<uint64_t
>(this->RetrieveInt64(index));
499 return RetrieveString(index);
504 return static_cast<float>(this->RetrieveDouble(index));
509 return this->RetrieveDouble(index);
514 #endif // CVMFS_SQL_IMPL_H_
bool Bind(const int index, const T &value)
const std::string & filename() const
std::string GetLastErrorMsg() const
double GetFreePageRatio() const
int page_cache_used
Bytes used for caching pages.
const std::string & filename() const
bool PrepareCommonQueries()
bool BeginTransaction() const
void ReadSchemaRevision()
Database(const std::string &filename, const OpenMode open_mode)
assert((mem||(size==0))&&"Out Of Memory")
int stmt_used
Bytes used for prepared statmements (lookaside + heap)
static DerivedT * Open(const std::string &filename, const OpenMode open_mode)
bool CreatePropertiesTable()
T GetProperty(const std::string &key) const
static bool HasInstance()
T GetPropertyDefault(const std::string &key, const T default_value) const
UniquePtr< Sql > set_property_
unsigned GetModifiedRowCount() const
sqlite3_int64 RetrieveInt64(const int idx_column) const
static SqliteMemoryManager * GetInstance()
T Retrieve(const int index)
UniquePtr< Sql > commit_transaction_
UniquePtr< Sql > has_property_
sqlite3 * sqlite_db() const
bool CommitTransaction() const
bool SetProperty(const std::string &key, const T value)
bool OpenDatabase(const int sqlite_open_flags)
bool HasProperty(const std::string &key) const
static const char * kSchemaRevisionKey
unsigned schema_revision_
int schema_used
Bytes used to store db schema.
void GetMemStatistics(MemStatistics *stats) const
void PrintSqlError(const std::string &error_msg)
DatabaseRaiiWrapper database_
static const char * kSchemaVersionKey
UniquePtr< Sql > get_property_
bool StoreSchemaRevision()
UniquePtr< Sql > begin_transaction_
void ReleaseLookasideBuffer(void *buffer)
static DerivedT * Create(const std::string &filename)
void * AssignLookasideBuffer(sqlite3 *db)
CVMFS_EXPORT void LogCvmfs(const LogSource source, const int mask, const char *format,...)