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;
 
  156static sqlite3_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);
 
  200      ::Error(
"VfsRdOnlyOpen", 
"cannot determine file size of %s\n", zName);
 
  204   p->pFile.pMethods = &io_methods;
 
  214int VfsRdOnlyDelete(sqlite3_vfs * , 
const char * , 
int )
 
  216   return SQLITE_IOERR_DELETE;
 
  221int VfsRdOnlyAccess(sqlite3_vfs * , 
const char * , 
int flags, 
int *pResOut)
 
  224   if (flags == SQLITE_ACCESS_READWRITE) {
 
  225      return SQLITE_OPEN_READONLY;
 
  232int VfsRdOnlyFullPathname(sqlite3_vfs * , 
const char *zPath, 
int nOut, 
char *zOut)
 
  234   zOut[nOut - 1] = 
'\0';
 
  235   sqlite3_snprintf(nOut, zOut, 
"%s", zPath);
 
  241int VfsRdOnlyRandomness(sqlite3_vfs * , 
int nBuf, 
char *zBuf)
 
  243   for (
int i = 0; i < nBuf; ++i) {
 
  251int VfsRdOnlySleep(sqlite3_vfs * , 
int microseconds)
 
  260int VfsRdOnlyGetLastError(sqlite3_vfs * , 
int , 
char * )
 
  267int VfsRdOnlyCurrentTimeInt64(sqlite3_vfs * , sqlite3_int64 *piNow)
 
  269   static constexpr sqlite3_int64 unixEpoch = 24405875 * (sqlite3_int64)8640000;
 
  272   *piNow = ((sqlite3_int64)t) * 1000 + unixEpoch;
 
  278int VfsRdOnlyCurrentTime(sqlite3_vfs *vfs, 
double *prNow)
 
  281   int rc = VfsRdOnlyCurrentTimeInt64(vfs, &i);
 
  282   *prNow = i / 86400000.0;
 
  289static sqlite3_vfs GetSqlite3Vfs()
 
  294   memset(&vfs, 0, 
sizeof(vfs));
 
  296   vfs.szOsFile      = 
sizeof(VfsRootFile);
 
  297   vfs.mxPathname    = 2000;
 
  298   vfs.zName         = gSQliteVfsName;
 
  299   vfs.xOpen         = VfsRdOnlyOpen;
 
  300   vfs.xDelete       = VfsRdOnlyDelete;
 
  301   vfs.xAccess       = VfsRdOnlyAccess;
 
  302   vfs.xFullPathname = VfsRdOnlyFullPathname;
 
  303   vfs.xRandomness   = VfsRdOnlyRandomness;
 
  304   vfs.xSleep        = VfsRdOnlySleep;
 
  305   vfs.xCurrentTime  = VfsRdOnlyCurrentTime;
 
  306   vfs.xGetLastError = VfsRdOnlyGetLastError;
 
  312static struct sqlite3_vfs kSqlite3Vfs = GetSqlite3Vfs();
 
  314static bool RegisterSqliteVfs()
 
  317   retval = sqlite3_vfs_register(&kSqlite3Vfs, 
false);
 
  318   return (retval == SQLITE_OK);
 
  337   : fType(
type), fIsActive(false), fInteger(0), fReal(0.0), fText(), fBlob(), fNull(nullptr)
 
  345   default: 
throw std::runtime_error(
"Internal error");
 
  360   static bool hasSqliteVfs = RegisterSqliteVfs();
 
  362      throw std::runtime_error(
"Cannot register SQlite VFS in RSqliteDS");
 
  366   retval = sqlite3_open_v2(fileName.c_str(), &
fDataSet->fDb, SQLITE_OPEN_READONLY | SQLITE_OPEN_NOMUTEX,
 
  368   if (retval != SQLITE_OK)
 
  376   retval = sqlite3_exec(
fDataSet->fDb, 
"PRAGMA temp_store=2;", 
nullptr, 
nullptr, 
nullptr);
 
  377   if (retval != SQLITE_OK)
 
  380   retval = sqlite3_prepare_v2(
fDataSet->fDb, query.c_str(), -1, &
fDataSet->fQuery, 
nullptr);
 
  381   if (retval != SQLITE_OK)
 
  384   int colCount = sqlite3_column_count(
fDataSet->fQuery);
 
  385   retval = sqlite3_step(
fDataSet->fQuery);
 
  386   if ((retval != SQLITE_ROW) && (retval != SQLITE_DONE))
 
  390   for (
int i = 0; i < colCount; ++i) {
 
  392      int type = SQLITE_NULL;
 
  395      const char *declTypeCstr = sqlite3_column_decltype(
fDataSet->fQuery, i);
 
  396      if (declTypeCstr == 
nullptr) {
 
  397         if (retval == SQLITE_ROW)
 
  400         std::string declType(declTypeCstr);
 
  401         std::transform(declType.begin(), declType.end(), declType.begin(), ::toupper);
 
  402         if (declType == 
"INTEGER")
 
  403            type = SQLITE_INTEGER;
 
  404         else if (declType == 
"FLOAT")
 
  406         else if (declType == 
"TEXT")
 
  408         else if (declType == 
"BLOB")
 
  411            throw std::runtime_error(
"Unexpected column decl type");
 
  436      default: 
throw std::runtime_error(
"Unhandled data type");
 
  472      std::string errmsg = 
"The type selected for column \"";
 
  474      errmsg += 
"\" does not correspond to column type, which is ";
 
  476      throw std::runtime_error(errmsg);
 
  488   std::vector<std::pair<ULong64_t, ULong64_t>> entryRanges;
 
  489   int retval = sqlite3_step(
fDataSet->fQuery);
 
  491   case SQLITE_DONE: 
return entryRanges;
 
  509   for (
unsigned i = 0; i < 
N; ++i) {
 
  514   throw std::runtime_error(
"Unknown column: " + std::string(colName));
 
  529   int retval = sqlite3_reset(
fDataSet->fQuery);
 
  530   if (retval != SQLITE_OK)
 
  531      throw std::runtime_error(
"SQlite error, reset");
 
  545   ROOT::RDataFrame rdf(std::make_unique<RSqliteDS>(std::string(fileName), std::string(query)));
 
  562   assert(entry + 1 == 
fNRow);
 
  565   for (
unsigned i = 0; i < 
N; ++i) {
 
  574         nbytes = sqlite3_column_bytes(
fDataSet->fQuery, i);
 
  578            fValues[i].fText = 
reinterpret_cast<const char *
>(sqlite3_column_text(
fDataSet->fQuery, i));
 
  582         nbytes = sqlite3_column_bytes(
fDataSet->fQuery, i);
 
  583         fValues[i].fBlob.resize(nbytes);
 
  585            std::memcpy(
fValues[i].fBlob.data(), sqlite3_column_blob(
fDataSet->fQuery, i), nbytes);
 
  589      default: 
throw std::runtime_error(
"Unhandled column type");
 
  600      ::Warning(
"SetNSlots", 
"Currently the SQlite data source faces performance degradation in multi-threaded mode. " 
  601                             "Consider turning off IMT.");
 
  610   std::string errmsg = 
"SQlite error: ";
 
  611#if SQLITE_VERSION_NUMBER < 3007015 
  612   errmsg += std::to_string(errcode);
 
  614   errmsg += sqlite3_errstr(errcode);
 
  616   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.
static constexpr int kFeatureHasSize
GetSize() does not return kUnknownFileSize.
std::vector< void * > Record_t
void SetNSlots(unsigned int nSlots) final
Almost a no-op, many slots can in fact reduce the performance due to thread synchronization.
static constexpr char const  * fgTypeNames[]
Corresponds to the types defined in ETypes.
std::string GetLabel() final
Return a string representation of the datasource type.
std::vector< std::string > fColumnNames
~RSqliteDS()
Frees the sqlite resources and closes the file.
bool HasColumn(std::string_view colName) const final
A linear search through the columns for the given name.
void Initialize() final
Resets the SQlite query engine at the beginning of the event loop.
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.
Record_t GetColumnReadersImpl(std::string_view name, const std::type_info &) final
Activates the given column's result value.
RSqliteDS(const std::string &fileName, const std::string &query)
Build the dataframe.
std::unique_ptr< Internal::RSqliteDSDataSet > fDataSet
std::vector< std::pair< ULong64_t, ULong64_t > > GetEntryRanges() final
Returns a range of size 1 as long as more rows are available in the SQL result set.
const std::vector< std::string > & GetColumnNames() const final
Returns the SELECT queries names.
bool SetEntry(unsigned int slot, ULong64_t entry) final
Stores the result of the current active sqlite query row as a C++ value.
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.
RDataFrame MakeSqliteDataFrame(std::string_view fileName, std::string_view query)
Factory method to create a SQlite RDataFrame.
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.
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