1
0
mirror of https://github.com/redis/node-redis.git synced 2025-08-10 11:43:01 +03:00

fix BITFIELD command

This commit is contained in:
leibale
2021-07-02 17:27:28 -04:00
parent aa10af9ec2
commit d2e01fa013
3 changed files with 98 additions and 125 deletions

View File

@@ -3,88 +3,39 @@ import { TestRedisServers, itWithClient } from '../test-utils';
import { transformArguments } from './BITFIELD'; import { transformArguments } from './BITFIELD';
describe('BITFIELD', () => { describe('BITFIELD', () => {
describe('transformArguments', () => { it('transformArguments', () => {
it('simple', () => { assert.deepEqual(
assert.deepEqual( transformArguments('key', [{
transformArguments('key'), operation: 'OVERFLOW',
['BITFIELD', 'key'] behavior: 'WRAP'
); }, {
}); operation: 'GET',
type: 'i8',
it('with GET', () => { offset: 0
assert.deepEqual( }, {
transformArguments('key', { operation: 'OVERFLOW',
GET: { behavior: 'SAT'
type: 'i8', }, {
offset: 0 operation: 'SET',
} type: 'i16',
}), offset: 1,
['BITFIELD', 'key', 'GET', 'i8', '0'] value: 0
); }, {
}); operation: 'OVERFLOW',
behavior: 'FAIL'
it('with SET', () => { }, {
assert.deepEqual( operation: 'INCRBY',
transformArguments('key', { type: 'i32',
SET: { offset: 2,
type: 'i8', increment: 1
offset: 0, }]),
value: 0 ['BITFIELD', 'key', 'OVERFLOW', 'WRAP', 'GET', 'i8', '0', 'OVERFLOW', 'SAT', 'SET', 'i16', '1', '0', 'OVERFLOW', 'FAIL', 'INCRBY', 'i32', '2', '1']
} );
}),
['BITFIELD', 'key', 'SET', 'i8', '0', '0']
);
});
it('with INCRBY', () => {
assert.deepEqual(
transformArguments('key', {
INCRBY: {
type: 'i8',
offset: 0,
increment: 0
}
}),
['BITFIELD', 'key', 'INCRBY', 'i8', '0', '0']
);
});
it('with OVERFLOW', () => {
assert.deepEqual(
transformArguments('key', {
OVERFLOW: 'WRAP'
}),
['BITFIELD', 'key', 'OVERFLOW', 'WRAP']
);
});
it('with GET, SET, INCRBY, OVERFLOW', () => {
assert.deepEqual(
transformArguments('key', {
GET: {
type: 'i8',
offset: 0
},
SET: {
type: 'i8',
offset: 0,
value: 0
},
INCRBY: {
type: 'i8',
offset: 0,
increment: 0
},
OVERFLOW: 'WRAP'
}),
['BITFIELD', 'key', 'GET', 'i8', '0', 'SET', 'i8', '0', '0', 'INCRBY', 'i8', '0', '0', 'OVERFLOW', 'WRAP']
);
})
}); });
itWithClient(TestRedisServers.OPEN, 'client.bitField', async client => { itWithClient(TestRedisServers.OPEN, 'client.bitField', async client => {
assert.deepEqual( assert.deepEqual(
await client.bitField('key'), await client.bitField('key', []),
[] []
); );
}); });

View File

@@ -1,4 +1,4 @@
import { transformReplyNumber } from './generic-transformers'; import { transformReplyNumberNullArray } from './generic-transformers';
export const FIRST_KEY_INDEX = 1; export const FIRST_KEY_INDEX = 1;
@@ -6,61 +6,79 @@ export const IS_READ_ONLY = true;
type BitFieldType = string; // TODO 'i[1-64]' | 'u[1-63]' type BitFieldType = string; // TODO 'i[1-64]' | 'u[1-63]'
interface BitFieldOptions { interface BitFieldOperation<S extends string> {
GET?: { operation: S;
type: BitFieldType;
offset: number | string;
};
SET?: {
type: BitFieldType;
offset: number | string;
value: number;
};
INCRBY?: {
type: BitFieldType;
offset: number | string;
increment: number;
};
OVERFLOW?: 'WRAP' | 'SAT' | 'FAIL';
} }
export function transformArguments(key: string, options?: BitFieldOptions): Array<string> { interface BitFieldGetOperation extends BitFieldOperation<'GET'> {
type: BitFieldType;
offset: number | string;
}
interface BitFieldSetOperation extends BitFieldOperation<'SET'> {
type: BitFieldType;
offset: number | string;
value: number;
}
interface BitFieldIncrByOperation extends BitFieldOperation<'INCRBY'> {
type: BitFieldType;
offset: number | string;
increment: number;
}
interface BitFieldOverflowOperation extends BitFieldOperation<'OVERFLOW'> {
behavior: string;
}
type BitFieldOperations = Array<
BitFieldGetOperation |
BitFieldSetOperation |
BitFieldIncrByOperation |
BitFieldOverflowOperation
>;
export function transformArguments(key: string, operations: BitFieldOperations): Array<string> {
const args = ['BITFIELD', key]; const args = ['BITFIELD', key];
if (options?.GET) { for (const options of operations) {
args.push( switch (options.operation) {
'GET', case 'GET':
options.GET.type, args.push(
options.GET.offset.toString() 'GET',
); options.type,
} options.offset.toString()
);
break;
if (options?.SET) { case 'SET':
args.push( args.push(
'SET', 'SET',
options.SET.type, options.type,
options.SET.offset.toString(), options.offset.toString(),
options.SET.value.toString() options.value.toString()
); );
} break;
if (options?.INCRBY) { case 'INCRBY':
args.push( args.push(
'INCRBY', 'INCRBY',
options.INCRBY.type, options.type,
options.INCRBY.offset.toString(), options.offset.toString(),
options.INCRBY.increment.toString() options.increment.toString()
); )
} break;
if (options?.OVERFLOW) { case 'OVERFLOW':
args.push( args.push(
'OVERFLOW', 'OVERFLOW',
options.OVERFLOW options.behavior
); );
break;
}
} }
return args; return args;
} }
export const transformReply = transformReplyNumber; export const transformReply = transformReplyNumberNullArray;

View File

@@ -10,6 +10,10 @@ export function transformReplyNumberArray(reply: Array<number>): Array<number> {
return reply; return reply;
} }
export function transformReplyNumberNullArray(reply: Array<number | null>): Array<number | null> {
return reply;
}
export function transformReplyString(reply: string): string { export function transformReplyString(reply: string): string {
return reply; return reply;
} }