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:
104 void CSqlValues::WriteL(CDbDataSource& aSource,CDbTable& aTable) const
106 // Set the row buffer with the values
109 __ASSERT(iValues.Count()>0);
110 CDbBlobSpace* blobstore=0;
111 TInt columns=iValues.Count();
112 for (TInt ii=0;ii<columns;++ii)
114 TDbColumn col(aSource.Column(ii+1));
115 const TEntry& e=iValues[ii];
116 if (TDbCol::IsLong(e.iType))
117 { // check if we need to delete a blob
119 blobstore=aTable.BlobsL();
121 const TDbBlob& blob=TDbColumnC(col).Blob();
122 if (!blob.IsInline())
123 blobstore->DeleteL(blob.Id());
125 if (e.iValue.IsNull())
138 col.SetL(e.iValue.Uint32());
143 col.SetL(e.iValue.Int32());
146 col.SetL(e.iValue.Int64());
149 col.SetL(e.iValue.Real32());
152 col.SetL(e.iValue.Real64());
155 col.SetL(e.iValue.Time());
158 col.SetL(e.iValue.Text8());
161 col.SetL(e.iValue.Text16());
163 case EDbColLongText8:
165 const TDesC8& val=e.iValue.Text8();
166 const TUint8* ptr=val.Ptr();
167 TInt size=val.Length();
168 if (size>blobstore->InlineLimit())
169 col.SetBlobL(blobstore->CreateL(EDbColLongText8,ptr,size),size);
171 col.SetBlobL(ptr,size);
174 case EDbColLongText16:
176 const TDesC16& val=e.iValue.Text16();
177 const TUint8* ptr=REINTERPRET_CAST(const TUint8*,val.Ptr());
178 TInt size=val.Length()<<1;
179 if (size>blobstore->InlineLimit())
180 col.SetBlobL(blobstore->CreateL(EDbColLongText16,ptr,size),size);
182 col.SetBlobL(ptr,size);
189 // Class CSqlDMLStatement
191 CSqlDMLStatement::~CSqlDMLStatement()
196 CSqlValues& CSqlDMLStatement::ValuesL()
198 CSqlValues* v=iValues;
200 iValues=v=new(ELeave) CSqlValues;
204 // Class CSqlInsertStatement
206 CSqlInsertStatement* CSqlInsertStatement::NewLC()
208 CSqlInsertStatement* self=new(ELeave) CSqlInsertStatement;
209 CleanupStack::PushL(self);
213 CDbIncremental* CSqlInsertStatement::ExecuteL(CDbTableDatabase& aDatabase,TDbTextComparison aComparison,TInt& aRows)
215 // Execute an insert-statement. This does not requre incremental work, so return 0
218 aRows=1; // 1 row changed after insertion
219 CSqlQuery* query=&Query();
220 RDbAccessPlan plan(query,aComparison);
221 plan.BuildLC(aDatabase,RDbRowSet::EInsertOnly,TDbWindow());
222 CDbDataSource& src=plan.Source();
224 src.NewRowL(KDbNullRecordId);
225 RDbTransaction& t=plan.Table().Database().Transaction();
227 Values().WriteL(src,plan.Table());
228 src.PrepareToWriteRowL(src.EAppend);
229 src.WriteRowL(src.EAppend,src.ENoSynch);
231 CleanupStack::Pop(); // transaction complete
232 CleanupStack::PopAndDestroy(); // plan
233 return 0; // no incremental work to be done
236 // Class CDbIncrementalDML
238 CDbIncrementalDML* CDbIncrementalDML::NewL(CSqlModifyStatement& aStatement,CDbTableDatabase& aDatabase,TDbTextComparison aComparison)
240 CSqlQuery* query=&aStatement.Query();
241 RDbAccessPlan plan(query,aComparison);
242 plan.BuildLC(aDatabase,RDbRowSet::EUpdatable,TDbWindow());
243 CDbIncrementalDML* self=new(ELeave) CDbIncrementalDML(plan);
244 CleanupStack::PopAndDestroy(); // plan
245 if (aStatement.IsUpdate())
247 CleanupStack::PushL(self);
248 self->iValues=aStatement.AdoptValues();
249 self->iValues->BindL(*self->iSource);
250 CleanupStack::Pop(); // self
252 self->iSource->Reset();
253 self->Transaction().DMLBegin();
254 self->SetState(EEvaluating);
258 CDbIncrementalDML::~CDbIncrementalDML()
260 if (iState!=ECommitted && iState!=EInitialising)
261 Transaction().DMLRollback();
266 TBool CDbIncrementalDML::NextL(TInt& aRows)
268 __ASSERT(iState!=ECommitted);
274 TDbPosition next=EDbNext;
276 { // evaluate the data source
278 if (iSource->EvaluateL(work,iRecord,atrow))
281 return ETrue; // more to do
283 iRecord=KDbNullRecordId;
287 // iterate across the data source
292 Transaction().DMLBeginLC();
293 CDbDataSource::TDelete del=iSource->DeleteRowL(iRecord,CDbDataSource::ESynch);
294 Transaction().DMLCommitL();
295 CleanupStack::Pop(); // transaction complete
300 case CDbDataSource::EDeletedAtEnd:
301 Transaction().DMLTouch();
302 Transaction().DMLCommitL();
305 case CDbDataSource::EDeletedInLimbo:
307 // coverity[fallthrough]
308 case CDbDataSource::EDeletedAtNext:
318 switch (iSource->GotoL(work,next,iRecord))
322 case CDbDataSource::ESuccess:
329 iSource->ReadRowL(iRecord);
330 iValues->WriteL(*iSource,iTable);
331 iSource->PrepareToWriteRowL(CDbDataSource::EReplace);
332 Transaction().DMLBeginLC();
333 iSource->WriteRowL(CDbDataSource::EReplace,CDbDataSource::ESynch);
334 Transaction().DMLCommitL();
335 CleanupStack::Pop(); // transaction complete
339 case CDbDataSource::ESynchFailure:
342 case CDbDataSource::EExhausted:
346 case CDbDataSource::ENoRow:
347 // completed the operation!
348 Transaction().DMLTouch();
349 Transaction().DMLCommitL();
358 // Class CSqlModifyStatement
360 CSqlModifyStatement* CSqlModifyStatement::NewLC()
362 CSqlModifyStatement* self=new(ELeave) CSqlModifyStatement;
363 CleanupStack::PushL(self);
367 CDbIncremental* CSqlModifyStatement::ExecuteL(CDbTableDatabase& aDatabase,TDbTextComparison aComparison,TInt& aRows)
369 // Execute an update/delete-statement, returning the incremental object that does the work
372 aRows=0; // no rows affected initially
373 return CDbIncrementalDML::NewL(*this,aDatabase,aComparison);