CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
STLContainerStreamer.cc
Go to the documentation of this file.
2 #include "STLContainerStreamer.h"
3 #include "ClassUtils.h"
4 #include "MappingElement.h"
5 #include "DataElement.h"
6 #include "ContainerSchema.h"
7 #include "RelationalBuffer.h"
11 #include "ArrayHandlerFactory.h"
12 #include "IArrayHandler.h"
13 #include "ArrayCommonImpl.h"
14 // externals
15 #include "CoralBase/Attribute.h"
16 #include "RelationalAccess/IBulkOperation.h"
18 
20  MappingElement& mapping,
21  ContainerSchema& contSchema ):
22  m_objectType( objectType ),
23  m_mappingElement( mapping ),
24  m_schema( contSchema ),
25  m_recordId(),
26  m_localElement(),
27  m_associative( ClassUtils::isTypeAssociativeContainer( objectType ) ),
28  m_offset( 0 ),
29  m_insertOperation( 0 ),
30  m_arrayHandler(),
31  m_keyWriter(),
32  m_dataWriter(){
33 }
34 
36 }
37 
40  RelationalBuffer& operationBuffer ){
41  if( !m_objectType ){
42  throwException( "Missing dictionary information for the type of the container \"" +
43  m_objectType.cppName() + "\"",
44  "STLContainerWriter::build" );
45  }
46  m_localElement.clear();
47  m_recordId.clear();
48  // allocate for the index...
49  m_recordId.push_back(0);
50 
51  RelationalStreamerFactory streamerFactory( m_schema );
52 
53  // first open the insert on the extra table...
54  m_insertOperation = &operationBuffer.newMultiRecordInsert( m_mappingElement.tableName() );
55  const std::vector<std::string>& columns = m_mappingElement.columnNames();
56  if( !columns.size() ){
57  throwException( "Id columns not found in the mapping.",
58  "STLContainerWriter::build");
59  }
60  for( size_t i=0; i<columns.size(); i++ ){
61  m_insertOperation->addId( columns[ i ] );
62  }
63 
64  m_offset = &offset;
65 
66  m_arrayHandler.reset( ArrayHandlerFactory::newArrayHandler( m_objectType ) );
67 
68  edm::TypeWithDict valueType;
69  if ( m_associative ){
70 
71  edm::TypeWithDict keyType = ClassUtils::containerKeyType(m_objectType);
72  edm::TypeWithDict keyResolvedType = ClassUtils::resolvedType(keyType);
73  if ( ! keyType || !keyResolvedType ) {
74  throwException( "Missing dictionary information for the key type of the container \"" +
75  m_objectType.cppName() + "\"",
76  "STLContainerWriter::build" );
77  }
78  std::string keyName("key_type");
79  // Retrieve the relevant mapping element
80  MappingElement::iterator iMe = m_mappingElement.find( keyName );
81  if ( iMe == m_mappingElement.end() ) {
82  throwException( "Item for \"" + keyName + "\" not found in the mapping element",
83  "STLContainerWriter::build" );
84  }
85 
86  m_keyWriter.reset( streamerFactory.newWriter( keyResolvedType, iMe->second ) );
87  m_keyWriter->build( m_localElement, *m_insertOperation, operationBuffer );
88  valueType = ClassUtils::containerDataType(m_objectType);
89  } else {
90  valueType = ClassUtils::containerValueType(m_objectType);
91  }
92 
93  edm::TypeWithDict valueResolvedType = ClassUtils::resolvedType(valueType);
94  // Check the component type
95  if ( ! valueType || !valueResolvedType ) {
96  throwException( "Missing dictionary information for the content type of the container \"" +
97  m_objectType.cppName() + "\"",
98  "STLContainerWriter::build" );
99  }
100 
101  std::string valueName(m_associative ? "mapped_type" : "value_type");
102  // Retrieve the relevant mapping element
103  MappingElement::iterator iMe = m_mappingElement.find( valueName );
104  if ( iMe == m_mappingElement.end() ) {
105  // Try again with the name of a possible typedef
106  std::string valueName2 = valueType.unscopedName();
107  iMe = m_mappingElement.find( valueName2 );
108  if ( iMe == m_mappingElement.end() ) {
109  throwException( "Item for \"" + valueName + "\" not found in the mapping element",
110  "STLContainerWriter::build" );
111  }
112  }
113 
114  m_dataWriter.reset( streamerFactory.newWriter( valueResolvedType, iMe->second ) );
115  m_dataWriter->build( m_localElement, *m_insertOperation, operationBuffer );
116  //operationBuffer.addToExecutionBuffer( *m_insertOperation );
117  return true;
118 }
119 
120 void ora::STLContainerWriter::setRecordId( const std::vector<int>& identity ){
121  m_recordId.clear();
122  for(size_t i=0;i<identity.size();i++) {
123  m_recordId.push_back( identity[i] );
124  }
125  m_recordId.push_back( 0 );
126 }
127 
129  const void* inputData ){
130 
131  if(!m_offset){
132  throwException("The streamer has not been built.",
133  "STLContainerWriter::write");
134  }
135 
136  const std::vector<std::string>& columns = m_mappingElement.columnNames();
137  if( columns.size() != m_recordId.size()+1){
138  throwException( "Object id elements provided are not matching with the mapped id columns.",
139  "STLContainerWriter::write");
140  }
141 
142  const edm::TypeWithDict& iteratorReturnType = m_arrayHandler->iteratorReturnType();
143  // Retrieve the container type
144  edm::TypeWithDict keyType;
145  if ( m_associative ) keyType = m_objectType.templateArgumentAt(0);
146  edm::MemberWithDict firstMember;
147  edm::MemberWithDict secondMember;
148  if( keyType ){
149  firstMember = iteratorReturnType.dataMemberByName( "first" );
150  if ( ! firstMember ) {
151  throwException( "Could not find the data member \"first\" for the class \"" +
152  iteratorReturnType.cppName() + "\"",
153  "STLContainerWriter::write" );
154  }
155  secondMember = iteratorReturnType.dataMemberByName( "second" );
156  if ( ! secondMember ) {
157  throwException( "Could not retrieve the data member \"second\" for the class \"" +
158  iteratorReturnType.cppName() + "\"",
159  "STLContainerWriter::write" );
160  }
161  }
162 
163  void* data = m_offset->address( inputData );
164 
165  // Use the iterator to loop over the elements of the container.
166  size_t containerSize = m_arrayHandler->size( data );
167 
168  if ( containerSize == 0 ) return;
169 
170  size_t startElementIndex = m_arrayHandler->startElementIndex( data );
171  std::auto_ptr<IArrayIteratorHandler> iteratorHandler( m_arrayHandler->iterate( data ) );
172 
173  InsertCache& bulkInsert = m_insertOperation->setUp( containerSize-startElementIndex+1 );
174 
175  for ( size_t iIndex = startElementIndex; iIndex < containerSize; ++iIndex ) {
176 
177  m_recordId[m_recordId.size()-1] = iIndex;
178  coral::AttributeList& dataBuff = m_insertOperation->data();
179 
180  dataBuff[ columns[0] ].data<int>() = oid;
181  for( size_t i = 1;i < columns.size(); i++ ){
182  dataBuff[ columns[i] ].data<int>() = m_recordId[i-1];
183  }
184 
185  void* objectReference = iteratorHandler->object();
186  void* componentData = objectReference;
187 
188  if ( keyType ) { // treat the key object first
189  void* keyData = static_cast< char* >( objectReference ) + firstMember.offset();
190  m_keyWriter->setRecordId( m_recordId );
191  m_keyWriter->write( oid, keyData );
192 
193  componentData = static_cast< char* >( objectReference ) + secondMember.offset();
194  }
195  m_dataWriter->setRecordId( m_recordId );
196 
197  m_dataWriter->write( oid, componentData );
198  bulkInsert.processNextIteration();
199 
200  // Increment the iterator
201  iteratorHandler->increment();
202  }
203 
204  // execute the insert...
205  m_arrayHandler->finalize( const_cast<void*>( data ) );
206 
207 }
208 
210  MappingElement& mapping,
211  ContainerSchema& contSchema ):
212  m_deleter( mapping ),
213  m_writer( objectType, mapping, contSchema ){
214 }
215 
217 }
218 
220  IRelationalData& relationalData,
221  RelationalBuffer& operationBuffer){
222  m_deleter.build( operationBuffer );
223  m_writer.build( offset, relationalData, operationBuffer );
224  return true;
225 }
226 
227 void ora::STLContainerUpdater::setRecordId( const std::vector<int>& identity ){
228  m_writer.setRecordId( identity );
229 }
230 
232  const void* data ){
233  m_deleter.erase( oid );
234  m_writer.write( oid, data );
235 }
236 
238  MappingElement& mapping,
239  ContainerSchema& contSchema ):
240  m_objectType( objectType ),
241  m_mappingElement( mapping ),
242  m_schema( contSchema ),
243  m_recordId(),
244  m_localElement(),
245  m_associative( ClassUtils::isTypeAssociativeContainer( objectType ) ),
246  m_offset(0 ),
247  m_query(),
248  m_arrayHandler(),
249  m_keyReader(),
250  m_dataReader(){
251 }
252 
254 }
255 
257  m_localElement.clear();
258  m_recordId.clear();
259  // allocate for the index...
260  m_recordId.push_back(0);
261 
262  RelationalStreamerFactory streamerFactory( m_schema );
263 
264  // first open the insert on the extra table...
265  m_query.reset( new MultiRecordSelectOperation( m_mappingElement.tableName(), m_schema.storageSchema() ));
266 
267  m_query->addWhereId( m_mappingElement.pkColumn() );
268  std::vector<std::string> recIdCols = m_mappingElement.recordIdColumns();
269  for( size_t i=0; i<recIdCols.size(); i++ ){
270  m_query->addId( recIdCols[ i ] );
271  m_query->addOrderId( recIdCols[ i ] );
272  }
273 
274  m_offset = &offset;
275 
276  m_arrayHandler.reset( ArrayHandlerFactory::newArrayHandler( m_objectType ) );
277 
278  edm::TypeWithDict valueType;
279  if ( m_associative ){
280 
281  edm::TypeWithDict keyType = ClassUtils::containerKeyType( m_objectType );
282  edm::TypeWithDict keyResolvedType = ClassUtils::resolvedType(keyType);
283 
284  if ( ! keyType ||!keyResolvedType ) {
285  throwException( "Missing dictionary information for the key type of the container \"" +
286  m_objectType.cppName() + "\"",
287  "STLContainerReader::build" );
288  }
289 
290  std::string keyName("key_type");
291  // Retrieve the relevant mapping element
292  MappingElement::iterator iMe = m_mappingElement.find( keyName );
293  if ( iMe == m_mappingElement.end() ) {
294  throwException( "Item for \"" + keyName + "\" not found in the mapping element",
295  "STLContainerReader::build" );
296  }
297 
298  m_keyReader.reset( streamerFactory.newReader( keyResolvedType, iMe->second ) );
299  m_keyReader->build( m_localElement, *m_query );
300 
301  valueType = ClassUtils::containerDataType(m_objectType);
302  } else {
303  valueType = ClassUtils::containerValueType(m_objectType);
304  }
305 
306  edm::TypeWithDict valueResolvedType = ClassUtils::resolvedType(valueType);
307  // Check the component type
308  if ( ! valueType ||!valueResolvedType ) {
309  throwException( "Missing dictionary information for the content type of the container \"" +
310  m_objectType.cppName() + "\"",
311  "STLContainerReader::build" );
312  }
313 
314  std::string valueName(m_associative ? "mapped_type" : "value_type");
315  // Retrieve the relevant mapping element
316  MappingElement::iterator iMe = m_mappingElement.find( valueName );
317  if ( iMe == m_mappingElement.end() ) {
318  // Try again with the name of a possible typedef
319  std::string valueName2 = valueType.unscopedName();
320  iMe = m_mappingElement.find( valueName2 );
321  if ( iMe == m_mappingElement.end() ) {
322  throwException( "Item for \"" + valueName + "\" not found in the mapping element",
323  "STLContainerReader::build" );
324  }
325  }
326 
327  m_dataReader.reset( streamerFactory.newReader( valueResolvedType, iMe->second ) );
328  m_dataReader->build( m_localElement, *m_query );
329  return true;
330 }
331 
333  if(!m_query.get()){
334  throwException("The streamer has not been built.",
335  "STLContainerReader::read");
336  }
337  coral::AttributeList& whereData = m_query->whereData();
338  whereData[ m_mappingElement.pkColumn() ].data<int>() = oid;
339  m_query->execute();
340  if(m_keyReader.get()) m_keyReader->select( oid );
341  m_dataReader->select( oid );
342 }
343 
344 void ora::STLContainerReader::setRecordId( const std::vector<int>& identity ){
345  m_recordId.clear();
346  for(size_t i=0;i<identity.size();i++) {
347  m_recordId.push_back( identity[i] );
348  }
349  // allocate the element for the index...
350  m_recordId.push_back( 0 );
351 }
352 
353 void ora::STLContainerReader::read( void* destinationData ) {
354 
355  if(!m_offset){
356  throwException("The streamer has not been built.",
357  "STLContainerReader::read");
358  }
359 
360  void* address = m_offset->address( destinationData );
361 
362  const edm::TypeWithDict& iteratorReturnType = m_arrayHandler->iteratorReturnType();
363  U_Primitives primitiveStub;
364 
365  edm::TypeWithDict keyType;
366  edm::MemberWithDict firstMember;
367  edm::MemberWithDict secondMember;
368  if ( m_associative ) {
369  keyType = m_objectType.templateArgumentAt(0);
370  firstMember = iteratorReturnType.dataMemberByName( "first" );
371  if ( ! firstMember ) {
372  throwException("Could not retrieve the data member \"first\" of the class \"" +
373  iteratorReturnType.cppName() + "\"",
374  "STLContainerReader::read" );
375  }
376  secondMember = iteratorReturnType.dataMemberByName( "second" );
377  if ( ! secondMember ) {
378  throwException( "Could not retrieve the data member \"second\" of the class \"" +
379  iteratorReturnType.cppName() + "\"",
380  "STLContainerReader::read" );
381  }
382  }
383 
384  bool isElementFundamental = iteratorReturnType.isFundamental();
385 
386  m_arrayHandler->clear( address );
387 
388  size_t cursorSize = m_query->selectionSize(m_recordId, m_recordId.size()-1);
389  unsigned int i=0;
390  // Create a new element for the array
391  void* objectData = 0;
392  if(isElementFundamental){
393  objectData = &primitiveStub;
394  } else {
395  objectData = iteratorReturnType.construct().address();
396  }
397 
398  while ( i< cursorSize ){
399 
400  m_recordId[m_recordId.size()-1] = (int)i;
401  m_query->selectRow( m_recordId );
402 
403  void* componentData = objectData;
404  void* keyData = 0;
405 
406  if ( keyType ) { // treat the key object first
407  keyData = static_cast< char* >( objectData ) + firstMember.offset();
408  m_keyReader->setRecordId( m_recordId );
409  m_keyReader->read( keyData );
410 
411  componentData = static_cast< char* >( objectData ) + secondMember.offset();
412  }
413  m_dataReader->setRecordId( m_recordId );
414  m_dataReader->read( componentData );
415 
416  size_t prevSize = m_arrayHandler->size( address );
417  m_arrayHandler->appendNewElement( address, objectData );
418  bool inserted = m_arrayHandler->size( address )>prevSize;
419  if ( !inserted ) {
420  throwException( "Could not insert a new element in the array type \"" +
421  m_objectType.cppName() + "\"",
422  "STLContainerReader::read" );
423  }
424  ++i;
425  }
426  if ( ! ( iteratorReturnType.isFundamental() ) ) {
427  iteratorReturnType.destruct( objectData );
428  }
429 
430  m_arrayHandler->finalize( address );
431 
432 }
433 
435  if(m_query.get()) m_query->clear();
436  if(m_keyReader.get()) m_keyReader->clear();
437  if(m_dataReader.get()) m_dataReader->clear();
438 }
439 
441  MappingElement& mapping,
442  ContainerSchema& contSchema ):
443  m_objectType( objectType ),
444  m_mapping( mapping ),
445  m_schema( contSchema ){
446 }
447 
449 }
450 
452  return new STLContainerWriter( m_objectType, m_mapping, m_schema );
453 }
454 
456  return new STLContainerUpdater( m_objectType, m_mapping, m_schema );
457 }
458 
460  return new STLContainerReader( m_objectType, m_mapping, m_schema );
461 }
int i
Definition: DBlmapReader.cc:9
edm::TypeWithDict resolvedType(const edm::TypeWithDict &typ)
Definition: ClassUtils.cc:486
void * address() const
bool build(DataElement &offset, IRelationalData &relationalData, RelationalBuffer &operationBuffer)
size_t offset() const
void setRecordId(const std::vector< int > &identity)
IRelationalReader * newReader()
std::string unscopedName() const
TypeWithDict templateArgumentAt(size_t index) const
MemberWithDict dataMemberByName(std::string const &) const
STLContainerWriter(const edm::TypeWithDict &objectType, MappingElement &mapping, ContainerSchema &contSchema)
Constructor.
STLContainerReader(const edm::TypeWithDict &objectType, MappingElement &mapping, ContainerSchema &contSchema)
Constructor.
std::string cppName() const
void write(int oid, const void *data)
Writes a data element.
bool build(DataElement &offset, IRelationalData &relationalData, RelationalBuffer &operationBuffer)
void read(void *address)
Reads a data element.
IRelationalWriter * newWriter(const edm::TypeWithDict &dataType, MappingElement &dataMapping)
static IArrayHandler * newArrayHandler(const edm::TypeWithDict &arrayType)
bool isFundamental() const
void setRecordId(const std::vector< int > &identity)
void setRecordId(const std::vector< int > &identity)
std::map< std::string, MappingElement >::iterator iterator
Iterator definition.
MultiRecordInsertOperation & newMultiRecordInsert(const std::string &tableName)
IRelationalReader * newReader(const edm::TypeWithDict &dataType, MappingElement &dataMapping)
STLContainerStreamer(const edm::TypeWithDict &objectType, MappingElement &mapping, ContainerSchema &contSchema)
bool isTypeAssociativeContainer(const edm::TypeWithDict &typ)
Definition: ClassUtils.cc:286
void destruct(void *address, bool dealloc=true) const
void update(int oid, const void *data)
Updates a data element.
IRelationalWriter * newWriter()
STLContainerUpdater(const edm::TypeWithDict &objectType, MappingElement &mapping, ContainerSchema &contSchema)
Constructor.
edm::TypeWithDict containerKeyType(const edm::TypeWithDict &typ)
Definition: ClassUtils.cc:429
edm::TypeWithDict containerDataType(const edm::TypeWithDict &typ)
Definition: ClassUtils.cc:449
void throwException(const std::string &message, const std::string &methodName) __attribute__((noreturn))
Definition: Exception.cc:10
bool build(DataElement &offset, IRelationalData &relationalData)
IRelationalUpdater * newUpdater()
tuple columns
Definition: mps_check.py:210
edm::TypeWithDict containerValueType(const edm::TypeWithDict &typ)
Definition: ClassUtils.cc:410
ObjectWithDict construct() const
tuple inputData
Definition: idDealer.py:72