Skip to content

Commit

Permalink
feat(schema-engine-wasm): stable skeleton + playground (#5111)
Browse files Browse the repository at this point in the history
* feat(schema-engine-wasm): created wasm-compatible schema-engine-wasm skeleton

* chore(schema-engine-wasm): added "make build-se-wasm" command

* fix(schema-engine-wasm): replace "SchemaEngineParams" class instance with JS object via tsify. Fix build.sh script

* feat(schema-engine-wasm): implement playground skeleton

* fix(schema-engine-wasm): clippy

* chore: update Cargo.lock

* chore: delete query-engine/driver-adapters/executor/db.sqlite

---------

Co-authored-by: jkomyno <[email protected]>
  • Loading branch information
jkomyno and jkomyno authored Jan 13, 2025
1 parent 8d21d25 commit 814e8ba
Show file tree
Hide file tree
Showing 16 changed files with 482 additions and 3 deletions.
17 changes: 17 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ members = [
"schema-engine/connectors/*",
"schema-engine/datamodel-renderer",
"schema-engine/json-rpc-api-build",
"schema-engine/mongodb-schema-describer",
"schema-engine/sql-migration-tests",
"schema-engine/sql-introspection-tests",
"schema-engine/mongodb-schema-describer",
"schema-engine/schema-engine-wasm",
"schema-engine/sql-schema-describer",
"query-engine/connectors/*",
"query-engine/connector-test-kit-rs/qe-setup",
Expand Down
10 changes: 9 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ clean-qe-wasm:
@echo "Cleaning query-engine/query-engine-wasm/pkg" && \
cd query-engine/query-engine-wasm/pkg && find . ! -name '.' ! -name '..' ! -name 'README.md' -exec rm -rf {} +

clean-se-wasm:
@echo "Cleaning schema-engine/schema-engine-wasm/pkg" && \
cd schema-engine/schema-engine-wasm/pkg && find . ! -name '.' ! -name '..' ! -name 'README.md' -exec rm -rf {} +

clean-cargo:
@echo "Cleaning cargo" && \
cargo clean
Expand Down Expand Up @@ -71,6 +75,10 @@ integrate-qe-wasm:
cd query-engine/query-engine-wasm && \
./build.sh $(QE_WASM_VERSION) ../prisma/packages/client/node_modules/@prisma/query-engine-wasm

build-se-wasm:
cd schema-engine/schema-engine-wasm && \
./build.sh $(QE_WASM_VERSION) schema-engine/schema-engine-wasm/pkg

build-schema-wasm:
@printf '%s\n' "🛠️ Building the Rust crate"
cargo build --profile $(PROFILE) --target=wasm32-unknown-unknown -p prisma-schema-build
Expand All @@ -85,7 +93,7 @@ build-schema-wasm:
pedantic:
RUSTFLAGS="-D warnings" cargo fmt -- --check
RUSTFLAGS="-D warnings" cargo clippy --all-features --all-targets
RUSTFLAGS="-D warnings" cargo clippy --all-features --all-targets -p query-engine-wasm -p prisma-schema-build --target wasm32-unknown-unknown
RUSTFLAGS="-D warnings" cargo clippy --all-features --all-targets -p query-engine-wasm -p schema-engine-wasm -p prisma-schema-build --target wasm32-unknown-unknown

release:
cargo build --release
Expand Down
1 change: 1 addition & 0 deletions query-engine/driver-adapters/executor/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
node_modules
pnpm-debug.log
dist/
./db.sqlite
6 changes: 5 additions & 1 deletion query-engine/driver-adapters/executor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,17 @@
"scripts": {
"build": "tsup ./src/testd-qe.ts ./src/bench.ts --format esm --dts",
"test:qe": "node --import tsx ./src/testd-qe.ts",
"demo:se": "node --import tsx ./src/demo-se.ts",
"clean:d1": "rm -rf ../../connector-test-kit-rs/query-engine-tests/.wrangler"
},
"tsup": {
"external": [
"../../../query-engine-wasm/pkg/postgresql/query_engine_bg.js",
"../../../query-engine-wasm/pkg/mysql/query_engine_bg.js",
"../../../query-engine-wasm/pkg/sqlite/query_engine_bg.js"
"../../../query-engine-wasm/pkg/sqlite/query_engine_bg.js",
"../../../schema-engine-wasm/pkg/postgresql/schema_engine_bg.js",
"../../../schema-engine-wasm/pkg/mysql/schema_engine_bg.js",
"../../../schema-engine-wasm/pkg/sqlite/schema_engine_bg.js"
]
},
"keywords": [],
Expand Down
93 changes: 93 additions & 0 deletions query-engine/driver-adapters/executor/src/demo-se.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import * as S from '@effect/schema/Schema'
import { bindAdapter } from '@prisma/driver-adapter-utils'

import type { DriverAdaptersManager } from './driver-adapters-manager'
import { Env } from './types'
import * as se from './schema-engine'
import { err } from './utils'
import { setupDriverAdaptersManager } from './setup'

/**
* Example run: `DRIVER_ADAPTER="libsql" pnpm demo:se`
*/
async function main(): Promise<void> {
const env = S.decodeUnknownSync(Env)(process.env)
console.log('[env]', env)

/**
* Static input for demo purposes.
*/

const url = 'file:./db.sqlite'

const schema = /* prisma */ `
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "sqlite"
url = "file:./db.sqlite"
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
content String
author User @relation(fields: [authorId], references: [id])
authorId Int
}
`

const driverAdapterManager = await setupDriverAdaptersManager(
env,
)

const { engine, adapter } = await initSE({
env,
driverAdapterManager,
url,
schema,
})

console.log('[adapter]', adapter)

// TODO: use `engine`.
}

type InitQueryEngineParams = {
env: Env
driverAdapterManager: DriverAdaptersManager
url: string
schema: string
}

async function initSE({
env,
driverAdapterManager,
url,
schema,
}: InitQueryEngineParams) {
const adapter = await driverAdapterManager.connect({ url })
const errorCapturingAdapter = bindAdapter(adapter)
const engineInstance = await se.initSchemaEngine(
{
datamodel: schema,
},
adapter,
)

return {
engine: engineInstance,
adapter: errorCapturingAdapter,
}
}

main().catch(err)
30 changes: 30 additions & 0 deletions query-engine/driver-adapters/executor/src/schema-engine-wasm.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import * as wasmPostgres from '../../../../schema-engine/schema-engine-wasm/pkg/postgresql/schema_engine_bg.js'
import * as wasmMysql from '../../../../schema-engine/schema-engine-wasm/pkg/mysql/schema_engine_bg.js'
import * as wasmSqlite from '../../../../schema-engine/schema-engine-wasm/pkg/sqlite/schema_engine_bg.js'
import fs from 'node:fs/promises'
import path from 'node:path'
import { __dirname } from './utils.js'

const wasm = {
postgres: wasmPostgres,
mysql: wasmMysql,
sqlite: wasmSqlite
}

type EngineName = keyof typeof wasm

const initializedModules = new Set<EngineName>()

export async function getSchemaEngineForProvider(provider: EngineName) {
const engine = wasm[provider]
if (!initializedModules.has(provider)) {
const subDir = provider === 'postgres' ? 'postgresql' : provider
const bytes = await fs.readFile(path.resolve(__dirname, '..', '..', '..', '..', 'schema-engine', 'schema-engine-wasm', 'pkg', subDir, 'schema_engine_bg.wasm'))
const module = new WebAssembly.Module(bytes)
const instance = new WebAssembly.Instance(module, { './schema_engine_bg.js': engine })
engine.__wbg_set_wasm(instance.exports)
initializedModules.add(provider)
}

return engine.SchemaEngine
}
25 changes: 25 additions & 0 deletions query-engine/driver-adapters/executor/src/schema-engine.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type { DriverAdapter } from '@prisma/driver-adapter-utils'
import { __dirname } from './utils'

export type SchemaEngineParams = {
// TODO: support multiple datamodels
datamodel: string
}

export interface SchemaEngine {
new(params: SchemaEngineParams, adapter: DriverAdapter): SchemaEngine
debugPanic(): Promise<void>
version(): Promise<string | undefined>
reset(): Promise<void>
}

export type QueryLogCallback = (log: string) => void

export async function initSchemaEngine(
params: SchemaEngineParams,
adapter: DriverAdapter,
): Promise<SchemaEngine> {
const { getSchemaEngineForProvider: getEngineForProvider } = await import('./schema-engine-wasm')
const WasmSchemaEngine = (await getEngineForProvider(adapter.provider)) as SchemaEngine
return new WasmSchemaEngine(params, adapter)
}
7 changes: 7 additions & 0 deletions schema-engine/schema-engine-wasm/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/target
**/*.rs.bk
Cargo.lock
bin/
pkg/
wasm-pack.log
node_modules/
36 changes: 36 additions & 0 deletions schema-engine/schema-engine-wasm/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
[package]
name = "schema-engine-wasm"
version = "0.1.0"
edition = "2021"

[lib]
doc = false
crate-type = ["cdylib"]
name = "schema_engine_wasm"

[features]
sqlite = ["driver-adapters/sqlite", "psl/sqlite"]
postgresql = ["driver-adapters/postgresql", "psl/postgresql"]
mysql = ["driver-adapters/mysql", "psl/mysql"]

[dependencies]
psl.workspace = true
quaint.workspace = true
tracing.workspace = true

js-sys.workspace = true
serde.workspace = true
tsify.workspace = true
wasm-bindgen.workspace = true
wasm-bindgen-futures.workspace = true
wasm-rs-dbg.workspace = true
driver-adapters = { path = "../../query-engine/driver-adapters" }

[build-dependencies]
build-utils.path = "../../libs/build-utils"

[package.metadata.wasm-pack.profile.release]
wasm-opt = false # use wasm-opt explicitly in `./build.sh`

[package.metadata.wasm-pack.profile.profiling]
wasm-opt = false # use wasm-opt explicitly in `./build.sh`
3 changes: 3 additions & 0 deletions schema-engine/schema-engine-wasm/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
build_utils::store_git_commit_hash_in_env();
}
Loading

0 comments on commit 814e8ba

Please sign in to comment.