| Line | Hits | Source |
|---|---|---|
| 1 | 1 | var _ = require('underscore'); |
| 2 | 1 | var debug = require('debug')('couchdb:general'); |
| 3 | 1 | var dbody = require('debug')('couchdb:body'); |
| 4 | 1 | var dreq = require('debug')('couchdb:request'); |
| 5 | ||
| 6 | ||
| 7 | 1 | require('buffer'); |
| 8 | ||
| 9 | 1 | module.exports = RequestBase; |
| 10 | ||
| 11 | 1 | function RequestBase(options) { |
| 12 | 139 | this.options = options || {}; |
| 13 | 139 | if (this.options.request) { |
| 14 | 61 | this.request = this.options.request; |
| 15 | } | |
| 16 | ||
| 17 | 139 | this.options = _.defaults(this.options || {}, { |
| 18 | method: 'GET' | |
| 19 | }); | |
| 20 | ||
| 21 | 139 | this.enableJson = true; |
| 22 | } | |
| 23 | ||
| 24 | 1 | ['HEAD', 'GET', 'POST', 'DELETE', 'PUT', 'COPY'].forEach(function(method) { |
| 25 | 6 | RequestBase.prototype['_' + method.toLowerCase()] = function(url, options, callback) { |
| 26 | 231 | if (typeof options == 'function') { |
| 27 | 175 | callback = options; |
| 28 | 175 | options = {}; |
| 29 | } | |
| 30 | ||
| 31 | 231 | options.method = method; |
| 32 | 231 | return this._request(url, options, callback); |
| 33 | }; | |
| 34 | }); | |
| 35 | ||
| 36 | ||
| 37 | 1 | RequestBase.prototype._request = function(url, options, callback) { |
| 38 | 248 | var request = this.request || (this.request = require('request').defaults(this.options)), |
| 39 | opt = { | |
| 40 | url: url | |
| 41 | }; | |
| 42 | ||
| 43 | ||
| 44 | 248 | if (this.options.auth) { |
| 45 | 133 | opt.auth = { |
| 46 | user: this.options.auth.user, | |
| 47 | pass: this.options.auth.pass, | |
| 48 | sendImmediately: true | |
| 49 | }; | |
| 50 | } | |
| 51 | ||
| 52 | ||
| 53 | 248 | if (typeof options == 'function') { |
| 54 | 0 | callback = options; |
| 55 | 248 | } else if (typeof options === 'string') { |
| 56 | 0 | opt.method = options; |
| 57 | } else { | |
| 58 | 248 | _.extend(opt, options); |
| 59 | } | |
| 60 | ||
| 61 | 248 | if (typeof opt.strictSSL == 'boolean') |
| 62 | 0 | opt.rejectUnauthorized = opt.strictSSL; |
| 63 | ||
| 64 | // set headers | |
| 65 | 248 | opt.headers = (opt.headers && typeof(opt.headers) == 'object') ? opt.headers : {}; |
| 66 | ||
| 67 | ||
| 68 | /* jshint sub: true */ | |
| 69 | 248 | if (opt.headers['Accept'] || opt.headers['accept'] || this.enableJson) |
| 70 | 244 | opt.headers["Accept"] = opt.headers["Accept"] || opt.headers["accept"] || "application/json"; |
| 71 | ||
| 72 | 248 | if (opt.headers['Content-Type'] || opt.headers['content-type'] || this.enableJson) { |
| 73 | 244 | opt.headers["Content-Type"] = opt.headers["Content-Type"] || opt.headers["content-type"] || "application/json"; |
| 74 | } | |
| 75 | ||
| 76 | // prevent bugs where people set encoding when piping | |
| 77 | 248 | if (opt.encoding !== undefined && callback) { |
| 78 | 0 | opt.encoding = opt.encoding; |
| 79 | 0 | delete opt.headers['Content-Type']; |
| 80 | 0 | delete opt.headers['Accept']; |
| 81 | } | |
| 82 | ||
| 83 | 248 | if (opt.headers['Content-Type'] === 'multipart/related' && opt.method === 'GET') { |
| 84 | 5 | opt.encoding = null; |
| 85 | } | |
| 86 | ||
| 87 | 248 | dreq(JSON.stringify(opt)); |
| 88 | ||
| 89 | 248 | debug(opt.method.toUpperCase() + ':' + opt.url); |
| 90 | 248 | return request(opt, function(err, res, body) { |
| 91 | 248 | if (Buffer.isBuffer(body)) |
| 92 | 5 | body = body.toString(); |
| 93 | ||
| 94 | 248 | dbody(typeof body == 'string' ? body : JSON.stringify(body)); |
| 95 | ||
| 96 | // handle string if json option is off | |
| 97 | 248 | if (typeof body == 'string' && (!res.headers['content-type'] || /json/.test(res.headers['content-type']))) { |
| 98 | 237 | try { |
| 99 | 237 | body = JSON.parse(body); |
| 100 | } catch (e) { | |
| 101 | 5 | var contentType = res.headers && res.headers['content-type']; |
| 102 | 5 | if (!contentType || contentType.indexOf('text/plain') == -1) |
| 103 | 5 | debug('JSON parse error:', e); |
| 104 | } | |
| 105 | } | |
| 106 | ||
| 107 | 249 | if (err) return (callback && callback(err, body, res)); |
| 108 | ||
| 109 | 247 | if (res.statusCode < 400) { |
| 110 | 239 | callback && callback(err, body, res); |
| 111 | } else { | |
| 112 | 8 | body = body || {}; |
| 113 | 8 | body.statusCode = res.statusCode; |
| 114 | 8 | callback && callback(body, null, res); |
| 115 | } | |
| 116 | }); | |
| 117 | }; |
| Line | Hits | Source |
|---|---|---|
| 1 | 1 | var _ = require('underscore'), |
| 2 | util = require('util'), | |
| 3 | RequestBase = require('./base'); | |
| 4 | ||
| 5 | 1 | function Config(url, options) { |
| 6 | 5 | RequestBase.call(this, options); |
| 7 | 5 | this.configUrl = url.replace(/\/$/, '') + '/_config'; |
| 8 | } | |
| 9 | ||
| 10 | 1 | util.inherits(Config, RequestBase); |
| 11 | ||
| 12 | 1 | _.extend(Config.prototype, { |
| 13 | all: function(callback) { | |
| 14 | 1 | this._get(this.configUrl, function(err, cfgs) { |
| 15 | 1 | callback(err, cfgs); |
| 16 | }); | |
| 17 | }, | |
| 18 | section: function(section) { | |
| 19 | 1 | var self = this; |
| 20 | 1 | return { |
| 21 | get: self.get.bind(self, section), | |
| 22 | set: self.set.bind(self, section), | |
| 23 | del: self.del.bind(self, section) | |
| 24 | }; | |
| 25 | }, | |
| 26 | get: function(section, key, callback) { | |
| 27 | 3 | this._get([this.configUrl, section, key].join('/'), function(err, val) { |
| 28 | 3 | if (err && err.statusCode == 404) { |
| 29 | // if the config key is not found, return undefined | |
| 30 | 1 | return callback(null, undefined); |
| 31 | } | |
| 32 | 2 | callback(err, val); |
| 33 | }); | |
| 34 | }, | |
| 35 | set: function(section, key, val, callback) { | |
| 36 | 2 | this._put([this.configUrl, section, key].join('/'), { |
| 37 | body: JSON.stringify(val) | |
| 38 | }, function(err, oldVal) { | |
| 39 | 2 | callback(err, oldVal); |
| 40 | }); | |
| 41 | }, | |
| 42 | del: function(section, key, callback) { | |
| 43 | 1 | this._delete([this.configUrl, section, key].join('/'), function(err, oldVal) { |
| 44 | 1 | callback(err, oldVal); |
| 45 | }); | |
| 46 | } | |
| 47 | }); | |
| 48 | ||
| 49 | ||
| 50 | ||
| 51 | 1 | module.exports = Config; |
| Line | Hits | Source |
|---|---|---|
| 1 | 1 | var assert = require('assert'), |
| 2 | crypto = require('crypto'), | |
| 3 | events = require('events'), | |
| 4 | _ = require('underscore'), | |
| 5 | util = require('util'), | |
| 6 | qs = require('querystring'), | |
| 7 | path = require('path'), | |
| 8 | Config = require('./config'), | |
| 9 | Database = require('./db'), | |
| 10 | RequestBase = require('./base'); | |
| 11 | ||
| 12 | ||
| 13 | 1 | function CouchDB(url, options) { |
| 14 | 34 | RequestBase.call(this, options); |
| 15 | 34 | this.url = url.replace(/\/$/, ''); |
| 16 | 34 | this.bindedDBs = {}; |
| 17 | } | |
| 18 | ||
| 19 | ||
| 20 | 1 | util.inherits(CouchDB, RequestBase); |
| 21 | ||
| 22 | 1 | _.extend(CouchDB.prototype, { |
| 23 | config: function(options) { | |
| 24 | 5 | return new Config(this.url, options || this.options); |
| 25 | }, | |
| 26 | /** | |
| 27 | * @param {string} dbname | |
| 28 | * @param {Object=} options if no options is passed the Database will share the same options as CouchDB | |
| 29 | */ | |
| 30 | database: function(dbname, options) { | |
| 31 | 39 | var db = new Database(this.url + '/' + dbname, dbname, options || this.options); |
| 32 | 39 | db.newUuids = this.newUuids.bind(this); |
| 33 | 39 | return db; |
| 34 | }, | |
| 35 | bind: function(dbname, options) { | |
| 36 | 34 | if (this[dbname] && !this.bindedDBs[dbname]) { |
| 37 | 1 | throw new Error('Invalid dbname for bind: ' + dbname); |
| 38 | } | |
| 39 | ||
| 40 | 33 | var db = this[dbname] = this.database(dbname, options || this.options); |
| 41 | ||
| 42 | 33 | this.bindedDBs[dbname] = true; |
| 43 | 33 | return this; |
| 44 | }, | |
| 45 | unbind: function(dbname) { | |
| 46 | 2 | if (this.hasOwnProperty(dbname) && this.bindedDBs[dbname]) { |
| 47 | 2 | delete this[dbname]; |
| 48 | 2 | delete this.bindedDBs[dbname]; |
| 49 | } | |
| 50 | 2 | return this; |
| 51 | }, | |
| 52 | existsDb: function(dbname, callback) { | |
| 53 | // on avaliable for couchdb >= 1.5 | |
| 54 | 0 | return new Database(this.url, dbname, this.options).exists(callback); |
| 55 | }, | |
| 56 | auth: function(user, pass) { | |
| 57 | 64 | delete this.options.auth; |
| 58 | 64 | this.options.headers && (delete this.options.headers.Authorization); |
| 59 | 64 | if (user) { |
| 60 | 36 | this.options.auth = { |
| 61 | user: user | |
| 62 | }; | |
| 63 | ||
| 64 | 36 | pass && (this.options.auth.pass = pass); |
| 65 | } | |
| 66 | 64 | return this; |
| 67 | }, | |
| 68 | /** | |
| 69 | * read version information | |
| 70 | * @param {function} callback | |
| 71 | */ | |
| 72 | info: function(callback) { | |
| 73 | 33 | this._get(this.url, function(err, info, res) { |
| 74 | 33 | callback(err, info); |
| 75 | }); | |
| 76 | }, | |
| 77 | /** | |
| 78 | * @callback statCallback | |
| 79 | * @param {Object} err | |
| 80 | * @param {} | |
| 81 | */ | |
| 82 | /** | |
| 83 | * @param {string|number} statisticId | |
| 84 | * @param {statCallback} callback | |
| 85 | * @auth | |
| 86 | */ | |
| 87 | stats: function(statisticId, callback) { | |
| 88 | 2 | if (typeof statisticId == 'function' && callback === undefined) { |
| 89 | 1 | callback = statisticId; |
| 90 | 1 | statisticId = undefined; |
| 91 | } | |
| 92 | ||
| 93 | 2 | this._get(this.url + '/_stats' + (statisticId ? ('/couchdb/' + statisticId) : ''), |
| 94 | function(err, stat, res) { | |
| 95 | 2 | callback(err, stat); |
| 96 | }); | |
| 97 | }, | |
| 98 | /** | |
| 99 | * List of running tasks | |
| 100 | * @param {function} callback | |
| 101 | * @auth | |
| 102 | */ | |
| 103 | activeTasks: function(callback) { | |
| 104 | 1 | this._get(this.url + '/_active_tasks', function(err, tasks, res) { |
| 105 | 1 | callback(err, tasks); |
| 106 | }); | |
| 107 | }, | |
| 108 | /** | |
| 109 | * @param {function} callback | |
| 110 | */ | |
| 111 | allDbs: function(callback) { | |
| 112 | 2 | this._get(this.url + '/_all_dbs', function(err, alldbs, res) { |
| 113 | 2 | callback && callback(err, alldbs); |
| 114 | }); | |
| 115 | }, | |
| 116 | newUuids: function(n, callback) { | |
| 117 | 3 | var self = this; |
| 118 | 3 | self.uuids_cache = self.uuids_cache || []; |
| 119 | ||
| 120 | 3 | if (self.uuids_cache.length >= n) { |
| 121 | 2 | var uuids = self.uuids_cache.slice(self.uuids_cache.length - n); |
| 122 | 2 | if (self.uuids_cache.length - n === 0) { |
| 123 | 1 | self.uuids_cache = []; |
| 124 | } else { | |
| 125 | 1 | self.uuids_cache = |
| 126 | self.uuids_cache.slice(0, self.uuids_cache.length - n); | |
| 127 | } | |
| 128 | 2 | return callback(null, uuids); |
| 129 | } else { | |
| 130 | // cache 100 ids for future usage | |
| 131 | 1 | this._get(this.url + "/_uuids?count=" + (100 + n), function(err, result) { |
| 132 | 1 | if (err) return callback(err); |
| 133 | 1 | var uuids = (result && result.uuids) || []; |
| 134 | 1 | self.uuids_cache = |
| 135 | self.uuids_cache.concat(uuids.slice(0, 100)); | |
| 136 | ||
| 137 | 1 | callback(err, uuids.slice(100)); |
| 138 | }); | |
| 139 | } | |
| 140 | }, | |
| 141 | ||
| 142 | /** | |
| 143 | * | |
| 144 | */ | |
| 145 | restart: function(callback) { | |
| 146 | 0 | this._post(this.url + '/_restart', function(err, body) { |
| 147 | 0 | callback(err); |
| 148 | }); | |
| 149 | }, | |
| 150 | /** | |
| 151 | * watch db updates events | |
| 152 | * | |
| 153 | * @param {number} timeout | |
| 154 | * @couchdb 1.4 | |
| 155 | */ | |
| 156 | dbUpdates: function(timeout, callback) { | |
| 157 | 0 | if (arguments.length == 1) { |
| 158 | 0 | if (typeof timeout == 'function') { |
| 159 | 0 | callback = timeout; |
| 160 | 0 | timeout = 0; |
| 161 | } | |
| 162 | } | |
| 163 | ||
| 164 | 0 | var params = {}; |
| 165 | ||
| 166 | 0 | if (timeout) |
| 167 | 0 | params.timeout = timeout; |
| 168 | ||
| 169 | 0 | if (callback) |
| 170 | 0 | params.feed = 'longpoll'; |
| 171 | else | |
| 172 | 0 | params.feed = 'continuous'; |
| 173 | ||
| 174 | 0 | if (callback) |
| 175 | 0 | this._get(this.url + '/_db_updates?' + qs.stringify(params), function(err, updates, res) { |
| 176 | 0 | callback(err, updates); |
| 177 | }); | |
| 178 | else { | |
| 179 | // TODO: publish continues event | |
| 180 | 0 | var bus = new events.EventEmitter(); |
| 181 | 0 | return bus; |
| 182 | } | |
| 183 | }, | |
| 184 | /** | |
| 185 | * @param {number} bytes | |
| 186 | * @param {number} offset | |
| 187 | * @parma {function} callback | |
| 188 | */ | |
| 189 | log: function(bytes, offset, callback) { | |
| 190 | 3 | if (typeof offset == 'function' && callback === undefined) { |
| 191 | 1 | callback = offset; |
| 192 | 1 | offset = undefined; |
| 193 | 2 | } else if (typeof bytes == 'function' && offset === undefined && callback === undefined) { |
| 194 | 1 | callback = bytes; |
| 195 | 1 | bytes = undefined; |
| 196 | } | |
| 197 | ||
| 198 | 3 | var query = {}, qstr; |
| 199 | 3 | (bytes !== undefined) && (query.bytes = bytes); |
| 200 | 3 | (offset !== undefined) && (query.offset = offset); |
| 201 | ||
| 202 | ||
| 203 | 3 | var qstr = qs.stringify(query); |
| 204 | ||
| 205 | 3 | this._get(this.url + '/_log?' + qstr, function(err, body) { |
| 206 | 3 | callback && callback(err, body || ''); |
| 207 | }); | |
| 208 | }, | |
| 209 | replicate: function(source, target, options, callback) { | |
| 210 | 0 | if (typeof options == 'function') { |
| 211 | 0 | callbak = options; |
| 212 | 0 | options = undefined; |
| 213 | } | |
| 214 | ||
| 215 | 0 | options = options || {}; |
| 216 | ||
| 217 | 0 | var body; |
| 218 | 0 | try { |
| 219 | 0 | body = JSON.stringify(_.extend({ |
| 220 | source: soruce, | |
| 221 | target: target | |
| 222 | }, options)); | |
| 223 | } catch (e) { | |
| 224 | 0 | return (callback && callback(e)); |
| 225 | } | |
| 226 | ||
| 227 | 0 | this._post(this.url + "/_replicate", { |
| 228 | body: body | |
| 229 | }, | |
| 230 | function(err, body) { | |
| 231 | 0 | callback && callback(err, body); |
| 232 | }); | |
| 233 | }, | |
| 234 | ||
| 235 | /** | |
| 236 | * @auth | |
| 237 | */ | |
| 238 | allDesignDocs: function(callback) { | |
| 239 | 1 | var self = this; |
| 240 | 1 | self.allDbs(function(err, dbs) { |
| 241 | 1 | if (err) return (callback && callback(err)); |
| 242 | 1 | var ddocs = []; |
| 243 | 1 | getDdocs(); |
| 244 | ||
| 245 | 1 | function getDdocs() { |
| 246 | 4 | if (dbs.length) { |
| 247 | 3 | var db = dbs.shift(); |
| 248 | 3 | self.database(db).allDesignDocs(function(err, data) { |
| 249 | 3 | if (err) return callback(err); |
| 250 | 3 | Array.prototype.push.apply(ddocs, data); |
| 251 | 3 | getDdocs(); |
| 252 | }); | |
| 253 | } else { | |
| 254 | 1 | callback && callback(undefined, ddocs); |
| 255 | } | |
| 256 | } | |
| 257 | }); | |
| 258 | }, | |
| 259 | // ======================== | |
| 260 | // Session Management | |
| 261 | // ======================== | |
| 262 | login: function(username, passwd, callback) { | |
| 263 | 6 | if (!this.options.jar) { |
| 264 | 5 | this.options.jar = this.__jar = require('request').jar(); |
| 265 | } | |
| 266 | 6 | this._post(this.url + '/_session', { |
| 267 | body: JSON.stringify({ | |
| 268 | name: username, | |
| 269 | password: passwd | |
| 270 | }) | |
| 271 | }, function(err, body, res) { | |
| 272 | 6 | callback && callback(err, body); |
| 273 | }); | |
| 274 | }, | |
| 275 | logout: function(callback) { | |
| 276 | 6 | var self = this; |
| 277 | 6 | this._delete(this.url + '/_session', function(err, body) { |
| 278 | 6 | if (self.__jar === self.options.jar) { |
| 279 | 6 | delete self.options.jar; |
| 280 | 6 | delete self.__jar; |
| 281 | } | |
| 282 | 6 | callback && callback.bind(self)(err, body); |
| 283 | }); | |
| 284 | }, | |
| 285 | /** | |
| 286 | * @callback sessionCallback | |
| 287 | * @parm {object} err | |
| 288 | * @param {object} info session information | |
| 289 | */ | |
| 290 | /** | |
| 291 | * @param {sessionCallback} callback | |
| 292 | */ | |
| 293 | session: function(callback) { | |
| 294 | 1 | this._get(this.url + '/_session', function(err, body) { |
| 295 | 1 | callback && callback(err, body); |
| 296 | }); | |
| 297 | } | |
| 298 | }); | |
| 299 | ||
| 300 | 1 | module.exports = CouchDB; |
| Line | Hits | Source |
|---|---|---|
| 1 | 1 | var _ = require('underscore'); |
| 2 | 1 | var util = require('util'); |
| 3 | 1 | var qs = require('querystring'); |
| 4 | 1 | var follow = require('follow'); |
| 5 | ||
| 6 | 1 | var Document = require('./doc'), |
| 7 | Local = require('./local'), | |
| 8 | DesignDoc = require('./ddoc'), | |
| 9 | RequestBase = require('./base'), | |
| 10 | Executor = require('./exec'); | |
| 11 | ||
| 12 | 1 | module.exports = Database; |
| 13 | ||
| 14 | /** | |
| 15 | * @param {string} url url that include dbname | |
| 16 | * @param {string} dbname | |
| 17 | * @param {Object=} options | |
| 18 | */ | |
| 19 | 1 | function Database(url, dbname, options) { |
| 20 | 42 | options = options || {}; |
| 21 | ||
| 22 | 42 | if (!url || !dbname) |
| 23 | 2 | throw new Error('url, dbname must be provided'); |
| 24 | ||
| 25 | 40 | RequestBase.call(this, options); |
| 26 | 40 | this.url = url.replace(/\/$/, ''); |
| 27 | 40 | this.dbname = dbname; |
| 28 | } | |
| 29 | ||
| 30 | 1 | util.inherits(Database, RequestBase); |
| 31 | ||
| 32 | 1 | _.extend(Database.prototype, { |
| 33 | /* | |
| 34 | * Extend Database object | |
| 35 | * @param {Object} extend | |
| 36 | */ | |
| 37 | extend: function(extend) { | |
| 38 | 1 | for (var key in extend) { |
| 39 | 2 | var val = extend[key]; |
| 40 | 2 | if (typeof val == 'function') { |
| 41 | 1 | this[key] = val.bind(this); |
| 42 | } else | |
| 43 | 1 | this[key] = val; |
| 44 | } | |
| 45 | 1 | return this; |
| 46 | }, | |
| 47 | doc: function(doc, options) { | |
| 48 | 28 | return new Document(this.url, doc, options || this.options); |
| 49 | }, | |
| 50 | insert: function(doc, options, callback) { | |
| 51 | 3 | if (typeof options == 'function') { |
| 52 | 2 | callback = options; |
| 53 | 2 | options = undefined; |
| 54 | } | |
| 55 | ||
| 56 | ||
| 57 | 3 | if (typeof options == 'string') { |
| 58 | 1 | doc._id = options; |
| 59 | 1 | options = undefined; |
| 60 | } | |
| 61 | ||
| 62 | 3 | var doc = this.doc(doc, options); |
| 63 | 3 | doc.create(callback); |
| 64 | }, | |
| 65 | fetch: function(id, callback) { | |
| 66 | 1 | this.doc(id).open(callback); |
| 67 | }, | |
| 68 | mfetch: function(ids, callback) { | |
| 69 | 1 | this.searchByKeys(ids, { |
| 70 | include_docs: true | |
| 71 | }, callback); | |
| 72 | }, | |
| 73 | local: function(options) { | |
| 74 | 1 | return new Local(this.url, options || this.options); |
| 75 | }, | |
| 76 | design: function(designName, options) { | |
| 77 | 19 | return new DesignDoc(this.url, designName, options || this.options); |
| 78 | }, | |
| 79 | designDoc: function() { | |
| 80 | 1 | return this.design.apply(this, arguments); |
| 81 | }, | |
| 82 | view: function(design, view, options) { | |
| 83 | 8 | if (typeof view != 'string') { |
| 84 | 8 | options = view; |
| 85 | 8 | var dv = design.split('/'); |
| 86 | 8 | design = dv[0]; |
| 87 | 8 | view = dv[1]; |
| 88 | } | |
| 89 | 8 | return this.design(design, options || this.options).view(view); |
| 90 | }, | |
| 91 | newUuids: function() { | |
| 92 | 1 | throw new Error('No newUuids method in Database'); |
| 93 | }, | |
| 94 | /** | |
| 95 | * @couchdb 1.5 | |
| 96 | */ | |
| 97 | exists: function(callback) { | |
| 98 | 0 | this._head(this.url, function(err, body, res) { |
| 99 | 0 | if (err && err.statusCode == 404) |
| 100 | 0 | return callback(null, false); |
| 101 | ||
| 102 | 0 | callback(err, !err, body); |
| 103 | }); | |
| 104 | }, | |
| 105 | info: function(callback) { | |
| 106 | 3 | this._get(this.url, function(err, info) { |
| 107 | 3 | callback(err, info); |
| 108 | }); | |
| 109 | }, | |
| 110 | create: function(callback) { | |
| 111 | 33 | this._put(this.url, function(err, body) { |
| 112 | 33 | if (body && body.error) { |
| 113 | 0 | callback && callback(err || body.reason); |
| 114 | } else | |
| 115 | 33 | callback && callback(err, body); |
| 116 | }); | |
| 117 | }, | |
| 118 | destroy: function(callback) { | |
| 119 | 34 | this._delete(this.url, callback); |
| 120 | }, | |
| 121 | purge: function(docs, callback) { | |
| 122 | 1 | var body; |
| 123 | 1 | try { |
| 124 | 1 | body = JSON.stringify(docs || {}); |
| 125 | } catch (e) { | |
| 126 | 0 | return (callback && callback(e)); |
| 127 | } | |
| 128 | // TODO: format docs obj | |
| 129 | 1 | this._post(this.url + '/_purge', { |
| 130 | body: body | |
| 131 | }, function(err, body) { | |
| 132 | 1 | callback && callback(err, body); |
| 133 | }); | |
| 134 | }, | |
| 135 | compact: function(callback) { | |
| 136 | 0 | this._post(this.url + '/_compact', callback); |
| 137 | }, | |
| 138 | compactDdoc: function(ddoc, callback) { | |
| 139 | 0 | this._post(this.url + '/_compact/' + ddoc, callback); |
| 140 | }, | |
| 141 | ensureCommit: function(callback) { | |
| 142 | 1 | this._post(this.url + '/_ensure_full_commit', callback); |
| 143 | }, | |
| 144 | viewCleanup: function(callback) { | |
| 145 | 1 | this._post(this.url + '/_view_cleanup', callback); |
| 146 | }, | |
| 147 | /** | |
| 148 | * @param {number} skip | |
| 149 | * @param {number} limit | |
| 150 | * @param {AllDocsOptions=} options | |
| 151 | * @param {function} callback | |
| 152 | */ | |
| 153 | allDocs: function(skip, limit, options, callback) { | |
| 154 | 4 | var query = this.select(); |
| 155 | 4 | if (arguments.length === 0) { |
| 156 | 1 | return query; |
| 157 | 3 | } else if (arguments.length == 1) { |
| 158 | 1 | callback = skip; |
| 159 | 1 | skip = limit = undefined; |
| 160 | 2 | } else if (arguments.length == 2 && typeof limit == 'function') { |
| 161 | 1 | callback = limit; |
| 162 | 1 | options = skip; |
| 163 | 1 | skip = limit = undefined; |
| 164 | 1 | } else if (arguments.length == 3 && typeof options == 'function') { |
| 165 | 1 | callback = options; |
| 166 | 1 | options = undefined; |
| 167 | } | |
| 168 | ||
| 169 | ||
| 170 | 3 | (typeof skip == 'number') && query.skip(skip); |
| 171 | 3 | (typeof limit == 'number') && query.limit(limit); |
| 172 | ||
| 173 | 3 | if (options) |
| 174 | 1 | query.set(options); |
| 175 | ||
| 176 | 3 | query.execute(callback); |
| 177 | }, | |
| 178 | /** | |
| 179 | * @name AllDocsOptions | |
| 180 | * @class | |
| 181 | * @property {boolean} inclusive_end | |
| 182 | * @property {boolean} include_docs whether include the full doc, default is false | |
| 183 | * @property {boolean} descending | |
| 184 | * @property {boolean} group | |
| 185 | * @property {number} group_level | |
| 186 | * @property {boolean} reduce | |
| 187 | * @property {number} skip | |
| 188 | * @property {number} limit | |
| 189 | */ | |
| 190 | /* | |
| 191 | * @param {string} startkey|keys | |
| 192 | * @param {string=} endkey | |
| 193 | * @param {AllDocsOptions=} options | |
| 194 | * @param {function} callback | |
| 195 | */ | |
| 196 | searchByKeys: function(startkey, endkey, options, callback) { | |
| 197 | 9 | var key, keys; |
| 198 | 9 | if (arguments.length == 2 && typeof endkey == 'function') { |
| 199 | 2 | callback = endkey; |
| 200 | 2 | if (startkey instanceof Array) { |
| 201 | 1 | keys = startkey; |
| 202 | } else { | |
| 203 | 1 | key = startkey; |
| 204 | } | |
| 205 | 2 | endkey = startkey = undefined; |
| 206 | 7 | } else if (arguments.length == 3 && typeof options == 'function') { |
| 207 | 7 | callback = options; |
| 208 | 7 | options = undefined; |
| 209 | 7 | if (typeof endkey != 'string') { |
| 210 | 2 | options = endkey; |
| 211 | 2 | if (startkey instanceof Array) { |
| 212 | 1 | keys = startkey; |
| 213 | } else { | |
| 214 | 1 | key = startkey; |
| 215 | } | |
| 216 | } | |
| 217 | } | |
| 218 | ||
| 219 | 9 | var query = this.select(); |
| 220 | 9 | if (!keys) { |
| 221 | 7 | key && query.key(key); |
| 222 | 7 | query.startkey(startkey || undefined).endkey(endkey || undefined).set(options).execute(callback); |
| 223 | } else { | |
| 224 | 2 | query.keys(keys).set(options).execute(callback); |
| 225 | } | |
| 226 | }, | |
| 227 | /** | |
| 228 | * @param {string} startid | |
| 229 | * @param {string} endId | |
| 230 | * @param {AllDocsOptions=} options | |
| 231 | * @param {function} callback | |
| 232 | */ | |
| 233 | searchByIds: function(startId, endId, options, callback) { | |
| 234 | 3 | if (arguments.length == 2 && typeof endId == 'function') { |
| 235 | 1 | callback = endId; |
| 236 | 1 | endId = startId; |
| 237 | 2 | } else if (arguments.length == 3 && typeof options == 'function') { |
| 238 | 2 | callback = options; |
| 239 | ||
| 240 | 2 | if (typeof endId == 'string') { |
| 241 | 1 | options = undefined; |
| 242 | } else { | |
| 243 | 1 | options = endId; |
| 244 | 1 | endId = startId; |
| 245 | } | |
| 246 | } | |
| 247 | ||
| 248 | 3 | this.select().betweenIds(startId || undefined, endId || undefined).set(options).execute(callback); |
| 249 | }, | |
| 250 | /** | |
| 251 | * | |
| 252 | */ | |
| 253 | select: function(options) { | |
| 254 | 17 | var self = this, |
| 255 | executor = new Executor(Database.prototype.select.additions, 'skip', 'limit', 'descending', 'endkey', 'startkey', 'endkey_docid', 'startkey_docid', | |
| 256 | 'group', 'group_level', 'include_docs', 'inclusive_end', 'key', 'reduce', 'stale', 'keys'); | |
| 257 | 17 | executor.execute = function(callback) { |
| 258 | 17 | var opts = _.clone(this.options); |
| 259 | ||
| 260 | 17 | try { |
| 261 | 17 | ['startkey', 'endkey', 'key'].forEach(function(p) { |
| 262 | 51 | opts[p] && (opts[p] = JSON.stringify(opts[p])); |
| 263 | }); | |
| 264 | } catch (e) { | |
| 265 | 0 | return (callback && callback(e)); |
| 266 | } | |
| 267 | ||
| 268 | 17 | if (opts.keys && opts.keys.length) { |
| 269 | 2 | var keys = opts.keys, |
| 270 | body, qstr = ''; | |
| 271 | 2 | delete opts.keys; |
| 272 | ||
| 273 | ||
| 274 | 2 | try { |
| 275 | 2 | body = JSON.stringify({ |
| 276 | keys: keys | |
| 277 | }); | |
| 278 | } catch (e) { | |
| 279 | 0 | e.oldMessage = e.message; |
| 280 | 0 | e.message = "'keys' parameter is invalid JSON."; |
| 281 | 0 | return (callback && callback(e)); |
| 282 | } | |
| 283 | ||
| 284 | 2 | var qstr = qs.stringify(opts); |
| 285 | ||
| 286 | 2 | self._post(self.url + '/_all_docs?' + qstr, { |
| 287 | body: body | |
| 288 | }, function(err, body) { | |
| 289 | 2 | if (err) return callback(err); |
| 290 | 2 | callback && callback(err, body.rows, body.total_rows, body.offset, body); |
| 291 | }); | |
| 292 | } else { | |
| 293 | 15 | var qstr = qs.stringify(opts); |
| 294 | ||
| 295 | 15 | self._get(self.url + '/_all_docs?' + qstr, function(err, body) { |
| 296 | 15 | if (err) return callback(err); |
| 297 | 15 | callback && callback(err, body.rows, body.total_rows, body.offset, body.update_seq, body); |
| 298 | }); | |
| 299 | } | |
| 300 | }; | |
| 301 | ||
| 302 | 17 | executor.betweenKeys = function(startkey, endkey) { |
| 303 | 1 | this.options.startkey = startkey; |
| 304 | 1 | this.options.endkey = endkey; |
| 305 | 1 | return this; |
| 306 | }; | |
| 307 | ||
| 308 | 17 | executor.betweenIds = function(startid, endid) { |
| 309 | 3 | this.options.startkey_docid = startid; |
| 310 | 3 | this.options.endkey_docid = endid; |
| 311 | 3 | return this; |
| 312 | }; | |
| 313 | ||
| 314 | 17 | if (options) |
| 315 | 0 | executor.set(options); |
| 316 | ||
| 317 | 17 | return executor; |
| 318 | }, | |
| 319 | /** | |
| 320 | * Get tempView result with given mapFn and reduceFn | |
| 321 | * | |
| 322 | * @param {function} mapFn map function for tempView | |
| 323 | * @param {function} reduceFn reduce function for tempView | |
| 324 | * @param {Object=} options | |
| 325 | * @param {function=} callback function called after response | |
| 326 | */ | |
| 327 | tempView: function(mapFn, reduceFn, options, callback) { | |
| 328 | 1 | if (arguments.length === 3) { |
| 329 | 1 | callback = options; |
| 330 | 1 | options = undefined; |
| 331 | } | |
| 332 | ||
| 333 | 1 | var body = { |
| 334 | language: "javascript" | |
| 335 | }; | |
| 336 | ||
| 337 | ||
| 338 | 1 | if (typeof(mapFn) != "string") |
| 339 | 1 | mapFn = "(" + mapFn.toString() + ")"; |
| 340 | ||
| 341 | 1 | body.map = mapFn; |
| 342 | ||
| 343 | 1 | if (reduceFn) { |
| 344 | 1 | if (typeof(reduceFn) != "string") |
| 345 | 0 | reduceFn = "(" + reduceFn.toString() + ")"; |
| 346 | 1 | body.reduce = reduceFn; |
| 347 | } | |
| 348 | ||
| 349 | 1 | var qstr = ''; |
| 350 | ||
| 351 | 1 | try { |
| 352 | 1 | body = JSON.stringify(body); |
| 353 | } catch (e) { | |
| 354 | 0 | return (callback && callback(e)); |
| 355 | } | |
| 356 | ||
| 357 | 1 | var qstr = qs.stringify(options); |
| 358 | ||
| 359 | 1 | this._post(this.url + "/_temp_view?" + qstr, { |
| 360 | body: body | |
| 361 | }, function(err, body) { | |
| 362 | 1 | callback && callback(err, body); |
| 363 | }); | |
| 364 | }, | |
| 365 | ||
| 366 | /** | |
| 367 | * Save a document to database, if doc have no revision, then create a new document. | |
| 368 | * @param {string} docid | |
| 369 | * @param {Object} doc | |
| 370 | * @param {Object=} options | |
| 371 | * @param {function} callback | |
| 372 | */ | |
| 373 | save: function(docid, doc, options, callback) { | |
| 374 | 2 | if (arguments.length == 3 && typeof options == 'function') { |
| 375 | 2 | callback = options; |
| 376 | 2 | options = {}; |
| 377 | } | |
| 378 | ||
| 379 | 2 | if (doc._rev) { |
| 380 | 1 | this.doc(docid, options).set(doc).create(callback); |
| 381 | } else | |
| 382 | 1 | this.doc(docid, options).set(doc).save(callback); |
| 383 | }, | |
| 384 | /** | |
| 385 | * @class | |
| 386 | * @name BulkSaveOption | |
| 387 | * @property {boolean=} new_edit | |
| 388 | */ | |
| 389 | /** | |
| 390 | * Create new or update docs in bulk | |
| 391 | * @param {Array} docs | |
| 392 | * @param {BulkSaveOption} options | |
| 393 | * @param {function} callback | |
| 394 | */ | |
| 395 | bulkSave: function(docs, options, callback) { | |
| 396 | 15 | if (arguments.length == 2 && typeof options == 'function') { |
| 397 | 13 | callback = options; |
| 398 | 13 | options = {}; |
| 399 | } | |
| 400 | ||
| 401 | 15 | var json = { |
| 402 | "docs": docs | |
| 403 | }; | |
| 404 | // put any options in the json | |
| 405 | // all_or_nothing / new_edits | |
| 406 | 15 | for (var option in options) { |
| 407 | 0 | json[option] = options[option]; |
| 408 | } | |
| 409 | ||
| 410 | 15 | var body; |
| 411 | 15 | try { |
| 412 | 15 | body = JSON.stringify(json); |
| 413 | } catch (e) { | |
| 414 | 0 | return (callback && callback(e)); |
| 415 | } | |
| 416 | ||
| 417 | 15 | this._request(this.url + "/_bulk_docs", { |
| 418 | method: 'POST', | |
| 419 | body: body | |
| 420 | }, function(err, results) { | |
| 421 | 15 | if (err && err.statusCode == 417) { |
| 422 | 0 | return (callback && callback({ |
| 423 | errors: results | |
| 424 | })); | |
| 425 | } | |
| 426 | ||
| 427 | 15 | if (err) |
| 428 | 0 | return (callback && callback(err)); |
| 429 | ||
| 430 | 15 | for (var i = 0; i < docs.length; i++) { |
| 431 | 37 | if (results[i].rev) { |
| 432 | 37 | (docs[i]._id) || (docs[i]._id = results[i].id); |
| 433 | 37 | docs[i]._rev = results[i].rev; |
| 434 | } | |
| 435 | } | |
| 436 | 15 | callback && callback(err, results); |
| 437 | }); | |
| 438 | }, | |
| 439 | allDesignDocs: function(callback) { | |
| 440 | 4 | return this.searchByKeys('_design/', '_design0', function(err, ddocs) { |
| 441 | 4 | callback && callback(err, ddocs); |
| 442 | }); | |
| 443 | }, | |
| 444 | // ========================== | |
| 445 | // Revisions | |
| 446 | // ========================== | |
| 447 | missingRevisions: function(query, callback) { | |
| 448 | 1 | this._post(this.url + '/_missing_revs', { |
| 449 | body: JSON.stringify(query) | |
| 450 | }, function(err, body) { | |
| 451 | 1 | callback && callback(err, body); |
| 452 | }); | |
| 453 | }, | |
| 454 | revisionsDiff: function(query, callback) { | |
| 455 | 1 | throw new Error('Not Implement Yet'); |
| 456 | }, | |
| 457 | revisionsLimit: function() { | |
| 458 | 1 | var self = this; |
| 459 | 1 | return { |
| 460 | get: function(callback) { | |
| 461 | 1 | self._get(self.url + '/_revs_limit', function(err, limit) { |
| 462 | 1 | callback(err, limit); |
| 463 | }); | |
| 464 | }, | |
| 465 | set: function(options, callback) { | |
| 466 | 1 | var body; |
| 467 | 1 | try { |
| 468 | 1 | body = JSON.stringify(options); |
| 469 | } catch (e) { | |
| 470 | 0 | return (callback && callback(e)); |
| 471 | } | |
| 472 | 1 | self._put(self.url + '/_revs_limit', { |
| 473 | body: body | |
| 474 | }, function(err, st) { | |
| 475 | 1 | callback && callback(err, st); |
| 476 | }); | |
| 477 | } | |
| 478 | }; | |
| 479 | }, | |
| 480 | // ========================== | |
| 481 | // Security | |
| 482 | // ========================== | |
| 483 | security: function() { | |
| 484 | 1 | var self = this; |
| 485 | 1 | return { |
| 486 | get: function(callback) { | |
| 487 | 1 | self._get(self.url + '/_security', function(err, sec) { |
| 488 | 1 | callback && callback(err, sec); |
| 489 | }); | |
| 490 | }, | |
| 491 | set: function(security, callback) { | |
| 492 | 1 | var body; |
| 493 | 1 | try { |
| 494 | 1 | body = JSON.stringify(security); |
| 495 | } catch (e) { | |
| 496 | 0 | return (calback && callback(e)); |
| 497 | } | |
| 498 | 1 | self._put(self.url + '/_security', { |
| 499 | body: body | |
| 500 | }, function(err, st) { | |
| 501 | 1 | callback && callback(err, st); |
| 502 | }); | |
| 503 | } | |
| 504 | }; | |
| 505 | }, | |
| 506 | /** | |
| 507 | * @param {Object=} options options pass to follow, see follow apis | |
| 508 | * @param {function=} callback if no callback is provided, a follow feed will return | |
| 509 | */ | |
| 510 | follow: function(options, callback) { | |
| 511 | 2 | if (arguments.length === 1 && typeof options == 'function') { |
| 512 | 0 | callback = options; |
| 513 | 0 | options = undefined; |
| 514 | } | |
| 515 | ||
| 516 | 2 | options = options || {}; |
| 517 | ||
| 518 | 2 | options.db = this.url; |
| 519 | ||
| 520 | 2 | if (callback) { |
| 521 | 1 | return follow(options, callback); |
| 522 | } else { | |
| 523 | 1 | return new follow.Feed(options); |
| 524 | } | |
| 525 | } | |
| 526 | }); |
| Line | Hits | Source |
|---|---|---|
| 1 | 1 | var _ = require('underscore'), |
| 2 | assert = require('assert'), | |
| 3 | qs = require('querystring'), | |
| 4 | util = require('util'); | |
| 5 | ||
| 6 | 1 | var Document = require('./doc'); |
| 7 | 1 | var View = require('./view'); |
| 8 | 1 | var List = require('./list'); |
| 9 | 1 | var Show = require('./show'); |
| 10 | ||
| 11 | 1 | function DesignDoc(dburl, name, options) { |
| 12 | 19 | Document.call(this, dburl, '_design/' + name, options); |
| 13 | 19 | this.designName = name; |
| 14 | ||
| 15 | } | |
| 16 | ||
| 17 | 1 | util.inherits(DesignDoc, Document); |
| 18 | ||
| 19 | 1 | _.extend(DesignDoc.prototype, { |
| 20 | _encodeId: function() { | |
| 21 | 15 | return this._id; |
| 22 | }, | |
| 23 | info: function(callback) { | |
| 24 | 1 | this._get(this.dburl + '/' + this._id + '/_info', function(err, body) { |
| 25 | 1 | callback(err, body); |
| 26 | }); | |
| 27 | }, | |
| 28 | create: function(batch, callback) { | |
| 29 | 4 | var self = this; |
| 30 | 4 | if (typeof batch == 'function') { |
| 31 | 4 | callback = batch; |
| 32 | 4 | batch = undefined; |
| 33 | } | |
| 34 | ||
| 35 | 4 | self._put(this.dburl + '/' + this._id + (batch ? ("?" + qs.stringify({ |
| 36 | batch: 'ok' | |
| 37 | })) : ''), { | |
| 38 | body: JSON.stringify(this.doc, fnTrans) | |
| 39 | }, function(err, result) { | |
| 40 | 4 | if (err) return (callback && callback(err)); |
| 41 | 4 | self.id(result.id); |
| 42 | 4 | self.rev(result.rev); |
| 43 | 4 | delete this.deleted; |
| 44 | 4 | callback && callback(null, result); |
| 45 | }); | |
| 46 | }, | |
| 47 | save: function(batch, callback) { | |
| 48 | 1 | var self = this; |
| 49 | 1 | if (arguments.length == 1 && typeof batch == 'function') { |
| 50 | 1 | callback = batch; |
| 51 | 1 | batch = undefined; |
| 52 | } | |
| 53 | ||
| 54 | 1 | var options = {}; |
| 55 | 1 | batch && (options.batch = 'ok'); |
| 56 | 1 | this._rev && (options.rev = this._rev); |
| 57 | ||
| 58 | 1 | self._put(this.dburl + '/' + this._id + '?' + qs.stringify(options), { |
| 59 | body: JSON.stringify(self.doc, fnTrans) | |
| 60 | }, function(err, result) { | |
| 61 | 1 | if (err) return (callback && callback(err)); |
| 62 | 1 | self.rev(result.rev); |
| 63 | 1 | callback && callback(err, result); |
| 64 | }); | |
| 65 | }, | |
| 66 | view: function(viewname, options) { | |
| 67 | 8 | return new View(this.dburl + '/' + this._id + '/_view/' + viewname, viewname, options || this.options); |
| 68 | }, | |
| 69 | show: function(showname, options) { | |
| 70 | 2 | return new Show(this.dburl + '/' + this._id + '/_show/' + showname, showname, options || this.options); |
| 71 | }, | |
| 72 | list: function(listname, options) { | |
| 73 | 1 | return new List(this.dburl + '/' + this._id + '/_list/' + listname, listname, options); |
| 74 | }, | |
| 75 | update: function(updatename, docId, options, callback) { | |
| 76 | 1 | var self = this; |
| 77 | 1 | if (arguments.length == 3 && typeof options == 'function') { |
| 78 | 1 | callback = options; |
| 79 | 1 | options = undefined; |
| 80 | } | |
| 81 | ||
| 82 | 1 | this.enableJson = false; |
| 83 | 1 | var rs = self._post(self.dburl + '/' + self._id + '/_update/' + updatename + '/' + encodeURIComponent(docId), |
| 84 | _.extend({}, options), callback); | |
| 85 | 1 | this.enableJson = true; |
| 86 | 1 | return rs; |
| 87 | } | |
| 88 | }); | |
| 89 | ||
| 90 | 1 | module.exports = DesignDoc; |
| 91 | ||
| 92 | ||
| 93 | ||
| 94 | 1 | function fnTrans(key, value) { |
| 95 | 106 | if (typeof value == 'function') |
| 96 | 28 | return '(' + value.toString() + ')'; |
| 97 | 78 | return value; |
| 98 | } |
| Line | Hits | Source |
|---|---|---|
| 1 | 1 | var _ = require('underscore'), |
| 2 | assert = require('assert'), | |
| 3 | util = require('util'), | |
| 4 | qs = require('querystring'), | |
| 5 | RequestBase = require('./base'); | |
| 6 | ||
| 7 | ||
| 8 | 1 | function Document(dburl, doc, options) { |
| 9 | // assign alias | |
| 10 | 49 | this.delete = this.del = this.destroy; |
| 11 | 49 | this.get = this.open; |
| 12 | ||
| 13 | 49 | if (!dburl) |
| 14 | 1 | throw new Error('Database url should not be empty'); |
| 15 | ||
| 16 | 48 | RequestBase.call(this, options); |
| 17 | 48 | this.dburl = dburl; |
| 18 | ||
| 19 | ||
| 20 | 48 | if (typeof doc === 'string') { |
| 21 | 29 | this._id = doc; |
| 22 | 29 | doc = undefined; |
| 23 | } else { | |
| 24 | 19 | this._id = doc._id; |
| 25 | 19 | this.set(doc); |
| 26 | } | |
| 27 | } | |
| 28 | ||
| 29 | 1 | util.inherits(Document, RequestBase); |
| 30 | ||
| 31 | ||
| 32 | 1 | _.extend(Document.prototype, { |
| 33 | _encodeId: function() { | |
| 34 | 31 | return encodeURIComponent(this._id); |
| 35 | }, | |
| 36 | new: function(newDoc) { | |
| 37 | 2 | if (newDoc) |
| 38 | 1 | this.doc = _.clone(newDoc); |
| 39 | ||
| 40 | 2 | this._id = undefined; |
| 41 | 2 | this._rev = undefined; |
| 42 | 2 | this._attachments = undefined; |
| 43 | 2 | return this; |
| 44 | }, | |
| 45 | id: function(id) { | |
| 46 | 17 | if (!arguments.length) |
| 47 | 1 | return this._id; |
| 48 | ||
| 49 | 16 | this._id = id; |
| 50 | 16 | this.doc && (this.doc._id = id); |
| 51 | 16 | return this; |
| 52 | }, | |
| 53 | rev: function(rev) { | |
| 54 | 40 | if (!arguments.length) |
| 55 | 4 | return this._rev; |
| 56 | 36 | this._rev = rev; |
| 57 | 36 | this.doc && (this.doc._rev = rev); |
| 58 | 36 | return this; |
| 59 | }, | |
| 60 | attach: function(attname, data, type) { | |
| 61 | 4 | var atts = {}; |
| 62 | 4 | if (arguments.length == 1) { |
| 63 | 2 | if (Array.isArray(attname)) { |
| 64 | 1 | attname.forEach(function(att) { |
| 65 | 2 | assert(Buffer.isBuffer(att.data) || (typeof att.data == 'string'), 'buffer must be a Buffer of String instance'); |
| 66 | 2 | var data = (typeof att.data == 'string') ? new Buffer(att.data) : att.data; |
| 67 | 2 | atts[att.name] = { |
| 68 | 'content_type': att.type || att.content_type, | |
| 69 | 'data': data.toString('base64') | |
| 70 | }; | |
| 71 | }); | |
| 72 | } else { | |
| 73 | 1 | for (var name in attname) { |
| 74 | 1 | var att = attname[name]; |
| 75 | 1 | assert(Buffer.isBuffer(att.data) || (typeof att.data == 'string'), 'buffer must be a Buffer of String instance'); |
| 76 | 1 | var data = (typeof att.data == 'string') ? new Buffer(att.data) : att.data; |
| 77 | 1 | atts[name] = { |
| 78 | 'content_type': att.type || att.content_type, | |
| 79 | 'data': data.toString('base64') | |
| 80 | }; | |
| 81 | } | |
| 82 | } | |
| 83 | } else { | |
| 84 | 2 | assert(Buffer.isBuffer(data) || (typeof data == 'string'), 'buffer must be a Buffer of String instance'); |
| 85 | 2 | if (typeof data == 'string') |
| 86 | 2 | data = new Buffer(data); |
| 87 | ||
| 88 | 2 | atts[attname] = { |
| 89 | 'content_type': type, | |
| 90 | 'data': data.toString('base64') | |
| 91 | }; | |
| 92 | } | |
| 93 | ||
| 94 | 4 | this.doc && (this.doc._attachments = _.extend(this.doc._attachments || {}, atts)); |
| 95 | 4 | this._attachments = _.extend(this._attachments || {}, atts); |
| 96 | ||
| 97 | 4 | return this; |
| 98 | }, | |
| 99 | update: function(newDoc) { | |
| 100 | 2 | this.doc = _.extend(this.doc, newDoc); |
| 101 | 2 | this._id = (newDoc && newDoc._id) || this._id; |
| 102 | 2 | this._rev = (newDoc && newDoc._rev) || this._rev; |
| 103 | 2 | this._attachments = (newDoc && newDoc._attachments) || this._attachments; |
| 104 | 2 | return this; |
| 105 | }, | |
| 106 | set: function(newDoc) { | |
| 107 | 37 | this.doc = _.clone(newDoc); |
| 108 | 37 | this._id = (newDoc && newDoc._id) || this._id; |
| 109 | 37 | this._rev = (newDoc && newDoc._rev) || this._rev; |
| 110 | 37 | this._attachments = (newDoc && newDoc._attachments) || this._attachments; |
| 111 | 37 | return this; |
| 112 | }, | |
| 113 | exists: function(callback) { | |
| 114 | 5 | if (this._id == null) |
| 115 | 1 | return callback(new Error("docid must be provided")); |
| 116 | ||
| 117 | 4 | this._head(this.dburl + '/' + this._encodeId(), function(err, body, res) { |
| 118 | 4 | if (err && err.statusCode == 404) { |
| 119 | 2 | return callback(undefined, false); |
| 120 | 2 | } else if (!err) { |
| 121 | 1 | return callback(undefined, true); |
| 122 | } | |
| 123 | 1 | callback(err); |
| 124 | }); | |
| 125 | }, | |
| 126 | /** | |
| 127 | * @name DocHeadOptions | |
| 128 | * @class | |
| 129 | * @property {string} rev | |
| 130 | * @property {boolean} revs | |
| 131 | * @property {boolean} revs_info | |
| 132 | */ | |
| 133 | /** | |
| 134 | * @param {DocHeadOptions=} options | |
| 135 | * @param {function} callback | |
| 136 | */ | |
| 137 | head: function(options, callback) { | |
| 138 | 3 | if (arguments.length == 1) { |
| 139 | 1 | callback = options; |
| 140 | 1 | options = {}; |
| 141 | } | |
| 142 | ||
| 143 | /* jshint eqnull: true */ | |
| 144 | 3 | if (this._id == null) |
| 145 | 1 | return callback(new Error("docid must be provided")); |
| 146 | ||
| 147 | 2 | if (this._rev) |
| 148 | 1 | options = _.extend({ |
| 149 | rev: this._rev | |
| 150 | }, options); | |
| 151 | ||
| 152 | 2 | this._head(this.dburl + '/' + this._encodeId() + '?' + qs.stringify(options), function(err, body, res) { |
| 153 | 2 | callback(err, res && res.headers, body); |
| 154 | }); | |
| 155 | ||
| 156 | 2 | return this; |
| 157 | }, | |
| 158 | /** | |
| 159 | * @name DocGetOptions | |
| 160 | * @class | |
| 161 | * @property {boolean} conflictss | |
| 162 | * @property {string} rev | |
| 163 | * @property {boolean} revs | |
| 164 | * @property {boolean} revs_info | |
| 165 | */ | |
| 166 | /** | |
| 167 | * @param {DocGetOptions=} options | |
| 168 | */ | |
| 169 | open: function(options, callback) { | |
| 170 | 14 | var self = this; |
| 171 | 14 | if (!callback && typeof options == 'function') |
| 172 | 11 | callback = options, options = {}; |
| 173 | 3 | else if (typeof options == 'string') { |
| 174 | 1 | options = { |
| 175 | rev: options | |
| 176 | }; | |
| 177 | } | |
| 178 | 14 | options = options || {}; |
| 179 | ||
| 180 | 14 | if (this._id === null || this._id === undefined) |
| 181 | 1 | return (callback && callback.call(this, new Error("docid must be provided"))); |
| 182 | ||
| 183 | 13 | if (this._rev) |
| 184 | 4 | options.rev = this._rev; |
| 185 | ||
| 186 | 13 | var qstr = qs.stringify(options); |
| 187 | ||
| 188 | 13 | var url = this.dburl + '/' + this._encodeId() + '?' + qstr; |
| 189 | 13 | this._get(url, function(err, body) { |
| 190 | 13 | if (!err && body) { |
| 191 | 12 | self.set(body); |
| 192 | } | |
| 193 | 13 | callback && callback.call(self, err, body); |
| 194 | }); | |
| 195 | }, | |
| 196 | /** | |
| 197 | * get a list of revisions for this document | |
| 198 | */ | |
| 199 | revisions: function(callback) { | |
| 200 | 2 | this.open({ |
| 201 | revs: true | |
| 202 | }, function(err, doc) { | |
| 203 | 3 | if (err) return (callback && callback(err)); |
| 204 | 1 | callback && callback(err, doc._revisions, doc); |
| 205 | }); | |
| 206 | }, | |
| 207 | create: function(batch, callback) { | |
| 208 | 12 | var self = this; |
| 209 | 12 | if (typeof batch == 'function') { |
| 210 | 11 | callback = batch; |
| 211 | 11 | batch = undefined; |
| 212 | } | |
| 213 | ||
| 214 | 12 | self._post(this.dburl + (batch ? ("?" + qs.stringify({ |
| 215 | batch: 'ok' | |
| 216 | })) : ''), { | |
| 217 | body: JSON.stringify(this.doc) | |
| 218 | }, function(err, result) { | |
| 219 | 12 | if (err) return (callback && callback(err)); |
| 220 | 12 | self.id(result.id); |
| 221 | 12 | self.rev(result.rev); |
| 222 | 12 | delete this.deleted; |
| 223 | 12 | callback && callback(null, result); |
| 224 | }); | |
| 225 | }, | |
| 226 | save: function(batch, callback) { | |
| 227 | 4 | var self = this; |
| 228 | 4 | if (arguments.length == 1 && typeof batch == 'function') { |
| 229 | 4 | callback = batch; |
| 230 | 4 | batch = undefined; |
| 231 | } | |
| 232 | ||
| 233 | 4 | var options = {}; |
| 234 | 4 | batch && (options.batch = 'ok'); |
| 235 | 4 | this._rev && (options.rev = this._rev); |
| 236 | ||
| 237 | 4 | self._put(this.dburl + '/' + this._encodeId() + '?' + qs.stringify(options), { |
| 238 | body: JSON.stringify(self.doc) | |
| 239 | }, function(err, result) { | |
| 240 | 4 | if (err) return (callback && callback(err)); |
| 241 | 4 | self.rev(result.rev); |
| 242 | 4 | callback && callback(err, result); |
| 243 | }); | |
| 244 | }, | |
| 245 | destroy: function(rev, callback) { | |
| 246 | 5 | if (arguments.length == 1 && typeof rev == 'function') { |
| 247 | 5 | callback = rev; |
| 248 | 5 | rev = undefined; |
| 249 | } | |
| 250 | ||
| 251 | 5 | rev = rev || this._rev; |
| 252 | ||
| 253 | /* jshint eqnull: true */ | |
| 254 | 5 | if (this._id == null) |
| 255 | 1 | return (callback && callback(new Error("docid must be provided"))); |
| 256 | ||
| 257 | 4 | if (rev == null) |
| 258 | 1 | return (callback && callback(new Error("revision must be provided"))); |
| 259 | ||
| 260 | 3 | var self = this; |
| 261 | 3 | self._delete(self.dburl + '/' + this._encodeId() + '?' + qs.stringify({ |
| 262 | rev: rev | |
| 263 | }), function(err, result) { | |
| 264 | 3 | if (self.doc) |
| 265 | 3 | self.doc._deleted = true; |
| 266 | 3 | self.deleted = true; |
| 267 | 3 | callback && callback(err, result); |
| 268 | }); | |
| 269 | }, | |
| 270 | /** | |
| 271 | * @name DocCopyOptions | |
| 272 | * @class | |
| 273 | * @property {string} from_rev | |
| 274 | * @property {string} to_rev | |
| 275 | */ | |
| 276 | /** | |
| 277 | * @param {string} id | |
| 278 | * @param {DocCopyOptions=} options | |
| 279 | * @param {function} callback | |
| 280 | */ | |
| 281 | copy: function(id, options, callback) { | |
| 282 | 2 | var self = this; |
| 283 | 2 | if (arguments.length == 2 && typeof options == 'function') { |
| 284 | 2 | callback = options; |
| 285 | 2 | options = undefined; |
| 286 | } | |
| 287 | ||
| 288 | 2 | options = options || {}; |
| 289 | ||
| 290 | 2 | this._copy(this.dburl + '/' + this._encodeId() + ((options.from_rev || this._rev) ? ('?' + qs.stringify({ |
| 291 | rev: options.from_rev || this._rev | |
| 292 | })) : ''), { | |
| 293 | headers: { | |
| 294 | Destination: id + (options.to_rev ? ('?' + qs.stringify({ | |
| 295 | rev: options.to_rev | |
| 296 | })) : '') | |
| 297 | } | |
| 298 | }, function(err, rs) { | |
| 299 | // TODO: discuss does it right to call the callback in context | |
| 300 | 2 | callback && callback.call(self, err, rs); |
| 301 | }); | |
| 302 | }, | |
| 303 | // ========================= | |
| 304 | // Attachment | |
| 305 | // ========================= | |
| 306 | addAttachment: function(attname, data, type, callback) { | |
| 307 | 12 | var self = this; |
| 308 | ||
| 309 | /* jshint eqnull: true */ | |
| 310 | 12 | if (this._id == null) |
| 311 | 1 | return (callback && callback(new Error("docid must be provided"))); |
| 312 | ||
| 313 | 11 | if (this._rev == null) |
| 314 | 1 | return (callback && callback(new Error("revision must be provided"))); |
| 315 | ||
| 316 | ||
| 317 | 10 | if (arguments.length == 2 && typeof data == 'function') { |
| 318 | 3 | callback = data; |
| 319 | // above 1.3.x ? | |
| 320 | 3 | var atts = {}, |
| 321 | mps = [], | |
| 322 | headers = { | |
| 323 | 'Content-Type': 'multipart/related' | |
| 324 | }; | |
| 325 | ||
| 326 | 3 | if (Array.isArray(attname)) { |
| 327 | 2 | attname.forEach(function(att) { |
| 328 | 4 | atts[att.name] = { |
| 329 | follows: true, | |
| 330 | length: att.data.length, | |
| 331 | content_type: att.type || att.content_type | |
| 332 | }; | |
| 333 | 4 | mps.push({ |
| 334 | body: att.data | |
| 335 | }); | |
| 336 | }); | |
| 337 | } else { | |
| 338 | 1 | for (var name in attname) { |
| 339 | 1 | var att = attname[name]; |
| 340 | 1 | atts[name] = { |
| 341 | follows: true, | |
| 342 | length: att.data.length, | |
| 343 | content_type: att.type || att.content_type | |
| 344 | }; | |
| 345 | 1 | mps.push({ |
| 346 | body: att.data | |
| 347 | }); | |
| 348 | } | |
| 349 | } | |
| 350 | ||
| 351 | 3 | mps.unshift({ |
| 352 | 'Content-Type': 'application/json', | |
| 353 | body: JSON.stringify(_.extend({}, this.doc, { | |
| 354 | _attachments: atts | |
| 355 | })) | |
| 356 | }); | |
| 357 | ||
| 358 | 3 | return this._put(this.dburl + '/' + this._encodeId(), { |
| 359 | headers: headers, | |
| 360 | multipart: mps | |
| 361 | }, function(err, rs, res) { | |
| 362 | 3 | if (err) return (callback && callback(err)); |
| 363 | 3 | self.rev(rs.rev); |
| 364 | 3 | callback && callback(err, rs); |
| 365 | }); | |
| 366 | } else { | |
| 367 | ||
| 368 | 7 | var headers = { |
| 369 | 'Content-Type': type | |
| 370 | }; | |
| 371 | ||
| 372 | 7 | data && (headers['Content-Length'] = data.length); |
| 373 | ||
| 374 | 7 | assert(!data || Buffer.isBuffer(data) || (typeof data == 'string'), 'buffer must be a Buffer of String instance'); |
| 375 | 7 | return this._put([this.dburl, '/', this._encodeId(), '/', encodeURIComponent(attname), |
| 376 | '?', this._rev ? qs.stringify({ | |
| 377 | rev: this._rev | |
| 378 | }) : '' | |
| 379 | ].join(''), { | |
| 380 | headers: headers, | |
| 381 | body: data | |
| 382 | }, | |
| 383 | function(err, body, res) { | |
| 384 | 7 | body && body.rev && self.rev(body.rev); |
| 385 | 7 | callback && callback(err, body, res); |
| 386 | }); | |
| 387 | } | |
| 388 | }, | |
| 389 | getAttachment: function(attname, callback) { | |
| 390 | 5 | return this._get(this.dburl + '/' + this._encodeId() + '/' + encodeURIComponent(attname), { |
| 391 | headers: { | |
| 392 | 'Content-Type': 'multipart/related' | |
| 393 | } | |
| 394 | }, function(err, buffer) { | |
| 395 | 5 | callback && callback(err, buffer); |
| 396 | }); | |
| 397 | }, | |
| 398 | delAttachment: function(attname, callback) { | |
| 399 | 3 | var self = this, |
| 400 | query = {}; | |
| 401 | 3 | this._rev && (query.rev = this._rev); |
| 402 | 3 | return this._delete(this.dburl + '/' + this._encodeId() + '/' + encodeURIComponent(attname) + '?' + |
| 403 | qs.stringify(query), function(err, body) { | |
| 404 | 3 | if (err) return (callback && callback(err)); |
| 405 | ||
| 406 | 3 | self.rev(body.rev); |
| 407 | 3 | callback && callback(err, body); |
| 408 | }); | |
| 409 | }, | |
| 410 | attachment: function(name) { | |
| 411 | 4 | var self = this; |
| 412 | 4 | return { |
| 413 | attach: function(data, type, callback) { | |
| 414 | 1 | self.addAttachment(name, data, type, callback); |
| 415 | }, | |
| 416 | get: function(callback) { | |
| 417 | 3 | self.getAttachment(name, callback); |
| 418 | }, | |
| 419 | update: function(data, type, callback) { | |
| 420 | 1 | self.addAttachment(name, data, type, callback); |
| 421 | }, | |
| 422 | del: function(callback) { | |
| 423 | 1 | self.delAttachment(name, callback); |
| 424 | } | |
| 425 | }; | |
| 426 | } | |
| 427 | }); | |
| 428 | ||
| 429 | ||
| 430 | ||
| 431 | 1 | module.exports = Document; |
| Line | Hits | Source |
|---|---|---|
| 1 | 1 | var _ = require('underscore'); |
| 2 | ||
| 3 | 1 | function capital(str) { |
| 4 | 139 | if (str) |
| 5 | 138 | return str.charAt(0).toUpperCase() + str.slice(1); |
| 6 | 1 | return ''; |
| 7 | } | |
| 8 | ||
| 9 | 1 | function Executor() { |
| 10 | 27 | var self = this; |
| 11 | 27 | this.options = {}; |
| 12 | ||
| 13 | 27 | Array.prototype.forEach.call(arguments, function(prop) { |
| 14 | 419 | addProperty(prop); |
| 15 | }); | |
| 16 | ||
| 17 | 27 | function addProperty(prop) { |
| 18 | 421 | if (prop instanceof Array) { |
| 19 | 1 | prop.forEach(addProperty); |
| 20 | 420 | } else if (typeof prop == 'string') { |
| 21 | 395 | var method = prop.split('_').map(function(val, idx) { |
| 22 | 534 | if (idx === 0) |
| 23 | 395 | return val; |
| 24 | 139 | return capital(val); |
| 25 | }).join(''); | |
| 26 | 395 | if (!self[method]) { |
| 27 | 395 | self[method] = function(val) { |
| 28 | /* jshint eqnull: true */ | |
| 29 | 28 | if (val != null) |
| 30 | 26 | self.options[prop] = val; |
| 31 | 28 | return this; |
| 32 | }; | |
| 33 | } | |
| 34 | } | |
| 35 | } | |
| 36 | } | |
| 37 | ||
| 38 | ||
| 39 | 1 | Executor.prototype.set = function(options) { |
| 40 | 14 | if (options) |
| 41 | 5 | this.options = _.extend(this.options, options); |
| 42 | ||
| 43 | 14 | return this; |
| 44 | }; | |
| 45 | ||
| 46 | ||
| 47 | 1 | Executor.prototype.exec = function() { |
| 48 | 7 | return this.execute.apply(this, arguments); |
| 49 | }; | |
| 50 | ||
| 51 | 1 | Executor.prototype.execute = function() {}; |
| 52 | ||
| 53 | 1 | module.exports = Executor; |
| Line | Hits | Source |
|---|---|---|
| 1 | 1 | var CouchDB = require('./couch'); |
| 2 | ||
| 3 | 1 | module.exports = function(url, options) { |
| 4 | 1 | return new CouchDB(url, options); |
| 5 | }; | |
| 6 | ||
| 7 | 1 | module.exports.CouchDB = CouchDB; |
| 8 | 1 | module.exports.Database = require('./db'); |
| 9 | 1 | module.exports.Document = require('./doc'); |
| 10 | 1 | module.exports.DesignDoc = require('./ddoc'); |
| 11 | 1 | module.exports.View = require('./view'); |
| 12 | 1 | module.exports.List = require('./list'); |
| 13 | 1 | module.exports.Show = require('./show'); |
| Line | Hits | Source |
|---|---|---|
| 1 | 1 | var _ = require('underscore'), |
| 2 | util = require('util'), | |
| 3 | RequestBase = require('./base'); | |
| 4 | ||
| 5 | 1 | module.exports = List; |
| 6 | ||
| 7 | 1 | function List(url, listName, options) { |
| 8 | 1 | RequestBase.call(this, options); |
| 9 | 1 | this.url = url.replace(/\/$/, ''); |
| 10 | 1 | this.listName = listName; |
| 11 | } | |
| 12 | ||
| 13 | 1 | util.inherits(List, RequestBase); |
| 14 | ||
| 15 | 1 | List.prototype.view = function(viewname, options, callback) { |
| 16 | 1 | if (arguments.length == 2 && typeof options == 'function') { |
| 17 | 1 | callback = options; |
| 18 | 1 | options = undefined; |
| 19 | } | |
| 20 | 1 | options = options || {}; |
| 21 | 1 | options.method = options.method || 'GET'; |
| 22 | ||
| 23 | 1 | this.enableJson = false; |
| 24 | 1 | var rs = this._request(this.url + '/' + viewname, options, callback); |
| 25 | 1 | this.enableJson = true; |
| 26 | 1 | return rs; |
| 27 | }; |
| Line | Hits | Source |
|---|---|---|
| 1 | 1 | var _ = require('underscore'), |
| 2 | util = require('util'), | |
| 3 | RequestBase = require('./base'); | |
| 4 | ||
| 5 | ||
| 6 | 1 | function Local(url, options) { |
| 7 | 1 | RequestBase.call(this, options); |
| 8 | } | |
| 9 | ||
| 10 | 1 | util.inherits(Local, RequestBase); |
| 11 | ||
| 12 | // TODO: | |
| 13 | 1 | _.extend(Local.prototype, { |
| 14 | create: function() { | |
| 15 | ||
| 16 | }, | |
| 17 | get: function() { | |
| 18 | ||
| 19 | }, | |
| 20 | update: function() { | |
| 21 | ||
| 22 | }, | |
| 23 | delete: function() { | |
| 24 | ||
| 25 | }, | |
| 26 | copy: function() { | |
| 27 | ||
| 28 | } | |
| 29 | }); | |
| 30 | ||
| 31 | 1 | module.exports = Local; |
| Line | Hits | Source |
|---|---|---|
| 1 | 1 | var _ = require('underscore'), |
| 2 | util = require('util'), | |
| 3 | RequestBase = require('./base'); | |
| 4 | ||
| 5 | 1 | module.exports = Show; |
| 6 | ||
| 7 | 1 | function Show(url, showName, options) { |
| 8 | 2 | RequestBase.call(this, options); |
| 9 | 2 | this.url = url.replace(/\/$/, ''); |
| 10 | 2 | this.showName = showName; |
| 11 | } | |
| 12 | ||
| 13 | 1 | util.inherits(Show, RequestBase); |
| 14 | ||
| 15 | 1 | Show.prototype.doc = function(docid, options, callback) { |
| 16 | 1 | if (arguments.length == 2 && typeof options == 'function') { |
| 17 | 1 | callback = options; |
| 18 | 1 | options = undefined; |
| 19 | } | |
| 20 | ||
| 21 | 1 | options = options || {}; |
| 22 | 1 | options.method = options.method || 'GET'; |
| 23 | ||
| 24 | 1 | this.enableJson = false; |
| 25 | 1 | var rs = this._request(this.url + '/' + encodeURIComponent(docid), options, callback); |
| 26 | 1 | this.enableJson = true; |
| 27 | 1 | return rs; |
| 28 | }; | |
| 29 | ||
| 30 | ||
| 31 | 1 | Show.prototype.get = function(options, callback) { |
| 32 | 1 | if (arguments.length == 1 && typeof options == 'function') { |
| 33 | 1 | callback = options; |
| 34 | 1 | options = undefined; |
| 35 | } | |
| 36 | ||
| 37 | 1 | options = options || {}; |
| 38 | ||
| 39 | 1 | this.enableJson = false; |
| 40 | 1 | var rs = this._get(this.url, options, callback); |
| 41 | 1 | this.enableJson = true; |
| 42 | 1 | return rs; |
| 43 | ||
| 44 | }; |
| Line | Hits | Source |
|---|---|---|
| 1 | 1 | var _ = require('underscore'), |
| 2 | util = require('util'), | |
| 3 | qs = require('querystring'), | |
| 4 | Executor = require('./exec'), | |
| 5 | RequestBase = require('./base'); | |
| 6 | ||
| 7 | ||
| 8 | 1 | function View(url, viewName, options) { |
| 9 | 8 | RequestBase.call(this, options); |
| 10 | 8 | this.url = url.replace(/\/$/, ''); |
| 11 | 8 | this.viewName = viewName; |
| 12 | } | |
| 13 | ||
| 14 | 1 | util.inherits(View, RequestBase); |
| 15 | ||
| 16 | 1 | _.extend(View.prototype, { |
| 17 | fetch: function(key, callback) { | |
| 18 | 1 | this.query().includeDocs(true).key(key).execute(callback); |
| 19 | }, | |
| 20 | mfetch: function(keys, callback) { | |
| 21 | 1 | this.query().includeDocs(true).keys(keys).execute(callback); |
| 22 | }, | |
| 23 | /** | |
| 24 | * | |
| 25 | */ | |
| 26 | query: function(options) { | |
| 27 | 8 | var self = this, |
| 28 | // use additions to extend properties for future or higher version couchdb | |
| 29 | executor = new Executor(View.prototype.query.additions, 'conflicts', 'skip', 'limit', 'descending', 'endkey', 'startkey', 'endkey_docid', 'startkey_docid', | |
| 30 | 'group', 'group_level', 'include_docs', 'inclusive_end', 'key', 'keys', 'reduce', 'stale', 'update_seq'); | |
| 31 | ||
| 32 | 8 | executor.betweenIds = function(startid, endid) { |
| 33 | 1 | this.options.startkey_docid = startid; |
| 34 | 1 | this.options.endkey_docid = endid; |
| 35 | 1 | return this; |
| 36 | }; | |
| 37 | ||
| 38 | 8 | executor.betweenKeys = function(startkey, endkey) { |
| 39 | 1 | this.options.startkey = startkey; |
| 40 | 1 | this.options.endkey = endkey; |
| 41 | 1 | return this; |
| 42 | }; | |
| 43 | ||
| 44 | 8 | executor.execute = function(callback) { |
| 45 | 8 | var opts = _.clone(this.options); |
| 46 | ||
| 47 | 8 | try { |
| 48 | 8 | ['startkey', 'endkey', 'key'].forEach(function(p) { |
| 49 | 24 | opts[p] && (opts[p] = JSON.stringify(opts[p])); |
| 50 | }); | |
| 51 | } catch (e) { | |
| 52 | 1 | return (callback && callback(e)); |
| 53 | } | |
| 54 | ||
| 55 | ||
| 56 | 7 | if (opts.keys && opts.keys.length) { |
| 57 | 1 | var keys = opts.keys; |
| 58 | 1 | delete opts.keys; |
| 59 | 1 | self._post(self.url + '?' + qs.stringify(opts), { |
| 60 | body: JSON.stringify({ | |
| 61 | keys: keys | |
| 62 | }) | |
| 63 | }, function(err, body) { | |
| 64 | 1 | if (err) return (callback && callback(err)); |
| 65 | 1 | callback && callback(err, body.rows, body.total_rows, body.offset, body); |
| 66 | }); | |
| 67 | ||
| 68 | } else { | |
| 69 | 6 | self._get(self.url + '?' + qs.stringify(opts), function(err, body) { |
| 70 | 6 | if (err) return (callback && callback(err)); |
| 71 | 6 | callback && callback(err, body.rows, body.total_rows, body.offset, body); |
| 72 | }); | |
| 73 | } | |
| 74 | }; | |
| 75 | ||
| 76 | 8 | if (options) { |
| 77 | 2 | if (typeof options == 'function') { |
| 78 | 1 | executor.exec(options); |
| 79 | } else | |
| 80 | 1 | executor.set(options); |
| 81 | } | |
| 82 | ||
| 83 | 8 | return executor; |
| 84 | } | |
| 85 | }); | |
| 86 | ||
| 87 | ||
| 88 | 1 | module.exports = View; |