Newer
Older

Bruno Burke
committed
(:require [document-storage.postgres.encoding :as encoding]
[editscript.core :as escript]
[clj-helper.vector :as vhelper]))

Bruno Burke
committed
(defn get-document-frame-by-version [storage document-id version repository]
(.run-query storage :get-document-frame-by-version
{:repository repository
:version version
:document-id document-id}))
(defn get-document-frame-by-id [storage frame-id repository]
(.run-query storage :get-document-frame
{:repository repository
:id frame-id}))
(defn get-last-document-frame [storage document-id repository]

Bruno Burke
committed
;;;TODO check if this can be speed up by using index in db

Bruno Burke
committed
(when-let [frame (.run-query storage :get-last-document-frame
{:repository repository
:document-id document-id})]
frame))
(defn get-last-document-version [storage document-id repository]

Bruno Burke
committed
(when-let [frame (get-last-document-frame storage document-id repository)]
(:version frame)))
(defn restore-document-version [storage document-id version repository]
(when-let [frames (.run-query storage :select-relevant-document-frames-by-version
{:repository repository
:document-id document-id
:version version})]
(let [next-frames (into {} (map (juxt :reference identity)) frames)
keyframe (vhelper/get-by frames (comp name :data_type) "key")]
(if keyframe
(loop [active-frame keyframe
data (encoding/decode-document (:data active-frame))]
(let [next-frame (get next-frames (:id active-frame))]
(if-not next-frame
data
(recur next-frame (escript/patch
data
(escript/edits->script (encoding/decode-document (:data next-frame))))))))
(throw
(ex-info (str "No keyframe for document " document-id " with version " version " in repository " repository)
{:document-id document-id
:version version
:repository repository}))))))
(defn load-document
([storage document-id repository]

Bruno Burke
committed
(when-let [last-document-version (get-last-document-version storage document-id repository)]
(load-document storage document-id last-document-version repository)))
(restore-document-version storage document-id version repository)))
(defn save-keyframe [storage document-id document last-version repository]
(let [doc (encoding/encode-document document)
last-version (or last-version 0)]
;;VALUES (:uuid, :document-id, :type, :encoding, :version, :reference, :data)
(.run-query storage :create-document-frame!
{:repository repository
:document-id document-id
:type :ds-type/key

Bruno Burke
committed
:encoding :ds-encoding/nippy
:version (inc last-version)

Bruno Burke
committed
(defn save-pframe [storage document-id doc last-version repository]
(let [last-doc (load-document storage document-id last-version repository)
last-frame (get-document-frame-by-version storage document-id last-version repository)
diff (escript/diff last-doc doc {:str-diff? false :algo :quick})

Bruno Burke
committed
diff-doc (encoding/encode-document (escript/get-edits diff))]
(.run-query storage :create-document-frame!
{:repository repository
:document-id document-id
:type :ds-type/diff
:encoding :ds-encoding/nippy
:version (inc last-version)
:reference (:id last-frame) ;;;FIXME save ID in reference not version
:data diff-doc})))
(defn save-document [storage document-id document repository options]

Bruno Burke
committed
(if-let [last-version (get-last-document-version storage document-id repository)]
(if (true? (:force-keyframe options))
(save-keyframe storage document-id document last-version repository)
(save-pframe storage document-id document last-version repository))
(save-keyframe storage document-id document -1 repository)))

Bruno Burke
committed
(defn delete-document [storage document-id repository]

Bruno Burke
committed
(.run-query storage :create-document-frame!
{:repository repository
:document-id document-id
:type :ds-type/delete
:encoding :ds-encoding/edn
:version (inc (get-last-document-version storage document-id repository))
:reference nil
:data (encoding/encode-document "")}))