|
| 1 | +import { Injectable } from "@nestjs/common"; |
| 2 | +import Redis from "ioredis"; |
| 3 | +import { redisConfig } from "../config/redis.config"; |
| 4 | +import { stringify } from "ts-jest"; |
| 5 | + |
| 6 | +@Injectable() |
| 7 | +export class RedisService { |
| 8 | + private readonly client: Redis = new Redis({ |
| 9 | + host: redisConfig.host, |
| 10 | + port: redisConfig.port, |
| 11 | + password: redisConfig.password, |
| 12 | + }); |
| 13 | + |
| 14 | + async set(key: string, value: any, ttl: number = 0) { |
| 15 | + if (typeof value === "object") value = JSON.stringify(value); |
| 16 | + |
| 17 | + await this.client.set(key, value, "KEEPTTL"); |
| 18 | + await this.client.expire(key, ttl); |
| 19 | + } |
| 20 | + |
| 21 | + async get(key: string) { |
| 22 | + return this.client.get(key); |
| 23 | + } |
| 24 | + |
| 25 | + async getTTL(key: string) { |
| 26 | + return this.client.ttl(key); |
| 27 | + } |
| 28 | + |
| 29 | + async getKeys(query: string) { |
| 30 | + const keys: string[] = []; |
| 31 | + let cursor = "0"; |
| 32 | + |
| 33 | + do { |
| 34 | + const [nextCursor, matchedKeys] = await this.client.scan( |
| 35 | + cursor, |
| 36 | + "MATCH", |
| 37 | + query, |
| 38 | + "COUNT", |
| 39 | + "100" |
| 40 | + ); |
| 41 | + cursor = nextCursor; |
| 42 | + keys.push(...matchedKeys); |
| 43 | + } while (cursor !== "0"); |
| 44 | + return keys; |
| 45 | + } |
| 46 | + |
| 47 | + async getHashValueByField(key: string, field: string) { |
| 48 | + return this.client.hget(key, field); |
| 49 | + } |
| 50 | + |
| 51 | + async setHashValueByField(key: string, field: string, value: any) { |
| 52 | + if (typeof value !== "string") value = stringify(value); |
| 53 | + return this.client.hset(key, field, value); |
| 54 | + } |
| 55 | + |
| 56 | + async delete(...keys: string[]) { |
| 57 | + return this.client.del(...keys); |
| 58 | + } |
| 59 | + |
| 60 | + async getValues(query: string) { |
| 61 | + const keys = await this.getKeys(query); |
| 62 | + if (!keys.length) return null; |
| 63 | + return this.client.mget(keys); |
| 64 | + } |
| 65 | + |
| 66 | + async getMap(query: string, valueType: "object" | "primitive" = "object") { |
| 67 | + const keys = await this.getKeys(query); |
| 68 | + const values = await this.getValues(query); |
| 69 | + if (!values) return null; |
| 70 | + |
| 71 | + return keys.reduce((acc, key, index) => { |
| 72 | + acc[key] = |
| 73 | + valueType === "object" |
| 74 | + ? JSON.parse(values[index]) |
| 75 | + : values[index]; |
| 76 | + return acc; |
| 77 | + }, {}); |
| 78 | + } |
| 79 | +} |
0 commit comments