Skip to content
Merged
Show file tree
Hide file tree
Changes from 61 commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
19ae59a
Initial pipelining POC.
rkistner May 13, 2024
e731747
Pipelining for async driver.
rkistner May 13, 2024
ef5fd85
Prettier; using keyword.
rkistner May 13, 2024
0ee0083
Add back higher-level implementation.
rkistner May 13, 2024
bcad97d
Refine bind behavior.
rkistner May 14, 2024
8774893
Refine stepping behavior.
rkistner May 14, 2024
b46e1a6
More tweaks to stepping logic.
rkistner May 14, 2024
a408173
Tweak dispose behavior.
rkistner May 14, 2024
68e6f12
Improve types; prototype for prepared query support.
rkistner May 15, 2024
07f9092
Tweak for execute.
rkistner May 15, 2024
016cfd0
Benchmarks
rkistner May 27, 2024
22da8f1
Add benchmarks.
rkistner Jun 6, 2024
ad896ae
Add node-sqlite3 benchmark.
rkistner Jun 6, 2024
26aa454
Add a pipeline implementation.
rkistner Jun 6, 2024
7401afd
Flatten commands.
rkistner Jun 7, 2024
5e9bf7f
Refactor driver api.
rkistner Jul 29, 2024
52552aa
Lots of improvements.
rkistner Jul 29, 2024
25c27d5
Tweaks.
rkistner Jul 29, 2024
5e917e4
Require transaction for pipeline.
rkistner Jul 29, 2024
12310a1
Test with mocha; add node-sqlite-driver.
rkistner Jul 29, 2024
84a45b5
Test with vitest or mocha
rkistner Jul 30, 2024
58fb6e6
Update tests.
rkistner Jul 30, 2024
d1be9b0
Fix error handling and more tests.
rkistner Jul 30, 2024
6218e00
Fixes for node:sqlite driver.
rkistner Jul 30, 2024
a55494a
Better skip.
rkistner Jul 30, 2024
dfb956f
Add node-sqlite-async-driver.
rkistner Jul 30, 2024
54ac796
Fix readonly transactions.
rkistner Jul 30, 2024
721ef62
Add JSON implementations.
rkistner Jul 30, 2024
6ded8b1
Cleanup.
rkistner Jul 30, 2024
1c8fe6f
Improve named parameter handling.
rkistner Jul 30, 2024
737aeea
Remove old bencharks.
rkistner Jul 31, 2024
2077f8d
corepack pnpm.
rkistner Jul 31, 2024
2c696e4
Add get and getOptional.
rkistner Jul 31, 2024
357619d
Experimental usingTransaction.
rkistner Jul 31, 2024
1fac050
Rename usingTransaction -> begin.
rkistner Aug 1, 2024
ab35018
Add explicit run() API.
rkistner Aug 1, 2024
9449fb1
Remove execute.
rkistner Aug 1, 2024
fcd0497
Big driver refactor.
rkistner Aug 1, 2024
fa08560
Use run() in impl.
rkistner Aug 1, 2024
91373e3
Fix benchmarks with new apis.
rkistner Aug 1, 2024
cace31b
Use db.begin() in benchmarks.
rkistner Aug 1, 2024
45e29e6
Remove todo.
rkistner Aug 1, 2024
7b105e0
Refactor driver workers.
rkistner Aug 15, 2024
74540dd
Restructure packages.
rkistner Aug 15, 2024
948cc33
Cleanup.
rkistner Aug 15, 2024
32a7767
Fix benchmarks.
rkistner Aug 15, 2024
a9b1e32
Cleanup.
rkistner Aug 15, 2024
93c1834
Use import.meta.resolve.
rkistner Aug 16, 2024
50cc7f2
Fixes and restructuring.
rkistner Aug 16, 2024
754077f
Use import.meta.url for vite compatibility.
rkistner Aug 16, 2024
f79ff7e
Refactoring and fixes.
rkistner Aug 16, 2024
dfc77f4
Refactor BetterSqliteDriver.
rkistner Aug 16, 2024
a2ebde5
Update benchmarks and fix concurrency issues.
rkistner Aug 16, 2024
4909e04
Rename packages.
rkistner Aug 17, 2024
023b520
Add test workflow.
rkistner Aug 17, 2024
0434fc4
Add readme.
rkistner Aug 17, 2024
d6fd5c7
Add extension support for better-sqlite3-driver.
rkistner Aug 19, 2024
02c4c5b
Fix driver options.
rkistner Aug 19, 2024
ebe8d1b
Add getLastChanges().
rkistner Aug 19, 2024
70ec950
Extract out ErrorStatement and WorkerDriverAdapter, simplifying the
rkistner Aug 27, 2024
ced6f01
Cleanup.
rkistner Aug 27, 2024
44de614
Add design notes.
rkistner Aug 27, 2024
c34fd11
Cleanup.
rkistner Aug 27, 2024
ceccd12
More defaults for readonly: true/false.
rkistner Aug 27, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added .env
Empty file.
3 changes: 3 additions & 0 deletions .envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
layout node
use node
[ -f .env ] && dotenv
31 changes: 31 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Ensures packages test correctly
name: Test Packages

on:
push:

jobs:
test:
name: Test Packages
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false

- uses: pnpm/action-setup@v4
name: Install pnpm

- name: Setup NodeJS
uses: actions/setup-node@v4
with:
node-version-file: '.node-version'

- name: Install dependencies
run: pnpm install

- name: Build
run: pnpm build

- name: Test
run: pnpm test
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
node_modules/
test-db/
*.db
lib/
tsconfig.tsbuildinfo
benchmarks/db
1 change: 1 addition & 0 deletions .node-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v22.5.1
3 changes: 3 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules/
lib/
pnpm-lock.yaml
6 changes: 6 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"trailingComma": "none",
"tabWidth": 2,
"semi": true,
"singleQuote": true
}
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# sqlite-js

Universal SQLite APIs for JavaScript.

## @sqlite-js/driver

This is a universal driver API and utilities for implementing drivers.

The APIs here are low-level, and should not be used directly in most use cases.

### @sqlite-js/driver/node

This is a driver implementation for NodeJS based on the experimental `node:sqlite` package.

## @sqlite-js/better-sqlite3-driver

This is a driver implementation for NodeJS implementation based `better-sqlite3`.

## @sqlite-js/api

This contains a higher-level API, including transaction support.
21 changes: 21 additions & 0 deletions benchmarks/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "benchmarks",
"type": "module",
"scripts": {
"build": "tsc -b",
"start": "NODE_OPTIONS=\"--experimental-sqlite --disable-warning=ExperimentalWarning\" node lib/index.js"
},
"dependencies": {
"better-sqlite3": "^11.0.0",
"prando": "^6.0.1",
"sqlite": "^5.1.1",
"sqlite3": "^5.1.7",
"@sqlite-js/driver": "workspace:^",
"@sqlite-js/better-sqlite3-driver": "workspace:^",
"@sqlite-js/api": "workspace:^"
},
"devDependencies": {
"@types/node": "^20.14.2",
"typescript": "^5.4.5"
}
}
108 changes: 108 additions & 0 deletions benchmarks/src/Benchmark.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import { BenchmarkResults } from './BenchmarkResults.js';

export abstract class Benchmark {
abstract name: string;

async runAll(): Promise<BenchmarkResults> {
let results = new BenchmarkResults(this.name);
let droppedFrames = 0;
let last = performance.now();
var timer = setInterval(() => {
const now = performance.now();
const diff = now - last;
last = now;
if (diff >= 16) {
droppedFrames += Math.floor(diff / 16);
}
}, 1);

await this.setUp();

await results.record('Test 1: 1000 INSERTs', this.test1.bind(this));
await results.record(
'Test 2: 25000 INSERTs in a transaction',
this.test2.bind(this)
);
await results.record(
'Test 3: 25000 INSERTs into an indexed table',
this.test3.bind(this)
);
await results.record(
'Test 4: 100 SELECTs without an index',
this.test4.bind(this)
);
await results.record(
'Test 5: 100 SELECTs on a string comparison',
this.test5.bind(this)
);
await results.record(
'Test 7: 5000 SELECTs with an index',
this.test7.bind(this)
);
await results.record(
'Test 8: 1000 UPDATEs without an index',
this.test8.bind(this)
);
await results.record(
'Test 9: 25000 UPDATEs with an index',
this.test9.bind(this)
);
await results.record(
'Test 10: 25000 text UPDATEs with an index',
this.test10.bind(this)
);
await results.record(
'Test 11: INSERTs from a SELECT',
this.test11.bind(this)
);
await results.record(
'Test 12: DELETE without an index',
this.test12.bind(this)
);
await results.record(
'Test 13: DELETE with an index',
this.test13.bind(this)
);
await results.record(
'Test 14: A big INSERT after a big DELETE',
this.test14.bind(this)
);
await results.record(
'Test 15: A big DELETE followed by many small INSERTs',
this.test15.bind(this)
);
await results.record('Test 16: Clear table', this.test16.bind(this));

await this.tearDown();

clearInterval(timer);

const diff = performance.now() - last;
if (diff >= 16) {
droppedFrames += Math.floor(diff / 16);
}

console.log(`Dropped frames: ${droppedFrames} (diff ${diff})`);
return results;
}

abstract setUp(): Promise<void>;

abstract test1(): Promise<void>;
abstract test2(): Promise<void>;
abstract test3(): Promise<void>;
abstract test4(): Promise<void>;
abstract test5(): Promise<void>;
abstract test7(): Promise<void>;
abstract test8(): Promise<void>;
abstract test9(): Promise<void>;
abstract test10(): Promise<void>;
abstract test11(): Promise<void>;
abstract test12(): Promise<void>;
abstract test13(): Promise<void>;
abstract test14(): Promise<void>;
abstract test15(): Promise<void>;
abstract test16(): Promise<void>;

abstract tearDown(): Promise<void>;
}
43 changes: 43 additions & 0 deletions benchmarks/src/BenchmarkResults.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
export class BenchmarkResults {
suite: string;

results: BenchmarkResult[] = [];

constructor(suite: string) {
this.suite = suite;
}

async record(name: string, callback: () => Promise<void>) {
const start = performance.now();
await callback();
const end = performance.now();
const elapsed = end - start;
this.results.push(new BenchmarkResult(name, elapsed));
console.log(`${name} :: ${Math.round(elapsed)}ms`);
// yield the event loop
await new Promise((resolve) => setTimeout(resolve, 0));
}

toString() {
return this.results.map((r) => r.toString()).join('\n');
}

toCsv() {
return this.results.map((r) => r.toCsv()).join('\n');
}
}

export class BenchmarkResult {
constructor(
public test: string,
public duration: number
) {}

toString() {
return `${this.test}: ${this.duration / 1000.0}s`;
}

toCsv() {
return `${this.test},${this.duration}`;
}
}
Loading