11"use strict" ; 
22var  _  =  { 
3-   clone : require ( "lodash.clone" ) , 
43  omit : require ( "lodash.omit" ) 
54} ; 
65var  async  =  require ( "async" ) ; 
@@ -30,7 +29,7 @@ MongoStore._isRelationshipAttribute = function(attribute) {
3029
3130
3231MongoStore . _toMongoDocument  =  function ( resource )  { 
33-   var  document  =  _ . clone ( resource ,  true ) ; 
32+   var  document  =  _ . omit ( resource ,  function ( value )   {   return   value   ===   undefined ;   } ) ; 
3433  document . _id  =  MongoStore . _mongoUuid ( document . id ) ; 
3534  return  document ; 
3635} ; 
@@ -49,18 +48,46 @@ MongoStore._getRelationshipAttributeNames = function(attributes) {
4948} ; 
5049
5150
52- MongoStore . _getSearchCriteria  =  function ( relationships )  { 
53-   if  ( ! relationships )  return  { } ; 
51+ MongoStore . prototype . _getSearchCriteria  =  function ( request )  { 
52+   var  self  =  this ; 
53+   if  ( ! request . params . filter )  return  {  } ; 
54+ 
55+   var  criteria  =  Object . keys ( request . params . filter ) . map ( function ( attribute )  { 
56+     var  attributeConfig  =  self . resourceConfig . attributes [ attribute ] ; 
57+     // If the filter attribute doens't exist, skip it 
58+     if  ( ! attributeConfig )  return  null ; 
59+ 
60+     var  values  =  request . params . filter [ attribute ] ; 
61+     // Relationships need to be queried via .id 
62+     if  ( attributeConfig . _settings )  { 
63+       attribute  +=  ".id" ; 
64+       // Filters on nested resources should be skipped 
65+       if  ( values  instanceof  Object )  return  null ; 
66+     } 
5467
55-   var  relationshipNames  =  Object . getOwnPropertyNames ( relationships ) ; 
56-   var  criteria  =  relationshipNames . reduce ( function ( partialCriteria ,  relationshipName )  { 
57-     var  relationshipId  =  relationships [ relationshipName ] ; 
58-     partialCriteria [ relationshipName  +  ".id" ]  =  relationshipId ; 
59-     return  partialCriteria ; 
60-   } ,  { } ) ; 
61-   debug ( "criteria>" ,  JSON . stringify ( criteria ,  null ,  2 ) ) ; 
68+     // Coerce values to an array to simplify the logic 
69+     if  ( ! ( values  instanceof  Array ) )  values  =  [  values  ] ; 
70+     values  =  values . map ( function ( value )  { 
71+       if  ( value [ 0 ]  ===  "<" )  return  {  $lt : value . substring ( 1 )  } ; 
72+       if  ( value [ 0 ]  ===  ">" )  return  {  $gt : value . substring ( 1 )  } ; 
73+       if  ( value [ 0 ]  ===  "~" )  return  new  RegExp ( "^"  +  value . substring ( 1 )  +  "$" ,  "i" ) ; 
74+       if  ( value [ 0 ]  ===  ":" )  return  new  RegExp ( value . substring ( 1 ) ) ; 
75+       return  value ; 
76+     } ) . map ( function ( value )  { 
77+       var  tmp  =  {  } ; 
78+       tmp [ attribute ]  =  value ; 
79+       return  tmp ; 
80+     } ) ; 
81+ 
82+     return  {  $or : values  } ; 
83+   } ) . filter ( function ( value )  { 
84+     return  value  !==  null ; 
85+   } ) ; 
6286
63-   return  criteria ; 
87+   if  ( criteria . length  ===  0 )  { 
88+     return  {  } ; 
89+   } 
90+   return  {  $and : criteria  } ; 
6491} ; 
6592
6693
@@ -95,7 +122,6 @@ MongoStore.prototype._applySort = function(request, cursor) {
95122  } 
96123  var  sortParam  =  {  } ; 
97124  sortParam [ attribute ]  =  order ; 
98-   debug ( "sort>" ,  sortParam ) ; 
99125
100126  return  cursor . sort ( sortParam ) ; 
101127} ; 
@@ -104,7 +130,6 @@ MongoStore.prototype._applySort = function(request, cursor) {
104130MongoStore . prototype . _applyPagination  =  function ( request ,  cursor )  { 
105131  if  ( ! request . params . page )  return  cursor ; 
106132
107-   debug ( "pagination>" ,  request . params . page . offset ,  request . params . page . limit ) ; 
108133  return  cursor . skip ( request . params . page . offset ) . limit ( request . params . page . limit ) ; 
109134} ; 
110135
@@ -125,7 +150,6 @@ MongoStore.prototype.initialise = function(resourceConfig) {
125150    return  console . error ( "error connecting to MongoDB:" ,  err . message ) ; 
126151  } ) . then ( function ( )  { 
127152    var  resourceName  =  resourceConfig . resource ; 
128-     debug ( "initialising resource ["  +  resourceName  +  "]" ) ; 
129153    var  collection  =  self . _db . collection ( resourceName ) ; 
130154    self . _createIndexesForRelationships ( collection ,  self . relationshipAttributeNames ) ; 
131155    self . ready  =  true ; 
@@ -156,7 +180,8 @@ MongoStore.prototype.populate = function(callback) {
156180MongoStore . prototype . search  =  function ( request ,  callback )  { 
157181  var  self  =  this ; 
158182  var  collection  =  self . _db . collection ( request . params . type ) ; 
159-   var  criteria  =  MongoStore . _getSearchCriteria ( request . params . relationships ) ; 
183+   var  criteria  =  self . _getSearchCriteria ( request ) ; 
184+   debug ( "search" ,  JSON . stringify ( criteria ) ) ; 
160185
161186  async . parallel ( { 
162187    resultSet : function ( asyncCallback )  { 
@@ -180,6 +205,8 @@ MongoStore.prototype.search = function(request, callback) {
180205MongoStore . prototype . find  =  function ( request ,  callback )  { 
181206  var  collection  =  this . _db . collection ( request . params . type ) ; 
182207  var  documentId  =  MongoStore . _mongoUuid ( request . params . id ) ; 
208+ 
209+   debug ( "findOne" ,  JSON . stringify ( {  _id : documentId  } ) ) ; 
183210  collection . findOne ( {  _id : documentId  } ,  {  _id : 0  } ,  function ( err ,  result )  { 
184211    if  ( err  ||  ! result )  { 
185212      return  callback ( MongoStore . _notFoundError ( request . params . type ,  request . params . id ) ) ; 
@@ -195,6 +222,7 @@ MongoStore.prototype.find = function(request, callback) {
195222MongoStore . prototype . create  =  function ( request ,  newResource ,  callback )  { 
196223  var  collection  =  this . _db . collection ( newResource . type ) ; 
197224  var  document  =  MongoStore . _toMongoDocument ( newResource ) ; 
225+   debug ( "insert" ,  JSON . stringify ( document ) ) ; 
198226  collection . insertOne ( document ,  function ( err )  { 
199227    if  ( err )  return  callback ( err ) ; 
200228    collection . findOne ( document ,  {  _id : 0  } ,  callback ) ; 
@@ -226,7 +254,7 @@ MongoStore.prototype.update = function(request, partialResource, callback) {
226254  var  collection  =  this . _db . collection ( request . params . type ) ; 
227255  var  documentId  =  MongoStore . _mongoUuid ( request . params . id ) ; 
228256  var  partialDocument  =  _ . omit ( partialResource ,  function ( value )  {  return  value  ===  undefined ;  } ) ; 
229-   debug ( "partialDocument> " ,  JSON . stringify ( partialDocument ,   null ,   2 ) ) ; 
257+   debug ( "findOneAndUpdate " ,  JSON . stringify ( partialDocument ) ) ; 
230258  collection . findOneAndUpdate ( { 
231259    _id : documentId 
232260  } ,  { 
@@ -235,12 +263,16 @@ MongoStore.prototype.update = function(request, partialResource, callback) {
235263    returnOriginal : false , 
236264    projection : {  _id : 0  } 
237265  } ,  function ( err ,  result )  { 
238-     debug ( "err>" ,  JSON . stringify ( err ,  null ,  2 ) ) ; 
239-     debug ( "result>" ,  JSON . stringify ( result ,  null ,  2 ) ) ; 
240-     if  ( err )  return  callback ( err ) ; 
266+     if  ( err )  { 
267+       debug ( "err" ,  JSON . stringify ( err ) ) ; 
268+       return  callback ( err ) ; 
269+     } 
270+ 
241271    if  ( ! result  ||  ! result . value )  { 
242272      return  callback ( MongoStore . _notFoundError ( request . params . type ,  request . params . id ) ) ; 
243273    } 
274+ 
275+     debug ( "result" ,  JSON . stringify ( result ) ) ; 
244276    return  callback ( null ,  result . value ) ; 
245277  } ) ; 
246278} ; 
0 commit comments