20 #include "KVSQLiteStatement.h"
21 #include "KVSQLiteResult.h"
31 using namespace std::chrono_literals;
49 unsigned long bindParamcount = sqlite3_bind_parameter_count(fStmt->fRes);
51 if (bindParamcount > 0) {
53 fNumPars = bindParamcount;
57 fNumPars = sqlite3_column_count(fStmt->fRes);
68 KVSQLiteStatement::~KVSQLiteStatement()
80 void KVSQLiteStatement::Close(
Option_t*)
83 sqlite3_finalize(fStmt->fRes);
86 fStmt->fRes =
nullptr;
87 fStmt->fConn =
nullptr;
97 #define CheckStmt(method, res) \
101 SetError(-1,"Statement handle is 0",method); \
110 #define CheckErrNo(method, force, res) \
112 int stmterrno = sqlite3_errcode(fStmt->fConn); \
113 if ((stmterrno!=0) || force) { \
114 const char* stmterrmsg = sqlite3_errmsg(fStmt->fConn); \
115 if (stmterrno==0) { stmterrno = -1; stmterrmsg = "SQLite statement error"; } \
116 SetError(stmterrno, stmterrmsg, method); \
125 #define CheckGetField(method, res) \
128 if (!IsResultSetMode()) { \
129 SetError(-1,"Cannot get statement parameters",method); \
132 if ((npar<0) || (npar>=fNumPars)) { \
133 SetError(-1,Form("Invalid parameter number %d", npar),method); \
143 Bool_t KVSQLiteStatement::CheckBindError(
const char* method,
int res)
145 if (res == SQLITE_RANGE) {
146 SetError(-1,
Form(
"SQLite parameter out of bounds, error: %d %s", res, sqlite3_errmsg(fStmt->fConn)), method);
149 if (res != SQLITE_OK) {
150 SetError(-1,
Form(
"SQLite error code during parameter binding, error: %d %s", res, sqlite3_errmsg(fStmt->fConn)), method);
163 Bool_t KVSQLiteStatement::Process()
165 CheckStmt(
"Process", kFALSE);
167 int res = sqlite3_step(fStmt->fRes);
168 if ((res != SQLITE_DONE) && (res != SQLITE_ROW)) {
169 if(res == SQLITE_BUSY)
176 Info(
"Process",
"DB locked: retry same statement processing in 50ms...(%d)",i);
177 std::this_thread::sleep_for(50ms);
178 res = sqlite3_step(fStmt->fRes);
180 while((i<4) && ((res != SQLITE_DONE) && (res != SQLITE_ROW)));
181 if ((res != SQLITE_DONE) && (res != SQLITE_ROW))
183 SetError(-1,
Form(
"SQLite error code during statement-stepping: %d %s", res, sqlite3_errmsg(fStmt->fConn)),
"Process");
189 SetError(-1,
Form(
"SQLite error code during statement-stepping: %d %s", res, sqlite3_errmsg(fStmt->fConn)),
"Process");
196 if (res == SQLITE_DONE) {
197 sqlite3_reset(fStmt->fRes);
200 if (IsResultSetMode()) {
205 if (IsSetParsMode()) {
210 if (res == SQLITE_ROW) {
227 Int_t KVSQLiteStatement::GetNumAffectedRows()
229 CheckStmt(
"GetNumAffectedRows", kFALSE);
231 return (
Int_t) sqlite3_changes(fStmt->fConn);
241 Int_t KVSQLiteStatement::GetNumParameters()
243 CheckStmt(
"GetNumParameters", -1);
245 Int_t res = sqlite3_bind_parameter_count(fStmt->fRes);
247 CheckErrNo(
"GetNumParameters", kFALSE, -1);
261 Bool_t KVSQLiteStatement::StoreResult()
265 CheckStmt(
"StoreResult", kFALSE);
277 Int_t KVSQLiteStatement::GetNumFields()
289 const char* KVSQLiteStatement::GetFieldName(
Int_t nfield)
291 if (!IsResultSetMode() || (nfield < 0) || (nfield >= sqlite3_column_count(fStmt->fRes)))
294 return sqlite3_column_name(fStmt->fRes, nfield);
304 Bool_t KVSQLiteStatement::NextResultRow()
308 if (!fStmt || !IsResultSetMode())
return kFALSE;
310 if (fIterationCount == 0) {
331 Bool_t KVSQLiteStatement::NextIteration()
335 if (!IsSetParsMode()) {
336 SetError(-1,
"Cannot call for that statement",
"NextIteration");
340 if (fIterationCount == 0) {
360 const char* KVSQLiteStatement::ConvertToString(
Int_t npar)
362 CheckGetField(
"ConvertToString",
"");
364 return reinterpret_cast<const char*
>(sqlite3_column_text(fStmt->fRes, npar));
374 long double KVSQLiteStatement::ConvertToNumeric(
Int_t npar)
376 CheckGetField(
"ConvertToNumeric", -1);
378 return (
long double) sqlite3_column_double(fStmt->fRes, npar);
390 CheckGetField(
"IsNull", kFALSE);
392 return (sqlite3_column_type(fStmt->fRes, npar) == SQLITE_NULL);
404 CheckGetField(
"GetInt", -1);
406 return (
Int_t) sqlite3_column_int(fStmt->fRes, npar);
418 CheckGetField(
"GetUInt", 0);
420 return (
UInt_t) sqlite3_column_int(fStmt->fRes, npar);
432 CheckGetField(
"GetLong", -1);
434 return (
Long_t) sqlite3_column_int64(fStmt->fRes, npar);
446 CheckGetField(
"GetLong64", -1);
448 return (
Long64_t) sqlite3_column_int64(fStmt->fRes, npar);
460 CheckGetField(
"GetULong64", 0);
462 return (
ULong64_t) sqlite3_column_int64(fStmt->fRes, npar);
474 CheckGetField(
"GetDouble", -1);
476 return (
Double_t) sqlite3_column_double(fStmt->fRes, npar);
486 const char* KVSQLiteStatement::GetString(
Int_t npar)
488 CheckGetField(
"GetString",
"");
490 return reinterpret_cast<const char*
>(sqlite3_column_text(fStmt->fRes, npar));
504 CheckGetField(
"GetBinary", kFALSE);
509 size_t sz = sqlite3_column_bytes(fStmt->fRes, npar);
511 delete [](
unsigned char*) mem;
512 mem = (
void*)
new unsigned char[sz];
516 memcpy(mem, sqlite3_column_blob(fStmt->fRes, npar), sz);
530 CheckGetField(
"GetDate", kFALSE);
532 TString val =
reinterpret_cast<const char*
>(sqlite3_column_text(fStmt->fRes, npar));
535 month =
d.GetMonth();
550 CheckGetField(
"GetTime", kFALSE);
552 TString val =
reinterpret_cast<const char*
>(sqlite3_column_text(fStmt->fRes, npar));
570 CheckGetField(
"GetDatime", kFALSE);
572 TString val =
reinterpret_cast<const char*
>(sqlite3_column_text(fStmt->fRes, npar));
575 month =
d.GetMonth();
594 CheckGetField(
"GetTimestamp", kFALSE);
596 TString val =
reinterpret_cast<const char*
>(sqlite3_column_text(fStmt->fRes, npar));
603 month =
d.GetMonth();
610 frac = (
Int_t)(atof(s_frac.
Data()) * 1.E3);
624 int res = sqlite3_bind_null(fStmt->fRes, npar + 1);
626 return CheckBindError(
"SetNull", res);
638 int res = sqlite3_bind_int(fStmt->fRes, npar + 1, value);
640 return CheckBindError(
"SetInt", res);
653 int res = sqlite3_bind_int(fStmt->fRes, npar + 1, (
Int_t)value);
655 return CheckBindError(
"SetUInt", res);
667 int res = sqlite3_bind_int64(fStmt->fRes, npar + 1, value);
669 return CheckBindError(
"SetLong", res);
681 int res = sqlite3_bind_int64(fStmt->fRes, npar + 1, value);
683 return CheckBindError(
"SetLong64", res);
696 int res = sqlite3_bind_int64(fStmt->fRes, npar + 1, (
Long64_t)value);
698 return CheckBindError(
"SetULong64", res);
710 int res = sqlite3_bind_double(fStmt->fRes, npar + 1, value);
712 return CheckBindError(
"SetDouble", res);
722 Bool_t KVSQLiteStatement::SetString(
Int_t npar,
const char* value,
Int_t maxsize)
724 int res = sqlite3_bind_text(fStmt->fRes, npar + 1, value, maxsize, SQLITE_TRANSIENT);
726 return CheckBindError(
"SetString", res);
741 SetError(-1,
"Passing negative value to size for BLOB to SQLite would cause undefined behaviour, refusing it!",
"SetBinary");
745 int res = sqlite3_bind_blob(fStmt->fRes, npar + 1, mem, (
size_t)size, SQLITE_TRANSIENT);
747 return CheckBindError(
"SetBinary", res);
760 int res = sqlite3_bind_text(fStmt->fRes, npar + 1, (
char*)
d.AsSQLString(), -1, SQLITE_TRANSIENT);
762 return CheckBindError(
"SetDate", res);
776 int res = sqlite3_bind_text(fStmt->fRes, npar + 1, (
char*)
d.AsSQLString(), -1, SQLITE_TRANSIENT);
778 return CheckBindError(
"SetTime", res);
792 int res = sqlite3_bind_text(fStmt->fRes, npar + 1, (
char*)
d.AsSQLString(), -1, SQLITE_TRANSIENT);
794 return CheckBindError(
"SetDatime", res);
808 TDatime d(year, month, day, hour, min, sec);
810 value.Form(
"%s.%03d", (
char*)
d.AsSQLString(), frac);
812 int res = sqlite3_bind_text(fStmt->fRes, npar + 1,
value.Data(), -1, SQLITE_TRANSIENT);
814 return CheckBindError(
"SetTimestamp", res);
size_t size(const MatrixT &matrix)
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
char * Form(const char *fmt,...)
const char * Data() const
Ssiz_t Last(char c) const
const char * Data() const
unsigned long long ULong64_t
double min(double x, double y)