@@ -19,6 +19,7 @@ module.exports = function(RED) {
19
19
var url = require ( 'url' ) ;
20
20
var querystring = require ( 'querystring' ) ;
21
21
var cfEnv = require ( "cfenv" ) ;
22
+ var Cloudant = require ( "cloudant" ) ;
22
23
23
24
var MAX_ATTEMPTS = 3 ;
24
25
@@ -124,52 +125,59 @@ module.exports = function(RED) {
124
125
this . operation = n . operation ;
125
126
this . payonly = n . payonly || false ;
126
127
this . database = n . database ;
127
- this . cloudant = n . cloudant ;
128
- this . url = _getUrl ( this , n ) ;
129
-
130
- if ( this . url ) {
131
- var node = this ;
132
-
133
- var nano = require ( 'nano' ) ( this . url ) ;
134
- var db = nano . use ( node . database ) ;
128
+ this . cloudantConfig = RED . nodes . getNode ( n . cloudant ) ;
129
+
130
+ var node = this ;
131
+ var credentials = {
132
+ account : node . cloudantConfig . credentials . user ,
133
+ password : node . cloudantConfig . credentials . password
134
+ } ;
135
+
136
+ Cloudant ( credentials , function ( err , cloudant ) {
137
+ if ( err ) { node . error ( err ) ; }
138
+ else {
139
+ // check if the database exists and create it if it doesn't
140
+ createDatabase ( cloudant , node ) ;
141
+
142
+ node . on ( "input" , function ( msg ) {
143
+ handleMessage ( cloudant , node , msg ) ;
144
+ } ) ;
145
+ }
146
+ } ) ;
135
147
136
- // check if the database exists and create it if it doesn't
137
- nano . db . list ( function ( err , body ) {
148
+ function createDatabase ( cloudant , node ) {
149
+ cloudant . db . list ( function ( err , all_dbs ) {
138
150
if ( err ) { node . error ( err ) ; }
139
151
else {
140
- if ( body && body . indexOf ( node . database ) < 0 ) {
141
- nano . db . create ( node . database , function ( err , body ) {
142
- if ( err ) { node . error ( err ) ; }
143
- } ) ;
152
+ if ( all_dbs && all_dbs . indexOf ( node . database ) < 0 ) {
153
+ cloudant . db . create ( node . database ) ;
144
154
}
145
155
}
146
156
} ) ;
157
+ }
158
+
159
+ function handleMessage ( cloudant , node , msg ) {
160
+ if ( node . operation === "insert" ) {
161
+ var msg = node . payonly ? msg . payload : msg ;
162
+ var root = node . payonly ? "payload" : "msg" ;
163
+ var doc = parseMessage ( msg , root ) ;
147
164
148
- node . on ( "input" , function ( msg ) {
149
- if ( node . operation === "insert" ) {
150
- var msg = node . payonly ? msg . payload : msg ;
151
- var root = node . payonly ? "payload" : "msg" ;
152
- var doc = parseMessage ( msg , root ) ;
165
+ insertDocument ( cloudant , node , doc , MAX_ATTEMPTS , function ( err , body ) {
166
+ if ( err ) { node . error ( err ) ; }
167
+ } ) ;
168
+ }
169
+ else if ( node . operation === "delete" ) {
170
+ var doc = parseMessage ( msg . payload || msg , "" ) ;
153
171
154
- insertDocument ( doc , db , MAX_ATTEMPTS , function ( err , body ) {
172
+ if ( "_rev" in doc && "_id" in doc ) {
173
+ var db = cloudant . use ( node . database ) ;
174
+ db . destroy ( doc . _id , doc . _rev , function ( err , body ) {
155
175
if ( err ) { node . error ( err ) ; }
156
176
} ) ;
177
+ } else {
178
+ node . error ( "_rev and _id are required to delete a document" ) ;
157
179
}
158
- else if ( node . operation === "delete" ) {
159
- var doc = parseMessage ( msg . payload || msg , "" ) ;
160
-
161
- if ( "_rev" in doc && "_id" in doc ) {
162
- db . destroy ( doc . _id , doc . _rev , function ( err , body ) {
163
- if ( err ) { node . error ( err ) ; }
164
- } ) ;
165
- } else {
166
- node . error ( "_rev and _id are required to delete a document" ) ;
167
- }
168
- }
169
- } ) ;
170
-
171
- } else {
172
- this . error ( "missing cloudant configuration" ) ;
180
+ }
173
181
}
174
182
175
183
function parseMessage ( msg , root ) {
@@ -194,12 +202,13 @@ module.exports = function(RED) {
194
202
// beforehand. If the database doesn't exist, it will create one
195
203
// with the name specified in +db+. To prevent loops, it only tries
196
204
// +attempts+ number of times.
197
- function insertDocument ( doc , db , attempts , callback ) {
205
+ function insertDocument ( cloudant , node , doc , attempts , callback ) {
206
+ var db = cloudant . use ( node . database ) ;
198
207
db . insert ( doc , function ( err , body ) {
199
208
if ( err && err . status_code === 404 && attempts > 0 ) {
200
209
// status_code 404 means the database was not found
201
- return nano . db . create ( db . config . db , function ( ) {
202
- insertDocument ( doc , db , attempts - 1 , callback ) ;
210
+ return cloudant . db . create ( db . config . db , function ( ) {
211
+ insertDocument ( cloudant , node , doc , attempts - 1 , callback ) ;
203
212
} ) ;
204
213
}
205
214
@@ -212,36 +221,66 @@ module.exports = function(RED) {
212
221
function CloudantInNode ( n ) {
213
222
RED . nodes . createNode ( this , n ) ;
214
223
215
- this . cloudant = n . cloudant ;
216
- this . url = _getUrl ( this , n ) ;
217
- this . database = n . database ;
218
- this . search = n . search ;
219
- this . design = n . design ;
220
- this . index = n . index ;
221
- this . payloadIn = "" ;
224
+ this . cloudantConfig = RED . nodes . getNode ( n . cloudant ) ;
225
+ this . database = n . database ;
226
+ this . search = n . search ;
227
+ this . design = n . design ;
228
+ this . index = n . index ;
229
+ this . inputId = "" ;
230
+
231
+ var node = this ;
232
+ var credentials = {
233
+ account : node . cloudantConfig . credentials . user ,
234
+ password : node . cloudantConfig . credentials . password
235
+ } ;
236
+
237
+ Cloudant ( credentials , function ( err , cloudant ) {
238
+ if ( err ) { node . error ( err ) ; }
239
+ else {
240
+ node . on ( "input" , function ( msg ) {
241
+ var db = cloudant . use ( node . database ) ;
242
+
243
+ if ( node . search === "_id_" ) {
244
+ var id = getDocumentId ( msg . payload ) ;
245
+ node . inputId = id ;
246
+
247
+ db . get ( id , function ( err , body ) {
248
+ sendDocumentOnPayload ( err , body , msg ) ;
249
+ } ) ;
250
+ }
251
+ else if ( node . search === "_idx_" ) {
252
+ var query = { q : formatSearchQuery ( msg . payload ) } ;
253
+ db . search ( node . design , node . index , query , function ( err , body ) {
254
+ sendDocumentOnPayload ( err , body , msg ) ;
255
+ } ) ;
256
+ }
257
+ } ) ;
258
+ }
259
+ } ) ;
222
260
223
- if ( this . url ) {
224
- var node = this ;
261
+ function getDocumentId ( payload ) {
262
+ if ( typeof payload === "object" ) {
263
+ if ( "_id" in payload || "id" in payload ) {
264
+ return payload . id || payload . _id ;
265
+ }
266
+ }
225
267
226
- var nano = require ( 'nano' ) ( node . url ) ;
227
- var db = nano . use ( node . database ) ;
268
+ return payload ;
269
+ }
228
270
229
- node . on ( "input" , function ( msg ) {
230
- node . payloadIn = msg . payload ;
271
+ function formatSearchQuery ( query ) {
272
+ if ( typeof query === "object" ) {
273
+ // useful when passing the query on HTTP params
274
+ if ( "q" in query ) { return query . q ; }
231
275
232
- if ( node . search === "_id_" ) {
233
- var id = msg . payload ;
234
- db . get ( id , function ( err , body ) {
235
- sendDocumentOnPayload ( err , body , msg ) ;
236
- } ) ;
237
- }
238
- else if ( node . search === "_idx_" ) {
239
- var query = { q : msg . payload } ;
240
- db . search ( node . design , node . index , query , function ( err , body ) {
241
- sendDocumentOnPayload ( err , body , msg ) ;
242
- } ) ;
276
+ var queryString = "" ;
277
+ for ( var key in query ) {
278
+ queryString += key + ":" + query [ key ] + " " ;
243
279
}
244
- } ) ;
280
+
281
+ return queryString . trim ( ) ;
282
+ }
283
+ return query ;
245
284
}
246
285
247
286
function sendDocumentOnPayload ( err , body , msg ) {
@@ -251,21 +290,21 @@ module.exports = function(RED) {
251
290
msg . payload = null ;
252
291
253
292
if ( err . description === "missing" ) {
254
- node . warn ( "Document '" + node . payloadIn + "' not found in database '" +
293
+ node . warn ( "Document '" + node . inputId + "' not found in database '" +
255
294
node . database + "'." ) ;
256
295
} else {
257
296
node . error ( err . reason ) ;
258
297
}
259
298
}
260
-
299
+
261
300
node . send ( msg ) ;
262
301
}
263
302
}
264
303
RED . nodes . registerType ( "cloudant in" , CloudantInNode ) ;
265
304
266
305
function _getUrl ( node , n ) {
267
306
if ( n . service == "_ext_" ) {
268
- var cloudantConfig = RED . nodes . getNode ( node . cloudant ) ;
307
+ var cloudantConfig = RED . nodes . getNode ( node . cloudantConfig ) ;
269
308
if ( cloudantConfig ) {
270
309
return cloudantConfig . url ;
271
310
}
0 commit comments