CMS 3D CMS Logo

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
CArrayStreamer.cc
Go to the documentation of this file.
2 #include "CArrayStreamer.h"
3 #include "ClassUtils.h"
4 #include "MappingElement.h"
5 #include "ContainerSchema.h"
6 #include "RelationalBuffer.h"
10 #include "ArrayHandlerFactory.h"
11 #include "IArrayHandler.h"
12 // externals
13 #include "CoralBase/Attribute.h"
14 #include "RelationalAccess/IBulkOperation.h"
15 #include "Reflex/Object.h"
16 
18  MappingElement& mapping,
19  ContainerSchema& contSchema ):
20  m_objectType( objectType ),
21  m_mappingElement( mapping ),
22  m_schema( contSchema ),
23  m_recordId(),
24  m_localElement( ),
25  m_offset( 0 ),
26  m_insertOperation( 0 ),
27  m_arrayHandler(),
28  m_dataWriter(){
29 }
30 
32 }
33 
36  RelationalBuffer& operationBuffer ){
37 
38  m_localElement.clear();
39  m_recordId.clear();
40  // allocate for the index...
41  m_recordId.push_back(0);
42 
43  // Check the array type
44  Reflex::Type arrayType = m_objectType.ToType();
45  Reflex::Type arrayResolvedType = ClassUtils::resolvedType(arrayType);
46  // Check the component type
47  if ( ! arrayType || !arrayResolvedType ) {
48  throwException( "Missing dictionary information for the element type of the array \"" +
49  m_objectType.Name(Reflex::SCOPED|Reflex::FINAL) + "\"",
50  "CArrayWriter::build" );
51  }
52 
53  RelationalStreamerFactory streamerFactory( m_schema );
54 
55  // first open the insert on the extra table...
56  m_insertOperation = &operationBuffer.newMultiRecordInsert( m_mappingElement.tableName() );
57  const std::vector<std::string>& columns = m_mappingElement.columnNames();
58  if( !columns.size() ){
59  throwException( "Id columns not found in the mapping.",
60  "CArrayWriter::build");
61  }
62  for( size_t i=0; i<columns.size(); i++ ){
63  m_insertOperation->addId( columns[ i ] );
64  }
65 
66  m_offset = &offset;
67 
68  m_arrayHandler.reset( ArrayHandlerFactory::newArrayHandler( m_objectType ) );
69 
70  std::string arrayTypeName = arrayType.Name();
71  // Retrieve the relevant mapping element
72  MappingElement::iterator iMe = m_mappingElement.find( arrayTypeName );
73  if ( iMe == m_mappingElement.end() ) {
74  throwException( "Item for \"" + arrayTypeName + "\" not found in the mapping element",
75  "CArrayWriter::build" );
76  }
77 
78  m_dataWriter.reset( streamerFactory.newWriter( arrayResolvedType, iMe->second ));
79  m_dataWriter->build( m_localElement, *m_insertOperation, operationBuffer );
80  return true;
81 }
82 
83 void ora::CArrayWriter::setRecordId( const std::vector<int>& identity ){
84  m_recordId.clear();
85  for(size_t i=0;i<identity.size();i++) {
86  m_recordId.push_back( identity[i] );
87  }
88  m_recordId.push_back( 0 );
89 }
90 
92  const void* inputData ){
93 
94  if(!m_offset){
95  throwException("The streamer has not been built.",
96  "CArrayWriter::write");
97  }
98  const std::vector<std::string>& columns = m_mappingElement.columnNames();
99  if( columns.size() != m_recordId.size()+1){
100  throwException( "Record id elements provided are not matching with the mapped id columns.",
101  "CArrayWriter::write");
102  }
103 
104  void* data = m_offset->address( inputData );
105 
106  // Use the iterator to loop over the elements of the container.
107  size_t containerSize = m_arrayHandler->size( data );
108  size_t persistentSize = m_arrayHandler->persistentSize( data );
109 
110  if ( containerSize == 0 || containerSize < persistentSize ) return;
111 
112  size_t startElementIndex = m_arrayHandler->startElementIndex( data );
113 
114  std::auto_ptr<IArrayIteratorHandler> iteratorHandler( m_arrayHandler->iterate( data ) );
115 
116  InsertCache& bulkOperation = m_insertOperation->setUp( containerSize-startElementIndex+1 );
117 
118  for ( size_t iIndex = startElementIndex; iIndex < containerSize; ++iIndex ) {
119 
120  m_recordId[m_recordId.size()-1] = iIndex;
121  coral::AttributeList& dataBuff = m_insertOperation->data();
122 
123  dataBuff[ columns[0] ].data<int>() = oid;
124  for( size_t i = 1;i < columns.size(); i++ ){
125  dataBuff[ columns[i] ].data<int>() = m_recordId[i-1];
126  }
127 
128  void* objectReference = iteratorHandler->object();
129 
130  m_dataWriter->setRecordId( m_recordId );
131  m_dataWriter->write( oid, objectReference );
132 
133  bulkOperation.processNextIteration();
134  // Increment the iterator
135  iteratorHandler->increment();
136  }
137 
138  m_arrayHandler->finalize( const_cast<void*>( data ) );
139 
140 }
141 
143  MappingElement& mapping,
144  ContainerSchema& contSchema ):
145  m_deleter( mapping ),
146  m_writer( objectType, mapping, contSchema ){
147 }
148 
150 }
151 
153  IRelationalData& relationalData,
154  RelationalBuffer& operationBuffer){
155  m_deleter.build( operationBuffer );
156  m_writer.build( offset, relationalData, operationBuffer );
157  return true;
158 }
159 
160 void ora::CArrayUpdater::setRecordId( const std::vector<int>& identity ){
161  m_writer.setRecordId( identity );
162 }
163 
165  const void* data ){
166  m_deleter.erase( oid );
167  m_writer.write( oid, data );
168 }
169 
171  MappingElement& mapping,
172  ContainerSchema& contSchema ):
173  m_objectType( objectType ),
174  m_mappingElement( mapping ),
175  m_schema( contSchema ),
176  m_recordId(),
177  m_localElement( ),
178  m_offset(0 ),
179  m_query(),
180  m_arrayHandler(),
181  m_dataReader(){
182 }
183 
185 }
186 
188  IRelationalData& relationalData ){
189 
190  m_localElement.clear();
191 
192  m_recordId.clear();
193  // allocate for the index...
194  m_recordId.push_back(0);
195 
196  // Check the array type
197  Reflex::Type arrayType = m_objectType.ToType();
198  Reflex::Type arrayResolvedType = ClassUtils::resolvedType(arrayType);
199  // Check the component type
200  if ( ! arrayType || !arrayResolvedType ) {
201  throwException( "Missing dictionary information for the element type of the array \"" +
202  m_objectType.Name(Reflex::SCOPED|Reflex::FINAL) + "\"",
203  "CArrayReader::build" );
204  }
205 
206  RelationalStreamerFactory streamerFactory( m_schema );
207 
208  // first open the insert on the extra table...
209  m_query.reset(new MultiRecordSelectOperation( m_mappingElement.tableName(), m_schema.storageSchema() ));
210  m_query->addWhereId( m_mappingElement.pkColumn() );
211  std::vector<std::string> recIdCols = m_mappingElement.recordIdColumns();
212  for( size_t i=0; i<recIdCols.size(); i++ ){
213  m_query->addId( recIdCols[ i ] );
214  m_query->addOrderId( recIdCols[ i ] );
215  }
216 
217  m_offset = &offset;
218 
219  m_arrayHandler.reset( ArrayHandlerFactory::newArrayHandler( m_objectType ) );
220 
221  std::string arrayTypeName = arrayType.Name();
222 
223  // Retrieve the relevant mapping element
224  MappingElement::iterator iMe = m_mappingElement.find( arrayTypeName );
225  if ( iMe == m_mappingElement.end() ) {
226  throwException( "Item for \"" + arrayTypeName + "\" not found in the mapping element",
227  "CArrayReader::build" );
228  }
229 
230  m_dataReader.reset( streamerFactory.newReader( arrayResolvedType, iMe->second ) );
231  m_dataReader->build( m_localElement, *m_query );
232  return true;
233 }
234 
236  if(!m_query.get()){
237  throwException("The streamer has not been built.",
238  "CArrayReader::select");
239  }
240  coral::AttributeList& whereData = m_query->whereData();
241  whereData[ m_mappingElement.pkColumn() ].data<int>() = oid;
242  m_query->execute();
243  m_dataReader->select( oid );
244 }
245 
246 void ora::CArrayReader::setRecordId( const std::vector<int>& identity ){
247  m_recordId.clear();
248  for(size_t i=0;i<identity.size();i++) {
249  m_recordId.push_back( identity[i] );
250  }
251  // allocate the element for the index...
252  m_recordId.push_back( 0 );
253 }
254 
255 void ora::CArrayReader::read( void* destinationData ) {
256  if(!m_offset){
257  throwException("The streamer has not been built.",
258  "CArrayReader::read");
259  }
260  void* address = m_offset->address( destinationData );
261 
262  Reflex::Type iteratorDereferenceReturnType = m_arrayHandler->iteratorReturnType();
263 
264  bool isElementFundamental = iteratorDereferenceReturnType.IsFundamental();
265 
266  std::string positionColumn = m_mappingElement.posColumn();
267 
268  size_t arraySize = m_objectType.ArrayLength();
269 
270  m_arrayHandler->clear( address );
271 
272  size_t cursorSize = m_query->selectionSize(m_recordId, m_recordId.size()-1);
273  unsigned int i=0;
274  while ( i< cursorSize ){
275 
276  m_recordId[m_recordId.size()-1] = (int)i;
277  m_query->selectRow( m_recordId );
278  coral::AttributeList& row = m_query->data();
279 
280  int arrayIndex = row[positionColumn].data< int >();
281 
282  // Create a new element for the array
283  void* objectData = 0;
284 
285  if(arrayIndex >= (int)arraySize){
286  throwException("Found more element then array size.",
287  "CArrayReader::read");
288 
289  }
290 
291  // the memory has been allocated already!
292  objectData = static_cast<char*>(address)+arrayIndex*iteratorDereferenceReturnType.SizeOf();
293 
294  if(!isElementFundamental){
295  // in this case the initialization is required: use default constructor...
296  iteratorDereferenceReturnType.Construct(Reflex::Type(0,0),std::vector< void* >(),objectData);
297  }
298 
299  m_dataReader->setRecordId( m_recordId );
300  m_dataReader->read( objectData );
301 
302  ++i;
303  }
304 
305  m_arrayHandler->finalize( address );
306 
307 }
308 
310  if(m_dataReader.get()) m_dataReader->clear();
311 }
312 
314  MappingElement& mapping,
315  ContainerSchema& contSchema ):
316  m_objectType( objectType ),
317  m_mapping( mapping ),
318  m_schema( contSchema ){
319 }
320 
322 }
323 
325  return new CArrayWriter( m_objectType, m_mapping, m_schema );
326 }
327 
329  return new CArrayUpdater( m_objectType, m_mapping, m_schema );
330 }
331 
333  return new CArrayReader( m_objectType, m_mapping, m_schema );
334 }
int i
Definition: DBlmapReader.cc:9
IRelationalReader * newReader()
char * address
Definition: mlp_lapack.h:14
IRelationalReader * newReader(const Reflex::Type &dataType, MappingElement &dataMapping)
bool build(DataElement &offset, IRelationalData &relationalData, RelationalBuffer &operationBuffer)
void select(int oid)
CArrayUpdater(const Reflex::Type &objectType, MappingElement &mapping, ContainerSchema &contSchema)
Constructor.
void update(int oid, const void *data)
Updates a data element.
CArrayStreamer(const Reflex::Type &objectType, MappingElement &mapping, ContainerSchema &contSchema)
void setRecordId(const std::vector< int > &identity)
static IArrayHandler * newArrayHandler(const Reflex::Type &arrayType)
void read(void *address)
Reads a data element.
CArrayWriter(const Reflex::Type &objectType, MappingElement &mapping, ContainerSchema &contSchema)
Constructor.
unsigned int offset(bool)
std::map< std::string, MappingElement >::iterator iterator
Iterator definition.
IRelationalUpdater * newUpdater()
MultiRecordInsertOperation & newMultiRecordInsert(const std::string &tableName)
Reflex::Type resolvedType(const Reflex::Type &typ)
Definition: ClassUtils.cc:380
IRelationalWriter * newWriter(const Reflex::Type &dataType, MappingElement &dataMapping)
bool build(DataElement &offset, IRelationalData &relationalData, RelationalBuffer &operationBuffer)
void write(int oid, const void *data)
Writes a data element.
bool build(DataElement &offset, IRelationalData &relationalData)
void setRecordId(const std::vector< int > &identity)
virtual ~CArrayWriter()
void throwException(const std::string &message, const std::string &methodName)
Definition: Exception.cc:10
IRelationalWriter * newWriter()
CArrayReader(const Reflex::Type &objectType, MappingElement &mapping, ContainerSchema &contSchema)
Constructor.
tuple inputData
Definition: idDealer.py:72
void setRecordId(const std::vector< int > &identity)