From eb5ed906fd8f3802a705381f52dc359963480504 Mon Sep 17 00:00:00 2001 From: flynn Date: Tue, 22 Jan 2019 03:00:52 +0100 Subject: [PATCH] add card layouts, convert postgresql querries to mysql --- README.md | 10 - cat.iml | 4 +- dev-config.edn_example | 2 +- project.clj | 4 +- resources/html/home.html | 217 ++++++++++-------- .../20190109004458-add-users-table.up.sql | 6 +- .../20190109005337-add-relation-table.up.sql | 12 +- ...114224209-add-request-status-type.down.sql | 1 - ...90114224209-add-request-status-type.up.sql | 2 - ...14224926-add-relation-request-table.up.sql | 10 +- resources/public/css/screen.css | 4 - resources/public/js/spec.json | 2 +- src/clj/cat/db/core.clj | 99 ++------ src/clj/cat/routes/home.clj | 18 +- src/clj/cat/routes/oauth.clj | 2 +- 15 files changed, 171 insertions(+), 222 deletions(-) delete mode 100644 resources/migrations/20190114224209-add-request-status-type.down.sql delete mode 100644 resources/migrations/20190114224209-add-request-status-type.up.sql diff --git a/README.md b/README.md index 099f77c..07e064b 100644 --- a/README.md +++ b/README.md @@ -69,16 +69,6 @@ In this case you need to shutdown and restart using run or repl. You can find these function available in the [userspace definitions][2] -### Notes -#### Database -* ENUM TYPE - - Because of the lack of typing in clojure and the forced typing of the jdbc driver -we need to manually manage conversion of enum types to clojure keywords. - - When adding an enum to the database, make sure to add it to the '+schema-enums+' set see [db][3] - - ## Production diff --git a/cat.iml b/cat.iml index 60ebdd1..794c729 100644 --- a/cat.iml +++ b/cat.iml @@ -71,7 +71,7 @@ - + @@ -127,6 +127,7 @@ + @@ -185,7 +186,6 @@ - diff --git a/dev-config.edn_example b/dev-config.edn_example index 0cd4687..bfb1fbf 100644 --- a/dev-config.edn_example +++ b/dev-config.edn_example @@ -12,4 +12,4 @@ :access-token-uri "https://api.twitter.com/oauth/access_token" :authorize-uri "https://api.twitter.com/oauth/authenticate" ; set your dev database connection URL here - :database-url "postgresql://localhost:5432/a_db_name?user=a_username&password=a_password"} \ No newline at end of file + :database-url "mysql://localhost:3306/a_db_name?user=a_username&password=a_password"} \ No newline at end of file diff --git a/project.clj b/project.clj index f79775d..e9393fb 100644 --- a/project.clj +++ b/project.clj @@ -27,7 +27,9 @@ [org.clojure/clojurescript "1.10.439" :scope "provided"] [org.clojure/tools.cli "0.4.1"] [org.clojure/tools.logging "0.4.1"] - [org.postgresql/postgresql "42.2.5"] + ;[org.postgresql/postgresql "42.2.5"] + [mysql/mysql-connector-java "8.0.12"] + [com.google.protobuf/protobuf-java "3.6.1"] ;https://www.webjars.org/ [org.webjars.npm/bulma "0.7.2"] [org.webjars/font-awesome "5.6.1"] diff --git a/resources/html/home.html b/resources/html/home.html index d7b2990..cf0a1b4 100644 --- a/resources/html/home.html +++ b/resources/html/home.html @@ -101,101 +101,134 @@ {% if user %}
-
-

Your cuddles

- - - - - - - - - {% for relation in user-relations %} - - - - - {% endfor %} - -
Person 1Person 2
{{relation.name}}{{relation.name_2}}
+
+
+
+

+ Your cuddles +

+
+ +
+
+ + + + + + + + + {% for relation in user-relations %} + + + + + {% endfor %} + +
Person 1Person 2
{{relation.name}}{{relation.name_2}}
+
+
+
-
- {% csrf-field %} -
-
-
- -
-
-
- -
-
-
-
-
- - - - - - - - {% for rr in rel-requests-out %} - - - - - {% endfor %} -
Outgoing requestsStatus
{{rr.to_name}} - - {% include "parts/colored-status.html" %} -
-
-
- - - - - - - - {% for rr in rel-requests-in %} - - - - {% ifequal rr.status "open" %} - - {% endifequal %} - - {% endfor %} -
Incoming requestsStatus
- {{rr.from_name}} - - {% include "parts/colored-status.html" %} - -
- {% csrf-field %} -
-
- -
-
- -
+
+
+

+ Outgoing requests +

+
+
+
+ + {% csrf-field %} +
+
+
+
- -
+
+
+ +
+
+ +
+ + + + + + + + {% for rr in rel-requests-out %} + + + + + {% endfor %} +
Outgoing requestsStatus
{{rr.to_name}} + + {% include "parts/colored-status.html" %} +
+
+
+
+ +
+
+
+

+ Incoming requests +

+
+
+
+ + + + + + + + {% for rr in rel-requests-in %} + + + + {% ifequal rr.status "open" %} + + {% endifequal %} + + {% endfor %} +
Incoming requestsStatus
+ {{rr.from_name}} + + {% include "parts/colored-status.html" %} + +
+ {% csrf-field %} +
+
+ +
+
+ +
+
+
+
+
diff --git a/resources/migrations/20190109004458-add-users-table.up.sql b/resources/migrations/20190109004458-add-users-table.up.sql index 787b4ee..b0f3ebb 100644 --- a/resources/migrations/20190109004458-add-users-table.up.sql +++ b/resources/migrations/20190109004458-add-users-table.up.sql @@ -1,4 +1,6 @@ CREATE TABLE users -(id SERIAL PRIMARY KEY, +(id INT NOT NULL AUTO_INCREMENT, name VARCHAR(255) NOT NULL, - gender VARCHAR(255)); \ No newline at end of file + gender VARCHAR(255), + + PRIMARY KEY(id)); \ No newline at end of file diff --git a/resources/migrations/20190109005337-add-relation-table.up.sql b/resources/migrations/20190109005337-add-relation-table.up.sql index aac53c1..5b991d5 100644 --- a/resources/migrations/20190109005337-add-relation-table.up.sql +++ b/resources/migrations/20190109005337-add-relation-table.up.sql @@ -1,6 +1,8 @@ CREATE TABLE relations -(id SERIAL PRIMARY KEY, - from_id INTEGER NOT NULL, - to_id INTEGER NOT NULL, - FOREIGN KEY (from_id) REFERENCES users (id), - FOREIGN KEY (to_id) REFERENCES users (id)); \ No newline at end of file +(id INT NOT NULL AUTO_INCREMENT, + from_id INT NOT NULL, + to_id INT NOT NULL, + + PRIMARY KEY(id), + FOREIGN KEY (from_id) REFERENCES users(id), + FOREIGN KEY (to_id) REFERENCES users(id)); \ No newline at end of file diff --git a/resources/migrations/20190114224209-add-request-status-type.down.sql b/resources/migrations/20190114224209-add-request-status-type.down.sql deleted file mode 100644 index 9cb9323..0000000 --- a/resources/migrations/20190114224209-add-request-status-type.down.sql +++ /dev/null @@ -1 +0,0 @@ -DROP TYPE STATUS; \ No newline at end of file diff --git a/resources/migrations/20190114224209-add-request-status-type.up.sql b/resources/migrations/20190114224209-add-request-status-type.up.sql deleted file mode 100644 index 2eb45b0..0000000 --- a/resources/migrations/20190114224209-add-request-status-type.up.sql +++ /dev/null @@ -1,2 +0,0 @@ -CREATE TYPE STATUS as ENUM -('open', 'accepted', 'declined'); \ No newline at end of file diff --git a/resources/migrations/20190114224926-add-relation-request-table.up.sql b/resources/migrations/20190114224926-add-relation-request-table.up.sql index deb1ce1..5761c47 100644 --- a/resources/migrations/20190114224926-add-relation-request-table.up.sql +++ b/resources/migrations/20190114224926-add-relation-request-table.up.sql @@ -1,7 +1,9 @@ CREATE TABLE relation_requests -(id SERIAL PRIMARY KEY, - from_id INTEGER NOT NULL, - to_id INTEGER NOT NULL, - status STATUS NOT NULL, +(id INT NOT NULL AUTO_INCREMENT, + from_id INT NOT NULL, + to_id INT NOT NULL, + status ENUM('open', 'accepted', 'declined') NOT NULL, + + PRIMARY KEY (id), FOREIGN KEY (from_id) REFERENCES users (id), FOREIGN KEY (to_id) REFERENCES users (id)); \ No newline at end of file diff --git a/resources/public/css/screen.css b/resources/public/css/screen.css index e9dd0a5..0309f03 100644 --- a/resources/public/css/screen.css +++ b/resources/public/css/screen.css @@ -4,10 +4,6 @@ body { height: 100%; } -table { - margin-top: 2em; -} - .loader-container { width: 700px; height: 425px; diff --git a/resources/public/js/spec.json b/resources/public/js/spec.json index 1b7e600..fd3f6cf 100644 --- a/resources/public/js/spec.json +++ b/resources/public/js/spec.json @@ -274,7 +274,7 @@ "value": "#ccc" }, "strokeWidth": { - "value": 0.5 + "value": 1 } } }, diff --git a/src/clj/cat/db/core.clj b/src/clj/cat/db/core.clj index 5a12dea..4efcb96 100644 --- a/src/clj/cat/db/core.clj +++ b/src/clj/cat/db/core.clj @@ -1,33 +1,30 @@ (ns cat.db.core (:require - [cheshire.core :refer [generate-string parse-string]] + [clj-time.jdbc] [clojure.java.jdbc :as jdbc] [clojure.tools.logging :as log] [conman.core :as conman] - [java-time :as jt] + [java-time.pre-java8 :as jt] [cat.config :refer [env]] [mount.core :refer [defstate]] [clojure.string :as s]) - (:import org.postgresql.util.PGobject - java.sql.Array - clojure.lang.IPersistentMap - clojure.lang.IPersistentVector - [java.sql + (:import [java.sql BatchUpdateException PreparedStatement])) + (defstate ^:dynamic *db* - :start (if-let [jdbc-url (env :database-url)] - (conman/connect! {:jdbc-url jdbc-url}) - (do - (log/warn "database connection URL was not found, please set :database-url in your config, e.g: dev-config.edn") - *db*)) - :stop (conman/disconnect! *db*)) + :start (if-let [jdbc-url (env :database-url)] + (conman/connect! {:jdbc-url jdbc-url}) + (do + (log/warn "database connection URL was not found, please set :database-url in your config, e.g: dev-config.edn") + *db*)) + :stop (conman/disconnect! *db*)) (conman/bind-connection *db* "sql/queries.sql") (extend-protocol jdbc/IResultSetReadColumn - java.sql.Timestamp + java.sql.Timestamp (result-set-read-column [v _2 _3] (.toLocalDateTime v)) java.sql.Date @@ -35,36 +32,10 @@ (.toLocalDate v)) java.sql.Time (result-set-read-column [v _2 _3] - (.toLocalTime v)) - Array - (result-set-read-column [v _ _] (vec (.getArray v))) - PGobject - (result-set-read-column [pgobj _metadata _index] - (let [type (.getType pgobj) - value (.getValue pgobj)] - (case type - "json" (parse-string value true) - "jsonb" (parse-string value true) - "citext" (str value) - value)))) - -(defn to-pg-json [value] - (doto (PGobject.) - (.setType "jsonb") - (.setValue (generate-string value)))) - -(extend-type clojure.lang.IPersistentVector - jdbc/ISQLParameter - (set-parameter [v ^java.sql.PreparedStatement stmt ^long idx] - (let [conn (.getConnection stmt) - meta (.getParameterMetaData stmt) - type-name (.getParameterTypeName meta idx)] - (if-let [elem-type (when (= (first type-name) \_) (apply str (rest type-name)))] - (.setObject stmt idx (.createArrayOf conn elem-type (to-array v))) - (.setObject stmt idx (to-pg-json v)))))) + (.toLocalTime v))) (extend-protocol jdbc/ISQLValue - java.util.Date + java.util.Date (sql-value [v] (java.sql.Timestamp. (.getTime v))) java.time.LocalTime @@ -78,46 +49,4 @@ (jt/sql-timestamp v)) java.time.ZonedDateTime (sql-value [v] - (jt/sql-timestamp v)) - IPersistentMap - (sql-value [value] (to-pg-json value)) - IPersistentVector - (sql-value [value] (to-pg-json value))) - - -; postgres enum type <--> clojure namespaces keywords - -; https://raw.githubusercontent.com/qutebrowser/qutebrowser/master/doc/img/cheatsheet-big.png -; Handle Inserting of keywords as enums into the db -; Usage: (insert! pg-db :files {:name "my-file.txt", :status :processing-status/pending}) -(defn kw->pgenum - "Convert clj keyword to equivalent PGobject" - [kw] - (let [type (-> (namespace kw) - (s/replace "-" "_")) - value (name kw)] - (doto (PGobject.) - (.setType type) - (.setValue value)))) - -(extend-type clojure.lang.Keyword - jdbc/ISQLValue - (sql-value [kw] - (kw->pgenum kw))) - -; Handle extracting keywords from the db enum type -; Usage: -; (query (:db user/system) ["SELECT * FROM files"]) -; => ({:status :processing-status/pending, :name "my-file.txt"}) -(def +schema-enums+ - "A set of all PostgreSQL enums in schema.sql. Used to convert - enum-values back into Clojure keywords." - #{"status"}) - -(extend-type String - jdbc/IResultSetReadColumn - (result-set-read-column [val rsmeta idx] - (let [type (.getColumnTypeName rsmeta idx)] - (if (contains? +schema-enums+ type) - (keyword (s/replace type "_" "-") val) - val)))) \ No newline at end of file + (jt/sql-timestamp v))) \ No newline at end of file diff --git a/src/clj/cat/routes/home.clj b/src/clj/cat/routes/home.clj index 87bc699..d0d761d 100644 --- a/src/clj/cat/routes/home.clj +++ b/src/clj/cat/routes/home.clj @@ -35,10 +35,6 @@ :title "Wrong request parameters" :message "Please contact your system administrator to fix this issue"})) -(defn map-status-to-value - [relation-requests] - (map (fn [rr] (cond-> rr (:status rr) (assoc :status (name (:status rr))))) relation-requests)) - (defroutes home-routes (GET "/" req (let [users (get-users) @@ -53,10 +49,10 @@ other_users (when user (seq (filter (fn [usr] (not (= (:id usr) (:id user)))) users))) - rel-requests-out (seq (map-status-to-value (db/get-relation-requests-from-user {:from_id (:id user)}))) - rel-requests-in (seq (map-status-to-value (db/get-relation-requests-to-user {:to_id (:id user)})))] - (log/info (str "Session: " (:session req))) - (log/info (str "Relation requests: \n OUTGOING: " rel-requests-out "\n INCOMING: " rel-requests-in)) + rel-requests-out (seq (db/get-relation-requests-from-user {:from_id (:id user)})) + rel-requests-in (seq (db/get-relation-requests-to-user {:to_id (:id user)}))] + ;(log/info (str "Session: " (:session req))) + ;(log/info (str "Relation requests: \n OUTGOING: " rel-requests-out "\n INCOMING: " rel-requests-in)) ;(log/info (str "User relations: " user-relations)) ;(log/info (str "Other Users: " other_users)) (home-page {:relations relations @@ -103,8 +99,8 @@ (contains? body :accept) (do (let [rr (db/get-relation-request rr_id_map)] (db/create-relation! {:from_id (:from_id rr) :to_id (:to_id rr)})) - (db/update-relation-request-status! (assoc rr_id_map :status :status/accepted))) - (contains? body :decline) (db/update-relation-request-status! (assoc rr_id_map :status :status/declined)) + (db/update-relation-request-status! (assoc rr_id_map :status "accepted"))) + (contains? body :decline) (db/update-relation-request-status! (assoc rr_id_map :status "declined")) :else false)] (if success (response/found "/") @@ -117,7 +113,7 @@ (do (db/create-relation-request! {:from_id (get-in req [:session :user :id]) :to_id (:to_id result) - :status :status/open}) + :status "open"}) (response/found "/")) (do (response/bad-request "Incorrect input"))))) diff --git a/src/clj/cat/routes/oauth.clj b/src/clj/cat/routes/oauth.clj index 07ec5b5..9d35a4e 100644 --- a/src/clj/cat/routes/oauth.clj +++ b/src/clj/cat/routes/oauth.clj @@ -7,7 +7,7 @@ [cat.moauth :as mo] [cat.db.core :refer [*db*] :as db])) -(def admins #{31 ;flynn +(def admins #{1 ;flynn }) (defn set-user! [user session redirect-url]