diff --git a/query-engine/driver-adapters/executor/.gitignore b/query-engine/driver-adapters/executor/.gitignore index 37b61ff565c..ea7cd1b095b 100644 --- a/query-engine/driver-adapters/executor/.gitignore +++ b/query-engine/driver-adapters/executor/.gitignore @@ -1,3 +1,4 @@ node_modules pnpm-debug.log dist/ +./db.sqlite diff --git a/query-engine/driver-adapters/executor/db.sqlite b/query-engine/driver-adapters/executor/db.sqlite new file mode 100644 index 00000000000..e69de29bb2d diff --git a/query-engine/driver-adapters/executor/package.json b/query-engine/driver-adapters/executor/package.json index 016a5f0a6a5..185797bfea2 100644 --- a/query-engine/driver-adapters/executor/package.json +++ b/query-engine/driver-adapters/executor/package.json @@ -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": [], diff --git a/query-engine/driver-adapters/executor/src/demo-se.ts b/query-engine/driver-adapters/executor/src/demo-se.ts new file mode 100644 index 00000000000..35868031b4e --- /dev/null +++ b/query-engine/driver-adapters/executor/src/demo-se.ts @@ -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 { + 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) diff --git a/query-engine/driver-adapters/executor/src/schema-engine-wasm.ts b/query-engine/driver-adapters/executor/src/schema-engine-wasm.ts new file mode 100644 index 00000000000..d589ce26bd6 --- /dev/null +++ b/query-engine/driver-adapters/executor/src/schema-engine-wasm.ts @@ -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() + +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 +} diff --git a/query-engine/driver-adapters/executor/src/schema-engine.ts b/query-engine/driver-adapters/executor/src/schema-engine.ts new file mode 100644 index 00000000000..f3881647b65 --- /dev/null +++ b/query-engine/driver-adapters/executor/src/schema-engine.ts @@ -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 + version(): Promise + reset(): Promise +} + +export type QueryLogCallback = (log: string) => void + +export async function initSchemaEngine( + params: SchemaEngineParams, + adapter: DriverAdapter, +): Promise { + const { getSchemaEngineForProvider: getEngineForProvider } = await import('./schema-engine-wasm') + const WasmSchemaEngine = (await getEngineForProvider(adapter.provider)) as SchemaEngine + return new WasmSchemaEngine(params, adapter) +}