diff --git a/project.clj b/project.clj
index 89f3beb..86181f2 100644
--- a/project.clj
+++ b/project.clj
@@ -8,7 +8,8 @@
[gorillalabs/neo4j-clj "1.1.0"]
[hiccup "1.0.5"]
[buddy/buddy-hashers "1.3.0"
- :exclusions [commons-codec]]]
+ :exclusions [commons-codec]]
+ [clj-time "0.14.4"]]
:plugins [[lein-ring "0.9.7"]]
:ring {:handler wanijo.handler/app}
:profiles {:dev {:dependencies
diff --git a/src/wanijo/attribute/domain.clj b/src/wanijo/attribute/domain.clj
new file mode 100644
index 0000000..af06d62
--- /dev/null
+++ b/src/wanijo/attribute/domain.clj
@@ -0,0 +1,17 @@
+(ns wanijo.attribute.domain
+ (:require [clojure.spec.alpha :as spec]
+ [wanijo.framework.neo4j :as neo4j]))
+
+(neo4j/defquery
+ findy-by-schema
+ "MATCH (a:attribute)-->(s:schema)
+ WHERE s.uuid = {uuid}
+ RETURN a
+ ORDER BY a.name")
+
+(defn find-by-schema! [schema-uuid]
+ (->>
+ (neo4j/exec-query!
+ findy-by-schema
+ {:uuid schema-uuid})
+ (map :a)))
diff --git a/src/wanijo/framework/auth.clj b/src/wanijo/framework/auth.clj
index abd587f..a70d679 100644
--- a/src/wanijo/framework/auth.clj
+++ b/src/wanijo/framework/auth.clj
@@ -19,7 +19,7 @@
(-> (redirect "/login")
(assoc :flash :invalid-credentials)))))
-(defn login [req]
+(defn login! [req]
(view/layout!
:content
[[:h1 "Kama ken"]
@@ -37,7 +37,7 @@
(anti-forgery-field))]))
(defroutes routes
- (GET "/login" [] login)
+ (GET "/login" [] login!)
(POST "/login-check" [] login-check!)
(GET "/logout" [] (-> (redirect "/login")
(assoc :session nil))))
diff --git a/src/wanijo/framework/neo4j.clj b/src/wanijo/framework/neo4j.clj
index bfcbe49..6c62caa 100644
--- a/src/wanijo/framework/neo4j.clj
+++ b/src/wanijo/framework/neo4j.clj
@@ -1,6 +1,8 @@
(ns wanijo.framework.neo4j
(:require [neo4j-clj.core :as db]
- [wanijo.framework.devmode :as devmode])
+ [wanijo.framework.devmode :as devmode]
+ [clj-time.format :as time-format]
+ [clj-time.local :as time-local])
(:import (java.util UUID)))
(def conn
@@ -23,10 +25,15 @@
(filter #(> (count %) 0))
(clojure.string/join \newline)))
-(defn exec-query [qry params]
+(defn exec-query! [qry params]
(with-open [session (db/get-session @conn)]
(devmode/send-to-bar
(str (butiful-query qry)
"
---Params---
"
params))
(qry session params)))
+
+(defn now-str []
+ (time-format/unparse
+ (time-format/formatters :basic-date-time)
+ (time-local/local-now)))
diff --git a/src/wanijo/framework/repl.clj b/src/wanijo/framework/repl.clj
index e441f49..cf9461f 100644
--- a/src/wanijo/framework/repl.clj
+++ b/src/wanijo/framework/repl.clj
@@ -11,7 +11,7 @@
SET n.uuid = {uuid}")
(defn create-user! [ident pw]
- (neo4j/exec-query
+ (neo4j/exec-query!
create-user
{:ident ident
:pw (hashers/derive pw)
diff --git a/src/wanijo/framework/time.clj b/src/wanijo/framework/time.clj
new file mode 100644
index 0000000..b9f0fa8
--- /dev/null
+++ b/src/wanijo/framework/time.clj
@@ -0,0 +1,2 @@
+(ns wanijo.framework.time
+ (:require [clj-time.core :as t]))
diff --git a/src/wanijo/framework/view.clj b/src/wanijo/framework/view.clj
index d7eb809..c17d6a0 100644
--- a/src/wanijo/framework/view.clj
+++ b/src/wanijo/framework/view.clj
@@ -36,7 +36,7 @@
(when authed?
[:section.header-content
(btnlink "/schema" "Jaki ijo" "header-content__link")
- (btnlink "/logout" "Lape" "header-content__link")])]
+ (btnlink "/logout" "Lape!" "header-content__link")])]
[:nav (when authed? "nav")]
(vec (concat [:main] content))
[:aside (when authed? "aside")]
diff --git a/src/wanijo/schema/domain.clj b/src/wanijo/schema/domain.clj
index b442b0d..332c468 100644
--- a/src/wanijo/schema/domain.clj
+++ b/src/wanijo/schema/domain.clj
@@ -6,10 +6,8 @@
(spec/and string? not-empty))
(spec/def ::created-at
- (spec/or :int (spec/and int?
- #(> % 20000101000000))
- :str (spec/and string?
- #(re-matches #"\d{4}\d{2}\d{2}\d{2}\d{2}\d{2}" %))))
+ (spec/and string?
+ #(re-matches #"\d{4}\d{2}\d{2}T\d{2}\d{2}\d{2}\.\d{3}Z" %)))
(neo4j/defquery
all-created-by
@@ -19,10 +17,11 @@
ORDER BY s.name")
(defn all-created-by! [user-uuid]
- (map :s
- (neo4j/exec-query
- all-created-by
- {:uuid user-uuid})))
+ (->>
+ (neo4j/exec-query!
+ all-created-by
+ {:uuid user-uuid})
+ (map :s)))
(neo4j/defquery
create-new
@@ -31,28 +30,63 @@
CREATE (s:schema)-[:created_by]->(u)
SET s.name = {name}
SET s.uuid = {s_uuid}
+ SET s.created_at = {created_at}
RETURN s")
(defn create-new! [name user-uuid]
(->>
- (neo4j/exec-query
+ (neo4j/exec-query!
create-new
{:u_uuid user-uuid
:name name
- :s_uuid (neo4j/uuid)})
+ :s_uuid (neo4j/uuid)
+ :created_at (neo4j/now-str)})
first
:uuid))
(neo4j/defquery
- find-by-id!
+ find-by-uuid
"MATCH (s:schema)
WHERE s.uuid = {uuid}
RETURN s")
(defn find-by-uuid! [uuid]
(->>
- (neo4j/exec-query
- find-by-id!
+ (neo4j/exec-query!
+ find-by-uuid
{:uuid uuid})
first
:s))
+
+(neo4j/defquery
+ schema-creator
+ "MATCH (s:schema)-->(u:user)
+ WHERE s.uuid = {uuid}
+ RETURN u.uuid as uuid")
+
+(defn find-schema-creator! [uuid]
+ (->>
+ (neo4j/exec-query!
+ schema-creator
+ {:uuid uuid})
+ first
+ :uuid))
+
+(defn can-user-modify? [schema-uuid user-uuid]
+ (let [creator (find-schema-creator! schema-uuid)]
+ (= creator user-uuid)))
+
+(neo4j/defquery
+ delete
+ "MATCH (s:schema)
+ WHERE s.uuid = {uuid}
+ OPTIONAL MATCH (s)--(a:attribute)
+ DELETE a
+ WITH s
+ MATCH (s)-[c]-()
+ DELETE c, s")
+
+(defn delete! [uuid]
+ (neo4j/exec-query!
+ delete
+ {:uuid uuid}))
diff --git a/src/wanijo/schema/routes.clj b/src/wanijo/schema/routes.clj
index 20fd9c6..decb183 100644
--- a/src/wanijo/schema/routes.clj
+++ b/src/wanijo/schema/routes.clj
@@ -1,10 +1,11 @@
(ns wanijo.schema.routes
- (:require [compojure.core :refer [defroutes GET POST]]
+ (:require [compojure.core :refer [defroutes GET POST DELETE]]
[ring.util.response :as resp]
[wanijo.framework.view :as view]
[wanijo.framework.form :as form]
[wanijo.schema.domain :as domain]
- [wanijo.schema.view :as view-schema]))
+ [wanijo.schema.view :as view-schema]
+ [wanijo.attribute.domain :as attr-domain]))
(defn new! [req]
(if (form/valid? view-schema/new-form req)
@@ -16,12 +17,20 @@
(view-schema/overview! req)))
(defn show-schema! [uuid session]
- (println uuid session)
(view-schema/show-schema!
(domain/find-by-uuid! uuid)
+ (attr-domain/find-by-schema! uuid)
session))
+(defn delete-schema! [uuid session]
+ (if (domain/can-user-modify? uuid (:uuid session))
+ (do
+ (domain/delete! uuid)
+ (resp/redirect "/schema"))
+ {:status 403}))
+
(defroutes routes
(GET "/schema" [] view-schema/overview!)
(GET "/schema/:uuid" [uuid :as req] (show-schema! uuid (:session req)))
- (POST "/schema/new" [] new!))
+ (POST "/schema/new" [] new!)
+ (DELETE "/schema/:uuid/delete" [uuid :as req] (delete-schema! uuid (:session req))))
diff --git a/src/wanijo/schema/view.clj b/src/wanijo/schema/view.clj
index 3a518c2..cacb046 100644
--- a/src/wanijo/schema/view.clj
+++ b/src/wanijo/schema/view.clj
@@ -8,7 +8,7 @@
(def new-form
{:fields {:schema-name {:label "Nimi"
:required true
- :spec :wanijo.domain.schema/name}}})
+ :spec ::domain/name}}})
(defn overview! [req]
(let [session (:session req)
@@ -37,8 +37,19 @@
(hform/submit-button "Pali")
(anti-forgery-field))])))
-(defn show-schema! [schema session]
+(defn show-schema! [schema attrs session]
(view/layout!
:session session
:content
- [[:h1 "Jaki ijo " (:name schema)]]))
+ [[:h1 "Jaki ijo " (:name schema)]
+ (hform/form-to
+ [:post "/schema/edit"])
+ [:h2 "Lili wan e jaki ijo"]
+ [:ul
+ (for [attr attrs]
+ [:li (:name attr)])]
+ [:h2 "Mute pali"]
+ (hform/form-to
+ [:delete (str "/schema/" (:uuid schema) "/delete")]
+ (anti-forgery-field)
+ (hform/submit-button "Pakala!"))]))
diff --git a/src/wanijo/user/domain.clj b/src/wanijo/user/domain.clj
index ac8c543..0572fdd 100644
--- a/src/wanijo/user/domain.clj
+++ b/src/wanijo/user/domain.clj
@@ -9,7 +9,7 @@
(defn find! [ident]
(->>
- (neo4j/exec-query
+ (neo4j/exec-query!
find-user
{:ident ident})
first