summaryrefslogtreecommitdiffstats
path: root/plugins/contacts/symbian/contactsmodel/cntdbdumper/src/dbdbmsdumper.cpp
blob: 0134517d34fe87b15eff294f3e9f99095b686a1b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
/*
* Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
* Contact: http://www.qt-project.org/legal
* 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: 
*
*/


/**
 @file
 @internalComponent
 @released
*/

#include <e32test.h>
#include <s32mem.h>
#include <badesca.h> //for cdescarray
#include <cntstd.h>
#include "dbdbmsdumper.h"
#include "dbhtmltags.h"
#include <coreappstest\testserver.h>

_LIT(KErrorMessage, "DBDbmsDumper Failed");
const TInt KMaxPathLength = 100;
const TInt KBufferLength = 80;

/**
Class destructor
*/
CDbDbmsDumper::~CDbDbmsDumper()
	{
	delete iBuffer;
	delete iTableNames;
	iFile.Close();
	iDatabase.Close();
	iDbsSession.Close();
	iFsSession.Close();
	}

/**
Second phase constructor for CDbDbmsDumper

@param  aDbName name of the database to be dumped.
@param	aOutputDir directory where html file will be generated		
*/	
void CDbDbmsDumper::ConstructL(const TDesC& aDbName, const TDesC& aOutputDir)
	{
	// Output File Name	
	_LIT(KOutputFile,"DbDump.html");
	TBuf<KMaxPathLength> path(aOutputDir);
	path.Append(KOutputFile);
	
	User::LeaveIfError(iFsSession.Connect());
	User::LeaveIfError(iDbsSession.Connect());

	// Copy the Contacts database from the contacts server private directory to 
	// the DBMS private directory
	RPIMTestServer serv;
	User::LeaveIfError(serv.Connect());
	
	_LIT(KDBContactsPrivFile, "?:\\private\\10003a73\\Contacts.cdb");
	_LIT(KDBDBMsPrivFile, "?:\\private\\100012a5\\DBS_100065FF_Contacts.cdb");
	
	TBuf<sizeof(KDBContactsPrivFile)> contactsDBPrivFilePath(KDBContactsPrivFile);
	TBuf<sizeof(KDBDBMsPrivFile)> dBMsPrivFilePath(KDBDBMsPrivFile);
	
	contactsDBPrivFilePath[0] = (TUint8) RFs::GetSystemDriveChar();
	dBMsPrivFilePath[0] = (TUint8) RFs::GetSystemDriveChar();
	
	serv.CopyFileL(contactsDBPrivFilePath, dBMsPrivFilePath);
	serv.Close();

	_LIT(KCntDbSecureFormat,"secure[100065FF]");

	// Contact databases are in DBMS private directory
	User::LeaveIfError(iDatabase.Open(iDbsSession, aDbName, KCntDbSecureFormat));
	User::LeaveIfError(iFile.Replace(iFsSession, path, EFileWrite) );

	iBuffer = HBufC8::NewL(KBufferLength);
	iTableNames = iDatabase.TableNamesL();
	}

/**
Return a concrete CDbDbmsDumper object

@param  aDbName name of the database to be dumped.
@param	aOutputDir directory where html file will be generated		
*/	
CDbDbmsDumper* CDbDbmsDumper::NewLC(const TDesC& aDbName, const TDesC& aOutputDir)
	{
	CDbDbmsDumper* self = new (ELeave) CDbDbmsDumper();
	CleanupStack::PushL(self);
	self->ConstructL(aDbName, aOutputDir);
	return self;
	}

/**
Returns number of tables that exist in the curent dbms database

*/
TInt CDbDbmsDumper::NumberOfTables() const
	{
	return iTableNames->Count();
	}

/**
Output one table to the html file. Traverse a table and output each row
in the html file

@param 	aTableIndex table index in the table array

*/
void CDbDbmsDumper::OutputTableToFileL(TInt aTableIndex) 
	{
	iFile.Write(KTable);
	OutputTableNameToFile(aTableIndex);
	CDesCArray* colNames = OutputTableColHeadingsToFileLC(aTableIndex);
	User::LeaveIfError(iDbTable.Open(iDatabase, (*iTableNames)[aTableIndex], RDbRowSet::EReadOnly) );
	User::LeaveIfError(iDbTable.SetNoIndex() );    // set rowset order as underlying row order       
	iDbTable.BeginningL();            // set cursor to start of table
	iDbTable.NextL();
	
	// output the table's rows
	while (!iDbTable.AtEnd() )
		{
		iFile.Write(KRow);
		OutputTableColDataToFileL(*colNames);
		iDbTable.NextL();
		iFile.Write(KRowEnd);	
		}

	iDbTable.Close();
	iFile.Write(KTableEnd);
	CleanupStack::PopAndDestroy(colNames);
	}

/**
Output table name to the html file

@param 	aTableIndex table index in the table array

*/
void CDbDbmsDumper::OutputTableNameToFile(TInt aTableIndex)
	{
	iFile.Write(KBold);	
	iBuffer->Des().Copy( (*iTableNames)[aTableIndex]); // write (*iTableNames)[aTableIndex] to the file.
	iFile.Write(*iBuffer);
	iFile.Write(KBoldEnd);
	}

/**
Outputs table header for the tables created in the html file
The header contains the column names

@param 	aTableIndex table index in the table array

*/
CDesCArray* CDbDbmsDumper::OutputTableColHeadingsToFileLC(TInt aTableIndex)
	{
	CDesCArraySeg* colNames = new (ELeave) CDesCArraySeg(8);
	CleanupStack::PushL(colNames);
	CDbColSet* colSet = iDatabase.ColSetL( (*iTableNames)[aTableIndex] );
	CleanupStack::PushL(colSet);
	const TInt KMaxCols( (colSet->Count() ) );  
	TInt counter = 0;
    iFile.Write(KHdRow);

	// cols are from 1, to maxCols. not from 0 to maxCols-1.
	for (counter = 1; counter <= KMaxCols; ++counter)
		{
		iFile.Write(KCell);
		iBuffer->Des().Copy( (*colSet)[counter].iName );
		colNames->AppendL((*colSet)[counter].iName);
		iFile.Write(*iBuffer);
		iFile.Write(KCellEnd);
		}

    iFile.Write(KRowEnd);
	CleanupStack::PopAndDestroy(colSet);
	return colNames;
	}

/**
Output a table row to the html file

@param colNames descriptor array containing rows to be written in the resulting html file

*/
void CDbDbmsDumper::OutputTableColDataToFileL(const CDesCArray& colNames)
	{
	TInt counter = 0;
	const TInt KNumberOfCols( (iDbTable.ColCount() ));  
	iDbTable.GetL(); // get the row to be output

    // cols are from 1, to maxCols. not from 0 to KNumberOfCols-1.
	for (counter = 1; counter <= KNumberOfCols; ++counter)   // for each column value in this row 
		{
		iFile.Write(KCell);

		if (iDbTable.IsColNull(counter) )
			{
			iBuffer->Des().Format(KNullCol); // write out 'NULL' to the file
			}
		else
			{
			switch ( iDbTable.ColType(counter) )
				{
				case EDbColInt8:
				case EDbColInt16:
				case EDbColInt32:
					{
					TInt32 val = iDbTable.ColInt32(counter); 
					iBuffer->Des().Format(KInt32String, val);
					}
				break;
				case EDbColBit:
				case EDbColUint8:
				case EDbColUint16:
				case EDbColUint32:
					{
					TUint32 val = iDbTable.ColUint32(counter); 
					iBuffer->Des().Format(KUInt32String, val);
					}
				break;
				case EDbColInt64:
					{
					TInt64 val = iDbTable.ColInt64(counter);
					iBuffer->Des().Format(KUInt64String, I64HIGH(val), I64LOW(val) );
					}
				break;
				case EDbColReal32:
					{
					TReal32 val = iDbTable.ColReal32(counter);
					iBuffer->Des().Format(KRealString, val);
					}
				break;
				case EDbColReal64:
					{
					TReal64 val = iDbTable.ColReal64(counter);
					iBuffer->Des().Format(KRealString, val);
					}
				break;
				case EDbColDateTime:
					{
					TTime val = iDbTable.ColTime(counter);
					TBuf<80> tmpBuffer;
					val.FormatL(tmpBuffer, KFormatDate);
					iBuffer->Des().Copy(tmpBuffer);
					}
				break;
				case EDbColBinary:
				case EDbColText8:
					{
					TPtrC8 val = iDbTable.ColDes8(counter);
					iBuffer->Des().Copy(val);
					}
				break;
				case EDbColText16:
					{
					TPtrC16 val = iDbTable.ColDes16(counter);
					iBuffer->Des().Copy(val);
					}
				break;
				case EDbColLongText8:
					iBuffer->Des().Format(KLongText8);   
				break;
				case EDbColLongText16:
					LongBinaryL(counter);
				break;
				case EDbColLongBinary:
					if (colNames[counter-1] == KFieldHeaderColName)
						{
						FieldHeaderColL(counter);
						}
					else 
						{
						LongBinaryL(counter);
						}
				break;
				default:
					iBuffer->Des().Format(KUnknownMessage);
				break;
				} // switch
			} // if

		iFile.Write(*iBuffer);
		iFile.Write(KCellEnd);
		
		} // for
	}


/**
Output the header blob to resulting html file

@param aFieldIndex column index containing the header values in dbms database

*/
void CDbDbmsDumper::FieldHeaderColL(TInt aFieldIndex)
	{
	TAutoClose<RDbColReadStream> headerBlob;
	TAutoClose<RStoreReadStream> stream;

	headerBlob.iObj.OpenL(iDbTable, aFieldIndex);
	CEmbeddedStore* headerStore=CEmbeddedStore::FromLC(headerBlob.iObj);
	stream.iObj.OpenLC(*headerStore, headerStore->Root());

	DumpStreamL(stream.iObj);

	CleanupStack::PopAndDestroy(&stream.iObj); //OpenLC
	CleanupStack::PopAndDestroy(headerStore);
	}

/**
Output the values stored in binary blob fields in dbms database

@param aFieldIndex column index containing the binary values in dbms database

*/
void CDbDbmsDumper::LongBinaryL(TInt aFieldIndex)
	{
	TAutoClose<RDbColReadStream> rdStream;
	rdStream.iObj.OpenL(iDbTable,aFieldIndex);
	
	DumpStreamL(rdStream.iObj);
	}

/**
Utility method. Used to read from read stream and output to html file

*/
void CDbDbmsDumper::DumpStreamL(RReadStream& stream)
	{
	const TInt KStreamSize = stream.Source()->SizeL();

	iFile.Write(KDumpFont);

	_LIT8(KSizeMessage, "size is %d <BR>");
	_LIT8(KEightSpaces, "        ");
	_LIT8(KByteFormat, "%02x&nbsp;");
	_LIT8(KFormatString, "%S&nbsp;<BR>\r\n");

	iBuffer->Des().Format(KSizeMessage, KStreamSize);
	iFile.Write(*iBuffer);

	TBuf8<8> str(KEightSpaces); //Reserve 8 symbols

	TInt counter(0);
	while (counter < KStreamSize)
		{
		for(TInt i=0; i < 8; ++i)
			{
			if (counter >= KStreamSize)
				{
				break;	
				}
			//format byte in a printable character	
			TInt8 byte( stream.ReadInt8L() );
			iBuffer->Des().Format(KByteFormat, byte);
			iFile.Write(*iBuffer);
			
			 str[i] = (byte>32 ? byte : '.');
			++counter;
			}
		iBuffer->Des().Format(KFormatString, &str);
		iFile.Write(*iBuffer);
		}

	iFile.Write(KDumpFontEnd);
	}

/**
Dump the content of a dbms database in a html file

*/
void CDbDbmsDumper::OutputDBContentsL()    
	{
	// Output Title
	_LIT8(KHdr,"<H2>Contacts Model DB Dump:</H2>");
	iFile.Write(KHdr);
	
	// Preferences Table Name that will appear first in the output file
	_LIT(KPrefTableName,"PREFERENCES");
	
	TInt counter = 0;
	const TInt KNumTables( (iTableNames->Count() )); 
	TBool outputPrefTable( (EFalse) );
	
	// if a Table named Preferences Exists in the DB output it first
	while (!outputPrefTable && counter < KNumTables)
		{
	    if ((*iTableNames)[counter++].Compare(KPrefTableName) == 0)
			{
			OutputTableToFileL(--counter);
			outputPrefTable = ETrue;
	   		}
	    }
	
	// for each table - output all tables except the Preferences Table	
	for (counter = 0; counter < KNumTables; ++counter)
		{
		if ((*iTableNames)[counter].Compare(KPrefTableName) != 0)
			{
			OutputTableToFileL(counter);
			}
		}			
	}

void RunDumpL()
	{
	// Location of Output Directory. (File will be called DbDump.html). Final "\" required on path.   
	_LIT(KOutputDir, "?:\\");	
	TBuf<sizeof(KOutputDir)> outputDir(KOutputDir);
	outputDir[0] = (TUint8) RFs::GetSystemDriveChar();
	
	// Location of Contacts DB
	_LIT(KDBName, "?:Contacts.cdb");	
	TBuf<sizeof(KDBName)> fileDBName(KDBName);
	fileDBName[0] = (TUint8) RFs::GetSystemDriveChar();
	
	// dump dbms database 
	CDbDbmsDumper* dbmsDumper = CDbDbmsDumper::NewLC(fileDBName, outputDir);
    dbmsDumper->OutputDBContentsL();   
	CleanupStack::PopAndDestroy(dbmsDumper);   
	}

GLDEF_C TInt E32Main()
	{
	__UHEAP_MARK;
	CActiveScheduler* scheduler = new CActiveScheduler;
	if (scheduler)
		{
		CActiveScheduler::Install(scheduler);
		CTrapCleanup* cleanup = CTrapCleanup::New();
		if (cleanup)
			{
			TRAPD(err,RunDumpL() );	
			__ASSERT_ALWAYS(err == KErrNone, User::Panic(KErrorMessage,err) ); 
			delete cleanup;
			}
		delete scheduler;
		}
	__UHEAP_MARKEND;
	return KErrNone;
    }