diff --git a/spec/QueryTools.spec.js b/spec/QueryTools.spec.js index 16b9e78433..def66355d6 100644 --- a/spec/QueryTools.spec.js +++ b/spec/QueryTools.spec.js @@ -88,6 +88,22 @@ describe('queryHash', function() { }); describe('matchesQuery', function() { + it('matches subquery', function() { + var obj = { + id: new Id('Item', '01'), + value: 42, + component: { + name: 'World', + type: 'question' + } + }; + var q = new Parse.Query('Item'); + q.equalTo('component.name', 'World'); + expect(matchesQuery(obj, q)).toBe(true); + obj['component.name'] = 'Other world'; + expect(matchesQuery(obj, q)).toBe(false); + }); + it('matches blanket queries', function() { var obj = { id: new Id('Klass', 'O1'), diff --git a/src/LiveQuery/QueryTools.js b/src/LiveQuery/QueryTools.js index 6a772ca107..d53c031b19 100644 --- a/src/LiveQuery/QueryTools.js +++ b/src/LiveQuery/QueryTools.js @@ -105,13 +105,45 @@ function matchesQuery(object: any, query: any): boolean { return matchesQuery(object, query._where); } for (var field in query) { - if (!matchesKeyConstraints(object, field, query[field])) { + if (~field.indexOf('.')) { + return matchesSubquery(object, field, query[field]) + } else if (!matchesKeyConstraints(object, field, query[field])) { return false; } } return true; } +/** + * Matches subquery + * Determines, if field is divided by dots, and expect field to be dotted path to object sub-key. + * + * @param object To search for key + * @param key Sub query, divided by dot(s) + * @param constraints Rules or value to apply + * @returns sub-object to search for key, or unmodified object, passed as param. + */ +function matchesSubquery(object, key, constraints){ + var transformed = object; + var subKey = key; + var keyParts = key.split(".").filter(function(a){return !!a;}); + + if (keyParts.length >= 2 && !(key in object)) { + while (keyParts.length > 1) { + subKey = keyParts.shift(); + if(transformed[subKey]){ + transformed = transformed[subKey]; + } else { + return matchesKeyConstraints(object, key, constraints); + } + } + subKey = keyParts.shift(); + return matchesKeyConstraints(transformed, subKey, constraints); + } else { + return matchesKeyConstraints(object, key, constraints); + } +} + function equalObjectsGeneric(obj, compareTo, eqlFn) { if (Array.isArray(obj)) { for (var i = 0; i < obj.length; i++) {