examples/SysLibs/SqlExample/sqlexample.cpp

Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2006-2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
00003 
00004 Redistribution and use in source and binary forms, with or without
00005 modification, are permitted provided that the following conditions are met:
00006 
00007 * Redistributions of source code must retain the above copyright notice, this
00008   list of conditions and the following disclaimer.
00009 * Redistributions in binary form must reproduce the above copyright notice,
00010   this list of conditions and the following disclaimer in the documentation
00011   and/or other materials provided with the distribution.
00012 * Neither the name of Nokia Corporation nor the names of its contributors
00013   may be used to endorse or promote products derived from this software
00014   without specific prior written permission.
00015 
00016 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00017 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00018 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00019 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00020 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00021 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00022 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00023 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00024 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00025 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026 
00027 Description: 
00028 This example program demonstrates the use of SQL APIs. 
00029 The code demonstrates how to create non secure and secure databases on 
00030 the writable drive and perform basic operations on the databases. 
00031 */
00032 
00033 
00034 
00035 
00036 
00040 #include "sqlexample.h"
00041 #include <e32cons.h>
00042 #include <sqldb.h>
00043 
00044 _LIT(KTitle, "SQL example");
00045 _LIT(KTextPressAKey, "\n\nPress any key to step through the example\n");
00046 _LIT(KExit,"Press any key to exit the application ");
00047 _LIT(KPressAKey,"Press any key to continue \n");
00048 _LIT(KNonSecure,"\nCreating a non secure database \n");
00049 _LIT(KSecure,"\nCreating a secure database \n");
00050 _LIT(KOpen,"Opening  the secure database \n");
00051 _LIT(KDelete,"Deleting the database(s)\n");
00052 _LIT(KClose,"Closing the database(s)\n");
00053 _LIT(KCopyNonSec,"\nCopying a non secure database to another non secure one \n");
00054 _LIT(KCopySecure,"\nCopying a secure database to another secure database \n");                                    
00055 _LIT(KAttach,"\nOpen a secure database and attach another secure database\n");
00056 _LIT(KCreateTable,"\nCreating a table\n");
00057 _LIT(KInsert,"Inserting records into the table\n");
00058 _LIT(KPrepare,"Preparing a query\n");
00059 _LIT(KExecute,"Executing a query\n");
00060 
00061 // Names of the databases created, operated upon and later deleted.
00062 _LIT(KDbName, "\\Example_db.db");
00063 _LIT(KAnotherDbName, "\\Example_Anotherdb.db");
00064 _LIT(KSecureDb1, "[E80000AF]db1.db");
00065 _LIT(KSecureDb2, "[E80000AF]db2.db");
00066 _LIT(KDatabase, "\\Sqlscalarfullselect.db");
00067 
00068 // Security policies used
00069 const TSecurityPolicy KPolicy1(ECapabilityReadUserData, ECapabilityNetworkControl,  ECapabilityWriteUserData);
00070 const TSecurityPolicy KPolicy2(ECapabilityReadUserData);
00071 
00077 CSqlExample* CSqlExample::NewLC()
00078         {
00079         CSqlExample* rep = new(ELeave) CSqlExample();
00080         CleanupStack::PushL(rep);
00081         rep->ConstructL();
00082         return rep;
00083         }
00084         
00088 CSqlExample::CSqlExample()
00089         {
00090         }       
00091 
00092 void CSqlExample::ConstructL()
00093         {
00094         iConsole = Console::NewL(KTitle,TSize(KConsFullScreen,KConsFullScreen));
00095         iConsole->Printf ( KTextPressAKey );
00096         iConsole->Getch ();
00097         }
00098 
00102 CSqlExample::~CSqlExample()
00103         {
00104         iConsole->Printf(KExit);
00105         iConsole->Getch();
00106         
00107         delete iConsole;
00108         }
00109         
00116 void CSqlExample::CreateNonSecureDBL()
00117         {
00118         TBuf<200> buffer;
00119         RSqlDatabase db;
00120                 
00121         // Create non-secure database
00122         iConsole->Printf(KNonSecure);
00123         TInt error;
00124         TRAP(error,db.Create(KDbName););
00125 
00126         _LIT(KTable,"CREATE TABLE A1(F1 INTEGER, F2 INTEGER)");
00127         User::LeaveIfError(error = db.Exec(KTable));
00128 
00129         db.Close();
00130         iConsole->Printf(KClose);
00131         iConsole->Printf(KPressAKey);
00132         iConsole->Getch();
00133         }
00134         
00143 void CSqlExample::CreateAndOpenSecureDBL()
00144         {
00145         RSqlDatabase db;
00146         RSqlSecurityPolicy securityPolicy;
00147         
00148         User::LeaveIfError(securityPolicy.Create(TSecurityPolicy(TSecurityPolicy::EAlwaysPass)));
00149         User::LeaveIfError(securityPolicy.SetDbPolicy(RSqlSecurityPolicy::EWritePolicy, KPolicy1));
00150                 
00151         iConsole->Printf(KSecure);
00152         User::LeaveIfError(db.Create(KSecureDb1, securityPolicy));
00153                 
00154         securityPolicy.Close(); 
00155         
00156         // Check that the database security policy matches the policy used 
00157         //when the database was created.
00158         User::LeaveIfError(db.GetSecurityPolicy(securityPolicy));
00159         
00160         _LIT(KSecureCreate,"CREATE TABLE secure(int_fld integer, null_int_fld integer default null)");  
00161         User::LeaveIfError(db.Exec(KSecureCreate));
00162 
00163         // Attempt to write to the secure database
00164         _LIT(KSecureInsert,"INSERT INTO secure(int_fld) values(200)");
00165         User::LeaveIfError(db.Exec(KSecureInsert));
00166         db.Close();
00167         
00168         iConsole->Printf(KOpen);
00169         // Open the secure database     
00170         User::LeaveIfError(db.Open(KSecureDb1));
00171         
00172         db.Close();
00173         iConsole->Printf(KClose);
00174         iConsole->Printf(KPressAKey);
00175         iConsole->Getch();
00176         securityPolicy.Close();
00177 
00178         }
00179         
00187 void CSqlExample::CopyDatabaseL()
00188         {
00189         RSqlDatabase db;        
00190         
00191         // Copy non-secure to non-secure database
00192         iConsole->Printf(KCopyNonSec);  
00193         User::LeaveIfError(RSqlDatabase::Copy(KDbName, KAnotherDbName));
00194         
00195         // Delete the source database
00196         iConsole->Printf(KDelete);
00197         User::LeaveIfError(RSqlDatabase::Delete(KAnotherDbName));
00198 
00199         // Create another secure database with a different security policy,
00200         // KSecureDb1 is already created with KPolicy1.
00201         RSqlSecurityPolicy securityPolicy;
00202         User::LeaveIfError(securityPolicy.Create(TSecurityPolicy(TSecurityPolicy::EAlwaysPass)));
00203         
00204         User::LeaveIfError(securityPolicy.SetDbPolicy(RSqlSecurityPolicy::EWritePolicy, KPolicy2));
00205                 
00206         User::LeaveIfError(db.Create(KSecureDb2, securityPolicy));
00207         
00208         User::LeaveIfError(db.GetSecurityPolicy(securityPolicy));
00209         db.Close();
00210         
00211         // Copy secure to secure database. The application is the database owner.
00212         iConsole->Printf(KCopySecure);
00213         User::LeaveIfError(RSqlDatabase::Copy(KSecureDb1, KSecureDb2));
00214         
00215         // Delete the source database
00216         iConsole->Printf(KDelete);
00217         User::LeaveIfError(RSqlDatabase::Delete(KSecureDb1));
00218 
00219         iConsole->Printf(KPressAKey);
00220         iConsole->Getch();
00221         securityPolicy.Close(); 
00222         db.Close();
00223 
00224         }
00225         
00233 void CSqlExample::AttachDatabasesL()
00234         {
00235         RSqlDatabase db;
00236         RSqlSecurityPolicy securityPolicy;
00237 
00238         _LIT(KAttachDb2, "Db2");
00239         
00240         User::LeaveIfError(db.Open(KSecureDb2));
00241         iConsole->Printf(KAttach);
00242         
00243         User::LeaveIfError(db.Attach(KDbName, KAttachDb2));
00244         
00245         // Attempt to write to the attached non secure database
00246         _LIT(KTabInsert,"INSERT INTO db2.a1(f1) valUES(10)");
00247         User::LeaveIfError(db.Exec(KTabInsert));
00248                         
00249         // Attempt to read from the attached non secure database
00250         _LIT(KSelect,"SELECT * FROM db2.a1");
00251         User::LeaveIfError(db.Exec(KSelect));
00252                 
00253         // Attempt to write to the main secure database
00254         _LIT(KAttachInsert,"INSERT INTO a1(f1) valUES(10)");
00255         User::LeaveIfError(db.Exec(KAttachInsert));
00256                 
00257         db.Close();
00258         iConsole->Printf(KDelete);
00259         User::LeaveIfError(RSqlDatabase::Delete(KDbName));
00260 
00261         User::LeaveIfError(RSqlDatabase::Delete(KSecureDb2));
00262 
00263         securityPolicy.Close();
00264         
00265         }
00266                 
00273 void CSqlExample:: DataTypesQueryL()
00274         {
00275         RSqlDatabase db;
00276         iConsole->Printf(KSecure);
00277         
00278         User::LeaveIfError(db.Create(KDbName));
00279 
00280         // Create a table with different numeric field types
00281         iConsole->Printf(KCreateTable);
00282         iConsole->Printf(KExecute);
00283         
00284         _LIT(KSql1, "CREATE TABLE Tbl(A INTEGER, B SMALLINT, C REAL, D DOUBLE PRECISION, E FLOAT, \
00285                                                             F DECIMAL)");                                                   
00286         User::LeaveIfError(db.Exec(KSql1));
00287         
00288         // Insert one record in to the created table
00289         iConsole->Printf(KInsert);                                 
00290         iConsole->Printf(KExecute);
00291         
00292         _LIT(KSql2, "INSERT INTO Tbl(A,B,C,D,E,F) VALUES(2000000000, 30000, 123.45, 0.912E+55,\
00293                                             1.34E-14, 1234.5678)");
00294         User::LeaveIfError(db.Exec(KSql2));
00295         
00296         // Get the inserted record data
00297         RSqlStatement stmt;
00298         iConsole->Printf(KPrepare);
00299         
00300         _LIT(KPrepQuery,"SELECT * FROM Tbl");
00301         User::LeaveIfError(stmt.Prepare(db, KPrepQuery));
00302         
00303         User::LeaveIfError(stmt.Next());
00304         stmt.Close();
00305         
00306         // The statement object has to be closed before db.Exec() call, 
00307         // otherwise the reported error is "database table is locked"
00308         // Insert second record in to the created table but inverse the column types.
00309         iConsole->Printf(KExecute);
00310         _LIT(KSql3, "INSERT INTO Tbl(A,   B,  C, D, E, F) VALUES(\
00311                                                                                 -2.5,1.1,12,23,45,111)");                                                                       
00312         User::LeaveIfError(db.Exec(KSql3)); 
00313         
00314         // Get the inserted record data
00315         _LIT(KPrepQuery2,"SELECT * FROM Tbl");
00316         User::LeaveIfError(stmt.Prepare(db, KPrepQuery2));
00317 
00318         User::LeaveIfError(stmt.Next());
00319         
00320         stmt.Close();
00321         
00322         // Insert third record in to the created table
00323         _LIT(KSql4, "INSERT INTO Tbl(A,B,C,D,E,F) VALUES(\
00324                                             2,3,123.45,1.5,2.5,1.56)");
00325         User::LeaveIfError(db.Exec(KSql4));
00326         
00327         stmt.Close();
00328         db.Close();
00329         User::LeaveIfError(RSqlDatabase::Delete(KDbName));
00330         }
00331         
00332 
00344 void CSqlExample::ScalarFullSelectL()
00345         {
00346         RSqlDatabase db;
00347         //Create  database.
00348         User::LeaveIfError(db.Create(KDatabase));
00349         
00350         _LIT(KTabCreateA,"CREATE TABLE A(F1 INTEGER, F2 INTEGER, F3 FLOAT, F4 TEXT, F5 BLOB)");
00351         User::LeaveIfError(db.Exec(KTabCreateA));
00352         
00353         _LIT(KTabInsert1A,"INSERT INTO A(F1, F2, F3, F4, F5) VALUES(1, 10000000000, 2.54, 'NAME1234567890', NULL)");
00354         User::LeaveIfError(db.Exec(KTabInsert1A));
00355         
00356         _LIT(KTabInsert2A,"INSERT INTO A(F1, F2, F3, F4) VALUES(2, 200, -1.11, 'ADDRESS')");    
00357         User::LeaveIfError(db.Exec(KTabInsert2A));
00358         
00359         RSqlStatement stmt;
00360         CleanupClosePushL(stmt);
00361         
00362         _LIT(KUpdate,"UPDATE A SET F5=:P WHERE F1 = 2");
00363         User::LeaveIfError(stmt.Prepare(db,KUpdate));
00364 
00365         // Open the parameter stream
00366         RSqlParamWriteStream strm;
00367         CleanupClosePushL(strm);
00368         
00369         // Prepare and set the parameter value (non-NULL value)
00370         User::LeaveIfError(strm.BindBinary(stmt, 0));
00371 
00372         for(TInt i=0;i<100;++i)
00373                 {
00374                 strm << static_cast <TUint8> (i);       
00375                 }
00376         // Write the buffered data into stream
00377         strm.CommitL();
00378         // Execute the prepared SQL statement   
00379         User::LeaveIfError(stmt.Exec());        
00380                 
00381         CleanupStack::PopAndDestroy(&strm);
00382         CleanupStack::PopAndDestroy(&stmt);
00383         
00384         TSqlScalarFullSelectQuery fullSelectQuery(db);
00385 
00386         TBuf<100> sql;
00387         
00388         // Query with F2 column (64-bit integer column)
00389         _LIT(KAnotherSql, "SELECT F2 FROM A WHERE F1 = 1");
00390         sql.Copy(KAnotherSql);
00391         // Read F2 as integer.
00392         TInt valInt = fullSelectQuery.SelectIntL(sql);
00393                 
00394         // Read F2 as 64-bit integer. Expected value: 10000000000
00395         TInt64  valInt64 = fullSelectQuery.SelectInt64L(sql);
00396         
00397         // Read F2 as real. Expected value: 10000000000.0
00398         TReal valReal = fullSelectQuery.SelectRealL(sql);
00399         
00400         // Read F2 as text. Expected value: zero-length 16-bit descriptor.
00401         TBuf<10> valText;
00402         TInt err = fullSelectQuery.SelectTextL(sql, valText);
00403 
00404         // Read F2 as binary. Expected value: zero-length 8-bit descriptor.
00405         TBuf8<10> valBinary;
00406         err = fullSelectQuery.SelectBinaryL(sql, valBinary);
00407         
00408         // Query with F4 column (text column) 
00409         _LIT(KSql4, "SELECT F4 FROM A WHERE F1 = 1");
00410         sql.Copy(KSql4);
00411         // Read F4 as integer. Expected value: 0.
00412         valInt = fullSelectQuery.SelectIntL(sql);
00413         
00414         //Read F4 as 64-bit integer. Expected value: 0.
00415         valInt64 = fullSelectQuery.SelectInt64L(sql);
00416         
00417         // Read F4 as real. Expected value: 0.0.
00418         valReal = fullSelectQuery.SelectRealL(sql);
00419         
00420         // Read F4 as text. Small buffer. Expected return code: positive value, which is the column length in characters.
00421         err = fullSelectQuery.SelectTextL(sql, valText);
00422         
00423         // Read F4 as text. Big enough buffer. 
00424         TBuf<32> valText2;
00425         err = fullSelectQuery.SelectTextL(sql, valText2);
00426         
00427         // Read F4 as binary. Expected error: KErrNone. Zero-length 8-bit descriptor.
00428         err = fullSelectQuery.SelectBinaryL(sql, valBinary);
00429 
00430         // Read F5 as binary. Big enough buffer.
00431         TBuf8<100> valBinary2;
00432         err = fullSelectQuery.SelectBinaryL(sql, valBinary2);
00433         
00434         // Text column value, small buffer, reallocation 
00435         HBufC* hbuf = HBufC::NewLC(10);
00436         TPtr name = hbuf->Des();
00437         sql.Copy(KSql4);
00438         err = fullSelectQuery.SelectTextL(sql, name);
00439         
00440         if(err > 0)
00441                 {
00442                 hbuf = hbuf->ReAllocL(err);
00443                 CleanupStack::Pop();    
00444                 CleanupStack::PushL(hbuf);
00445                 name.Set(hbuf->Des());
00446                 err = fullSelectQuery.SelectTextL(sql, name);
00447         
00448                 }
00449         CleanupStack::PopAndDestroy(); // hbuf, can't be put as parameter, because may be reallocated
00450         //Close database, delete database file.
00451         db.Close();
00452         User::LeaveIfError(RSqlDatabase::Delete(KDatabase));
00453         
00454         }
00455         
00463 void CSqlExample::ColumnBinaryStreamL()
00464         {
00465         RSqlDatabase db;
00466         TInt error;
00467         User::LeaveIfError(db.Create(KDbName));
00468 
00469         // Create a table
00470         _LIT(KSqlStmt1, "CREATE TABLE A(Fld1 INTEGER, Fld2 BLOB);");
00471         
00472         User::LeaveIfError(error = db.Exec(KSqlStmt1));
00473         const TInt KDataLen = 100;
00474 
00475         _LIT(KSqlStmt2, "INSERT INTO A(Fld1, Fld2) VALUES(");
00476         
00477         // Allocate a buffer for the SQL statement.
00478         HBufC8* buf = HBufC8::New(KSqlStmt2().Length() + KDataLen * 2 + 10);
00479         
00480         TPtr8 sql = buf->Des();
00481         
00482         // Insert row 1
00483 
00484         _LIT(KHexValStr1, "7E");
00485         sql.Copy(KSqlStmt2);
00486         
00487         _LIT(KString1, "1, x'");
00488         sql.Append(KString1);
00489         TInt i;
00490         for(i=0;i<KDataLen;++i)
00491                 {
00492                 sql.Append(KHexValStr1);
00493                 }
00494         _LIT(KString2, "')");   
00495         sql.Append(KString2);
00496 
00497         User::LeaveIfError(db.Exec(sql));
00498 
00499         // Insert row 2
00500         
00501         _LIT(KHexValStr2, "A3");
00502         sql.Copy(KSqlStmt2);
00503         _LIT(KString3, "2, x'");
00504         sql.Append(KString3);
00505         for(i=0;i<KDataLen;++i)
00506                 {
00507                 sql.Append(KHexValStr2);
00508                 }
00509         _LIT(KString4, "')");
00510         sql.Append(KString4);
00511 
00512         User::LeaveIfError(db.Exec(sql));
00513         
00514         // Prepare SELECT SQL statement
00515         _LIT(KSqlStmt3, "SELECT * FROM A");
00516         
00517         RSqlStatement stmt;
00518         User::LeaveIfError(error = stmt.Prepare(db, KSqlStmt3));
00519         
00520         // Move on row 1
00521         User::LeaveIfError(error = stmt.Next());
00522 
00523         // Read the long binary column using a stream
00524         RSqlColumnReadStream columnStream;
00525         error = columnStream.ColumnBinary(stmt, 1);
00526         
00527         
00528         TInt size = stmt.ColumnSize(1);
00529         TPtr8 colData = buf->Des();
00530         TRAP(error, columnStream.ReadL(colData, size));
00531         columnStream.Close();
00532         
00533         User::LeaveIfError(stmt.Next());
00534                 
00535         //Read row 2 using ColumnBinary(TInt aColumnIndex, TDes8& aDest).
00536         error = stmt.ColumnBinary(1, colData);
00537 
00538         //Read row 2 using a stream
00539         colData.Zero();
00540         error = columnStream.ColumnBinary(stmt, 1);
00541         
00542         size = stmt.ColumnSize(1);
00543         TRAP(error, columnStream.ReadL(colData, size));
00544         columnStream.Close();
00545         
00546         stmt.Close();
00547                 
00548         delete buf; 
00549         buf = NULL;
00550         
00551         db.Close();
00552 
00553         error = RSqlDatabase::Delete(KDbName);
00554         
00555         }
00556 
00557                                 
00558 LOCAL_C void MainL()
00559         {
00560         // Create an Active Scheduler to handle asychronous calls
00561         CActiveScheduler* scheduler = new (ELeave) CActiveScheduler;
00562         CleanupStack::PushL(scheduler);
00563         CActiveScheduler::Install( scheduler );
00564         CSqlExample* app = CSqlExample::NewLC();
00565         
00566         // Create a non secure database
00567         app->CreateNonSecureDBL();
00568         
00569         // Create and open a secure database
00570         app->CreateAndOpenSecureDBL();
00571         
00572         // Copy two databases
00573         app->CopyDatabaseL();
00574         
00575         // Attach two databases
00576         app->AttachDatabasesL();
00577         
00578         // Simple query and query with paramaters
00579         app->DataTypesQueryL();
00580         
00581         //Prepares and executes a query with a large parameter
00582         // writing that parameter using streaming (RParamWriteStream)
00583         app->ScalarFullSelectL();
00584         
00585         // Prepare and execute a query which returns data,
00586         // and read that data using streaming (RColumnReadStream)
00587         app->ColumnBinaryStreamL();
00588                 
00589         CleanupStack::PopAndDestroy(2); //app, scheduler
00590         
00591         }
00592 
00593 GLDEF_C TInt E32Main()
00594         {
00595     __UHEAP_MARK;
00596     CTrapCleanup* cleanup = CTrapCleanup::New();
00597     if(cleanup == NULL)
00598         {
00599         return KErrNoMemory;
00600         }
00601     TRAPD(err, MainL());
00602         if(err != KErrNone)
00603                 {
00604                 User::Panic(_L("Failed to complete"),err);
00605                 }
00606 
00607     delete cleanup;
00608     __UHEAP_MARKEND;
00609     return KErrNone;
00610         }

Generated by  doxygen 1.6.2