CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
Database.cc
Go to the documentation of this file.
5 #include "DatabaseSession.h"
6 #include "DatabaseContainer.h"
7 #include "TransactionCache.h"
8 #include "ContainerSchema.h"
9 #include "IDatabaseSchema.h"
10 #include "ClassUtils.h"
11 
12 namespace ora {
13 
14  class DatabaseImpl {
15  public:
17  m_session(0),
18  m_transaction(0){
19  m_session.reset( new DatabaseSession );
20  m_transaction.reset( new Transaction( *m_session ));
21  }
22 
23  DatabaseImpl(boost::shared_ptr<ConnectionPool>& connectionPool):
24  m_session(0),
25  m_transaction(0){
26  m_session.reset( new DatabaseSession( connectionPool ) );
27  m_transaction.reset( new Transaction( *m_session )) ;
28  }
29 
31  }
32 
33  std::auto_ptr<DatabaseSession> m_session;
34  std::auto_ptr<Transaction> m_transaction;
35  };
36 
37  std::string nameFromClass( const Reflex::Type& contType ){
38  return contType.Name( Reflex::SCOPED );
39  }
40 
41  Container getContainerFromSession( const std::string& name, const Reflex::Type& contType, DatabaseSession& session ){
42  Handle<DatabaseContainer> contHandle = session.containerHandle( name );
43  if( !contHandle ){
46  contHandle = session.createContainer( name, contType );
47  } else {
48  throwException("Container \""+name+"\" does not exist in the database.",
49  "Database::insertItem");
50  }
51  }
52 
53  return Container( contHandle );
54  }
55 }
56 
57 std::string ora::Database::nameForContainer( const std::type_info& typeInfo ){
58  Reflex::Type contType = ClassUtils::lookupDictionary( typeInfo );
59  return nameFromClass( contType );
60 }
61 
62 std::string ora::Database::nameForContainer( const std::string& className ){
63  return className;
64 }
65 
67  m_impl( new DatabaseImpl ){
68 }
69 
71  m_impl( rhs.m_impl ){
72 }
73 
74 ora::Database::Database(boost::shared_ptr<ConnectionPool>& connectionPool):
75  m_impl( new DatabaseImpl( connectionPool) ){
76 }
77 
79  disconnect();
80 }
81 
83  if( this != &rhs ) m_impl = rhs.m_impl;
84  return *this;
85 }
86 
88  return m_impl->m_session->configuration();
89 }
90 
91 bool ora::Database::connect( const std::string& connectionString,
92  bool readOnly ){
93  return m_impl->m_session->connect( connectionString, readOnly );
94 }
95 
96 bool ora::Database::connect( const std::string& connectionString,
97  const std::string& asRole,
98  bool readOnly ){
99  return m_impl->m_session->connect( connectionString, asRole, readOnly );
100 }
101 
103  m_impl->m_session->disconnect();
104 }
105 
107  return m_impl->m_session->isConnected();
108 }
109 
110 const std::string& ora::Database::connectionString() {
111  return m_impl->m_session->connectionString();
112 }
113 
115  if(!m_impl->m_session->isConnected()) {
116  throwException("No database storage connected.","Database::transaction");
117  }
118  return *m_impl->m_transaction;
119 }
120 
122  if(!m_impl->m_session->isConnected()) {
123  throwException("No database storage connected.","Database::checkTransaction");
124  }
125  if(!m_impl->m_transaction->isActive()) {
126  throwException("Transaction is not active.","Database::checkTransaction");
127  }
128 }
129 
131  checkTransaction();
132  return m_impl->m_session->exists();
133 }
134 
135 bool ora::Database::create( std::string userSchemaVersion ){
136  bool created = false;
137  if( !exists()){
138  m_impl->m_session->create( userSchemaVersion );
139  created = true;
140  }
141  return created;
142 }
143 
145  bool dropped = false;
146  if( exists()){
147  open();
148  const std::map<int, Handle<DatabaseContainer> >& conts = m_impl->m_session->containers();
149  for(std::map<int, Handle<DatabaseContainer> >::const_iterator iC = conts.begin();
150  iC != conts.end(); iC++ ){
151  iC->second->drop();
152  }
153  m_impl->m_session->drop();
154  dropped = true;
155  }
156  return dropped;
157 }
158 
159 void ora::Database::setAccessPermission( const std::string& principal, bool forWrite ){
160  if( exists()){
161  open();
162  m_impl->m_session->setAccessPermission( principal, forWrite );
163  const std::map<int, Handle<DatabaseContainer> >& conts = m_impl->m_session->containers();
164  for(std::map<int, Handle<DatabaseContainer> >::const_iterator iC = conts.begin();
165  iC != conts.end(); iC++ ){
166  iC->second->setAccessPermission( principal, forWrite );
167  }
168  }
169 }
170 
171 void ora::Database::open( bool writingAccess /*=false*/){
172  checkTransaction();
173  if( !m_impl->m_session->exists() ){
174  if( writingAccess && m_impl->m_session->configuration().properties().getFlag( Configuration::automaticDatabaseCreation() ) ){
175  m_impl->m_session->create();
176  } else {
177  throwException("Database does not exists in \""+m_impl->m_session->connectionString()+"\"","Database::open");
178  }
179  }
180  m_impl->m_session->open();
181 }
182 
184  checkTransaction();
185  if( !m_impl->m_session->exists() ){
186  throwException("Database does not exists in \""+m_impl->m_session->connectionString()+"\"","Database::schemaVersion");
187  }
188  return Version::fromString( m_impl->m_session->schemaVersion( userSchema ) );
189 }
190 
191 std::set< std::string > ora::Database::containers() {
192  open();
193  std::set< std::string > contList;
194  const std::map<int, Handle<DatabaseContainer> >& conts = m_impl->m_session->containers();
195  for(std::map<int, Handle<DatabaseContainer> >::const_iterator iC = conts.begin();
196  iC != conts.end(); iC++ ){
197  contList.insert( iC->second->name() );
198  }
199  return contList;
200 }
201 
203  const std::type_info& typeInfo ){
204  open( true );
205  if( m_impl->m_session->containerHandle( name ) ){
206  throwException("Container with name \""+name+"\" already exists in the database.",
207  "Database::createContainer");
208  }
209  Reflex::Type contType = ClassUtils::lookupDictionary( typeInfo );
210  Handle<DatabaseContainer> cont = m_impl->m_session->createContainer( name, contType );
211  return Container( cont );
212 }
213 
214 ora::Container ora::Database::createContainer( const std::type_info& typeInfo ){
215  open( true );
216  Reflex::Type contType = ClassUtils::lookupDictionary( typeInfo );
217  std::string name = nameFromClass( contType );
218  if( m_impl->m_session->containerHandle( name ) ){
219  throwException("Container with name \""+name+"\" already exists in the database.",
220  "Database::createContainer");
221  }
222  Handle<DatabaseContainer> cont = m_impl->m_session->createContainer( name, contType );
223  return Container( cont );
224 }
225 
227  std::string name ){
228  open( true );
229  Reflex::Type contType = ClassUtils::lookupDictionary( className );
230  if( name.empty() ) name = nameForContainer( className );
231  if( m_impl->m_session->containerHandle( name ) ){
232  throwException("Container with name \""+name+"\" already exists in the database.",
233  "Database::createContainer");
234  }
235  Handle<DatabaseContainer> cont = m_impl->m_session->createContainer( name, contType );
236  return Container( cont );
237 }
238 
239 ora::Container ora::Database::getContainer( const std::string& containerName,
240  const std::type_info& typeInfo){
241  open( true );
242  Reflex::Type objType = ClassUtils::lookupDictionary( typeInfo );
243  return getContainerFromSession( containerName, objType, *m_impl->m_session );
244 }
245 
246 ora::Container ora::Database::getContainer( const std::type_info& typeInfo ){
247  open( true );
248  Reflex::Type objType = ClassUtils::lookupDictionary( typeInfo );
249  std::string contName = nameFromClass( objType );
250  return getContainerFromSession( contName, objType, *m_impl->m_session);
251 }
252 
253 bool ora::Database::dropContainer( const std::string& name ){
254  open();
255  if( !m_impl->m_session->containerHandle( name ) ){
256  return false;
257  }
258  m_impl->m_session->dropContainer( name );
259  return true;
260 }
261 
262 bool ora::Database::lockContainer( const std::string& name ){
263  open();
264  Handle<DatabaseContainer> cont = m_impl->m_session->containerHandle( name );
265  if( !cont ){
266  throwException("Container \""+name+"\" does not exist in the database.",
267  "Database::lockContainer");
268  }
269  return cont->lock();
270 }
271 
273  open();
274  Handle<DatabaseContainer> cont = m_impl->m_session->containerHandle( name );
275  if( !cont ){
276  throwException("Container \""+name+"\" does not exist in the database.",
277  "Database::containerHandle");
278  }
279  return Container( cont );
280 }
281 
283  open();
284  Handle<DatabaseContainer> cont = m_impl->m_session->containerHandle( contId );
285  if( !cont ){
286  std::stringstream messg;
287  messg << "Container with id=" << contId << " not found in the database.";
288  throwException(messg.str(),
289  "Database::containerHandle");
290  }
291  return Container( cont );
292 }
293 
295  Container cont = containerHandle( oid.containerId() );
296  return cont.fetchItem( oid.itemId() );
297 }
298 
299 ora::OId ora::Database::insertItem(const std::string& containerName,
300  const Object& dataObject ){
301  open( true );
302  Container cont = getContainerFromSession( containerName, dataObject.type(), *m_impl->m_session );
303  int itemId = cont.insertItem( dataObject );
304  return OId( cont.id(), itemId );
305 }
306 
308  const Object& dataObject ){
309  open();
310  Container cont = containerHandle( oid.containerId() );
311  cont.updateItem( oid.itemId(), dataObject );
312 }
313 
314 void ora::Database::erase(const OId& oid){
315  open();
316  Container cont = containerHandle( oid.containerId() );
317  cont.erase( oid.itemId() );
318 }
319 
321  open();
322  const std::map<int,Handle<DatabaseContainer> >& containers = m_impl->m_session->containers();
323  for( std::map<int,Handle<DatabaseContainer> >::const_iterator iCont = containers.begin();
324  iCont != containers.end(); ++iCont ){
325  iCont->second->flush();
326  }
327 }
328 
329 void ora::Database::setObjectName( const std::string& name, const OId& oid ){
330  open( true );
331  m_impl->m_session->setObjectName( name, oid.containerId(), oid.itemId() );
332 }
333 
334 bool ora::Database::eraseObjectName( const std::string& name ){
335  open();
336  return m_impl->m_session->eraseObjectName( name );
337 }
338 
340  open();
341  return m_impl->m_session->eraseAllNames();
342 }
343 
344 bool ora::Database::getItemId( const std::string& name, ora::OId& destination ){
345  open();
346  return m_impl->m_session->getItemId( name, destination );
347 }
348 
349 boost::shared_ptr<void> ora::Database::getTypedObjectByName( const std::string& name, const std::type_info& typeInfo ){
350  open();
351  Reflex::Type objType = ClassUtils::lookupDictionary( typeInfo );
352  return m_impl->m_session->fetchTypedObjectByName( name, objType );
353 }
354 
356  open();
357  return m_impl->m_session->fetchObjectByName( name );
358 }
359 
361  std::vector<std::string>& destination ){
362  checkTransaction();
363  if( !m_impl->m_session->exists() ){
364  throwException("Database does not exists in \""+m_impl->m_session->connectionString()+"\"","Database::getNamesForObject");
365  }
366  return m_impl->m_session->getNamesForObject( oid.containerId(), oid.itemId(), destination );
367 }
368 
369 bool ora::Database::listObjectNames( std::vector<std::string>& destination ){
370  checkTransaction();
371  if( !m_impl->m_session->exists() ){
372  throwException("Database does not exists in \""+m_impl->m_session->connectionString()+"\"","Database::listObjectNames");
373  }
374  return m_impl->m_session->listObjectNames( destination );
375 }
376 
378  checkTransaction();
379  Handle<DatabaseUtilitySession> utilSession = m_impl->m_session->utility();
380  return DatabaseUtility( utilSession );
381 }
382 
384  return m_impl->m_session->storageAccessSession();
385 }
386 
Handle< DatabaseContainer > containerHandle(const std::string &name)
bool create(std::string userSchemaVersion=std::string(""))
Definition: Database.cc:135
std::auto_ptr< DatabaseSession > m_session
Definition: Database.cc:33
void flush()
Definition: Database.cc:320
bool getFlag(const std::string &flagName) const
Definition: Properties.cc:36
void updateItem(int itemId, const Object &data)
Definition: Container.cc:137
Object fetchItemByName(const std::string &name)
Definition: Database.cc:355
EcalChannelStatus Container
std::string nameFromClass(const Reflex::Type &contType)
Definition: Database.cc:37
static Version fromString(const std::string &versionString)
Definition: Version.cc:24
Properties & properties()
const std::string & connectionString()
Definition: Database.cc:110
int insertItem(const Object &data)
Definition: Container.cc:122
void checkTransaction()
Definition: Database.cc:121
bool getItemId(const std::string &name, OId &destination)
Definition: Database.cc:344
Definition: OId.h:8
virtual ~Database()
Definition: Database.cc:78
std::auto_ptr< Transaction > m_transaction
Definition: Database.cc:34
ora::Version schemaVersion(bool userSchema=false)
Definition: Database.cc:183
static std::string automaticContainerCreation()
void open(bool writingAccess=false)
Definition: Database.cc:171
Object fetchItem(int itemId)
Definition: Container.cc:102
static std::string automaticDatabaseCreation()
bool lockContainer(const std::string &name)
Definition: Database.cc:262
Transaction & transaction()
Definition: Database.cc:114
SharedSession & storageAccessSession()
Definition: Database.cc:383
void disconnect()
Definition: Database.cc:102
void erase(const OId &oid)
Definition: Database.cc:314
Object fetchItem(const OId &oid)
Definition: Database.cc:294
Container containerHandle(const std::string &name)
Definition: Database.cc:272
bool exists()
Definition: Database.cc:130
std::set< std::string > containers()
Definition: Database.cc:191
int containerId() const
Definition: OId.cc:50
bool dropContainer(const std::string &name)
Definition: Database.cc:253
DatabaseImpl(boost::shared_ptr< ConnectionPool > &connectionPool)
Definition: Database.cc:23
Container createContainer()
boost::shared_ptr< DatabaseImpl > m_impl
Definition: Database.h:193
DatabaseUtility utility()
Definition: Database.cc:377
bool getNamesForObject(const OId &oid, std::vector< std::string > &destination)
Definition: Database.cc:360
OId insertItem(const std::string &containerName, const Object &data)
Definition: Database.cc:299
Database & operator=(const Database &rhs)
Definition: Database.cc:82
Handle< DatabaseContainer > createContainer(const std::string &containerName, const Reflex::Type &type)
bool connect(const std::string &connectionString, bool readOnly=false)
Definition: Database.cc:91
void erase(int itemId)
Definition: Container.cc:154
bool eraseObjectName(const std::string &name)
Definition: Database.cc:334
int cont
bool drop()
Definition: Database.cc:144
Configuration & configuration()
static std::string nameForContainer(const std::type_info &typeInfo)
Definition: Database.cc:57
bool isConnected()
Definition: Database.cc:106
const Reflex::Type & type() const
Definition: Object.cc:45
bool eraseAllNames()
Definition: Database.cc:339
bool listObjectNames(std::vector< std::string > &destination)
Definition: Database.cc:369
void throwException(const std::string &message, const std::string &methodName)
Definition: Exception.cc:10
Container getContainerFromSession(const std::string &name, const Reflex::Type &contType, DatabaseSession &session)
Definition: Database.cc:41
boost::shared_ptr< void > getTypedObjectByName(const std::string &name, const std::type_info &typeInfo)
Definition: Database.cc:349
Configuration & configuration()
Definition: Database.cc:87
Reflex::Type lookupDictionary(const std::type_info &typeInfo, bool throwFlag=true)
Definition: ClassUtils.cc:93
void updateItem(const OId &oid, const Object &data)
Definition: Database.cc:307
void setObjectName(const std::string &name, const OId &oid)
Definition: Database.cc:329
std::string className(const T &t)
Definition: ClassName.h:30
Container getContainer(const std::string &name, const std::type_info &typeInfo)
Definition: Database.cc:239
void setAccessPermission(const std::string &principal, bool forWrite)
Definition: Database.cc:159
int itemId() const
Definition: OId.cc:54