-
Notifications
You must be signed in to change notification settings - Fork 235
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement a type for different client connectors and expose first cla…
…ss citizens (#4074) for each of the connectors that are built-in.
- Loading branch information
Miguel Fernández
authored
Jul 24, 2023
1 parent
6a4762d
commit f5c61f9
Showing
11 changed files
with
201 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
use crate::mysql_datamodel_connector; | ||
use psl_core::{ | ||
datamodel_connector::RelationMode, | ||
js_connector::{Flavor, JsConnector}, | ||
}; | ||
|
||
pub(crate) static PLANETSCALE_SERVERLESS: JsConnector = JsConnector { | ||
flavor: Flavor::MySQL, | ||
canonical_connector: &mysql_datamodel_connector::MySqlDatamodelConnector, | ||
|
||
provider_name: "@prisma/planetscale", | ||
name: "planetscale serverless", | ||
enforced_relation_mode: Some(RelationMode::Prisma), | ||
allowed_protocols: Some(&["mysql", "https", "mysqls"]), | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
use crate::datamodel_connector::*; | ||
use enumflags2::BitFlags; | ||
|
||
/// JsConnector represents a type of connector that is implemented partially | ||
/// in javascript and used from rust through the js-connectors crate | ||
/// | ||
/// Rather than a unit struct per individual connector, like we have for the rest | ||
/// of the builtin connectors, we have a single struct which state represents the | ||
/// features that vary in this connector with respect to a cannonical connector | ||
/// for the flavor of SQL the particular JsConnector speaks. | ||
/// | ||
/// For example, the _planetscale serverless_ connector is compatible with MySQL, | ||
/// so it reuses the builtin MySQL connector (the cannonical for the MySQL flavor) | ||
/// for most of its features. | ||
#[derive(Copy, Clone)] | ||
pub struct JsConnector { | ||
pub flavor: Flavor, | ||
pub canonical_connector: &'static dyn Connector, | ||
|
||
pub provider_name: &'static str, | ||
pub name: &'static str, | ||
pub enforced_relation_mode: Option<RelationMode>, | ||
pub allowed_protocols: Option<&'static [&'static str]>, | ||
} | ||
|
||
#[derive(Copy, Clone)] | ||
pub enum Flavor { | ||
MySQL, | ||
} | ||
|
||
impl Connector for JsConnector { | ||
fn as_js_connector(&self) -> Option<JsConnector> { | ||
Some(*self) | ||
} | ||
|
||
fn provider_name(&self) -> &'static str { | ||
self.provider_name | ||
} | ||
|
||
fn name(&self) -> &str { | ||
self.name | ||
} | ||
|
||
fn capabilities(&self) -> ConnectorCapabilities { | ||
self.canonical_connector.capabilities() | ||
} | ||
|
||
fn max_identifier_length(&self) -> usize { | ||
self.canonical_connector.max_identifier_length() | ||
} | ||
|
||
fn referential_actions(&self) -> enumflags2::BitFlags<parser_database::ReferentialAction> { | ||
self.canonical_connector.referential_actions() | ||
} | ||
|
||
fn available_native_type_constructors(&self) -> &'static [NativeTypeConstructor] { | ||
self.canonical_connector.available_native_type_constructors() | ||
} | ||
|
||
fn scalar_type_for_native_type(&self, native_type: &NativeTypeInstance) -> parser_database::ScalarType { | ||
self.canonical_connector.scalar_type_for_native_type(native_type) | ||
} | ||
|
||
fn default_native_type_for_scalar_type(&self, scalar_type: &parser_database::ScalarType) -> NativeTypeInstance { | ||
self.canonical_connector | ||
.default_native_type_for_scalar_type(scalar_type) | ||
} | ||
|
||
fn native_type_is_default_for_scalar_type( | ||
&self, | ||
native_type: &NativeTypeInstance, | ||
scalar_type: &parser_database::ScalarType, | ||
) -> bool { | ||
self.canonical_connector | ||
.native_type_is_default_for_scalar_type(native_type, scalar_type) | ||
} | ||
|
||
fn native_type_to_parts(&self, native_type: &NativeTypeInstance) -> (&'static str, Vec<String>) { | ||
self.canonical_connector.native_type_to_parts(native_type) | ||
} | ||
|
||
fn parse_native_type( | ||
&self, | ||
name: &str, | ||
args: &[String], | ||
span: diagnostics::Span, | ||
diagnostics: &mut diagnostics::Diagnostics, | ||
) -> Option<NativeTypeInstance> { | ||
self.canonical_connector | ||
.parse_native_type(name, args, span, diagnostics) | ||
} | ||
|
||
fn validate_url(&self, url: &str) -> Result<(), String> { | ||
if let Some(allowed_protocols) = self.allowed_protocols { | ||
let scheme = url.split(':').next().unwrap_or(""); | ||
if allowed_protocols.contains(&scheme) { | ||
Ok(()) | ||
} else { | ||
Err(format!( | ||
"The URL scheme `{}` is not valid for the {} connector. The following schemes are allowed: {}", | ||
scheme, | ||
self.name, | ||
allowed_protocols.join(", ") | ||
)) | ||
} | ||
} else { | ||
self.canonical_connector.validate_url(url) | ||
} | ||
} | ||
|
||
fn default_relation_mode(&self) -> RelationMode { | ||
if let Some(relation_mode) = self.enforced_relation_mode { | ||
relation_mode | ||
} else { | ||
self.canonical_connector.default_relation_mode() | ||
} | ||
} | ||
|
||
fn allowed_relation_mode_settings(&self) -> BitFlags<RelationMode> { | ||
if let Some(relation_mode) = self.enforced_relation_mode { | ||
BitFlags::from(relation_mode) | ||
} else { | ||
self.canonical_connector.allowed_relation_mode_settings() | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
8 changes: 8 additions & 0 deletions
8
psl/psl/tests/validation/js_connectors/prisma_planetscale.prisma
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
generator client { | ||
provider = "prisma-client-js" | ||
} | ||
|
||
datasource db { | ||
provider = "@prisma/planetscale" | ||
url = "mysql://" | ||
} |
15 changes: 15 additions & 0 deletions
15
.../tests/validation/js_connectors/prisma_planetscale_doesnt_support_relation_mode_fk.prisma
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
generator client { | ||
provider = "prisma-client-js" | ||
} | ||
|
||
datasource db { | ||
provider = "@prisma/planetscale" | ||
url = "mysql://" | ||
relationMode = "foreignKeys" | ||
} | ||
// [1;91merror[0m: [1mError validating datasource `relationMode`: Invalid relation mode setting: "foreignKeys". Supported values: "prisma"[0m | ||
// [1;94m-->[0m [4mschema.prisma:8[0m | ||
// [1;94m | [0m | ||
// [1;94m 7 | [0m url = "mysql://" | ||
// [1;94m 8 | [0m relationMode = [1;91m"foreignKeys"[0m | ||
// [1;94m | [0m |
8 changes: 8 additions & 0 deletions
8
psl/psl/tests/validation/js_connectors/prisma_planetscale_https_url.prisma
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
generator client { | ||
provider = "prisma-client-js" | ||
} | ||
|
||
datasource db { | ||
provider = "@prisma/planetscale" | ||
url = "https://" | ||
} |
8 changes: 8 additions & 0 deletions
8
psl/psl/tests/validation/js_connectors/prisma_planetscale_mysqls_url.prisma
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
generator client { | ||
provider = "prisma-client-js" | ||
} | ||
|
||
datasource db { | ||
provider = "@prisma/planetscale" | ||
url = "mysqls://" | ||
} |
9 changes: 0 additions & 9 deletions
9
psl/psl/tests/validation/mysql/node_drivers/prisma_mysql.prisma
This file was deleted.
Oops, something went wrong.