CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
QueryableVectorStreamer.cc
Go to the documentation of this file.
7 #include "MappingElement.h"
8 #include "ContainerSchema.h"
9 #include "ArrayHandlerFactory.h"
10 #include "ClassUtils.h"
11 #include "IArrayHandler.h"
12 #include "ArrayCommonImpl.h"
13 #include "RelationalBuffer.h"
14 // externals
15 #include "RelationalAccess/IBulkOperation.h"
16 #include "Reflex/Member.h"
17 #include "Reflex/Base.h"
18 #include "CoralBase/Attribute.h"
19 
20 namespace ora {
21 
22  class QVReader {
23  public:
24  QVReader( const Reflex::Type& objectType, MappingElement& mapping, ContainerSchema& contSchema ):
25  m_objectType( objectType ),
27  m_reader( ClassUtils::containerSubType(objectType,"store_base_type"), mapping, contSchema ){
29  InputRelationalData dummy;
30  m_reader.build( m_localElement,dummy );
31  }
32 
33  void read( const std::vector<int>& fullId, void* destinationAddress){
34  m_reader.select( fullId[0] );
35  std::vector<int> recordId;
36  for(size_t i=1;i<fullId.size();i++) {
37  recordId.push_back( fullId[i] );
38  }
39  m_reader.setRecordId(recordId);
40  m_reader.read( destinationAddress );
41  m_reader.clear();
42  }
43 
44  private:
48  };
49 
50  class QVQueryMaker {
51  public:
52  QVQueryMaker( const Reflex::Type& objectType, MappingElement& mapping, ContainerSchema& contSchema ):
53  m_objectType( objectType ),
54  m_mappingElement( mapping ),
55  m_schema( contSchema ),
56  m_recordId(),
58  m_query(),
60  m_oid(-1){
61  }
62 
64  }
65 
66  bool build(){
68  m_recordId.clear();
69  // allocate for the index...
70  m_recordId.push_back(0);
71 
72  RelationalStreamerFactory streamerFactory( m_schema );
73  // first open the insert on the extra table...
75 
76  m_query->addWhereId( m_mappingElement.pkColumn() );
77  std::vector<std::string> recIdCols = m_mappingElement.recordIdColumns();
78  for( size_t i=0; i<recIdCols.size(); i++ ){
79  m_query->addId( recIdCols[ i ] );
80  m_query->addOrderId( recIdCols[ i ] );
81  }
82 
83  Reflex::Type storeBaseType = ClassUtils::containerSubType(m_objectType,"range_store_base_type");
84  if( !storeBaseType ){
85  throwException( "Missing dictionary information for the range store base type of the container \"" +
86  m_objectType.Name(Reflex::SCOPED) + "\"",
87  "QVQueryMaker::build" );
88  }
89 
90  m_arrayHandler.reset( ArrayHandlerFactory::newArrayHandler( storeBaseType ) );
91 
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  "QVQueryMaker::build" );
99  }
100  std::string valueName = valueType.Name();
101  // Retrieve the relevant mapping element
103  if ( iMe == m_mappingElement.end() ) {
104  throwException( "Item for \"" + valueName + "\" not found in the mapping element",
105  "QVQueryMaker::build" );
106  }
107 
108  m_dataReader.reset( streamerFactory.newReader( valueResolvedType, iMe->second ) );
109  m_dataReader->build( m_localElement, *m_query );
110  return true;
111  }
112 
113  void setQueryCondition( IRelationalData& queryData, const Selection& selection, MappingElement& mappingElement ){
114  coral::AttributeList& whereData = queryData.whereData();
115  // adding the selection conditions
116  const std::vector<std::pair<std::string,std::string> >& theItems = selection.items();
117  std::stringstream cond;
118  unsigned int i=0;
119  for(std::vector<std::pair<std::string,std::string> >::const_iterator iItem = theItems.begin();
120  iItem != theItems.end();
121  ++iItem){
122  cond << " AND ";
123  std::string varName = Selection::variableNameFromUniqueString(iItem->first);
124  std::stringstream selColumn;
125  std::string colName("");
126  if(varName == Selection::indexVariable()){
127  colName = mappingElement.columnNames()[mappingElement.columnNames().size()-1]; // the position column is the last
128  selColumn << colName<<"_"<<i;
129  whereData.extend<int>(selColumn.str());
130  whereData[selColumn.str()].data<int>() = selection.data()[iItem->first].data<int>();
131  } else {
132  MappingElement::iterator iElem = mappingElement.find("value_type");
133  if ( iElem == mappingElement.end() ) {
134  throwException( "Item for element \"value_type\" not found in the mapping element",
135  "QVQueryMaker::setQueryCondition" );
136  }
137  MappingElement& valueTypeElement = iElem->second;
138  if( valueTypeElement.elementType()==MappingElement::Primitive ){
139  if(varName!="value_type"){
140  throwException( "Item for element \"" + varName + "\" not found in the mapping element",
141  "QVQueryMaker::setQueryCondition" );
142  }
143  colName = valueTypeElement.columnNames()[0];
144  } else if( valueTypeElement.elementType()==MappingElement::Object ){
145  MappingElement::iterator iInnerElem = valueTypeElement.find(varName);
146  if ( iInnerElem == valueTypeElement.end() ) {
147  throwException( "Item for element \"" + varName + "\" not found in the mapping element",
148  "QVQueryMaker::setQueryCondition" );
149  }
150  colName = iInnerElem->second.columnNames()[0];
151  } else {
152  throwException( "Queries cannot be executed on types mapped on "+
154  "QVQueryMaker::setQueryCondition" );
155  }
156  selColumn << colName<<"_"<<i;
157  whereData.extend(selColumn.str(),selection.data()[iItem->first].specification().type());
158  whereData[selColumn.str()].setValueFromAddress(selection.data()[iItem->first].addressOfData());
159  }
160  cond << colName << " " << iItem->second << " :"<<selColumn.str();
161  i++;
162  selColumn.str("");
163  }
164 
165  // add the resulting condition clause
166  queryData.whereClause()+=cond.str();
167  }
168 
169  void select( const std::vector<int>& fullId, const Selection& selection ){
170  if(!m_query.get()){
171  throwException("The reader has not been built.",
172  "QVReader::select");
173  }
174 
175  m_oid = fullId[0];
176  m_recordId.clear();
177  for(size_t i=1;i<fullId.size();i++) {
178  m_recordId.push_back( fullId[i] );
179  }
180  // allocate the element for the index...
181  m_recordId.push_back( 0 );
182 
183  coral::AttributeList& whereData = m_query->whereData();
184  whereData[ m_mappingElement.pkColumn() ].data<int>() = fullId[0];
185 
187 
188  m_query->execute();
189  }
190 
191  size_t selectionCount( const std::vector<int>& fullId, const Selection& selection ){
193  std::string countColumn("COUNT(*)");
194  countQuery.addData( countColumn ,typeid(int) );
195  countQuery.addWhereId( m_mappingElement.pkColumn() );
196  std::vector<std::string> recIdColumns = m_mappingElement.recordIdColumns();
197  for( size_t i=0;i<recIdColumns.size();i++){
198  countQuery.addWhereId( recIdColumns[i] );
199  }
200 
201  coral::AttributeList& whereData = countQuery.whereData();
202  // Fill-in the identities.
203  whereData[ m_mappingElement.pkColumn() ].data<int>() = fullId[0];
204  for ( size_t i=0;i<fullId.size();i++ ){
205  whereData[ recIdColumns[i] ].data<int>() = fullId[i+1];
206  }
207 
208  setQueryCondition( countQuery, selection, m_mappingElement );
209  countQuery.execute();
210 
211  size_t result = 0;
212  if( countQuery.nextCursorRow() ){
213  coral::AttributeList& row = countQuery.data();
214  result = row[countColumn].data<int>();
215  }
216  return result;
217  }
218 
219  void executeAndLoad(void* address){
220 
221  if(!m_query.get()){
222  throwException("The reader has not been built.",
223  "QVReader::read");
224  }
225  Reflex::Type iteratorDereferenceReturnType = m_arrayHandler->iteratorReturnType();
226  Reflex::Member firstMember = iteratorDereferenceReturnType.MemberByName( "first" );
227  if ( ! firstMember ) {
228  throwException( "Could not retrieve the data member \"first\" of the class \"" +
229  iteratorDereferenceReturnType.Name(Reflex::SCOPED) + "\"",
230  "QVQueryMakerAndLoad::read" );
231  }
232  Reflex::Member secondMember = iteratorDereferenceReturnType.MemberByName( "second" );
233  if ( ! secondMember ) {
234  throwException( "Could not retrieve the data member \"second\" of the class \"" +
235  iteratorDereferenceReturnType.Name(Reflex::SCOPED) + "\"",
236  "QVQueryMakerAndLoad::read" );
237  }
238 
239  m_arrayHandler->clear( address );
240 
241  unsigned int i=0;
242  while ( m_query->nextCursorRow() ){
243 
244  // Create a new element for the array
245  void* objectData = iteratorDereferenceReturnType.Construct().Address();
246  void* positionData = static_cast< char* >( objectData ) + firstMember.Offset();
247  void* containerData = static_cast< char* >( objectData ) + secondMember.Offset();
248 
249  m_recordId[m_recordId.size()-1] = (int)i;
250  coral::AttributeList& row = m_query->data();
251 
252  *(size_t*)positionData = (size_t)(row[m_mappingElement.posColumn()].data<int>());
253 
254  m_dataReader->setRecordId( m_recordId );
255  m_dataReader->select( m_oid );
256  m_dataReader->read( containerData );
257 
258  size_t prevSize = m_arrayHandler->size( address );
259  m_arrayHandler->appendNewElement( address, objectData );
260  bool inserted = m_arrayHandler->size( address )>prevSize;
261 
262  iteratorDereferenceReturnType.Destruct( objectData );
263  if ( !inserted ) {
264  throwException( "Could not insert a new element in the array type \"" +
265  m_objectType.Name(Reflex::SCOPED|Reflex::FINAL) + "\"",
266  "QVQueryMakerAndLoad::executeAndLoad" );
267  }
268  ++i;
269  }
270 
271  m_arrayHandler->finalize( address );
272  m_query->clear();
273  }
274 
275  private:
279  std::vector<int> m_recordId;
281  std::auto_ptr<SelectOperation> m_query;
282  std::auto_ptr<IArrayHandler> m_arrayHandler;
283  std::auto_ptr<IRelationalReader> m_dataReader;
284  int m_oid;
285  };
286 
288 
289  public:
290 
291  // constructor
292  QueryableVectorLoader( const Reflex::Type& objectType, MappingElement& mapping, ContainerSchema& contSchema,
293  const std::vector<int>& fullId ):
294  m_isValid(true),
295  m_reader( objectType, mapping, contSchema ),
296  m_queryMaker( objectType, mapping, contSchema ),
297  m_identity(fullId){
298  }
299 
300  // destructor
302  }
303 
304  public:
305 
306  // triggers the data loading
307  bool load(void* address) const {
308  bool ret = false;
309  if(m_isValid) {
310  m_reader.read( m_identity, address );
311  ret = true;
312  }
313  return ret;
314  }
315 
316  bool loadSelection(const Selection& selection, void* address) const {
317  bool ret = false;
318  if(m_isValid) {
320  m_queryMaker.select( m_identity, selection );
321  m_queryMaker.executeAndLoad( address );
322  ret = true;
323  }
324  return ret;
325  }
326 
327  size_t getSelectionCount( const Selection& selection ) const {
328  size_t ret = 0;
329  if(m_isValid) {
330  ret = m_queryMaker.selectionCount( m_identity, selection );
331  }
332  return ret;
333  }
334 
335  void invalidate(){
336  m_isValid = false;
337  }
338 
339  bool isValid() const{
340  return m_isValid;
341  }
342 
343  private:
344  bool m_isValid;
347  std::vector<int> m_identity;
348  };
349 
350 }
351 
353  MappingElement& mapping,
354  ContainerSchema& contSchema ):
355  m_objectType( objectType ),
356  m_offset( 0 ),
357  m_localElement(),
358  m_writer(ClassUtils::containerSubType(objectType,"store_base_type"), mapping, contSchema ){
359 }
360 
362 }
363 
366  RelationalBuffer& operationBuffer ){
367  m_offset = &offset;
368  m_localElement.clear();
369  return m_writer.build( m_localElement, data, operationBuffer );
370 }
371 
372 void ora::QueryableVectorWriter::setRecordId( const std::vector<int>& identity ){
373  m_writer.setRecordId( identity );
374 }
375 
377  const void* inputData ){
378  if(!m_offset){
379  throwException("The streamer has not been built.",
380  "QueryableVectorWriter::write");
381  }
382  void* vectorAddress = m_offset->address( inputData );
383  Reflex::Object vectorObj( m_objectType,const_cast<void*>(vectorAddress));
384  vectorObj.Invoke("load",0);
385  void* storageAddress = 0;
386  vectorObj.Invoke("storageAddress",storageAddress);
387  m_writer.write( oid, storageAddress );
388 }
389 
391  MappingElement& mapping,
392  ContainerSchema& contSchema ):
393  m_objectType( objectType ),
394  m_offset( 0 ),
395  m_localElement(),
396  m_updater( ClassUtils::containerSubType(objectType,"store_base_type"), mapping, contSchema ){
397 }
398 
400 }
401 
403  IRelationalData& relationalData,
404  RelationalBuffer& operationBuffer){
405  m_offset = &offset;
406  m_localElement.clear();
407  return m_updater.build( m_localElement, relationalData, operationBuffer );
408 }
409 
410 void ora::QueryableVectorUpdater::setRecordId( const std::vector<int>& identity ){
411  m_updater.setRecordId( identity );
412 }
413 
415  const void* data ){
416  if(!m_offset){
417  throwException("The streamer has not been built.",
418  "QueryableVectorUpdater::update");
419  }
420  void* vectorAddress = m_offset->address( data );
421  Reflex::Object vectorObj( m_objectType,const_cast<void*>(vectorAddress));
422  vectorObj.Invoke("load",0);
423  void* storageAddress = 0;
424  vectorObj.Invoke("storageAddress",storageAddress);
425  m_updater.update( oid, storageAddress );
426 }
427 
429  MappingElement& mapping,
430  ContainerSchema& contSchema ):
431  m_objectType(objectType),
432  m_mapping( mapping ),
433  m_schema( contSchema ),
434  m_dataElement( 0 ),
435  m_loaders(),
436  m_tmpIds(){
437 }
438 
440  for(std::vector<boost::shared_ptr<IVectorLoader> >::const_iterator iL = m_loaders.begin();
441  iL != m_loaders.end(); ++iL ){
442  (*iL)->invalidate();
443  }
444 }
445 
447  IRelationalData& ){
448  m_dataElement = &dataElement;
449  m_tmpIds.clear();
450  m_tmpIds.push_back(0);
451  return true;
452 }
453 
455  m_tmpIds[0] = oid;
456 }
457 
458 void ora::QueryableVectorReader::setRecordId( const std::vector<int>& identity ){
459  m_tmpIds.resize( 1+identity.size() );
460  for( size_t i=0;i<identity.size();i++){
461  m_tmpIds[1+i] = identity[i];
462  }
463 }
464 
465 void ora::QueryableVectorReader::read( void* destinationData ) {
466  if(!m_dataElement){
467  throwException("The streamer has not been built.",
468  "QueryableVectorReader::read");
469  }
470 
471  // finding the address (on the instance) where to install the loader
472  Reflex::Member loaderMember = m_objectType.DataMemberByName("m_loader");
473  if(!loaderMember){
474  throwException("The loader member has not been found.",
475  "QueryableVectorReader::read");
476  }
477  DataElement& loaderMemberElement = m_dataElement->addChild( loaderMember.Offset(), 0 );
478  void* loaderAddress = loaderMemberElement.address( destinationData );
479 
480  // creating and registering the new loader to assign
481  boost::shared_ptr<IVectorLoader> loader( new QueryableVectorLoader( m_objectType, m_mapping, m_schema, m_tmpIds ) );
482  m_loaders.push_back(loader);
483  // installing the loader
484  *(static_cast<boost::shared_ptr<IVectorLoader>*>( loaderAddress )) = loader;
485 }
486 
488 }
489 
490 
492  MappingElement& mapping,
493  ContainerSchema& contSchema ):
494  m_objectType( objectType ),
495  m_mapping( mapping ),
496  m_schema( contSchema ){
497 }
498 
500 }
501 
503  return new QueryableVectorWriter( m_objectType, m_mapping, m_schema );
504 }
505 
507  return new QueryableVectorUpdater( m_objectType, m_mapping, m_schema );
508 }
509 
511  return new QueryableVectorReader( m_objectType, m_mapping, m_schema );
512 }
int i
Definition: DBlmapReader.cc:9
QueryableVectorStreamer(const Reflex::Type &objectType, MappingElement &mapping, ContainerSchema &contSchema)
bool build(DataElement &offset, IRelationalData &relationalData)
void setQueryCondition(IRelationalData &queryData, const Selection &selection, MappingElement &mappingElement)
virtual coral::AttributeList & whereData()=0
char * address
Definition: mlp_lapack.h:14
size_t getSelectionCount(const Selection &selection) const
ContainerSchema & m_schema
IRelationalReader * newReader(const Reflex::Type &dataType, MappingElement &dataMapping)
void * address(const void *topLevelAddress) const
Definition: DataElement.cc:48
const coral::AttributeList & data() const
Definition: Selection.cc:118
bool load(void *address) const
void executeAndLoad(void *address)
static std::string variableNameFromUniqueString(const std::string &uniqueString)
Definition: Selection.cc:20
bool build(DataElement &offset, IRelationalData &relationalData, RelationalBuffer &operationBuffer)
selection
main part
Definition: corrVsCorr.py:98
QueryableVectorWriter(const Reflex::Type &objectType, MappingElement &mapping, ContainerSchema &contSchema)
Constructor.
DataElement & addChild(size_t declaringScopeOffset, Reflex::OffsetFunction offsetFunction)
Definition: DataElement.cc:26
void write(int oid, const void *data)
Writes a data element.
ElementType elementType() const
MappingElement & m_mappingElement
void setRecordId(const std::vector< int > &identity)
virtual std::string & whereClause()=0
void read(const std::vector< int > &fullId, void *destinationAddress)
Reflex::Type containerSubType(const Reflex::Type &typ, const std::string &subTypeName)
Definition: ClassUtils.cc:389
std::auto_ptr< IArrayHandler > m_arrayHandler
std::vector< int > m_recordId
std::vector< std::string > recordIdColumns() const
static IArrayHandler * newArrayHandler(const Reflex::Type &arrayType)
static std::string indexVariable()
Definition: Selection.cc:26
std::string posColumn() const
tuple result
Definition: query.py:137
static std::string elementTypeAsString(ElementType elementType)
Converts the enumeration type to a string.
QVQueryMaker(const Reflex::Type &objectType, MappingElement &mapping, ContainerSchema &contSchema)
size_t selectionCount(const std::vector< int > &fullId, const Selection &selection)
void update(int oid, const void *data)
Updates a data element.
bool loadSelection(const Selection &selection, void *address) const
iterator find(const std::string &key)
Retrieves a sub-element.
unsigned int offset(bool)
std::string pkColumn() const
std::map< std::string, MappingElement >::iterator iterator
Iterator definition.
const std::vector< std::string > & columnNames() const
Reflex::Type containerValueType(const Reflex::Type &typ)
Definition: ClassUtils.cc:341
void read(void *address)
Reads a data element.
std::auto_ptr< SelectOperation > m_query
Reflex::Type resolvedType(const Reflex::Type &typ)
Definition: ClassUtils.cc:404
QueryableVectorReader(const Reflex::Type &objectType, MappingElement &mapping, ContainerSchema &contSchema)
Constructor.
void setRecordId(const std::vector< int > &identity)
void read(void *address)
Reads a data element.
void setRecordId(const std::vector< int > &identity)
coral::ISchema & storageSchema()
void select(const std::vector< int > &fullId, const Selection &selection)
iterator end()
Returns an iterator in the end of the sequence.
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:82
void setRecordId(const std::vector< int > &identity)
const std::string & tableName() const
void throwException(const std::string &message, const std::string &methodName)
Definition: Exception.cc:10
const std::vector< std::pair< std::string, std::string > > & items() const
Definition: Selection.cc:113
std::auto_ptr< IRelationalReader > m_dataReader
void select(int oid)
QueryableVectorLoader(const Reflex::Type &objectType, MappingElement &mapping, ContainerSchema &contSchema, const std::vector< int > &fullId)
QueryableVectorUpdater(const Reflex::Type &objectType, MappingElement &mapping, ContainerSchema &contSchema)
Constructor.
bool build(DataElement &offset, IRelationalData &relationalData)
bool build(DataElement &offset, IRelationalData &relationalData, RelationalBuffer &operationBuffer)
QVReader(const Reflex::Type &objectType, MappingElement &mapping, ContainerSchema &contSchema)
tuple inputData
Definition: idDealer.py:72