Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Refactor & fixes.

- Got rid of old promise-based callbacks.
- Tightened some of the code up.
- Fixed an issue with save(), where it would save twice.
  • Loading branch information...
commit 59694c267c7d421134fda26a256388487af53c2c 1 parent 8d3fd1f
cloudhead authored

Showing 1 changed file with 66 additions and 98 deletions. Show diff stats Hide diff stats

  1. +66 98 lib/cradle.js
164 lib/cradle.js
@@ -115,23 +115,17 @@ cradle.Connection.prototype.rawRequest = function (method, path, options, data,
115 115 // This is the entry point for all requests to CouchDB, at this point,
116 116 // the database name has been embed in the url, by one of the wrappers.
117 117 //
118   -cradle.Connection.prototype.request = function (method, path, options, data, headers) {
119   - var promise = new(events.EventEmitter), request, that = this, emitError = false;
  118 +cradle.Connection.prototype.request = function (method, path, /* [options], [data], [headers] */ callback) {
  119 + var request, that = this, args = Array.prototype.slice.call(arguments, 2);
120 120
121   - promise.addCallback = function (callback) {
122   - if (callback) {
123   - this.addListener("done", callback);
124   - }
125   - return this;
126   - };
127   - promise.addListener('newListener', function (event, listener) {
128   - if (event === 'error') {
129   - emitError = true;
130   - }
131   - });
  121 + if (typeof(callback = args.pop()) !== 'function') {
  122 + args.push(callback);
  123 + callback = function () {};
  124 + }
132 125
133   - // HTTP Headers
134   - headers = cradle.merge({ host: this.host }, headers || {});
  126 + var options = args.shift() || {},
  127 + data = args.shift() || null,
  128 + headers = cradle.merge({ host: this.host }, args.shift() || {});
135 129
136 130 //
137 131 // Handle POST/PUT data. We also convert functions to strings,
@@ -144,7 +138,7 @@ cradle.Connection.prototype.request = function (method, path, options, data, hea
144 138 } else { return val }
145 139 });
146 140 headers["Content-Length"] = data.length;
147   - headers["Content-Type"] = "application/json";
  141 + headers["Content-Type"] = "application/json";
148 142 }
149 143
150 144 request = this.rawRequest(method, path, options, data, headers);
@@ -154,20 +148,19 @@ cradle.Connection.prototype.request = function (method, path, options, data, hea
154 148 // dispatch the request.
155 149 //
156 150 request.addListener('response', function (res) {
157   - var body = '';
  151 + var body = [];
158 152
159 153 res.setEncoding('utf8');
160 154 res.addListener('data', function (chunk) {
161   - body += (chunk || '');
  155 + chunk && body.push(chunk);
162 156 }).addListener('end', function () {
163 157 var obj, response;
164 158
165 159 if (method === 'HEAD') {
166   - promise.emit("done", null, res.headers, res.statusCode);
167   - promise.emit("success", res.headers, res.statusCode);
  160 + callback(null, res.headers, res.statusCode);
168 161 } else {
169   - try { obj = JSON.parse(body) }
170   - catch (e) { return promise.emitError(e) }
  162 + try { obj = JSON.parse(body.join('')) }
  163 + catch (e) { return callback(e) }
171 164
172 165 // If the `raw` option was set, we return the parsed
173 166 // body as-is. If not, we wrap it in a `Response` object.
@@ -176,19 +169,10 @@ cradle.Connection.prototype.request = function (method, path, options, data, hea
176 169 } else {
177 170 response = new(cradle.Response)(obj, res);
178 171 }
179   -
180   - promise.emit("done", (response.error && response.json) || null, response);
181   -
182   - if (response.error && emitError) {
183   - promise.emit("error", response.error);
184   - } else {
185   - promise.emit("success", response);
186   - }
  172 + callback((response.error && response.json) || null, response);
187 173 }
188 174 });
189 175 });
190   -
191   - return promise;
192 176 };
193 177
194 178 //
@@ -253,30 +237,22 @@ cradle.Connection.prototype.database = function (name) {
253 237
254 238 // A wrapper around `Connection.request`,
255 239 // which prepends the database name.
256   - query: function (method, path, options, data, headers) {
257   - return that.request(
258   - method, [name, path].join('/'), options, data, headers
259   - );
  240 + query: function (method, path /* [options], [data], [headers], [callback] */) {
  241 + var args = Array.prototype.slice.call(arguments, 2);
  242 + that.request.apply(that, [method, [name, path].join('/')].concat(args));
260 243 },
261   - exists: function () {
262   - var promise = new(events.EventEmitter),
263   - args = new(Args)(arguments);
264   -
265   - this.query('GET', '/').addCallback(function (err, res) {
  244 + exists: function (callback) {
  245 + this.query('GET', '/', function (err, res) {
266 246 if (err) {
267 247 if (res.headers.status === 404) {
268   - args.callback(null, false);
269   - promise.emit("success", false);
  248 + callback(null, false);
270 249 } else {
271   - args.callback(err, res);
272   - promise.emit("error", res);
  250 + callback(err, res);
273 251 }
274 252 } else {
275   - args.callback(null, true);
276   - promise.emit("success", true);
  253 + callback(null, true);
277 254 }
278 255 });
279   - return promise;
280 256 },
281 257
282 258 // Fetch either a single document from the database, or cache,
@@ -287,16 +263,16 @@ cradle.Connection.prototype.database = function (name) {
287 263 args = new(Args)(arguments);
288 264
289 265 if (Array.isArray(id)) { // Bulk GET
290   - return this.query('POST', '/_all_docs', { include_docs: true }, { keys: id })
291   - .addCallback(function (err, res) { args.callback(err, res) });
  266 + this.query('POST', '/_all_docs', { include_docs: true }, { keys: id },
  267 + function (err, res) { args.callback(err, res) });
292 268 } else {
293 269 if (rev && args.length === 2) {
294   - if (typeof(rev) === 'string') { options = {rev: rev} }
  270 + if (typeof(rev) === 'string') { options = { rev: rev } }
295 271 else if (typeof(rev) === 'object') { options = rev }
296 272 } else if (this.cache.has(id)) {
297 273 return args.callback(null, this.cache.get(id));
298 274 }
299   - return this.query('GET', id, options).addCallback(function (err, res) {
  275 + this.query('GET', id, options, function (err, res) {
300 276 if (! err) that.cache.save(res.id, res.json);
301 277 args.callback(err, res);
302 278 });
@@ -320,24 +296,23 @@ cradle.Connection.prototype.database = function (name) {
320 296 } else {
321 297 throw new(Error)("Couldn't save without a _rev");
322 298 }
  299 + this.insert(doc, args.callback);
323 300 } else {
324 301 this.insert.apply(arguments);
325 302 }
326   - return this.insert(doc, args.callback);
327 303 },
328 304
329   - put: function (id, doc) {
330   - var cache = this.cache, args = new(Args)(arguments);
  305 + put: function (id, doc, callback) {
  306 + var cache = this.cache;
331 307 if (typeof(id) !== 'string') { throw new(TypeError)("id must be a string") }
332   - return this.query('PUT', id, null, doc).addCallback(function (e, res) {
333   - if (! e) cache.save(id, cradle.merge({}, doc, { _rev: res.rev }));
334   - args.callback(e, res);
  308 + this.query('PUT', id, null, doc, function (e, res) {
  309 + if (! e) { cache.save(id, cradle.merge({}, doc, { _rev: res.rev })) }
  310 + callback && callback(e, res);
335 311 });
336 312 },
337 313
338   - head: function (id) {
339   - var args = new(Args)(arguments);
340   - return this.query('HEAD', id, null).addCallback(args.callback);
  314 + head: function (id, callback) {
  315 + this.query('HEAD', id, null, callback);
341 316 },
342 317
343 318 insert: function (/* [id], doc, ... */) {
@@ -353,16 +328,16 @@ cradle.Connection.prototype.database = function (name) {
353 328 } else {
354 329 doc = args.last;
355 330 }
356   - return this.query('PUT', id, null, doc).addCallback(writeThrough);
  331 + this.query('PUT', id, null, doc, writeThrough);
357 332
358 333 // PUT or POST a single document
359 334 } else if (args.length === 1 && !Array.isArray(args.first)) {
360 335 doc = args.first;
361 336 id = doc._id;
362 337 if (id) {
363   - return this.query('PUT', id, null, doc).addCallback(writeThrough);
  338 + this.query('PUT', id, null, doc, writeThrough);
364 339 } else {
365   - return this.query('POST', '/', null, doc).addCallback(writeThrough);
  340 + this.query('POST', '/', null, doc, writeThrough);
366 341 }
367 342
368 343 // Bulk insert
@@ -373,14 +348,13 @@ cradle.Connection.prototype.database = function (name) {
373 348 } else {
374 349 doc = {docs: args.all};
375 350 }
376   - return this.query('POST', '/_bulk_docs', {}, doc)
377   - .addCallback(function (err, res) {
  351 + this.query('POST', '/_bulk_docs', {}, doc, function (err, res) {
378 352 args.callback(err, res);
379 353 });
380 354 }
381 355
382 356 function writeThrough(err, res) {
383   - if (! err) that.cache.save(id, cradle.merge({}, doc, { _rev: res.rev }));
  357 + if (! err) { that.cache.save(id, cradle.merge({}, doc, { _rev: res.rev })) }
384 358 args.callback(err, res);
385 359 }
386 360 },
@@ -392,7 +366,7 @@ cradle.Connection.prototype.database = function (name) {
392 366 if (arguments.length > 1) {
393 367 throw new(Error)("destroy() doesn't take any additional arguments");
394 368 } else {
395   - return this.query('DELETE', '/').addCallback(callback);
  369 + this.query('DELETE', '/', callback);
396 370 }
397 371 },
398 372
@@ -404,33 +378,33 @@ cradle.Connection.prototype.database = function (name) {
404 378
405 379 if (typeof(rev) !== 'string') {
406 380 if (doc = this.cache.get(id)) { rev = doc._rev }
407   - else { throw new(Error)("rev needs to be supplied") }
  381 + else { throw new(Error)("rev needs to be supplied") }
408 382 }
409   - return this.query('DELETE', id, {rev: rev})
410   - .addCallback(function (err, res) {
411   - if (! err) that.cache.purge(id);
  383 + this.query('DELETE', id, {rev: rev}, function (err, res) {
  384 + if (! err) { that.cache.purge(id) }
412 385 args.callback(err, res);
413 386 });
414 387 },
415   - create: function (c) {
416   - return this.query('PUT', '/').addCallback(c);
  388 + create: function (callback) {
  389 + this.query('PUT', '/', callback);
417 390 },
418   - info: function (c) {
419   - return this.query('GET', '/').addCallback(c);
  391 + info: function (callback) {
  392 + this.query('GET', '/', callback);
420 393 },
421   - all: function (options) {
422   - return this.query('GET', '/_all_docs', typeof(options) === 'object' ? options : {})
423   - .addCallback(Args.last(arguments));
  394 + all: function (options, callback) {
  395 + if (arguments.length === 1) { callback = options, options = {} }
  396 + this.query('GET', '/_all_docs', options, callback);
424 397 },
425 398 compact: function (design) {
426   - return this.query('POST', '/_compact' + (typeof(design) === 'string' ? '/' + design : ''))
427   - .addCallback(Args.last(arguments));
  399 + this.query('POST', '/_compact' + (typeof(design) === 'string' ? '/' + design : ''),
  400 + Args.last(arguments));
428 401 },
429   - viewCleanup: function (c) {
430   - return this.query('POST', '/_view_cleanup').addCallback(c);
  402 + viewCleanup: function (callback) {
  403 + this.query('POST', '/_view_cleanup', callback);
431 404 },
432 405 allBySeq: function (options) {
433   - return this.query('GET', '/_all_docs_by_seq', options).addCallback(c);
  406 + options = typeof(options) === 'object' ? options : {};
  407 + this.query('GET', '/_all_docs_by_seq', options, Args.last(arguments));
434 408 },
435 409
436 410 // Query a view, passing any options to the query string.
@@ -444,9 +418,7 @@ cradle.Connection.prototype.database = function (name) {
444 418 if (k in options) { options[k] = JSON.stringify(options[k]) }
445 419 });
446 420 }
447   - return this.query(
448   - 'GET', ['_design', path[0], '_view', path[1]].join('/'), options
449   - ).addCallback(args.callback);
  421 + this.query('GET', ['_design', path[0], '_view', path[1]].join('/'), options, args.callback);
450 422 },
451 423
452 424 push: function (doc) {},
@@ -454,7 +426,6 @@ cradle.Connection.prototype.database = function (name) {
454 426 saveAttachment: function (docOrId, attachmentName, contentType, dataOrStream) {
455 427 var rev, id, doc, pathname, headers = {}, response, body = '', resHeaders, error, db = this;
456 428 var args = new(Args)(arguments);
457   - var promise = new(events.EventEmitter);
458 429
459 430 if (typeof(docOrId) === 'string') {
460 431 id = docOrId;
@@ -487,10 +458,8 @@ cradle.Connection.prototype.database = function (name) {
487 458 revpos: new(Number)(response.rev.match(/^\d+/)[0])
488 459 };
489 460 }
490   - args.callback(response);
491   - promise.emit("success", response);
  461 + args.callback(null, response);
492 462 });
493   - return promise;
494 463 },
495 464
496 465 getAttachment: function(docId, attachmentName) {
@@ -506,24 +475,23 @@ cradle.Connection.prototype.database = function (name) {
506 475 // Wrapper functions for the server API
507 476 //
508 477 cradle.Connection.prototype.databases = function (c) {
509   - return this.request('GET', '/_all_dbs').addCallback(c);
  478 + this.request('GET', '/_all_dbs', c);
510 479 };
511 480 cradle.Connection.prototype.config = function (c) {
512   - return this.request('GET', '/_config').addCallback(c);
  481 + this.request('GET', '/_config', c);
513 482 };
514 483 cradle.Connection.prototype.info = function (c) {
515   - return this.request('GET', '/').addCallback(c);
  484 + this.request('GET', '/', c);
516 485 };
517 486 cradle.Connection.prototype.stats = function (c) {
518   - return this.request('GET', '/_stats').addCallback(c);
  487 + this.request('GET', '/_stats', c);
519 488 };
520 489 cradle.Connection.prototype.activeTasks = function (c) {
521   - return this.request('GET', '/_active_tasks').addCallback(c);
  490 + this.request('GET', '/_active_tasks', c);
522 491 };
523 492 cradle.Connection.prototype.uuids = function (count, callback) {
524 493 if (typeof(count) === 'function') { callback = count, count = null }
525   - return this.request('GET', '/_uuids', count ? {count: count} : {})
526   - .addCallback(callback);
  494 + this.request('GET', '/_uuids', count ? {count: count} : {}, callback);
527 495 };
528 496
529 497 cradle.merge = function (target) {

0 comments on commit 59694c2

Please sign in to comment.
Something went wrong with that request. Please try again.