KaliVeda
Toolkit for HIC analysis
Loading...
Searching...
No Matches
KVSQLROOTFile.cpp
1#include "KVSQLROOTFile.h"
2#include "TSystem.h"
3
5
6
7
9
10KVString KVSQLROOTFile::UUID_for_object(const KVString& name) const
11{
12 // Return unique identifier used to store object with given name in ROOT file
13
14 fObjDB->select_data("objTable", "unique_id", Form("name = \"%s\"", name.Data()));
15 KVString uuid;
16 while (fObjDB->get_next_result())
17 uuid = get_objTable()["unique_id"].get_data<KVString>();
18 return uuid;
19}
20
21
22
25
27{
28 // Retrieve object from file using its name
29
30 auto it = fObjList.find(uuid.Data());// object already retrieved from file ?
31 if (it != fObjList.end()) return it->second;
32 auto t = fObjStore->Get(uuid);
33 fObjList[uuid.Data()] = t;
34 return t;
35}
36
37
38
57
59{
60 // Open or (re)create a combined ROOT object store & SQL database with info on the stored objects.
61 //
62 // \param[in] filepath path to file. any shell variables will be expanded.
63 // \param[in] option see TFile constructors for possible values. default="READ".
64 //
65 // This will actually open or create two files in the directory given by filepath:
66 // + `objStore.root` - ROOT file containing objects
67 // + `objInfos.sqlite` - SQLite database containing metadata for objects
68 //
69 // When first created, the SQLite database contains a table `objTable` with the
70 // following columns:
71 //
72 // obj_idx | name | class | unique_id
73 // ------- | ---- | ----- | ---------
74 // * | * | * | *
75 //
76 // The `unique_id` for each object is generated using TUUID.
77
78 TString FP = filepath;
80 OPT.ToUpper();
81
83 if (OPT.Contains("CREATE")) {
84 // create directory using path
85 gSystem->mkdir(filepath, true); // recursive: create any missing directories in path
86 gSystem->Chmod(filepath, 0775); // make writable for group
87 }
88 FP.Append("/");
89 TString rpath = FP + "objStore.root";
90 if (OPT == "RECREATE") gSystem->Unlink(rpath);
92 fObjStore.reset(new TFile(rpath, OPT));
95
96 TString sqlpath = FP + "objInfos.sqlite";
97 if (OPT == "RECREATE") gSystem->Unlink(sqlpath);
98 fObjDB.reset(new KVSQLite::database(sqlpath));
99 if (OPT.Contains("CREATE")) {
100 // set up object table
101 KVSQLite::table tmp("objTable");
102 tmp.add_primary_key("obj_idx");
103 tmp.add_column("name", "TEXT");
104 tmp.add_column("class", "TEXT");
105 tmp.add_column("unique_id", "TEXT");
106 fObjDB->add_table(tmp);
107 }
108 gSystem->Chmod(sqlpath, 0664); // make writable for group
109}
110
111
112
116
118{
119 // Manually 'delete' ROOT file in order to force writing to disk,
120 // then change access permissions to make it writable for group
121
122 fObjStore.reset(nullptr);
124}
125
126
127
147
149{
150 // Write object in ROOT file, store infos given in list
151 //
152 // @param obj pointer to object to store
153 // @param infos list of metadata associated with object
154 //
155 // If it does not already exist, this will add to the SQLite database a table `objInfos` with the following columns:
156 //
157 // info_idx | obj_idx
158 // -------- | -------
159 // * | *
160 //
161 // This table will be augmented with columns corresponding to the names of the metadata contained in infos.
162 // e.g. if infos = {{"name","john"},{"age",50}} the table will become
163 //
164 // info_idx | obj_idx | name | age
165 // -------- | ------- | ---- | ---
166 // * | * | * | *
167 //
168
169 if (!fObjDB->has_table("objInfos")) {
170 // set up object info table if not already done
171 KVSQLite::table tmp("objInfos");
172 tmp.add_primary_key("info_idx");
173 tmp.add_foreign_key("objTable", "obj_idx");
174 fObjDB->add_table(tmp);
175 }
176 // add any missing columns to info table
177 fObjDB->add_missing_columns("objInfos", infos);
178 // get unique ID for object
179 TUUID unid;
180 TString unique_id = unid.AsString();
181 // write object in ROOT file
183 fObjStore->cd();
184 obj->Write(unique_id);
186 // store infos on object
187 // 1 - write name, class & unique id in object table
188 fObjDB->prepare_data_insertion("objTable");
189 get_objTable()["name"] = obj->GetName();
190 get_objTable()["class"] = obj->ClassName();
191 get_objTable()["unique_id"] = unique_id;
192 fObjDB->insert_data_row();
193 fObjDB->end_data_insertion();
194 // 2 - get index of object from object table
195 fObjDB->select_data("objTable", "obj_idx", Form("unique_id=\"%s\"", unique_id.Data()));
196 int obj_idx;
197 while (fObjDB->get_next_result()) obj_idx = get_objTable()["obj_idx"].get_data<int>();
198 // 3 - add infos on object in info table
199 fObjDB->prepare_data_insertion("objInfos");
200 KVNameValueList info_copy(infos);
201 info_copy.SetValue("obj_idx", obj_idx);
202 //get_objInfos()["obj_idx"]=obj_idx;
203 //for(auto& info : infos) get_objInfos()[info.GetName()]=info;
204 get_objInfos().prepare_data(info_copy);
205 fObjDB->insert_data_row();
206 fObjDB->end_data_insertion();
207}
208
209
210
213
215{
216 // Return pointer to object with given name
217
219}
220
221
222
225
227{
228 // List the contents of the file with associated infos
229 KVString colnames = "name,class,";
230 colnames += get_objInfos().get_column_names("obj_idx info_idx");
231 colnames.Begin(",");
232 TString tabs("\t\t\t\t");
233 while (!colnames.End()) {
234 std::cout << colnames.Next() << tabs;
235 }
236 std::cout << "\n==========================================================================================\n";
237 if (fObjDB->select_data("objTable,objInfos", colnames)) {
238 while (fObjDB->get_next_result()) {
239 colnames.Begin(",");
240 while (!colnames.End()) {
241 auto colname = colnames.Next();
242 if (colname == "name" || colname == "class")
243 std::cout << get_objTable()[colname].get_data<TString>() << tabs;
244 else
245 std::cout << get_objInfos()[colname].get_data<TString>() << tabs;
246 }
247 std::cout << std::endl;
248 }
249 }
250 else {
251 Error("ls", "Problem with KVSQLite::database::select_data");
252 }
253}
254
255
256
277
279{
280 // Fill the list given as argument with pointers to all objects which obey the given selection.
281 //
282 // The 'where' string will be used as the `WHERE` clause of an SQLite selection.
283 //
284 // Examples:
285 //
286 //~~~~
287 //WHERE column_1 = 100;
288 //
289 //WHERE column_2 IN (1,2,3);
290 //
291 //WHERE column_3 LIKE 'An%';
292 //
293 //WHERE column_4 BETWEEN 10 AND 20;
294 //~~~~
295 //
296 // Note that string arguments should be enclosed in single quotes.
297 //
298 // The columns of both the `objTable` (`name`, `class`) and `objInfos` tables can be used in the selection.
299
300 fObjDB->select_data("objTable,objInfos", "unique_id", where);
301 while (fObjDB->get_next_result()) {
302 auto uuid = get_objTable()["unique_id"].get_data<KVString>();
303 list->Add(get_object_with_UUID(uuid));
304 }
305}
306
307
331
332void KVSQLROOTFile::FillListOfObjectsWithSelection(KVSeqCollection* list, const KVString& where, const KVString& numberlist_column, int value)
333{
334 // Fill the list given as argument with pointers to all objects which obey the given selection.
335 // 'numberlist_column' is the name of a column in the `objInfos` table containing strings which may be
336 // interpreted as KVNumberList objects. Only the entries with a number list containing 'value'
337 // will be selected.
338 //
339 // The 'where' string will be used as the `WHERE` clause of an SQLite selection.
340 //
341 // Examples:
342 //
343 //~~~~
344 //WHERE column_1 = 100;
345 //
346 //WHERE column_2 IN (1,2,3);
347 //
348 //WHERE column_3 LIKE 'An%';
349 //
350 //WHERE column_4 BETWEEN 10 AND 20;
351 //~~~~
352 //
353 // Note that string arguments should be enclosed in single quotes.
354 //
355 // The columns of both the `objTable` (`name`, `class`) and `objInfos` tables can be used in the selection.
356
357 fObjDB->select_data("objTable,objInfos", Form("unique_id,%s", numberlist_column.Data()), where);
358 while (fObjDB->get_next_result()) {
359 KVNumberList nl(get_objInfos()[numberlist_column].get_data<KVString>());
360 if (nl.Contains(value)) {
361 auto uuid = get_objTable()["unique_id"].get_data<KVString>();
362 list->Add(get_object_with_UUID(uuid));
363 }
364 }
365}
366
367
#define OPT
const char Option_t
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
char name[80]
char * Form(const char *fmt,...)
R__EXTERN TSystem * gSystem
Handles lists of named parameters with different types, a list of KVNamedParameter objects.
void SetValue(const Char_t *name, value_type value)
Strings used to represent a set of ranges of values.
Bool_t Contains(Int_t val) const
returns kTRUE if the value 'val' is contained in the ranges defined by the number list
Combine ROOT file containing objects with SQLite database with info on the objects.
KVSQLite::table & get_objInfos() const
void WriteObject(const TObject *, const KVNameValueList &)
KVSQLite::table & get_objTable() const
void FillListOfObjectsWithSelection(KVSeqCollection *list, const KVString &where)
TObject * Get(const KVString &name) const
Return pointer to object with given name.
void ls(Option_t *="") const
List the contents of the file with associated infos.
std::unordered_map< std::string, TObject * > fObjList
for quick look-up of objects using unique id
TObject * get_object_with_UUID(const KVString &name) const
Retrieve object from file using its name.
void restore_working_directory()
KVString UUID_for_object(const KVString &) const
Return unique identifier used to store object with given name in ROOT file.
std::unique_ptr< TFile > fObjStore
TString fCurrentROOTFilePath
full path to current ROOT file
std::unique_ptr< KVSQLite::database > fObjDB
KVSQLROOTFile(const KVString &filepath, Option_t *option="READ")
void save_working_directory()
Interface to ROOT SQLite database backend.
Definition SQLiteDB.h:401
const column & add_foreign_key(const TString &other_table, const TString &other_column)
const column & add_primary_key(const TString &name)
column & add_column(const KVSQLite::column &c)
TString get_column_names(const TString &exclude="", const TString &delim=",") const
void prepare_data(const KVNameValueList &, const KVNamedParameter *=nullptr)
KaliVeda extensions to ROOT collection classes.
virtual void Add(TObject *obj)
Extension of ROOT TString class which allows backwards compatibility with ROOT v3....
Definition KVString.h:73
void Begin(TString delim) const
Definition KVString.cpp:565
Bool_t End() const
Definition KVString.cpp:634
KVString Next(Bool_t strip_whitespace=kFALSE) const
Definition KVString.cpp:695
virtual const char * GetName() const
virtual const char * ClassName() const
virtual Int_t Write(const char *name=nullptr, Int_t option=0, Int_t bufsize=0)
virtual void Error(const char *method, const char *msgfmt,...) const
const char * Data() const
TString & Append(char c, Ssiz_t rep=1)
virtual int Chmod(const char *file, UInt_t mode)
virtual int mkdir(const char *name, Bool_t recursive=kFALSE)
virtual char * ExpandPathName(const char *path)
virtual int Unlink(const char *name)
const char * AsString() const
ClassImp(TPyArg)