extensions/cookie/test/unit/head_cookies.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* Any copyright is dedicated to the Public Domain.
michael@0 2 * http://creativecommons.org/publicdomain/zero/1.0/
michael@0 3 */
michael@0 4
michael@0 5 Components.utils.import("resource://gre/modules/Services.jsm");
michael@0 6 Components.utils.import("resource://gre/modules/NetUtil.jsm");
michael@0 7 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
michael@0 8
michael@0 9 const Cc = Components.classes;
michael@0 10 const Ci = Components.interfaces;
michael@0 11 const Cr = Components.results;
michael@0 12
michael@0 13 XPCOMUtils.defineLazyServiceGetter(Services, "cookies",
michael@0 14 "@mozilla.org/cookieService;1",
michael@0 15 "nsICookieService");
michael@0 16 XPCOMUtils.defineLazyServiceGetter(Services, "cookiemgr",
michael@0 17 "@mozilla.org/cookiemanager;1",
michael@0 18 "nsICookieManager2");
michael@0 19
michael@0 20 XPCOMUtils.defineLazyServiceGetter(Services, "etld",
michael@0 21 "@mozilla.org/network/effective-tld-service;1",
michael@0 22 "nsIEffectiveTLDService");
michael@0 23
michael@0 24 function do_check_throws(f, result, stack)
michael@0 25 {
michael@0 26 if (!stack)
michael@0 27 stack = Components.stack.caller;
michael@0 28
michael@0 29 try {
michael@0 30 f();
michael@0 31 } catch (exc) {
michael@0 32 if (exc.result == result)
michael@0 33 return;
michael@0 34 do_throw("expected result " + result + ", caught " + exc, stack);
michael@0 35 }
michael@0 36 do_throw("expected result " + result + ", none thrown", stack);
michael@0 37 }
michael@0 38
michael@0 39 // Helper to step a generator function and catch a StopIteration exception.
michael@0 40 function do_run_generator(generator)
michael@0 41 {
michael@0 42 try {
michael@0 43 generator.next();
michael@0 44 } catch (e) {
michael@0 45 if (e != StopIteration)
michael@0 46 do_throw("caught exception " + e, Components.stack.caller);
michael@0 47 }
michael@0 48 }
michael@0 49
michael@0 50 // Helper to finish a generator function test.
michael@0 51 function do_finish_generator_test(generator)
michael@0 52 {
michael@0 53 do_execute_soon(function() {
michael@0 54 generator.close();
michael@0 55 do_test_finished();
michael@0 56 });
michael@0 57 }
michael@0 58
michael@0 59 function _observer(generator, topic) {
michael@0 60 Services.obs.addObserver(this, topic, false);
michael@0 61
michael@0 62 this.generator = generator;
michael@0 63 this.topic = topic;
michael@0 64 }
michael@0 65
michael@0 66 _observer.prototype = {
michael@0 67 observe: function (subject, topic, data) {
michael@0 68 do_check_eq(this.topic, topic);
michael@0 69
michael@0 70 Services.obs.removeObserver(this, this.topic);
michael@0 71
michael@0 72 // Continue executing the generator function.
michael@0 73 if (this.generator)
michael@0 74 do_run_generator(this.generator);
michael@0 75
michael@0 76 this.generator = null;
michael@0 77 this.topic = null;
michael@0 78 }
michael@0 79 }
michael@0 80
michael@0 81 // Close the cookie database. If a generator is supplied, it will be invoked
michael@0 82 // once the close is complete.
michael@0 83 function do_close_profile(generator, cleanse) {
michael@0 84 // Register an observer for db close.
michael@0 85 let obs = new _observer(generator, "cookie-db-closed");
michael@0 86
michael@0 87 // Close the db.
michael@0 88 let service = Services.cookies.QueryInterface(Ci.nsIObserver);
michael@0 89 service.observe(null, "profile-before-change", cleanse ? cleanse : "");
michael@0 90 }
michael@0 91
michael@0 92 // Load the cookie database. If a generator is supplied, it will be invoked
michael@0 93 // once the load is complete.
michael@0 94 function do_load_profile(generator) {
michael@0 95 // Register an observer for read completion.
michael@0 96 let obs = new _observer(generator, "cookie-db-read");
michael@0 97
michael@0 98 // Load the profile.
michael@0 99 let service = Services.cookies.QueryInterface(Ci.nsIObserver);
michael@0 100 service.observe(null, "profile-do-change", "");
michael@0 101 }
michael@0 102
michael@0 103 // Set a single session cookie using http and test the cookie count
michael@0 104 // against 'expected'
michael@0 105 function do_set_single_http_cookie(uri, channel, expected) {
michael@0 106 Services.cookies.setCookieStringFromHttp(uri, null, null, "foo=bar", null, channel);
michael@0 107 do_check_eq(Services.cookiemgr.countCookiesFromHost(uri.host), expected);
michael@0 108 }
michael@0 109
michael@0 110 // Set four cookies; with & without channel, http and non-http; and test
michael@0 111 // the cookie count against 'expected' after each set.
michael@0 112 function do_set_cookies(uri, channel, session, expected) {
michael@0 113 let suffix = session ? "" : "; max-age=1000";
michael@0 114
michael@0 115 // without channel
michael@0 116 Services.cookies.setCookieString(uri, null, "oh=hai" + suffix, null);
michael@0 117 do_check_eq(Services.cookiemgr.countCookiesFromHost(uri.host), expected[0]);
michael@0 118 // with channel
michael@0 119 Services.cookies.setCookieString(uri, null, "can=has" + suffix, channel);
michael@0 120 do_check_eq(Services.cookiemgr.countCookiesFromHost(uri.host), expected[1]);
michael@0 121 // without channel, from http
michael@0 122 Services.cookies.setCookieStringFromHttp(uri, null, null, "cheez=burger" + suffix, null, null);
michael@0 123 do_check_eq(Services.cookiemgr.countCookiesFromHost(uri.host), expected[2]);
michael@0 124 // with channel, from http
michael@0 125 Services.cookies.setCookieStringFromHttp(uri, null, null, "hot=dog" + suffix, null, channel);
michael@0 126 do_check_eq(Services.cookiemgr.countCookiesFromHost(uri.host), expected[3]);
michael@0 127 }
michael@0 128
michael@0 129 function do_count_enumerator(enumerator) {
michael@0 130 let i = 0;
michael@0 131 while (enumerator.hasMoreElements()) {
michael@0 132 enumerator.getNext();
michael@0 133 ++i;
michael@0 134 }
michael@0 135 return i;
michael@0 136 }
michael@0 137
michael@0 138 function do_count_cookies() {
michael@0 139 return do_count_enumerator(Services.cookiemgr.enumerator);
michael@0 140 }
michael@0 141
michael@0 142 // Helper object to store cookie data.
michael@0 143 function Cookie(name,
michael@0 144 value,
michael@0 145 host,
michael@0 146 path,
michael@0 147 expiry,
michael@0 148 lastAccessed,
michael@0 149 creationTime,
michael@0 150 isSession,
michael@0 151 isSecure,
michael@0 152 isHttpOnly)
michael@0 153 {
michael@0 154 this.name = name;
michael@0 155 this.value = value;
michael@0 156 this.host = host;
michael@0 157 this.path = path;
michael@0 158 this.expiry = expiry;
michael@0 159 this.lastAccessed = lastAccessed;
michael@0 160 this.creationTime = creationTime;
michael@0 161 this.isSession = isSession;
michael@0 162 this.isSecure = isSecure;
michael@0 163 this.isHttpOnly = isHttpOnly;
michael@0 164
michael@0 165 let strippedHost = host.charAt(0) == '.' ? host.slice(1) : host;
michael@0 166
michael@0 167 try {
michael@0 168 this.baseDomain = Services.etld.getBaseDomainFromHost(strippedHost);
michael@0 169 } catch (e) {
michael@0 170 if (e.result == Cr.NS_ERROR_HOST_IS_IP_ADDRESS ||
michael@0 171 e.result == Cr.NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS)
michael@0 172 this.baseDomain = strippedHost;
michael@0 173 }
michael@0 174 }
michael@0 175
michael@0 176 // Object representing a database connection and associated statements. The
michael@0 177 // implementation varies depending on schema version.
michael@0 178 function CookieDatabaseConnection(file, schema)
michael@0 179 {
michael@0 180 // Manually generate a cookies.sqlite file with appropriate rows, columns,
michael@0 181 // and schema version. If it already exists, just set up our statements.
michael@0 182 let exists = file.exists();
michael@0 183
michael@0 184 this.db = Services.storage.openDatabase(file);
michael@0 185 this.schema = schema;
michael@0 186 if (!exists)
michael@0 187 this.db.schemaVersion = schema;
michael@0 188
michael@0 189 switch (schema) {
michael@0 190 case 1:
michael@0 191 {
michael@0 192 if (!exists) {
michael@0 193 this.db.executeSimpleSQL(
michael@0 194 "CREATE TABLE moz_cookies ( \
michael@0 195 id INTEGER PRIMARY KEY, \
michael@0 196 name TEXT, \
michael@0 197 value TEXT, \
michael@0 198 host TEXT, \
michael@0 199 path TEXT, \
michael@0 200 expiry INTEGER, \
michael@0 201 isSecure INTEGER, \
michael@0 202 isHttpOnly INTEGER)");
michael@0 203 }
michael@0 204
michael@0 205 this.stmtInsert = this.db.createStatement(
michael@0 206 "INSERT INTO moz_cookies ( \
michael@0 207 id, \
michael@0 208 name, \
michael@0 209 value, \
michael@0 210 host, \
michael@0 211 path, \
michael@0 212 expiry, \
michael@0 213 isSecure, \
michael@0 214 isHttpOnly) \
michael@0 215 VALUES ( \
michael@0 216 :id, \
michael@0 217 :name, \
michael@0 218 :value, \
michael@0 219 :host, \
michael@0 220 :path, \
michael@0 221 :expiry, \
michael@0 222 :isSecure, \
michael@0 223 :isHttpOnly)");
michael@0 224
michael@0 225 this.stmtDelete = this.db.createStatement(
michael@0 226 "DELETE FROM moz_cookies WHERE id = :id");
michael@0 227
michael@0 228 break;
michael@0 229 }
michael@0 230
michael@0 231 case 2:
michael@0 232 {
michael@0 233 if (!exists) {
michael@0 234 this.db.executeSimpleSQL(
michael@0 235 "CREATE TABLE moz_cookies ( \
michael@0 236 id INTEGER PRIMARY KEY, \
michael@0 237 name TEXT, \
michael@0 238 value TEXT, \
michael@0 239 host TEXT, \
michael@0 240 path TEXT, \
michael@0 241 expiry INTEGER, \
michael@0 242 lastAccessed INTEGER, \
michael@0 243 isSecure INTEGER, \
michael@0 244 isHttpOnly INTEGER)");
michael@0 245 }
michael@0 246
michael@0 247 this.stmtInsert = this.db.createStatement(
michael@0 248 "INSERT OR REPLACE INTO moz_cookies ( \
michael@0 249 id, \
michael@0 250 name, \
michael@0 251 value, \
michael@0 252 host, \
michael@0 253 path, \
michael@0 254 expiry, \
michael@0 255 lastAccessed, \
michael@0 256 isSecure, \
michael@0 257 isHttpOnly) \
michael@0 258 VALUES ( \
michael@0 259 :id, \
michael@0 260 :name, \
michael@0 261 :value, \
michael@0 262 :host, \
michael@0 263 :path, \
michael@0 264 :expiry, \
michael@0 265 :lastAccessed, \
michael@0 266 :isSecure, \
michael@0 267 :isHttpOnly)");
michael@0 268
michael@0 269 this.stmtDelete = this.db.createStatement(
michael@0 270 "DELETE FROM moz_cookies WHERE id = :id");
michael@0 271
michael@0 272 this.stmtUpdate = this.db.createStatement(
michael@0 273 "UPDATE moz_cookies SET lastAccessed = :lastAccessed WHERE id = :id");
michael@0 274
michael@0 275 break;
michael@0 276 }
michael@0 277
michael@0 278 case 3:
michael@0 279 {
michael@0 280 if (!exists) {
michael@0 281 this.db.executeSimpleSQL(
michael@0 282 "CREATE TABLE moz_cookies ( \
michael@0 283 id INTEGER PRIMARY KEY, \
michael@0 284 baseDomain TEXT, \
michael@0 285 name TEXT, \
michael@0 286 value TEXT, \
michael@0 287 host TEXT, \
michael@0 288 path TEXT, \
michael@0 289 expiry INTEGER, \
michael@0 290 lastAccessed INTEGER, \
michael@0 291 isSecure INTEGER, \
michael@0 292 isHttpOnly INTEGER)");
michael@0 293
michael@0 294 this.db.executeSimpleSQL(
michael@0 295 "CREATE INDEX moz_basedomain ON moz_cookies (baseDomain)");
michael@0 296 }
michael@0 297
michael@0 298 this.stmtInsert = this.db.createStatement(
michael@0 299 "INSERT INTO moz_cookies ( \
michael@0 300 id, \
michael@0 301 baseDomain, \
michael@0 302 name, \
michael@0 303 value, \
michael@0 304 host, \
michael@0 305 path, \
michael@0 306 expiry, \
michael@0 307 lastAccessed, \
michael@0 308 isSecure, \
michael@0 309 isHttpOnly) \
michael@0 310 VALUES ( \
michael@0 311 :id, \
michael@0 312 :baseDomain, \
michael@0 313 :name, \
michael@0 314 :value, \
michael@0 315 :host, \
michael@0 316 :path, \
michael@0 317 :expiry, \
michael@0 318 :lastAccessed, \
michael@0 319 :isSecure, \
michael@0 320 :isHttpOnly)");
michael@0 321
michael@0 322 this.stmtDelete = this.db.createStatement(
michael@0 323 "DELETE FROM moz_cookies WHERE id = :id");
michael@0 324
michael@0 325 this.stmtUpdate = this.db.createStatement(
michael@0 326 "UPDATE moz_cookies SET lastAccessed = :lastAccessed WHERE id = :id");
michael@0 327
michael@0 328 break;
michael@0 329 }
michael@0 330
michael@0 331 case 4:
michael@0 332 {
michael@0 333 if (!exists) {
michael@0 334 this.db.executeSimpleSQL(
michael@0 335 "CREATE TABLE moz_cookies ( \
michael@0 336 id INTEGER PRIMARY KEY, \
michael@0 337 baseDomain TEXT, \
michael@0 338 name TEXT, \
michael@0 339 value TEXT, \
michael@0 340 host TEXT, \
michael@0 341 path TEXT, \
michael@0 342 expiry INTEGER, \
michael@0 343 lastAccessed INTEGER, \
michael@0 344 creationTime INTEGER, \
michael@0 345 isSecure INTEGER, \
michael@0 346 isHttpOnly INTEGER \
michael@0 347 CONSTRAINT moz_uniqueid UNIQUE (name, host, path))");
michael@0 348
michael@0 349 this.db.executeSimpleSQL(
michael@0 350 "CREATE INDEX moz_basedomain ON moz_cookies (baseDomain)");
michael@0 351
michael@0 352 this.db.executeSimpleSQL(
michael@0 353 "PRAGMA journal_mode = WAL");
michael@0 354 }
michael@0 355
michael@0 356 this.stmtInsert = this.db.createStatement(
michael@0 357 "INSERT INTO moz_cookies ( \
michael@0 358 baseDomain, \
michael@0 359 name, \
michael@0 360 value, \
michael@0 361 host, \
michael@0 362 path, \
michael@0 363 expiry, \
michael@0 364 lastAccessed, \
michael@0 365 creationTime, \
michael@0 366 isSecure, \
michael@0 367 isHttpOnly) \
michael@0 368 VALUES ( \
michael@0 369 :baseDomain, \
michael@0 370 :name, \
michael@0 371 :value, \
michael@0 372 :host, \
michael@0 373 :path, \
michael@0 374 :expiry, \
michael@0 375 :lastAccessed, \
michael@0 376 :creationTime, \
michael@0 377 :isSecure, \
michael@0 378 :isHttpOnly)");
michael@0 379
michael@0 380 this.stmtDelete = this.db.createStatement(
michael@0 381 "DELETE FROM moz_cookies \
michael@0 382 WHERE name = :name AND host = :host AND path = :path");
michael@0 383
michael@0 384 this.stmtUpdate = this.db.createStatement(
michael@0 385 "UPDATE moz_cookies SET lastAccessed = :lastAccessed \
michael@0 386 WHERE name = :name AND host = :host AND path = :path");
michael@0 387
michael@0 388 break;
michael@0 389 }
michael@0 390
michael@0 391 default:
michael@0 392 do_throw("unrecognized schemaVersion!");
michael@0 393 }
michael@0 394 }
michael@0 395
michael@0 396 CookieDatabaseConnection.prototype =
michael@0 397 {
michael@0 398 insertCookie: function(cookie)
michael@0 399 {
michael@0 400 if (!(cookie instanceof Cookie))
michael@0 401 do_throw("not a cookie");
michael@0 402
michael@0 403 switch (this.schema)
michael@0 404 {
michael@0 405 case 1:
michael@0 406 this.stmtInsert.bindByName("id", cookie.creationTime);
michael@0 407 this.stmtInsert.bindByName("name", cookie.name);
michael@0 408 this.stmtInsert.bindByName("value", cookie.value);
michael@0 409 this.stmtInsert.bindByName("host", cookie.host);
michael@0 410 this.stmtInsert.bindByName("path", cookie.path);
michael@0 411 this.stmtInsert.bindByName("expiry", cookie.expiry);
michael@0 412 this.stmtInsert.bindByName("isSecure", cookie.isSecure);
michael@0 413 this.stmtInsert.bindByName("isHttpOnly", cookie.isHttpOnly);
michael@0 414 break;
michael@0 415
michael@0 416 case 2:
michael@0 417 this.stmtInsert.bindByName("id", cookie.creationTime);
michael@0 418 this.stmtInsert.bindByName("name", cookie.name);
michael@0 419 this.stmtInsert.bindByName("value", cookie.value);
michael@0 420 this.stmtInsert.bindByName("host", cookie.host);
michael@0 421 this.stmtInsert.bindByName("path", cookie.path);
michael@0 422 this.stmtInsert.bindByName("expiry", cookie.expiry);
michael@0 423 this.stmtInsert.bindByName("lastAccessed", cookie.lastAccessed);
michael@0 424 this.stmtInsert.bindByName("isSecure", cookie.isSecure);
michael@0 425 this.stmtInsert.bindByName("isHttpOnly", cookie.isHttpOnly);
michael@0 426 break;
michael@0 427
michael@0 428 case 3:
michael@0 429 this.stmtInsert.bindByName("id", cookie.creationTime);
michael@0 430 this.stmtInsert.bindByName("baseDomain", cookie.baseDomain);
michael@0 431 this.stmtInsert.bindByName("name", cookie.name);
michael@0 432 this.stmtInsert.bindByName("value", cookie.value);
michael@0 433 this.stmtInsert.bindByName("host", cookie.host);
michael@0 434 this.stmtInsert.bindByName("path", cookie.path);
michael@0 435 this.stmtInsert.bindByName("expiry", cookie.expiry);
michael@0 436 this.stmtInsert.bindByName("lastAccessed", cookie.lastAccessed);
michael@0 437 this.stmtInsert.bindByName("isSecure", cookie.isSecure);
michael@0 438 this.stmtInsert.bindByName("isHttpOnly", cookie.isHttpOnly);
michael@0 439 break;
michael@0 440
michael@0 441 case 4:
michael@0 442 this.stmtInsert.bindByName("baseDomain", cookie.baseDomain);
michael@0 443 this.stmtInsert.bindByName("name", cookie.name);
michael@0 444 this.stmtInsert.bindByName("value", cookie.value);
michael@0 445 this.stmtInsert.bindByName("host", cookie.host);
michael@0 446 this.stmtInsert.bindByName("path", cookie.path);
michael@0 447 this.stmtInsert.bindByName("expiry", cookie.expiry);
michael@0 448 this.stmtInsert.bindByName("lastAccessed", cookie.lastAccessed);
michael@0 449 this.stmtInsert.bindByName("creationTime", cookie.creationTime);
michael@0 450 this.stmtInsert.bindByName("isSecure", cookie.isSecure);
michael@0 451 this.stmtInsert.bindByName("isHttpOnly", cookie.isHttpOnly);
michael@0 452 break;
michael@0 453
michael@0 454 default:
michael@0 455 do_throw("unrecognized schemaVersion!");
michael@0 456 }
michael@0 457
michael@0 458 do_execute_stmt(this.stmtInsert);
michael@0 459 },
michael@0 460
michael@0 461 deleteCookie: function(cookie)
michael@0 462 {
michael@0 463 if (!(cookie instanceof Cookie))
michael@0 464 do_throw("not a cookie");
michael@0 465
michael@0 466 switch (this.db.schemaVersion)
michael@0 467 {
michael@0 468 case 1:
michael@0 469 case 2:
michael@0 470 case 3:
michael@0 471 this.stmtDelete.bindByName("id", cookie.creationTime);
michael@0 472 break;
michael@0 473
michael@0 474 case 4:
michael@0 475 this.stmtDelete.bindByName("name", cookie.name);
michael@0 476 this.stmtDelete.bindByName("host", cookie.host);
michael@0 477 this.stmtDelete.bindByName("path", cookie.path);
michael@0 478 break;
michael@0 479
michael@0 480 default:
michael@0 481 do_throw("unrecognized schemaVersion!");
michael@0 482 }
michael@0 483
michael@0 484 do_execute_stmt(this.stmtDelete);
michael@0 485 },
michael@0 486
michael@0 487 updateCookie: function(cookie)
michael@0 488 {
michael@0 489 if (!(cookie instanceof Cookie))
michael@0 490 do_throw("not a cookie");
michael@0 491
michael@0 492 switch (this.db.schemaVersion)
michael@0 493 {
michael@0 494 case 1:
michael@0 495 do_throw("can't update a schema 1 cookie!");
michael@0 496
michael@0 497 case 2:
michael@0 498 case 3:
michael@0 499 this.stmtUpdate.bindByName("id", cookie.creationTime);
michael@0 500 this.stmtUpdate.bindByName("lastAccessed", cookie.lastAccessed);
michael@0 501 break;
michael@0 502
michael@0 503 case 4:
michael@0 504 this.stmtDelete.bindByName("name", cookie.name);
michael@0 505 this.stmtDelete.bindByName("host", cookie.host);
michael@0 506 this.stmtDelete.bindByName("path", cookie.path);
michael@0 507 this.stmtUpdate.bindByName("lastAccessed", cookie.lastAccessed);
michael@0 508 break;
michael@0 509
michael@0 510 default:
michael@0 511 do_throw("unrecognized schemaVersion!");
michael@0 512 }
michael@0 513
michael@0 514 do_execute_stmt(this.stmtUpdate);
michael@0 515 },
michael@0 516
michael@0 517 close: function()
michael@0 518 {
michael@0 519 this.stmtInsert.finalize();
michael@0 520 this.stmtDelete.finalize();
michael@0 521 if (this.stmtUpdate)
michael@0 522 this.stmtUpdate.finalize();
michael@0 523 this.db.close();
michael@0 524
michael@0 525 this.stmtInsert = null;
michael@0 526 this.stmtDelete = null;
michael@0 527 this.stmtUpdate = null;
michael@0 528 this.db = null;
michael@0 529 }
michael@0 530 }
michael@0 531
michael@0 532 function do_get_cookie_file(profile)
michael@0 533 {
michael@0 534 let file = profile.clone();
michael@0 535 file.append("cookies.sqlite");
michael@0 536 return file;
michael@0 537 }
michael@0 538
michael@0 539 // Count the cookies from 'host' in a database. If 'host' is null, count all
michael@0 540 // cookies.
michael@0 541 function do_count_cookies_in_db(connection, host)
michael@0 542 {
michael@0 543 let select = null;
michael@0 544 if (host) {
michael@0 545 select = connection.createStatement(
michael@0 546 "SELECT COUNT(1) FROM moz_cookies WHERE host = :host");
michael@0 547 select.bindByName("host", host);
michael@0 548 } else {
michael@0 549 select = connection.createStatement(
michael@0 550 "SELECT COUNT(1) FROM moz_cookies");
michael@0 551 }
michael@0 552
michael@0 553 select.executeStep();
michael@0 554 let result = select.getInt32(0);
michael@0 555 select.reset();
michael@0 556 select.finalize();
michael@0 557 return result;
michael@0 558 }
michael@0 559
michael@0 560 // Execute 'stmt', ensuring that we reset it if it throws.
michael@0 561 function do_execute_stmt(stmt)
michael@0 562 {
michael@0 563 try {
michael@0 564 stmt.executeStep();
michael@0 565 stmt.reset();
michael@0 566 } catch (e) {
michael@0 567 stmt.reset();
michael@0 568 throw e;
michael@0 569 }
michael@0 570 }

mercurial