ydb-embedded-ui 1.13.2 → 1.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +40 -0
- package/dist/assets/icons/flask.svg +3 -0
- package/dist/components/InfoViewer/formatters/common.ts +15 -0
- package/dist/components/InfoViewer/formatters/index.ts +2 -0
- package/dist/components/InfoViewer/formatters/schema.ts +43 -0
- package/dist/components/InfoViewer/schemaInfo/CDCStreamInfo.tsx +44 -0
- package/dist/components/InfoViewer/schemaInfo/PersQueueGroupInfo.tsx +34 -0
- package/dist/components/{IndexInfoViewer/IndexInfoViewer.tsx → InfoViewer/schemaInfo/TableIndexInfo.tsx} +7 -18
- package/dist/components/InfoViewer/schemaInfo/index.ts +3 -0
- package/dist/components/InfoViewer/schemaOverview/CDCStreamOverview.tsx +44 -0
- package/dist/components/InfoViewer/schemaOverview/PersQueueGroupOverview.tsx +35 -0
- package/dist/components/InfoViewer/schemaOverview/index.ts +2 -0
- package/dist/components/QueryResultTable/Cell/Cell.tsx +33 -0
- package/dist/components/QueryResultTable/Cell/index.ts +1 -0
- package/dist/components/QueryResultTable/QueryResultTable.scss +11 -0
- package/dist/components/QueryResultTable/QueryResultTable.tsx +115 -0
- package/dist/components/QueryResultTable/i18n/en.json +3 -0
- package/dist/components/QueryResultTable/i18n/index.ts +11 -0
- package/dist/components/QueryResultTable/i18n/ru.json +3 -0
- package/dist/components/QueryResultTable/index.ts +1 -0
- package/dist/containers/App/App.scss +1 -0
- package/dist/containers/Storage/DiskStateProgressBar/DiskStateProgressBar.scss +39 -14
- package/dist/containers/Storage/DiskStateProgressBar/DiskStateProgressBar.tsx +18 -7
- package/dist/containers/Storage/Pdisk/__tests__/colors.tsx +4 -3
- package/dist/containers/Storage/Vdisk/__tests__/colors.tsx +7 -7
- package/dist/containers/Tenant/Diagnostics/DiagnosticsPages.ts +6 -2
- package/dist/containers/Tenant/Diagnostics/HotKeys/HotKeys.js +1 -1
- package/dist/containers/Tenant/Diagnostics/Overview/Overview.tsx +8 -3
- package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.js +1 -1
- package/dist/containers/Tenant/Diagnostics/TopShards/TopShards.js +1 -1
- package/dist/containers/Tenant/ObjectSummary/ObjectSummary.tsx +36 -10
- package/dist/containers/Tenant/Preview/Preview.js +15 -57
- package/dist/containers/Tenant/Preview/Preview.scss +4 -8
- package/dist/containers/Tenant/QueryEditor/QueryEditor.js +12 -41
- package/dist/containers/Tenant/QueryEditor/QueryEditor.scss +0 -4
- package/dist/containers/Tenant/QueryEditor/QueryExplain/QueryExplain.scss +1 -2
- package/dist/containers/Tenant/QueryEditor/QueryResult/QueryResult.scss +2 -2
- package/dist/containers/Tenant/Schema/SchemaTree/SchemaTree.tsx +1 -1
- package/dist/containers/Tenant/utils/schema.ts +3 -0
- package/dist/containers/Tenant/utils/schemaActions.ts +1 -2
- package/dist/containers/Tenants/Tenants.js +12 -2
- package/dist/containers/UserSettings/UserSettings.tsx +26 -3
- package/dist/services/api.d.ts +19 -2
- package/dist/services/api.js +2 -2
- package/dist/setupTests.js +4 -0
- package/dist/store/reducers/executeQuery.js +4 -9
- package/dist/store/reducers/{preview.js → preview.ts} +22 -18
- package/dist/store/reducers/settings.js +3 -1
- package/dist/store/utils.ts +88 -0
- package/dist/types/api/query.ts +147 -0
- package/dist/types/api/schema.ts +235 -2
- package/dist/types/index.ts +33 -0
- package/dist/types/store/query.ts +9 -0
- package/dist/utils/{constants.js → constants.ts} +11 -6
- package/dist/utils/index.js +0 -24
- package/dist/utils/query.test.ts +189 -0
- package/dist/utils/query.ts +156 -0
- package/dist/utils/tests/providers.tsx +29 -0
- package/package.json +2 -2
- package/dist/store/utils.js +0 -51
package/dist/types/api/schema.ts
CHANGED
@@ -56,9 +56,12 @@ interface TPathDescription {
|
|
56
56
|
ColumnTableDescription?: unknown;
|
57
57
|
|
58
58
|
TableIndex?: TIndexDescription;
|
59
|
+
|
60
|
+
CdcStreamDescription?: TCdcStreamDescription;
|
61
|
+
PersQueueGroup?: TPersQueueGroupDescription;
|
59
62
|
}
|
60
63
|
|
61
|
-
interface TDirEntry {
|
64
|
+
export interface TDirEntry {
|
62
65
|
Name?: string;
|
63
66
|
/** uint64 */
|
64
67
|
PathId?: string;
|
@@ -208,12 +211,50 @@ export interface TIndexDescription {
|
|
208
211
|
DataSize?: string;
|
209
212
|
}
|
210
213
|
|
214
|
+
enum ECdcStreamMode {
|
215
|
+
ECdcStreamModeInvalid = 'ECdcStreamModeInvalid',
|
216
|
+
ECdcStreamModeKeysOnly = 'ECdcStreamModeKeysOnly',
|
217
|
+
ECdcStreamModeUpdate = 'ECdcStreamModeUpdate',
|
218
|
+
ECdcStreamModeNewImage = 'ECdcStreamModeNewImage',
|
219
|
+
ECdcStreamModeOldImage = 'ECdcStreamModeOldImage',
|
220
|
+
ECdcStreamModeNewAndOldImages = 'ECdcStreamModeNewAndOldImages',
|
221
|
+
}
|
222
|
+
|
223
|
+
enum ECdcStreamFormat {
|
224
|
+
ECdcStreamFormatInvalid = 'ECdcStreamFormatInvalid',
|
225
|
+
ECdcStreamFormatProto = 'ECdcStreamFormatProto',
|
226
|
+
ECdcStreamFormatJson = 'ECdcStreamFormatJson',
|
227
|
+
}
|
228
|
+
|
229
|
+
enum ECdcStreamState {
|
230
|
+
ECdcStreamStateInvalid = 'ECdcStreamStateInvalid',
|
231
|
+
ECdcStreamStateReady = 'ECdcStreamStateReady',
|
232
|
+
ECdcStreamStateDisabled = 'ECdcStreamStateDisabled',
|
233
|
+
}
|
234
|
+
|
235
|
+
interface TPathID {
|
236
|
+
/** fixed64 */
|
237
|
+
OwnerId?: string;
|
238
|
+
/** uint64 */
|
239
|
+
LocalId?: string;
|
240
|
+
}
|
241
|
+
|
242
|
+
export interface TCdcStreamDescription {
|
243
|
+
Name?: string;
|
244
|
+
Mode?: ECdcStreamMode;
|
245
|
+
Format?: ECdcStreamFormat;
|
246
|
+
PathId?: TPathID;
|
247
|
+
State?: ECdcStreamState;
|
248
|
+
/** uint64 */
|
249
|
+
SchemaVersion?: string;
|
250
|
+
}
|
251
|
+
|
211
252
|
// incomplete
|
212
253
|
export enum EPathType {
|
213
254
|
EPathTypeInvalid = 'EPathTypeInvalid',
|
214
255
|
EPathTypeDir = 'EPathTypeDir',
|
215
256
|
EPathTypeTable = 'EPathTypeTable',
|
216
|
-
|
257
|
+
EPathTypePersQueueGroup = 'EPathTypePersQueueGroup',
|
217
258
|
EPathTypeSubDomain = 'EPathTypeSubDomain',
|
218
259
|
|
219
260
|
EPathTypeTableIndex = 'EPathTypeTableIndex',
|
@@ -264,3 +305,195 @@ interface TPathVersion {
|
|
264
305
|
/** uint64 */
|
265
306
|
GeneralVersion?: string;
|
266
307
|
}
|
308
|
+
|
309
|
+
interface TPartitionKeyRange {
|
310
|
+
// Inclusive left border. Emptiness means -inf.
|
311
|
+
FromBound?: string;
|
312
|
+
// Exclusive right border. Emptiness means +inf.
|
313
|
+
ToBound?: string;
|
314
|
+
}
|
315
|
+
|
316
|
+
interface TPartition {
|
317
|
+
PartitionId?: number;
|
318
|
+
/** uint64 */
|
319
|
+
TabletId?: string;
|
320
|
+
KeyRange?: TPartitionKeyRange;
|
321
|
+
}
|
322
|
+
|
323
|
+
interface TPartitionToAdd {
|
324
|
+
PartitionId?: number;
|
325
|
+
GroupId?: number;
|
326
|
+
}
|
327
|
+
|
328
|
+
interface TCodecs {
|
329
|
+
/** int64 */
|
330
|
+
Ids?: string[];
|
331
|
+
Codecs?: string[];
|
332
|
+
}
|
333
|
+
|
334
|
+
interface TKeyComponentSchema {
|
335
|
+
Name?: string;
|
336
|
+
TypeId?: number;
|
337
|
+
}
|
338
|
+
|
339
|
+
enum EMeteringMode {
|
340
|
+
METERING_MODE_RESERVED_CAPACITY = 'METERING_MODE_RESERVED_CAPACITY',
|
341
|
+
METERING_MODE_REQUEST_UNITS = 'METERING_MODE_REQUEST_UNITS',
|
342
|
+
}
|
343
|
+
|
344
|
+
interface TReadQuota {
|
345
|
+
ClientId?: string;
|
346
|
+
/** uint64 */
|
347
|
+
SpeedInBytesPerSecond?: string;
|
348
|
+
/** uint64 */
|
349
|
+
BurstSize?: string;
|
350
|
+
}
|
351
|
+
|
352
|
+
interface TChannelProfile {
|
353
|
+
PoolKind?: string;
|
354
|
+
/** uint64 */
|
355
|
+
Size?: string;
|
356
|
+
ReadIops?: number;
|
357
|
+
ReadBandwidth?: number;
|
358
|
+
WriteIops?: number;
|
359
|
+
WriteBandwidth?: number;
|
360
|
+
}
|
361
|
+
|
362
|
+
interface IamCredentials {
|
363
|
+
Endpoint?: string;
|
364
|
+
ServiceAccountKey?: string;
|
365
|
+
}
|
366
|
+
|
367
|
+
interface TCredentials {
|
368
|
+
OauthToken?: string;
|
369
|
+
JwtParams?: string;
|
370
|
+
Iam?: IamCredentials;
|
371
|
+
}
|
372
|
+
|
373
|
+
interface TMirrorPartitionConfig {
|
374
|
+
Endpoint?: string;
|
375
|
+
EndpointPort?: number;
|
376
|
+
Topic?: string;
|
377
|
+
Consumer?: string;
|
378
|
+
/** uint64 */
|
379
|
+
ReadFromTimestampsMs?: string;
|
380
|
+
Credentials?: TCredentials;
|
381
|
+
Database?: string;
|
382
|
+
UseSecureConnection?: boolean;
|
383
|
+
SyncWriteTime?: boolean;
|
384
|
+
}
|
385
|
+
|
386
|
+
interface TPQPartitionConfig {
|
387
|
+
MaxCountInPartition?: number;
|
388
|
+
/** int64 */
|
389
|
+
MaxSizeInPartition?: string;
|
390
|
+
LifetimeSeconds: number;
|
391
|
+
/** uint64 */
|
392
|
+
StorageLimitBytes?: string;
|
393
|
+
|
394
|
+
ImportantClientId?: string[];
|
395
|
+
LowWatermark?: number;
|
396
|
+
SourceIdLifetimeSeconds?: number;
|
397
|
+
SourceIdMaxCounts?: number;
|
398
|
+
|
399
|
+
/** uint64 */
|
400
|
+
WriteSpeedInBytesPerSecond?: string;
|
401
|
+
/** uint64 */
|
402
|
+
BurstSize?: string;
|
403
|
+
|
404
|
+
ReadQuota?: TReadQuota[];
|
405
|
+
/** uint64 */
|
406
|
+
MaxWriteInflightSize?: string;
|
407
|
+
/** uint64 */
|
408
|
+
BorderWriteInflightSize?: string;
|
409
|
+
|
410
|
+
NumChannels?: number;
|
411
|
+
|
412
|
+
TotalPartitions?: number;
|
413
|
+
|
414
|
+
ExplicitChannelProfiles?: TChannelProfile[];
|
415
|
+
|
416
|
+
MirrorFrom?: TMirrorPartitionConfig;
|
417
|
+
};
|
418
|
+
|
419
|
+
interface TPQTabletConfig {
|
420
|
+
/** uint64 */
|
421
|
+
CacheSize?: string;
|
422
|
+
PartitionConfig: TPQPartitionConfig;
|
423
|
+
/** @deprecated use Partitions */
|
424
|
+
PartitionIds?: number[];
|
425
|
+
TopicName?: string;
|
426
|
+
Version?: number;
|
427
|
+
LocalDC?: boolean;
|
428
|
+
RequireAuthWrite?: boolean;
|
429
|
+
RequireAuthRead?: boolean;
|
430
|
+
Producer?: string;
|
431
|
+
Ident?: string;
|
432
|
+
Topic?: string;
|
433
|
+
DC?: string;
|
434
|
+
|
435
|
+
ReadRules?: string[];
|
436
|
+
/** uint64[] */
|
437
|
+
ReadFromTimestampsMs?: number[];
|
438
|
+
/** uint64[] */
|
439
|
+
ConsumerFormatVersions?: number[];
|
440
|
+
|
441
|
+
ConsumerCodecs?: TCodecs[];
|
442
|
+
ReadRuleServiceTypes?: string;
|
443
|
+
|
444
|
+
/** uint64 */
|
445
|
+
FormatVersion?: string;
|
446
|
+
Codecs?: TCodecs;
|
447
|
+
|
448
|
+
/** uint64[] */
|
449
|
+
ReadRuleVersions?: string[];
|
450
|
+
/** uint64[] */
|
451
|
+
ReadRuleGenerations?: string[];
|
452
|
+
|
453
|
+
TopicPath?: string;
|
454
|
+
|
455
|
+
YcCloudId?: string;
|
456
|
+
YcFolderId?: string;
|
457
|
+
YdbDatabaseId?: string;
|
458
|
+
YdbDatabasePath?: string;
|
459
|
+
FederationAccount?: string;
|
460
|
+
|
461
|
+
PartitionKeySchema?: TKeyComponentSchema[];
|
462
|
+
|
463
|
+
Partitions?: TPartition[];
|
464
|
+
|
465
|
+
MeteringMode?: EMeteringMode;
|
466
|
+
}
|
467
|
+
|
468
|
+
interface TMessageGroup {
|
469
|
+
// Id of message group (SourceId)
|
470
|
+
Id?: string;
|
471
|
+
// Range of the key to which it is allowed to write.
|
472
|
+
KeyRange?: TPartitionKeyRange;
|
473
|
+
}
|
474
|
+
|
475
|
+
interface TBootstrapConfig {
|
476
|
+
ExplicitMessageGroups?: TMessageGroup[];
|
477
|
+
}
|
478
|
+
|
479
|
+
export interface TPersQueueGroupDescription {
|
480
|
+
Name: string;
|
481
|
+
/** uint64 */
|
482
|
+
PathId?: string;
|
483
|
+
TotalGroupCount: number;
|
484
|
+
|
485
|
+
PartitionsToAdd?: TPartitionToAdd[];
|
486
|
+
PartitionsToDelete?: number[];
|
487
|
+
NextPartitionId?: number;
|
488
|
+
PartitionPerTablet?: number;
|
489
|
+
PQTabletConfig: TPQTabletConfig;
|
490
|
+
Partitions?: TPartition[];
|
491
|
+
/** uint64 */
|
492
|
+
AlterVersion?: string;
|
493
|
+
/** uint64 */
|
494
|
+
BalancerTabletID?: string;
|
495
|
+
|
496
|
+
PartitionBoundaries?: any;
|
497
|
+
|
498
|
+
BootstrapConfig?: TBootstrapConfig;
|
499
|
+
}
|
package/dist/types/index.ts
CHANGED
@@ -1 +1,34 @@
|
|
1
1
|
export type RequiredField<Src, Fields extends keyof Src> = Src & Required<Pick<Src, Fields>>;
|
2
|
+
|
3
|
+
export enum YQLType {
|
4
|
+
// Numeric
|
5
|
+
Bool = 'Bool',
|
6
|
+
Int8 = 'Int8',
|
7
|
+
Int16 = 'Int16',
|
8
|
+
Int32 = 'Int32',
|
9
|
+
Int64 = 'Int64',
|
10
|
+
Uint8 = 'Uint8',
|
11
|
+
Uint16 = 'Uint16',
|
12
|
+
Uint32 = 'Uint32',
|
13
|
+
Uint64 = 'Uint64',
|
14
|
+
Float = 'Float',
|
15
|
+
Double = 'Double',
|
16
|
+
Decimal = 'Decimal',
|
17
|
+
|
18
|
+
// String
|
19
|
+
String = 'String',
|
20
|
+
Utf8 = 'Utf8',
|
21
|
+
Json = 'Json',
|
22
|
+
JsonDocument = 'JsonDocument',
|
23
|
+
Yson = 'Yson',
|
24
|
+
Uuid = 'Uuid',
|
25
|
+
|
26
|
+
// Date and time
|
27
|
+
Date = 'Date',
|
28
|
+
Datetime = 'Datetime',
|
29
|
+
Timestamp = 'Timestamp',
|
30
|
+
Interval = 'Interval',
|
31
|
+
TzDate = 'TzDate',
|
32
|
+
TzDateTime = 'TzDateTime',
|
33
|
+
TzTimestamp = 'TzTimestamp',
|
34
|
+
}
|
@@ -14,7 +14,8 @@ export const GIGABYTE = 1_000_000_000;
|
|
14
14
|
export const TERABYTE = 1_000_000_000_000;
|
15
15
|
export const GROUP = 'group';
|
16
16
|
|
17
|
-
export const
|
17
|
+
export const HOUR_IN_SECONDS = 60 * 60;
|
18
|
+
export const DAY_IN_SECONDS = 24 * HOUR_IN_SECONDS;
|
18
19
|
|
19
20
|
export const TABLET_STATES = {
|
20
21
|
TABLET_VOLATILE_STATE_UNKNOWN: 'unknown',
|
@@ -87,13 +88,15 @@ export const TABLET_SYMBOLS = {
|
|
87
88
|
TenantSlotBroker: 'TB',
|
88
89
|
};
|
89
90
|
|
90
|
-
|
91
|
+
const isTabletType = (type: string): type is keyof typeof TABLET_SYMBOLS => type in TABLET_SYMBOLS;
|
92
|
+
|
93
|
+
export const getTabletLabel = (type?: string) => {
|
91
94
|
if (!type) {
|
92
|
-
return;
|
95
|
+
return undefined;
|
93
96
|
}
|
94
|
-
const defaultValue = type.match(/[A-Z]/g)
|
97
|
+
const defaultValue = type.match(/[A-Z]/g)?.join('');
|
95
98
|
|
96
|
-
return TABLET_SYMBOLS[type]
|
99
|
+
return isTabletType(type) ? TABLET_SYMBOLS[type] : defaultValue;
|
97
100
|
};
|
98
101
|
|
99
102
|
export const LOAD_AVERAGE_TIME_INTERVALS = ['1 min', '5 min', '15 min'];
|
@@ -116,12 +119,14 @@ export const ALL = 'All';
|
|
116
119
|
export const PROBLEMS = 'With problems';
|
117
120
|
|
118
121
|
export const THEME_KEY = 'theme';
|
122
|
+
export const INVERTED_DISKS_KEY = 'invertedDisks';
|
119
123
|
export const SAVED_QUERIES_KEY = 'saved_queries';
|
120
124
|
export const QUERIES_HISTORY_KEY = 'queries_history';
|
121
125
|
export const DATA_QA_TUNE_COLUMNS_POPUP = 'tune-columns-popup';
|
122
126
|
|
123
127
|
export const defaultUserSettings = {
|
124
128
|
[THEME_KEY]: 'light',
|
129
|
+
[INVERTED_DISKS_KEY]: false,
|
125
130
|
};
|
126
131
|
export const DEFAULT_SIZE_RESULT_PANE_KEY = 'default-size-result-pane';
|
127
132
|
export const DEFAULT_SIZE_TENANT_SUMMARY_KEY = 'default-size-tenant-summary-pane';
|
@@ -139,7 +144,7 @@ export const DEFAULT_TABLE_SETTINGS = {
|
|
139
144
|
syncHeadOnResize: true,
|
140
145
|
dynamicRender: true,
|
141
146
|
highlightRows: true,
|
142
|
-
};
|
147
|
+
} as const;
|
143
148
|
|
144
149
|
export const TENANT_INITIAL_TAB_KEY = 'saved_tenant_initial_tab';
|
145
150
|
export const QUERY_INITIAL_RUN_ACTION_KEY = 'query_initial_run_action';
|
package/dist/utils/index.js
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
import numeral from 'numeral';
|
2
2
|
import locales from 'numeral/locales'; // eslint-disable-line no-unused-vars
|
3
|
-
import _ from 'lodash';
|
4
3
|
|
5
4
|
import {i18n} from './i18n';
|
6
5
|
import {MEGABYTE, TERABYTE, DAY_IN_SECONDS, GIGABYTE} from './constants';
|
@@ -143,26 +142,3 @@ export const getMetaForExplainNode = (node) => {
|
|
143
142
|
return '';
|
144
143
|
}
|
145
144
|
};
|
146
|
-
|
147
|
-
export const prepareQueryResponse = (data) => {
|
148
|
-
return _.map(data, (item) => {
|
149
|
-
const formattedData = {};
|
150
|
-
|
151
|
-
for (const field in item) {
|
152
|
-
if (Object.prototype.hasOwnProperty.call(item, field)) {
|
153
|
-
const type = typeof item[field];
|
154
|
-
if (type === 'object' || type === 'boolean' || Array.isArray(item[field])) {
|
155
|
-
formattedData[field] = JSON.stringify(item[field]);
|
156
|
-
} else {
|
157
|
-
formattedData[field] = item[field];
|
158
|
-
}
|
159
|
-
}
|
160
|
-
}
|
161
|
-
|
162
|
-
return formattedData;
|
163
|
-
});
|
164
|
-
};
|
165
|
-
|
166
|
-
export function prepareQueryError(error) {
|
167
|
-
return error.data?.error?.message || error.data || error
|
168
|
-
}
|
@@ -0,0 +1,189 @@
|
|
1
|
+
import {parseQueryAPIExecuteResponse} from './query';
|
2
|
+
|
3
|
+
describe('API utils', () => {
|
4
|
+
describe('json/viewer/query', () => {
|
5
|
+
describe('parseQueryAPIExecuteResponse', () => {
|
6
|
+
describe('old format', () => {
|
7
|
+
describe('plain response', () => {
|
8
|
+
it('should handle empty response', () => {
|
9
|
+
expect(parseQueryAPIExecuteResponse(null).result).toBeUndefined();
|
10
|
+
});
|
11
|
+
|
12
|
+
it('should parse json string', () => {
|
13
|
+
const json = {foo: 'bar'};
|
14
|
+
const response = JSON.stringify(json);
|
15
|
+
expect(parseQueryAPIExecuteResponse(response).result).toEqual(json);
|
16
|
+
});
|
17
|
+
|
18
|
+
// it should not be in the response, but is there because of a bug
|
19
|
+
it('should ignore request plan as the response', () => {
|
20
|
+
const response = {queries: 'some queries'};
|
21
|
+
expect(parseQueryAPIExecuteResponse(response).result).toBeUndefined();
|
22
|
+
});
|
23
|
+
|
24
|
+
it('should accept key-value rows', () => {
|
25
|
+
const response = [{foo: 'bar'}];
|
26
|
+
expect(parseQueryAPIExecuteResponse(response).result).toEqual(response);
|
27
|
+
});
|
28
|
+
});
|
29
|
+
|
30
|
+
describe('deep response without stats', () => {
|
31
|
+
it('should parse json string in the result field', () => {
|
32
|
+
const json = {foo: 'bar'};
|
33
|
+
const response = {result: JSON.stringify(json)};
|
34
|
+
expect(parseQueryAPIExecuteResponse(response).result).toEqual(json);
|
35
|
+
});
|
36
|
+
|
37
|
+
// it should not be in the response, but is there because of a bug
|
38
|
+
it('should ignore request plan in the result field', () => {
|
39
|
+
const response = {result: {queries: 'some queries'}};
|
40
|
+
expect(parseQueryAPIExecuteResponse(response).result).toBeUndefined();
|
41
|
+
});
|
42
|
+
|
43
|
+
it('should accept key-value rows in the result field', () => {
|
44
|
+
const response = {result: [{foo: 'bar'}]};
|
45
|
+
expect(parseQueryAPIExecuteResponse(response).result).toEqual(response.result);
|
46
|
+
});
|
47
|
+
});
|
48
|
+
|
49
|
+
describe('deep response with stats', () => {
|
50
|
+
it('should parse json string in the result field', () => {
|
51
|
+
const json = {foo: 'bar'};
|
52
|
+
const response = {
|
53
|
+
result: JSON.stringify(json),
|
54
|
+
stats: {metric: 'good'},
|
55
|
+
};
|
56
|
+
const actual = parseQueryAPIExecuteResponse(response);
|
57
|
+
expect(actual.result).toEqual(json);
|
58
|
+
expect(actual.stats).toEqual(response.stats);
|
59
|
+
});
|
60
|
+
|
61
|
+
// it should not be in the response, but is there because of a bug
|
62
|
+
it('should ignore request plan in the result field', () => {
|
63
|
+
const response = {
|
64
|
+
result: {queries: 'some queries'},
|
65
|
+
stats: {metric: 'good'},
|
66
|
+
};
|
67
|
+
const actual = parseQueryAPIExecuteResponse(response);
|
68
|
+
expect(actual.result).toBeUndefined();
|
69
|
+
expect(actual.stats).toEqual(response.stats);
|
70
|
+
});
|
71
|
+
|
72
|
+
it('should accept key-value rows in the result field', () => {
|
73
|
+
const response = {
|
74
|
+
result: [{foo: 'bar'}],
|
75
|
+
stats: {metric: 'good'},
|
76
|
+
};
|
77
|
+
const actual = parseQueryAPIExecuteResponse(response);
|
78
|
+
expect(actual.result).toEqual(response.result);
|
79
|
+
expect(actual.stats).toEqual(response.stats);
|
80
|
+
});
|
81
|
+
|
82
|
+
it('should accept stats without a result', () => {
|
83
|
+
const response = {
|
84
|
+
stats: {metric: 'good'},
|
85
|
+
};
|
86
|
+
const actual = parseQueryAPIExecuteResponse(response);
|
87
|
+
expect(actual.result).toBeUndefined();
|
88
|
+
expect(actual.stats).toEqual(response.stats);
|
89
|
+
});
|
90
|
+
});
|
91
|
+
});
|
92
|
+
|
93
|
+
describe('new format', () => {
|
94
|
+
describe('response without stats', () => {
|
95
|
+
it('should parse modern schema', () => {
|
96
|
+
const response = {
|
97
|
+
result: [['42', 'hello world']],
|
98
|
+
columns: [{
|
99
|
+
name: 'id',
|
100
|
+
type: 'Uint64?'
|
101
|
+
}, {
|
102
|
+
name: 'value',
|
103
|
+
type: 'Utf8?'
|
104
|
+
}],
|
105
|
+
};
|
106
|
+
const actual = parseQueryAPIExecuteResponse(response);
|
107
|
+
expect(actual.result).toEqual([{
|
108
|
+
id: '42',
|
109
|
+
value: 'hello world'
|
110
|
+
}]);
|
111
|
+
expect(actual.columns).toEqual(response.columns);
|
112
|
+
});
|
113
|
+
|
114
|
+
it('should handle empty response for classic schema', () => {
|
115
|
+
expect(parseQueryAPIExecuteResponse(null).result).toBeUndefined();
|
116
|
+
});
|
117
|
+
|
118
|
+
it('should parse plain classic schema', () => {
|
119
|
+
const response = [{foo: 'bar'}];
|
120
|
+
expect(parseQueryAPIExecuteResponse(response).result).toEqual(response);
|
121
|
+
});
|
122
|
+
|
123
|
+
it('should parse deep classic schema', () => {
|
124
|
+
const response = {result: [{foo: 'bar'}]};
|
125
|
+
expect(parseQueryAPIExecuteResponse(response).result).toEqual(response.result);
|
126
|
+
});
|
127
|
+
|
128
|
+
it('should parse ydb schema', () => {
|
129
|
+
const response = {result: [{foo: 'bar'}]};
|
130
|
+
expect(parseQueryAPIExecuteResponse(response).result).toEqual(response.result);
|
131
|
+
});
|
132
|
+
});
|
133
|
+
|
134
|
+
describe('response with stats', () => {
|
135
|
+
it('should parse modern schema', () => {
|
136
|
+
const response = {
|
137
|
+
result: [['42', 'hello world']],
|
138
|
+
columns: [{
|
139
|
+
name: 'id',
|
140
|
+
type: 'Uint64?'
|
141
|
+
}, {
|
142
|
+
name: 'value',
|
143
|
+
type: 'Utf8?'
|
144
|
+
}],
|
145
|
+
stats: {metric: 'good'},
|
146
|
+
};
|
147
|
+
const actual = parseQueryAPIExecuteResponse(response);
|
148
|
+
expect(actual.result).toEqual([{
|
149
|
+
id: '42',
|
150
|
+
value: 'hello world'
|
151
|
+
}]);
|
152
|
+
expect(actual.columns).toEqual(response.columns);
|
153
|
+
expect(actual.stats).toEqual(response.stats);
|
154
|
+
});
|
155
|
+
|
156
|
+
it('should parse classic schema', () => {
|
157
|
+
const response = {
|
158
|
+
result: [{foo: 'bar'}],
|
159
|
+
stats: {metric: 'good'},
|
160
|
+
};
|
161
|
+
const actual = parseQueryAPIExecuteResponse(response);
|
162
|
+
expect(actual.result).toEqual(response.result);
|
163
|
+
expect(actual.stats).toEqual(response.stats);
|
164
|
+
});
|
165
|
+
|
166
|
+
it('should parse ydb schema', () => {
|
167
|
+
const response = {
|
168
|
+
result: [{foo: 'bar'}],
|
169
|
+
stats: {metric: 'good'},
|
170
|
+
};
|
171
|
+
const actual = parseQueryAPIExecuteResponse(response);
|
172
|
+
expect(actual.result).toEqual(response.result);
|
173
|
+
expect(actual.stats).toEqual(response.stats);
|
174
|
+
});
|
175
|
+
|
176
|
+
it('should accept stats without a result', () => {
|
177
|
+
const response = {
|
178
|
+
stats: {metric: 'good'},
|
179
|
+
};
|
180
|
+
const actual = parseQueryAPIExecuteResponse(response);
|
181
|
+
expect(actual.result).toBeUndefined();
|
182
|
+
expect(actual.columns).toBeUndefined();
|
183
|
+
expect(actual.stats).toEqual(response.stats);
|
184
|
+
});
|
185
|
+
});
|
186
|
+
});
|
187
|
+
});
|
188
|
+
});
|
189
|
+
});
|