Skip to content
Snippets Groups Projects
Commit 23d9c4e0 authored by Bruno Burke's avatar Bruno Burke :hamburger:
Browse files

non-iterative single-query restore-document for pgstorage

parent be5d58ca
No related branches found
No related tags found
1 merge request!1Draft: Migration
Pipeline #93805 passed
......@@ -44,3 +44,31 @@ INSERT INTO :i:repository-table
-- :name get-last-document-frame :? :1
-- :doc retrieve the last document-frame given the document-id.
SELECT * FROM :i:repository-table WHERE document_id = :document-id order by "version" desc limit 1
-- :name select-relevant-document-frames :? :*
-- :doc retrieve all necessary document frames to restore the latest document version
with RECURSIVE rec AS (
SELECT ru.*, 0 AS degree
FROM :i:repository-table ru, (select rr.id from :i:repository-table rr where document_id = :document-id
order by version desc limit 1) as init
WHERE ru.id = init.id
UNION
SELECT ru.*, rec.degree + 1 AS degree
FROM :i:repository-table ru
JOIN rec ON ru.id = rec.reference and rec.data_type != 'key')
select * from rec;
-- :name select-relevant-document-frames-by-version :? :*
-- :doc retrieve all necessary document frames to restore a given document version
with RECURSIVE rec AS (
SELECT ru.*, 0 AS degree
FROM :i:repository-table ru, (select rr.id from :i:repository-table rr where document_id = :document-id
AND version = :version) as init
WHERE ru.id = init.id
UNION
SELECT ru.*, rec.degree + 1 AS degree
FROM :i:repository-table ru
JOIN rec ON ru.id = rec.reference and rec.data_type != 'key')
select * from rec;
(ns document-storage.postgres.documents
(:require [document-storage.postgres.encoding :as encoding]
[editscript.core :as escript]))
[editscript.core :as escript]
[clj-helper.vector :as vhelper]))
(defn get-document-frame-by-version [storage document-id version repository]
......@@ -25,27 +26,34 @@
(:version frame)))
(defn restore-document [storage frame-id repository]
(when-let [frame (get-document-frame-by-id storage frame-id repository)]
(case (name (: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 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]
(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))))
(restore-document-version storage document-id version repository)))
(defn save-keyframe [storage document-id document last-version repository]
(let [doc (encoding/encode-document document)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment