diff --git a/README.md b/README.md index 434adc42..5dd1abcd 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ ## Requirements * Rust via Rustup -* MongoDB `>= 4` +* MongoDB `>= 5` * OpenSSL development files or get dependencies automatically with Nix diff --git a/crates/integration-tests/src/tests/local_relationship.rs b/crates/integration-tests/src/tests/local_relationship.rs new file mode 100644 index 00000000..6a897a58 --- /dev/null +++ b/crates/integration-tests/src/tests/local_relationship.rs @@ -0,0 +1,45 @@ +use crate::query; +use insta::assert_yaml_snapshot; +use serde_json::json; + +#[tokio::test] +async fn joins_local_relationships() -> anyhow::Result<()> { + assert_yaml_snapshot!( + query( + r#" + query { + movies(limit: 2, order_by: {title: Asc}, where: {title: {_iregex: "Rear"}}) { + id + title + comments(limit: 2, order_by: {id: Asc}) { + email + text + movie { + id + title + } + user { + email + comments(limit: 2, order_by: {id: Asc}) { + email + text + user { + email + comments(limit: 2, order_by: {id: Asc}) { + email + } + } + } + } + } + } + } + "# + ) + .variables(json!({ "limit": 11, "movies_limit": 2 })) + .run() + .await? + ); + Ok(()) +} + diff --git a/crates/integration-tests/src/tests/mod.rs b/crates/integration-tests/src/tests/mod.rs index a46760ec..d3b88c96 100644 --- a/crates/integration-tests/src/tests/mod.rs +++ b/crates/integration-tests/src/tests/mod.rs @@ -8,6 +8,7 @@ // mod basic; +mod local_relationship; mod native_procedure; mod native_query; mod remote_relationship; diff --git a/crates/integration-tests/src/tests/native_query.rs b/crates/integration-tests/src/tests/native_query.rs index e408ddc2..03d11002 100644 --- a/crates/integration-tests/src/tests/native_query.rs +++ b/crates/integration-tests/src/tests/native_query.rs @@ -16,3 +16,27 @@ async fn runs_native_query_with_function_representation() -> anyhow::Result<()> ); Ok(()) } + +#[tokio::test] +async fn runs_native_query_with_collection_representation() -> anyhow::Result<()> { + assert_yaml_snapshot!( + query( + r#" + query { + title_word_frequencies( + where: {count: {_eq: 2}} + order_by: {word: Asc} + offset: 100 + limit: 25 + ) { + word + count + } + } + "# + ) + .run() + .await? + ); + Ok(()) +} diff --git a/crates/integration-tests/src/tests/snapshots/integration_tests__tests__local_relationship__joins_local_relationships.snap b/crates/integration-tests/src/tests/snapshots/integration_tests__tests__local_relationship__joins_local_relationships.snap new file mode 100644 index 00000000..9ed9a0ee --- /dev/null +++ b/crates/integration-tests/src/tests/snapshots/integration_tests__tests__local_relationship__joins_local_relationships.snap @@ -0,0 +1,61 @@ +--- +source: crates/integration-tests/src/tests/local_relationship.rs +expression: "query(r#\"\n query {\n movies(limit: 2, order_by: {title: Asc}, where: {title: {_iregex: \"Rear\"}}) {\n id\n title\n comments(limit: 2, order_by: {id: Asc}) {\n email\n text\n movie {\n id\n title\n }\n user {\n email\n comments(limit: 2, order_by: {id: Asc}) {\n email\n text\n user {\n email\n comments(limit: 2, order_by: {id: Asc}) {\n email\n }\n }\n }\n }\n }\n }\n }\n \"#).variables(json!({\n \"limit\": 11, \"movies_limit\": 2\n })).run().await?" +--- +data: + movies: + - comments: + - email: iain_glen@gameofthron.es + movie: + id: + $oid: 573a1398f29313caabceb0b1 + title: A Night in the Life of Jimmy Reardon + text: Debitis tempore cum natus quaerat dolores quibusdam perferendis. Pariatur aspernatur officia libero quod pariatur nobis neque. Maiores non ipsam iste repellendus distinctio praesentium iure. + user: + comments: + - email: iain_glen@gameofthron.es + text: Minus sequi incidunt cum magnam. Quam voluptatum vitae ab voluptatum cum. Autem perferendis nisi nulla dolores aut recusandae. + user: + comments: + - email: iain_glen@gameofthron.es + - email: iain_glen@gameofthron.es + email: iain_glen@gameofthron.es + - email: iain_glen@gameofthron.es + text: Impedit consectetur ex cupiditate enim. Placeat assumenda reiciendis iste neque similique nesciunt aperiam. + user: + comments: + - email: iain_glen@gameofthron.es + - email: iain_glen@gameofthron.es + email: iain_glen@gameofthron.es + email: iain_glen@gameofthron.es + id: + $oid: 573a1398f29313caabceb0b1 + title: A Night in the Life of Jimmy Reardon + - comments: + - email: owen_teale@gameofthron.es + movie: + id: + $oid: 573a1394f29313caabcdfa00 + title: Rear Window + text: Nobis corporis rem hic ipsa cum impedit. Esse nihil cum est minima ducimus temporibus minima. Sed reprehenderit tempore similique nam. Ipsam nesciunt veniam aut amet ut. + user: + comments: + - email: owen_teale@gameofthron.es + text: A ut dolor illum deleniti repellendus. Iste fugit in quas minus nobis sunt rem. Animi possimus dolor alias natus consequatur saepe. Nihil quam magni aspernatur nisi. + user: + comments: + - email: owen_teale@gameofthron.es + - email: owen_teale@gameofthron.es + email: owen_teale@gameofthron.es + - email: owen_teale@gameofthron.es + text: Repudiandae repellat quia officiis. Quidem voluptatum vel id itaque et. Corrupti corporis magni voluptas quae itaque fugiat quae. + user: + comments: + - email: owen_teale@gameofthron.es + - email: owen_teale@gameofthron.es + email: owen_teale@gameofthron.es + email: owen_teale@gameofthron.es + id: + $oid: 573a1394f29313caabcdfa00 + title: Rear Window +errors: ~ diff --git a/crates/integration-tests/src/tests/snapshots/integration_tests__tests__native_query__runs_native_query_with_collection_representation.snap b/crates/integration-tests/src/tests/snapshots/integration_tests__tests__native_query__runs_native_query_with_collection_representation.snap new file mode 100644 index 00000000..c044a25f --- /dev/null +++ b/crates/integration-tests/src/tests/snapshots/integration_tests__tests__native_query__runs_native_query_with_collection_representation.snap @@ -0,0 +1,57 @@ +--- +source: crates/integration-tests/src/tests/native_query.rs +expression: "query(r#\"\n query {\n title_word_frequencies(\n where: {count: {_eq: 2}}\n order_by: {word: Asc}\n offset: 100\n limit: 25\n ) {\n word\n count\n }\n }\n \"#).run().await?" +--- +data: + title_word_frequencies: + - count: 2 + word: Amish + - count: 2 + word: Amor? + - count: 2 + word: Anara + - count: 2 + word: Anarchy + - count: 2 + word: Anastasia + - count: 2 + word: Anchorman + - count: 2 + word: Andre + - count: 2 + word: Andrei + - count: 2 + word: Andromeda + - count: 2 + word: Andrè + - count: 2 + word: Angela + - count: 2 + word: Angelica + - count: 2 + word: "Angels'" + - count: 2 + word: "Angels:" + - count: 2 + word: Angst + - count: 2 + word: Animation + - count: 2 + word: Annabelle + - count: 2 + word: Anonyma + - count: 2 + word: Anonymous + - count: 2 + word: Answer + - count: 2 + word: Ant + - count: 2 + word: Antarctic + - count: 2 + word: Antoinette + - count: 2 + word: Anybody + - count: 2 + word: Anywhere +errors: ~ diff --git a/fixtures/connector/sample_mflix/native_queries/title_word_requency.json b/fixtures/connector/sample_mflix/native_queries/title_word_requency.json new file mode 100644 index 00000000..b8306b2d --- /dev/null +++ b/fixtures/connector/sample_mflix/native_queries/title_word_requency.json @@ -0,0 +1,30 @@ +{ + "name": "title_word_frequency", + "representation": "collection", + "inputCollection": "movies", + "description": "words appearing in movie titles with counts", + "resultDocumentType": "TitleWordFrequency", + "objectTypes": { + "TitleWordFrequency": { + "fields": { + "_id": { "type": { "scalar": "string" } }, + "count": { "type": { "scalar": "int" } } + } + } + }, + "pipeline": [ + { + "$replaceWith": { + "title_words": { "$split": ["$title", " "] } + } + }, + { "$unwind": { "path": "$title_words" } }, + { + "$group": { + "_id": "$title_words", + "count": { "$count": {} } + } + } + ] +} + diff --git a/fixtures/ddn/sample_mflix/dataconnectors/sample_mflix.hml b/fixtures/ddn/sample_mflix/dataconnectors/sample_mflix.hml index 3ffc1172..091a6358 100644 --- a/fixtures/ddn/sample_mflix/dataconnectors/sample_mflix.hml +++ b/fixtures/ddn/sample_mflix/dataconnectors/sample_mflix.hml @@ -850,6 +850,10 @@ definition: type: type: named name: String + TitleWordFrequency: + fields: + _id: { type: { type: named, name: String } } + count: { type: { type: named, name: Int } } collections: - name: comments arguments: {} @@ -891,6 +895,14 @@ definition: unique_columns: - _id foreign_keys: {} + - name: title_word_frequency + arguments: {} + type: TitleWordFrequency + uniqueness_constraints: + title_word_frequency_id: + unique_columns: + - _id + foreign_keys: {} functions: - name: hello description: Basic test of native queries diff --git a/fixtures/ddn/sample_mflix/models/TitleWordFrequency.hml b/fixtures/ddn/sample_mflix/models/TitleWordFrequency.hml new file mode 100644 index 00000000..a1a58c7e --- /dev/null +++ b/fixtures/ddn/sample_mflix/models/TitleWordFrequency.hml @@ -0,0 +1,90 @@ +--- +kind: ObjectType +version: v1 +definition: + name: TitleWordFrequency + fields: + - name: word + type: String! + - name: count + type: Int! + graphql: + typeName: TitleWordFrequency + inputTypeName: TitleWordFrequencyInput + dataConnectorTypeMapping: + - dataConnectorName: sample_mflix + dataConnectorObjectType: TitleWordFrequency + fieldMapping: + word: + column: + name: _id + count: + column: + name: count + +--- +kind: TypePermissions +version: v1 +definition: + typeName: TitleWordFrequency + permissions: + - role: admin + output: + allowedFields: + - word + - count + +--- +kind: ObjectBooleanExpressionType +version: v1 +definition: + name: TitleWordFrequencyBoolExp + objectType: TitleWordFrequency + dataConnectorName: sample_mflix + dataConnectorObjectType: TitleWordFrequency + comparableFields: + - fieldName: word + operators: + enableAll: true + - fieldName: count + operators: + enableAll: true + graphql: + typeName: TitleWordFrequencyBoolExp + +--- +kind: Model +version: v1 +definition: + name: TitleWordFrequency + objectType: TitleWordFrequency + source: + dataConnectorName: sample_mflix + collection: title_word_frequency + filterExpressionType: TitleWordFrequencyBoolExp + orderableFields: + - fieldName: word + orderByDirections: + enableAll: true + - fieldName: count + orderByDirections: + enableAll: true + graphql: + selectMany: + queryRootField: title_word_frequencies + selectUniques: + - queryRootField: title_word_frequency + uniqueIdentifier: + - word + orderByExpressionType: TitleWordFrequencyOrderBy + +--- +kind: ModelPermissions +version: v1 +definition: + modelName: TitleWordFrequency + permissions: + - role: admin + select: + filter: null + diff --git a/fixtures/ddn/sample_mflix/relationships/movie_comments.hml b/fixtures/ddn/sample_mflix/relationships/movie_comments.hml new file mode 100644 index 00000000..fdb475b4 --- /dev/null +++ b/fixtures/ddn/sample_mflix/relationships/movie_comments.hml @@ -0,0 +1,35 @@ +kind: Relationship +version: v1 +definition: + name: comments + source: Movies + target: + model: + name: Comments + relationshipType: Array + mapping: + - source: + fieldPath: + - fieldName: id + target: + modelField: + - fieldName: movieId + +--- +kind: Relationship +version: v1 +definition: + name: movie + source: Comments + target: + model: + name: Movies + relationshipType: Object + mapping: + - source: + fieldPath: + - fieldName: movieId + target: + modelField: + - fieldName: id + diff --git a/fixtures/ddn/sample_mflix/relationships/user_comments.hml b/fixtures/ddn/sample_mflix/relationships/user_comments.hml new file mode 100644 index 00000000..25d5304d --- /dev/null +++ b/fixtures/ddn/sample_mflix/relationships/user_comments.hml @@ -0,0 +1,34 @@ +kind: Relationship +version: v1 +definition: + name: comments + source: Users + target: + model: + name: Comments + relationshipType: Array + mapping: + - source: + fieldPath: + - fieldName: email + target: + modelField: + - fieldName: email + +--- +kind: Relationship +version: v1 +definition: + name: user + source: Comments + target: + model: + name: Users + relationshipType: Object + mapping: + - source: + fieldPath: + - fieldName: email + target: + modelField: + - fieldName: email diff --git a/justfile b/justfile index afeb2633..94e74999 100644 --- a/justfile +++ b/justfile @@ -17,7 +17,6 @@ test-e2e: (_arion "arion-compose/e2e-testing.nix" "test") # Run `just test-integration` on several MongoDB versions test-mongodb-versions: - MONGODB_IMAGE=mongo:4 just test-integration # MONGODB_IMAGE=mongo:5 just test-integration # there's a problem with the native query example in v5 MONGODB_IMAGE=mongo:6 just test-integration MONGODB_IMAGE=mongo:7 just test-integration