Improve project page related queries and mutations.

This commit is contained in:
Andrey Antukh 2019-12-17 22:10:52 +01:00
parent 0a9ef0d345
commit 05ec4560b9
4 changed files with 38 additions and 39 deletions

View file

@ -14,21 +14,21 @@
[uxbox.services.queries.project-pages :refer [decode-row]]
[uxbox.services.util :as su]
[uxbox.common.pages :as cp]
[uxbox.common.spec :as cs]
[uxbox.util.exceptions :as ex]
[uxbox.util.blob :as blob]
[uxbox.util.sql :as sql]
[uxbox.util.spec :as us]
[uxbox.util.uuid :as uuid]))
;; --- Helpers & Specs
(s/def ::id ::cs/uuid)
(s/def ::name ::cs/string)
(s/def ::id ::us/uuid)
(s/def ::name ::us/string)
(s/def ::data ::cp/data)
(s/def ::user ::cs/uuid)
(s/def ::project-id ::cs/uuid)
(s/def ::user ::us/uuid)
(s/def ::project-id ::us/uuid)
(s/def ::metadata ::cp/metadata)
(s/def ::ordering ::cs/number)
(s/def ::ordering ::us/number)
;; --- Mutation: Create Page
@ -157,31 +157,37 @@
:stored-version (:version page)}))
(let [ops (:operations params)
data (-> (:data page)
(blob/decode)
(cp/process-ops ops)
(blob/encode))
(blob/decode)
(cp/process-ops ops)
(blob/encode))
page (assoc page
:user-id (:user params)
:data data
:version (inc (:version page))
:operations (blob/encode ops))]
(-> (update-page-data conn page)
(p/then (fn [_] (insert-page-snapshot conn page)))
(p/then (fn [s] (retrieve-lagged-operations conn s params))))))
(su/defstr sql:lagged-snapshots
"select s.id, s.page_id, s.version, s.operations,
s.created_at, s.modified_at, s.user_id
"select s.id, s.operations
from project_page_snapshots as s
where s.page_id = $1
and s.version > $2
and s.id != $3")
and s.version > $2")
(defn- retrieve-lagged-operations
[conn snapshot params]
(let [sql sql:lagged-snapshots]
(-> (db/query conn [sql (:id params) (:version params) (:id snapshot)])
(p/then (partial mapv decode-row)))))
(-> (db/query conn [sql (:id params) (:version params) #_(:id snapshot)])
(p/then (fn [rows]
{:id (:id params)
:version (:version snapshot)
:operations (into [] (comp (map decode-row)
(map :operations)
(mapcat identity))
rows)})))))
;; --- Mutation: Delete Page
@ -220,7 +226,7 @@
;; (some-> (db/fetch-one conn sqlv)
;; (decode-row))))
;; (s/def ::label ::cs/string)
;; (s/def ::label ::us/string)
;; (s/def ::update-page-history
;; (s/keys :req-un [::user ::id ::pinned ::label]))

View file

@ -111,13 +111,13 @@
(s/def ::pinned ::us/boolean)
(s/def ::since ::us/integer)
(s/def ::page-history
(s/def ::project-page-snapshots
(s/keys :req-un [::page-id ::user]
:opt-un [::max ::pinned ::since]))
(defn retrieve-page-history
[{:keys [page-id user since max pinned] :or {since Long/MAX_VALUE max 10}}]
(let [sql (-> (sql/from ["pages_history" "ph"])
(defn retrieve-page-snapshots
[conn {:keys [page-id user since max pinned] :or {since Long/MAX_VALUE max 10}}]
(let [sql (-> (sql/from ["project_page_snapshots" "ph"])
(sql/select "ph.*")
(sql/where ["ph.user_id = ?" user]
["ph.page_id = ?" page-id]
@ -126,15 +126,14 @@
["ph.pinned = ?" true]))
(sql/order "ph.version desc")
(sql/limit max))]
(-> (db/query db/pool (sql/fmt sql))
(-> (db/query conn (sql/fmt sql))
(p/then (partial mapv decode-row)))))
(sq/defquery ::page-history
(sq/defquery ::project-page-snapshots
[{:keys [page-id user] :as params}]
(db/with-atomic [conn db/pool]
(p/do! (retrieve-page conn {:id page-id :user user})
(retrieve-page-history conn params))))
(retrieve-page-snapshots conn params))))
;; --- Helpers

View file

@ -8,8 +8,6 @@
"A helpers for work with exceptions."
(:require [clojure.spec.alpha :as s]))
;; TODO: moved to uxbox.common.exceptions
(s/def ::type keyword?)
(s/def ::code keyword?)
(s/def ::mesage string?)

View file

@ -10,6 +10,7 @@
[clojure.spec.alpha :as s]
[cuerdas.core :as str]
[datoteka.core :as fs]
[expound.alpha :as expound]
[uxbox.util.exceptions :as ex])
(:import java.time.Instant))
@ -23,23 +24,18 @@
(def uuid-rx
#"^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$")
(def number-rx
#"^[+-]?([0-9]*\.?[0-9]+|[0-9]+\.?[0-9]*)([eE][+-]?[0-9]+)?$")
;; --- Public Api
(defn conform
[spec data]
(let [result (s/conform spec data)]
(if (= result ::s/invalid)
[nil (s/explain-data spec data)]
[result nil])))
(defn valid?
[spec data]
(if (s/valid? spec data)
true
(s/explain spec data)))
(when (= result ::s/invalid)
(throw (ex/error :type :validation
:code :spec-validation
:explain (with-out-str
(expound/printer data))
:data (::s/problems data))))
result))
;; --- Predicates
@ -113,7 +109,7 @@
[v]
(cond
(number? v) v
(re-matches number-rx v) (Double/parseDouble v)
(str/numeric? v) (Double/parseDouble v)
:else ::s/invalid))