1 | #include <base/system.h> |
2 | #include <engine/console.h> |
3 | #include <engine/sqlite.h> |
4 | |
5 | #include <sqlite3.h> |
6 | |
7 | void CSqliteDeleter::operator()(sqlite3 *pSqlite) |
8 | { |
9 | sqlite3_close(pSqlite); |
10 | } |
11 | |
12 | void CSqliteStmtDeleter::operator()(sqlite3_stmt *pStmt) |
13 | { |
14 | sqlite3_finalize(pStmt); |
15 | } |
16 | |
17 | int SqliteHandleError(IConsole *pConsole, int Error, sqlite3 *pSqlite, const char *pContext) |
18 | { |
19 | if(Error != SQLITE_OK && Error != SQLITE_DONE && Error != SQLITE_ROW) |
20 | { |
21 | char aBuf[512]; |
22 | str_format(buffer: aBuf, buffer_size: sizeof(aBuf), format: "%s at %s" , sqlite3_errmsg(pSqlite), pContext); |
23 | pConsole->Print(Level: IConsole::OUTPUT_LEVEL_STANDARD, pFrom: "sqlite3" , pStr: aBuf); |
24 | } |
25 | return Error; |
26 | } |
27 | |
28 | CSqlite SqliteOpen(IConsole *pConsole, IStorage *pStorage, const char *pPath) |
29 | { |
30 | char aFullPath[IO_MAX_PATH_LENGTH]; |
31 | pStorage->GetCompletePath(Type: IStorage::TYPE_SAVE, pDir: pPath, pBuffer: aFullPath, BufferSize: sizeof(aFullPath)); |
32 | sqlite3 *pSqlite = nullptr; |
33 | const bool ErrorOpening = SQLITE_HANDLE_ERROR(sqlite3_open(aFullPath, &pSqlite)) != SQLITE_OK; |
34 | // Even on error, the database is initialized and needs to be freed. |
35 | // Except on allocation failure, but then it'll be nullptr which is |
36 | // also fine. |
37 | CSqlite pResult{pSqlite}; |
38 | if(ErrorOpening) |
39 | { |
40 | return nullptr; |
41 | } |
42 | bool Error = false; |
43 | Error = Error || SQLITE_HANDLE_ERROR(sqlite3_exec(pSqlite, "PRAGMA journal_mode = WAL" , nullptr, nullptr, nullptr)); |
44 | Error = Error || SQLITE_HANDLE_ERROR(sqlite3_exec(pSqlite, "PRAGMA synchronous = NORMAL" , nullptr, nullptr, nullptr)); |
45 | if(Error) |
46 | { |
47 | return nullptr; |
48 | } |
49 | return pResult; |
50 | } |
51 | |
52 | CSqliteStmt SqlitePrepare(IConsole *pConsole, sqlite3 *pSqlite, const char *pStatement) |
53 | { |
54 | sqlite3_stmt *pTemp; |
55 | if(SQLITE_HANDLE_ERROR(sqlite3_prepare_v2(pSqlite, pStatement, -1, &pTemp, nullptr))) |
56 | { |
57 | return nullptr; |
58 | } |
59 | return CSqliteStmt{pTemp}; |
60 | } |
61 | |