44constexpr char const *gSQliteVfsName =
"ROOT-Davix-readonly";
53 VfsRootFile() =
default;
56 std::unique_ptr<ROOT::Internal::RRawFile> fRawFile;
63int VfsRdOnlyClose(sqlite3_file *pFile)
65 VfsRootFile *
p =
reinterpret_cast<VfsRootFile *
>(pFile);
73int VfsRdOnlyRead(sqlite3_file *pFile,
void *zBuf,
int count, sqlite_int64
offset)
75 VfsRootFile *
p =
reinterpret_cast<VfsRootFile *
>(pFile);
76 auto nbytes =
p->fRawFile->ReadAt(zBuf, count,
offset);
77 return (nbytes !=
static_cast<unsigned int>(count)) ? SQLITE_IOERR : SQLITE_OK;
82int VfsRdOnlyWrite(sqlite3_file * ,
const void * ,
int , sqlite_int64 )
84 return SQLITE_OPEN_READONLY;
89int VfsRdOnlyTruncate(sqlite3_file * , sqlite_int64 )
91 return SQLITE_OPEN_READONLY;
96int VfsRdOnlySync(sqlite3_file * ,
int )
103int VfsRdOnlyFileSize(sqlite3_file *pFile, sqlite_int64 *pSize)
105 VfsRootFile *
p =
reinterpret_cast<VfsRootFile *
>(pFile);
106 *pSize =
p->fRawFile->GetSize();
112int VfsRdOnlyLock(sqlite3_file * ,
int )
119int VfsRdOnlyUnlock(sqlite3_file * ,
int )
126int VfsRdOnlyCheckReservedLock(sqlite3_file * ,
int *pResOut)
134int VfsRdOnlyFileControl(sqlite3_file * ,
int ,
void * )
136 return SQLITE_NOTFOUND;
141int VfsRdOnlySectorSize(sqlite3_file * )
143 return SQLITE_OPEN_READONLY;
148int VfsRdOnlyDeviceCharacteristics(sqlite3_file * )
150 return SQLITE_OPEN_READONLY;
156sqlite3_io_methods GetSqlite3IoMethods()
160 sqlite3_io_methods io_methods;
161 memset(&io_methods, 0,
sizeof(io_methods));
162 io_methods.iVersion = 1;
163 io_methods.xClose = VfsRdOnlyClose;
164 io_methods.xRead = VfsRdOnlyRead;
165 io_methods.xWrite = VfsRdOnlyWrite;
166 io_methods.xTruncate = VfsRdOnlyTruncate;
167 io_methods.xSync = VfsRdOnlySync;
168 io_methods.xFileSize = VfsRdOnlyFileSize;
169 io_methods.xLock = VfsRdOnlyLock;
170 io_methods.xUnlock = VfsRdOnlyUnlock;
171 io_methods.xCheckReservedLock = VfsRdOnlyCheckReservedLock;
172 io_methods.xFileControl = VfsRdOnlyFileControl;
173 io_methods.xSectorSize = VfsRdOnlySectorSize;
174 io_methods.xDeviceCharacteristics = VfsRdOnlyDeviceCharacteristics;
180int VfsRdOnlyOpen(sqlite3_vfs * ,
const char *zName, sqlite3_file *pFile,
int flags,
int * )
183 VfsRootFile *
p =
new (pFile) VfsRootFile();
184 p->pFile.pMethods =
nullptr;
188 static const sqlite3_io_methods io_methods = GetSqlite3IoMethods();
190 if (flags & (SQLITE_OPEN_READWRITE | SQLITE_OPEN_DELETEONCLOSE | SQLITE_OPEN_EXCLUSIVE))
195 ::Error(
"VfsRdOnlyOpen",
"Cannot open %s\n", zName);
199 p->pFile.pMethods = &io_methods;
209int VfsRdOnlyDelete(sqlite3_vfs * ,
const char * ,
int )
211 return SQLITE_IOERR_DELETE;
216int VfsRdOnlyAccess(sqlite3_vfs * ,
const char * ,
int flags,
int *pResOut)
219 if (flags == SQLITE_ACCESS_READWRITE) {
220 return SQLITE_OPEN_READONLY;
227int VfsRdOnlyFullPathname(sqlite3_vfs * ,
const char *zPath,
int nOut,
char *zOut)
229 zOut[nOut - 1] =
'\0';
230 sqlite3_snprintf(nOut, zOut,
"%s", zPath);
236int VfsRdOnlyRandomness(sqlite3_vfs * ,
int nBuf,
char *zBuf)
238 for (
int i = 0; i < nBuf; ++i) {
246int VfsRdOnlySleep(sqlite3_vfs * ,
int microseconds)
255int VfsRdOnlyGetLastError(sqlite3_vfs * ,
int ,
char * )
262int VfsRdOnlyCurrentTimeInt64(sqlite3_vfs * , sqlite3_int64 *piNow)
264 static constexpr sqlite3_int64 unixEpoch = 24405875 * (sqlite3_int64)8640000;
267 *piNow = ((sqlite3_int64)t) * 1000 + unixEpoch;
273int VfsRdOnlyCurrentTime(sqlite3_vfs *vfs,
double *prNow)
276 int rc = VfsRdOnlyCurrentTimeInt64(vfs, &i);
277 *prNow = i / 86400000.0;
284sqlite3_vfs GetSqlite3Vfs()
289 memset(&vfs, 0,
sizeof(vfs));
291 vfs.szOsFile =
sizeof(VfsRootFile);
292 vfs.mxPathname = 2000;
293 vfs.zName = gSQliteVfsName;
294 vfs.xOpen = VfsRdOnlyOpen;
295 vfs.xDelete = VfsRdOnlyDelete;
296 vfs.xAccess = VfsRdOnlyAccess;
297 vfs.xFullPathname = VfsRdOnlyFullPathname;
298 vfs.xRandomness = VfsRdOnlyRandomness;
299 vfs.xSleep = VfsRdOnlySleep;
300 vfs.xCurrentTime = VfsRdOnlyCurrentTime;
301 vfs.xGetLastError = VfsRdOnlyGetLastError;
307struct sqlite3_vfs kSqlite3Vfs = GetSqlite3Vfs();
309bool RegisterSqliteVfs()
312 retval = sqlite3_vfs_register(&kSqlite3Vfs,
false);
313 return (retval == SQLITE_OK);
332 : fType(
type), fIsActive(false), fInteger(0), fReal(0.0), fText(), fBlob(), fNull(nullptr)
340 default:
throw std::runtime_error(
"Internal error");
355 static bool hasSqliteVfs = RegisterSqliteVfs();
357 throw std::runtime_error(
"Cannot register SQlite VFS in RSqliteDS");
361 retval = sqlite3_open_v2(fileName.c_str(), &
fDataSet->fDb, SQLITE_OPEN_READONLY | SQLITE_OPEN_NOMUTEX,
363 if (retval != SQLITE_OK)
371 retval = sqlite3_exec(
fDataSet->fDb,
"PRAGMA temp_store=2;",
nullptr,
nullptr,
nullptr);
372 if (retval != SQLITE_OK)
375 retval = sqlite3_prepare_v2(
fDataSet->fDb, query.c_str(), -1, &
fDataSet->fQuery,
nullptr);
376 if (retval != SQLITE_OK)
379 int colCount = sqlite3_column_count(
fDataSet->fQuery);
380 retval = sqlite3_step(
fDataSet->fQuery);
381 if ((retval != SQLITE_ROW) && (retval != SQLITE_DONE))
385 for (
int i = 0; i < colCount; ++i) {
387 int type = SQLITE_NULL;
390 const char *declTypeCstr = sqlite3_column_decltype(
fDataSet->fQuery, i);
391 if (declTypeCstr ==
nullptr) {
392 if (retval == SQLITE_ROW)
395 std::string declType(declTypeCstr);
396 std::transform(declType.begin(), declType.end(), declType.begin(), ::toupper);
397 if (declType ==
"INTEGER")
398 type = SQLITE_INTEGER;
399 else if (declType ==
"FLOAT")
401 else if (declType ==
"TEXT")
403 else if (declType ==
"BLOB")
406 throw std::runtime_error(
"Unexpected column decl type");
431 default:
throw std::runtime_error(
"Unhandled data type");
438RSqliteDS::~RSqliteDS()
451const std::vector<std::string> &RSqliteDS::GetColumnNames()
const
467 std::string errmsg =
"The type selected for column \"";
469 errmsg +=
"\" does not correspond to column type, which is ";
471 throw std::runtime_error(errmsg);
481std::vector<std::pair<ULong64_t, ULong64_t>> RSqliteDS::GetEntryRanges()
483 std::vector<std::pair<ULong64_t, ULong64_t>> entryRanges;
484 int retval = sqlite3_step(
fDataSet->fQuery);
486 case SQLITE_DONE:
return entryRanges;
500std::string RSqliteDS::GetTypeName(std::string_view colName)
const
504 for (
unsigned i = 0; i <
N; ++i) {
509 throw std::runtime_error(
"Unknown column: " + std::string(colName));
514bool RSqliteDS::HasColumn(std::string_view colName)
const
521void RSqliteDS::Initialize()
524 int retval = sqlite3_reset(
fDataSet->fQuery);
525 if (retval != SQLITE_OK)
526 throw std::runtime_error(
"SQlite error, reset");
529std::string RSqliteDS::GetLabel()
540 ROOT::RDataFrame rdf(std::make_unique<RSqliteDS>(std::string(fileName), std::string(query)));
548 assert(entry + 1 ==
fNRow);
551 for (
unsigned i = 0; i <
N; ++i) {
560 nbytes = sqlite3_column_bytes(
fDataSet->fQuery, i);
564 fValues[i].fText =
reinterpret_cast<const char *
>(sqlite3_column_text(
fDataSet->fQuery, i));
568 nbytes = sqlite3_column_bytes(
fDataSet->fQuery, i);
569 fValues[i].fBlob.resize(nbytes);
571 std::memcpy(
fValues[i].fBlob.data(), sqlite3_column_blob(
fDataSet->fQuery, i), nbytes);
575 default:
throw std::runtime_error(
"Unhandled column type");
583void RSqliteDS::SetNSlots(
unsigned int nSlots)
586 ::Warning(
"SetNSlots",
"Currently the SQlite data source faces performance degradation in multi-threaded mode. "
587 "Consider turning off IMT.");
594void RSqliteDS::SqliteError(
int errcode)
596 std::string errmsg =
"SQlite error: ";
597#if SQLITE_VERSION_NUMBER < 3007015
598 errmsg += std::to_string(errcode);
600 errmsg += sqlite3_errstr(errcode);
602 throw std::runtime_error(errmsg);
unsigned long long ULong64_t
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
R__EXTERN TRandom * gRandom
R__EXTERN TSystem * gSystem
static std::unique_ptr< RRawFile > Create(std::string_view url, ROptions options=ROptions())
Factory method that returns a suitable concrete implementation according to the transport in the url.
std::vector< void * > Record_t
static constexpr char const * fgTypeNames[]
Corresponds to the types defined in ETypes.
std::vector< std::string > fColumnNames
std::vector< ETypes > fColumnTypes
std::string GetTypeName(std::string_view colName) const final
Returns the C++ type for a given column name, implemented as a linear search through all the columns.
ETypes
All the types known to SQlite. Changes require changing fgTypeNames, too.
RSqliteDS(const std::string &fileName, const std::string &query)
Build the dataframe.
std::unique_ptr< Internal::RSqliteDSDataSet > fDataSet
void SqliteError(int errcode)
Helper function to throw an exception if there is a fatal sqlite error, e.g. an I/O error.
std::vector< Value_t > fValues
The data source is inherently single-threaded and returns only one row at a time. This vector holds t...
ROOT's RDataFrame offers a modern, high-level interface for analysis of data stored in TTree ,...
virtual UInt_t Integer(UInt_t imax)
Returns a random integer uniformly distributed on the interval [ 0, imax-1 ].
virtual void Sleep(UInt_t milliSec)
Sleep milliSec milli seconds.
RDataFrame FromSqlite(std::string_view fileName, std::string_view query)
Factory method to create a SQlite RDataFrame.
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
The state of an open dataset in terms of the sqlite3 C library.
void * fPtr
Points to one of the values; an address to this pointer is returned by GetColumnReadersImpl.
std::vector< unsigned char > fBlob