From c19820709d0abd7625d214e11308117d6d8acb78 Mon Sep 17 00:00:00 2001 From: Anton Standrik Date: Wed, 16 Oct 2024 16:12:31 +0300 Subject: [PATCH 1/7] feat: snippets for table (under tree dots in navigation tree) --- .../Schema/SchemaViewer/SchemaViewer.tsx | 39 ++------ src/containers/Tenant/utils/schema.ts | 8 ++ src/containers/Tenant/utils/schemaActions.ts | 89 ++++++++++++------- .../Tenant/utils/schemaQueryTemplates.ts | 14 ++- src/utils/hooks/index.ts | 1 + src/utils/hooks/useTableData.ts | 82 +++++++++++++++++ .../prepareTableData.ts} | 16 ++-- 7 files changed, 179 insertions(+), 70 deletions(-) create mode 100644 src/utils/hooks/useTableData.ts rename src/{containers/Tenant/Schema/SchemaViewer/prepareData.ts => utils/prepareTableData.ts} (92%) diff --git a/src/containers/Tenant/Schema/SchemaViewer/SchemaViewer.tsx b/src/containers/Tenant/Schema/SchemaViewer/SchemaViewer.tsx index 794d0af5a..d117e13b7 100644 --- a/src/containers/Tenant/Schema/SchemaViewer/SchemaViewer.tsx +++ b/src/containers/Tenant/Schema/SchemaViewer/SchemaViewer.tsx @@ -1,14 +1,10 @@ import React from 'react'; -import {skipToken} from '@reduxjs/toolkit/query'; - import {ResizeableDataTable} from '../../../../components/ResizeableDataTable/ResizeableDataTable'; import {TableSkeleton} from '../../../../components/TableSkeleton/TableSkeleton'; -import {overviewApi} from '../../../../store/reducers/overview/overview'; -import {viewSchemaApi} from '../../../../store/reducers/viewSchema/viewSchema'; import type {EPathType} from '../../../../types/api/schema'; import {DEFAULT_TABLE_SETTINGS} from '../../../../utils/constants'; -import {useAutoRefreshInterval} from '../../../../utils/hooks'; +import {useTableData} from '../../../../utils/hooks'; import { isColumnEntityType, isExternalTableType, @@ -24,7 +20,6 @@ import { getRowTableColumns, getViewColumns, } from './columns'; -import {prepareSchemaData, prepareViewSchema} from './prepareData'; import {b} from './shared'; import './SchemaViewer.scss'; @@ -37,31 +32,11 @@ interface SchemaViewerProps { } export const SchemaViewer = ({type, path, tenantName, extended = false}: SchemaViewerProps) => { - const [autoRefreshInterval] = useAutoRefreshInterval(); - const {currentData, isLoading: loading} = overviewApi.useGetOverviewQuery( - { - paths: [path], - database: tenantName, - }, - { - pollingInterval: autoRefreshInterval, - }, - ); - - const {data: schemaData} = currentData ?? {}; - - const viewSchemaRequestParams = isViewType(type) ? {path, database: tenantName} : skipToken; - - const {data: viewColumnsData, isLoading: isViewSchemaLoading} = - viewSchemaApi.useGetViewSchemaQuery(viewSchemaRequestParams); - - const tableData = React.useMemo(() => { - if (isViewType(type)) { - return prepareViewSchema(viewColumnsData); - } - - return prepareSchemaData(type, schemaData); - }, [schemaData, type, viewColumnsData]); + const {tableData, isOverviewLoading, isViewSchemaLoading} = useTableData({ + type, + path, + tenantName, + }); const hasAutoIncrement = React.useMemo(() => { return tableData.some((i) => i.autoIncrement); @@ -88,7 +63,7 @@ export const SchemaViewer = ({type, path, tenantName, extended = false}: SchemaV return []; }, [type, extended, hasAutoIncrement, hasDefaultValue]); - if (loading || isViewSchemaLoading) { + if (isOverviewLoading || isViewSchemaLoading) { return ; } diff --git a/src/containers/Tenant/utils/schema.ts b/src/containers/Tenant/utils/schema.ts index 4257c3e1c..1aaac1300 100644 --- a/src/containers/Tenant/utils/schema.ts +++ b/src/containers/Tenant/utils/schema.ts @@ -41,6 +41,14 @@ const pathTypeToNodeType: Record [EPathType.EPathTypeReplication]: 'async_replication', }; +export const nodeTableTypeToPathType: Partial> = { + table: EPathType.EPathTypeTable, + index: EPathType.EPathTypeTableIndex, + column_table: EPathType.EPathTypeColumnTable, + external_table: EPathType.EPathTypeExternalTable, + view: EPathType.EPathTypeView, +}; + export const mapPathTypeToNavigationTreeType = ( type: EPathType = EPathType.EPathTypeDir, subType?: EPathSubType, diff --git a/src/containers/Tenant/utils/schemaActions.ts b/src/containers/Tenant/utils/schemaActions.ts index 590b4e2ed..5e4792cd7 100644 --- a/src/containers/Tenant/utils/schemaActions.ts +++ b/src/containers/Tenant/utils/schemaActions.ts @@ -1,15 +1,18 @@ import copy from 'copy-to-clipboard'; import type {NavigationTreeNodeType, NavigationTreeProps} from 'ydb-ui-components'; +import type {AppDispatch} from '../../../store'; import {changeUserInput} from '../../../store/reducers/executeQuery'; import {TENANT_PAGES_IDS, TENANT_QUERY_TABS_ID} from '../../../store/reducers/tenant/constants'; import {setQueryTab, setTenantPage} from '../../../store/reducers/tenant/tenant'; import type {QueryMode, QuerySettings} from '../../../types/store/query'; import createToast from '../../../utils/createToast'; +import {getTableDataPromise} from '../../../utils/hooks'; import {transformPath} from '../ObjectSummary/transformPath'; import i18n from '../i18n'; -import type {SchemaQueryParams} from './schemaQueryTemplates'; +import {nodeTableTypeToPathType} from './schema'; +import type {TemplateFn} from './schemaQueryTemplates'; import { addTableIndex, alterAsyncReplicationTemplate, @@ -36,52 +39,74 @@ interface ActionsAdditionalEffects { showCreateDirectoryDialog?: (path: string) => void; } +interface AdditionalInputQueryOptions { + mode?: QueryMode; + withTableData?: boolean; +} + +interface BindActionParams { + tenantName: string; + type: NavigationTreeNodeType; + path: string; + relativePath: string; +} + const bindActions = ( - schemaQueryParams: SchemaQueryParams, - dispatch: React.Dispatch, + params: BindActionParams, + dispatch: AppDispatch, additionalEffects: ActionsAdditionalEffects, ) => { const {setActivePath, updateQueryExecutionSettings, showCreateDirectoryDialog} = additionalEffects; - const inputQuery = (tmpl: (params?: SchemaQueryParams) => string, mode?: QueryMode) => () => { - if (mode) { - updateQueryExecutionSettings({queryMode: mode}); + const inputQuery = (tmpl: TemplateFn, options?: AdditionalInputQueryOptions) => () => { + if (options?.mode) { + updateQueryExecutionSettings({queryMode: options.mode}); } - dispatch(changeUserInput({input: tmpl(schemaQueryParams)})); + const pathType = nodeTableTypeToPathType[params.type]; + + const userInputDataPromise = + options?.withTableData && pathType + ? getTableDataPromise(params.path, params.tenantName, pathType, dispatch) + : Promise.resolve(undefined); + + userInputDataPromise.then((tableData) => { + dispatch(changeUserInput({input: tmpl({...params, tableData})})); + }); + dispatch(setTenantPage(TENANT_PAGES_IDS.query)); dispatch(setQueryTab(TENANT_QUERY_TABS_ID.newQuery)); - setActivePath(schemaQueryParams.path); + setActivePath(params.path); }; return { createDirectory: showCreateDirectoryDialog ? () => { - showCreateDirectoryDialog(schemaQueryParams.path); + showCreateDirectoryDialog(params.path); } : undefined, - createTable: inputQuery(createTableTemplate, 'script'), - createColumnTable: inputQuery(createColumnTableTemplate, 'script'), - createAsyncReplication: inputQuery(createAsyncReplicationTemplate, 'script'), - alterAsyncReplication: inputQuery(alterAsyncReplicationTemplate, 'script'), - dropAsyncReplication: inputQuery(dropAsyncReplicationTemplate, 'script'), - alterTable: inputQuery(alterTableTemplate, 'script'), - selectQuery: inputQuery(selectQueryTemplate), - upsertQuery: inputQuery(upsertQueryTemplate), - createExternalTable: inputQuery(createExternalTableTemplate, 'script'), - dropExternalTable: inputQuery(dropExternalTableTemplate, 'script'), - selectQueryFromExternalTable: inputQuery(selectQueryTemplate, 'query'), - createTopic: inputQuery(createTopicTemplate, 'script'), - alterTopic: inputQuery(alterTopicTemplate, 'script'), - dropTopic: inputQuery(dropTopicTemplate, 'script'), - createView: inputQuery(createViewTemplate, 'script'), - dropView: inputQuery(dropViewTemplate, 'script'), - dropIndex: inputQuery(dropTableIndex, 'script'), - addTableIndex: inputQuery(addTableIndex, 'script'), + createTable: inputQuery(createTableTemplate, {mode: 'script'}), + createColumnTable: inputQuery(createColumnTableTemplate, {mode: 'script'}), + createAsyncReplication: inputQuery(createAsyncReplicationTemplate, {mode: 'script'}), + alterAsyncReplication: inputQuery(alterAsyncReplicationTemplate, {mode: 'script'}), + dropAsyncReplication: inputQuery(dropAsyncReplicationTemplate, {mode: 'script'}), + alterTable: inputQuery(alterTableTemplate, {mode: 'script'}), + selectQuery: inputQuery(selectQueryTemplate, {withTableData: true}), + upsertQuery: inputQuery(upsertQueryTemplate, {withTableData: true}), + createExternalTable: inputQuery(createExternalTableTemplate, {mode: 'script'}), + dropExternalTable: inputQuery(dropExternalTableTemplate, {mode: 'script'}), + selectQueryFromExternalTable: inputQuery(selectQueryTemplate, {mode: 'query'}), + createTopic: inputQuery(createTopicTemplate, {mode: 'script'}), + alterTopic: inputQuery(alterTopicTemplate, {mode: 'script'}), + dropTopic: inputQuery(dropTopicTemplate, {mode: 'script'}), + createView: inputQuery(createViewTemplate, {mode: 'script'}), + dropView: inputQuery(dropViewTemplate, {mode: 'script'}), + dropIndex: inputQuery(dropTableIndex, {mode: 'script'}), + addTableIndex: inputQuery(addTableIndex, {mode: 'script'}), copyPath: () => { try { - copy(schemaQueryParams.relativePath); + copy(params.relativePath); createToast({ name: 'Copied', title: i18n('actions.copied'), @@ -101,10 +126,14 @@ const bindActions = ( type ActionsSet = ReturnType['getActions']>; export const getActions = - (dispatch: React.Dispatch, additionalEffects: ActionsAdditionalEffects, rootPath = '') => + (dispatch: AppDispatch, additionalEffects: ActionsAdditionalEffects, rootPath = '') => (path: string, type: NavigationTreeNodeType) => { const relativePath = transformPath(path, rootPath); - const actions = bindActions({path, relativePath}, dispatch, additionalEffects); + const actions = bindActions( + {path, relativePath, tenantName: rootPath, type}, + dispatch, + additionalEffects, + ); const copyItem = {text: i18n('actions.copyPath'), action: actions.copyPath}; const DIR_SET: ActionsSet = [ diff --git a/src/containers/Tenant/utils/schemaQueryTemplates.ts b/src/containers/Tenant/utils/schemaQueryTemplates.ts index 0a319dd8b..d7c8a5508 100644 --- a/src/containers/Tenant/utils/schemaQueryTemplates.ts +++ b/src/containers/Tenant/utils/schemaQueryTemplates.ts @@ -1,8 +1,13 @@ +import type {SchemaData} from '../Schema/SchemaViewer/types'; + export interface SchemaQueryParams { path: string; relativePath: string; + tableData?: SchemaData[]; } +export type TemplateFn = (params?: SchemaQueryParams) => string; + export const createTableTemplate = (params?: SchemaQueryParams) => { return `-- docs: https://ydb.tech/en/docs/yql/reference/syntax/create_table CREATE TABLE \`${params?.relativePath || '$path'}/ydb_row_table\` ( @@ -67,13 +72,18 @@ export const alterTableTemplate = (params?: SchemaQueryParams) => { ADD COLUMN numeric_column Int32;`; }; export const selectQueryTemplate = (params?: SchemaQueryParams) => { - return `SELECT * + const columns = params?.tableData?.map((column) => '`' + column.name + '`').join(', ') || '*'; + + return `SELECT ${columns} FROM \`${params?.relativePath || '$path'}\` LIMIT 10;`; }; export const upsertQueryTemplate = (params?: SchemaQueryParams) => { + const columns = + params?.tableData?.map((column) => `\`${column.name}\``).join(', ') || `\`id\`, \`name\``; + return `UPSERT INTO \`${params?.relativePath || '$path'}\` - ( \`id\`, \`name\` ) + ( ${columns} ) VALUES ( );`; }; diff --git a/src/utils/hooks/index.ts b/src/utils/hooks/index.ts index 59b698f82..8dd6227e9 100644 --- a/src/utils/hooks/index.ts +++ b/src/utils/hooks/index.ts @@ -6,3 +6,4 @@ export * from './useTableSort'; export * from './useSearchQuery'; export * from './useAutoRefreshInterval'; export * from './useEventHandler'; +export * from './useTableData'; diff --git a/src/utils/hooks/useTableData.ts b/src/utils/hooks/useTableData.ts new file mode 100644 index 000000000..2514e9b46 --- /dev/null +++ b/src/utils/hooks/useTableData.ts @@ -0,0 +1,82 @@ +import React from 'react'; + +import {skipToken} from '@reduxjs/toolkit/query'; + +import {isViewType} from '../../containers/Tenant/utils/schema'; +import type {AppDispatch} from '../../store'; +import {overviewApi} from '../../store/reducers/overview/overview'; +import {viewSchemaApi} from '../../store/reducers/viewSchema/viewSchema'; +import type {EPathType} from '../../types/api/schema'; +import {prepareSchemaData, prepareViewSchema} from '../prepareTableData'; + +import {useAutoRefreshInterval} from './useAutoRefreshInterval'; + +interface UseTableDataProps { + type?: EPathType; + path: string; + tenantName: string; +} + +const getOverviewData = async (path: string, tenantName: string, dispatch: AppDispatch) => { + const {data: schemaData} = await dispatch( + overviewApi.endpoints.getOverview.initiate({ + paths: [path], + database: tenantName, + }), + ); + return schemaData; +}; + +const getViewSchemaData = async (path: string, tenantName: string, dispatch: AppDispatch) => { + const {data: viewColumnsData} = await dispatch( + viewSchemaApi.endpoints.getViewSchema.initiate({path, database: tenantName}), + ); + return viewColumnsData; +}; + +export const getTableDataPromise = async ( + path: string, + tenantName: string, + type: EPathType, + dispatch: AppDispatch, +) => { + const schemaData = await getOverviewData(path, tenantName, dispatch); + const viewColumnsData = isViewType(type) + ? await getViewSchemaData(path, tenantName, dispatch) + : null; + + return isViewType(type) && viewColumnsData + ? prepareViewSchema(viewColumnsData) + : prepareSchemaData(type, schemaData?.data); +}; + +export const useTableData = ({type, path, tenantName}: UseTableDataProps) => { + const [autoRefreshInterval] = useAutoRefreshInterval(); + + const overviewQuery = overviewApi.useGetOverviewQuery( + { + paths: [path], + database: tenantName, + }, + { + pollingInterval: autoRefreshInterval, + }, + ); + + const viewSchemaQuery = viewSchemaApi.useGetViewSchemaQuery( + isViewType(type) ? {path, database: tenantName} : skipToken, + ); + + const tableData = React.useMemo(() => { + if (isViewType(type)) { + return prepareViewSchema(viewSchemaQuery.data); + } + return prepareSchemaData(type, overviewQuery.currentData?.data); + }, [overviewQuery.currentData?.data, type, viewSchemaQuery.data]); + + return { + tableData, + isViewSchemaLoading: viewSchemaQuery.isLoading, + isOverviewLoading: overviewQuery.isLoading, + }; +}; diff --git a/src/containers/Tenant/Schema/SchemaViewer/prepareData.ts b/src/utils/prepareTableData.ts similarity index 92% rename from src/containers/Tenant/Schema/SchemaViewer/prepareData.ts rename to src/utils/prepareTableData.ts index a349a3d75..d235d1bf9 100644 --- a/src/containers/Tenant/Schema/SchemaViewer/prepareData.ts +++ b/src/utils/prepareTableData.ts @@ -1,4 +1,10 @@ -import type {ColumnType} from '../../../../types/api/query'; +import type {SchemaData} from '../containers/Tenant/Schema/SchemaViewer/types'; +import { + isColumnEntityType, + isExternalTableType, + isRowTableType, +} from '../containers/Tenant/utils/schema'; +import type {ColumnType} from '../types/api/query'; import type { EPathType, TColumnTableDescription, @@ -6,12 +12,10 @@ import type { TExternalTableDescription, TFamilyDescription, TTableDescription, -} from '../../../../types/api/schema'; -import {EColumnCodec} from '../../../../types/api/schema'; -import type {Nullable} from '../../../../utils/typecheckers'; -import {isColumnEntityType, isExternalTableType, isRowTableType} from '../../utils/schema'; +} from '../types/api/schema'; +import {EColumnCodec} from '../types/api/schema'; -import type {SchemaData} from './types'; +import type {Nullable} from './typecheckers'; function formatColumnCodec(codec?: EColumnCodec) { if (!codec) { From adc597a181267e133a95051178fa41199a39972b Mon Sep 17 00:00:00 2001 From: Anton Standrik Date: Thu, 17 Oct 2024 16:08:03 +0300 Subject: [PATCH 2/7] feat: use mutation --- .../Tenant/Schema/SchemaTree/SchemaTree.tsx | 16 ++++ .../Schema/SchemaViewer/SchemaViewer.tsx | 39 +++++++-- .../Schema/SchemaViewer/prepareData.ts} | 16 ++-- src/containers/Tenant/utils/schemaActions.ts | 72 ++++++++-------- src/services/api.ts | 4 +- src/store/reducers/tableSchemaData.ts | 71 ++++++++++++++++ src/store/reducers/viewSchema/viewSchema.ts | 2 +- src/utils/hooks/index.ts | 1 - src/utils/hooks/useTableData.ts | 82 ------------------- 9 files changed, 168 insertions(+), 135 deletions(-) rename src/{utils/prepareTableData.ts => containers/Tenant/Schema/SchemaViewer/prepareData.ts} (92%) create mode 100644 src/store/reducers/tableSchemaData.ts delete mode 100644 src/utils/hooks/useTableData.ts diff --git a/src/containers/Tenant/Schema/SchemaTree/SchemaTree.tsx b/src/containers/Tenant/Schema/SchemaTree/SchemaTree.tsx index 2f7d52c0a..2f3ca6c2d 100644 --- a/src/containers/Tenant/Schema/SchemaTree/SchemaTree.tsx +++ b/src/containers/Tenant/Schema/SchemaTree/SchemaTree.tsx @@ -7,6 +7,8 @@ import {NavigationTree} from 'ydb-ui-components'; import {useCreateDirectoryFeatureAvailable} from '../../../../store/reducers/capabilities/hooks'; import {schemaApi} from '../../../../store/reducers/schema/schema'; +import type {GetTableSchemaDataParams} from '../../../../store/reducers/tableSchemaData'; +import {useGetTableSchemaDataMutation} from '../../../../store/reducers/tableSchemaData'; import type {EPathType, TEvDescribeSchemeResult} from '../../../../types/api/schema'; import {useQueryExecutionSettings, useTypedDispatch} from '../../../../utils/hooks'; import {getSchemaControls} from '../../utils/controls'; @@ -26,6 +28,19 @@ export function SchemaTree(props: SchemaTreeProps) { const createDirectoryFeatureAvailable = useCreateDirectoryFeatureAvailable(); const {rootPath, rootName, rootType, currentPath, onActivePathUpdate} = props; const dispatch = useTypedDispatch(); + const [getTableSchemaDataMutation] = useGetTableSchemaDataMutation(); + + const getTableSchemaDataPromise = React.useCallback( + async (args: GetTableSchemaDataParams) => { + try { + const result = await getTableSchemaDataMutation(args).unwrap(); + return result; + } catch (e) { + return undefined; + } + }, + [getTableSchemaDataMutation], + ); const [querySettings, setQueryExecutionSettings] = useQueryExecutionSettings(); const [createDirectoryOpen, setCreateDirectoryOpen] = React.useState(false); @@ -119,6 +134,7 @@ export function SchemaTree(props: SchemaTreeProps) { showCreateDirectoryDialog: createDirectoryFeatureAvailable ? handleOpenCreateDirectoryDialog : undefined, + getTableSchemaDataPromise, }, rootPath, )} diff --git a/src/containers/Tenant/Schema/SchemaViewer/SchemaViewer.tsx b/src/containers/Tenant/Schema/SchemaViewer/SchemaViewer.tsx index d117e13b7..794d0af5a 100644 --- a/src/containers/Tenant/Schema/SchemaViewer/SchemaViewer.tsx +++ b/src/containers/Tenant/Schema/SchemaViewer/SchemaViewer.tsx @@ -1,10 +1,14 @@ import React from 'react'; +import {skipToken} from '@reduxjs/toolkit/query'; + import {ResizeableDataTable} from '../../../../components/ResizeableDataTable/ResizeableDataTable'; import {TableSkeleton} from '../../../../components/TableSkeleton/TableSkeleton'; +import {overviewApi} from '../../../../store/reducers/overview/overview'; +import {viewSchemaApi} from '../../../../store/reducers/viewSchema/viewSchema'; import type {EPathType} from '../../../../types/api/schema'; import {DEFAULT_TABLE_SETTINGS} from '../../../../utils/constants'; -import {useTableData} from '../../../../utils/hooks'; +import {useAutoRefreshInterval} from '../../../../utils/hooks'; import { isColumnEntityType, isExternalTableType, @@ -20,6 +24,7 @@ import { getRowTableColumns, getViewColumns, } from './columns'; +import {prepareSchemaData, prepareViewSchema} from './prepareData'; import {b} from './shared'; import './SchemaViewer.scss'; @@ -32,11 +37,31 @@ interface SchemaViewerProps { } export const SchemaViewer = ({type, path, tenantName, extended = false}: SchemaViewerProps) => { - const {tableData, isOverviewLoading, isViewSchemaLoading} = useTableData({ - type, - path, - tenantName, - }); + const [autoRefreshInterval] = useAutoRefreshInterval(); + const {currentData, isLoading: loading} = overviewApi.useGetOverviewQuery( + { + paths: [path], + database: tenantName, + }, + { + pollingInterval: autoRefreshInterval, + }, + ); + + const {data: schemaData} = currentData ?? {}; + + const viewSchemaRequestParams = isViewType(type) ? {path, database: tenantName} : skipToken; + + const {data: viewColumnsData, isLoading: isViewSchemaLoading} = + viewSchemaApi.useGetViewSchemaQuery(viewSchemaRequestParams); + + const tableData = React.useMemo(() => { + if (isViewType(type)) { + return prepareViewSchema(viewColumnsData); + } + + return prepareSchemaData(type, schemaData); + }, [schemaData, type, viewColumnsData]); const hasAutoIncrement = React.useMemo(() => { return tableData.some((i) => i.autoIncrement); @@ -63,7 +88,7 @@ export const SchemaViewer = ({type, path, tenantName, extended = false}: SchemaV return []; }, [type, extended, hasAutoIncrement, hasDefaultValue]); - if (isOverviewLoading || isViewSchemaLoading) { + if (loading || isViewSchemaLoading) { return ; } diff --git a/src/utils/prepareTableData.ts b/src/containers/Tenant/Schema/SchemaViewer/prepareData.ts similarity index 92% rename from src/utils/prepareTableData.ts rename to src/containers/Tenant/Schema/SchemaViewer/prepareData.ts index d235d1bf9..a349a3d75 100644 --- a/src/utils/prepareTableData.ts +++ b/src/containers/Tenant/Schema/SchemaViewer/prepareData.ts @@ -1,10 +1,4 @@ -import type {SchemaData} from '../containers/Tenant/Schema/SchemaViewer/types'; -import { - isColumnEntityType, - isExternalTableType, - isRowTableType, -} from '../containers/Tenant/utils/schema'; -import type {ColumnType} from '../types/api/query'; +import type {ColumnType} from '../../../../types/api/query'; import type { EPathType, TColumnTableDescription, @@ -12,10 +6,12 @@ import type { TExternalTableDescription, TFamilyDescription, TTableDescription, -} from '../types/api/schema'; -import {EColumnCodec} from '../types/api/schema'; +} from '../../../../types/api/schema'; +import {EColumnCodec} from '../../../../types/api/schema'; +import type {Nullable} from '../../../../utils/typecheckers'; +import {isColumnEntityType, isExternalTableType, isRowTableType} from '../../utils/schema'; -import type {Nullable} from './typecheckers'; +import type {SchemaData} from './types'; function formatColumnCodec(codec?: EColumnCodec) { if (!codec) { diff --git a/src/containers/Tenant/utils/schemaActions.ts b/src/containers/Tenant/utils/schemaActions.ts index 5e4792cd7..04bed6ab4 100644 --- a/src/containers/Tenant/utils/schemaActions.ts +++ b/src/containers/Tenant/utils/schemaActions.ts @@ -3,12 +3,13 @@ import type {NavigationTreeNodeType, NavigationTreeProps} from 'ydb-ui-component import type {AppDispatch} from '../../../store'; import {changeUserInput} from '../../../store/reducers/executeQuery'; +import type {GetTableSchemaDataParams} from '../../../store/reducers/tableSchemaData'; import {TENANT_PAGES_IDS, TENANT_QUERY_TABS_ID} from '../../../store/reducers/tenant/constants'; import {setQueryTab, setTenantPage} from '../../../store/reducers/tenant/tenant'; import type {QueryMode, QuerySettings} from '../../../types/store/query'; import createToast from '../../../utils/createToast'; -import {getTableDataPromise} from '../../../utils/hooks'; import {transformPath} from '../ObjectSummary/transformPath'; +import type {SchemaData} from '../Schema/SchemaViewer/types'; import i18n from '../i18n'; import {nodeTableTypeToPathType} from './schema'; @@ -37,11 +38,9 @@ interface ActionsAdditionalEffects { updateQueryExecutionSettings: (settings?: Partial) => void; setActivePath: (path: string) => void; showCreateDirectoryDialog?: (path: string) => void; -} - -interface AdditionalInputQueryOptions { - mode?: QueryMode; - withTableData?: boolean; + getTableSchemaDataPromise?: ( + params: GetTableSchemaDataParams, + ) => Promise; } interface BindActionParams { @@ -56,19 +55,28 @@ const bindActions = ( dispatch: AppDispatch, additionalEffects: ActionsAdditionalEffects, ) => { - const {setActivePath, updateQueryExecutionSettings, showCreateDirectoryDialog} = - additionalEffects; - - const inputQuery = (tmpl: TemplateFn, options?: AdditionalInputQueryOptions) => () => { - if (options?.mode) { - updateQueryExecutionSettings({queryMode: options.mode}); + const { + setActivePath, + updateQueryExecutionSettings, + showCreateDirectoryDialog, + getTableSchemaDataPromise, + } = additionalEffects; + + const inputQuery = (tmpl: TemplateFn, mode?: QueryMode) => () => { + if (mode) { + updateQueryExecutionSettings({queryMode: mode}); } const pathType = nodeTableTypeToPathType[params.type]; + const withTableData = [selectQueryTemplate, upsertQueryTemplate].includes(tmpl); const userInputDataPromise = - options?.withTableData && pathType - ? getTableDataPromise(params.path, params.tenantName, pathType, dispatch) + withTableData && pathType && getTableSchemaDataPromise + ? getTableSchemaDataPromise({ + path: params.path, + tenantName: params.tenantName, + type: pathType, + }) : Promise.resolve(undefined); userInputDataPromise.then((tableData) => { @@ -86,24 +94,24 @@ const bindActions = ( showCreateDirectoryDialog(params.path); } : undefined, - createTable: inputQuery(createTableTemplate, {mode: 'script'}), - createColumnTable: inputQuery(createColumnTableTemplate, {mode: 'script'}), - createAsyncReplication: inputQuery(createAsyncReplicationTemplate, {mode: 'script'}), - alterAsyncReplication: inputQuery(alterAsyncReplicationTemplate, {mode: 'script'}), - dropAsyncReplication: inputQuery(dropAsyncReplicationTemplate, {mode: 'script'}), - alterTable: inputQuery(alterTableTemplate, {mode: 'script'}), - selectQuery: inputQuery(selectQueryTemplate, {withTableData: true}), - upsertQuery: inputQuery(upsertQueryTemplate, {withTableData: true}), - createExternalTable: inputQuery(createExternalTableTemplate, {mode: 'script'}), - dropExternalTable: inputQuery(dropExternalTableTemplate, {mode: 'script'}), - selectQueryFromExternalTable: inputQuery(selectQueryTemplate, {mode: 'query'}), - createTopic: inputQuery(createTopicTemplate, {mode: 'script'}), - alterTopic: inputQuery(alterTopicTemplate, {mode: 'script'}), - dropTopic: inputQuery(dropTopicTemplate, {mode: 'script'}), - createView: inputQuery(createViewTemplate, {mode: 'script'}), - dropView: inputQuery(dropViewTemplate, {mode: 'script'}), - dropIndex: inputQuery(dropTableIndex, {mode: 'script'}), - addTableIndex: inputQuery(addTableIndex, {mode: 'script'}), + createTable: inputQuery(createTableTemplate, 'script'), + createColumnTable: inputQuery(createColumnTableTemplate, 'script'), + createAsyncReplication: inputQuery(createAsyncReplicationTemplate, 'script'), + alterAsyncReplication: inputQuery(alterAsyncReplicationTemplate, 'script'), + dropAsyncReplication: inputQuery(dropAsyncReplicationTemplate, 'script'), + alterTable: inputQuery(alterTableTemplate, 'script'), + selectQuery: inputQuery(selectQueryTemplate), + upsertQuery: inputQuery(upsertQueryTemplate), + createExternalTable: inputQuery(createExternalTableTemplate, 'script'), + dropExternalTable: inputQuery(dropExternalTableTemplate, 'script'), + selectQueryFromExternalTable: inputQuery(selectQueryTemplate, 'query'), + createTopic: inputQuery(createTopicTemplate, 'script'), + alterTopic: inputQuery(alterTopicTemplate, 'script'), + dropTopic: inputQuery(dropTopicTemplate, 'script'), + createView: inputQuery(createViewTemplate, 'script'), + dropView: inputQuery(dropViewTemplate, 'script'), + dropIndex: inputQuery(dropTableIndex, 'script'), + addTableIndex: inputQuery(addTableIndex, 'script'), copyPath: () => { try { copy(params.relativePath); diff --git a/src/services/api.ts b/src/services/api.ts index 659b9f40b..2ddc2be44 100644 --- a/src/services/api.ts +++ b/src/services/api.ts @@ -374,7 +374,7 @@ export class YdbEmbeddedAPI extends AxiosWrapper { ); } getDescribe( - {path, database}: {path: string; database: string}, + {path, database, timeout}: {path: string; database: string; timeout?: Timeout}, {concurrentId, signal}: AxiosOptions = {}, ) { return this.get>( @@ -386,7 +386,7 @@ export class YdbEmbeddedAPI extends AxiosWrapper { partition_stats: true, subs: 0, }, - {concurrentId: concurrentId || `getDescribe|${path}`, requestConfig: {signal}}, + {concurrentId: concurrentId || `getDescribe|${path}`, requestConfig: {signal}, timeout}, ); } getSchemaAcl( diff --git a/src/store/reducers/tableSchemaData.ts b/src/store/reducers/tableSchemaData.ts new file mode 100644 index 000000000..30628180e --- /dev/null +++ b/src/store/reducers/tableSchemaData.ts @@ -0,0 +1,71 @@ +import { + prepareSchemaData, + prepareViewSchema, +} from '../../containers/Tenant/Schema/SchemaViewer/prepareData'; +import type {SchemaData} from '../../containers/Tenant/Schema/SchemaViewer/types'; +import {isViewType} from '../../containers/Tenant/utils/schema'; +import type {EPathType} from '../../types/api/schema'; +import {isQueryErrorResponse} from '../../utils/query'; + +import {api} from './api'; +import {createViewSchemaQuery} from './viewSchema/viewSchema'; + +export interface GetTableSchemaDataParams { + path: string; + tenantName: string; + type: EPathType; +} + +const tableSchemaDataConcurrentId = 'getTableSchemaData'; + +const TABLE_SCHEMA_TIMEOUT = 1000; + +export const tableSchemeDataApi = api.injectEndpoints({ + endpoints: (build) => ({ + getTableSchemaData: build.mutation({ + queryFn: async ({path, tenantName, type}, {signal}) => { + try { + const schemaData = await window.api.getDescribe( + { + path, + database: tenantName, + timeout: TABLE_SCHEMA_TIMEOUT, + }, + {signal, concurrentId: tableSchemaDataConcurrentId + 'describe'}, + ); + + if (isViewType(type)) { + const response = await window.api.sendQuery( + { + query: createViewSchemaQuery(path), + database: tenantName, + action: 'execute-scan', + timeout: TABLE_SCHEMA_TIMEOUT, + }, + { + withRetries: true, + concurrentId: tableSchemaDataConcurrentId + 'query', + }, + ); + + if (isQueryErrorResponse(response)) { + return {error: response}; + } + + const viewColumnsData = {data: response?.result?.[0]?.columns || []}; + const result = prepareViewSchema(viewColumnsData.data); + return {data: result}; + } + + const result = prepareSchemaData(type, schemaData); + + return {data: result}; + } catch (error) { + return {error}; + } + }, + }), + }), +}); + +export const {useGetTableSchemaDataMutation} = tableSchemeDataApi; diff --git a/src/store/reducers/viewSchema/viewSchema.ts b/src/store/reducers/viewSchema/viewSchema.ts index eba8c3d11..94283aa7e 100644 --- a/src/store/reducers/viewSchema/viewSchema.ts +++ b/src/store/reducers/viewSchema/viewSchema.ts @@ -1,7 +1,7 @@ import {isQueryErrorResponse} from '../../../utils/query'; import {api} from '../api'; -function createViewSchemaQuery(path: string) { +export function createViewSchemaQuery(path: string) { return `SELECT * FROM \`${path}\` LIMIT 0`; } diff --git a/src/utils/hooks/index.ts b/src/utils/hooks/index.ts index 8dd6227e9..59b698f82 100644 --- a/src/utils/hooks/index.ts +++ b/src/utils/hooks/index.ts @@ -6,4 +6,3 @@ export * from './useTableSort'; export * from './useSearchQuery'; export * from './useAutoRefreshInterval'; export * from './useEventHandler'; -export * from './useTableData'; diff --git a/src/utils/hooks/useTableData.ts b/src/utils/hooks/useTableData.ts deleted file mode 100644 index 2514e9b46..000000000 --- a/src/utils/hooks/useTableData.ts +++ /dev/null @@ -1,82 +0,0 @@ -import React from 'react'; - -import {skipToken} from '@reduxjs/toolkit/query'; - -import {isViewType} from '../../containers/Tenant/utils/schema'; -import type {AppDispatch} from '../../store'; -import {overviewApi} from '../../store/reducers/overview/overview'; -import {viewSchemaApi} from '../../store/reducers/viewSchema/viewSchema'; -import type {EPathType} from '../../types/api/schema'; -import {prepareSchemaData, prepareViewSchema} from '../prepareTableData'; - -import {useAutoRefreshInterval} from './useAutoRefreshInterval'; - -interface UseTableDataProps { - type?: EPathType; - path: string; - tenantName: string; -} - -const getOverviewData = async (path: string, tenantName: string, dispatch: AppDispatch) => { - const {data: schemaData} = await dispatch( - overviewApi.endpoints.getOverview.initiate({ - paths: [path], - database: tenantName, - }), - ); - return schemaData; -}; - -const getViewSchemaData = async (path: string, tenantName: string, dispatch: AppDispatch) => { - const {data: viewColumnsData} = await dispatch( - viewSchemaApi.endpoints.getViewSchema.initiate({path, database: tenantName}), - ); - return viewColumnsData; -}; - -export const getTableDataPromise = async ( - path: string, - tenantName: string, - type: EPathType, - dispatch: AppDispatch, -) => { - const schemaData = await getOverviewData(path, tenantName, dispatch); - const viewColumnsData = isViewType(type) - ? await getViewSchemaData(path, tenantName, dispatch) - : null; - - return isViewType(type) && viewColumnsData - ? prepareViewSchema(viewColumnsData) - : prepareSchemaData(type, schemaData?.data); -}; - -export const useTableData = ({type, path, tenantName}: UseTableDataProps) => { - const [autoRefreshInterval] = useAutoRefreshInterval(); - - const overviewQuery = overviewApi.useGetOverviewQuery( - { - paths: [path], - database: tenantName, - }, - { - pollingInterval: autoRefreshInterval, - }, - ); - - const viewSchemaQuery = viewSchemaApi.useGetViewSchemaQuery( - isViewType(type) ? {path, database: tenantName} : skipToken, - ); - - const tableData = React.useMemo(() => { - if (isViewType(type)) { - return prepareViewSchema(viewSchemaQuery.data); - } - return prepareSchemaData(type, overviewQuery.currentData?.data); - }, [overviewQuery.currentData?.data, type, viewSchemaQuery.data]); - - return { - tableData, - isViewSchemaLoading: viewSchemaQuery.isLoading, - isOverviewLoading: overviewQuery.isLoading, - }; -}; From 9e3b29d257afd9d5d32f9fe5fc60e6bc5d52492f Mon Sep 17 00:00:00 2001 From: Anton Standrik Date: Thu, 17 Oct 2024 16:26:18 +0300 Subject: [PATCH 3/7] fix: use existing endpoints --- src/store/reducers/overview/overview.ts | 14 ++++++-- src/store/reducers/tableSchemaData.ts | 38 +++++++++------------ src/store/reducers/viewSchema/viewSchema.ts | 16 +++++++-- 3 files changed, 43 insertions(+), 25 deletions(-) diff --git a/src/store/reducers/overview/overview.ts b/src/store/reducers/overview/overview.ts index 070e1b175..bdd548e27 100644 --- a/src/store/reducers/overview/overview.ts +++ b/src/store/reducers/overview/overview.ts @@ -1,9 +1,18 @@ +import type {Timeout} from '../../../types/api/query'; import {api} from '../api'; export const overviewApi = api.injectEndpoints({ endpoints: (build) => ({ getOverview: build.query({ - queryFn: async ({paths, database}: {paths: string[]; database: string}, {signal}) => { + queryFn: async ( + { + paths, + database, + timeout, + concurrentId, + }: {paths: string[]; database: string; timeout?: Timeout; concurrentId?: string}, + {signal}, + ) => { try { const [data, ...additionalData] = await Promise.all( paths.map((p) => @@ -11,8 +20,9 @@ export const overviewApi = api.injectEndpoints({ { path: p, database, + timeout, }, - {signal}, + {signal, concurrentId}, ), ), ); diff --git a/src/store/reducers/tableSchemaData.ts b/src/store/reducers/tableSchemaData.ts index 30628180e..7c55a669a 100644 --- a/src/store/reducers/tableSchemaData.ts +++ b/src/store/reducers/tableSchemaData.ts @@ -8,7 +8,8 @@ import type {EPathType} from '../../types/api/schema'; import {isQueryErrorResponse} from '../../utils/query'; import {api} from './api'; -import {createViewSchemaQuery} from './viewSchema/viewSchema'; +import {overviewApi} from './overview/overview'; +import {viewSchemaApi} from './viewSchema/viewSchema'; export interface GetTableSchemaDataParams { path: string; @@ -16,48 +17,43 @@ export interface GetTableSchemaDataParams { type: EPathType; } -const tableSchemaDataConcurrentId = 'getTableSchemaData'; - const TABLE_SCHEMA_TIMEOUT = 1000; +const getTableSchemaDataConcurrentId = 'getTableSchemaData'; + export const tableSchemeDataApi = api.injectEndpoints({ endpoints: (build) => ({ getTableSchemaData: build.mutation({ - queryFn: async ({path, tenantName, type}, {signal}) => { + queryFn: async ({path, tenantName, type}, {dispatch}) => { try { - const schemaData = await window.api.getDescribe( - { - path, + const schemaData = await dispatch( + overviewApi.endpoints.getOverview.initiate({ + paths: [path], database: tenantName, timeout: TABLE_SCHEMA_TIMEOUT, - }, - {signal, concurrentId: tableSchemaDataConcurrentId + 'describe'}, + concurrentId: getTableSchemaDataConcurrentId + 'getOverview', + }), ); if (isViewType(type)) { - const response = await window.api.sendQuery( - { - query: createViewSchemaQuery(path), + const response = await dispatch( + viewSchemaApi.endpoints.getViewSchema.initiate({ database: tenantName, - action: 'execute-scan', + path, timeout: TABLE_SCHEMA_TIMEOUT, - }, - { - withRetries: true, - concurrentId: tableSchemaDataConcurrentId + 'query', - }, + concurrentId: getTableSchemaDataConcurrentId + 'getViewSchema', + }), ); if (isQueryErrorResponse(response)) { return {error: response}; } - const viewColumnsData = {data: response?.result?.[0]?.columns || []}; - const result = prepareViewSchema(viewColumnsData.data); + const result = prepareViewSchema(response.data); return {data: result}; } - const result = prepareSchemaData(type, schemaData); + const result = prepareSchemaData(type, schemaData.data?.data); return {data: result}; } catch (error) { diff --git a/src/store/reducers/viewSchema/viewSchema.ts b/src/store/reducers/viewSchema/viewSchema.ts index 94283aa7e..1a9ab04d7 100644 --- a/src/store/reducers/viewSchema/viewSchema.ts +++ b/src/store/reducers/viewSchema/viewSchema.ts @@ -1,3 +1,4 @@ +import type {Timeout} from '../../../types/api/query'; import {isQueryErrorResponse} from '../../../utils/query'; import {api} from '../api'; @@ -8,15 +9,26 @@ export function createViewSchemaQuery(path: string) { export const viewSchemaApi = api.injectEndpoints({ endpoints: (build) => ({ getViewSchema: build.query({ - queryFn: async ({database, path}: {database: string; path: string}) => { + queryFn: async ({ + database, + path, + timeout, + concurrentId, + }: { + database: string; + path: string; + timeout?: Timeout; + concurrentId?: string; + }) => { try { const response = await window.api.sendQuery( { query: createViewSchemaQuery(path), database, action: 'execute-scan', + timeout, }, - {withRetries: true}, + {withRetries: true, concurrentId}, ); if (isQueryErrorResponse(response)) { From 2efd40cd7219571ca45d0ef79658e4f07f28d22f Mon Sep 17 00:00:00 2001 From: Anton Standrik Date: Thu, 17 Oct 2024 20:55:39 +0300 Subject: [PATCH 4/7] fix: review fixes --- .../Tenant/Schema/SchemaTree/SchemaTree.tsx | 9 +++++++- src/services/api.ts | 4 ++-- src/store/reducers/overview/overview.ts | 14 ++----------- src/store/reducers/tableSchemaData.ts | 21 ++++++------------- src/store/reducers/viewSchema/viewSchema.ts | 16 ++------------ src/utils/index.ts | 4 ++-- 6 files changed, 22 insertions(+), 46 deletions(-) diff --git a/src/containers/Tenant/Schema/SchemaTree/SchemaTree.tsx b/src/containers/Tenant/Schema/SchemaTree/SchemaTree.tsx index 2f3ca6c2d..edb49e30b 100644 --- a/src/containers/Tenant/Schema/SchemaTree/SchemaTree.tsx +++ b/src/containers/Tenant/Schema/SchemaTree/SchemaTree.tsx @@ -10,6 +10,8 @@ import {schemaApi} from '../../../../store/reducers/schema/schema'; import type {GetTableSchemaDataParams} from '../../../../store/reducers/tableSchemaData'; import {useGetTableSchemaDataMutation} from '../../../../store/reducers/tableSchemaData'; import type {EPathType, TEvDescribeSchemeResult} from '../../../../types/api/schema'; +import {wait} from '../../../../utils'; +import {SECOND_IN_MS} from '../../../../utils/constants'; import {useQueryExecutionSettings, useTypedDispatch} from '../../../../utils/hooks'; import {getSchemaControls} from '../../utils/controls'; import {isChildlessPathType, mapPathTypeToNavigationTreeType} from '../../utils/schema'; @@ -24,6 +26,8 @@ interface SchemaTreeProps { onActivePathUpdate: (path: string) => void; } +const TABLE_SCHEMA_TIMEOUT = SECOND_IN_MS * 2; + export function SchemaTree(props: SchemaTreeProps) { const createDirectoryFeatureAvailable = useCreateDirectoryFeatureAvailable(); const {rootPath, rootName, rootType, currentPath, onActivePathUpdate} = props; @@ -33,7 +37,10 @@ export function SchemaTree(props: SchemaTreeProps) { const getTableSchemaDataPromise = React.useCallback( async (args: GetTableSchemaDataParams) => { try { - const result = await getTableSchemaDataMutation(args).unwrap(); + const result = await Promise.race([ + getTableSchemaDataMutation(args).unwrap(), + wait(TABLE_SCHEMA_TIMEOUT), + ]); return result; } catch (e) { return undefined; diff --git a/src/services/api.ts b/src/services/api.ts index 2ddc2be44..659b9f40b 100644 --- a/src/services/api.ts +++ b/src/services/api.ts @@ -374,7 +374,7 @@ export class YdbEmbeddedAPI extends AxiosWrapper { ); } getDescribe( - {path, database, timeout}: {path: string; database: string; timeout?: Timeout}, + {path, database}: {path: string; database: string}, {concurrentId, signal}: AxiosOptions = {}, ) { return this.get>( @@ -386,7 +386,7 @@ export class YdbEmbeddedAPI extends AxiosWrapper { partition_stats: true, subs: 0, }, - {concurrentId: concurrentId || `getDescribe|${path}`, requestConfig: {signal}, timeout}, + {concurrentId: concurrentId || `getDescribe|${path}`, requestConfig: {signal}}, ); } getSchemaAcl( diff --git a/src/store/reducers/overview/overview.ts b/src/store/reducers/overview/overview.ts index bdd548e27..070e1b175 100644 --- a/src/store/reducers/overview/overview.ts +++ b/src/store/reducers/overview/overview.ts @@ -1,18 +1,9 @@ -import type {Timeout} from '../../../types/api/query'; import {api} from '../api'; export const overviewApi = api.injectEndpoints({ endpoints: (build) => ({ getOverview: build.query({ - queryFn: async ( - { - paths, - database, - timeout, - concurrentId, - }: {paths: string[]; database: string; timeout?: Timeout; concurrentId?: string}, - {signal}, - ) => { + queryFn: async ({paths, database}: {paths: string[]; database: string}, {signal}) => { try { const [data, ...additionalData] = await Promise.all( paths.map((p) => @@ -20,9 +11,8 @@ export const overviewApi = api.injectEndpoints({ { path: p, database, - timeout, }, - {signal, concurrentId}, + {signal}, ), ), ); diff --git a/src/store/reducers/tableSchemaData.ts b/src/store/reducers/tableSchemaData.ts index 7c55a669a..2622d149d 100644 --- a/src/store/reducers/tableSchemaData.ts +++ b/src/store/reducers/tableSchemaData.ts @@ -17,31 +17,16 @@ export interface GetTableSchemaDataParams { type: EPathType; } -const TABLE_SCHEMA_TIMEOUT = 1000; - -const getTableSchemaDataConcurrentId = 'getTableSchemaData'; - export const tableSchemeDataApi = api.injectEndpoints({ endpoints: (build) => ({ getTableSchemaData: build.mutation({ queryFn: async ({path, tenantName, type}, {dispatch}) => { try { - const schemaData = await dispatch( - overviewApi.endpoints.getOverview.initiate({ - paths: [path], - database: tenantName, - timeout: TABLE_SCHEMA_TIMEOUT, - concurrentId: getTableSchemaDataConcurrentId + 'getOverview', - }), - ); - if (isViewType(type)) { const response = await dispatch( viewSchemaApi.endpoints.getViewSchema.initiate({ database: tenantName, path, - timeout: TABLE_SCHEMA_TIMEOUT, - concurrentId: getTableSchemaDataConcurrentId + 'getViewSchema', }), ); @@ -53,6 +38,12 @@ export const tableSchemeDataApi = api.injectEndpoints({ return {data: result}; } + const schemaData = await dispatch( + overviewApi.endpoints.getOverview.initiate({ + paths: [path], + database: tenantName, + }), + ); const result = prepareSchemaData(type, schemaData.data?.data); return {data: result}; diff --git a/src/store/reducers/viewSchema/viewSchema.ts b/src/store/reducers/viewSchema/viewSchema.ts index 1a9ab04d7..94283aa7e 100644 --- a/src/store/reducers/viewSchema/viewSchema.ts +++ b/src/store/reducers/viewSchema/viewSchema.ts @@ -1,4 +1,3 @@ -import type {Timeout} from '../../../types/api/query'; import {isQueryErrorResponse} from '../../../utils/query'; import {api} from '../api'; @@ -9,26 +8,15 @@ export function createViewSchemaQuery(path: string) { export const viewSchemaApi = api.injectEndpoints({ endpoints: (build) => ({ getViewSchema: build.query({ - queryFn: async ({ - database, - path, - timeout, - concurrentId, - }: { - database: string; - path: string; - timeout?: Timeout; - concurrentId?: string; - }) => { + queryFn: async ({database, path}: {database: string; path: string}) => { try { const response = await window.api.sendQuery( { query: createViewSchemaQuery(path), database, action: 'execute-scan', - timeout, }, - {withRetries: true, concurrentId}, + {withRetries: true}, ); if (isQueryErrorResponse(response)) { diff --git a/src/utils/index.ts b/src/utils/index.ts index 308dce79e..8957aa474 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -6,8 +6,8 @@ export function valueIsDefined(value: T | null | undefined): value is T { return value !== null && value !== undefined; } -export async function wait(time: number) { +export async function wait(time: number, value?: T): Promise { return new Promise((resolve) => { - setTimeout(resolve, time); + setTimeout(() => resolve(value), time); }); } From d81165ae0ceaeb191799e35fbb97911dcb9fd459 Mon Sep 17 00:00:00 2001 From: Anton Standrik Date: Thu, 17 Oct 2024 20:58:10 +0300 Subject: [PATCH 5/7] fix: checks fix --- src/containers/Tenant/Schema/SchemaTree/SchemaTree.tsx | 4 ++-- src/store/reducers/tableSchemaData.ts | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/containers/Tenant/Schema/SchemaTree/SchemaTree.tsx b/src/containers/Tenant/Schema/SchemaTree/SchemaTree.tsx index edb49e30b..98fd08c98 100644 --- a/src/containers/Tenant/Schema/SchemaTree/SchemaTree.tsx +++ b/src/containers/Tenant/Schema/SchemaTree/SchemaTree.tsx @@ -7,8 +7,8 @@ import {NavigationTree} from 'ydb-ui-components'; import {useCreateDirectoryFeatureAvailable} from '../../../../store/reducers/capabilities/hooks'; import {schemaApi} from '../../../../store/reducers/schema/schema'; +import {tableSchemaDataApi} from '../../../../store/reducers/tableSchemaData'; import type {GetTableSchemaDataParams} from '../../../../store/reducers/tableSchemaData'; -import {useGetTableSchemaDataMutation} from '../../../../store/reducers/tableSchemaData'; import type {EPathType, TEvDescribeSchemeResult} from '../../../../types/api/schema'; import {wait} from '../../../../utils'; import {SECOND_IN_MS} from '../../../../utils/constants'; @@ -32,7 +32,7 @@ export function SchemaTree(props: SchemaTreeProps) { const createDirectoryFeatureAvailable = useCreateDirectoryFeatureAvailable(); const {rootPath, rootName, rootType, currentPath, onActivePathUpdate} = props; const dispatch = useTypedDispatch(); - const [getTableSchemaDataMutation] = useGetTableSchemaDataMutation(); + const [getTableSchemaDataMutation] = tableSchemaDataApi.useGetTableSchemaDataMutation(); const getTableSchemaDataPromise = React.useCallback( async (args: GetTableSchemaDataParams) => { diff --git a/src/store/reducers/tableSchemaData.ts b/src/store/reducers/tableSchemaData.ts index 2622d149d..af7ce34a6 100644 --- a/src/store/reducers/tableSchemaData.ts +++ b/src/store/reducers/tableSchemaData.ts @@ -17,7 +17,7 @@ export interface GetTableSchemaDataParams { type: EPathType; } -export const tableSchemeDataApi = api.injectEndpoints({ +export const tableSchemaDataApi = api.injectEndpoints({ endpoints: (build) => ({ getTableSchemaData: build.mutation({ queryFn: async ({path, tenantName, type}, {dispatch}) => { @@ -54,5 +54,3 @@ export const tableSchemeDataApi = api.injectEndpoints({ }), }), }); - -export const {useGetTableSchemaDataMutation} = tableSchemeDataApi; From d537ae44068cfeffce3e6212b588439f68a5ec4b Mon Sep 17 00:00:00 2001 From: Anton Standrik Date: Thu, 17 Oct 2024 21:24:23 +0300 Subject: [PATCH 6/7] fix: checks --- src/store/reducers/tableSchemaData.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/store/reducers/tableSchemaData.ts b/src/store/reducers/tableSchemaData.ts index af7ce34a6..93485c34b 100644 --- a/src/store/reducers/tableSchemaData.ts +++ b/src/store/reducers/tableSchemaData.ts @@ -40,11 +40,11 @@ export const tableSchemaDataApi = api.injectEndpoints({ const schemaData = await dispatch( overviewApi.endpoints.getOverview.initiate({ - paths: [path], + path, database: tenantName, }), ); - const result = prepareSchemaData(type, schemaData.data?.data); + const result = prepareSchemaData(type, schemaData.data); return {data: result}; } catch (error) { From e4c3198e9a91fb7453f07f14996d4accae25b36c Mon Sep 17 00:00:00 2001 From: Anton Standrik Date: Thu, 17 Oct 2024 21:31:36 +0300 Subject: [PATCH 7/7] fix: rm unused query --- src/store/reducers/viewSchema/viewSchema.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/store/reducers/viewSchema/viewSchema.ts b/src/store/reducers/viewSchema/viewSchema.ts index 94283aa7e..eba8c3d11 100644 --- a/src/store/reducers/viewSchema/viewSchema.ts +++ b/src/store/reducers/viewSchema/viewSchema.ts @@ -1,7 +1,7 @@ import {isQueryErrorResponse} from '../../../utils/query'; import {api} from '../api'; -export function createViewSchemaQuery(path: string) { +function createViewSchemaQuery(path: string) { return `SELECT * FROM \`${path}\` LIMIT 0`; }