12 #include "KVSQLiteServer.h"
13 #include "KVSQLiteResult.h"
14 #include "KVSQLiteStatement.h"
24 using namespace std::chrono_literals;
44 fSrvInfo += sqlite3_libversion();
46 if (strncmp(db,
"sqlite://", 9)) {
48 Error(
"KVSQLiteServer",
"protocol in db argument should be sqlite it is %s",
49 givenProtocol.
Data());
54 const char* dbase = db + 9;
56 #ifndef SQLITE_OPEN_URI
57 #define SQLITE_OPEN_URI 0x00000000
59 #if SQLITE_VERSION_NUMBER >= 3005000
60 Int_t error = sqlite3_open_v2(dbase, &fSQLite, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_URI, NULL);
62 Int_t error = sqlite3_open(dbase, &fSQLite);
74 Error(
"KVSQLiteServer",
"opening of %s failed with error: %d %s", dbase, sqlite3_errcode(fSQLite), sqlite3_errmsg(fSQLite));
75 sqlite3_close(fSQLite);
91 sqlite3_close(fSQLite);
109 sqlite3_close(fSQLite);
126 return Exec(
"BEGIN TRANSACTION");
130 #if ROOT_VERSION_CODE >= ROOT_VERSION(6,26,0)
142 return sqlite3_get_autocommit(fSQLite) == 0;
156 return Exec(
"COMMIT TRANSACTION");
169 return Exec(
"ROLLBACK TRANSACTION");
183 if (!IsConnected()) {
184 Error(
"Query",
"not connected");
188 sqlite3_stmt* preparedStmt =
nullptr;
189 const char* tail =
nullptr;
192 #if SQLITE_VERSION_NUMBER >= 3005000
193 int retVal = sqlite3_prepare_v2(fSQLite, sql, -1, &preparedStmt, &tail);
195 int retVal = sqlite3_prepare(fSQLite, sql, -1, &preparedStmt, &tail);
197 if (retVal != SQLITE_OK) {
198 SetError(retVal,sqlite3_errmsg(fSQLite),
"Query");
199 Info(
"Query",
"Query was:%s",sql);
202 if (tail && tail[0] !=
'\0')
203 Warning(
"Query",
"Don't use multiple queries, '%s' query was ignored", tail);
218 if (!IsConnected()) {
219 Error(
"Exec",
"not connected");
224 int ret = sqlite3_exec(fSQLite, sql, NULL, NULL, NULL);
225 if (ret != SQLITE_OK) {
226 SetError(ret,sqlite3_errmsg(fSQLite),
"Exec");
243 Error(
"SelectDataBase",
"SelectDataBase command makes no sense for SQLite!");
257 Error(
"GetDataBases",
"GetDataBases command makes no sense for SQLite!");
273 if (!IsConnected()) {
274 Error(
"GetTables",
"not connected");
278 TString sql =
"SELECT name FROM sqlite_master where type='table'";
280 sql +=
Form(
" AND name LIKE '%s'", wild);
300 Info(
"GetTablesList",
"Database is locked. Try again in 50ms...");
301 std::this_thread::sleep_for(50ms);
302 Info(
"GetTablesList",
"Try number %d...",i);
305 while(!
l && IsLocked() && (i<6));
307 Info(
"GetTablesList",
"...database access successful!");
329 if (!IsConnected()) {
330 Error(
"GetColumns",
"not connected");
335 Error(
"GetColumns",
"Not implementable for SQLite as a query with wildcard, use GetFieldNames() after SELECT instead!");
339 TString sql =
Form(
"PRAGMA table_info('%s')", table);
354 if (!IsConnected()) {
355 Error(
"GetTableInfo",
"not connected");
359 if (!tablename || (*tablename == 0))
return nullptr;
361 TSQLResult* columnRes = GetColumns(
"", tablename);
363 if (columnRes ==
nullptr) {
364 Error(
"GetTableInfo",
"could not query columns");
368 TList* lst =
nullptr;
372 while ((columnRow = columnRes->
Next()) !=
nullptr) {
409 Error(
"CreateDataBase",
"CreateDataBase command makes no sense for SQLite!");
423 Error(
"DropDataBase",
"DropDataBase command makes no sense for SQLite!");
437 if (!IsConnected()) {
438 Error(
"Reload",
"not connected");
442 Error(
"Reload",
"not implemented");
456 if (!IsConnected()) {
457 Error(
"Shutdown",
"not connected");
461 Error(
"Shutdown",
"not implemented");
490 SetError(-1,
"no query string specified",
"Statement");
494 if (!IsConnected()) {
495 Error(
"Statement",
"not connected");
499 sqlite3_stmt* preparedStmt =
nullptr;
500 const char* tail =
nullptr;
505 #if SQLITE_VERSION_NUMBER >= 3005000
506 int retVal = sqlite3_prepare_v2(fSQLite, sql, -1, &preparedStmt, &tail);
508 int retVal = sqlite3_prepare(fSQLite, sql, -1, &preparedStmt, &tail);
510 if (retVal != SQLITE_OK) {
511 SetError(retVal,sqlite3_errmsg(fSQLite),
"Statement");
514 if (tail && tail[0] !=
'\0')
515 Warning(
"Statement",
"Don't use multiple statements, '%s' statement was ignored", tail);
518 stmt->
fConn = fSQLite;
519 stmt->
fRes = preparedStmt;
533 if (!IsConnected()) {
534 Error(
"ServerInfo",
"not connected");
538 return fSrvInfo.Data();
547 return GetErrorCode()==SQLITE_BUSY;
556 return GetErrorCode()==SQLITE_OK;
char * Form(const char *fmt,...)
Modified copy of TSQLiteResult.
Modified copy of TSQLiteServer.
Bool_t StartTransaction() final
TSQLResult * GetDataBases(const char *wild=nullptr) final
TSQLResult * Query(const char *sql) final
TSQLResult * GetColumns(const char *dbname, const char *table, const char *wild=nullptr) final
Bool_t HasTransactionInFlight() final
returns kTRUE when transaction is running
TSQLTableInfo * GetTableInfo(const char *tablename) final
Int_t CreateDataBase(const char *dbname) final
Int_t SelectDataBase(const char *dbname) final
void Close(Option_t *opt="") final
Close connection to SQLite DB.
TList * GetTablesList(const char *wild=nullptr) final
const char * ServerInfo() final
Return server info, must be deleted by user.
KVSQLiteServer(const char *db, const char *uid=nullptr, const char *pw=nullptr)
Bool_t Exec(const char *sql) final
TSQLResult * GetTables(const char *dbname, const char *wild=nullptr) final
Int_t DropDataBase(const char *dbname) final
TSQLStatement * Statement(const char *sql, Int_t=100) final
Produce TSQLiteStatement.
~KVSQLiteServer()
Close SQLite DB.
Bool_t HasStatement() const final
Modified copy of TSQLiteStatement.
void Add(TObject *obj) override
virtual TSQLRow * Next()=0
virtual const char * GetField(Int_t field)=0
virtual TList * GetTablesList(const char *wild=nullptr)
const char * Data() const
CPYCPPYY_EXTERN bool Exec(const std::string &cmd)