feature (console): adding consoleDataType to the table column type

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/7547
GitOrigin-RevId: 13967c84b3ab09b918e94d60ce4f8aa0244fce25
This commit is contained in:
Vijay Prasanna 2023-01-19 13:50:57 +05:30 committed by hasura-bot
parent 42a536a8ab
commit f5e17e6161
19 changed files with 143 additions and 76 deletions

View File

@ -77,6 +77,7 @@ export const useFiltersAndSortFormValues = ({
(tableSchema?.columns || []).map(column => ({
name: column.column_name,
dataType: column.data_type as TableColumn['dataType'],
consoleDataType: 'string',
}))
),
// NOTE: this processing is needed only when the component is loaded for the first time — do not change the dependency array

View File

@ -108,6 +108,7 @@ export const TableBrowseRowsContainer = (
(tableSchema?.columns || []).map(column => ({
name: column.column_name,
dataType: column.data_type as TableColumn['dataType'],
consoleDataType: 'string',
}))
);

View File

@ -347,11 +347,13 @@ describe('convertUrlToDataGridOptions', () => {
name: 'AlbumId',
dataType: 'number',
graphQLProperties: { name: 'AlbumId', scalarType: 'decimal' },
consoleDataType: 'number',
},
{
name: 'Title',
dataType: 'string',
graphQLProperties: { name: 'Title', scalarType: 'String' },
consoleDataType: 'string',
},
];
@ -368,6 +370,7 @@ describe('convertValueToGraphQL', () => {
const tableColumn: TableColumn = {
name: 'AlbumId',
dataType: 'number',
consoleDataType: 'number',
graphQLProperties: {
name: 'AlbumId',
scalarType: 'decimal',
@ -381,6 +384,7 @@ describe('convertValueToGraphQL', () => {
const tableColumn: TableColumn = {
name: 'AlbumId',
dataType: 'number',
consoleDataType: 'number',
graphQLProperties: {
name: 'AlbumId',
scalarType: 'float',
@ -394,6 +398,7 @@ describe('convertValueToGraphQL', () => {
const tableColumn: TableColumn = {
name: 'AlbumId',
dataType: 'bool',
consoleDataType: 'number',
graphQLProperties: {
name: 'AlbumId',
scalarType: 'boolean',
@ -407,6 +412,7 @@ describe('convertValueToGraphQL', () => {
const tableColumn: TableColumn = {
name: 'AlbumId',
dataType: 'string',
consoleDataType: 'number',
graphQLProperties: {
name: 'AlbumId',
scalarType: 'string',
@ -420,6 +426,7 @@ describe('convertValueToGraphQL', () => {
const tableColumn: TableColumn = {
name: 'AlbumId',
dataType: 'string',
consoleDataType: 'string',
graphQLProperties: {
name: 'AlbumId',
scalarType: 'string',
@ -433,6 +440,7 @@ describe('convertValueToGraphQL', () => {
const tableColumn: TableColumn = {
name: 'AlbumId',
dataType: 'number',
consoleDataType: 'number',
graphQLProperties: {
name: 'AlbumId',
scalarType: 'int',
@ -446,6 +454,7 @@ describe('convertValueToGraphQL', () => {
const tableColumn: TableColumn = {
name: 'AlbumId',
dataType: 'number',
consoleDataType: 'number',
graphQLProperties: {
name: 'AlbumId',
scalarType: 'float',

View File

@ -17,6 +17,7 @@ const columns: TableColumn[] = [
{
name: 'ID',
dataType: 'number',
consoleDataType: 'number',
graphQLProperties: {
name: 'ID',
scalarType: 'Int',
@ -25,6 +26,7 @@ const columns: TableColumn[] = [
{
name: 'FirstName',
dataType: 'string',
consoleDataType: 'string',
graphQLProperties: {
name: 'FirstName',
scalarType: 'String',
@ -33,6 +35,7 @@ const columns: TableColumn[] = [
{
name: 'UpdatedAt',
dataType: 'string',
consoleDataType: 'string',
graphQLProperties: {
name: 'UpdatedAtCustomName',
scalarType: 'String',

View File

@ -16,6 +16,7 @@ export const Primary: ComponentStory<typeof LegacyRunQuery> = () => (
{
name: 'ID',
dataType: 'number',
consoleDataType: 'number',
graphQLProperties: {
name: 'ID',
scalarType: 'Int',
@ -24,6 +25,7 @@ export const Primary: ComponentStory<typeof LegacyRunQuery> = () => (
{
name: 'FirstName',
dataType: 'string',
consoleDataType: 'string',
graphQLProperties: {
name: 'FirstName',
scalarType: 'String',
@ -32,6 +34,7 @@ export const Primary: ComponentStory<typeof LegacyRunQuery> = () => (
{
name: 'UpdatedAt',
dataType: 'string',
consoleDataType: 'string',
graphQLProperties: {
name: 'UpdatedAtCustomName',
scalarType: 'String',

View File

@ -43,10 +43,12 @@ describe('adaptFormValuesToQuery', () => {
{
name: 'id',
dataType: 'number',
consoleDataType: 'number',
},
{
name: 'text',
dataType: 'string',
consoleDataType: 'string',
},
];
expect(adaptFormValuesToQuery(input, columnDataTypes)).toEqual(expected);
@ -74,6 +76,7 @@ describe('adaptFormValuesToQuery', () => {
{
name: 'id',
dataType: 'number',
consoleDataType: 'number',
},
];
expect(adaptFormValuesToQuery(input, columnDataTypes)).toEqual(expected);
@ -101,6 +104,7 @@ describe('adaptFormValuesToQuery', () => {
{
name: 'idDeleted',
dataType: 'bool',
consoleDataType: 'boolean',
},
];
expect(adaptFormValuesToQuery(input, columnDataTypes)).toEqual(expected);
@ -128,6 +132,7 @@ describe('adaptFormValuesToQuery', () => {
{
name: 'idDeleted',
dataType: 'bool',
consoleDataType: 'boolean',
},
];
expect(adaptFormValuesToQuery(input, columnDataTypes)).toEqual(expected);
@ -164,10 +169,12 @@ it('does not try to parse non-integer values on integer field types', () => {
{
name: 'id',
dataType: 'number',
consoleDataType: 'number',
},
{
name: 'text',
dataType: 'number',
dataType: 'string',
consoleDataType: 'string',
},
];
expect(adaptFormValuesToQuery(input, columnDataTypes)).toEqual(expected);

View File

@ -19,6 +19,7 @@ const columns: TableColumn[] = [
{
name: 'ID',
dataType: 'number',
consoleDataType: 'number',
graphQLProperties: {
name: 'ID',
scalarType: 'Int',
@ -27,6 +28,7 @@ const columns: TableColumn[] = [
{
name: 'FirstName',
dataType: 'string',
consoleDataType: 'string',
graphQLProperties: {
name: 'FirstName',
scalarType: 'String',
@ -35,6 +37,7 @@ const columns: TableColumn[] = [
{
name: 'UpdatedAt',
dataType: 'string',
consoleDataType: 'string',
graphQLProperties: {
name: 'UpdatedAtCustomName',
scalarType: 'String',

View File

@ -8,7 +8,8 @@ const adaptTableColumns = (result: RunSQLResponse['result']): TableColumn[] => {
return result.slice(1).map(row => ({
name: row[0],
dataType: adaptSQLDataType(row[1]),
dataType: row[1],
consoleDataType: adaptSQLDataType(row[1]),
nullable: row[2] === 'YES',
}));
};

View File

@ -23,16 +23,25 @@ export const adaptIntrospectedBigQueryTables = (
return adaptedResponse ?? [];
};
export function adaptSQLDataType(sqlDataType: string): TableColumn['dataType'] {
const DataTypeToSQLTypeMap: Record<TableColumn['dataType'], string[]> = {
bool: ['BOOL'],
string: ['STRING', 'STRUCT', 'varchar'],
number: ['BIGNUMERIC', 'FLOAT64', 'INT64', 'INTERVAL', 'NUMERIC'],
datetime: ['DATE', 'DATETIME'],
timestamp: ['TIME', 'TIMESTAMP'],
xml: ['xml'],
json: ['JSON'],
};
export function adaptSQLDataType(
sqlDataType: string
): TableColumn['consoleDataType'] {
const DataTypeToSQLTypeMap: Record<TableColumn['consoleDataType'], string[]> =
{
boolean: ['BOOL'],
text: [],
string: [
'STRING',
'STRUCT',
'varchar',
'DATE',
'DATETIME',
'TIME',
'TIMESTAMP',
],
number: ['BIGNUMERIC', 'FLOAT64', 'INT64', 'INTERVAL', 'NUMERIC'],
json: ['JSON', 'xml'],
};
const [dataType] = getEntries(DataTypeToSQLTypeMap).find(([, value]) =>
value.includes(sqlDataType)

View File

@ -22,7 +22,8 @@ const adaptTableColumns = (result: RunSQLResponse['result']): TableColumn[] => {
return result.slice(1).map(row => ({
name: row[0],
dataType: adaptSQLDataType(row[1]),
dataType: row[1],
consoleDataType: adaptSQLDataType(row[1]),
nullable: row[2] === 'YES',
}));
};
@ -123,6 +124,7 @@ export const getTableColumns = async ({
return {
name: column.name,
dataType: column.dataType,
consoleDataType: column.consoleDataType,
nullable: column.nullable,
isPrimaryKey: primaryKeys.includes(column.name),
graphQLProperties: {

View File

@ -8,7 +8,8 @@ const adaptTableColumns = (result: RunSQLResponse['result']): TableColumn[] => {
return result.slice(1).map(row => ({
name: row[0],
dataType: adaptSQLDataType(row[1]),
consoleDataType: adaptSQLDataType(row[1]),
dataType: row[1],
nullable: row[2] === 'YES',
}));
};

View File

@ -1,8 +1,14 @@
import { getEntries } from '@/components/Services/Data/Common/tsUtils';
import { TableColumn } from '../types';
export function adaptSQLDataType(sqlDataType: string): TableColumn['dataType'] {
const DataTypeToSQLTypeMap: Record<TableColumn['dataType'], string[]> = {
bool: ['boolean', 'bool'],
export function adaptSQLDataType(
sqlDataType: string
): TableColumn['consoleDataType'] {
const consoleDataTypeToSQLTypeMap: Record<
TableColumn['consoleDataType'],
string[]
> = {
boolean: ['boolean', 'bool'],
string: [
'box',
'character',
@ -17,14 +23,20 @@ export function adaptSQLDataType(sqlDataType: string): TableColumn['dataType'] {
'pg_snapshot',
'point',
'polygon',
'text',
'tsquery',
'tsvector',
'txid_snapshot',
'uuid',
'char',
'varchar',
'date',
'time',
'time',
'timetz',
'timestamptz',
'timestamp',
],
text: ['text'],
number: [
'bigint',
'bigserial',
@ -53,15 +65,12 @@ export function adaptSQLDataType(sqlDataType: string): TableColumn['dataType'] {
'serial2',
'serial4',
],
datetime: ['date', 'time', 'time', 'timetz'],
timestamp: ['timestamptz', 'timestamp'],
xml: ['xml'],
json: ['interval', 'json', 'jsonb'],
json: ['interval', 'json', 'jsonb', 'xml'],
};
const [dataType] = Object.entries(DataTypeToSQLTypeMap).find(([, value]) =>
const [dataType] = getEntries(consoleDataTypeToSQLTypeMap).find(([, value]) =>
value.includes(sqlDataType)
) ?? ['string', []];
return dataType as TableColumn['dataType'];
return dataType;
}

View File

@ -79,6 +79,10 @@ export const getTableColumns = async (props: GetTableColumnsProps) => {
return {
name: column.name,
dataType: adaptAgentDataType(column.type),
/**
Will be updated once GDC supports mutations
*/
consoleDataType: 'string',
nullable: column.nullable,
isPrimaryKey: primaryKeys.includes(column.name),
graphQLProperties: {

View File

@ -20,7 +20,8 @@ const adaptTableColumns = (result: RunSQLResponse['result']): TableColumn[] => {
return result.slice(1).map(row => ({
name: row[0],
dataType: adaptSQLDataType(row[1]),
dataType: row[1],
consoleDataType: adaptSQLDataType(row[1]),
nullable: !!row[2],
}));
};
@ -115,6 +116,7 @@ WHERE
return {
name: column.name,
dataType: column.dataType,
consoleDataType: column.consoleDataType,
nullable: column.nullable,
isPrimaryKey: primaryKeys.includes(column.name),
graphQLProperties: {

View File

@ -1,37 +1,32 @@
import { getEntries } from '@/components/Services/Data/Common/tsUtils';
import { TableColumn } from '../types';
export function adaptSQLDataType(sqlDataType: string): TableColumn['dataType'] {
const DataTypeToSQLTypeMap: Record<TableColumn['dataType'], string[]> = {
bool: [],
string: ['char', 'text', 'varchar'],
number: [
'bigint',
'bit',
'decimal',
'int',
'money',
'numeric',
'smallint',
'smallmoney',
'float',
'real',
],
datetime: [
'date',
'datetime',
'datetime2',
'datetimeoffset',
'smalldatetime',
'time',
],
timestamp: [],
xml: ['xml'],
json: [],
};
export function adaptSQLDataType(
sqlDataType: string
): TableColumn['consoleDataType'] {
const DataTypeToSQLTypeMap: Record<TableColumn['consoleDataType'], string[]> =
{
boolean: [],
string: ['char', 'boolean', 'text', 'varchar'],
number: [
'bigint',
'bit',
'decimal',
'int',
'money',
'numeric',
'smallint',
'smallmoney',
'float',
'real',
],
text: ['text'],
json: [],
};
const [dataType] = Object.entries(DataTypeToSQLTypeMap).find(([, value]) =>
const [dataType] = getEntries(DataTypeToSQLTypeMap).find(([, value]) =>
value.includes(sqlDataType)
) ?? ['string', []];
return dataType as TableColumn['dataType'];
return dataType;
}

View File

@ -1,5 +1,3 @@
/* eslint-disable no-underscore-dangle */
/* eslint-disable @typescript-eslint/no-unused-vars */
import { getScalarType, getTypeName } from '@/features/GraphQLUtils';
import { areTablesEqual } from '@/features/hasura-metadata-api';
import { GraphQLType } from 'graphql';
@ -22,7 +20,8 @@ const adaptTableColumns = (result: RunSQLResponse['result']): TableColumn[] => {
return result.slice(1).map(row => ({
name: row[0],
dataType: adaptSQLDataType(row[1]),
dataType: row[1],
consoleDataType: adaptSQLDataType(row[1]),
nullable: row[2] === 'YES',
}));
};
@ -76,6 +75,7 @@ export const getTableColumns = async ({
});
const graphQLFields =
// eslint-disable-next-line no-underscore-dangle
introspectionResult.data.__schema.types.find(
(t: any) => t.name === queryRoot
)?.fields ?? [];
@ -123,6 +123,7 @@ export const getTableColumns = async ({
return {
name: column.name,
dataType: column.dataType,
consoleDataType: column.consoleDataType,
nullable: column.nullable,
isPrimaryKey: primaryKeys.includes(column.name),
graphQLProperties: {

View File

@ -1,3 +1,4 @@
import { getEntries } from '@/components/Services/Data/Common/tsUtils';
import { TableColumn } from '../types';
function containsUppercase(str: string) {
@ -8,9 +9,14 @@ export function adaptStringForPostgres(str: string) {
return containsUppercase(str) ? `"${str}"` : str;
}
export function adaptSQLDataType(sqlDataType: string): TableColumn['dataType'] {
const DataTypeToSQLTypeMap: Record<TableColumn['dataType'], string[]> = {
bool: ['boolean', 'bool'],
export function adaptSQLDataType(
sqlDataType: string
): TableColumn['consoleDataType'] {
const consoleDataTypeToSQLTypeMap: Record<
TableColumn['consoleDataType'],
string[]
> = {
boolean: ['boolean', 'bool'],
string: [
'box',
'character',
@ -25,14 +31,20 @@ export function adaptSQLDataType(sqlDataType: string): TableColumn['dataType'] {
'pg_snapshot',
'point',
'polygon',
'text',
'tsquery',
'tsvector',
'txid_snapshot',
'uuid',
'char',
'varchar',
'date',
'time',
'time',
'timetz',
'timestamptz',
'timestamp',
],
text: ['text'],
number: [
'bigint',
'bigserial',
@ -61,15 +73,12 @@ export function adaptSQLDataType(sqlDataType: string): TableColumn['dataType'] {
'serial2',
'serial4',
],
datetime: ['date', 'time', 'time', 'timetz'],
timestamp: ['timestamptz', 'timestamp'],
xml: ['xml'],
json: ['interval', 'json', 'jsonb'],
json: ['interval', 'json', 'jsonb', 'xml'],
};
const [dataType] = Object.entries(DataTypeToSQLTypeMap).find(([, value]) =>
const [dataType] = getEntries(consoleDataTypeToSQLTypeMap).find(([, value]) =>
value.includes(sqlDataType)
) ?? ['string', []];
return dataType as TableColumn['dataType'];
return dataType;
}

View File

@ -55,15 +55,18 @@ export type IntrospectedTable = {
};
export type TableColumn = {
/**
* Name of the column as defined in the DB
*/
name: string;
dataType:
| 'string'
| 'number'
| 'bool'
| 'json'
| 'datetime'
| 'timestamp'
| 'xml';
/**
* dataType of the column as defined in the DB
*/
dataType: string;
/**
* console data type: the dataType property is group into one of these types and console uses this internally
*/
consoleDataType: 'string' | 'text' | 'json' | 'number' | 'boolean';
nullable?: boolean;
isPrimaryKey?: boolean;
graphQLProperties?: {

View File

@ -75,6 +75,7 @@ export const formDataInput: Input = {
name: 'ArtistId',
scalarType: 'decimal',
},
consoleDataType: 'number',
},
{
name: 'Name',
@ -85,6 +86,7 @@ export const formDataInput: Input = {
name: 'Name',
scalarType: 'String',
},
consoleDataType: 'string',
},
],
};
@ -105,6 +107,7 @@ export const defaultValuesInput: Parameters<typeof createDefaultValues>[0] = {
name: 'ArtistId',
scalarType: 'decimal',
},
consoleDataType: 'number',
},
{
name: 'Name',
@ -115,6 +118,7 @@ export const defaultValuesInput: Parameters<typeof createDefaultValues>[0] = {
name: 'Name',
scalarType: 'String',
},
consoleDataType: 'string',
},
],
schema,