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 ),
41 m_localElement.clear();
44 m_recordId.push_back(0);
50 const std::vector<std::string>& columns = m_mappingElement.columnNames();
51 if( !columns.size() ){
53 "STLContainerWriter::build");
55 for(
size_t i=0;
i<columns.size();
i++ ){
56 m_insertOperation->addId( columns[
i ] );
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" );
73 std::string keyName = keyType.Name();
76 if ( iMe == m_mappingElement.end() ) {
77 throwException(
"Item for \"" + keyName +
"\" not found in the mapping element",
78 "STLContainerWriter::build" );
81 m_keyWriter.reset( streamerFactory.
newWriter( keyResolvedType, iMe->second ) );
82 m_keyWriter->build( m_localElement, *m_insertOperation, operationBuffer );
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" );
96 std::string valueName = valueType.Name();
99 if ( iMe == m_mappingElement.end() ) {
100 throwException(
"Item for \"" + valueName +
"\" not found in the mapping element",
101 "STLContainerWriter::build" );
104 m_dataWriter.reset( streamerFactory.
newWriter( valueResolvedType, iMe->second ) );
105 m_dataWriter->build( m_localElement, *m_insertOperation, operationBuffer );
112 for(
size_t i=0;
i<identity.size();
i++) {
113 m_recordId.push_back( identity[
i] );
115 m_recordId.push_back( 0 );
123 "STLContainerWriter::write");
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");
132 const Reflex::Type& iteratorReturnType = m_arrayHandler->iteratorReturnType();
135 if ( m_associative ) keyType = m_objectType.TemplateArgumentAt(0);
136 Reflex::Member firstMember;
137 Reflex::Member secondMember;
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" );
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" );
153 void*
data = m_offset->address( inputData );
156 size_t containerSize = m_arrayHandler->size( data );
158 if ( containerSize == 0 )
return;
160 size_t startElementIndex = m_arrayHandler->startElementIndex( data );
161 std::auto_ptr<IArrayIteratorHandler> iteratorHandler( m_arrayHandler->iterate( data ) );
163 InsertCache& bulkInsert = m_insertOperation->setUp( containerSize-startElementIndex+1 );
165 for (
size_t iIndex = startElementIndex; iIndex < containerSize; ++iIndex ) {
167 m_recordId[m_recordId.size()-1] = iIndex;
168 coral::AttributeList& dataBuff = m_insertOperation->data();
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];
175 void* objectReference = iteratorHandler->object();
176 void* componentData = objectReference;
179 void* keyData =
static_cast< char*
>( objectReference ) + firstMember.Offset();
180 m_keyWriter->setRecordId( m_recordId );
181 m_keyWriter->write( oid, keyData );
183 componentData =
static_cast< char*
>( objectReference ) + secondMember.Offset();
185 m_dataWriter->setRecordId( m_recordId );
187 m_dataWriter->write( oid, componentData );
191 iteratorHandler->increment();
195 m_arrayHandler->finalize( const_cast<void*>( data ) );
202 m_deleter( mapping ),
203 m_writer( objectType, mapping, contSchema ){
212 m_deleter.build( operationBuffer );
213 m_writer.build( offset, relationalData, operationBuffer );
218 m_writer.setRecordId( identity );
223 m_deleter.erase( oid );
224 m_writer.write( oid, data );
230 m_objectType( objectType ),
231 m_mappingElement( mapping ),
232 m_schema( contSchema ),
247 m_localElement.clear();
250 m_recordId.push_back(0);
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 ] );
269 if ( m_associative ){
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" );
280 std::string keyName = keyType.Name();
283 if ( iMe == m_mappingElement.end() ) {
284 throwException(
"Item for \"" + keyName +
"\" not found in the mapping element",
285 "STLContainerReader::build" );
288 m_keyReader.reset( streamerFactory.
newReader( keyResolvedType, iMe->second ) );
289 m_keyReader->build( m_localElement, *m_query );
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" );
304 std::string valueName = valueType.Name();
307 if ( iMe == m_mappingElement.end() ) {
308 throwException(
"Item for \"" + valueName +
"\" not found in the mapping element",
309 "STLContainerReader::build" );
312 m_dataReader.reset( streamerFactory.
newReader( valueResolvedType, iMe->second ) );
313 m_dataReader->build( m_localElement, *m_query );
320 "STLContainerReader::read");
322 coral::AttributeList& whereData = m_query->whereData();
323 whereData[ m_mappingElement.pkColumn() ].data<
int>() = oid;
325 if(m_keyReader.get()) m_keyReader->select( oid );
326 m_dataReader->select( oid );
331 for(
size_t i=0;
i<identity.size();
i++) {
332 m_recordId.push_back( identity[
i] );
335 m_recordId.push_back( 0 );
342 "STLContainerReader::read");
345 void*
address = m_offset->address( destinationData );
347 const Reflex::Type& iteratorReturnType = m_arrayHandler->iteratorReturnType();
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" );
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" );
369 bool isElementFundamental = iteratorReturnType.IsFundamental();
371 m_arrayHandler->clear( address );
373 size_t cursorSize = m_query->selectionSize(m_recordId, m_recordId.size()-1);
375 while ( i< cursorSize ){
377 m_recordId[m_recordId.size()-1] = (int)i;
378 m_query->selectRow( m_recordId );
381 void* objectData = 0;
382 if(isElementFundamental){
383 objectData = &primitiveStub;
385 objectData = iteratorReturnType.Construct().Address();
388 void* componentData = objectData;
392 keyData =
static_cast< char*
>( objectData ) + firstMember.Offset();
393 m_keyReader->setRecordId( m_recordId );
394 m_keyReader->read( keyData );
396 componentData =
static_cast< char*
>( objectData ) + secondMember.Offset();
398 m_dataReader->setRecordId( m_recordId );
399 m_dataReader->read( componentData );
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 );
408 throwException(
"Could not insert a new element in the array type \"" +
409 m_objectType.Name(Reflex::SCOPED) +
"\"",
410 "STLContainerReader::read" );
415 m_arrayHandler->finalize( address );
420 if(m_query.get()) m_query->clear();
421 if(m_keyReader.get()) m_keyReader->clear();
422 if(m_dataReader.get()) m_dataReader->clear();
428 m_objectType( objectType ),
429 m_mapping( mapping ),
430 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()
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)
STLContainerUpdater(const Reflex::Type &objectType, MappingElement &mapping, ContainerSchema &contSchema)
Constructor.