⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 data.cpp

📁 在手机操作系统symbina上使用的一个脚本扩展语言的代码实现,可以参考用于自己的开发
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// DATA.CPP
//
// Copyright (c) 1997-2002 Symbian Ltd. All rights reserved.

#include <f32file.h>
#include <s32file.h>
#include <d32dbms.h>
#include <e32base.h>

#include <opx.h>
#include <oplapi.h>
#include <oplerr.h>
#include <opldb.h>
#include <opldoc.h>

#include <eikenv.h>

// Define UIDs to match the correct version of OPL database files
#ifdef _UNICODE
	#define KUidOplInterpreter 0x10005D2E
	#define KUidExternalOplFile 0x1000008A
#else
	#define KUidOplInterpreter 0x10000168
	#define KUidExternalOplFile 0x1000008A
#endif

const TInt KUidOpxOplDb=0x10004EC7;
const TInt KOpxDataVersion=0x600;

class COpxOplDb : public COpxBase 
	{
public:
	static COpxOplDb* NewLC(OplAPI& aOplAPI);
	virtual void RunL(TInt aProcNum);
	virtual TInt CheckVersion(TInt aVersion);
private:
	// The language extension procedures
	enum TExtensions
		{
		EODbGetTableCount=1,
		EODbGetTableName,
		EODbGetIndexCount,
		EODbGetIndexName,
		EODbGetIndexDescription,
		EODbGetFieldCount,
		EODbGetFieldName,
		EODbGetFieldType,
		EODbGetFieldSize,
		EODbGetCanBeEmpty,
		EODbOpenR,
		EODbOpen,
		EODbStartTable,
		EODbTableField,
		EODbCreateTable,
		EODbGetLength,
		EODbGetString,
		EODbGetInt,
		EODbGetReal,
		EODbGetReal32,
		EODbGetWord,
		EODbGetDateTime,
		EODbGetLong,
		EODbPutEmpty,
		EODbPutString,
		EODbPutInt,
		EODbPutReal,
		EODbPutReal32,
		EODbPutWord,
		EODbPutDateTime,
		EODbPutLong,
		EODbFindWhere,
		EODbUse,
		EODbSeekInt,
		EODbSeekWord,
		EODbSeekText,
		EODbSeekReal,
		EODbSeekDateTime,
		EODbCount,
		EODbFindSql
		};
	void DbGetTableCount() const;
	void DbGetTableName() const;
	void DbGetIndexCount() const;
	void DbGetIndexName() const;
	void DbGetIndexDescription() const;
	void DbGetFieldCount() const;
	void DbGetField(TInt aProcNum) const;
	void DbOpen(TBool allowUpdates) const;
	void DbStartTable();
	void DbTableField();
	void DbCreateTable();
	void DbGet(TInt aProcNum) const;
	void DbPut(TInt aProcNum) const;
	TInt DbFindWhere() const;
	void DbUse() const;
	void DbSeek(TInt aProcNum) const;
	void DbCount() const;
private:
	COpxOplDb(OplAPI& aOplAPI);
	void ConstructL();
	~COpxOplDb();
private:
	CDbColSet* iDbColSet;
	};

//
// Accessing an OPL database
//
class CDbasePtr : public CBase
	{
public:
	static CDbasePtr* NewLC(OplAPI &anOplAPI, const TDesC &aFileName, 
							TBool anUpdate, TBool aCreateIfAbsent);
	~CDbasePtr();
	RDbStoreDatabase& Dbase() { return *iDbasePtr; }
private:
	CDbasePtr();
private:
	RDbStoreDatabase* iDbasePtr;
	RDbStoreDatabase iDbase;
	TBool iOwner;
	CFileStore* iStore;
	};

CDbasePtr::CDbasePtr()
	:iOwner(EFalse)
	{
	}

CDbasePtr::~CDbasePtr()
	{
	if (iOwner)
		{
		iDbase.Close();
		delete iStore;
		}
	}

CDbasePtr* CDbasePtr::NewLC(OplAPI &anOplAPI, const TDesC &aFileName, 
							TBool anUpdate, TBool aCreateIfAbsent)
	{
	COplDb* db;
	TParse parser;
	RFs& aFs = anOplAPI.EikonEnv().FsSession();
	aFs.Parse(aFileName, parser);
	CDbasePtr* self = new (ELeave) CDbasePtr;
	CleanupStack::PushL(self);
	if ((db=anOplAPI.DbManager()->OplDbCollection()->FindOpenDbase(parser.FullName(),EFalse))!=NULL)
		{
		// db is open in OPL program
		self->iDbasePtr = &db->StoreDbase();
		return self;
		}
	// Database file is not currently open.	Does it exist?
	TEntry entry;
	TInt err = aFs.Entry(parser.FullName(),entry);
	if (!err)
		{
		// the file exists, open database
		self->iStore=CFileStore::OpenLC(aFs,parser.FullName(),
			(anUpdate ? (EFileRead|EFileWrite) : EFileRead)); // file closed on error	
			RStoreReadStream inStream;
		inStream.OpenLC(*(self->iStore), self->iStore->Root());
		TOplDocRootStream shellData;
		inStream>>shellData;
		CleanupStack::PopAndDestroy(); // inStream
		self->iDbase.OpenL(self->iStore, shellData.iStreamId);
		self->iOwner = ETrue;
		self->iDbasePtr = &(self->iDbase);
		CleanupStack::Pop(); // iStore now owned by self
		return self;
		}
	// File does not exist
	if (!aCreateIfAbsent)
		User::Leave(KOplErrNotExists);
	// We have to create the file with an empty database
	self->iStore=CPermanentFileStore::CreateLC(aFs,parser.FullName(),EFileRead|EFileWrite);
	TUidType uids(KPermanentFileStoreLayoutUid,TUid::Uid(KUidExternalOplFile));
	self->iStore->SetTypeL(uids);
	// Write the root stream
	TOplDocRootStream shellData;
	shellData.iStreamId=self->iDbase.CreateL(self->iStore);
	shellData.iAppUid=TUid::Uid(KUidOplInterpreter);

	RStoreWriteStream root;
	TStreamId rootId=root.CreateLC(*(self->iStore));
	root<<shellData;
	root.CommitL(); // root stream
	CleanupStack::PopAndDestroy(); // root

	self->iStore->SetRootL(rootId);
	self->iStore->CommitL();
	self->iOwner = ETrue;
	self->iDbasePtr = &(self->iDbase);
	CleanupStack::Pop(); // iStore now owned by self
	return self;
	}

//
// The language extension procedures provided by this OPX
//
void COpxOplDb::DbGetTableCount() const
	{
	TPtrC dbname = iOplAPI.PopString();
	CDbasePtr* dbase = CDbasePtr::NewLC(iOplAPI, dbname, EFalse, EFalse);
	CDbTableNames* tables = dbase->Dbase().TableNamesL();
	CleanupStack::PushL(tables);
	TInt32 noTables = tables->Count();
	iOplAPI.Push(noTables);
	CleanupStack::PopAndDestroy(2);	// tables, dbase
	}

void COpxOplDb::DbGetTableName() const
	{
	TInt ind = iOplAPI.PopInt32();
	TPtrC dbname = iOplAPI.PopString();
	CDbasePtr* dbase = CDbasePtr::NewLC(iOplAPI, dbname, EFalse, EFalse);
	CDbTableNames* tables = dbase->Dbase().TableNamesL();
	CleanupStack::PushL(tables);
	if (ind < 1 || tables->Count() < ind)
		User::Leave(KOplErrOutOfRange);

	TBufC<255> tname = (*tables)[ind-1];
	iOplAPI.PushL(tname);
	CleanupStack::PopAndDestroy(2);	// tables, dbase
	}

void COpxOplDb::DbGetIndexCount() const
	{
	TPtrC tbname = iOplAPI.PopString();
	TPtrC dbname = iOplAPI.PopString();
	CDbasePtr* dbase = CDbasePtr::NewLC(iOplAPI, dbname, EFalse, EFalse);
	CDbIndexNames* indices = dbase->Dbase().IndexNamesL(tbname);
	CleanupStack::PushL(indices);
	TInt32 noIndex = indices->Count();
	iOplAPI.Push(noIndex);
	CleanupStack::PopAndDestroy(2);	// indices, dbase
	}

void COpxOplDb::DbGetIndexName() const
	{
	TInt ind = iOplAPI.PopInt32();
	TPtrC tbname = iOplAPI.PopString();
	TPtrC dbname = iOplAPI.PopString();
	CDbasePtr* dbase = CDbasePtr::NewLC(iOplAPI, dbname, EFalse, EFalse);
	CDbIndexNames* indices = dbase->Dbase().IndexNamesL(tbname);
	CleanupStack::PushL(indices);
	if (ind < 1 || indices->Count() < ind)
		User::Leave(KOplErrOutOfRange);

	TBufC<255> iname = (*indices)[ind-1];
	iOplAPI.PushL(iname);
	CleanupStack::PopAndDestroy(2);	// indices, dbase
	}

void COpxOplDb::DbGetIndexDescription() const
	{
	TPtrC ixname = iOplAPI.PopString();
	TPtrC tbname = iOplAPI.PopString();
	TPtrC dbname = iOplAPI.PopString();
	CDbasePtr* dbase = CDbasePtr::NewLC(iOplAPI, dbname, EFalse, EFalse);
	CDbKey* aKey = dbase->Dbase().KeyL(ixname, tbname);
	CleanupStack::PushL(aKey);
	TBuf<255> keyDesc;
	TInt i;
	TDbKeyCol aKeyCol;

	_LIT(KOpenBrace," (");
	_LIT(KCloseBrace,") ");
	_LIT(KAscending,"Ascending ");
	_LIT(KDescending,"Descending ");
	_LIT(KUnique," Unique");
	_LIT(KFolded," Folded");
	_LIT(KCollated," Collated");

	for (i = 0; i < aKey->Count(); i++)
		{
		aKeyCol = (*aKey)[i];
		keyDesc.Append(aKeyCol.iName);
		keyDesc.Append(KOpenBrace);
		keyDesc.AppendNum(aKeyCol.iLength);
		keyDesc.Append(KCloseBrace);
		if (aKeyCol.iOrder == TDbKeyCol::EAsc)
			keyDesc.Append(KAscending);
		else
			keyDesc.Append(KDescending);
		}
	if (aKey->IsUnique())
		keyDesc.Append(KUnique);
	switch (aKey->Comparison())
		{
	case EDbCompareNormal:
		break;
	case EDbCompareFolded:
		keyDesc.Append(KFolded);
		break;
	case EDbCompareCollated:
		keyDesc.Append(KCollated);
		break;
		}
	iOplAPI.PushL(keyDesc);
	CleanupStack::PopAndDestroy(2);	// aKey, dbase
	}

void COpxOplDb::DbGetFieldCount() const
	{
	TPtrC tbname = iOplAPI.PopString();
	TPtrC dbname = iOplAPI.PopString();
	CDbasePtr* dbase = CDbasePtr::NewLC(iOplAPI, dbname, EFalse, EFalse);
	CDbColSet* aColSet = dbase->Dbase().ColSetL(tbname);
	CleanupStack::PushL(aColSet);
	TInt32 noField = aColSet->Count();
	iOplAPI.Push(noField);
	CleanupStack::PopAndDestroy(2);	// aColSet, dbase
	}

void COpxOplDb::DbGetField(TInt aProcNum) const
	{
	TInt ind = iOplAPI.PopInt32();
	TPtrC tbname = iOplAPI.PopString();
	TPtrC dbname = iOplAPI.PopString();
	CDbasePtr* dbase = CDbasePtr::NewLC(iOplAPI, dbname, EFalse, EFalse);
	CDbColSet* aColSet = dbase->Dbase().ColSetL(tbname);
	CleanupStack::PushL(aColSet);
	if (ind < 1 || aColSet->Count() < ind)
		User::Leave(KOplErrOutOfRange);
	// Get the information
	switch (aProcNum)
		{
	case EODbGetFieldName:
		iOplAPI.PushL((*aColSet)[ind].iName);
		break;
	case EODbGetFieldType:
		iOplAPI.Push(TInt32((*aColSet)[ind].iType));
		break;
	case EODbGetCanBeEmpty:
		iOplAPI.Push(((*aColSet)[ind].iAttributes & TDbCol::ENotNull) ? TInt16(0) : TInt16(-1));
		break;
	case EODbGetFieldSize:
		iOplAPI.Push(TInt32((*aColSet)[ind].iMaxLength));
		break;
		}
	CleanupStack::PopAndDestroy(2);	// aColSet, dbase
	}

void COpxOplDb::DbOpen(TBool allowUpdate) const
	{
	TPtrC theTypes = iOplAPI.PopString();
	TPtrC string = iOplAPI.PopString();
	TInt aLog = iOplAPI.PopInt32();
	if (aLog < EDbA || EDbZ < aLog)
		User::Leave(KOplErrOutOfRange);
	COplDbManager* dbManager = iOplAPI.DbManager();
	if (dbManager->GetiLogNames()->FindRowSet(aLog)!=NULL)				 
		User::Leave(KOplErrOpen);
	COplFieldMap* aFieldMap = COplFieldMap::NewLC(theTypes.Length());
	TInt i;
	TBuf<20> fieldName;
	_LIT(KFieldFormat,"F%d");
	for (i = 0; i < theTypes.Length(); i++)
		{
		fieldName.Format(KFieldFormat, i + 1);
		switch (theTypes[i])
			{
		case '%':
			fieldName.Append('%');
			aFieldMap->AppendFieldL(fieldName, 0);
			break;
		case '&':
			fieldName.Append('&');
			aFieldMap->AppendFieldL(fieldName, 1);
			break;
		case '.':
			aFieldMap->AppendFieldL(fieldName, 2);
			break;
		case '$':
			fieldName.Append('$');
			aFieldMap->AppendFieldL(fieldName, 3);
			break;
		case '?':
			aFieldMap->AppendFieldL(fieldName, 4);
			break;
		default:
			User::Leave(KOplErrOutOfRange);
			}
		}
	COplRowSet* aRowSet = COplRowSet::NewL(*(dbManager->OplDbCollection()), 
		iOplAPI.EikonEnv().FsSession(), string, aFieldMap,
		EDbOpen, allowUpdate);
	aRowSet->SetOplFieldMap(aFieldMap);
	CleanupStack::Pop(); // aFieldMap (aRowSet has taken ownership)
	dbManager->GetiLogNames()->AddRowSet(aLog, aRowSet);
	dbManager->UseLog(aLog);
	dbManager->NextL();
	iOplAPI.Push(0.0);
	}

void COpxOplDb::DbStartTable()
	{
	delete iDbColSet;
	iDbColSet = NULL;
	iDbColSet=CDbColSet::NewL();
	iOplAPI.Push(0.0);
	}

void COpxOplDb::DbTableField()
	{
	TInt32 length = iOplAPI.PopInt32();
	TDbColType type = TDbColType(iOplAPI.PopInt32());
	TPtrC fieldName(iOplAPI.PopString());
	if (length < 0 || length > KOplMaxStringFieldLength)
		User::Leave(KOplErrSyntax);
	TDbCol aCol(fieldName, type);
	if (type == EDbColText || type == EDbColBinary)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -