Skip to content

Instantly share code, notes, and snippets.

@vslinko
Last active January 5, 2016 17:17
Show Gist options
  • Save vslinko/29d926bc069caaa32553 to your computer and use it in GitHub Desktop.
Save vslinko/29d926bc069caaa32553 to your computer and use it in GitHub Desktop.
Neo4j Helpers
'use strict';
const CypherQuery = require('./cypher').CypherQuery;
module.exports = function createQueryExecutor(context) {
const executor = function executeQuery(query) {
if (typeof query === 'function') {
return query(executor);
}
const rawQuery = query instanceof CypherQuery
? query.getRawQuery()
: query;
return new Promise((resolve, reject) => {
context.cypher(rawQuery, (err, result) => {
if (err) {
reject(err);
} else {
resolve(result);
}
});
});
};
return executor;
}
'use strict';
const createQueryExecutor = require('./createQueryExecutor');
module.exports = function createTransactionExecutor(db) {
return function executeTransaction(cb) {
const tx = db.beginTransaction();
const executeQuery = createQueryExecutor(tx);
return Promise.resolve(executeQuery(cb))
.then((result) => {
return new Promise((resolve, reject) => {
tx.commit((err) => {
if (err) {
reject(err);
} else {
resolve(result);
}
});
});
})
.then(undefined, (err) => {
if (tx.state === tx.STATE_OPEN || tx.state === tx.STATE_PENDING) {
return new Promise((resolve, reject) => {
tx.rollback(() => {
reject(err);
});
});
}
throw err;
});
};
};
'use strict';
class CypherQuery {
constructor(strings, values) {
this._strings = strings;
this._values = values;
}
getRawQuery() {
return this._getRawQuery({paramPrefix: 'p_'});
}
_getRawQuery(config) {
const paramPrefix = config.paramPrefix;
return this._strings
.reduce((rawQuery, string, index) => {
const query = rawQuery.query;
const params = rawQuery.params;
if (index === 0) {
return {query: string, params: {}};
}
const paramIndex = index - 1;
const value = this._values[paramIndex];
if (value instanceof CypherQuery) {
const options = value._getRawQuery({
paramPrefix: paramPrefix + paramIndex + '_',
});
return {
query: `${query}${options.query}${string}`,
params: Object.assign({}, params, options.params),
};
}
return {
query: `${query}{${paramPrefix}${paramIndex}}${string}`,
params: Object.assign({}, params, {
[`${paramPrefix}${paramIndex}`]: value,
}),
};
}, {query: '', params: {}});
}
}
function cypher(strings) {
const values = Array.prototype.slice.call(arguments, 1);
return new CypherQuery(strings, values);
}
module.exports.CypherQuery = CypherQuery;
module.exports.cypher = cypher;
@Pepeye
Copy link

Pepeye commented Dec 30, 2015

@vslinko Hi - I was looking through your Ripster repo and must say well done. I use neo4j a lot and recently discovered React/Redux, Graphql and Relay.

I'm particularly interested right now in moving an existing Neo4j + Rails api to Neo4j + Node + Graphql. Could you I ask you a for a big favour - to comment the above 3 gist which i see is also featured in the ripster: src/graphql/db.js file.

I can follow most of the code but a little lost here - the bit I'm not following so well is in the _getRawQuery method in the cypher.js above.

@MerrickClark
Copy link

@Pepeye I'm on a similar learning path myself, haven't tried this code yet, but looking forward to it. Would be great to collaborate on learning resources! Have you seen this one yet: https://github.com/chentsulin/awesome-graphql ? It seems there's not too many GraphQL + Neo4j resources out there yet...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment