import Redis from 'ioredis' import { type } from 'os' const unflatten = require('flat').unflatten var flatten = require('flat') import ListContactsServiceCache from "../services/ContactServices/ListContactsServiceCache" import { redisConn } from './TicketCache' const deleteContactsByIdCache = async (id: string | number) => { const redis: any = await redisConn(); if(!redis) return if (redis.status !== 'connect') return const contact_cache: any = await redis.hgetall(`contact:${id}`) try { if (contact_cache && Object.keys(contact_cache).length > 0) { await redis.del(`contact:${id}`) console.log(`Contacts cache number ${contact_cache['number']} deleted!`) } else { console.log('CONTACT CACHE NOT FOUND!') } } catch (error) { console.log(`There was an error on deleteContactsByIdCache: ${error}`) } redis.quit() } const updateContactCache = async (hash: any, json_object: any) => { const redis: any = await redisConn(); if(!redis) return if (redis.status !== 'connect') return const pipeline = redis.pipeline() let entries = Object.entries(json_object) entries.forEach((e: any) => { pipeline.hset(hash, e[0], e[1]) }) await pipeline.exec(() => { console.log("Key/value inserted/updated") }); redis.quit() } const updateContactCacheById = async (id: string | number, update_fields: object | any) => { const redis: any = await redisConn(); if(!redis) return if (redis.status !== 'connect') return const contact_cache: any = await redis.hgetall(`contact:${id}`) try { if (contact_cache && Object.keys(contact_cache).length > 0) { // await redis.del(`contact:${id}`) update_fields.escaped_name = escapeCharCache(update_fields.name) await updateContactCache(`contact:${id}`, update_fields) console.log(`CONTACT ${contact_cache['number']} CACHE WAS UPDATED!`) } else { console.log('CONTACT CACHE NOT FOUND!') } } catch (error) { console.log(`There was an error on updateContactCacheById: ${error}`) } redis.quit() } const createOrUpdateContactCache = async (hash: any, contact: any) => { const redis: any = await redisConn(); if(!redis) return if (redis.status !== 'connect') return if (contact.name) { contact.escaped_name = escapeCharCache(contact.name) } await redis.hmset(hash, contact); redis.quit() } async function searchContactCache(search: string, offset: number, limit: number) { const redis: any = await redisConn(); if(!redis) return if (redis.status !== 'connect') return null search = escapeCharCache(search) const response: any = await redis.call('FT.SEARCH', 'idx_contact', `(@escaped_name:*${search}*)|(@number:*${search}*)`, 'LIMIT', offset, limit, 'SORTBY', 'escaped_name', 'ASC') redis.quit() if (response.length === 1) { return [] } const results: any = [] for (let n = 2; n < response.length; n += 2) { const result: any = {} const fieldNamesAndValues = response[n] for (let m = 0; m < fieldNamesAndValues.length; m += 2) { const k = fieldNamesAndValues[m] const v = fieldNamesAndValues[m + 1] result[k] = v } results.push(result) } return results } const removeExtraSpace = (str: string) => { str = str.replace(/^\s+/g, '') return str.replace(/\s+/g, ' ') } const escapeCharCache = (str: string) => { const pattern = /[\'|\"|\.|\,|\;|\<|\>|\{|\}|\[|\]|\"|\'|\=|\~|\*|\:|\#|\+|\^|\$|\@|\%|\!|\&|\)|\(|/|\-|\\)]/g; // no match, use replace function. let newStr = str.replace(pattern, (t1) => `\\${t1}`); newStr = removeExtraSpace(newStr) return newStr.trim() } const loadContactsCache = async () => { await createContactIndexCache('idx_contact') const redis: any = await redisConn(); if(!redis) return if (redis.status !== 'connect') return let contacts = await ListContactsServiceCache() const pipeline = redis.pipeline() for (let i = 0; i < contacts.length; i++) { contacts[i].createdAt = new Date(contacts[i].createdAt).toISOString() contacts[i].updatedAt = new Date(contacts[i].updatedAt).toISOString() contacts[i].escaped_name = escapeCharCache(contacts[i].name) pipeline.hmset(`contact:${contacts[i].id}`, contacts[i]); } await pipeline.exec(() => { console.log(`${contacts.length} CONTACTS INSERTED IN CACHE!`) }); redis.quit() } const createContactIndexCache = async (hashIndex: string) => { const redis: any = await redisConn(); if(!redis) return if (redis.status !== 'connect') return try { const lst_index_redis: any = await redis.call('FT._LIST') if (lst_index_redis.includes(hashIndex)) { console.log('entrou...') await redis.call('FT.DROPINDEX', hashIndex) } const response = await redis.call('FT.CREATE', hashIndex, 'ON', 'HASH', 'PREFIX', '1', 'contact:', 'SCHEMA', 'escaped_name', 'TEXT', 'SORTABLE', 'number', 'TEXT', 'SORTABLE') console.log('Contact index created: ', response) } catch (error) { console.log('There was an error on createContactIndexCache: ', error) } redis.quit() } export { loadContactsCache, searchContactCache, deleteContactsByIdCache, updateContactCacheById, createOrUpdateContactCache, escapeCharCache }