michael@0: /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- michael@0: vim:set ts=2 sw=2 sts=2 et: michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: // This file tests the functions of mozIStorageStatementWrapper michael@0: michael@0: function setup() michael@0: { michael@0: getOpenedDatabase().createTable("test", "id INTEGER PRIMARY KEY, val NONE," + michael@0: "alt_val NONE"); michael@0: } michael@0: michael@0: /** michael@0: * A convenience wrapper for do_check_eq. Calls do_check_eq on aActualVal michael@0: * and aReturnedVal, with one caveat. michael@0: * michael@0: * Date objects are converted before parameter binding to PRTime's (microsecs michael@0: * since epoch). They are not reconverted when retrieved from the database. michael@0: * This function abstracts away this reconversion so that you can pass in, michael@0: * for example: michael@0: * michael@0: * checkVal(new Date(), aReturnedVal) // this michael@0: * checkVal(new Date().valueOf() * 1000.0, aReturnedVal) // instead of this michael@0: * michael@0: * Should any other types require conversion in the future, their conversions michael@0: * may also be abstracted away here. michael@0: * michael@0: * @param aActualVal michael@0: * the value inserted into the database michael@0: * @param aReturnedVal michael@0: * the value retrieved from the database michael@0: */ michael@0: function checkVal(aActualVal, aReturnedVal) michael@0: { michael@0: if (aActualVal instanceof Date) aActualVal = aActualVal.valueOf() * 1000.0; michael@0: do_check_eq(aActualVal, aReturnedVal); michael@0: } michael@0: michael@0: /** michael@0: * Removes all rows from our test table. michael@0: */ michael@0: function clearTable() michael@0: { michael@0: var stmt = createStatement("DELETE FROM test"); michael@0: stmt.execute(); michael@0: stmt.finalize(); michael@0: ensureNumRows(0); michael@0: } michael@0: michael@0: /** michael@0: * Ensures that the number of rows in our test table is equal to aNumRows. michael@0: * Calls do_check_eq on aNumRows and the value retrieved by SELECT'ing COUNT(*). michael@0: * michael@0: * @param aNumRows michael@0: * the number of rows our test table should contain michael@0: */ michael@0: function ensureNumRows(aNumRows) michael@0: { michael@0: var stmt = createStatement("SELECT COUNT(*) AS number FROM test"); michael@0: do_check_true(stmt.step()); michael@0: do_check_eq(aNumRows, stmt.row.number); michael@0: stmt.reset(); michael@0: stmt.finalize(); michael@0: } michael@0: michael@0: /** michael@0: * Inserts aVal into our test table and checks that insertion was successful by michael@0: * retrieving the newly inserted value from the database and comparing it michael@0: * against aVal. aVal is bound to a single parameter. michael@0: * michael@0: * @param aVal michael@0: * value to insert into our test table and check michael@0: */ michael@0: function insertAndCheckSingleParam(aVal) michael@0: { michael@0: clearTable(); michael@0: michael@0: var stmt = createStatement("INSERT INTO test (val) VALUES (:val)"); michael@0: stmt.params.val = aVal; michael@0: stmt.execute(); michael@0: stmt.finalize(); michael@0: michael@0: ensureNumRows(1); michael@0: michael@0: stmt = createStatement("SELECT val FROM test WHERE id = 1"); michael@0: do_check_true(stmt.step()); michael@0: checkVal(aVal, stmt.row.val); michael@0: stmt.reset(); michael@0: stmt.finalize(); michael@0: } michael@0: michael@0: /** michael@0: * Inserts aVal into our test table and checks that insertion was successful by michael@0: * retrieving the newly inserted value from the database and comparing it michael@0: * against aVal. aVal is bound to two separate parameters, both of which are michael@0: * checked against aVal. michael@0: * michael@0: * @param aVal michael@0: * value to insert into our test table and check michael@0: */ michael@0: function insertAndCheckMultipleParams(aVal) michael@0: { michael@0: clearTable(); michael@0: michael@0: var stmt = createStatement("INSERT INTO test (val, alt_val) " + michael@0: "VALUES (:val, :val)"); michael@0: stmt.params.val = aVal; michael@0: stmt.execute(); michael@0: stmt.finalize(); michael@0: michael@0: ensureNumRows(1); michael@0: michael@0: stmt = createStatement("SELECT val, alt_val FROM test WHERE id = 1"); michael@0: do_check_true(stmt.step()); michael@0: checkVal(aVal, stmt.row.val); michael@0: checkVal(aVal, stmt.row.alt_val); michael@0: stmt.reset(); michael@0: stmt.finalize(); michael@0: } michael@0: michael@0: /** michael@0: * A convenience function that prints out a description of aVal using michael@0: * aVal.toString and aVal.toSource. Output is useful when the test fails. michael@0: * michael@0: * @param aVal michael@0: * a value inserted or to be inserted into our test table michael@0: */ michael@0: function printValDesc(aVal) michael@0: { michael@0: try michael@0: { michael@0: var toSource = aVal.toSource(); michael@0: } michael@0: catch (exc) michael@0: { michael@0: toSource = ""; michael@0: } michael@0: print("Testing value: toString=" + aVal + michael@0: (toSource ? " toSource=" + toSource : "")); michael@0: } michael@0: michael@0: function run_test() michael@0: { michael@0: setup(); michael@0: michael@0: // function JSValStorageStatementBinder in michael@0: // storage/src/mozStorageStatementParams.cpp tells us that the following types michael@0: // and only the following types are valid as statement parameters: michael@0: var vals = [ michael@0: 1337, // int michael@0: 3.1337, // double michael@0: "foo", // string michael@0: true, // boolean michael@0: null, // null michael@0: new Date(), // Date object michael@0: ]; michael@0: michael@0: vals.forEach(function (val) michael@0: { michael@0: printValDesc(val); michael@0: print("Single parameter"); michael@0: insertAndCheckSingleParam(val); michael@0: print("Multiple parameters"); michael@0: insertAndCheckMultipleParams(val) michael@0: }); michael@0: michael@0: cleanup(); michael@0: }