test_bindArray.js (3693B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 /* 6 * This file tests binding arrays to statements. 7 */ 8 9 add_task(async function test_errors() { 10 let db = Services.storage.openSpecialDatabase("memory"); 11 let stmt = db.createStatement("SELECT * FROM carray(?1)"); 12 13 Assert.throws( 14 () => stmt.bindArrayOfIntegersByIndex(0, 1), 15 /NS_ERROR_XPC_CANT_CONVERT_PRIMITIVE_TO_ARRAY/, 16 "Not an array" 17 ); 18 Assert.throws( 19 () => stmt.bindArrayOfIntegersByIndex(0, "string"), 20 /NS_ERROR_XPC_CANT_CONVERT_PRIMITIVE_TO_ARRAY/, 21 "Not an array" 22 ); 23 Assert.throws( 24 () => stmt.bindArrayOfIntegersByIndex(0, null), 25 /NS_ERROR_XPC_CANT_CONVERT_PRIMITIVE_TO_ARRAY/, 26 "Not an array" 27 ); 28 Assert.throws( 29 () => stmt.bindArrayOfUTF8StringsByIndex(0, null), 30 /NS_ERROR_XPC_CANT_CONVERT_PRIMITIVE_TO_ARRAY/, 31 "Not an array" 32 ); 33 34 stmt.finalize(); 35 db.close(); 36 }); 37 38 add_task(async function test_bind_empty_array() { 39 let db = Services.storage.openSpecialDatabase("memory"); 40 let stmt = db.createStatement("SELECT * FROM carray(?1)"); 41 stmt.bindArrayOfIntegersByIndex(0, []); 42 Assert.ok(!stmt.executeStep(), "Execution succeeds with no results"); 43 stmt.finalize(); 44 db.close(); 45 }); 46 47 add_task(async function test_bind() { 48 let db = getOpenedDatabase(); 49 db.executeSimpleSQL(` 50 CREATE TABLE test ( 51 id INTEGER, 52 value BLOB /* no affinity */ 53 ) 54 `); 55 56 db.executeSimpleSQL(` 57 INSERT INTO test (value) 58 VALUES 59 (1), 60 (2), 61 (1.1), 62 (2.2), 63 ("test1"), 64 ("test2") 65 `); 66 67 function bindStatement(stmt, results) { 68 if (Number.isInteger(results[0])) { 69 stmt.bindArrayOfIntegersByIndex(0, results); 70 stmt.bindArrayOfIntegersByName("values", results); 71 } else if (typeof results[0] == "number") { 72 stmt.bindArrayOfDoublesByIndex(0, results); 73 stmt.bindArrayOfDoublesByName("values", results); 74 } else if (typeof results[0] == "string") { 75 stmt.bindArrayOfStringsByIndex(0, results); 76 stmt.bindArrayOfStringsByName("values", results); 77 } 78 } 79 80 for (let results of [[1, 2], [1.1, 2.2], ["test1", "test2"], []]) { 81 info("sync statement"); 82 let query = ` 83 SELECT value FROM test 84 WHERE value IN carray(?1) 85 AND value IN carray(:values) 86 `; 87 let stmt = db.createStatement(query); 88 bindStatement(stmt, results); 89 for (let result of results) { 90 Assert.ok(stmt.executeStep()); 91 Assert.equal(stmt.row.value, result); 92 } 93 stmt.finalize(); 94 95 info("async statement"); 96 stmt = db.createAsyncStatement(query); 97 bindStatement(stmt, results); 98 let rv = await new Promise((resolve, reject) => { 99 let rows = []; 100 stmt.executeAsync({ 101 handleResult(resultSet) { 102 let row = null; 103 do { 104 row = resultSet.getNextRow(); 105 if (row) { 106 rows.push(row); 107 } 108 } while (row); 109 }, 110 handleError(error) { 111 reject(new Error(`Failed to execute statement: ${error.message}`)); 112 }, 113 handleCompletion(reason) { 114 if (reason == Ci.mozIStorageStatementCallback.REASON_FINISHED) { 115 resolve(rows.map(r => r.getResultByIndex(0))); 116 } else { 117 reject(new Error("Statement failed to execute or was cancelled")); 118 } 119 }, 120 }); 121 }); 122 Assert.deepEqual(rv, results); 123 stmt.finalize(); 124 } 125 // we are the last test using this connection and since it has gone async 126 // we *must* call asyncClose on it. 127 await asyncClose(db); 128 });