You've already forked node-redis
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:
@@ -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', []),
|
||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@@ -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;
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user