Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

seraph

Package Overview
Dependencies
Maintainers
2
Versions
53
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

seraph - npm Package Compare versions

Comparing version 0.8.0 to 0.9.1

lib/legacyindex.js

289

lib/index.js

@@ -6,258 +6,53 @@ var async = require('async');

function isValidType(type, callback) {
if (type !== 'node' && type !== 'relationship') {
callback(new Error("Invalid index type (should be 'node' or " +
"'relationship'."));
return false;
}
return true;
}
// although it looks like this will support compound keys, neo4j-2 doesn't yet,
// so attempting to create one will just give you an error from neo4j.
exports.create = function(label, keys, callback) {
if (!Array.isArray(keys)) keys = [keys];
function saveUnique(mode) {
return function() {
var args = [].slice.call(arguments);
var type = args.shift();
args.push(mode);
if (type == 'node') return saveUniqueNode.apply(this, args);
else return saveUniqueRel.apply(this, args);
};
label = encodeURIComponent(label);
var body = { property_keys: keys };
var endpoint = util.format('schema/index/%s', label);
var op = this.operation(endpoint, 'POST', body);
this.call(op, function(err, index) {
if (err) callback(err);
else callback(null, index);
});
};
function saveUniqueNode(node, index, key, value, callback, mode) {
// this will need to be updated when compound keys are supported
exports.createIfNone = function(label, keys, callback) {
var self = this;
var request = {
key: key,
value: value,
properties: node
};
var endpoint = util.format('index/node/%s?uniqueness=%s', index, mode);
var op = this.operation(endpoint, 'POST', request);
this.call(op, function(err, node) {
if (err) return callback(err);
callback(null, this._createNodeObject(node));
exports.create.call(self, label, keys, function(err, index) {
if (!err) return callback(null, index);
if (err.statusCode != 409) return callback(err);
exports.indexes.call(self, label, function(err, indexes) {
if (err) return callback(err);
var index = indexes.filter(function(index) {
return index.property_keys[0] == keys;
});
callback(null, index[0]);
});
});
};
function saveUniqueRel(start, rel, end, props, idx, key, value, cb, mode) {
var self = this;
if (typeof props == 'string') {
mode = cb;
cb = value;
value = key;
key = idx;
idx = props;
props = undefined;
}
start = this._getId(start);
end = this._getId(end);
if (!this._isValidId(start) || !this._isValidId(end)) {
return callback(new Error("Invalid ID"));
}
var request = {
key: key,
value: value,
start: this._location('node', start),
end: this._location('node', end),
type: rel
};
if (props) request.properties = props;
var endpoint = util.format('index/relationship/%s?uniqueness=%s', idx, mode);
var op = this.operation(endpoint, 'POST', request);
this.call(op, function(err, rel) {
if (err) return cb(err);
cb(null, self._createRelationshipObject(rel));
exports.indexes = function(label, callback) {
label = encodeURIComponent(label);
var endpoint = util.format('schema/index/%s', label);
var op = this.operation(endpoint, 'GET');
this.call(op, function(err, indexes) {
if (err) callback(err);
else callback(null, indexes);
});
};
var indexModule = module.exports = {
create: function(type, name, config, callback) {
if (typeof name === 'function') {
callback = name;
name = type;
type = 'node';
config = null;
} else if (typeof config === 'function') {
callback = config;
if (typeof name === 'object' && !Array.isArray(name)) {
config = name;
name = type;
type = 'node';
} else {
config = null;
}
}
if (Array.isArray(name)) {
var txn = this._safeBatch();
var indexer = naan.ncurry(txn[type].index.create, config, 1);
async.map(name, indexer, callback);
return this._safeBatchCommit(txn);
}
if (!isValidType(type, callback)) {
return;
}
var request = { name: name };
if (config != null) {
request.config = config;
}
var endpoint = util.format('index/%s', type);
var op = this.operation(endpoint, 'POST', request);
this.call(op, function(err) {
callback(err);
});
},
add: function(type, indexName, obj, key, value, callback) {
if (typeof value === 'function') {
callback = value;
value = key;
key = obj;
obj = indexName;
indexName = type;
type = 'node';
}
if (Array.isArray(obj)) {
var txn = this._safeBatch();
var args = [indexName, key, value];
var indexer = naan.ecurry(txn[type].index.add, args, [0, 2, 3]);
async.map(obj, indexer, callback);
return this._safeBatchCommit(txn);
}
if (!isValidType(type, callback)) {
return;
}
var id = this._getId(obj);
if (!this._isValidId(id)) {
return callback(new Error("Invalid ID"));
}
var location = this._location(type, id);
var request = {
uri: location,
key: key,
value: value
};
indexName = encodeURIComponent(indexName);
var endpoint = util.format('index/%s/%s', type, indexName);
var op = this.operation(endpoint, 'POST', request);
this.call(op, function(err) {
callback(err);
});
},
readAsList: function(type, indexName, key, value, callback) {
if (typeof value === 'function') {
callback = value;
value = key;
key = indexName;
indexName = type;
type = 'node';
}
if (!isValidType(type, callback)) {
return;
}
indexName = encodeURIComponent(indexName);
value = encodeURIComponent(value);
key = encodeURIComponent(key);
var ep = util.format('index/%s/%s/%s/%s', type, indexName, key, value);
var op = this.operation(ep, 'GET');
var self = this;
this.call(op, function(err, entities) {
if (err) {
return callback(err);
}
var entityObjects = entities.map(function(entity) {
return type === 'node'
? self._createNodeObject(entity)
: self._createRelationshipObject(entity);
});
callback(null, entityObjects);
});
},
read: function(type, indexName, key, value, callback) {
indexModule.readAsList.call(this, type, indexName, key, value, function (err, results) {
if (err) return callback(err);
if (results.length === 1) {
callback(null, results[0]);
} else if (results.length === 0) {
callback(null, false);
} else {
callback(null, results);
}
});
},
getOrSaveUnique: saveUnique('get_or_create'),
saveUniqueOrFail: saveUnique('create_or_fail'),
remove: function(type, indexName, obj, key, value, callback) {
if (typeof key === 'function') {
callback = key, key = null, value = null;
} else if (typeof value === 'function') {
callback = value, value = null;
}
if (Array.isArray(obj)) {
var txn = this._safeBatch();
var args = [indexName, key, value];
var rm = naan.ecurry(txn[type].index.remove, args, [0, 2, 3]);
async.map(obj, rm, callback);
return this._safeBatchCommit(txn);
}
var id = this._getId(obj);
if (!this._isValidId(id)) {
return callback(new Error("Invalid ID"));
}
indexName = encodeURIComponent(indexName);
var endpoint = util.format('index/%s/%s', type, indexName);
if (key) endpoint += '/' + encodeURIComponent(key);
if (value) endpoint += '/' + encodeURIComponent(value)
endpoint += '/' + id;
var op = this.operation(endpoint, 'DELETE');
this.call(op, function(err) {
callback(err);
});
},
delete: function(type, indexName, callback) {
if (Array.isArray(indexName)) {
var txn = this._safeBatch();
async.map(indexName, txn[type].index.delete, callback);
return this._safeBatchCommit(txn);
}
indexName = encodeURIComponent(indexName);
var endpoint = util.format('index/%s/%s', type, indexName);
var op = this.operation(endpoint, 'DELETE');
this.call(op, function(err) {
callback(err);
});
}
};
exports.drop = function(label, key, callback) {
label = encodeURIComponent(label);
key = encodeURIComponent(key);
var endpoint = util.format('schema/index/%s/%s', label, key);
var op = this.operation(endpoint, 'DELETE');
this.call(op, function(err) {
if (err) callback(err);
else callback();
});
}

@@ -1,3 +0,1 @@

/* -*- Mode: Javascript; js-indent-level: 2 -*- */
var async = require('async');

@@ -295,15 +293,2 @@ var naan = require('naan');

saveUnique: function(node, index, key, value, returnExistingOnConflict, cb) {
if (typeof returnExistingOnConflict == 'function') {
cb = returnExistingOnConflict;
returnExistingOnConflict = false;
}
if (returnExistingOnConflict) {
this.node.index.getOrSaveUnique(node, index, key, value, cb);
} else {
this.node.index.saveUniqueOrFail(node, index, key, value, cb);
}
},
label: function(node, label, replace, callback) {

@@ -310,0 +295,0 @@ if (typeof replace == 'function') {

@@ -1,3 +0,1 @@

/* -*- Mode: Javascript; js-indent-level: 2 -*- */
var async = require('async');

@@ -138,27 +136,3 @@ var naan = require('naan');

});
},
createUnique: function(start, rel, end, props, index, key, value,
returnExistingOnConflict, cb) {
if (typeof props == 'string') {
cb = returnExistingOnConflict;
returnExistingOnConflict = value;
value = key;
key = index;
index = props;
props = undefined;
}
if (typeof returnExistingOnConflict == 'function') {
cb = returnExistingOnConflict;
returnExistingOnConflict = false;
}
if (returnExistingOnConflict) {
this.rel.index.getOrSaveUnique(start, rel, end, props,
index, key, value, cb);
} else {
this.rel.index.saveUniqueOrFail(start, rel, end, props,
index, key, value, cb);
}
}
};

@@ -1,3 +0,1 @@

/* -*- Mode: Javascript; js-indent-level: 2 -*- */
var naan = require('naan');

@@ -44,10 +42,11 @@ var async = require('async');

this.relationship = this.rel = bindAllTo(this, require('./relationship'));
var indexGeneric = bindAllTo(this, require('./index'));
this.index = bindAllTo(this, require('./index'));
var legacyindexGeneric = bindAllTo(this, require('./legacyindex'));
// Alias & curry seraph.index on seraph.node & seraph.rel
this.node.index = naan.curry(indexGeneric.add, 'node');
this.rel.index = naan.curry(indexGeneric.add, 'relationship');
naan.ecrock(this.node.index, indexGeneric, naan.curry, 'node');
naan.ecrock(this.rel.index, indexGeneric, naan.curry, 'relationship');
this.node.legacyindex = naan.curry(legacyindexGeneric.add, 'node');
this.rel.legacyindex = naan.curry(legacyindexGeneric.add, 'relationship');
naan.ecrock(this.node.legacyindex, legacyindexGeneric, naan.curry, 'node');
naan.ecrock(this.rel.legacyindex, legacyindexGeneric, naan.curry, 'relationship');

@@ -54,0 +53,0 @@ _.extend(this, this.node);

@@ -8,3 +8,3 @@ {

"description": "A thin and familiar layer between node and neo4j's REST api.",
"version": "0.8.0",
"version": "0.9.1",
"repository": {

@@ -11,0 +11,0 @@ "url": "https://github.com/brikteknologier/seraph"

@@ -47,4 +47,2 @@ # Seraph.js

* [save (node.save)](#node.save) - create or update a node
* [saveUnique (node.saveUnique)](#node.saveUnique) - save a node using an index
to enforce uniqueness
* [read (node.read)](#node.read) - read a node

@@ -56,3 +54,4 @@ * [find (node.find)](#node.find) - find a node using a predicate

relationships of a node
* [index (node.index)](#node.index) - add a node to an index
* [legacyindex (node.legacyindex)](#node.legacyindex) - add a node to a legacy
index
* [label (node.label)](#node.label) - add a label to a node

@@ -68,4 +67,2 @@ * [removeLabel (node.removeLabel)](#node.removeLabel) - remove a label from a

* [rel.create](#rel.create) - create a relationship
* [rel.createUnique](#rel.createUnique) - create a relationship using an index
to enforce uniqueness
* [rel.update](#rel.update) - update the properties of a relationship

@@ -75,16 +72,23 @@ * [rel.read](#rel.read) - read a relationship

### Index Operations
* [index.create](#index.create) - create an index
* [index.add](#index.add) - add a nodes/rels to an index
* [index.read](#index.read) - read nodes/rels from an index
* [index.remove](#index.remove) - remove nodes/rels from an index
* [index.delete](#index.delete) - delete an index
* [index.getOrSaveUnique](#index.getOrSaveUnique) - get or save a node using an
index for uniqueness
* [index.saveUniqueOrFail](#index.saveUniqueOrFail) - save a node using an index
to enforce uniqueness
### Indexing operations
* [index.create](#index.create) - create an index on a label and property name
* [index.createIfNone(#index.createIfNone) - create an index or return the old
one
* [index.indexes](#index.indexes) - read out the indexes for a label
* [index.drop](#index.drop) - drop an index
### Legacy Index Operations
* [legacyindex.create](#legacyindex.create) - create an index
* [legacyindex.add](#legacyindex.add) - add a nodes/rels to an index
* [legacyindex.read](#legacyindex.read) - read nodes/rels from an index
* [legacyindex.remove](#legacyindex.remove) - remove nodes/rels from an index
* [legacyindex.delete](#legacyindex.delete) - delete an index
* [legacyindex.getOrSaveUnique](#legacyindex.getOrSaveUnique) - get or save a node
using an index for uniqueness
* [legacyindex.saveUniqueOrFail](#legacyindex.saveUniqueOrFail) - save a node
using an index to enforce uniqueness
## Compatibility
Seraph 0.8.0 only works with Neo4j-2.0.0-RC1 and later.
Seraph `~0.9.0` only works with Neo4j-2.0.0-RC1 and later.

@@ -337,3 +341,3 @@ ## Testing

var performance = txn.relate(singer, 'performs_on', album, {role: 'Primary Artist'});
txn.rel.index('performances', performance, 'year', '2008');
txn.rel.legacyindex('performances', performance, 'year', '2008');

@@ -437,44 +441,2 @@ txn.commit(function(err, results) {});

<a name="node.saveUnique" />
### node.saveUnique(node, index, key, value, [returnExistingOnConflict = false,] callback)
Save a node, using an index to enforce uniqueness.
See also [node.index.saveUniqueOrFail](#index.saveUniqueOrFail) &
[node.index.getOrSaveUnique](#index.getOrSaveUnique).
__Arguments__
* `node` - an object to create or update
* `index` - the index in which `key` and `value` are relevant
* `key` - the key under which to index this node and enforce uniqueness
* `value` - the value under which to index this node and enforce uniqueness
* `returnExistingOnConflict` (optional, default=`false`) - what to do when there is
a conflict (when the index you specified already refers to a node). If set to
`true`, the node that the index currently refers to is returned. Otherwise,
an error is return indicating that there was a conflict (you can check this by
testing `err.statusCode == 409`.
* `callback` - function(err, node) - `node` is the newly created node or the node
that was in the specified index, depending on `returnExistingOnConflict`.
__Example__
```javascript
db.saveUnique({name: 'jon'}, 'people', 'name', 'jon', function(err, node) {
//node = { name: 'jon', id: 1 }
db.saveUnique({age: 24}, 'people', 'name', 'jon', function(err, node) {
//err.statusCode == 409, because there was already a node indexed under
//people(name="jon").
});
db.saveUnique({location:'Bergen'}, 'people', 'name', 'jon', true, function(err, node) {
// node = {name: 'jon', id: 1}
// because there was node already indexed under people(name="jon") and we
// specified that we wanted that node returned on the event of a conflict.
});
});
```
---------------------------------------
<a name="node.read" />

@@ -489,4 +451,4 @@ ### read(id|object, [property,] callback)

`err.statusCode` will equal `404`. This is inconsistent with behaviour of
[node.index.read](#index.read), but it is justified because the Neo4j REST api
behaviour is inconsistent in this way as well.
[node.legacyindex.read](#legacyindex.read), but it is justified because the
Neo4j REST api behaviour is inconsistent in this way as well.

@@ -755,52 +717,2 @@ __Arguments__

<a name="rel.createUnique" />
### rel.createUnique(firstId|firstObj, type, secondId|secondObj, [properties,] index, key, value, [returnExistingOnConflict = false,] callback)
Create a relationship between two nodes, using an index to enforce uniqueness.
See also [rel.index.saveUniqueOrFail](#index.saveUniqueOrFail) &
[rel.index.getOrSaveUnique](#index.getOrSaveUnique).
__Arguments__
* `firstId | firstObject` - id of the start node or an object with an id property
for the start node
* `type` - the name of the relationship
* `secondId | secondObject` - id of the end node or an object with an id property
for the end node
* `properties` (optional, default=`{}`) - properties of the relationship
* `index` - the index in which `key` and `value` are relevant
* `key` - the key under which to index this relationship and enforce uniqueness
* `value` - the value under which to index this relationship and enforce uniqueness
* `returnExistingOnConflict` (optional, default=`false`) - what to do when there is
a conflict (when the index you specified already refers to a relationship). If
set to `true`, the relationship that the index currently refers to is returned.
Otherwise, an error is return indicating that there was a conflict (you can
check this by testing `err.statusCode == 409`.
* `callback` - function(err, relationship) - `relationship` is the newly created
relationship or the relationship that was in the specified index, depending
on `returnExistingOnConflict`
__Example__
```javascript
db.rel.createUnique(1, 'knows', 2, 'friendships', 'type', 'super', function(err, rel) {
// rel = {start: 1, end: 2, type: 'knows', properties: {}, id = 1}
db.rel.createUnique(1, 'knows', 2, 'friendships', 'type', 'super', function(err, node) {
//err.statusCode == 409, because there was already a relationship indexed under
//friendships(type="super").
});
db.rel.createUnique(1, 'knows', 2, 'friendships', 'type', 'super', true, function(err, node) {
// rel = {start: 1, end: 2, type: 'knows', properties: {}, id = 1}
// no new index was created, the first one was returned - because there was
// already a relationship indexed under friendships(type="super") and we
// specified that on the event of a conflict we wanted the indexed rel to
// be returned
});
});
```
---------------------------------------
<a name="rel.update" />

@@ -890,25 +802,130 @@ ### rel.update(relationship, [key, value,] callback)

## Index Operations
## Indexing Operations
**For more of an overview on schema-based indexing, check out the [neo4j docs
on the subject](http://docs.neo4j.org/chunked/milestone/graphdb-neo4j-schema.html#graphdb-neo4j-schema-indexes).**
<a name="index.create" />
### node.index.create(name, [config,] callback)
### rel.index.create(name, [config,] callback)
### index.create(label, key, callback)
Create a new index. If you're using the default index configuration, this
method is not necessary - you can just start using the index with
[index.add](#index.add) as if it already existed.
Create an index on `label` with `key`. Note that schema-based indexes are
performance-boosting only and do not imply any uniqueness constraints.
__NOTE for index functions:__ there are two different types on index in neo4j -
__node__ indexes and __relationship__ indexes. When you're working with __node__
indexes, you use the functions on `node.index`. Similarly, when you're working
on __relationship__ indexes you use the functions on `rel.index`. Most of the
functions on both of these are identical (excluding the uniqueness functions),
but one acts upon node indexes, and the other upon relationship indexes.
__Arguments__
* `label` - the label to create an index on
* `key` - the key to index, i.e. `'name'`. Note that compound indexes are not
yet supported by neo4j-2
* `callback` - function(err, index). `index` is an object that reflects the
index that was created, i.e. `{ label: 'Person', { property_keys: ['name'] }`.
Note that if you've already created the index, you'll get a conflict error. You
can check this by checking `err`'s `statusCode` property. `409` indicates a
conflict. You can avoid this by using [index.createIfNone](#index.createIfNone)
__Example__
```javascript
db.index.create('Person', 'name', function(err, index) {
console.log(index); // -> { label: 'Person', { property_keys: ['name'] }
});
```
---------------------------------------
<a name="index.createIfNone" />
### index.createIfNone(label, key, callback)
Create an index on `label` with `key`. Exactly the same as
[index.create](#index.create) except it will not throw an error if it encounters
a conflict.
__Arguments__
* `name` - the name of the index that is being created
* `config` (optional, default=`{}`) - the configuration of the index. See the [neo4j docs](http://docs.neo4j.org/chunked/milestone/rest-api-indexes.html#rest-api-create-node-index-with-configuration)
* `label` - the label to create an index on
* `key` - the key to index, i.e. `'name'`. Note that compound indexes are not
yet supported by neo4j-2
* `callback` - function(err, index). `index` is an object that reflects the
index that was created, i.e. `{ label: 'Person', { property_keys: ['name'] }`.
__Example__
```javascript
db.index.createIfNone('Person', 'name', function(err, index) {
console.log(index); // -> { label: 'Person', { property_keys: ['name'] }
});
```
---------------------------------------
<a name="index.indexes" />
### index.indexes(label, callback)
Retrieve a listing of the indexes on a label.
__Arguments__
* `label` - the label to retrieve indexes for
* `callback` - function(err, indexes). `indexes` is an array of objects that
reflect the indexes on this label, i.e.
`[{ label: 'Person', { property_keys: ['name'] }]`.
__Example__
```javascript
db.index.indexes('Person', function(err, index) {
console.log(index); // -> [ { label: 'Person', { property_keys: ['name'] } ]
});
```
---------------------------------------
<a name="index.drop" />
### index.drop(label, key, callback)
Drop an index from a label
__Arguments__
* `label` - the label to drop the index from
* `key` - the key to drop the index from
* `callback` - function(err). if `err` is falsy, the index was dropped
successfully.
__Example__
```javascript
db.index.drop('Person', 'name' function(err) {
if (!err) console.log('Index dropped!');
});
```
## Legacy Index Operations
**Note that as of Neo4j-2.0.0 legacy indexes are no longer the preferred way to
handle indexing**
<a name="legacyindex.create" />
### node.legacyindex.create(name, [config,] callback)
### rel.legacyindex.create(name, [config,] callback)
Create a new legacy index. If you're using the default legacy index configuration,
this method is not necessary - you can just start using the legacy index with
[legacyindex.add](#legacyindex.add) as if it already existed.
__NOTE for legacy index functions:__ there are two different types of legacy
index in neo4j - __node__ legacy indexes and __relationship__ legacy indexes.
When you're working with __node__ legacy indexes, you use the functions on
`node.legacyindex`. Similarly, when you're working on __relationship__ legacy
indexes you use the functions on `rel.legacyindex`. Most of the functions on
both of these are identical (excluding the uniqueness functions), but one acts
upon node legacy indexes, and the other upon relationship legacy indexes.
__Arguments__
* `name` - the name of the legacy index that is being created
* `config` (optional, default=`{}`) - the configuration of the legacy index.
See the [neo4j docs](http://docs.neo4j.org/chunked/milestone/rest-api-indexes.html#rest-api-create-node-index-with-configuration)
for more information.
* `callback` - function(err). If `err` is falsy, the index has been created.
* `callback` - function(err). If `err` is falsy, the legacy index has been created.

@@ -919,4 +936,4 @@ __Example__

var indexConfig = { type: 'fulltext', provider: 'lucene' };
db.node.index.create('a_fulltext_index', indexConfig, function(err) {
if (!err) console.log('a fulltext index has been created!');
db.node.legacyindex.create('a_fulltext_index', indexConfig, function(err) {
if (!err) console.log('a fulltext legacy index has been created!');
});

@@ -927,22 +944,24 @@ ```

<a name="index.add" />
<a name="node.index" />
### node.index.add(indexName, id|object, key, value, callback);
### rel.index.add(indexName, id|object, key, value, callback);
*`node.index.add` is aliased as __node.index__ & __index__*
<a name="legacyindex.add" />
<a name="node.legacyindex" />
### node.legacyindex.add(indexName, id|object, key, value, callback);
### rel.legacyindex.add(indexName, id|object, key, value, callback);
*`node.legacyindex.add` is aliased as __node.legacyindex__ & __legacyindex__*
Add a node/relationship to an index.
Add a node/relationship to a legacy index.
__NOTE for index functions:__ there are two different types on index in neo4j -
__node__ indexes and __relationship__ indexes. When you're working with __node__
indexes, you use the functions on `node.index`. Similarly, when you're working
on __relationship__ indexes you use the functions on `rel.index`. Most of the
functions on both of these are identical (excluding the uniqueness functions),
but one acts upon node indexes, and the other upon relationship indexes.
__NOTE for legacy index functions:__ there are two different types of legacy
index in neo4j - __node__ legacy indexes and __relationship__ legacy indexes.
When you're working with __node__ legacy indexes, you use the functions on
`node.legacyindex`. Similarly, when you're working on __relationship__ legacy
indexes you use the functions on `rel.legacyindex`. Most of the functions on
both of these are identical (excluding the uniqueness functions), but one acts
upon node legacy indexes, and the other upon relationship legacy indexes.
__Arguments__
* `indexName` - the name of the index to add the node/relationship to.
* `id | object` - the id of the node/relationship to add to the index or an object
with an id property of the node/relationship to add to the index.
* `indexName` - the name of the legacy index to add the node/relationship to.
* `id | object` - the id of the node/relationship to add to the legacy index or
an object with an id property of the node/relationship to add to the legacy
index.
* `key` - the key to index the node/relationship with

@@ -957,3 +976,3 @@ * `value` - the value to index the node/relationship with

db.save({ name: 'Jon', }, function(err, node) {
db.index('people', node, 'name', node.name, function(err) {
db.legacyindex('people', node, 'name', node.name, function(err) {
if (!err) console.log('Jon has been indexed!');

@@ -966,19 +985,20 @@ });

<a name="index.read" />
### node.index.read(indexName, key, value, callback);
### rel.index.read(indexName, key, value, callback);
<a name="legacyindex.read" />
### node.legacyindex.read(indexName, key, value, callback);
### rel.legacyindex.read(indexName, key, value, callback);
Read the object(s) from an index that match a key-value pair. See also
[index.readAsList](#index.readAsList).
Read the object(s) from a legacy index that match a key-value pair. See also
[legacyindex.readAsList](#legacyindex.readAsList).
__NOTE for index functions:__ there are two different types on index in neo4j -
__node__ indexes and __relationship__ indexes. When you're working with __node__
indexes, you use the functions on `node.index`. Similarly, when you're working
on __relationship__ indexes you use the functions on `rel.index`. Most of the
functions on both of these are identical (excluding the uniqueness functions),
but one acts upon node indexes, and the other upon relationship indexes.
__NOTE for legacy index functions:__ there are two different types of legacy
index in neo4j - __node__ legacy indexes and __relationship__ legacy indexes.
When you're working with __node__ legacy indexes, you use the functions on
`node.legacyindex`. Similarly, when you're working on __relationship__ legacy
indexes you use the functions on `rel.legacyindex`. Most of the functions on
both of these are identical (excluding the uniqueness functions), but one acts
upon node legacy indexes, and the other upon relationship legacy indexes.
__Arguments__
* `indexName` - the index to read from
* `indexName` - the legacy index to read from
* `key` - the key to match

@@ -988,5 +1008,6 @@ * `value` - the value to match

(or an array of them if there was more than one) that matched the given
key-value pair in the given index. If nothing matched, `results === false`.
[index.readAsList](#index.readAsList) is similar, but always gives `results` as
an array, with zero, one or more elements.
key-value pair in the given legacy index. If nothing matched,
`results === false`. [legacyindex.readAsList](#legacyindex.readAsList) is
similar, but always gives `results` as an array, with zero, one or more
elements.

@@ -996,3 +1017,3 @@ __Example__

```javascript
db.rel.index.read('friendships', 'location', 'Norway', function(err, rels) {
db.rel.legacyindex.read('friendships', 'location', 'Norway', function(err, rels) {
// `rels` is an array of all relationships indexed in the `friendships`

@@ -1005,25 +1026,26 @@ // index, with a value `Norway` for the key `location`.

<a name="index.readAsList" />
### node.index.readAsList(indexName, key, value, callback);
### rel.index.readAsList(indexName, key, value, callback);
<a name="legacyindex.readAsList" />
### node.legacyindex.readAsList(indexName, key, value, callback);
### rel.legacyindex.readAsList(indexName, key, value, callback);
Read the object(s) from an index that match a key-value pair. See also
[index.read](#index.read).
Read the object(s) from a legacy index that match a key-value pair. See also
[legacyindex.read](#legacyindex.read).
__NOTE for index functions:__ there are two different types on index in neo4j -
__node__ indexes and __relationship__ indexes. When you're working with __node__
indexes, you use the functions on `node.index`. Similarly, when you're working
on __relationship__ indexes you use the functions on `rel.index`. Most of the
functions on both of these are identical (excluding the uniqueness functions),
but one acts upon node indexes, and the other upon relationship indexes.
__NOTE for legacy index functions:__ there are two different types of legacy
index in neo4j - __node__ legacy indexes and __relationship__ legacy indexes.
When you're working with __node__ legacy indexes, you use the functions on
`node.legacyindex`. Similarly, when you're working on __relationship__ legacy
indexes you use the functions on `rel.legacyindex`. Most of the functions on
both of these are identical (excluding the uniqueness functions), but one acts
upon node legacy indexes, and the other upon relationship legacy indexes.
__Arguments__
* `indexName` - the index to read from
* `indexName` - the legacy index to read from
* `key` - the key to match
* `value` - the value to match
* `callback` - function(err, results). `results` is an array of node or
relationship objects that matched the given key-value pair in the given index.
[index.read](#index.read) is similar, but gives `results` as `false`, an object
or an array of objects depending on the number of hits.
relationship objects that matched the given key-value pair in the given legacy
index. [legacyindex.read](#legacyindex.read) is similar, but gives `results`
as `false`, an object or an array of objects depending on the number of hits.

@@ -1033,5 +1055,5 @@ __Example__

```javascript
db.rel.index.readAsList('friendships', 'location', 'Norway', function(err, rels) {
db.rel.legacyindex.readAsList('friendships', 'location', 'Norway', function(err, rels) {
// `rels` is an array of all relationships indexed in the `friendships`
// index, with a value `Norway` for the key `location`.
// legacy index, with a value `Norway` for the key `location`.
});

@@ -1042,23 +1064,25 @@ ```

<a name="index.remove" />
### node.index.remove(indexName, id|object, [key, [value,]] callback);
### rel.index.remove(indexName, id|object, [key, [value,]] callback);
<a name="legacyindex.remove" />
### node.legacyindex.remove(indexName, id|object, [key, [value,]] callback);
### rel.legacyindex.remove(indexName, id|object, [key, [value,]] callback);
Remove a node/relationship from an index.
Remove a node/relationship from a legacy index.
__NOTE for index functions:__ there are two different types on index in neo4j -
__node__ indexes and __relationship__ indexes. When you're working with __node__
indexes, you use the functions on `node.index`. Similarly, when you're working
on __relationship__ indexes you use the functions on `rel.index`. Most of the
functions on both of these are identical (excluding the uniqueness functions),
but one acts upon node indexes, and the other upon relationship indexes.
__NOTE for legacy index functions:__ there are two different types of legacy
index in neo4j - __node__ legacy indexes and __relationship__ legacy indexes.
When you're working with __node__ legacy indexes, you use the functions on
`node.legacyindex`. Similarly, when you're working on __relationship__ legacy
indexes you use the functions on `rel.legacyindex`. Most of the functions on
both of these are identical (excluding the uniqueness functions), but one acts
upon node legacy indexes, and the other upon relationship legacy indexes.
__Arguments__
* `indexName` - the index to remove the node/relationship from.
* `id | object` - the id of the node/relationship to remove from the index or an
object with an id property of the node/relationship to remove from the index.
* `indexName` - the legacy index to remove the node/relationship from.
* `id | object` - the id of the node/relationship to remove from the legacy
index or an object with an id property of the node/relationship to remove from
the legacy index.
* `key` (optional) - the key from which to remove the node/relationship. If none
is specified, every reference to the node/relationship is deleted from the
index.
legacy index.
* `value` (optional) - the value from which to remove the node/relationship. If

@@ -1073,7 +1097,7 @@ none is specified, every reference to the node/relationship is deleted for the

```javascript
db.node.index.remove('people', 6821, function(err) {
db.node.legacyindex.remove('people', 6821, function(err) {
if (!err) console.log("Every reference of node 6821 has been removed from the people index");
});
db.rel.index.remove('friendships', 351, 'in', 'Australia', function(err) {
db.rel.legacyindex.remove('friendships', 351, 'in', 'Australia', function(err) {
if (!err) console.log("Relationship 351 is no longer indexed as a friendship in Australia");

@@ -1085,19 +1109,20 @@ })

<a name="index.delete" />
### node.index.delete(name, callback);
### rel.index.delete(name, callback);
<a name="legacyindex.delete" />
### node.legacyindex.delete(name, callback);
### rel.legacyindex.delete(name, callback);
Delete an index.
Delete a legacy index.
__NOTE for index functions:__ there are two different types on index in neo4j -
__node__ indexes and __relationship__ indexes. When you're working with __node__
indexes, you use the functions on `node.index`. Similarly, when you're working
on __relationship__ indexes you use the functions on `rel.index`. Most of the
functions on both of these are identical (excluding the uniqueness functions),
but one acts upon node indexes, and the other upon relationship indexes.
__NOTE for legacy index functions:__ there are two different types of legacy
index in neo4j - __node__ legacy indexes and __relationship__ legacy indexes.
When you're working with __node__ legacy indexes, you use the functions on
`node.legacyindex`. Similarly, when you're working on __relationship__ legacy
indexes you use the functions on `rel.legacyindex`. Most of the functions on
both of these are identical (excluding the uniqueness functions), but one acts
upon node legacy indexes, and the other upon relationship legacy indexes.
__Arguments__
* `name` - the name of the index to delete
* `callback` - function(err). if `err` is falsy, the index has been deleted.
* `name` - the name of the legacy index to delete
* `callback` - function(err). if `err` is falsy, the legacy index has been deleted.

@@ -1107,3 +1132,3 @@ __Example__

```javascript
db.rel.index.delete('friendships', function(err) {
db.rel.legacyindex.delete('friendships', function(err) {
if (!err) console.log('The `friendships` index has been deleted');

@@ -1115,18 +1140,19 @@ })

<a name="index.getOrSaveUnique" />
### node.index.getOrSaveUnique(node, index, key, value, callback);
### rel.index.getOrSaveUnique(startNode, relName, endNode, [properties,] index, key, value, callback);
<a name="legacyindex.getOrSaveUnique" />
### node.legacyindex.getOrSaveUnique(node, index, key, value, callback);
### rel.legacyindex.getOrSaveUnique(startNode, relName, endNode, [properties,] index, key, value, callback);
Save a node or relationship, using an index to enforce uniqueness. If there is
already a node or relationship saved under the specified `key` and `value` in
the specified `index`, that node or relationship will be returned.
Save a node or relationship, using a legacy index to enforce uniqueness. If
there is already a node or relationship saved under the specified `key` and
`value` in the specified `index`, that node or relationship will be returned.
Note that you cannot use this function to update nodes.
__NOTE for index functions:__ there are two different types on index in neo4j -
__node__ indexes and __relationship__ indexes. When you're working with __node__
indexes, you use the functions on `node.index`. Similarly, when you're working
on __relationship__ indexes you use the functions on `rel.index`. Most of the
functions on both of these are identical (excluding the uniqueness functions),
but one acts upon node indexes, and the other upon relationship indexes.
__NOTE for legacy index functions:__ there are two different types of legacy
index in neo4j - __node__ legacy indexes and __relationship__ legacy indexes.
When you're working with __node__ legacy indexes, you use the functions on
`node.legacyindex`. Similarly, when you're working on __relationship__ legacy
indexes you use the functions on `rel.legacyindex`. Most of the functions on
both of these are identical (excluding the uniqueness functions), but one acts
upon node legacy indexes, and the other upon relationship legacy indexes.

@@ -1136,3 +1162,3 @@ __Arguments (node)__

* `node` - the node to save
* `index` - the name of the index in which `key` and `value` are relevant
* `index` - the name of the legacy index in which `key` and `value` are relevant
* `key` - the key to check or store under

@@ -1149,3 +1175,3 @@ * `value` - the value to check or store under

created relationship.
* `index` - the name of the index in which `key` and `value` are relevant
* `index` - the name of the legacy index in which `key` and `value` are relevant
* `key` - the key to check or store under

@@ -1161,7 +1187,7 @@ * `value` - the value to check or store under

var tag = { name: 'finnish' };
db.node.index.getOrSaveUnique(tag, 'tags', 'name', tag.name, function(err, tag) {
db.node.legacyindex.getOrSaveUnique(tag, 'tags', 'name', tag.name, function(err, tag) {
// tag == { id: 1, name: 'finnish' }
// save another new object with the same properties
db.node.index.getOrSaveUnique({name: 'finnish'}, 'tags', 'name', 'finnish', function(err, newTag) {
db.node.legacyindex.getOrSaveUnique({name: 'finnish'}, 'tags', 'name', 'finnish', function(err, newTag) {
// newTag == { id: 1, name: 'finnish' }

@@ -1175,18 +1201,19 @@ // no save was performed because there was already an object at that index

<a name="index.saveUniqueOrFail" />
### node.index.saveUniqueOrFail(node, index, key, value, callback);
### rel.index.saveUniqueOrFail(startNode, relName, endNode, [properties,] index, key, value, callback);
<a name="legacyindex.saveUniqueOrFail" />
### node.legacyindex.saveUniqueOrFail(node, index, key, value, callback);
### rel.legacyindex.saveUniqueOrFail(startNode, relName, endNode, [properties,] index, key, value, callback);
Save a node or relationship, using an index to enforce uniqueness. If there is
already a node or relationship saved under the specified `key` and `value` in
the specified `index`, an error is returned indicating that there as a conflict.
You can check if the result was a conflict by checking if
Save a node or relationship, using a legacy index to enforce uniqueness. If
there is already a node or relationship saved under the specified `key` and
`value` in the specified `index`, an error is returned indicating that there
as a conflict. You can check if the result was a conflict by checking if
`err.statusCode == 409`.
__NOTE for index functions:__ there are two different types on index in neo4j -
__node__ indexes and __relationship__ indexes. When you're working with __node__
indexes, you use the functions on `node.index`. Similarly, when you're working
on __relationship__ indexes you use the functions on `rel.index`. Most of the
functions on both of these are identical (excluding the uniqueness functions),
but one acts upon node indexes, and the other upon relationship indexes.
__NOTE for legacy index functions:__ there are two different types of legacy
index in neo4j - __node__ legacy indexes and __relationship__ legacy indexes.
When you're working with __node__ legacy indexes, you use the functions on
`node.legacyindex`. Similarly, when you're working on __relationship__ legacy
indexes you use the functions on `rel.legacyindex`. Most of the functions on
both of these are identical (excluding the uniqueness functions), but one acts
upon node legacy indexes, and the other upon relationship legacy indexes.

@@ -1196,7 +1223,7 @@ __Arguments (node)__

* `node` - the node to save
* `index` - the name of the index in which `key` and `value` are relevant
* `index` - the name of the legacy index in which `key` and `value` are relevant
* `key` - the key to check or store under
* `value` - the value to check or store under
* `callback` - function(err, node) - returns your created node, or an err with
`statusCode == 409` if a node already existed at that index
`statusCode == 409` if a node already existed at that legacy index

@@ -1209,7 +1236,8 @@ __Arguments (relationship)__

created relationship.
* `index` - the name of the index in which `key` and `value` are relevant
* `index` - the name of the legacy index in which `key` and `value` are relevant
* `key` - the key to check or store under
* `value` - the value to check or store under
* `callback` - function(err, rel) - returns your created relationship, or an
err with `statusCode == 409` if a relationship already existed at that index
err with `statusCode == 409` if a relationship already existed at that legacy
index

@@ -1220,7 +1248,7 @@ __Example__

var tag = { name: 'finnish' };
db.node.index.saveUniqueOrFail(tag, 'tags', 'name', tag.name, function(err, tag) {
db.node.legacyindex.saveUniqueOrFail(tag, 'tags', 'name', tag.name, function(err, tag) {
// tag == { id: 1, name: 'finnish' }
// save another new object with the same properties
db.node.index.saveUniqueOrFail({name: 'finnish'}, 'tags', 'name', 'finnish', function(err, newTag) {
db.node.legacyindex.saveUniqueOrFail({name: 'finnish'}, 'tags', 'name', 'finnish', function(err, newTag) {
// newTag == undefined

@@ -1227,0 +1255,0 @@ // err.statusCode == 409 (conflict)

@@ -90,6 +90,6 @@ /* -*- Mode: Javascript; js-indent-level: 2 -*- */

db.batch(function(db) {
db.index(iname, user, 'something', 'magical');
db.legacyindex(iname, user, 'something', 'magical');
}, function(err, results) {
assert(!err);
db.index.read(iname, 'something', 'magical', function(err, node) {
db.legacyindex.read(iname, 'something', 'magical', function(err, node) {
assert(!err);

@@ -269,7 +269,7 @@ assert(node.person == 'indexable');

var person = txn.save({name:'Jon'});
txn.index(idx, person, 'thing', 'stuff');
txn.legacyindex(idx, person, 'thing', 'stuff');
txn.commit(function(err, results) {
assert(!err);
db.index.read(idx, 'thing', 'stuff', function(err, person1) {
db.legacyindex.read(idx, 'thing', 'stuff', function(err, person1) {
assert(!err);

@@ -287,7 +287,7 @@ assert.deepEqual(person1, results[person]);

var person = txn.save({name:'Jon'});
txn.index(idx, person, 'thing', 'stuff');
txn.legacyindex(idx, person, 'thing', 'stuff');
txn.commit(function(err, txnResults) {
assert(!err);
db.index.readAsList(idx, 'thing', 'stuff', function(err, readResults) {
db.legacyindex.readAsList(idx, 'thing', 'stuff', function(err, readResults) {
assert(!err);

@@ -294,0 +294,0 @@ assert.equal(readResults.length, 1);

@@ -1,6 +0,4 @@

/* -*- Mode: Javascript; js-indent-level: 2 -*- */
var testDatabase = require('./util/database');
var db = require('../')(testDatabase.url);
var uniqn = require('./util/ponies').uniqn;
var db = require('../')(testDatabase.url);

@@ -10,6 +8,10 @@ var assert = require('assert');

describe('seraph.index', function() {
it('should create an index with inferred type', function(done) {
db.index.create(uniqn(), function(err) {
assert.ok(!err);
describe('seraph#index', function() {
it('should create an index on a key', function(done) {
var labelname = uniqn();
db.index.create(labelname, 'name', function(err, index) {
assert(!err);
assert.equal(index.label, labelname);
assert.equal(index.property_keys.length, 1);
assert.equal(index.property_keys[0], 'name');
done();

@@ -19,55 +21,14 @@ });

it('should create an index with a config', function(done) {
db.index.create(uniqn(), {
type: 'fulltext',
provider: 'lucene'
}, function(err) {
assert.ok(!err);
done();
});
});
it('should create an index for a relationship', function(done) {
db.rel.index.create(uniqn(), function(err) {
assert.ok(!err);
done();
});
});
it('should create in index with config and inferred type', function(done) {
db.index.create(uniqn(), {
type: 'fulltext',
provider: 'lucene'
}, function(err) {
assert.ok(!err);
done();
});
});
it('should accept an array of indexes to create', function(done) {
db.rel.index.create([uniqn(), uniqn(), uniqn()],
function(err) {
assert.ok(!err);
done();
});
});
it('should be aliased on `seraph.node`', function(done) {
db.node.index.create(uniqn(), function(err) {
assert.ok(!err);
done();
})
});
it('should be aliased on `seraph.rel`', function(done) {
db.rel.index.create(uniqn(), function(err) {
assert.ok(!err);
done();
})
});
it('should add a ndoe to an index', function(done) {
db.save({name: 'Jon'}, function(err, node) {
db.node.index.add(uniqn(), node, 'test', 'sannelig', function(err) {
assert.ok(!err);
it('should create an index and not return an error if it exists', function(done) {
var labelname = uniqn();
db.index.createIfNone(labelname, 'name', function(err, index) {
assert(!err);
assert.equal(index.label, labelname);
assert.equal(index.property_keys.length, 1);
assert.equal(index.property_keys[0], 'name');
db.index.createIfNone(labelname, 'name', function(err, index) {
assert(!err);
assert.equal(index.label, labelname);
assert.equal(index.property_keys.length, 1);
assert.equal(index.property_keys[0], 'name');
done();

@@ -77,408 +38,27 @@ });

});
it('should alias seraph.index.add as seraph.node.index', function(done) {
db.save({name: 'Jon'}, function(err, node) {
db.node.index(uniqn(), node, 'test', 'sannelig', function(err) {
assert.ok(!err);
done();
});
});
});
it('should read zero objects from an index as `false`', function(done) {
var iname = uniqn();
function createAndIndex(done) {
db.save({ name: 'Helge' }, function(err, node) {
db.node.index(iname, node, 'person', 'true', function(err) {
done();
});
});
}
function readIndex(done) {
db.index.read(iname, 'person', 'false', function(err, results) {
assert.ok(!err);
assert.equal(results, false);
done();
})
}
async.series([createAndIndex, readIndex], done);
});
it('should read a single object from an index', function(done) {
var iname = uniqn();
function createAndIndex(done) {
db.save({ name: 'Helge' }, function(err, node) {
db.node.index(iname, node, 'person', 'true', function(err) {
done();
});
});
}
function readIndex(done) {
db.index.read(iname, 'person', 'true', function(err, node) {
assert.ok(!err);
assert.equal(node.name, 'Helge');
done();
})
}
async.series([createAndIndex, readIndex], done);
});
it('should read a single object from an index with a space', function(done) {
var iname = uniqn();
function createAndIndex(done) {
db.save({ name: 'Helge' }, function(err, node) {
db.node.index(iname, node, 'person', 'has a space', function(err) {
done();
});
});
}
function readIndex(done) {
db.index.read(iname, 'person', 'has a space', function(err, node) {
assert.ok(!err);
assert.equal(node.name, 'Helge');
done();
})
}
async.series([createAndIndex, readIndex], done);
});
it('should read a single object from an index named with a space', function(done) {
var iname = uniqn() + " with a space";
function createAndIndex(done) {
db.save({ name: 'Helge' }, function(err, node) {
db.node.index(iname, node, 'person', 'has a space', function(err) {
done();
});
});
}
function readIndex(done) {
db.index.read(iname, 'person', 'has a space', function(err, node) {
assert.ok(!err);
assert.equal(node.name, 'Helge');
done();
})
}
async.series([createAndIndex, readIndex], done);
});
it('should read all values of a kv pair in an index', function(done) {
var iname = uniqn();
function createAndIndex(done) {
db.save([{ name: 'Helge' }, { name: 'Erlend' }], function(err, nodes) {
db.node.index(iname, nodes, 'company', 'brik', function(err) {
done();
});
});
}
function readIndex(done) {
db.index.read(iname, 'company', 'brik', function(err, nodes) {
assert.ok(!err);
var names = nodes.map(function(node) { return node.name });
assert.ok(names.indexOf("Helge") !== -1);
assert.ok(names.indexOf("Erlend") !== -1);
done();
})
}
async.series([createAndIndex, readIndex], done);
});
it('should read a kv pair as a relationship', function(done) {
var iname = uniqn();
function createAndIndex(done) {
db.save([{ name: 'Helge' }, { name: 'Erlend' }], function(err, nodes) {
db.relate(nodes[0], 'knows', nodes[1], function(err, rel) {
db.rel.index(iname, rel, 'company', 'brik', function(err) {
done(null, nodes);
});
})
});
}
function readIndex(nodes, done) {
db.rel.index.read(iname, 'company', 'brik', function(err, rel) {
assert.ok(!err);
assert.equal(rel.start, nodes[0].id);
assert.equal(rel.end, nodes[1].id);
assert.equal(rel.type, 'knows');
done();
})
}
async.waterfall([createAndIndex, readIndex], done);
});
it('should readAsList zero objects from an index as `[]`', function(done) {
var iname = uniqn();
function createAndIndex(done) {
db.save({ name: 'Helge' }, function(err, node) {
db.node.index(iname, node, 'person', 'true', function(err) {
done();
});
});
}
function readIndex(done) {
db.index.readAsList(iname, 'person', 'false', function(err, results) {
assert.ok(!err);
assert.deepEqual(results, []);
done();
})
}
async.series([createAndIndex, readIndex], done);
});
it('should readAsList a single object from an index as a list', function(done) {
var iname = uniqn();
function createAndIndex(done) {
db.save({ name: 'Helge' }, function(err, node) {
db.node.index(iname, node, 'person', 'true', function(err) {
done();
});
});
}
function readIndex(done) {
db.index.readAsList(iname, 'person', 'true', function(err, results) {
assert.ok(!err);
assert.equal(results.length, 1);
assert.equal(results[0].name, 'Helge');
done();
})
}
async.series([createAndIndex, readIndex], done);
});
it('should readAsList all values of a kv pair in an index', function(done) {
var iname = uniqn();
function createAndIndex(done) {
db.save([{ name: 'Helge' }, { name: 'Erlend' }], function(err, nodes) {
db.node.index(iname, nodes, 'company', 'brik', function(err) {
done();
});
});
}
function readIndex(done) {
db.index.readAsList(iname, 'company', 'brik', function(err, nodes) {
assert.ok(!err);
var names = nodes.map(function(node) { return node.name });
assert.ok(names.indexOf("Helge") !== -1);
assert.ok(names.indexOf("Erlend") !== -1);
done();
})
}
async.series([createAndIndex, readIndex], done);
});
it('should remove a node from an index', function(done) {
var iname = uniqn();
function createAndIndex(done) {
db.save({ name: 'Helge' }, function(err, node) {
db.node.index(iname, node, 'person', 'true', function(err) {
done();
});
});
}
function readIndex(done) {
db.index.read(iname, 'person', 'true', function(err, node) {
assert.equal(node.name, "Helge");
db.index.remove(iname, node, 'person', 'true', function(err) {
assert.ok(!err)
db.index.read(iname, 'person', 'true', function(err, nodes) {
assert.ok(!err);
assert.ok(!nodes);
done();
});
});
})
}
async.series([createAndIndex, readIndex], done);
});
it('should remove all instances of a node from an index for a key', function(done) {
var iname = uniqn();
function createAndIndex(done) {
db.save({ name: 'Helge' }, function(err, node) {
db.node.index(iname, node, 'person', 'true', function(err) {
db.node.index(iname, node, 'person', 'false', function(err) {
done();
});
});
});
}
function readIndex(done) {
db.index.read(iname, 'person', 'true', function(err, node) {
assert.equal(node.name, "Helge");
db.index.remove(iname, node, 'person', function(err) {
assert.ok(!err)
db.index.read(iname, 'person', 'true', function(err, nodes) {
assert.ok(!err);
assert.ok(!nodes);
db.index.read(iname, 'person', 'false', function(err, nodes) {
assert.ok(!err);
assert.ok(!nodes);
done();
});
});
});
})
}
async.series([createAndIndex, readIndex], done);
});
it('should remove all instances of a node from an index', function(done) {
var iname = uniqn();
function createAndIndex(done) {
db.save({ name: 'Helge' }, function(err, node) {
db.node.index(iname, node, 'person', 'true', function(err) {
db.node.index(iname, node, 'otherkey', 'false', function(err) {
done();
});
});
});
}
function readIndex(done) {
db.index.read(iname, 'person', 'true', function(err, node) {
assert.equal(node.name, "Helge");
db.index.remove(iname, node, function(err) {
assert.ok(!err)
db.index.read(iname, 'person', 'true', function(err, nodes) {
assert.ok(!err);
assert.ok(!nodes);
db.index.read(iname, 'otherkey', 'false', function(err, nodes) {
assert.ok(!err);
assert.ok(!nodes);
done();
});
});
});
})
}
async.series([createAndIndex, readIndex], done);
});
it('should delete an index', function(done) {
var iname = uniqn();
function createAndIndex(done) {
db.save({ name: 'Helge' }, function(err, node) {
db.node.index(iname, node, 'person', 'true', function(err) {
db.node.index(iname, node, 'otherkey', 'false', function(err) {
done();
});
});
});
}
function readIndex(done) {
db.index.read(iname, 'person', 'true', function(err, node) {
assert.equal(node.name, "Helge");
db.index.delete(iname, function(err) {
assert.ok(!err)
db.index.read(iname, 'person', 'true', function(err, nodes) {
assert.ok(err);
assert.ok(!nodes);
db.index.read(iname, 'otherkey', 'false', function(err, nodes) {
assert.ok(err);
assert.ok(!nodes);
done();
});
});
});
})
}
async.series([createAndIndex, readIndex], done);
});
describe('uniqueness', function() {
it('should create a unique node', function(done) {
var index = uniqn();
var node = { name: 'Johanna' };
db.index.getOrSaveUnique(node, index, 'name', 'johanna',
function(err, node) {
it('should list indexes for a label', function(done) {
var labelname = uniqn();
db.index.create(labelname, 'name', function(err, index) {
assert(!err);
db.index.indexes(labelname, function(err, indexes) {
assert(!err);
assert.equal(node.name, 'Johanna');
assert(node.id);
assert.equal(indexes.length, 1);
assert.equal(indexes[0].label, labelname);
assert.equal(indexes[0].property_keys.length, 1);
assert.equal(indexes[0].property_keys[0], 'name');
done();
});
});
});
it('should get an existing node instead of creating a new', function(done) {
var index = uniqn();
var node = { name: 'Johanna' };
db.index.getOrSaveUnique(node, index, 'name', 'johanna',
function(err, originalNode) {
it('should drop an index', function(done) {
var labelname = uniqn();
db.index.create(labelname, 'name', function(err, index) {
assert(!err);
db.index.drop(labelname, 'name', function(err) {
assert(!err);
db.index.getOrSaveUnique(node, index, 'name', 'johanna',
function(err, newNode) {
db.index.indexes(labelname, function(err, indexes) {
assert(!err);
assert.equal(newNode.id, originalNode.id);
db.index.read(index, 'name', 'johanna', function(err, node) {
assert(!err);
assert(node);
assert.equal(node.id, originalNode.id);
assert.equal(node.name, 'Johanna');
done();
});
});
});
});
it('should create a unique rel', function(done) {
var index = uniqn();
function setupNodes(cb) {
var node = { name: 'Johanna' };
var node2 = { name: 'Sun sarkyä anna mä en' };
db.save([node, node2], function(err,nodes) {
assert(!err);
cb(nodes[0], nodes[1]);
});
}
setupNodes(function(node, node2) {
db.rel.index.getOrSaveUnique(node, 'sings', node2, index, 'name',
'johanna', function(err, rel) {
assert(!err);
assert(rel.id);
assert(rel.start);
assert.equal(rel.start, node.id);
assert(rel.end);
assert.equal(rel.end, node2.id);
assert.equal(rel.type, 'sings');
assert(indexes.length == 0);
done();

@@ -488,301 +68,3 @@ });

});
it('should create a unique rel with properties', function(done) {
var index = uniqn();
function setupNodes(cb) {
var node = { name: 'Johanna' };
var node2 = { name: 'Sun sarkyä anna mä en' };
db.save([node, node2], function(err,nodes) {
assert(!err);
cb(nodes[0], nodes[1]);
});
}
var props = { original: true };
setupNodes(function(node, node2) {
db.rel.index.getOrSaveUnique(node, 'sings', node2, props, index, 'name',
'johanna', function(err, rel) {
assert(!err);
assert(rel.id);
assert(rel.start);
assert.equal(rel.start, node.id);
assert(rel.end);
assert.equal(rel.end, node2.id);
assert.equal(rel.type, 'sings');
assert.deepEqual(rel.properties, props);
done();
});
});
});
it('should get original rel in get-or-save mode when saving',
function(done) {
var index = uniqn();
function setupNodes(cb) {
var node = { name: 'Johanna' };
var node2 = { name: 'Sun sarkyä anna mä en' };
db.save([node, node2], function(err,nodes) {
assert(!err);
cb(nodes[0], nodes[1]);
});
}
setupNodes(function(node, node2) {
db.rel.index.getOrSaveUnique(node, 'sings', node2, index, 'name',
'johanna', function(err, rel) {
assert(!err);
db.rel.index.getOrSaveUnique(node, 'sung', node2, index, 'name',
'johanna', function(err, newRel) {
assert(!err);
assert.deepEqual(newRel, rel);
db.rel.index.read(index, 'name', 'johanna', function(err, irel) {
assert.equal(rel.id, irel.id);
done();
});
});
});
});
});
it('should create a unique node in save-or-fail mode', function(done) {
var index = uniqn();
var node = { name: 'Johanna' };
db.index.saveUniqueOrFail(node, index, 'name', 'johanna',
function(err, node) {
assert(!err);
assert.equal(node.name, 'Johanna');
assert(node.id);
db.index.read(index, 'name', 'johanna', function(err, inode) {
assert(!err);
assert.equal(inode.id, node.id);
done();
});
});
});
it('should create a unique rel in save-or-fail mode', function(done) {
var index = uniqn();
function setupNodes(cb) {
var node = { name: 'Johanna' };
var node2 = { name: 'Sun sarkyä anna mä en' };
db.save([node, node2], function(err,nodes) {
assert(!err);
cb(nodes[0], nodes[1]);
});
}
setupNodes(function(node, node2) {
db.rel.index.saveUniqueOrFail(node, 'sings', node2, index, 'name',
'johanna', function(err, rel) {
assert(!err);
assert(rel.id);
assert(rel.start);
assert.equal(rel.start, node.id);
assert(rel.end);
assert.equal(rel.end, node2.id);
assert.equal(rel.type, 'sings');
db.rel.index.read(index, 'name', 'johanna', function(err, irel) {
assert(!err);
assert.deepEqual(irel, rel);
done();
});
});
});
});
it('should create a unique rel with properties in save-or-fail mode',
function(done) {
var index = uniqn();
function setupNodes(cb) {
var node = { name: 'Johanna' };
var node2 = { name: 'Sun sarkyä anna mä en' };
db.save([node, node2], function(err,nodes) {
assert(!err);
cb(nodes[0], nodes[1]);
});
}
var props = { original: true };
setupNodes(function(node, node2) {
db.rel.index.saveUniqueOrFail(node, 'sings', node2, props, index, 'name',
'johanna', function(err, rel) {
assert(!err);
assert(rel.id);
assert(rel.start);
assert.equal(rel.start, node.id);
assert(rel.end);
assert.equal(rel.end, node2.id);
assert.equal(rel.type, 'sings');
assert.deepEqual(rel.properties, props);
db.rel.index.read(index, 'name', 'johanna', function(err, irel) {
assert(!err);
assert.deepEqual(rel, irel);
done();
});
});
});
});
it('should fail in save-or-fail mode when re-writing a unique rel',
function(done) {
var index = uniqn();
function setupNodes(cb) {
var node = { name: 'Johanna' };
var node2 = { name: 'Sun sarkyä anna mä en' };
db.save([node, node2], function(err,nodes) {
assert(!err);
cb(nodes[0], nodes[1]);
});
}
setupNodes(function(node, node2) {
db.rel.index.saveUniqueOrFail(node, 'sings', node2, index, 'name',
'johanna', function(err, rel) {
assert(!err);
db.rel.index.saveUniqueOrFail(node, 'sung', node2, index, 'name',
'johanna', function(err, newRel) {
assert(err);
assert(err.statusCode == 409);
assert(!newRel);
db.rel.index.read(index, 'name', 'johanna', function(err, irel) {
assert(!err);
assert.deepEqual(irel, rel);
done();
});
});
});
});
});
it('should fail in save-or-fail mode when re-writing a unique node',
function(done) {
var index = uniqn();
var node = { name: 'Johanna' };
db.index.saveUniqueOrFail(node, index, 'name', 'johanna',
function(err, originalNode) {
assert(!err);
db.index.saveUniqueOrFail(node, index, 'name', 'johanna',
function(err, newNode) {
assert(err);
assert(err.statusCode == 409);
assert(!newNode);
done()
});
});
});
it('alias should fail in save-or-fail mode when re-writing a unique rel',
function(done) {
var index = uniqn();
function setupNodes(cb) {
var node = { name: 'Johanna' };
var node2 = { name: 'Sun sarkyä anna mä en' };
db.save([node, node2], function(err,nodes) {
assert(!err);
cb(nodes[0], nodes[1]);
});
}
setupNodes(function(node, node2) {
db.rel.createUnique(node, 'sings', node2, index, 'name',
'johanna', function(err, rel) {
assert(!err);
db.rel.createUnique(node, 'sung', node2, index, 'name',
'johanna', function(err, newRel) {
assert(err);
assert(err.statusCode == 409);
assert(!newRel);
db.rel.index.read(index, 'name', 'johanna', function(err, irel) {
assert(!err);
assert.deepEqual(rel, irel);
done();
});
});
});
});
});
it('alias should fail in save-or-fail mode when re-writing a unique node',
function(done) {
var index = uniqn();
var node = { name: 'Johanna' };
db.saveUnique(node, index, 'name', 'johanna',
function(err, originalNode) {
assert(!err);
db.saveUnique(node, index, 'name', 'johanna', function(err, newNode) {
assert(err);
assert(err.statusCode == 409);
assert(!newNode);
db.index.read(index, 'name', 'johanna', function(err, inode) {
assert(!err);
assert.deepEqual(inode, originalNode);
done();
});
});
});
});
it('alias should get original rel in get-or-save mode when saving',
function(done) {
var index = uniqn();
function setupNodes(cb) {
var node = { name: 'Johanna' };
var node2 = { name: 'Sun sarkyä anna mä en' };
db.save([node, node2], function(err,nodes) {
assert(!err);
cb(nodes[0], nodes[1]);
});
}
setupNodes(function(node, node2) {
db.rel.createUnique(node, 'sings', node2, index, 'name',
'johanna', true, function(err, rel) {
assert(!err);
db.rel.createUnique(node, 'sung', node2, index, 'name',
'johanna', true, function(err, newRel) {
assert(!err);
assert.deepEqual(newRel, rel);
done();
});
});
});
});
it('alias should get an existing node instead of creating a new',
function(done) {
var index = uniqn();
var node = { name: 'Johanna' };
db.saveUnique(node, index, 'name', 'johanna', true,
function(err, originalNode) {
assert(!err);
db.saveUnique(node, index, 'name', 'johanna', true,
function(err, newNode) {
assert(!err);
assert.equal(newNode.id, originalNode.id);
db.index.read(index, 'name', 'johanna', function(err, node) {
assert(!err);
assert(node);
assert.equal(node.id, originalNode.id);
assert.equal(node.name, 'Johanna');
done();
});
});
});
});
});
});

@@ -383,3 +383,3 @@ /* -*- Mode: Javascript; js-indent-level: 2 -*- */

users = users.slice(1);
db.index(uniqueKey, users, 'some_thing', 'perhaps', function() {
db.legacyindex(uniqueKey, users, 'some_thing', 'perhaps', function() {
done();

@@ -386,0 +386,0 @@ })

@@ -24,6 +24,6 @@ /* -*- Mode: Javascript; js-indent-level: 2 -*- */

function mkIdx(node, done) {
db.index(idxName, node.id, 'application', node.jelly, done);
db.legacyindex(idxName, node.id, 'application', node.jelly, done);
}
function readIdx(done) {
db.node.index.read(idxName, 'application',
db.node.legacyindex.read(idxName, 'application',
origNode.jelly, done);

@@ -30,0 +30,0 @@ }

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc