storage/test/unit/test_connection_executeAsync.js

branch
TOR_BUG_9701
changeset 8
97036ab72558
equal deleted inserted replaced
-1:000000000000 0:d46239ac9ae1
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 the functionality of mozIStorageConnection::executeAsync for
7 * both mozIStorageStatement and mozIStorageAsyncStatement.
8 */
9
10 const INTEGER = 1;
11 const TEXT = "this is test text";
12 const REAL = 3.23;
13 const BLOB = [1, 2];
14
15 function test_create_and_add()
16 {
17 getOpenedDatabase().executeSimpleSQL(
18 "CREATE TABLE test (" +
19 "id INTEGER, " +
20 "string TEXT, " +
21 "number REAL, " +
22 "nuller NULL, " +
23 "blober BLOB" +
24 ")"
25 );
26
27 let stmts = [];
28 stmts[0] = getOpenedDatabase().createStatement(
29 "INSERT INTO test (id, string, number, nuller, blober) VALUES (?, ?, ?, ?, ?)"
30 );
31 stmts[0].bindByIndex(0, INTEGER);
32 stmts[0].bindByIndex(1, TEXT);
33 stmts[0].bindByIndex(2, REAL);
34 stmts[0].bindByIndex(3, null);
35 stmts[0].bindBlobByIndex(4, BLOB, BLOB.length);
36 stmts[1] = getOpenedDatabase().createAsyncStatement(
37 "INSERT INTO test (string, number, nuller, blober) VALUES (?, ?, ?, ?)"
38 );
39 stmts[1].bindByIndex(0, TEXT);
40 stmts[1].bindByIndex(1, REAL);
41 stmts[1].bindByIndex(2, null);
42 stmts[1].bindBlobByIndex(3, BLOB, BLOB.length);
43
44 getOpenedDatabase().executeAsync(stmts, stmts.length, {
45 handleResult: function(aResultSet)
46 {
47 dump("handleResult("+aResultSet+")\n");
48 do_throw("unexpected results obtained!");
49 },
50 handleError: function(aError)
51 {
52 dump("handleError("+aError.result+")\n");
53 do_throw("unexpected error!");
54 },
55 handleCompletion: function(aReason)
56 {
57 dump("handleCompletion("+aReason+")\n");
58 do_check_eq(Ci.mozIStorageStatementCallback.REASON_FINISHED, aReason);
59
60 // Check that the result is in the table
61 let stmt = getOpenedDatabase().createStatement(
62 "SELECT string, number, nuller, blober FROM test WHERE id = ?"
63 );
64 stmt.bindByIndex(0, INTEGER);
65 try {
66 do_check_true(stmt.executeStep());
67 do_check_eq(TEXT, stmt.getString(0));
68 do_check_eq(REAL, stmt.getDouble(1));
69 do_check_true(stmt.getIsNull(2));
70 let count = { value: 0 };
71 let blob = { value: null };
72 stmt.getBlob(3, count, blob);
73 do_check_eq(BLOB.length, count.value);
74 for (let i = 0; i < BLOB.length; i++)
75 do_check_eq(BLOB[i], blob.value[i]);
76 }
77 finally {
78 stmt.finalize();
79 }
80
81 // Make sure we have two rows in the table
82 stmt = getOpenedDatabase().createStatement(
83 "SELECT COUNT(1) FROM test"
84 );
85 try {
86 do_check_true(stmt.executeStep());
87 do_check_eq(2, stmt.getInt32(0));
88 }
89 finally {
90 stmt.finalize();
91 }
92
93 // Run the next test.
94 run_next_test();
95 }
96 });
97 stmts[0].finalize();
98 stmts[1].finalize();
99 }
100
101 function test_multiple_bindings_on_statements()
102 {
103 // This tests to make sure that we pass all the statements multiply bound
104 // parameters when we call executeAsync.
105 const AMOUNT_TO_ADD = 5;
106 const ITERATIONS = 5;
107
108 let stmts = [];
109 let db = getOpenedDatabase();
110 let sqlString = "INSERT INTO test (id, string, number, nuller, blober) " +
111 "VALUES (:int, :text, :real, :null, :blob)";
112 // We run the same statement twice, and should insert 2 * AMOUNT_TO_ADD.
113 for (let i = 0; i < ITERATIONS; i++) {
114 // alternate the type of statement we create
115 if (i % 2)
116 stmts[i] = db.createStatement(sqlString);
117 else
118 stmts[i] = db.createAsyncStatement(sqlString);
119
120 let params = stmts[i].newBindingParamsArray();
121 for (let j = 0; j < AMOUNT_TO_ADD; j++) {
122 let bp = params.newBindingParams();
123 bp.bindByName("int", INTEGER);
124 bp.bindByName("text", TEXT);
125 bp.bindByName("real", REAL);
126 bp.bindByName("null", null);
127 bp.bindBlobByName("blob", BLOB, BLOB.length);
128 params.addParams(bp);
129 }
130 stmts[i].bindParameters(params);
131 }
132
133 // Get our current number of rows in the table.
134 let currentRows = 0;
135 let countStmt = getOpenedDatabase().createStatement(
136 "SELECT COUNT(1) AS count FROM test"
137 );
138 try {
139 do_check_true(countStmt.executeStep());
140 currentRows = countStmt.row.count;
141 }
142 finally {
143 countStmt.reset();
144 }
145
146 // Execute asynchronously.
147 getOpenedDatabase().executeAsync(stmts, stmts.length, {
148 handleResult: function(aResultSet)
149 {
150 do_throw("Unexpected call to handleResult!");
151 },
152 handleError: function(aError)
153 {
154 print("Error code " + aError.result + " with message '" +
155 aError.message + "' returned.");
156 do_throw("Unexpected error!");
157 },
158 handleCompletion: function(aReason)
159 {
160 print("handleCompletion(" + aReason +
161 ") for test_multiple_bindings_on_statements");
162 do_check_eq(Ci.mozIStorageStatementCallback.REASON_FINISHED, aReason);
163
164 // Check to make sure we added all of our rows.
165 try {
166 do_check_true(countStmt.executeStep());
167 do_check_eq(currentRows + (ITERATIONS * AMOUNT_TO_ADD),
168 countStmt.row.count);
169 }
170 finally {
171 countStmt.finalize();
172 }
173
174 // Run the next test.
175 run_next_test();
176 }
177 });
178 stmts.forEach(function(stmt) stmt.finalize());
179 }
180
181 function test_asyncClose_does_not_complete_before_statements()
182 {
183 let stmt = createStatement("SELECT * FROM sqlite_master");
184 let executed = false;
185 stmt.executeAsync({
186 handleResult: function(aResultSet)
187 {
188 },
189 handleError: function(aError)
190 {
191 print("Error code " + aError.result + " with message '" +
192 aError.message + "' returned.");
193 do_throw("Unexpected error!");
194 },
195 handleCompletion: function(aReason)
196 {
197 print("handleCompletion(" + aReason +
198 ") for test_asyncClose_does_not_complete_before_statements");
199 do_check_eq(Ci.mozIStorageStatementCallback.REASON_FINISHED, aReason);
200 executed = true;
201 }
202 });
203 stmt.finalize();
204
205 getOpenedDatabase().asyncClose(function() {
206 // Ensure that the statement executed to completion.
207 do_check_true(executed);
208
209 // Reset gDBConn so that later tests will get a new connection object.
210 gDBConn = null;
211 run_next_test();
212 });
213 }
214
215 function test_asyncClose_does_not_throw_no_callback()
216 {
217 getOpenedDatabase().asyncClose();
218
219 // Reset gDBConn so that later tests will get a new connection object.
220 gDBConn = null;
221 run_next_test();
222 }
223
224 function test_double_asyncClose_throws()
225 {
226 let conn = getOpenedDatabase();
227 conn.asyncClose();
228 try {
229 conn.asyncClose();
230 do_throw("should have thrown");
231 // There is a small race condition here, which can cause either of
232 // Cr.NS_ERROR_NOT_INITIALIZED or Cr.NS_ERROR_UNEXPECTED to be thrown.
233 } catch (e if "result" in e && e.result == Cr.NS_ERROR_NOT_INITIALIZED) {
234 do_print("NS_ERROR_NOT_INITIALIZED");
235 } catch (e if "result" in e && e.result == Cr.NS_ERROR_UNEXPECTED) {
236 do_print("NS_ERROR_UNEXPECTED");
237 } catch (e) {
238 }
239
240 // Reset gDBConn so that later tests will get a new connection object.
241 gDBConn = null;
242 run_next_test();
243 }
244
245 ////////////////////////////////////////////////////////////////////////////////
246 //// Test Runner
247
248 [
249 test_create_and_add,
250 test_multiple_bindings_on_statements,
251 test_asyncClose_does_not_complete_before_statements,
252 test_asyncClose_does_not_throw_no_callback,
253 test_double_asyncClose_throws,
254 ].forEach(add_test);
255
256 function run_test()
257 {
258 cleanup();
259 run_next_test();
260 }

mercurial