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"
18 #include "CoralBase/Attribute.h"
19 
20 namespace ora {
21 
22  class QVReader {
23  public:
24  QVReader( const edm::TypeWithDict& 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 edm::TypeWithDict& 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  edm::TypeWithDict 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.cppName() + "\"",
87  "QVQueryMaker::build" );
88  }
89 
90  m_arrayHandler.reset( ArrayHandlerFactory::newArrayHandler( storeBaseType ) );
91 
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  "QVQueryMaker::build" );
99  }
100  // Retrieve the relevant mapping element
101  MappingElement::iterator iMe = m_mappingElement.find( "value_type" );
102  if ( iMe == m_mappingElement.end() ) {
103  throwException( "Item for \"value_type\" not found in the mapping element",
104  "QVQueryMaker::build" );
105  }
106 
107  m_dataReader.reset( streamerFactory.newReader( valueResolvedType, iMe->second ) );
108  m_dataReader->build( m_localElement, *m_query );
109  return true;
110  }
111 
112  void setQueryCondition( IRelationalData& queryData, const Selection& selection, MappingElement& mappingElement ){
113  coral::AttributeList& whereData = queryData.whereData();
114  // adding the selection conditions
115  const std::vector<std::pair<std::string,std::string> >& theItems = selection.items();
116  std::stringstream cond;
117  unsigned int i=0;
118  for(std::vector<std::pair<std::string,std::string> >::const_iterator iItem = theItems.begin();
119  iItem != theItems.end();
120  ++iItem){
121  cond << " AND ";
123  std::stringstream selColumn;
124  std::string colName("");
125  if(varName == Selection::indexVariable()){
126  colName = mappingElement.columnNames()[mappingElement.columnNames().size()-1]; // the position column is the last
127  selColumn << colName<<"_"<<i;
128  whereData.extend<int>(selColumn.str());
129  whereData[selColumn.str()].data<int>() = selection.data()[iItem->first].data<int>();
130  } else {
131  MappingElement::iterator iElem = mappingElement.find("value_type");
132  if ( iElem == mappingElement.end() ) {
133  throwException( "Item for element \"value_type\" not found in the mapping element",
134  "QVQueryMaker::setQueryCondition" );
135  }
136  MappingElement& valueTypeElement = iElem->second;
137  if( valueTypeElement.elementType()==MappingElement::Primitive ){
138  if(varName!="value_type"){
139  throwException( "Item for element \"" + varName + "\" not found in the mapping element",
140  "QVQueryMaker::setQueryCondition" );
141  }
142  colName = valueTypeElement.columnNames()[0];
143  } else if( valueTypeElement.elementType()==MappingElement::Object ){
144  MappingElement::iterator iInnerElem = valueTypeElement.find(varName);
145  if ( iInnerElem == valueTypeElement.end() ) {
146  throwException( "Item for element \"" + varName + "\" not found in the mapping element",
147  "QVQueryMaker::setQueryCondition" );
148  }
149  colName = iInnerElem->second.columnNames()[0];
150  } else {
151  throwException( "Queries cannot be executed on types mapped on "+
153  "QVQueryMaker::setQueryCondition" );
154  }
155  selColumn << colName<<"_"<<i;
156  whereData.extend(selColumn.str(),selection.data()[iItem->first].specification().type());
157  whereData[selColumn.str()].setValueFromAddress(selection.data()[iItem->first].addressOfData());
158  }
159  cond << colName << " " << iItem->second << " :"<<selColumn.str();
160  i++;
161  selColumn.str("");
162  }
163 
164  // add the resulting condition clause
165  queryData.whereClause()+=cond.str();
166  }
167 
168  void select( const std::vector<int>& fullId, const Selection& selection ){
169  if(!m_query.get()){
170  throwException("The reader has not been built.",
171  "QVReader::select");
172  }
173 
174  m_oid = fullId[0];
175  m_recordId.clear();
176  for(size_t i=1;i<fullId.size();i++) {
177  m_recordId.push_back( fullId[i] );
178  }
179  // allocate the element for the index...
180  m_recordId.push_back( 0 );
181 
182  coral::AttributeList& whereData = m_query->whereData();
183  whereData[ m_mappingElement.pkColumn() ].data<int>() = fullId[0];
184 
186 
187  m_query->execute();
188  }
189 
190  size_t selectionCount( const std::vector<int>& fullId, const Selection& selection ){
192  std::string countColumn("COUNT(*)");
193  countQuery.addData( countColumn ,typeid(int) );
194  countQuery.addWhereId( m_mappingElement.pkColumn() );
195  std::vector<std::string> recIdColumns = m_mappingElement.recordIdColumns();
196  for( size_t i=0;i<recIdColumns.size();i++){
197  countQuery.addWhereId( recIdColumns[i] );
198  }
199 
200  coral::AttributeList& whereData = countQuery.whereData();
201  // Fill-in the identities.
202  whereData[ m_mappingElement.pkColumn() ].data<int>() = fullId[0];
203  for ( size_t i=0;i<fullId.size();i++ ){
204  whereData[ recIdColumns[i] ].data<int>() = fullId[i+1];
205  }
206 
207  setQueryCondition( countQuery, selection, m_mappingElement );
208  countQuery.execute();
209 
210  size_t result = 0;
211  if( countQuery.nextCursorRow() ){
212  coral::AttributeList& row = countQuery.data();
213  result = row[countColumn].data<int>();
214  }
215  return result;
216  }
217 
218  void executeAndLoad(void* address){
219 
220  if(!m_query.get()){
221  throwException("The reader has not been built.",
222  "QVReader::read");
223  }
224  edm::TypeWithDict iteratorDereferenceReturnType = m_arrayHandler->iteratorReturnType();
225  edm::MemberWithDict firstMember = iteratorDereferenceReturnType.dataMemberByName( "first" );
226  if ( ! firstMember ) {
227  throwException( "Could not retrieve the data member \"first\" of the class \"" +
228  iteratorDereferenceReturnType.cppName() + "\"",
229  "QVQueryMakerAndLoad::read" );
230  }
231  edm::MemberWithDict secondMember = iteratorDereferenceReturnType.dataMemberByName( "second" );
232  if ( ! secondMember ) {
233  throwException( "Could not retrieve the data member \"second\" of the class \"" +
234  iteratorDereferenceReturnType.cppName() + "\"",
235  "QVQueryMakerAndLoad::read" );
236  }
237 
238  m_arrayHandler->clear( address );
239 
240  unsigned int i=0;
241  while ( m_query->nextCursorRow() ){
242 
243  // Create a new element for the array
244  void* objectData = iteratorDereferenceReturnType.construct().address();
245  void* positionData = static_cast< char* >( objectData ) + firstMember.offset();
246  void* containerData = static_cast< char* >( objectData ) + secondMember.offset();
247 
248  m_recordId[m_recordId.size()-1] = (int)i;
249  coral::AttributeList& row = m_query->data();
250 
251  *(size_t*)positionData = (size_t)(row[m_mappingElement.posColumn()].data<int>());
252 
253  m_dataReader->setRecordId( m_recordId );
254  m_dataReader->select( m_oid );
255  m_dataReader->read( containerData );
256 
257  size_t prevSize = m_arrayHandler->size( address );
258  m_arrayHandler->appendNewElement( address, objectData );
259  bool inserted = m_arrayHandler->size( address )>prevSize;
260 
261  iteratorDereferenceReturnType.destruct( objectData );
262  if ( !inserted ) {
263  throwException( "Could not insert a new element in the array type \"" +
264  m_objectType.cppName() + "\"",
265  "QVQueryMakerAndLoad::executeAndLoad" );
266  }
267  ++i;
268  }
269 
270  m_arrayHandler->finalize( address );
271  m_query->clear();
272  }
273 
274  private:
278  std::vector<int> m_recordId;
280  std::auto_ptr<SelectOperation> m_query;
281  std::auto_ptr<IArrayHandler> m_arrayHandler;
282  std::auto_ptr<IRelationalReader> m_dataReader;
283  int m_oid;
284  };
285 
287 
288  public:
289 
290  // constructor
291  QueryableVectorLoader( const edm::TypeWithDict& objectType, MappingElement& mapping, ContainerSchema& contSchema,
292  const std::vector<int>& fullId ):
293  m_isValid(true),
294  m_reader( objectType, mapping, contSchema ),
295  m_queryMaker( objectType, mapping, contSchema ),
296  m_identity(fullId){
297  }
298 
299  // destructor
301  }
302 
303  public:
304 
305  // triggers the data loading
306  bool load(void* address) const override {
307  bool ret = false;
308  if(m_isValid) {
309  m_reader.read( m_identity, address );
310  ret = true;
311  }
312  return ret;
313  }
314 
315  bool loadSelection(const Selection& selection, void* address) const override {
316  bool ret = false;
317  if(m_isValid) {
319  m_queryMaker.select( m_identity, selection );
320  m_queryMaker.executeAndLoad( address );
321  ret = true;
322  }
323  return ret;
324  }
325 
326  size_t getSelectionCount( const Selection& selection ) const override {
327  size_t ret = 0;
328  if(m_isValid) {
329  ret = m_queryMaker.selectionCount( m_identity, selection );
330  }
331  return ret;
332  }
333 
334  void invalidate() override{
335  m_isValid = false;
336  }
337 
338  bool isValid() const override{
339  return m_isValid;
340  }
341 
342  private:
343  bool m_isValid;
346  std::vector<int> m_identity;
347  };
348 
349 }
350 
352  MappingElement& mapping,
353  ContainerSchema& contSchema ):
354  m_objectType( objectType ),
355  m_offset( 0 ),
356  m_localElement(),
357  m_writer(ClassUtils::containerSubType(objectType,"store_base_type"), mapping, contSchema ){
358 }
359 
361 }
362 
365  RelationalBuffer& operationBuffer ){
366  m_offset = &offset;
367  m_localElement.clear();
368  return m_writer.build( m_localElement, data, operationBuffer );
369 }
370 
371 void ora::QueryableVectorWriter::setRecordId( const std::vector<int>& identity ){
372  m_writer.setRecordId( identity );
373 }
374 
376  const void* inputData ){
377  if(!m_offset){
378  throwException("The streamer has not been built.",
379  "QueryableVectorWriter::write");
380  }
381  void* vectorAddress = m_offset->address( inputData );
382  edm::ObjectWithDict vectorObj( m_objectType, const_cast<void*>(vectorAddress) );
383  m_objectType.functionMemberByName("load").invoke(vectorObj,nullptr);
384  void* storageAddress = nullptr;
385  edm::ObjectWithDict storAddObj = edm::ObjectWithDict( edm::TypeWithDict(typeid(void*)), &storageAddress );
386  m_objectType.functionMemberByName("storageAddress").invoke(vectorObj, &storAddObj);
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  edm::ObjectWithDict vectorObj( m_objectType,const_cast<void*>(vectorAddress));
422  m_objectType.functionMemberByName("load").invoke(vectorObj, nullptr);
423  void* storageAddress = nullptr;
424  edm::ObjectWithDict storAddObj = edm::ObjectWithDict( edm::TypeWithDict(typeid(void*)), &storageAddress );
425  m_objectType.functionMemberByName("storageAddress").invoke(vectorObj, &storAddObj);
426  m_updater.update( oid, storageAddress );
427 }
428 
430  MappingElement& mapping,
431  ContainerSchema& contSchema ):
432  m_objectType(objectType),
433  m_mapping( mapping ),
434  m_schema( contSchema ),
435  m_dataElement( 0 ),
436  m_loaders(),
437  m_tmpIds(){
438 }
439 
441  for(std::vector<boost::shared_ptr<IVectorLoader> >::const_iterator iL = m_loaders.begin();
442  iL != m_loaders.end(); ++iL ){
443  (*iL)->invalidate();
444  }
445 }
446 
448  IRelationalData& ){
449  m_dataElement = &dataElement;
450  m_tmpIds.clear();
451  m_tmpIds.push_back(0);
452  return true;
453 }
454 
456  m_tmpIds[0] = oid;
457 }
458 
459 void ora::QueryableVectorReader::setRecordId( const std::vector<int>& identity ){
460  m_tmpIds.resize( 1+identity.size() );
461  for( size_t i=0;i<identity.size();i++){
462  m_tmpIds[1+i] = identity[i];
463  }
464 }
465 
466 void ora::QueryableVectorReader::read( void* destinationData ) {
467  if(!m_dataElement){
468  throwException("The streamer has not been built.",
469  "QueryableVectorReader::read");
470  }
471 
472  // finding the address (on the instance) where to install the loader
473  edm::MemberWithDict loaderMember = m_objectType.dataMemberByName("m_loader");
474  if(!loaderMember){
475  throwException("The loader member has not been found.",
476  "QueryableVectorReader::read");
477  }
478  DataElement& loaderMemberElement = m_dataElement->addChild( loaderMember.offset(), 0 );
479  void* loaderAddress = loaderMemberElement.address( destinationData );
480 
481  // creating and registering the new loader to assign
482  boost::shared_ptr<IVectorLoader> loader( new QueryableVectorLoader( m_objectType, m_mapping, m_schema, m_tmpIds ) );
483  m_loaders.push_back(loader);
484  // installing the loader
485  *(static_cast<boost::shared_ptr<IVectorLoader>*>( loaderAddress )) = loader;
486 }
487 
489 }
490 
491 
493  MappingElement& mapping,
494  ContainerSchema& contSchema ):
495  m_objectType( objectType ),
496  m_mapping( mapping ),
497  m_schema( contSchema ){
498 }
499 
501 }
502 
504  return new QueryableVectorWriter( m_objectType, m_mapping, m_schema );
505 }
506 
508  return new QueryableVectorUpdater( m_objectType, m_mapping, m_schema );
509 }
510 
512  return new QueryableVectorReader( m_objectType, m_mapping, m_schema );
513 }
int i
Definition: DBlmapReader.cc:9
bool build(DataElement &offset, IRelationalData &relationalData)
void setQueryCondition(IRelationalData &queryData, const Selection &selection, MappingElement &mappingElement)
virtual coral::AttributeList & whereData()=0
edm::TypeWithDict resolvedType(const edm::TypeWithDict &typ)
Definition: ClassUtils.cc:486
ContainerSchema & m_schema
size_t getSelectionCount(const Selection &selection) const override
void * address() const
void * address(const void *topLevelAddress) const
Definition: DataElement.cc:49
const coral::AttributeList & data() const
Definition: Selection.cc:112
QueryableVectorUpdater(const edm::TypeWithDict &objectType, MappingElement &mapping, ContainerSchema &contSchema)
Constructor.
void executeAndLoad(void *address)
bool load(void *address) const override
size_t offset() const
static std::string variableNameFromUniqueString(const std::string &uniqueString)
Definition: Selection.cc:14
QueryableVectorLoader(const edm::TypeWithDict &objectType, MappingElement &mapping, ContainerSchema &contSchema, const std::vector< int > &fullId)
bool build(DataElement &offset, IRelationalData &relationalData, RelationalBuffer &operationBuffer)
selection
main part
Definition: corrVsCorr.py:98
void write(int oid, const void *data)
Writes a data element.
ElementType elementType() const
MappingElement & m_mappingElement
void setRecordId(const std::vector< int > &identity)
MemberWithDict dataMemberByName(std::string const &) const
virtual std::string & whereClause()=0
void read(const std::vector< int > &fullId, void *destinationAddress)
std::string cppName() const
std::auto_ptr< IArrayHandler > m_arrayHandler
std::vector< int > m_recordId
std::vector< std::string > recordIdColumns() const
edm::TypeWithDict containerSubType(const edm::TypeWithDict &typ, const std::string &subTypeName)
Definition: ClassUtils.cc:468
static std::string indexVariable()
Definition: Selection.cc:20
std::string posColumn() const
tuple result
Definition: query.py:137
static std::string elementTypeAsString(ElementType elementType)
Converts the enumeration type to a string.
static IArrayHandler * newArrayHandler(const edm::TypeWithDict &arrayType)
QVQueryMaker(const edm::TypeWithDict &objectType, MappingElement &mapping, ContainerSchema &contSchema)
size_t selectionCount(const std::vector< int > &fullId, const Selection &selection)
edm::TypeWithDict m_objectType
void update(int oid, const void *data)
Updates a data element.
iterator find(const std::string &key)
Retrieves a sub-element.
std::string pkColumn() const
std::map< std::string, MappingElement >::iterator iterator
Iterator definition.
QVReader(const edm::TypeWithDict &objectType, MappingElement &mapping, ContainerSchema &contSchema)
const std::vector< std::string > & columnNames() const
DataElement & addChild(size_t declaringScopeOffset, size_toffset)
Definition: DataElement.cc:27
void read(void *address)
Reads a data element.
edm::TypeWithDict m_objectType
std::auto_ptr< SelectOperation > m_query
void setRecordId(const std::vector< int > &identity)
bool loadSelection(const Selection &selection, void *address) const override
IRelationalReader * newReader(const edm::TypeWithDict &dataType, MappingElement &dataMapping)
void read(void *address)
Reads a data element.
void setRecordId(const std::vector< int > &identity)
void destruct(void *address, bool dealloc=true) const
QueryableVectorWriter(const edm::TypeWithDict &objectType, MappingElement &mapping, ContainerSchema &contSchema)
Constructor.
QueryableVectorStreamer(const edm::TypeWithDict &objectType, MappingElement &mapping, ContainerSchema &contSchema)
coral::ISchema & storageSchema()
void throwException(const std::string &message, const std::string &methodName) __attribute__((noreturn))
Definition: Exception.cc:10
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
edm::TypeWithDict containerValueType(const edm::TypeWithDict &typ)
Definition: ClassUtils.cc:410
void setRecordId(const std::vector< int > &identity)
const std::string & tableName() const
ObjectWithDict construct() const
const std::vector< std::pair< std::string, std::string > > & items() const
Definition: Selection.cc:107
QueryableVectorReader(const edm::TypeWithDict &objectType, MappingElement &mapping, ContainerSchema &contSchema)
Constructor.
std::auto_ptr< IRelationalReader > m_dataReader
void select(int oid)
bool build(DataElement &offset, IRelationalData &relationalData)
bool build(DataElement &offset, IRelationalData &relationalData, RelationalBuffer &operationBuffer)
tuple inputData
Definition: idDealer.py:72