×
Namespaces

Variants
Actions

Navigating through a Symbian DBMS database table

From Nokia Developer Wiki
Jump to: navigation, search

This article demonstrates how to navigate through a table within a Symbian Database Management System (DBMS) database. It extends other DBMS examples available on this wiki.

Note.pngNote: DBMS is the "native" database system on Symbian. SQLite is now present on all current devices

Article Metadata
Article
Created: kiran10182 (30 May 2007)
Last edited: hamishwillee (02 Feb 2012)

Contents

Source code

MyDatabase.h

#ifndef __MYDATABASE_H__
#define __MYDATABASE_H__
 
 
#include <e32std.h>
#include <d32dbms.h> // RDbNamedDatabase
#include <f32file.h> // RFs
 
// for TDesC
#include <e32cmn.h>
 
typedef TBuf<1024> TQueryBuffer;
 
 
//Database name
_LIT(KMyDatabaseName, "DBMSTest.db");
 
// Constants for MyTable Table
//Table name
_LIT(KMyTable, "MyTable");
//MyTable Fields
_LIT(KPrimaryCol, "MyTableId");
_LIT(KNameCol, "Name");
_LIT(KPhoneCol, "Phone");
_LIT(KEMailCol, "EMail");
 
class TMyTableItem
{
public:
TMyTableItem(): iPrimeId(-1){};
public:
TInt iPrimeId;
TBuf8<100> iName;
TBuf8<20> iPhone;
TBuf8<40> iEMail;
public:
inline void Reset()
{
iPrimeId = 0;
iName.Zero();
iPhone.Zero();
iEMail.Zero();
}
};
 
class CMyDatabase : public CBase
{
public: // Creation and destruction
static CMyDatabase* NewL();
~CMyDatabase();
 
 
public:
TInt Close(); // For closing the Database
 
/************************* MyTable Table******************/
//Code Starts - MyTable Table
void CreateMyTableTableL();
void CreateMyTableIndexL();
void DropMyTableTable();
TInt AddMyTableRecord(TMyTableItem& aMyTableItem);
RArray<TMyTableItem> GetMyTableRecordsByKeyL(TDesC& aSearchString);
TBool UpdateMyTableRecord(TMyTableItem& aMyTableItem);
void ReadMyTableItemsL(RArray<TMyTableItem>& aMyTableItemArray);
TBool RemoveMyTableRecord(TMyTableItem& aMyTableItem);
TInt RemoveAllMyTableRecords(TInt& aResultCount);
TBool GetMyTableRecordsById(TInt& Id,TMyTableItem& aMyTableItem);
 
// For Navigation purpose
void PrepareMyTableView();
TBool GetMyTableFirstRecord(TMyTableItem& aMyTableItem);
TBool GetMyTableNextRecord(TMyTableItem& aMyTableItem);
TBool GetMyTablePreviousRecord(TMyTableItem& aMyTableItem);
TBool GetMyTableLastRecord(TMyTableItem& aMyTableItem);
 
// For returning number of records in the MyTable table
TInt GetMyTableCount();
//Code Ends - MyTable Table
 
 
private: // Construction
 
void ConstructL();
CMyDatabase();
 
private: // Member data
RArray<TMyTableItem> aMyTableItemArray;
 
//For checking whether fucntion is returning without any error.
TBool iReturnFlag;
 
//These will help in navigation functions
TBool BookmarkFlag;
TBool iAtBeginningFlag;
TDbBookmark iBookmark;
 
//For Databse manipulation
RFs iFsSession;
RDbNamedDatabase iMyDatabase;
 
//For Navigation purpose
RDbView iMyTableView;
};
 
#endif // __MYDATABASE_H__



MyDatabase.cpp

Database and table construction

#include <bautils.h>    // BaflUtils::FileExists
#include <eikenv.h>
#include "MyDatabase.h"
 
 
// ---------------------------------------------------------------------------
// CMyDatabase::NewL()
//
// Create instance of the MobiCRM database engine.
// ---------------------------------------------------------------------------
CMyDatabase* CMyDatabase::NewL()
{
CMyDatabase* self = new (ELeave)CMyDatabase();
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop();
return self;
}
 
 
 
// ---------------------------------------------------------------------------
// CMyDatabase::ConstructL()
//
// Second phase construction. Leaves, if RFs session cannot be created.
// Database Creation/Open is performed in this 2nd phase constructor
// ---------------------------------------------------------------------------
void CMyDatabase::ConstructL()
{
TInt err = iFsSession.Connect();
if(err)
User::Leave(err);
 
TFileName DBFileName;
// private path with no drive on it
//For e.g: If UID3=0xe42d8cfd, then PrivatePath=\Private\e42d8cfd\
iFsSession.PrivatePath(DBFileName); // So DBFileName= \Private\e42d8cfd\

TFindFile PrivFolder(iFsSession);
// find out the drive
if(KErrNone == PrivFolder.FindByDir(DBFileName, KNullDesC))
{
DBFileName.Copy(PrivFolder.File());
//Now DBFileName= C:\Private\e42d8cfd\DBMSTest.db Or E:\.....
DBFileName.Append(KMyDatabaseName);
 
if(!BaflUtils::FileExists(iFsSession, DBFileName))
{
// no database exists so we make one
User::LeaveIfError(iMyDatabase.Create(iFsSession, DBFileName));
// and will create the onlt table needed for it
CreateMyTableTableL();
 
//Close the database here so next time open it for further operations
Close();
}
else
{
User::LeaveIfError(iMyDatabase.Open(iFsSession, DBFileName));
PrepareMyTableView();
}
}
}
 
 
 
// ---------------------------------------------------------------------------
// CMyDatabase::CMyDatabase()
//
// Constructor
// ---------------------------------------------------------------------------
CMyDatabase::CMyDatabase()
{
}
 
 
 
 
// ---------------------------------------------------------------------------
// CMyDatabase::~CMyDatabase()
//
// Destructor of the MobiCRM database engine. Release resources.
// ---------------------------------------------------------------------------
CMyDatabase::~CMyDatabase()
{
Close(); // Close the Database
iFsSession.Close();
}
 
 
 
// ---------------------------------------------------------------------------
// CMyDatabase::Close()
//
// Close the database.
// ---------------------------------------------------------------------------
TInt CMyDatabase::Close()
{
iMyDatabase.Close();
return KErrNone;
}
 
//Database Operations are completed here




Table operations

Following implemetation is for Table manipulation

//Table operations start here
// ---------------------------------------------------------------------------
// CMyDatabase::PrepareMyTableView()
//
// Prepares the view for Navigation purpose.
// ---------------------------------------------------------------------------
//Prepare global view of the table of Database which will help in navigation.
void CMyDatabase::PrepareMyTableView()
{
//SELECT * FROM MyTable ORDER BY MyTableId
_LIT(KSelect,"SELECT * FROM ");
_LIT(KOrderBy, " ORDER BY ");
 
TQueryBuffer QueryBuffer;
QueryBuffer.Copy(KSelect);
QueryBuffer.Append(KMyTable);
QueryBuffer.Append(KOrderBy);
QueryBuffer.Append(KPrimaryCol);
 
 
iMyTableView.Prepare(iMyDatabase,TDbQuery(QueryBuffer));
iMyTableView.EvaluateAll();
iMyTableView.FirstL();
}
 
 
 
// ---------------------------------------------------------------------------
// CMyDatabase::CreateMyTableTableL()
//
// Creates MyTable table. Leaves, if the table cannot be created.
// ---------------------------------------------------------------------------
void CMyDatabase::CreateMyTableTableL()
{
 
// Specify columns for MyTable table
TDbCol primaryCol(KPrimaryCol, EDbColInt32);
TDbCol nameCol(KNameCol, EDbColText8);
TDbCol phoneCol(KPhoneCol, EDbColText8);
TDbCol emailCol(KEMailCol, EDbColText8);
 
primaryCol.iAttributes= TDbCol::EAutoIncrement;
nameCol.iAttributes= TDbCol::ENotNull;
 
// Add the columns to column set
CDbColSet* MyTableColSet = CDbColSet::NewLC();
MyTableColSet->AddL(primaryCol);
MyTableColSet->AddL(nameCol);
MyTableColSet->AddL(phoneCol);
MyTableColSet->AddL(emailCol);
 
// Create the MyTable table
User::LeaveIfError(iMyDatabase.CreateTable(KMyTable,*MyTableColSet));
CleanupStack::PopAndDestroy(MyTableColSet);
}
 
 
 
 
// ---------------------------------------------------------------------------
// CMyDatabase::AddMyTableRecord()
//
// Add a record to database using RDbView and SQL
// ---------------------------------------------------------------------------
TInt CMyDatabase::AddMyTableRecord(TMyTableItem& aMyTableItem)
{
if(aMyTableItem.iName.Length()==0)
{
return KErrGeneral;
}
 
TQueryBuffer QueryBuffer;
// SELECT * FROM MyTable
QueryBuffer.Copy(_L("SELECT * FROM "));
QueryBuffer.Append(KMyTable);
 
iMyDatabase.Begin();
 
RDbView MyView;
MyView.Prepare(iMyDatabase, TDbQuery(QueryBuffer));
CleanupClosePushL(MyView);
 
MyView.InsertL();
 
MyView.SetColL(2, aMyTableItem.iName);
MyView.SetColL(3, aMyTableItem.iPhone);
MyView.SetColL(4, aMyTableItem.iEMail);
 
MyView.PutL();
 
// Here we are getting autoincremented unique MyTableId.
aMyTableItem.iPrimeId = MyView.ColInt(1);
 
CleanupStack::PopAndDestroy(1); // Myview
iMyDatabase.Commit();
 
iMyTableView.Reset();
PrepareMyTableView();
 
GetMyTableLastRecord(aMyTableItem);
return KErrNone;
}
 
 
 
 
// ---------------------------------------------------------------------------
// CMyDatabase::DropMyTableTable()
//
// Drop the MyTable table incrementally. Uses RDbIncremental and DDL statement.
// ---------------------------------------------------------------------------
void CMyDatabase::DropMyTableTable()
{
 
_LIT(KDropTable, "DROP TABLE ");
 
// Sql: DROP TABLE MyTable
TQueryBuffer sqlStr;
sqlStr.Append(KDropTable);
sqlStr.Append(KMyTable);
 
RDbIncremental incOp;
TInt incStep = 0xFFFF;
// Initialise Execution
TInt incStat = incOp.Execute(iMyDatabase, sqlStr, incStep);
while (incStep>0 && incStat==KErrNone)
{
incStat = incOp.Next(incStep); // Do the work
}
incOp.Close();
}
 
 
 
 
// ---------------------------------------------------------------------------
// CMyDatabase::ReadMyTableItemsL()
//
//This will read all the records of MyTable table
//and Stores in aMyTableItemArray RArray
// ---------------------------------------------------------------------------
void CMyDatabase::ReadMyTableItemsL(RArray<TMyTableItem>& aMyTableItemArray)
{
aMyTableItemArray.Reset();// first reset the array
 
TQueryBuffer QueryBuffer;
// SELECT * FROM MyTable
QueryBuffer.Copy(_L("SELECT * FROM "));
QueryBuffer.Append(KMyTable);
 
RDbView Myview;
Myview.Prepare(iMyDatabase,TDbQuery(QueryBuffer));
CleanupClosePushL(Myview);
Myview.EvaluateAll();
Myview.FirstL();
 
// Just delete one instance of the message
while(Myview.AtRow())
{
Myview.GetL();
 
TMyTableItem NewItem;
NewItem.iPrimeId = Myview.ColInt(1);
NewItem.iName.Copy(Myview.ColDes8(2));
NewItem.iPhone.Copy(Myview.ColDes8(3));
NewItem.iEMail.Copy(Myview.ColDes8(4));
 
// Append the record in the RArray
aMyTableItemArray.Append(NewItem);
 
Myview.NextL();
}
CleanupStack::PopAndDestroy(1); // Myview
}
 
 
 
 
// ---------------------------------------------------------------------------
// CMyDatabase::GetMyTableRecordsByKeyL()
//
//This will read all the records of MyTable table
//and Stores in aMyTableItemArray RArray as per "Search String" supplied
// ---------------------------------------------------------------------------
RArray<TMyTableItem> CMyDatabase::GetMyTableRecordsByKeyL(TDesC& aSearchString)
{
RArray<TMyTableItem> aMyTableItemArray;
aMyTableItemArray.Reset();// first reset the array
 
//SELECT * FROM MyTable WHERE Name LIKE 'aSearchString' ORDER BY MyTableId
_LIT(KSelect,"SELECT * FROM ");
_LIT(KWhere, " WHERE ");
_LIT(KLike, " LIKE '");
_LIT(KOrderBy, "' ORDER BY ");
 
TQueryBuffer QueryBuffer;
QueryBuffer.Copy(KSelect);
QueryBuffer.Append(KMyTable);
QueryBuffer.Append(KWhere);
QueryBuffer.Append(KNameCol);
QueryBuffer.Append(KLike);
QueryBuffer.Append(aSearchString);
QueryBuffer.Append(KOrderBy);
QueryBuffer.Append(KPrimaryCol);
 
 
RDbView Myview;
Myview.Prepare(iMyDatabase,TDbQuery(QueryBuffer));
CleanupClosePushL(Myview);
Myview.EvaluateAll();
Myview.FirstL();
 
// Just delete one instance of the message
while(Myview.AtRow())
{
Myview.GetL();
 
TMyTableItem NewItem;
NewItem.iPrimeId = Myview.ColInt(1);
NewItem.iName.Copy(Myview.ColDes8(2));
NewItem.iPhone.Copy(Myview.ColDes8(3));
NewItem.iEMail.Copy(Myview.ColDes8(4));
 
// Append the record in the RArray
aMyTableItemArray.AppendL(NewItem);
Myview.NextL();
}
CleanupStack::PopAndDestroy(1); // Myview
 
return aMyTableItemArray;
}
 
 
 
 
// ---------------------------------------------------------------------------
// CMyDatabase::RemoveMyTableRecord()
//
// Delete a record on PrimaryKey col base
// ---------------------------------------------------------------------------
TBool CMyDatabase::RemoveMyTableRecord(TMyTableItem& aMyTableItem)
{
//Get the value of Primary key in local variable
TInt aPrimeId = aMyTableItem.iPrimeId;
aMyTableItem.Reset(); // Reset the RArray to determine correct result
 
iReturnFlag = EFalse;
_LIT(KSelect,"SELECT * FROM ");
_LIT(KWhere, " WHERE ");
_LIT(KEqual," = ");
 
// Sql: DELETE FROM MyTable WHERE MyTableId = aPrimeId
TQueryBuffer QueryBuffer;
QueryBuffer.Copy(KSelect);
QueryBuffer.Append(KMyTable);
QueryBuffer.Append(KWhere);
QueryBuffer.Append(KPrimaryCol);
QueryBuffer.Append(KEqual);
QueryBuffer.AppendNum(aPrimeId);
 
iMyDatabase.Begin();
 
RDbView Myview;
// Prepare the view with the formed query.
Myview.Prepare(iMyDatabase,TDbQuery(QueryBuffer));
CleanupClosePushL(Myview);
 
Myview.EvaluateAll();
Myview.FirstL();
 
// we have autoincrement in index so it should be unique
// but just to make sure, we use 'while', instead of 'if'
while(Myview.AtRow())
{
if(iAtBeginningFlag)
{
Myview.GetL();
Myview.DeleteL();
Myview.NextL();
iMyTableView.Reset();
PrepareMyTableView();
GetMyTableFirstRecord(aMyTableItem);
iAtBeginningFlag = EFalse;
iReturnFlag = ETrue;
break;
}
GetMyTablePreviousRecord(aMyTableItem);
Myview.GetL();
Myview.DeleteL();
Myview.NextL();
iReturnFlag = ETrue;
}
 
CleanupStack::PopAndDestroy(1); // Myview
iMyDatabase.Commit();
// compacts the databse, by physicaly removig deleted data.
iMyDatabase.Compact();
 
if(iReturnFlag)
{
iMyTableView.Reset();
PrepareMyTableView();
if(iAtBeginningFlag)
{
aMyTableItem.Reset();
GetMyTableFirstRecord(aMyTableItem);
}
if(BookmarkFlag)
{
iMyTableView.GotoL(iBookmark);
}
}
return iReturnFlag;
}
 
 
 
 
// ---------------------------------------------------------------------------
// CMyDatabase::RemoveAllMyTableRecords()
//
// Delete records using asynchronous API. (RDbUpdate and DML)
// This implementation is still synchronous, because it uses
// User::WaitForRequest. Normally asynchronous functionality should be hidden
// into active object and client callback interfaces.
// ---------------------------------------------------------------------------
TInt CMyDatabase::RemoveAllMyTableRecords(TInt& aResultCount)
{
_LIT(KDeleteFrom, "DELETE FROM ");
 
// Sql: DELETE FROM MyTable
TQueryBuffer QueryBuffer;
QueryBuffer.Copy(KDeleteFrom);
QueryBuffer.Append(KMyTable);
 
RDbUpdate updOp;
TRequestStatus incStat(1);
TInt updStat = updOp.Execute(iMyDatabase, QueryBuffer, EDbCompareFolded);
while (updStat==KErrNone && incStat ==1)
{
updOp.Next(incStat); // Start async operation. It returns
// immediately.
User::WaitForRequest(incStat); // For simplicity wait completion here.
}
 
aResultCount = updOp.RowCount();
updOp.Close();
 
if(updStat!=KErrNone)
return updStat; // System wide error code
else
return incStat.Int(); // KErrNone or system wide error code
}
 
 
 
 
// ---------------------------------------------------------------------------
// CMyDatabase::UpdateMyTableRecord()
//
// Update the table with the newer values
// supplied in the TMyTableItem reference argument.
// Here RDbView is used for updating values.
// ---------------------------------------------------------------------------
TBool CMyDatabase::UpdateMyTableRecord(TMyTableItem& aMyTableItem)
{
iReturnFlag = EFalse;
TQueryBuffer QueryBuffer;
QueryBuffer.Copy(_L("SELECT * FROM "));
QueryBuffer.Append(KMyTable);
QueryBuffer.Append(_L(" WHERE "));
QueryBuffer.Append(KPrimaryCol);
QueryBuffer.Append(_L(" = "));
QueryBuffer.AppendNum(aMyTableItem.iPrimeId);
 
iMyDatabase.Begin();
 
RDbView Myview;
Myview.Prepare(iMyDatabase, TDbQuery(QueryBuffer));
CleanupClosePushL(Myview);
 
Myview.EvaluateAll();
Myview.FirstL();
 
if(Myview.AtRow())
{
Myview.UpdateL();
Myview.SetColL(2, aMyTableItem.iName);
Myview.SetColL(3, aMyTableItem.iPhone);
Myview.SetColL(4, aMyTableItem.iEMail);
Myview.PutL();
iReturnFlag = ETrue; //No error
}
CleanupStack::PopAndDestroy(1); // Myview
iMyDatabase.Commit();
 
return iReturnFlag;
}
 
 
 
 
// ---------------------------------------------------------------------------
// CMyDatabase::GetMyTableRecordsById()
//
// Fetch the record values on the basis of matching Id
// Stores the resultant data in the supplied TMyTableItem reference argument.
// Here RDbView is used for updating values.
// ---------------------------------------------------------------------------
TBool CMyDatabase::GetMyTableRecordsById(TInt& Id,TMyTableItem& NewItem)
{
iReturnFlag = EFalse;
//SELECT * FROM MyTable WHERE MyTableId = Id ORDER BY MyTableId
_LIT(KSelect,"SELECT * FROM ");
_LIT(KWhere, " WHERE ");
_LIT(KSearch," = ");
_LIT(KOrderBy, " ORDER BY ");
 
TQueryBuffer QueryBuffer;
QueryBuffer.Copy(KSelect);
QueryBuffer.Append(KMyTable);
QueryBuffer.Append(KWhere);
QueryBuffer.Append(KPrimaryCol);
QueryBuffer.Append(KSearch);
QueryBuffer.AppendNum(Id);
QueryBuffer.Append(KOrderBy);
QueryBuffer.Append(KPrimaryCol);
 
 
RDbView Myview;
Myview.Prepare(iMyDatabase,TDbQuery(QueryBuffer));
CleanupClosePushL(Myview);
Myview.EvaluateAll();
Myview.FirstL();
 
// Just delete one instance of the message
while(Myview.AtRow())
{
Myview.GetL();
 
NewItem.iPrimeId = Myview.ColInt(1);
NewItem.iName.Copy(Myview.ColDes8(2));
NewItem.iPhone.Copy(Myview.ColDes8(3));
NewItem.iEMail.Copy(Myview.ColDes8(4));
 
Myview.NextL();
iReturnFlag = ETrue;
}
CleanupStack::PopAndDestroy(1); // Myview
return iReturnFlag;
}



Navigation Functions

Following functions are implemented for navigation purpose.

/*************************Navigation functions********************************/
//Following function is implemented to navigate
//in the Next Direction in the Table view
TBool CMyDatabase::GetMyTableNextRecord(TMyTableItem& NewItem)
{
iAtBeginningFlag = EFalse;
BookmarkFlag=EFalse;
iReturnFlag = EFalse;
if(iMyTableView.AtRow())
{
iMyTableView.NextL();
if(iMyTableView.AtEnd())
{
iMyTableView.LastL();
return EFalse;
}
iMyTableView.GetL();
NewItem.iPrimeId = iMyTableView.ColInt(1);
NewItem.iName.Copy(iMyTableView.ColDes8(2));
NewItem.iPhone.Copy(iMyTableView.ColDes8(3));
NewItem.iEMail.Copy(iMyTableView.ColDes8(4));
 
iReturnFlag = ETrue;
}
return iReturnFlag;
}
 
 
//Following function is implemented to navigate
//on the First record of the Table view
TBool CMyDatabase::GetMyTableFirstRecord(TMyTableItem& NewItem)
{
iAtBeginningFlag = EFalse;
BookmarkFlag=EFalse;
iReturnFlag = EFalse;
if(iMyTableView.AtRow())
{
iMyTableView.FirstL();
if(iMyTableView.AtEnd())
return EFalse;
iMyTableView.GetL();
NewItem.iPrimeId = iMyTableView.ColInt(1);
NewItem.iName.Copy(iMyTableView.ColDes8(2));
NewItem.iPhone.Copy(iMyTableView.ColDes8(3));
NewItem.iEMail.Copy(iMyTableView.ColDes8(4));
iReturnFlag = ETrue;
iAtBeginningFlag = ETrue;
}
return iReturnFlag;
}
 
 
//Following function is implemented to navigate
//in the Previous Direction in the Table view
TBool CMyDatabase::GetMyTablePreviousRecord(TMyTableItem& NewItem)
{
iAtBeginningFlag = EFalse;
iReturnFlag = EFalse;
if(iMyTableView.AtRow())
{
iMyTableView.PreviousL();
if(iMyTableView.AtBeginning())
{
iMyTableView.FirstL();
BookmarkFlag=EFalse;
iAtBeginningFlag = ETrue;
return EFalse;
}
iMyTableView.GetL();
NewItem.iPrimeId = iMyTableView.ColInt(1);
NewItem.iName.Copy(iMyTableView.ColDes8(2));
NewItem.iPhone.Copy(iMyTableView.ColDes8(3));
NewItem.iEMail.Copy(iMyTableView.ColDes8(4));
iBookmark = iMyTableView.Bookmark();
iReturnFlag = ETrue;
BookmarkFlag = ETrue;
}
return iReturnFlag;
}
 
 
//Following function is implemented to navigate
//on the Last record of the Table view
TBool CMyDatabase::GetMyTableLastRecord(TMyTableItem& NewItem)
{
iAtBeginningFlag = EFalse;
BookmarkFlag = EFalse;
iReturnFlag = EFalse;
if(iMyTableView.AtRow())
{
iMyTableView.LastL();
if(iMyTableView.AtEnd())
return EFalse;
iMyTableView.GetL();
NewItem.iPrimeId = iMyTableView.ColInt(1);
NewItem.iName.Copy(iMyTableView.ColDes8(2));
NewItem.iPhone.Copy(iMyTableView.ColDes8(3));
NewItem.iEMail.Copy(iMyTableView.ColDes8(4));
iReturnFlag = ETrue;
}
return iReturnFlag;
}
/***************************Navigation ends here******************************/



Following function gives number of the record in the Table of the Database.

TInt CMyDatabase::GetMyTableCount()
{
TQueryBuffer QueryBuffer;
//SELECT * FROM MyTable
QueryBuffer.Copy(_L("SELECT * FROM "));
QueryBuffer.Append(KMyTable);
 
RDbView Myview;
Myview.Prepare(iMyDatabase,TDbQuery(QueryBuffer));
CleanupClosePushL(Myview);
Myview.EvaluateAll();
TInt RecordCount=Myview.CountL();
CleanupStack::PopAndDestroy(1); // Myview
return RecordCount;
}
// Code Ends - MyTable table



Related Links

This page was last modified on 2 February 2012, at 07:33.
89 page views in the last 30 days.