Josha von Gizycki 5 years ago
commit 42ec83d2e6

@ -9,16 +9,28 @@
WHERE s.uuid = {uuid}
OPTIONAL MATCH
(i)-[:tagged_with]->(t:tag)
RETURN i, t")
OPTIONAL MATCH
(i)<-[:of]-(p:property),
(p)-[:of]->(a:attribute)
RETURN i, t, p, a")
(defn flatten-grouped-rows [instance grouped-rows]
{:post [(spec/assert ::domain-instance/instance-with-tags-and-props %)]}
(assoc instance
:tags (->> grouped-rows
(map :t)
(filter some?)
distinct)
:properties (->> grouped-rows
(filter #(some? (:p %)))
(map #(assoc (:p %)
:attribute (:a %)))
distinct)))
(defn find-by-schema! [schema-uuid]
{:post [(spec/assert ::domain-instance/instances-with-tags %)]}
{:post [(spec/assert ::domain-instance/instances-with-tags-and-props %)]}
(->> (neo4j/exec-query! findy-by-schema
{:uuid schema-uuid})
(group-by :i)
(map #(assoc (key %)
:tags (->> (val %)
(map :t)
(filter some?))))
(map #(flatten-grouped-rows (key %) (val %)))
(sort-by :name)))
(neo4j/defquery create-instance

@ -24,9 +24,12 @@
(spec/def ::contains-schema
(spec/keys :req-un [::db-schema/schema]))
(spec/def ::instances-with-tags
(spec/coll-of (spec/merge ::instance
(spec/keys :req-un [::tags]))))
(spec/def ::instance-with-tags-and-props
(spec/merge ::instance
(spec/keys :req-un [::tags
::properties])))
(spec/def ::instances-with-tags-and-props
(spec/coll-of ::instance-with-tags-and-props))
(spec/def ::instance-with-schema
(spec/merge ::instance ::contains-schema))

@ -3,22 +3,24 @@
GET POST DELETE]]
[ring.util.response :as resp]
[formulare.core :as form]
[wanijo.instance
[view :as view]
[db :as domain]
[forms :as forms-inst]]
[wanijo.schema
[db :as domain-schema]
[middleware :as middleware-schema]]
[wanijo.instance.view.edit :refer [edit]]
[wanijo.instance.view.instances :refer [instances]]
[wanijo.instance.view.show :refer [show]]
[wanijo.instance.view.link-selection :refer [link-selection]]
[wanijo.instance.view.starred :refer [starred]]
[wanijo.instance.db :as domain]
[wanijo.instance.forms :as forms-inst]
[wanijo.schema.db :as domain-schema]
[wanijo.schema.middleware :as middleware-schema]
[wanijo.link.db :as domain-link]
[wanijo.infrastructure.routing :refer [register! path]]
[wanijo.attribute.db :as db-attr]))
(defn list! [schema-uuid req]
(view/list! (domain-schema/find-by-uuid! schema-uuid)
(domain/find-by-schema! schema-uuid)
(forms-inst/with-attributes (db-attr/required! schema-uuid))
req))
(instances (domain-schema/find-by-uuid! schema-uuid)
(domain/find-by-schema! schema-uuid)
(forms-inst/with-attributes (db-attr/required! schema-uuid))
req))
(defn new! [req]
(let [schema-uuid (get-in req [:params :schema-uuid])
@ -46,9 +48,9 @@
:starred
(domain/is-starred! uuid
user-uuid))]
(view/show! instance
(domain-schema/accessible-schemas! user-uuid)
req)))
(show instance
(domain-schema/accessible-schemas! user-uuid)
req)))
(defn form! [attrs]
(forms-inst/with-attributes attrs))
@ -57,11 +59,11 @@
(let [instance (instance! uuid)
attrs (db-attr/find-by-instance! uuid)
user-uuid (get-in req [:session :uuid])]
(view/edit! instance
(form! attrs)
(forms-inst/instance->form-data instance)
(domain-schema/accessible-schemas! user-uuid)
req)))
(edit instance
(form! attrs)
(forms-inst/instance->form-data instance)
(domain-schema/accessible-schemas! user-uuid)
req)))
(defn edit! [uuid req]
(let [attrs (db-attr/find-by-instance! uuid)
@ -74,7 +76,7 @@
(resp/redirect (path :instance-show instance)))
(show! uuid req))))
(defn delete! [uuid req]
(defn delete! [uuid]
(let [schema (domain-schema/find-by-instance! uuid)]
(domain/delete! uuid)
(resp/redirect (path :instance-list
@ -82,13 +84,13 @@
(defn link-form! [schema-uuid]
(forms-inst/link-form
(domain/find-by-schema! schema-uuid)))
(domain/find-by-schema! schema-uuid)))
(defn link-selection! [uuid schema-uuid req]
(view/link-selection (instance! uuid)
(domain-schema/find-by-uuid! schema-uuid)
(link-form! schema-uuid)
req))
(link-selection (instance! uuid)
(domain-schema/find-by-uuid! schema-uuid)
(link-form! schema-uuid)
req))
(defn create-link! [uuid schema-uuid req]
(let [form (link-form! schema-uuid)]
@ -101,7 +103,7 @@
(resp/redirect (path :instance-edit-form {:uuid uuid})))
(link-selection! uuid schema-uuid req))))
(defn delete-link! [uuid link-uuid req]
(defn delete-link! [uuid link-uuid]
(domain-link/delete! link-uuid)
(resp/redirect (path :instance-edit-form {:uuid uuid})))
@ -116,19 +118,19 @@
(resp/redirect (path :instance-show {:uuid uuid})))
(defn list-starred! [req]
(view/list-starred
(domain/starred-by-user! (-> req :session :uuid))
req))
(starred
(domain/starred-by-user! (-> req :session :uuid))
req))
(defroutes routes
(wrap-routes
(GET (register! :instance-list "/instance/list/:schema-uuid")
[schema-uuid :as req]
(list! schema-uuid req))
(middleware-schema/wrap-allowed-to-read
#(get-in % [:params :schema-uuid])))
(GET (register! :instance-list "/instance/list/:schema-uuid")
[schema-uuid :as req]
(list! schema-uuid req))
(middleware-schema/wrap-allowed-to-read
#(get-in % [:params :schema-uuid])))
(POST (register! :instance-new "/instance/new") []
new!)
new!)
(GET (register! :instance-show "/instance/:uuid")
[uuid :as req]
(show! uuid req))
@ -137,10 +139,10 @@
(edit-form! uuid req))
(POST (register! :instance-edit "/instance/:uuid")
[uuid :as req]
(edit! uuid req))
(edit! uuid req))
(DELETE (register! :instance-delete "/instance/:uuid")
[uuid :as req]
(delete! uuid req))
[uuid]
(delete! uuid))
(GET (register! :instance-link-selection
"/instance/:uuid/link/:schema-uuid")
[uuid schema-uuid :as req]
@ -148,19 +150,19 @@
(POST (register! :instance-link-create
"/instance/:uuid/link/:schema-uuid")
[uuid schema-uuid :as req]
(create-link! uuid schema-uuid req))
(create-link! uuid schema-uuid req))
(DELETE (register! :instance-link-delete
"/instance/:uuid/link/:link-uuid")
[uuid link-uuid :as req]
(delete-link! uuid link-uuid req))
[uuid link-uuid]
(delete-link! uuid link-uuid))
(POST (register! :instance-mark-starred
"/instance/:uuid/starred")
[uuid :as req]
(mark-starred! uuid req))
(mark-starred! uuid req))
(DELETE (register! :instance-remove-starred
"/instance/:uuid/starred")
[uuid :as req]
(remove-starred! uuid req))
(remove-starred! uuid req))
(GET (register! :instance-list-starred "/instance/starred/list")
[:as req]
(list-starred! req)))

@ -1,263 +0,0 @@
(ns wanijo.instance.view
(:require [hiccup
[form :as hform]
[core :refer [h]]]
[ring.util.anti-forgery :refer [anti-forgery-field]]
[markdown.core :as md]
[formulare.core :as form]
[wanijo.tag.view :as view-tag]
[wanijo.visualisation.viz :as viz]
[wanijo.infrastructure
[view :as view]
[routing :refer [path]]
[time :refer [prettify-dt]]]))
(defn tags-for-search [{tags :tags}]
[:span.tags-for-search
(reduce #(str %1 ":" (:name %2)) "" tags)])
(defn list! [schema instances new-form req]
(view/layout!
:request req
:content
[[:h1 "All Instances of schema "
[:span.schema-title__name (h (:name schema))]]
[:h1 "New Instance"]
(hform/form-to [:post (path :instance-new)]
(form/render-widgets new-form {} req)
(hform/hidden-field "schema-uuid"
(:uuid schema))
(hform/submit-button "Create!"))
[:table
[:thead
[:tr
[:th "Name"]
[:th "Updated"]
[:th "Created"]]]
[:tbody
(for [instance instances]
[:tr
[:td
[:a {:href (path :instance-show instance)}
(h (:name instance))]
(tags-for-search instance)]
[:td (prettify-dt (:updated_at instance))]
[:td (prettify-dt (:created_at instance))]])]]]))
(defn list-starred [instances req]
(view/layout!
:request req
:content
[[:h1 "Starred instances"]
[:table
[:thead
[:tr
[:th "Name"]
[:th "Starred"]
[:th "Updated"]
[:th "Created"]]]
[:tbody
(for [instance instances]
[:tr
[:td
[:a {:href (path :instance-show instance)}
(h (:name instance))]]
[:td (prettify-dt (:starred_at instance))]
[:td (prettify-dt (:updated_at instance))]
[:td (prettify-dt (:created_at instance))]])]]]))
(defn show! [instance schemas req]
(view/layout!
:request req
:content
[[:h1
(if (:starred instance)
(hform/form-to {:class "inline"}
[:delete (path :instance-mark-starred instance)]
(anti-forgery-field)
(hform/submit-button "★"))
(hform/form-to {:class "inline"}
[:post (path :instance-mark-starred instance)]
(anti-forgery-field)
(hform/submit-button "☆")))
"&nbsp;"
(h (-> instance :schema :name))
"&nbsp;"
[:small (h (:name instance))]]
[:p [:small
[:a {:href (path :instance-list
{:schema-uuid (-> instance :schema :uuid)})}
"Back to List"]
" | "
[:a {:href (path :instance-edit-form instance)}
"Edit Instance"]
" | "
[:a {:href (path :vis-explore {:instance-uuid (:uuid instance)})}
"Explore from here"]]]
(when (seq (:tags instance))
[:section.tags
(view-tag/tag-list (:tags instance))])
(when (seq (:properties instance))
[:section.properties
[:h2 "Properties"]
(for [prop (:properties instance)
:let [attr (:attribute prop)
type (:type attr)
render-fn (case type
"date" #(str (prettify-dt %))
"markdown" md/md-to-html-string
#(str "<p>" % "</p>"))]]
(list [:h3 (h (:name attr))]
[:div {:class (str "instance-content "
"attr-type-" type)}
(render-fn (:value prop))]))])
(when (or (seq (:links-out instance))
(seq (:links-in instance)))
[:section.visualisation
[:h2 "Visualisation"]
[:p (viz/single-instance instance)]])
(when (seq (:links-out instance))
[:section.links-out
[:h2 "Outgoing Links"]
[:table
[:thead
[:tr
[:th "Name"]
[:th "Instance"]
[:th "Schema"]
[:th "Created"]]]
[:tbody
(for [{:keys [link target schema] :as row} (:links-out instance)
:let [name (:name link)
empty (empty? name)
name (if empty [:i "empty"] (h name))]]
[:tr
[:td
name
(tags-for-search row)]
[:td [:a {:href (path :instance-show target)}
(h (:name target))]]
[:td [:a {:href (path :instance-list
{:schema-uuid (:uuid schema)})}
(h (:name schema))]]
[:td (prettify-dt (:created_at link))]])]]])
(when (seq (:links-in instance))
[:section.links-in
[:h2 "Incoming Links"]
[:table
[:thead
[:tr
[:th "Name"]
[:th "Instance"]
[:th "Schema"]
[:th "Created"]]]
[:tbody
(for [{:keys [link source schema] :as row} (:links-in instance)
:let [name (:name link)
empty (empty? name)
name (if empty [:i "empty"] (h name))]]
[:tr
[:td
name
(tags-for-search row)]
[:td [:a {:href (path :instance-show source)}
(h (:name source))]]
[:td [:a {:href (path :instance-list
{:schema-uuid (:uuid schema)})}
(h (:name schema))]]
[:td (prettify-dt (:created_at link))]])]]])
[:section.quick-edits
[:h2 "Quick edits"]
[:section.link-instance
[:h3 "Link Instance with Instance of Schema..."]
[:ul
(for [schema schemas]
[:li
[:a {:href (path :instance-link-selection
{:uuid (:uuid instance)
:schema-uuid (:uuid schema)})}
(h (:name schema))]])]]
[:section.tag-instance
[:h3 "Add or create Tags"]
(view-tag/new-tag-form instance)]]]))
(defn edit! [instance form form-data schemas req]
(view/layout!
:request req
:content
[[:h1
(h (-> instance :schema :name))
"&nbsp;"
[:small (h (:name instance))]]
[:p [:small
[:a {:href (path :instance-list
{:schema-uuid (-> instance :schema :uuid)})}
"Back to List"]
" | "
[:a {:href (path :instance-show instance)}
"Back to Instance"]]]
[:section.edit-instance
[:h2 "Edit Instance"]
(hform/form-to [:post (path :instance-edit instance)]
(form/render-widgets form form-data req)
(hform/submit-button "Edit!"))
(hform/form-to [:delete (path :instance-delete instance)]
(anti-forgery-field)
(view/delete-btn))]
(when (seq (:links-out instance))
[:section.links-out
[:h2 "Outgoing Links"]
[:table
[:thead
[:tr
[:th "Name"]
[:th "Instance"]
[:th "Schema"]
[:th "Created"]
[:th]]]
[:tbody
(for [{:keys [link target schema]} (:links-out instance)
:let [name (:name link)
empty (empty? name)
name (if empty [:i "empty"] (h name))]]
[:tr
[:td name]
[:td [:a {:href (path :instance-show target)}
(h (:name target))]]
[:td [:a {:href (path :instance-list
{:schema-uuid (:uuid schema)})}
(h (:name schema))]]
[:td (prettify-dt (:created_at link))]
[:td (hform/form-to [:delete (path :instance-link-delete
{:uuid (:uuid instance)
:link-uuid (:uuid link)})]
(anti-forgery-field)
(view/delete-btn))]])]]])
(when (seq (:tags instance))
[:section.tags
[:h2 "Tags"]
(view-tag/tag-table instance)])
[:section.link-instance
[:h2 "Link Instance with Instance of Schema..."]
[:ul
(for [schema schemas]
[:li
[:a {:href (path :instance-link-selection
{:uuid (:uuid instance)
:schema-uuid (:uuid schema)})}
(h (:name schema))]])]]]))
(defn link-selection [instance schema form req]
(view/layout!
:request req
:content
[[:h1
[:small "Link " (-> instance :schema :name) " "]
(h (:name instance))
[:small " with "]
(h (:name schema))]
(hform/form-to [:post (path :instance-link-create
{:uuid (:uuid instance)
:schema-uuid (:uuid schema)})]
(form/render-widgets form nil req)
(hform/submit-button "Link!"))]))

@ -0,0 +1,75 @@
(ns wanijo.instance.view.edit
(:require [hiccup.form :as hform]
[hiccup.core :refer [h]]
[ring.util.anti-forgery :refer [anti-forgery-field]]
[wanijo.infrastructure.view :as view]
[wanijo.infrastructure.routing :refer [path]]
[wanijo.infrastructure.time :refer [prettify-dt]]
[wanijo.tag.view :as view-tag]
[formulare.core :as form]))
(defn edit [instance form form-data schemas req]
(view/layout!
:request req
:content
[[:h1
(h (-> instance :schema :name))
"&nbsp;"
[:small (h (:name instance))]]
[:p [:small
[:a {:href (path :instance-list
{:schema-uuid (-> instance :schema :uuid)})}
"Back to List"]
" | "
[:a {:href (path :instance-show instance)}
"Back to Instance"]]]
[:section.edit-instance
[:h2 "Edit Instance"]
(hform/form-to [:post (path :instance-edit instance)]
(form/render-widgets form form-data req)
(hform/submit-button "Edit!"))
(hform/form-to [:delete (path :instance-delete instance)]
(anti-forgery-field)
(view/delete-btn))]
(when (seq (:links-out instance))
[:section.links-out
[:h2 "Outgoing Links"]
[:table
[:thead
[:tr
[:th "Name"]
[:th "Instance"]
[:th "Schema"]
[:th "Created"]
[:th]]]
[:tbody
(for [{:keys [link target schema]} (:links-out instance)
:let [name (:name link)
empty (empty? name)
name (if empty [:i "empty"] (h name))]]
[:tr
[:td name]
[:td [:a {:href (path :instance-show target)}
(h (:name target))]]
[:td [:a {:href (path :instance-list
{:schema-uuid (:uuid schema)})}
(h (:name schema))]]
[:td (prettify-dt (:created_at link))]
[:td (hform/form-to [:delete (path :instance-link-delete
{:uuid (:uuid instance)
:link-uuid (:uuid link)})]
(anti-forgery-field)
(view/delete-btn))]])]]])
(when (seq (:tags instance))
[:section.tags
[:h2 "Tags"]
(view-tag/tag-table instance)])
[:section.link-instance
[:h2 "Link Instance with Instance of Schema..."]
[:ul
(for [schema schemas]
[:li
[:a {:href (path :instance-link-selection
{:uuid (:uuid instance)
:schema-uuid (:uuid schema)})}
(h (:name schema))]])]]]))

@ -0,0 +1,46 @@
(ns wanijo.instance.view.instances
(:require [hiccup.form :as hform]
[hiccup.core :refer [h]]
[formulare.core :as form]
[wanijo.instance.view.view :as view-instance]
[wanijo.infrastructure.view :as view]
[wanijo.infrastructure.routing :refer [path]]
[wanijo.infrastructure.time :refer [prettify-dt]]))
(defn instances [schema instances new-form req]
(view/layout!
:request req
:content
[[:h1 "All Instances of schema "
[:span.schema-title__name (h (:name schema))]]
[:h1 "New Instance"]
(hform/form-to [:post (path :instance-new)]
(form/render-widgets new-form {} req)
(hform/hidden-field "schema-uuid"
(:uuid schema))
(hform/submit-button "Create!"))
[:table
[:thead
[:tr
[:th "Name"]
(map (fn [attr] [:th (h (:name attr))])
(:req-attrs schema))
[:th "Updated"]
[:th "Created"]]]
[:tbody
(for [instance instances]
[:tr
[:td
[:a {:href (path :instance-show instance)}
(h (:name instance))]
(view-instance/tags-for-search instance)]
(map (fn [attr]
[:td (->> (:properties instance)
(filter #(= (:uuid attr)
(-> % :attribute :uuid)))
first
:value
h)])
(:req-attrs schema))
[:td (prettify-dt (:updated_at instance))]
[:td (prettify-dt (:created_at instance))]])]]]))

@ -0,0 +1,21 @@
(ns wanijo.instance.view.link-selection
(:require [hiccup.form :as hform]
[hiccup.core :refer [h]]
[wanijo.infrastructure.view :as view]
[wanijo.infrastructure.routing :refer [path]]
[formulare.core :as form]))
(defn link-selection [instance schema form req]
(view/layout!
:request req
:content
[[:h1
[:small "Link " (-> instance :schema :name) " "]
(h (:name instance))
[:small " with "]
(h (:name schema))]
(hform/form-to [:post (path :instance-link-create
{:uuid (:uuid instance)
:schema-uuid (:uuid schema)})]
(form/render-widgets form nil req)
(hform/submit-button "Link!"))]))

@ -0,0 +1,126 @@
(ns wanijo.instance.view.show
(:require [hiccup.form :as hform]
[hiccup.core :refer [h]]
[ring.util.anti-forgery :refer [anti-forgery-field]]
[wanijo.infrastructure.view :as view]
[wanijo.infrastructure.routing :refer [path]]
[wanijo.infrastructure.time :refer [prettify-dt]]
[wanijo.instance.view.view :as view-instance]
[wanijo.tag.view :as view-tag]
[markdown.core :as md]
[wanijo.visualisation.viz :as viz]))
(defn show [instance schemas req]
(view/layout!
:request req
:content
[[:h1
(if (:starred instance)
(hform/form-to {:class "inline"}
[:delete (path :instance-mark-starred instance)]
(anti-forgery-field)
(hform/submit-button "★"))
(hform/form-to {:class "inline"}
[:post (path :instance-mark-starred instance)]
(anti-forgery-field)
(hform/submit-button "☆")))
"&nbsp;"
(h (-> instance :schema :name))
"&nbsp;"
[:small (h (:name instance))]]
[:p [:small
[:a {:href (path :instance-list
{:schema-uuid (-> instance :schema :uuid)})}
"Back to List"]
" | "
[:a {:href (path :instance-edit-form instance)}
"Edit Instance"]
" | "
[:a {:href (path :vis-explore {:instance-uuid (:uuid instance)})}
"Explore from here"]]]
(when (seq (:tags instance))
[:section.tags
(view-tag/tag-list (:tags instance))])
(when (seq (:properties instance))
[:section.properties
[:h2 "Properties"]
(for [prop (:properties instance)
:let [attr (:attribute prop)
type (:type attr)
render-fn (case type
"date" #(str (prettify-dt %))
"markdown" md/md-to-html-string
#(str "<p>" % "</p>"))]]
(list [:h3 (h (:name attr))]
[:div {:class (str "instance-content "
"attr-type-" type)}
(render-fn (:value prop))]))])
(when (or (seq (:links-out instance))
(seq (:links-in instance)))
[:section.visualisation
[:h2 "Visualisation"]
[:p (viz/single-instance instance)]])
(when (seq (:links-out instance))
[:section.links-out
[:h2 "Outgoing Links"]
[:table
[:thead
[:tr
[:th "Name"]
[:th "Instance"]
[:th "Schema"]
[:th "Created"]]]
[:tbody
(for [{:keys [link target schema] :as row} (:links-out instance)
:let [name (:name link)
empty (empty? name)
name (if empty [:i "empty"] (h name))]]
[:tr
[:td
name
(view-instance/tags-for-search row)]
[:td [:a {:href (path :instance-show target)}
(h (:name target))]]
[:td [:a {:href (path :instance-list
{:schema-uuid (:uuid schema)})}
(h (:name schema))]]
[:td (prettify-dt (:created_at link))]])]]])
(when (seq (:links-in instance))
[:section.links-in
[:h2 "Incoming Links"]
[:table
[:thead
[:tr
[:th "Name"]
[:th "Instance"]
[:th "Schema"]
[:th "Created"]]]
[:tbody
(for [{:keys [link source schema] :as row} (:links-in instance)
:let [name (:name link)
empty (empty? name)
name (if empty [:i "empty"] (h name))]]
[:tr
[:td
name
(view-instance/tags-for-search row)]
[:td [:a {:href (path :instance-show source)}
(h (:name source))]]
[:td [:a {:href (path :instance-list
{:schema-uuid (:uuid schema)})}
(h (:name schema))]]
[:td (prettify-dt (:created_at link))]])]]])
[:section.quick-edits
[:h2 "Quick edits"]
[:section.link-instance
[:h3 "Link Instance with Instance of Schema..."]
[:ul
(for [schema schemas]
[:li
[:a {:href (path :instance-link-selection
{:uuid (:uuid instance)
:schema-uuid (:uuid schema)})}
(h (:name schema))]])]]
[:section.tag-instance
[:h3 "Add or create Tags"]
(view-tag/new-tag-form instance)]]]))

@ -0,0 +1,27 @@
(ns wanijo.instance.view.starred
(:require [hiccup.core :refer [h]]
[wanijo.infrastructure.view :as view]
[wanijo.infrastructure.routing :refer [path]]
[wanijo.infrastructure.time :refer [prettify-dt]]))
(defn starred [instances req]
(view/layout!
:request req
:content
[[:h1 "Starred instances"]
[:table
[:thead
[:tr
[:th "Name"]
[:th "Starred"]
[:th "Updated"]
[:th "Created"]]]
[:tbody
(for [instance instances]
[:tr
[:td
[:a {:href (path :instance-show instance)}
(h (:name instance))]]
[:td (prettify-dt (:starred_at instance))]
[:td (prettify-dt (:updated_at instance))]
[:td (prettify-dt (:created_at instance))]])]]]))

@ -0,0 +1,6 @@
(ns wanijo.instance.view.view
(:require [hiccup.core :refer [h]]))
(defn tags-for-search [{tags :tags}]
[:span.tags-for-search
(reduce #(str %1 ":" (h (:name %2))) "" tags)])

@ -1,18 +1,7 @@
(ns wanijo.schema.db
(:require [clojure.spec.alpha :as spec]
[wanijo.specs :as specs]
[wanijo.infrastructure.neo4j :as neo4j]))
(spec/def ::name
(spec/and ::specs/name (complement empty?)))
(spec/def ::assigned-to
(spec/or :public empty?
:assigned (spec/coll-of ::neo4j/uuid)
:assigned-single ::neo4j/uuid))
(spec/def ::schema
(spec/keys ::req-un [::name
::specs/created-at
::neo4j/uuid]))
(:require [wanijo.infrastructure.neo4j :as neo4j]
[wanijo.schema.domain :as domain]
[clojure.spec.alpha :as spec]))
(neo4j/defquery all-created-by
"MATCH (s:schema)-[:created_by]->(u:user)
@ -22,8 +11,8 @@
(defn all-created-by! [user-uuid]
(map :s
(neo4j/exec-query!
all-created-by
{:uuid user-uuid})))
all-created-by
{:uuid user-uuid})))
(neo4j/defquery all
"MATCH (s:schema)
@ -43,38 +32,32 @@
RETURN s")
(defn create-new! [schema-name user-uuid]
(->>
(neo4j/exec-query!
create-new
{:u_uuid user-uuid
:name schema-name
:s_uuid (neo4j/uuid)
:created_at (neo4j/now-str)})
first
:uuid))
(neo4j/exec-query!
create-new
{:u_uuid user-uuid
:name schema-name
:s_uuid (neo4j/uuid)
:created_at (neo4j/now-str)})
first
:uuid))
(neo4j/defquery find-by-uuid
"MATCH (s:schema)
WHERE s.uuid = {uuid}
RETURN s")
OPTIONAL MATCH
(s)<-[:of]-(a:attribute)
WHERE a.required = 1
RETURN s, a
ORDER BY a.name")
(defn find-by-uuid! [uuid]
(->>
(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))
{:post [(spec/assert ::domain/schema-with-req-attrs %)]}
(let [result (neo4j/exec-query!
find-by-uuid
{:uuid uuid})
schema (:s (first result))]
(when schema
(assoc schema
:req-attrs (map :a result)))))
(neo4j/defquery schema-permissions
"MATCH (s:schema {uuid:{schema_uuid}})
@ -86,13 +69,12 @@
-[:permission {type:{type}}]-
(s)) AS is_public")
(defn has-user-permission? [perm-type schema-uuid user-uuid]
(let [permissions (first (neo4j/exec-query! schema-permissions
{:schema_uuid schema-uuid
:user_uuid user-uuid
:type perm-type}))
public? (:is_public permissions)
user? (:user_has_permission permissions)]
(or public? user?)))
(let [perms (first
(neo4j/exec-query! schema-permissions
{:schema_uuid schema-uuid
:user_uuid user-uuid
:type perm-type}))]
(domain/has-user-permission? perms)))
(defn has-user-write-permissions? [schema-uuid user-uuid]
(has-user-permission? "write" schema-uuid user-uuid))
(defn has-user-read-permissions? [schema-uuid user-uuid]
@ -120,8 +102,8 @@
DELETE c, s")
(defn delete! [uuid]
(neo4j/exec-query!
delete
{:uuid uuid}))
delete
{:uuid uuid}))
(neo4j/defquery edit
"MATCH (s:schema)
@ -129,8 +111,8 @@
SET s.name = {name}")
(defn edit! [schema]
(neo4j/exec-query!
edit
schema))
edit
schema))
(neo4j/defquery assigned-users
"MATCH (s:schema)-[p:permission]-(u:user)
@ -139,8 +121,8 @@
ORDER BY u.ident")
(defn assigned-users! [uuid]
(neo4j/exec-query!
assigned-users
{:uuid uuid}))
assigned-users
{:uuid uuid}))
(neo4j/defquery assigned-schemas
"MATCH (s1:schema)-[p:permission]-(s2:schema)
@ -149,8 +131,8 @@
ORDER BY s2.name")
(defn assigned-schemas! [uuid]
(neo4j/exec-query!
assigned-schemas
{:uuid uuid}))
assigned-schemas
{:uuid uuid}))
(defn find-with-assigned-entities! [uuid]
(let [users (reduce #(case (-> %2 :p :type)
@ -160,7 +142,7 @@
{:write []
:read []}
(assigned-users! uuid))
schemas (map #(-> % :s2 :uuid) (assigned-schemas! uuid))]
schemas (map #(-> % :s2 :uuid) (assigned-schemas! uuid))]
(assoc (find-by-uuid! uuid)
:assigned-read-users (:read users)
:assigned-write-users (:write users)
@ -178,13 +160,13 @@
CREATE (s)<-[:permission{type:{permtype}}]-(u)")
(defn assign-users! [uuid users permission]
(neo4j/exec-queries!
[remove-assignments
{:uuid uuid
:permtype permission}]
[create-assignments
{:uuid uuid
:users users
:permtype permission}]))
[remove-assignments
{:uuid uuid
:permtype permission}]
[create-assignments
{:uuid uuid
:users users
:permtype permission}]))
(neo4j/defquery remove-schema-assignments
"MATCH (s1:schema)-[p:permission]-(s2:schema)
@ -197,10 +179,10 @@
CREATE (s1)-[:permission]->(s2)")
(defn assign-schemas! [uuid schemas]
(neo4j/exec-queries!
[remove-schema-assignments
{:uuid uuid}]
[create-schema-assignments
{:uuid uuid :schemas schemas}]))
[remove-schema-assignments
{:uuid uuid}]
[create-schema-assignments
{:uuid uuid :schemas schemas}]))
(neo4j/defquery find-by-instance
"MATCH (i:instance {uuid:{uuid}})-[:of]->(s:schema)

@ -0,0 +1,27 @@
(ns wanijo.schema.domain
(:require [clojure.spec.alpha :as spec]
[wanijo.specs :as specs]
[wanijo.attribute.domain :as domain-attr]
[wanijo.infrastructure.neo4j :as neo4j]))
(spec/def ::name
(spec/and ::specs/name (complement empty?)))
(spec/def ::assigned-to
(spec/or :public empty?
:assigned (spec/coll-of ::neo4j/uuid)
:assigned-single ::neo4j/uuid))
(spec/def ::schema
(spec/keys ::req-un [::name
::specs/created-at
::neo4j/uuid]))
(defn has-user-permission?
[{public? :is_public
user-permission :user_has_permission}]
(or public? user-permission))
(spec/def ::req-attrs
(spec/coll-of ::domain-attr/attribute))
(spec/def ::schema-with-req-attrs
(spec/merge ::schema
:req-un [::req-attrs]))

@ -2,7 +2,6 @@
(:require [compojure.core :refer [defroutes GET POST DELETE] :as comp]
[ring.util.response :as resp]
[formulare.core :as form]
[wanijo.infrastructure.view :as view]
[wanijo.infrastructure.routing :refer [register! path]]
[wanijo.user.db :as domain-user]
[wanijo.schema
@ -21,7 +20,7 @@
(resp/redirect (path :schema-overview)))
(schema-view/overview! req)))
(defn delete-schema! [uuid session]
(defn delete-schema! [uuid]
(domain/delete! uuid)
(resp/redirect (path :schema-overview)))
@ -73,8 +72,8 @@
(POST (register! :schema-assign-schemas "/schema/assign/schemas") []
assign-schemas!)
(DELETE (register! :schema-delete "/schema/:uuid")
[uuid :as req]
(delete-schema! uuid (:session req))))
[uuid]
(delete-schema! uuid)))
(defroutes read-routes
(GET (register! :schema-show "/schema/:uuid")

Loading…
Cancel
Save