sqlite: add more logging

Summary:
This diff adds more logging to SQLite so we can see what statements are being
executed in logs. Setting `eden.fs.sqlite=DBG9` will show every SQL statement
being executed and bound values.

Reviewed By: chadaustin

Differential Revision: D25223472

fbshipit-source-id: ed089b7ec112c75d9f7bc63d9fe53f0ec2bd6420
This commit is contained in:
Zeyi (Rice) Fan 2021-03-02 09:55:38 -08:00 committed by Facebook GitHub Bot
parent ea5a69b81f
commit 0327b74975
2 changed files with 44 additions and 21 deletions

View File

@ -25,17 +25,20 @@ void checkSqliteResult(sqlite3* db, int result) {
}
// Sometimes the db instance holds more useful context
if (db) {
throw std::runtime_error(to<string>(
"sqlite error: ",
auto error = fmt::format(
"sqlite error ({}): {} {}",
result,
": ",
sqlite3_errstr(result),
" ",
sqlite3_errmsg(db)));
sqlite3_errmsg(db));
XLOG(DBG6) << error;
throw std::runtime_error(error);
} else {
auto error =
fmt::format("sqlite error ({}): {}", result, sqlite3_errstr(result));
XLOG(DBG6) << error;
// otherwise resort to a simpler number->string mapping
throw std::runtime_error(error);
}
// otherwise resort to a simpler number->string mapping
throw std::runtime_error(
to<string>("sqlite error: ", result, ": ", sqlite3_errstr(result)));
}
SqliteDatabase::SqliteDatabase(const char* addr) {
@ -108,12 +111,37 @@ void SqliteStatement::bind(
folly::StringPiece blob,
void (*bindType)(void*)) {
auto param = unsignedNoToInt(paramNo);
XLOGF(DBG9, "?{} = {}", paramNo, blob);
checkSqliteResult(
db_,
sqlite3_bind_blob64(
stmt_, param, blob.data(), sqlite3_uint64(blob.size()), bindType));
}
void SqliteStatement::bind(
size_t paramNo,
folly::ByteRange blob,
void (*bindType)(void*)) {
auto sp = folly::StringPiece(blob);
bind(paramNo, sp, bindType);
}
void SqliteStatement::bind(size_t paramNo, int64_t id) {
XLOGF(DBG9, "?{} = {}", paramNo, id);
checkSqliteResult(db_, sqlite3_bind_int64(stmt_, paramNo, id));
}
void SqliteStatement::bind(size_t paramNo, uint64_t id) {
XLOGF(DBG9, "?{} = {}", paramNo, id);
checkSqliteResult(
db_, sqlite3_bind_int64(stmt_, unsignedNoToInt(paramNo), id));
}
void SqliteStatement::bind(size_t paramNo, uint32_t id) {
XLOGF(DBG9, "?{} = {}", paramNo, id);
checkSqliteResult(db_, sqlite3_bind_int(stmt_, unsignedNoToInt(paramNo), id));
}
StringPiece SqliteStatement::columnBlob(size_t colNo) const {
auto col = unsignedNoToInt(colNo);
return StringPiece(
@ -122,7 +150,7 @@ StringPiece SqliteStatement::columnBlob(size_t colNo) const {
}
uint64_t SqliteStatement::columnUint64(size_t colNo) const {
return sqlite3_column_int64(stmt_, unsignedNoToInt(colNo));
return sqlite3_column_int64(stmt_, folly::to_signed(colNo));
}
SqliteStatement::~SqliteStatement() {

View File

@ -140,22 +140,17 @@ class SqliteStatement {
/** Identical to the StringPiece variant of `bind` defined above,
* but accepts a ByteRange parameter instead */
inline void bind(
void bind(
size_t paramNo,
folly::ByteRange blob,
void (*bindType)(void*) = SQLITE_STATIC) {
bind(paramNo, folly::StringPiece(blob), bindType);
}
void (*bindType)(void*) = SQLITE_STATIC);
inline void bind(size_t paramNo, uint64_t id) {
checkSqliteResult(
db_, sqlite3_bind_int64(stmt_, unsignedNoToInt(paramNo), id));
}
void bind(size_t paramNo, int64_t id);
void bind(size_t paramNo, uint64_t id);
void bind(size_t paramNo, uint32_t id);
inline void bind(size_t paramNo, uint32_t id) {
checkSqliteResult(
db_, sqlite3_bind_int(stmt_, unsignedNoToInt(paramNo), id));
}
/** Reference a blob column in the current row returned by the statement.
* This is only valid to call once `step()` has returned true. The
* return value is invalidated by a subsequent `step()` call or by the