Skip to content

Instantly share code, notes, and snippets.

@holyjak
Created April 30, 2014 15:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save holyjak/61d780888f12c3a31b60 to your computer and use it in GitHub Desktop.
Save holyjak/61d780888f12c3a31b60 to your computer and use it in GitHub Desktop.
Code for http://wp.me/pTHiC-10R, part 1
(require '[cheshire.core :refer [parse-string]])
(defn db-array [col] (reify java.sql.Array (getArray [_] (object-array col))))
(defn- json->data [data fields]
(map (fn [data]
(reduce (fn [data field]
(assoc data field (parse-string (get data field) true)))
data fields)) data))
(defn- discount-size [discount]
(if (or
(> (:amount discount) 10000)
(> (:percent discount) 5))
:high
:normal))
(defn- jdbc-array-to-set
"Convert a PostgreSQL JDBC4Array inside the map `m` - at the key `k` - into a se"
[key m] (update-in m [key] #(some->> % (.getArray) (into #{}))))
(defn- compute-discount
"Derive the :discount map based on the car's own discount and its active campaign, if applicable"
[car]
(let [{:keys [json campaign_discount_amount campaign_discount_percent]} car
{:keys [discount_amount discount_percent]} json
discount? (:use_campaign car)
amount (if discount?
(apply + (remove nil? [discount_amount campaign_discount_amount]))
discount_amount)
percent (if discount?
(apply + (remove nil? [discount_percent campaign_discount_percent]))
discount_percent)
discount {:amount amount
:percent percent}
discount-size (discount-size discount)
]
(assoc car :discount discount :discount-size discount-size)))
(defn merge-campaigns
"Given vector of car+campaign for a particular car, return a single car map
with a selected campaign.
"
[car+campaigns]
{:pre [(sequential? car+campaigns) :id]}
(let [campaign-ks [:use_campaign :campaign_discount_amount :campaign_discount_percent :active]
car (apply dissoc
(first car+campaigns)
campaign-ks)
campaign (->> car+campaigns
(map #(select-keys % campaign-ks))
(filter :active)
(sort-by :use_campaign) ;; true, if any, will be last
last)]
(assoc car :best-campaign campaign)))
(defn refine-cars
"Process get-cars query result set - derive additional data, transform values into better ones
There is one row per car and campaign, a car may have more campaigns - we pick the best one.
"
[cars-raw]
(->> cars-raw
(#(json->data % [:json]))
(#(map merge-campaigns
(vals (group-by :id %))))
(map (comp ;; reminder - the 1st fn is executed last
compute-discount
(fn [m] (update-in m [:keywords] (partial remove nil?))) ;; {NULL} => []
(partial jdbc-array-to-set :keywords)
(partial jdbc-array-to-set :category_ref)
))
))
(refine-cars [
{:id 1
:json "{\"discount_amount\":9000,\"discount_percent\":0}"
:campaign_discount_amount 2000
:campaign_discount_percent nil
:use_campaign false
:active true
:keywords (db-array ["fast"])
:category_ref (db-array [])}])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment