(ns document-storage.postgres.documents (:require [document-storage.postgres.encoding :as encoding] [editscript.core :as escript])) (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] (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] (when-let [frame (get-last-document-frame storage document-id repository)] (:version frame))) (defn restore-document [storage frame-id repository] (when-let [frame (get-document-frame-by-id storage frame-id repository)] (case (:data_type frame) "key" (encoding/decode-document (:data frame)) "diff" (let [data (encoding/decode-document (:data frame))] (escript/patch ;;;FIXME load document-frame by ID (restore-document storage (:reference frame) repository) (escript/edits->script data))) (throw (ex-info (str "Unknown data-type " (:data_type frame) " for frame " frame-id) {:frame-id frame-id :frame frame}))))) (defn load-document ([storage document-id repository] (when-let [last-document-version (get-last-document-version storage document-id repository)] (load-document storage document-id last-document-version repository))) ([storage document-id version repository] (when-let [frame (get-document-frame-by-version storage document-id version repository)] (restore-document storage (:id frame) repository)))) (defn save-keyframe [storage document-id document repository] (let [doc (encoding/encode-document document)] ;;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 :encoding :ds-encoding/nippy :version 0 :reference nil :data doc}))) (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) 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] (if-let [last-version (get-last-document-version storage document-id repository)] (save-pframe storage document-id document last-version repository) (save-keyframe storage document-id document repository))) (defn delete-document [storage document-id repository] (.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 ""}))