diff --git a/Cargo.lock b/Cargo.lock index b694095b0..9db9936a0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1526,6 +1526,7 @@ dependencies = [ "clap", "insta", "ndc-postgres-configuration", + "schemars", "serde", "serde_json", "serde_yaml", diff --git a/changelog.md b/changelog.md index 94bf3beb6..a55f35b1e 100644 --- a/changelog.md +++ b/changelog.md @@ -2,6 +2,20 @@ ## [Unreleased] +### Changed + +- The ndc-postgres-cli `initialize` command will now generate + the jsonschema of the configuration format as well. + ([#361](https://github.com/hasura/ndc-postgres/pull/361)) +- A few fields in the configuration format has been changed: + + - `configureOptions` was renamed to `introspectionOptions` + - `connectionUri`, `poolSettings` and `isolationLevel` are now nested under `connectionSettings` + - `mutationsVersion` was moved from `configureOptions` to the top-level + - A new field was added: `$schema` references the jsonschema of the configuration format + + ([#361](https://github.com/hasura/ndc-postgres/pull/361)) + ## [v0.4.1] - 2024-03-06 ### Fixed diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index b7926f902..ac1097eea 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -12,6 +12,7 @@ ndc-postgres-configuration = { path = "../configuration" } anyhow = "1.0.80" clap = { version = "4.5.2", features = ["derive", "env"] } +schemars = { version = "0.8.16", features = ["smol_str", "preserve_order"] } serde = { version = "1.0.197", features = ["derive"] } serde_json = { version = "1.0.114", features = ["raw_value"] } serde_yaml = "0.9.32" diff --git a/crates/cli/src/lib.rs b/crates/cli/src/lib.rs index 613999fb3..8559686a4 100644 --- a/crates/cli/src/lib.rs +++ b/crates/cli/src/lib.rs @@ -26,6 +26,7 @@ pub enum Command { /// Initialize a configuration in the current (empty) directory. Initialize { #[arg(long)] + /// Whether to create the hasura connector metadata. with_metadata: bool, }, /// Update the configuration by introspecting the database, using the configuration options. @@ -75,6 +76,18 @@ async fn initialize(with_metadata: bool, context: Context) -> ) .await?; + // create the jsonschema file + let configuration_jsonschema_file_path = context + .context_path + .join(configuration::CONFIGURATION_JSONSCHEMA_FILENAME); + + let output = schemars::schema_for!(ndc_postgres_configuration::RawConfiguration); + fs::write( + &configuration_jsonschema_file_path, + serde_json::to_string_pretty(&output)?, + ) + .await?; + // if requested, create the metadata if with_metadata { let metadata_dir = context.context_path.join(".hasura-connector"); @@ -134,6 +147,7 @@ async fn update(context: Context) -> anyhow::Result<()> { serde_json::from_str(&configuration_file_contents)? }; let output = configuration::introspect(input, &context.environment).await?; + fs::write( &configuration_file_path, serde_json::to_string_pretty(&output)?, diff --git a/crates/cli/tests/update_tests.rs b/crates/cli/tests/update_tests.rs index 60035a142..64dc09900 100644 --- a/crates/cli/tests/update_tests.rs +++ b/crates/cli/tests/update_tests.rs @@ -17,8 +17,13 @@ async fn test_update_configuration() -> anyhow::Result<()> { { let configuration_file_path = dir.path().join("configuration.json"); + let connection_settings = + configuration::version3::connection_settings::DatabaseConnectionSettings { + connection_uri: connection_uri.clone(), + ..configuration::version3::connection_settings::DatabaseConnectionSettings::empty() + }; let input = RawConfiguration::Version3(configuration::version3::RawConfiguration { - connection_uri: connection_uri.clone(), + connection_settings, ..configuration::version3::RawConfiguration::empty() }); fs::write(configuration_file_path, serde_json::to_string(&input)?).await?; @@ -39,11 +44,11 @@ async fn test_update_configuration() -> anyhow::Result<()> { let output: RawConfiguration = serde_json::from_str(&contents)?; match output { RawConfiguration::Version3(configuration::version3::RawConfiguration { - connection_uri: updated_connection_uri, + connection_settings, metadata, .. }) => { - assert_eq!(updated_connection_uri, connection_uri); + assert_eq!(connection_settings.connection_uri, connection_uri); let some_table_metadata = metadata.tables.0.get("Artist"); assert!(some_table_metadata.is_some()); } diff --git a/crates/configuration/src/configuration.rs b/crates/configuration/src/configuration.rs index 0cf728112..4e29d9e44 100644 --- a/crates/configuration/src/configuration.rs +++ b/crates/configuration/src/configuration.rs @@ -14,6 +14,7 @@ use crate::values::{ConnectionUri, IsolationLevel, PoolSettings, Secret}; use crate::version3; pub const CONFIGURATION_FILENAME: &str = "configuration.json"; +pub const CONFIGURATION_JSONSCHEMA_FILENAME: &str = "schema.json"; /// The parsed connector configuration. #[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)] @@ -68,7 +69,7 @@ pub async fn parse_configuration( message: error.to_string(), })?; let connection_uri = - match configuration.connection_uri { + match configuration.connection_settings.connection_uri { ConnectionUri(Secret::Plain(uri)) => Ok(uri), ConnectionUri(Secret::FromEnvironment { variable }) => environment .read(&variable) @@ -79,9 +80,9 @@ pub async fn parse_configuration( }?; Ok(Configuration { metadata: configuration.metadata, - pool_settings: configuration.pool_settings, + pool_settings: configuration.connection_settings.pool_settings, connection_uri, - isolation_level: configuration.isolation_level, - mutations_version: configuration.configure_options.mutations_version, + isolation_level: configuration.connection_settings.isolation_level, + mutations_version: configuration.mutations_version, }) } diff --git a/crates/configuration/src/lib.rs b/crates/configuration/src/lib.rs index 3618eb721..1101cff67 100644 --- a/crates/configuration/src/lib.rs +++ b/crates/configuration/src/lib.rs @@ -7,6 +7,7 @@ pub mod version3; pub use configuration::{ introspect, parse_configuration, Configuration, RawConfiguration, CONFIGURATION_FILENAME, + CONFIGURATION_JSONSCHEMA_FILENAME, }; pub use error::Error; pub use values::{ConnectionUri, IsolationLevel, PoolSettings, Secret}; diff --git a/crates/configuration/src/version3/connection_settings.rs b/crates/configuration/src/version3/connection_settings.rs new file mode 100644 index 000000000..df6d0bb18 --- /dev/null +++ b/crates/configuration/src/version3/connection_settings.rs @@ -0,0 +1,33 @@ +//! Database connection settings. + +use crate::values::{ConnectionUri, IsolationLevel, PoolSettings, Secret}; +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +pub const DEFAULT_CONNECTION_URI_VARIABLE: &str = "CONNECTION_URI"; + +/// Database connection settings. +#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)] +#[serde(rename_all = "camelCase")] +pub struct DatabaseConnectionSettings { + /// Connection string for a Postgres-compatible database. + pub connection_uri: ConnectionUri, + /// Connection pool settings. + #[serde(default)] + pub pool_settings: PoolSettings, + /// Query isolation level. + #[serde(default)] + pub isolation_level: IsolationLevel, +} + +impl DatabaseConnectionSettings { + pub fn empty() -> Self { + Self { + connection_uri: ConnectionUri(Secret::FromEnvironment { + variable: DEFAULT_CONNECTION_URI_VARIABLE.into(), + }), + pool_settings: PoolSettings::default(), + isolation_level: IsolationLevel::default(), + } + } +} diff --git a/crates/configuration/src/version3/mod.rs b/crates/configuration/src/version3/mod.rs index 9499df2f6..b64c19497 100644 --- a/crates/configuration/src/version3/mod.rs +++ b/crates/configuration/src/version3/mod.rs @@ -1,6 +1,7 @@ //! Internal Configuration and state for our connector. mod comparison; +pub mod connection_settings; mod options; use std::borrow::Cow; @@ -17,39 +18,42 @@ use query_engine_metadata::metadata; use crate::environment::Environment; use crate::error::Error; -use crate::values::{ConnectionUri, IsolationLevel, PoolSettings, Secret}; +use crate::values::{ConnectionUri, Secret}; const CONFIGURATION_QUERY: &str = include_str!("version3.sql"); -pub const DEFAULT_CONNECTION_URI_VARIABLE: &str = "CONNECTION_URI"; - /// Initial configuration, just enough to connect to a database and elaborate a full /// 'Configuration'. #[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)] #[serde(rename_all = "camelCase")] pub struct RawConfiguration { - // Connection string for a Postgres-compatible database - pub connection_uri: ConnectionUri, - #[serde(default)] - pub pool_settings: PoolSettings, + /// Jsonschema of the configuration format. + #[serde(rename = "$schema")] #[serde(default)] - pub isolation_level: IsolationLevel, + pub schema: Option, + /// Database connection settings. + pub connection_settings: connection_settings::DatabaseConnectionSettings, + /// Connector metadata. #[serde(default)] pub metadata: metadata::Metadata, + /// Database introspection options. + #[serde(default)] + pub introspection_options: options::IntrospectionOptions, + /// Which version of the generated mutation procedures to include in the schema response #[serde(default)] - pub configure_options: options::ConfigureOptions, + pub mutations_version: Option, } impl RawConfiguration { pub fn empty() -> Self { Self { - connection_uri: ConnectionUri(Secret::FromEnvironment { - variable: DEFAULT_CONNECTION_URI_VARIABLE.into(), - }), - pool_settings: PoolSettings::default(), - isolation_level: IsolationLevel::default(), + schema: Some(crate::CONFIGURATION_JSONSCHEMA_FILENAME.to_string()), + connection_settings: connection_settings::DatabaseConnectionSettings::empty(), metadata: metadata::Metadata::default(), - configure_options: options::ConfigureOptions::default(), + introspection_options: options::IntrospectionOptions::default(), + // we'll change this to `Some(MutationsVersions::V1)` when we + // want to "release" this behaviour + mutations_version: None, } } } @@ -59,7 +63,7 @@ pub async fn validate_raw_configuration( file_path: PathBuf, config: RawConfiguration, ) -> Result { - match &config.connection_uri { + match &config.connection_settings.connection_uri { ConnectionUri(Secret::Plain(uri)) if uri.is_empty() => { Err(Error::EmptyConnectionUri { file_path }) } @@ -74,7 +78,7 @@ pub async fn introspect( args: RawConfiguration, environment: impl Environment, ) -> anyhow::Result { - let uri = match &args.connection_uri { + let uri = match &args.connection_settings.connection_uri { ConnectionUri(Secret::Plain(value)) => Cow::Borrowed(value), ConnectionUri(Secret::FromEnvironment { variable }) => { Cow::Owned(environment.read(variable)?) @@ -86,19 +90,19 @@ pub async fn introspect( .await?; let query = sqlx::query(CONFIGURATION_QUERY) - .bind(&args.configure_options.excluded_schemas) - .bind(&args.configure_options.unqualified_schemas_for_tables) + .bind(&args.introspection_options.excluded_schemas) + .bind(&args.introspection_options.unqualified_schemas_for_tables) .bind( &args - .configure_options + .introspection_options .unqualified_schemas_for_types_and_procedures, ) .bind(serde_json::to_value( - &args.configure_options.comparison_operator_mapping, + &args.introspection_options.comparison_operator_mapping, )?) .bind( &args - .configure_options + .introspection_options .introspect_prefix_function_comparison_operators, ); @@ -155,9 +159,8 @@ pub async fn introspect( filter_aggregate_functions(&scalar_types, aggregate_functions); Ok(RawConfiguration { - connection_uri: args.connection_uri, - pool_settings: args.pool_settings, - isolation_level: args.isolation_level, + schema: args.schema, + connection_settings: args.connection_settings, metadata: metadata::Metadata { tables, native_queries: args.metadata.native_queries, @@ -165,7 +168,8 @@ pub async fn introspect( comparison_operators: relevant_comparison_operators, composite_types: args.metadata.composite_types, }, - configure_options: args.configure_options, + introspection_options: args.introspection_options, + mutations_version: args.mutations_version, }) } @@ -175,15 +179,23 @@ pub fn occurring_scalar_types( tables: &metadata::TablesInfo, native_queries: &metadata::NativeQueries, ) -> BTreeSet { - let tables_column_types = tables.0.values().flat_map(|v| v.columns.values()); - let native_queries_column_types = native_queries.0.values().flat_map(|v| v.columns.values()); - let native_queries_arguments_types = - native_queries.0.values().flat_map(|v| v.arguments.values()); + let tables_column_types = tables + .0 + .values() + .flat_map(|v| v.columns.values().map(|c| &c.r#type)); + let native_queries_column_types = native_queries + .0 + .values() + .flat_map(|v| v.columns.values().map(|c| &c.r#type)); + let native_queries_arguments_types = native_queries + .0 + .values() + .flat_map(|v| v.arguments.values().map(|c| &c.r#type)); tables_column_types .chain(native_queries_column_types) .chain(native_queries_arguments_types) - .filter_map(|c| match c.r#type { + .filter_map(|t| match t { metadata::Type::ScalarType(ref t) => Some(t.clone()), // only keep scalar types metadata::Type::ArrayType(_) | metadata::Type::CompositeType(_) => None, }) diff --git a/crates/configuration/src/version3/options.rs b/crates/configuration/src/version3/options.rs index 10c425deb..e95d09049 100644 --- a/crates/configuration/src/version3/options.rs +++ b/crates/configuration/src/version3/options.rs @@ -3,14 +3,12 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use query_engine_metadata::metadata; - use super::comparison::ComparisonOperatorMapping; /// Options which only influence how the configuration is updated. #[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)] #[serde(rename_all = "camelCase")] -pub struct ConfigureOptions { +pub struct IntrospectionOptions { /// Schemas which are excluded from introspection. The default setting will exclude the /// internal schemas of Postgres, Citus, Cockroach, and the PostGIS extension. #[serde(default = "default_excluded_schemas")] @@ -25,9 +23,6 @@ pub struct ConfigureOptions { /// The mapping of comparison operator names to apply when updating the configuration #[serde(default = "ComparisonOperatorMapping::default_mappings")] pub comparison_operator_mapping: Vec, - /// Which version of the generated mutation procedures to include in the schema response - #[serde(default)] - pub mutations_version: Option, /// Which prefix functions (i.e., non-infix operators) to generate introspection metadata for. /// /// This list will accept any boolean-returning function taking two concrete scalar types as @@ -38,17 +33,14 @@ pub struct ConfigureOptions { pub introspect_prefix_function_comparison_operators: Vec, } -impl Default for ConfigureOptions { - fn default() -> ConfigureOptions { - ConfigureOptions { +impl Default for IntrospectionOptions { + fn default() -> IntrospectionOptions { + IntrospectionOptions { excluded_schemas: default_excluded_schemas(), unqualified_schemas_for_tables: default_unqualified_schemas_for_tables(), unqualified_schemas_for_types_and_procedures: default_unqualified_schemas_for_types_and_procedures(), comparison_operator_mapping: ComparisonOperatorMapping::default_mappings(), - // we'll change this to `Some(MutationsVersions::V1)` when we - // want to "release" this behaviour - mutations_version: None, introspect_prefix_function_comparison_operators: default_introspect_prefix_function_comparison_operators(), } diff --git a/crates/connectors/ndc-postgres/src/schema.rs b/crates/connectors/ndc-postgres/src/schema.rs index 0f5295b7c..e428964d0 100644 --- a/crates/connectors/ndc-postgres/src/schema.rs +++ b/crates/connectors/ndc-postgres/src/schema.rs @@ -163,12 +163,12 @@ pub async fn get_schema( arguments: info .arguments .iter() - .map(|(name, column_info)| { + .map(|(name, readonly_column_info)| { ( name.clone(), models::ArgumentInfo { - description: column_info.description.clone(), - argument_type: column_to_type(column_info), + description: readonly_column_info.description.clone(), + argument_type: readonly_column_to_type(readonly_column_info), }, ) }) @@ -208,7 +208,7 @@ pub async fn get_schema( column.name.clone(), models::ObjectField { description: column.description.clone(), - r#type: column_to_type(column), + r#type: readonly_column_to_type(column), }, ) })), @@ -253,7 +253,7 @@ pub async fn get_schema( name.clone(), models::ArgumentInfo { description: column_info.description.clone(), - argument_type: column_to_type(column_info), + argument_type: readonly_column_to_type(column_info), }, ) }) @@ -286,6 +286,7 @@ pub async fn get_schema( }) } +/// Extract the models::Type representation of a column. fn column_to_type(column: &metadata::ColumnInfo) -> models::Type { match &column.nullable { metadata::Nullable::NonNullable => type_to_type(&column.r#type), @@ -295,6 +296,16 @@ fn column_to_type(column: &metadata::ColumnInfo) -> models::Type { } } +/// Extract the models::Type representation of a readonly column. +fn readonly_column_to_type(column: &metadata::ReadOnlyColumnInfo) -> models::Type { + match &column.nullable { + metadata::Nullable::NonNullable => type_to_type(&column.r#type), + metadata::Nullable::Nullable => models::Type::Nullable { + underlying_type: Box::new(type_to_type(&column.r#type)), + }, + } +} + fn type_to_type(typ: &metadata::Type) -> models::Type { match &typ { metadata::Type::ArrayType(typ) => models::Type::Array { diff --git a/crates/query-engine/metadata/src/metadata/native_queries.rs b/crates/query-engine/metadata/src/metadata/native_queries.rs index 372d07418..2c53fd4e2 100644 --- a/crates/query-engine/metadata/src/metadata/native_queries.rs +++ b/crates/query-engine/metadata/src/metadata/native_queries.rs @@ -22,10 +22,10 @@ pub struct NativeQueryInfo { /// such as `SELECT * FROM authors WHERE name = {{author_name}}` pub sql: NativeQuerySql, /// Columns returned by the Native Query - pub columns: BTreeMap, + pub columns: BTreeMap, #[serde(default)] /// Names and types of arguments that can be passed to this Native Query - pub arguments: BTreeMap, + pub arguments: BTreeMap, #[serde(default)] pub description: Option, /// True if this native query mutates the database @@ -34,6 +34,18 @@ pub struct NativeQueryInfo { pub is_procedure: bool, } +/// Information about a native query column. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)] +#[serde(rename_all = "camelCase")] +pub struct ReadOnlyColumnInfo { + pub name: String, + pub r#type: Type, + #[serde(default)] + pub nullable: Nullable, + #[serde(default)] + pub description: Option, +} + /// A part of a Native Query text, either raw text or a parameter. #[derive(Debug, Clone, PartialEq, Eq)] pub enum NativeQueryPart { diff --git a/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__configuration_tests__get_configuration_schema.snap b/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__configuration_tests__get_configuration_schema.snap index 7f930b522..76fd0dc95 100644 --- a/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__configuration_tests__get_configuration_schema.snap +++ b/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__configuration_tests__get_configuration_schema.snap @@ -11,7 +11,7 @@ expression: schema "description": "Initial configuration, just enough to connect to a database and elaborate a full 'Configuration'.", "type": "object", "required": [ - "connectionUri", + "connectionSettings", "version" ], "properties": { @@ -21,31 +21,24 @@ expression: schema "3" ] }, - "connectionUri": { - "$ref": "#/definitions/ConnectionUri" - }, - "poolSettings": { - "default": { - "maxConnections": 50, - "poolTimeout": 30, - "idleTimeout": 180, - "connectionLifetime": 600 - }, - "allOf": [ - { - "$ref": "#/definitions/PoolSettings" - } + "$schema": { + "description": "Jsonschema of the configuration format.", + "default": null, + "type": [ + "string", + "null" ] }, - "isolationLevel": { - "default": "ReadCommitted", + "connectionSettings": { + "description": "Database connection settings.", "allOf": [ { - "$ref": "#/definitions/IsolationLevel" + "$ref": "#/definitions/DatabaseConnectionSettings" } ] }, "metadata": { + "description": "Connector metadata.", "default": { "tables": {}, "compositeTypes": {}, @@ -59,7 +52,8 @@ expression: schema } ] }, - "configureOptions": { + "introspectionOptions": { + "description": "Database introspection options.", "default": { "excludedSchemas": [ "information_schema", @@ -184,7 +178,6 @@ expression: schema "operatorKind": "custom" } ], - "mutationsVersion": null, "introspectPrefixFunctionComparisonOperators": [ "box_above", "box_below", @@ -316,7 +309,19 @@ expression: schema }, "allOf": [ { - "$ref": "#/definitions/ConfigureOptions" + "$ref": "#/definitions/IntrospectionOptions" + } + ] + }, + "mutationsVersion": { + "description": "Which version of the generated mutation procedures to include in the schema response", + "default": null, + "anyOf": [ + { + "$ref": "#/definitions/MutationsVersion" + }, + { + "type": "null" } ] } @@ -324,6 +329,46 @@ expression: schema } ], "definitions": { + "DatabaseConnectionSettings": { + "description": "Database connection settings.", + "type": "object", + "required": [ + "connectionUri" + ], + "properties": { + "connectionUri": { + "description": "Connection string for a Postgres-compatible database.", + "allOf": [ + { + "$ref": "#/definitions/ConnectionUri" + } + ] + }, + "poolSettings": { + "description": "Connection pool settings.", + "default": { + "maxConnections": 50, + "poolTimeout": 30, + "idleTimeout": 180, + "connectionLifetime": 600 + }, + "allOf": [ + { + "$ref": "#/definitions/PoolSettings" + } + ] + }, + "isolationLevel": { + "description": "Query isolation level.", + "default": "ReadCommitted", + "allOf": [ + { + "$ref": "#/definitions/IsolationLevel" + } + ] + } + } + }, "ConnectionUri": { "$ref": "#/definitions/Secret" }, @@ -762,7 +807,7 @@ expression: schema "description": "Columns returned by the Native Query", "type": "object", "additionalProperties": { - "$ref": "#/definitions/ColumnInfo" + "$ref": "#/definitions/ReadOnlyColumnInfo" } }, "arguments": { @@ -770,7 +815,7 @@ expression: schema "default": {}, "type": "object", "additionalProperties": { - "$ref": "#/definitions/ColumnInfo" + "$ref": "#/definitions/ReadOnlyColumnInfo" } }, "description": { @@ -789,6 +834,37 @@ expression: schema "Native_query_sql": { "type": "string" }, + "ReadOnlyColumnInfo": { + "description": "Information about a native query column.", + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "$ref": "#/definitions/Type" + }, + "nullable": { + "default": "nullable", + "allOf": [ + { + "$ref": "#/definitions/Nullable" + } + ] + }, + "description": { + "default": null, + "type": [ + "string", + "null" + ] + } + } + }, "AggregateFunctions": { "description": "All supported aggregate functions, grouped by type.", "type": "object", @@ -853,7 +929,7 @@ expression: schema "custom" ] }, - "ConfigureOptions": { + "IntrospectionOptions": { "description": "Options which only influence how the configuration is updated.", "type": "object", "properties": { @@ -1008,18 +1084,6 @@ expression: schema "$ref": "#/definitions/ComparisonOperatorMapping" } }, - "mutationsVersion": { - "description": "Which version of the generated mutation procedures to include in the schema response", - "default": null, - "anyOf": [ - { - "$ref": "#/definitions/MutationsVersion" - }, - { - "type": "null" - } - ] - }, "introspectPrefixFunctionComparisonOperators": { "description": "Which prefix functions (i.e., non-infix operators) to generate introspection metadata for.\n\nThis list will accept any boolean-returning function taking two concrete scalar types as arguments.\n\nThe default includes comparisons for various build-in types as well as those of PostGIS.", "default": [ diff --git a/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__configuration_tests__get_rawconfiguration_v3_schema.snap b/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__configuration_tests__get_rawconfiguration_v3_schema.snap index 2df4826b6..b7de07cbd 100644 --- a/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__configuration_tests__get_rawconfiguration_v3_schema.snap +++ b/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__configuration_tests__get_rawconfiguration_v3_schema.snap @@ -8,34 +8,27 @@ expression: schema "description": "Initial configuration, just enough to connect to a database and elaborate a full 'Configuration'.", "type": "object", "required": [ - "connectionUri" + "connectionSettings" ], "properties": { - "connectionUri": { - "$ref": "#/definitions/ConnectionUri" - }, - "poolSettings": { - "default": { - "maxConnections": 50, - "poolTimeout": 30, - "idleTimeout": 180, - "connectionLifetime": 600 - }, - "allOf": [ - { - "$ref": "#/definitions/PoolSettings" - } + "$schema": { + "description": "Jsonschema of the configuration format.", + "default": null, + "type": [ + "string", + "null" ] }, - "isolationLevel": { - "default": "ReadCommitted", + "connectionSettings": { + "description": "Database connection settings.", "allOf": [ { - "$ref": "#/definitions/IsolationLevel" + "$ref": "#/definitions/DatabaseConnectionSettings" } ] }, "metadata": { + "description": "Connector metadata.", "default": { "tables": {}, "compositeTypes": {}, @@ -49,7 +42,8 @@ expression: schema } ] }, - "configureOptions": { + "introspectionOptions": { + "description": "Database introspection options.", "default": { "excludedSchemas": [ "information_schema", @@ -174,7 +168,6 @@ expression: schema "operatorKind": "custom" } ], - "mutationsVersion": null, "introspectPrefixFunctionComparisonOperators": [ "box_above", "box_below", @@ -306,12 +299,64 @@ expression: schema }, "allOf": [ { - "$ref": "#/definitions/ConfigureOptions" + "$ref": "#/definitions/IntrospectionOptions" + } + ] + }, + "mutationsVersion": { + "description": "Which version of the generated mutation procedures to include in the schema response", + "default": null, + "anyOf": [ + { + "$ref": "#/definitions/MutationsVersion" + }, + { + "type": "null" } ] } }, "definitions": { + "DatabaseConnectionSettings": { + "description": "Database connection settings.", + "type": "object", + "required": [ + "connectionUri" + ], + "properties": { + "connectionUri": { + "description": "Connection string for a Postgres-compatible database.", + "allOf": [ + { + "$ref": "#/definitions/ConnectionUri" + } + ] + }, + "poolSettings": { + "description": "Connection pool settings.", + "default": { + "maxConnections": 50, + "poolTimeout": 30, + "idleTimeout": 180, + "connectionLifetime": 600 + }, + "allOf": [ + { + "$ref": "#/definitions/PoolSettings" + } + ] + }, + "isolationLevel": { + "description": "Query isolation level.", + "default": "ReadCommitted", + "allOf": [ + { + "$ref": "#/definitions/IsolationLevel" + } + ] + } + } + }, "ConnectionUri": { "$ref": "#/definitions/Secret" }, @@ -750,7 +795,7 @@ expression: schema "description": "Columns returned by the Native Query", "type": "object", "additionalProperties": { - "$ref": "#/definitions/ColumnInfo" + "$ref": "#/definitions/ReadOnlyColumnInfo" } }, "arguments": { @@ -758,7 +803,7 @@ expression: schema "default": {}, "type": "object", "additionalProperties": { - "$ref": "#/definitions/ColumnInfo" + "$ref": "#/definitions/ReadOnlyColumnInfo" } }, "description": { @@ -777,6 +822,37 @@ expression: schema "Native_query_sql": { "type": "string" }, + "ReadOnlyColumnInfo": { + "description": "Information about a native query column.", + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "$ref": "#/definitions/Type" + }, + "nullable": { + "default": "nullable", + "allOf": [ + { + "$ref": "#/definitions/Nullable" + } + ] + }, + "description": { + "default": null, + "type": [ + "string", + "null" + ] + } + } + }, "AggregateFunctions": { "description": "All supported aggregate functions, grouped by type.", "type": "object", @@ -841,7 +917,7 @@ expression: schema "custom" ] }, - "ConfigureOptions": { + "IntrospectionOptions": { "description": "Options which only influence how the configuration is updated.", "type": "object", "properties": { @@ -996,18 +1072,6 @@ expression: schema "$ref": "#/definitions/ComparisonOperatorMapping" } }, - "mutationsVersion": { - "description": "Which version of the generated mutation procedures to include in the schema response", - "default": null, - "anyOf": [ - { - "$ref": "#/definitions/MutationsVersion" - }, - { - "type": "null" - } - ] - }, "introspectPrefixFunctionComparisonOperators": { "description": "Which prefix functions (i.e., non-infix operators) to generate introspection metadata for.\n\nThis list will accept any boolean-returning function taking two concrete scalar types as arguments.\n\nThe default includes comparisons for various build-in types as well as those of PostGIS.", "default": [ diff --git a/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__configuration_tests__postgres_current_only_configure_v3_initial_configuration_is_unchanged.snap b/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__configuration_tests__postgres_current_only_configure_v3_initial_configuration_is_unchanged.snap index f15cad200..fc56b9811 100644 --- a/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__configuration_tests__postgres_current_only_configure_v3_initial_configuration_is_unchanged.snap +++ b/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__configuration_tests__postgres_current_only_configure_v3_initial_configuration_is_unchanged.snap @@ -3,16 +3,19 @@ source: crates/tests/databases-tests/src/postgres/configuration_tests.rs expression: default_configuration --- { - "connectionUri": { - "variable": "MAGIC_URI" - }, - "poolSettings": { - "maxConnections": 50, - "poolTimeout": 30, - "idleTimeout": 180, - "connectionLifetime": 600 + "$schema": "schema.json", + "connectionSettings": { + "connectionUri": { + "variable": "MAGIC_URI" + }, + "poolSettings": { + "maxConnections": 50, + "poolTimeout": 30, + "idleTimeout": 180, + "connectionLifetime": 600 + }, + "isolationLevel": "ReadCommitted" }, - "isolationLevel": "ReadCommitted", "metadata": { "tables": { "Album": { @@ -1776,7 +1779,7 @@ expression: default_configuration } } }, - "configureOptions": { + "introspectionOptions": { "excludedSchemas": [ "information_schema", "pg_catalog", @@ -1900,7 +1903,6 @@ expression: default_configuration "operatorKind": "custom" } ], - "mutationsVersion": null, "introspectPrefixFunctionComparisonOperators": [ "box_above", "box_below", @@ -2029,5 +2031,6 @@ expression: default_configuration "xmlvalidate", "xpath_exists" ] - } + }, + "mutationsVersion": null } diff --git a/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__openapi_tests__openapi__up_to_date_generated_schema.snap b/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__openapi_tests__openapi__up_to_date_generated_schema.snap index 40a6c9ba3..1598fcb42 100644 --- a/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__openapi_tests__openapi__up_to_date_generated_schema.snap +++ b/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__openapi_tests__openapi__up_to_date_generated_schema.snap @@ -11,7 +11,7 @@ expression: generated_schema_json "description": "Initial configuration, just enough to connect to a database and elaborate a full 'Configuration'.", "type": "object", "required": [ - "connectionUri", + "connectionSettings", "version" ], "properties": { @@ -21,31 +21,22 @@ expression: generated_schema_json "3" ] }, - "connectionUri": { - "$ref": "#/components/schemas/ConnectionUri" - }, - "poolSettings": { - "default": { - "maxConnections": 50, - "poolTimeout": 30, - "idleTimeout": 180, - "connectionLifetime": 600 - }, - "allOf": [ - { - "$ref": "#/components/schemas/PoolSettings" - } - ] + "$schema": { + "description": "Jsonschema of the configuration format.", + "default": null, + "type": "string", + "nullable": true }, - "isolationLevel": { - "default": "ReadCommitted", + "connectionSettings": { + "description": "Database connection settings.", "allOf": [ { - "$ref": "#/components/schemas/IsolationLevel" + "$ref": "#/components/schemas/DatabaseConnectionSettings" } ] }, "metadata": { + "description": "Connector metadata.", "default": { "tables": {}, "compositeTypes": {}, @@ -59,7 +50,8 @@ expression: generated_schema_json } ] }, - "configureOptions": { + "introspectionOptions": { + "description": "Database introspection options.", "default": { "excludedSchemas": [ "information_schema", @@ -184,7 +176,6 @@ expression: generated_schema_json "operatorKind": "custom" } ], - "mutationsVersion": null, "introspectPrefixFunctionComparisonOperators": [ "box_above", "box_below", @@ -316,14 +307,64 @@ expression: generated_schema_json }, "allOf": [ { - "$ref": "#/components/schemas/ConfigureOptions" + "$ref": "#/components/schemas/IntrospectionOptions" } ] + }, + "mutationsVersion": { + "description": "Which version of the generated mutation procedures to include in the schema response", + "default": null, + "allOf": [ + { + "$ref": "#/components/schemas/MutationsVersion" + } + ], + "nullable": true } } } ], "definitions": { + "DatabaseConnectionSettings": { + "description": "Database connection settings.", + "type": "object", + "required": [ + "connectionUri" + ], + "properties": { + "connectionUri": { + "description": "Connection string for a Postgres-compatible database.", + "allOf": [ + { + "$ref": "#/components/schemas/ConnectionUri" + } + ] + }, + "poolSettings": { + "description": "Connection pool settings.", + "default": { + "maxConnections": 50, + "poolTimeout": 30, + "idleTimeout": 180, + "connectionLifetime": 600 + }, + "allOf": [ + { + "$ref": "#/components/schemas/PoolSettings" + } + ] + }, + "isolationLevel": { + "description": "Query isolation level.", + "default": "ReadCommitted", + "allOf": [ + { + "$ref": "#/components/schemas/IsolationLevel" + } + ] + } + } + }, "ConnectionUri": { "$ref": "#/components/schemas/Secret" }, @@ -748,7 +789,7 @@ expression: generated_schema_json "description": "Columns returned by the Native Query", "type": "object", "additionalProperties": { - "$ref": "#/components/schemas/ColumnInfo" + "$ref": "#/components/schemas/ReadOnlyColumnInfo" } }, "arguments": { @@ -756,7 +797,7 @@ expression: generated_schema_json "default": {}, "type": "object", "additionalProperties": { - "$ref": "#/components/schemas/ColumnInfo" + "$ref": "#/components/schemas/ReadOnlyColumnInfo" } }, "description": { @@ -773,6 +814,35 @@ expression: generated_schema_json "Native_query_sql": { "type": "string" }, + "ReadOnlyColumnInfo": { + "description": "Information about a native query column.", + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "name": { + "type": "string" + }, + "type": { + "$ref": "#/components/schemas/Type" + }, + "nullable": { + "default": "nullable", + "allOf": [ + { + "$ref": "#/components/schemas/Nullable" + } + ] + }, + "description": { + "default": null, + "type": "string", + "nullable": true + } + } + }, "AggregateFunctions": { "description": "All supported aggregate functions, grouped by type.", "type": "object", @@ -837,7 +907,7 @@ expression: generated_schema_json "custom" ] }, - "ConfigureOptions": { + "IntrospectionOptions": { "description": "Options which only influence how the configuration is updated.", "type": "object", "properties": { @@ -992,16 +1062,6 @@ expression: generated_schema_json "$ref": "#/components/schemas/ComparisonOperatorMapping" } }, - "mutationsVersion": { - "description": "Which version of the generated mutation procedures to include in the schema response", - "default": null, - "allOf": [ - { - "$ref": "#/components/schemas/MutationsVersion" - } - ], - "nullable": true - }, "introspectPrefixFunctionComparisonOperators": { "description": "Which prefix functions (i.e., non-infix operators) to generate introspection metadata for.\n\nThis list will accept any boolean-returning function taking two concrete scalar types as arguments.\n\nThe default includes comparisons for various build-in types as well as those of PostGIS.", "default": [ diff --git a/crates/tests/tests-common/src/common_tests/configuration_v3_tests.rs b/crates/tests/tests-common/src/common_tests/configuration_v3_tests.rs index cf80da4c9..335b6b957 100644 --- a/crates/tests/tests-common/src/common_tests/configuration_v3_tests.rs +++ b/crates/tests/tests-common/src/common_tests/configuration_v3_tests.rs @@ -5,9 +5,7 @@ use similar_asserts::assert_eq; use tokio::fs; use ndc_postgres_configuration::environment::Variable; -use ndc_postgres_configuration::version3::{ - introspect, RawConfiguration, DEFAULT_CONNECTION_URI_VARIABLE, -}; +use ndc_postgres_configuration::version3::{connection_settings, introspect, RawConfiguration}; use ndc_postgres_configuration::{ConnectionUri, Secret}; use crate::ndc_metadata::helpers::get_path_from_project_root; @@ -27,7 +25,7 @@ pub async fn configure_is_idempotent( let args: RawConfiguration = serde_json::from_value(expected_value.clone())?; let environment = HashMap::from([( - DEFAULT_CONNECTION_URI_VARIABLE.into(), + connection_settings::DEFAULT_CONNECTION_URI_VARIABLE.into(), connection_string.into(), )]); @@ -43,10 +41,14 @@ pub async fn configure_initial_configuration_is_unchanged( connection_string: &str, ) -> RawConfiguration { let connection_uri_variable: Variable = "MAGIC_URI".into(); - let args = RawConfiguration { + let connection_settings = connection_settings::DatabaseConnectionSettings { connection_uri: ConnectionUri(Secret::FromEnvironment { variable: connection_uri_variable.clone(), }), + ..connection_settings::DatabaseConnectionSettings::empty() + }; + let args = RawConfiguration { + connection_settings, ..RawConfiguration::empty() }; let environment = HashMap::from([(connection_uri_variable, connection_string.into())]); diff --git a/crates/tests/tests-common/src/ndc_metadata/configuration.rs b/crates/tests/tests-common/src/ndc_metadata/configuration.rs index 538ba8406..7e417906f 100644 --- a/crates/tests/tests-common/src/ndc_metadata/configuration.rs +++ b/crates/tests/tests-common/src/ndc_metadata/configuration.rs @@ -5,7 +5,6 @@ use std::path::Path; use tokio::fs; -use ndc_postgres_configuration as configuration; use ndc_postgres_configuration::RawConfiguration; use super::helpers::get_path_from_project_root; @@ -45,11 +44,9 @@ pub async fn delete_ndc_metadata(ndc_metadata_path: impl AsRef) -> anyhow: fn set_connection_uri(input: RawConfiguration, connection_uri: String) -> RawConfiguration { match input { - RawConfiguration::Version3(config) => { - RawConfiguration::Version3(configuration::version3::RawConfiguration { - connection_uri: connection_uri.into(), - ..config - }) + RawConfiguration::Version3(mut config) => { + config.connection_settings.connection_uri = connection_uri.into(); + RawConfiguration::Version3(config) } } } diff --git a/crates/tests/tests-common/src/router.rs b/crates/tests/tests-common/src/router.rs index 610d6b36e..781cde31d 100644 --- a/crates/tests/tests-common/src/router.rs +++ b/crates/tests/tests-common/src/router.rs @@ -16,7 +16,8 @@ pub async fn create_router( // Initialize server state with the configuration above, injecting the URI. let environment = HashMap::from([( - ndc_postgres_configuration::version3::DEFAULT_CONNECTION_URI_VARIABLE.into(), + ndc_postgres_configuration::version3::connection_settings::DEFAULT_CONNECTION_URI_VARIABLE + .into(), connection_uri.to_string(), )]); let setup = PostgresSetup::new(environment); diff --git a/justfile b/justfile index 7b1a7cc78..0350c5b77 100644 --- a/justfile +++ b/justfile @@ -79,10 +79,6 @@ dev-citus: start-dependencies -x clippy \ -x 'run --bin ndc-postgres -- serve --configuration {{CITUS_V3_CHINOOK_NDC_METADATA}}' -# Generate the JSON Schema document for the the configuration. -document-jsonschema: - RUST_LOG=INFO cargo run --bin jsonschema-generator - # Generate the OpenAPI Schema document for the configuration. document-openapi: RUST_LOG=INFO cargo run --bin openapi-generator @@ -173,6 +169,13 @@ test *args: start-dependencies # re-generate the NDC metadata configuration file generate-configuration: build start-dependencies + # Generate the schema.json by initializing and then removing the configuration. + mkdir ./static/myschema + CONNECTION_URI='{{POSTGRESQL_EMPTY_CONNECTION_URI}}' HASURA_PLUGIN_CONNECTOR_CONTEXT_PATH='./static/myschema' \ + cargo run --bin ndc-postgres-cli -- initialize + mv ./static/myschema/schema.json ./static/schema.json + rm -r ./static/myschema + CONNECTION_URI='{{POSTGRESQL_EMPTY_CONNECTION_URI}}' HASURA_PLUGIN_CONNECTOR_CONTEXT_PATH='{{POSTGRES_BROKEN_QUERIES_NDC_METADATA}}' \ cargo run --bin ndc-postgres-cli -- update diff --git a/static/aurora/v3-chinook-ndc-metadata/configuration.json b/static/aurora/v3-chinook-ndc-metadata/configuration.json index 7c497c822..203f82594 100644 --- a/static/aurora/v3-chinook-ndc-metadata/configuration.json +++ b/static/aurora/v3-chinook-ndc-metadata/configuration.json @@ -1,15 +1,18 @@ { "version": "3", - "connectionUri": { - "variable": "CONNECTION_URI" - }, - "poolSettings": { - "maxConnections": 1, - "poolTimeout": 600, - "idleTimeout": 180, - "connectionLifetime": 600 + "$schema": "../../schema.json", + "connectionSettings": { + "connectionUri": { + "variable": "CONNECTION_URI" + }, + "poolSettings": { + "maxConnections": 1, + "poolTimeout": 600, + "idleTimeout": 180, + "connectionLifetime": 600 + }, + "isolationLevel": "ReadCommitted" }, - "isolationLevel": "ReadCommitted", "metadata": { "tables": { "Album": { diff --git a/static/citus/v3-chinook-ndc-metadata/configuration.json b/static/citus/v3-chinook-ndc-metadata/configuration.json index 4aea52d28..a87492212 100644 --- a/static/citus/v3-chinook-ndc-metadata/configuration.json +++ b/static/citus/v3-chinook-ndc-metadata/configuration.json @@ -1,15 +1,18 @@ { "version": "3", - "connectionUri": { - "variable": "CONNECTION_URI" - }, - "poolSettings": { - "maxConnections": 50, - "poolTimeout": 30, - "idleTimeout": 180, - "connectionLifetime": 600 + "$schema": "../../schema.json", + "connectionSettings": { + "connectionUri": { + "variable": "CONNECTION_URI" + }, + "poolSettings": { + "maxConnections": 50, + "poolTimeout": 30, + "idleTimeout": 180, + "connectionLifetime": 600 + }, + "isolationLevel": "ReadCommitted" }, - "isolationLevel": "ReadCommitted", "metadata": { "tables": { "Album": { @@ -2681,7 +2684,7 @@ } } }, - "configureOptions": { + "introspectionOptions": { "excludedSchemas": [ "information_schema", "pg_catalog", @@ -2803,7 +2806,6 @@ "operatorKind": "custom" } ], - "mutationsVersion": "v1", "introspectPrefixFunctionComparisonOperators": [ "box_above", "box_below", @@ -2932,5 +2934,6 @@ "xmlvalidate", "xpath_exists" ] - } + }, + "mutationsVersion": "v1" } diff --git a/static/cockroach/v3-chinook-ndc-metadata/configuration.json b/static/cockroach/v3-chinook-ndc-metadata/configuration.json index 59bf1dbec..f8b723dd7 100644 --- a/static/cockroach/v3-chinook-ndc-metadata/configuration.json +++ b/static/cockroach/v3-chinook-ndc-metadata/configuration.json @@ -1,15 +1,18 @@ { "version": "3", - "connectionUri": { - "variable": "CONNECTION_URI" - }, - "poolSettings": { - "maxConnections": 50, - "poolTimeout": 30, - "idleTimeout": 180, - "connectionLifetime": 600 + "$schema": "../../schema.json", + "connectionSettings": { + "connectionUri": { + "variable": "CONNECTION_URI" + }, + "poolSettings": { + "maxConnections": 50, + "poolTimeout": 30, + "idleTimeout": 180, + "connectionLifetime": 600 + }, + "isolationLevel": "ReadCommitted" }, - "isolationLevel": "ReadCommitted", "metadata": { "tables": { "Album": { @@ -2517,7 +2520,7 @@ } } }, - "configureOptions": { + "introspectionOptions": { "excludedSchemas": [ "information_schema", "pg_catalog", @@ -2639,7 +2642,6 @@ "operatorKind": "custom" } ], - "mutationsVersion": "v1", "introspectPrefixFunctionComparisonOperators": [ "box_above", "box_below", @@ -2768,5 +2770,6 @@ "xmlvalidate", "xpath_exists" ] - } + }, + "mutationsVersion": "v1" } diff --git a/static/postgres/broken-queries-ndc-metadata/configuration.json b/static/postgres/broken-queries-ndc-metadata/configuration.json index d885e27a1..9d1670f62 100644 --- a/static/postgres/broken-queries-ndc-metadata/configuration.json +++ b/static/postgres/broken-queries-ndc-metadata/configuration.json @@ -1,15 +1,18 @@ { "version": "3", - "connectionUri": { - "variable": "CONNECTION_URI" - }, - "poolSettings": { - "maxConnections": 50, - "poolTimeout": 30, - "idleTimeout": 180, - "connectionLifetime": 600 + "$schema": "../../schema.json", + "connectionSettings": { + "connectionUri": { + "variable": "CONNECTION_URI" + }, + "poolSettings": { + "maxConnections": 50, + "poolTimeout": 30, + "idleTimeout": 180, + "connectionLifetime": 600 + }, + "isolationLevel": "ReadCommitted" }, - "isolationLevel": "ReadCommitted", "metadata": { "tables": {}, "compositeTypes": {}, @@ -111,7 +114,7 @@ } } }, - "configureOptions": { + "introspectionOptions": { "excludedSchemas": [ "information_schema", "pg_catalog", @@ -233,7 +236,6 @@ "operatorKind": "custom" } ], - "mutationsVersion": "v1", "introspectPrefixFunctionComparisonOperators": [ "box_above", "box_below", @@ -362,5 +364,6 @@ "xmlvalidate", "xpath_exists" ] - } + }, + "mutationsVersion": "v1" } diff --git a/static/postgres/v3-chinook-ndc-metadata/configuration.json b/static/postgres/v3-chinook-ndc-metadata/configuration.json index a95eb1a5a..512d01ee3 100644 --- a/static/postgres/v3-chinook-ndc-metadata/configuration.json +++ b/static/postgres/v3-chinook-ndc-metadata/configuration.json @@ -1,15 +1,18 @@ { "version": "3", - "connectionUri": { - "variable": "CONNECTION_URI" - }, - "poolSettings": { - "maxConnections": 50, - "poolTimeout": 30, - "idleTimeout": 180, - "connectionLifetime": 600 + "$schema": "../../schema.json", + "connectionSettings": { + "connectionUri": { + "variable": "CONNECTION_URI" + }, + "poolSettings": { + "maxConnections": 50, + "poolTimeout": 30, + "idleTimeout": 180, + "connectionLifetime": 600 + }, + "isolationLevel": "ReadCommitted" }, - "isolationLevel": "ReadCommitted", "metadata": { "tables": { "Album": { @@ -3010,7 +3013,7 @@ } } }, - "configureOptions": { + "introspectionOptions": { "excludedSchemas": [ "information_schema", "pg_catalog", @@ -3132,7 +3135,6 @@ "operatorKind": "custom" } ], - "mutationsVersion": "v1", "introspectPrefixFunctionComparisonOperators": [ "box_above", "box_below", @@ -3261,5 +3263,6 @@ "xmlvalidate", "xpath_exists" ] - } + }, + "mutationsVersion": "v1" } diff --git a/static/schema.json b/static/schema.json new file mode 100644 index 000000000..cafdfa974 --- /dev/null +++ b/static/schema.json @@ -0,0 +1,1145 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "RawConfiguration", + "description": "The parsed connector configuration.", + "oneOf": [ + { + "description": "Initial configuration, just enough to connect to a database and elaborate a full 'Configuration'.", + "type": "object", + "required": ["connectionSettings", "version"], + "properties": { + "version": { + "type": "string", + "enum": ["3"] + }, + "$schema": { + "description": "Jsonschema of the configuration format.", + "default": null, + "type": ["string", "null"] + }, + "connectionSettings": { + "description": "Database connection settings.", + "allOf": [ + { + "$ref": "#/definitions/DatabaseConnectionSettings" + } + ] + }, + "metadata": { + "description": "Connector metadata.", + "default": { + "tables": {}, + "compositeTypes": {}, + "nativeQueries": {}, + "aggregateFunctions": {}, + "comparisonOperators": {} + }, + "allOf": [ + { + "$ref": "#/definitions/Metadata" + } + ] + }, + "introspectionOptions": { + "description": "Database introspection options.", + "default": { + "excludedSchemas": [ + "information_schema", + "pg_catalog", + "tiger", + "crdb_internal", + "columnar", + "columnar_internal" + ], + "unqualifiedSchemasForTables": ["public"], + "unqualifiedSchemasForTypesAndProcedures": [ + "public", + "pg_catalog", + "tiger" + ], + "comparisonOperatorMapping": [ + { + "operatorName": "=", + "exposedName": "_eq", + "operatorKind": "equal" + }, + { + "operatorName": "<=", + "exposedName": "_lte", + "operatorKind": "custom" + }, + { + "operatorName": ">", + "exposedName": "_gt", + "operatorKind": "custom" + }, + { + "operatorName": ">=", + "exposedName": "_gte", + "operatorKind": "custom" + }, + { + "operatorName": "<", + "exposedName": "_lt", + "operatorKind": "custom" + }, + { + "operatorName": "!=", + "exposedName": "_neq", + "operatorKind": "custom" + }, + { + "operatorName": "LIKE", + "exposedName": "_like", + "operatorKind": "custom" + }, + { + "operatorName": "NOT LIKE", + "exposedName": "_nlike", + "operatorKind": "custom" + }, + { + "operatorName": "ILIKE", + "exposedName": "_ilike", + "operatorKind": "custom" + }, + { + "operatorName": "NOT ILIKE", + "exposedName": "_nilike", + "operatorKind": "custom" + }, + { + "operatorName": "SIMILAR TO", + "exposedName": "_similar", + "operatorKind": "custom" + }, + { + "operatorName": "NOT SIMILAR TO", + "exposedName": "_nsimilar", + "operatorKind": "custom" + }, + { + "operatorName": "<>", + "exposedName": "_neq", + "operatorKind": "custom" + }, + { + "operatorName": "~~", + "exposedName": "_like", + "operatorKind": "custom" + }, + { + "operatorName": "!~~", + "exposedName": "_nlike", + "operatorKind": "custom" + }, + { + "operatorName": "~~*", + "exposedName": "_ilike", + "operatorKind": "custom" + }, + { + "operatorName": "!~~*", + "exposedName": "_nilike", + "operatorKind": "custom" + }, + { + "operatorName": "~", + "exposedName": "_regex", + "operatorKind": "custom" + }, + { + "operatorName": "!~", + "exposedName": "_nregex", + "operatorKind": "custom" + }, + { + "operatorName": "~*", + "exposedName": "_iregex", + "operatorKind": "custom" + }, + { + "operatorName": "!~*", + "exposedName": "_niregex", + "operatorKind": "custom" + } + ], + "introspectPrefixFunctionComparisonOperators": [ + "box_above", + "box_below", + "box_contain", + "box_contain_pt", + "box_contained", + "box_left", + "box_overabove", + "box_overbelow", + "box_overlap", + "box_overleft", + "box_overright", + "box_right", + "box_same", + "circle_above", + "circle_below", + "circle_contain", + "circle_contain_pt", + "circle_contained", + "circle_left", + "circle_overabove", + "circle_overbelow", + "circle_overlap", + "circle_overleft", + "circle_overright", + "circle_right", + "circle_same", + "contains_2d", + "equals", + "geography_overlaps", + "geometry_above", + "geometry_below", + "geometry_contained_3d", + "geometry_contains", + "geometry_contains_3d", + "geometry_contains_nd", + "geometry_left", + "geometry_overabove", + "geometry_overbelow", + "geometry_overlaps", + "geometry_overlaps_3d", + "geometry_overlaps_nd", + "geometry_overleft", + "geometry_overright", + "geometry_right", + "geometry_same", + "geometry_same_3d", + "geometry_same_nd", + "geometry_within", + "geometry_within_nd", + "inet_same_family", + "inter_lb", + "inter_sb", + "inter_sl", + "is_contained_2d", + "ishorizontal", + "isparallel", + "isperp", + "isvertical", + "jsonb_contained", + "jsonb_contains", + "jsonb_exists", + "jsonb_path_exists_opr", + "jsonb_path_match_opr", + "line_intersect", + "line_parallel", + "line_perp", + "lseg_intersect", + "lseg_parallel", + "lseg_perp", + "network_overlap", + "network_sub", + "network_sup", + "on_pb", + "on_pl", + "on_ppath", + "on_ps", + "on_sb", + "on_sl", + "overlaps_2d", + "path_contain_pt", + "path_inter", + "point_above", + "point_below", + "point_horiz", + "point_left", + "point_right", + "point_vert", + "poly_above", + "poly_below", + "poly_contain", + "poly_contain_pt", + "poly_contained", + "poly_left", + "poly_overabove", + "poly_overbelow", + "poly_overlap", + "poly_overleft", + "poly_overright", + "poly_right", + "poly_same", + "pt_contained_poly", + "st_3dintersects", + "st_contains", + "st_containsproperly", + "st_coveredby", + "st_covers", + "st_crosses", + "st_disjoint", + "st_equals", + "st_intersects", + "st_isvalid", + "st_orderingequals", + "st_overlaps", + "st_relatematch", + "st_touches", + "st_within", + "starts_with", + "ts_match_qv", + "ts_match_tq", + "ts_match_tt", + "ts_match_vq", + "tsq_mcontained", + "tsq_mcontains", + "xmlexists", + "xmlvalidate", + "xpath_exists" + ] + }, + "allOf": [ + { + "$ref": "#/definitions/IntrospectionOptions" + } + ] + }, + "mutationsVersion": { + "description": "Which version of the generated mutation procedures to include in the schema response", + "default": null, + "anyOf": [ + { + "$ref": "#/definitions/MutationsVersion" + }, + { + "type": "null" + } + ] + } + } + } + ], + "definitions": { + "DatabaseConnectionSettings": { + "description": "Database connection settings.", + "type": "object", + "required": ["connectionUri"], + "properties": { + "connectionUri": { + "description": "Connection string for a Postgres-compatible database.", + "allOf": [ + { + "$ref": "#/definitions/ConnectionUri" + } + ] + }, + "poolSettings": { + "description": "Connection pool settings.", + "default": { + "maxConnections": 50, + "poolTimeout": 30, + "idleTimeout": 180, + "connectionLifetime": 600 + }, + "allOf": [ + { + "$ref": "#/definitions/PoolSettings" + } + ] + }, + "isolationLevel": { + "description": "Query isolation level.", + "default": "ReadCommitted", + "allOf": [ + { + "$ref": "#/definitions/IsolationLevel" + } + ] + } + } + }, + "ConnectionUri": { + "$ref": "#/definitions/Secret" + }, + "Secret": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "object", + "required": ["variable"], + "properties": { + "variable": { + "$ref": "#/definitions/Variable" + } + } + } + ] + }, + "Variable": { + "description": "The name of an an environment variable.", + "type": "string" + }, + "PoolSettings": { + "description": "Settings for the PostgreSQL connection pool", + "type": "object", + "properties": { + "maxConnections": { + "description": "maximum number of pool connections", + "default": 50, + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "poolTimeout": { + "description": "timeout for acquiring a connection from the pool (seconds)", + "default": 30, + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "idleTimeout": { + "description": "idle timeout for releasing a connection from the pool (seconds)", + "default": 180, + "type": ["integer", "null"], + "format": "uint64", + "minimum": 0.0 + }, + "connectionLifetime": { + "description": "maximum lifetime for an individual connection (seconds)", + "default": 600, + "type": ["integer", "null"], + "format": "uint64", + "minimum": 0.0 + } + } + }, + "IsolationLevel": { + "description": "The isolation level of the transaction in which a query is executed.", + "oneOf": [ + { + "description": "Prevents reading data from another uncommitted transaction.", + "type": "string", + "enum": ["ReadCommitted"] + }, + { + "description": "Reading the same data twice is guaranteed to return the same result.", + "type": "string", + "enum": ["RepeatableRead"] + }, + { + "description": "Concurrent transactions behave identically to serializing them one at a time.", + "type": "string", + "enum": ["Serializable"] + } + ] + }, + "Metadata": { + "description": "Metadata information.", + "type": "object", + "properties": { + "tables": { + "default": {}, + "allOf": [ + { + "$ref": "#/definitions/TablesInfo" + } + ] + }, + "compositeTypes": { + "default": {}, + "allOf": [ + { + "$ref": "#/definitions/CompositeTypes" + } + ] + }, + "nativeQueries": { + "default": {}, + "allOf": [ + { + "$ref": "#/definitions/NativeQueries" + } + ] + }, + "aggregateFunctions": { + "default": {}, + "allOf": [ + { + "$ref": "#/definitions/AggregateFunctions" + } + ] + }, + "comparisonOperators": { + "default": {}, + "allOf": [ + { + "$ref": "#/definitions/ComparisonOperators" + } + ] + } + } + }, + "TablesInfo": { + "description": "Mapping from a \"table\" name to its information.", + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/TableInfo" + } + }, + "TableInfo": { + "description": "Information about a database table (or any other kind of relation).", + "type": "object", + "required": ["columns", "schemaName", "tableName"], + "properties": { + "schemaName": { + "type": "string" + }, + "tableName": { + "type": "string" + }, + "columns": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/ColumnInfo" + } + }, + "uniquenessConstraints": { + "default": {}, + "allOf": [ + { + "$ref": "#/definitions/UniquenessConstraints" + } + ] + }, + "foreignRelations": { + "default": {}, + "allOf": [ + { + "$ref": "#/definitions/ForeignRelations" + } + ] + }, + "description": { + "default": null, + "type": ["string", "null"] + } + } + }, + "ColumnInfo": { + "description": "Information about a database column.", + "type": "object", + "required": ["name", "type"], + "properties": { + "name": { + "type": "string" + }, + "type": { + "$ref": "#/definitions/Type" + }, + "nullable": { + "default": "nullable", + "allOf": [ + { + "$ref": "#/definitions/Nullable" + } + ] + }, + "hasDefault": { + "$ref": "#/definitions/HasDefault" + }, + "isIdentity": { + "$ref": "#/definitions/IsIdentity" + }, + "isGenerated": { + "$ref": "#/definitions/IsGenerated" + }, + "description": { + "default": null, + "type": ["string", "null"] + } + } + }, + "Type": { + "description": "The type of values that a column, field, or argument may take.", + "oneOf": [ + { + "type": "object", + "required": ["scalarType"], + "properties": { + "scalarType": { + "$ref": "#/definitions/ScalarType" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": ["compositeType"], + "properties": { + "compositeType": { + "type": "string" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": ["arrayType"], + "properties": { + "arrayType": { + "$ref": "#/definitions/Type" + } + }, + "additionalProperties": false + } + ] + }, + "ScalarType": { + "description": "A Scalar Type.", + "type": "string" + }, + "Nullable": { + "description": "Can this column contain null values", + "type": "string", + "enum": ["nullable", "nonNullable"] + }, + "HasDefault": { + "description": "Does this column have a default value.", + "type": "string", + "enum": ["noDefault", "hasDefault"] + }, + "IsIdentity": { + "description": "Is this column an identity column.", + "type": "string", + "enum": ["notIdentity", "identityByDefault", "identityAlways"] + }, + "IsGenerated": { + "description": "Is this column a generated column.", + "type": "string", + "enum": ["notGenerated", "stored"] + }, + "UniquenessConstraints": { + "description": "A mapping from the name of a unique constraint to its value.", + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/UniquenessConstraint" + } + }, + "UniquenessConstraint": { + "description": "The set of columns that make up a uniqueness constraint.", + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + }, + "ForeignRelations": { + "description": "A mapping from the name of a foreign key constraint to its value.", + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/ForeignRelation" + } + }, + "ForeignRelation": { + "description": "A foreign key constraint.", + "type": "object", + "required": ["columnMapping", "foreignTable"], + "properties": { + "foreignSchema": { + "type": ["string", "null"] + }, + "foreignTable": { + "type": "string" + }, + "columnMapping": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "CompositeTypes": { + "description": "Map of all known composite types.", + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/CompositeType" + } + }, + "CompositeType": { + "description": "Information about a composite type. These are very similar to tables, but with the crucial difference that composite types do not support constraints (such as NOT NULL).", + "type": "object", + "required": ["fields", "name"], + "properties": { + "name": { + "type": "string" + }, + "fields": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/FieldInfo" + } + }, + "description": { + "default": null, + "type": ["string", "null"] + } + } + }, + "FieldInfo": { + "description": "Information about a composite type field.", + "type": "object", + "required": ["name", "type"], + "properties": { + "name": { + "type": "string" + }, + "type": { + "$ref": "#/definitions/Type" + }, + "description": { + "default": null, + "type": ["string", "null"] + } + } + }, + "NativeQueries": { + "description": "Metadata information of native queries.", + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/NativeQueryInfo" + } + }, + "NativeQueryInfo": { + "description": "Information about a Native Query", + "type": "object", + "required": ["columns", "sql"], + "properties": { + "sql": { + "description": "SQL expression to use for the Native Query. We can interpolate values using `{{variable_name}}` syntax, such as `SELECT * FROM authors WHERE name = {{author_name}}`", + "allOf": [ + { + "$ref": "#/definitions/Native_query_sql" + } + ] + }, + "columns": { + "description": "Columns returned by the Native Query", + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/ReadOnlyColumnInfo" + } + }, + "arguments": { + "description": "Names and types of arguments that can be passed to this Native Query", + "default": {}, + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/ReadOnlyColumnInfo" + } + }, + "description": { + "default": null, + "type": ["string", "null"] + }, + "isProcedure": { + "description": "True if this native query mutates the database", + "type": "boolean" + } + } + }, + "Native_query_sql": { + "type": "string" + }, + "ReadOnlyColumnInfo": { + "description": "Information about a native query column.", + "type": "object", + "required": ["name", "type"], + "properties": { + "name": { + "type": "string" + }, + "type": { + "$ref": "#/definitions/Type" + }, + "nullable": { + "default": "nullable", + "allOf": [ + { + "$ref": "#/definitions/Nullable" + } + ] + }, + "description": { + "default": null, + "type": ["string", "null"] + } + } + }, + "AggregateFunctions": { + "description": "All supported aggregate functions, grouped by type.", + "type": "object", + "additionalProperties": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/AggregateFunction" + } + } + }, + "AggregateFunction": { + "type": "object", + "required": ["returnType"], + "properties": { + "returnType": { + "$ref": "#/definitions/ScalarType" + } + } + }, + "ComparisonOperators": { + "description": "The complete list of supported binary operators for scalar types. Not all of these are supported for every type.", + "type": "object", + "additionalProperties": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/ComparisonOperator" + } + } + }, + "ComparisonOperator": { + "description": "Represents a postgres binary comparison operator", + "type": "object", + "required": ["argumentType", "operatorKind", "operatorName"], + "properties": { + "operatorName": { + "type": "string" + }, + "operatorKind": { + "$ref": "#/definitions/OperatorKind" + }, + "argumentType": { + "$ref": "#/definitions/ScalarType" + }, + "isInfix": { + "default": true, + "type": "boolean" + } + } + }, + "OperatorKind": { + "description": "Is it a built-in operator, or a custom operator.", + "type": "string", + "enum": ["equal", "in", "custom"] + }, + "IntrospectionOptions": { + "description": "Options which only influence how the configuration is updated.", + "type": "object", + "properties": { + "excludedSchemas": { + "description": "Schemas which are excluded from introspection. The default setting will exclude the internal schemas of Postgres, Citus, Cockroach, and the PostGIS extension.", + "default": [ + "information_schema", + "pg_catalog", + "tiger", + "crdb_internal", + "columnar", + "columnar_internal" + ], + "type": "array", + "items": { + "type": "string" + } + }, + "unqualifiedSchemasForTables": { + "description": "The names of Tables and Views in these schemas will be returned unqualified. The default setting will set the `public` schema as unqualified.", + "default": ["public"], + "type": "array", + "items": { + "type": "string" + } + }, + "unqualifiedSchemasForTypesAndProcedures": { + "description": "The types and procedures in these schemas will be returned unqualified.", + "default": ["public", "pg_catalog", "tiger"], + "type": "array", + "items": { + "type": "string" + } + }, + "comparisonOperatorMapping": { + "description": "The mapping of comparison operator names to apply when updating the configuration", + "default": [ + { + "operatorName": "=", + "exposedName": "_eq", + "operatorKind": "equal" + }, + { + "operatorName": "<=", + "exposedName": "_lte", + "operatorKind": "custom" + }, + { + "operatorName": ">", + "exposedName": "_gt", + "operatorKind": "custom" + }, + { + "operatorName": ">=", + "exposedName": "_gte", + "operatorKind": "custom" + }, + { + "operatorName": "<", + "exposedName": "_lt", + "operatorKind": "custom" + }, + { + "operatorName": "!=", + "exposedName": "_neq", + "operatorKind": "custom" + }, + { + "operatorName": "LIKE", + "exposedName": "_like", + "operatorKind": "custom" + }, + { + "operatorName": "NOT LIKE", + "exposedName": "_nlike", + "operatorKind": "custom" + }, + { + "operatorName": "ILIKE", + "exposedName": "_ilike", + "operatorKind": "custom" + }, + { + "operatorName": "NOT ILIKE", + "exposedName": "_nilike", + "operatorKind": "custom" + }, + { + "operatorName": "SIMILAR TO", + "exposedName": "_similar", + "operatorKind": "custom" + }, + { + "operatorName": "NOT SIMILAR TO", + "exposedName": "_nsimilar", + "operatorKind": "custom" + }, + { + "operatorName": "<>", + "exposedName": "_neq", + "operatorKind": "custom" + }, + { + "operatorName": "~~", + "exposedName": "_like", + "operatorKind": "custom" + }, + { + "operatorName": "!~~", + "exposedName": "_nlike", + "operatorKind": "custom" + }, + { + "operatorName": "~~*", + "exposedName": "_ilike", + "operatorKind": "custom" + }, + { + "operatorName": "!~~*", + "exposedName": "_nilike", + "operatorKind": "custom" + }, + { + "operatorName": "~", + "exposedName": "_regex", + "operatorKind": "custom" + }, + { + "operatorName": "!~", + "exposedName": "_nregex", + "operatorKind": "custom" + }, + { + "operatorName": "~*", + "exposedName": "_iregex", + "operatorKind": "custom" + }, + { + "operatorName": "!~*", + "exposedName": "_niregex", + "operatorKind": "custom" + } + ], + "type": "array", + "items": { + "$ref": "#/definitions/ComparisonOperatorMapping" + } + }, + "introspectPrefixFunctionComparisonOperators": { + "description": "Which prefix functions (i.e., non-infix operators) to generate introspection metadata for.\n\nThis list will accept any boolean-returning function taking two concrete scalar types as arguments.\n\nThe default includes comparisons for various build-in types as well as those of PostGIS.", + "default": [ + "box_above", + "box_below", + "box_contain", + "box_contain_pt", + "box_contained", + "box_left", + "box_overabove", + "box_overbelow", + "box_overlap", + "box_overleft", + "box_overright", + "box_right", + "box_same", + "circle_above", + "circle_below", + "circle_contain", + "circle_contain_pt", + "circle_contained", + "circle_left", + "circle_overabove", + "circle_overbelow", + "circle_overlap", + "circle_overleft", + "circle_overright", + "circle_right", + "circle_same", + "contains_2d", + "equals", + "geography_overlaps", + "geometry_above", + "geometry_below", + "geometry_contained_3d", + "geometry_contains", + "geometry_contains_3d", + "geometry_contains_nd", + "geometry_left", + "geometry_overabove", + "geometry_overbelow", + "geometry_overlaps", + "geometry_overlaps_3d", + "geometry_overlaps_nd", + "geometry_overleft", + "geometry_overright", + "geometry_right", + "geometry_same", + "geometry_same_3d", + "geometry_same_nd", + "geometry_within", + "geometry_within_nd", + "inet_same_family", + "inter_lb", + "inter_sb", + "inter_sl", + "is_contained_2d", + "ishorizontal", + "isparallel", + "isperp", + "isvertical", + "jsonb_contained", + "jsonb_contains", + "jsonb_exists", + "jsonb_path_exists_opr", + "jsonb_path_match_opr", + "line_intersect", + "line_parallel", + "line_perp", + "lseg_intersect", + "lseg_parallel", + "lseg_perp", + "network_overlap", + "network_sub", + "network_sup", + "on_pb", + "on_pl", + "on_ppath", + "on_ps", + "on_sb", + "on_sl", + "overlaps_2d", + "path_contain_pt", + "path_inter", + "point_above", + "point_below", + "point_horiz", + "point_left", + "point_right", + "point_vert", + "poly_above", + "poly_below", + "poly_contain", + "poly_contain_pt", + "poly_contained", + "poly_left", + "poly_overabove", + "poly_overbelow", + "poly_overlap", + "poly_overleft", + "poly_overright", + "poly_right", + "poly_same", + "pt_contained_poly", + "st_3dintersects", + "st_contains", + "st_containsproperly", + "st_coveredby", + "st_covers", + "st_crosses", + "st_disjoint", + "st_equals", + "st_intersects", + "st_isvalid", + "st_orderingequals", + "st_overlaps", + "st_relatematch", + "st_touches", + "st_within", + "starts_with", + "ts_match_qv", + "ts_match_tq", + "ts_match_tt", + "ts_match_vq", + "tsq_mcontained", + "tsq_mcontains", + "xmlexists", + "xmlvalidate", + "xpath_exists" + ], + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "ComparisonOperatorMapping": { + "description": "Define the names that comparison operators will be exposed as by the automatic introspection.", + "type": "object", + "required": ["exposedName", "operatorKind", "operatorName"], + "properties": { + "operatorName": { + "description": "The name of the operator as defined by the database", + "type": "string" + }, + "exposedName": { + "description": "The name the operator will appear under in the exposed API", + "type": "string" + }, + "operatorKind": { + "description": "Equal, In or Custom.", + "allOf": [ + { + "$ref": "#/definitions/OperatorKind" + } + ] + } + } + }, + "MutationsVersion": { + "description": "Which version of the generated mutations will be included in the schema", + "type": "string", + "enum": ["v1"] + } + } +} diff --git a/static/yugabyte/v3-chinook-ndc-metadata/configuration.json b/static/yugabyte/v3-chinook-ndc-metadata/configuration.json index 0fcaf0900..713ac12a1 100644 --- a/static/yugabyte/v3-chinook-ndc-metadata/configuration.json +++ b/static/yugabyte/v3-chinook-ndc-metadata/configuration.json @@ -1,15 +1,18 @@ { "version": "3", - "connectionUri": { - "variable": "CONNECTION_URI" - }, - "poolSettings": { - "maxConnections": 50, - "poolTimeout": 30, - "idleTimeout": 180, - "connectionLifetime": 600 + "$schema": "../../schema.json", + "connectionSettings": { + "connectionUri": { + "variable": "CONNECTION_URI" + }, + "poolSettings": { + "maxConnections": 50, + "poolTimeout": 30, + "idleTimeout": 180, + "connectionLifetime": 600 + }, + "isolationLevel": "ReadCommitted" }, - "isolationLevel": "ReadCommitted", "metadata": { "tables": { "Album": { @@ -2672,7 +2675,7 @@ } } }, - "configureOptions": { + "introspectionOptions": { "excludedSchemas": [ "information_schema", "pg_catalog", @@ -2794,7 +2797,6 @@ "operatorKind": "custom" } ], - "mutationsVersion": "v1", "introspectPrefixFunctionComparisonOperators": [ "box_above", "box_below", @@ -2923,5 +2925,6 @@ "xmlvalidate", "xpath_exists" ] - } + }, + "mutationsVersion": "v1" }