Skip to content

Commit

Permalink
Handle datamodel parsing in opts
Browse files Browse the repository at this point in the history
  • Loading branch information
Julius de Bruijn committed Mar 23, 2020
1 parent e33c54f commit 8fd19f9
Show file tree
Hide file tree
Showing 26 changed files with 316 additions and 456 deletions.
2 changes: 1 addition & 1 deletion .envrc
Expand Up @@ -18,4 +18,4 @@ export PRISMA_BINARY_PATH=$(pwd)/target/release/prisma
export MIGRATION_ENGINE_BINARY_PATH=$(pwd)/target/release/migration-engine

# This must be in sync with the setting in the engineer build CLI
export SQLITE_MAX_VARIABLE_NUMBER=250000
export SQLITE_MAX_VARIABLE_NUMBER=250000
1 change: 0 additions & 1 deletion .rustfmt.toml

This file was deleted.

1 change: 1 addition & 0 deletions .rustfmt.toml
@@ -1,4 +1,3 @@
use datamodel::common::names::NameNormalizer;
use datamodel::{
DefaultValue as DMLDef, Field, FieldArity, FieldType, IndexDefinition, Model, OnDeleteStrategy,
RelationInfo, ScalarType, ScalarValue as SV, ValueGenerator as VG,
Expand Down
58 changes: 20 additions & 38 deletions query-engine/prisma/src/cli.rs
@@ -1,40 +1,36 @@
use crate::{
configuration,
context::PrismaContext,
dmmf,
error::PrismaError,
opt::{CliOpt, PrismaOpt, Subcommand},
request_handlers::{graphql::*, PrismaRequest, RequestHandler},
PrismaResult, {CliOpt, PrismaOpt, Subcommand},
PrismaResult,
};
use datamodel::{Configuration, Datamodel};
use prisma_models::DatamodelConverter;
use query_core::{
schema::{QuerySchemaRef, SupportedCapabilities},
BuildMode, QuerySchemaBuilder,
};
use std::{collections::HashMap, convert::TryFrom, sync::Arc};

#[derive(Debug)]
pub struct ExecuteRequest {
legacy: bool,
query: String,
datamodel: String,
datamodel: Datamodel,
config: Configuration,
force_transactions: bool,
enable_raw_queries: bool,
overwrite_datasources: Option<String>,
}

#[derive(Debug)]
pub struct DmmfRequest {
datamodel: String,
datamodel: Datamodel,
build_mode: BuildMode,
enable_raw_queries: bool,
overwrite_datasources: Option<String>,
}

#[derive(Debug)]
pub struct GetConfigRequest {
datamodel: String,
overwrite_datasources: Option<String>,
config: Configuration,
}

pub enum CliCommand {
Expand All @@ -47,15 +43,10 @@ impl TryFrom<&PrismaOpt> for CliCommand {
type Error = PrismaError;

fn try_from(opts: &PrismaOpt) -> crate::PrismaResult<CliCommand> {
let subcommand = opts.subcommand.clone().ok_or_else(|| {
PrismaError::InvocationError(String::from("cli subcommand not present"))
})?;

let datamodel = opts
.datamodel
.clone()
.xor(opts.datamodel_path.clone())
.expect("Datamodel should be provided either as path or base64-encoded string.");
let subcommand = opts
.subcommand
.as_ref()
.ok_or_else(|| PrismaError::InvocationError(String::from("cli subcommand not present")))?;

match subcommand {
Subcommand::Cli(ref cliopts) => match cliopts {
Expand All @@ -67,23 +58,21 @@ impl TryFrom<&PrismaOpt> for CliCommand {
};

Ok(CliCommand::Dmmf(DmmfRequest {
datamodel,
datamodel: opts.datamodel(true)?,
build_mode,
enable_raw_queries: opts.enable_raw_queries,
overwrite_datasources: opts.overwrite_datasources.clone(),
}))
}
CliOpt::GetConfig => Ok(CliCommand::GetConfig(GetConfigRequest {
datamodel,
overwrite_datasources: opts.overwrite_datasources.clone(),
config: opts.configuration(true)?,
})),
CliOpt::ExecuteRequest(input) => Ok(CliCommand::ExecuteRequest(ExecuteRequest {
query: input.query.clone(),
force_transactions: opts.always_force_transactions,
overwrite_datasources: opts.overwrite_datasources.clone(),
enable_raw_queries: opts.enable_raw_queries,
legacy: input.legacy,
datamodel,
datamodel: opts.datamodel(false)?,
config: opts.configuration(false)?,
})),
},
}
Expand All @@ -94,18 +83,13 @@ impl CliCommand {
pub async fn execute(self) -> PrismaResult<()> {
match self {
CliCommand::Dmmf(request) => Self::dmmf(request),
CliCommand::GetConfig(input) => {
Self::get_config(input.datamodel, input.overwrite_datasources)
}
CliCommand::GetConfig(input) => Self::get_config(input.config),
CliCommand::ExecuteRequest(request) => Self::execute_request(request).await,
}
}

fn dmmf(request: DmmfRequest) -> PrismaResult<()> {
let dm = datamodel::parse_datamodel_and_ignore_env_errors(&request.datamodel)
.map_err(|errors| PrismaError::ConversionError(errors, request.datamodel.clone()))?;

let template = DatamodelConverter::convert(&dm);
let template = DatamodelConverter::convert(&request.datamodel);

// temporary code duplication
let internal_data_model = template.build("".into());
Expand All @@ -120,16 +104,15 @@ impl CliCommand {

let query_schema: QuerySchemaRef = Arc::new(schema_builder.build());

let dmmf = dmmf::render_dmmf(&dm, query_schema);
let dmmf = dmmf::render_dmmf(&request.datamodel, query_schema);
let serialized = serde_json::to_string_pretty(&dmmf)?;

println!("{}", serialized);

Ok(())
}

fn get_config(datamodel: String, overwrite_datasources: Option<String>) -> PrismaResult<()> {
let config = configuration::load(&datamodel, overwrite_datasources, true)?;
fn get_config(config: Configuration) -> PrismaResult<()> {
let json = datamodel::json::mcf::config_to_mcf_json_value(&config);
let serialized = serde_json::to_string(&json)?;

Expand All @@ -142,11 +125,10 @@ impl CliCommand {
let decoded = base64::decode(&request.query)?;
let decoded_request = String::from_utf8(decoded)?;

let ctx = PrismaContext::builder(request.datamodel)
let ctx = PrismaContext::builder(request.config, request.datamodel)
.legacy(request.legacy)
.force_transactions(request.force_transactions)
.enable_raw_queries(request.enable_raw_queries)
.overwrite_datasources(request.overwrite_datasources)
.build()
.await?;

Expand Down
50 changes: 0 additions & 50 deletions query-engine/prisma/src/configuration.rs

This file was deleted.

51 changes: 13 additions & 38 deletions query-engine/prisma/src/context.rs
@@ -1,24 +1,20 @@
use crate::{configuration, exec_loader, PrismaError, PrismaResult};
use crate::{exec_loader, PrismaError, PrismaResult};
use query_core::{
schema::{QuerySchemaRef, SupportedCapabilities},
BuildMode, QueryExecutor, QuerySchemaBuilder,
};
// use prisma_models::InternalDataModelRef;
use datamodel::Datamodel;
use datamodel::{Configuration, Datamodel};
use prisma_models::DatamodelConverter;
use std::sync::Arc;

/// Prisma request context containing all immutable state of the process.
/// There is usually only one context initialized per process.
pub struct PrismaContext {
// Internal data model used throughout the query engine.
//internal_data_model: InternalDataModelRef,
/// The api query schema.
query_schema: QuerySchemaRef,

/// DML-based v2 datamodel.
dm: Datamodel,

/// Central query executor.
pub executor: Box<dyn QueryExecutor + Send + Sync + 'static>,
}
Expand All @@ -27,8 +23,8 @@ pub struct ContextBuilder {
legacy: bool,
force_transactions: bool,
enable_raw_queries: bool,
datamodel: String,
overwrite_datasources: Option<String>,
datamodel: Datamodel,
config: Configuration,
}

impl ContextBuilder {
Expand All @@ -47,40 +43,27 @@ impl ContextBuilder {
self
}

pub fn overwrite_datasources(mut self, val: Option<String>) -> Self {
self.overwrite_datasources = val;
self
}

pub async fn build(self) -> PrismaResult<PrismaContext> {
PrismaContext::new(
self.config,
self.datamodel,
self.legacy,
self.force_transactions,
self.enable_raw_queries,
self.datamodel,
self.overwrite_datasources,
)
.await
}
}

impl PrismaContext {
/// Initializes a new Prisma context.
/// Loads all immutable state for the query engine:
/// 1. The data model. This has different options on how to initialize. See data_model_loader module. The Prisma configuration (prisma.yml) is used as fallback.
/// 2. The data model is converted to the internal data model.
/// 3. The api query schema is constructed from the internal data model.
async fn new(
config: Configuration,
dm: Datamodel,
legacy: bool,
force_transactions: bool,
enable_raw_queries: bool,
datamodel: String,
overwrite_datasources: Option<String>,
) -> PrismaResult<Self> {
let dm = datamodel::parse_datamodel(&datamodel)
.map_err(|errors| PrismaError::ConversionError(errors, datamodel.clone()))?;

let config = configuration::load(&datamodel, overwrite_datasources, false)?;
let template = DatamodelConverter::convert(&dm);

// We only support one data source at the moment, so take the first one (default not exposed yet).
Expand All @@ -96,20 +79,12 @@ impl PrismaContext {
let internal_data_model = template.build(db_name);

// Construct query schema
let build_mode = if legacy {
BuildMode::Legacy
} else {
BuildMode::Modern
};
let build_mode = if legacy { BuildMode::Legacy } else { BuildMode::Modern };

let capabilities = SupportedCapabilities::empty(); // todo connector capabilities.

let schema_builder = QuerySchemaBuilder::new(
&internal_data_model,
&capabilities,
build_mode,
enable_raw_queries,
);
let schema_builder =
QuerySchemaBuilder::new(&internal_data_model, &capabilities, build_mode, enable_raw_queries);

let query_schema: QuerySchemaRef = Arc::new(schema_builder.build());

Expand All @@ -120,13 +95,13 @@ impl PrismaContext {
})
}

pub fn builder(datamodel: String) -> ContextBuilder {
pub fn builder(config: Configuration, datamodel: Datamodel) -> ContextBuilder {
ContextBuilder {
legacy: false,
force_transactions: false,
enable_raw_queries: false,
overwrite_datasources: None,
datamodel,
config,
}
}

Expand Down
5 changes: 1 addition & 4 deletions query-engine/prisma/src/dmmf/mod.rs
Expand Up @@ -72,10 +72,7 @@ impl Serialize for DMMFMapping {
}
}

pub fn render_dmmf(
dml: &datamodel::Datamodel,
query_schema: QuerySchemaRef,
) -> DataModelMetaFormat {
pub fn render_dmmf(dml: &datamodel::Datamodel, query_schema: QuerySchemaRef) -> DataModelMetaFormat {
let (schema, mappings) = DMMFQuerySchemaRenderer::render(query_schema);
let datamodel_json = datamodel::json::dmmf::render_to_dmmf_value(&dml);

Expand Down
10 changes: 2 additions & 8 deletions query-engine/prisma/src/dmmf/schema/field_renderer.rs
Expand Up @@ -16,11 +16,7 @@ impl<'a> Renderer<'a, DMMFFieldWrapper> for DMMFFieldRenderer {
}

impl DMMFFieldRenderer {
fn render_input_field(
&self,
input_field: InputFieldRef,
ctx: &RenderContext,
) -> DMMFFieldWrapper {
fn render_input_field(&self, input_field: InputFieldRef, ctx: &RenderContext) -> DMMFFieldWrapper {
let type_info = input_field.field_type.into_renderer().render(ctx);
let field = DMMFInputField {
name: input_field.name.clone(),
Expand All @@ -44,9 +40,7 @@ impl DMMFFieldRenderer {
}

fn render_arguments(&self, args: &[Argument], ctx: &RenderContext) -> Vec<DMMFArgument> {
args.iter()
.map(|arg| self.render_argument(arg, ctx))
.collect()
args.iter().map(|arg| self.render_argument(arg, ctx)).collect()
}

fn render_argument(&self, arg: &Argument, ctx: &RenderContext) -> DMMFArgument {
Expand Down
4 changes: 1 addition & 3 deletions query-engine/prisma/src/dmmf/schema/mod.rs
Expand Up @@ -92,9 +92,7 @@ impl RenderContext {
let model_name = m.model.name.clone();
let tag_str = format!("{}", m.tag);
let mut mappings = self.mappings.borrow_mut();
let mapping = mappings
.iter()
.find(|mapping| mapping.model_name == model_name);
let mapping = mappings.iter().find(|mapping| mapping.model_name == model_name);

match mapping {
Some(ref existing) => existing.add_operation(tag_str, name.clone()),
Expand Down

0 comments on commit 8fd19f9

Please sign in to comment.