UNPKG

21.5 kBJavaScriptView Raw
1// Generated by CoffeeScript 1.10.0
2var ArrayResult, AtomFeed, Cursor, EventEmitter, Feed, IterableResult, OrderByLimitFeed, Promise, UnionedFeed, ar, aropt, error, mkErr, protoResponseType, setImmediate, util, varar,
3 bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
4 slice = [].slice,
5 extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
6 hasProp = {}.hasOwnProperty;
7
8error = require('./errors');
9
10util = require('./util');
11
12protoResponseType = require('./proto-def').Response.ResponseType;
13
14Promise = require('bluebird');
15
16EventEmitter = require('events').EventEmitter;
17
18ar = util.ar;
19
20varar = util.varar;
21
22aropt = util.aropt;
23
24mkErr = util.mkErr;
25
26if (typeof setImmediate === "undefined" || setImmediate === null) {
27 setImmediate = function(cb) {
28 return setTimeout(cb, 0);
29 };
30}
31
32IterableResult = (function() {
33 IterableResult.prototype.stackSize = 100;
34
35 function IterableResult(conn, token, opts, root) {
36 this._eachCb = bind(this._eachCb, this);
37 this._conn = conn;
38 this._token = token;
39 this._opts = opts;
40 this._root = root;
41 this._responses = [];
42 this._responseIndex = 0;
43 this._outstandingRequests = 1;
44 this._iterations = 0;
45 this._endFlag = false;
46 this._contFlag = false;
47 this._closeAsap = false;
48 this._cont = null;
49 this._cbQueue = [];
50 this._closeCb = null;
51 this._closeCbPromise = null;
52 this.next = this._next;
53 }
54
55 IterableResult.prototype._addResponse = function(response) {
56 if (response.t === this._type || response.t === protoResponseType.SUCCESS_SEQUENCE) {
57 if (response.r.length > 0) {
58 this._responses.push(response);
59 }
60 } else {
61 this._responses.push(response);
62 }
63 this._outstandingRequests -= 1;
64 if (response.t !== this._type) {
65 this._endFlag = true;
66 if (this._closeCb != null) {
67 switch (response.t) {
68 case protoResponseType.COMPILE_ERROR:
69 this._closeCb(mkErr(error.ReqlServerCompileError, response, this._root));
70 break;
71 case protoResponseType.CLIENT_ERROR:
72 this._closeCb(mkErr(error.ReqlClientError, response, this._root));
73 break;
74 case protoResponseType.RUNTIME_ERROR:
75 this._closeCb(mkErr(util.errorClass(response.e), response, this._root));
76 break;
77 default:
78 this._closeCb();
79 }
80 }
81 }
82 this._contFlag = false;
83 if (this._closeAsap === false) {
84 this._promptNext();
85 } else {
86 this.close(this._closeCb);
87 }
88 return this;
89 };
90
91 IterableResult.prototype._getCallback = function() {
92 var cb, immediateCb;
93 this._iterations += 1;
94 cb = this._cbQueue.shift();
95 if (this._iterations % this.stackSize === this.stackSize - 1) {
96 immediateCb = (function(err, row) {
97 return setImmediate(function() {
98 return cb(err, row);
99 });
100 });
101 return immediateCb;
102 } else {
103 return cb;
104 }
105 };
106
107 IterableResult.prototype._handleRow = function() {
108 var cb, response, row;
109 response = this._responses[0];
110 row = util.recursivelyConvertPseudotype(response.r[this._responseIndex], this._opts);
111 cb = this._getCallback();
112 this._responseIndex += 1;
113 if (this._responseIndex === response.r.length) {
114 this._responses.shift();
115 this._responseIndex = 0;
116 }
117 return cb(null, row);
118 };
119
120 IterableResult.prototype.bufferEmpty = function() {
121 return this._responses.length === 0 || this._responses[0].r.length <= this._responseIndex;
122 };
123
124 IterableResult.prototype._promptNext = function() {
125 var cb, errType, response;
126 if (this._closeCbPromise != null) {
127 cb = this._getCallback();
128 cb(new error.ReqlDriverError("Cursor is closed."));
129 }
130 while (this._cbQueue[0] != null) {
131 if (this.bufferEmpty() === true) {
132 if (this._endFlag === true) {
133 cb = this._getCallback();
134 cb(new error.ReqlDriverError("No more rows in the cursor."));
135 } else if (this._responses.length <= 1) {
136 this._promptCont();
137 }
138 return;
139 } else {
140 response = this._responses[0];
141 if (this._responses.length === 1) {
142 this._promptCont();
143 }
144 switch (response.t) {
145 case protoResponseType.SUCCESS_PARTIAL:
146 this._handleRow();
147 break;
148 case protoResponseType.SUCCESS_SEQUENCE:
149 if (response.r.length === 0) {
150 this._responses.shift();
151 } else {
152 this._handleRow();
153 }
154 break;
155 case protoResponseType.COMPILE_ERROR:
156 this._responses.shift();
157 cb = this._getCallback();
158 cb(mkErr(error.ReqlServerCompileError, response, this._root));
159 break;
160 case protoResponseType.CLIENT_ERROR:
161 this._responses.shift();
162 cb = this._getCallback();
163 cb(mkErr(error.ReqlClientError, response, this._root));
164 break;
165 case protoResponseType.RUNTIME_ERROR:
166 this._responses.shift();
167 cb = this._getCallback();
168 errType = util.errorClass(response.e);
169 cb(mkErr(errType, response, this._root));
170 break;
171 default:
172 this._responses.shift();
173 cb = this._getCallback();
174 cb(new error.ReqlDriverError("Unknown response type for cursor"));
175 }
176 }
177 }
178 };
179
180 IterableResult.prototype._promptCont = function() {
181 if ((!this._contFlag) && (!this._endFlag) && this._conn.isOpen()) {
182 this._contFlag = true;
183 this._outstandingRequests += 1;
184 return this._conn._continueQuery(this._token);
185 }
186 };
187
188 IterableResult.prototype.hasNext = function() {
189 throw new error.ReqlDriverError("The `hasNext` command has been removed since 1.13. Use `next` instead.");
190 };
191
192 IterableResult.prototype._next = varar(0, 1, function(cb) {
193 var fn;
194 if ((cb != null) && typeof cb !== "function") {
195 throw new error.ReqlDriverError("First argument to `next` must be a function or undefined.");
196 }
197 fn = (function(_this) {
198 return function(cb) {
199 _this._cbQueue.push(cb);
200 return _this._promptNext();
201 };
202 })(this);
203 return Promise.fromNode(fn).nodeify(cb);
204 });
205
206 IterableResult.prototype.close = varar(0, 1, function(cb) {
207 if (this._closeCbPromise != null) {
208 if (this._closeCbPromise.isPending()) {
209 this._closeCbPromise = this._closeCbPromise.nodeify(cb);
210 } else {
211 this._closeCbPromise = Promise.resolve().nodeify(cb);
212 }
213 } else {
214 if (this._endFlag) {
215 this._closeCbPromise = Promise.resolve().nodeify(cb);
216 this._responses = [];
217 this._responseIndex = 0;
218 } else {
219 this._closeCbPromise = new Promise((function(_this) {
220 return function(resolve, reject) {
221 _this._closeCb = function(err) {
222 _this._responses = [];
223 _this._responseIndex = 0;
224 while (_this._cbQueue.length > 0) {
225 _this._cbQueue.shift();
226 }
227 _this._outstandingRequests = 0;
228 if (err) {
229 return reject(err);
230 } else {
231 return resolve();
232 }
233 };
234 _this._closeAsap = true;
235 _this._outstandingRequests += 1;
236 return _this._conn._endQuery(_this._token);
237 };
238 })(this)).nodeify(cb);
239 }
240 }
241 return this._closeCbPromise;
242 });
243
244 IterableResult.prototype.each = varar(1, 2, function(cb, onFinished) {
245 var nextCb, self;
246 if (typeof cb !== 'function') {
247 throw new error.ReqlDriverError("First argument to each must be a function.");
248 }
249 if ((onFinished != null) && typeof onFinished !== 'function') {
250 throw new error.ReqlDriverError("Optional second argument to each must be a function.");
251 }
252 self = this;
253 nextCb = (function(_this) {
254 return function(err, data) {
255 if (err != null) {
256 if (err.message === 'No more rows in the cursor.') {
257 return typeof onFinished === "function" ? onFinished() : void 0;
258 } else {
259 return cb(err);
260 }
261 } else if (cb(null, data) !== false) {
262 return _this._next(nextCb);
263 } else {
264 return typeof onFinished === "function" ? onFinished() : void 0;
265 }
266 };
267 })(this);
268 return this._next(nextCb);
269 });
270
271 IterableResult.prototype.eachAsync = varar(1, 3, function(cb, errCb, options) {
272 var nextCb, pending, resPromise, userCb;
273 if (options == null) {
274 options = {
275 concurrency: 1
276 };
277 }
278 if (typeof cb !== 'function') {
279 throw new error.ReqlDriverError('First argument to eachAsync must be a function.');
280 }
281 if (errCb != null) {
282 if (typeof errCb === 'object') {
283 options = errCb;
284 errCb = void 0;
285 } else if (typeof errCb !== 'function') {
286 throw new error.ReqlDriverError("Optional second argument to eachAsync must be a function or `options` object");
287 }
288 }
289 if (!(options && typeof options.concurrency === 'number' && options.concurrency > 0)) {
290 throw new error.ReqlDriverError("Optional `options.concurrency` argument to eachAsync must be a positive number");
291 }
292 pending = [];
293 userCb = function(data) {
294 var doneChecking, handlerArg, handlerCalled, ret;
295 if (cb.length <= 1) {
296 ret = Promise.resolve(cb(data));
297 } else {
298 handlerCalled = false;
299 doneChecking = false;
300 handlerArg = void 0;
301 ret = Promise.fromNode(function(handler) {
302 var asyncRet;
303 asyncRet = cb(data, function(err) {
304 handlerCalled = true;
305 if (doneChecking) {
306 return handler(err);
307 } else {
308 return handlerArg = err;
309 }
310 });
311 if (asyncRet !== void 0) {
312 handler(new error.ReqlDriverError("A two-argument row handler for eachAsync may only return undefined."));
313 } else if (handlerCalled) {
314 handler(handlerArg);
315 }
316 return doneChecking = true;
317 });
318 }
319 return ret.then(function(data) {
320 if (data === void 0 || typeof data === Promise) {
321 return data;
322 }
323 throw new error.ReqlDriverError("Row handler for eachAsync may only return a Promise or undefined.");
324 });
325 };
326 nextCb = (function(_this) {
327 return function() {
328 if (_this._closeCbPromise != null) {
329 return Promise.resolve().then(function(data) {
330 throw new error.ReqlDriverError("Cursor is closed.");
331 });
332 } else {
333 return _this._next().then(function(data) {
334 if (pending.length < options.concurrency) {
335 return data;
336 }
337 return Promise.any(pending)["catch"](Promise.AggregateError, function(errs) {
338 throw errs[0];
339 })["return"](data);
340 }).then(function(data) {
341 var p;
342 p = userCb(data).then(function() {
343 return pending.splice(pending.indexOf(p), 1);
344 });
345 return pending.push(p);
346 }).then(nextCb)["catch"](function(err) {
347 if ((err != null ? err.message : void 0) !== 'No more rows in the cursor.') {
348 throw err;
349 }
350 return Promise.all(pending);
351 });
352 }
353 };
354 })(this);
355 resPromise = nextCb().then(function() {
356 if (errCb != null) {
357 return errCb(null);
358 }
359 })["catch"](function(err) {
360 if (errCb != null) {
361 return errCb(err);
362 }
363 throw err;
364 });
365 if (errCb == null) {
366 return resPromise;
367 }
368 return null;
369 });
370
371 IterableResult.prototype._each = IterableResult.prototype.each;
372
373 IterableResult.prototype._eachAsync = IterableResult.prototype.eachAsync;
374
375 IterableResult.prototype.toArray = varar(0, 1, function(cb) {
376 var results, wrapper;
377 if ((cb != null) && typeof cb !== 'function') {
378 throw new error.ReqlDriverCompileError("First argument to `toArray` must be a function or undefined.");
379 }
380 results = [];
381 wrapper = (function(_this) {
382 return function(res) {
383 results.push(res);
384 return void 0;
385 };
386 })(this);
387 return this.eachAsync(wrapper).then((function(_this) {
388 return function() {
389 return results;
390 };
391 })(this)).nodeify(cb);
392 });
393
394 IterableResult.prototype._makeEmitter = function() {
395 this.emitter = new EventEmitter;
396 this.each = function() {
397 throw new error.ReqlDriverError("You cannot use the cursor interface and the EventEmitter interface at the same time.");
398 };
399 return this.next = function() {
400 throw new error.ReqlDriverError("You cannot use the cursor interface and the EventEmitter interface at the same time.");
401 };
402 };
403
404 IterableResult.prototype.addListener = function(event, listener) {
405 if (this.emitter == null) {
406 this._makeEmitter();
407 setImmediate((function(_this) {
408 return function() {
409 return _this._each(_this._eachCb);
410 };
411 })(this));
412 }
413 return this.emitter.addListener(event, listener);
414 };
415
416 IterableResult.prototype.on = function(event, listener) {
417 if (this.emitter == null) {
418 this._makeEmitter();
419 setImmediate((function(_this) {
420 return function() {
421 return _this._each(_this._eachCb);
422 };
423 })(this));
424 }
425 return this.emitter.on(event, listener);
426 };
427
428 IterableResult.prototype.once = function(event, listener) {
429 if (this.emitter == null) {
430 this._makeEmitter();
431 setImmediate((function(_this) {
432 return function() {
433 return _this._each(_this._eachCb);
434 };
435 })(this));
436 }
437 return this.emitter.once(event, listener);
438 };
439
440 IterableResult.prototype.removeListener = function(event, listener) {
441 if (this.emitter == null) {
442 this._makeEmitter();
443 setImmediate((function(_this) {
444 return function() {
445 return _this._each(_this._eachCb);
446 };
447 })(this));
448 }
449 return this.emitter.removeListener(event, listener);
450 };
451
452 IterableResult.prototype.removeAllListeners = function(event) {
453 if (this.emitter == null) {
454 this._makeEmitter();
455 setImmediate((function(_this) {
456 return function() {
457 return _this._each(_this._eachCb);
458 };
459 })(this));
460 }
461 return this.emitter.removeAllListeners(event);
462 };
463
464 IterableResult.prototype.setMaxListeners = function(n) {
465 if (this.emitter == null) {
466 this._makeEmitter();
467 setImmediate((function(_this) {
468 return function() {
469 return _this._each(_this._eachCb);
470 };
471 })(this));
472 }
473 return this.emitter.setMaxListeners(n);
474 };
475
476 IterableResult.prototype.listeners = function(event) {
477 if (this.emitter == null) {
478 this._makeEmitter();
479 setImmediate((function(_this) {
480 return function() {
481 return _this._each(_this._eachCb);
482 };
483 })(this));
484 }
485 return this.emitter.listeners(event);
486 };
487
488 IterableResult.prototype.emit = function() {
489 var args, ref;
490 args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
491 if (this.emitter == null) {
492 this._makeEmitter();
493 setImmediate((function(_this) {
494 return function() {
495 return _this._each(_this._eachCb);
496 };
497 })(this));
498 }
499 return (ref = this.emitter).emit.apply(ref, args);
500 };
501
502 IterableResult.prototype._eachCb = function(err, data) {
503 if (err != null) {
504 return this.emitter.emit('error', err);
505 } else {
506 return this.emitter.emit('data', data);
507 }
508 };
509
510 return IterableResult;
511
512})();
513
514Cursor = (function(superClass) {
515 extend(Cursor, superClass);
516
517 function Cursor() {
518 this._type = protoResponseType.SUCCESS_PARTIAL;
519 Cursor.__super__.constructor.apply(this, arguments);
520 }
521
522 Cursor.prototype.toString = ar(function() {
523 return "[object Cursor]";
524 });
525
526 return Cursor;
527
528})(IterableResult);
529
530Feed = (function(superClass) {
531 extend(Feed, superClass);
532
533 function Feed() {
534 this._type = protoResponseType.SUCCESS_PARTIAL;
535 Feed.__super__.constructor.apply(this, arguments);
536 }
537
538 Feed.prototype.hasNext = function() {
539 throw new error.ReqlDriverError("`hasNext` is not available for feeds.");
540 };
541
542 Feed.prototype.toArray = function() {
543 throw new error.ReqlDriverError("`toArray` is not available for feeds.");
544 };
545
546 Feed.prototype.toString = ar(function() {
547 return "[object Feed]";
548 });
549
550 return Feed;
551
552})(IterableResult);
553
554UnionedFeed = (function(superClass) {
555 extend(UnionedFeed, superClass);
556
557 function UnionedFeed() {
558 this._type = protoResponseType.SUCCESS_PARTIAL;
559 UnionedFeed.__super__.constructor.apply(this, arguments);
560 }
561
562 UnionedFeed.prototype.hasNext = function() {
563 throw new error.ReqlDriverError("`hasNext` is not available for feeds.");
564 };
565
566 UnionedFeed.prototype.toArray = function() {
567 throw new error.ReqlDriverError("`toArray` is not available for feeds.");
568 };
569
570 UnionedFeed.prototype.toString = ar(function() {
571 return "[object UnionedFeed]";
572 });
573
574 return UnionedFeed;
575
576})(IterableResult);
577
578AtomFeed = (function(superClass) {
579 extend(AtomFeed, superClass);
580
581 function AtomFeed() {
582 this._type = protoResponseType.SUCCESS_PARTIAL;
583 AtomFeed.__super__.constructor.apply(this, arguments);
584 }
585
586 AtomFeed.prototype.hasNext = function() {
587 throw new error.ReqlDriverError("`hasNext` is not available for feeds.");
588 };
589
590 AtomFeed.prototype.toArray = function() {
591 throw new error.ReqlDriverError("`toArray` is not available for feeds.");
592 };
593
594 AtomFeed.prototype.toString = ar(function() {
595 return "[object AtomFeed]";
596 });
597
598 return AtomFeed;
599
600})(IterableResult);
601
602OrderByLimitFeed = (function(superClass) {
603 extend(OrderByLimitFeed, superClass);
604
605 function OrderByLimitFeed() {
606 this._type = protoResponseType.SUCCESS_PARTIAL;
607 OrderByLimitFeed.__super__.constructor.apply(this, arguments);
608 }
609
610 OrderByLimitFeed.prototype.hasNext = function() {
611 throw new error.ReqlDriverError("`hasNext` is not available for feeds.");
612 };
613
614 OrderByLimitFeed.prototype.toArray = function() {
615 throw new error.ReqlDriverError("`toArray` is not available for feeds.");
616 };
617
618 OrderByLimitFeed.prototype.toString = ar(function() {
619 return "[object OrderByLimitFeed]";
620 });
621
622 return OrderByLimitFeed;
623
624})(IterableResult);
625
626ArrayResult = (function(superClass) {
627 extend(ArrayResult, superClass);
628
629 function ArrayResult() {
630 return ArrayResult.__super__.constructor.apply(this, arguments);
631 }
632
633 ArrayResult.prototype._hasNext = ar(function() {
634 if (this.__index == null) {
635 this.__index = 0;
636 }
637 return this.__index < this.length;
638 });
639
640 ArrayResult.prototype._next = varar(0, 1, function(cb) {
641 var fn;
642 fn = (function(_this) {
643 return function(cb) {
644 var self;
645 if (_this._closeCbPromise != null) {
646 cb(new error.ReqlDriverError("Cursor is closed."));
647 }
648 if (_this._hasNext() === true) {
649 self = _this;
650 if (self.__index % _this.stackSize === _this.stackSize - 1) {
651 return setImmediate(function() {
652 return cb(null, self[self.__index++]);
653 });
654 } else {
655 return cb(null, self[self.__index++]);
656 }
657 } else {
658 return cb(new error.ReqlDriverError("No more rows in the cursor."));
659 }
660 };
661 })(this);
662 return Promise.fromNode(fn).nodeify(cb);
663 });
664
665 ArrayResult.prototype.toArray = varar(0, 1, function(cb) {
666 var fn;
667 fn = (function(_this) {
668 return function(cb) {
669 if (_this._closeCbPromise != null) {
670 cb(new error.ReqlDriverError("Cursor is closed."));
671 }
672 if (_this.__index != null) {
673 return cb(null, _this.slice(_this.__index, _this.length));
674 } else {
675 return cb(null, _this);
676 }
677 };
678 })(this);
679 return Promise.fromNode(fn).nodeify(cb);
680 });
681
682 ArrayResult.prototype.close = varar(0, 1, function(cb) {
683 this.length = 0;
684 this.__index = 0;
685 this._closeCbPromise = Promise.resolve().nodeify(cb);
686 return this._closeCbPromise;
687 });
688
689 ArrayResult.prototype.makeIterable = function(response) {
690 var method, name, ref;
691 response.__proto__ = {};
692 ref = ArrayResult.prototype;
693 for (name in ref) {
694 method = ref[name];
695 if (name !== 'constructor') {
696 if (name === '_next') {
697 response.__proto__['next'] = method;
698 response.__proto__['_next'] = method;
699 } else {
700 response.__proto__[name] = method;
701 }
702 }
703 }
704 response.__proto__.__proto__ = [].__proto__;
705 return response;
706 };
707
708 return ArrayResult;
709
710})(IterableResult);
711
712module.exports.Cursor = Cursor;
713
714module.exports.Feed = Feed;
715
716module.exports.AtomFeed = AtomFeed;
717
718module.exports.OrderByLimitFeed = OrderByLimitFeed;
719
720module.exports.makeIterable = ArrayResult.prototype.makeIterable;