这是indexloc提供的服务,不要输入任何密码
Skip to content

Change procedure to mutation #70

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

Merged
merged 5 commits into from
May 1, 2024
Merged
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ This changelog documents the changes between release versions.
- Add root `configuration.json` or `configuration.yaml` file to allow editing cli options. ([#68](https://github.com/hasura/ndc-mongodb/pull/68))
- Update default sample size to 100. ([#68](https://github.com/hasura/ndc-mongodb/pull/68))
- Add `all_schema_nullable` option defaulted to true. ([#68](https://github.com/hasura/ndc-mongodb/pull/68))
- Change `native_procedure` to `native_mutation` along with code renaming ([#70](https://github.com/hasura/ndc-mongodb/pull/70))
- Note: `native_procedures` folder in configuration is not deprecated. It will continue to work for a few releases, but renaming your folder is all that is needed.

## [0.0.5] - 2024-04-26
- Fix incorrect order of results for query requests with more than 10 variable sets (#37)
Expand Down
58 changes: 29 additions & 29 deletions crates/configuration/src/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use ndc_models as ndc;
use serde::{Deserialize, Serialize};

use crate::{
native_procedure::NativeProcedure,
native_mutation::NativeMutation,
native_query::{NativeQuery, NativeQueryRepresentation},
read_directory, schema, serialized,
};
Expand All @@ -28,22 +28,22 @@ pub struct Configuration {
/// response.
pub functions: BTreeMap<String, (ndc::FunctionInfo, ndc::CollectionInfo)>,

/// Procedures are based on native procedures.
pub procedures: BTreeMap<String, ndc::ProcedureInfo>,
/// Mutations are based on native mutations.
pub mutations: BTreeMap<String, ndc::ProcedureInfo>,

/// Native procedures allow arbitrary MongoDB commands where types of results are
/// Native murations allow arbitrary MongoDB commands where types of results are
/// specified via user configuration.
pub native_procedures: BTreeMap<String, NativeProcedure>,
pub native_mutations: BTreeMap<String, NativeMutation>,

/// Native queries allow arbitrary aggregation pipelines that can be included in a query plan.
pub native_queries: BTreeMap<String, NativeQuery>,

/// Object types defined for this connector include types of documents in each collection,
/// types for objects inside collection documents, types for native query and native procedure
/// types for objects inside collection documents, types for native query and native mutation
/// arguments and results.
///
/// The object types here combine object type defined in files in the `schema/`,
/// `native_queries/`, and `native_procedures/` subdirectories in the connector configuration
/// `native_queries/`, and `native_mutations/` subdirectories in the connector configuration
/// directory.
pub object_types: BTreeMap<String, schema::ObjectType>,

Expand All @@ -53,11 +53,11 @@ pub struct Configuration {
impl Configuration {
pub fn validate(
schema: serialized::Schema,
native_procedures: BTreeMap<String, serialized::NativeProcedure>,
native_mutations: BTreeMap<String, serialized::NativeMutation>,
native_queries: BTreeMap<String, serialized::NativeQuery>,
options: ConfigurationOptions
) -> anyhow::Result<Self> {
let object_types_iter = || merge_object_types(&schema, &native_procedures, &native_queries);
let object_types_iter = || merge_object_types(&schema, &native_mutations, &native_queries);
let object_type_errors = {
let duplicate_type_names: Vec<&str> = object_types_iter()
.map(|(name, _)| name.as_ref())
Expand All @@ -81,7 +81,7 @@ impl Configuration {
.map(|(name, nq)| (name, nq.into()))
.collect();

let internal_native_procedures: BTreeMap<_, _> = native_procedures
let internal_native_mutations: BTreeMap<_, _> = native_mutations
.into_iter()
.map(|(name, np)| (name, np.into()))
.collect();
Expand Down Expand Up @@ -129,12 +129,12 @@ impl Configuration {
})
.partition_result();

let procedures = internal_native_procedures
let mutations = internal_native_mutations
.iter()
.map(|(name, native_procedure)| {
.map(|(name, native_mutation)| {
(
name.to_owned(),
native_procedure_to_procedure_info(name, native_procedure),
native_mutation_to_mutation_info(name, native_mutation),
)
})
.collect();
Expand All @@ -153,8 +153,8 @@ impl Configuration {
Ok(Configuration {
collections,
functions,
procedures,
native_procedures: internal_native_procedures,
mutations,
native_mutations: internal_native_mutations,
native_queries: internal_native_queries,
object_types,
options
Expand Down Expand Up @@ -204,18 +204,18 @@ impl Default for ConfigurationIntrospectionOptions {

fn merge_object_types<'a>(
schema: &'a serialized::Schema,
native_procedures: &'a BTreeMap<String, serialized::NativeProcedure>,
native_mutations: &'a BTreeMap<String, serialized::NativeMutation>,
native_queries: &'a BTreeMap<String, serialized::NativeQuery>,
) -> impl Iterator<Item = (&'a String, &'a schema::ObjectType)> {
let object_types_from_schema = schema.object_types.iter();
let object_types_from_native_procedures = native_procedures
let object_types_from_native_mutations = native_mutations
.values()
.flat_map(|native_procedure| &native_procedure.object_types);
.flat_map(|native_mutation| &native_mutation.object_types);
let object_types_from_native_queries = native_queries
.values()
.flat_map(|native_query| &native_query.object_types);
object_types_from_schema
.chain(object_types_from_native_procedures)
.chain(object_types_from_native_mutations)
.chain(object_types_from_native_queries)
}

Expand Down Expand Up @@ -305,15 +305,15 @@ fn function_result_type(
Ok(value_field.r#type.clone().into())
}

fn native_procedure_to_procedure_info(
procedure_name: &str,
procedure: &NativeProcedure,
fn native_mutation_to_mutation_info(
mutation_name: &str,
mutation: &NativeMutation,
) -> ndc::ProcedureInfo {
ndc::ProcedureInfo {
name: procedure_name.to_owned(),
description: procedure.description.clone(),
arguments: arguments_to_ndc_arguments(procedure.arguments.clone()),
result_type: procedure.result_type.clone().into(),
name: mutation_name.to_owned(),
description: mutation.description.clone(),
arguments: arguments_to_ndc_arguments(mutation.arguments.clone()),
result_type: mutation.result_type.clone().into(),
}
}

Expand Down Expand Up @@ -364,9 +364,9 @@ mod tests {
.into_iter()
.collect(),
};
let native_procedures = [(
let native_mutations = [(
"hello".to_owned(),
serialized::NativeProcedure {
serialized::NativeMutation {
object_types: [(
"Album".to_owned(),
schema::ObjectType {
Expand All @@ -385,7 +385,7 @@ mod tests {
)]
.into_iter()
.collect();
let result = Configuration::validate(schema, native_procedures, Default::default(), Default::default());
let result = Configuration::validate(schema, native_mutations, Default::default(), Default::default());
let error_msg = result.unwrap_err().to_string();
assert!(error_msg.contains("multiple definitions"));
assert!(error_msg.contains("Album"));
Expand Down
21 changes: 17 additions & 4 deletions crates/configuration/src/directory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,16 @@ use tokio_stream::wrappers::ReadDirStream;
use crate::{configuration::ConfigurationOptions, serialized::Schema, with_name::WithName, Configuration};

pub const SCHEMA_DIRNAME: &str = "schema";
pub const NATIVE_PROCEDURES_DIRNAME: &str = "native_procedures";
pub const NATIVE_MUTATIONS_DIRNAME: &str = "native_mutations";
pub const NATIVE_QUERIES_DIRNAME: &str = "native_queries";
pub const CONFIGURATION_OPTIONS_BASENAME: &str = "configuration";
pub const CONFIGURATION_OPTIONS_METADATA: &str = ".configuration_metadata";

// Deprecated: Discussion came out that we standardize names and the decision
// was to use `native_mutations`. We should leave this in for a few releases
// with some CHANGELOG/Docs messaging around deprecation
pub const NATIVE_PROCEDURES_DIRNAME: &str = "native_procedures";

pub const CONFIGURATION_EXTENSIONS: [(&str, FileFormat); 3] =
[("json", JSON), ("yaml", YAML), ("yml", YAML)];
pub const DEFAULT_EXTENSION: &str = "json";
Expand All @@ -40,23 +45,31 @@ pub async fn read_directory(
.unwrap_or_default();
let schema = schemas.into_values().fold(Schema::default(), Schema::merge);

// Deprecated see message above at NATIVE_PROCEDURES_DIRNAME
let native_procedures = read_subdir_configs(&dir.join(NATIVE_PROCEDURES_DIRNAME))
.await?
.unwrap_or_default();

// TODO: Once we fully remove `native_procedures` after a deprecation period we can remove `mut`
let mut native_mutations = read_subdir_configs(&dir.join(NATIVE_MUTATIONS_DIRNAME))
.await?
.unwrap_or_default();

let native_queries = read_subdir_configs(&dir.join(NATIVE_QUERIES_DIRNAME))
.await?
.unwrap_or_default();

let options = parse_configuration_options_file(dir)
.await;

Configuration::validate(schema, native_procedures, native_queries, options)
native_mutations.extend(native_procedures.into_iter());

Configuration::validate(schema, native_mutations, native_queries, options)
}

/// Parse all files in a directory with one of the allowed configuration extensions according to
/// the given type argument. For example if `T` is `NativeProcedure` this function assumes that all
/// json and yaml files in the given directory should be parsed as native procedure configurations.
/// the given type argument. For example if `T` is `NativeMutation` this function assumes that all
/// json and yaml files in the given directory should be parsed as native mutation configurations.
///
/// Assumes that every configuration file has a `name` field.
async fn read_subdir_configs<T>(subdir: &Path) -> anyhow::Result<Option<BTreeMap<String, T>>>
Expand Down
2 changes: 1 addition & 1 deletion crates/configuration/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
mod configuration;
mod directory;
pub mod native_procedure;
pub mod native_mutation;
pub mod native_query;
pub mod schema;
mod serialized;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,24 @@ use crate::{
serialized::{self},
};

/// Internal representation of Native Procedures. For doc comments see
/// [crate::serialized::NativeProcedure]
/// Internal representation of Native Mutations. For doc comments see
/// [crate::serialized::NativeMutation]
///
/// Note: this type excludes `name` and `object_types` from the serialized type. Object types are
/// intended to be merged into one big map so should not be accessed through values of this type.
/// Native query values are stored in maps so names should be taken from map keys.
#[derive(Clone, Debug)]
pub struct NativeProcedure {
pub struct NativeMutation {
pub result_type: Type,
pub arguments: BTreeMap<String, ObjectField>,
pub command: bson::Document,
pub selection_criteria: Option<SelectionCriteria>,
pub description: Option<String>,
}

impl From<serialized::NativeProcedure> for NativeProcedure {
fn from(value: serialized::NativeProcedure) -> Self {
NativeProcedure {
impl From<serialized::NativeMutation> for NativeMutation {
fn from(value: serialized::NativeMutation) -> Self {
NativeMutation {
result_type: value.result_type,
arguments: value.arguments,
command: value.command,
Expand Down
4 changes: 2 additions & 2 deletions crates/configuration/src/serialized/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
mod native_procedure;
mod native_mutation;
mod native_query;
mod schema;

pub use self::{native_procedure::NativeProcedure, native_query::NativeQuery, schema::Schema};
pub use self::{native_mutation::NativeMutation, native_query::NativeQuery, schema::Schema};
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,22 @@ use crate::schema::{ObjectField, ObjectType, Type};
/// An arbitrary database command using MongoDB's runCommand API.
/// See https://www.mongodb.com/docs/manual/reference/method/db.runCommand/
///
/// Native Procedures appear as "procedures" in your data graph.
/// Native Mutations appear as "mutations" in your data graph.
#[derive(Clone, Debug, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
pub struct NativeProcedure {
pub struct NativeMutation {
/// You may define object types here to reference in `result_type`. Any types defined here will
/// be merged with the definitions in `schema.json`. This allows you to maintain hand-written
/// types for native procedures without having to edit a generated `schema.json` file.
/// types for native mutations without having to edit a generated `schema.json` file.
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
pub object_types: BTreeMap<String, ObjectType>,

/// Type of data returned by the procedure. You may reference object types defined in the
/// Type of data returned by the mutation. You may reference object types defined in the
/// `object_types` list in this definition, or you may reference object types from
/// `schema.json`.
pub result_type: Type,

/// Arguments to be supplied for each procedure invocation. These will be substituted into the
/// Arguments to be supplied for each mutation invocation. These will be substituted into the
/// given `command`.
///
/// Argument values are standard JSON mapped from GraphQL input types, not Extended JSON.
Expand All @@ -40,7 +40,7 @@ pub struct NativeProcedure {
/// See https://www.mongodb.com/docs/manual/reference/mongodb-extended-json/
///
/// Keys and values in the command may contain placeholders of the form `{{variableName}}`
/// which will be substituted when the native procedure is executed according to the given
/// which will be substituted when the native mutation is executed according to the given
/// arguments.
///
/// Placeholders must be inside quotes so that the command can be stored in JSON format. If the
Expand Down
2 changes: 1 addition & 1 deletion crates/configuration/src/serialized/native_query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ pub struct NativeQuery {
/// The pipeline may include Extended JSON.
///
/// Keys and values in the pipeline may contain placeholders of the form `{{variableName}}`
/// which will be substituted when the native procedure is executed according to the given
/// which will be substituted when the native query is executed according to the given
/// arguments.
///
/// Placeholders must be inside quotes so that the pipeline can be stored in JSON format. If
Expand Down
2 changes: 1 addition & 1 deletion crates/integration-tests/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@

mod basic;
mod local_relationship;
mod native_procedure;
mod native_mutation;
mod native_query;
mod remote_relationship;
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use insta::assert_yaml_snapshot;
use serde_json::json;

#[tokio::test]
async fn updates_with_native_procedure() -> anyhow::Result<()> {
async fn updates_with_native_mutation() -> anyhow::Result<()> {
let id_1 = 5471;
let id_2 = 5472;
let mutation = r#"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
source: crates/integration-tests/src/tests/native_procedure.rs
source: crates/integration-tests/src/tests/native_mutation.rs
expression: "query(r#\"\n query {\n artist1: artist(where: { artistId: { _eq: 5471 } }, limit: 1) {\n artistId\n name\n }\n artist2: artist(where: { artistId: { _eq: 5472 } }, limit: 1) {\n artistId\n name\n }\n }\n \"#).run().await?"
---
data:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use http::StatusCode;
use mongodb::bson;
use thiserror::Error;

use crate::procedure::ProcedureError;
use crate::mutation::MutationError;

/// A superset of the DC-API `AgentError` type. This enum adds error cases specific to the MongoDB
/// agent.
Expand All @@ -21,7 +21,7 @@ pub enum MongoAgentError {
MongoDBSerialization(#[from] mongodb::bson::ser::Error),
MongoDBSupport(#[from] mongodb_support::error::Error),
NotImplemented(&'static str),
ProcedureError(#[from] ProcedureError),
MutationError(#[from] MutationError),
Serialization(serde_json::Error),
UnknownAggregationFunction(String),
UnspecifiedRelation(String),
Expand Down Expand Up @@ -76,7 +76,7 @@ impl MongoAgentError {
}
MongoDBSupport(err) => (StatusCode::BAD_REQUEST, ErrorResponse::new(&err)),
NotImplemented(missing_feature) => (StatusCode::BAD_REQUEST, ErrorResponse::new(&format!("The MongoDB agent does not yet support {missing_feature}"))),
ProcedureError(err) => (StatusCode::BAD_REQUEST, ErrorResponse::new(err)),
MutationError(err) => (StatusCode::BAD_REQUEST, ErrorResponse::new(err)),
Serialization(err) => (StatusCode::INTERNAL_SERVER_ERROR, ErrorResponse::new(&err)),
UnknownAggregationFunction(function) => (
StatusCode::BAD_REQUEST,
Expand Down
2 changes: 1 addition & 1 deletion crates/mongodb-agent-common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ pub mod health;
pub mod interface_types;
pub mod mongodb;
pub mod mongodb_connection;
pub mod procedure;
pub mod mutation;
pub mod query;
pub mod scalar_types_capabilities;
pub mod schema;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use thiserror::Error;
use crate::query::arguments::ArgumentError;

#[derive(Debug, Error)]
pub enum ProcedureError {
pub enum MutationError {
#[error("error executing mongodb command: {0}")]
ExecutionError(#[from] mongodb::error::Error),

Expand Down
Loading