const { MEMBER_SEPARATOR, NULL_CHARACTER } = require('./constants')
const createEvent = require('./createEvent')
const getLoader = require('./getLoader')
const v = require('./validate')
/**
* Asynchronously returns all the events that are related to the given value.
*
* @function EntityAttribute#getByValue
* @param {?String} value The given value.
* @param {('ascending'|'descending')} [order='ascending'] The order of the returned events.
* @param {Function} done The final callback. Invoked with `(err, events)`.
* @return {Array.<Event>} An array of events representing all the entities whose attribute had/has
* the given value.
*/
module.exports = function EntityAttribute$getByValue(aValue, aOrder, aDone) {
let order
let done
if (typeof aOrder === 'function') {
order = 'ascending'
done = aOrder
} else {
order = aOrder
done = aDone
}
if (!v.callback(done, "argument 3, 'done'")) {
throw v.lastError
}
const canBeNull = this._isNullable
if (!v.value(aValue, canBeNull, "argument 1, 'value'")) {
done(v.lastError)
return
}
if (!v.order(order, "argument 2, 'order'")) {
done(v.lastError)
return
}
const value = aValue || NULL_CHARACTER
const client = this._client
const isCaseSensitive = this._isCaseSensitive
getLoader(client).load('getByValue', (err, sha) => {
if (err) {
done(err)
return
}
client.evalsha(
sha,
0,
this._keyPrefix,
isCaseSensitive,
MEMBER_SEPARATOR,
value,
order,
(err, reply) => {
if (err) {
done(err)
return
}
// TODO: move to constructor
const transform = isCaseSensitive
? r => {
const [value, createdAt, entityId] = r.split(MEMBER_SEPARATOR)
return createEvent(NULL_CHARACTER, entityId, value, createdAt)
}
: r => {
const [createdAt, entityId, value] = r.split(MEMBER_SEPARATOR).slice(1)
return createEvent(NULL_CHARACTER, entityId, value, createdAt)
}
done(null, reply.map(transform))
}
)
})
}