os/persistentdata/persistentstorage/sql/TEST/testexecute/SQLite/src/sqlfn.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // It would have been nice to create a new object every time we jump to
    15 // a new config block but reporting (INFO_PRINTF and ERR_PRINTF) doesn't
    16 // work from sub-objects. All in all the structure isn't what I'd like,
    17 // perhaps I'm missing some TEF functionality which would get around this. 
    18 // Various bits of repetition may be removed into utility class(es).
    19 // Some utility methods probably should go into utility class(es).
    20 // Unimplemented 8-bit methods, e.g Exec8.
    21 // 
    22 //
    23 
    24 #include "sqlfn.h"
    25 #include "Te_SQL_SuiteDefs.h"
    26 #include "common.h"
    27 
    28 // Contains code to perform functions on SQLite databases - what functions
    29 // and in what order is determined by the content of the config (.ini) file.
    30 
    31 CSQLFnStep::~CSQLFnStep()
    32 /**
    33  * Destructor
    34  */
    35     {
    36     // Get rid of the RFs object.. Note this isn't set up in the constructor
    37     // but in doTestStepL.
    38     irfs.Close();
    39 
    40     // Get rid of the semaphore objects.
    41     isemA.Close();
    42     isemB.Close();
    43 
    44     // Get rid of the hashes. These are originally set up in doTestStepL.
    45     delete ierrhsh;
    46     delete icoltypehsh;
    47     delete iactionhsh;
    48     delete icaphsh;
    49     delete ipolhsh;
    50     delete iobjhsh;
    51 
    52     // Get rid of the config item.
    53     if(icfg)delete icfg;
    54     }
    55 CSQLFnStep::CSQLFnStep()
    56     {
    57     // Create a global semaphore to be used by all instances of this framework
    58     // to be used for synchronising separate threads when 'CONCURRENT' is
    59     // used. If it already exists, then perhaps another thread already has it
    60     // which is fine - in that case just open it.
    61     TInt err = isemA.CreateGlobal(_L("SQLiteSemA"), 0);
    62     if(err == KErrAlreadyExists)
    63     	{
    64         err = isemA.OpenGlobal(_L("SQLiteSemA"));
    65     	}
    66     if(err != KErrNone)
    67     	{
    68 		INFO_PRINTF2(_L("Error %d creating semaphore"), err);
    69 		__ASSERT_ALWAYS(err == KErrNone, User::Invariant());
    70     	}
    71 
    72 	//
    73 	// Second semaphore require for DEF140385.
    74 	//
    75     err = isemB.CreateGlobal(_L("SQLiteSemB"), 0);
    76     if(err == KErrAlreadyExists)
    77     	{
    78         err = isemB.OpenGlobal(_L("SQLiteSemB"));
    79     	}
    80     if(err != KErrNone)
    81     	{
    82 		INFO_PRINTF2(_L("Error %d creating semaphoreB"), err);
    83 		__ASSERT_ALWAYS(err == KErrNone, User::Invariant());
    84     	}
    85     }
    86 TVerdict CSQLFnStep::doTestStepPostambleL()
    87     {
    88     // Try to make sure that the database and statement resources have been
    89     // properly closed (in case of problems).
    90     isqlst.Close();
    91     isqldb.Close();
    92     return TestStepResult();
    93     }
    94 TVerdict CSQLFnStep::doTestStepL()
    95 /**
    96  * @return - TVerdict code
    97  * Override of base class pure virtual. Our implementation only gets called
    98  * if the base class doTestStepPreambleL() did not leave. That being the case,
    99  * the current test result value will be EPass.
   100  */
   101     {
   102     // Create the RFs object so we can talk to the file-system when necessary.
   103     // Moved from the constructor to shut up leavescan.
   104     User::LeaveIfError(irfs.Connect());
   105     irfs.ShareProtected();
   106 
   107     // Make sure the database and statement objects get cleaned up..
   108     CleanupClosePushL(isqldb);
   109     CleanupClosePushL(isqlst);
   110 
   111     // Make sure that the icfg member is definitely unset when we start.
   112     icfg = NULL;
   113 
   114     // Get the hashes we use to associate words with numbers (e.g
   115     // KErrNone with 0). If these fail due to lack of memory they will
   116     // PANIC, which is fine. If we're that short of memory nothing is
   117     // going to work anyway.
   118     ierrhsh = new CSQLErrHash();
   119     icoltypehsh = new CSQLColTypeHash();
   120     iactionhsh = new CSQLTEFAction();
   121     icaphsh = new CSQLCapability();
   122     ipolhsh = new CSQLPolicy();
   123     iobjhsh = new CSQLObject();
   124      
   125     // Set the test result to PASS to start with and call the main block..
   126     SetTestStepResult(EPass);    
   127     SQLDbStepL(ConfigSection());
   128 
   129     // Clean up the database and statement objects.
   130     CleanupStack::PopAndDestroy(2, &isqldb);
   131 
   132     return TestStepResult();
   133     }
   134 // This is our 'main' function. It works out what method (e.g RSqlStatement::
   135 // Close) the user wants (based on the configuration file) and then calls
   136 // the appropriate wrapper function which runs the wanted method and reports
   137 // on any unexpected errors.
   138 void CSQLFnStep::SQLDbStepL(const TPtrC& acfgblk)
   139     {
   140     _LIT(KTestFunction, "SQLDbStep");
   141 
   142     /*
   143      * Go through all of the actions defined in the configuration file
   144      * acting on each. The counter will keep incrementing until we
   145      * fail to find a config item called 'CreateNN', or 'OpenNN' etc.
   146      * The two arrays hold Parameter and Column indices for use in
   147      * any method that needs one. E.G..
   148      */
   149     TInt ended=0;
   150 
   151     iasync = i8bit = EFalse;
   152     for(TInt count=0 ; ; count++)
   153         {
   154         TPtrC argument;
   155         TInt whatfun=Efn_undefined;
   156         for(TInt i=0 ; i < Efn_undefined ; i++)
   157             {
   158             // Construct something like 'ColumnInt37'
   159             TBuf<KStatementFunMaxLength> stfn(*(iactionhsh->GetStringFromNum(i)));
   160             stfn.AppendNum(count);
   161 
   162             // Does it exist in the config file? If not try e.g 'ColumnReal37'
   163             if(!GetStringFromConfig(acfgblk, stfn, argument))
   164                 continue;
   165 
   166             whatfun = i;
   167             if(whatfun == Ectrl_endblock)
   168                 ended = 1;
   169             // The GetString was successful, so we drop out anyway.
   170             break;
   171             }
   172         // If we hit an EndBlock marker or couldn't find any keyword with
   173         // the current counter number then drop out.
   174         if((whatfun == Efn_undefined) || (whatfun == Ectrl_endblock))
   175             break;
   176 
   177         // If there's a comma in the argument, split it up. We do
   178         // this here (rather than, more logically, in the called methods)
   179         // because we'd end up repeating the 'CommaSeparated' call in
   180         // all of the wrapper methods. Also, we need the indices for
   181         // Column and Parameter index resolution.
   182         TInt arg1, arg2;
   183         TPtrC arg3;
   184         CommaSeparated(argument, arg1, arg2);
   185         CommaSeparated(argument, arg1, arg3);
   186 
   187         TInt err=0;
   188         switch(whatfun)
   189             {
   190                 case Efn_nop: break;
   191             // First the RSqlDatabase methods...
   192                 case Efn_create:
   193                         Create(argument, acfgblk, count);
   194                         break;
   195                 case Efn_createl:
   196                         CreateL_(argument, acfgblk, count);
   197                         break;
   198                 case Efn_createsp:
   199                         CreateSP(argument, acfgblk, count);
   200                         break;
   201                 case Efn_open:
   202                         Open(argument, acfgblk, count);
   203                         break;
   204                 case Efn_openl:
   205                         OpenL_(argument, acfgblk, count);
   206                         break;
   207                 case Efn_attach:
   208                         Attach(argument, acfgblk, count);
   209                         break;
   210                 case Efn_detach:
   211                         Detach(argument, acfgblk, count);
   212                         break;
   213                 case Efn_copy:
   214                         Copy(argument, acfgblk, count);
   215                         break;
   216                 case Efn_close:
   217                         Close();
   218                         break;
   219                 case Efn_delete:
   220                         Delete(argument, acfgblk, count);
   221                         break;
   222                 case Efn_lasterrormessage:
   223                         LastErrorMessage(argument);
   224                         break;
   225                 case Efn_exec:
   226                         Exec(argument, acfgblk, count);
   227                         break;
   228                 case Efn_setisolationlevel:
   229                         SetIsolationLevel(argument, acfgblk, count);
   230                         break;
   231                 case Efn_reservedrivespace:
   232                         ReserveDriveSpace(arg1, acfgblk, count);
   233                         break;
   234                 case Efn_freereservedspace:
   235                         FreeReservedSpace();
   236                         break;
   237                 case Efn_getreserveaccess:
   238                         GetReserveAccess(acfgblk, count);
   239                         break;
   240                 case Efn_releasereserveaccess:
   241                         ReleaseReserveAccess();
   242                         break;
   243 
   244             // Now the RSqlStatement methods...
   245                 case Erstmt_prepare:
   246                         Prepare(argument, acfgblk, count);
   247                         break;
   248                 case Erstmt_preparel:
   249                         PrepareL_(argument, acfgblk, count);
   250                         break;
   251                 case Erstmt_close:
   252                         Close(1);
   253                         break;
   254                 case Erstmt_atrow:
   255                         AtRow(argument);
   256                         break;
   257                 case Erstmt_reset:
   258                         err = isqlst.Reset();
   259                         ReportOnError(KTestFunction, _L("Reset"), acfgblk,
   260                                                                  count, err);
   261                         break;
   262                 case Erstmt_exec:
   263                         {
   264                             TBuf<KConfigItemMaxNameLength> apiname(_L("st_exec"));
   265                             if(!iasync)
   266                                 err = isqlst.Exec();
   267                             else
   268                                 {
   269                                 TChar ch = 'A';
   270                                 apiname.Append(ch);
   271                                 TRequestStatus trs;
   272                                 isqlst.Exec(trs);
   273                                 User::WaitForRequest(trs);
   274                                 err = trs.Int();
   275                                 }
   276                             ReportOnError(KTestFunction, apiname,
   277                                                         acfgblk, count, err);
   278                         }
   279                         break;
   280                 case Erstmt_next:
   281                         Next(argument, acfgblk, count);
   282                         break;
   283                 case Erstmt_paramindex:
   284                             {
   285                             TInt pidx = ParamIndex(argument, acfgblk, count);
   286                             // The test designer will have to remember how many
   287                             // param indices have been stuck in this array..
   288                             if(pidx >= 0)ipidxs.Append(pidx);
   289                             }
   290                         break;
   291                 case Erstmt_colindex:
   292                             {
   293                             TInt cidx = ColumnIndex(argument, acfgblk, count);
   294                             // The test designer will have to remember how many
   295                             // column indices have been stuck in this array..
   296                             if(cidx >= 0)icidxs.Append(cidx);
   297                             }
   298                         break;
   299                 case Erstmt_coltype:
   300                         // ColumnType needs the ColumnIndex (the last arg)
   301                         // and also the expected result, which it will get from
   302                         // the config file. We have to deal with the ColumnIndex
   303                         // here because it lives in our scope, not that of the
   304                         // method we're calling..
   305                         // The test designer will have to remember how many
   306                         // column indices have been stuck in this array..
   307                         ColumnType(icidxs[arg1], arg3);
   308                         break;
   309                 case Erstmt_colsize:
   310                         ColumnSize(icidxs[arg1], arg2);
   311                         break;
   312                 case Erstmt_bindnull:
   313                         BindNull(ipidxs[arg1], acfgblk, count);
   314                         break;
   315                 case Erstmt_bindint:
   316                         BindInt(ipidxs[arg1], arg2, acfgblk, count);
   317                         break;
   318                 case Erstmt_bindint64:
   319                         BindInt64(ipidxs[arg1], arg3, acfgblk, count);
   320                         break;
   321                 case Erstmt_bindreal:
   322                         {
   323                         TLex tl = arg3;
   324                         TReal tr;
   325                         tl.Val(tr);
   326                         BindReal(ipidxs[arg1], tr, acfgblk, count);
   327                         }
   328                         break;
   329                 case Erstmt_bindtext:
   330                         BindText(ipidxs[arg1], arg3, acfgblk, count);
   331                         break;
   332                 case Erstmt_bindbigtext:
   333                         // Not an RSqlStatement method, but calls BindText
   334                         // after reading from a file.
   335                         BindBigTextL(ipidxs[arg1], arg3, acfgblk, count);
   336                         break;
   337                 case Erstmt_bindbinary:
   338                         BindBinaryL(ipidxs[arg1], arg3, acfgblk, count);
   339                         break;
   340                 case Erstmt_isnull:
   341                         IsNull(icidxs[arg1], arg3);
   342                         break;
   343                 case Erstmt_colint:
   344                         ColumnInt(icidxs[arg1], arg2);
   345                         break;
   346                 case Erstmt_colint64:
   347                         ColumnInt64(icidxs[arg1], arg3);
   348                         break;
   349                 case Erstmt_colreal:
   350                         {
   351                         TLex tl = arg3;
   352                         TReal tr2;
   353                         tl.Val(tr2);
   354                         ColumnReal(icidxs[arg1], tr2);
   355                         }
   356                         break;
   357                 case Erstmt_coltextL:
   358                         ColumnTextL(icidxs[arg1], arg3, acfgblk, count);
   359                         break;
   360                 case Erstmt_coltextP:
   361                         ColumnTextPL(icidxs[arg1], arg3, acfgblk, count);
   362                         break;
   363                 case Erstmt_coltextD:
   364                         ColumnTextDL(icidxs[arg1], arg3, acfgblk, count);
   365                         break;
   366                 case Erstmt_colbinL:
   367                         ColumnBinaryL(icidxs[arg1], arg3, acfgblk, count);
   368                         break;
   369                 case Erstmt_colbinP:
   370                         ColumnBinaryPL(icidxs[arg1], arg3, acfgblk, count);
   371                         break;
   372                 case Erstmt_colbinD:
   373                         ColumnBinaryDL(icidxs[arg1], arg3, acfgblk, count);
   374                         break;
   375 
   376                 case Esp_create:
   377                         SPCreate(acfgblk, count);
   378                         break;
   379                 case Esp_createl:
   380                         SPCreate(argument, acfgblk, count);
   381                         break;
   382                 case Esp_close:
   383                         SPClose();
   384                         break;
   385                 case Esp_setdbpolicy:
   386                         SPSetDBPolicy(argument, acfgblk, count);
   387                         break;
   388                 case Esp_setpolicy:
   389                         SPSetPolicy(argument, acfgblk, count);
   390                         break;
   391                 case Esp_externalizel:
   392                         SPExternalize(argument, acfgblk, count);
   393                         break;
   394                 case Esp_internalizel:
   395                         SPInternalize(argument, acfgblk, count);
   396                         break;
   397 
   398                 case Estreamwrite_bindtext:
   399                         SWBindTextL(ipidxs[arg1], arg3, acfgblk, count);
   400                         break;
   401                 case Estreamwrite_bindbinary:
   402                         SWBindBinaryL(ipidxs[arg1], arg3, acfgblk, count);
   403                         break;
   404                 case Estreamread_columntext:
   405                         SRColumnTextL(icidxs[arg1], arg3, acfgblk, count);
   406                         break;
   407                 case Estreamread_columnbinary:
   408                         SRColumnBinaryL(icidxs[arg1], arg3, acfgblk, count);
   409                         break;
   410                 case Edefineconfig:
   411                         {
   412                         if(icfg)
   413                             delete icfg;
   414                         TInt len = argument.Length();
   415                         if(len)
   416                             {
   417                             // At the time of writing, configuration strings
   418                             // are limited to 255 bytes.
   419                             TBuf8<256> arg;
   420                             arg.Copy(argument);
   421                             icfg = new TPtrC8(arg);
   422                             }
   423                         else
   424                             icfg = NULL;
   425                         }
   426                         break;
   427 
   428             // Actions that aren't direct method calls..
   429                 case Ectrl_newblock:
   430                         // Continue executing from another configuration
   431                         // block. Obviously this restarts the step
   432                         // counter at zero. It's unfortunate that we can't
   433                         // create a new test object here, that would be
   434                         // so much neater. But logging doesn't work in
   435                         // sub-objects (it could be bodged around but it
   436                         // really would be a bodge). A shame, we could have
   437                         // lots of member vars holding all this junk we're
   438                         // passing around. Note that because we don't create
   439                         // a new object we are playing with the same
   440                         // RSqlDatabase and RSqlStatement objects.
   441                         SQLDbStepL(argument);
   442                         break;
   443                 case Ectrl_function:
   444                         // Pure virtual. Lives elsewhere..
   445                         ResolveTestFunctionL(acfgblk, count, argument);
   446                         break;
   447 
   448                 case Ectrl_waitA:
   449                         // Wait for the isem member semaphore to receive
   450                         // arg1 signals for this thread. Obviously this assumes
   451                         // there's another thread that's going to execute
   452                         // a 'Signal' at some point.
   453 						for(TInt ii=0 ; ii<arg1 ; ++ii)
   454                             {
   455                             WaitA();
   456                             }
   457                         break;
   458                 case Ectrl_waitB:
   459                         // Wait for the isemB member semaphore to receive
   460                         // arg1 signals for this thread. Obviously this assumes
   461                         // there's another thread that's going to execute
   462                         // a 'SignalB' at some point.
   463 						for(TInt ii=0 ; ii<arg1 ; ++ii)
   464                             {
   465                             WaitB();
   466                             }
   467                         break;
   468                 case Ectrl_signalA:
   469                         // E.G Signal37=6 to wake up six threads that are
   470                         // waiting on isem.
   471                         SignalA(arg1);
   472                         break;
   473                 case Ectrl_signalB:
   474                         // E.G SignalB37=6 to wake up six threads that are
   475                         // waiting on isemB..
   476                         SignalB(arg1);
   477                         break;
   478                 case Ectrl_sleep:
   479                         INFO_PRINTF2(_L("Sleeping for %d microseconds"), arg1);
   480                         User::After(arg1);
   481                         break;
   482                 case Ectrl_eightbit:
   483                         if((argument == _L("On")) || (argument == _L("True")))
   484                             i8bit = ETrue;
   485                         else
   486                             i8bit = EFalse;
   487                         break;
   488                 case Ectrl_async:
   489                         if((argument == _L("On")) || (argument == _L("True")))
   490                             iasync = ETrue;
   491                         else
   492                             iasync = EFalse;
   493                         break;
   494 
   495             // Big problems if this stuff executes.
   496                 case Efn_undefined:
   497                         SetTestStepResult(EFail);
   498                         INFO_PRINTF1(HTML_RED);
   499                         ERR_PRINTF1(_L("This should never happen. A"));
   500                         INFO_PRINTF1(HTML_COLOUR_OFF);
   501                         break;
   502                 default:
   503                         SetTestStepResult(EFail);
   504                         INFO_PRINTF1(HTML_RED);
   505                         ERR_PRINTF1(_L("This should never happen. B"));
   506                         INFO_PRINTF1(HTML_COLOUR_OFF);
   507                         break;
   508             }
   509         // Let's get rid of any colour. Can get tangled in multi-threaded
   510         // tests.
   511         INFO_PRINTF1(HTML_COLOUR_OFF);
   512         }
   513     // If we get to this point and the 'ended' flag hasn't been set then
   514     // we haven't seen an 'EndBlockNN=' line in the config file. That
   515     // usually means the test has a missing <keyword><number> item
   516     // which is a test  failure.
   517     if(!ended)
   518         {
   519         SetTestStepResult(EFail);
   520         INFO_PRINTF1(HTML_RED);
   521         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);
   522         INFO_PRINTF1(HTML_COLOUR_OFF);
   523         }
   524     }
   525 
   526 // ----------Methods to exercise RSqlDatabase methods ------------------------
   527 
   528 TBool CSQLFnStep::Create(const TPtrC& adbnm,
   529                          const TDesC &acfgblk, TInt acnnum)
   530     {
   531     _LIT(KTestFunction, "Create");
   532     INFO_PRINTF3(_L("%S: Database name is %S "), &KTestFunction, &adbnm);
   533 
   534     // Try to create the database.
   535     TInt rc = isqldb.Create(adbnm, icfg);
   536     ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, rc);
   537     if(rc == KErrNone) return ETrue;
   538     return EFalse;
   539     }
   540 TBool CSQLFnStep::CreateL_(const TPtrC& adbnm,
   541                            const TDesC &acfgblk, TInt acnnum)
   542     {
   543     _LIT(KTestFunction, "CreateL");
   544     INFO_PRINTF3(_L("%S: Database name is %S "), &KTestFunction, &adbnm);
   545 
   546     // Try to create the database. Trap any leave (we're actually duplicating
   547     // what is in the non-leaving Create method, but hey, this is black box
   548     // testing, we're not supposed to know that..)
   549     TInt rc=KErrNone;
   550     TRAP(rc, isqldb.CreateL(adbnm, icfg));
   551     ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, rc);
   552     if(rc == KErrNone) return ETrue;
   553     return EFalse;
   554     }
   555 
   556 TBool CSQLFnStep::CreateSP(const TPtrC& adbnm, const TDesC &acfgblk, TInt acnnum)
   557     {
   558     _LIT(KTestFunction, "CreateSP");
   559     INFO_PRINTF3(_L("%S: Database name is %S "), &KTestFunction, &adbnm);
   560 
   561     TInt rc = isqldb.Create(adbnm, isqlsp, icfg);
   562     ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, rc);
   563     if(rc == KErrNone) return ETrue;
   564     return EFalse;
   565     }
   566     
   567 TBool CSQLFnStep::Open(const TPtrC& adbnm,
   568                        const TDesC &acfgblk, TInt acnnum)
   569     {
   570     _LIT(KTestFunction, "Open");
   571     INFO_PRINTF3(_L("%S: Database name is %S "), &KTestFunction, &adbnm);
   572 
   573     // Try to open the database.
   574     TInt rc = isqldb.Open(adbnm, icfg);
   575     ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, rc);
   576     if(rc == KErrNone) return ETrue;
   577     return EFalse;
   578     }
   579 TBool CSQLFnStep::OpenL_(const TPtrC& adbnm,
   580                          const TDesC &acfgblk, TInt acnnum)
   581     {
   582     _LIT(KTestFunction, "OpenL");
   583     INFO_PRINTF3(_L("%S: Database name is %S "), &KTestFunction, &adbnm);
   584 
   585     // Try to open the database.
   586     TInt rc = KErrNone;
   587     TRAP(rc, isqldb.OpenL(adbnm, icfg));
   588     ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, rc);
   589     if(rc == KErrNone) return ETrue;
   590     return EFalse;
   591     }
   592 // Close the current database.
   593 void CSQLFnStep::Close()
   594     {
   595 //  _LIT(KTestFunction, "Close");
   596     isqldb.Close();
   597     return;
   598     }
   599 void CSQLFnStep::Attach(const TPtrC &arg,
   600                         const TDesC &acfgblk, TInt acnnum)
   601     {
   602     _LIT(KTestFunction, "Attach");
   603     TPtrC sqldb, sqldbname;
   604     // Break arg into 'sqldb', the path/filename of the database to attach
   605     // and sqldbname, the name by which the database will be referred to
   606     // through this Attach.
   607     CommaSeparated(arg, sqldb, sqldbname);
   608     TInt rc = isqldb.Attach(sqldb, sqldbname);
   609     ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, rc);
   610     return;
   611     }
   612 void CSQLFnStep::Detach(const TPtrC &arg,
   613                         const TDesC &acfgblk, TInt acnnum)
   614     {
   615     _LIT(KTestFunction, "Detach");
   616     TInt rc = isqldb.Detach(arg);
   617     ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, rc);
   618     return;
   619     }
   620 void CSQLFnStep::Copy(const TPtrC &arg,
   621                       const TDesC &acfgblk, TInt acnnum)
   622     {
   623     _LIT(KTestFunction, "Copy");
   624     TPtrC sqldb1, sqldb2;
   625     CommaSeparated(arg, sqldb1, sqldb2);
   626     TInt rc = isqldb.Copy(sqldb1, sqldb2);
   627     ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, rc);
   628     return;
   629     }
   630 TBool CSQLFnStep::Delete(const TPtrC& adbnm,
   631                          const TDesC &acfgblk, TInt acnnum)
   632     {
   633     _LIT(KTestFunction, "Delete");
   634     INFO_PRINTF3(_L("%S: Database name is %S "), &KTestFunction, &adbnm);
   635 
   636     // Try to delete the database.
   637     TInt rc = isqldb.Delete(adbnm);
   638     ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, rc);
   639     if(rc == KErrNone) return ETrue;
   640     return EFalse;
   641     }
   642 void CSQLFnStep::LastErrorMessage(const TPtrC& arg)
   643                 
   644     {
   645     _LIT(KTestFunction, "LastErrorMessage");
   646 
   647     TPtrC lem = isqldb.LastErrorMessage();
   648     if(arg.Length() == 0)
   649         {
   650         INFO_PRINTF3(_L("%S: '%S'"), &KTestFunction, &lem);
   651         return; // No particular error message was expected, so just return.
   652         }
   653     if(lem != arg)
   654         {
   655         SetTestStepResult(EFail);
   656         INFO_PRINTF1(HTML_RED);
   657         ERR_PRINTF4(_L("%S: Expected Message '%S', got '%S'"), &KTestFunction,
   658                                                                    &arg, &lem);
   659         INFO_PRINTF1(HTML_COLOUR_OFF);
   660         }
   661     else
   662         {
   663         INFO_PRINTF1(HTML_GREEN);
   664         INFO_PRINTF3(_L("%S: Got expected Message '%S'"), &KTestFunction, &arg);
   665         INFO_PRINTF1(HTML_COLOUR_OFF);
   666         }
   667     return;
   668     }
   669 void CSQLFnStep::Exec(const TPtrC& arg,
   670                       const TDesC &acfgblk, TInt acnnum)
   671     {
   672     _LIT(KTestFunction, "Exec");
   673     TBuf<KConfigItemMaxNameLength> apiname(KTestFunction);
   674     TInt rc;
   675     if(i8bit == EFalse)
   676         {
   677         if(!iasync)
   678             rc = isqldb.Exec(arg);
   679         else
   680             {
   681             TChar ch = 'A';
   682             apiname.Append(ch);
   683             TRequestStatus trs;
   684             isqldb.Exec(arg, trs);
   685             User::WaitForRequest(trs);
   686             rc = trs.Int();
   687             }
   688         }
   689     else
   690         {
   691         apiname.AppendNum(8);
   692         RBuf8 b8;
   693         b8.Create(arg.Length());
   694         b8.Copy(arg);
   695         if(!iasync)
   696             rc = isqldb.Exec(b8);
   697         else
   698             {
   699             TChar ch = 'A';
   700             apiname.Append(ch);
   701             TRequestStatus trs;
   702             isqldb.Exec(b8, trs);
   703             User::WaitForRequest(trs);
   704             rc = trs.Int();
   705             }
   706         b8.Close();
   707         }
   708     ReportOnError(KTestFunction, apiname, acfgblk, acnnum, rc);
   709     return;
   710     }
   711 void CSQLFnStep::SetIsolationLevel(const TPtrC& arg,
   712                                    const TDesC &acfgblk, TInt acnnum)
   713     {
   714     _LIT(KTestFunction, "SetIsolationLevel");
   715     // Get the expected error code..
   716     TPtrC experrS;
   717     TInt experr = ActionNoToErrEnum(acfgblk, acnnum, experrS);
   718 
   719     INFO_PRINTF2(_L("SetIsolationLevel: %S"), &arg);
   720     RSqlDatabase::TIsolationLevel sil;
   721     if(arg == _L("EReadUncommitted"))
   722         sil = RSqlDatabase::EReadUncommitted;
   723     else if(arg == _L("EReadCommitted"))
   724         sil = RSqlDatabase::EReadCommitted;
   725     else if(arg == _L("ERepeatableRead"))
   726         sil = RSqlDatabase::ERepeatableRead;
   727     else if(arg == _L("ESerializable"))
   728         sil = RSqlDatabase::ESerializable;
   729     else
   730         {
   731         SetTestStepResult(EFail);
   732         INFO_PRINTF1(HTML_RED);
   733         ERR_PRINTF3(_L("%S: Unrecognized TIsolationLevel '%S'"), 
   734                                                     &KTestFunction, &arg);
   735         INFO_PRINTF1(HTML_COLOUR_OFF);
   736         return;
   737         }
   738 
   739     TInt rc = isqldb.SetIsolationLevel(sil);
   740     TPtrC err;
   741     ErrEnumToString(rc,err);
   742     if(rc != experr)
   743         {
   744         SetTestStepResult(EFail);
   745         INFO_PRINTF1(HTML_RED);
   746         ERR_PRINTF3(_L("Unexpected SetIsolationLevel error %d/%S"), rc, &err);
   747         TPtrC lem = isqldb.LastErrorMessage();
   748         ERR_PRINTF2(_L(" - Last Error Message: %S"), &lem);
   749         INFO_PRINTF1(HTML_COLOUR_OFF);
   750         return;
   751         }
   752     else
   753         INFO_PRINTF2(_L("SetIsolation level, got error %S as expected"), &err);
   754     return;
   755     }
   756 
   757 void CSQLFnStep::ReserveDriveSpace(TInt ares,
   758                                    const TDesC& acfgblk, const TInt acnnum)
   759     {
   760     _LIT(KTestFunction, "ReserveDriveSpace");
   761 
   762     // Try to reserve space..
   763     TInt rc = isqldb.ReserveDriveSpace(ares);
   764     ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, rc);
   765     return;
   766     }
   767 void CSQLFnStep::FreeReservedSpace()
   768     {
   769 //    _LIT(KTestFunction, "FreeReservedSpace");
   770     isqldb.FreeReservedSpace();
   771     return;
   772     }
   773 void CSQLFnStep::GetReserveAccess(const TDesC& acfgblk,
   774                                   const TInt acnnum)
   775     {
   776     _LIT(KTestFunction, "GetReserveAccess");
   777 
   778     // Try to reserve space..
   779     TInt rc = isqldb.GetReserveAccess();
   780     ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, rc);
   781     return;
   782     }
   783 void CSQLFnStep::ReleaseReserveAccess()
   784     {
   785 //    _LIT(KTestFunction, "ReleaseReserveSpace");
   786     isqldb.ReleaseReserveAccess();
   787     return;
   788     }
   789 
   790 // ----------Methods to exercise RSqlStatement methods ------------------------
   791 //
   792 // Execute a Close on the current RSqlStatement. This also clears out the
   793 // arrays of RBufs and RBuf8s which are used for BindText and
   794 // BindBinary (just a way of keeping the buffers in scope until the 
   795 // Exec/Close happens) and loses all of the ParameterIndex and ColumnIndex's.
   796 // The 'TInt' argument is just to differentiate between the RSqlDatabase
   797 // Close wrapper, and this RSqlStatement Close wrapper.
   798 void CSQLFnStep::Close(TInt)
   799     {
   800 //    _LIT(KTestFunction, "St_Close");
   801 
   802     // Close the RSqlStatement.
   803     isqlst.Close();
   804 
   805     // Empty the arrays where we keep references to BindXXX buffers,
   806     // closing those buffers as we go.
   807     for(TInt count = iBindRBufarr.Count() - 1 ; count >= 0; count--)
   808         {
   809         iBindRBufarr[count].Close();
   810         iBindRBufarr.Remove(count);
   811         }
   812     for(TInt count = iBindRBuf8arr.Count() - 1 ; count >= 0 ; count--)
   813         {
   814         iBindRBuf8arr[count].Close();
   815         iBindRBuf8arr.Remove(count);
   816         }
   817     if((iBindRBuf8arr.Count() != 0) || (iBindRBufarr.Count() != 0))
   818         {
   819         User::Panic(_L("RBuf arrays not empty"), 512);
   820         }
   821 
   822     // Empty the ParameterIndex and ColumnIndex arrays.
   823     while(ipidxs.Count()) ipidxs.Remove(0);
   824     while(icidxs.Count()) icidxs.Remove(0);
   825 
   826     return;
   827     }
   828 void CSQLFnStep::Next(TPtrC& arg,
   829                       const TDesC &acfgblk, TInt acnnum=-1)
   830     {
   831     _LIT(KTestFunction, "Next");
   832     TInt rc = isqlst.Next();
   833 
   834     // If arg is not zero length it will be KSqlAtEnd/KSqlAtRow, turn that
   835     // into the enumeration.
   836     if(arg.Length())
   837         {
   838         TInt expn = ErrStringToEnum(arg);
   839         TPtrC errS;
   840         ErrEnumToString(rc, errS); // Convert the actual rc to a string.
   841         if(expn != rc)
   842             {
   843             SetTestStepResult(EFail);
   844             INFO_PRINTF1(HTML_RED);
   845             ERR_PRINTF7(_L("%S/%S: Got %S/%d, expected %S/%d"), &KTestFunction,
   846                                     &acfgblk, &errS, rc, &arg, expn );
   847             INFO_PRINTF1(HTML_COLOUR_OFF);
   848             }
   849         }
   850     ReportOnError(KTestFunction, _L("Next"), acfgblk, acnnum, rc);
   851     return;
   852     }
   853 
   854 // Call the RSqlStatement method 'AtRow'. This returns a boolean. This
   855 // method expects the config file to contain a line resembling
   856 // 'AtRow57=false'. The return value is checked against the config
   857 // value and error/info is reported.
   858 void CSQLFnStep::AtRow(const TPtrC &arg)
   859 
   860     {
   861     _LIT(KTestFunction, "AtRow");
   862     TBuf<8> atrres(arg);
   863     atrres.LowerCase();
   864     TBool expected = EFalse;
   865     if(atrres == _L("false"))
   866         expected = EFalse;
   867     else if(atrres == _L("true"))
   868         expected = ETrue;
   869     else
   870         {
   871         SetTestStepResult(EFail);
   872         INFO_PRINTF1(HTML_RED);
   873         ERR_PRINTF3(_L("%S: expected config item to be true/false, got %S"),
   874                       &KTestFunction, &arg);
   875         INFO_PRINTF1(HTML_COLOUR_OFF);
   876         }
   877     TBool atr = isqlst.AtRow();
   878     if(atr != expected)
   879         {
   880         SetTestStepResult(EFail);
   881         INFO_PRINTF1(HTML_RED);
   882         ERR_PRINTF4(_L("%S: expected AtRow to return %S, got %d"),
   883                            &KTestFunction, &atrres, atr);
   884         INFO_PRINTF1(HTML_COLOUR_OFF);
   885         return;
   886         }
   887     else
   888         {
   889         INFO_PRINTF1(HTML_GREEN);
   890         INFO_PRINTF3(_L("%S: Got expected result, %S"), &KTestFunction, &atrres);
   891         INFO_PRINTF1(HTML_COLOUR_OFF);
   892         }
   893     return;
   894     }
   895 // Call the RSqlStatement method 'Prepare'. This returns an int. This
   896 // method expects the config file to contain a line resembling
   897 // 'Prepare43=Create Table tbl3(f1 etc)'. The return value is checked
   898 // against the expected error (in ReportOnError).
   899 void CSQLFnStep::Prepare(const TPtrC &arg,
   900                          const TDesC &acfgblk, TInt acnnum=-1)
   901     {
   902     _LIT(KTestFunction, "Prepare");
   903     INFO_PRINTF3(_L("%S: Prepare command is %S"), &KTestFunction, &arg);
   904 
   905     TInt rc;
   906     if(i8bit == EFalse)
   907         rc = isqlst.Prepare(isqldb, arg);
   908     else
   909         {
   910         RBuf8 b8;
   911         b8.Create(arg.Length());
   912         b8.Copy(arg);
   913         rc = isqlst.Prepare(isqldb, b8);
   914         b8.Close();
   915         }
   916     ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, rc);
   917     }
   918 void CSQLFnStep::PrepareL_(const TPtrC &arg,
   919                            const TDesC &acfgblk, TInt acnnum=-1)
   920     {
   921     _LIT(KTestFunction, "PrepareL");
   922     INFO_PRINTF3(_L("%S: PrepareL command is %S"), &KTestFunction, &arg);
   923 
   924     TInt rc=KErrNone;
   925     if(i8bit == EFalse)
   926         {
   927         TRAP(rc, isqlst.PrepareL(isqldb, arg));
   928         }
   929     else
   930         {
   931         RBuf8 b8;
   932         b8.Create(arg.Length());
   933         b8.Copy(arg);
   934         TRAP(rc, isqlst.PrepareL(isqldb, b8));
   935         b8.Close();
   936         }
   937     ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, rc);
   938     }
   939 // Call the RSqlStatement method 'ParamIndex'. This returns an int. This
   940 // method expects the config file to contain a line resembling
   941 // 'ParamIndex12=:Frog'. The return value is returned.
   942 TInt CSQLFnStep::ParamIndex(const TDesC &arg,
   943                             const TDesC &acfgblk, TInt acnnum=-1)
   944     {
   945     _LIT(KTestFunction, "ParameterIndex");
   946 
   947     // If the test specifies ':?' was the parameter index, we'll assume that
   948     // ':?' was given in the SELECT (a nameless parameter), this always gives
   949     // '1' for the paramIndex.
   950     if(arg == _L(":?"))
   951         return 1;
   952 
   953     // If arg resembles '23,*explicit*', then return the leading integer.
   954     // This is so we can call BindEtc with bad values for PANIC testing
   955     // or otherwise generate a specific parameter index.
   956     TInt pidx=0;
   957     TPtrC rhs;
   958     CommaSeparated(arg, pidx, rhs);
   959     if(rhs == _L("*explicit*"))
   960         {
   961         INFO_PRINTF3(_L("%S: Returning explicit Parameter Index %d"),
   962                                                       &KTestFunction, pidx);
   963         return pidx;
   964         }
   965 
   966     // Ok, run ParameterIndex.
   967     pidx = isqlst.ParameterIndex(arg);
   968 
   969     // ParameterIndex returns a non-negative integer on success. If the
   970     // return is negative, we have a problem. We cannot know what the
   971     // return is if the operation has succeeded, so checking the error
   972     // code is limited to required errors, i.e < 0.
   973     // ReportOnError will set test result to failure if the error doesn't
   974     // match our expected error.
   975     if(pidx < 0)
   976         ReportOnError(KTestFunction, _L("ParameterIndex"),
   977                        acfgblk, acnnum, pidx);
   978     return pidx;
   979     }
   980 // Call the RSqlStatement method 'ColumnIndex'. This returns an int. This
   981 // method expects the config file to contain a line resembling
   982 // 'ColumnIndex12=Fld3'. The return value is returned.
   983 TInt CSQLFnStep::ColumnIndex(const TPtrC& arg,
   984                              const TDesC &acfgblk, TInt acnnum=-1)
   985     {
   986     _LIT(KTestFunction, "ColumnIndex");
   987 
   988     // If no column is specified then return zero - this may be necessary
   989     // if the test is for example counting lines in a table ...
   990     // >select count(*) from mytbl;
   991     // In this case obviously there is no namable column, but the Api just
   992     // requires that the index for ColumnInt will be zero.
   993     if(arg.Length() == 0) return 0;
   994 
   995     // If arg resembles '23,*explicit*', then return the leading integer.
   996     // This is so we can call ColumnEtc with bad values for PANIC testing
   997     // or otherwise generate a specific parameter index.
   998     TInt colIndex=0;
   999     TPtrC rhs;
  1000     CommaSeparated(arg, colIndex, rhs);
  1001     if(rhs == _L("*explicit*"))
  1002         {
  1003         INFO_PRINTF3(_L("%S: Returning explicit Column Index %d"),
  1004                                                       &KTestFunction, colIndex);
  1005         return colIndex;
  1006         }
  1007     colIndex = isqlst.ColumnIndex(arg);
  1008     // ColumnIndex returns a non-negative integer on success. If the
  1009     // return is negative, we have a problem. We cannot know what the
  1010     // return is if the operation has succeeded, so checking the error
  1011     // code is limited to required errors, i.e < 0.
  1012     // ReportOnError will set test result to failure if the error doesn't
  1013     // match our expected error.
  1014     if(colIndex < 0)
  1015         ReportOnError(KTestFunction, _L("ColumnIndex"),
  1016                        acfgblk, acnnum, colIndex);
  1017     return colIndex;
  1018     }
  1019 // Call the RSqlStatement method 'ColumnType'.
  1020 void CSQLFnStep::ColumnType(const TInt &acidx, const TPtrC &aexp)
  1021 
  1022     {
  1023     _LIT(KTestFunction, "ColumnType");
  1024     TSqlColumnType gottype = isqlst.ColumnType(acidx);
  1025     TPtrC got(SqlColumnTypeToString(gottype));
  1026 
  1027     if((aexp.Length() ==0) || (StringToSqlColumnType(aexp)==gottype))
  1028         {
  1029         INFO_PRINTF1(HTML_GREEN);
  1030         INFO_PRINTF3(_L("%S: Got Column type %S"), &KTestFunction, &got); 
  1031         INFO_PRINTF1(HTML_COLOUR_OFF);
  1032         return;
  1033         }
  1034 
  1035     // If the expected type hasn't been specified then just display what
  1036     // we've got.
  1037     INFO_PRINTF1(HTML_RED);
  1038     ERR_PRINTF4(_L("%S: Got Column type %S, expected %S"),
  1039                           &KTestFunction, &got, &aexp);
  1040     SetTestStepResult(EFail);
  1041     INFO_PRINTF1(HTML_COLOUR_OFF);
  1042     return;
  1043     }
  1044 // Call the RSqlStatement method 'ColumnSize'. Check it against the
  1045 // expected size specified in the config file.
  1046 void CSQLFnStep::ColumnSize(const TInt& acolidx, const TInt &axexp)
  1047     {
  1048     _LIT(KTestFunction, "ColumnSize");
  1049     TInt csize = isqlst.ColumnSize(acolidx);
  1050 
  1051     if((axexp != -1) && (axexp != csize))
  1052         {
  1053         INFO_PRINTF1(HTML_RED);
  1054         SetTestStepResult(EFail);
  1055         ERR_PRINTF4(_L("%S: Got Column size %d, expected %d"),
  1056                        &KTestFunction, csize, axexp);
  1057         INFO_PRINTF1(HTML_COLOUR_OFF);
  1058         return;
  1059         }
  1060     // If colsize is -1 display what we have.
  1061     INFO_PRINTF3(_L("%S: Got Column size %d"), &KTestFunction, csize); 
  1062 
  1063     return;
  1064     }
  1065 // Onto the Bind methods...
  1066 void CSQLFnStep::BindNull(const TInt& apidx,
  1067                           const TDesC &acfgblk, const TInt acnnum=-1)
  1068     {
  1069     _LIT(KTestFunction, "BindNull");
  1070      
  1071     TInt err = isqlst.BindNull(apidx);
  1072     ReportOnError(KTestFunction, _L("BindNull"), acfgblk, acnnum, err);
  1073 
  1074     return;
  1075     }
  1076 void CSQLFnStep::BindInt(const TInt& apidx, const TInt& atob,
  1077                          const TDesC &acfgblk, const TInt acnnum=-1)
  1078     {
  1079     _LIT(KTestFunction, "BindInt");
  1080      
  1081     TInt err = isqlst.BindInt(apidx, atob);
  1082     ReportOnError(KTestFunction, _L("BindInt"), acfgblk, acnnum, err);
  1083 
  1084     return;
  1085     }
  1086 void CSQLFnStep::BindInt64(const TInt& apidx, const TPtrC& atob,
  1087                            const TDesC &acfgblk, const TInt acnnum=-1)
  1088     {
  1089     _LIT(KTestFunction, "BindInt64");
  1090     TInt64 bind;
  1091     TLex tl = atob;
  1092     tl.Val(bind);
  1093     TInt err = isqlst.BindInt64(apidx, bind);
  1094     ReportOnError(KTestFunction, _L("BindInt64"), acfgblk, acnnum, err);
  1095 
  1096     return;
  1097     }
  1098 void CSQLFnStep::BindReal(const TInt& apidx, const TReal& areal,
  1099                           const TDesC &acfgblk, const TInt acnnum=-1)
  1100     {
  1101     _LIT(KTestFunction, "BindReal");
  1102     TInt err = isqlst.BindReal(apidx, areal);
  1103     ReportOnError(KTestFunction, _L("BindReal"), acfgblk, acnnum, err);
  1104 
  1105     return;
  1106     }
  1107 // BindText from the config line...
  1108 // May be modified to return a ref which we can keep on the
  1109 // stack in the main loop. Then, when we hit a 'Next' that can be cleared.
  1110 // This is necessary because there are scoping problems with text and
  1111 // binarys - the SQL code expects buffers to remain in scope until
  1112 // the Exec/Next.
  1113 void CSQLFnStep::BindText(const TInt& apidx, const TPtrC& atxt,
  1114                           const TDesC &acfgblk, const TInt acnnum=-1)
  1115     {
  1116     _LIT(KTestFunction, "BindText");
  1117     TInt err = isqlst.BindText(apidx, atxt);
  1118     ReportOnError(KTestFunction, _L("BindText"), acfgblk, acnnum, err);
  1119 
  1120     return;
  1121     }
  1122 // An additional method to let us bind more than one line of text from
  1123 // a config file...
  1124 // If the Bind is successful the buffer which has been bound is appended
  1125 // to the 'iBindRBufarr' array. This is necessary to keep it in scope until
  1126 // the 'Next'/'Exec' actions.
  1127 void CSQLFnStep::BindBigTextL(const TInt& apidx, const TPtrC& arg,
  1128                               const TDesC &acfgblk, const TInt acnnum=-1)
  1129     {
  1130     _LIT(KTestFunction, "BindBigText");
  1131     RBuf buf;
  1132 
  1133     TInt fsize = FileSize(arg);
  1134     if(fsize < 0) return;  // This will have reported an error if necessary.
  1135     
  1136 #ifdef _UNICODE
  1137     fsize >>= 1;  // We're assuming here that one character is two bytes..
  1138 #endif
  1139 
  1140     // Create a buffer big enough for the text in the file.
  1141     TInt err = buf.Create(fsize);
  1142     if(err != KErrNone)
  1143         {
  1144         SetTestStepResult(EFail);
  1145         INFO_PRINTF1(HTML_RED);
  1146         ERR_PRINTF3(_L("%S: Can't allocate file buffer %S"), &KTestFunction, &arg);
  1147         INFO_PRINTF1(HTML_COLOUR_OFF);
  1148         return;
  1149         }
  1150     // Don't push buf onto the cleanup stack. We'll keep a reference to it
  1151     // which get removed on RSqlStatement::Reset.
  1152 
  1153     // Use an RFileReadStream because we need to worry about characters,
  1154     // not just bytes.
  1155     RFileReadStream rflrs;
  1156     if(rflrs.Open(irfs, arg, EFileRead) != KErrNone)
  1157         {
  1158         SetTestStepResult(EFail);
  1159         INFO_PRINTF1(HTML_RED);
  1160         ERR_PRINTF3(_L("%S: Can't open file %S"), &KTestFunction, &arg);
  1161         buf.Close();
  1162         INFO_PRINTF1(HTML_COLOUR_OFF);
  1163         return;
  1164         }
  1165     CleanupClosePushL(rflrs);
  1166     rflrs.ReadL(buf);
  1167 
  1168     // Do the bind...
  1169     err = isqlst.BindText(apidx, buf);
  1170     ReportOnError(KTestFunction, _L("BindText"), acfgblk, acnnum, err);
  1171     // Drop out if it failed.
  1172     if(err != KErrNone)
  1173         {
  1174         CleanupStack::PopAndDestroy(1, &rflrs);
  1175         buf.Close();
  1176         return;
  1177         }
  1178     CleanupStack::PopAndDestroy(1, &rflrs);
  1179 
  1180     // Tack the buffer onto the internal array. This keeps it in 
  1181     // scope until a RSqlStatement::Close is performed when it will get
  1182     // destroyed.
  1183     iBindRBufarr.Append(buf);
  1184 
  1185     return;
  1186     }
  1187 // If the Bind is successful the buffer which has been bound is appended
  1188 // to the 'iBindRBuf8arr' array. This is necessary to keep it in scope until
  1189 // the 'Next'/'Exec' actions.
  1190 void CSQLFnStep::BindBinaryL(const TInt& apidx, const TDesC& arg,
  1191                               const TDesC &acfgblk, const TInt acnnum)
  1192     {
  1193     _LIT(KTestFunction, "BindBinary");
  1194     TInt fsize = FileSize(arg);
  1195     if(fsize < 0)
  1196         {
  1197         SetTestStepResult(EFail);
  1198         INFO_PRINTF1(HTML_RED);
  1199         ERR_PRINTF3(_L("%S: Can't find file %S"), &KTestFunction, &arg);
  1200         INFO_PRINTF1(HTML_COLOUR_OFF);
  1201         return;
  1202         }
  1203     // Create the buffer we're going to bind from. We'll keep a reference
  1204     // to this so it doesn't go out of scope (it mustn't
  1205     // until Exec/Reset) so don't put it on the cleanup stack.
  1206     RBuf8 ap;
  1207     TInt err = ap.Create(fsize);
  1208     ReportOnError(KTestFunction, _L("BufferCreate"), acfgblk, acnnum, err);
  1209     if(err != KErrNone) return;
  1210 
  1211     // Now open the file specified in the argument.
  1212     RFile file;
  1213     TFileName fn = arg;
  1214     err = file.Open(irfs, fn, 0);
  1215     ReportOnError(KTestFunction, _L("FileOpen"), acfgblk, acnnum, err);
  1216     if(err != KErrNone)
  1217         {
  1218         ap.Close();
  1219         return;
  1220         }
  1221     CleanupClosePushL(file);
  1222 
  1223     // Attempt to read from the file.
  1224     err = file.Read(ap, fsize);
  1225     ReportOnError(KTestFunction, _L("FileRead"), acfgblk, acnnum, err);
  1226     if(err != KErrNone)
  1227         {
  1228         CleanupStack::PopAndDestroy(1, &file);
  1229         ap.Close();
  1230         return;
  1231         }
  1232 
  1233     // Do the bind...
  1234     err = isqlst.BindBinary(apidx, ap);
  1235     ReportOnError(KTestFunction, _L("BindBinary"), acfgblk, acnnum, err);
  1236 
  1237     // Drop out if it failed.
  1238     if(err != KErrNone)
  1239         {
  1240         CleanupStack::PopAndDestroy(1, &file);
  1241         ap.Close();
  1242         return;
  1243         }
  1244 
  1245     CleanupStack::PopAndDestroy(1, &file);
  1246 
  1247     // Ok things seemed to have worked. Tack the buffer onto our internal
  1248     // RBuf8 array to keep it in scope. It will finally get trashed when
  1249     // we do the next RSqlStatement::Reset.
  1250     iBindRBuf8arr.Append(ap);
  1251 
  1252     return;
  1253     }
  1254 void CSQLFnStep::IsNull(const TInt& apidx, const TPtrC& atxt)
  1255     {
  1256     _LIT(KTestFunction, "IsNull");
  1257     TBuf<8> isn(atxt);
  1258     isn.LowerCase();
  1259     TBool expected;
  1260     if(isn == _L("false"))
  1261         expected = EFalse;
  1262     else if(isn == _L("true"))
  1263         expected = ETrue;
  1264     else
  1265         {
  1266         SetTestStepResult(EFail);
  1267         INFO_PRINTF1(HTML_RED);
  1268         ERR_PRINTF3(_L("%S: expected argument item to be true/false, got %S"),
  1269                      &KTestFunction, &atxt);
  1270         INFO_PRINTF1(HTML_COLOUR_OFF);
  1271         return;
  1272         }
  1273     if(isqlst.IsNull(apidx) != expected)
  1274         {
  1275         SetTestStepResult(EFail);
  1276         INFO_PRINTF1(HTML_RED);
  1277         ERR_PRINTF3(_L("%S: expected IsNull to return %S"), &KTestFunction,
  1278                             &atxt);
  1279         INFO_PRINTF1(HTML_COLOUR_OFF);
  1280         return;
  1281         }
  1282     else
  1283         {
  1284         INFO_PRINTF1(HTML_GREEN);
  1285         INFO_PRINTF3(_L("%S: Got expected result, %S"), &KTestFunction, &atxt);
  1286         INFO_PRINTF1(HTML_COLOUR_OFF);
  1287         }
  1288     return;
  1289     }
  1290 void CSQLFnStep::ColumnInt(const TInt& acidx, const TInt& aint)
  1291     {
  1292     _LIT(KTestFunction, "ColumnInt");
  1293 
  1294     TInt got = isqlst.ColumnInt(acidx);
  1295     if(got != aint)
  1296         {
  1297         SetTestStepResult(EFail);
  1298         INFO_PRINTF1(HTML_RED);
  1299         ERR_PRINTF4(_L("%S: expected ColumnInt to return %d, got %d"),
  1300                            &KTestFunction, aint, got);
  1301         INFO_PRINTF1(HTML_COLOUR_OFF);
  1302         return;
  1303         }
  1304     else
  1305         {
  1306         INFO_PRINTF1(HTML_GREEN);
  1307         INFO_PRINTF3(_L("%S: Got expected result, %d"), &KTestFunction,
  1308                            got);
  1309         INFO_PRINTF1(HTML_COLOUR_OFF);
  1310         }
  1311     return;
  1312     }
  1313 void CSQLFnStep::ColumnInt64(const TInt& acidx, const TPtrC& aintS)
  1314     {
  1315     _LIT(KTestFunction, "ColumnInt64");
  1316 
  1317     TLex tl(aintS);
  1318     TInt64 aint;
  1319     tl.Val(aint);
  1320     TInt64 got = isqlst.ColumnInt64(acidx);
  1321     if(got != aint)
  1322         {
  1323         SetTestStepResult(EFail);
  1324         INFO_PRINTF1(HTML_RED);
  1325         ERR_PRINTF3(_L("%S: expected ColumnInt to return %S"),
  1326                                    &KTestFunction, &aint);
  1327         INFO_PRINTF1(HTML_COLOUR_OFF);
  1328         return;
  1329         }
  1330     else
  1331         {
  1332         INFO_PRINTF1(HTML_GREEN);
  1333         INFO_PRINTF3(_L("%S: Got expected result, %ld"), &KTestFunction,
  1334                            got);
  1335         INFO_PRINTF1(HTML_COLOUR_OFF);
  1336         }
  1337     return;
  1338     }
  1339 void CSQLFnStep::ColumnReal(const TInt& acidx, const TReal& areal)
  1340     {
  1341     _LIT(KTestFunction, "ColumnReal");
  1342 
  1343     TReal got = isqlst.ColumnReal(acidx);
  1344     if(got != areal)
  1345         {
  1346         SetTestStepResult(EFail);
  1347         INFO_PRINTF1(HTML_RED);
  1348         ERR_PRINTF4(_L("%S: expected ColumnReal to return %f, got %f"),
  1349                            &KTestFunction, areal, got);
  1350         INFO_PRINTF1(HTML_COLOUR_OFF);
  1351         return;
  1352         }
  1353     else
  1354         {
  1355         INFO_PRINTF1(HTML_GREEN);
  1356         INFO_PRINTF3(_L("%S: Got expected result, %f"), &KTestFunction, got);
  1357         INFO_PRINTF1(HTML_COLOUR_OFF);
  1358         }
  1359     return;
  1360     }
  1361 void CSQLFnStep::ColumnTextL(const TInt& acidx, const TPtrC& atxt,
  1362                              const TDesC &acfgblk, const TInt acnnum=-1)
  1363     {
  1364     _LIT(KTestFunction, "ColumnTextL");
  1365 
  1366     TPtrC got = isqlst.ColumnTextL(acidx);
  1367     TInt err;
  1368 
  1369     // First the simplest, does the text match the config text?
  1370     if(got == atxt)
  1371         {
  1372         INFO_PRINTF1(HTML_GREEN);
  1373         INFO_PRINTF3(_L("%S: Got expected result, %S"), &KTestFunction,
  1374                            &got);
  1375         INFO_PRINTF1(HTML_COLOUR_OFF);
  1376         return;
  1377         }
  1378 
  1379     // Perhaps 'atxt' is a file, CompareTextAgainstFile will
  1380     // return KErrNotFound if it can't find the file.
  1381     if((err = CompareTextAgainstFileL(got, atxt)) == KErrNone)
  1382         {
  1383         INFO_PRINTF1(HTML_GREEN);
  1384         INFO_PRINTF3(_L("%S: Text match with file %S"), &KTestFunction,
  1385                            &atxt);
  1386         INFO_PRINTF1(HTML_COLOUR_OFF);
  1387         return;
  1388         }
  1389 
  1390     ReportOnError(KTestFunction, _L("ColumnTextL"), acfgblk, acnnum, err);
  1391 
  1392     return;
  1393     }
  1394 void CSQLFnStep::ColumnTextPL(const TInt& acidx, const TPtrC &arg,
  1395                               const TDesC& acfgblk, const TInt acnnum=-1)
  1396     {
  1397     _LIT(KTestFunction, "ColumnTextP");
  1398 
  1399     TPtrC got;
  1400     TInt err = isqlst.ColumnText(acidx, got);
  1401     ReportOnError(KTestFunction, _L("ColumnTextP"), acfgblk, acnnum, err);
  1402 
  1403     // First the simplest, does the text match the config text?
  1404     if(got == arg)
  1405         {
  1406         INFO_PRINTF1(HTML_GREEN);
  1407         INFO_PRINTF3(_L("%S: Got expected result, %S"), &KTestFunction,
  1408                            &got);
  1409         INFO_PRINTF1(HTML_COLOUR_OFF);
  1410         return;
  1411         }
  1412 
  1413     // Perhaps 'arg' is a file, CompareTextAgainstFile will
  1414     // return KErrNotFound if it can't find the file.
  1415     if((err = CompareTextAgainstFileL(got, arg)) == KErrNone)
  1416         {
  1417         INFO_PRINTF1(HTML_GREEN);
  1418         INFO_PRINTF3(_L("%S: Text match with file %S"), &KTestFunction,
  1419                            &arg);
  1420         INFO_PRINTF1(HTML_COLOUR_OFF);
  1421         return;
  1422         }
  1423 
  1424     ReportOnError(KTestFunction, _L("ColumnTextP"), acfgblk, acnnum, err);
  1425     }
  1426 void CSQLFnStep::ColumnTextDL(const TInt& acidx, const TPtrC &arg,
  1427                               const TDesC& acfgblk, const TInt acnnum=-1)
  1428     {
  1429     _LIT(KTestFunction, "ColumnTextD");
  1430 // Masses of duplication.. We should have a common method to get around
  1431 // this, but perhaps when time permits..
  1432 
  1433     // How big is this item? This is measured in bytes, not characters.
  1434     TInt colsize = isqlst.ColumnSize(acidx);
  1435 
  1436     // Allocate a buffer.
  1437     RBuf buf;
  1438     TInt err = buf.Create(colsize);
  1439     INFO_PRINTF3(_L("%S: colsize %d"), &KTestFunction, colsize);
  1440     if(err != KErrNone)
  1441         {
  1442         SetTestStepResult(EFail);
  1443         INFO_PRINTF1(HTML_RED);
  1444         ERR_PRINTF3(_L("%S: Failed to allocate %d"), &KTestFunction,
  1445                            colsize);
  1446         INFO_PRINTF1(HTML_COLOUR_OFF);
  1447         }
  1448     CleanupClosePushL(buf);
  1449 
  1450     // Call ColumnText(TInt aColumnIndex, TDes& aDest);
  1451     err = isqlst.ColumnText(acidx, buf);
  1452     ReportOnError(KTestFunction, _L("ColumnTextD"), acfgblk, acnnum, err);
  1453     if(err != KErrNone)
  1454         {
  1455         CleanupStack::PopAndDestroy(1, &buf);
  1456         return;
  1457         }
  1458 
  1459     // First the simplest, does the text match the config text?
  1460     if(buf == arg)
  1461         {
  1462         INFO_PRINTF1(HTML_GREEN);
  1463         INFO_PRINTF3(_L("%S: Got expected result, %S"), &KTestFunction,
  1464                            &buf);
  1465         INFO_PRINTF1(HTML_COLOUR_OFF);
  1466         CleanupStack::PopAndDestroy(1, &buf);
  1467         return;
  1468         }
  1469 
  1470     // Perhaps 'arg' is a file, CompareTextAgainstFile will
  1471     // return KErrNotFound if it can't find the file.
  1472     if((err = CompareTextAgainstFileL(buf, arg)) == KErrNone)
  1473         {
  1474         INFO_PRINTF1(HTML_GREEN);
  1475         INFO_PRINTF3(_L("%S: Text match with file %S"), &KTestFunction,
  1476                            &arg);
  1477         INFO_PRINTF1(HTML_COLOUR_OFF);
  1478         CleanupStack::PopAndDestroy(1, &buf);
  1479         return;
  1480         }
  1481 
  1482     ReportOnError(KTestFunction, _L("ColumnTextD"), acfgblk, acnnum, err);
  1483     CleanupStack::PopAndDestroy(1, &buf);
  1484     return;
  1485     }
  1486 void CSQLFnStep::ColumnBinaryL(const TInt& acidx, const TPtrC &arg,
  1487                                const TDesC& acfgblk, const TInt acnnum=-1)
  1488     {
  1489     _LIT(KTestFunction, "ColumnBinaryL");
  1490 
  1491     // Get the output from ColumnBinary.
  1492     TPtrC8 colb = isqlst.ColumnBinaryL(acidx);
  1493     INFO_PRINTF3(_L("%S: Got length %d"), &KTestFunction, colb.Length());
  1494     // If both are zero length, then we're expected nothing, which is a
  1495     // reasonable possibility.
  1496     if((colb.Length() == 0) && (arg.Length() == 0))
  1497         {
  1498         INFO_PRINTF1(HTML_GREEN);
  1499         INFO_PRINTF2(_L("%S: Got expected empty buffer."), &KTestFunction);
  1500         INFO_PRINTF1(HTML_COLOUR_OFF);
  1501         return;
  1502         }
  1503 
  1504     // Compare ColumnBinary return against a file.
  1505     TInt err = CompareBinaryAgainstFileL(colb, arg);
  1506     ReportOnError(KTestFunction, _L("ColumnBinaryL"), acfgblk, acnnum, err);
  1507 
  1508     return;
  1509     }
  1510 void CSQLFnStep::ColumnBinaryPL(const TInt& acidx, const TPtrC &arg,
  1511                                 const TDesC& acfgblk, const TInt acnnum=-1)
  1512     {
  1513     _LIT(KTestFunction, "ColumnBinaryP");
  1514 
  1515     TInt csize = isqlst.ColumnSize(acidx);
  1516     INFO_PRINTF3(_L("%S: Colsize %d"), &KTestFunction, csize);
  1517 #ifdef _UNICODE
  1518     if(isqlst.ColumnType(acidx) == ESqlText) csize <<= 1;
  1519 #endif
  1520 
  1521     RBuf8 data;
  1522     TInt err;
  1523     if((err = data.Create(csize)) != KErrNone)
  1524         {
  1525         ReportOnError(KTestFunction, _L("Createbuf"), acfgblk, acnnum, err);
  1526         return;
  1527         }
  1528     CleanupClosePushL(data);
  1529     err = isqlst.ColumnBinary(acidx, data);
  1530     ReportOnError(KTestFunction, _L("ColumnBinaryP"), acfgblk, acnnum, err);
  1531     if((data.Length()==0) && (arg.Length()==0))
  1532         {
  1533         INFO_PRINTF1(HTML_GREEN);
  1534         INFO_PRINTF2(_L("%S: Got expected empty buffer."), &KTestFunction);
  1535         INFO_PRINTF1(HTML_COLOUR_OFF);
  1536         CleanupStack::PopAndDestroy(1, &data);
  1537         return;
  1538         }
  1539     if(err != KErrNone)
  1540         {
  1541         CleanupStack::PopAndDestroy(1, &data);
  1542            return;
  1543         }
  1544 
  1545     // Compare ColumnBinary return against a file.
  1546     err = CompareBinaryAgainstFileL(data, arg);
  1547     ReportOnError(KTestFunction, _L("FileCompare"), acfgblk, acnnum, err);
  1548     CleanupStack::PopAndDestroy(1, &data);
  1549     return;
  1550     }
  1551 void CSQLFnStep::ColumnBinaryDL(const TInt& acidx, const TPtrC &arg,
  1552                                 const TDesC& acfgblk, const TInt acnnum=-1)
  1553     {
  1554     _LIT(KTestFunction, "ColumnBinaryD");
  1555 
  1556     // How big is this item?
  1557     TInt colsize = isqlst.ColumnSize(acidx);
  1558     INFO_PRINTF3(_L("%S: colsize %d"), &KTestFunction, colsize);
  1559 #ifdef _UNICODE
  1560     if(isqlst.ColumnType(acidx) == ESqlText) colsize <<= 1;
  1561 #endif
  1562 
  1563     // Allocate a buffer.
  1564     RBuf8 buf;
  1565     TInt err = buf.Create(colsize);
  1566     if(err != KErrNone)
  1567         {
  1568         SetTestStepResult(EFail);
  1569         INFO_PRINTF1(HTML_RED);
  1570         ERR_PRINTF3(_L("%S: Failed to allocate %d bytes"), &KTestFunction,
  1571                            colsize);
  1572         INFO_PRINTF1(HTML_COLOUR_OFF);
  1573         }
  1574     CleanupClosePushL(buf);
  1575 
  1576     // Call ColumnBinary(TInt aColumnIndex, TDes8& aDest);
  1577     err = isqlst.ColumnBinary(acidx, buf);
  1578     ReportOnError(KTestFunction, _L("ColumnBinaryD"), acfgblk, acnnum, err);
  1579     if(err != KErrNone)
  1580         {
  1581         CleanupStack::PopAndDestroy(1, &buf);
  1582         return;
  1583         }
  1584     if((buf.Length()==0) && (arg.Length()==0))
  1585         {
  1586         CleanupStack::PopAndDestroy(1, &buf);
  1587         INFO_PRINTF1(HTML_GREEN);
  1588         INFO_PRINTF2(_L("%S: Got expected empty buffer."), &KTestFunction);
  1589         INFO_PRINTF1(HTML_COLOUR_OFF);
  1590         return;
  1591         }
  1592 
  1593     // Compare ColumnBinary return against a file.
  1594     err = CompareBinaryAgainstFileL(buf, arg);
  1595     ReportOnError(KTestFunction, _L("ColumnBinaryD"), acfgblk, acnnum, err);
  1596     CleanupStack::PopAndDestroy(1, &buf);
  1597 
  1598     return;
  1599     }
  1600 
  1601 // The following four methods, SWBindText, SWBindBinary, SRColumnText and
  1602 // SRColumnBinary are Stream-Write and Stream-Read methods.
  1603 // In each case 'arg' specifies a file which is opened as a source (SW)
  1604 // of data, or else as another stream (SR) to compare against.
  1605 void CSQLFnStep::SWBindTextL(const TInt& apidx, const TPtrC &arg,
  1606                              const TDesC& acfgblk, const TInt acnnum=-1)
  1607     {
  1608     _LIT(KTestFunction, "SWBindText");
  1609     RSqlParamWriteStream sqlw;
  1610     // Get the WriteStream to stuff data down..
  1611     TInt err = sqlw.BindText(isqlst, apidx);
  1612     ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, err);
  1613     if(err != KErrNone) return;
  1614     WriteFileToStreamL(sqlw, arg);
  1615     sqlw.Close();
  1616     return;
  1617     }
  1618 void CSQLFnStep::SWBindBinaryL(const TInt& apidx, const TPtrC &arg,
  1619                                const TDesC& acfgblk, const TInt acnnum=-1)
  1620     {
  1621     _LIT(KTestFunction, "SWBindBinary");
  1622     RSqlParamWriteStream sqlw;
  1623     // Get the WriteStream to stuff data down..
  1624     TInt err = sqlw.BindBinary(isqlst, apidx);
  1625     ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, err);
  1626     if(err != KErrNone) return;
  1627     WriteFileToStreamL(sqlw, arg);
  1628     sqlw.Close();
  1629     return;
  1630     }
  1631 void CSQLFnStep::SRColumnTextL(const TInt& acidx, const TPtrC &arg,
  1632                               const TDesC& acfgblk, const TInt acnnum=-1)
  1633     {
  1634     _LIT(KTestFunction, "SRColumnText");
  1635 
  1636     // First find out how much data is in this cell..
  1637     TInt dsize = isqlst.ColumnSize(acidx);
  1638     INFO_PRINTF3(_L("%S: ColumnSize is %d"), &KTestFunction, dsize);
  1639 
  1640     RSqlColumnReadStream sqlr;
  1641     TInt err = sqlr.ColumnText(isqlst, acidx);
  1642     ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, err);
  1643     if(err != KErrNone) return;
  1644     // Ok, we have a Read Stream..
  1645     CleanupClosePushL(sqlr);
  1646 
  1647     // Compare it..
  1648     TInt rc = CompareTextStreamAgainstFileL(sqlr, dsize, arg);
  1649     if(rc)
  1650         {
  1651         SetTestStepResult(EFail);
  1652         INFO_PRINTF1(HTML_RED);
  1653         ERR_PRINTF3(_L("%S: Stream comparison failure, file %S"),
  1654                            &KTestFunction, &arg);
  1655         INFO_PRINTF1(HTML_COLOUR_OFF);
  1656         }
  1657     else
  1658         {
  1659         INFO_PRINTF1(HTML_GREEN);
  1660         INFO_PRINTF3(_L("%S: Stream comparison success, file %S"),
  1661                            &KTestFunction, &arg);
  1662         INFO_PRINTF1(HTML_COLOUR_OFF);
  1663         }
  1664     CleanupStack::PopAndDestroy(1,&sqlr);
  1665     return;
  1666     }
  1667 void CSQLFnStep::SRColumnBinaryL(const TInt& acidx, const TPtrC &arg,
  1668                                  const TDesC& acfgblk, const TInt acnnum=-1)
  1669     {
  1670     _LIT(KTestFunction, "SRColumnBinary");
  1671 
  1672     // First find out how much data is in this cell..
  1673     TInt dsize = isqlst.ColumnSize(acidx);
  1674     INFO_PRINTF3(_L("%S: Colsize is %d"), &KTestFunction, dsize);
  1675 #ifdef _UNICODE
  1676     if(isqlst.ColumnType(acidx) == ESqlText) dsize <<= 1;
  1677 #endif
  1678 
  1679     // Get our RReadStream and check for errors.
  1680     RSqlColumnReadStream sqlr;
  1681     TInt err = sqlr.ColumnBinary(isqlst, acidx);
  1682     ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, err);
  1683     if(err != KErrNone) return;
  1684     // Ok, we have a Read Stream..
  1685     CleanupClosePushL(sqlr);
  1686 
  1687     // Compare it..
  1688     TInt rc = CompareBinaryStreamAgainstFileL(sqlr, dsize, arg);
  1689     if(rc)
  1690         {
  1691         SetTestStepResult(EFail);
  1692         INFO_PRINTF1(HTML_RED);
  1693         ERR_PRINTF3(_L("%S: Stream comparison failure, file %S"),
  1694                            &KTestFunction, &arg);
  1695         INFO_PRINTF1(HTML_COLOUR_OFF);
  1696         }
  1697     else
  1698         {
  1699         INFO_PRINTF1(HTML_GREEN);
  1700         INFO_PRINTF3(_L("%S: Stream comparison success, file %S"),
  1701                            &KTestFunction, &arg);
  1702         INFO_PRINTF1(HTML_COLOUR_OFF);
  1703         }
  1704     CleanupStack::PopAndDestroy(1,&sqlr);
  1705     return;
  1706     }
  1707 
  1708 TBool CSQLFnStep::SPCreate(const TDesC &acfgblk, const TInt acnnum)
  1709     {
  1710     _LIT(KTestFunction, "SPCreate");
  1711     
  1712     TSecurityPolicy defaultPolicy;
  1713     
  1714     // Try to create the SQLDB security policy.
  1715     TInt rc = isqlsp.Create(defaultPolicy);
  1716     ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, rc);
  1717     if(rc == KErrNone) return ETrue;
  1718     return EFalse;
  1719     }
  1720 
  1721 TBool CSQLFnStep::SPCreate(const TPtrC&, const TDesC &acfgblk, const TInt acnnum)
  1722     {
  1723     _LIT(KTestFunction, "SPCreate");
  1724     
  1725     TSecurityPolicy defaultPolicy;
  1726     
  1727     // Try to create the SQLDB security policy.
  1728     TInt rc = KErrNone;
  1729     TRAP(rc, isqlsp.CreateL(defaultPolicy));
  1730     ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, rc);
  1731     if(rc == KErrNone) return ETrue;
  1732     return EFalse;
  1733     }
  1734 
  1735 void CSQLFnStep::SPClose()
  1736     {
  1737     isqlsp.Close();
  1738     return;
  1739     }
  1740 
  1741 TBool CSQLFnStep::SPSetDBPolicy(const TPtrC& apol, const TDesC &acfgblk, const TInt acnnum)
  1742     {
  1743     _LIT(KTestFunction, "SPSetDBPolicy");
  1744 
  1745     //extract the policy level and capability from the argument passed in
  1746     TPtrC level, cap;
  1747     CommaSeparated(apol, level, cap);
  1748 
  1749     //create the security policy object with the supplied capability
  1750     TSecurityPolicy sp((TCapability)(icaphsh->GetNumFromString(cap)));
  1751 
  1752     INFO_PRINTF2(_L("SetDBPolicy: %S"), &level);
  1753     INFO_PRINTF2(_L("Capabilities are: %S"), &cap);
  1754     
  1755     TInt rc = isqlsp.SetDbPolicy(((RSqlSecurityPolicy::TPolicyType)ipolhsh->GetNumFromString(level)), sp);
  1756     ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, rc);
  1757     if(rc == KErrNone) return ETrue;
  1758     return EFalse;
  1759     }
  1760 
  1761 TBool CSQLFnStep::SPSetPolicy(const TPtrC& apol, const TDesC &acfgblk, const TInt acnnum)
  1762     {
  1763     _LIT(KTestFunction, "SPSetPolicy");
  1764 
  1765     //extract the policy level and capability from the argument passed in
  1766     TPtrC arg, arg2, object, name, level, caps;
  1767     CommaSeparated(apol, object, arg);
  1768     CommaSeparated(arg, name, arg2);
  1769     CommaSeparated(arg2, level, caps);
  1770 
  1771     //create the security policy object with the supplied capability
  1772     TSecurityPolicy sp((TCapability)(icaphsh->GetNumFromString(caps)));
  1773 
  1774     INFO_PRINTF2(_L("SetPolicy: %S"), &level);
  1775     INFO_PRINTF2(_L("Capabilities are: %S"), &caps);
  1776     INFO_PRINTF2(_L("Object type is: %S"), &object);
  1777     INFO_PRINTF2(_L("Object name is: %S"), &name);
  1778     
  1779     TInt rc = isqlsp.SetPolicy(((RSqlSecurityPolicy::TObjectType)iobjhsh->GetNumFromString(object)), name, ((RSqlSecurityPolicy::TPolicyType)ipolhsh->GetNumFromString(level)), sp);
  1780     ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, rc);
  1781     if(rc == KErrNone) return ETrue;
  1782     return EFalse;
  1783     }
  1784 
  1785 void CSQLFnStep::SPExternalize(const TPtrC &arg, const TDesC &acfgblk, const TInt acnnum)
  1786     {
  1787     _LIT(KTestFunction, "SPExternalize");
  1788     
  1789     RFileWriteStream rfws;
  1790 
  1791     TInt err = rfws.Create(irfs, arg, EFileStream);
  1792     if(err != KErrNone)
  1793         {
  1794         SetTestStepResult(EFail);
  1795         INFO_PRINTF1(HTML_RED);
  1796         ERR_PRINTF4(_L("%S: Can't open file %S, err %d"), &KTestFunction, &arg,
  1797                          err );
  1798         INFO_PRINTF1(HTML_COLOUR_OFF);
  1799         return;
  1800         }
  1801     
  1802     TInt rc = KErrNone;
  1803     TRAP(rc, isqlsp.ExternalizeL(rfws));
  1804     TRAP(rc, rfws.CommitL());
  1805     ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, rc);
  1806     rfws.Close();    
  1807     return;
  1808     }
  1809 
  1810 void CSQLFnStep::SPInternalize(const TPtrC &arg, const TDesC &acfgblk, const TInt acnnum)
  1811     {
  1812     _LIT(KTestFunction, "SPInternalize");
  1813     
  1814     RFileReadStream rfrs;
  1815     
  1816     TInt err = rfrs.Open(irfs, arg, EFileStream);
  1817     if(err != KErrNone)
  1818         {
  1819         SetTestStepResult(EFail);
  1820         INFO_PRINTF1(HTML_RED);
  1821         ERR_PRINTF3(_L("%S: Failed to open stream from file %S"), &KTestFunction, &arg);
  1822         INFO_PRINTF1(HTML_COLOUR_OFF);
  1823         return;
  1824         }
  1825     
  1826     TInt rc = KErrNone;
  1827     TRAP(rc, isqlsp.InternalizeL(rfrs));
  1828         
  1829     ReportOnError(KTestFunction, KTestFunction, acfgblk, acnnum, rc);
  1830     rfrs.Close();     
  1831     return;
  1832     }
  1833 
  1834 // - Utility functions... ---  we should remove these into a separate class -- 
  1835 //
  1836 // Stream functions - should we have a persistent stream? Here it goes
  1837 // out of scope once the method completes, but what about a case where for
  1838 // example we write to a cell, then write some more later to the same cell?
  1839 //
  1840 // Loads more duplication..
  1841 TInt CSQLFnStep::CompareTextStreamAgainstFileL(RReadStream &as, TInt asiz,
  1842                                                const TPtrC &afile)
  1843     {
  1844     _LIT(KTestFunction, "CompareTextStreamAgainstFile");
  1845     // Get the file size. This is in bytes, so for Unicode will be
  1846     // out by a factor of two. Also, if created with notepad or similar
  1847     // will have a 'FEFF' two byte marker at the start (which SQLite
  1848     // strips when it sees it).
  1849     TInt fsize = FileSize(afile);
  1850     if(fsize < 0) return fsize;;
  1851     // We don't divide asiz by two: This will have originated in ColumnSize
  1852     // which returns the number of characters in a cell.
  1853     TInt textlen = asiz;
  1854 #ifdef _UNICODE
  1855     fsize >>= 1;
  1856 #endif
  1857 
  1858     // If fsize is 1 different (2 bytes) from textlen, then we'll expect
  1859     // a unicode marker. If not 1 or zero give up straight away.
  1860     TInt diff = fsize - textlen;
  1861     TInt ucmark = (diff == 1);
  1862     if((diff>1) || (diff<0))
  1863         {
  1864         INFO_PRINTF1(HTML_COLOUR_OFF);
  1865         ERR_PRINTF4(_L("%S Size mismatch. Expected %d, got %d"),
  1866                                                 &KTestFunction, fsize, textlen);
  1867         SetTestStepResult(EFail);
  1868         INFO_PRINTF1(HTML_COLOUR_OFF);
  1869         return KTEFSQLSizeError;
  1870         }
  1871 
  1872     // Open the reference file specified in the argument.
  1873     // Use an RFileReadStream because we need to worry about characters,
  1874     // not just bytes.
  1875     RFileReadStream rflrs;
  1876     TInt err = rflrs.Open(irfs, afile, EFileRead);
  1877     if(err != KErrNone)
  1878         return err;
  1879     CleanupClosePushL(rflrs);
  1880 
  1881     // Dumps the FEFF marker bytes for unicode files.
  1882     // SQLite does the same for text.
  1883     if(ucmark)
  1884         {
  1885         TInt16 mark = rflrs.ReadInt16L();  // byte order?
  1886         if((mark != (TInt16)0xfeff) && (mark != (TInt16)0xfffe))
  1887             {
  1888             CleanupStack::PopAndDestroy(1, &rflrs);
  1889             return KTEFSQLSizeError;
  1890             }
  1891         }
  1892 
  1893     // For each 32768 chars in the text buffer...
  1894     const TInt slice = 32768;
  1895     RBuf fbuf, abuf;
  1896     err = fbuf.Create(slice);
  1897     if(err == KErrNone) err = abuf.Create(slice);
  1898     if(err != KErrNone)
  1899         {
  1900         CleanupStack::PopAndDestroy(1, &rflrs);
  1901         return KErrNoMemory;
  1902         }
  1903     CleanupClosePushL(fbuf);
  1904     CleanupClosePushL(abuf);
  1905 
  1906     TInt rc = KErrNone;
  1907     for(TInt pos=0; pos < textlen ; pos += slice)
  1908         {
  1909         TInt toread = textlen - pos;
  1910         if(toread > slice)
  1911             toread = slice;
  1912 
  1913         // Read 'toread' characters from the file and from the passed in
  1914         // data.
  1915         as.ReadL(abuf, toread);
  1916         TPtrC txtslice = abuf.Left(toread);
  1917         rflrs.ReadL(fbuf, toread);
  1918         TPtrC fileslice = fbuf.Left(toread);
  1919 
  1920         // Compare ..
  1921         if (fileslice != txtslice)
  1922             { 
  1923             rc = KTEFSQLSizeError;
  1924             break;
  1925             }
  1926         }
  1927     CleanupStack::PopAndDestroy(3, &rflrs);
  1928     return rc;
  1929     }
  1930 
  1931 // Loads more duplication..
  1932 TInt CSQLFnStep::CompareBinaryStreamAgainstFileL(RReadStream &as, TInt asiz,
  1933                                                 const TPtrC &afile)
  1934     {
  1935     _LIT(KTestFunction, "CompareBinaryStreamAgainstFile");
  1936     // Get the file size. This is in bytes.
  1937     TInt fsize = FileSize(afile);
  1938     if(fsize < 0) return fsize;;
  1939 
  1940     // If sizes differ give up immediately.
  1941     if(fsize - asiz)
  1942         {
  1943         INFO_PRINTF1(HTML_COLOUR_OFF);
  1944         ERR_PRINTF4(_L("%S Size mismatch. Expected %d, got %d"),
  1945                                                 &KTestFunction, fsize, asiz);
  1946         SetTestStepResult(EFail);
  1947         INFO_PRINTF1(HTML_COLOUR_OFF);
  1948         return KTEFSQLSizeError;
  1949         }
  1950 
  1951     // Open the reference file specified in the argument.
  1952     // Use an RFileReadStream because we need to worry about characters,
  1953     // not just bytes.
  1954     RFileReadStream rflrs;
  1955     TInt err = rflrs.Open(irfs, afile, EFileRead);
  1956     if(err != KErrNone) return err;
  1957     CleanupClosePushL(rflrs);
  1958 
  1959     // For each 32768 chars in the text buffer...
  1960     const TInt slice = 32768;
  1961     RBuf8 fbuf, abuf;
  1962     err = fbuf.Create(slice);
  1963     if(err == KErrNone) err = abuf.Create(slice);
  1964     if(err != KErrNone)
  1965         {
  1966         CleanupStack::PopAndDestroy(1, &rflrs);
  1967         return err;
  1968         }
  1969     CleanupClosePushL(fbuf);
  1970     CleanupClosePushL(abuf);
  1971 
  1972     TInt rc = KErrNone;
  1973     for(TInt pos=0; pos < asiz ; pos += slice)
  1974         {
  1975         TInt toread = asiz - pos;
  1976         if(toread > slice)
  1977             toread = slice;
  1978 
  1979         // Read 'toread' characters from the file and from the passed in
  1980         // data. Do we really need to chop out only the read bits for
  1981         // comparison? Wouldn't comparing fbuf and abuf work?
  1982         rflrs.ReadL(fbuf, toread);
  1983         TPtr8 fslice = fbuf.LeftTPtr(toread);
  1984         as.ReadL(abuf, toread);
  1985         TPtr8 aslice = abuf.LeftTPtr(toread);
  1986 
  1987         // Compare .. (does this compare only what's been read?)
  1988         if (fslice != aslice)
  1989             { 
  1990             rc = KTEFSQLSizeError;
  1991             break;
  1992             }
  1993         }
  1994     CleanupStack::PopAndDestroy(3, &rflrs);
  1995     return rc;
  1996     }
  1997 void CSQLFnStep::WriteFileToStreamL(RWriteStream &as1, const TPtrC &afile)
  1998     {
  1999     _LIT(KTestFunction, "WriteFileToStream");
  2000     // Open the reference file specified in the argument.
  2001     RFileReadStream rflrs;
  2002     TInt err = rflrs.Open(irfs, afile, EFileRead);
  2003     // Do we want to return anything?
  2004     if(err != KErrNone)
  2005         {
  2006         SetTestStepResult(EFail);
  2007         INFO_PRINTF1(HTML_RED);
  2008         ERR_PRINTF3(_L("%S: Failed to open stream from file %S"),
  2009                            &KTestFunction, &afile);
  2010         INFO_PRINTF1(HTML_COLOUR_OFF);
  2011         return;
  2012         }
  2013     CleanupClosePushL(rflrs);
  2014     as1.WriteL(rflrs);
  2015     CleanupStack::PopAndDestroy(1, &rflrs);
  2016     return;
  2017     }
  2018 
  2019 TInt CSQLFnStep::CompareBinaryAgainstFileL(const TDesC8 &abuf,
  2020                                           const TFileName& afile)
  2021     {
  2022     _LIT(KTestFunction, "CompareBinaryAgainstFile");
  2023     // Get the file size.
  2024     TInt fsize = FileSize(afile);
  2025     if(fsize < 0) return fsize;
  2026     // How much binary do we have?
  2027     TInt binlen = abuf.Length();
  2028 
  2029     INFO_PRINTF4(_L("%S: Filelen %d, Binlen %d"), &KTestFunction, fsize, binlen);
  2030 
  2031     // If sizes differ drop out immediately.
  2032     if(fsize - binlen)
  2033         return KTEFSQLSizeError;
  2034 
  2035     // Open the reference file specified in the argument.
  2036     // Use an RFileReadStream because we need to worry about characters,
  2037     // not just bytes.
  2038     RFileReadStream rflrs;
  2039     TInt err = rflrs.Open(irfs, afile, EFileRead);
  2040     if(err != KErrNone)
  2041         return err;
  2042     CleanupClosePushL(rflrs);
  2043 
  2044     // For each 32768 chars in the text buffer...
  2045     const TInt slice = 32768;
  2046     RBuf8 fbuf;
  2047     fbuf.Create(slice);
  2048     CleanupClosePushL(fbuf);
  2049 
  2050     TInt rc = KErrNone;
  2051     for(TInt pos=0; pos < binlen ; pos += slice)
  2052         {
  2053         TInt toread = binlen - pos;
  2054         if(toread > slice)
  2055             toread = slice;
  2056 
  2057         // Read 'toread' bytes from the file and from the passed in
  2058         // data.
  2059         rflrs.ReadL(fbuf, toread);
  2060         TPtrC8 fileslice = fbuf.Left(toread);
  2061         TPtrC8 binslice = abuf.Mid(pos, toread);
  2062 
  2063         // Compare ..
  2064         if (fileslice != binslice)
  2065             { 
  2066             rc = KTEFSQLSizeError;
  2067             break;
  2068             }
  2069         }
  2070 
  2071     INFO_PRINTF2(_L("%S: Comparison successful"), &KTestFunction);
  2072     CleanupStack::PopAndDestroy(2, &rflrs);
  2073     return rc;
  2074     }
  2075 
  2076 // Tested and working..
  2077 TInt CSQLFnStep::CompareTextAgainstFileL(const TDesC &atxt,
  2078                                         const TFileName& afile)
  2079     {
  2080     // Get the file size. This is in bytes, so for Unicode will be
  2081     // out by a factor of two. Also, if created with notepad or similar
  2082     // will have a 'FEFF' two byte marker at the start (which SQLite
  2083     // strips when it sees it).
  2084     TInt fsize = FileSize(afile);
  2085     if(fsize < 0) return fsize;
  2086 #ifdef _UNICODE
  2087     fsize >>= 1;
  2088 #endif
  2089     // How much text do we have?
  2090     TInt textlen = atxt.Length();
  2091 
  2092     // If fsize is 1 different (2 bytes) from textlen, then we'll expect
  2093     // a unicode marker. If not 1 or zero give up straight away.
  2094     TInt diff = fsize - textlen;
  2095     TInt ucmark = (diff == 1);
  2096     if((diff>1) || (diff<0))
  2097         {
  2098         ERR_PRINTF3(_L("FSIZE is %d, textlen is %d"), fsize, textlen);
  2099         return KTEFSQLSizeError;
  2100         }
  2101 
  2102     // Open the reference file specified in the argument.
  2103     // Use an RFileReadStream because we need to worry about characters,
  2104     // not just bytes.
  2105     RFileReadStream rflrs;
  2106     TInt err = rflrs.Open(irfs, afile, EFileRead);
  2107     if(err != KErrNone)
  2108         return err;
  2109     CleanupClosePushL(rflrs);
  2110 
  2111     // Dumps the FEFF marker bytes for unicode files.
  2112     // SQLite does the same for text.
  2113     if(ucmark)
  2114         {
  2115         TInt16 mark = rflrs.ReadInt16L();  // byte order?
  2116         if((mark != (TInt16)0xfeff) && (mark != (TInt16)0xfffe))
  2117             {
  2118             CleanupStack::PopAndDestroy(1, &rflrs);
  2119             return KTEFSQLSizeError;
  2120             }
  2121         }
  2122 
  2123     // For each 32768 chars in the text buffer...
  2124     const TInt slice = 32768;
  2125     RBuf fbuf;
  2126     fbuf.Create(slice);
  2127     CleanupClosePushL(fbuf);
  2128 
  2129     TInt rc = KErrNone;
  2130     for(TInt pos=0; pos < textlen ; pos += slice)
  2131         {
  2132         TInt toread = textlen - pos;
  2133         if(toread > slice)
  2134             toread = slice;
  2135 
  2136         // Read 'toread' characters from the file and from the passed in
  2137         // data.
  2138         rflrs.ReadL(fbuf, toread);
  2139         TPtrC txtslice = atxt.Mid(pos, toread);
  2140 
  2141         // Compare ..
  2142         if (fbuf != txtslice)
  2143             { 
  2144             rc = KTEFSQLSizeError;
  2145             break;
  2146             }
  2147         }
  2148     CleanupStack::PopAndDestroy(2, &rflrs);
  2149     return rc;
  2150     }
  2151 
  2152 // Get the expected error code for the current action. Assume KErrNone if it
  2153 // isn't in the config file. We might have (in the config file)
  2154 // ExpectedError27=KSqlErrPermission
  2155 int CSQLFnStep::ActionNoToErrEnum(const TDesC& acfgsec, const TInt aActionNum,
  2156                                   TPtrC& aes)
  2157     {
  2158     TBuf<KConfigItemMaxNameLength> cnfgerr(_L("ExpectedError"));
  2159     if(aActionNum != -1) cnfgerr.AppendNum(aActionNum);
  2160     if(!GetStringFromConfig(acfgsec, cnfgerr, aes))
  2161         aes.Set(_L("KErrNone"));
  2162     return(ErrStringToEnum(aes));
  2163 }
  2164 TInt CSQLFnStep::ErrStringToEnum(TPtrC &aerr)
  2165     {
  2166     return(ierrhsh->GetNumFromString(aerr));
  2167     }
  2168 void CSQLFnStep::ErrEnumToString(const TInt &aerr, TPtrC &aptrstr)
  2169     {
  2170     aptrstr.Set(*(ierrhsh->GetStringFromNum(aerr)));
  2171     return;
  2172     }
  2173 const TPtrC CSQLFnStep::SqlColumnTypeToString(TSqlColumnType &asqltype)
  2174     {
  2175     return *icoltypehsh->GetStringFromNum(asqltype);
  2176     }
  2177 TSqlColumnType CSQLFnStep::StringToSqlColumnType(const TDesC &atype)
  2178     {
  2179     return (TSqlColumnType) icoltypehsh->GetNumFromString(atype);
  2180     }
  2181 /*
  2182  * A helper function to report on an error. This won't say anything if the
  2183  * error received (aerr) is equal to the error expected as defined in the
  2184  * configuration file.
  2185  */
  2186 void CSQLFnStep::ReportOnError(const TDesC &afnnam, const TDesC &apinam,
  2187                                 const TDesC &acfgblk, const TInt acfgno,
  2188                                 const TInt aerr)
  2189     {
  2190     // Get the expected error.
  2191     TPtrC experrS;
  2192     TInt experr = ActionNoToErrEnum(acfgblk, acfgno, experrS);
  2193 
  2194     // Some methods such as Exec and Next return a positive value on
  2195     // success. If we're not expecting an error and the actual error code
  2196     // is positive just return, everything is cool.
  2197     if((experr == KErrNone) && (aerr >= 0))
  2198         return;
  2199 
  2200     // Is the actual error the same as the expected error?
  2201     if(aerr != experr)
  2202         {
  2203         INFO_PRINTF1(HTML_RED);
  2204         SetTestStepResult(EFail);
  2205         TPtrC errS;
  2206         ErrEnumToString(aerr, errS); // Convert the actual error to a string.
  2207 
  2208         ERR_PRINTF7(_L("%S: %S gave error %d/%S, expected %d/%S"),
  2209                         &afnnam, &apinam, aerr, &errS, experr, &experrS);
  2210         // Run 'LastErrorMessage' if we unexpectedly have 'KSqlErrGeneral',
  2211         // often what it has to say is very helpful.
  2212         if(aerr == KSqlErrGeneral)
  2213             LastErrorMessage(_L(""));
  2214 
  2215         INFO_PRINTF1(HTML_COLOUR_OFF);
  2216         }
  2217     else if(aerr != KErrNone)
  2218         {
  2219         INFO_PRINTF1(HTML_GREEN);
  2220         INFO_PRINTF5(_L("%S: %S got expected error %d/%S"), &afnnam, &apinam,
  2221                               aerr, &experrS);
  2222         INFO_PRINTF1(HTML_COLOUR_OFF);
  2223         }
  2224     return;
  2225     }
  2226 TBool CSQLFnStep::FromConfig(const TDesC &afnnam, const TDesC &acfgblk,
  2227                              const TDesC &acfgname, TPtrC &acfgval)
  2228     {
  2229     if(!GetStringFromConfig(acfgblk, acfgname, acfgval))
  2230         {
  2231         INFO_PRINTF1(HTML_RED);
  2232         ERR_PRINTF4(_L("%S: Failed to get %S:%S parameter."), &afnnam, &acfgblk,
  2233                                                               &acfgname);
  2234         SetTestStepResult(EFail);
  2235         INFO_PRINTF1(HTML_COLOUR_OFF);
  2236         return EFalse;
  2237         }
  2238     return ETrue;
  2239     }
  2240 TBool CSQLFnStep::FromConfig(const TDesC &afnnam, const TDesC &acfgblk,
  2241                              const TDesC &acfgname, TInt &acfgval)
  2242     {
  2243     if(!GetIntFromConfig(acfgblk, acfgname, acfgval))
  2244         {
  2245         INFO_PRINTF1(HTML_RED);
  2246         ERR_PRINTF4(_L("%S: Failed to get %S:%S parameter."), &afnnam, &acfgblk,
  2247                            &acfgname);
  2248         SetTestStepResult(EFail);
  2249         INFO_PRINTF1(HTML_COLOUR_OFF);
  2250         return EFalse;
  2251         }
  2252     return ETrue;
  2253     }
  2254 TBool CSQLFnStep::FromConfig(const TDesC &afnnam, const TDesC &acfgblk,
  2255                              const TDesC &acfgname, TReal &acfgval)
  2256     {
  2257     TPtrC gotS;
  2258     if(!GetStringFromConfig(acfgblk, acfgname, gotS))
  2259         {
  2260         INFO_PRINTF1(HTML_RED);
  2261         ERR_PRINTF4(_L("%S: Failed to get %S:%S parameter."), &afnnam, &acfgblk,
  2262                                                               &acfgname);
  2263         SetTestStepResult(EFail);
  2264         INFO_PRINTF1(HTML_COLOUR_OFF);
  2265         return EFalse;
  2266         }
  2267     TLex tl = gotS;
  2268     if(tl.Val(acfgval) != KErrNone)
  2269         {
  2270         ERR_PRINTF5(_L("%S:%S Failed to convert %S:%S to real."),
  2271                            &afnnam, &acfgblk, &acfgname, &gotS);
  2272         return EFalse;
  2273         }
  2274 
  2275     return ETrue;
  2276     }
  2277 // Looking for, e.g, "9876,1234" 
  2278 void CSQLFnStep::CommaSeparated(const TPtrC& ainp, TInt &aint, TInt &aint2)
  2279     {
  2280 //    _LIT(KTestFunction, "CommaSeparated");
  2281 
  2282     // Read in what kind of binds we'll be doing..
  2283     TInt origlen = ainp.Length();
  2284     TChar comma(',');
  2285     TInt comoffset = ainp.Locate(comma);
  2286     if(comoffset != KErrNotFound)
  2287         {
  2288         TPtrC left = ainp.Left(comoffset);
  2289         TLex tl(left);
  2290         tl.Val(aint);
  2291         TInt rightlen = origlen - comoffset - 1;
  2292         TPtrC right = ainp.Right(rightlen);
  2293         tl = right;
  2294         tl.Val(aint2);
  2295         }
  2296     else
  2297         {
  2298         TLex tl(ainp);
  2299         tl.Val(aint);
  2300         aint2=-1;
  2301         }
  2302     }
  2303 // Looking for, e.g, "9876,some words"
  2304 void CSQLFnStep::CommaSeparated(const TPtrC& ainp, TInt &aint, TPtrC &astr)
  2305     {
  2306 //    _LIT(KTestFunction, "CommaSeparated");
  2307 
  2308     TInt origlen = ainp.Length();
  2309     TChar comma(',');
  2310     TInt comoffset = ainp.Locate(comma);
  2311     if(comoffset != KErrNotFound)
  2312         {
  2313         TPtrC left = ainp.Left(comoffset);
  2314         TLex tl(left);
  2315         tl.Val(aint);
  2316         TInt rightlen = origlen - comoffset - 1;
  2317         astr.Set(ainp.Right(rightlen));
  2318         }
  2319     else
  2320         {
  2321         TLex tl(ainp);
  2322         tl.Val(aint);
  2323         astr.Set(_L(""));
  2324         }
  2325     }
  2326 void CSQLFnStep::CommaSeparated(const TPtrC& ainp, TPtrC &aleft, TPtrC &aright)
  2327     {
  2328 //    _LIT(KTestFunction, "CommaSeparated");
  2329     aleft.Set(ainp);
  2330     aright.Set(_L(""));
  2331 
  2332     TInt origlen = ainp.Length();
  2333     TChar comma(',');
  2334     TInt comoffset = ainp.Locate(comma);
  2335     if(comoffset != KErrNotFound)
  2336         {
  2337         aleft.Set(ainp.Left(comoffset));
  2338         TInt rightlen = origlen - comoffset - 1;
  2339         aright.Set(ainp.Right(rightlen));
  2340         }
  2341     else
  2342         return;
  2343     }
  2344 TInt CSQLFnStep::FileSize(const TPtrC &afile)
  2345     {
  2346     // First open the file specified in the argument.
  2347     // This lot gets duplicated a lot.
  2348     RFile file;
  2349     TFileName fn = afile;
  2350     TInt err;
  2351     if((err = file.Open(irfs, fn, 0)) != KErrNone)
  2352         {
  2353         INFO_PRINTF1(HTML_RED);
  2354         ERR_PRINTF3(_L("Cannot open %S to get filesize, err %d"), &afile, err);
  2355         SetTestStepResult(EFail);
  2356         INFO_PRINTF1(HTML_COLOUR_OFF);
  2357 
  2358         return err;
  2359         }
  2360     TInt fsize;
  2361     file.Size(fsize);
  2362     file.Close();
  2363     return fsize;
  2364     }
  2365