Skip to content

Commit

Permalink
impl relation rest endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
lgessler committed Apr 30, 2024
1 parent 5d8f283 commit e2658e6
Show file tree
Hide file tree
Showing 8 changed files with 161 additions and 21 deletions.
5 changes: 4 additions & 1 deletion src/main/glam/models/document.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@
{:token-layer/tokens [:token/id :token/begin :token/end :token/text]}
{:token-layer/span-layers
[:span-layer/id
{:span-layer/spans [:span/id :span/value :span/tokens]}]}]}]}]}
{:span-layer/spans [:span/id :span/value :span/tokens]}
{:span-layer/relation-layers
[:relation-layer/id
{:relation-layer/relations [:relation/id :relation/value :relation/source :relation/target]}]}]}]}]}]}
(doc/get-with-layer-data-for-pathom node id)))

#?(:clj
Expand Down
54 changes: 48 additions & 6 deletions src/main/glam/models/relation.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
(r/get node id)))

#?(:clj
(pc/defmutation save-relation [{:keys [node] :as env} {:relation/keys [id value source target] :as relation}]
(pc/defmutation set-value [{:keys [node] :as env} {:relation/keys [id value] :as relation}]
{::pc/transform (ma/writeable-required :relation/id)}
(cond
(nil? (r/get node id))
Expand All @@ -26,19 +26,61 @@
(not (string? value))
(server-error "Value must be a string.")

(not (ma/ident-locked? env [:relation/id id]))
(server-error (ma/lock-holder-error-msg env [:relation/id id]))

:else
(if-let [result (r/merge node id {:relation/value value})]
(server-message (str "Successfully set relation value to " value))
(server-error (str "Failed to modify relation " id))))))

#?(:clj
(pc/defmutation set-source [{:keys [node] :as env} {:relation/keys [id source] :as relation}]
{::pc/transform (ma/writeable-required :relation/id)}
(cond
(nil? (r/get node id))
(server-error (str "Relation with id " id " does not exist."))

(not (:span/id (s/get node source)))
(server-error "Source span does not exist")

(not (ma/ident-locked? env [:relation/id id]))
(server-error (ma/lock-holder-error-msg env [:relation/id id]))

:else
(if-let [result (r/merge node id {:relation/source source})]
(server-message (str "Successfully set relation source to " source))
(server-error (str "Failed to modify relation " id))))))

#?(:clj
(pc/defmutation set-target [{:keys [node] :as env} {:relation/keys [id target] :as relation}]
{::pc/transform (ma/writeable-required :relation/id)}
(cond
(nil? (r/get node id))
(server-error (str "Relation with id " id " does not exist."))

(not (:span/id (s/get node target)))
(server-error "Target span does not exist")
(server-error "Source span does not exist")

(not (ma/ident-locked? env [:relation/id id]))
(server-error (ma/lock-holder-error-msg env [:relation/id id]))

:else
(if-let [result (r/merge node id {:relation/value value})]
(server-message "Successfully saved relation")
(server-error (str "Failed to save relation " id))))))
(if-let [result (r/merge node id {:relation/target target})]
(server-message (str "Successfully set relation target to " target))
(server-error (str "Failed to modify relation " id))))))

#?(:clj
(pc/defmutation delete-relation [{:keys [node] :as env} {:relation/keys [id] :as relation}]
{::pc/transform (ma/writeable-required :relation/id)}
(cond
(nil? (:relation/id (gxe/entity node id)))
(server-error 404 (str "Relation does not exist with ID " id))

:else
(if-let [result (s/delete node id)]
(server-message (str "Successfully deleted relation " id))
(server-error 500 (str "Failed to delete relation " id))))))

#?(:clj
(pc/defmutation create-relation
Expand Down Expand Up @@ -71,4 +113,4 @@

;; admin --------------------------------------------------------------------------------
#?(:clj
(def relation-resolvers [get-relation save-relation create-relation]))
(def relation-resolvers [get-relation set-value set-source set-target delete-relation create-relation]))
7 changes: 1 addition & 6 deletions src/main/glam/models/relation_layer.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,6 @@
::pc/transform (ma/readable-required :relation-layer/id)}
(rl/get node id)))

#?(:clj
(pc/defresolver get-relations [{:keys [node] :as env} {:relation-layer/keys [id]}]
{::pc/input #{:relation-layer/id}
::pc/output [{:relation-layer/relations [:relation/id :relation/value :relation/layer :relation/source :relation/target]}]}))

;; admin --------------------------------------------------------------------------------
;;
#?(:clj
Expand Down Expand Up @@ -107,5 +102,5 @@
(server-message (str "Relation layer " name " shifted " (if up? "up" "down") ".")))))))

#?(:clj
(def relation-layer-resolvers [get-relation-layer get-relations create-relation-layer save-relation-layer
(def relation-layer-resolvers [get-relation-layer create-relation-layer save-relation-layer
delete-relation-layer shift-relation-layer]))
4 changes: 3 additions & 1 deletion src/main/glam/server/rest_api/core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
[glam.server.rest-api.util :refer [postprocess-middleware]]
[glam.server.rest-api.session :refer [session-routes]]
[glam.server.rest-api.user :refer [user-routes user-admin-routes]]
[glam.server.rest-api.relation :refer [relation-routes]]
[glam.server.rest-api.span :refer [span-routes]]
[glam.server.rest-api.token :refer [token-routes]]
[glam.server.rest-api.text :refer [text-routes]]
Expand Down Expand Up @@ -108,7 +109,8 @@
["/body"
text-routes
token-routes
span-routes]]
span-routes
relation-routes]]
["/admin"
{:swagger {:tags ["admin"]}}
user-admin-routes
Expand Down
80 changes: 80 additions & 0 deletions src/main/glam/server/rest_api/relation.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
(ns glam.server.rest-api.relation
(:require [glam.server.id-counter :refer [id?]]
[glam.models.relation :as r]
[glam.server.rest-api.util :as util]
[malli.experimental.lite :as ml]))

(defn create-relation [{{{:keys [value layer source target]} :body} :parameters parser :pathom-parser :as req}]
(let [result (parser req [(list `r/create-relation
{:relation/layer layer
:relation/value value
:relation/source source
:relation/target target})])
data (get result `r/create-relation)]
(if (:server/error? data)
{:status (:server/code data)
:body data}
{:status 200
:body (util/get-created-id data)})))

(defn get-relation [{{{:keys [id]} :path} :parameters parser :pathom-parser :as req}]
(let [result (parser req [{[:relation/id id]
[:relation/id :relation/layer :relation/value :relation/source :relation/target]}])
data (get result [:relation/id id])]
(if (util/failed-get? data)
{:status 404
:body {:error true :message "Relation does not exist."}}
{:status 200
:body data})))

(defn delete-relation [{{{:keys [id]} :path} :parameters parser :pathom-parser :as req}]
(let [result (parser req [(list `r/delete-relation {:relation/id id})])
data (get result `r/delete-relation)]
{:status (:server/code data)
:body data}))

(defn patch-relation [{{{:keys [id]} :path
{:keys [action value source target]} :body} :parameters
parser :pathom-parser
:as req}]
(let [action-symbol ({"setValue" `r/set-value
"setSource" `r/set-source
"setTarget" `r/set-target}
action)
action-params ({"setValue" {:relation/value value}
"setSource" {:relation/source source}
"setTarget" {:relation/target target}}
action)]
(if (nil? action-symbol)
{:status 400
:body {:error true :message (str "Unknown action: `" action "`")}}
(let [result (parser req [(list action-symbol (merge {:relation/id id} action-params))])
data (get result action-symbol)]
{:status (:server/code data)
:body data}))))

(def relation-routes
["/relation"
[""
{:post {:parameters {:body {:value any?
:layer id?
:source id?
:target id?}}
:description "Creates a new relation. ID is given in the response under \"id\"."
:handler create-relation}}]

["/:id"
{:get {:parameters {:path {:id id?}}
:handler get-relation}
:delete {:parameters {:path {:id id?}}
:handler delete-relation}
:patch
{:parameters {:path {:id id?}
:body {:action [:enum "setValue" "setTarget" "setSource"]
:value (ml/optional any?)
:source (ml/optional id?)
:target (ml/optional id?)}}
:description "setValue: sets the relation's `value` to body param `value`.
setSource: sets the relation's `source` to body param `source`.
setTarget: sets the relation's `target` to body param `target`."
:handler patch-relation}}]])
25 changes: 23 additions & 2 deletions src/main/glam/xtdb/document.clj
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,12 @@
:token-layer/span-layers (mapv #(get-doc-info node doc-id id [:span-layer/id %]) sl-ids)}))

(defmethod get-doc-info :span-layer/id [node doc-id parent-id [key id]]
(let [spans (->> (xt/q (xt/db node)
(let [rl-ids (map first (xt/q (xt/db node)
'{:find [?rl]
:where [[?sl :span-layer/relation-layers ?rl]]
:in [?sl]}
id))
spans (->> (xt/q (xt/db node)
'{:find [(pull ?s [:span/id :span/value :span/tokens])]
:where [[?s :span/tokens ?tok]
[?s :span/layer ?sl]
Expand All @@ -87,7 +92,23 @@
[parent-id doc-id id])
(mapv (fn [[id]] {:span/id id})))]
{:span-layer/id id
:span-layer/spans spans}))
:span-layer/spans spans
:span-layer/relation-layers (mapv #(get-doc-info node doc-id id [:relation-layer/id %]) rl-ids)}))

(defmethod get-doc-info :relation-layer/id [node doc-id parent-id [key id]]
(let [relations (->> (xt/q (xt/db node)
'{:find [(pull ?r [:relation/id :relation/value :relation/source :relation/target])]
:where [[?r :relation/source ?s]
[?r :relation/layer ?rl]
[?s :span/layer ?sl]
[?s :span/tokens ?tok]
[?tok :token/text ?txt]
[?txt :text/document ?doc]]
:in [[?sl ?doc ?rl]]}
[parent-id doc-id id])
(mapv (fn [[id]] {:relation/id id})))]
{:relation-layer/id id
:relation-layer/relations relations}))

(defn get-with-layer-data-for-pathom
[node id]
Expand Down
4 changes: 1 addition & 3 deletions src/main/glam/xtdb/relation.clj
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
:relation/target
:relation/value])

(def snapshot-attrs [:relation/id :relation/value :relation/source :relation/target])

(defn xt->pathom [doc]
(when doc
(-> doc
Expand All @@ -36,7 +34,7 @@

;; Mutations --------------------------------------------------------------------------------
(defn merge [node eid m]
(gxe/merge node eid (select-keys m [:relation/value])))
(gxe/merge node eid (select-keys m [:relation/value :relation/source :relation/target])))

(gxe/deftx delete [node eid]
[(gxe/delete* eid)])
3 changes: 1 addition & 2 deletions src/main/glam/xtdb/span.clj
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@
(defn xt->pathom [doc]
(when doc
(-> doc
(update :span/layer gxc/identize :span-layer/id)
(update :span/tokens gxc/identize :token/id))))
(update :span/layer gxc/identize :span-layer/id))))

(defn create* [{:span/keys [id] :as attrs}]
(gxe/put* (gxc/create-record "span" id attrs attr-keys)))
Expand Down

0 comments on commit e2658e6

Please sign in to comment.