diff -r 000000000000 -r 1f04cf54edd8 symhelp/helpmodel/dbwriter/DBWRITER.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/symhelp/helpmodel/dbwriter/DBWRITER.CPP Tue Jan 26 15:15:23 2010 +0200 @@ -0,0 +1,630 @@ +// Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#include "DBWRITER.H" +#include + +// User includes +#include "HLPMODEL.H" +#include "hlppanic.h" + + + + +enum TDbWriterPanic + { + EDbWriterNoRowAtCursor, + EDbWriterInvalidColumnType, + EDbWriterStoreNotOpen + }; + + +GLDEF_C void Panic(TDbWriterPanic aReason) + { + _LIT(KHlpPanicText, "DbWriter"); + User::Panic(KHlpPanicText, aReason); + } + + + +// +// Create the database +// + +CHlpRowSet::CHlpRowSet(RDbView* aView) + : iView(aView) + { + } + +EXPORT_C CHlpRowSet::~CHlpRowSet() + { + iView->Close(); + delete iView; + } + +EXPORT_C TBool CHlpRowSet::AtRow() + { + return iView->AtRow(); + } + +EXPORT_C TBool CHlpRowSet::AtBeginning() + { + return iView->AtBeginning(); + } + +EXPORT_C TBool CHlpRowSet::AtEnd() + { + return iView->AtEnd(); + } + +EXPORT_C TBool CHlpRowSet::FirstL() + { + return iView->FirstL(); + } + +EXPORT_C TBool CHlpRowSet::LastL() + { + return iView->LastL(); + } + +EXPORT_C TInt CHlpRowSet::CountL() + { + return iView->CountL(); + } + +EXPORT_C void CHlpRowSet::NextL() + { + iView->NextL(); + } + +EXPORT_C void CHlpRowSet::PreviousL() + { + // coverity [unchecked_value] + iView->PreviousL(); + } + +EXPORT_C RDbView* CHlpRowSet::View() + { + return iView; + } + + +// This method could leave while getting column set for the rowset. +// @leave KErrNoMemory not enough memory to carry out the operation + +EXPORT_C TDbColNo CHlpRowSet::MapColNameToColNo(const TDesC& aName) + { + CDbColSet* columnSet = iView->ColSetL(); + CleanupStack::PushL(columnSet); + TInt columnNumber = columnSet->ColNo(aName); + CleanupStack::PopAndDestroy(columnSet); + return columnNumber; + } + + +// This method could leave while getting column set for the rowset. +// @leave KErrNoMemory not enough memory to carry out the operation + +EXPORT_C TDbColNo CHlpRowSet::MapColNameToColNo(const TDbCol& aCol) + { + CDbColSet* columnSet = iView->ColSetL(); + CleanupStack::PushL(columnSet); + TInt columnNumber = columnSet->ColNo(aCol.iName); + CleanupStack::PopAndDestroy(columnSet); + return columnNumber; + } + + + + + + + + + + + + + + +// +// CHlpView class - Read only access to database views +// + +CHlpView::CHlpView(RDbView* aView) +: CHlpRowSet(aView) + { + } + +CHlpView::~CHlpView() + { + View()->Close(); + } + +void CHlpView::ConstructL() + { + } + +EXPORT_C CHlpView* CHlpView::NewLC(RDbView* aView) + { + CHlpView* self = new(ELeave)CHlpView(aView); + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + +EXPORT_C CHlpView* CHlpView::NewL(RDbView* aView) + { + CHlpView* self = CHlpView::NewLC(aView); + CleanupStack::Pop(); + return self; + } + +EXPORT_C void CHlpView::GetL() + { + View()->GetL(); + } + +EXPORT_C void CHlpView::GetTextL(TDbColNo aCol, TDes& aText) + { + __ASSERT_ALWAYS(View()->AtRow(), Panic(EDbWriterNoRowAtCursor)); + aText = View()->ColDes(aCol); + } + +EXPORT_C void CHlpView::GetRichTextL(TDbColNo aTextCol, TDbColNo aMarkupCol, CRichText& aRichText) + { + __ASSERT_ALWAYS(View()->AtRow(), Panic(EDbWriterNoRowAtCursor)); + TPtrC ptr=View()->ColDes(aTextCol); + aRichText.InsertL(0, ptr); + GetMarkupL(aRichText, aMarkupCol); + } + +EXPORT_C void CHlpView::GetValL(TDbColNo aCol, TUint32& aValue) + { + __ASSERT_ALWAYS(View()->AtRow(), Panic(EDbWriterNoRowAtCursor)); + aValue=View()->ColUint16(aCol); + } + +void CHlpView::GetMarkupL(CRichText& aRichText, TDbColNo aMarkupCol) + { + __ASSERT_ALWAYS(View()->ColDef(aMarkupCol).iType == EDbColLongBinary, Panic(EDbWriterInvalidColumnType)); + + RDbColReadStream blob; + blob.OpenLC(*View(), aMarkupCol); + + CEmbeddedStore* embeddedStore = CEmbeddedStore::FromLC(blob); + RStoreReadStream markupStream; + markupStream.OpenLC(*embeddedStore, embeddedStore->Root()); + aRichText.InternalizeMarkupDataL(markupStream); + iStoreResolver.iStore = embeddedStore; + + aRichText.SetPictureFactory(iPictureFactory, &iStoreResolver); + aRichText.DetachFromStoreL(CPicture::EDetachFull); + CleanupStack::PopAndDestroy(3); // embeddedStore, markupStream, blob + } + + + + + + + + + + + +// +// CHlpTable class - write access to database views +// + +CHlpTable::CHlpTable(RDbView* aView) +: CHlpRowSet(aView) + { + } + +CHlpTable::~CHlpTable() + { +// View()->Close(); + } + +void CHlpTable::ConstructL() + { + } + +EXPORT_C CHlpTable* CHlpTable::NewLC(RDbView* aView) + { + CHlpTable* self=new(ELeave)CHlpTable(aView); + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + +EXPORT_C CHlpTable* CHlpTable::NewL(RDbView* aView) + { + CHlpTable* self=CHlpTable::NewLC(aView); + CleanupStack::Pop(); + return self; + } + +EXPORT_C void CHlpTable::InsertL() + { + View()->InsertL(); + } + +EXPORT_C void CHlpTable::PutL() + { + View()->PutL(); + } + +EXPORT_C void CHlpTable::SetColL(TDbColNo aCol, const TDesC& aText) + { + __ASSERT_ALWAYS(View()->AtRow(), Panic(EDbWriterNoRowAtCursor)); + View()->SetColL(aCol, aText); + } + +EXPORT_C void CHlpTable::SetColL(TDbColNo aCol, TUint32 aValue) + { + __ASSERT_ALWAYS(View()->AtRow(), Panic(EDbWriterNoRowAtCursor)); + View()->SetColL(aCol, aValue); + } + +EXPORT_C void CHlpTable::SetColL(TDbColNo aCol, const CFbsBitmap& aBitmap) + { + __ASSERT_ALWAYS(View()->AtRow(), Panic(EDbWriterNoRowAtCursor)); + + RDbColWriteStream blob; + blob.OpenLC(*View(), aCol); + blob << aBitmap; + blob.CommitL(); + CleanupStack::PopAndDestroy(); // blob + } + +EXPORT_C void CHlpTable::SetColL(TDbColNo aTextCol, TDbColNo aMarkupCol, CRichText& aRichText) + { + __ASSERT_ALWAYS(View()->AtRow(), Panic(EDbWriterNoRowAtCursor)); + HBufC* buf = HBufC::NewLC(aRichText.DocumentLength()); + TPtr ptr = buf->Des(); + aRichText.Extract(ptr); + SetLongTextL(*buf, aTextCol); + CleanupStack::PopAndDestroy(); // buf + + if (aRichText.HasMarkupData()) + SetMarkupL(aRichText, aMarkupCol); + else + View()->SetColNullL(aMarkupCol); + } + +EXPORT_C void CHlpTable::SetColL(TDbColNo aTextCol, CRichText& aRichText) + { + __ASSERT_ALWAYS(View()->AtRow(), Panic(EDbWriterNoRowAtCursor)); + HBufC* buf = HBufC::NewL(aRichText.DocumentLength()); + CleanupStack::PushL(buf); + TPtr ptr = buf->Des(); + aRichText.Extract(ptr); + View()->SetColL(aTextCol,ptr); + CleanupStack::PopAndDestroy(); // buf + } + +void CHlpTable::SetLongTextL(const TDesC& aText, TDbColNo aLongTextCol) + { + RDbColWriteStream stream; + stream.OpenLC(*View(), aLongTextCol); + stream.WriteL(aText); + stream.CommitL(); + CleanupStack::PopAndDestroy(); // stream + } + +void CHlpTable::SetMarkupL(CRichText& aRichText, TDbColNo aMarkupCol) + { + aRichText.DetachFromStoreL(CPicture::EDetachFull); + RDbColWriteStream blob; + blob.OpenL(*View(), aMarkupCol); + CEmbeddedStore* embeddedStore=CEmbeddedStore::NewLC(blob); // takes ownership of blob + CStoreMap* map=CStoreMap::NewLC(*embeddedStore); + aRichText.StoreMarkupComponentsL(*embeddedStore, *map); + + RStoreWriteStream markup(*map); + embeddedStore->SetRootL(markup.CreateLC(*embeddedStore)); + aRichText.ExternalizeMarkupDataL(markup); + markup.CommitL(); + map->Reset(); + CleanupStack::PopAndDestroy(2); // map, markup + embeddedStore->CommitL(); + CleanupStack::PopAndDestroy(); // embeddedStore + } + +const CStreamStore& THlpStoreResolver::StreamStoreL(TInt /*aPos*/) const + { + return *iStore; + } + + + + + + + + + + + + + + + +// +// CHlpDbWriter class +// + +CHlpDbWriter::CHlpDbWriter(RFs& aFs) +: iFs(aFs) + { + } + +EXPORT_C CHlpDbWriter::~CHlpDbWriter() + { + iDatabase.Close(); + delete iTables; + delete iDictionary; + delete iStore; + delete iUids; + delete iImagesAlreadyStored; +} + +void CHlpDbWriter::ConstructL() + { + iDictionary = CStreamDictionary::NewL(); + iTables = new(ELeave) CArrayPtrFlat(4); + iUids = new(ELeave) CArrayFixFlat(2); + iImagesAlreadyStored = new(ELeave) CArrayFixFlat(10); + } + +EXPORT_C CHlpDbWriter* CHlpDbWriter::NewL(RFs& aFs) + { + CHlpDbWriter* self = CHlpDbWriter::NewLC(aFs); + CleanupStack::Pop(); //self + return self; + } + +EXPORT_C CHlpDbWriter* CHlpDbWriter::NewLC(RFs& aFs) + { + CHlpDbWriter* self = new(ELeave) CHlpDbWriter(aFs); + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + +EXPORT_C void CHlpDbWriter::SetDatabaseUidL(TUid& aUid) + { + __ASSERT_DEBUG(iStore, Panic(EDbWriterStoreNotOpen)); + + TUidType type(KPermanentFileStoreLayoutUid, KUidHlpApp, aUid); + iStore->SetTypeL(type); + } + +EXPORT_C void CHlpDbWriter::CreateFileL(const TDesC& aFileName) + { + CPermanentFileStore* store = NULL; + + if (!BaflUtils::FileExists(iFs, aFileName)) + store = CPermanentFileStore::CreateL(iFs, aFileName, EFileRead|EFileWrite); + else // Change this so that the program panics if the file exists. + store = CPermanentFileStore::ReplaceL(iFs, aFileName, EFileRead|EFileWrite); + + delete iStore; + iStore = store; + iFileName = aFileName; + } + +EXPORT_C void CHlpDbWriter::AddBitmapL(TInt aBitmapId) + { + TKeyArrayFix key(_FOFF(TUid, iUid), ECmpTUint); + iImagesAlreadyStored->InsertIsqL(TUid::Uid(aBitmapId), key); + } + +EXPORT_C TBool CHlpDbWriter::IsBitmapStored(TInt aBitmapId) const + { + TInt index = KErrNotFound; + TKeyArrayFix key(_FOFF(TUid, iUid), ECmpTUint); + return (!iImagesAlreadyStored->FindIsq(TUid::Uid(aBitmapId), key, index)); + } + +EXPORT_C TInt CHlpDbWriter::BitmapCount() const + { + return iImagesAlreadyStored->Count(); + } + +EXPORT_C TInt CHlpDbWriter::BitmapIdForIndex(TInt aIndex) const + { + return iImagesAlreadyStored->At(aIndex).iUid; + } + +EXPORT_C void CHlpDbWriter::CreateDatabaseL() + { + TStreamId dbStream=iDatabase.CreateL(iStore); + iDictionary->AssignL(KUidHlpDbStream, dbStream); + DoCreateDatabaseL(); + DoOpenTablesL(); + } + +void CHlpDbWriter::DoCreateDatabaseL() + { + // create the table schemas + User::LeaveIfError(iDatabase.Execute(KHlpDMLTopicTable)); + User::LeaveIfError(iDatabase.Execute(KHlpDMLIndexTable)); + User::LeaveIfError(iDatabase.Execute(KHlpDMLTopicIndexTable)); + User::LeaveIfError(iDatabase.Execute(KHlpDMLContextTable)); + User::LeaveIfError(iDatabase.Execute(KHlpDMLImageTable)); + + // create the indices + User::LeaveIfError(iDatabase.Execute(KHlpDMLTopicTableIdx)); + User::LeaveIfError(iDatabase.Execute(KHlpDMLIndexTableIdx)); + User::LeaveIfError(iDatabase.Execute(KHlpDMLTopicIndexTableIdx)); + User::LeaveIfError(iDatabase.Execute(KHlpDMLContextTableIdx)); + User::LeaveIfError(iDatabase.Execute(KHlpDMLImageTableIdx)); + } + +EXPORT_C void CHlpDbWriter::CompressDatabaseL() + { + StoreUidsL(); + StoreStreamDictionaryL(); + + iStore->CommitL(); + iDatabase.CompressL(*iStore, iDictionary->At(KUidHlpDbStream)); + iStore->CompactL(); + iStore->CommitL(); + } + +void CHlpDbWriter::DoOpenTablesL() + { + iTables->AppendL(DoOpenTableLC(ETopicTable)); + CleanupStack::Pop(); // ret from DoOpenTableL + iTables->AppendL(DoOpenTableLC(EIndexTable)); + CleanupStack::Pop(); // ret from DoOpenTableL + iTables->AppendL(DoOpenTableLC(ETopicIndexTable)); + CleanupStack::Pop(); // ret from DoOpenTableL + iTables->AppendL(DoOpenTableLC(EContextTable)); + CleanupStack::Pop(); // ret from DoOpenTableL + iTables->AppendL(DoOpenTableLC(EImageTable)); + CleanupStack::Pop(); // ret from DoOpenTableL + } + +CHlpTable* CHlpDbWriter::DoOpenTableLC(TInt aTable) + { + TBuf<255> sql; + + switch(aTable) + { + case ETopicTable: + sql=KHlpSQLTopicTable; + break; + case EIndexTable: + sql=KHlpSQLIndexTable; + break; + case ETopicIndexTable: + sql=KHlpSQLTopicIndexTable; + break; + case EContextTable: + sql=KHlpSQLContextTable; + break; + case EImageTable: + sql=KHlpSQLImageTable; + break; + default: + User::Leave(KErrNotSupported); + } + + RDbView* view = new(ELeave) RDbView; + CleanupStack::PushL(view); + User::LeaveIfError(view->Prepare(iDatabase, sql, RDbView::EUpdatable)); + User::LeaveIfError(view->EvaluateAll()); + CHlpTable* table = CHlpTable::NewL(view); + CleanupStack::Pop(); // view + CleanupStack::PushL(table); + + return table; + } + + + +void CHlpDbWriter::StoreUidsL() + { + RStoreWriteStream out; + TStreamId uidStream = out.CreateLC(*iStore); + iDictionary->AssignL(KUidHlpUidStream, uidStream); + out.WriteInt32L(iUids->Count()); + if (iUids->Count() > 0) + { + for(TInt i=0; i < iUids->Count(); i++) + { + out.WriteInt32L((*iUids)[i].iUid); + } + } + out.CommitL(); + out.Close(); + CleanupStack::PopAndDestroy(); // out + } + +void CHlpDbWriter::StoreStreamDictionaryL() + { + // Store the stream dictionary in the root + RStoreWriteStream out; + TStreamId root = out.CreateLC(*iStore); + iStore->SetRootL(root); + out << *iDictionary; + out.CommitL(); + out.Close(); + CleanupStack::PopAndDestroy(); // out + } + +EXPORT_C void CHlpDbWriter::CloseFileL() // should this be make private and put in the destructor? + { + iDatabase.Close(); + iStore->CompactL(); + iStore->CommitL(); + delete iStore; + iStore=NULL; + iUids->Reset(); + iTables->ResetAndDestroy(); + iTables->Reset(); + + // Have to do this because there is no reset procedure for a stream dictionary + CStreamDictionary* newDictionary = CStreamDictionary::NewL(); + delete iDictionary; + iDictionary = newDictionary; + } + +EXPORT_C void CHlpDbWriter::SetUidL(TUid aUid) + { + TKeyArrayFix key(_FOFF(TUid,iUid),ECmpTUint32); + TInt indexNotReferenced = KErrNotFound; + if (iUids->Find(aUid,key, indexNotReferenced) != KErrNone) + iUids->AppendL(aUid); + } + +EXPORT_C void CHlpDbWriter::BeginTransaction() + { + iDatabase.Begin(); + } + +EXPORT_C void CHlpDbWriter::CommitTransaction() + { + iDatabase.Commit(); + } + +EXPORT_C CHlpTable* CHlpDbWriter::TopicTable() + { + return iTables->At(ETopicTable); + } + +EXPORT_C CHlpTable* CHlpDbWriter::IndexTable() + { + return iTables->At(EIndexTable); + } + +EXPORT_C CHlpTable* CHlpDbWriter::TopicIndexTable() + { + return iTables->At(ETopicIndexTable); + } + +EXPORT_C CHlpTable* CHlpDbWriter::ContextTable() + { + return iTables->At(EContextTable); + } + +EXPORT_C CHlpTable* CHlpDbWriter::ImageTable() + { + return iTables->At(EImageTable); + }