fetch_older_msg = async (
  table_id,
  viewname,
  {
    participant_field,
    msg_relation,
    msgsender_field,
    msgview,
    msgform,
    participant_maxread_field,
  },
  body,
  { req, res },
  { fetchOlderMsgQuery }
) => {
  const partRow = await fetchOlderMsgQuery(participant_field, body);
  if (!partRow)
    return {
      json: {
        error: "Not participating",
      },
    };

  const [msgtable_name, msgkey_to_room] = msg_relation.split(".");
  const v = await View.findOne({ name: msgview });
  const vresps = await v.runMany(
    { [msgkey_to_room]: +body.room_id },
    {
      req,
      res,
      orderBy: "id",
      orderDesc: true,
      limit,
      where: { id: { lt: +body.lt_msg_id } },
    }
  );
  vresps.reverse();
  const n_retrieved = vresps.length;
  const min_read_id = Math.min.apply(
    Math,
    vresps.map((r) => r.row.id)
  );
  const msglist = vresps.map((r) => r.html).join("");
  return {
    json: {
      success: "ok",
      prepend: msglist,
      remove_fetch_older: n_retrieved < limit,
      new_fetch_older_lt: min_read_id,
    },
  };
}
@param {*} table_id
@param {*} viewname
@param {object} optsOne.
@param {string} optsOne.participant_field
@param {string} optsOne.msg_relation
@param {*} optsOne.msgsender_field
@param {string} optsOne.msgview
@param {*} optsOne.msgform
@param {*} optsOne.participant_maxread_field
@param {object} body
@param {object} optsTwo
@param {object} optsTwo.req
@param {object} optsTwo.res
@returns {Promise<object>}