91 lines
2.3 KiB
TypeScript
91 lines
2.3 KiB
TypeScript
import { Injectable, OnModuleDestroy, Logger } from '@nestjs/common';
|
|
import { ConfigService } from '@nestjs/config';
|
|
import Redis from 'ioredis';
|
|
|
|
@Injectable()
|
|
export class RedisService implements OnModuleDestroy {
|
|
private readonly logger = new Logger(RedisService.name);
|
|
private readonly client: Redis;
|
|
|
|
constructor(private readonly configService: ConfigService) {
|
|
const host = this.configService.get<string>('REDIS_HOST') || 'localhost';
|
|
const port = this.configService.get<number>('REDIS_PORT') || 6379;
|
|
const password = this.configService.get<string>('REDIS_PASSWORD');
|
|
const db = this.configService.get<number>('REDIS_DB') || 1;
|
|
|
|
this.client = new Redis({
|
|
host,
|
|
port,
|
|
password: password || undefined,
|
|
db,
|
|
});
|
|
|
|
this.client.on('connect', () => {
|
|
this.logger.log(`Connected to Redis at ${host}:${port}, DB: ${db}`);
|
|
});
|
|
|
|
this.client.on('error', (err) => {
|
|
this.logger.error('Redis connection error:', err);
|
|
});
|
|
}
|
|
|
|
async onModuleDestroy() {
|
|
await this.client.quit();
|
|
this.logger.log('Redis connection closed');
|
|
}
|
|
|
|
getClient(): Redis {
|
|
return this.client;
|
|
}
|
|
|
|
async get(key: string): Promise<string | null> {
|
|
return this.client.get(key);
|
|
}
|
|
|
|
async set(key: string, value: string, ttlSeconds?: number): Promise<void> {
|
|
if (ttlSeconds) {
|
|
await this.client.setex(key, ttlSeconds, value);
|
|
} else {
|
|
await this.client.set(key, value);
|
|
}
|
|
}
|
|
|
|
async del(key: string): Promise<void> {
|
|
await this.client.del(key);
|
|
}
|
|
|
|
async delByPattern(pattern: string): Promise<number> {
|
|
const keys = await this.client.keys(pattern);
|
|
if (keys.length === 0) {
|
|
return 0;
|
|
}
|
|
return this.client.del(...keys);
|
|
}
|
|
|
|
async exists(key: string): Promise<boolean> {
|
|
const result = await this.client.exists(key);
|
|
return result === 1;
|
|
}
|
|
|
|
async setJson<T>(key: string, value: T, ttlSeconds?: number): Promise<void> {
|
|
await this.set(key, JSON.stringify(value), ttlSeconds);
|
|
}
|
|
|
|
async getJson<T>(key: string): Promise<T | null> {
|
|
const value = await this.get(key);
|
|
if (!value) {
|
|
return null;
|
|
}
|
|
try {
|
|
return JSON.parse(value) as T;
|
|
} catch {
|
|
this.logger.warn(`Failed to parse JSON for key: ${key}`);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
async ttl(key: string): Promise<number> {
|
|
return this.client.ttl(key);
|
|
}
|
|
}
|