Update contrib.
1 // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // SQL DML statements for Table framework
22 inline CSqlValues::TEntry::TEntry(const RSqlLiteral& aValue)
26 CSqlValues::CSqlValues()
27 :iValues(EGranularity)
30 CSqlValues::~CSqlValues()
32 // close all the literal objects
35 for (TInt ii=iValues.Count();--ii>=0;)
36 iValues[ii].iValue.Close();
40 void CSqlValues::AddL(const RSqlLiteral& aLiteral)
43 __DEBUG(e.iType=TDbColType(-1);)
44 __LEAVE_IF_ERROR(iValues.Append(e));
47 void CSqlValues::BindL(const CDbDataSource& aSource)
49 // Bind the values to a column set and optional column name list
52 iValues.Compress(); // we have finished adding values
53 TInt columns=iValues.Count();
55 if (aSource.ColumnCount()<columns)
56 __LEAVE(KErrArgument); // insert-statement is bad
57 for (TInt ii=0;ii<columns;++ii)
59 TEntry& e=iValues[ii];
60 __ASSERT(e.iType==-1);
61 e.iType=aSource.ColumnDef(ii+1).Type();
62 if (e.iValue.IsNull())
66 default: // cannot set this kind of column from SQL
97 case EDbColLongText16:
101 case EDbColLongBinary:
108 void CSqlValues::WriteL(CDbDataSource& aSource,CDbTable& aTable) const
110 // Set the row buffer with the values
113 __ASSERT(iValues.Count()>0);
114 CDbBlobSpace* blobstore=0;
115 TInt columns=iValues.Count();
116 for (TInt ii=0;ii<columns;++ii)
118 TDbColumn col(aSource.Column(ii+1));
119 const TEntry& e=iValues[ii];
120 if (TDbCol::IsLong(e.iType))
121 { // check if we need to delete a blob
123 blobstore=aTable.BlobsL();
125 const TDbBlob& blob=TDbColumnC(col).Blob();
126 if (!blob.IsInline())
127 blobstore->DeleteL(blob.Id());
129 if (e.iValue.IsNull())
142 col.SetL(e.iValue.Uint32());
147 col.SetL(e.iValue.Int32());
150 col.SetL(e.iValue.Int64());
153 col.SetL(e.iValue.Real32());
156 col.SetL(e.iValue.Real64());
159 col.SetL(e.iValue.Time());
162 col.SetL(e.iValue.Text8());
165 col.SetL(e.iValue.Text16());
167 case EDbColLongText8:
169 const TDesC8& val=e.iValue.Text8();
170 const TUint8* ptr=val.Ptr();
171 TInt size=val.Length();
172 if (size>blobstore->InlineLimit())
173 col.SetBlobL(blobstore->CreateL(EDbColLongText8,ptr,size),size);
175 col.SetBlobL(ptr,size);
178 case EDbColLongText16:
180 const TDesC16& val=e.iValue.Text16();
181 const TUint8* ptr=REINTERPRET_CAST(const TUint8*,val.Ptr());
182 TInt size=val.Length()<<1;
183 if (size>blobstore->InlineLimit())
184 col.SetBlobL(blobstore->CreateL(EDbColLongText16,ptr,size),size);
186 col.SetBlobL(ptr,size);
191 const TDesC8& val=e.iValue.Blob();
192 // const TUint8* ptr=REINTERPRET_CAST(const TUint8*,val.Ptr());
193 // TInt size=val.Length();
195 // col.SetBlobL(ptr,size);
198 case EDbColLongBinary:
200 const TDesC8& val=e.iValue.Blob();
201 const TUint8* ptr=REINTERPRET_CAST(const TUint8*,val.Ptr());
202 TInt size=val.Length();
203 col.SetBlobL(blobstore->CreateL(EDbColLongBinary,ptr,size),size);
210 // Class CSqlDMLStatement
212 CSqlDMLStatement::~CSqlDMLStatement()
217 CSqlValues& CSqlDMLStatement::ValuesL()
219 CSqlValues* v=iValues;
221 iValues=v=new(ELeave) CSqlValues;
225 // Class CSqlInsertStatement
227 CSqlInsertStatement* CSqlInsertStatement::NewLC()
229 CSqlInsertStatement* self=new(ELeave) CSqlInsertStatement;
230 CleanupStack::PushL(self);
234 CDbIncremental* CSqlInsertStatement::ExecuteL(CDbTableDatabase& aDatabase,TDbTextComparison aComparison,TInt& aRows)
236 // Execute an insert-statement. This does not requre incremental work, so return 0
239 aRows=1; // 1 row changed after insertion
240 CSqlQuery* query=&Query();
241 RDbAccessPlan plan(query,aComparison);
242 plan.BuildLC(aDatabase,RDbRowSet::EInsertOnly,TDbWindow());
243 CDbDataSource& src=plan.Source();
245 src.NewRowL(KDbNullRecordId);
246 RDbTransaction& t=plan.Table().Database().Transaction();
248 Values().WriteL(src,plan.Table());
249 src.PrepareToWriteRowL(src.EAppend);
250 src.WriteRowL(src.EAppend,src.ENoSynch);
252 CleanupStack::Pop(); // transaction complete
253 CleanupStack::PopAndDestroy(); // plan
254 return 0; // no incremental work to be done
257 // Class CDbIncrementalDML
259 CDbIncrementalDML* CDbIncrementalDML::NewL(CSqlModifyStatement& aStatement,CDbTableDatabase& aDatabase,TDbTextComparison aComparison)
261 CSqlQuery* query=&aStatement.Query();
262 RDbAccessPlan plan(query,aComparison);
263 plan.BuildLC(aDatabase,RDbRowSet::EUpdatable,TDbWindow());
264 CDbIncrementalDML* self=new(ELeave) CDbIncrementalDML(plan);
265 CleanupStack::PopAndDestroy(); // plan
266 if (aStatement.IsUpdate())
268 CleanupStack::PushL(self);
269 self->iValues=aStatement.AdoptValues();
270 self->iValues->BindL(*self->iSource);
271 CleanupStack::Pop(); // self
273 self->iSource->Reset();
274 self->Transaction().DMLBegin();
275 self->SetState(EEvaluating);
279 CDbIncrementalDML::~CDbIncrementalDML()
281 if (iState!=ECommitted && iState!=EInitialising)
282 Transaction().DMLRollback();
287 TBool CDbIncrementalDML::NextL(TInt& aRows)
289 __ASSERT(iState!=ECommitted);
295 TDbPosition next=EDbNext;
297 { // evaluate the data source
299 if (iSource->EvaluateL(work,iRecord,atrow))
302 return ETrue; // more to do
304 iRecord=KDbNullRecordId;
308 // iterate across the data source
313 Transaction().DMLBeginLC();
314 CDbDataSource::TDelete del=iSource->DeleteRowL(iRecord,CDbDataSource::ESynch);
315 Transaction().DMLCommitL();
316 CleanupStack::Pop(); // transaction complete
321 case CDbDataSource::EDeletedAtEnd:
322 Transaction().DMLTouch();
323 Transaction().DMLCommitL();
326 case CDbDataSource::EDeletedInLimbo:
328 case CDbDataSource::EDeletedAtNext:
338 switch (iSource->GotoL(work,next,iRecord))
342 case CDbDataSource::ESuccess:
349 iSource->ReadRowL(iRecord);
350 iValues->WriteL(*iSource,iTable);
351 iSource->PrepareToWriteRowL(CDbDataSource::EReplace);
352 Transaction().DMLBeginLC();
353 iSource->WriteRowL(CDbDataSource::EReplace,CDbDataSource::ESynch);
354 Transaction().DMLCommitL();
355 CleanupStack::Pop(); // transaction complete
359 case CDbDataSource::ESynchFailure:
362 case CDbDataSource::EExhausted:
366 case CDbDataSource::ENoRow:
367 // completed the operation!
368 Transaction().DMLTouch();
369 Transaction().DMLCommitL();
378 // Class CSqlModifyStatement
380 CSqlModifyStatement* CSqlModifyStatement::NewLC()
382 CSqlModifyStatement* self=new(ELeave) CSqlModifyStatement;
383 CleanupStack::PushL(self);
387 CDbIncremental* CSqlModifyStatement::ExecuteL(CDbTableDatabase& aDatabase,TDbTextComparison aComparison,TInt& aRows)
389 // Execute an update/delete-statement, returning the incremental object that does the work
392 aRows=0; // no rows affected initially
393 return CDbIncrementalDML::NewL(*this,aDatabase,aComparison);