Skip to content

Commit

Permalink
Fix collection schemas not having a unique constraint for the _id c…
Browse files Browse the repository at this point in the history
…olumn (#32)
  • Loading branch information
daniel-chambers committed Apr 9, 2024
1 parent 3d151cf commit 1b96bb8
Show file tree
Hide file tree
Showing 13 changed files with 47 additions and 45 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ This changelog documents the changes between release versions.
- Fix bug in v2 to v3 conversion of query responses containing nested objects ([PR #27](https://github.com/hasura/ndc-mongodb/pull/27))
- Fixed bug where use of aggregate functions in queries would fail ([#26](https://github.com/hasura/ndc-mongodb/pull/26))
- Rename Any type to ExtendedJSON to make its representation clearer ([#30](https://github.com/hasura/ndc-mongodb/pull/30))
- The collection primary key `_id` property now has a unique constraint generated in the NDC schema for it ([#32](https://github.com/hasura/ndc-mongodb/pull/32))

## [0.0.3] - 2024-03-28
- Use separate schema files for each collection ([PR #14](https://github.com/hasura/ndc-mongodb/pull/14))
Expand Down
31 changes: 27 additions & 4 deletions crates/mongodb-connector/src/schema.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use lazy_static::lazy_static;
use mongodb_support::BsonScalarType;
use std::collections::BTreeMap;

use configuration::{native_procedure::NativeProcedure, schema, Configuration};
Expand All @@ -15,8 +16,8 @@ pub async fn get_schema(
config: &Configuration,
) -> Result<models::SchemaResponse, connector::SchemaError> {
let schema = &config.schema;
let collections = schema.collections.iter().map(map_collection).collect();
let object_types = config.object_types().map(map_object_type).collect();
let collections = schema.collections.iter().map(|(collection_name, collection)| map_collection(&object_types, collection_name, collection)).collect();

let procedures = config
.native_procedures
Expand Down Expand Up @@ -86,14 +87,36 @@ fn map_type(t: &schema::Type) -> models::Type {
map_normalized_type(&t.clone().normalize_type())
}

fn map_collection((name, collection): (&String, &schema::Collection)) -> models::CollectionInfo {
fn get_primary_key_uniqueness_constraint(object_types: &BTreeMap<String, models::ObjectType>, name: &str, collection: &schema::Collection) -> Option<(String, models::UniquenessConstraint)> {
// Check to make sure our collection's object type contains the _id objectid field
// If it doesn't (should never happen, all collections need an _id column), don't generate the constraint
let object_type = object_types.get(&collection.r#type)?;
let id_field = object_type.fields.get("_id")?;
match &id_field.r#type {
models::Type::Named { name } => {
if *name == BsonScalarType::ObjectId.graphql_name() { Some(()) } else { None }
},
models::Type::Nullable { .. } => None,
models::Type::Array { .. } => None,
models::Type::Predicate { .. } => None,
}?;
let uniqueness_constraint = models::UniquenessConstraint {
unique_columns: vec!["_id".into()]
};
let constraint_name = format!("{}_id", name);
Some((constraint_name, uniqueness_constraint))
}

fn map_collection(object_types: &BTreeMap<String, models::ObjectType>, name: &str, collection: &schema::Collection) -> models::CollectionInfo {
let pk_constraint = get_primary_key_uniqueness_constraint(object_types, name, collection);

models::CollectionInfo {
name: name.clone(),
name: name.to_owned(),
collection_type: collection.r#type.clone(),
description: collection.description.clone(),
arguments: Default::default(),
foreign_keys: Default::default(),
uniqueness_constraints: Default::default(),
uniqueness_constraints: BTreeMap::from_iter(pk_constraint),
}
}

Expand Down
6 changes: 2 additions & 4 deletions fixtures/connector/chinook/schema/Album.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,11 @@
},
"_id": {
"type": {
"nullable": {
"scalar": "objectId"
}
"scalar": "objectId"
}
}
},
"description": "Object type for collection Album"
}
}
}
}
6 changes: 2 additions & 4 deletions fixtures/connector/chinook/schema/Artist.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,11 @@
},
"_id": {
"type": {
"nullable": {
"scalar": "objectId"
}
"scalar": "objectId"
}
}
},
"description": "Object type for collection Artist"
}
}
}
}
6 changes: 2 additions & 4 deletions fixtures/connector/chinook/schema/Customer.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,11 @@
},
"_id": {
"type": {
"nullable": {
"scalar": "objectId"
}
"scalar": "objectId"
}
}
},
"description": "Object type for collection Customer"
}
}
}
}
6 changes: 2 additions & 4 deletions fixtures/connector/chinook/schema/Employee.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,11 @@
},
"_id": {
"type": {
"nullable": {
"scalar": "objectId"
}
"scalar": "objectId"
}
}
},
"description": "Object type for collection Employee"
}
}
}
}
6 changes: 2 additions & 4 deletions fixtures/connector/chinook/schema/Genre.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,11 @@
},
"_id": {
"type": {
"nullable": {
"scalar": "objectId"
}
"scalar": "objectId"
}
}
},
"description": "Object type for collection Genre"
}
}
}
}
4 changes: 1 addition & 3 deletions fixtures/connector/chinook/schema/Invoice.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,7 @@
},
"_id": {
"type": {
"nullable": {
"scalar": "objectId"
}
"scalar": "objectId"
}
}
},
Expand Down
4 changes: 1 addition & 3 deletions fixtures/connector/chinook/schema/InvoiceLine.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,7 @@
},
"_id": {
"type": {
"nullable": {
"scalar": "objectId"
}
"scalar": "objectId"
}
}
},
Expand Down
6 changes: 2 additions & 4 deletions fixtures/connector/chinook/schema/MediaType.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,11 @@
},
"_id": {
"type": {
"nullable": {
"scalar": "objectId"
}
"scalar": "objectId"
}
}
},
"description": "Object type for collection MediaType"
}
}
}
}
6 changes: 2 additions & 4 deletions fixtures/connector/chinook/schema/Playlist.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,11 @@
},
"_id": {
"type": {
"nullable": {
"scalar": "objectId"
}
"scalar": "objectId"
}
}
},
"description": "Object type for collection Playlist"
}
}
}
}
6 changes: 2 additions & 4 deletions fixtures/connector/chinook/schema/PlaylistTrack.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,11 @@
},
"_id": {
"type": {
"nullable": {
"scalar": "objectId"
}
"scalar": "objectId"
}
}
},
"description": "Object type for collection PlaylistTrack"
}
}
}
}
4 changes: 1 addition & 3 deletions fixtures/connector/chinook/schema/Track.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,7 @@
},
"_id": {
"type": {
"nullable": {
"scalar": "objectId"
}
"scalar": "objectId"
}
}
},
Expand Down

0 comments on commit 1b96bb8

Please sign in to comment.