1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/persistentdata/persistentstorage/sql/TEST/testexecute/SQLite/src/sqlfn.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,2365 @@
1.4 +// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// It would have been nice to create a new object every time we jump to
1.18 +// a new config block but reporting (INFO_PRINTF and ERR_PRINTF) doesn't
1.19 +// work from sub-objects. All in all the structure isn't what I'd like,
1.20 +// perhaps I'm missing some TEF functionality which would get around this.
1.21 +// Various bits of repetition may be removed into utility class(es).
1.22 +// Some utility methods probably should go into utility class(es).
1.23 +// Unimplemented 8-bit methods, e.g Exec8.
1.24 +//
1.25 +//
1.26 +
1.27 +#include "sqlfn.h"
1.28 +#include "Te_SQL_SuiteDefs.h"
1.29 +#include "common.h"
1.30 +
1.31 +// Contains code to perform functions on SQLite databases - what functions
1.32 +// and in what order is determined by the content of the config (.ini) file.
1.33 +
1.34 +CSQLFnStep::~CSQLFnStep()
1.35 +/**
1.36 + * Destructor
1.37 + */
1.38 + {
1.39 + // Get rid of the RFs object.. Note this isn't set up in the constructor
1.40 + // but in doTestStepL.
1.41 + irfs.Close();
1.42 +
1.43 + // Get rid of the semaphore objects.
1.44 + isemA.Close();
1.45 + isemB.Close();
1.46 +
1.47 + // Get rid of the hashes. These are originally set up in doTestStepL.
1.48 + delete ierrhsh;
1.49 + delete icoltypehsh;
1.50 + delete iactionhsh;
1.51 + delete icaphsh;
1.52 + delete ipolhsh;
1.53 + delete iobjhsh;
1.54 +
1.55 + // Get rid of the config item.
1.56 + if(icfg)delete icfg;
1.57 + }
1.58 +CSQLFnStep::CSQLFnStep()
1.59 + {
1.60 + // Create a global semaphore to be used by all instances of this framework
1.61 + // to be used for synchronising separate threads when 'CONCURRENT' is
1.62 + // used. If it already exists, then perhaps another thread already has it
1.63 + // which is fine - in that case just open it.
1.64 + TInt err = isemA.CreateGlobal(_L("SQLiteSemA"), 0);
1.65 + if(err == KErrAlreadyExists)
1.66 + {
1.67 + err = isemA.OpenGlobal(_L("SQLiteSemA"));
1.68 + }
1.69 + if(err != KErrNone)
1.70 + {
1.71 + INFO_PRINTF2(_L("Error %d creating semaphore"), err);
1.72 + __ASSERT_ALWAYS(err == KErrNone, User::Invariant());
1.73 + }
1.74 +
1.75 + //
1.76 + // Second semaphore require for DEF140385.
1.77 + //
1.78 + err = isemB.CreateGlobal(_L("SQLiteSemB"), 0);
1.79 + if(err == KErrAlreadyExists)
1.80 + {
1.81 + err = isemB.OpenGlobal(_L("SQLiteSemB"));
1.82 + }
1.83 + if(err != KErrNone)
1.84 + {
1.85 + INFO_PRINTF2(_L("Error %d creating semaphoreB"), err);
1.86 + __ASSERT_ALWAYS(err == KErrNone, User::Invariant());
1.87 + }
1.88 + }
1.89 +TVerdict CSQLFnStep::doTestStepPostambleL()
1.90 + {
1.91 + // Try to make sure that the database and statement resources have been
1.92 + // properly closed (in case of problems).
1.93 + isqlst.Close();
1.94 + isqldb.Close();
1.95 + return TestStepResult();
1.96 + }
1.97 +TVerdict CSQLFnStep::doTestStepL()
1.98 +/**
1.99 + * @return - TVerdict code
1.100 + * Override of base class pure virtual. Our implementation only gets called
1.101 + * if the base class doTestStepPreambleL() did not leave. That being the case,
1.102 + * the current test result value will be EPass.
1.103 + */
1.104 + {
1.105 + // Create the RFs object so we can talk to the file-system when necessary.
1.106 + // Moved from the constructor to shut up leavescan.
1.107 + User::LeaveIfError(irfs.Connect());
1.108 + irfs.ShareProtected();
1.109 +
1.110 + // Make sure the database and statement objects get cleaned up..
1.111 + CleanupClosePushL(isqldb);
1.112 + CleanupClosePushL(isqlst);
1.113 +
1.114 + // Make sure that the icfg member is definitely unset when we start.
1.115 + icfg = NULL;
1.116 +
1.117 + // Get the hashes we use to associate words with numbers (e.g
1.118 + // KErrNone with 0). If these fail due to lack of memory they will
1.119 + // PANIC, which is fine. If we're that short of memory nothing is
1.120 + // going to work anyway.
1.121 + ierrhsh = new CSQLErrHash();
1.122 + icoltypehsh = new CSQLColTypeHash();
1.123 + iactionhsh = new CSQLTEFAction();
1.124 + icaphsh = new CSQLCapability();
1.125 + ipolhsh = new CSQLPolicy();
1.126 + iobjhsh = new CSQLObject();
1.127 +
1.128 + // Set the test result to PASS to start with and call the main block..
1.129 + SetTestStepResult(EPass);
1.130 + SQLDbStepL(ConfigSection());
1.131 +
1.132 + // Clean up the database and statement objects.
1.133 + CleanupStack::PopAndDestroy(2, &isqldb);
1.134 +
1.135 + return TestStepResult();
1.136 + }
1.137 +// This is our 'main' function. It works out what method (e.g RSqlStatement::
1.138 +// Close) the user wants (based on the configuration file) and then calls
1.139 +// the appropriate wrapper function which runs the wanted method and reports
1.140 +// on any unexpected errors.
1.141 +void CSQLFnStep::SQLDbStepL(const TPtrC& acfgblk)
1.142 + {
1.143 + _LIT(KTestFunction, "SQLDbStep");
1.144 +
1.145 + /*
1.146 + * Go through all of the actions defined in the configuration file
1.147 + * acting on each. The counter will keep incrementing until we
1.148 + * fail to find a config item called 'CreateNN', or 'OpenNN' etc.
1.149 + * The two arrays hold Parameter and Column indices for use in
1.150 + * any method that needs one. E.G..
1.151 + */
1.152 + TInt ended=0;
1.153 +
1.154 + iasync = i8bit = EFalse;
1.155 + for(TInt count=0 ; ; count++)
1.156 + {
1.157 + TPtrC argument;
1.158 + TInt whatfun=Efn_undefined;
1.159 + for(TInt i=0 ; i < Efn_undefined ; i++)
1.160 + {
1.161 + // Construct something like 'ColumnInt37'
1.162 + TBuf<KStatementFunMaxLength> stfn(*(iactionhsh->GetStringFromNum(i)));
1.163 + stfn.AppendNum(count);
1.164 +
1.165 + // Does it exist in the config file? If not try e.g 'ColumnReal37'
1.166 + if(!GetStringFromConfig(acfgblk, stfn, argument))
1.167 + continue;
1.168 +
1.169 + whatfun = i;
1.170 + if(whatfun == Ectrl_endblock)
1.171 + ended = 1;
1.172 + // The GetString was successful, so we drop out anyway.
1.173 + break;
1.174 + }
1.175 + // If we hit an EndBlock marker or couldn't find any keyword with
1.176 + // the current counter number then drop out.
1.177 + if((whatfun == Efn_undefined) || (whatfun == Ectrl_endblock))
1.178 + break;
1.179 +
1.180 + // If there's a comma in the argument, split it up. We do
1.181 + // this here (rather than, more logically, in the called methods)
1.182 + // because we'd end up repeating the 'CommaSeparated' call in
1.183 + // all of the wrapper methods. Also, we need the indices for
1.184 + // Column and Parameter index resolution.
1.185 + TInt arg1, arg2;
1.186 + TPtrC arg3;
1.187 + CommaSeparated(argument, arg1, arg2);
1.188 + CommaSeparated(argument, arg1, arg3);
1.189 +
1.190 + TInt err=0;
1.191 + switch(whatfun)
1.192 + {
1.193 + case Efn_nop: break;
1.194 + // First the RSqlDatabase methods...
1.195 + case Efn_create:
1.196 + Create(argument, acfgblk, count);
1.197 + break;
1.198 + case Efn_createl:
1.199 + CreateL_(argument, acfgblk, count);
1.200 + break;
1.201 + case Efn_createsp:
1.202 + CreateSP(argument, acfgblk, count);
1.203 + break;
1.204 + case Efn_open:
1.205 + Open(argument, acfgblk, count);
1.206 + break;
1.207 + case Efn_openl:
1.208 + OpenL_(argument, acfgblk, count);
1.209 + break;
1.210 + case Efn_attach:
1.211 + Attach(argument, acfgblk, count);
1.212 + break;
1.213 + case Efn_detach:
1.214 + Detach(argument, acfgblk, count);
1.215 + break;
1.216 + case Efn_copy:
1.217 + Copy(argument, acfgblk, count);
1.218 + break;
1.219 + case Efn_close:
1.220 + Close();
1.221 + break;
1.222 + case Efn_delete:
1.223 + Delete(argument, acfgblk, count);
1.224 + break;
1.225 + case Efn_lasterrormessage:
1.226 + LastErrorMessage(argument);
1.227 + break;
1.228 + case Efn_exec:
1.229 + Exec(argument, acfgblk, count);
1.230 + break;
1.231 + case Efn_setisolationlevel:
1.232 + SetIsolationLevel(argument, acfgblk, count);
1.233 + break;
1.234 + case Efn_reservedrivespace:
1.235 + ReserveDriveSpace(arg1, acfgblk, count);
1.236 + break;
1.237 + case Efn_freereservedspace:
1.238 + FreeReservedSpace();
1.239 + break;
1.240 + case Efn_getreserveaccess:
1.241 + GetReserveAccess(acfgblk, count);
1.242 + break;
1.243 + case Efn_releasereserveaccess:
1.244 + ReleaseReserveAccess();
1.245 + break;
1.246 +
1.247 + // Now the RSqlStatement methods...
1.248 + case Erstmt_prepare:
1.249 + Prepare(argument, acfgblk, count);
1.250 + break;
1.251 + case Erstmt_preparel:
1.252 + PrepareL_(argument, acfgblk, count);
1.253 + break;
1.254 + case Erstmt_close:
1.255 + Close(1);
1.256 + break;
1.257 + case Erstmt_atrow:
1.258 + AtRow(argument);
1.259 + break;
1.260 + case Erstmt_reset:
1.261 + err = isqlst.Reset();
1.262 + ReportOnError(KTestFunction, _L("Reset"), acfgblk,
1.263 + count, err);
1.264 + break;
1.265 + case Erstmt_exec:
1.266 + {
1.267 + TBuf<KConfigItemMaxNameLength> apiname(_L("st_exec"));
1.268 + if(!iasync)
1.269 + err = isqlst.Exec();
1.270 + else
1.271 + {
1.272 + TChar ch = 'A';
1.273 + apiname.Append(ch);
1.274 + TRequestStatus trs;
1.275 + isqlst.Exec(trs);
1.276 + User::WaitForRequest(trs);
1.277 + err = trs.Int();
1.278 + }
1.279 + ReportOnError(KTestFunction, apiname,
1.280 + acfgblk, count, err);
1.281 + }
1.282 + break;
1.283 + case Erstmt_next:
1.284 + Next(argument, acfgblk, count);
1.285 + break;
1.286 + case Erstmt_paramindex:
1.287 + {
1.288 + TInt pidx = ParamIndex(argument, acfgblk, count);
1.289 + // The test designer will have to remember how many
1.290 + // param indices have been stuck in this array..
1.291 + if(pidx >= 0)ipidxs.Append(pidx);
1.292 + }
1.293 + break;
1.294 + case Erstmt_colindex:
1.295 + {
1.296 + TInt cidx = ColumnIndex(argument, acfgblk, count);
1.297 + // The test designer will have to remember how many
1.298 + // column indices have been stuck in this array..
1.299 + if(cidx >= 0)icidxs.Append(cidx);
1.300 + }
1.301 + break;
1.302 + case Erstmt_coltype:
1.303 + // ColumnType needs the ColumnIndex (the last arg)
1.304 + // and also the expected result, which it will get from
1.305 + // the config file. We have to deal with the ColumnIndex
1.306 + // here because it lives in our scope, not that of the
1.307 + // method we're calling..
1.308 + // The test designer will have to remember how many
1.309 + // column indices have been stuck in this array..
1.310 + ColumnType(icidxs[arg1], arg3);
1.311 + break;
1.312 + case Erstmt_colsize:
1.313 + ColumnSize(icidxs[arg1], arg2);
1.314 + break;
1.315 + case Erstmt_bindnull:
1.316 + BindNull(ipidxs[arg1], acfgblk, count);
1.317 + break;
1.318 + case Erstmt_bindint:
1.319 + BindInt(ipidxs[arg1], arg2, acfgblk, count);
1.320 + break;
1.321 + case Erstmt_bindint64:
1.322 + BindInt64(ipidxs[arg1], arg3, acfgblk, count);
1.323 + break;
1.324 + case Erstmt_bindreal:
1.325 + {
1.326 + TLex tl = arg3;
1.327 + TReal tr;
1.328 + tl.Val(tr);
1.329 + BindReal(ipidxs[arg1], tr, acfgblk, count);
1.330 + }
1.331 + break;
1.332 + case Erstmt_bindtext:
1.333 + BindText(ipidxs[arg1], arg3, acfgblk, count);
1.334 + break;
1.335 + case Erstmt_bindbigtext:
1.336 + // Not an RSqlStatement method, but calls BindText
1.337 + // after reading from a file.
1.338 + BindBigTextL(ipidxs[arg1], arg3, acfgblk, count);
1.339 + break;
1.340 + case Erstmt_bindbinary:
1.341 + BindBinaryL(ipidxs[arg1], arg3, acfgblk, count);
1.342 + break;
1.343 + case Erstmt_isnull:
1.344 + IsNull(icidxs[arg1], arg3);
1.345 + break;
1.346 + case Erstmt_colint:
1.347 + ColumnInt(icidxs[arg1], arg2);
1.348 + break;
1.349 + case Erstmt_colint64:
1.350 + ColumnInt64(icidxs[arg1], arg3);
1.351 + break;
1.352 + case Erstmt_colreal:
1.353 + {
1.354 + TLex tl = arg3;
1.355 + TReal tr2;
1.356 + tl.Val(tr2);
1.357 + ColumnReal(icidxs[arg1], tr2);
1.358 + }
1.359 + break;
1.360 + case Erstmt_coltextL:
1.361 + ColumnTextL(icidxs[arg1], arg3, acfgblk, count);
1.362 + break;
1.363 + case Erstmt_coltextP:
1.364 + ColumnTextPL(icidxs[arg1], arg3, acfgblk, count);
1.365 + break;
1.366 + case Erstmt_coltextD:
1.367 + ColumnTextDL(icidxs[arg1], arg3, acfgblk, count);
1.368 + break;
1.369 + case Erstmt_colbinL:
1.370 + ColumnBinaryL(icidxs[arg1], arg3, acfgblk, count);
1.371 + break;
1.372 + case Erstmt_colbinP:
1.373 + ColumnBinaryPL(icidxs[arg1], arg3, acfgblk, count);
1.374 + break;
1.375 + case Erstmt_colbinD:
1.376 + ColumnBinaryDL(icidxs[arg1], arg3, acfgblk, count);
1.377 + break;
1.378 +
1.379 + case Esp_create:
1.380 + SPCreate(acfgblk, count);
1.381 + break;
1.382 + case Esp_createl:
1.383 + SPCreate(argument, acfgblk, count);
1.384 + break;
1.385 + case Esp_close:
1.386 + SPClose();
1.387 + break;
1.388 + case Esp_setdbpolicy:
1.389 + SPSetDBPolicy(argument, acfgblk, count);
1.390 + break;
1.391 + case Esp_setpolicy:
1.392 + SPSetPolicy(argument, acfgblk, count);
1.393 + break;
1.394 + case Esp_externalizel:
1.395 + SPExternalize(argument, acfgblk, count);
1.396 + break;
1.397 + case Esp_internalizel:
1.398 + SPInternalize(argument, acfgblk, count);
1.399 + break;
1.400 +
1.401 + case Estreamwrite_bindtext:
1.402 + SWBindTextL(ipidxs[arg1], arg3, acfgblk, count);
1.403 + break;
1.404 + case Estreamwrite_bindbinary:
1.405 + SWBindBinaryL(ipidxs[arg1], arg3, acfgblk, count);
1.406 + break;
1.407 + case Estreamread_columntext:
1.408 + SRColumnTextL(icidxs[arg1], arg3, acfgblk, count);
1.409 + break;
1.410 + case Estreamread_columnbinary:
1.411 + SRColumnBinaryL(icidxs[arg1], arg3, acfgblk, count);
1.412 + break;
1.413 + case Edefineconfig:
1.414 + {
1.415 + if(icfg)
1.416 + delete icfg;
1.417 + TInt len = argument.Length();
1.418 + if(len)
1.419 + {
1.420 + // At the time of writing, configuration strings
1.421 + // are limited to 255 bytes.
1.422 + TBuf8<256> arg;
1.423 + arg.Copy(argument);
1.424 + icfg = new TPtrC8(arg);
1.425 + }
1.426 + else
1.427 + icfg = NULL;
1.428 + }
1.429 + break;
1.430 +
1.431 + // Actions that aren't direct method calls..
1.432 + case Ectrl_newblock:
1.433 + // Continue executing from another configuration
1.434 + // block. Obviously this restarts the step
1.435 + // counter at zero. It's unfortunate that we can't
1.436 + // create a new test object here, that would be
1.437 + // so much neater. But logging doesn't work in
1.438 + // sub-objects (it could be bodged around but it
1.439 + // really would be a bodge). A shame, we could have
1.440 + // lots of member vars holding all this junk we're
1.441 + // passing around. Note that because we don't create
1.442 + // a new object we are playing with the same
1.443 + // RSqlDatabase and RSqlStatement objects.
1.444 + SQLDbStepL(argument);
1.445 + break;
1.446 + case Ectrl_function:
1.447 + // Pure virtual. Lives elsewhere..
1.448 + ResolveTestFunctionL(acfgblk, count, argument);
1.449 + break;
1.450 +
1.451 + case Ectrl_waitA:
1.452 + // Wait for the isem member semaphore to receive
1.453 + // arg1 signals for this thread. Obviously this assumes
1.454 + // there's another thread that's going to execute
1.455 + // a 'Signal' at some point.
1.456 + for(TInt ii=0 ; ii<arg1 ; ++ii)
1.457 + {
1.458 + WaitA();
1.459 + }
1.460 + break;
1.461 + case Ectrl_waitB:
1.462 + // Wait for the isemB member semaphore to receive
1.463 + // arg1 signals for this thread. Obviously this assumes
1.464 + // there's another thread that's going to execute
1.465 + // a 'SignalB' at some point.
1.466 + for(TInt ii=0 ; ii<arg1 ; ++ii)
1.467 + {
1.468 + WaitB();
1.469 + }
1.470 + break;
1.471 + case Ectrl_signalA:
1.472 + // E.G Signal37=6 to wake up six threads that are
1.473 + // waiting on isem.
1.474 + SignalA(arg1);
1.475 + break;
1.476 + case Ectrl_signalB:
1.477 + // E.G SignalB37=6 to wake up six threads that are
1.478 + // waiting on isemB..
1.479 + SignalB(arg1);
1.480 + break;
1.481 + case Ectrl_sleep:
1.482 + INFO_PRINTF2(_L("Sleeping for %d microseconds"), arg1);
1.483 + User::After(arg1);
1.484 + break;
1.485 + case Ectrl_eightbit:
1.486 + if((argument == _L("On")) || (argument == _L("True")))
1.487 + i8bit = ETrue;
1.488 + else
1.489 + i8bit = EFalse;
1.490 + break;
1.491 + case Ectrl_async:
1.492 + if((argument == _L("On")) || (argument == _L("True")))
1.493 + iasync = ETrue;
1.494 + else
1.495 + iasync = EFalse;
1.496 + break;
1.497 +
1.498 + // Big problems if this stuff executes.
1.499 + case Efn_undefined:
1.500 + SetTestStepResult(EFail);
1.501 + INFO_PRINTF1(HTML_RED);
1.502 + ERR_PRINTF1(_L("This should never happen. A"));
1.503 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.504 + break;
1.505 + default:
1.506 + SetTestStepResult(EFail);
1.507 + INFO_PRINTF1(HTML_RED);
1.508 + ERR_PRINTF1(_L("This should never happen. B"));
1.509 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.510 + break;
1.511 + }
1.512 + // Let's get rid of any colour. Can get tangled in multi-threaded
1.513 + // tests.
1.514 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.515 + }
1.516 + // If we get to this point and the 'ended' flag hasn't been set then
1.517 + // we haven't seen an 'EndBlockNN=' line in the config file. That
1.518 + // usually means the test has a missing <keyword><number> item
1.519 + // which is a test failure.
1.520 + if(!ended)
1.521 + {
1.522 + SetTestStepResult(EFail);
1.523 + INFO_PRINTF1(HTML_RED);
1.524 + ERR_PRINTF2(_L("Put an 'EndBlock' marker at the end of all config blocks. This is intended to\nspot missing numbers (which cause the test to drop out) failing to generate a failure (%S)"), &acfgblk);
1.525 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.526 + }
1.527 + }
1.528 +
1.529 +// ----------Methods to exercise RSqlDatabase methods ------------------------
1.530 +
1.531 +TBool CSQLFnStep::Create(const TPtrC& adbnm,
1.532 + const TDesC &acfgblk, TInt acnnum)
1.533 + {
1.534 + _LIT(KTestFunction, "Create");
1.535 + INFO_PRINTF3(_L("%S: Database name is %S "), &KTestFunction, &adbnm);
1.536 +
1.537 + // Try to create the database.
1.538 + TInt rc = isqldb.Create(adbnm, icfg);
1.539 + ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, rc);
1.540 + if(rc == KErrNone) return ETrue;
1.541 + return EFalse;
1.542 + }
1.543 +TBool CSQLFnStep::CreateL_(const TPtrC& adbnm,
1.544 + const TDesC &acfgblk, TInt acnnum)
1.545 + {
1.546 + _LIT(KTestFunction, "CreateL");
1.547 + INFO_PRINTF3(_L("%S: Database name is %S "), &KTestFunction, &adbnm);
1.548 +
1.549 + // Try to create the database. Trap any leave (we're actually duplicating
1.550 + // what is in the non-leaving Create method, but hey, this is black box
1.551 + // testing, we're not supposed to know that..)
1.552 + TInt rc=KErrNone;
1.553 + TRAP(rc, isqldb.CreateL(adbnm, icfg));
1.554 + ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, rc);
1.555 + if(rc == KErrNone) return ETrue;
1.556 + return EFalse;
1.557 + }
1.558 +
1.559 +TBool CSQLFnStep::CreateSP(const TPtrC& adbnm, const TDesC &acfgblk, TInt acnnum)
1.560 + {
1.561 + _LIT(KTestFunction, "CreateSP");
1.562 + INFO_PRINTF3(_L("%S: Database name is %S "), &KTestFunction, &adbnm);
1.563 +
1.564 + TInt rc = isqldb.Create(adbnm, isqlsp, icfg);
1.565 + ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, rc);
1.566 + if(rc == KErrNone) return ETrue;
1.567 + return EFalse;
1.568 + }
1.569 +
1.570 +TBool CSQLFnStep::Open(const TPtrC& adbnm,
1.571 + const TDesC &acfgblk, TInt acnnum)
1.572 + {
1.573 + _LIT(KTestFunction, "Open");
1.574 + INFO_PRINTF3(_L("%S: Database name is %S "), &KTestFunction, &adbnm);
1.575 +
1.576 + // Try to open the database.
1.577 + TInt rc = isqldb.Open(adbnm, icfg);
1.578 + ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, rc);
1.579 + if(rc == KErrNone) return ETrue;
1.580 + return EFalse;
1.581 + }
1.582 +TBool CSQLFnStep::OpenL_(const TPtrC& adbnm,
1.583 + const TDesC &acfgblk, TInt acnnum)
1.584 + {
1.585 + _LIT(KTestFunction, "OpenL");
1.586 + INFO_PRINTF3(_L("%S: Database name is %S "), &KTestFunction, &adbnm);
1.587 +
1.588 + // Try to open the database.
1.589 + TInt rc = KErrNone;
1.590 + TRAP(rc, isqldb.OpenL(adbnm, icfg));
1.591 + ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, rc);
1.592 + if(rc == KErrNone) return ETrue;
1.593 + return EFalse;
1.594 + }
1.595 +// Close the current database.
1.596 +void CSQLFnStep::Close()
1.597 + {
1.598 +// _LIT(KTestFunction, "Close");
1.599 + isqldb.Close();
1.600 + return;
1.601 + }
1.602 +void CSQLFnStep::Attach(const TPtrC &arg,
1.603 + const TDesC &acfgblk, TInt acnnum)
1.604 + {
1.605 + _LIT(KTestFunction, "Attach");
1.606 + TPtrC sqldb, sqldbname;
1.607 + // Break arg into 'sqldb', the path/filename of the database to attach
1.608 + // and sqldbname, the name by which the database will be referred to
1.609 + // through this Attach.
1.610 + CommaSeparated(arg, sqldb, sqldbname);
1.611 + TInt rc = isqldb.Attach(sqldb, sqldbname);
1.612 + ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, rc);
1.613 + return;
1.614 + }
1.615 +void CSQLFnStep::Detach(const TPtrC &arg,
1.616 + const TDesC &acfgblk, TInt acnnum)
1.617 + {
1.618 + _LIT(KTestFunction, "Detach");
1.619 + TInt rc = isqldb.Detach(arg);
1.620 + ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, rc);
1.621 + return;
1.622 + }
1.623 +void CSQLFnStep::Copy(const TPtrC &arg,
1.624 + const TDesC &acfgblk, TInt acnnum)
1.625 + {
1.626 + _LIT(KTestFunction, "Copy");
1.627 + TPtrC sqldb1, sqldb2;
1.628 + CommaSeparated(arg, sqldb1, sqldb2);
1.629 + TInt rc = isqldb.Copy(sqldb1, sqldb2);
1.630 + ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, rc);
1.631 + return;
1.632 + }
1.633 +TBool CSQLFnStep::Delete(const TPtrC& adbnm,
1.634 + const TDesC &acfgblk, TInt acnnum)
1.635 + {
1.636 + _LIT(KTestFunction, "Delete");
1.637 + INFO_PRINTF3(_L("%S: Database name is %S "), &KTestFunction, &adbnm);
1.638 +
1.639 + // Try to delete the database.
1.640 + TInt rc = isqldb.Delete(adbnm);
1.641 + ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, rc);
1.642 + if(rc == KErrNone) return ETrue;
1.643 + return EFalse;
1.644 + }
1.645 +void CSQLFnStep::LastErrorMessage(const TPtrC& arg)
1.646 +
1.647 + {
1.648 + _LIT(KTestFunction, "LastErrorMessage");
1.649 +
1.650 + TPtrC lem = isqldb.LastErrorMessage();
1.651 + if(arg.Length() == 0)
1.652 + {
1.653 + INFO_PRINTF3(_L("%S: '%S'"), &KTestFunction, &lem);
1.654 + return; // No particular error message was expected, so just return.
1.655 + }
1.656 + if(lem != arg)
1.657 + {
1.658 + SetTestStepResult(EFail);
1.659 + INFO_PRINTF1(HTML_RED);
1.660 + ERR_PRINTF4(_L("%S: Expected Message '%S', got '%S'"), &KTestFunction,
1.661 + &arg, &lem);
1.662 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.663 + }
1.664 + else
1.665 + {
1.666 + INFO_PRINTF1(HTML_GREEN);
1.667 + INFO_PRINTF3(_L("%S: Got expected Message '%S'"), &KTestFunction, &arg);
1.668 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.669 + }
1.670 + return;
1.671 + }
1.672 +void CSQLFnStep::Exec(const TPtrC& arg,
1.673 + const TDesC &acfgblk, TInt acnnum)
1.674 + {
1.675 + _LIT(KTestFunction, "Exec");
1.676 + TBuf<KConfigItemMaxNameLength> apiname(KTestFunction);
1.677 + TInt rc;
1.678 + if(i8bit == EFalse)
1.679 + {
1.680 + if(!iasync)
1.681 + rc = isqldb.Exec(arg);
1.682 + else
1.683 + {
1.684 + TChar ch = 'A';
1.685 + apiname.Append(ch);
1.686 + TRequestStatus trs;
1.687 + isqldb.Exec(arg, trs);
1.688 + User::WaitForRequest(trs);
1.689 + rc = trs.Int();
1.690 + }
1.691 + }
1.692 + else
1.693 + {
1.694 + apiname.AppendNum(8);
1.695 + RBuf8 b8;
1.696 + b8.Create(arg.Length());
1.697 + b8.Copy(arg);
1.698 + if(!iasync)
1.699 + rc = isqldb.Exec(b8);
1.700 + else
1.701 + {
1.702 + TChar ch = 'A';
1.703 + apiname.Append(ch);
1.704 + TRequestStatus trs;
1.705 + isqldb.Exec(b8, trs);
1.706 + User::WaitForRequest(trs);
1.707 + rc = trs.Int();
1.708 + }
1.709 + b8.Close();
1.710 + }
1.711 + ReportOnError(KTestFunction, apiname, acfgblk, acnnum, rc);
1.712 + return;
1.713 + }
1.714 +void CSQLFnStep::SetIsolationLevel(const TPtrC& arg,
1.715 + const TDesC &acfgblk, TInt acnnum)
1.716 + {
1.717 + _LIT(KTestFunction, "SetIsolationLevel");
1.718 + // Get the expected error code..
1.719 + TPtrC experrS;
1.720 + TInt experr = ActionNoToErrEnum(acfgblk, acnnum, experrS);
1.721 +
1.722 + INFO_PRINTF2(_L("SetIsolationLevel: %S"), &arg);
1.723 + RSqlDatabase::TIsolationLevel sil;
1.724 + if(arg == _L("EReadUncommitted"))
1.725 + sil = RSqlDatabase::EReadUncommitted;
1.726 + else if(arg == _L("EReadCommitted"))
1.727 + sil = RSqlDatabase::EReadCommitted;
1.728 + else if(arg == _L("ERepeatableRead"))
1.729 + sil = RSqlDatabase::ERepeatableRead;
1.730 + else if(arg == _L("ESerializable"))
1.731 + sil = RSqlDatabase::ESerializable;
1.732 + else
1.733 + {
1.734 + SetTestStepResult(EFail);
1.735 + INFO_PRINTF1(HTML_RED);
1.736 + ERR_PRINTF3(_L("%S: Unrecognized TIsolationLevel '%S'"),
1.737 + &KTestFunction, &arg);
1.738 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.739 + return;
1.740 + }
1.741 +
1.742 + TInt rc = isqldb.SetIsolationLevel(sil);
1.743 + TPtrC err;
1.744 + ErrEnumToString(rc,err);
1.745 + if(rc != experr)
1.746 + {
1.747 + SetTestStepResult(EFail);
1.748 + INFO_PRINTF1(HTML_RED);
1.749 + ERR_PRINTF3(_L("Unexpected SetIsolationLevel error %d/%S"), rc, &err);
1.750 + TPtrC lem = isqldb.LastErrorMessage();
1.751 + ERR_PRINTF2(_L(" - Last Error Message: %S"), &lem);
1.752 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.753 + return;
1.754 + }
1.755 + else
1.756 + INFO_PRINTF2(_L("SetIsolation level, got error %S as expected"), &err);
1.757 + return;
1.758 + }
1.759 +
1.760 +void CSQLFnStep::ReserveDriveSpace(TInt ares,
1.761 + const TDesC& acfgblk, const TInt acnnum)
1.762 + {
1.763 + _LIT(KTestFunction, "ReserveDriveSpace");
1.764 +
1.765 + // Try to reserve space..
1.766 + TInt rc = isqldb.ReserveDriveSpace(ares);
1.767 + ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, rc);
1.768 + return;
1.769 + }
1.770 +void CSQLFnStep::FreeReservedSpace()
1.771 + {
1.772 +// _LIT(KTestFunction, "FreeReservedSpace");
1.773 + isqldb.FreeReservedSpace();
1.774 + return;
1.775 + }
1.776 +void CSQLFnStep::GetReserveAccess(const TDesC& acfgblk,
1.777 + const TInt acnnum)
1.778 + {
1.779 + _LIT(KTestFunction, "GetReserveAccess");
1.780 +
1.781 + // Try to reserve space..
1.782 + TInt rc = isqldb.GetReserveAccess();
1.783 + ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, rc);
1.784 + return;
1.785 + }
1.786 +void CSQLFnStep::ReleaseReserveAccess()
1.787 + {
1.788 +// _LIT(KTestFunction, "ReleaseReserveSpace");
1.789 + isqldb.ReleaseReserveAccess();
1.790 + return;
1.791 + }
1.792 +
1.793 +// ----------Methods to exercise RSqlStatement methods ------------------------
1.794 +//
1.795 +// Execute a Close on the current RSqlStatement. This also clears out the
1.796 +// arrays of RBufs and RBuf8s which are used for BindText and
1.797 +// BindBinary (just a way of keeping the buffers in scope until the
1.798 +// Exec/Close happens) and loses all of the ParameterIndex and ColumnIndex's.
1.799 +// The 'TInt' argument is just to differentiate between the RSqlDatabase
1.800 +// Close wrapper, and this RSqlStatement Close wrapper.
1.801 +void CSQLFnStep::Close(TInt)
1.802 + {
1.803 +// _LIT(KTestFunction, "St_Close");
1.804 +
1.805 + // Close the RSqlStatement.
1.806 + isqlst.Close();
1.807 +
1.808 + // Empty the arrays where we keep references to BindXXX buffers,
1.809 + // closing those buffers as we go.
1.810 + for(TInt count = iBindRBufarr.Count() - 1 ; count >= 0; count--)
1.811 + {
1.812 + iBindRBufarr[count].Close();
1.813 + iBindRBufarr.Remove(count);
1.814 + }
1.815 + for(TInt count = iBindRBuf8arr.Count() - 1 ; count >= 0 ; count--)
1.816 + {
1.817 + iBindRBuf8arr[count].Close();
1.818 + iBindRBuf8arr.Remove(count);
1.819 + }
1.820 + if((iBindRBuf8arr.Count() != 0) || (iBindRBufarr.Count() != 0))
1.821 + {
1.822 + User::Panic(_L("RBuf arrays not empty"), 512);
1.823 + }
1.824 +
1.825 + // Empty the ParameterIndex and ColumnIndex arrays.
1.826 + while(ipidxs.Count()) ipidxs.Remove(0);
1.827 + while(icidxs.Count()) icidxs.Remove(0);
1.828 +
1.829 + return;
1.830 + }
1.831 +void CSQLFnStep::Next(TPtrC& arg,
1.832 + const TDesC &acfgblk, TInt acnnum=-1)
1.833 + {
1.834 + _LIT(KTestFunction, "Next");
1.835 + TInt rc = isqlst.Next();
1.836 +
1.837 + // If arg is not zero length it will be KSqlAtEnd/KSqlAtRow, turn that
1.838 + // into the enumeration.
1.839 + if(arg.Length())
1.840 + {
1.841 + TInt expn = ErrStringToEnum(arg);
1.842 + TPtrC errS;
1.843 + ErrEnumToString(rc, errS); // Convert the actual rc to a string.
1.844 + if(expn != rc)
1.845 + {
1.846 + SetTestStepResult(EFail);
1.847 + INFO_PRINTF1(HTML_RED);
1.848 + ERR_PRINTF7(_L("%S/%S: Got %S/%d, expected %S/%d"), &KTestFunction,
1.849 + &acfgblk, &errS, rc, &arg, expn );
1.850 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.851 + }
1.852 + }
1.853 + ReportOnError(KTestFunction, _L("Next"), acfgblk, acnnum, rc);
1.854 + return;
1.855 + }
1.856 +
1.857 +// Call the RSqlStatement method 'AtRow'. This returns a boolean. This
1.858 +// method expects the config file to contain a line resembling
1.859 +// 'AtRow57=false'. The return value is checked against the config
1.860 +// value and error/info is reported.
1.861 +void CSQLFnStep::AtRow(const TPtrC &arg)
1.862 +
1.863 + {
1.864 + _LIT(KTestFunction, "AtRow");
1.865 + TBuf<8> atrres(arg);
1.866 + atrres.LowerCase();
1.867 + TBool expected = EFalse;
1.868 + if(atrres == _L("false"))
1.869 + expected = EFalse;
1.870 + else if(atrres == _L("true"))
1.871 + expected = ETrue;
1.872 + else
1.873 + {
1.874 + SetTestStepResult(EFail);
1.875 + INFO_PRINTF1(HTML_RED);
1.876 + ERR_PRINTF3(_L("%S: expected config item to be true/false, got %S"),
1.877 + &KTestFunction, &arg);
1.878 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.879 + }
1.880 + TBool atr = isqlst.AtRow();
1.881 + if(atr != expected)
1.882 + {
1.883 + SetTestStepResult(EFail);
1.884 + INFO_PRINTF1(HTML_RED);
1.885 + ERR_PRINTF4(_L("%S: expected AtRow to return %S, got %d"),
1.886 + &KTestFunction, &atrres, atr);
1.887 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.888 + return;
1.889 + }
1.890 + else
1.891 + {
1.892 + INFO_PRINTF1(HTML_GREEN);
1.893 + INFO_PRINTF3(_L("%S: Got expected result, %S"), &KTestFunction, &atrres);
1.894 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.895 + }
1.896 + return;
1.897 + }
1.898 +// Call the RSqlStatement method 'Prepare'. This returns an int. This
1.899 +// method expects the config file to contain a line resembling
1.900 +// 'Prepare43=Create Table tbl3(f1 etc)'. The return value is checked
1.901 +// against the expected error (in ReportOnError).
1.902 +void CSQLFnStep::Prepare(const TPtrC &arg,
1.903 + const TDesC &acfgblk, TInt acnnum=-1)
1.904 + {
1.905 + _LIT(KTestFunction, "Prepare");
1.906 + INFO_PRINTF3(_L("%S: Prepare command is %S"), &KTestFunction, &arg);
1.907 +
1.908 + TInt rc;
1.909 + if(i8bit == EFalse)
1.910 + rc = isqlst.Prepare(isqldb, arg);
1.911 + else
1.912 + {
1.913 + RBuf8 b8;
1.914 + b8.Create(arg.Length());
1.915 + b8.Copy(arg);
1.916 + rc = isqlst.Prepare(isqldb, b8);
1.917 + b8.Close();
1.918 + }
1.919 + ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, rc);
1.920 + }
1.921 +void CSQLFnStep::PrepareL_(const TPtrC &arg,
1.922 + const TDesC &acfgblk, TInt acnnum=-1)
1.923 + {
1.924 + _LIT(KTestFunction, "PrepareL");
1.925 + INFO_PRINTF3(_L("%S: PrepareL command is %S"), &KTestFunction, &arg);
1.926 +
1.927 + TInt rc=KErrNone;
1.928 + if(i8bit == EFalse)
1.929 + {
1.930 + TRAP(rc, isqlst.PrepareL(isqldb, arg));
1.931 + }
1.932 + else
1.933 + {
1.934 + RBuf8 b8;
1.935 + b8.Create(arg.Length());
1.936 + b8.Copy(arg);
1.937 + TRAP(rc, isqlst.PrepareL(isqldb, b8));
1.938 + b8.Close();
1.939 + }
1.940 + ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, rc);
1.941 + }
1.942 +// Call the RSqlStatement method 'ParamIndex'. This returns an int. This
1.943 +// method expects the config file to contain a line resembling
1.944 +// 'ParamIndex12=:Frog'. The return value is returned.
1.945 +TInt CSQLFnStep::ParamIndex(const TDesC &arg,
1.946 + const TDesC &acfgblk, TInt acnnum=-1)
1.947 + {
1.948 + _LIT(KTestFunction, "ParameterIndex");
1.949 +
1.950 + // If the test specifies ':?' was the parameter index, we'll assume that
1.951 + // ':?' was given in the SELECT (a nameless parameter), this always gives
1.952 + // '1' for the paramIndex.
1.953 + if(arg == _L(":?"))
1.954 + return 1;
1.955 +
1.956 + // If arg resembles '23,*explicit*', then return the leading integer.
1.957 + // This is so we can call BindEtc with bad values for PANIC testing
1.958 + // or otherwise generate a specific parameter index.
1.959 + TInt pidx=0;
1.960 + TPtrC rhs;
1.961 + CommaSeparated(arg, pidx, rhs);
1.962 + if(rhs == _L("*explicit*"))
1.963 + {
1.964 + INFO_PRINTF3(_L("%S: Returning explicit Parameter Index %d"),
1.965 + &KTestFunction, pidx);
1.966 + return pidx;
1.967 + }
1.968 +
1.969 + // Ok, run ParameterIndex.
1.970 + pidx = isqlst.ParameterIndex(arg);
1.971 +
1.972 + // ParameterIndex returns a non-negative integer on success. If the
1.973 + // return is negative, we have a problem. We cannot know what the
1.974 + // return is if the operation has succeeded, so checking the error
1.975 + // code is limited to required errors, i.e < 0.
1.976 + // ReportOnError will set test result to failure if the error doesn't
1.977 + // match our expected error.
1.978 + if(pidx < 0)
1.979 + ReportOnError(KTestFunction, _L("ParameterIndex"),
1.980 + acfgblk, acnnum, pidx);
1.981 + return pidx;
1.982 + }
1.983 +// Call the RSqlStatement method 'ColumnIndex'. This returns an int. This
1.984 +// method expects the config file to contain a line resembling
1.985 +// 'ColumnIndex12=Fld3'. The return value is returned.
1.986 +TInt CSQLFnStep::ColumnIndex(const TPtrC& arg,
1.987 + const TDesC &acfgblk, TInt acnnum=-1)
1.988 + {
1.989 + _LIT(KTestFunction, "ColumnIndex");
1.990 +
1.991 + // If no column is specified then return zero - this may be necessary
1.992 + // if the test is for example counting lines in a table ...
1.993 + // >select count(*) from mytbl;
1.994 + // In this case obviously there is no namable column, but the Api just
1.995 + // requires that the index for ColumnInt will be zero.
1.996 + if(arg.Length() == 0) return 0;
1.997 +
1.998 + // If arg resembles '23,*explicit*', then return the leading integer.
1.999 + // This is so we can call ColumnEtc with bad values for PANIC testing
1.1000 + // or otherwise generate a specific parameter index.
1.1001 + TInt colIndex=0;
1.1002 + TPtrC rhs;
1.1003 + CommaSeparated(arg, colIndex, rhs);
1.1004 + if(rhs == _L("*explicit*"))
1.1005 + {
1.1006 + INFO_PRINTF3(_L("%S: Returning explicit Column Index %d"),
1.1007 + &KTestFunction, colIndex);
1.1008 + return colIndex;
1.1009 + }
1.1010 + colIndex = isqlst.ColumnIndex(arg);
1.1011 + // ColumnIndex returns a non-negative integer on success. If the
1.1012 + // return is negative, we have a problem. We cannot know what the
1.1013 + // return is if the operation has succeeded, so checking the error
1.1014 + // code is limited to required errors, i.e < 0.
1.1015 + // ReportOnError will set test result to failure if the error doesn't
1.1016 + // match our expected error.
1.1017 + if(colIndex < 0)
1.1018 + ReportOnError(KTestFunction, _L("ColumnIndex"),
1.1019 + acfgblk, acnnum, colIndex);
1.1020 + return colIndex;
1.1021 + }
1.1022 +// Call the RSqlStatement method 'ColumnType'.
1.1023 +void CSQLFnStep::ColumnType(const TInt &acidx, const TPtrC &aexp)
1.1024 +
1.1025 + {
1.1026 + _LIT(KTestFunction, "ColumnType");
1.1027 + TSqlColumnType gottype = isqlst.ColumnType(acidx);
1.1028 + TPtrC got(SqlColumnTypeToString(gottype));
1.1029 +
1.1030 + if((aexp.Length() ==0) || (StringToSqlColumnType(aexp)==gottype))
1.1031 + {
1.1032 + INFO_PRINTF1(HTML_GREEN);
1.1033 + INFO_PRINTF3(_L("%S: Got Column type %S"), &KTestFunction, &got);
1.1034 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.1035 + return;
1.1036 + }
1.1037 +
1.1038 + // If the expected type hasn't been specified then just display what
1.1039 + // we've got.
1.1040 + INFO_PRINTF1(HTML_RED);
1.1041 + ERR_PRINTF4(_L("%S: Got Column type %S, expected %S"),
1.1042 + &KTestFunction, &got, &aexp);
1.1043 + SetTestStepResult(EFail);
1.1044 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.1045 + return;
1.1046 + }
1.1047 +// Call the RSqlStatement method 'ColumnSize'. Check it against the
1.1048 +// expected size specified in the config file.
1.1049 +void CSQLFnStep::ColumnSize(const TInt& acolidx, const TInt &axexp)
1.1050 + {
1.1051 + _LIT(KTestFunction, "ColumnSize");
1.1052 + TInt csize = isqlst.ColumnSize(acolidx);
1.1053 +
1.1054 + if((axexp != -1) && (axexp != csize))
1.1055 + {
1.1056 + INFO_PRINTF1(HTML_RED);
1.1057 + SetTestStepResult(EFail);
1.1058 + ERR_PRINTF4(_L("%S: Got Column size %d, expected %d"),
1.1059 + &KTestFunction, csize, axexp);
1.1060 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.1061 + return;
1.1062 + }
1.1063 + // If colsize is -1 display what we have.
1.1064 + INFO_PRINTF3(_L("%S: Got Column size %d"), &KTestFunction, csize);
1.1065 +
1.1066 + return;
1.1067 + }
1.1068 +// Onto the Bind methods...
1.1069 +void CSQLFnStep::BindNull(const TInt& apidx,
1.1070 + const TDesC &acfgblk, const TInt acnnum=-1)
1.1071 + {
1.1072 + _LIT(KTestFunction, "BindNull");
1.1073 +
1.1074 + TInt err = isqlst.BindNull(apidx);
1.1075 + ReportOnError(KTestFunction, _L("BindNull"), acfgblk, acnnum, err);
1.1076 +
1.1077 + return;
1.1078 + }
1.1079 +void CSQLFnStep::BindInt(const TInt& apidx, const TInt& atob,
1.1080 + const TDesC &acfgblk, const TInt acnnum=-1)
1.1081 + {
1.1082 + _LIT(KTestFunction, "BindInt");
1.1083 +
1.1084 + TInt err = isqlst.BindInt(apidx, atob);
1.1085 + ReportOnError(KTestFunction, _L("BindInt"), acfgblk, acnnum, err);
1.1086 +
1.1087 + return;
1.1088 + }
1.1089 +void CSQLFnStep::BindInt64(const TInt& apidx, const TPtrC& atob,
1.1090 + const TDesC &acfgblk, const TInt acnnum=-1)
1.1091 + {
1.1092 + _LIT(KTestFunction, "BindInt64");
1.1093 + TInt64 bind;
1.1094 + TLex tl = atob;
1.1095 + tl.Val(bind);
1.1096 + TInt err = isqlst.BindInt64(apidx, bind);
1.1097 + ReportOnError(KTestFunction, _L("BindInt64"), acfgblk, acnnum, err);
1.1098 +
1.1099 + return;
1.1100 + }
1.1101 +void CSQLFnStep::BindReal(const TInt& apidx, const TReal& areal,
1.1102 + const TDesC &acfgblk, const TInt acnnum=-1)
1.1103 + {
1.1104 + _LIT(KTestFunction, "BindReal");
1.1105 + TInt err = isqlst.BindReal(apidx, areal);
1.1106 + ReportOnError(KTestFunction, _L("BindReal"), acfgblk, acnnum, err);
1.1107 +
1.1108 + return;
1.1109 + }
1.1110 +// BindText from the config line...
1.1111 +// May be modified to return a ref which we can keep on the
1.1112 +// stack in the main loop. Then, when we hit a 'Next' that can be cleared.
1.1113 +// This is necessary because there are scoping problems with text and
1.1114 +// binarys - the SQL code expects buffers to remain in scope until
1.1115 +// the Exec/Next.
1.1116 +void CSQLFnStep::BindText(const TInt& apidx, const TPtrC& atxt,
1.1117 + const TDesC &acfgblk, const TInt acnnum=-1)
1.1118 + {
1.1119 + _LIT(KTestFunction, "BindText");
1.1120 + TInt err = isqlst.BindText(apidx, atxt);
1.1121 + ReportOnError(KTestFunction, _L("BindText"), acfgblk, acnnum, err);
1.1122 +
1.1123 + return;
1.1124 + }
1.1125 +// An additional method to let us bind more than one line of text from
1.1126 +// a config file...
1.1127 +// If the Bind is successful the buffer which has been bound is appended
1.1128 +// to the 'iBindRBufarr' array. This is necessary to keep it in scope until
1.1129 +// the 'Next'/'Exec' actions.
1.1130 +void CSQLFnStep::BindBigTextL(const TInt& apidx, const TPtrC& arg,
1.1131 + const TDesC &acfgblk, const TInt acnnum=-1)
1.1132 + {
1.1133 + _LIT(KTestFunction, "BindBigText");
1.1134 + RBuf buf;
1.1135 +
1.1136 + TInt fsize = FileSize(arg);
1.1137 + if(fsize < 0) return; // This will have reported an error if necessary.
1.1138 +
1.1139 +#ifdef _UNICODE
1.1140 + fsize >>= 1; // We're assuming here that one character is two bytes..
1.1141 +#endif
1.1142 +
1.1143 + // Create a buffer big enough for the text in the file.
1.1144 + TInt err = buf.Create(fsize);
1.1145 + if(err != KErrNone)
1.1146 + {
1.1147 + SetTestStepResult(EFail);
1.1148 + INFO_PRINTF1(HTML_RED);
1.1149 + ERR_PRINTF3(_L("%S: Can't allocate file buffer %S"), &KTestFunction, &arg);
1.1150 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.1151 + return;
1.1152 + }
1.1153 + // Don't push buf onto the cleanup stack. We'll keep a reference to it
1.1154 + // which get removed on RSqlStatement::Reset.
1.1155 +
1.1156 + // Use an RFileReadStream because we need to worry about characters,
1.1157 + // not just bytes.
1.1158 + RFileReadStream rflrs;
1.1159 + if(rflrs.Open(irfs, arg, EFileRead) != KErrNone)
1.1160 + {
1.1161 + SetTestStepResult(EFail);
1.1162 + INFO_PRINTF1(HTML_RED);
1.1163 + ERR_PRINTF3(_L("%S: Can't open file %S"), &KTestFunction, &arg);
1.1164 + buf.Close();
1.1165 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.1166 + return;
1.1167 + }
1.1168 + CleanupClosePushL(rflrs);
1.1169 + rflrs.ReadL(buf);
1.1170 +
1.1171 + // Do the bind...
1.1172 + err = isqlst.BindText(apidx, buf);
1.1173 + ReportOnError(KTestFunction, _L("BindText"), acfgblk, acnnum, err);
1.1174 + // Drop out if it failed.
1.1175 + if(err != KErrNone)
1.1176 + {
1.1177 + CleanupStack::PopAndDestroy(1, &rflrs);
1.1178 + buf.Close();
1.1179 + return;
1.1180 + }
1.1181 + CleanupStack::PopAndDestroy(1, &rflrs);
1.1182 +
1.1183 + // Tack the buffer onto the internal array. This keeps it in
1.1184 + // scope until a RSqlStatement::Close is performed when it will get
1.1185 + // destroyed.
1.1186 + iBindRBufarr.Append(buf);
1.1187 +
1.1188 + return;
1.1189 + }
1.1190 +// If the Bind is successful the buffer which has been bound is appended
1.1191 +// to the 'iBindRBuf8arr' array. This is necessary to keep it in scope until
1.1192 +// the 'Next'/'Exec' actions.
1.1193 +void CSQLFnStep::BindBinaryL(const TInt& apidx, const TDesC& arg,
1.1194 + const TDesC &acfgblk, const TInt acnnum)
1.1195 + {
1.1196 + _LIT(KTestFunction, "BindBinary");
1.1197 + TInt fsize = FileSize(arg);
1.1198 + if(fsize < 0)
1.1199 + {
1.1200 + SetTestStepResult(EFail);
1.1201 + INFO_PRINTF1(HTML_RED);
1.1202 + ERR_PRINTF3(_L("%S: Can't find file %S"), &KTestFunction, &arg);
1.1203 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.1204 + return;
1.1205 + }
1.1206 + // Create the buffer we're going to bind from. We'll keep a reference
1.1207 + // to this so it doesn't go out of scope (it mustn't
1.1208 + // until Exec/Reset) so don't put it on the cleanup stack.
1.1209 + RBuf8 ap;
1.1210 + TInt err = ap.Create(fsize);
1.1211 + ReportOnError(KTestFunction, _L("BufferCreate"), acfgblk, acnnum, err);
1.1212 + if(err != KErrNone) return;
1.1213 +
1.1214 + // Now open the file specified in the argument.
1.1215 + RFile file;
1.1216 + TFileName fn = arg;
1.1217 + err = file.Open(irfs, fn, 0);
1.1218 + ReportOnError(KTestFunction, _L("FileOpen"), acfgblk, acnnum, err);
1.1219 + if(err != KErrNone)
1.1220 + {
1.1221 + ap.Close();
1.1222 + return;
1.1223 + }
1.1224 + CleanupClosePushL(file);
1.1225 +
1.1226 + // Attempt to read from the file.
1.1227 + err = file.Read(ap, fsize);
1.1228 + ReportOnError(KTestFunction, _L("FileRead"), acfgblk, acnnum, err);
1.1229 + if(err != KErrNone)
1.1230 + {
1.1231 + CleanupStack::PopAndDestroy(1, &file);
1.1232 + ap.Close();
1.1233 + return;
1.1234 + }
1.1235 +
1.1236 + // Do the bind...
1.1237 + err = isqlst.BindBinary(apidx, ap);
1.1238 + ReportOnError(KTestFunction, _L("BindBinary"), acfgblk, acnnum, err);
1.1239 +
1.1240 + // Drop out if it failed.
1.1241 + if(err != KErrNone)
1.1242 + {
1.1243 + CleanupStack::PopAndDestroy(1, &file);
1.1244 + ap.Close();
1.1245 + return;
1.1246 + }
1.1247 +
1.1248 + CleanupStack::PopAndDestroy(1, &file);
1.1249 +
1.1250 + // Ok things seemed to have worked. Tack the buffer onto our internal
1.1251 + // RBuf8 array to keep it in scope. It will finally get trashed when
1.1252 + // we do the next RSqlStatement::Reset.
1.1253 + iBindRBuf8arr.Append(ap);
1.1254 +
1.1255 + return;
1.1256 + }
1.1257 +void CSQLFnStep::IsNull(const TInt& apidx, const TPtrC& atxt)
1.1258 + {
1.1259 + _LIT(KTestFunction, "IsNull");
1.1260 + TBuf<8> isn(atxt);
1.1261 + isn.LowerCase();
1.1262 + TBool expected;
1.1263 + if(isn == _L("false"))
1.1264 + expected = EFalse;
1.1265 + else if(isn == _L("true"))
1.1266 + expected = ETrue;
1.1267 + else
1.1268 + {
1.1269 + SetTestStepResult(EFail);
1.1270 + INFO_PRINTF1(HTML_RED);
1.1271 + ERR_PRINTF3(_L("%S: expected argument item to be true/false, got %S"),
1.1272 + &KTestFunction, &atxt);
1.1273 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.1274 + return;
1.1275 + }
1.1276 + if(isqlst.IsNull(apidx) != expected)
1.1277 + {
1.1278 + SetTestStepResult(EFail);
1.1279 + INFO_PRINTF1(HTML_RED);
1.1280 + ERR_PRINTF3(_L("%S: expected IsNull to return %S"), &KTestFunction,
1.1281 + &atxt);
1.1282 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.1283 + return;
1.1284 + }
1.1285 + else
1.1286 + {
1.1287 + INFO_PRINTF1(HTML_GREEN);
1.1288 + INFO_PRINTF3(_L("%S: Got expected result, %S"), &KTestFunction, &atxt);
1.1289 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.1290 + }
1.1291 + return;
1.1292 + }
1.1293 +void CSQLFnStep::ColumnInt(const TInt& acidx, const TInt& aint)
1.1294 + {
1.1295 + _LIT(KTestFunction, "ColumnInt");
1.1296 +
1.1297 + TInt got = isqlst.ColumnInt(acidx);
1.1298 + if(got != aint)
1.1299 + {
1.1300 + SetTestStepResult(EFail);
1.1301 + INFO_PRINTF1(HTML_RED);
1.1302 + ERR_PRINTF4(_L("%S: expected ColumnInt to return %d, got %d"),
1.1303 + &KTestFunction, aint, got);
1.1304 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.1305 + return;
1.1306 + }
1.1307 + else
1.1308 + {
1.1309 + INFO_PRINTF1(HTML_GREEN);
1.1310 + INFO_PRINTF3(_L("%S: Got expected result, %d"), &KTestFunction,
1.1311 + got);
1.1312 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.1313 + }
1.1314 + return;
1.1315 + }
1.1316 +void CSQLFnStep::ColumnInt64(const TInt& acidx, const TPtrC& aintS)
1.1317 + {
1.1318 + _LIT(KTestFunction, "ColumnInt64");
1.1319 +
1.1320 + TLex tl(aintS);
1.1321 + TInt64 aint;
1.1322 + tl.Val(aint);
1.1323 + TInt64 got = isqlst.ColumnInt64(acidx);
1.1324 + if(got != aint)
1.1325 + {
1.1326 + SetTestStepResult(EFail);
1.1327 + INFO_PRINTF1(HTML_RED);
1.1328 + ERR_PRINTF3(_L("%S: expected ColumnInt to return %S"),
1.1329 + &KTestFunction, &aint);
1.1330 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.1331 + return;
1.1332 + }
1.1333 + else
1.1334 + {
1.1335 + INFO_PRINTF1(HTML_GREEN);
1.1336 + INFO_PRINTF3(_L("%S: Got expected result, %ld"), &KTestFunction,
1.1337 + got);
1.1338 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.1339 + }
1.1340 + return;
1.1341 + }
1.1342 +void CSQLFnStep::ColumnReal(const TInt& acidx, const TReal& areal)
1.1343 + {
1.1344 + _LIT(KTestFunction, "ColumnReal");
1.1345 +
1.1346 + TReal got = isqlst.ColumnReal(acidx);
1.1347 + if(got != areal)
1.1348 + {
1.1349 + SetTestStepResult(EFail);
1.1350 + INFO_PRINTF1(HTML_RED);
1.1351 + ERR_PRINTF4(_L("%S: expected ColumnReal to return %f, got %f"),
1.1352 + &KTestFunction, areal, got);
1.1353 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.1354 + return;
1.1355 + }
1.1356 + else
1.1357 + {
1.1358 + INFO_PRINTF1(HTML_GREEN);
1.1359 + INFO_PRINTF3(_L("%S: Got expected result, %f"), &KTestFunction, got);
1.1360 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.1361 + }
1.1362 + return;
1.1363 + }
1.1364 +void CSQLFnStep::ColumnTextL(const TInt& acidx, const TPtrC& atxt,
1.1365 + const TDesC &acfgblk, const TInt acnnum=-1)
1.1366 + {
1.1367 + _LIT(KTestFunction, "ColumnTextL");
1.1368 +
1.1369 + TPtrC got = isqlst.ColumnTextL(acidx);
1.1370 + TInt err;
1.1371 +
1.1372 + // First the simplest, does the text match the config text?
1.1373 + if(got == atxt)
1.1374 + {
1.1375 + INFO_PRINTF1(HTML_GREEN);
1.1376 + INFO_PRINTF3(_L("%S: Got expected result, %S"), &KTestFunction,
1.1377 + &got);
1.1378 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.1379 + return;
1.1380 + }
1.1381 +
1.1382 + // Perhaps 'atxt' is a file, CompareTextAgainstFile will
1.1383 + // return KErrNotFound if it can't find the file.
1.1384 + if((err = CompareTextAgainstFileL(got, atxt)) == KErrNone)
1.1385 + {
1.1386 + INFO_PRINTF1(HTML_GREEN);
1.1387 + INFO_PRINTF3(_L("%S: Text match with file %S"), &KTestFunction,
1.1388 + &atxt);
1.1389 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.1390 + return;
1.1391 + }
1.1392 +
1.1393 + ReportOnError(KTestFunction, _L("ColumnTextL"), acfgblk, acnnum, err);
1.1394 +
1.1395 + return;
1.1396 + }
1.1397 +void CSQLFnStep::ColumnTextPL(const TInt& acidx, const TPtrC &arg,
1.1398 + const TDesC& acfgblk, const TInt acnnum=-1)
1.1399 + {
1.1400 + _LIT(KTestFunction, "ColumnTextP");
1.1401 +
1.1402 + TPtrC got;
1.1403 + TInt err = isqlst.ColumnText(acidx, got);
1.1404 + ReportOnError(KTestFunction, _L("ColumnTextP"), acfgblk, acnnum, err);
1.1405 +
1.1406 + // First the simplest, does the text match the config text?
1.1407 + if(got == arg)
1.1408 + {
1.1409 + INFO_PRINTF1(HTML_GREEN);
1.1410 + INFO_PRINTF3(_L("%S: Got expected result, %S"), &KTestFunction,
1.1411 + &got);
1.1412 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.1413 + return;
1.1414 + }
1.1415 +
1.1416 + // Perhaps 'arg' is a file, CompareTextAgainstFile will
1.1417 + // return KErrNotFound if it can't find the file.
1.1418 + if((err = CompareTextAgainstFileL(got, arg)) == KErrNone)
1.1419 + {
1.1420 + INFO_PRINTF1(HTML_GREEN);
1.1421 + INFO_PRINTF3(_L("%S: Text match with file %S"), &KTestFunction,
1.1422 + &arg);
1.1423 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.1424 + return;
1.1425 + }
1.1426 +
1.1427 + ReportOnError(KTestFunction, _L("ColumnTextP"), acfgblk, acnnum, err);
1.1428 + }
1.1429 +void CSQLFnStep::ColumnTextDL(const TInt& acidx, const TPtrC &arg,
1.1430 + const TDesC& acfgblk, const TInt acnnum=-1)
1.1431 + {
1.1432 + _LIT(KTestFunction, "ColumnTextD");
1.1433 +// Masses of duplication.. We should have a common method to get around
1.1434 +// this, but perhaps when time permits..
1.1435 +
1.1436 + // How big is this item? This is measured in bytes, not characters.
1.1437 + TInt colsize = isqlst.ColumnSize(acidx);
1.1438 +
1.1439 + // Allocate a buffer.
1.1440 + RBuf buf;
1.1441 + TInt err = buf.Create(colsize);
1.1442 + INFO_PRINTF3(_L("%S: colsize %d"), &KTestFunction, colsize);
1.1443 + if(err != KErrNone)
1.1444 + {
1.1445 + SetTestStepResult(EFail);
1.1446 + INFO_PRINTF1(HTML_RED);
1.1447 + ERR_PRINTF3(_L("%S: Failed to allocate %d"), &KTestFunction,
1.1448 + colsize);
1.1449 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.1450 + }
1.1451 + CleanupClosePushL(buf);
1.1452 +
1.1453 + // Call ColumnText(TInt aColumnIndex, TDes& aDest);
1.1454 + err = isqlst.ColumnText(acidx, buf);
1.1455 + ReportOnError(KTestFunction, _L("ColumnTextD"), acfgblk, acnnum, err);
1.1456 + if(err != KErrNone)
1.1457 + {
1.1458 + CleanupStack::PopAndDestroy(1, &buf);
1.1459 + return;
1.1460 + }
1.1461 +
1.1462 + // First the simplest, does the text match the config text?
1.1463 + if(buf == arg)
1.1464 + {
1.1465 + INFO_PRINTF1(HTML_GREEN);
1.1466 + INFO_PRINTF3(_L("%S: Got expected result, %S"), &KTestFunction,
1.1467 + &buf);
1.1468 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.1469 + CleanupStack::PopAndDestroy(1, &buf);
1.1470 + return;
1.1471 + }
1.1472 +
1.1473 + // Perhaps 'arg' is a file, CompareTextAgainstFile will
1.1474 + // return KErrNotFound if it can't find the file.
1.1475 + if((err = CompareTextAgainstFileL(buf, arg)) == KErrNone)
1.1476 + {
1.1477 + INFO_PRINTF1(HTML_GREEN);
1.1478 + INFO_PRINTF3(_L("%S: Text match with file %S"), &KTestFunction,
1.1479 + &arg);
1.1480 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.1481 + CleanupStack::PopAndDestroy(1, &buf);
1.1482 + return;
1.1483 + }
1.1484 +
1.1485 + ReportOnError(KTestFunction, _L("ColumnTextD"), acfgblk, acnnum, err);
1.1486 + CleanupStack::PopAndDestroy(1, &buf);
1.1487 + return;
1.1488 + }
1.1489 +void CSQLFnStep::ColumnBinaryL(const TInt& acidx, const TPtrC &arg,
1.1490 + const TDesC& acfgblk, const TInt acnnum=-1)
1.1491 + {
1.1492 + _LIT(KTestFunction, "ColumnBinaryL");
1.1493 +
1.1494 + // Get the output from ColumnBinary.
1.1495 + TPtrC8 colb = isqlst.ColumnBinaryL(acidx);
1.1496 + INFO_PRINTF3(_L("%S: Got length %d"), &KTestFunction, colb.Length());
1.1497 + // If both are zero length, then we're expected nothing, which is a
1.1498 + // reasonable possibility.
1.1499 + if((colb.Length() == 0) && (arg.Length() == 0))
1.1500 + {
1.1501 + INFO_PRINTF1(HTML_GREEN);
1.1502 + INFO_PRINTF2(_L("%S: Got expected empty buffer."), &KTestFunction);
1.1503 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.1504 + return;
1.1505 + }
1.1506 +
1.1507 + // Compare ColumnBinary return against a file.
1.1508 + TInt err = CompareBinaryAgainstFileL(colb, arg);
1.1509 + ReportOnError(KTestFunction, _L("ColumnBinaryL"), acfgblk, acnnum, err);
1.1510 +
1.1511 + return;
1.1512 + }
1.1513 +void CSQLFnStep::ColumnBinaryPL(const TInt& acidx, const TPtrC &arg,
1.1514 + const TDesC& acfgblk, const TInt acnnum=-1)
1.1515 + {
1.1516 + _LIT(KTestFunction, "ColumnBinaryP");
1.1517 +
1.1518 + TInt csize = isqlst.ColumnSize(acidx);
1.1519 + INFO_PRINTF3(_L("%S: Colsize %d"), &KTestFunction, csize);
1.1520 +#ifdef _UNICODE
1.1521 + if(isqlst.ColumnType(acidx) == ESqlText) csize <<= 1;
1.1522 +#endif
1.1523 +
1.1524 + RBuf8 data;
1.1525 + TInt err;
1.1526 + if((err = data.Create(csize)) != KErrNone)
1.1527 + {
1.1528 + ReportOnError(KTestFunction, _L("Createbuf"), acfgblk, acnnum, err);
1.1529 + return;
1.1530 + }
1.1531 + CleanupClosePushL(data);
1.1532 + err = isqlst.ColumnBinary(acidx, data);
1.1533 + ReportOnError(KTestFunction, _L("ColumnBinaryP"), acfgblk, acnnum, err);
1.1534 + if((data.Length()==0) && (arg.Length()==0))
1.1535 + {
1.1536 + INFO_PRINTF1(HTML_GREEN);
1.1537 + INFO_PRINTF2(_L("%S: Got expected empty buffer."), &KTestFunction);
1.1538 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.1539 + CleanupStack::PopAndDestroy(1, &data);
1.1540 + return;
1.1541 + }
1.1542 + if(err != KErrNone)
1.1543 + {
1.1544 + CleanupStack::PopAndDestroy(1, &data);
1.1545 + return;
1.1546 + }
1.1547 +
1.1548 + // Compare ColumnBinary return against a file.
1.1549 + err = CompareBinaryAgainstFileL(data, arg);
1.1550 + ReportOnError(KTestFunction, _L("FileCompare"), acfgblk, acnnum, err);
1.1551 + CleanupStack::PopAndDestroy(1, &data);
1.1552 + return;
1.1553 + }
1.1554 +void CSQLFnStep::ColumnBinaryDL(const TInt& acidx, const TPtrC &arg,
1.1555 + const TDesC& acfgblk, const TInt acnnum=-1)
1.1556 + {
1.1557 + _LIT(KTestFunction, "ColumnBinaryD");
1.1558 +
1.1559 + // How big is this item?
1.1560 + TInt colsize = isqlst.ColumnSize(acidx);
1.1561 + INFO_PRINTF3(_L("%S: colsize %d"), &KTestFunction, colsize);
1.1562 +#ifdef _UNICODE
1.1563 + if(isqlst.ColumnType(acidx) == ESqlText) colsize <<= 1;
1.1564 +#endif
1.1565 +
1.1566 + // Allocate a buffer.
1.1567 + RBuf8 buf;
1.1568 + TInt err = buf.Create(colsize);
1.1569 + if(err != KErrNone)
1.1570 + {
1.1571 + SetTestStepResult(EFail);
1.1572 + INFO_PRINTF1(HTML_RED);
1.1573 + ERR_PRINTF3(_L("%S: Failed to allocate %d bytes"), &KTestFunction,
1.1574 + colsize);
1.1575 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.1576 + }
1.1577 + CleanupClosePushL(buf);
1.1578 +
1.1579 + // Call ColumnBinary(TInt aColumnIndex, TDes8& aDest);
1.1580 + err = isqlst.ColumnBinary(acidx, buf);
1.1581 + ReportOnError(KTestFunction, _L("ColumnBinaryD"), acfgblk, acnnum, err);
1.1582 + if(err != KErrNone)
1.1583 + {
1.1584 + CleanupStack::PopAndDestroy(1, &buf);
1.1585 + return;
1.1586 + }
1.1587 + if((buf.Length()==0) && (arg.Length()==0))
1.1588 + {
1.1589 + CleanupStack::PopAndDestroy(1, &buf);
1.1590 + INFO_PRINTF1(HTML_GREEN);
1.1591 + INFO_PRINTF2(_L("%S: Got expected empty buffer."), &KTestFunction);
1.1592 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.1593 + return;
1.1594 + }
1.1595 +
1.1596 + // Compare ColumnBinary return against a file.
1.1597 + err = CompareBinaryAgainstFileL(buf, arg);
1.1598 + ReportOnError(KTestFunction, _L("ColumnBinaryD"), acfgblk, acnnum, err);
1.1599 + CleanupStack::PopAndDestroy(1, &buf);
1.1600 +
1.1601 + return;
1.1602 + }
1.1603 +
1.1604 +// The following four methods, SWBindText, SWBindBinary, SRColumnText and
1.1605 +// SRColumnBinary are Stream-Write and Stream-Read methods.
1.1606 +// In each case 'arg' specifies a file which is opened as a source (SW)
1.1607 +// of data, or else as another stream (SR) to compare against.
1.1608 +void CSQLFnStep::SWBindTextL(const TInt& apidx, const TPtrC &arg,
1.1609 + const TDesC& acfgblk, const TInt acnnum=-1)
1.1610 + {
1.1611 + _LIT(KTestFunction, "SWBindText");
1.1612 + RSqlParamWriteStream sqlw;
1.1613 + // Get the WriteStream to stuff data down..
1.1614 + TInt err = sqlw.BindText(isqlst, apidx);
1.1615 + ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, err);
1.1616 + if(err != KErrNone) return;
1.1617 + WriteFileToStreamL(sqlw, arg);
1.1618 + sqlw.Close();
1.1619 + return;
1.1620 + }
1.1621 +void CSQLFnStep::SWBindBinaryL(const TInt& apidx, const TPtrC &arg,
1.1622 + const TDesC& acfgblk, const TInt acnnum=-1)
1.1623 + {
1.1624 + _LIT(KTestFunction, "SWBindBinary");
1.1625 + RSqlParamWriteStream sqlw;
1.1626 + // Get the WriteStream to stuff data down..
1.1627 + TInt err = sqlw.BindBinary(isqlst, apidx);
1.1628 + ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, err);
1.1629 + if(err != KErrNone) return;
1.1630 + WriteFileToStreamL(sqlw, arg);
1.1631 + sqlw.Close();
1.1632 + return;
1.1633 + }
1.1634 +void CSQLFnStep::SRColumnTextL(const TInt& acidx, const TPtrC &arg,
1.1635 + const TDesC& acfgblk, const TInt acnnum=-1)
1.1636 + {
1.1637 + _LIT(KTestFunction, "SRColumnText");
1.1638 +
1.1639 + // First find out how much data is in this cell..
1.1640 + TInt dsize = isqlst.ColumnSize(acidx);
1.1641 + INFO_PRINTF3(_L("%S: ColumnSize is %d"), &KTestFunction, dsize);
1.1642 +
1.1643 + RSqlColumnReadStream sqlr;
1.1644 + TInt err = sqlr.ColumnText(isqlst, acidx);
1.1645 + ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, err);
1.1646 + if(err != KErrNone) return;
1.1647 + // Ok, we have a Read Stream..
1.1648 + CleanupClosePushL(sqlr);
1.1649 +
1.1650 + // Compare it..
1.1651 + TInt rc = CompareTextStreamAgainstFileL(sqlr, dsize, arg);
1.1652 + if(rc)
1.1653 + {
1.1654 + SetTestStepResult(EFail);
1.1655 + INFO_PRINTF1(HTML_RED);
1.1656 + ERR_PRINTF3(_L("%S: Stream comparison failure, file %S"),
1.1657 + &KTestFunction, &arg);
1.1658 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.1659 + }
1.1660 + else
1.1661 + {
1.1662 + INFO_PRINTF1(HTML_GREEN);
1.1663 + INFO_PRINTF3(_L("%S: Stream comparison success, file %S"),
1.1664 + &KTestFunction, &arg);
1.1665 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.1666 + }
1.1667 + CleanupStack::PopAndDestroy(1,&sqlr);
1.1668 + return;
1.1669 + }
1.1670 +void CSQLFnStep::SRColumnBinaryL(const TInt& acidx, const TPtrC &arg,
1.1671 + const TDesC& acfgblk, const TInt acnnum=-1)
1.1672 + {
1.1673 + _LIT(KTestFunction, "SRColumnBinary");
1.1674 +
1.1675 + // First find out how much data is in this cell..
1.1676 + TInt dsize = isqlst.ColumnSize(acidx);
1.1677 + INFO_PRINTF3(_L("%S: Colsize is %d"), &KTestFunction, dsize);
1.1678 +#ifdef _UNICODE
1.1679 + if(isqlst.ColumnType(acidx) == ESqlText) dsize <<= 1;
1.1680 +#endif
1.1681 +
1.1682 + // Get our RReadStream and check for errors.
1.1683 + RSqlColumnReadStream sqlr;
1.1684 + TInt err = sqlr.ColumnBinary(isqlst, acidx);
1.1685 + ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, err);
1.1686 + if(err != KErrNone) return;
1.1687 + // Ok, we have a Read Stream..
1.1688 + CleanupClosePushL(sqlr);
1.1689 +
1.1690 + // Compare it..
1.1691 + TInt rc = CompareBinaryStreamAgainstFileL(sqlr, dsize, arg);
1.1692 + if(rc)
1.1693 + {
1.1694 + SetTestStepResult(EFail);
1.1695 + INFO_PRINTF1(HTML_RED);
1.1696 + ERR_PRINTF3(_L("%S: Stream comparison failure, file %S"),
1.1697 + &KTestFunction, &arg);
1.1698 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.1699 + }
1.1700 + else
1.1701 + {
1.1702 + INFO_PRINTF1(HTML_GREEN);
1.1703 + INFO_PRINTF3(_L("%S: Stream comparison success, file %S"),
1.1704 + &KTestFunction, &arg);
1.1705 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.1706 + }
1.1707 + CleanupStack::PopAndDestroy(1,&sqlr);
1.1708 + return;
1.1709 + }
1.1710 +
1.1711 +TBool CSQLFnStep::SPCreate(const TDesC &acfgblk, const TInt acnnum)
1.1712 + {
1.1713 + _LIT(KTestFunction, "SPCreate");
1.1714 +
1.1715 + TSecurityPolicy defaultPolicy;
1.1716 +
1.1717 + // Try to create the SQLDB security policy.
1.1718 + TInt rc = isqlsp.Create(defaultPolicy);
1.1719 + ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, rc);
1.1720 + if(rc == KErrNone) return ETrue;
1.1721 + return EFalse;
1.1722 + }
1.1723 +
1.1724 +TBool CSQLFnStep::SPCreate(const TPtrC&, const TDesC &acfgblk, const TInt acnnum)
1.1725 + {
1.1726 + _LIT(KTestFunction, "SPCreate");
1.1727 +
1.1728 + TSecurityPolicy defaultPolicy;
1.1729 +
1.1730 + // Try to create the SQLDB security policy.
1.1731 + TInt rc = KErrNone;
1.1732 + TRAP(rc, isqlsp.CreateL(defaultPolicy));
1.1733 + ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, rc);
1.1734 + if(rc == KErrNone) return ETrue;
1.1735 + return EFalse;
1.1736 + }
1.1737 +
1.1738 +void CSQLFnStep::SPClose()
1.1739 + {
1.1740 + isqlsp.Close();
1.1741 + return;
1.1742 + }
1.1743 +
1.1744 +TBool CSQLFnStep::SPSetDBPolicy(const TPtrC& apol, const TDesC &acfgblk, const TInt acnnum)
1.1745 + {
1.1746 + _LIT(KTestFunction, "SPSetDBPolicy");
1.1747 +
1.1748 + //extract the policy level and capability from the argument passed in
1.1749 + TPtrC level, cap;
1.1750 + CommaSeparated(apol, level, cap);
1.1751 +
1.1752 + //create the security policy object with the supplied capability
1.1753 + TSecurityPolicy sp((TCapability)(icaphsh->GetNumFromString(cap)));
1.1754 +
1.1755 + INFO_PRINTF2(_L("SetDBPolicy: %S"), &level);
1.1756 + INFO_PRINTF2(_L("Capabilities are: %S"), &cap);
1.1757 +
1.1758 + TInt rc = isqlsp.SetDbPolicy(((RSqlSecurityPolicy::TPolicyType)ipolhsh->GetNumFromString(level)), sp);
1.1759 + ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, rc);
1.1760 + if(rc == KErrNone) return ETrue;
1.1761 + return EFalse;
1.1762 + }
1.1763 +
1.1764 +TBool CSQLFnStep::SPSetPolicy(const TPtrC& apol, const TDesC &acfgblk, const TInt acnnum)
1.1765 + {
1.1766 + _LIT(KTestFunction, "SPSetPolicy");
1.1767 +
1.1768 + //extract the policy level and capability from the argument passed in
1.1769 + TPtrC arg, arg2, object, name, level, caps;
1.1770 + CommaSeparated(apol, object, arg);
1.1771 + CommaSeparated(arg, name, arg2);
1.1772 + CommaSeparated(arg2, level, caps);
1.1773 +
1.1774 + //create the security policy object with the supplied capability
1.1775 + TSecurityPolicy sp((TCapability)(icaphsh->GetNumFromString(caps)));
1.1776 +
1.1777 + INFO_PRINTF2(_L("SetPolicy: %S"), &level);
1.1778 + INFO_PRINTF2(_L("Capabilities are: %S"), &caps);
1.1779 + INFO_PRINTF2(_L("Object type is: %S"), &object);
1.1780 + INFO_PRINTF2(_L("Object name is: %S"), &name);
1.1781 +
1.1782 + TInt rc = isqlsp.SetPolicy(((RSqlSecurityPolicy::TObjectType)iobjhsh->GetNumFromString(object)), name, ((RSqlSecurityPolicy::TPolicyType)ipolhsh->GetNumFromString(level)), sp);
1.1783 + ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, rc);
1.1784 + if(rc == KErrNone) return ETrue;
1.1785 + return EFalse;
1.1786 + }
1.1787 +
1.1788 +void CSQLFnStep::SPExternalize(const TPtrC &arg, const TDesC &acfgblk, const TInt acnnum)
1.1789 + {
1.1790 + _LIT(KTestFunction, "SPExternalize");
1.1791 +
1.1792 + RFileWriteStream rfws;
1.1793 +
1.1794 + TInt err = rfws.Create(irfs, arg, EFileStream);
1.1795 + if(err != KErrNone)
1.1796 + {
1.1797 + SetTestStepResult(EFail);
1.1798 + INFO_PRINTF1(HTML_RED);
1.1799 + ERR_PRINTF4(_L("%S: Can't open file %S, err %d"), &KTestFunction, &arg,
1.1800 + err );
1.1801 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.1802 + return;
1.1803 + }
1.1804 +
1.1805 + TInt rc = KErrNone;
1.1806 + TRAP(rc, isqlsp.ExternalizeL(rfws));
1.1807 + TRAP(rc, rfws.CommitL());
1.1808 + ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, rc);
1.1809 + rfws.Close();
1.1810 + return;
1.1811 + }
1.1812 +
1.1813 +void CSQLFnStep::SPInternalize(const TPtrC &arg, const TDesC &acfgblk, const TInt acnnum)
1.1814 + {
1.1815 + _LIT(KTestFunction, "SPInternalize");
1.1816 +
1.1817 + RFileReadStream rfrs;
1.1818 +
1.1819 + TInt err = rfrs.Open(irfs, arg, EFileStream);
1.1820 + if(err != KErrNone)
1.1821 + {
1.1822 + SetTestStepResult(EFail);
1.1823 + INFO_PRINTF1(HTML_RED);
1.1824 + ERR_PRINTF3(_L("%S: Failed to open stream from file %S"), &KTestFunction, &arg);
1.1825 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.1826 + return;
1.1827 + }
1.1828 +
1.1829 + TInt rc = KErrNone;
1.1830 + TRAP(rc, isqlsp.InternalizeL(rfrs));
1.1831 +
1.1832 + ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, rc);
1.1833 + rfrs.Close();
1.1834 + return;
1.1835 + }
1.1836 +
1.1837 +// - Utility functions... --- we should remove these into a separate class --
1.1838 +//
1.1839 +// Stream functions - should we have a persistent stream? Here it goes
1.1840 +// out of scope once the method completes, but what about a case where for
1.1841 +// example we write to a cell, then write some more later to the same cell?
1.1842 +//
1.1843 +// Loads more duplication..
1.1844 +TInt CSQLFnStep::CompareTextStreamAgainstFileL(RReadStream &as, TInt asiz,
1.1845 + const TPtrC &afile)
1.1846 + {
1.1847 + _LIT(KTestFunction, "CompareTextStreamAgainstFile");
1.1848 + // Get the file size. This is in bytes, so for Unicode will be
1.1849 + // out by a factor of two. Also, if created with notepad or similar
1.1850 + // will have a 'FEFF' two byte marker at the start (which SQLite
1.1851 + // strips when it sees it).
1.1852 + TInt fsize = FileSize(afile);
1.1853 + if(fsize < 0) return fsize;;
1.1854 + // We don't divide asiz by two: This will have originated in ColumnSize
1.1855 + // which returns the number of characters in a cell.
1.1856 + TInt textlen = asiz;
1.1857 +#ifdef _UNICODE
1.1858 + fsize >>= 1;
1.1859 +#endif
1.1860 +
1.1861 + // If fsize is 1 different (2 bytes) from textlen, then we'll expect
1.1862 + // a unicode marker. If not 1 or zero give up straight away.
1.1863 + TInt diff = fsize - textlen;
1.1864 + TInt ucmark = (diff == 1);
1.1865 + if((diff>1) || (diff<0))
1.1866 + {
1.1867 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.1868 + ERR_PRINTF4(_L("%S Size mismatch. Expected %d, got %d"),
1.1869 + &KTestFunction, fsize, textlen);
1.1870 + SetTestStepResult(EFail);
1.1871 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.1872 + return KTEFSQLSizeError;
1.1873 + }
1.1874 +
1.1875 + // Open the reference file specified in the argument.
1.1876 + // Use an RFileReadStream because we need to worry about characters,
1.1877 + // not just bytes.
1.1878 + RFileReadStream rflrs;
1.1879 + TInt err = rflrs.Open(irfs, afile, EFileRead);
1.1880 + if(err != KErrNone)
1.1881 + return err;
1.1882 + CleanupClosePushL(rflrs);
1.1883 +
1.1884 + // Dumps the FEFF marker bytes for unicode files.
1.1885 + // SQLite does the same for text.
1.1886 + if(ucmark)
1.1887 + {
1.1888 + TInt16 mark = rflrs.ReadInt16L(); // byte order?
1.1889 + if((mark != (TInt16)0xfeff) && (mark != (TInt16)0xfffe))
1.1890 + {
1.1891 + CleanupStack::PopAndDestroy(1, &rflrs);
1.1892 + return KTEFSQLSizeError;
1.1893 + }
1.1894 + }
1.1895 +
1.1896 + // For each 32768 chars in the text buffer...
1.1897 + const TInt slice = 32768;
1.1898 + RBuf fbuf, abuf;
1.1899 + err = fbuf.Create(slice);
1.1900 + if(err == KErrNone) err = abuf.Create(slice);
1.1901 + if(err != KErrNone)
1.1902 + {
1.1903 + CleanupStack::PopAndDestroy(1, &rflrs);
1.1904 + return KErrNoMemory;
1.1905 + }
1.1906 + CleanupClosePushL(fbuf);
1.1907 + CleanupClosePushL(abuf);
1.1908 +
1.1909 + TInt rc = KErrNone;
1.1910 + for(TInt pos=0; pos < textlen ; pos += slice)
1.1911 + {
1.1912 + TInt toread = textlen - pos;
1.1913 + if(toread > slice)
1.1914 + toread = slice;
1.1915 +
1.1916 + // Read 'toread' characters from the file and from the passed in
1.1917 + // data.
1.1918 + as.ReadL(abuf, toread);
1.1919 + TPtrC txtslice = abuf.Left(toread);
1.1920 + rflrs.ReadL(fbuf, toread);
1.1921 + TPtrC fileslice = fbuf.Left(toread);
1.1922 +
1.1923 + // Compare ..
1.1924 + if (fileslice != txtslice)
1.1925 + {
1.1926 + rc = KTEFSQLSizeError;
1.1927 + break;
1.1928 + }
1.1929 + }
1.1930 + CleanupStack::PopAndDestroy(3, &rflrs);
1.1931 + return rc;
1.1932 + }
1.1933 +
1.1934 +// Loads more duplication..
1.1935 +TInt CSQLFnStep::CompareBinaryStreamAgainstFileL(RReadStream &as, TInt asiz,
1.1936 + const TPtrC &afile)
1.1937 + {
1.1938 + _LIT(KTestFunction, "CompareBinaryStreamAgainstFile");
1.1939 + // Get the file size. This is in bytes.
1.1940 + TInt fsize = FileSize(afile);
1.1941 + if(fsize < 0) return fsize;;
1.1942 +
1.1943 + // If sizes differ give up immediately.
1.1944 + if(fsize - asiz)
1.1945 + {
1.1946 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.1947 + ERR_PRINTF4(_L("%S Size mismatch. Expected %d, got %d"),
1.1948 + &KTestFunction, fsize, asiz);
1.1949 + SetTestStepResult(EFail);
1.1950 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.1951 + return KTEFSQLSizeError;
1.1952 + }
1.1953 +
1.1954 + // Open the reference file specified in the argument.
1.1955 + // Use an RFileReadStream because we need to worry about characters,
1.1956 + // not just bytes.
1.1957 + RFileReadStream rflrs;
1.1958 + TInt err = rflrs.Open(irfs, afile, EFileRead);
1.1959 + if(err != KErrNone) return err;
1.1960 + CleanupClosePushL(rflrs);
1.1961 +
1.1962 + // For each 32768 chars in the text buffer...
1.1963 + const TInt slice = 32768;
1.1964 + RBuf8 fbuf, abuf;
1.1965 + err = fbuf.Create(slice);
1.1966 + if(err == KErrNone) err = abuf.Create(slice);
1.1967 + if(err != KErrNone)
1.1968 + {
1.1969 + CleanupStack::PopAndDestroy(1, &rflrs);
1.1970 + return err;
1.1971 + }
1.1972 + CleanupClosePushL(fbuf);
1.1973 + CleanupClosePushL(abuf);
1.1974 +
1.1975 + TInt rc = KErrNone;
1.1976 + for(TInt pos=0; pos < asiz ; pos += slice)
1.1977 + {
1.1978 + TInt toread = asiz - pos;
1.1979 + if(toread > slice)
1.1980 + toread = slice;
1.1981 +
1.1982 + // Read 'toread' characters from the file and from the passed in
1.1983 + // data. Do we really need to chop out only the read bits for
1.1984 + // comparison? Wouldn't comparing fbuf and abuf work?
1.1985 + rflrs.ReadL(fbuf, toread);
1.1986 + TPtr8 fslice = fbuf.LeftTPtr(toread);
1.1987 + as.ReadL(abuf, toread);
1.1988 + TPtr8 aslice = abuf.LeftTPtr(toread);
1.1989 +
1.1990 + // Compare .. (does this compare only what's been read?)
1.1991 + if (fslice != aslice)
1.1992 + {
1.1993 + rc = KTEFSQLSizeError;
1.1994 + break;
1.1995 + }
1.1996 + }
1.1997 + CleanupStack::PopAndDestroy(3, &rflrs);
1.1998 + return rc;
1.1999 + }
1.2000 +void CSQLFnStep::WriteFileToStreamL(RWriteStream &as1, const TPtrC &afile)
1.2001 + {
1.2002 + _LIT(KTestFunction, "WriteFileToStream");
1.2003 + // Open the reference file specified in the argument.
1.2004 + RFileReadStream rflrs;
1.2005 + TInt err = rflrs.Open(irfs, afile, EFileRead);
1.2006 + // Do we want to return anything?
1.2007 + if(err != KErrNone)
1.2008 + {
1.2009 + SetTestStepResult(EFail);
1.2010 + INFO_PRINTF1(HTML_RED);
1.2011 + ERR_PRINTF3(_L("%S: Failed to open stream from file %S"),
1.2012 + &KTestFunction, &afile);
1.2013 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.2014 + return;
1.2015 + }
1.2016 + CleanupClosePushL(rflrs);
1.2017 + as1.WriteL(rflrs);
1.2018 + CleanupStack::PopAndDestroy(1, &rflrs);
1.2019 + return;
1.2020 + }
1.2021 +
1.2022 +TInt CSQLFnStep::CompareBinaryAgainstFileL(const TDesC8 &abuf,
1.2023 + const TFileName& afile)
1.2024 + {
1.2025 + _LIT(KTestFunction, "CompareBinaryAgainstFile");
1.2026 + // Get the file size.
1.2027 + TInt fsize = FileSize(afile);
1.2028 + if(fsize < 0) return fsize;
1.2029 + // How much binary do we have?
1.2030 + TInt binlen = abuf.Length();
1.2031 +
1.2032 + INFO_PRINTF4(_L("%S: Filelen %d, Binlen %d"), &KTestFunction, fsize, binlen);
1.2033 +
1.2034 + // If sizes differ drop out immediately.
1.2035 + if(fsize - binlen)
1.2036 + return KTEFSQLSizeError;
1.2037 +
1.2038 + // Open the reference file specified in the argument.
1.2039 + // Use an RFileReadStream because we need to worry about characters,
1.2040 + // not just bytes.
1.2041 + RFileReadStream rflrs;
1.2042 + TInt err = rflrs.Open(irfs, afile, EFileRead);
1.2043 + if(err != KErrNone)
1.2044 + return err;
1.2045 + CleanupClosePushL(rflrs);
1.2046 +
1.2047 + // For each 32768 chars in the text buffer...
1.2048 + const TInt slice = 32768;
1.2049 + RBuf8 fbuf;
1.2050 + fbuf.Create(slice);
1.2051 + CleanupClosePushL(fbuf);
1.2052 +
1.2053 + TInt rc = KErrNone;
1.2054 + for(TInt pos=0; pos < binlen ; pos += slice)
1.2055 + {
1.2056 + TInt toread = binlen - pos;
1.2057 + if(toread > slice)
1.2058 + toread = slice;
1.2059 +
1.2060 + // Read 'toread' bytes from the file and from the passed in
1.2061 + // data.
1.2062 + rflrs.ReadL(fbuf, toread);
1.2063 + TPtrC8 fileslice = fbuf.Left(toread);
1.2064 + TPtrC8 binslice = abuf.Mid(pos, toread);
1.2065 +
1.2066 + // Compare ..
1.2067 + if (fileslice != binslice)
1.2068 + {
1.2069 + rc = KTEFSQLSizeError;
1.2070 + break;
1.2071 + }
1.2072 + }
1.2073 +
1.2074 + INFO_PRINTF2(_L("%S: Comparison successful"), &KTestFunction);
1.2075 + CleanupStack::PopAndDestroy(2, &rflrs);
1.2076 + return rc;
1.2077 + }
1.2078 +
1.2079 +// Tested and working..
1.2080 +TInt CSQLFnStep::CompareTextAgainstFileL(const TDesC &atxt,
1.2081 + const TFileName& afile)
1.2082 + {
1.2083 + // Get the file size. This is in bytes, so for Unicode will be
1.2084 + // out by a factor of two. Also, if created with notepad or similar
1.2085 + // will have a 'FEFF' two byte marker at the start (which SQLite
1.2086 + // strips when it sees it).
1.2087 + TInt fsize = FileSize(afile);
1.2088 + if(fsize < 0) return fsize;
1.2089 +#ifdef _UNICODE
1.2090 + fsize >>= 1;
1.2091 +#endif
1.2092 + // How much text do we have?
1.2093 + TInt textlen = atxt.Length();
1.2094 +
1.2095 + // If fsize is 1 different (2 bytes) from textlen, then we'll expect
1.2096 + // a unicode marker. If not 1 or zero give up straight away.
1.2097 + TInt diff = fsize - textlen;
1.2098 + TInt ucmark = (diff == 1);
1.2099 + if((diff>1) || (diff<0))
1.2100 + {
1.2101 + ERR_PRINTF3(_L("FSIZE is %d, textlen is %d"), fsize, textlen);
1.2102 + return KTEFSQLSizeError;
1.2103 + }
1.2104 +
1.2105 + // Open the reference file specified in the argument.
1.2106 + // Use an RFileReadStream because we need to worry about characters,
1.2107 + // not just bytes.
1.2108 + RFileReadStream rflrs;
1.2109 + TInt err = rflrs.Open(irfs, afile, EFileRead);
1.2110 + if(err != KErrNone)
1.2111 + return err;
1.2112 + CleanupClosePushL(rflrs);
1.2113 +
1.2114 + // Dumps the FEFF marker bytes for unicode files.
1.2115 + // SQLite does the same for text.
1.2116 + if(ucmark)
1.2117 + {
1.2118 + TInt16 mark = rflrs.ReadInt16L(); // byte order?
1.2119 + if((mark != (TInt16)0xfeff) && (mark != (TInt16)0xfffe))
1.2120 + {
1.2121 + CleanupStack::PopAndDestroy(1, &rflrs);
1.2122 + return KTEFSQLSizeError;
1.2123 + }
1.2124 + }
1.2125 +
1.2126 + // For each 32768 chars in the text buffer...
1.2127 + const TInt slice = 32768;
1.2128 + RBuf fbuf;
1.2129 + fbuf.Create(slice);
1.2130 + CleanupClosePushL(fbuf);
1.2131 +
1.2132 + TInt rc = KErrNone;
1.2133 + for(TInt pos=0; pos < textlen ; pos += slice)
1.2134 + {
1.2135 + TInt toread = textlen - pos;
1.2136 + if(toread > slice)
1.2137 + toread = slice;
1.2138 +
1.2139 + // Read 'toread' characters from the file and from the passed in
1.2140 + // data.
1.2141 + rflrs.ReadL(fbuf, toread);
1.2142 + TPtrC txtslice = atxt.Mid(pos, toread);
1.2143 +
1.2144 + // Compare ..
1.2145 + if (fbuf != txtslice)
1.2146 + {
1.2147 + rc = KTEFSQLSizeError;
1.2148 + break;
1.2149 + }
1.2150 + }
1.2151 + CleanupStack::PopAndDestroy(2, &rflrs);
1.2152 + return rc;
1.2153 + }
1.2154 +
1.2155 +// Get the expected error code for the current action. Assume KErrNone if it
1.2156 +// isn't in the config file. We might have (in the config file)
1.2157 +// ExpectedError27=KSqlErrPermission
1.2158 +int CSQLFnStep::ActionNoToErrEnum(const TDesC& acfgsec, const TInt aActionNum,
1.2159 + TPtrC& aes)
1.2160 + {
1.2161 + TBuf<KConfigItemMaxNameLength> cnfgerr(_L("ExpectedError"));
1.2162 + if(aActionNum != -1) cnfgerr.AppendNum(aActionNum);
1.2163 + if(!GetStringFromConfig(acfgsec, cnfgerr, aes))
1.2164 + aes.Set(_L("KErrNone"));
1.2165 + return(ErrStringToEnum(aes));
1.2166 +}
1.2167 +TInt CSQLFnStep::ErrStringToEnum(TPtrC &aerr)
1.2168 + {
1.2169 + return(ierrhsh->GetNumFromString(aerr));
1.2170 + }
1.2171 +void CSQLFnStep::ErrEnumToString(const TInt &aerr, TPtrC &aptrstr)
1.2172 + {
1.2173 + aptrstr.Set(*(ierrhsh->GetStringFromNum(aerr)));
1.2174 + return;
1.2175 + }
1.2176 +const TPtrC CSQLFnStep::SqlColumnTypeToString(TSqlColumnType &asqltype)
1.2177 + {
1.2178 + return *icoltypehsh->GetStringFromNum(asqltype);
1.2179 + }
1.2180 +TSqlColumnType CSQLFnStep::StringToSqlColumnType(const TDesC &atype)
1.2181 + {
1.2182 + return (TSqlColumnType) icoltypehsh->GetNumFromString(atype);
1.2183 + }
1.2184 +/*
1.2185 + * A helper function to report on an error. This won't say anything if the
1.2186 + * error received (aerr) is equal to the error expected as defined in the
1.2187 + * configuration file.
1.2188 + */
1.2189 +void CSQLFnStep::ReportOnError(const TDesC &afnnam, const TDesC &apinam,
1.2190 + const TDesC &acfgblk, const TInt acfgno,
1.2191 + const TInt aerr)
1.2192 + {
1.2193 + // Get the expected error.
1.2194 + TPtrC experrS;
1.2195 + TInt experr = ActionNoToErrEnum(acfgblk, acfgno, experrS);
1.2196 +
1.2197 + // Some methods such as Exec and Next return a positive value on
1.2198 + // success. If we're not expecting an error and the actual error code
1.2199 + // is positive just return, everything is cool.
1.2200 + if((experr == KErrNone) && (aerr >= 0))
1.2201 + return;
1.2202 +
1.2203 + // Is the actual error the same as the expected error?
1.2204 + if(aerr != experr)
1.2205 + {
1.2206 + INFO_PRINTF1(HTML_RED);
1.2207 + SetTestStepResult(EFail);
1.2208 + TPtrC errS;
1.2209 + ErrEnumToString(aerr, errS); // Convert the actual error to a string.
1.2210 +
1.2211 + ERR_PRINTF7(_L("%S: %S gave error %d/%S, expected %d/%S"),
1.2212 + &afnnam, &apinam, aerr, &errS, experr, &experrS);
1.2213 + // Run 'LastErrorMessage' if we unexpectedly have 'KSqlErrGeneral',
1.2214 + // often what it has to say is very helpful.
1.2215 + if(aerr == KSqlErrGeneral)
1.2216 + LastErrorMessage(_L(""));
1.2217 +
1.2218 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.2219 + }
1.2220 + else if(aerr != KErrNone)
1.2221 + {
1.2222 + INFO_PRINTF1(HTML_GREEN);
1.2223 + INFO_PRINTF5(_L("%S: %S got expected error %d/%S"), &afnnam, &apinam,
1.2224 + aerr, &experrS);
1.2225 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.2226 + }
1.2227 + return;
1.2228 + }
1.2229 +TBool CSQLFnStep::FromConfig(const TDesC &afnnam, const TDesC &acfgblk,
1.2230 + const TDesC &acfgname, TPtrC &acfgval)
1.2231 + {
1.2232 + if(!GetStringFromConfig(acfgblk, acfgname, acfgval))
1.2233 + {
1.2234 + INFO_PRINTF1(HTML_RED);
1.2235 + ERR_PRINTF4(_L("%S: Failed to get %S:%S parameter."), &afnnam, &acfgblk,
1.2236 + &acfgname);
1.2237 + SetTestStepResult(EFail);
1.2238 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.2239 + return EFalse;
1.2240 + }
1.2241 + return ETrue;
1.2242 + }
1.2243 +TBool CSQLFnStep::FromConfig(const TDesC &afnnam, const TDesC &acfgblk,
1.2244 + const TDesC &acfgname, TInt &acfgval)
1.2245 + {
1.2246 + if(!GetIntFromConfig(acfgblk, acfgname, acfgval))
1.2247 + {
1.2248 + INFO_PRINTF1(HTML_RED);
1.2249 + ERR_PRINTF4(_L("%S: Failed to get %S:%S parameter."), &afnnam, &acfgblk,
1.2250 + &acfgname);
1.2251 + SetTestStepResult(EFail);
1.2252 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.2253 + return EFalse;
1.2254 + }
1.2255 + return ETrue;
1.2256 + }
1.2257 +TBool CSQLFnStep::FromConfig(const TDesC &afnnam, const TDesC &acfgblk,
1.2258 + const TDesC &acfgname, TReal &acfgval)
1.2259 + {
1.2260 + TPtrC gotS;
1.2261 + if(!GetStringFromConfig(acfgblk, acfgname, gotS))
1.2262 + {
1.2263 + INFO_PRINTF1(HTML_RED);
1.2264 + ERR_PRINTF4(_L("%S: Failed to get %S:%S parameter."), &afnnam, &acfgblk,
1.2265 + &acfgname);
1.2266 + SetTestStepResult(EFail);
1.2267 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.2268 + return EFalse;
1.2269 + }
1.2270 + TLex tl = gotS;
1.2271 + if(tl.Val(acfgval) != KErrNone)
1.2272 + {
1.2273 + ERR_PRINTF5(_L("%S:%S Failed to convert %S:%S to real."),
1.2274 + &afnnam, &acfgblk, &acfgname, &gotS);
1.2275 + return EFalse;
1.2276 + }
1.2277 +
1.2278 + return ETrue;
1.2279 + }
1.2280 +// Looking for, e.g, "9876,1234"
1.2281 +void CSQLFnStep::CommaSeparated(const TPtrC& ainp, TInt &aint, TInt &aint2)
1.2282 + {
1.2283 +// _LIT(KTestFunction, "CommaSeparated");
1.2284 +
1.2285 + // Read in what kind of binds we'll be doing..
1.2286 + TInt origlen = ainp.Length();
1.2287 + TChar comma(',');
1.2288 + TInt comoffset = ainp.Locate(comma);
1.2289 + if(comoffset != KErrNotFound)
1.2290 + {
1.2291 + TPtrC left = ainp.Left(comoffset);
1.2292 + TLex tl(left);
1.2293 + tl.Val(aint);
1.2294 + TInt rightlen = origlen - comoffset - 1;
1.2295 + TPtrC right = ainp.Right(rightlen);
1.2296 + tl = right;
1.2297 + tl.Val(aint2);
1.2298 + }
1.2299 + else
1.2300 + {
1.2301 + TLex tl(ainp);
1.2302 + tl.Val(aint);
1.2303 + aint2=-1;
1.2304 + }
1.2305 + }
1.2306 +// Looking for, e.g, "9876,some words"
1.2307 +void CSQLFnStep::CommaSeparated(const TPtrC& ainp, TInt &aint, TPtrC &astr)
1.2308 + {
1.2309 +// _LIT(KTestFunction, "CommaSeparated");
1.2310 +
1.2311 + TInt origlen = ainp.Length();
1.2312 + TChar comma(',');
1.2313 + TInt comoffset = ainp.Locate(comma);
1.2314 + if(comoffset != KErrNotFound)
1.2315 + {
1.2316 + TPtrC left = ainp.Left(comoffset);
1.2317 + TLex tl(left);
1.2318 + tl.Val(aint);
1.2319 + TInt rightlen = origlen - comoffset - 1;
1.2320 + astr.Set(ainp.Right(rightlen));
1.2321 + }
1.2322 + else
1.2323 + {
1.2324 + TLex tl(ainp);
1.2325 + tl.Val(aint);
1.2326 + astr.Set(_L(""));
1.2327 + }
1.2328 + }
1.2329 +void CSQLFnStep::CommaSeparated(const TPtrC& ainp, TPtrC &aleft, TPtrC &aright)
1.2330 + {
1.2331 +// _LIT(KTestFunction, "CommaSeparated");
1.2332 + aleft.Set(ainp);
1.2333 + aright.Set(_L(""));
1.2334 +
1.2335 + TInt origlen = ainp.Length();
1.2336 + TChar comma(',');
1.2337 + TInt comoffset = ainp.Locate(comma);
1.2338 + if(comoffset != KErrNotFound)
1.2339 + {
1.2340 + aleft.Set(ainp.Left(comoffset));
1.2341 + TInt rightlen = origlen - comoffset - 1;
1.2342 + aright.Set(ainp.Right(rightlen));
1.2343 + }
1.2344 + else
1.2345 + return;
1.2346 + }
1.2347 +TInt CSQLFnStep::FileSize(const TPtrC &afile)
1.2348 + {
1.2349 + // First open the file specified in the argument.
1.2350 + // This lot gets duplicated a lot.
1.2351 + RFile file;
1.2352 + TFileName fn = afile;
1.2353 + TInt err;
1.2354 + if((err = file.Open(irfs, fn, 0)) != KErrNone)
1.2355 + {
1.2356 + INFO_PRINTF1(HTML_RED);
1.2357 + ERR_PRINTF3(_L("Cannot open %S to get filesize, err %d"), &afile, err);
1.2358 + SetTestStepResult(EFail);
1.2359 + INFO_PRINTF1(HTML_COLOUR_OFF);
1.2360 +
1.2361 + return err;
1.2362 + }
1.2363 + TInt fsize;
1.2364 + file.Size(fsize);
1.2365 + file.Close();
1.2366 + return fsize;
1.2367 + }
1.2368 +