Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(sql-schema-connector): wasm-compatible sql-schema-connector #5126

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
4 changes: 3 additions & 1 deletion quaint/src/ast/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ impl Function<'_> {
}
}

/// A database function type
/// A database function type.
/// Not every function is supported by every database.
/// TODO: Use `cfg` compilation flags to enable/disable functions based on the database family.
#[derive(Debug, Clone, PartialEq)]
pub(crate) enum FunctionType<'a> {
RowToJson(RowToJson<'a>),
Expand Down
2 changes: 2 additions & 0 deletions quaint/src/visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ pub trait Visitor<'a> {
/// Visit a non-parameterized value.
fn visit_raw_value(&mut self, value: Value<'a>) -> Result;

// TODO: JSON functions such as this one should only be required when
// `#[cfg(any(feature = "postgresql", feature = "mysql"))]` or similar filters apply.
fn visit_json_extract(&mut self, json_extract: JsonExtract<'a>) -> Result;

fn visit_json_extract_last_array_item(&mut self, extract: JsonExtractLastArrayElem<'a>) -> Result;
Expand Down
12 changes: 0 additions & 12 deletions quaint/src/visitor/mssql.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use super::{NativeColumnType, Visitor};
#[cfg(any(feature = "postgresql", feature = "mysql"))]
use crate::prelude::{JsonArrayAgg, JsonBuildObject, JsonExtract, JsonType, JsonUnquote};
use crate::{
ast::{
Expand Down Expand Up @@ -672,12 +671,10 @@ impl<'a> Visitor<'a> for Mssql<'a> {
Ok(())
}

#[cfg(any(feature = "postgresql", feature = "mysql"))]
fn visit_json_extract(&mut self, _json_extract: JsonExtract<'a>) -> visitor::Result {
unimplemented!("JSON filtering is not yet supported on MSSQL")
}

#[cfg(any(feature = "postgresql", feature = "mysql"))]
fn visit_json_array_contains(
&mut self,
_left: Expression<'a>,
Expand All @@ -687,32 +684,26 @@ impl<'a> Visitor<'a> for Mssql<'a> {
unimplemented!("JSON filtering is not yet supported on MSSQL")
}

#[cfg(any(feature = "postgresql", feature = "mysql"))]
fn visit_json_type_equals(&mut self, _left: Expression<'a>, _json_type: JsonType, _not: bool) -> visitor::Result {
unimplemented!("JSON_TYPE is not yet supported on MSSQL")
}

#[cfg(any(feature = "postgresql", feature = "mysql"))]
fn visit_json_unquote(&mut self, _json_unquote: JsonUnquote<'a>) -> visitor::Result {
unimplemented!("JSON filtering is not yet supported on MSSQL")
}

#[cfg(feature = "postgresql")]
fn visit_json_array_agg(&mut self, _array_agg: JsonArrayAgg<'a>) -> visitor::Result {
unimplemented!("JSON_AGG is not yet supported on MSSQL")
}

#[cfg(feature = "postgresql")]
fn visit_json_build_object(&mut self, _build_obj: JsonBuildObject<'a>) -> visitor::Result {
unimplemented!("JSON_BUILD_OBJECT is not yet supported on MSSQL")
}

#[cfg(feature = "postgresql")]
fn visit_text_search(&mut self, _text_search: crate::prelude::TextSearch<'a>) -> visitor::Result {
unimplemented!("Full-text search is not yet supported on MSSQL")
}

#[cfg(feature = "postgresql")]
fn visit_matches(
&mut self,
_left: Expression<'a>,
Expand All @@ -722,23 +713,20 @@ impl<'a> Visitor<'a> for Mssql<'a> {
unimplemented!("Full-text search is not yet supported on MSSQL")
}

#[cfg(feature = "postgresql")]
fn visit_text_search_relevance(
&mut self,
_text_search_relevance: crate::prelude::TextSearchRelevance<'a>,
) -> visitor::Result {
unimplemented!("Full-text search is not yet supported on MSSQL")
}

#[cfg(any(feature = "postgresql", feature = "mysql"))]
fn visit_json_extract_last_array_item(
&mut self,
_extract: crate::prelude::JsonExtractLastArrayElem<'a>,
) -> visitor::Result {
unimplemented!("JSON filtering is not yet supported on MSSQL")
}

#[cfg(any(feature = "postgresql", feature = "mysql"))]
fn visit_json_extract_first_array_item(
&mut self,
_extract: crate::prelude::JsonExtractFirstArrayElem<'a>,
Expand Down
4 changes: 3 additions & 1 deletion query-engine/connector-test-kit-rs/qe-setup/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ psl.workspace = true
quaint.workspace = true
mongodb-client = { path = "../../../libs/mongodb-client" }
schema-core = { path = "../../../schema-engine/core" }
sql-schema-connector = { path = "../../../schema-engine/connectors/sql-schema-connector" }
sql-schema-connector = { path = "../../../schema-engine/connectors/sql-schema-connector", features = [
"all-native",
] }
test-setup = { path = "../../../libs/test-setup" }
enumflags2.workspace = true
serde.workspace = true
Expand Down
49 changes: 30 additions & 19 deletions schema-engine/connectors/sql-schema-connector/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,44 @@ version = "0.1.0"

[features]
vendored-openssl = ["quaint/vendored-openssl"]
postgresql = ["psl/postgresql", "quaint/postgresql", "schema-connector/postgresql", "sql-schema-describer/postgresql"]
postgresql-native = ["postgresql", "quaint/postgresql-native", "quaint/pooled"]
sqlite = ["psl/sqlite", "quaint/sqlite", "schema-connector/sqlite", "sql-schema-describer/sqlite"]
sqlite-native = ["sqlite", "quaint/sqlite-native", "quaint/pooled", "quaint/expose-drivers", "sqlx-sqlite", "sqlx-core"]
mysql = ["psl/mysql", "quaint/mysql", "schema-connector/mysql", "sql-schema-describer/mysql"]
mysql-native = ["mysql", "quaint/mysql-native", "quaint/pooled"]
mssql = ["psl/mssql", "quaint/mssql", "schema-connector/mssql", "sql-schema-describer/mssql"]
mssql-native = ["mssql", "quaint/mssql-native", "quaint/pooled"]
cockroachdb = ["psl/cockroachdb", "quaint/postgresql", "schema-connector/cockroachdb", "sql-schema-describer/cockroachdb"]
cockroachdb-native = ["cockroachdb", "quaint/postgresql-native", "quaint/pooled"]
all-native = [
"vendored-openssl",
"quaint/fmt-sql",
"postgresql-native",
"sqlite-native",
"mysql-native",
"mssql-native",
"cockroachdb-native",
"schema-connector/all-native",
"sql-schema-describer/all-native",
"user-facing-errors/all-native",
]

[dependencies]
psl.workspace = true
quaint = { workspace = true, features = [
"all-native",
"expose-drivers",
"pooled",
"fmt-sql",
] }
tokio.workspace = true
quaint.workspace = true
tokio = { version = "1", features = ["macros", "sync", "io-util", "time"] }
serde.workspace = true
indoc.workspace = true
uuid.workspace = true
indexmap.workspace = true

prisma-value = { path = "../../../libs/prisma-value" }
schema-connector = { path = "../schema-connector", features = [
"all-native",
] }
sql-schema-describer = { path = "../../sql-schema-describer", features = [
"all-native",
] }
schema-connector = { path = "../schema-connector" }
sql-schema-describer = { path = "../../sql-schema-describer" }
datamodel-renderer = { path = "../../datamodel-renderer" }
sql-ddl = { path = "../../../libs/sql-ddl" }
user-facing-errors = { path = "../../../libs/user-facing-errors", features = [
"sql",
"all-native",
] }
user-facing-errors = { path = "../../../libs/user-facing-errors", features = ["sql"] }

chrono.workspace = true
connection-string.workspace = true
Expand All @@ -47,7 +57,8 @@ either = "1.6"
sqlformat = "0.2.1"
sqlparser = "0.32.0"
versions = "6.1.0"
sqlx-sqlite = { version = "0.8.0" }
sqlx-core = "0.8.0"
sqlx-sqlite = { version = "0.8.0", optional = true }
sqlx-core = { version = "0.8.0", optional = true }

[dev-dependencies]
expect-test = "1"
14 changes: 14 additions & 0 deletions schema-engine/connectors/sql-schema-connector/src/flavour.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,28 @@
//! in order to avoid cluttering the connector with conditionals. This is a private implementation
//! detail of the SQL connector.

#[cfg(feature = "mssql")]
mod mssql;

#[cfg(feature = "mysql")]
mod mysql;

#[cfg(any(feature = "postgresql", feature = "cockroachdb"))]
mod postgres;

#[cfg(feature = "sqlite")]
mod sqlite;

#[cfg(feature = "mssql")]
pub(crate) use mssql::MssqlFlavour;

#[cfg(feature = "mysql")]
pub(crate) use mysql::MysqlFlavour;

#[cfg(any(feature = "postgresql", feature = "cockroachdb"))]
pub(crate) use postgres::PostgresFlavour;

#[cfg(feature = "sqlite")]
pub(crate) use sqlite::SqliteFlavour;

use crate::{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
mod connection;
mod shadow_db;
#[cfg(feature = "mssql-native")]
mod native;

#[cfg(not(feature = "mssql-native"))]
mod wasm;

#[cfg(feature = "mssql-native")]
use native::{generic_apply_migration_script, shadow_db, Connection};

#[cfg(not(feature = "mssql-native"))]
use wasm::{generic_apply_migration_script, shadow_db, Connection};

use self::connection::*;
use crate::SqlFlavour;
use connection_string::JdbcString;
use indoc::formatdoc;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//! All the quaint-wrangling for the mssql connector should happen here.
pub(super) mod shadow_db;

use quaint::{
connector::{self, MssqlUrl},
prelude::{ConnectionInfo, NativeConnectionInfo, Queryable},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::flavour::*;
use schema_connector::{migrations_directory::MigrationDirectory, ConnectorResult};
use crate::flavour::{MssqlFlavour, SqlFlavour};
use schema_connector::{migrations_directory::MigrationDirectory, ConnectorError, ConnectorResult, Namespaces};
use sql_schema_describer::SqlSchema;

pub(super) async fn sql_schema_from_migrations_history(
pub async fn sql_schema_from_migrations_history(
migrations: &[MigrationDirectory],
mut shadow_db: MssqlFlavour,
namespaces: Option<Namespaces>,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
//! All the quaint-wrangling for the mssql connector should happen here.

pub(super) mod shadow_db;

use enumflags2::BitFlags;
use quaint::connector::{ColumnType, DescribedColumn, DescribedParameter, GetRow, MssqlUrl, ToColumnNames};
use schema_connector::{BoxFuture, ConnectorError, ConnectorResult, Namespaces};
use sql_schema_describer::{mssql as describer, DescriberErrorKind, SqlSchema};
use user_facing_errors::schema_engine::ApplyMigrationError;

// TODO: use ExternalConnector here.
pub(super) struct Connection();

impl Connection {
pub(super) async fn new(connection_str: &str) -> ConnectorResult<Self> {
panic!("[sql-schema-connector::flavour::mssql::wasm] Not implemented");
}

#[tracing::instrument(skip(self, params))]
pub(super) async fn describe_schema(
&mut self,
params: &super::Params,
namespaces: Option<Namespaces>,
) -> ConnectorResult<SqlSchema> {
panic!("[sql-schema-connector::flavour::mssql::wasm] Not implemented");
}

pub(super) async fn raw_cmd(&mut self, sql: &str, params: &super::Params) -> ConnectorResult<()> {
tracing::debug!(query_type = "raw_cmd", sql);
panic!("[sql-schema-connector::flavour::mssql::wasm] Not implemented");
}

pub(super) async fn version(&mut self, params: &super::Params) -> ConnectorResult<Option<String>> {
tracing::debug!(query_type = "version");
panic!("[sql-schema-connector::flavour::mssql::wasm] Not implemented");
}

pub(super) async fn query(
&mut self,
query: quaint::ast::Query<'_>,
conn_params: &super::Params,
) -> ConnectorResult<quaint::prelude::ResultSet> {
use quaint::visitor::Visitor;
let (sql, params) = quaint::visitor::Mssql::build(query).unwrap();
self.query_raw(&sql, &params, conn_params).await
}

pub(super) async fn query_raw(
&mut self,
sql: &str,
params: &[quaint::prelude::Value<'_>],
conn_params: &super::Params,
) -> ConnectorResult<quaint::prelude::ResultSet> {
tracing::debug!(query_type = "query_raw", sql);
panic!("[sql-schema-connector::flavour::mssql::wasm] Not implemented");
}
}

pub(super) async fn generic_apply_migration_script(
migration_name: &str,
script: &str,
conn: &mut Connection,
) -> ConnectorResult<()> {
tracing::debug!(query_type = "raw_cmd", script);
panic!("[sql-schema-connector::flavour::mssql::wasm] Not implemented");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use crate::flavour::{MssqlFlavour, SqlFlavour};
use schema_connector::Namespaces;
use schema_connector::{migrations_directory::MigrationDirectory, ConnectorResult};
use sql_schema_describer::SqlSchema;

pub async fn sql_schema_from_migrations_history(
migrations: &[MigrationDirectory],
mut shadow_db: MssqlFlavour,
namespaces: Option<Namespaces>,
) -> ConnectorResult<SqlSchema> {
panic!("[sql-schema-connector::flavour::mssql::wasm] Not implemented");
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
mod connection;
mod shadow_db;
#[cfg(feature = "mysql-native")]
mod native;

#[cfg(not(feature = "mysql-native"))]
mod wasm;

#[cfg(feature = "mysql-native")]
use native::{shadow_db, Connection};

#[cfg(not(feature = "mysql-native"))]
use wasm::{shadow_db, Connection};

use self::connection::*;
use crate::{error::SystemDatabase, flavour::SqlFlavour};
use enumflags2::BitFlags;
use indoc::indoc;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//! All the quaint-wrangling for the mysql connector should happen here.

pub(super) mod shadow_db;

use enumflags2::BitFlags;
use quaint::{
connector::{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::flavour::*;
use crate::flavour::{mysql, MysqlFlavour, SqlFlavour};
use schema_connector::{migrations_directory::MigrationDirectory, ConnectorResult};
use sql_schema_describer::SqlSchema;

pub(super) async fn sql_schema_from_migrations_history(
pub async fn sql_schema_from_migrations_history(
migrations: &[MigrationDirectory],
mut shadow_db: MysqlFlavour,
) -> ConnectorResult<SqlSchema> {
Expand All @@ -14,7 +14,7 @@ pub(super) async fn sql_schema_from_migrations_history(
migration.migration_name()
);

super::scan_migration_script_impl(&script);
mysql::scan_migration_script_impl(&script);

shadow_db
.apply_migration_script(migration.migration_name(), &script)
Expand Down
Loading
Loading