Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
24 changes: 0 additions & 24 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,7 @@ permissions:
checks: write

jobs:
build-wasm:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v7

- name: Prepare the toolchain
working-directory: wasm-lib
run: ./prepare-ci.sh

- name: Build SQLite
working-directory: wasm-lib
run: ./build.sh

- uses: actions/upload-artifact@v7
with:
name: libsqlite3-wasm
path: wasm-lib/libsqlite3.wasm

build:
needs: build-wasm
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
Expand All @@ -55,10 +35,6 @@ jobs:
java-version: '${{ matrix.java-version }}'
cache: maven

- uses: actions/download-artifact@v8
with:
name: libsqlite3-wasm

- name: Test sqlite-jdbc-wasm
run: mvn -B clean install

Expand Down
58 changes: 58 additions & 0 deletions .github/workflows/wasm-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: Publish Wasm

on:
workflow_dispatch:
inputs:
version:
description: 'SQLite version to publish, must be semver (e.g. 3.53.4)'
required: true
sign:
description: 'Sign the artifact with cosign'
required: false
type: boolean
default: true

permissions:
contents: read
packages: write
id-token: write

jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7

- name: Prepare the toolchain
working-directory: wasm-lib
run: ./prepare-ci.sh

- name: Build SQLite
working-directory: wasm-lib
run: ./build.sh

- name: Install ORAS
uses: oras-project/setup-oras@v1
with:
version: '1.2.2'

- name: Install cosign
if: ${{ inputs.sign }}
uses: sigstore/cosign-installer@v3
with:
cosign-release: 'v3.1.2'

- name: Login to GHCR
run: echo "${{ secrets.GITHUB_TOKEN }}" | oras login ghcr.io -u ${{ github.actor }} --password-stdin

- name: Push wasm artifact
working-directory: wasm-lib
run: |
oras push \
"ghcr.io/roastedroot/sqlite4j-wasm:${{ inputs.version }}" \
libsqlite3.wasm:application/wasm

- name: Sign with cosign
if: ${{ inputs.sign }}
run: |
cosign sign --yes "ghcr.io/roastedroot/sqlite4j-wasm:${{ inputs.version }}"
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,35 @@ Among the main reasons:
There are a few steps to achieve the result:

- compile SQLite to [WebAssembly](https://webassembly.org/)
- publish the resulting `.wasm` to an OCI registry, and fetch it at build time with [inlay](https://github.com/roastedroot/inlay)
- translate the SQLite payload to pure Java bytecode using [Endive Compiler](https://endive.run/docs/usage/build-time-compiler)
- run SQLite similarly to how it's done using JNI in the original JDBC dirver, but all in pure Java
- ship an extremely small and self contained `jar` that can run wherever the JVM can go!

### The SQLite Wasm artifact

The `.wasm` module is not committed to this repository. It is built by
[`wasm-lib/build.sh`](wasm-lib/build.sh), published to
`ghcr.io/roastedroot/sqlite4j-wasm` by the
[Publish Wasm](.github/workflows/wasm-publish.yml) workflow, and pulled during
`generate-sources` by `inlay:fetch`. The exact artifact is pinned by digest in
[`wkg.lock`](wkg.lock), so ordinary builds need no C toolchain and no network beyond
the registry.

To move to a new SQLite release: run the *Publish Wasm* workflow with the new version,
bump `<sqlite.wasm.version>` in [`pom.xml`](pom.xml), then refresh the lock with

```sh
mvn io.roastedroot:inlay-maven-plugin:fetch -Dinlay.update
```

When iterating on the wasm locally, build it with `wasm-lib/build.sh` and point the
build at it directly:

```sh
mvn install -Dinlay.skip -Dsqlite.wasm.file=$PWD/wasm-lib/libsqlite3.wasm
```

## Design Decisions

You can mostly expect to have a behavior equal to the original [xerial/sqlite-jdbc](https://github.com/xerial/sqlite-jdbc/), there are, although, some notable differences due to the different nature of WASM.
Expand Down
27 changes: 26 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
<junit.version>5.14.4</junit.version>
<surefire.version>3.5.6</surefire.version>
<endive.version>1.0.1</endive.version>
<inlay.version>0.0.3</inlay.version>
<sqlite.wasm.version>3.53.4</sqlite.wasm.version>
<sqlite.wasm.file>${project.build.directory}/wasm/libsqlite3.wasm</sqlite.wasm.file>
</properties>

<licenses>
Expand Down Expand Up @@ -150,6 +153,28 @@
</executions>
</plugin>

<plugin>
<groupId>io.roastedroot</groupId>
<artifactId>inlay-maven-plugin</artifactId>
<version>${inlay.version}</version>
<executions>
<execution>
<id>fetch-sqlite-wasm</id>
<goals>
<goal>fetch</goal>
</goals>
<configuration>
<modules>
<module>
<imageRef>ghcr.io/roastedroot/sqlite4j-wasm:${sqlite.wasm.version}</imageRef>
<outputFile>${sqlite.wasm.file}</outputFile>
</module>
</modules>
</configuration>
</execution>
</executions>
</plugin>

<plugin>
<groupId>run.endive</groupId>
<artifactId>endive-compiler-maven-plugin</artifactId>
Expand All @@ -162,7 +187,7 @@
</goals>
<configuration>
<name>io.roastedroot.sqlite4j.SQLiteModule</name>
<wasmFile>${project.basedir}/wasm-lib/libsqlite3.wasm</wasmFile>
<wasmFile>${sqlite.wasm.file}</wasmFile>
</configuration>
</execution>
</executions>
Expand Down
2 changes: 2 additions & 0 deletions wasm-lib/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ binaryen
sqlite-amalgamation
*.zip
*.tar.gz
libsqlite3.wasm
libsqlite3-opt.wasm
10 changes: 5 additions & 5 deletions wasm-lib/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
# mv wasi-sdk-25.0-x86_64-linux wasi-sdk
# rm wasi-sdk-25.0-x86_64-linux.tar.gz

# Download the latest SQLite amalgamation 3.48.0 as of today
# Download the latest SQLite amalgamation 3.53.4 as of today
# rm -rf sqlite-amalgamation
# wget https://www.sqlite.org/2026/sqlite-amalgamation-3530300.zip
# unzip sqlite-amalgamation-3530300.zip
# mv sqlite-amalgamation-3530300 sqlite-amalgamation
# rm sqlite-amalgamation-3530300.zip
# wget https://www.sqlite.org/2026/sqlite-amalgamation-3530400.zip
# unzip sqlite-amalgamation-3530400.zip
# mv sqlite-amalgamation-3530400 sqlite-amalgamation
# rm sqlite-amalgamation-3530400.zip

# Download and install Binaryen for optimizations
# rm -rf binaryen
Expand Down
Binary file removed wasm-lib/libsqlite3.wasm
Binary file not shown.
8 changes: 4 additions & 4 deletions wasm-lib/prepare-ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ mv wasi-sdk-25.0-x86_64-linux wasi-sdk
rm wasi-sdk-25.0-x86_64-linux.tar.gz

rm -rf sqlite-amalgamation
wget https://www.sqlite.org/2026/sqlite-amalgamation-3530300.zip
unzip sqlite-amalgamation-3530300.zip
mv sqlite-amalgamation-3530300 sqlite-amalgamation
rm sqlite-amalgamation-3530300.zip
wget https://www.sqlite.org/2026/sqlite-amalgamation-3530400.zip
unzip sqlite-amalgamation-3530400.zip
mv sqlite-amalgamation-3530400 sqlite-amalgamation
rm sqlite-amalgamation-3530400.zip

rm -rf binaryen
wget https://github.com/WebAssembly/binaryen/releases/download/version_121/binaryen-version_121-x86_64-linux.tar.gz
Expand Down
12 changes: 12 additions & 0 deletions wkg.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# This file is automatically generated.
# It is not intended for manual editing.
version = 1

[[packages]]
name = "roastedroot:sqlite4j-wasm"
registry = "ghcr.io"

[[packages.versions]]
requirement = "=3.53.4"
version = "3.53.4"
digest = "sha256:5747c92d3054f6a29802ba2a06b198b9f76dfcfe1d3201ad64729a3567b47e71"
Loading