15 #include "CoralBase/Attribute.h"
16 #include "RelationalAccess/IBulkOperation.h"
17 #include "Reflex/Member.h"
22 m_objectType( objectType ),
23 m_mappingElement( mapping ),
24 m_schema( contSchema ),
29 m_insertOperation( 0 ),
42 throwException(
"Missing dictionary information for the type of the container \"" +
43 m_objectType.Name(Reflex::SCOPED|Reflex::FINAL) +
"\"",
44 "STLContainerWriter::build" );
46 m_localElement.clear();
49 m_recordId.push_back(0);
55 const std::vector<std::string>& columns = m_mappingElement.columnNames();
56 if( !columns.size() ){
58 "STLContainerWriter::build");
60 for(
size_t i=0;
i<columns.size();
i++ ){
61 m_insertOperation->addId( columns[
i ] );
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" );
81 if ( iMe == m_mappingElement.end() ) {
82 throwException(
"Item for \"" + keyName +
"\" not found in the mapping element",
83 "STLContainerWriter::build" );
86 m_keyWriter.reset( streamerFactory.
newWriter( keyResolvedType, iMe->second ) );
87 m_keyWriter->build( m_localElement, *m_insertOperation, operationBuffer );
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" );
104 if ( iMe == m_mappingElement.end() ) {
105 throwException(
"Item for \"" + valueName +
"\" not found in the mapping element",
106 "STLContainerWriter::build" );
109 m_dataWriter.reset( streamerFactory.
newWriter( valueResolvedType, iMe->second ) );
110 m_dataWriter->build( m_localElement, *m_insertOperation, operationBuffer );
117 for(
size_t i=0;
i<identity.size();
i++) {
118 m_recordId.push_back( identity[
i] );
120 m_recordId.push_back( 0 );
128 "STLContainerWriter::write");
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");
137 const Reflex::Type& iteratorReturnType = m_arrayHandler->iteratorReturnType();
140 if ( m_associative ) keyType = m_objectType.TemplateArgumentAt(0);
141 Reflex::Member firstMember;
142 Reflex::Member secondMember;
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" );
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" );
158 void*
data = m_offset->address( inputData );
161 size_t containerSize = m_arrayHandler->size( data );
163 if ( containerSize == 0 )
return;
165 size_t startElementIndex = m_arrayHandler->startElementIndex( data );
166 std::auto_ptr<IArrayIteratorHandler> iteratorHandler( m_arrayHandler->iterate( data ) );
168 InsertCache& bulkInsert = m_insertOperation->setUp( containerSize-startElementIndex+1 );
170 for (
size_t iIndex = startElementIndex; iIndex < containerSize; ++iIndex ) {
172 m_recordId[m_recordId.size()-1] = iIndex;
173 coral::AttributeList& dataBuff = m_insertOperation->data();
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];
180 void* objectReference = iteratorHandler->object();
181 void* componentData = objectReference;
184 void* keyData =
static_cast< char*
>( objectReference ) + firstMember.Offset();
185 m_keyWriter->setRecordId( m_recordId );
186 m_keyWriter->write( oid, keyData );
188 componentData =
static_cast< char*
>( objectReference ) + secondMember.Offset();
190 m_dataWriter->setRecordId( m_recordId );
192 m_dataWriter->write( oid, componentData );
196 iteratorHandler->increment();
200 m_arrayHandler->finalize( const_cast<void*>( data ) );
207 m_deleter( mapping ),
208 m_writer( objectType, mapping, contSchema ){
217 m_deleter.build( operationBuffer );
218 m_writer.build( offset, relationalData, operationBuffer );
223 m_writer.setRecordId( identity );
228 m_deleter.erase( oid );
229 m_writer.write( oid, data );
235 m_objectType( objectType ),
236 m_mappingElement( mapping ),
237 m_schema( contSchema ),
252 m_localElement.clear();
255 m_recordId.push_back(0);
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 ] );
274 if ( m_associative ){
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" );
288 if ( iMe == m_mappingElement.end() ) {
289 throwException(
"Item for \"" + keyName +
"\" not found in the mapping element",
290 "STLContainerReader::build" );
293 m_keyReader.reset( streamerFactory.
newReader( keyResolvedType, iMe->second ) );
294 m_keyReader->build( m_localElement, *m_query );
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" );
312 if ( iMe == m_mappingElement.end() ) {
313 throwException(
"Item for \"" + valueName +
"\" not found in the mapping element",
314 "STLContainerReader::build" );
317 m_dataReader.reset( streamerFactory.
newReader( valueResolvedType, iMe->second ) );
318 m_dataReader->build( m_localElement, *m_query );
325 "STLContainerReader::read");
327 coral::AttributeList& whereData = m_query->whereData();
328 whereData[ m_mappingElement.pkColumn() ].data<
int>() = oid;
330 if(m_keyReader.get()) m_keyReader->select( oid );
331 m_dataReader->select( oid );
336 for(
size_t i=0;
i<identity.size();
i++) {
337 m_recordId.push_back( identity[
i] );
340 m_recordId.push_back( 0 );
347 "STLContainerReader::read");
350 void* address = m_offset->address( destinationData );
352 const Reflex::Type& iteratorReturnType = m_arrayHandler->iteratorReturnType();
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" );
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" );
374 bool isElementFundamental = iteratorReturnType.IsFundamental();
376 m_arrayHandler->clear( address );
378 size_t cursorSize = m_query->selectionSize(m_recordId, m_recordId.size()-1);
380 while ( i< cursorSize ){
382 m_recordId[m_recordId.size()-1] = (int)i;
383 m_query->selectRow( m_recordId );
386 void* objectData = 0;
387 if(isElementFundamental){
388 objectData = &primitiveStub;
390 objectData = iteratorReturnType.Construct().Address();
393 void* componentData = objectData;
397 keyData =
static_cast< char*
>( objectData ) + firstMember.Offset();
398 m_keyReader->setRecordId( m_recordId );
399 m_keyReader->read( keyData );
401 componentData =
static_cast< char*
>( objectData ) + secondMember.Offset();
403 m_dataReader->setRecordId( m_recordId );
404 m_dataReader->read( componentData );
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 );
413 throwException(
"Could not insert a new element in the array type \"" +
414 m_objectType.Name(Reflex::SCOPED) +
"\"",
415 "STLContainerReader::read" );
420 m_arrayHandler->finalize( address );
425 if(m_query.get()) m_query->clear();
426 if(m_keyReader.get()) m_keyReader->clear();
427 if(m_dataReader.get()) m_dataReader->clear();
433 m_objectType( objectType ),
434 m_mapping( mapping ),
435 m_schema( contSchema ){
IRelationalReader * newReader(const Reflex::Type &dataType, MappingElement &dataMapping)
bool isTypeAssociativeContainer(const Reflex::Type &typ)
bool build(DataElement &offset, IRelationalData &relationalData, RelationalBuffer &operationBuffer)
virtual ~STLContainerWriter()
virtual ~STLContainerUpdater()
STLContainerStreamer(const Reflex::Type &objectType, MappingElement &mapping, ContainerSchema &contSchema)
void setRecordId(const std::vector< int > &identity)
IRelationalReader * newReader()
virtual ~STLContainerReader()
Reflex::Type containerDataType(const Reflex::Type &typ)
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 processNextIteration()
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)
Reflex::Type containerValueType(const Reflex::Type &typ)
MultiRecordInsertOperation & newMultiRecordInsert(const std::string &tableName)
STLContainerReader(const Reflex::Type &objectType, MappingElement &mapping, ContainerSchema &contSchema)
Constructor.
Reflex::Type resolvedType(const Reflex::Type &typ)
IRelationalWriter * newWriter(const Reflex::Type &dataType, MappingElement &dataMapping)
void update(int oid, const void *data)
Updates a data element.
IRelationalWriter * newWriter()
void throwException(const std::string &message, const std::string &methodName) __attribute__((noreturn))
bool build(DataElement &offset, IRelationalData &relationalData)
char data[epos_bytes_allocation]
STLContainerWriter(const Reflex::Type &objectType, MappingElement &mapping, ContainerSchema &contSchema)
Constructor.
IRelationalUpdater * newUpdater()
STLContainerUpdater(const Reflex::Type &objectType, MappingElement &mapping, ContainerSchema &contSchema)
Constructor.