📄 lb_dbase.cpp
字号:
delete aParent; // CLose file allowing auto compaction
for (TInt ii = 0; ii<count; ii++)
{
if (iOplDb[ii]==aParent)
{
iOplDb.Delete(ii);
break;
}
}
if (aRuntime.UserFlags() & KOplStateAutoCompact)
aRuntime.DbManager()->CompactL(file);
}
}
EXPORT_C void CLogicalNames::AddRowSet(TInt aLogName, COplRowSet* anOplRowSet)
{
iLogNames[aLogName]=anOplRowSet;
iCount+=1;
}
EXPORT_C COplDb* COplDbCollection::FindOpenDbase(const TDesC &aName,const TBool aIncAccessCount)
{
TInt count;
TInt ii;
count = iOplDb.Count();
TFileName upper(aName);
upper.UpperCase();
for (ii = 0; ii<count; ii++)
{
if (((iOplDb)[ii])->Name()==upper)
{
if(aIncAccessCount)
(iOplDb[ii]->AccessCount()++);
return (iOplDb)[ii];
}
}
return(NULL);
}
EXPORT_C COplDb* COplDbCollection::CreateOrOpenDbaseL(const TDesC &aName,const TOplDbOpenMode aMode,const TBool aUpdate)
{
COplDb *db;
RFs &fs=TheRuntime()->ConEnv()->FsSession();
if ((db=FindOpenDbase(aName,ETrue))==NULL)
{
TFileName upper(aName);
upper.UpperCase();
db=COplDb::NewLC(upper);
iOplDb.AppendL(db);
TRAPD(err,db->OpenL(fs,aName,aUpdate));
if((aMode==EDbCreate) && err==KErrNotFound)
{
TRAP(err,db->CreateL(fs,aName));
if (err)
fs.Delete(aName);
}
if (err)
{
iOplDb.Delete(iOplDb.Count()-1);
User::Leave(err);
}
db->AccessCount()=1;
CleanupStack::Pop(); // db
}
return db;
}
void COplDb::CreateL(RFs& aFs,const TDesC& aDbaseName)
{
iStore=CPermanentFileStore::CreateL(aFs,aDbaseName,EFileRead|EFileWrite);
COplRuntime* rt=TheRuntime();
// Make it an apparch document only if name matches the SETDOC name$ setting
TUidType uids(KPermanentFileStoreLayoutUid,KUidExternalOplFile); //default to no doc
if (rt->CurrentDocumentName().CompareF(aDbaseName)==0)
uids=TUidType(KPermanentFileStoreLayoutUid,KUidOplDoc,rt->CommandLine().AppUid());
iStore->SetTypeL(uids);
// Write the root stream
TOplDocRootStream shellData;
shellData.iStreamId=iDbase.CreateL(iStore);
shellData.iAppUid=KUidOplInterpreter;
RStoreWriteStream root;
TStreamId rootId=root.CreateLC(*iStore);
root<<shellData;
root.CommitL(); // root stream
CleanupStack::PopAndDestroy(); // root
iStore->SetRootL(rootId);
iStore->CommitL();
}
void COplDb::OpenL(RFs& aFs,const TDesC& aDbaseName,const TBool aUpdate)
{
TUidType type(KPermanentFileStoreLayoutUid,KUidAppDllDoc,KUidDataApp);
TEntry entry;
aFs.Entry(aDbaseName,entry);
if (entry.iType.MostDerived()==type.MostDerived())
//data model
{
iStore=CFileStore::OpenL(aFs,aDbaseName,EFileRead); // READ ONLY FOR
// iDaModel=CDaModel::NewL(*iStore);
iDataApp=ETrue;
// iDaModel->OpenDatabaseL(iDbase,*iStore);
CStreamDictionary* streamDic = CStreamDictionary::NewLC();
RStoreReadStream inStream;
inStream.OpenLC(*iStore,iStore->Root());
inStream >> *streamDic;
CleanupStack::PopAndDestroy(); // stream
TStreamId dataHeadStreamId;
dataHeadStreamId = streamDic->At(KUidDataHeadStream);
CleanupStack::PopAndDestroy(); // streamDic
inStream.OpenLC(*iStore, dataHeadStreamId);
TStreamId dbStreamId;
inStream >> dbStreamId;
CleanupStack::PopAndDestroy(); // stream
iDbase.OpenL(iStore,dbStreamId);
}
else
{
iStore=CFileStore::OpenL(aFs,aDbaseName,aUpdate?EFileRead|EFileWrite:EFileRead); // file closed on error
RStoreReadStream inStream;
inStream.OpenLC(*iStore,iStore->Root());
TOplDocRootStream shellData;
inStream>>shellData;
CleanupStack::PopAndDestroy(); // inStream
iDbase.OpenL(iStore,shellData.iStreamId);
iDataApp=EFalse;
}
}
EXPORT_C void COplDb::Close()
{
if (iStore)
iDbase.Close();
}
EXPORT_C TInt COplDb::CreateTable(const TDesC& aTableName,const CDbColSet& aColSet)
{
return (iDbase.CreateTable(aTableName,aColSet));
}
EXPORT_C void COplDbManager::GenerateSQL(TInt aFirstString, TInt aNoOfStrings,const TDesC& aString,TDes& aSQL)
// Generate where clause
{
aSQL.Zero();
TInt ff(0);
TInt numberOfFields=((iCurrOplRowSet->AccessMap())->GetNoOfFields());
for(TInt jj=0;jj<aFirstString;jj++)
{
if (jj>0) // takes us to first string field (or 2nd) =ff
ff++;
while ((iCurrOplRowSet->AccessMap())->ReadType(ff)!=EDbColText)
ff++;
}
for(TInt ii=0;ii<aNoOfStrings;ii++)
{
if (ii>0)
{
aSQL.Append(KOr);
ff++;
}
while ((iCurrOplRowSet->AccessMap())->ReadType(ff)!=EDbColText)
{
ff++;
if (ff>=numberOfFields)
User::Leave(KOplErrSyntax);
}
aSQL.Append(((*iCurrOplRowSet->AccessColSet())[ff+1]).iName);
aSQL.Append(KLikeQuote);
aSQL.Append(aString);
aSQL.Append('\'');
}
}
CBufFlat* COplDbManager::GenerateSQLBufLC(TInt aFirstString, TInt aNoOfStrings,const TDesC& aString)
// Generate WHERE clause in dynamic buffer
// New function added to fix bug SW1-397 : FIND and FINDFIELD were using a TBuf<256> for the query
{
CBufFlat* sqlBuf=CBufFlat::NewL(128);
CleanupStack::PushL(sqlBuf);
TInt ff(0);
TInt numberOfFields=((iCurrOplRowSet->AccessMap())->GetNoOfFields());
for(TInt jj=0;jj<aFirstString;jj++)
{
if (jj>0) // takes us to first string field (or 2nd) =ff
ff++;
while ((iCurrOplRowSet->AccessMap())->ReadType(ff)!=EDbColText)
{
ff++;
if (ff>=numberOfFields)
User::Leave(KOplErrSyntax); //!!todo -- check this.
}
}
for(TInt ii=0;ii<aNoOfStrings;ii++)
{
if (ii>0)
{
TPtrC bufOr=KOr();
sqlBuf->InsertL(sqlBuf->Size(),bufOr.Ptr(),bufOr.Size());
ff++;
}
while ((iCurrOplRowSet->AccessMap())->ReadType(ff)!=EDbColText)
{
ff++;
if (ff>=numberOfFields)
User::Leave(KOplErrSyntax);
}
TPtrC name=((*iCurrOplRowSet->AccessColSet())[ff+1]).iName;
sqlBuf->InsertL(sqlBuf->Size(),name.Ptr(),name.Size());
TPtrC bufLike=KLikeQuote();
sqlBuf->InsertL(sqlBuf->Size(),bufLike.Ptr(),bufLike.Size());
sqlBuf->InsertL(sqlBuf->Size(),aString.Ptr(),aString.Size());
TPtrC bufQuote=KQuote();
sqlBuf->InsertL(sqlBuf->Size(),bufQuote.Ptr(),bufQuote.Size());
}
return sqlBuf;
}
EXPORT_C TInt COplDbManager::NoOfStrFields()
{
TInt numberOfFields=((iCurrOplRowSet->AccessMap())->GetNoOfFields());
TInt num(0);
for(TInt ii=0;ii<numberOfFields;ii++)
{
if(iCurrOplRowSet->AccessMap()->ReadType(ii)==EDbColText)
num++;
}
return num;
}
EXPORT_C void COplDbManager::FindString(const TDesC& aString)
{
TInt num=NoOfStrFields();
// Fix for bug SW1-397 : FIND and FINDFIELD were using a TBuf<256> for the query
CBufFlat* sql=GenerateSQLBufLC(1,num,aString);
//!!TODO Does this comparefolded thing need changing for Unicode?
TPtrC8 sqlPtr=sql->Ptr(0);
TPtr newBuf((TText*)sqlPtr.Ptr(),sql->Size()>>1,sql->Size()>>1);
TDbQuery dbQuery(newBuf,EDbCompareFolded);
TInt iterations(KErrNotFound);
if(iCurrDbRowSet->AtRow())
iterations=iCurrDbRowSet->FindL(RDbRowSet::EForwards, dbQuery);
if (iterations==KErrNotFound)
{
iCurrOplRowSet->SetPos(iCurrDbRowSet->CountL()+1);
iStack.Push(TInt16(0));
}
else
{
iCurrOplRowSet->SetPosRelative(iterations);
iStack.Push(TInt16(iCurrOplRowSet->GetPos()));
}
CleanupStack::PopAndDestroy(); // sql
return;
}
const TInt KOplFindForward = 0x01;
const TInt KOplFindFromAnEnd = 0x02;
const TInt KOplFindCaseDependent = 0x10;
const TInt KOplFindFieldMask = KOplFindForward|KOplFindFromAnEnd|KOplFindCaseDependent;
EXPORT_C void COplDbManager::FindField()
{
TInt flag=iStack.PopInt16();
TInt num=iStack.PopInt16();
TInt start=iStack.PopInt16();
TPtrC string=iStack.PopString();
//!!TODO Does this comparefolded thing need changing?
TDbTextComparison caseDependancy(EDbCompareFolded); // o -> not , 1 -> dependant
RDbRowSet::TDirection direction;
TInt numMax=NoOfStrFields();
if ((start+num-1>numMax) || (flag & (~KOplFindFieldMask)))
User::Leave(KOplErrInvalidArgs);
if (flag&KOplFindForward)
{
direction=RDbRowSet::EForwards;
if (flag&KOplFindFromAnEnd)
FirstL(); // use dbms , NO
if (!iCurrDbRowSet->AtRow())
{
iStack.Push(TInt16(0));
iCurrOplRowSet->SetPos(iCurrDbRowSet->CountL()+1);
return;
}
}
else
{
direction=RDbRowSet::EBackwards;
if ((flag&KOplFindFromAnEnd) || (!iCurrDbRowSet->AtRow()))
LastL();
}
if (flag&KOplFindCaseDependent)
caseDependancy=EDbCompareNormal;
// Fix for bug SW1-397 : FIND and FINDFIELD were using a TBuf<256> for the query
CBufFlat* sql=GenerateSQLBufLC(start,num,string);
TPtrC8 sqlPtr=sql->Ptr(0);
TPtr newBuf((TText*)sqlPtr.Ptr(),sql->Size()>>1,sql->Size()>>1);
TDbQuery dbQuery(newBuf,caseDependancy);
TInt iterations=iCurrDbRowSet->FindL(direction, dbQuery);
if (iterations==KErrNotFound)
{
iStack.Push(TInt16(0));
if(direction==RDbRowSet::EForwards)
iCurrOplRowSet->SetPos(iCurrDbRowSet->CountL()+1);
else
FirstL();
}
else
{
iCurrOplRowSet->SetPosRelative(direction==RDbRowSet::EForwards?iterations:-iterations);
TInt16 ret=TInt16(iCurrOplRowSet->GetPos());
iStack.Push(ret);
}
CleanupStack::PopAndDestroy(); // sql
}
EXPORT_C TInt COplDbManager::Bookmark()
{
TInt count=iBookmarkArray.Count();
TInt ret(-1);
TOplBookmark mark;
for(TInt ii=0;ii<count;ii++)
{
if (!iBookmarkArray[ii].MarkAlive())
{
ret=ii;
mark.SetMark(iCurrDbRowSet->Bookmark());
iBookmarkArray[ret]=(mark);
break;
}
}
if(ret<0)
{
ret=count;
mark.SetMark(iCurrDbRowSet->Bookmark());
iBookmarkArray.AppendL(mark);
}
return (ret+1);
}
EXPORT_C void COplDbManager::GotoMark(TInt aMark)
{
if(aMark<1 || aMark>iBookmarkArray.Count() || !iBookmarkArray[aMark-1].MarkAlive())
User::Leave(KOplErrInvalidArgs);
else
iCurrDbRowSet->GotoL(iBookmarkArray[aMark-1].GetMark());
}
EXPORT_C void COplDbManager::KillMark(TInt aMark)
{
if (aMark<1)
User::Leave(KOplErrInvalidArgs);
iBookmarkArray[aMark-1].KillMark();
}
EXPORT_C void TOplBookmark::SetMark(TDbBookmark aMark)
{
iBookmark=aMark;
iAlive=ETrue;
}
EXPORT_C TInt32 COplDbManager::Space()
/*
Returns LONG of bytes left on the device where the current logical name is from
*/
{
TVolumeInfo info;
iFs.Volume(info,TDriveUnit(iCurrOplRowSet->ParentDbase()->Name()));
return info.iFree.Low();
}
EXPORT_C void COplDbManager::DeleteTable(TPtrC aTable,TPtrC aDbase)
{
TFileName dbName(aDbase);
TParse parser;
iFs.Parse(dbName,parser);
TBufC<KMaxFileName> name(parser.FullName());
COplDb *db;
if ((db=iOplDbCollection->FindOpenDbase(name,EFalse))==NULL)
{
db=COplDb::NewLC(name);
db->OpenL(iFs,name,ETrue);
}
else
User::Leave(KOplErrOpen);
db->StoreDbase().DropTable(aTable);
db->Close();
CleanupStack::PopAndDestroy(); // db
}
EXPORT_C void COplDbManager::BeginTrans()
{
RDbStoreDatabase& store=iCurrOplRowSet->ParentDbase()->StoreDbase();
if ((!iCurrOplRowSet->InAppendOrUpdate()) && (!iCurrOplRowSet->InModifyOrInsert()) && (!store.InTransaction()))
store.Begin();
else
User::Leave(KOplErrInTransaction); // error if in any mode already
}
EXPORT_C void COplDbManager::CommitTrans()
{
RDbStoreDatabase& store=iCurrOplRowSet->ParentDbase()->StoreDbase();
if ((!iCurrOplRowSet->InAppendOrUpdate()) && (!iCurrOplRowSet->InModifyOrInsert()) && (store.InTransaction()))
User::LeaveIfError(store.Commit());
else
User::Leave(KOplErrInTransaction); // error if in any mode already
}
EXPORT_C void COplDbManager::Rollback()
{
RDbStoreDatabase& store=iCurrOplRowSet->ParentDbase()->StoreDbase();
if ((!iCurrOplRowSet->InAppendOrUpdate()) && (!iCurrOplRowSet->InModifyOrInsert()) && (store.InTransaction()))
store.Rollback();
else
User::Leave(KOplErrInTransaction); // error if in any mode already
ResetRelatedViews();
}
EXPORT_C TInt COplDbManager::InTrans()
{
return (iCurrOplRowSet->ParentDbase()->StoreDbase().InTransaction() ? -1 : 0);
}
EXPORT_C void COplDbManager::CompactL(TPtrC aDbase)
{
TParse parser;
iFs.Parse(aDbase,parser);
CFileStore* store=CFileStore::OpenLC(iFs,parser.FullName(),EFileRead|EFileWrite); // file closed on error
store->CompactL();
store->CommitL();
CleanupStack::PopAndDestroy(); // store
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -