11var is = require ( "../types/comparisons" ) ;
22var Serializer = require ( "../serializer" ) ;
33var canReflect = require ( "can-reflect" ) ;
4+ var ValuesNot = require ( "../types/values-not" ) ;
5+ var ValuesAnd = require ( "../types/values-and" ) ;
46
57function makeNew ( Constructor ) {
68 return function ( value ) {
@@ -47,10 +49,37 @@ addHydrateFrom("$gte", makeNew(is.GreaterThanEqual));
4749addHydrateFromValues ( "$in" , makeNew ( is . In ) ) ;
4850addHydrateFrom ( "$lt" , makeNew ( is . LessThan ) ) ;
4951addHydrateFrom ( "$lte" , makeNew ( is . LessThanEqual ) ) ;
50- addHydrateFromValues ( "$nin" , makeNew ( is . GreaterThan ) ) ;
5152
53+ addHydrateFromValues ( "$all" , makeNew ( is . All ) ) ;
5254
55+ // This is a mapping of types to their opposite. The $not hydrator
56+ // uses this to create a more specific type, since they are logical opposites.
57+ var oppositeTypeMap = {
58+ LessThan : { Type : is . GreaterThanEqual , prop : "value" } ,
59+ LessThanEqual : { Type : is . GreaterThan , prop : "value" } ,
60+ GreaterThan : { Type : is . LessThanEqual , prop : "value" } ,
61+ GreaterThanEqual : { Type : is . LessThan , prop : "value" } ,
62+ In : { Type : is . NotIn , prop : "values" } ,
63+ NotIn : { Type : is . In , prop : "values" }
64+ } ;
65+
66+ hydrateMap [ "$not" ] = function ( value , unknownHydrator ) {
67+ // Many nots can be hydrated to their opposite.
68+ var hydratedValue = hydrateValue ( value [ "$not" ] , unknownHydrator ) ;
69+ var typeName = hydratedValue . constructor . name ;
5370
71+ if ( oppositeTypeMap [ typeName ] ) {
72+ var options = oppositeTypeMap [ typeName ] ;
73+ var OppositeConstructor = options . Type ;
74+ var prop = options . prop ;
75+
76+ return new OppositeConstructor ( hydratedValue [ prop ] ) ;
77+ }
78+
79+ return new ValuesNot ( hydratedValue ) ;
80+ } ;
81+
82+ addHydrateFromValues ( "$nin" , makeNew ( is . NotIn ) ) ;
5483
5584
5685var serializer = new Serializer ( [
@@ -73,7 +102,8 @@ var serializer = new Serializer([
73102 canReflect . assignMap ( obj , serialize ( clause ) ) ;
74103 } ) ;
75104 return obj ;
76- } ]
105+ } ] ,
106+ [ is . All , function ( all , serialize ) { return { $all : serialize ( all . values ) } } ]
77107 /*[is.Or, function(or, serialize){
78108 return {
79109 $or: or.values.map(function(value){
@@ -83,41 +113,44 @@ var serializer = new Serializer([
83113 }]*/
84114] ) ;
85115
86- module . exports = {
87- hydrate : function ( value , hydrateUnknown ) {
88- if ( ! hydrateUnknown ) {
89- hydrateUnknown = function ( ) {
90- throw new Error ( "can-query-logic doesn't recognize operator: " + JSON . stringify ( value ) ) ;
91- }
116+ function hydrateValue ( value , hydrateUnknown ) {
117+ if ( ! hydrateUnknown ) {
118+ hydrateUnknown = function ( ) {
119+ throw new Error ( "can-query-logic doesn't recognize operator: " + JSON . stringify ( value ) ) ;
92120 }
93- if ( Array . isArray ( value ) ) {
94- return new is . In ( value . map ( function ( value ) {
95- return hydrateUnknown ( value ) ;
96- } ) ) ;
97- }
98- else if ( value && typeof value === "object" ) {
99- var keys = Object . keys ( value ) ;
100- var allKeysAreComparisons = keys . every ( function ( key ) {
101- return hydrateMap [ key ]
121+ }
122+ if ( Array . isArray ( value ) ) {
123+ return new is . In ( value . map ( function ( value ) {
124+ return hydrateUnknown ( value ) ;
125+ } ) ) ;
126+ }
127+ else if ( value && typeof value === "object" ) {
128+ var keys = Object . keys ( value ) ;
129+ var allKeysAreComparisons = keys . every ( function ( key ) {
130+ return hydrateMap [ key ]
131+ } ) ;
132+ if ( allKeysAreComparisons ) {
133+ var andClauses = keys . map ( function ( key ) {
134+ var part = { } ;
135+ part [ key ] = value [ key ] ;
136+ var hydrator = hydrateMap [ key ] ;
137+ return hydrator ( part , hydrateUnknown ) ;
102138 } ) ;
103- if ( allKeysAreComparisons ) {
104- var andClauses = keys . map ( function ( key ) {
105- var part = { } ;
106- part [ key ] = value [ key ] ;
107- var hydrator = hydrateMap [ key ] ;
108- return hydrator ( part , hydrateUnknown ) ;
109- } ) ;
110- if ( andClauses . length > 1 ) {
111- return new is . And ( andClauses ) ;
112- } else {
113- return andClauses [ 0 ] ;
114- }
139+ if ( andClauses . length > 1 ) {
140+ return new is . And ( andClauses ) ;
115141 } else {
116- return hydrateUnknown ( value ) ;
142+ return andClauses [ 0 ] ;
117143 }
118144 } else {
119- return new is . In ( [ hydrateUnknown ( value ) ] ) ;
145+ return hydrateUnknown ( value ) ;
120146 }
121- } ,
147+ } else {
148+ return new is . In ( [ hydrateUnknown ( value ) ] ) ;
149+ }
150+ }
151+
152+ module . exports = {
153+ // value - something from a query, for example {$in: [1,2]}
154+ hydrate : hydrateValue ,
122155 serializer : serializer
123156} ;
0 commit comments