Last active
August 29, 2015 13:57
-
-
Save judell/9744381 to your computer and use it in GitHub Desktop.
draft of CouchDB adaptor for TiddlyWiki
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*\ | |
title: $:/plugins/tiddlywiki/tiddlyweb/tiddlywebadaptor.js | |
type: application/javascript | |
module-type: syncadaptor | |
A sync adaptor module for synchronising with Couch compatible servers | |
\*/ | |
(function () { | |
/*jslint node: true, browser: true */ | |
/*global $tw: false */ | |
"use strict"; | |
function CouchDBAdaptor(syncer) { | |
this.syncer = syncer; | |
this.host = this.getHost(); | |
this.recipe = undefined; | |
this.logger = new $tw.utils.Logger("CouchDBAdaptor"); | |
} | |
CouchDBAdaptor.prototype.getHost = function () { } | |
CouchDBAdaptor.prototype.getTiddlerInfo = function (tiddler) { | |
return { | |
bag: tiddler.fields["bag"] | |
}; | |
}; | |
/* | |
Get the current status of the TiddlyWeb connection | |
*/ | |
CouchDBAdaptor.prototype.getStatus = function (callback) { | |
// debugger; | |
console.log('getStatus'); | |
var self = this; | |
if (callback) { | |
callback(null, false, null); | |
} | |
}; | |
/* | |
Provide the array of skinny tiddler that the syncer is looking for | |
*/ | |
CouchDBAdaptor.prototype.getSkinnyTiddlers = function (callback) { | |
// debugger; | |
var self = this; | |
couchdb.get("SkinnyTiddlers", function (err, doc) { | |
self.logger.log('got Skinny Tiddlers: ') | |
self.logger.log(doc); | |
callback(null, doc.tiddlers); | |
}); | |
}; | |
/* | |
Save a tiddler and invoke the callback with (err,adaptorInfo,revision) | |
*/ | |
CouchDBAdaptor.prototype.saveTiddler = function (tiddler, callback) { | |
// debugger; | |
var title_to_save = tiddler.fields.title; | |
this.logger.log('saving ' + title_to_save); | |
var self = this; | |
var changeCount = this.syncer.wiki.getChangeCount(title_to_save).toString(); | |
couchdb.get("SkinnyTiddlers", function (err, doc) { | |
var skinnies = []; | |
var found = false; | |
self.syncer.wiki.forEachTiddler({ sortField: "title" }, function (title, tiddler) { | |
var tiddlerFields = {}; | |
$tw.utils.each(tiddler.fields, function (field, name) { | |
// if (name !== "text") { | |
if (name !== "text") { | |
tiddlerFields[name] = tiddler.fields[name]; | |
} | |
}); | |
tiddlerFields["revision"] = self.syncer.wiki.getChangeCount(title); | |
tiddlerFields.type = tiddlerFields.type || "text/vnd.tiddlywiki"; | |
skinnies.push(tiddlerFields); | |
}); | |
var new_doc = { | |
_id: "SkinnyTiddlers", | |
_rev: doc._rev, | |
tiddlers: skinnies | |
} | |
couchdb.put(new_doc, function (err, resp) { | |
console.log(err); | |
console.log(resp); | |
}); | |
}); | |
couchdb.get(title_to_save, function (err, doc) { | |
if (err == null) { | |
couchdb.put(tiddler.fields, title_to_save, doc._rev, {}, function (err, response) { console.log(err); console.log(response); }); | |
} | |
else { | |
if (err.status == 404) { | |
couchdb.put(tiddler.fields, title_to_save, null, {}, function (err, response) { console.log(err); console.log(response); }); | |
} | |
else { | |
console.log(err); | |
} | |
} | |
}); | |
var enqueue_load = false; | |
// if (!tiddler.fields['draft.of']) { | |
if (enqueue_load) { | |
console.log('queueing load for ' + title_to_save); | |
self.syncer.enqueueSyncTask({ | |
type: "load", | |
title: title_to_save | |
}); | |
} | |
var ETag = '"' + encodeURIComponent(title_to_save) + "/" + changeCount + ":" + '"'; | |
var etagInfo = self.parseEtag(ETag); | |
callback(null, { | |
bag: etagInfo.bag | |
}, etagInfo.revision); | |
}; | |
/* | |
Load a tiddler and invoke the callback with (err,tiddlerFields) | |
*/ | |
CouchDBAdaptor.prototype.loadTiddler = function (title, callback) { | |
console.log('loading ' + title); | |
// debugger; | |
var self = this; | |
couchdb.get(title, function (err, doc) { | |
console.log(err); | |
console.log('loaded ' + doc); | |
delete doc._id; | |
delete doc._rev; | |
if (doc['modified']) | |
doc['modified'] = new Date(doc['modified']); | |
if (doc['created']) | |
doc['created'] = new Date(doc['created']); | |
callback(null, doc); | |
}); | |
}; | |
/* | |
Delete a tiddler and invoke the callback with (err) | |
*/ | |
CouchDBAdaptor.prototype.deleteTiddler = function (title, callback) { | |
console.log('deleting ' + title); | |
// debugger; | |
var self = this, | |
bag = this.syncer.tiddlerInfo[title].adaptorInfo.bag; | |
// If we don't have a bag it means that the tiddler hasn't been seen by the server, so we don't need to delete it | |
if (!bag) { | |
return callback(null); | |
} | |
couchdb.get(title, function (err, doc) { | |
couchdb.remove(doc, function (err, doc) { | |
}); | |
}); | |
callback(null); | |
}; | |
/* | |
Split a TiddlyWeb Etag into its constituent parts. For example: | |
``` | |
"system-images_public/unsyncedIcon/946151:9f11c278ccde3a3149f339f4a1db80dd4369fc04" | |
``` | |
Note that the value includes the opening and closing double quotes. | |
The parts are: | |
``` | |
<bag>/<title>/<revision>:<hash> | |
``` | |
*/ | |
CouchDBAdaptor.prototype.parseEtag = function (etag) { | |
var firstSlash = etag.indexOf("/"), | |
lastSlash = etag.lastIndexOf("/"), | |
colon = etag.lastIndexOf(":"); | |
if (firstSlash === -1 || lastSlash === -1 || colon === -1) { | |
return null; | |
} else { | |
return { | |
bag: decodeURIComponent(etag.substring(1, firstSlash)), | |
title: decodeURIComponent(etag.substring(firstSlash + 1, lastSlash)), | |
revision: etag.substring(lastSlash + 1, colon) | |
}; | |
} | |
}; | |
if ($tw.browser) { | |
exports.adaptorClass = CouchDBAdaptor; | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment