Skip to content

Commit

Permalink
feat: add rows limit to query settings (#1291)
Browse files Browse the repository at this point in the history
  • Loading branch information
astandrik authored Sep 23, 2024
1 parent 61c3562 commit 1728e61
Show file tree
Hide file tree
Showing 22 changed files with 162 additions and 96 deletions.
10 changes: 10 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"@gravity-ui/table": "^0.5.0",
"@gravity-ui/uikit": "^6.20.1",
"@gravity-ui/websql-autocomplete": "^9.1.0",
"@hookform/resolvers": "^3.9.0",
"@reduxjs/toolkit": "^2.2.3",
"@tanstack/react-table": "^8.19.3",
"axios": "^1.7.3",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,12 @@
import type {QuerySettings} from '../../../../../types/store/query';
import {
DEFAULT_QUERY_SETTINGS,
QUERY_MODES,
STATISTICS_MODES,
TRACING_LEVELS,
TRANSACTION_MODES,
} from '../../../../../utils/query';

const DEFAULT_QUERY_SETTINGS: QuerySettings = {
queryMode: QUERY_MODES.query,
transactionMode: TRANSACTION_MODES.implicit,
timeout: '60',
statisticsMode: STATISTICS_MODES.none,
tracingLevel: TRACING_LEVELS.detailed,
};

import getChangedQueryExecutionSettings from './getChangedQueryExecutionSettings';

describe('getChangedQueryExecutionSettings', () => {
Expand All @@ -27,7 +20,8 @@ describe('getChangedQueryExecutionSettings', () => {
const currentSettings: QuerySettings = {
...DEFAULT_QUERY_SETTINGS,
queryMode: QUERY_MODES.data,
timeout: '30',
timeout: 30,
limitRows: undefined,
};
const result = getChangedQueryExecutionSettings(currentSettings, DEFAULT_QUERY_SETTINGS);
expect(result).toEqual(['queryMode', 'timeout']);
Expand All @@ -37,7 +31,8 @@ describe('getChangedQueryExecutionSettings', () => {
const currentSettings: QuerySettings = {
queryMode: QUERY_MODES.data,
transactionMode: TRANSACTION_MODES.onlinero,
timeout: '90',
timeout: 90,
limitRows: DEFAULT_QUERY_SETTINGS.limitRows,
statisticsMode: STATISTICS_MODES.basic,
tracingLevel: TRACING_LEVELS.basic,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ export default function getChangedQueryExecutionSettings(
const defaultMap = new Map(Object.entries(defaultSettings));

return Array.from(currentMap.keys()).filter(
(key) => currentMap.get(key) !== defaultMap.get(key),
(key) =>
currentMap.has(key) &&
currentMap.get(key) !== undefined &&
currentMap.get(key) !== defaultMap.get(key),
) as (keyof QuerySettings)[];
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type {QuerySettings} from '../../../../../types/store/query';
import {
DEFAULT_QUERY_SETTINGS,
QUERY_MODES,
QUERY_MODES_TITLES,
STATISTICS_MODES,
Expand All @@ -13,14 +14,6 @@ import {QUERY_SETTINGS_FIELD_SETTINGS} from '../../QuerySettingsDialog/constants

import getChangedQueryExecutionSettingsDescription from './getChangedQueryExecutionSettingsDescription';

const DEFAULT_QUERY_SETTINGS: QuerySettings = {
queryMode: QUERY_MODES.query,
transactionMode: TRANSACTION_MODES.implicit,
timeout: '60',
statisticsMode: STATISTICS_MODES.none,
tracingLevel: TRACING_LEVELS.detailed,
};

describe('getChangedQueryExecutionSettingsDescription', () => {
it('should return an empty object if no settings changed', () => {
const currentSettings: QuerySettings = {...DEFAULT_QUERY_SETTINGS};
Expand All @@ -37,7 +30,8 @@ describe('getChangedQueryExecutionSettingsDescription', () => {
const currentSettings: QuerySettings = {
...DEFAULT_QUERY_SETTINGS,
queryMode: QUERY_MODES.pg,
timeout: '63',
timeout: 63,
limitRows: 100,
};

const result = getChangedQueryExecutionSettingsDescription({
Expand All @@ -51,14 +45,16 @@ describe('getChangedQueryExecutionSettingsDescription', () => {
(option) => option.value === QUERY_MODES.pg,
)?.content,
[QUERY_SETTINGS_FIELD_SETTINGS.timeout.title]: '63',
[QUERY_SETTINGS_FIELD_SETTINGS.limitRows.title]: '100',
});
});

it('should return the correct description for all changed settings', () => {
const currentSettings: QuerySettings = {
queryMode: QUERY_MODES.data,
transactionMode: TRANSACTION_MODES.snapshot,
timeout: '120',
timeout: 120,
limitRows: DEFAULT_QUERY_SETTINGS.limitRows,
statisticsMode: STATISTICS_MODES.profile,
tracingLevel: TRACING_LEVELS.diagnostic,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,18 @@ export default function getChangedQueryExecutionSettingsDescription({

keys.forEach((key) => {
const settings = QUERY_SETTINGS_FIELD_SETTINGS[key];
const currentValue = currentSettings[key] as string;
const currentValue = currentSettings[key];

if ('options' in settings) {
const content = settings.options.find((option) => option.value === currentValue)
?.content as string;
const content = settings.options.find(
(option) => option.value === currentValue,
)?.content;

result[settings.title] = content;
} else {
result[settings.title] = currentValue;
if (content) {
result[settings.title] = content;
}
} else if (currentValue) {
result[settings.title] = String(currentValue);
}
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
flex: 6;
}

&__limit-rows,
&__timeout {
width: 33.3%;
margin-right: var(--g-spacing-2);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';

import {Dialog, Link as ExternalLink, Flex, TextInput} from '@gravity-ui/uikit';
import {zodResolver} from '@hookform/resolvers/zod';
import {Controller, useForm} from 'react-hook-form';

import {useTracingLevelOptionAvailable} from '../../../../store/reducers/capabilities/hooks';
Expand All @@ -15,6 +16,7 @@ import {
useTypedDispatch,
useTypedSelector,
} from '../../../../utils/hooks';
import {querySettingsValidationSchema} from '../../../../utils/query';

import {QuerySettingsSelect} from './QuerySettingsSelect';
import {QUERY_SETTINGS_FIELD_SETTINGS} from './constants';
Expand Down Expand Up @@ -66,8 +68,13 @@ interface QuerySettingsFormProps {
}

function QuerySettingsForm({initialValues, onSubmit, onClose}: QuerySettingsFormProps) {
const {control, handleSubmit} = useForm<QuerySettings>({
const {
control,
handleSubmit,
formState: {errors},
} = useForm<QuerySettings>({
defaultValues: initialValues,
resolver: zodResolver(querySettingsValidationSchema),
});

const enableTracingLevel = useTracingLevelOptionAvailable();
Expand All @@ -85,6 +92,7 @@ function QuerySettingsForm({initialValues, onSubmit, onClose}: QuerySettingsForm
control={control}
render={({field}) => (
<QuerySettingsSelect
id="queryMode"
setting={field.value}
onUpdateSetting={field.onChange}
settingOptions={QUERY_SETTINGS_FIELD_SETTINGS.queryMode.options}
Expand All @@ -104,10 +112,15 @@ function QuerySettingsForm({initialValues, onSubmit, onClose}: QuerySettingsForm
render={({field}) => (
<React.Fragment>
<TextInput
id="timeout"
type="number"
{...field}
value={field.value?.toString()}
className={b('timeout')}
placeholder="60"
validationState={errors.timeout ? 'invalid' : undefined}
errorMessage={errors.timeout?.message}
errorPlacement="inside"
/>
<span className={b('timeout-suffix')}>
{i18n('form.timeout.seconds')}
Expand All @@ -128,6 +141,7 @@ function QuerySettingsForm({initialValues, onSubmit, onClose}: QuerySettingsForm
control={control}
render={({field}) => (
<QuerySettingsSelect
id="tracingLevel"
setting={field.value}
onUpdateSetting={field.onChange}
settingOptions={
Expand All @@ -149,6 +163,7 @@ function QuerySettingsForm({initialValues, onSubmit, onClose}: QuerySettingsForm
control={control}
render={({field}) => (
<QuerySettingsSelect
id="transactionMode"
setting={field.value}
onUpdateSetting={field.onChange}
settingOptions={
Expand All @@ -169,6 +184,7 @@ function QuerySettingsForm({initialValues, onSubmit, onClose}: QuerySettingsForm
control={control}
render={({field}) => (
<QuerySettingsSelect
id="statisticsMode"
setting={field.value}
onUpdateSetting={field.onChange}
settingOptions={
Expand All @@ -179,6 +195,30 @@ function QuerySettingsForm({initialValues, onSubmit, onClose}: QuerySettingsForm
/>
</div>
</Flex>
<Flex direction="row" alignItems="flex-start" className={b('dialog-row')}>
<label htmlFor="limitRows" className={b('field-title')}>
{QUERY_SETTINGS_FIELD_SETTINGS.limitRows.title}
</label>
<div className={b('control-wrapper')}>
<Controller
name="limitRows"
control={control}
render={({field}) => (
<TextInput
id="limitRows"
type="number"
{...field}
value={field.value?.toString()}
className={b('limit-rows')}
placeholder="10000"
validationState={errors.limitRows ? 'invalid' : undefined}
errorMessage={errors.limitRows?.message}
errorPlacement="inside"
/>
)}
/>
</div>
</Flex>
</Dialog.Body>
<Dialog.Footer
textButtonApply={i18n('button-done')}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type SelectType = QueryMode | TransactionMode | StatisticsMode | TracingLevel;
type QuerySettingSelectOption<T> = SelectOption<T> & {isDefault?: boolean};

interface QuerySettingsSelectProps<T extends SelectType> {
id?: string;
setting: T;
settingOptions: QuerySettingSelectOption<T>[];
onUpdateSetting: (mode: T) => void;
Expand All @@ -32,6 +33,7 @@ export function QuerySettingsSelect<T extends SelectType>(props: QuerySettingsSe
return (
<div className={b('selector')}>
<Select<T>
id={props.id}
options={props.settingOptions}
value={[props.setting]}
onUpdate={(value) => {
Expand Down
3 changes: 3 additions & 0 deletions src/containers/Tenant/Query/QuerySettingsDialog/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,4 +148,7 @@ export const QUERY_SETTINGS_FIELD_SETTINGS = {
timeout: {
title: formI18n('form.timeout'),
},
limitRows: {
title: formI18n('form.limit-rows'),
},
} as const;
3 changes: 3 additions & 0 deletions src/containers/Tenant/Query/QuerySettingsDialog/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@
"form.transaction-mode": "Transaction mode",
"form.statistics-mode": "Statistics collection mode",
"form.tracing-level": "Tracing level",
"form.limit-rows": "Limit rows",
"button-done": "Save",
"button-cancel": "Cancel",
"form.timeout.seconds": "sec",
"form.validation.timeout": "Must be positive",
"form.validation.limitRows": "Must be between 1 and 100000",
"description.default": " (default)",
"docs": "Documentation"
}
3 changes: 3 additions & 0 deletions src/containers/Tenant/Query/QuerySettingsDialog/i18n/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@
"form.transaction-mode": "Уровень изоляции",
"form.statistics-mode": "Режим сбора статистики",
"form.tracing-level": "Tracing level",
"form.limit-rows": "Лимит строк",
"button-done": "Готово",
"button-cancel": "Отменить",
"form.timeout.seconds": "сек",
"form.validation.timeout": "Таймаут должен быть положительным",
"form.validation.limitRows": "Лимит строк должен быть между 1 и 100000",
"description.default": " (default)",
"docs": "Документация"
}
1 change: 1 addition & 0 deletions src/services/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,7 @@ export class YdbEmbeddedAPI extends AxiosWrapper {
transaction_mode?: TransactionMode;
timeout?: Timeout;
query_id?: string;
limit_rows?: number;
},
{concurrentId, signal, withRetries}: AxiosOptions = {},
) {
Expand Down
3 changes: 1 addition & 2 deletions src/services/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {
AUTOCOMPLETE_ON_ENTER,
AUTO_REFRESH_INTERVAL,
BINARY_DATA_IN_PLAIN_TEXT_DISPLAY,
DEFAULT_QUERY_SETTINGS,
ENABLE_AUTOCOMPLETE,
INVERTED_DISKS_KEY,
IS_HOTKEYS_HELP_HIDDEN_KEY,
Expand All @@ -23,7 +22,7 @@ import {
USE_CLUSTER_BALANCER_AS_BACKEND_KEY,
USE_PAGINATED_TABLES_KEY,
} from '../utils/constants';
import {QUERY_ACTIONS} from '../utils/query';
import {DEFAULT_QUERY_SETTINGS, QUERY_ACTIONS} from '../utils/query';
import {parseJson} from '../utils/utils';

export type SettingsObject = Record<string, unknown>;
Expand Down
3 changes: 3 additions & 0 deletions src/store/reducers/executeQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,9 @@ export const executeQueryApi = api.injectEndpoints({
querySettings.tracingLevel && enableTracingLevel
? TracingLevelNumber[querySettings.tracingLevel]
: undefined,
limit_rows: isNumeric(querySettings.limitRows)
? Number(querySettings.limitRows)
: undefined,
transaction_mode:
querySettings.transactionMode === 'implicit'
? undefined
Expand Down
11 changes: 4 additions & 7 deletions src/types/store/query.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import type {z} from 'zod';

import type {
QUERY_ACTIONS,
QUERY_MODES,
QUERY_SYNTAX,
STATISTICS_MODES,
TRACING_LEVELS,
TRANSACTION_MODES,
querySettingsValidationSchema,
} from '../../utils/query';
import type {IResponseError, NetworkError} from '../api/error';
import type {
Expand Down Expand Up @@ -39,13 +42,7 @@ export interface QueryRequestParams {
query: string;
}

export interface QuerySettings {
queryMode: QueryMode;
transactionMode: TransactionMode;
timeout?: string;
statisticsMode?: StatisticsMode;
tracingLevel?: TracingLevel;
}
export type QuerySettings = z.infer<typeof querySettingsValidationSchema>;

export type QueryErrorResponse = IResponseError<QueryErrorResponseData>;
export type QueryError = NetworkError | QueryErrorResponse;
Expand Down
Loading

0 comments on commit 1728e61

Please sign in to comment.