function classifyCountTransform()

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})`
    );
  }