neo4j
Version:
Neo4j driver (REST API client) for Node.js
589 lines (553 loc) • 17.4 kB
JavaScript
// Generated by CoffeeScript 1.8.0
(function() {
var $, Constraint, Error, GraphDatabase, Index, Node, Relationship, Request, Transaction, URL, assert, lib, _normalizeAuth, _transform,
__slice = [].slice;
$ = require('underscore');
assert = require('assert');
Constraint = require('./Constraint');
Error = require('./errors').Error;
Index = require('./Index');
lib = require('../package.json');
Node = require('./Node');
Relationship = require('./Relationship');
Request = require('request');
Transaction = require('./Transaction');
URL = require('url');
module.exports = GraphDatabase = (function() {
GraphDatabase.prototype.headers = {
'User-Agent': "node-neo4j/" + lib.version
};
function GraphDatabase(opts) {
var uri, _ref;
if (opts == null) {
opts = {};
}
if (typeof opts === 'string') {
opts = {
url: opts
};
}
this.url = opts.url, this.auth = opts.auth, this.headers = opts.headers, this.proxy = opts.proxy, this.agent = opts.agent;
if (!this.url) {
throw new TypeError('URL to Neo4j required');
}
uri = URL.parse(this.url);
if (uri.auth && (this.auth != null)) {
delete uri.auth;
this.url = URL.format(uri);
}
this.auth = _normalizeAuth((_ref = this.auth) != null ? _ref : uri.auth);
this.headers || (this.headers = {});
this.headers = $(this.headers).chain().clone().defaults(this.constructor.prototype.headers).value();
}
GraphDatabase.prototype.http = function(opts, cb) {
var body, headers, method, path, raw;
if (opts == null) {
opts = {};
}
if (typeof opts === 'string') {
opts = {
path: opts
};
}
method = opts.method, path = opts.path, headers = opts.headers, body = opts.body, raw = opts.raw;
if (!path) {
throw new TypeError('Path required');
}
method || (method = 'GET');
headers || (headers = {});
headers = $(headers).chain().clone().defaults(this.headers).extend({
'X-Stream': 'true'
}).value();
return Request({
method: method,
url: URL.resolve(this.url, path),
proxy: this.proxy,
auth: this.auth,
headers: headers,
agent: this.agent,
json: body != null ? body : true,
encoding: 'utf8',
gzip: true
}, cb && (function(_this) {
return function(err, resp) {
if (err) {
return cb(err);
}
if (raw) {
return cb(null, resp);
}
if (err = Error._fromResponse(resp)) {
return cb(err);
}
return cb(null, _transform(resp.body));
};
})(this));
};
GraphDatabase.prototype.checkPasswordChangeNeeded = function(cb) {
var _ref;
if (!((_ref = this.auth) != null ? _ref.username : void 0)) {
throw new TypeError('No `auth` specified in constructor!');
}
return this.http({
method: 'GET',
path: "/user/" + (encodeURIComponent(this.auth.username))
}, function(err, user) {
if (err) {
return cb(err);
}
return cb(null, user.password_change_required);
});
};
GraphDatabase.prototype.changePassword = function(opts, cb) {
var password, _ref;
if (opts == null) {
opts = {};
}
if (typeof opts === 'string') {
opts = {
password: opts
};
}
password = opts.password;
if (!((_ref = this.auth) != null ? _ref.username : void 0)) {
throw new TypeError('No `auth` specified in constructor!');
}
if (!password) {
throw new TypeError('Password required');
}
return this.http({
method: 'POST',
path: "/user/" + (encodeURIComponent(this.auth.username)) + "/password",
body: {
password: password
}
}, (function(_this) {
return function(err) {
if (err) {
return cb(err);
}
_this.auth.password = password;
return cb(null);
};
})(this));
};
GraphDatabase.prototype.cypher = function(opts, cb, _tx) {
var body, commit, format, formats, headers, lean, method, params, path, queries, query, rollback, single;
if (opts == null) {
opts = {};
}
if (typeof opts === 'string') {
opts = {
query: opts
};
}
if (opts instanceof Array) {
opts = {
queries: opts
};
}
queries = opts.queries, query = opts.query, params = opts.params, headers = opts.headers, lean = opts.lean, commit = opts.commit, rollback = opts.rollback;
if (!_tx && rollback) {
throw new Error('Illegal state: rolling back without a transaction!');
}
if (commit && rollback) {
throw new Error('Illegal state: both committing and rolling back!');
}
if (rollback && (query || queries)) {
throw new Error('Illegal state: rolling back with query/queries!');
}
if (!_tx && commit === false) {
throw new TypeError('Can’t refuse to commit without a transaction! To begin a new transaction without committing, call `db.beginTransaction()`, and then call `cypher` on that.');
}
if (!_tx && !(query || queries)) {
throw new TypeError('Query or queries required');
}
if (query && queries) {
throw new TypeError('Can’t supply both a single query and a batch of queries! Do you have a bug in your code?');
}
if (queries && params) {
throw new TypeError('When batching multiple queries, params must be supplied with each query, not globally.');
}
if (queries && lean) {
throw new TypeError('When batching multiple queries, `lean` must be specified with each query, not globally.');
}
if ((commit || rollback) && !(query || queries) && !_tx._id) {
cb(null, null);
return;
}
method = 'POST';
if (rollback) {
method = 'DELETE';
}
path = '/db/data/transaction';
if (_tx != null ? _tx._id : void 0) {
path += "/" + _tx._id;
}
if (commit || !_tx) {
path += '/commit';
}
if (query) {
queries = [
{
query: query,
params: params,
lean: lean
}
];
single = true;
} else {
single = !queries;
queries || (queries = []);
}
formats = [];
body = {
statements: (function() {
var _i, _len, _ref, _results;
_results = [];
for (_i = 0, _len = queries.length; _i < _len; _i++) {
query = queries[_i];
if (typeof query === 'string') {
query = {
query: query
};
}
if (query.headers) {
throw new TypeError('When batching multiple queries, custom request headers cannot be supplied per query; they must be supplied globally.');
}
_ref = query, query = _ref.query, params = _ref.params, lean = _ref.lean;
formats.push(format = lean ? 'row' : 'rest');
_results.push({
statement: query,
parameters: params || {},
resultDataContents: [format]
});
}
return _results;
})()
};
return this.http({
method: method,
path: path,
headers: headers,
body: body,
raw: true
}, (function(_this) {
return function(err, resp) {
var columns, data, error, errors, i, result, results, _ref;
if (err) {
return cb(err);
}
if (err = Error._fromResponse(resp)) {
return cb(err);
}
if (_tx != null) {
_tx._updateFromResponse(resp);
}
_ref = resp.body, results = _ref.results, errors = _ref.errors;
results = (function() {
var _i, _len, _results;
_results = [];
for (i = _i = 0, _len = results.length; _i < _len; i = ++_i) {
result = results[i];
columns = result.columns, data = result.data;
format = formats[i];
_results.push($(data).pluck(format).map(function(row) {
var column, j, _j, _len1;
result = {};
for (j = _j = 0, _len1 = columns.length; _j < _len1; j = ++_j) {
column = columns[j];
result[column] = row[j];
}
if (format === 'rest') {
result = _transform(result);
}
return result;
}));
}
return _results;
})();
if (single) {
if (queries.length) {
assert.equal(queries.length, 1, 'There should be *exactly* one query given.');
assert(results.length <= 1, 'There should be *at most* one set of results.');
results = results[0];
} else {
assert.equal(results.length, 0, 'There should be *no* results.');
results = null;
}
}
if (errors.length) {
error = errors[0];
err = Error._fromObject(error);
}
return cb(err, results);
};
})(this));
};
GraphDatabase.prototype.beginTransaction = function() {
return new Transaction(this);
};
GraphDatabase.prototype.getLabels = function(cb) {
return this.http({
method: 'GET',
path: '/db/data/labels'
}, cb);
};
GraphDatabase.prototype.getPropertyKeys = function(cb) {
return this.http({
method: 'GET',
path: '/db/data/propertykeys'
}, cb);
};
GraphDatabase.prototype.getRelationshipTypes = function(cb) {
return this.http({
method: 'GET',
path: '/db/data/relationship/types'
}, cb);
};
GraphDatabase.prototype.getIndexes = function(opts, cb) {
var label, path;
if (opts == null) {
opts = {};
}
if (typeof opts === 'function') {
cb = opts;
opts = {};
}
if (typeof opts === 'string') {
opts = {
label: opts
};
}
label = opts.label;
path = '/db/data/schema/index';
if (label) {
path += "/" + (encodeURIComponent(label));
}
return this.http({
method: 'GET',
path: path
}, function(err, indexes) {
return cb(err, indexes != null ? indexes.map(Index._fromRaw) : void 0);
});
};
GraphDatabase.prototype.hasIndex = function(opts, cb) {
var label, property;
if (opts == null) {
opts = {};
}
label = opts.label, property = opts.property;
if (!(label && property)) {
throw new TypeError('Label and property required to query whether an index exists.');
}
return this.getIndexes({
label: label
}, function(err, indexes) {
return cb(err, indexes != null ? indexes.some(function(index) {
return index.label === label && index.property === property;
}) : void 0);
});
};
GraphDatabase.prototype.createIndex = function(opts, cb) {
var label, property;
if (opts == null) {
opts = {};
}
label = opts.label, property = opts.property;
if (!(label && property)) {
throw new TypeError('Label and property required to create an index.');
}
return this.http({
method: 'POST',
path: "/db/data/schema/index/" + (encodeURIComponent(label)),
body: {
'property_keys': [property]
},
raw: true
}, function(err, resp) {
if (err) {
return cb(err);
}
if (resp.statusCode === 409) {
return cb(null, null);
}
if (err = Error._fromResponse(resp)) {
return cb(err);
}
return cb(err, resp.body ? Index._fromRaw(resp.body) : void 0);
});
};
GraphDatabase.prototype.dropIndex = function(opts, cb) {
var label, property;
if (opts == null) {
opts = {};
}
label = opts.label, property = opts.property;
if (!(label && property)) {
throw new TypeError('Label and property required to drop an index.');
}
return this.http({
method: 'DELETE',
path: "/db/data/schema/index/" + (encodeURIComponent(label)) + "/" + (encodeURIComponent(property)),
raw: true
}, function(err, resp) {
if (err) {
return cb(err);
}
if (resp.statusCode === 404) {
return cb(null, false);
}
if (err = Error._fromResponse(resp)) {
return cb(err);
}
return cb(err, true);
});
};
GraphDatabase.prototype.getConstraints = function(opts, cb) {
var label, path;
if (opts == null) {
opts = {};
}
if (typeof opts === 'function') {
cb = opts;
opts = {};
}
if (typeof opts === 'string') {
opts = {
label: opts
};
}
label = opts.label;
path = '/db/data/schema/constraint';
if (label) {
path += "/" + (encodeURIComponent(label));
}
return this.http({
method: 'GET',
path: path
}, function(err, constraints) {
return cb(err, constraints != null ? constraints.map(Constraint._fromRaw) : void 0);
});
};
GraphDatabase.prototype.hasConstraint = function(opts, cb) {
var label, property;
if (opts == null) {
opts = {};
}
label = opts.label, property = opts.property;
if (!(label && property)) {
throw new TypeError('Label and property required to query whether a constraint exists.');
}
return this.http({
method: 'GET',
path: "/db/data/schema/constraint/" + (encodeURIComponent(label)) + "/uniqueness"
}, function(err, constraints) {
if (err) {
return cb(err);
} else {
return cb(null, constraints.some(function(constraint) {
constraint = Constraint._fromRaw(constraint);
return constraint.label === label && constraint.property === property;
}));
}
});
};
GraphDatabase.prototype.createConstraint = function(opts, cb) {
var label, property;
if (opts == null) {
opts = {};
}
label = opts.label, property = opts.property;
if (!(label && property)) {
throw new TypeError('Label and property required to create a constraint.');
}
return this.http({
method: 'POST',
path: "/db/data/schema/constraint/" + (encodeURIComponent(label)) + "/uniqueness",
body: {
'property_keys': [property]
},
raw: true
}, function(err, resp) {
if (err) {
return cb(err);
}
if (resp.statusCode === 409) {
return cb(null, null);
}
if (err = Error._fromResponse(resp)) {
return cb(err);
}
return cb(err, resp.body ? Constraint._fromRaw(resp.body) : void 0);
});
};
GraphDatabase.prototype.dropConstraint = function(opts, cb) {
var label, property;
if (opts == null) {
opts = {};
}
label = opts.label, property = opts.property;
if (!(label && property)) {
throw new TypeError('Label and property required to drop a constraint.');
}
return this.http({
method: 'DELETE',
path: "/db/data/schema/constraint/" + (encodeURIComponent(label)) + "/uniqueness/" + (encodeURIComponent(property)),
raw: true
}, function(err, resp) {
if (err) {
return cb(err);
}
if (resp.statusCode === 404) {
return cb(null, false);
}
if (err = Error._fromResponse(resp)) {
return cb(err);
}
return cb(err, true);
});
};
return GraphDatabase;
})();
_normalizeAuth = function(auth) {
var password, passwordParts, username, _ref;
if (!auth) {
return null;
}
if (typeof auth === 'string') {
_ref = auth.split(':'), username = _ref[0], passwordParts = 2 <= _ref.length ? __slice.call(_ref, 1) : [];
password = passwordParts.join(':');
auth = {
username: username,
password: password
};
}
if ((Object.keys(auth)).length === 0) {
return null;
}
return auth;
};
_transform = function(obj) {
var key, map, node, rel, val;
if ((!obj) || (typeof obj !== 'object')) {
return obj;
}
if (obj instanceof Array) {
return obj.map(_transform);
}
if (rel = Relationship._fromRaw(obj)) {
return rel;
}
if (node = Node._fromRaw(obj)) {
return node;
}
map = {};
for (key in obj) {
val = obj[key];
map[key] = _transform(val);
}
return map;
};
}).call(this);
//# sourceMappingURL=GraphDatabase.js.map