sapling/eden/fs/sqlite/Sqlite.cpp
Xavier Deguillard b251082355 silence some msvc warnings from sqlite.{h,cpp}
Summary:
We have a lot of warnings on Windows, which in case of a build failure makes
it hard to find the actual cause, let's start by silencing the Sqlite ones.

Reviewed By: wez

Differential Revision: D21238029

fbshipit-source-id: 95763dcd06af77d45b7a769a93e0bbd6cabfa9c3
2020-04-26 21:14:24 -07:00

118 lines
2.9 KiB
C++

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This software may be used and distributed according to the terms of the
* GNU General Public License version 2.
*/
#include "eden/fs/sqlite/Sqlite.h"
using folly::StringPiece;
using folly::Synchronized;
using folly::to;
using std::string;
namespace facebook {
namespace eden {
// Given a sqlite result code, if the result was not successful
// (SQLITE_OK), format an error message and throw an exception.
void checkSqliteResult(sqlite3* db, int result) {
if (result == SQLITE_OK) {
return;
}
// Sometimes the db instance holds more useful context
if (db) {
throw std::runtime_error(to<string>(
"sqlite error: ",
result,
": ",
sqlite3_errstr(result),
" ",
sqlite3_errmsg(db)));
}
// otherwise resort to a simpler number->string mapping
throw std::runtime_error(
to<string>("sqlite error: ", result, ": ", sqlite3_errstr(result)));
}
SqliteDatabase::SqliteDatabase(AbsolutePathPiece path) {
sqlite3* db = nullptr;
auto result = sqlite3_open(path.copy().c_str(), &db);
if (result != SQLITE_OK) {
// On most error conditions sqlite3_open() does allocate the DB object,
// and it needs to be closed afterwards if it is non-null.
sqlite3_close(db);
checkSqliteResult(nullptr, result);
}
db_ = db;
}
void SqliteDatabase::close() {
auto db = db_.wlock();
if (*db) {
sqlite3_close(*db);
*db = nullptr;
}
}
SqliteDatabase::~SqliteDatabase() {
close();
}
Synchronized<sqlite3*>::LockedPtr SqliteDatabase::lock() {
return db_.wlock();
}
SqliteStatement::SqliteStatement(
folly::Synchronized<sqlite3*>::LockedPtr& db,
folly::StringPiece query)
: db_{*db} {
checkSqliteResult(
db_,
sqlite3_prepare_v2(
db_, query.data(), unsignedNoToInt(query.size()), &stmt_, nullptr));
}
bool SqliteStatement::step() {
auto result = sqlite3_step(stmt_);
switch (result) {
case SQLITE_ROW:
return true;
case SQLITE_DONE:
sqlite3_reset(stmt_);
return false;
default:
checkSqliteResult(db_, result);
folly::assume_unreachable();
}
}
void SqliteStatement::bind(
size_t paramNo,
folly::StringPiece blob,
void (*bindType)(void*)) {
auto param = unsignedNoToInt(paramNo);
checkSqliteResult(
db_,
sqlite3_bind_blob64(
stmt_, param, blob.data(), sqlite3_uint64(blob.size()), bindType));
}
StringPiece SqliteStatement::columnBlob(size_t colNo) const {
auto col = unsignedNoToInt(colNo);
return StringPiece(
reinterpret_cast<const char*>(sqlite3_column_blob(stmt_, col)),
sqlite3_column_bytes(stmt_, col));
}
uint64_t SqliteStatement::columnUint64(size_t colNo) const {
return sqlite3_column_int64(stmt_, unsignedNoToInt(colNo));
}
SqliteStatement::~SqliteStatement() {
sqlite3_finalize(stmt_);
}
} // namespace eden
} // namespace facebook