UNPKG

5.32 kBJavaScriptView Raw
1var _ = require("underscore");
2var DataLayer = require("./DataLayer");
3var helpers = require("../helpers");
4
5// https://github.com/haio/neo4j-io
6
7module.exports = DataLayer.extend("Neo4jLayer", {
8
9 parseArguments: function(args){
10 switch(args.length){
11 case 0: return false;
12 case 1:
13 if(typeof args[0] !== "function") return false;
14 else return [undefined,{},args[0]];
15 case 2:
16 if(typeof args[1] !== "function") return false;
17 else return [args[0],{}, args[1]];
18 case 3:
19 if(typeof args[2] !== "function") return false;
20 else return [args[0],args[1], args[2]];
21 default: return false;
22 }
23 },
24
25 parseOptions: function(data, options){
26 if(!options.labels) options.labels = "";
27 if(!data) options.properties = "";
28 else{
29 var properties = _.pick(data, _.without(this.publicFields || _.keys(this.fields), this.primaryKey));
30 options.properties = "{"+_.keys(properties).map(function(prop){
31 return [prop, ": ", "#", prop].join("");
32 }).join(", ")+"}";
33 }
34 },
35
36 formatResult: function(result){
37 if(Array.isArray(result)) result = result.pop();
38 return _.extend(result.data, _.object([[this.primaryKey, result.metadata.id]]));
39 },
40
41 create: function(obj, options, cb){
42 var self = this;
43 var properties = _.pick(obj, _.without(this.publicFields || _.keys(this.fields), this.primaryKey));
44 if(_.keys(properties).length === 0) return cb("Error: empty object");
45 this.query("CREATE (@nodeName@labels @properties) RETURN @nodeName", {values: properties, options: options}, function(err, result){
46 if(err) return cb(err);
47 cb(null, self.formatResult(result[0]));
48 });
49 },
50
51 find: function(pattern, options, cb){
52 var self = this;
53 if(typeof pattern === "number" || typeof pattern === "string"){
54 this.neo4j.Node.get(pattern).then(function(result){
55 cb(null, self.formatResult(result));
56 }).catch(function(err){cb(err);});
57 }
58 else if(Array.isArray(pattern) && _.every(pattern, function(p){return typeof p === "number" || typeof p === "string"})){
59 this.query("MATCH (@nodeName@labels) WHERE ID(@nodeName) IN ["+this.neo4j.escape(pattern)+"] RETURN @nodeName", {values: false, options: options}, function(err, result){
60 if(err) return cb(err);
61 cb(null, result.map(function(r){return self.formatResult(r);}));
62 });
63 }
64 else if(_.isObject(pattern)){
65 var properties = _.pick(pattern, _.without(this.publicFields || _.keys(this.fields), this.primaryKey));
66 if(_.keys(properties).length === 0) return cb(null, []);
67 this.query("MATCH (@nodeName@labels) WHERE "+_.keys(properties).map(function(prop){
68 if(Array.isArray(properties[prop])){
69 return ["@nodeName", ".", prop, " IN ", "[", properties[prop].map(function(val){
70 return self.neo4j.escape(val);
71 }), "]"].join("");
72 }
73 return ["@nodeName", ".", prop, "=", "#", prop].join("");
74 }).join(" AND ")+" RETURN @nodeName", {values: properties, options: options}, function(err, result){
75 if(err) return cb(err);
76 cb(null, result.map(function(r){return self.formatResult(r);}));
77 });
78 }
79 else{
80 this.query("MATCH (@nodeName@labels) RETURN @nodeName", {values: false, options: options}, function(err, result){
81 if(err) return cb(err);
82 cb(null, result.map(function(r){return self.formatResult(r);}));
83 });
84 }
85 },
86
87 findOne: function(pattern, options, cb){
88 // TODO
89 },
90
91 update: function(pattern, options, cb){
92 // http://neo4j.com/docs/stable/query-set.html
93 },
94
95 delete: function(pattern, options, cb){
96
97 },
98
99
100}, {
101
102 setupDatabase: function(self, env, name){
103 var Prototype = this;
104 self.setupNode = function(cb){ Prototype.setupStore(self, env, function(err){
105 if(err) return cb(err);
106 env.i.do("log.sys", "DataLayer:neo4j", name);
107 cb();
108 }); }
109 },
110
111 setupStore: function(instance, env, cb){
112 instance.neo4j = env.engines.neo4j;
113 instance.query = function(query, data, cb){
114 _.extend(data.options, {nodeName: instance.nodeName, debug: data.options.debug || this.options.debug });
115 this.parseOptions(data.values, data.options);
116 var query = this.neo4j.format(query, data, cb);
117 if(query === false) return cb("Invalid query");
118 if(data.options.debug){
119 env.i.do("log.debug", ["[ Neo4j debug ]",
120 [ " V V V V V V V V V V V V V V V V ","==============================================================================================>>>",
121 data.options.debug,
122 "Neo4j> "+query,
123 "DATA> "+JSON.stringify(data.values),
124 "==============================================================================================<<<",""
125 ].join("\n")
126 ]);
127 delete data.options.debug;
128 }
129 this.neo4j.query(query, data.values).then(function(result){ cb(null, result.data); }).catch(cb);
130 }
131 cb();
132 },
133
134 extend: function(name, props, statics){
135 this.setMethods(this.prototype, props);
136 return DataLayer.extend.apply(this, arguments);
137 }
138});