Nickolay - KiokuJS.Backend.CouchDB-0.01
Name
KiokuJS.Backend.CouchDB - Some clever yet compact description
SYNOPSIS
// declaring our class
Class('KiokuJS.Backend.CouchDB', {
})
// then instantiating it
var instance = new KiokuJS.Backend.CouchDB({
})
// and doing something totally awesome with it :D
instance.method(param1, param2)
DESCRIPTION
KiokuJS.Backend.CouchDB
is a stub for Joose-orientied JSAN modules.
ISA
None.
DOES
None.
TRAITS
None.
ATTRIBUTES
attributeName
AttributeType attributeName
Attribute description
METHODS
methodName
method signature
Method description
EXAMPLES
Our class can be used like this:
// then instantiating it
var instance = new KiokuJS.Backend.CouchDB({
})
and like that:
// then instantiating it
var instance = new KiokuJS.Backend.CouchDB({
})
GETTING HELP
This extension is supported via github issues tracker: http://github.com/SamuraiJack/Module-Stub/issues
For general Joose questions you can also visit #joose on irc.freenode.org or the forum at: http://joose.it/forum
SEE ALSO
Web page of this module: http://github.com/SamuraiJack/Module-Stub/
General documentation for Joose: http://openjsan.org/go/?l=Joose
BUGS
All complex software has bugs lurking in it, and this module is no exception.
Please report any bugs through the web interface at http://github.com/SamuraiJack/Module-Stub/issues
AUTHORS
Nickolay Platonov nplatonov@cpan.org
COPYRIGHT AND LICENSE
This software is Copyright (c) 2010 by Nickolay Platonov nplatonov@cpan.org.
This is free software, licensed under:
The GNU Lesser General Public License, Version 3, June 2007
Class('KiokuJS.Backend.CouchDB', { isa : 'KiokuJS.Backend', use : [ 'JSON2', Joose.is_NodeJS ? 'HTTP.Request.Provider.NodeJS' : 'HTTP.Request.Provider.XHR', 'KiokuJS.Backend.CouchDB.Node', 'KiokuJS.Exception.Format', 'KiokuJS.Exception.Network', 'KiokuJS.Exception.LookUp', 'KiokuJS.Exception.Overwrite', 'KiokuJS.Exception.Update', 'KiokuJS.Exception.Conflict' ], does : [ 'KiokuJS.Backend.Feature.Overwrite', 'KiokuJS.Backend.Feature.Update' ], has : { dbURL : '', host : null, port : 5984, prefix : '', dbName : '', nodeClass : Joose.I.FutureClass('KiokuJS.Backend.CouchDB.Node') }, after : { initialize : function () { this.dbURL = this.dbURL.replace(/\/+$/, '') this.prefix = this.prefix.replace(/\/+$/, '') } }, methods : { getRequest : function (config) { return new HTTP.Request.Provider.getRequest(config) }, getURLforCouch : function () { return 'http://' + this.host + ':' + this.port + '/index.html' + this.prefix }, getURLforDB : function () { if (this.dbURL) return this.dbURL return this.getURLforCouch() + '/index.html' + this.dbName } }, continued : { methods : { __createDB : function () { this.getRequest({ method : 'PUT', url : this.getURLforDB() }).andThen(function (res) { this.CONTINUE(this.deserialize(res.text)) }, this) }, __deleteDB : function () { this.getRequest({ method : 'DELETE', url : this.getURLforDB() }).andThen(function (res) { this.CONTINUE(this.deserialize(res.text)) }, this) }, __createView : function (designDoc, viewName, map, reduce) { var doc = { views : {} } var view = doc.views[ viewName ] = {} view.map = map.toString() if (reduce) view.reduce = reduce.toString() var serialized = this.serialize(doc) this.insertDocument('/doc/s/sa/samuraijack/KiokuJS/Backend/CouchDB/001/lib/KiokuJS/Backend/_design/index.html' + designDoc, null, serialized, 'store').now() }, insertDocument : function (id, rev, entry, mode) { var me = this this.getRequest({ method : 'PUT', url : this.getURLforDB() + '/index.html' + id, data : entry }).except(function (e) { if (e.status == 409) { var response = me.deserialize(e.text) if (response.error == 'conflict') { if (mode == 'insert') throw new KiokuJS.Exception.Overwrite({ id : id, newValue : entry }) if (!rev && mode == 'update') throw new KiokuJS.Exception.Update({ message : 'ID = [' + id + ']' }) throw new KiokuJS.Exception.Conflict({ message : 'ID = [' + id + ']' + ', revision: ' + rev + ', entry: ' + entry }) } } throw new KiokuJS.Exception.Network({ nativeEx : e }) }).andThen(function (res) { var response = me.deserialize(res.text) if (response.ok) this.CONTINUE(response.id, response.rev) else throw new KiokuJS.Exception({ message : res.text }) }) }, getDocument : function (id, rev) { var me = this this.getRequest({ method : 'GET', url : this.getURLforDB() + '/index.html' + id, query : rev ? { rev : rev } : null }).except(function (e) { if (e.status == 404) throw new KiokuJS.Exception.LookUp({ id : id, backendName : me.meta.name }) throw new KiokuJS.Exception.Network({ nativeEx : e }) }).andThen(function (res) { this.CONTINUE(me.deserialize(res.text)) }) }, deleteDocument : function (id, rev) { this.getRequest({ method : 'DELETE', url : this.getURLforDB() + '/index.html' + id, query : { rev : rev } }).except(function (e) { if (e.status == 409) throw new KiokuJS.Exception.Conflict({ message : 'Id [' + id + '] not found or revision [' + rev + '] is not current' }) throw new KiokuJS.Exception.Network({ nativeEx : e }) }).andThen(function (res) { this.CONTINUE(me.deserialize(res.text)) }) }, get : function (idsToGet, mode) { var me = this var CONT = this.CONT Joose.A.each(idsToGet, function (id) { CONT.AND(function () { me.getDocument(id).now() }) }) CONT.andThen(function () { var entries = Joose.A.map(arguments, function (returned) { var doc = returned[0] if (doc instanceof KiokuJS.Exception) throw doc return me.nodeClass.entryFromDoc(doc) }) this.CONTINUE(entries) }) }, insert : function (entries, mode) { var me = this var CONT = this.CONT var processedEntries = [] Joose.A.each(entries, function (entry, index) { CONT.AND(function () { var string = me.serialize(me.nodeClass.docFromEntry(entry)) me.insertDocument(entry.ID, entry.REV, string, mode).andThen(function (id, rev) { processedEntries[ index ] = { ID : id, REV : rev } this.CONTINUE() }) }) }) CONT.andThen(function () { Joose.A.each(arguments, function (insertResult) { var res = insertResult[0] if (res instanceof KiokuJS.Exception) throw res }) this.CONTINUE(processedEntries) }) }, remove : function (entriesOrIds) { var me = this var CONT = this.CONT Joose.A.each(entriesOrIds, function (entryOrId) { CONT.AND(function () { // entry if (entryOrId === Object(entryOrId)) this.deleteDocument(entryOrId.ID, entryOrId.REV).now() else { this.getDocument(entryOrId, null).andThen(function (doc) { this.deleteDocument(doc._id, doc._rev).now() }) } }) }) CONT.andThen(function () { Joose.A.each(arguments, function (res) { if (res[0] instanceof KiokuJS.Exception) throw res[0] }) this.CONTINUE() }) }, exists : function (idsToCheck) { var me = this var CONT = this.CONT Joose.A.each(idsToCheck, function (id) { CONT.AND(function () { this.getDocument(id).now() }) }) CONT.andThen(function () { var results = Joose.A.map(arguments, function (checkResult) { var res = checkResult[0] if (res instanceof KiokuJS.Exception.LookUp) return false if (res === Object(res) && res._id) return true throw res }) this.CONTINUE(results) }) }, queryView : function (designDoc, viewName, query) { this.getRequest({ method : 'GET', url : this.getURLforDB() + '/_design/index.html' + designDoc + '/_view/index.html' + viewName, query : query }).except(function (e) { throw new KiokuJS.Exception.Network({ nativeEx : e }) }).andThen(function (res) { this.CONTINUE(this.deserialize(res.text)) }, this) }, search : function (scope, args) { var searchArgs = Joose.O.copy(args[0]) var view = searchArgs.view var designDoc = searchArgs.designDoc delete searchArgs.view delete searchArgs.designDoc this.queryView(designDoc, view, searchArgs).andThen(function (response) { if (searchArgs.raw) { this.CONTINUE(response) return } var ids = Joose.A.map(response.rows, function (row) { return row.id }) scope.lookUp.apply(scope, ids).now() }) } } } })