UNPKG

neo4j-fiber

Version:

Most advanced and efficient Neo4j REST API Driver, with support of https and GrapheneDB

221 lines (198 loc) 6.06 kB
var _ = require('./helpers')._; var check = require('./check').check; /* @locus Server @summary Implementation of cursor for Neo4j results @class Neo4jCursor */ function Neo4jCursor (_cursor) { this._cursor = _cursor; this.length = this._cursor.length; this._current = 0; this.hasNext = (this._cursor.length > 1); this.hasPrevious = false; } Neo4jCursor.define('cursor', { get: function () { return this._cursor; }, set: function () { console.warn('This is not going to work, you trying to reset cursor, make new Cypher query instead'); } }); /* @locus Server @summary Returns array of fetched rows. If query was passed with `reactive` option - data will be updated each event loop. @name fetch @class Neo4jCursor @returns {[Object]} - Returns array of fetched rows */ Neo4jCursor.prototype.fetch = function (firstOnly) { var data = []; this.forEach(function (row) { data.push(row); }, firstOnly); return data; }; /* @locus Server @summary Move cursor to first item and return it @name first @class Neo4jCursor @returns {[Object]} - Array of data instances or `undefined` if cursor has no items */ Neo4jCursor.prototype.first = function () { this._current = 0; this.hasNext = (this._cursor.length > 1); this.hasPrevious = false; return this._cursor[0]; }; /* @locus Server @summary Get current data instance(s) on cursor @name current @class Neo4jCursor @returns {[Object]} - Array of data instances or `undefined` if cursor has no items */ Neo4jCursor.prototype.current = function () { return this._cursor[this._current]; }; /* @locus Server @summary Go to next item on cursor and return it @name next @class Neo4jCursor @returns {[Object]} - Array of data instances, or `undefined` if no next item */ Neo4jCursor.prototype.next = function () { if (this.hasNext) { if (this._current <= this.length - 1) { ++this._current; this.hasNext = (this._current !== this.length - 1); this.hasPrevious = true; return this._cursor[this._current]; } } }; /* @locus Server @summary Go to previous item on cursor and return it @name previous @class Neo4jCursor @returns {[Object]} - Array of data instances, or `undefined` if no previous item */ Neo4jCursor.prototype.previous = function () { if (this.hasPrevious) { if (this._current >= 1) { --this._current; this.hasNext = true; this.hasPrevious = (this._current !== 0); return this._cursor[this._current]; } } }; /* @locus Server @summary [EXPEMENETAL] Puts all unique objects from current cursor into Mongo collection @name toMongo @class Neo4jCursor @param {Collection} MongoCollection - Instance of Mongo collection created via `new Mongo.Collection()` @returns {Collection} */ Neo4jCursor.prototype.toMongo = function (MongoCollection) { MongoCollection._ensureIndex({ id: 1 }, { background: true, sparse: true, unique: true }); var nodes = {}; this.forEach(function (row) { var node, nodeAlias; for (nodeAlias in row) { node = row[nodeAlias]; if (node != null ? node.id : void 0) { if (nodes[node.id] == null) { nodes[node.id] = { columns: [nodeAlias] }; } nodes[node.id].columns = _.union(nodes[node.id].columns, [nodeAlias]); nodes[node.id] = _.extend(nodes[node.id], node); if (nodes[node.id]._service) { nodes[node.id]._service = void 0; delete nodes[node.id]._service; } MongoCollection.upsert({ id: node.id }, { $set: nodes[node.id] }); } } }); return MongoCollection; }; /* @locus Server @summary Iterates thought Neo4j query results. And returns data as `Neo4jData`, `Neo4jRelationship` or `Neo4jNode` instance (depends from Cypher query). This function will move cursor to latest item. @name each @class Neo4jCursor @param {Function} callback - Callback function, with `node` (as `Neo4jData`, `Neo4jRelationship` or `Neo4jNode` instance(s)), `num`, `cursor` arguments @returns {undefined} */ Neo4jCursor.prototype.each = function (callback) { check(callback, Function); if (this.length > 0) { var first = true; while (this.hasNext || first) { if (first) { callback(this.first(), this._current, this._cursor); first = false; } else { callback(this.next(), this._current, this._cursor); } } } }; /* @locus Server @summary Iterates though Neo4j query results. If query was passed with `reactive` option - data will be updated each event loop. @name forEach @class Neo4jCursor @param {Function} callback - Callback function, with `data` (plain object), `num`, `cursor` arguments @returns {undefined} */ Neo4jCursor.prototype.forEach = function (callback, firstOnly) { var nodeAlias, i, rowId = -1; check(callback, Function); while (++rowId < this.cursor.length) { var data = {}; if (this.cursor[rowId] && typeof this.cursor[rowId].get === 'function') { data = this.cursor[rowId].get(); } else if (_.isObject(this.cursor[rowId])) { for (nodeAlias in this.cursor[rowId]) { if (_.isArray(this.cursor[rowId][nodeAlias])) { data[nodeAlias] = []; for (i = 0; i < this.cursor[rowId][nodeAlias].length; i++) { if (this.cursor[rowId][nodeAlias][i] && typeof this.cursor[rowId][nodeAlias][i].get === 'function') { data[nodeAlias].push(this.cursor[rowId][nodeAlias][i].get()); } else { data[nodeAlias].push(this.cursor[rowId][nodeAlias][i]); } } } else if (this.cursor[rowId][nodeAlias] && typeof this.cursor[rowId][nodeAlias].get === 'function') { data[nodeAlias] = this.cursor[rowId][nodeAlias].get(); } else { data[nodeAlias] = this.cursor[rowId][nodeAlias]; } } } callback(data, rowId, this._cursor); if (firstOnly) { break; } } }; module.exports = Neo4jCursor;