Wiki

Clone wiki

gnd / VersionControlStrategy

Introduction

CouchDb has revisions, but these are largely to support replication. It doesn't maintain prior revisions of a document.

The page at [1] introduces a way of storing past revisions as attachments. They're not parsed, so don't slow the app down, but are safely managed by the database.

Whilst experimenting, it appeared that when I updated a document, the attachments are lost. This would be a pain - since we'd have to download all attachments, then re-attach them to the new document version.

The article at [2] explains how to overcome this: when you submit the changed document, if the document includes the attachment stubs, the attachments are retained.

Storing version information

Each time we save a new version of a document we introduce (or extend) an array of history data. This array will contain objects with these attributes:

  • date of change (in JSON date format)
  • user that made change
  • brief description of change
  • a list of ids of documents that contributed to the change (in case of merge)
  • attachment id of the previous version of the document (stored as an attachment, as described below).

Strategy

Create document:

curl -X PUT http://127.0.0.1:5984/temp/1 -d '{"name":"the_doc"}'

{"ok":true,"id":"1","rev":"1-aaa0c8fbc32d307019757190310a4add"}

Ok, now add an attachment

curl -X PUT http://127.0.0.1:5984/temp/1/a?rev=1-aaa0c8fbc32d307019757190310a4add -d '{"name":"the_attachment"}'

{"ok":true,"id":"1","rev":"2-49e183bcd2b8693058aa44ec6a16ce3d"}

Now do a GET, so we have the stub(s)

curl -X GET http://127.0.0.1:5984/temp/1

{"_id":"1","_rev":"2-49e183bcd2b8693058aa44ec6a16ce3d","name":"the_doc","_attachments":{"a":{"content_type":"application/x-www-form-urlencoded","revpos":2,"digest":"md5-EwgZhvUv+8vFYgXVRp8BLQ==","length":25,"stub":true}}}

Now we can update the document to the_doc2

curl -X PUT http://127.0.0.1:5984/temp/1 -d  '{"_id":"1","_rev":"2-49e183bcd2b8693058aa44ec6a16ce3d","name":"the_doc2","_attachments":{"a":{"content_type":"application/x-www-form-urlencoded","revpos":2,"digest":"md5-EwgZhvUv+8vFYgXVRp8BLQ==","length":25,"stub":true}}}'

{"ok":true,"id":"1","rev":"3-5652788b9e4aed34df4e42f0b5417ba0"}

Now do a GET to check it's all ok

curl -X GET http://127.0.0.1:5984/temp/1

{"_id":"1","_rev":"3-5652788b9e4aed34df4e42f0b5417ba0","name":"the_doc2","_attachments":{"a":{"content_type":"application/x-www-form-urlencoded","revpos":2,"digest":"md5-EwgZhvUv+8vFYgXVRp8BLQ==","length":25,"stub":true}}}

Done

1. http://jchrisa.net/drl/_design/sofa/_list/post/post-page?startkey=%5B%22Versioning-docs-in-CouchDB%22%5D

2. http://osdir.com/ml/db.couchdb.devel/2008-01/msg00031.html

Updated