Skip to content

Commit

Permalink
redis Add mGet operation (#739)
Browse files Browse the repository at this point in the history
* feat(redis): Add mGet method to retrieve values for multiple keys

* feat(redis): Add mGet unit tests

* feat(redis): Add mGet function for fetching values from multiple keys

I have also remove a console.log for hget and add logging for scan

* Add changeset

* bump version and update changelog
  • Loading branch information
mtuchi authored Aug 28, 2024
1 parent 409e3a2 commit 152deb0
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 3 deletions.
8 changes: 8 additions & 0 deletions packages/redis/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# @openfn/language-redis

## 1.2.0

### Minor Changes

- c1e3221: - Add `mGet()` function
- Remove console.log in `hget()`
- Add logging to `scan()`

## 1.1.2

### Patch Changes
Expand Down
57 changes: 57 additions & 0 deletions packages/redis/ast.json
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,63 @@
},
"valid": true
},
{
"name": "mGet",
"params": [
"keys"
],
"docs": {
"description": "Get the values at specified paths in JSON documents stored at multiple keys.",
"tags": [
{
"title": "example",
"description": "mGet([\"patient\", \"doctor\"]);",
"caption": "Get JSON document values of the patient and doctor keys"
},
{
"title": "function",
"description": null,
"name": null
},
{
"title": "public",
"description": null,
"type": null
},
{
"title": "param",
"description": "The keys at which the JSON documents are stored.",
"type": {
"type": "TypeApplication",
"expression": {
"type": "NameExpression",
"name": "Array"
},
"applications": [
{
"type": "NameExpression",
"name": "string"
}
]
},
"name": "keys"
},
{
"title": "state",
"description": "{RedisState}"
},
{
"title": "returns",
"description": null,
"type": {
"type": "NameExpression",
"name": "Operation"
}
}
]
},
"valid": true
},
{
"name": "hGetAll",
"params": [
Expand Down
2 changes: 1 addition & 1 deletion packages/redis/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@openfn/language-redis",
"version": "1.1.2",
"version": "1.2.0",
"description": "OpenFn redis adaptor",
"type": "module",
"exports": {
Expand Down
26 changes: 24 additions & 2 deletions packages/redis/src/Adaptor.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,6 @@ export function hget(key, field) {

console.log(`Fetching value of '${resolvedKey}' key`);
const result = await client.hGet(resolvedKey, resolvedField);
console.log({ result });

return composeNextState(state, result);
};
}
Expand All @@ -136,6 +134,26 @@ export function jGet(key) {
};
}

/**
* Get the values at specified paths in JSON documents stored at multiple keys.
* @example <caption>Get JSON document values of the patient and doctor keys</caption>
* mGet(["patient", "doctor"]);
* @function
* @public
* @param {string[]} keys - The keys at which the JSON documents are stored.
* @state {RedisState}
* @returns {Operation}
*/
export function mGet(keys) {
return async state => {
const [resolvedKeys] = expandReferences(state, keys);
console.log(`Fetching values for ${resolvedKeys.length} keys`);
const results = await client.json.mGet(resolvedKeys, '$');

return composeNextState(state, results);
};
}

/**
* Get all fields and values of a hash, as an object, for a specified key.
* @example <caption>Get the hash obejct at the noderedis:animals:1 key</caption>
Expand Down Expand Up @@ -262,11 +280,13 @@ export function scan(pattern, options = {}) {
pattern,
options
);
console.log(`Scanning for keys matching '${resolvedPattern}'`);

const { type, count } = resolvedOptions;

let cursor = 0;
const result = [];

do {
const reply = await client.scan(cursor, {
MATCH: resolvedPattern,
Expand All @@ -279,6 +299,8 @@ export function scan(pattern, options = {}) {
}
} while (cursor !== 0);

console.log(`Found ${result.length} keys`);

return composeNextState(state, result);
};
}
Expand Down
61 changes: 61 additions & 0 deletions packages/redis/test/Adaptor.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
setMockClient,
hGetAll,
jGet,
mGet,
jSet,
} from '../src';

Expand Down Expand Up @@ -497,6 +498,66 @@ describe('jGet', () => {
});
});

describe('mGet', function () {
const mgetClient = {
json: {
mGet: async keys => {
expect(keys).to.eql(['a', 'b', 'c']);
return ['1', '2', '3'];
},
},
};
it('should expand references', async () => {
setMockClient(mgetClient);
const state = { keys: ['a', 'b', 'c'] };
await mGet(s => s.keys)(state);
});
it('should throw if keys are not specified', async () => {
setMockClient({
json: {
mGet: async () => {
throw new Error();
},
},
});

const state = {};
try {
await mGet()(state);
} catch (error) {
expect(error.message).to.eql(
`Cannot read properties of undefined (reading 'length')`
);
}
});
it('should throw if keys is empty array', async () => {
setMockClient({
json: {
mGet: async () => {
throw new Error(
`ERR wrong number of arguments for 'json.mget' command`
);
},
},
});

const state = {};
try {
await mGet([])(state);
} catch (error) {
expect(error.message).to.eql(
`ERR wrong number of arguments for 'json.mget' command`
);
}
});
it('should fetch values for multiple keys', async () => {
setMockClient(mgetClient);
const state = {};
const result = await mGet(['a', 'b', 'c'])(state);
expect(result.data).to.eql(['1', '2', '3']);
});
});

describe('jSet', () => {
const jSetClient = {
json: {
Expand Down

0 comments on commit 152deb0

Please sign in to comment.