@@ -5,13 +5,16 @@ var _ = {
55var async = require ( "async" ) ;
66var debug = require ( "./debugging" ) ;
77var mongodb = require ( "mongodb" ) ;
8-
8+ var Joi = require ( "joi" ) ;
99
1010var MongoStore = module . exports = function MongoStore ( config ) {
1111 this . _config = config ;
1212} ;
1313
1414
15+ var FILTER_OPERATORS = [ "<" , ">" , "~" , ":" ] ;
16+
17+
1518/**
1619 Handlers readiness status. This should be set to `true` once all handlers are ready to process requests.
1720 */
@@ -48,13 +51,43 @@ MongoStore._getRelationshipAttributeNames = function(attributes) {
4851} ;
4952
5053
54+ MongoStore . _splitFilterElement = function ( filterElementStr ) {
55+ if ( FILTER_OPERATORS . indexOf ( filterElementStr [ 0 ] ) !== - 1 ) {
56+ return { operator : filterElementStr [ 0 ] , value : filterElementStr . substring ( 1 ) } ;
57+ }
58+ return { operator : null , value : filterElementStr } ;
59+ } ;
60+
61+
62+ MongoStore . _filterElementToMongoExpr = function ( attributeConfig , filterElementStr ) {
63+ var filterElement = MongoStore . _splitFilterElement ( filterElementStr ) ;
64+ var value = filterElement . value ;
65+ if ( ! attributeConfig . _settings ) { // not a relationship attribute
66+ var validationResult = attributeConfig . validate ( filterElement . value ) ;
67+ if ( validationResult . error ) return null ;
68+ value = validationResult . value ;
69+ }
70+ if ( ! filterElement . operator ) return value ;
71+ if ( [ "~" , ":" ] . indexOf ( filterElement . operator ) !== - 1 && typeof value !== "string" ) {
72+ return null ;
73+ }
74+ var mongoExpr = {
75+ ">" : { $gt : value } ,
76+ "<" : { $lt : value } ,
77+ "~" : new RegExp ( "^" + value + "$" , "i" ) ,
78+ ":" : new RegExp ( value )
79+ } [ filterElement . operator ] ;
80+ return mongoExpr ;
81+ } ;
82+
83+
5184MongoStore . prototype . _getSearchCriteria = function ( request ) {
5285 var self = this ;
5386 if ( ! request . params . filter ) return { } ;
5487
5588 var criteria = Object . keys ( request . params . filter ) . map ( function ( attribute ) {
5689 var attributeConfig = self . resourceConfig . attributes [ attribute ] ;
57- // If the filter attribute doens 't exist, skip it
90+ // If the filter attribute doesn 't exist, skip it
5891 if ( ! attributeConfig ) return null ;
5992
6093 var values = request . params . filter [ attribute ] ;
@@ -65,28 +98,33 @@ MongoStore.prototype._getSearchCriteria = function(request) {
6598 if ( values instanceof Object ) return null ;
6699 }
67100
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-
101+ values = [ ] . concat ( values ) ; // Coerce values to an array to simplify the logic
102+ var filterElemForAttrToMongoExpr = MongoStore . _filterElementToMongoExpr . bind ( null , attributeConfig ) ;
103+ values = values . map ( filterElemForAttrToMongoExpr ) ;
104+ values = values . reduce ( function ( mongoExpressions , mongoExpr ) {
105+ if ( mongoExpr !== null ) {
106+ var mongoExprForAttr = { } ;
107+ mongoExprForAttr [ attribute ] = mongoExpr ;
108+ mongoExpressions . push ( mongoExprForAttr ) ;
109+ }
110+ return mongoExpressions ;
111+ } , [ ] ) ;
112+ if ( values . length === 0 ) {
113+ return null ;
114+ }
115+ if ( values . length === 1 ) {
116+ return values [ 0 ] ;
117+ }
82118 return { $or : values } ;
83119 } ) . filter ( function ( value ) {
84120 return value !== null ;
85121 } ) ;
86-
87122 if ( criteria . length === 0 ) {
88123 return { } ;
89124 }
125+ if ( criteria . length === 1 ) {
126+ return criteria [ 0 ] ;
127+ }
90128 return { $and : criteria } ;
91129} ;
92130
@@ -192,7 +230,11 @@ MongoStore.prototype.populate = function(callback) {
192230 self . _db . dropDatabase ( function ( err ) {
193231 if ( err ) return console . error ( "error dropping database" , err . message ) ;
194232 async . each ( self . resourceConfig . examples , function ( document , cb ) {
195- self . create ( { params : { } } , document , cb ) ;
233+ var validationResult = Joi . validate ( document , self . resourceConfig . attributes ) ;
234+ if ( validationResult . error ) {
235+ return cb ( validationResult . error ) ;
236+ }
237+ self . create ( { params : { } } , validationResult . value , cb ) ;
196238 } , function ( error ) {
197239 if ( error ) console . error ( "error creating example document:" , error ) ;
198240 return callback ( ) ;
0 commit comments