Skip to content

Commit

Permalink
chore: get rid of adapter object, pass connection info and add CI
Browse files Browse the repository at this point in the history
  • Loading branch information
jacek-prisma committed Jan 16, 2025
1 parent cf4ff41 commit ca3bd67
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 45 deletions.
65 changes: 65 additions & 0 deletions .github/workflows/publish-query-compiler-wasm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: Build and publish @prisma/query-compiler-wasm
run-name: npm - release @prisma/query-compiler-wasm@${{ github.event.inputs.packageVersion }} from ${{ github.event.inputs.enginesHash }} on ${{ github.event.inputs.npmDistTag }}

concurrency: publish-query-compiler-wasm

on:
# usually triggered via GH Actions Workflow in prisma/engines-wrapper repo
workflow_dispatch:
inputs:
packageVersion:
required: true
description: "New @prisma/query-compiler-wasm package version"
enginesHash:
required: true
description: "query-compiler commit to build"
npmDistTag:
required: true
default: "latest"
description: "npm dist-tag (e.g. latest or integration)"

jobs:
build:
name: Build and publish @prisma/query-compiler-wasm
runs-on: ubuntu-latest
steps:
- name: Print input
run: echo "${{ toJson(github.event.inputs) }}"

- uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.enginesHash }}

- uses: ./.github/workflows/include/rust-wasm-setup

- name: Build @prisma/query-compiler-wasm
run: make build-qc-wasm
env:
QE_WASM_VERSION: ${{ github.event.inputs.packageVersion }}

- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: "20.x"

- name: Set up NPM token for publishing
run: echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > ~/.npmrc

- name: Publish @prisma/query-compiler-wasm
run: npm publish --access public --tag ${{ github.event.inputs.npmDistTag }}
working-directory: query-compiler/query-compiler-wasm/pkg

#
# Failure handlers
#
- name: Set current job url in SLACK_FOOTER env var
if: ${{ failure() }}
run: echo "SLACK_FOOTER=<$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID|Click here to go to the job logs>" >> $GITHUB_ENV
- name: Slack Notification on Failure
if: ${{ failure() }}
uses: rtCamp/[email protected]
env:
SLACK_TITLE: "Building and publishing @prisma/query-compiler-wasm failed :x:"
SLACK_COLOR: "#FF0000"
SLACK_CHANNEL: feed-prisma-query-compiler-wasm-publish-failures
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_WASM_FAILING }}
9 changes: 4 additions & 5 deletions Cargo.lock

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

11 changes: 5 additions & 6 deletions query-compiler/query-compiler-wasm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,6 @@ doc = false
crate-type = ["cdylib"]
name = "query_compiler_wasm"

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

[dependencies]
psl.workspace = true
quaint.workspace = true
Expand All @@ -23,7 +18,6 @@ serde.workspace = true
serde_json.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" }
query-core = { path = "../../query-engine/core" }
Expand All @@ -34,6 +28,11 @@ request-handlers = { path = "../../query-engine/request-handlers", default-featu
[build-dependencies]
build-utils.path = "../../libs/build-utils"

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

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

Expand Down
40 changes: 21 additions & 19 deletions query-compiler/query-compiler-wasm/src/wasm/compiler.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#![allow(dead_code)]
#![allow(unused_variables)]

use driver_adapters::JsObject;
use driver_adapters::{AdapterFlavour, JsConnectionInfo};
use psl::ConnectorRegistry;
use quaint::connector::{ConnectionInfo, ExternalConnector};
use quaint::connector::ConnectionInfo;
use query_core::protocol::EngineProtocol;
use request_handlers::RequestBody;
use serde::Deserialize;
Expand Down Expand Up @@ -45,54 +45,56 @@ fn register_panic_hook() {
});
}

/// The main query engine used by JS
#[wasm_bindgen]
pub struct QueryCompiler {
schema: Arc<schema::QuerySchema>,
adapter: Arc<dyn ExternalConnector>,
protocol: EngineProtocol,
}

#[derive(Deserialize, Tsify)]
#[serde(rename_all = "camelCase")]
#[tsify(from_wasm_abi)]
pub struct QueryCompilerParams {
// TODO: support multiple datamodels
datamodel: String,
flavour: AdapterFlavour,
connection_info: JsConnectionInfo,
}

#[wasm_bindgen]
pub struct QueryCompiler {
schema: Arc<schema::QuerySchema>,
connection_info: ConnectionInfo,
protocol: EngineProtocol,
}

#[wasm_bindgen]
impl QueryCompiler {
#[wasm_bindgen(constructor)]
pub fn new(params: QueryCompilerParams, adapter: JsObject) -> Result<QueryCompiler, wasm_bindgen::JsError> {
let QueryCompilerParams { datamodel, .. } = params;
pub fn new(params: QueryCompilerParams) -> Result<QueryCompiler, wasm_bindgen::JsError> {
let QueryCompilerParams {
datamodel,
flavour,
connection_info,
} = params;

// Note: if we used `psl::validate`, we'd add ~1MB to the Wasm artifact (before gzip).
let schema = Arc::new(psl::parse_without_validation(datamodel.into(), CONNECTOR_REGISTRY));
let schema = Arc::new(schema::build(schema, true));
let adapter = Arc::new(driver_adapters::from_js(adapter));

tracing::info!(git_hash = env!("GIT_HASH"), "Starting query-compiler-wasm");
register_panic_hook();

Ok(Self {
schema,
adapter,
connection_info: ConnectionInfo::External(connection_info.into_external_connection_info(&flavour)),
protocol: EngineProtocol::Json,
})
}

#[wasm_bindgen]
pub async fn compile(
pub fn compile(
&self,
request: String,
_human_readable: bool, // ignored on wasm to not compile it in
) -> Result<String, wasm_bindgen::JsError> {
let request = RequestBody::try_from_str(&request, self.protocol)?;
let query_doc = request.into_doc(&self.schema)?;

let connection_info = ConnectionInfo::External(self.adapter.get_connection_info().await?);

let plan = query_compiler::compile(&self.schema, query_doc, &connection_info)?;
let plan = query_compiler::compile(&self.schema, query_doc, &self.connection_info)?;
Ok(serde_json::to_string(&plan)?)
}
}
25 changes: 17 additions & 8 deletions query-engine/driver-adapters/executor/src/demo-qc.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as S from "@effect/schema/Schema";
import { bindAdapter } from "@prisma/driver-adapter-utils";
import { bindAdapter, ConnectionInfo } from "@prisma/driver-adapter-utils";

import type { DriverAdaptersManager } from "./driver-adapters-manager";
import { Env } from "./types";
Expand Down Expand Up @@ -55,7 +55,7 @@ async function main(): Promise<void> {
schema,
});

const query = await compiler.compile(
const query = compiler.compile(
JSON.stringify({
modelName: "User",
action: "createOne",
Expand Down Expand Up @@ -89,12 +89,21 @@ async function initQC({
}: InitQueryCompilerParams) {
const adapter = await driverAdapterManager.connect({ url });
const errorCapturingAdapter = bindAdapter(adapter);
const compiler = await qc.initQueryCompiler(
{
datamodel: schema,
},
adapter,
);

let connectionInfo: ConnectionInfo = {};
if (errorCapturingAdapter.getConnectionInfo) {
const result = errorCapturingAdapter.getConnectionInfo();
if (!result.ok) {
throw result.error;
}
connectionInfo = result.value;
}

const compiler = await qc.initQueryCompiler({
datamodel: schema,
flavour: adapter.provider,
connectionInfo,
});

return {
compiler: compiler,
Expand Down
13 changes: 7 additions & 6 deletions query-engine/driver-adapters/executor/src/query-compiler.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
import type { DriverAdapter } from "@prisma/driver-adapter-utils";
import { ConnectionInfo } from "@prisma/driver-adapter-utils";
import { __dirname } from "./utils";
import { AdapterFlavour } from "query-engine-wasm-baseline";

export type QueryCompilerParams = {
// TODO: support multiple datamodels
datamodel: string;
flavour: AdapterFlavour;
connectionInfo: ConnectionInfo;
};

export interface QueryCompiler {
new (params: QueryCompilerParams, adapter: DriverAdapter): QueryCompiler;
new (params: QueryCompilerParams): QueryCompiler;
compile(query: string): Promise<string>;
}

export async function initQueryCompiler(
params: QueryCompilerParams,
adapter: DriverAdapter,
): Promise<QueryCompiler> {
const { getQueryCompilerForProvider } = await import("./query-compiler-wasm");
console.log(getQueryCompilerForProvider);
const WasmQueryCompiler = (await getQueryCompilerForProvider(
adapter.provider,
params.flavour,
)) as QueryCompiler;
return new WasmQueryCompiler(params, adapter);
return new WasmQueryCompiler(params);
}
1 change: 1 addition & 0 deletions query-engine/driver-adapters/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ impl From<DriverAdapterError> for QuaintError {

pub use queryable::from_js;
pub(crate) use transaction::JsTransaction;
pub use types::{AdapterFlavour, JsConnectionInfo};

#[cfg(target_arch = "wasm32")]
pub use wasm::JsObjectExtern as JsObject;
Expand Down
5 changes: 4 additions & 1 deletion query-engine/driver-adapters/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@ use serde_repr::{Deserialize_repr, Serialize_repr};
#[derive(Debug, Eq, PartialEq, Clone)]
pub enum AdapterFlavour {
#[cfg(feature = "mysql")]
#[cfg_attr(target_arch = "wasm32", serde(rename = "mysql"))]
Mysql,
#[cfg(feature = "postgresql")]
#[cfg_attr(target_arch = "wasm32", serde(rename = "postgres"))]
Postgres,
#[cfg(feature = "sqlite")]
#[cfg_attr(target_arch = "wasm32", serde(rename = "sqlite"))]
Sqlite,
}

Expand Down Expand Up @@ -71,7 +74,7 @@ impl From<&AdapterFlavour> for SqlFamily {
#[cfg_attr(target_arch = "wasm32", derive(Deserialize))]
#[cfg_attr(target_arch = "wasm32", serde(rename_all = "camelCase"))]
#[derive(Default)]
pub(crate) struct JsConnectionInfo {
pub struct JsConnectionInfo {
pub schema_name: Option<String>,
pub max_bind_values: Option<u32>,
}
Expand Down

0 comments on commit ca3bd67

Please sign in to comment.