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"
17 #include "Reflex/Member.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.Name(Reflex::SCOPED|Reflex::FINAL) + "\"",
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  Reflex::Type valueType;
69  if ( m_associative ){
70 
71  Reflex::Type keyType = ClassUtils::containerKeyType(m_objectType);
72  Reflex::Type keyResolvedType = ClassUtils::resolvedType(keyType);
73  if ( ! keyType || !keyResolvedType ) {
74  throwException( "Missing dictionary information for the key type of the container \"" +
75  m_objectType.Name(Reflex::SCOPED) + "\"",
76  "STLContainerWriter::build" );
77  }
78  std::string keyName = keyType.Name();
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  Reflex::Type 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.Name(Reflex::SCOPED) + "\"",
98  "STLContainerWriter::build" );
99  }
100 
101  std::string valueName = valueType.Name();
102  // Retrieve the relevant mapping element
103  MappingElement::iterator iMe = m_mappingElement.find( valueName );
104  if ( iMe == m_mappingElement.end() ) {
105  throwException( "Item for \"" + valueName + "\" not found in the mapping element",
106  "STLContainerWriter::build" );
107  }
108 
109  m_dataWriter.reset( streamerFactory.newWriter( valueResolvedType, iMe->second ) );
110  m_dataWriter->build( m_localElement, *m_insertOperation, operationBuffer );
111  //operationBuffer.addToExecutionBuffer( *m_insertOperation );
112  return true;
113 }
114 
115 void ora::STLContainerWriter::setRecordId( const std::vector<int>& identity ){
116  m_recordId.clear();
117  for(size_t i=0;i<identity.size();i++) {
118  m_recordId.push_back( identity[i] );
119  }
120  m_recordId.push_back( 0 );
121 }
122 
124  const void* inputData ){
125 
126  if(!m_offset){
127  throwException("The streamer has not been built.",
128  "STLContainerWriter::write");
129  }
130 
131  const std::vector<std::string>& columns = m_mappingElement.columnNames();
132  if( columns.size() != m_recordId.size()+1){
133  throwException( "Object id elements provided are not matching with the mapped id columns.",
134  "STLContainerWriter::write");
135  }
136 
137  const Reflex::Type& iteratorReturnType = m_arrayHandler->iteratorReturnType();
138  // Retrieve the container type
139  Reflex::Type keyType;
140  if ( m_associative ) keyType = m_objectType.TemplateArgumentAt(0);
141  Reflex::Member firstMember;
142  Reflex::Member secondMember;
143  if( keyType ){
144  firstMember = iteratorReturnType.MemberByName( "first" );
145  if ( ! firstMember ) {
146  throwException( "Could not find the data member \"first\" for the class \"" +
147  iteratorReturnType.Name(Reflex::SCOPED) + "\"",
148  "STLContainerWriter::write" );
149  }
150  secondMember = iteratorReturnType.MemberByName( "second" );
151  if ( ! secondMember ) {
152  throwException( "Could not retrieve the data member \"second\" for the class \"" +
153  iteratorReturnType.Name(Reflex::SCOPED) + "\"",
154  "STLContainerWriter::write" );
155  }
156  }
157 
158  void* data = m_offset->address( inputData );
159 
160  // Use the iterator to loop over the elements of the container.
161  size_t containerSize = m_arrayHandler->size( data );
162 
163  if ( containerSize == 0 ) return;
164 
165  size_t startElementIndex = m_arrayHandler->startElementIndex( data );
166  std::auto_ptr<IArrayIteratorHandler> iteratorHandler( m_arrayHandler->iterate( data ) );
167 
168  InsertCache& bulkInsert = m_insertOperation->setUp( containerSize-startElementIndex+1 );
169 
170  for ( size_t iIndex = startElementIndex; iIndex < containerSize; ++iIndex ) {
171 
172  m_recordId[m_recordId.size()-1] = iIndex;
173  coral::AttributeList& dataBuff = m_insertOperation->data();
174 
175  dataBuff[ columns[0] ].data<int>() = oid;
176  for( size_t i = 1;i < columns.size(); i++ ){
177  dataBuff[ columns[i] ].data<int>() = m_recordId[i-1];
178  }
179 
180  void* objectReference = iteratorHandler->object();
181  void* componentData = objectReference;
182 
183  if ( keyType ) { // treat the key object first
184  void* keyData = static_cast< char* >( objectReference ) + firstMember.Offset();
185  m_keyWriter->setRecordId( m_recordId );
186  m_keyWriter->write( oid, keyData );
187 
188  componentData = static_cast< char* >( objectReference ) + secondMember.Offset();
189  }
190  m_dataWriter->setRecordId( m_recordId );
191 
192  m_dataWriter->write( oid, componentData );
193  bulkInsert.processNextIteration();
194 
195  // Increment the iterator
196  iteratorHandler->increment();
197  }
198 
199  // execute the insert...
200  m_arrayHandler->finalize( const_cast<void*>( data ) );
201 
202 }
203 
205  MappingElement& mapping,
206  ContainerSchema& contSchema ):
207  m_deleter( mapping ),
208  m_writer( objectType, mapping, contSchema ){
209 }
210 
212 }
213 
215  IRelationalData& relationalData,
216  RelationalBuffer& operationBuffer){
217  m_deleter.build( operationBuffer );
218  m_writer.build( offset, relationalData, operationBuffer );
219  return true;
220 }
221 
222 void ora::STLContainerUpdater::setRecordId( const std::vector<int>& identity ){
223  m_writer.setRecordId( identity );
224 }
225 
227  const void* data ){
228  m_deleter.erase( oid );
229  m_writer.write( oid, data );
230 }
231 
233  MappingElement& mapping,
234  ContainerSchema& contSchema ):
235  m_objectType( objectType ),
236  m_mappingElement( mapping ),
237  m_schema( contSchema ),
238  m_recordId(),
239  m_localElement(),
240  m_associative( ClassUtils::isTypeAssociativeContainer( objectType ) ),
241  m_offset(0 ),
242  m_query(),
243  m_arrayHandler(),
244  m_keyReader(),
245  m_dataReader(){
246 }
247 
249 }
250 
252  m_localElement.clear();
253  m_recordId.clear();
254  // allocate for the index...
255  m_recordId.push_back(0);
256 
257  RelationalStreamerFactory streamerFactory( m_schema );
258 
259  // first open the insert on the extra table...
260  m_query.reset( new MultiRecordSelectOperation( m_mappingElement.tableName(), m_schema.storageSchema() ));
261 
262  m_query->addWhereId( m_mappingElement.pkColumn() );
263  std::vector<std::string> recIdCols = m_mappingElement.recordIdColumns();
264  for( size_t i=0; i<recIdCols.size(); i++ ){
265  m_query->addId( recIdCols[ i ] );
266  m_query->addOrderId( recIdCols[ i ] );
267  }
268 
269  m_offset = &offset;
270 
271  m_arrayHandler.reset( ArrayHandlerFactory::newArrayHandler( m_objectType ) );
272 
273  Reflex::Type valueType;
274  if ( m_associative ){
275 
276  Reflex::Type keyType = ClassUtils::containerKeyType( m_objectType );
277  Reflex::Type keyResolvedType = ClassUtils::resolvedType(keyType);
278 
279  if ( ! keyType ||!keyResolvedType ) {
280  throwException( "Missing dictionary information for the key type of the container \"" +
281  m_objectType.Name(Reflex::SCOPED) + "\"",
282  "STLContainerReader::build" );
283  }
284 
285  std::string keyName = keyType.Name();
286  // Retrieve the relevant mapping element
287  MappingElement::iterator iMe = m_mappingElement.find( keyName );
288  if ( iMe == m_mappingElement.end() ) {
289  throwException( "Item for \"" + keyName + "\" not found in the mapping element",
290  "STLContainerReader::build" );
291  }
292 
293  m_keyReader.reset( streamerFactory.newReader( keyResolvedType, iMe->second ) );
294  m_keyReader->build( m_localElement, *m_query );
295 
296  valueType = ClassUtils::containerDataType(m_objectType);
297  } else {
298  valueType = ClassUtils::containerValueType(m_objectType);
299  }
300 
301  Reflex::Type valueResolvedType = ClassUtils::resolvedType(valueType);
302  // Check the component type
303  if ( ! valueType ||!valueResolvedType ) {
304  throwException( "Missing dictionary information for the content type of the container \"" +
305  m_objectType.Name(Reflex::SCOPED) + "\"",
306  "STLContainerReader::build" );
307  }
308 
309  std::string valueName = valueType.Name();
310  // Retrieve the relevant mapping element
311  MappingElement::iterator iMe = m_mappingElement.find( valueName );
312  if ( iMe == m_mappingElement.end() ) {
313  throwException( "Item for \"" + valueName + "\" not found in the mapping element",
314  "STLContainerReader::build" );
315  }
316 
317  m_dataReader.reset( streamerFactory.newReader( valueResolvedType, iMe->second ) );
318  m_dataReader->build( m_localElement, *m_query );
319  return true;
320 }
321 
323  if(!m_query.get()){
324  throwException("The streamer has not been built.",
325  "STLContainerReader::read");
326  }
327  coral::AttributeList& whereData = m_query->whereData();
328  whereData[ m_mappingElement.pkColumn() ].data<int>() = oid;
329  m_query->execute();
330  if(m_keyReader.get()) m_keyReader->select( oid );
331  m_dataReader->select( oid );
332 }
333 
334 void ora::STLContainerReader::setRecordId( const std::vector<int>& identity ){
335  m_recordId.clear();
336  for(size_t i=0;i<identity.size();i++) {
337  m_recordId.push_back( identity[i] );
338  }
339  // allocate the element for the index...
340  m_recordId.push_back( 0 );
341 }
342 
343 void ora::STLContainerReader::read( void* destinationData ) {
344 
345  if(!m_offset){
346  throwException("The streamer has not been built.",
347  "STLContainerReader::read");
348  }
349 
350  void* address = m_offset->address( destinationData );
351 
352  const Reflex::Type& iteratorReturnType = m_arrayHandler->iteratorReturnType();
353  U_Primitives primitiveStub;
354 
355  Reflex::Type keyType;
356  Reflex::Member firstMember;
357  Reflex::Member secondMember;
358  if ( m_associative ) {
359  keyType = m_objectType.TemplateArgumentAt(0);
360  firstMember = iteratorReturnType.MemberByName( "first" );
361  if ( ! firstMember ) {
362  throwException("Could not retrieve the data member \"first\" of the class \"" +
363  iteratorReturnType.Name(Reflex::SCOPED) + "\"",
364  "STLContainerReader::read" );
365  }
366  secondMember = iteratorReturnType.MemberByName( "second" );
367  if ( ! secondMember ) {
368  throwException( "Could not retrieve the data member \"second\" of the class \"" +
369  iteratorReturnType.Name(Reflex::SCOPED) + "\"",
370  "STLContainerReader::read" );
371  }
372  }
373 
374  bool isElementFundamental = iteratorReturnType.IsFundamental();
375 
376  m_arrayHandler->clear( address );
377 
378  size_t cursorSize = m_query->selectionSize(m_recordId, m_recordId.size()-1);
379  unsigned int i=0;
380  while ( i< cursorSize ){
381 
382  m_recordId[m_recordId.size()-1] = (int)i;
383  m_query->selectRow( m_recordId );
384 
385  // Create a new element for the array
386  void* objectData = 0;
387  if(isElementFundamental){
388  objectData = &primitiveStub;
389  } else {
390  objectData = iteratorReturnType.Construct().Address();
391  }
392 
393  void* componentData = objectData;
394  void* keyData = 0;
395 
396  if ( keyType ) { // treat the key object first
397  keyData = static_cast< char* >( objectData ) + firstMember.Offset();
398  m_keyReader->setRecordId( m_recordId );
399  m_keyReader->read( keyData );
400 
401  componentData = static_cast< char* >( objectData ) + secondMember.Offset();
402  }
403  m_dataReader->setRecordId( m_recordId );
404  m_dataReader->read( componentData );
405 
406  size_t prevSize = m_arrayHandler->size( address );
407  m_arrayHandler->appendNewElement( address, objectData );
408  bool inserted = m_arrayHandler->size( address )>prevSize;
409  if ( ! ( iteratorReturnType.IsFundamental() ) ) {
410  iteratorReturnType.Destruct( objectData );
411  }
412  if ( !inserted ) {
413  throwException( "Could not insert a new element in the array type \"" +
414  m_objectType.Name(Reflex::SCOPED) + "\"",
415  "STLContainerReader::read" );
416  }
417  ++i;
418  }
419 
420  m_arrayHandler->finalize( address );
421 
422 }
423 
425  if(m_query.get()) m_query->clear();
426  if(m_keyReader.get()) m_keyReader->clear();
427  if(m_dataReader.get()) m_dataReader->clear();
428 }
429 
431  MappingElement& mapping,
432  ContainerSchema& contSchema ):
433  m_objectType( objectType ),
434  m_mapping( mapping ),
435  m_schema( contSchema ){
436 }
437 
439 }
440 
442  return new STLContainerWriter( m_objectType, m_mapping, m_schema );
443 }
444 
446  return new STLContainerUpdater( m_objectType, m_mapping, m_schema );
447 }
448 
450  return new STLContainerReader( m_objectType, m_mapping, m_schema );
451 }
int i
Definition: DBlmapReader.cc:9
char * address
Definition: mlp_lapack.h:14
IRelationalReader * newReader(const Reflex::Type &dataType, MappingElement &dataMapping)
bool isTypeAssociativeContainer(const Reflex::Type &typ)
Definition: ClassUtils.cc:211
bool build(DataElement &offset, IRelationalData &relationalData, RelationalBuffer &operationBuffer)
STLContainerStreamer(const Reflex::Type &objectType, MappingElement &mapping, ContainerSchema &contSchema)
void setRecordId(const std::vector< int > &identity)
IRelationalReader * newReader()
Reflex::Type containerDataType(const Reflex::Type &typ)
Definition: ClassUtils.cc:373
void write(int oid, const void *data)
Writes a data element.
static IArrayHandler * newArrayHandler(const Reflex::Type &arrayType)
bool build(DataElement &offset, IRelationalData &relationalData, RelationalBuffer &operationBuffer)
void read(void *address)
Reads a data element.
void setRecordId(const std::vector< int > &identity)
unsigned int offset(bool)
void setRecordId(const std::vector< int > &identity)
std::map< std::string, MappingElement >::iterator iterator
Iterator definition.
Reflex::Type containerKeyType(const Reflex::Type &typ)
Definition: ClassUtils.cc:357
Reflex::Type containerValueType(const Reflex::Type &typ)
Definition: ClassUtils.cc:341
MultiRecordInsertOperation & newMultiRecordInsert(const std::string &tableName)
STLContainerReader(const Reflex::Type &objectType, MappingElement &mapping, ContainerSchema &contSchema)
Constructor.
Reflex::Type resolvedType(const Reflex::Type &typ)
Definition: ClassUtils.cc:404
IRelationalWriter * newWriter(const Reflex::Type &dataType, MappingElement &dataMapping)
void update(int oid, const void *data)
Updates a data element.
IRelationalWriter * newWriter()
bool build(DataElement &offset, IRelationalData &relationalData)
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:82
STLContainerWriter(const Reflex::Type &objectType, MappingElement &mapping, ContainerSchema &contSchema)
Constructor.
IRelationalUpdater * newUpdater()
void throwException(const std::string &message, const std::string &methodName)
Definition: Exception.cc:10
STLContainerUpdater(const Reflex::Type &objectType, MappingElement &mapping, ContainerSchema &contSchema)
Constructor.
tuple inputData
Definition: idDealer.py:72