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
6 changes: 6 additions & 0 deletions .github/workflows/test-query-compiler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ jobs:
should_fail_tests_list: query-compiler/query-engine-tests-todo/planetscale/fail
relation_load_strategy: '["query"]'

- name: mysql2
setup_task: dev-mysql2-qc
ignored_tests_list: query-compiler/query-engine-tests-todo/mysql2/skip
should_fail_tests_list: query-compiler/query-engine-tests-todo/mysql2/fail
relation_load_strategy: '["query"]'

- name: d1
setup_task: dev-d1-qc
ignored_tests_list: query-compiler/query-engine-tests-todo/d1/skip
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/test-query-engine.yml
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,8 @@ jobs:
adapter:
- name: 'planetscale (wasm)'
setup_task: 'dev-planetscale-wasm'
- name: 'mysql2 (wasm)'
setup_task: 'dev-mysql2-wasm'
- name: 'pg (wasm)'
setup_task: 'dev-pg-wasm'
- name: 'neon (wasm)'
Expand Down
11 changes: 11 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,17 @@ test-planetscale-qc: dev-planetscale-qc test-qe-st
test-driver-adapter-planetscale: test-planetscale-js
test-driver-adapter-planetscale-wasm: test-planetscale-wasm

start-mysql2:
docker compose -f docker-compose.yml up -d --remove-orphans mysql-8-0

dev-mysql2-wasm: start-mysql2 build-qe-wasm build-driver-adapters-kit-qe
cp $(CONFIG_PATH)/mysql2-wasm $(CONFIG_FILE)

dev-mysql2-qc: start-mysql2 build-qc-wasm build-driver-adapters-kit-qc
cp $(CONFIG_PATH)/mysql2-qc $(CONFIG_FILE)

test-mysql2-qc: dev-mysql2-qc test-qe-st

######################
# Local dev commands #
######################
Expand Down
1 change: 1 addition & 0 deletions libs/driver-adapters/executor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"dependencies": {
"@effect/schema": "0.64.20",
"@prisma/adapter-better-sqlite3": "workspace:*",
"@prisma/adapter-mysql2": "workspace:*",
"@prisma/adapter-d1": "workspace:*",
"@prisma/adapter-libsql": "workspace:*",
"@prisma/adapter-neon": "workspace:*",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { PrismaMySQL2 } from '@prisma/adapter-mysql2'
import type {
SqlDriverAdapter,
SqlMigrationAwareDriverAdapterFactory,
} from '@prisma/driver-adapter-utils'
import type { DriverAdaptersManager, SetupDriverAdaptersInput } from './index'
import type { DriverAdapterTag, EnvForAdapter } from '../types'

const TAG = 'mysql2' as const satisfies DriverAdapterTag
type TAG = typeof TAG

export class MySQL2Manager implements DriverAdaptersManager {
#factory: SqlMigrationAwareDriverAdapterFactory
#adapter?: SqlDriverAdapter

private constructor(
private env: EnvForAdapter<TAG>,
{ url }: SetupDriverAdaptersInput,
) {
const database = new URL(url).pathname.split('/').pop()
this.#factory = new PrismaMySQL2({
uri: url,
database,
})
}

static async setup(env: EnvForAdapter<TAG>, input: SetupDriverAdaptersInput) {
return new MySQL2Manager(env, input)
}

factory() {
return this.#factory
}

async connect() {
this.#adapter = await this.#factory.connect()
return this.#adapter
}

async teardown() {
await this.#adapter?.dispose()
}
}
5 changes: 5 additions & 0 deletions libs/driver-adapters/executor/src/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { LibSQLManager } from './driver-adapters-manager/libsql'
import { PlanetScaleManager } from './driver-adapters-manager/planetscale'
import { D1Manager } from './driver-adapters-manager/d1'
import { BetterSQLite3Manager } from './driver-adapters-manager/better-sqlite3'
import { MySQL2Manager } from './driver-adapters-manager/mysql2'

export async function setupDriverAdaptersManager(
env: Env,
Expand Down Expand Up @@ -40,5 +41,9 @@ export async function setupDriverAdaptersManager(
{ DRIVER_ADAPTER: 'better-sqlite3' },
async (env) => await BetterSQLite3Manager.setup(env, input),
)
.with(
{ DRIVER_ADAPTER: 'mysql2' },
async (env) => await MySQL2Manager.setup(env, input),
)
.exhaustive()
}
8 changes: 7 additions & 1 deletion libs/driver-adapters/executor/src/types/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,13 @@ export const Env = S.extend(
EnvPlanetScale,
EnvNeonWS,
S.struct({
DRIVER_ADAPTER: S.literal('pg', 'libsql', 'd1', 'better-sqlite3'),
DRIVER_ADAPTER: S.literal(
'pg',
'libsql',
'd1',
'better-sqlite3',
'mysql2',
),
}),
),
S.union(
Expand Down
1 change: 1 addition & 0 deletions libs/driver-adapters/pnpm-workspace.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
packages:
- '../../../prisma/packages/adapter-d1'
- '../../../prisma/packages/adapter-better-sqlite3'
- '../../../prisma/packages/adapter-mysql2'
- '../../../prisma/packages/adapter-libsql'
- '../../../prisma/packages/adapter-neon'
- '../../../prisma/packages/adapter-pg'
Expand Down
2 changes: 2 additions & 0 deletions quaint/src/connector/external.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ pub enum AdapterName {
LibSQL,
BetterSQLite3,
Planetscale,
MySQL2,
Mssql,
Unknown,
}
Expand All @@ -38,6 +39,7 @@ impl FromStr for AdapterName {
"d1-http" => Ok(Self::D1(AdapterD1::HTTP)),
"libsql" => Ok(Self::LibSQL),
"better-sqlite3" => Ok(Self::BetterSQLite3),
"mysql2" => Ok(Self::MySQL2),
"planetscale" => Ok(Self::Planetscale),
"mssql" => Ok(Self::Mssql),
_ => Ok(Self::Unknown),
Expand Down
6 changes: 6 additions & 0 deletions query-compiler/query-engine-tests-todo/mysql2/fail/query
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
new::interactive_tx::interactive_tx::batch_queries_failure
new::regressions::prisma_7434::not_in_chunking::not_in_batch_filter
queries::aggregation::group_by::aggregation_group_by::group_by_ordering_sum_aggregation
queries::chunking::chunking::order_by_aggregation_should_fail
queries::filters::self_relation_regression::sr_regression::all_categories
writes::nested_mutations::already_converted::nested_connect_inside_update::connect_inside_update::p1_c1req_rel_child_idempotent
1 change: 1 addition & 0 deletions query-compiler/query-engine-tests-todo/mysql2/skip/query
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ pub enum DriverAdapter {
#[serde(rename = "better-sqlite3")]
BetterSQLite3,

#[serde(rename = "mysql2")]
MySQL2,

#[serde(rename = "mssql")]
Mssql,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,13 +135,17 @@ pub(crate) fn connection_string(
ConnectorVersion::MySql(v) => match v {
Some(MySqlVersion::V5_6) if is_ci => format!("mysql://root:prisma@test-db-mysql-5-6:3306/{database}"),
Some(MySqlVersion::V5_7) if is_ci => format!("mysql://root:prisma@test-db-mysql-5-7:3306/{database}"),
Some(MySqlVersion::V8) if is_ci => format!("mysql://root:prisma@test-db-mysql-8:3306/{database}"),
Some(MySqlVersion::V8 | MySqlVersion::Mysql2JsWasm) if is_ci => {
format!("mysql://root:prisma@test-db-mysql-8:3306/{database}")
}
Some(MySqlVersion::MariaDb) if is_ci => {
format!("mysql://root:prisma@test-db-mysql-mariadb:3306/{database}")
}
Some(MySqlVersion::V5_6) => format!("mysql://root:prisma@127.0.0.1:3309/{database}"),
Some(MySqlVersion::V5_7) => format!("mysql://root:prisma@127.0.0.1:3306/{database}"),
Some(MySqlVersion::V8) => format!("mysql://root:prisma@127.0.0.1:3307/{database}"),
Some(MySqlVersion::V8 | MySqlVersion::Mysql2JsWasm) => {
format!("mysql://root:prisma@127.0.0.1:3307/{database}")
}
Some(MySqlVersion::MariaDb) => {
format!("mysql://root:prisma@127.0.0.1:3308/{database}")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ pub enum MySqlVersion {
V5_7,
V8,
MariaDb,
Mysql2JsWasm,
}

impl TryFrom<&str> for MySqlVersion {
Expand All @@ -45,6 +46,7 @@ impl TryFrom<&str> for MySqlVersion {
"5.7" => Self::V5_7,
"8" => Self::V8,
"mariadb" => Self::MariaDb,
"mysql2.js.wasm" => Self::Mysql2JsWasm,
_ => return Err(TestError::parse_error(format!("Unknown MySQL version `{s}`"))),
};

Expand All @@ -59,6 +61,7 @@ impl Display for MySqlVersion {
MySqlVersion::V5_7 => f.write_str("5.7"),
MySqlVersion::V8 => f.write_str("8"),
MySqlVersion::MariaDb => f.write_str("mariadb"),
MySqlVersion::Mysql2JsWasm => f.write_str("mysql2.js.wasm"),
}
}
}
6 changes: 6 additions & 0 deletions query-engine/connector-test-kit-rs/test-configs/mysql2-js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"connector": "mysql",
"version": "mysql2.js",
"driver_adapter": "mysql2",
"external_test_executor": "Napi"
}
6 changes: 6 additions & 0 deletions query-engine/connector-test-kit-rs/test-configs/mysql2-qc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"connector": "mysql",
"version": "mysql2.js.wasm",
"driver_adapter": "mysql2",
"external_test_executor": "QueryCompiler"
}
52 changes: 28 additions & 24 deletions query-engine/core/src/query_graph_builder/write/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,32 +39,16 @@ pub(crate) fn update_record(
Some(&field),
)?;

if query_schema.relation_mode().is_prisma() {
let read_parent_node = graph.create_node(utils::read_id_infallible(
model.clone(),
model.shard_aware_primary_identifier(),
filter,
));
let read_parent_node = graph.create_node(utils::read_id_infallible(
model.clone(),
model.shard_aware_primary_identifier(),
filter,
));

utils::insert_emulated_on_update(graph, query_schema, &model, &read_parent_node, &update_node)?;
let needs_read_parent = query_schema.relation_mode().is_prisma() || !can_use_atomic_update;

graph.create_edge(
&read_parent_node,
&update_node,
QueryGraphDependency::ProjectedDataDependency(
model.shard_aware_primary_identifier(),
Box::new(move |mut update_node, parent_ids| {
if let Node::Query(Query::Write(WriteQuery::UpdateRecord(ref mut ur))) = update_node {
ur.set_record_filter(parent_ids.into());
}

Ok(update_node)
}),
Some(DataExpectation::non_empty_rows(
MissingRecord::builder().operation(DataOperation::Update).build(),
)),
),
)?;
if query_schema.relation_mode().is_prisma() {
utils::insert_emulated_on_update(graph, query_schema, &model, &read_parent_node, &update_node)?;
}

// If the update can be done in a single operation (which includes getting the result back),
Expand Down Expand Up @@ -107,6 +91,26 @@ pub(crate) fn update_record(
)?;
}

if needs_read_parent {
graph.create_edge(
&read_parent_node,
&update_node,
QueryGraphDependency::ProjectedDataDependency(
model.shard_aware_primary_identifier(),
Box::new(move |mut update_node, parent_ids| {
if let Node::Query(Query::Write(WriteQuery::UpdateRecord(ref mut ur))) = update_node {
ur.set_record_filter(parent_ids.into());
}

Ok(update_node)
}),
Some(DataExpectation::non_empty_rows(
MissingRecord::builder().operation(DataOperation::Update).build(),
)),
),
)?;
}

Ok(())
}

Expand Down
Loading