CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
DatabaseContainer.cc
Go to the documentation of this file.
2 #include "DatabaseContainer.h"
3 #include "DatabaseSession.h"
4 #include "ContainerSchema.h"
5 #include "IRelationalStreamer.h"
6 #include "RelationalBuffer.h"
7 #include "RelationalOperation.h"
8 #include "DataElement.h"
9 #include "RelationalDeleter.h"
11 #include "IDatabaseSchema.h"
12 #include "ClassUtils.h"
13 #include "MappingRules.h"
14 // externals
15 #include "CoralBase/Attribute.h"
16 
17 namespace ora {
18 
19  class WriteBuffer {
20  public:
21  explicit WriteBuffer( ContainerSchema& contSchema ):
22  m_buffer(),
23  m_operationBuffer( contSchema.storageSchema() ),
25  m_writer(),
26  m_topLevelInsert( 0 ){
27 
28  MappingElement& topLevelMapping = contSchema.mapping( true ).topElement();
29  m_topLevelInsert = &m_operationBuffer.newInsert( topLevelMapping.tableName() );
30  m_topLevelInsert->addId( topLevelMapping.columnNames()[ 0 ] );
31  const Reflex::Type& type = contSchema.type();
32  MappingElement::iterator iMap = topLevelMapping.find( type.Name(Reflex::SCOPED) );
33  // the first inner mapping is the relevant...
34  if( iMap == topLevelMapping.end()){
35  throwException("Could not find a mapping element for class \""+
36  type.Name(Reflex::SCOPED)+"\"",
37  "WriteBuffer::WriteBuffer");
38  }
39  MappingElement& mapping = iMap->second;
40  RelationalStreamerFactory streamerFactory( contSchema );
41  m_writer.reset( streamerFactory.newWriter( type, mapping ) );
43  }
44 
45 
47  }
48 
49  void registerForWrite( int oid, const void* data ){
50  m_buffer.push_back( std::make_pair(oid, data ) );
51  }
52 
53  size_t flush(){
54  size_t nobj = 0;
55  for( std::vector<std::pair<int, const void*> >::const_iterator iW = m_buffer.begin();
56  iW != m_buffer.end(); ++iW ){
57  write( iW->first, iW->second );
58  if( m_operationBuffer.flush() ) nobj++;
59  }
60  m_buffer.clear();
61  return nobj;
62  }
63 
64  private:
65  void write( int oid, const void* data ){
66  coral::AttributeList& dataBuff = m_topLevelInsert->data();
67  dataBuff.begin()->data<int>() = oid;
68  m_writer->write( oid, data );
69  }
70 
71  private:
72  std::vector<std::pair<int, const void*> > m_buffer;
75  std::auto_ptr<IRelationalWriter> m_writer;
77  };
78 
79  class UpdateBuffer {
80  public:
81  explicit UpdateBuffer( ContainerSchema& contSchema ):
82  m_buffer(),
83  m_operationBuffer( contSchema.storageSchema() ),
85  m_depDeleter(),
86  m_updater(),
87  m_topLevelUpdate( 0 ){
88 
89  std::vector<MappingElement> dependentMappings;
90  contSchema.mappingForDependentClasses( dependentMappings );
91  m_depDeleter.reset( new RelationalDeleter( dependentMappings ) );
93  dependentMappings.clear();
94 
95  MappingElement& topLevelMapping = contSchema.mapping( true ).topElement();
97  m_topLevelUpdate->addId( topLevelMapping.columnNames()[ 0 ] );
98  m_topLevelUpdate->addWhereId( topLevelMapping.columnNames()[ 0 ] );
99  const Reflex::Type& type = contSchema.type();
100  MappingElement::iterator iMap = topLevelMapping.find( type.Name(Reflex::SCOPED) );
101  // the first inner mapping is the relevant...
102  if( iMap == topLevelMapping.end()){
103  throwException("Could not find a mapping element for class \""+
104  type.Name(Reflex::SCOPED)+"\"",
105  "UpdateBuffer::UpdateBuffer");
106  }
107  MappingElement& mapping = iMap->second;
108  RelationalStreamerFactory streamerFactory( contSchema );
109  m_updater.reset( streamerFactory.newUpdater( type, mapping ));
111  }
112 
114  }
115 
116 
117  void registerForUpdate( int oid, const void* data ){
118  m_buffer.push_back( std::make_pair( oid, data ));
119  }
120 
121 
122  size_t flush(){
123  size_t nobj = 0;
124  for( std::vector<std::pair<int, const void*> >::const_iterator iU = m_buffer.begin();
125  iU != m_buffer.end(); ++iU ){
126  update( iU->first, iU->second );
127  if( m_operationBuffer.flush()) nobj++;
128  }
129  m_buffer.clear();
130  return nobj;
131  }
132 
133 
134  private:
135  void update( int oid, const void* data ){
136  // erase the dependencies (cannot be updated...)
137  m_depDeleter->erase( oid );
138  coral::AttributeList& dataBuff = m_topLevelUpdate->data();
139  dataBuff.begin()->data<int>() = oid;
140  coral::AttributeList& whereDataBuff = m_topLevelUpdate->whereData();
141  whereDataBuff.begin()->data<int>() = oid;
142  m_updater->update( oid, data );
143  }
144 
145 
146  private:
147  std::vector<std::pair<int, const void*> > m_buffer;
150  std::auto_ptr<RelationalDeleter> m_depDeleter;
151  std::auto_ptr<IRelationalUpdater> m_updater;
153  };
154 
155  class ReadBuffer {
156  public:
157  explicit ReadBuffer( ContainerSchema& contSchema ):
159  m_type( contSchema.type() ),
160  m_reader(),
161  m_topLevelQuery( contSchema.mapping().topElement().tableName(), contSchema.storageSchema() ){
162 
163  MappingElement& topLevelMapping = contSchema.mapping().topElement();
164  m_topLevelQuery.addWhereId( topLevelMapping.columnNames()[ 0 ] );
165  MappingElement::iterator iMap = topLevelMapping.find( m_type.Name(Reflex::SCOPED) );
166  // the first inner mapping is the good one ...
167  if( iMap == topLevelMapping.end()){
168  throwException("Could not find a mapping element for class \""+
169  m_type.Name(Reflex::SCOPED)+"\"",
170  "ReadBuffer::ReadBuffer");
171  }
172  MappingElement& mapping = iMap->second;
173  RelationalStreamerFactory streamerFactory( contSchema );
174  m_reader.reset( streamerFactory.newReader( m_type, mapping )) ;
176  }
177 
179  }
180 
181  void* read( int oid ){
182  coral::AttributeList& dataBuff = m_topLevelQuery.whereData();
183  dataBuff.begin()->data<int>() = oid;
185  m_reader->select( oid );
186  void* destination = 0;
188  destination = ClassUtils::constructObject( m_type );
189  m_reader->read( destination );
190  }
191  m_reader->clear();
193  return destination;
194  }
195 
196  const Reflex::Type& type(){
197  return m_type;
198  }
199 
200  private:
203  std::auto_ptr<IRelationalReader> m_reader;
205  };
206 
207  class DeleteBuffer {
208  public:
209  explicit DeleteBuffer( ContainerSchema& contSchema ):
210  m_buffer(),
211  m_operationBuffer( contSchema.storageSchema() ),
212  m_mainDeleter(),
213  m_depDeleter(){
214  m_mainDeleter.reset( new RelationalDeleter( contSchema.mapping().topElement() ));
216 
217  std::vector<MappingElement> dependentMappings;
218  contSchema.mappingForDependentClasses( dependentMappings );
219  m_depDeleter.reset( new RelationalDeleter( dependentMappings ) );
221  dependentMappings.clear();
222  }
223 
225  }
226 
227 
228  void registerForDelete( int oid ){
229  m_buffer.push_back( oid );
230  }
231 
232  size_t flush(){
233  size_t nobj = 0;
234  for( std::vector<int>::const_iterator iD = m_buffer.begin();
235  iD != m_buffer.end(); ++iD ){
236  m_depDeleter->erase( *iD );
237  m_mainDeleter->erase( *iD );
238  if( m_operationBuffer.flush() ) nobj++;
239  }
240  m_buffer.clear();
241  return nobj;
242  }
243 
244  private:
245  std::vector<int> m_buffer;
247  std::auto_ptr<RelationalDeleter> m_mainDeleter;
248  std::auto_ptr<RelationalDeleter> m_depDeleter;
249  };
250 
251 }
252 
254  ReadBuffer& buffer ):
255  m_query( schema.mapping().topElement().tableName(), schema.storageSchema() ),
256  m_itemId( -1 ),
257  m_readBuffer( buffer ){
258  const std::string& idCol = schema.mapping().topElement().columnNames()[0];
259  m_query.addId( idCol );
260  m_query.addOrderId( idCol );
261 }
262 
264 }
265 
267  m_query.execute();
268 }
269 
271  bool prevValid = (m_itemId != -1);
272  bool currValid = false;
273  m_itemId = -1;
274  if( m_query.nextCursorRow() ){
275  coral::AttributeList& row = m_query.data();
276  m_itemId = row.begin()->data<int>();
277  currValid = true;
278  }
279 
280  if( !currValid && prevValid ) m_query.clear();
281  return currValid;
282 }
283 
285  void* ret = 0;
286  if( m_itemId != -1 ){
287  ret = m_readBuffer.read( m_itemId );
288  }
289  return ret;
290 }
291 
293  if( !ClassUtils::isType( type(), asType ) ){
294  throwException("Provided output object type \""+asType.Name(Reflex::SCOPED)+"\" does not match with the container type \""+
295  type().Name(Reflex::SCOPED)+"\"","IteratorBuffer::getItemAsType");
296  }
297  return getItem();
298 }
299 
301  return m_itemId;
302 }
303 
305  return m_readBuffer.type();
306 }
307 
309  const std::string& containerName,
310  const std::string& className,
311  unsigned int containerSize,
313  m_schema( new ContainerSchema(contId, containerName, className, session) ),
314  m_writeBuffer(),
315  m_updateBuffer(),
316  m_readBuffer(),
317  m_deleteBuffer(),
318  m_iteratorBuffer(),
319  m_size( containerSize ),
320  m_containerUpdateTable( session.containerUpdateTable() ){
321 }
322 
324  const std::string& containerName,
325  const Reflex::Type& containerType,
327  m_schema( new ContainerSchema(contId, containerName, containerType, session) ),
328  m_writeBuffer(),
329  m_updateBuffer(),
330  m_readBuffer(),
331  m_deleteBuffer(),
332  m_iteratorBuffer(),
333  m_size(0),
334  m_containerUpdateTable( session.containerUpdateTable() ){
335 }
336 
338  m_iteratorBuffer.clear();
339 }
340 
342  return m_schema->containerId();
343 }
344 
345 const std::string& ora::DatabaseContainer::name(){
346  return m_schema->containerName();
347 }
348 
350  return m_schema->className();
351 }
352 
354  return m_schema->type();
355 }
356 
358  return m_schema->mappingVersion();
359 }
360 
362  return m_size;
363 }
364 
366  if(!m_readBuffer.get()){
367  m_readBuffer.reset( new ReadBuffer( *m_schema ) );
368  }
369  if( !m_iteratorBuffer ){
370  m_iteratorBuffer.reset( new IteratorBuffer(*m_schema, *m_readBuffer ) );
371  m_iteratorBuffer->reset();
372  }
373  return m_iteratorBuffer;
374 }
375 
377  m_schema->create();
378 }
379 
381  m_schema->drop();
382 }
383 
385  m_schema->extendIfRequired( dependentType );
386 }
387 
389 
390  if(!m_readBuffer.get()){
391  m_readBuffer.reset( new ReadBuffer( *m_schema ) );
392  }
393  return m_readBuffer->read( itemId );
394 }
395 
397  const Reflex::Type& asType){
398  if(!m_readBuffer.get()){
399  m_readBuffer.reset( new ReadBuffer( *m_schema ) );
400  }
401  if( !ClassUtils::isType( type(), asType ) ){
402  throwException("Provided output object type \""+asType.Name(Reflex::SCOPED)+"\" does not match with the container type \""+
403  type().Name(Reflex::SCOPED)+"\"","DatabaseContainer::fetchItemAsType");
404  }
405  return m_readBuffer->read( itemId );
406 }
407 
409  const Reflex::Type& dataType ){
410  if(!m_writeBuffer.get()){
411  m_writeBuffer.reset( new WriteBuffer( *m_schema ) );
412  }
413  Reflex::Type inputResType = ClassUtils::resolvedType( dataType );
414  Reflex::Type contType = ClassUtils::resolvedType(m_schema->type());
415  if( inputResType.Name()!= contType.Name() && !inputResType.HasBase( contType ) ){
416  throwException( "Provided input object type=\""+inputResType.Name()+
417  "\" does not match with the container type=\""+contType.Name()+"\"",
418  "DatabaseContainer::insertItem" );
419  }
420 
421  int newId = m_schema->containerSequences().getNextId( MappingRules::sequenceNameForContainer( m_schema->containerName()) );
422  m_writeBuffer->registerForWrite( newId, data );
423  return newId;
424 }
425 
427  const void* data,
428  const Reflex::Type& dataType ){
429  if(!m_updateBuffer.get()){
430  m_updateBuffer.reset( new UpdateBuffer( *m_schema ) );
431  }
432  Reflex::Type inputResType = ClassUtils::resolvedType( dataType );
433  Reflex::Type contType = ClassUtils::resolvedType(m_schema->type());
434  if( inputResType.Name()!= contType.Name() && !inputResType.HasBase( contType ) ){
435  throwException( "Provided input object type=\""+inputResType.Name()+"\" does not match with the container type=\""+
436  contType.Name()+"\".",
437  "DatabaseContainer::updateItem" );
438  }
439 
440  m_updateBuffer->registerForUpdate( itemId, data );
441 }
442 
443 void ora::DatabaseContainer::erase( int itemId ){
444  if(!m_deleteBuffer.get()){
445  m_deleteBuffer.reset( new DeleteBuffer( *m_schema ) );
446  }
447  m_deleteBuffer->registerForDelete( itemId );
448 }
449 
451  size_t prevSize = m_size;
452  if(m_writeBuffer.get()) m_size += m_writeBuffer->flush();
453  if(m_updateBuffer.get()) m_updateBuffer->flush();
454  if(m_deleteBuffer.get()) m_size -= m_deleteBuffer->flush();
455  m_schema->containerSequences().sinchronizeAll();
456  if( prevSize != m_size ){
457  m_containerUpdateTable.takeNote( id(), m_size );
458  }
459 }
460 
461 void ora::DatabaseContainer::setItemName( const std::string& name,
462  int itemId ){
463  m_schema->dbSession().setObjectName( name, m_schema->containerId(), itemId );
464 }
465 
466 bool ora::DatabaseContainer::getNames( std::vector<std::string>& destination ){
467  return m_schema->dbSession().getNamesForContainer( m_schema->containerId(), destination );
468 }
469 
470 
type
Definition: HCALResponse.h:22
void registerForUpdate(int oid, const void *data)
const std::string & name()
DatabaseContainer(int contId, const std::string &containerName, const std::string &className, unsigned int containerSize, DatabaseSession &session)
WriteBuffer(ContainerSchema &contSchema)
std::auto_ptr< RelationalDeleter > m_depDeleter
const Reflex::Type & type()
std::auto_ptr< IRelationalWriter > m_writer
IRelationalReader * newReader(const Reflex::Type &dataType, MappingElement &dataMapping)
RelationalBuffer m_operationBuffer
void * constructObject(const Reflex::Type &typ)
Definition: ClassUtils.cc:118
coral::AttributeList & whereData()
void addId(const std::string &columnName)
void write(int oid, const void *data)
void updateItem(int itemId, const void *data, const Reflex::Type &type)
DataElement m_topLevelElement
void * read(int oid)
UpdateBuffer(ContainerSchema &contSchema)
int insertItem(const void *data, const Reflex::Type &type)
RelationalBuffer m_operationBuffer
bool getNames(std::vector< std::string > &destination)
void * getItemAsType(const Reflex::Type &type)
DataElement m_topLevelElement
const Reflex::Type & type()
ReadBuffer(ContainerSchema &contSchema)
InsertOperation & newInsert(const std::string &tableName)
std::auto_ptr< IRelationalUpdater > m_updater
const Reflex::Type & type()
bool mappingForDependentClasses(std::vector< MappingElement > &destination)
const std::string & className()
const MappingElement & topElement() const
Definition: MappingTree.h:139
void addId(const std::string &columnName)
SelectOperation m_query
void extendSchema(const Reflex::Type &dependentType)
std::vector< std::pair< int, const void * > > m_buffer
IteratorBuffer(ContainerSchema &schema, ReadBuffer &buffer)
iterator find(const std::string &key)
Retrieves a sub-element.
std::map< std::string, MappingElement >::iterator iterator
Iterator definition.
const std::vector< std::string > & columnNames() const
const std::string & mappingVersion()
Reflex::Type resolvedType(const Reflex::Type &typ)
Definition: ClassUtils.cc:380
void addOrderId(const std::string &columnName)
std::vector< std::pair< int, const void * > > m_buffer
UpdateOperation * m_topLevelUpdate
std::vector< int > m_buffer
coral::AttributeList & data()
IRelationalWriter * newWriter(const Reflex::Type &dataType, MappingElement &dataMapping)
void * fetchItem(int itemId)
coral::AttributeList & whereData()
IRelationalUpdater * newUpdater(const Reflex::Type &dataType, MappingElement &dataMapping)
InsertOperation * m_topLevelInsert
void addWhereId(const std::string &columnName)
void registerForWrite(int oid, const void *data)
void addWhereId(const std::string &columnName)
iterator end()
Returns an iterator in the end of the sequence.
std::auto_ptr< RelationalDeleter > m_depDeleter
void registerForDelete(int oid)
UpdateOperation & newUpdate(const std::string &tableName, bool addToResult=false)
void setItemName(const std::string &name, int itemId)
MappingTree & mapping(bool writeEnabled=false)
Handle< IteratorBuffer > iteratorBuffer()
const Reflex::Type & m_type
void * fetchItemAsType(int itemId, const Reflex::Type &asType)
const Reflex::Type & type()
static std::string sequenceNameForContainer(const std::string &containerName)
Definition: MappingRules.cc:14
DeleteBuffer(ContainerSchema &contSchema)
const std::string & tableName() const
void throwException(const std::string &message, const std::string &methodName)
Definition: Exception.cc:10
std::auto_ptr< IRelationalReader > m_reader
RelationalBuffer m_operationBuffer
void update(int oid, const void *data)
std::auto_ptr< RelationalDeleter > m_mainDeleter
std::string className(const T &t)
Definition: ClassName.h:30
SelectOperation m_topLevelQuery
bool isType(const Reflex::Type &type, const Reflex::Type &baseType)
Definition: ClassUtils.cc:49
DataElement m_topLevelElement