ATLAS Offline Software
Loading...
Searching...
No Matches
CoraCoolDatabase Class Reference

#include <CoraCoolDatabase.h>

Collaboration diagram for CoraCoolDatabase:

Public Member Functions

 CoraCoolDatabase (const std::string &m_dbconn, cool::IDatabasePtr cooldb, coral::IConnectionService &coralsvc, const bool readonly=false)
bool connect ()
bool disconnect ()
const std::string & dbname () const
cool::IDatabasePtr coolDatabase () const
CoraCoolFolderPtr createFolder (const std::string &coolpath, const std::string &coraltable, const cool::IRecordSpecification &fkspec, const cool::IRecordSpecification &payloadspec, const std::string &coralfk, const std::string &coralpk, const std::string &description="", const cool::FolderVersioning::Mode mode=cool::FolderVersioning::SINGLE_VERSION, const bool createParents=false)
CoraCoolFolderPtr getFolder (const std::string &coolfolder)
bool existsFolder (const std::string &coolfolder)
bool parseFolderDescription (const std::string &folderdesc, std::string &tablename, std::string &keycolcool, std::string &fkeycolcoral, std::string &pkeycolcoral)
bool deleteFolder (const std::string &coolfolder)

Private Member Functions

bool extractCoralConStr (std::string_view coolstr)
std::string encodeAttrSpec (const cool::IRecordSpecification &spec)
bool storeSpec (const std::string &tablename, const std::string &spec)

Private Attributes

cool::IDatabasePtr m_cooldb
std::string m_dbconn
std::string m_dbname
bool m_connected
bool m_readonly
coral::IConnectionService & m_coralsvc
coral::ISessionProxy * m_proxy
coral::MessageStream m_log

Detailed Description

Definition at line 24 of file CoraCoolDatabase.h.

Constructor & Destructor Documentation

◆ CoraCoolDatabase()

CoraCoolDatabase::CoraCoolDatabase ( const std::string & m_dbconn,
cool::IDatabasePtr cooldb,
coral::IConnectionService & coralsvc,
const bool readonly = false )

Definition at line 37 of file CoraCoolDatabase.cxx.

40 :
41 m_cooldb(std::move(cooldb)),
42 m_connected(false),
43 m_readonly(readonly),
44 m_coralsvc(coralsvc),
45 m_proxy(0),
46 m_log("CoraCool")
47{
48 if (!extractCoralConStr(dbconn)) {
49 m_log << coral::Error << "Cannot derive CORAL connection string from: "
50 << dbconn << coral::MessageStream::endmsg;
51 throw CoraCoolException("Bad connection string",
52 "CoraCoolDatabase::CoraCoolDatabase");
53 }
54 m_log << coral::Debug << "CORAL dbconnection string is: " << m_dbconn
55 << coral::MessageStream::endmsg;
56}
coral::IConnectionService & m_coralsvc
coral::ISessionProxy * m_proxy
coral::MessageStream m_log
bool extractCoralConStr(std::string_view coolstr)
cool::IDatabasePtr m_cooldb

Member Function Documentation

◆ connect()

bool CoraCoolDatabase::connect ( )

Definition at line 58 of file CoraCoolDatabase.cxx.

58 {
59 if (!m_connected) {
60 coral::AccessMode access=m_readonly ? coral::ReadOnly : coral::Update;
61 try {
62 m_proxy=m_coralsvc.connect(m_dbconn,access);
63 m_connected=true;
64 }
65 catch (std::exception& e) {
66 m_log << coral::Error << "Exception caught: " << e.what() <<
67 coral::MessageStream::endmsg;
68 m_connected=false;
69 }
70 }
71 return m_connected;
72}
access(filename, mode)

◆ coolDatabase()

cool::IDatabasePtr CoraCoolDatabase::coolDatabase ( ) const
inline

Definition at line 99 of file CoraCoolDatabase.h.

100{return m_cooldb; }

◆ createFolder()

CoraCoolFolderPtr CoraCoolDatabase::createFolder ( const std::string & coolpath,
const std::string & coraltable,
const cool::IRecordSpecification & fkspec,
const cool::IRecordSpecification & payloadspec,
const std::string & coralfk,
const std::string & coralpk,
const std::string & description = "",
const cool::FolderVersioning::Mode mode = cool::FolderVersioning::SINGLE_VERSION,
const bool createParents = false )

Definition at line 199 of file CoraCoolDatabase.cxx.

207 {
208
209 // check input parameters
210 if (coraltable.size()>18) throw CoraCoolException(
211 "CORAL tablename too long (max 18 chars)",
212 "CoraCoolDatabase::createFolder");
213 // encode the folder description string
214 // first remove any existing coracool string
215 std::string::size_type p1,p2;
216 std::string newdesc=description;
217 p1=description.find("<coracool>");
218 p2=description.find("</coracool>");
219 if (p1!=std::string::npos && p2!=std::string::npos) {
220 newdesc=description.substr(0,p1);
221 newdesc.append(description, p2+11);
222 }
223 // COOL foreign key column is name of COOL payload attribute
224 newdesc+="<coracool>";
225 newdesc+=coraltable;
226 newdesc+=':';
227 newdesc+=fkspec[0].name();
228 newdesc+=':';
229 newdesc+= coralfk;
230 newdesc+=':';
231 newdesc+=coralpk;
232 newdesc+="</coracool>";
233 m_log << coral::Debug << "Created new description: " << newdesc <<
234 coral::MessageStream::endmsg;
235
236 // check for rows in key generation table, create if needed
237 // start transaction here
238 connect();
239 m_proxy->transaction().start(false);
240 CoraCoolSequence seqfk(m_dbname,m_dbname+"_"+coraltable+"_FK",m_proxy,true);
241 if (coralfk!=coralpk)
242 CoraCoolSequence seqpk(m_dbname,m_dbname+"_"+coraltable+"_PK",m_proxy,true);
243
244 // endcode and store the attributelist specification in CORACOOLATTR table
245 if (!storeSpec(m_dbname+"_"+coraltable,
246 encodeAttrSpec(payloadspec)))
247 throw CoraCoolException("Cannot store payload specification",
248 "CoraCoolDatabase::createFolder");
249
250 // create CORAL table
251 try {
252 m_log << coral::Debug << "Generate CORAL table:" << coraltable <<
253 coral::MessageStream::endmsg;
254 coral::TableDescription tdesc("CoraCoolPayload");
255 tdesc.setName(m_dbname+"_"+coraltable);
256 for (unsigned int i=0;i<payloadspec.size();++i) {
257 const cool::IFieldSpecification& field=payloadspec[i];
258 int maxsize=field.storageType().maxSize();
259 if (field.storageType()==cool::StorageType::Blob64k) maxsize=0;
260 const std::string typen=coral::AttributeSpecification::typeNameForId(
261 field.storageType().cppType());
262 m_log << coral::Debug << "Insert column " << field.name() <<
263 " of type " << typen << std::endl;
264 tdesc.insertColumn(field.name(),typen,maxsize,false);
265 }
266 // declare primary key
267 tdesc.setPrimaryKey(coralpk);
268 // create separate index on FK if different
269 if (coralfk!=coralpk)
270 tdesc.createIndex(m_dbname+"_"+coraltable+"F",coralfk,false);
271
272 m_proxy->nominalSchema().createTable(tdesc);
273 m_proxy->transaction().commit();
274 m_log << coral::Debug << "Created coral table " << coral::MessageStream::endmsg;
275
276 // disconnect/reconnect to avoid connection problems
277 disconnect();
278 sleep(1);
279 connect();
280 }
281 catch (std::exception& e) {
282 // problem in table creation
283 throw CoraCoolException(e.what(),"CoraCoolDatabase::createFolder");
284 }
285
286 // create corresponding COOL folder
287 // this has to go after CORAL manipulations otherwise get problems
288 // with schema consistency
289 // disconnect/reconnect to COOL first in order to reset COOL
290 // avoiding problems due to the reset database connection
291 m_log << coral::Debug << "Disconnect/reconnect COOL connection" <<
292 coral::MessageStream::endmsg;
293 m_cooldb->closeDatabase();
294 m_cooldb->openDatabase();
295 m_log << coral::Debug << "Create COOL folder" << coolpath << coral::MessageStream::endmsg;
296
297 m_cooldb->createFolder(coolpath,
298 cool::FolderSpecification(mode,fkspec),newdesc,createParents);
299 m_log << coral::Debug << "Created COOL folder" << coral::MessageStream::endmsg;
300
301 // all structures created,
302 // generate return value by instantiating new folder
303 CoraCoolFolderPtr folder(new CoraCoolFolder(coolpath,
304 m_proxy, m_cooldb,this,m_log));
305 return folder;
306}
boost::shared_ptr< CoraCoolFolder > CoraCoolFolderPtr
std::string encodeAttrSpec(const cool::IRecordSpecification &spec)
bool storeSpec(const std::string &tablename, const std::string &spec)
std::string description
glabal timer - how long have I taken so far?
Definition hcg.cxx:91

◆ dbname()

const std::string & CoraCoolDatabase::dbname ( ) const
inline

Definition at line 97 of file CoraCoolDatabase.h.

97{ return m_dbname; }

◆ deleteFolder()

bool CoraCoolDatabase::deleteFolder ( const std::string & coolfolder)

Definition at line 369 of file CoraCoolDatabase.cxx.

369 {
370 m_log << coral::Debug << "Deleting folder " << coolfolder << coral::MessageStream::endmsg;
371 std::string desc;
372 // get COOL folder and description
373 try {
374 cool::IFolderPtr folder=m_cooldb->getFolder(coolfolder);
375 desc=folder->description();
376 // delete the COOL folder
377 m_cooldb->dropNode(coolfolder);
378 }
379 catch (cool::Exception& e) {
380 throw CoraCoolException(e.what(),"CoraCoolDatabase::deleteFolder");
381 }
382 // extract the CORAL folder name
383 std::string tablename,keycolcool,fkeycolcoral,pkeycolcoral;
384 if (parseFolderDescription(desc,tablename,keycolcool,
385 fkeycolcoral,pkeycolcoral)) {
386 m_log << coral::Debug << "Drop CORAL payload table " << tablename
387 << coral::MessageStream::endmsg;
388 // drop the CORAL table
389 connect();
390 m_proxy->transaction().start(false);
391 m_proxy->nominalSchema().dropIfExistsTable(tablename);
392 // remove primary/foreign key rows from sequence table
393 CoraCoolSequence seqfk(m_dbname,tablename+"_FK",m_proxy);
394 seqfk.dropSeq();
395 if (fkeycolcoral!=pkeycolcoral) {
396 CoraCoolSequence seqpk(m_dbname,tablename+"_PK",m_proxy);
397 seqpk.dropSeq();
398 }
399 // remove the row from the CORACOOLATTR table
400 coral::AttributeList bindvar;
401 bindvar.extend<std::string>("SNAME");
402 bindvar[0].data<std::string>()=tablename;
403 coral::ITable& table=m_proxy->nominalSchema().tableHandle(
404 m_dbname+"_CORACOOLATTR");
405 long rows=table.dataEditor().deleteRows("NAME=:SNAME",bindvar);
406 if (rows!=1) m_log << coral::Error << "Unexpected number of rows "
407 << rows << " with key " << tablename <<
408 " deleted from CORACOOLATTR table" << coral::MessageStream::endmsg;
409 m_proxy->transaction().commit();
410 // pause for thought
411 disconnect();
412 sleep(1);
413 connect();
414 }
415 return true;
416}
bool parseFolderDescription(const std::string &folderdesc, std::string &tablename, std::string &keycolcool, std::string &fkeycolcoral, std::string &pkeycolcoral)

◆ disconnect()

bool CoraCoolDatabase::disconnect ( )

Definition at line 74 of file CoraCoolDatabase.cxx.

74 {
75 if (m_connected) {
76 delete m_proxy;
77 m_connected=false;
78 }
79 return m_connected;
80}

◆ encodeAttrSpec()

std::string CoraCoolDatabase::encodeAttrSpec ( const cool::IRecordSpecification & spec)
private

Definition at line 138 of file CoraCoolDatabase.cxx.

139 {
140 std::string result="";
141 unsigned int n=spec.size();
142 for (unsigned int i=0;i<n;++i) {
143 const cool::IFieldSpecification& field=spec[i];
144 result+=field.name();
145 result+=':';
146 result+=field.storageType().name();
147 if (i<n-1) result+=',';
148 }
149 return result;
150}

◆ existsFolder()

bool CoraCoolDatabase::existsFolder ( const std::string & coolfolder)

Definition at line 316 of file CoraCoolDatabase.cxx.

316 {
317 // first check if the COOL folder exists
318 if (!m_cooldb->existsFolder(coolfolder)) {
319 return false;
320 } else {
321 // if it does, check the folder description finds a coracool tag
322 // note this does not check the CORACOOL table actually exists
323 cool::IFolderPtr folder=m_cooldb->getFolder(coolfolder);
324 std::string tablename,keycolcool,fkeycolcoral,pkeycolcoral;
325 return parseFolderDescription(folder->description(),tablename,
326 keycolcool,fkeycolcoral,pkeycolcoral);
327 }
328}

◆ extractCoralConStr()

bool CoraCoolDatabase::extractCoralConStr ( std::string_view coolstr)
private

Definition at line 82 of file CoraCoolDatabase.cxx.

82 {
83 // extract CORAL database string from COOL one
84 bool dbok=false;
85 // first check for initial colon - if so, technology-specific string
86 std::string::size_type c1=coolstr.find(':');
87 if (c1!=std::string::npos) {
88 std::string_view techno,server,schema;
89 techno=coolstr.substr(0,c1);
90 std::string::size_type c2;
91 c2=coolstr.find(';');
92 if (c2==std::string::npos) c2=coolstr.size();
93 server=coolstr.substr(c1+3,c2-c1-3);
94 c1=coolstr.find("schema=");
95 if (c1!=std::string::npos) {
96 c2=coolstr.find(';',c1+7);
97 if (c2==std::string::npos) c2=coolstr.size();
98 schema=coolstr.substr(c1+7,c2-c1-7);
99 }
100 c1=coolstr.find("dbname=");
101 if (c1!=std::string::npos) {
102 c2=coolstr.find(';',c1+7);
103 if (c2==std::string::npos) c2=coolstr.size();
104 m_dbname=std::string(coolstr.substr(c1+7,c2-c1-7));
105 }
106 // construct the connection string
107 if (techno=="oracle" || techno=="mysql" || techno=="frontier") {
108 if (!server.empty() && !schema.empty()) {
109 m_dbconn=std::string(techno);
110 m_dbconn+= "://";
112 m_dbconn+='/';
114 dbok=true;
115 }
116 } else if (techno=="sqlite") {
117 if (!schema.empty()) {
118 m_dbconn="sqlite_file:";
120 dbok=true;
121 }
122 }
123 } else {
124 c1=coolstr.find('/');
125 if (c1!=std::string::npos) {
126 m_dbconn=std::string(coolstr.substr(0,c1));
127 m_dbname=std::string(coolstr.substr(c1+1));
128 dbok=true;
129 }
130 }
131 if (m_dbname.empty()) dbok=false;
132 m_log << coral::Debug << "Extracted CORAL connection string: " << m_dbconn
133 << " and database name: " << m_dbname << " with status " << dbok <<
134 coral::MessageStream::endmsg;
135 return dbok;
136}

◆ getFolder()

CoraCoolFolderPtr CoraCoolDatabase::getFolder ( const std::string & coolfolder)

Definition at line 309 of file CoraCoolDatabase.cxx.

309 {
310 connect();
311 CoraCoolFolderPtr folder(new CoraCoolFolder(
312 coolfolder,m_proxy,m_cooldb,this,m_log));
313 return folder;
314}

◆ parseFolderDescription()

bool CoraCoolDatabase::parseFolderDescription ( const std::string & folderdesc,
std::string & tablename,
std::string & keycolcool,
std::string & fkeycolcoral,
std::string & pkeycolcoral )

Definition at line 330 of file CoraCoolDatabase.cxx.

334 {
335 // parse the folder description string to extract CORAL table and FKs
336 // format <coracool>Table:COOL_key:CORAL_fkey:CORAL_pkey</coracool>
337 // if CORAL_pkey is missing, assumed to be same as CORAL_fkey
338 // return false for parsing problem or missing <coracool> specification
339 // otherwise set return arguments
340
341 // find <coracool> part of the description
342 std::string::size_type p1,p2,c1,c2,c3;
343 p1=folderdesc.find("<coracool>");
344 p2=folderdesc.find("</coracool>");
345 if (p1==std::string::npos || p2==std::string::npos) return false;
346 // find the two : separating the values
347 c1=folderdesc.find(':',p1+10);
348 if (c1==std::string::npos) return false;
349 c2=folderdesc.find(':',c1+1);
350 if (c2==std::string::npos) return false;
351
352 tablename=m_dbname;
353 tablename+= '_';
354 tablename.append(folderdesc,p1+10,c1-p1-10);
355 keycolcool=folderdesc.substr(c1+1,c2-c1-1);
356 fkeycolcoral=folderdesc.substr(c2+1,p2-c2-1);
357 // check for third colon to specify separate primary key
358 c3=folderdesc.find(':',c2+1);
359 if (c3!=std::string::npos) {
360 fkeycolcoral=folderdesc.substr(c2+1,c3-c2-1);
361 pkeycolcoral=folderdesc.substr(c3+1,p2-c3-1);
362 } else {
363 fkeycolcoral=folderdesc.substr(c2+1,p2-c2-1);
364 pkeycolcoral=fkeycolcoral;
365 }
366 return true;
367}

◆ storeSpec()

bool CoraCoolDatabase::storeSpec ( const std::string & tablename,
const std::string & spec )
private

Definition at line 152 of file CoraCoolDatabase.cxx.

153 {
154 m_log << coral::Debug << "Store AttrList specification for table " <<
155 tablename << " : " << spec <<coral::MessageStream::endmsg;
156 // first check for existance of table
157 const std::string attrtable=m_dbname+"_CORACOOLATTR";
158 coral::ITable* table;
159 try {
160 table=&(m_proxy->nominalSchema().tableHandle(attrtable));
161 }
162 catch (coral::SchemaException& e) {
163 m_log << coral::Debug << "Creating table " << attrtable << coral::MessageStream::endmsg;
164 coral::TableDescription tdesc(attrtable);
165 tdesc.setName(attrtable);
166 tdesc.insertColumn("NAME","string",31,false);
167 tdesc.insertColumn("ATTRSPEC","string",4000,false);
168 tdesc.setPrimaryKey("NAME");
169 table=&(m_proxy->nominalSchema().createTable(tdesc));
170 // pause for thought
171 m_proxy->transaction().commit();
172 sleep(1);
173 m_proxy->transaction().start(false);
174 table=&(m_proxy->nominalSchema().tableHandle(attrtable));
175 }
176 if (table==0) {
177 m_log << coral::Error << "No pointer to " << attrtable << coral::MessageStream::endmsg;
178 return false;
179 }
180 // now update table with specification
181 try {
182 coral::AttributeList data;
183 data.extend<std::string>("NAME");
184 data.extend<std::string>("ATTRSPEC");
185 data[0].data<std::string>()=tablename;
186 data[1].data<std::string>()=spec;
187 coral::ITableDataEditor& editor=table->dataEditor();
188 editor.insertRow(data);
189 }
190 catch (coral::SchemaException&e) {
191 m_log << coral::Error << "Could not insert " << tablename << " into "
192 << attrtable << " exception: " << e.what() <<
193 coral::MessageStream::endmsg;
194 return false;
195 }
196 return true;
197}
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11

Member Data Documentation

◆ m_connected

bool CoraCoolDatabase::m_connected
private

Definition at line 90 of file CoraCoolDatabase.h.

◆ m_cooldb

cool::IDatabasePtr CoraCoolDatabase::m_cooldb
private

Definition at line 87 of file CoraCoolDatabase.h.

◆ m_coralsvc

coral::IConnectionService& CoraCoolDatabase::m_coralsvc
private

Definition at line 92 of file CoraCoolDatabase.h.

◆ m_dbconn

std::string CoraCoolDatabase::m_dbconn
private

Definition at line 88 of file CoraCoolDatabase.h.

◆ m_dbname

std::string CoraCoolDatabase::m_dbname
private

Definition at line 89 of file CoraCoolDatabase.h.

◆ m_log

coral::MessageStream CoraCoolDatabase::m_log
private

Definition at line 94 of file CoraCoolDatabase.h.

◆ m_proxy

coral::ISessionProxy* CoraCoolDatabase::m_proxy
private

Definition at line 93 of file CoraCoolDatabase.h.

◆ m_readonly

bool CoraCoolDatabase::m_readonly
private

Definition at line 91 of file CoraCoolDatabase.h.


The documentation for this class was generated from the following files: