diff --git a/test/parallel/test-sqlite-database-sync-dispose.js b/test/parallel/test-sqlite-database-sync-dispose.js index 67a1ab6757b848..7fe18c29f7d12c 100644 --- a/test/parallel/test-sqlite-database-sync-dispose.js +++ b/test/parallel/test-sqlite-database-sync-dispose.js @@ -30,4 +30,59 @@ suite('DatabaseSync.prototype[Symbol.dispose]()', () => { db.close(); }, /database is not open/); }); + + test('invalidates prepared statements', () => { + const db = new DatabaseSync(nextDb()); + db.exec(` + CREATE TABLE data(key INTEGER PRIMARY KEY, val INTEGER); + INSERT INTO data (key, val) VALUES (1, 2); + `); + + const select = db.prepare('SELECT * FROM data'); + const insert = db.prepare('INSERT INTO data (key, val) VALUES (?, ?)'); + const iterator = select.iterate(); + + db[Symbol.dispose](); + assert.strictEqual(db.isOpen, false); + + for (const method of ['prepare', 'exec']) { + assert.throws(() => { + db[method]('SELECT 1'); + }, { + code: 'ERR_INVALID_STATE', + message: /database is not open/, + }); + } + + assert.throws(() => { + select.get(); + }, { + code: 'ERR_INVALID_STATE', + message: /statement has been finalized/, + }); + assert.throws(() => { + select.all(); + }, { + code: 'ERR_INVALID_STATE', + message: /statement has been finalized/, + }); + assert.throws(() => { + select.iterate(); + }, { + code: 'ERR_INVALID_STATE', + message: /statement has been finalized/, + }); + assert.throws(() => { + insert.run(2, 4); + }, { + code: 'ERR_INVALID_STATE', + message: /statement has been finalized/, + }); + assert.throws(() => { + iterator.next(); + }, { + code: 'ERR_INVALID_STATE', + message: /statement has been finalized/, + }); + }); }); diff --git a/test/parallel/test-sqlite-database-sync.js b/test/parallel/test-sqlite-database-sync.js index d778f839098737..c0e17da5aa174d 100644 --- a/test/parallel/test-sqlite-database-sync.js +++ b/test/parallel/test-sqlite-database-sync.js @@ -343,6 +343,120 @@ suite('DatabaseSync.prototype.close()', () => { }); t.assert.strictEqual(db.isOpen, false); }); + + test('invalidates prepared statements', (t) => { + const db = new DatabaseSync(nextDb()); + db.exec(` + CREATE TABLE data(key INTEGER PRIMARY KEY, val INTEGER); + INSERT INTO data (key, val) VALUES (1, 2); + `); + + const select = db.prepare('SELECT * FROM data'); + const insert = db.prepare('INSERT INTO data (key, val) VALUES (?, ?)'); + const iterator = select.iterate(); + + t.assert.strictEqual(db.close(), undefined); + t.assert.strictEqual(db.isOpen, false); + + for (const method of ['prepare', 'exec']) { + t.assert.throws(() => { + db[method]('SELECT 1'); + }, { + code: 'ERR_INVALID_STATE', + message: /database is not open/, + }); + } + + t.assert.throws(() => { + select.get(); + }, { + code: 'ERR_INVALID_STATE', + message: /statement has been finalized/, + }); + t.assert.throws(() => { + select.all(); + }, { + code: 'ERR_INVALID_STATE', + message: /statement has been finalized/, + }); + t.assert.throws(() => { + select.iterate(); + }, { + code: 'ERR_INVALID_STATE', + message: /statement has been finalized/, + }); + t.assert.throws(() => { + insert.run(2, 4); + }, { + code: 'ERR_INVALID_STATE', + message: /statement has been finalized/, + }); + t.assert.throws(() => { + iterator.next(); + }, { + code: 'ERR_INVALID_STATE', + message: /statement has been finalized/, + }); + }); + + test('keeps prepared statements invalid after reopening', (t) => { + const db = new DatabaseSync(nextDb()); + t.after(() => { + if (db.isOpen) db.close(); + }); + + db.exec(` + CREATE TABLE data(key INTEGER PRIMARY KEY, val INTEGER); + INSERT INTO data (key, val) VALUES (1, 2); + `); + + const select = db.prepare('SELECT * FROM data'); + const insert = db.prepare('INSERT INTO data (key, val) VALUES (?, ?)'); + const iterator = select.iterate(); + + db.close(); + db.open(); + + t.assert.throws(() => { + select.get(); + }, { + code: 'ERR_INVALID_STATE', + message: /statement has been finalized/, + }); + t.assert.throws(() => { + select.all(); + }, { + code: 'ERR_INVALID_STATE', + message: /statement has been finalized/, + }); + t.assert.throws(() => { + select.iterate(); + }, { + code: 'ERR_INVALID_STATE', + message: /statement has been finalized/, + }); + t.assert.throws(() => { + insert.run(2, 4); + }, { + code: 'ERR_INVALID_STATE', + message: /statement has been finalized/, + }); + t.assert.throws(() => { + iterator.next(); + }, { + code: 'ERR_INVALID_STATE', + message: /statement has been finalized/, + }); + + t.assert.deepStrictEqual( + db.prepare('SELECT * FROM data').all(), + [{ __proto__: null, key: 1, val: 2 }], + ); + t.assert.strictEqual( + db.exec('INSERT INTO data (key, val) VALUES (2, 4)'), + undefined, + ); + }); }); suite('DatabaseSync.prototype.prepare()', () => {