From 923014d5637108726805d1ebaff21d0dd773facf Mon Sep 17 00:00:00 2001 From: Bart Akeley Date: Tue, 31 Oct 2017 22:09:32 -0500 Subject: [PATCH] move SQL out of code using HugSQL --- project.clj | 3 +- src/aretherecookies/db.clj | 76 +++++++++------------------------ src/aretherecookies/handler.clj | 8 ++-- src/aretherecookies/queries.sql | 13 ++++++ 4 files changed, 41 insertions(+), 59 deletions(-) create mode 100644 src/aretherecookies/queries.sql diff --git a/project.clj b/project.clj index 669011d..330d5db 100644 --- a/project.clj +++ b/project.clj @@ -13,7 +13,8 @@ [ring-middleware-format "0.7.2"] [org.clojure/data.json "0.2.6"] [ring/ring-json "0.4.0"] - [ring/ring-jetty-adapter "1.4.0"]] + [ring/ring-jetty-adapter "1.4.0"] + [com.layerware/hugsql "0.4.8"]] :plugins [[lein-ring "0.9.7"] [lein-environ "1.1.0"]] :ring {:handler aretherecookies.app/app} :profiles diff --git a/src/aretherecookies/db.clj b/src/aretherecookies/db.clj index 298b762..5e9405a 100644 --- a/src/aretherecookies/db.clj +++ b/src/aretherecookies/db.clj @@ -1,66 +1,32 @@ (ns aretherecookies.db - (:require - [clojure.java.jdbc :as jdbc] + (:require [clojure.java.jdbc :as jdbc] [environ.core :refer [env]] - [clojure.string :as str]) - (:import com.mchange.v2.c3p0.ComboPooledDataSource)) + [clojure.string :as str] + [hugsql.core :as hugsql]) + (:import com.mchange.v2.c3p0.ComboPooledDataSource)) -(def db-spec { - :uri (env :database-jdbc-uri) - :password (env :database-password) - :user (env :database-user) - :name (env :database-name) -}) +(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)) + [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)) + (.setMaxIdleTimeExcessConnections (* 30 60)) ;; expire connections after 3 hours of inactivity: - (.setMaxIdleTime (* 3 60 60)))] + (.setMaxIdleTime (* 3 60 60)))] (println (str "jdbc:" (:url spec))) {:datasource cpds})) -(def pooled-db (delay (pool db-spec))) +(defonce pooled-db (delay (pool db-spec))) -(def location-query " -SELECT - id, - name, - place_id, - category, - images, - thumbImage, - ST_AsGeoJSON(loc) as location, - ST_Distance( - loc, - @LOCATION@ - ) / 1609 as distance -FROM food_items -WHERE - ST_DWithin( - loc, - @LOCATION@, - @DISTANCE@ * 1609 - ) -ORDER BY distance ASC;") - -(defn point-text [lng lat] - (-> - "ST_GeogFromText('SRID=4326;POINT(@LONGITUDE@ @LATITUDE@)')" - (str/replace "@LONGITUDE@" (str lng)) - (str/replace "@LATITUDE@" (str lat)))) - -(defn build-fooditems-query [lng lat dist] - (-> - location-query - (str/replace "@LOCATION@" (point-text (str lng) (str lat))) - (str/replace "@DISTANCE@" (str dist)))) - -(defn query-food-items [query] - (jdbc/query @pooled-db [query])) \ No newline at end of file +(defn query-food-items-by-distance [{:keys [lat lng radius]}] + (food-items-by-distance @pooled-db {:dist radius :lng lng :lat lat})) \ No newline at end of file diff --git a/src/aretherecookies/handler.clj b/src/aretherecookies/handler.clj index fa32b48..d7d29d5 100644 --- a/src/aretherecookies/handler.clj +++ b/src/aretherecookies/handler.clj @@ -1,5 +1,5 @@ (ns aretherecookies.handler - (:require [aretherecookies.db :refer [query-food-items build-fooditems-query]] + (:require [aretherecookies.db :refer [query-food-items-by-distance]] [compojure.core :refer :all] [compojure.route :as route] [clojure.data.json :as json] @@ -41,8 +41,10 @@ (hash-map :orderby orderby :filter filter - :fooditems (food-items-to-json - (query-food-items (build-fooditems-query lng lat (get filter "radius"))))) + :fooditems (food-items-to-json + (query-food-items-by-distance {:lat lat + :lng lng + :radius (get filter "radius")}))) :value-fn uuid-to-string))) (defroutes app-routes diff --git a/src/aretherecookies/queries.sql b/src/aretherecookies/queries.sql new file mode 100644 index 0000000..a5d32b7 --- /dev/null +++ b/src/aretherecookies/queries.sql @@ -0,0 +1,13 @@ +-- :name food-items-by-distance :raw +SELECT + id, + name, + place_id, + category, + images, + thumbImage, + ST_AsGeoJSON(loc) as location, + ST_Distance(loc, ST_SetSRID(ST_Point(:lng, :lat),4326)::geography) / 1609 as distance +FROM food_items +WHERE ST_DWithin(loc, ST_SetSRID(ST_Point(:lng, :lat),4326)::geography, :dist * 1609) +ORDER BY distance ASC \ No newline at end of file