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