in packages/sqrl-redis-functions/src/CountFunctions.ts [402:474]
function classifyCountTransform(
state: CompileState,
ast: CustomCallAst,
args: CountArguments
) {
const { hasAlias, keyedCounterName, whereAst } = interpretCountArgs(
state,
ast,
args
);
// Rewrite this count as a subtraction between other counts (whoah)
if (PREVIOUS_CONFIG.hasOwnProperty(args.timespan.type)) {
const previousConfig = PREVIOUS_CONFIG[args.timespan.type];
// Convert into a subtract(left, right)
// We transform into calls to count() which in turn will get transformed
// themselves. This is necessary because the previous config might
// itself be a recursive count.
//
// weekOverWeek = lastWeek - previousLastWeek
// = lastWeek - (lastTwoWeeks - lastWeek)
//
const resultAst = AstBuilder.call("_subtract", [
classifyCountTransform(state, ast, {
...args,
timespan: previousConfig.subtractLeft,
}),
classifyCountTransform(state, ast, {
...args,
timespan: previousConfig.subtractRight,
}),
]);
if (!previousConfig.allowNegativeValue) {
const subtractionAst = state.setGlobal(
ast,
resultAst,
`count(${args.timespan.type}:${keyedCounterName})`
);
return AstBuilder.branch(
// if result < 0
AstBuilder.call("_cmpL", [subtractionAst, AstBuilder.constant(0)]),
// then null
AstBuilder.constant(null),
// else result
subtractionAst
);
}
return resultAst;
}
const addAst = AstBuilder.branch(
AstBuilder.and([whereAst, AstBuilder.feature("SqrlIsClassify")]),
AstBuilder.constant(1),
AstBuilder.constant(0)
);
const resultAst = AstBuilder.call("_add", [
hasAlias ? AstBuilder.constant(0) : addAst,
AstBuilder.call("max", [
AstBuilder.call("concat", [
AstBuilder.constant([0]),
databaseCountTransform(state, ast, args),
]),
]),
]);
return state.setGlobal(
ast,
resultAst,
`count(${getNameForTimespan(args.timespan)}:${keyedCounterName})`
);
}