Home | History | Annotate | Download | only in database
      1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 /**
      6  * @fileoverview A collection of common functions used by all database
      7  * performance tests.
      8  */
      9 
     10 var CANNOT_OPEN_DB = -1;
     11 var SETUP_FAILED = -2;
     12 var TEST_FAILED = -3;
     13 
     14 var TRANSACTIONS = 1000;  // number of transactions; number of rows in the DB
     15 var RANDOM_STRING_LENGTH = 20;  // the length of the string on each row
     16 
     17 /**
     18  * Generates a random string of upper-case letters of
     19  * RANDOM_STRING_LENGTH length.
     20  */
     21 function getRandomString() {
     22   var s = '';
     23   for (var i = 0; i < RANDOM_STRING_LENGTH; i++)
     24     s += String.fromCharCode(Math.floor(Math.random() * 26) + 64);
     25   return s;
     26 }
     27 
     28 /**
     29  * Sets up and runs a performance test.
     30  * @param {!Object} params An object which must have the following fields:
     31  *   dbName: The database name.
     32  *   readOnly: If true, transactions will be run using the readTransaction()
     33  *       method. Otherwise, transaction() will be used.
     34  *   insertRowsAtSetup: Determines if setting up the database should include
     35  *       inserting TRANSACTIONS rows in it.
     36  *   transactionCallback: The transaction callback that should be timed. This
     37  *       function will be run TRANSACTIONS times and must take a transaction
     38  *       object as its only parameter.
     39  *   customRunTransactions: A custom function for running and timing
     40  *       transactions. If this parameter is not null, runPerformanceTest() will
     41  *       ignore the txFnct parameter and will call customRunTransactions() as
     42  *       soon as the setup is complete. In this case, the user is responsible
     43  *       for running and timing the transactions. If not null, this parameter
     44  *       must be a function that takes a database object as its only parameter.
     45  */
     46 function runPerformanceTest(params) {
     47   var db = openTestDatabase(params.dbName);
     48   if (!db) {
     49     testComplete(CANNOT_OPEN_DB);
     50     return;
     51   }
     52 
     53   db.transaction(
     54       function(tx) {
     55         tx.executeSql('CREATE TABLE IF NOT EXISTS Test (ID INT, Foo TEXT)', [],
     56                       function(tx, data) {}, function(tx, error) {});
     57         tx.executeSql('DELETE FROM Test');
     58         if (params.insertRowsAtSetup) {
     59           var randomString = getRandomString();
     60           for (var i = 0; i < TRANSACTIONS; i++) {
     61             tx.executeSql('INSERT INTO Test VALUES (?, ?)',
     62                           [i, randomString]);
     63           }
     64         }
     65       }, function(error) {
     66         testComplete(SETUP_FAILED);
     67       }, function() {
     68         if (params.customRunTransactions)
     69           params.customRunTransactions(db);
     70         else
     71           runTransactions(db, params.readOnly, params.transactionCallback);
     72       });
     73 }
     74 
     75 /**
     76  * Opens a database with the given name.
     77  * @param {string} name The name of the database.
     78  */
     79 function openTestDatabase(name) {
     80   if (window.openDatabase) {
     81     return window.openDatabase(name, '1.0', 'Test database.',
     82                                TRANSACTIONS * RANDOM_STRING_LENGTH);
     83   }
     84 
     85   return null;
     86 }
     87 
     88 /**
     89  * Runs the given transaction TRANSACTIONS times.
     90  * @param {!Object} db The database to run transactions on.
     91  * @param {boolean} readOnly If true, all transactions will be run using the
     92  *     db.readTransaction() call. Otherwise, the transactions will be run
     93  *     using the db.transaction() call.
     94  * @param {function(!Object)} The transaction callback.
     95  */
     96 function runTransactions(db, readOnly, transactionCallback) {
     97   var transactionsCompleted = 0;
     98   var transactionFunction = readOnly ? db.readTransaction : db.transaction;
     99   var startTime = Date.now();
    100   for (var i = 0; i < TRANSACTIONS; i++) {
    101     transactionFunction.call(db, transactionCallback,
    102                              function(error) {
    103                                testComplete(TEST_FAILED);
    104                              }, function() {
    105                                if (++transactionsCompleted == TRANSACTIONS)
    106                                  testComplete(Date.now() - startTime);
    107                              });
    108   }
    109 }
    110