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