diff --git a/project.clj b/project.clj index 3e35d19..affadaa 100644 --- a/project.clj +++ b/project.clj @@ -9,7 +9,8 @@ [org.postgresql/postgresql "42.1.4.jre6"] [com.mchange/c3p0 "0.9.5.2"] [ring-middleware-format "0.7.2"] - [org.clojure/data.json "0.2.6"]] + [org.clojure/data.json "0.2.6"] + [ring/ring-json "0.4.0"]] :plugins [[lein-ring "0.9.7"]] :ring {:handler aretherecookies.handler/app} :profiles diff --git a/sample-post.json b/sample-post.json new file mode 100644 index 0000000..36022b6 --- /dev/null +++ b/sample-post.json @@ -0,0 +1,8 @@ +{ + "lat": 30.3033267, + "lng": -97.7286718, + "orderby": "distance", + "filter": { + "radius": 10 + } +} diff --git a/src/aretherecookies/handler.clj b/src/aretherecookies/handler.clj index 08b4002..7174602 100644 --- a/src/aretherecookies/handler.clj +++ b/src/aretherecookies/handler.clj @@ -3,7 +3,10 @@ [compojure.route :as route] [ring.middleware.defaults :refer [wrap-defaults site-defaults]] [clojure.java.jdbc :as jdbc] - [clojure.data.json :as json]) + [clojure.data.json :as json] + [clojure.string :as str] + [ring.middleware.anti-forgery :refer :all] + [ring.middleware.json :refer [wrap-json-body]]) (:import com.mchange.v2.c3p0.ComboPooledDataSource)) (def db-spec {:dbtype "postgresql" @@ -38,25 +41,38 @@ ST_AsGeoJSON(loc) as location, ST_Distance( loc, - ST_GeogFromText('SRID=4326;POINT(-97.7286718 30.3033267)') + @LOCATION@ ) / 1609 as distance FROM food_items WHERE ST_DWithin( loc, - ST_GeogFromText('SRID=4326;POINT(-97.7286718 30.3033267)'), - 10 * 1609 + @LOCATION@, + @DISTANCE@ * 1609 ) ORDER BY distance ASC;") -(jdbc/query @pooled-db - [location-query]) +(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 uuid-to-string [key value] (if (instance? java.util.UUID value) (.toString value) value)) (defn get-coords [item] - (-> item (get :location) json/read-str (get "coordinates"))) + (-> + item + (get :location) + json/read-str + (get "coordinates"))) (defn build-lat-lng [[lng lat]] (hash-map :longitude lng :latitude lat)) @@ -66,22 +82,30 @@ (hash-map :longitude lng :latitude lat))) (defn parse-location [item] - (-> item build-latlng (merge item) (dissoc :location))) + (-> + item + build-latlng + (merge item) + (dissoc :location))) -(defn food-items-to-json [response] - (map parse-location response)) +(defn food-items-to-json [query-result] + (map parse-location query-result)) -(defn food-items-handler [location orderby filter] +(defn food-items-handler [{{lat "lat" lng "lng" filter "filter" orderby "orderby"} :body}] (json/write-str (hash-map :orderby orderby :filter filter - :fooditems (food-items-to-json (jdbc/query @pooled-db [location-query]))) + :fooditems (food-items-to-json + (jdbc/query @pooled-db [(build-fooditems-query lng lat (get filter "radius"))]))) :value-fn uuid-to-string)) (defroutes app-routes - (GET "/fooditems" [location orderby filter] (food-items-handler location orderby filter)) + (GET "/" [] (str {:csrf-token + *anti-forgery-token*})) + (POST "/test" req "ok") + (POST "/fooditems" req (wrap-json-body food-items-handler)) (GET "/echo" [location orderby filter] (str location orderby filter))) (def app - (wrap-defaults app-routes site-defaults)) + (wrap-defaults app-routes (assoc-in site-defaults [:security :anti-forgery] false)))