This is a middleware that binds the dynamic variables Note that this merely parses them and passes them on: the mechanics of paginating the response based on the limit
and offset still needs to be handled downstream, though if handling it in SQL is unavailable it could be done with
this namespace's | (ns metabase.server.middleware.offset-paging (:require [medley.core :as m] [metabase.request.core :as request])) |
(set! *warn-on-reflection* true) | |
(def ^:private default-limit 50) (def ^:private default-offset 0) | |
For parameters that should have a single value, only return the 1st if multiple values were passed in the request | (defn- ensure-single-value [v] (if (sequential? v) (first v) v)) |
(defn- parse-paging-params [{{:strs [limit offset]} :query-params}] (let [limit (some-> limit ensure-single-value parse-long) offset (some-> offset ensure-single-value parse-long)] (when (or limit offset) {:limit (or limit default-limit), :offset (or offset default-offset)}))) | |
(defn- with-paging-params [request {:keys [limit offset]}] (-> request (assoc ::limit limit, ::offset offset) (m/dissoc-in [:query-params "offset"]) (m/dissoc-in [:query-params "limit"]) (m/dissoc-in [:params :offset]) (m/dissoc-in [:params :limit]))) | |
Limit offset paging. This has many downsides but many upsides, chief among them at-will random paging. (it isn't stable with respect to underlying data changing, though) | (defn handle-paging [handler] (fn [request respond raise] (if-let [{:keys [limit offset] :as paging-params} (parse-paging-params request)] (request/with-limit-and-offset limit offset (handler (with-paging-params request paging-params) respond raise)) (handler request respond raise)))) |