import { createHash } from 'crypto'
import { clear as clearCache } from '../lib/generic.js'
/**
* Helper functions for managing `result-set` cache.
*
* @module Helper/ResultSet
*/
/**
* Build a cache key for the result set.
*
* @param {object} [opts={}] - The options for building the cache key
* @param {object} [opts.model] - The model associated with the result set
* @param {string} [opts.id] - The ID of the result set
* @param {object} [opts.filter] - The filter applied to the result set
* @param {object} [opts.options] - Additional options for building the cache key
* @returns {string} - Returns the generated cache key
*/
export function buildKey (opts = {}) {
const { model, id, filter, options } = opts
const { fmt, noResultSanitizer, refs } = options
const { merge } = this.app.lib._
let extra = merge({}, filter, { fmt, noResultSanitizer, refs })
extra = createHash('md5').update(JSON.stringify(extra)).digest('hex')
const key = `dobo|${model.name}|${options.action}|${id}|${extra}`
return key
}
/**
* Clear cached result set items.
*
* @async
* @method
* @param {object} [opts={}] - The options for clearing the cached result set
* @returns {Promise<void>}
*/
export async function clear (opts = {}) {
if (!this.instance) return
await clearCache.call(this, opts)
}
/**
* Get a cached result set item.
*
* @async
* @method
* @param {object} [opts={}] - The options for retrieving the cached result set
* @returns {Promise<*>} - Returns the cached result set item or false if not found
*/
export async function get (opts = {}) {
if (!this.instance) return
const { isEmpty } = this.app.lib._
if (opts.options.noCache || opts.model.cache.ttlDur === 0) return false
const key = buildKey.call(this, opts)
const result = await this.instance.get(key)
return isEmpty(result) ? false : result
}
/**
* Remove a cached result set item.
*
* @async
* @method
* @param {object} [opts={}] - The options for removing the cached result set
* @returns {Promise<void>}
*/
export async function remove (opts = {}) {
if (!this.instance) return
if (opts.options.noCache || opts.model.cache.ttlDur === 0) return
const key = buildKey.call(this, opts)
await this.instance.delete(key)
}
/**
* Set a cached result set item.
*
* @async
* @method
* @param {object} [opts={}] - The options for setting the cached result set
* @returns {Promise<void>}
*/
export async function set (opts = {}) {
if (!this.instance) return
if (opts.options.noCache || opts.model.cache.ttlDur === 0) return
let ttl = opts.ttl ?? opts.model.cache.ttlDur
if (ttl <= 0) ttl = 1
const key = buildKey.call(this, opts)
const value = opts.result
await this.instance.set(key, value, ttl)
}