Commit a3d56b43 authored by ivan minutillo's avatar ivan minutillo
Browse files

added basic queries for observation layer
parent 1ba4afdd
No preview for this file type
......@@ -7,6 +7,7 @@
[com.walmartlabs/lacinia-pedestal "0.5.0"]
[io.aviso/logging "0.2.0"]
[org.clojure/java.jdbc "0.7.8"]
[honeysql "0.9.1"]
[com.stuartsierra/component "0.3.2"]
[camel-snake-kebab "0.4.0"]
[seancorfield/next.jdbc "1.0.7"]
......
......@@ -30,16 +30,20 @@
:finished {:type Boolean
:description "The process is complete or not. This is irrespective of if the original goal has been met, and indicates that no more will be done."}
; Inverse relationships and queries
:inputs {:type (list :EconomicEvent)}
:outputs {:type (list :EconomicEvent)}
:unplannedEconomicEvents {:type (list :EconomicEvent)}
:committedInputs {:type (list :EconomicEvent)}
:committedOutputs {:type (list :EconomicEvent)}
:inputs {:type (list :EconomicEvent)
:resolve :query/get-inputs}
:outputs {:type (list :EconomicEvent)
:resolve :query/get-outputs}
; :unplannedEconomicEvents {:type (list :EconomicEvent)}
; :committedInputs {:type (list :EconomicEvent)}
; :committedOutputs {:type (list :EconomicEvent)}
}}
:Action {:description "An informal or formal textual identifier for an object. Does not imply uniqueness."
:fields {:id {:type (non-null Int)}
:name {:type (non-null String)}}}
:label {:type String}
:resourceEffect {:type String}
}}
:Unit {:description "Defines a unit of measurement, along with its display symbol."
:fields {:id {:type (non-null Int)}
......@@ -49,7 +53,11 @@
:fields {:id {:type (non-null Int)}
:name {:type String}
:note {:type String}
:type {:type String}}}
:type {:type String}
:economicEvents {:type (list :EconomicEvent)
:resolve :query/get-agent-economic-event}
:inventoriedEconomicResources {:type (list :EconomicResource)
:resolve :query/get-agent-inventoriedEconomicResource}}}
:ResourceSpecification {:description "An informal or formal textual identifier for an object. Does not imply uniqueness."
:fields {:id {:type (non-null Int)}
......@@ -59,13 +67,13 @@
:EconomicResource {:description "References one or more concepts in a common taxonomy or other classification scheme for purposes of categorization or grouping."
:fields {:id {:type (non-null Int)}
:name {:type String}
:track {:type (list :trackResult)}
:accountingQuantityNumericValue {:type Float}
:accountingQuantityUnit {:type Unit}
:onhandQuantityUnit {:type Unit}
:onhandQuantityNumericValue {:type Float}
:unitOfEffort {:type Unit}
:note {:type String}
:owner {:type Agent}
:conformsTo {:type ResourceSpecification}}}
:EconomicEvent {:description "Relates an economic event to a verb, such as consume, produce, work, improve, etc."
......@@ -82,11 +90,7 @@
:effortQuantityNumericValue {:type Float}
:effortQuantityUnit {:type Unit}
:resourceInventoriedAs {:type EconomicResource}
:resourceConformsTo {:type ResourceSpecification}}}
:IncomingValueflows {:description "Relates the whole valueflows starting from a resource"
:fields {:text {:type String}
:type {:type String}}}}
:resourceConformsTo {:type ResourceSpecification}}}}
:queries {; Agent module
:agent {:type :Agent
......@@ -158,13 +162,10 @@
:description "Retrieve all units"
:args {}
:resolve :query/allUnits}}
:mutations
{:createEconomicEvent
{:type :EconomicEvent
:description "Add a new event with the possibility to create or not a new resource"
:args {:event {:type :EconomicEventCreateParams}}
:resolve :mutation/createEconomicEvent}}}
; :mutations
; {:createEconomicEvent
; {:type :EconomicEvent
; :description "Add a new event with the possibility to create or not a new resource"
; :args {:event {:type :EconomicEventCreateParams}}
; :resolve :mutation/createEconomicEvent}}
}
(ns vfprocess.db.queries
(:require [next.jdbc :as jdbc]
[next.jdbc.sql :as sql]
[next.jdbc.optional :as opt]
[next.jdbc.specs :as specs]))
[next.jdbc.sql :refer [insert!]]
[honeysql.helpers :refer :all :as helpers]
[honeysql.core :as sql]
[next.jdbc.optional :as opt]))
(specs/instrument)
(def ds
{:dbtype "sqlite"
:host :none
......@@ -15,49 +15,35 @@
(defn query
([table id]
(jdbc/execute-one! db
[(str "select * from " table " where id = ?" id)]
{:builder-fn opt/as-unqualified-maps}))
(let [query (-> (select :*)
(merge-where [:= :id id])
(from table)
sql/format)]
(jdbc/execute-one! db
query
{:builder-fn opt/as-unqualified-maps})))
([table]
(jdbc/execute! db
[(str "select * from " table)]
{:builder-fn opt/as-unqualified-maps})))
; Query Process by id or returns all the processes
(defn query-process
([id]
(let [process (jdbc/execute-one! db
["select * from Process where id = ?" id]
{:builder-fn opt/as-unqualified-maps})
inputs (jdbc/execute! db
["select * from EconomicEvent where inputOf = ?" id]
{:builder-fn opt/as-unqualified-maps})
(let [query (-> (select :*)
(from table)
sql/format)]
(jdbc/execute! db
query
{:builder-fn opt/as-unqualified-maps}))))
outputs (jdbc/execute! db
["select * from EconomicEvent where outputOf = ?" id]
{:builder-fn opt/as-unqualified-maps})]
(-> process
(merge {:inputs inputs})
(merge {:outputs outputs}))))
([]
(jdbc/execute! db
["select * from Process"]
{:builder-fn opt/as-unqualified-maps}
)))
(defn query-economic-events
([id]
(defn query-economic-event
[id]
(let [event (jdbc/execute-one! db
["select * from EconomicEvent where id = ?" id]
{:builder-fn opt/as-unqualified-maps})
effortQuantityUnit (query "Unit" (:unit event))
action (query "Action" (:action event))
provider (query "Agent" (:provider event))
receiver (query "Agent" (:receiver event))
resourceInventoriedAs (query "EconomicResource" (:resourceInventoriedAs event))
resourceConformsTo (query "ResourceSpecification" (:resourceConformsTo event))
inputOf (query-process (:inputOf event))
outputOf (query-process (:outputOf event))]
effortQuantityUnit (query :Unit (:resourceQuantityUnit event))
action (query :Action (:action event))
provider (query :Agent (:provider event))
receiver (query :Agent (:receiver event))
resourceInventoriedAs (query :EconomicResource (:resourceInventoriedAs event))
resourceConformsTo (query :ResourceSpecification (:resourceConformsTo event))
inputOf (query :Process (:inputOf event))
outputOf (query :Process (:outputOf event))]
(-> event
(merge {:inputOf inputOf})
(merge {:outputOf outputOf})
......@@ -67,27 +53,87 @@
(merge {:receiver receiver})
(merge {:resourceConformsTo resourceConformsTo})
(merge {:resourceInventoriedAs resourceInventoriedAs}))))
([]
(jdbc/execute! db
["select * from EconomicEvent"]
{:builder-fn opt/as-unqualified-maps})))
(defn create-economic-event
[event]
(sql/insert! db
:EconomicEvent
{:action (:action event)
:resourceQuantityNumericValue (:resourceQuantityNumericValue event)
:resourceQuantityUnit (:resourceQuantityUnit event)
:effortQuantityNumericValue (:effortQuantityNumericValue event)
:effortQuantityUnit (:effortQuantityUnit event)
:hasPointInTime (:hasPointInTime event)
:note (:note event)
:provider (:provider event)
:receiver (:receiver event)
:resourceInventoriedAs (:resourceInventoriedAs event)
:resourceConformsTo (:resourceConformsTo event)
:inputOf (:inputOf event)
:outputOf (:outputOf event)
:toResourceInventoriedAs (:toResourceInventoriedAs event)}))
(defn query-all-economic-event
[]
(let [ids (jdbc/execute! db
["select id from EconomicEvent"]
{:builder-fn opt/as-unqualified-maps})]
(map #(query-economic-event (:id %)) ids)))
(defn query-economic-resource
[id]
(let [resource (jdbc/execute-one! db
["select * from EconomicResource where id = ?" id]
{:builder-fn opt/as-unqualified-maps})
accountingQuantityUnit (query :Unit (:accountingQuantityUnit resource))
unitOfEffort (query :Unit (:unitOfEffort resource))
conformsTo (query :ResourceSpecification (:conformsTo resource))
onHandQuantityUnit (query :Unit (:onHandQuantityUnit resource))
owner (query :Agent (:owner resource))]
(-> resource
(merge {:accountingQuantityUnit accountingQuantityUnit})
(merge {:unitOfEffort unitOfEffort})
(merge {:conformsTo conformsTo})
(merge {:onHandQuantityUnit onHandQuantityUnit})
(merge {:owner owner}))))
(defn query-all-economic-resource
[]
(let [ids (jdbc/execute! db
["select id from EconomicResource"]
{:builder-fn opt/as-unqualified-maps})]
(map #(query-economic-resource (:id %)) ids)))
(defn get-process-inputs
[id]
(let [ids (jdbc/execute! db
["select id from EconomicEvent where inputOf = ?" id]
{:builder-fn opt/as-unqualified-maps})]
(map #(query-economic-event (:id %)) ids)))
(defn get-process-outputs
[id]
(let [ids (jdbc/execute! db
["select id from EconomicEvent where outputOf = ?" id]
{:builder-fn opt/as-unqualified-maps})]
(map #(query-economic-event (:id %)) ids)))
(defn get-agent-economic-event
[id]
(let [ids (jdbc/execute! db
["select id from EconomicEvent where provider = ?" id]
{:builder-fn opt/as-unqualified-maps})]
(map #(query-economic-event (:id %)) ids)))
(defn get-agent-inventoriedEconomicResource
[id]
(let [ids (jdbc/execute! db
["select id from EconomicResource where owner = ?" id]
{:builder-fn opt/as-unqualified-maps})]
(map #(query :EconomicResource (:id %)) ids)))
; ; MUTATIONS TODO
; (defn create-economic-event
; [event]
; (insert! db
; :EconomicEvent
; {:action (:action event)
; :resourceQuantityNumericValue (:resourceQuantityNumericValue event)
; :resourceQuantityUnit (:resourceQuantityUnit event)
; :effortQuantityNumericValue (:effortQuantityNumericValue event)
; :effortQuantityUnit (:effortQuantityUnit event)
; :hasPointInTime (:hasPointInTime event)
; :note (:note event)
; :provider (:provider event)
; :receiver (:receiver event)
; :resourceInventoriedAs (:resourceInventoriedAs event)
; :resourceConformsTo (:resourceConformsTo event)
; :inputOf (:inputOf event)
; :outputOf (:outputOf event)
; :toResourceInventoriedAs (:toResourceInventoriedAs event)}))
(ns vfprocess.db.traversal
(:require [next.jdbc :as jdbc]
[next.jdbc.optional :as opt]
[com.walmartlabs.lacinia.schema :refer [tag-with-type]]
[vfprocess.db.queries :refer [db query query-process]]))
; (ns vfprocess.db.traversal
; (:require [next.jdbc :as jdbc]
; [next.jdbc.optional :as opt]
; [com.walmartlabs.lacinia.schema :refer [tag-with-type]]
; [vfprocess.db.queries :refer [db query ]]))
(defn visited?
"Predicate which returns true if the node v has been visited already, false otherwise."
[v coll]
(some #(= % v) coll))
; (defn visited?
; "Predicate which returns true if the node v has been visited already, false otherwise."
; [v coll]
; (some #(= % v) coll))
(defn first-neighbors
[v]
(let [node (query "EconomicResource" v)]
(tag-with-type (-> node
(merge {:type (str "outputOf_" (:id node))})) :EconomicEvent)
))
(defn find-id
[type]
(.substring type (+ (.indexOf type "_") 1)))
; (defn first-neighbors
; [v]
; (let [node (query "EconomicResource" v)]
; (tag-with-type (-> node
; (merge {:type (str "outputOf_" (:id node))})) :EconomicEvent)
; ))
(defn find-neighbors
"Returns the sequence of neighbors for the given node"
[v coll]
(get coll v))
; (defn find-id
; [type]
; (.substring type (+ (.indexOf type "_") 1)))
(defn find-tracks
"Returns the sequence of neighbors for the given node"
[v]
(let [id (find-id (:type v))]
(cond
; If the node is a process, retrieve the input economic event
(.contains (:type v) "process")
(let [node (jdbc/execute-one! db
["select * from EconomicEvent where inputOf = ? " id]
{:builder-fn opt/as-unqualified-maps})]
(if (= nil node)
nil
(tag-with-type (-> node
(merge {:type (str "inputOf_" (:id node))})) :EconomicEvent)))
; If the node is an economic event input of a process, retrieve the incoming resource
(.contains (:type v) "inputOf")
(let [node (query "EconomicResource" id)]
(if (= nil node)
nil
(tag-with-type (-> node
(merge {:type (str "economicResource_" (:id node))})) :EconomicResource)))
; (defn find-neighbors
; "Returns the sequence of neighbors for the given node"
; [v coll]
; (get coll v))
; If the node is an economic event output of a process, retrieve the incoming process
(.contains (:type v) "outputOf")
(let [node (query-process (:outputOf v))]
(if (= nil node)
nil
(tag-with-type (-> node
(merge {:type (str "process_" (:id node))})) :Process)))
; (defn find-tracks
; "Returns the sequence of neighbors for the given node"
; [v]
; (let [id (find-id (:type v))]
; (cond
; ; If the node is a process, retrieve the input economic event
; (.contains (:type v) "process")
; (let [node (jdbc/execute-one! db
; ["select * from EconomicEvent where inputOf = ? " id]
; {:builder-fn opt/as-unqualified-maps})]
; (if (= nil node)
; nil
; (tag-with-type (-> node
; (merge {:type (str "inputOf_" (:id node))})) :EconomicEvent)))
; If the node is a resource, retrieve the incoming event (outputOf)
(.contains (:type v) "economicResource")
(let [node (jdbc/execute-one! db
["select * from EconomicEvent where resourceInventoriedAs = ?" id]
{:builder-fn opt/as-unqualified-maps})]
(if (= nil node)
nil
(tag-with-type (-> node
(merge {:type (str "outputOf_" (:id node))})) :EconomicEvent)))
:else nil)))
; ; If the node is an economic event input of a process, retrieve the incoming resource
; (.contains (:type v) "inputOf")
; (let [node (query "EconomicResource" id)]
; (if (= nil node)
; nil
; (tag-with-type (-> node
; (merge {:type (str "economicResource_" (:id node))})) :EconomicResource)))
(defn incoming-vf-dfs
"Traverses a graph in Depth First Search (DFS)"
[v]
(loop [stack (vector v) ;; Use a stack to store nodes we need to explore
visited []] ;; A vector to store the sequence of visited nodes
(if (empty? stack) ;; Base case - return visited nodes if the stack is empty
visited
(let [v (peek stack)
neighbors (find-tracks v)
new-stack (if (= nil neighbors) [] (vector neighbors))]
(if (= nil neighbors)
(recur new-stack visited)
(recur new-stack (conj visited neighbors)))))))
; ; If the node is an economic event output of a process, retrieve the incoming process
; (.contains (:type v) "outputOf")
; (let [node (query :Process (:outputOf v))]
; (if (= nil node)
; nil
; (tag-with-type (-> node
; (merge {:type (str "process_" (:id node))})) :Process)))
; ; If the node is a resource, retrieve the incoming event (outputOf)
; (.contains (:type v) "economicResource")
; (let [node (jdbc/execute-one! db
; ["select * from EconomicEvent where resourceInventoriedAs = ?" id]
; {:builder-fn opt/as-unqualified-maps})]
; (if (= nil node)
; nil
; (tag-with-type (-> node
; (merge {:type (str "outputOf_" (:id node))})) :EconomicEvent)))
; :else nil)))
; (defn graph-dfs
; (defn incoming-vf-dfs
; "Traverses a graph in Depth First Search (DFS)"
; [v]
; (loop [stack (vector v) ;; Use a stack to store nodes we need to explore
; visited []] ;; A vector to store the sequence of visited nodes
; (if (empty? stack) ;; Base case - return visited nodes if the stack is empty
; visited
; (let [v (peek stack)
; neighbors (find-tracks v)
; not-visited (filter (complement #(visited? % visited)) neighbors)
; new-stack (into (pop stack) not-visited)]
; (if (visited? v visited)
; new-stack (if (= nil neighbors) [] (vector neighbors))]
; (if (= nil neighbors)
; (recur new-stack visited)
; (recur new-stack (conj visited v)))))))
; (recur new-stack (conj visited neighbors)))))))
; ; (defn graph-dfs
; ; "Traverses a graph in Depth First Search (DFS)"
; ; [v]
; ; (loop [stack (vector v) ;; Use a stack to store nodes we need to explore
; ; visited []] ;; A vector to store the sequence of visited nodes
; ; (if (empty? stack) ;; Base case - return visited nodes if the stack is empty
; ; visited
; ; (let [v (peek stack)
; ; neighbors (find-tracks v)
; ; not-visited (filter (complement #(visited? % visited)) neighbors)
; ; new-stack (into (pop stack) not-visited)]
; ; (if (visited? v visited)
; ; (recur new-stack visited)
; ; (recur new-stack (conj visited v)))))))
......@@ -5,123 +5,57 @@
[next.jdbc.sql :as sql]
[com.walmartlabs.lacinia.schema :as schema]
[vfprocess.db.traversal :refer [incoming-vf-dfs
first-neighbors]]
[vfprocess.db.queries :refer [db
query
query-process
create-economic-event]]
get-process-inputs
get-process-outputs
query-economic-resource
query-economic-event
query-all-economic-event
query-all-economic-resource
get-agent-inventoriedEconomicResource
get-agent-economic-event]]
[clojure.edn :as edn]))
(defn find-economicResource-by-id [id]
(let [economicResource (query "EconomicResource" id)
first-node {:type (str "economicResource_" id)}
incoming-valueflows (incoming-vf-dfs first-node)]
(-> economicResource
(merge {:track incoming-valueflows}))))
;; TODO: from scratch
(defn mutationNewEconomicEvent
[args]
(let [{:keys [event]} args
economicResource (query "EconomicResource" (:resourceInventoriedAs event))
toEconomicResource (query "EconomicResource" (:toResourceInventoriedAs event))
action (query "Action" (:action event))
economicEvent (create-economic-event event)
]
(cond
(some? (:resourceInventoriedAs event))
(cond
(= (:resourceEffect action) "+")
(if (= (:createResource event) true)
(sql/insert! db :EconomicResource economicResource)
(do
(sql/update! db :EconomicResource
{:accountingQuantityNumericValue (+
(:accountingQuantityNumericValue economicResource)
(:resourceQuantityNumericValue event))
:onhandQuantitynumericValue (+
(:accountingQuantityNumericValue economicResource)
(:resourceQuantityNumericValue event))}
{:id (:id economicResource)})
event))
(= (:resourceEffect action) "-")
(do
(sql/update! db :EconomicResource
{:accountingQuantityNumericValue (-
(:accountingQuantityNumericValue economicResource)
(:resourceQuantityNumericValue event))
:onhandQuantitynumericValue (-
(:accountingQuantityNumericValue economicResource)
(:resourceQuantityNumericValue event))}
{:id (:id economicResource)})
event)
(or (= (:label action) "transferCustody") (= (:label action) "transferComplete") (= (:label action) "move"))
(do
(sql/update! db :EconomicResource
{:onhandQuantitynumericValue (-
(:accountingQuantityNumericValue economicResource)
(:resourceQuantityNumericValue event))}
{:id (:id economicResource)})
event)
(or (= (:label action) "transferAllRights") (= (:label action) "transferComplete") (= (:label action) "move"))
(do
(sql/update! db :EconomicResource
{:accountingQuantityNumericValue (-
(:accountingQuantityNumericValue economicResource)
(:resourceQuantityNumericValue event))}
{:id (:id economicResource)})
event)
:else nil)
(some? (:toResourceInventoriedAs event))
(do
(sql/update! db :EconomicResource
{:accountingQuantityNumericValue (+
(:accountingQuantityNumericValue toEconomicResource)
(:resourceQuantityNumericValue event))
:onhandQuantitynumericValue (+
(:accountingQuantityNumericValue toEconomicResource)
(:resourceQuantityNumericValue event))}
{:id (:id economicResource)})
event)
:else nil
)
)
)
(defn resolver-map
[]
{:query/process (fn [_ args _] (let [{:keys [id]} args]
(query-process id)))
:query/allProcesses (fn [_ _ _] (query-process))
(query :Process id)))
:query/get-inputs (fn [_ _ value] (let [{:keys [id]} value]
(get-process-inputs id)))
:query/get-outputs (fn [_ _ value] (let [{:keys [id]} value]
(get-process-outputs id)))
:query/get-agent-economic-event (fn [_ _ value] (let [{:keys [id]} value]
(get-agent-economic-event id)))
:query/get-agent-inventoriedEconomicResource (fn [_ _ value] (let [{:keys [id]} value]
(get-agent-inventoriedEconomicResource id)))
:query/allProcesses (fn [_ _ _] (query :Process))
:query/agent (fn [_ args _] (let [{:keys [id]} args]