@@ -5,13 +5,17 @@ var async = require("async");
55var crypto = require ( "crypto" ) ;
66var debug = require ( "debug" ) ( "jsonApi:store:relationaldb" ) ;
77var Joi = require ( "joi" ) ;
8+ var semver = require ( "semver" ) ;
89var _ = {
910 pick : require ( "lodash.pick" ) ,
1011 assign : require ( "lodash.assign" ) ,
1112 omit : require ( "lodash.omit" )
1213} ;
1314
15+ var MIN_SERVER_VERSION = "1.10.0" ;
16+
1417var SqlStore = module . exports = function SqlStore ( config ) {
18+ SqlStore . _checkMinServerVersion ( ) ;
1519 this . config = config ;
1620} ;
1721
@@ -22,6 +26,14 @@ SqlStore._sequelizeInstances = Object.create(null);
2226 */
2327SqlStore . prototype . ready = false ;
2428
29+ SqlStore . _checkMinServerVersion = function ( ) {
30+ var serverVersion = require ( 'jsonapi-server' ) . _version ;
31+ if ( ! serverVersion ) return ;
32+ if ( semver . lt ( serverVersion , MIN_SERVER_VERSION ) ) {
33+ throw new Error ( "This version of jsonapi-store-mongodb requires jsonapi-server>=" + MIN_SERVER_VERSION + "." ) ;
34+ }
35+ } ;
36+
2537/**
2638 initialise gets invoked once for each resource that uses this hander.
2739 In this instance, we're instantiating a Sequelize instance and building models.
@@ -137,6 +149,7 @@ SqlStore.prototype._joiSchemaToSequelizeModel = function(joiSchema) {
137149 if ( attribute . _type === "string" ) model [ attributeName ] = { type : Sequelize . STRING , allowNull : true } ;
138150 if ( attribute . _type === "date" ) model [ attributeName ] = { type : Sequelize . STRING , allowNull : true } ;
139151 if ( attribute . _type === "number" ) model [ attributeName ] = { type : Sequelize . INTEGER , allowNull : true } ;
152+ if ( attribute . _type === "boolean" ) model [ attributeName ] = { type : Sequelize . BOOLEAN , allowNull : true } ;
140153 } ) ;
141154
142155 return model ;
@@ -251,35 +264,42 @@ SqlStore.prototype._filterInclude = function(relationships) {
251264SqlStore . prototype . _generateSearchBlock = function ( request ) {
252265 var self = this ;
253266
254- var attributesToFilter = _ . omit ( request . params . filter , Object . keys ( self . relations ) ) ;
255- var searchBlock = self . _recurseOverSearchBlock ( attributesToFilter ) ;
267+ var attributesToFilter = _ . omit ( request . params . processedFilter , Object . keys ( self . relations ) ) ;
268+ var searchBlock = SqlStore . _getSearchBlock ( attributesToFilter ) ;
256269 return searchBlock ;
257270} ;
258271
259- SqlStore . prototype . _recurseOverSearchBlock = function ( obj ) {
260- var self = this ;
261- if ( ! obj ) return { } ;
272+ SqlStore . _scalarFilterElementToWhereObj = function ( element ) {
273+ var value = element . value ;
274+ if ( ! element . operator ) return value ;
275+ var whereObj = {
276+ ">" : { $gt : value } ,
277+ "<" : { $lt : value } ,
278+ "~" : { $like : value } ,
279+ ":" : { $like : "%" + value + "%" }
280+ } [ element . operator ] ;
281+ return whereObj ;
282+ } ;
283+
284+ SqlStore . _filterElementToSearchBlock = function ( filterElement ) {
285+ if ( ! filterElement ) return { } ;
286+ var whereObjs = filterElement . map ( function ( scalarFilterElement ) {
287+ return SqlStore . _scalarFilterElementToWhereObj ( scalarFilterElement ) ;
288+ } ) ;
289+ if ( ! whereObjs . length ) return { } ;
290+ if ( filterElement . length === 1 ) {
291+ return whereObjs [ 0 ] ;
292+ }
293+ return { $or : whereObjs } ;
294+ } ;
295+
296+ SqlStore . _getSearchBlock = function ( filter ) {
297+ if ( ! filter ) return { } ;
262298 var searchBlock = { } ;
263299
264- Object . keys ( obj ) . forEach ( function ( attributeName ) {
265- var textToMatch = obj [ attributeName ] ;
266- if ( textToMatch instanceof Array ) {
267- searchBlock [ attributeName ] = { $or : textToMatch . map ( function ( i ) {
268- return self . _recurseOverSearchBlock ( { i : i } ) . i ;
269- } ) } ;
270- } else if ( textToMatch instanceof Object ) {
271- // Do nothing, its a nested filter
272- } else if ( textToMatch [ 0 ] === ">" ) {
273- searchBlock [ attributeName ] = { $gt : textToMatch . substring ( 1 ) } ;
274- } else if ( textToMatch [ 0 ] === "<" ) {
275- searchBlock [ attributeName ] = { $lt : textToMatch . substring ( 1 ) } ;
276- } else if ( textToMatch [ 0 ] === "~" ) {
277- searchBlock [ attributeName ] = { $like : textToMatch . substring ( 1 ) } ;
278- } else if ( textToMatch [ 0 ] === ":" ) {
279- searchBlock [ attributeName ] = { $like : "%" + textToMatch . substring ( 1 ) + "%" } ;
280- } else {
281- searchBlock [ attributeName ] = textToMatch ;
282- }
300+ Object . keys ( filter ) . forEach ( function ( attributeName ) {
301+ var filterElement = filter [ attributeName ] ;
302+ searchBlock [ attributeName ] = SqlStore . _filterElementToSearchBlock ( filterElement ) ;
283303 } ) ;
284304
285305 return searchBlock ;
0 commit comments