#include #include #include #include #include #include #include #include namespace { auto code_from(std::int32_t code) -> std::int32_t { switch (code & 0xff) { case SQLITE_OK: case SQLITE_ROW: case SQLITE_DONE: return 0; case SQLITE_MISUSE: case SQLITE_RANGE: return noto::detail::error_invalid_argument; case SQLITE_NOTFOUND: case SQLITE_EMPTY: return noto::detail::error_not_found; case SQLITE_BUSY: case SQLITE_LOCKED: return noto::detail::error_unavailable; case SQLITE_INTERRUPT: return noto::detail::error_canceled; case SQLITE_AUTH: case SQLITE_PERM: case SQLITE_READONLY: return noto::detail::error_permission_denied; case SQLITE_CONSTRAINT: return noto::detail::error_constraint_violation; case SQLITE_ERROR: return noto::detail::error_syntax_error; case SQLITE_CORRUPT: case SQLITE_NOTADB: return noto::detail::error_data_loss; case SQLITE_IOERR: case SQLITE_CANTOPEN: return noto::detail::error_unavailable; case SQLITE_NOMEM: return noto::detail::error_resource_exhausted; default: return noto::detail::error_internal; } } auto message_from(std::int32_t code, sqlite3 *database, std::string_view operation) -> std::string { auto message = std::string{}; if (!operation.empty()) { message += operation; message += ": "; } if (database != nullptr) { message += sqlite3_errmsg(database); } else { message += sqlite3_errstr(code); } return message; } } auto noto::error_from(std::int32_t code, sqlite3 *database, std::string_view operation) -> modulus::error { return noto::detail::make_error(code_from(code), message_from(code, database, operation)); } auto noto::result_from(std::int32_t code, sqlite3 *database, std::string_view operation) -> std::expected { if (code == SQLITE_OK || code == SQLITE_ROW || code == SQLITE_DONE) { return {}; } return noto::detail::fail_void(noto::error_from(code, database, operation)); }