aretherecookies-server/src/aretherecookies/db.clj
2018-06-03 12:25:33 -05:00

96 lines
No EOL
3.2 KiB
Clojure

(ns aretherecookies.db
(:require [clojure.java.jdbc :as jdbc]
[environ.core :refer [env]]
[clojure.string :as str]
[hugsql.core :as hugsql])
(:import com.mchange.v2.c3p0.ComboPooledDataSource))
; defines a number of functions in this namesapce as defined in queries.sql
; by-distance
; by-last-updated
; by-quantity
; select-food-items
; within-radius
; has-category
; select-images
; update-images
(hugsql/def-db-fns "aretherecookies/queries.sql")
(def db-spec {:uri (env :database-jdbc-uri)
:password (env :database-password)
:user (env :database-user)
:name (env :database-name)})
(defn pool
[spec]
(let [cpds (doto (ComboPooledDataSource.)
(.setDriverClass "org.postgresql.Driver")
(.setJdbcUrl (str "jdbc:" (:uri spec)))
(.setUser (:user spec))
(.setPassword (:password spec))
;; expire excess connections after 30 minutes of inactivity:
(.setMaxIdleTimeExcessConnections (* 30 60))
;; expire connections after 3 hours of inactivity:
(.setMaxIdleTime (* 3 60 60)))]
(println (str "jdbc:" (:url spec)))
{:datasource cpds}))
(defonce pooled-db (delay (pool db-spec)))
(defn get-orderby [{orderby :orderby} & args]
(apply
(cond
(= orderby "distance") by-distance
(= orderby "lastupdated") by-last-updated
(= orderby "quantity") by-quantity
:else by-distance)
args))
(defn wrap-in-quotes [token]
(str/replace token #"(^|$)" "'"))
(defn wildcard
[term]
(str "%" (str/join (interpose "%" term)) "%"))
(defn get-where [{:keys [:lat :lng :filter]}]
(food-items-where-clause {:lat lat
:lng lng
:dist (:radius filter)
:categories (map wrap-in-quotes (:categories filter))
:search (wildcard (:search filter))}))
(defn query-food-items [{lat :lat lng :lng filter :filter}]
(select-food-items
@pooled-db
{:lat lat
:lng lng
:where (get-where {:lat lat :lng lng :filter filter})
:order (get-orderby filter)}))
(defn insert-quantity [{:keys [:foodItemId :quantity]}]
(insert-quantity-query @pooled-db {:food_item_id foodItemId :quantity quantity}))
(defn select-latest-quantity [{:keys [:foodItemId]}]
(select-latest-quantity-query @pooled-db {:food_item_id (wrap-in-quotes foodItemId)}))
(defn create-food-item [{:keys [:name :placeId :category :quantity :latitude :longitude]}]
(let [food-item (first (insert-food-item
@pooled-db
{:name name
:placeId placeId
:category category
:longitude longitude
:latitude latitude}))
quantity (first (insert-quantity {:foodItemId (:id food-item) :quantity quantity}))]
(merge food-item (select-keys quantity [:quantity :date]))))
(defn get-images
"query database for a list of images for a food item id"
[foodItemId]
(select-images @pooled-db {:foodItemId foodItemId}))
(defn add-image
"update the list of images for given food item id"
[image]
(insert-image @pooled-db image))