common = require './common' test = (obj, query) -> for k,v of query if k.charAt(0) == '$' # this is a logical operator res = testExpressions(obj, v, k) else value = common.getParamValueFromPath(obj, k) if common.typeOf(v) isnt common.OBJECT_TYPE if common.typeOf(value) is common.ARRAY_TYPE res = value.indexOf(v) != -1 else res = v == value else for k2,v2 of v switch k2 when '$ne' if common.typeOf(value) is common.ARRAY_TYPE res = value.indexOf(v2) == -1 else res = value != v2 when '$lt' res = value < v2 when '$lte' res = value <= v2 when '$gt' res = value > v2 when '$gte' res = value >= v2 when '$regex' res = v2.test(value) when '$in' throw new Error('Operator not supported') when '$nin' throw new Error('Operator not supported') when '$all' throw new Error('Operator not supported') when '$exists' throw new Error('Operator not supported') else throw new Error('Operator not supported') if not res return false return true testExpressions = (obj, expressions, lop) -> for f in expressions res = test(obj, f) switch lop when '$and' return false if not res when '$or' return true if res when '$nor' return false if res return switch lop when '$and' then true when '$or' then false when '$nor' then true else throw new Error('Unknown logical operator') projection = (query, proj) -> for k,v of query if k.charAt(0) == '$' # this is a logical operator for q in v projection(q, proj) else proj[k] = 1 exports.test = test exports.projection = projection