Skip to content

Commit ab060d6

Browse files
fix: 🐛 certain groups not being shown
1 parent 2936303 commit ab060d6

2 files changed

Lines changed: 37 additions & 22 deletions

File tree

readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ Run `red --help` to see all available command line arguments.
3838
- `RED_DELIMITER`: The delimiter used to group keys (default: `:`)
3939

4040
### Configuration file
41-
A configuration file can be placed either in the directory where Red is executed, or in any higher-level directory, up to the user's home directory. Lower level configuration files take precedence over higher-level ones.
41+
A configuration file can be placed either in the directory where Red is executed, or in any higher-level directory, up to your home directory. Lower level configuration files take precedence over higher-level ones.
4242
The following file names are supported:
4343

4444
- .redrc

src/util/redis-get-grouped-keys.ts

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -55,29 +55,44 @@ export class RedisUtils {
5555
getChildGroups = async (params: {
5656
depth: number;
5757
}): Promise<KeyReturnType[]> => {
58+
// We essentally have to scan over all keys in order to find groups. Not just one extra level down, because a key existing 2 extra levels down does mean that the intermediate level is a group.
5859
const groups = new Map<string, KeyReturnType>();
59-
// If we're looking for N levels deep groups, that means that the keys are N+1 levels deep
60-
const relevantKeys = await this.getChildKeys({ depth: params.depth + 1 });
61-
for (const key of relevantKeys) {
62-
// Remove the last section to get the group name
63-
const fullPath = key.fullPath
64-
.split(this.delimiter)
65-
.slice(0, -1)
66-
.join(this.delimiter);
67-
const pathPrefix =
68-
this.path.length > 0 ? `${this.path}${this.delimiter}` : "";
69-
const relativePath = fullPath.slice(pathPrefix.length);
70-
if (relativePath === "") {
71-
continue;
72-
}
73-
groups.set(fullPath, {
74-
fullPath,
75-
relativePath,
76-
baseName: relativePath.split(this.delimiter).slice(-1)[0],
77-
isGroup: true,
60+
const scanStream = this.redis.scanStream({
61+
match: [this.path, "*"].filter(Boolean).join(this.delimiter),
62+
});
63+
return new Promise<KeyReturnType[]>((resolve, reject) => {
64+
scanStream.on("end", () => resolve([...groups.values()]));
65+
scanStream.on("error", (error) => reject(error));
66+
scanStream.on("data", (bunchOfKeys: string[]) => {
67+
for (const fullKey of bunchOfKeys) {
68+
const pathPrefix =
69+
this.path.length > 0 ? `${this.path}${this.delimiter}` : "";
70+
71+
const relativeKey = fullKey.slice(pathPrefix.length);
72+
let relativeKeySections = relativeKey.split(this.delimiter);
73+
relativeKeySections.pop(); // Remove last section, as that is the key itself, not a group
74+
75+
relativeKeySections = relativeKeySections.slice(0, params.depth); // Limit to depth
76+
77+
if (relativeKeySections.length === 0) {
78+
continue;
79+
}
80+
81+
for (let i = 0; i < relativeKeySections.length; i++) {
82+
const baseName = relativeKeySections[i];
83+
const groupRelativePath = relativeKeySections.slice(0, i + 1);
84+
const relativePath = groupRelativePath.join(this.delimiter);
85+
const fullPath = [pathPrefix, relativePath].join("");
86+
groups.set(fullPath, {
87+
baseName,
88+
relativePath,
89+
fullPath,
90+
isGroup: true,
91+
});
92+
}
93+
}
7894
});
79-
}
80-
return [...groups.values()];
95+
});
8196
};
8297

8398
getDirectChildKeys = (): Promise<KeyReturnType[]> => {

0 commit comments

Comments
 (0)