Mongo: Enable browse rows and relationship tabs

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/9579
GitOrigin-RevId: 470b4226ce327faca4040c7b46541fc953a3cd15
This commit is contained in:
Julian 2023-06-23 15:16:51 -03:00 committed by hasura-bot
parent 0add59185d
commit 324e02b43e
8 changed files with 4491 additions and 127 deletions

View File

@ -115,6 +115,11 @@ services:
timeout: 10s
retries: 5
start_period: 5s
mongo-data-connector:
image: hasura/mongo-data-connector:v2.27.0
container_name: mongo_connector
ports:
- 3000:3000
volumes:
metadata_db_data:

View File

@ -1,3 +1,5 @@
import { getNullableType, isListType, isObjectType } from 'graphql';
import { TableColumn } from '../DataSource';
import { DataGridOptions } from './components/DataGrid/DataGrid';
import { applyWhereAndSortConditionsToQueryString } from './components/DataGrid/DataGrid.utils';
@ -16,3 +18,13 @@ export const setWhereAndSortToUrl = (options: DataGridOptions) => {
window.history.pushState({ path: newUrl }, '', newUrl);
}
};
export function isScalarGraphQLType(column: TableColumn): boolean {
if (!column.graphQLProperties?.graphQLType) {
return false;
}
const nullableType = getNullableType(column.graphQLProperties?.graphQLType);
const isObjectOrArray =
isListType(nullableType) || isObjectType(nullableType);
return !isObjectOrArray;
}

View File

@ -4,6 +4,7 @@ import { Table } from '../../hasura-metadata-types';
import { useHttpClient } from '../../Network';
import { AxiosInstance } from 'axios';
import { useQuery } from 'react-query';
import { isScalarGraphQLType } from '../BrowseRows.utils';
type FetchRowsArgs = {
columns: UseRowsPropType['columns'];
@ -28,7 +29,14 @@ export const fetchRows = async ({
const result = await DataSource(httpClient).getTableRows({
dataSourceName,
table,
columns: columns ?? tableColumns.map(column => column.name),
columns:
columns ??
tableColumns
// Filter out columns that are objects or arrays
// We do this because generateGraphQLSelectQuery cannot handle those types
// TODO: Remove this filter once we improve generateGraphQLSelectQuery
.filter(isScalarGraphQLType)
.map(column => column.name),
options,
});

View File

@ -9,15 +9,6 @@ export type EnabledTabs = {
};
export function getEnabledTabs(kind: string | undefined): EnabledTabs {
if (kind === 'Mongo') {
return {
browse: false,
insert: false,
modify: true,
relationships: false,
permissions: true,
};
}
return {
browse: true,
insert: true,

View File

@ -1,6 +1,6 @@
/* eslint-disable no-underscore-dangle */
import { getScalarType, getTypeName } from '../../../GraphQLUtils';
import { GraphQLType } from 'graphql';
import { GraphQLType, buildClientSchema, isObjectType } from 'graphql';
import { GDCTable } from '..';
import {
exportMetadata,
@ -11,6 +11,7 @@ import { GetTableColumnsProps, TableColumn } from '../../types';
import { adaptAgentDataType } from './utils';
import { GetTableInfoResponse } from './types';
import { areTablesEqual } from '../../../hasura-metadata-api';
import { getTableDisplayName } from '../../../DatabaseRelationships';
export const getTableColumns = async (props: GetTableColumnsProps) => {
const { httpClient, dataSourceName, table } = props;
@ -42,6 +43,7 @@ export const getTableColumns = async (props: GetTableColumnsProps) => {
introspectionResult.data.__schema.types.find(
(t: any) => t.name === queryRoot
)?.fields ?? [];
const schema = buildClientSchema(introspectionResult.data);
const scalarTypes = graphQLFields
.map(({ name, type }: { name: string; type: GraphQLType }) => {
@ -65,6 +67,9 @@ export const getTableColumns = async (props: GetTableColumnsProps) => {
});
const primaryKeys = tableInfo?.primary_key ? tableInfo.primary_key : [];
const tableName = getTableDisplayName(tableInfo.name);
const type = schema.getType(tableName);
const fields = isObjectType(type) ? type.getFields() : {};
return tableInfo.columns.map<TableColumn>(column => {
const graphqlFieldName =
@ -75,7 +80,7 @@ export const getTableColumns = async (props: GetTableColumnsProps) => {
scalarTypes.find(
({ name }: { name: string }) => name === graphqlFieldName
) ?? null;
const field = fields[graphqlFieldName];
return {
name: column.name,
dataType: adaptAgentDataType(column.type),
@ -88,6 +93,7 @@ export const getTableColumns = async (props: GetTableColumnsProps) => {
graphQLProperties: {
name: graphqlFieldName,
scalarType: scalarType?.type ?? null,
graphQLType: field?.type,
},
};
});

View File

@ -82,7 +82,21 @@ export function adaptAgentDataType(
};
const [dataType] = getEntries(DataTypeToSQLTypeMap).find(([, value]) =>
value.includes(sqlDataType.toLowerCase())
value.includes(
// Check if sqlDataType is a string or an object
// Reason is `Error: sqlDataType.toLowerCase is not a function`
/*
sqlDataType ->
{
element_type: "string",
nullable: false,
type: "array"
}
*/
typeof sqlDataType === 'string'
? sqlDataType.toLowerCase()
: (sqlDataType as any).type.toLowerCase() // Doubt: Could also be element_type in the case of arrays
)
) ?? ['string', []];
return dataType;

View File

@ -1,3 +1,4 @@
import { GraphQLType } from 'graphql';
import {
Legacy_SourceToRemoteSchemaRelationship,
LocalTableArrayRelationship,
@ -73,6 +74,7 @@ export type TableColumn = {
graphQLProperties?: {
name: string;
scalarType: string;
graphQLType?: GraphQLType | undefined;
};
};