UNPKG

6.35 kBJavaScriptView Raw
1/**
2 * Store: SimpleDB
3 * - Saving data using SimpleDB
4**/
5
6//var uuid = require("node-uuid"),
7
8var CRUD = function( options ){
9
10 // use the provided db (error control?)
11 this.db = options.db;
12 this.table = this.table || options.table || false;
13 // continue with parent (if available)
14}
15
16CRUD.prototype = {
17
18 constructor: CRUD,
19
20 create: function( data, callback ){
21 // fallbacks
22 data = data || {};
23 callback = callback || function(){};
24 // variables
25 var self = this;
26
27 var attributes = this.attributes( data );
28
29 this.db.call("PutAttributes", attributes, function( err, result ){
30 if (err) return callback(err);
31 var response = self.parse( result );
32 // error control
33 callback( null, response );
34 });
35 },
36
37 read: function( data, callback, options ) {
38 // fallbacks
39 options = options || {};
40 callback = callback || function(){};
41 // variables
42 var self = this;
43 var query = "select * from "+ this.table;
44 if( data ){
45 query += " where "+ this.query( data, options );
46 }
47
48 this.db.call("Select", { SelectExpression: query }, function(err, result) {
49 if (err) return callback(err);
50 var response = self.parse( result["SelectResult"] );
51 // convert to an array if returning a single object (for no id)
52 //if ( response && (typeof data.id == "undefined") && !(response instanceof Array) ){
53 // response = [response];
54 //}
55 callback( null, response );
56 });
57
58 },
59
60 update: function( data, callback ) {
61 // fallback for no callback
62 callback = callback || function(){};
63 // variables
64 var self = this;
65 // don't execute with no specified id...
66 if( typeof data.id == "undefined" ) return callback({ error: "No object id specified" });
67
68 var attributes = this.attributes( data, { replace : true });
69
70 this.db.call("PutAttributes", attributes, function( err, result ){
71 if (err) return callback(err);
72 var response = self.parse( result );
73 // error control
74 callback( null, response );
75 });
76
77 },
78
79 destroy: function( data, callback, options ) {
80 // fallbacks
81 options = options || {};
82 callback = callback || function(){};
83 // variables
84 var self = this;
85 // don't execute with no specified id...
86 if( typeof data.id == "undefined" ) return callback({ error: "No object id specified" });
87
88 var attributes = this.attributes( data, { noAttr: true } );
89
90 this.db.call("DeleteAttributes", attributes, function( err, result ){
91 if (err) return callback(err);
92 var response = self.parse( result );
93 // error control
94 //...
95 // return a standard success response
96 callback( null, { success: true });
97 });
98
99 },
100
101 query: function( data, options ){
102 // fallbacks
103 options = options || {};
104 var str = "";
105
106 //if(typeof data === "string") return data;
107
108 var first = true;
109
110 for( var key in data ){
111 if( !first ) str += " and ";
112 var exp = "";
113 // conditions
114 if( key == "$or" || key == "$and" ){
115 var length = data[key].length;
116 for(var num in data[key]){
117 var condition = data[key][num];
118 // loop...
119 exp += "("+ this.query( condition ) +")";
120 if( num < length-1 ) exp += ( key == "$or" ) ? " or " : " and ";
121 }
122 str += "("+ exp +")";
123 } else {
124 exp = "`{{field}}`='{{value}}'";
125 //
126 var field = key;
127 var value = data[key];
128 // check the key
129 var like = ( key.search(/\./) > -1 ) ? true : false ;
130 // if looking into the object...
131 if(like){
132 exp = "`{{field}}` like '%{{value}}%'";
133 var field = key.split(".");
134 field = field[0];
135 }
136 // operators
137 if(data[key] && data[key].$gt){
138 exp = "`{{field}}` > '{{value}}'";
139 value = data[key].$gt;
140 }
141 if(data[key] && data[key].$lt){
142 exp = "`{{field}}` < '{{value}}'";
143 value = data[key].$lt;
144 }
145
146 if( typeof value == "object") value = JSON.stringify(value);
147 str += exp.replace("{{field}}", field).replace("{{value}}", value);
148 }
149
150 //
151 first = false;
152 }
153
154 if( options.limit ){
155 str += " limit "+ options.limit;
156 }
157
158 return str;
159
160 },
161
162 // Helpers
163
164 attributes: function(model, options){
165 //default options
166 options = options || {};
167 options.replace = options.replace || false;
168 options.noAttr = options.noAttr || false;
169
170 var query = {};
171 var count = 0;
172
173 // create id if not defined
174 //if( typeof model.id == "undefined" ) model.id = uuid.v1();
175
176 query.DomainName = this.table;
177 query.ItemName = model.id;
178 // if we don't require any attributes end now
179 if(options.noAttr) return query;
180
181 // deal with attributes
182 for( var key in model ){
183 //if( key == "id" ) continue;
184 var item = new Array()
185 query["Attribute."+ count +".Name"] = key;
186 query["Attribute."+ count +".Value"] = ( typeof model[key] != "object") ? model[key] : JSON.stringify(model[key]);
187 if(options.replace) query["Attribute."+ count +".Replace"] = true;
188 count++;
189 }
190
191 return query;
192 },
193
194 parse: function( data ) {
195
196 // return empty if there are no results
197 if( typeof data["Item"] == "undefined"){
198 return false;
199 }
200
201 if( data["Item"] instanceof Array ){
202
203 // deconstruct the response to an array
204 var collection = [];
205
206 for( i in data["Item"] ){
207
208 var model = {};
209 var attr = data["Item"][i]["Attribute"];
210 //var attr = data["Item"][i];
211
212 // parse as independent attributes
213 var key = "";
214 for( k in attr ){
215
216 try{
217 model[attr[k]["Name"]] = JSON.parse( attr[k]["Value"] );
218 } catch(err) {
219 // output err.message ?
220 model[attr[k]["Name"]] = attr[k]["Value"];
221 }
222
223 }
224 // ovewrite any model id present with the Attribute Name
225 model.id = data["Item"][i]["Name"];
226 // filter model
227 model = this.filter( model );
228 //
229 collection.push(model);
230
231 }
232
233 } else {
234
235 var model = {};
236 var attr = data["Item"]["Attribute"];
237
238 if( attr instanceof Array ){
239 for (var i in attr) {
240 try{
241 model[attr[i]["Name"]] = JSON.parse( attr[i]["Value"] );
242 } catch(err) {
243 // output err.message ?
244 model[attr[i]["Name"]] = attr[i]["Value"];
245 }
246 }
247 } else {
248 // this is only one item
249 model[attr["Name"]] = attr["Value"];
250 }
251
252 // ovewrite any model id present with the Attribute Name
253 model.id = data["Item"]["Name"];
254 // filter model
255 model = this.filter( model );
256 }
257
258 // check if we have a model or collection returned
259 return collection || model;
260
261 }
262
263}
264
265// Helpers
266
267
268
269module.exports = CRUD;