Skip to content

Commit

Permalink
Update Rust SDK and add NDC v0.1.2 support (#42)
Browse files Browse the repository at this point in the history
  • Loading branch information
daniel-chambers committed Apr 17, 2024
1 parent 8b61723 commit 2931b2c
Show file tree
Hide file tree
Showing 7 changed files with 183 additions and 114 deletions.
22 changes: 9 additions & 13 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 4 additions & 30 deletions crates/mongodb-agent-common/src/scalar_types_capabilities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ pub fn aggregate_functions(
[(A::Count, S::Int)]
.into_iter()
.chain(iter_if(
is_ordered(scalar_type),
scalar_type.is_orderable(),
[A::Min, A::Max]
.into_iter()
.map(move |op| (op, scalar_type)),
))
.chain(iter_if(
is_numeric(scalar_type),
scalar_type.is_numeric(),
[A::Avg, A::Sum]
.into_iter()
.map(move |op| (op, scalar_type)),
Expand All @@ -44,11 +44,11 @@ pub fn comparison_operators(
scalar_type: BsonScalarType,
) -> impl Iterator<Item = (ComparisonFunction, BsonScalarType)> {
iter_if(
is_comparable(scalar_type),
scalar_type.is_comparable(),
[(C::Equal, scalar_type), (C::NotEqual, scalar_type)].into_iter(),
)
.chain(iter_if(
is_ordered(scalar_type),
scalar_type.is_orderable(),
[
C::LessThan,
C::LessThanOrEqual,
Expand Down Expand Up @@ -83,32 +83,6 @@ fn capabilities(scalar_type: BsonScalarType) -> ScalarTypeCapabilities {
}
}

fn numeric_types() -> [BsonScalarType; 4] {
[S::Double, S::Int, S::Long, S::Decimal]
}

fn is_numeric(scalar_type: BsonScalarType) -> bool {
numeric_types().contains(&scalar_type)
}

fn is_comparable(scalar_type: BsonScalarType) -> bool {
let not_comparable = [S::Regex, S::Javascript, S::JavascriptWithScope];
!not_comparable.contains(&scalar_type)
}

fn is_ordered(scalar_type: BsonScalarType) -> bool {
let ordered = [
S::Double,
S::Decimal,
S::Int,
S::Long,
S::String,
S::Date,
S::Timestamp,
];
ordered.contains(&scalar_type)
}

/// If `condition` is true returns an iterator with the same items as the given `iter` input.
/// Otherwise returns an empty iterator.
fn iter_if<Item>(condition: bool, iter: impl Iterator<Item = Item>) -> impl Iterator<Item = Item> {
Expand Down
60 changes: 0 additions & 60 deletions crates/mongodb-connector/src/api_type_conversions/capabilities.rs

This file was deleted.

2 changes: 0 additions & 2 deletions crates/mongodb-connector/src/api_type_conversions/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
mod capabilities;
mod conversion_error;
mod helpers;
mod query_request;
Expand All @@ -7,7 +6,6 @@ mod query_traversal;

#[allow(unused_imports)]
pub use self::{
capabilities::v2_to_v3_scalar_type_capabilities,
conversion_error::ConversionError,
query_request::{v3_to_v2_query_request, QueryContext},
query_response::{v2_to_v3_explain_response, v2_to_v3_query_response},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1270,7 +1270,7 @@ mod tests {
(
"Int".to_owned(),
ScalarType {
representation: Some(TypeRepresentation::Integer),
representation: Some(TypeRepresentation::Int32),
aggregate_functions: BTreeMap::from([(
"avg".into(),
AggregateFunctionDefinition {
Expand Down
105 changes: 97 additions & 8 deletions crates/mongodb-connector/src/capabilities.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
use std::collections::BTreeMap;

use mongodb_agent_common::scalar_types_capabilities::scalar_types_capabilities;
use mongodb_agent_common::{
comparison_function::ComparisonFunction,
scalar_types_capabilities::{aggregate_functions, comparison_operators},
};
use mongodb_support::BsonScalarType;
use ndc_sdk::models::{
Capabilities, CapabilitiesResponse, LeafCapability, QueryCapabilities,
RelationshipCapabilities, ScalarType,
AggregateFunctionDefinition, Capabilities, CapabilitiesResponse, ComparisonOperatorDefinition,
LeafCapability, QueryCapabilities, RelationshipCapabilities, ScalarType, Type,
TypeRepresentation,
};

use crate::api_type_conversions::v2_to_v3_scalar_type_capabilities;

pub fn mongo_capabilities_response() -> CapabilitiesResponse {
ndc_sdk::models::CapabilitiesResponse {
version: "0.1.1".to_owned(),
version: "0.1.2".to_owned(),
capabilities: Capabilities {
query: QueryCapabilities {
aggregates: Some(LeafCapability {}),
Expand All @@ -29,6 +32,92 @@ pub fn mongo_capabilities_response() -> CapabilitiesResponse {
}
}

pub fn scalar_types() -> BTreeMap<std::string::String, ScalarType> {
v2_to_v3_scalar_type_capabilities(scalar_types_capabilities())
pub fn scalar_types() -> BTreeMap<String, ScalarType> {
enum_iterator::all::<BsonScalarType>()
.map(make_scalar_type)
.chain([extended_json_scalar_type()])
.collect::<BTreeMap<_, _>>()
}

fn extended_json_scalar_type() -> (String, ScalarType) {
(
mongodb_support::EXTENDED_JSON_TYPE_NAME.to_owned(),
ScalarType {
representation: Some(TypeRepresentation::JSON),
aggregate_functions: BTreeMap::new(),
comparison_operators: BTreeMap::new(),
},
)
}

fn make_scalar_type(bson_scalar_type: BsonScalarType) -> (String, ScalarType) {
let scalar_type_name = bson_scalar_type.graphql_name();
let scalar_type = ScalarType {
representation: bson_scalar_type_representation(bson_scalar_type),
aggregate_functions: bson_aggregation_functions(bson_scalar_type),
comparison_operators: bson_comparison_operators(bson_scalar_type),
};
(scalar_type_name, scalar_type)
}

fn bson_scalar_type_representation(bson_scalar_type: BsonScalarType) -> Option<TypeRepresentation> {
match bson_scalar_type {
BsonScalarType::Double => Some(TypeRepresentation::Float64),
BsonScalarType::Decimal => Some(TypeRepresentation::BigDecimal), // Not quite.... Mongo Decimal is 128-bit, BigDecimal is unlimited
BsonScalarType::Int => Some(TypeRepresentation::Int32),
BsonScalarType::Long => Some(TypeRepresentation::Int64),
BsonScalarType::String => Some(TypeRepresentation::String),
BsonScalarType::Date => Some(TypeRepresentation::Timestamp), // Mongo Date is milliseconds since unix epoch
BsonScalarType::Timestamp => None, // Internal Mongo timestamp type
BsonScalarType::BinData => None,
BsonScalarType::ObjectId => Some(TypeRepresentation::String), // Mongo ObjectId is usually expressed as a 24 char hex string (12 byte number)
BsonScalarType::Bool => Some(TypeRepresentation::Boolean),
BsonScalarType::Null => None,
BsonScalarType::Regex => None,
BsonScalarType::Javascript => None,
BsonScalarType::JavascriptWithScope => None,
BsonScalarType::MinKey => None,
BsonScalarType::MaxKey => None,
BsonScalarType::Undefined => None,
BsonScalarType::DbPointer => None,
BsonScalarType::Symbol => None,
}
}

fn bson_aggregation_functions(
bson_scalar_type: BsonScalarType,
) -> BTreeMap<String, AggregateFunctionDefinition> {
aggregate_functions(bson_scalar_type)
.map(|(fn_name, result_type)| {
let aggregation_definition = AggregateFunctionDefinition {
result_type: bson_to_named_type(result_type),
};
(fn_name.graphql_name().to_owned(), aggregation_definition)
})
.collect()
}

fn bson_comparison_operators(
bson_scalar_type: BsonScalarType,
) -> BTreeMap<String, ComparisonOperatorDefinition> {
comparison_operators(bson_scalar_type)
.map(|(comparison_fn, arg_type)| {
let fn_name = comparison_fn.graphql_name().to_owned();
match comparison_fn {
ComparisonFunction::Equal => (fn_name, ComparisonOperatorDefinition::Equal),
_ => (
fn_name,
ComparisonOperatorDefinition::Custom {
argument_type: bson_to_named_type(arg_type),
},
),
}
})
.collect()
}

fn bson_to_named_type(bson_scalar_type: BsonScalarType) -> Type {
Type::Named {
name: bson_scalar_type.graphql_name(),
}
}
Loading

0 comments on commit 2931b2c

Please sign in to comment.