Skip to content

Commit

Permalink
Fix close and add support for new stage 3 ECMAScript explicit resourc…
Browse files Browse the repository at this point in the history
…e management (#133)

* Fix db.close #132

* Add support for Stage 3 ECMAScript Explicit Resource Management #101
  • Loading branch information
samwillis authored Aug 1, 2024
1 parent 971eee3 commit a3e1e16
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 13 deletions.
37 changes: 25 additions & 12 deletions packages/pglite/src/pglite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import {
NotificationResponseMessage,
} from "pg-protocol/dist/messages.js";

export class PGlite implements PGliteInterface {
export class PGlite implements PGliteInterface, AsyncDisposable {
fs?: Filesystem;
protected mod?: PostgresMod;

Expand Down Expand Up @@ -344,22 +344,35 @@ export class PGlite implements PGliteInterface {
}

// Close the database
await new Promise<void>(async (resolve, reject) => {
try {
await this.execProtocol(serialize.end());
} catch (e) {
const err = e as { name: string; status: number };
if (err.name === "ExitStatus" && err.status === 0) {
resolve();
} else {
reject(e);
}
try {
await this.execProtocol(serialize.end());
} catch (e) {
const err = e as { name: string; status: number };
if (err.name === "ExitStatus" && err.status === 0) {
// Database closed successfully
// An earlier build of PGlite would throw an error here when closing
// leaving this here for now. I believe it was a bug in Emscripten.
} else {
throw e;
}
});
}

// Close the filesystem
await this.fs!.close();

this.#closed = true;
this.#closing = false;
}

/**
* Close the database when the object exits scope
* Stage 3 ECMAScript Explicit Resource Management
* https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-2.html#using-declarations-and-explicit-resource-management
*/
async [Symbol.asyncDispose]() {
await this.close();
}

/**
* Execute a single SQL statement
* This uses the "Extended Query" postgres wire protocol message.
Expand Down
11 changes: 10 additions & 1 deletion packages/pglite/src/worker/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export type PGliteWorkerOptions = PGliteOptions & {
id?: string;
};

export class PGliteWorker implements PGliteInterface {
export class PGliteWorker implements PGliteInterface, AsyncDisposable {
#initPromise: Promise<void>;
#debug: DebugLevel = 0;

Expand Down Expand Up @@ -300,6 +300,15 @@ export class PGliteWorker implements PGliteInterface {
this.#workerProcess.terminate();
}

/**
* Close the database when the object exits scope
* Stage 3 ECMAScript Explicit Resource Management
* https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-2.html#using-declarations-and-explicit-resource-management
*/
async [Symbol.asyncDispose]() {
await this.close();
}

/**
* Execute a single SQL statement
* This uses the "Extended Query" postgres wire protocol message.
Expand Down
20 changes: 20 additions & 0 deletions packages/pglite/tests/basic.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -371,3 +371,23 @@ test("basic copy to/from blob", async (t) => {
affectedRows: 0,
});
});

test("basic close", async (t) => {
const db = new PGlite();
await db.query(`
CREATE TABLE IF NOT EXISTS test (
id SERIAL PRIMARY KEY,
name TEXT
);
`);
await db.query("INSERT INTO test (name) VALUES ('test');");
await db.close();
await t.throwsAsync(
async () => {
await db.query("SELECT * FROM test;");
},
{
message: "PGlite is closed",
}
);
});
13 changes: 13 additions & 0 deletions packages/pglite/tests/targets/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,19 @@ export function tests(env, dbFilename, target) {
});
});

test.serial(`targets ${target} close`, async (t) => {
const err = await evaluate(async () => {
try {
await db.close();
} catch (e) {
console.error(e);
return e.message;
}
return null;
});
t.is(err, null);
});

if (dbFilename === "memory://") {
// Skip the rest of the tests for memory:// as it's not persisted
return;
Expand Down

1 comment on commit a3e1e16

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.