Skip to content

Commit

Permalink
Merge branch 'main' into extbuild
Browse files Browse the repository at this point in the history
  • Loading branch information
pmp-p authored Jul 31, 2024
2 parents 17ed9bd + ed66a04 commit 682ca7b
Show file tree
Hide file tree
Showing 77 changed files with 4,744 additions and 477 deletions.
1 change: 0 additions & 1 deletion cibuild.sh
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,6 @@ then
# TEMP FIX for SDK
SSL_INCDIR=$EMSDK/upstream/emscripten/cache/sysroot/include/openssl
[ -f $SSL_INCDIR/evp.h ] || ln -s $PREFIX/include/openssl $SSL_INCDIR

SKIP="\
[\
sslinfo bool_plperl hstore_plperl hstore_plpython jsonb_plperl jsonb_plpython\
Expand Down
33 changes: 31 additions & 2 deletions packages/benchmark/benchmarks-rtt.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,23 @@ const CONFIGURATIONS = new Map(
db: "pglite",
dataDir: "idb://benchmark-rtt",
},
{
label: "PGlite IDB<br> <i>relaxed durability</i>",
db: "pglite",
dataDir: "idb://benchmark-rtt-rd",
options: { relaxedDurability: true },
},
{
label: "PGlite OPFS AHP",
db: "pglite",
dataDir: "opfs-ahp://benchmark-rtt",
},
{
label: "PGlite OPFS AHP<br> <i>relaxed durability</i>",
db: "pglite",
dataDir: "opfs-ahp://benchmark-rtt-rd",
options: { relaxedDurability: true },
},
{
label: 'SQLite Memory',
db: 'wa-sqlite',
Expand All @@ -39,6 +56,14 @@ const CONFIGURATIONS = new Map(
vfsClass: 'OriginPrivateFileSystemVFS',
vfsArgs: []
},
{
label: 'SQLite OPFS AHP',
db: 'wa-sqlite',
isAsync: false,
vfsModule: './node_modules/wa-sqlite/src/examples/AccessHandlePoolVFS.js',
vfsClass: 'AccessHandlePoolVFS',
vfsArgs: ['/benchmark-rtt-sqlite-ahp']
},
].map((obj) => [obj.label, obj])
);

Expand Down Expand Up @@ -107,7 +132,11 @@ document.getElementById("start").addEventListener("click", async (event) => {
// Remove OPFS
const root = await navigator.storage.getDirectory();
for await (const handle of root.values()) {
await root.removeEntry(handle.name, { recursive: true });
try {
await root.removeEntry(handle.name, { recursive: true });
} catch (e) {
// ignore
}
}

const Comlink = await ComlinkReady;
Expand Down Expand Up @@ -170,6 +199,6 @@ document.getElementById("start").addEventListener("click", async (event) => {
function addEntry(parent, text) {
const tag = parent.parentElement.tagName === "TBODY" ? "td" : "th";
const child = document.createElement(tag);
child.textContent = text;
child.innerHTML = text;
parent.appendChild(child);
}
32 changes: 31 additions & 1 deletion packages/benchmark/benchmarks.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,24 @@ const CONFIGURATIONS = new Map(
label: "Emscripten IndexedDB FS",
dataDir: "idb://benchmark",
},
{
label: "Emscripten IndexedDB FS<br> <i>relaxed durability</i>",
dataDir: "idb://benchmark-rd",
options: { relaxedDurability: true },
},
{
label: "OPFS Access Handle Pool",
dataDir: "opfs-ahp://benchmark-ahp",
},
{
label: "OPFS Access Handle Pool<br> <i>relaxed durability</i>",
dataDir: "opfs-ahp://benchmark-ahp-rd",
options: { relaxedDurability: true },
},
// {
// label: "OPFS Worker",
// dataDir: "opfs-worker://benchmark-worker",
// },
].map((obj) => [obj.label, obj])
);

Expand Down Expand Up @@ -77,6 +95,16 @@ document.getElementById("start").addEventListener("click", async (event) => {
}
});

// Remove OPFS
const root = await navigator.storage.getDirectory();
for await (const handle of root.values()) {
try {
await root.removeEntry(handle.name, { recursive: true });
} catch (e) {
// ignore
}
}

const benchmarks = await benchmarksReady;
const Comlink = await ComlinkReady;
try {
Expand All @@ -101,6 +129,7 @@ document.getElementById("start").addEventListener("click", async (event) => {
const query = await workerProxy({
dataDir: config.dataDir,
label: config.label,
options: config.options,
});

await query(preamble);
Expand All @@ -123,6 +152,7 @@ document.getElementById("start").addEventListener("click", async (event) => {
document.getElementById("error").textContent = e.stack.includes(e.message)
? e.stack
: `${e.stack}\n${e.message}`;
throw e;
} finally {
// @ts-ignore
event.target.disabled = false;
Expand All @@ -132,6 +162,6 @@ document.getElementById("start").addEventListener("click", async (event) => {
function addEntry(parent, text) {
const tag = parent.parentElement.tagName === "TBODY" ? "td" : "th";
const child = document.createElement(tag);
child.textContent = text;
child.innerHTML = text;
parent.appendChild(child);
}
15 changes: 14 additions & 1 deletion packages/benchmark/demo-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,20 @@ import { PGlite } from "../pglite/dist/index.js";
* @returns {Promise<Function>}
*/
async function open(config) {
const pg = new PGlite(config.dataDir);
if (config.dataDir.startsWith("opfs-")) {
// delete the existing database
const root = await navigator.storage.getDirectory();
const dirName = config.dataDir.slice(config.dataDir.indexOf("://") + 3);
try {
const dir = await root.getDirectoryHandle(dirName, { create: false });
await dir.remove();
} catch (e) {
// ignore
}
}

console.log("Opening PGLite database:", JSON.stringify(config, null, 2));
const pg = new PGlite(config.dataDir, config.options);
await pg.waitReady;

// Create the query interface.
Expand Down
2 changes: 1 addition & 1 deletion packages/benchmark/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@
"tsx": "^4.7.1"
},
"dependencies": {
"wa-sqlite": "github:rhashimoto/wa-sqlite"
"wa-sqlite": "github:rhashimoto/wa-sqlite#v0.9.14"
}
}
9 changes: 4 additions & 5 deletions packages/benchmark/rtt-demo-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import * as SQLite from './node_modules/wa-sqlite/src/sqlite-api.js';
import { createTag } from "./node_modules/wa-sqlite/src/examples/tag.js";
import { PGlite } from "../pglite/dist/index.js";
import { PGlite } from "../pglite/dist/index.js?1";

const WA_SQLITE = './node_modules/wa-sqlite/dist/wa-sqlite.mjs';
const WA_SQLITE_ASYNC = './node_modules/wa-sqlite/dist/wa-sqlite-async.mjs';
Expand All @@ -15,18 +15,17 @@ const WA_SQLITE_ASYNC = './node_modules/wa-sqlite/dist/wa-sqlite-async.mjs';
);

async function open(config) {
console.log('Opening database:', config)
if (config.db === 'wa-sqlite') {
console.log('Opening SQLite database:', config)
console.log('Opening SQLite database:', JSON.stringify(config, null, 2))
return openSQLite(config);
} else if (config.db === 'pglite') {
console.log('Opening PGLite database:', config)
console.log('Opening PGLite database:', JSON.stringify(config, null, 2))
return openPGlite(config);
}
}

async function openPGlite(config) {
const pg = new PGlite(config.dataDir);
const pg = new PGlite(config.dataDir, config.options);
await pg.waitReady;

// Create the query interface.
Expand Down
25 changes: 23 additions & 2 deletions packages/pglite/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -318,12 +318,33 @@ The `.query<T>()` method can take a TypeScript type describing the expected shap

### Web Workers:

It's likely that you will want to run PGlite in a Web Worker so that it doesn't block the main thread. To aid in this we provide a `PGliteWorker` with the same API as the core `PGlite` but it runs Postgres in a dedicated Web Worker. To use, import from the `/worker` export:
It's likely that you will want to run PGlite in a Web Worker so that it doesn't block the main thread. To aid in this we provide a `PGliteWorker` with the same API as the core `PGlite` but it runs Postgres in a dedicated Web Worker.

First you need to create a js file for your worker instance, initiate PGlite with the worker extension, and start it:

```js
// my-pglite-worker.js
import { PGlite } from "@electric-sql/pglite";
import { worker } from "@electric-sql/pglite/worker";

worker({
async init() {
return new PGlite();
},
});
```

Then connect the `PGliteWorker` to your new worker process:

```js
import { PGliteWorker } from "@electric-sql/pglite/worker";

const pg = new PGliteWorker('idb://my-database');
const pg = new PGliteWorker(
new Worker(new URL("./my-pglite-worker.js", import.meta.url), {
type: "module",
})
);

await pg.exec(`
CREATE TABLE IF NOT EXISTS test (
id SERIAL PRIMARY KEY,
Expand Down
12 changes: 12 additions & 0 deletions packages/pglite/examples/opfs-worker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { PGlite } from "../dist/index.js";
import { worker } from "../dist/worker/index.js";

worker({
async init() {
const pg = new PGlite("opfs-ahp://my-test-db2");
// If you want run any specific setup code for the worker process, you can do it here.
return pg;
},
});

console.log("Worker process started");
49 changes: 49 additions & 0 deletions packages/pglite/examples/opfs.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<script type="module">
import { PGliteWorker } from "../dist/worker/index.js";

console.log("Starting...");
const start = performance.now();
const pg = new PGliteWorker(
new Worker(new URL("./opfs-worker.js", import.meta.url), {
type: "module",
})
);

console.log("Waiting for ready...");
await pg.waitReady;

console.log("Ready! Took", performance.now() - start, "ms");

console.log("Creating table...");
await pg.exec(`
CREATE TABLE IF NOT EXISTS test (
id SERIAL PRIMARY KEY,
name TEXT
);
`);

console.log("Inserting data...");
await pg.exec("INSERT INTO test (name) VALUES ('test');");

console.log("Selecting data...");
const res = await pg.exec(`
SELECT * FROM test;
`);

console.log(res);

// Transaction example:
console.log("Transaction example...");
await pg.transaction(async (tx) => {
await tx.exec("INSERT INTO test (name) VALUES ('test2');");
await tx.exec("INSERT INTO test (name) VALUES ('test3');");
});

console.log("Selecting data...");
const res2 = await pg.exec(`
SELECT * FROM test;
`);

console.log(res2);

</script>
17 changes: 17 additions & 0 deletions packages/pglite/examples/worker-process.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { PGlite } from "../dist/index.js";
import { worker } from "../dist/worker/index.js";
import { vector } from "../dist/vector/index.js";

worker({
async init() {
const pg = new PGlite({
extensions: {
vector,
},
});
// If you want run any specific setup code for the worker process, you can do it here.
return pg;
},
});

console.log("Worker process started");
Loading

0 comments on commit 682ca7b

Please sign in to comment.