Řešení, na kterém právě pracuji a které zatím funguje dobře, implementuje návrh, který jsem navrhl v otázce
Zde se podělím o specifika své implementace
Pro vytváření delt a použití k rekonstrukci fulltextu používám fantastický knihovna google-diff-match-patch . Můžete si přečíst agnostickou implementaci dokumentaci API abyste lépe porozuměli níže uvedeným příkladům kódu, i když je každopádně docela čitelný.
google-diff-match-patch má implementace Java a JS, takže jej mohu použít k výpočtu deltas s Java na serveru. Rozhodl jsem se převést každou deltu na řetězec, aby mohl být snadno uložen v databázi a snadno spotřebován knihovnou JS na klientovi. Více o tom níže.
public String getBackwardsDelta(String editedBlogPost, String existingBlogPost) {
diff_match_patch dmp = new diff_match_patch();
LinkedList<diff_match_patch.Patch> patches =
dmp.patch_make(editedBlogPost, existingBlogPost);
return dmp.patch_toText(patches);
}
N.B. chvíli mi trvalo, než jsem přišel na to, jak stáhnout oficiální sestavení google-diff-match-patch pomocí maven. Není to v centrálním repozitáři maven, ale v jejich vlastním repo na googlecode.com. Jen pro povšimnutí, někteří lidé to forkovali a umístili své forkované verze do maven central, ale pokud opravdu chcete oficiální verzi, můžete ji získat přidáním repo a závislosti do vašeho pom.xml
takto
<repository>
<id>google-diff-patch-match</id>
<name>google-diff-patch-match</name>
<url>https://google-diff-match-patch.googlecode.com/svn/trunk/maven/</url>
</repository>
<dependency>
<groupId>diff_match_patch</groupId>
<artifactId>diff_match_patch</artifactId>
<version>current</version>
</dependency>
Pro frontend předám plný text nejnovějšího blogového příspěvku spolu s řetězcem delt v čase, které představují každou úpravu, a poté rekonstruuji úplný text každé verze v prohlížeči v JS.
K získání knihovny používám npm + browserify. Knihovna je dostupná na npm jako diff-match-patch . Verze 1.0.0 je jediná verze.
getTextFromDelta: function(originalText, delta) {
var DMP = require('diff-match-patch'); // get the constructor function
var dmp = new DMP();
var patches = dmp.patch_fromText(delta);
return dmp.patch_apply(patches, originalText)[0];
}
A je to, funguje to fantasticky.
Pokud jde o ukládání úprav blogových příspěvků, používám pouze tabulku BLOG_POST_EDITS
kde ukládám ID příspěvku na blogu, časové razítko, kdy byla úprava provedena (které později používám ke správnému objednání úprav, aby se vytvořil řetězec při rekonstrukci fulltextových verzí na klientovi), a zpětná delta mezi aktuálním živým vysíláním blogový příspěvek v BLOG_POST
tabulku a příchozí upravenou verzi blogového příspěvku.
Rozhodl jsem se uložit „řetězec“ deltas, protože to dobře vyhovuje mému případu použití a je jednodušší na straně kódu serveru. Znamená to, že za účelem rekonstrukce verze M N musím klientovi poslat řetězec delt N-(M-1) zpět z plného textu živého blogového příspěvku do verze M. Ale v mém případě použití chcete pokaždé poslat celý řetězec, takže je to v pořádku.
Pro trochu lepší bezdrátovou efektivitu při vyžádání konkrétních verzí by bylo možné všechny delty přepočítat z nové upravené verze blogového příspěvku zpět na každou (obnovenou) verzi při každé úpravě, ale to by znamenalo více práce a složitosti server.