1
0
mirror of https://github.com/redis/node-redis.git synced 2025-08-06 02:15:48 +03:00

CAE-193: add "IGNORE" options to time series commands (for v5 branch) (#2753)

* CAE-193: add "IGNORE" options to time series commands (for v5 branch)

* add INCR/DECR and modify tests to not test ignore on older version

* require maxTimeDiff/maxValDiff to be specified

also rename them

* fix add/ignore test after api change

* update tests for api change in IGNORE option
This commit is contained in:
Shaya Potter
2024-10-11 11:22:31 +03:00
committed by GitHub
parent 949b944b0f
commit f7d824c07c
10 changed files with 110 additions and 19 deletions

View File

@@ -57,16 +57,29 @@ describe('TS.ADD', () => {
);
});
it('with RETENTION, ENCODING, CHUNK_SIZE, ON_DUPLICATE, LABELS', () => {
it ('with IGNORE', () => {
assert.deepEqual(
ADD.transformArguments('key', '*', 1, {
IGNORE: {
maxTimeDiff: 1,
maxValDiff: 1
}
}),
['TS.ADD', 'key', '*', '1', 'IGNORE', '1', '1']
)
});
it('with RETENTION, ENCODING, CHUNK_SIZE, ON_DUPLICATE, LABELS, IGNORE', () => {
assert.deepEqual(
ADD.transformArguments('key', '*', 1, {
RETENTION: 1,
ENCODING: TIME_SERIES_ENCODING.UNCOMPRESSED,
CHUNK_SIZE: 1,
ON_DUPLICATE: TIME_SERIES_DUPLICATE_POLICIES.BLOCK,
LABELS: { label: 'value' }
LABELS: { label: 'value' },
IGNORE: { maxTimeDiff: 1, maxValDiff: 1}
}),
['TS.ADD', 'key', '*', '1', 'RETENTION', '1', 'ENCODING', 'UNCOMPRESSED', 'CHUNK_SIZE', '1', 'ON_DUPLICATE', 'BLOCK', 'LABELS', 'label', 'value']
['TS.ADD', 'key', '*', '1', 'RETENTION', '1', 'ENCODING', 'UNCOMPRESSED', 'CHUNK_SIZE', '1', 'ON_DUPLICATE', 'BLOCK', 'LABELS', 'label', 'value', 'IGNORE', '1', '1']
);
});
});

View File

@@ -8,15 +8,22 @@ import {
TimeSeriesDuplicatePolicies,
Labels,
pushLabelsArgument,
Timestamp
Timestamp,
pushIgnoreArgument
} from '.';
export interface TsIgnoreOptions {
maxTimeDiff: number;
maxValDiff: number;
}
export interface TsAddOptions {
RETENTION?: number;
ENCODING?: TimeSeriesEncoding;
CHUNK_SIZE?: number;
ON_DUPLICATE?: TimeSeriesDuplicatePolicies;
LABELS?: Labels;
IGNORE?: TsIgnoreOptions;
}
export default {
@@ -47,6 +54,8 @@ export default {
pushLabelsArgument(args, options?.LABELS);
pushIgnoreArgument(args, options?.IGNORE);
return args;
},
transformReply: undefined as unknown as () => NumberReply

View File

@@ -48,15 +48,28 @@ describe('TS.ALTER', () => {
);
});
it('with RETENTION, CHUNK_SIZE, DUPLICATE_POLICY, LABELS', () => {
it('with IGNORE', () => {
assert.deepEqual(
ALTER.transformArguments('key', {
IGNORE: {
maxTimeDiff: 1,
maxValDiff: 1
}
}),
['TS.ALTER', 'key', 'IGNORE', '1', '1']
)
});
it('with RETENTION, CHUNK_SIZE, DUPLICATE_POLICY, LABELS, IGNORE', () => {
assert.deepEqual(
ALTER.transformArguments('key', {
RETENTION: 1,
CHUNK_SIZE: 1,
DUPLICATE_POLICY: TIME_SERIES_DUPLICATE_POLICIES.BLOCK,
LABELS: { label: 'value' }
LABELS: { label: 'value' },
IGNORE: { maxTimeDiff: 1, maxValDiff: 1}
}),
['TS.ALTER', 'key', 'RETENTION', '1', 'CHUNK_SIZE', '1', 'DUPLICATE_POLICY', 'BLOCK', 'LABELS', 'label', 'value']
['TS.ALTER', 'key', 'RETENTION', '1', 'CHUNK_SIZE', '1', 'DUPLICATE_POLICY', 'BLOCK', 'LABELS', 'label', 'value', 'IGNORE', '1', '1']
);
});
});

View File

@@ -1,8 +1,8 @@
import { RedisArgument, SimpleStringReply, Command } from '@redis/client/dist/lib/RESP/types';
import { TsCreateOptions } from './CREATE';
import { pushRetentionArgument, pushChunkSizeArgument, pushDuplicatePolicy, pushLabelsArgument } from '.';
import { pushRetentionArgument, pushChunkSizeArgument, pushDuplicatePolicy, pushLabelsArgument, pushIgnoreArgument } from '.';
export type TsAlterOptions = Pick<TsCreateOptions, 'RETENTION' | 'CHUNK_SIZE' | 'DUPLICATE_POLICY' | 'LABELS'>;
export type TsAlterOptions = Pick<TsCreateOptions, 'RETENTION' | 'CHUNK_SIZE' | 'DUPLICATE_POLICY' | 'LABELS' | 'IGNORE'>;
export default {
FIRST_KEY_INDEX: 1,
@@ -18,6 +18,8 @@ export default {
pushLabelsArgument(args, options?.LABELS);
pushIgnoreArgument(args, options?.IGNORE);
return args;
},
transformReply: undefined as unknown as () => SimpleStringReply<'OK'>

View File

@@ -57,16 +57,29 @@ describe('TS.CREATE', () => {
);
});
it('with RETENTION, ENCODING, CHUNK_SIZE, DUPLICATE_POLICY, LABELS', () => {
it('with IGNORE', () => {
assert.deepEqual(
CREATE.transformArguments('key', {
IGNORE: {
maxTimeDiff: 1,
maxValDiff: 1
}
}),
['TS.CREATE', 'key', 'IGNORE', '1', '1']
)
});
it('with RETENTION, ENCODING, CHUNK_SIZE, DUPLICATE_POLICY, LABELS, IGNORE', () => {
assert.deepEqual(
CREATE.transformArguments('key', {
RETENTION: 1,
ENCODING: TIME_SERIES_ENCODING.UNCOMPRESSED,
CHUNK_SIZE: 1,
DUPLICATE_POLICY: TIME_SERIES_DUPLICATE_POLICIES.BLOCK,
LABELS: { label: 'value' }
LABELS: { label: 'value' },
IGNORE: { maxTimeDiff: 1, maxValDiff: 1}
}),
['TS.CREATE', 'key', 'RETENTION', '1', 'ENCODING', 'UNCOMPRESSED', 'CHUNK_SIZE', '1', 'DUPLICATE_POLICY', 'BLOCK', 'LABELS', 'label', 'value']
['TS.CREATE', 'key', 'RETENTION', '1', 'ENCODING', 'UNCOMPRESSED', 'CHUNK_SIZE', '1', 'DUPLICATE_POLICY', 'BLOCK', 'LABELS', 'label', 'value', 'IGNORE', '1', '1']
);
});
});

View File

@@ -7,8 +7,10 @@ import {
TimeSeriesDuplicatePolicies,
pushDuplicatePolicy,
Labels,
pushLabelsArgument
pushLabelsArgument,
pushIgnoreArgument
} from '.';
import { TsIgnoreOptions } from './ADD';
export interface TsCreateOptions {
RETENTION?: number;
@@ -16,6 +18,7 @@ export interface TsCreateOptions {
CHUNK_SIZE?: number;
DUPLICATE_POLICY?: TimeSeriesDuplicatePolicies;
LABELS?: Labels;
IGNORE?: TsIgnoreOptions;
}
export default {
@@ -34,6 +37,8 @@ export default {
pushLabelsArgument(args, options?.LABELS);
pushIgnoreArgument(args, options?.IGNORE);
return args;
},
transformReply: undefined as unknown as () => SimpleStringReply<'OK'>

View File

@@ -56,6 +56,18 @@ describe('TS.DECRBY', () => {
);
});
it ('with IGNORE', () => {
assert.deepEqual(
DECRBY.transformArguments('key', 1, {
IGNORE: {
maxTimeDiff: 1,
maxValDiff: 1
}
}),
['TS.DECRBY', 'key', '1', 'IGNORE', '1', '1']
)
});
it('with TIMESTAMP, RETENTION, UNCOMPRESSED, CHUNK_SIZE and LABELS', () => {
assert.deepEqual(
DECRBY.transformArguments('key', 1, {
@@ -63,9 +75,10 @@ describe('TS.DECRBY', () => {
RETENTION: 1,
UNCOMPRESSED: true,
CHUNK_SIZE: 2,
LABELS: { label: 'value' }
LABELS: { label: 'value' },
IGNORE: { maxTimeDiff: 1, maxValDiff: 1 }
}),
['TS.DECRBY', 'key', '1', 'TIMESTAMP', '*', 'RETENTION', '1', 'UNCOMPRESSED', 'CHUNK_SIZE', '2', 'LABELS', 'label', 'value']
['TS.DECRBY', 'key', '1', 'TIMESTAMP', '*', 'RETENTION', '1', 'UNCOMPRESSED', 'CHUNK_SIZE', '2', 'LABELS', 'label', 'value', 'IGNORE', '1', '1']
);
});
});

View File

@@ -65,6 +65,18 @@ describe('TS.INCRBY', () => {
);
});
it ('with IGNORE', () => {
assert.deepEqual(
INCRBY.transformArguments('key', 1, {
IGNORE: {
maxTimeDiff: 1,
maxValDiff: 1
}
}),
['TS.INCRBY', 'key', '1', 'IGNORE', '1', '1']
)
});
it('with TIMESTAMP, RETENTION, UNCOMPRESSED, CHUNK_SIZE and LABELS', () => {
assert.deepEqual(
INCRBY.transformArguments('key', 1, {
@@ -72,10 +84,11 @@ describe('TS.INCRBY', () => {
RETENTION: 1,
UNCOMPRESSED: true,
CHUNK_SIZE: 1,
LABELS: { label: 'value' }
LABELS: { label: 'value' },
IGNORE: { maxTimeDiff: 1, maxValDiff: 1 }
}),
['TS.INCRBY', 'key', '1', 'TIMESTAMP', '*', 'RETENTION', '1', 'UNCOMPRESSED',
'CHUNK_SIZE', '1', 'LABELS', 'label', 'value']
'CHUNK_SIZE', '1', 'LABELS', 'label', 'value', 'IGNORE', '1', '1']
);
});
});

View File

@@ -1,5 +1,6 @@
import { RedisArgument, NumberReply, Command } from '@redis/client/dist/lib/RESP/types';
import { Timestamp, transformTimestampArgument, pushRetentionArgument, pushChunkSizeArgument, Labels, pushLabelsArgument } from '.';
import { Timestamp, transformTimestampArgument, pushRetentionArgument, pushChunkSizeArgument, Labels, pushLabelsArgument, pushIgnoreArgument } from '.';
import { TsIgnoreOptions } from './ADD';
export interface TsIncrByOptions {
TIMESTAMP?: Timestamp;
@@ -7,6 +8,7 @@ export interface TsIncrByOptions {
UNCOMPRESSED?: boolean;
CHUNK_SIZE?: number;
LABELS?: Labels;
IGNORE?: TsIgnoreOptions;
}
export function transformIncrByArguments(
@@ -35,6 +37,8 @@ export function transformIncrByArguments(
pushLabelsArgument(args, options?.LABELS);
pushIgnoreArgument(args, options?.IGNORE);
return args;
}

View File

@@ -1,5 +1,5 @@
import type { BlobStringReply, CommandArguments, DoubleReply, NumberReply, RedisArgument, RedisCommands, TuplesReply, UnwrapReply } from '@redis/client/dist/lib/RESP/types';
import ADD from './ADD';
import ADD, { TsIgnoreOptions } from './ADD';
import ALTER from './ALTER';
import CREATE from './CREATE';
import CREATERULE from './CREATERULE';
@@ -67,6 +67,12 @@ export default {
revRange: REVRANGE
} as const satisfies RedisCommands;
export function pushIgnoreArgument(args: Array<RedisArgument>, ignore?: TsIgnoreOptions) {
if (ignore !== undefined) {
args.push('IGNORE', ignore.maxTimeDiff.toString(), ignore.maxValDiff.toString());
}
}
export function pushRetentionArgument(args: Array<RedisArgument>, retention?: number) {
if (retention !== undefined) {
args.push('RETENTION', retention.toString());