diff --git a/CHANGELOG.md b/CHANGELOG.md index 010b1024..c70c630e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,33 @@ +X.Y.Z Release notes +============================================================= +### Breaking changes +* None. + +### Enhancements +* None. + +### Bug fixes +* [Sync] Avoid hammering the ROS authentication service when large numbers of Realms are opened at once. + +### Internal +* None. + + +2.2.15 Release notes (2018-3-9) +============================================================= +### Breaking changes +* None. + +### Enhancements +* None. + +### Bug fixes +* Fixed a bug that could result in notifications from the global notifier being delayed or not delivered at all when multiple Realms change at once. + +### Internal +* None. + + 2.2.14 Release notes (2018-3-5) ============================================================= ### Breaking changes diff --git a/dependencies.list b/dependencies.list index 2e946f06..b5b26536 100644 --- a/dependencies.list +++ b/dependencies.list @@ -1,5 +1,5 @@ PACKAGE_NAME=realm-js -VERSION=2.2.14 +VERSION=2.2.15 REALM_CORE_VERSION=5.1.2 REALM_SYNC_VERSION=2.2.15 REALM_OBJECT_SERVER_VERSION=2.5.1 diff --git a/docs/tutorials/query-language.md b/docs/tutorials/query-language.md index a7a093e8..57cb0b9a 100644 --- a/docs/tutorials/query-language.md +++ b/docs/tutorials/query-language.md @@ -23,7 +23,7 @@ let merlots = wines.filtered('variety == $0 && vintage <= $1', 'Merlot', maxYear ``` -### Relational operators +### Conditional operators You can use equality comparison on all property types: `==` and `!=` @@ -35,7 +35,7 @@ Example: let oldContacts = realm.objects('Contact').filtered('age > 2'); ``` -Note that for boolean properties, you should test against the expected keyword. +Note that for boolean properties, you should test against `true` or `false`. Example: ```JS @@ -43,7 +43,7 @@ let women = realm.objects('Contact').filtered('isMale == false'); ``` ### String operators -For string properties, prefix, suffix, and substring queries are supported by using the `BEGINSWITH`, `ENDSWITH`, and `CONTAINS` operators. +For string properties, prefix, suffix, and substring queries are supported by using the `BEGINSWITH`, `ENDSWITH`, `CONTAINS` and `LIKE` operators. For any string operation you can append `[c]` to the operator to make it case insensitive. @@ -53,6 +53,45 @@ let peopleWhoseNameContainsA = realm.objects('Contact').filtered('name CONTAINS[ let Johns = realm.objects('Contact').filtered('name ==[c] "john"'); ``` +You can do simple wildcard matching with `LIKE` which supports using `?` to match a single character and `*` to match zero or multiple characters. + +Example: +```JS +// Matches "John" and "Johnny" +let Johns = realm.objects('Contact').filtered('name LIKE "John*"'); +``` + ### Composition Use parentheses and the `&&`/`AND` and `||`/`OR` operators to compose queries. You can negate a predicate with `!`/`NOT`. +### Queries on collections + +When objects contain lists you can query into them using the collection operators `ANY`, `ALL` and `NONE`. + +Example: +```JS +// Find contacts with one or more teenage friends +let teens = realm.objects('Contact').filtered('ANY friends.age < 14'); + +// Find contacts where all friends are older than 21 +let adults = realm.objects('Contact').filtered('ALL friends.age > 21'); +``` + +You can query on aggregates over properties in the lists using the aggregate operators `.@count`, `.@avg`, `.@min`, `.@max` and `.@sum`. + +Example: +```JS +// Find contacts without friends +let lonely = realm.objects('Contact').filtered('friends.@count == 0'); + +// Find contacts where the average age of their friends is above 40 +let adults = realm.objects('Contact').filtered('friends.@avg.age > 40'); +``` + +Subqueries using the `SUBQUERY` operator allows you to filter the lists across multiple parameters while querying them. + +Example: +```JS +// Find contacts with friends above 21 in SF +let teens = realm.objects('Contact').filtered('SUBQUERY(friends, $friend, $friend.age > 21 AND $friend.city = "SF").@count > 0'); +``` diff --git a/lib/index.js b/lib/index.js index 0458588e..b8350fe1 100644 --- a/lib/index.js +++ b/lib/index.js @@ -122,7 +122,9 @@ require('./extensions')(realmConstructor); if (realmConstructor.Sync) { if (getContext() === 'nodejs') { nodeRequire('./notifier')(realmConstructor); - Object.defineProperty(realmConstructor, 'Worker', {value: nodeRequire('./worker')}); + if (!realmConstructor.Worker) { + Object.defineProperty(realmConstructor, 'Worker', {value: nodeRequire('./worker')}); + } } } diff --git a/lib/user-methods.js b/lib/user-methods.js index 9634ef37..2367837d 100644 --- a/lib/user-methods.js +++ b/lib/user-methods.js @@ -36,8 +36,43 @@ function checkTypes(args, types) { } } -/* global fetch */ -const performFetch = typeof fetch === 'undefined' ? node_require('node-fetch') : fetch; +// Perform a HTTP request, enqueuing it if too many requests are already in +// progress to avoid hammering the server. +const performFetch = (function() { + const doFetch = typeof fetch === 'undefined' ? node_require('node-fetch') : fetch; + const queue = []; + let count = 0; + const maxCount = 5; + const next = () => { + if (count >= maxCount) { + return; + } + const req = queue.shift(); + if (!req) { + return; + } + const [url, options, resolve, reject] = req; + ++count; + // node doesn't support Promise.prototype.finally until 10 + doFetch(url, options) + .then(response => { + --count; + next(); + resolve(response); + }) + .catch(error => { + --count; + next(); + reject(error); + }); + }; + return (url, options) => { + return new Promise((resolve, reject) => { + queue.push([url, options, resolve, reject]); + next(); + }); + }; +})(); const url_parse = require('url-parse'); diff --git a/package.json b/package.json index 22312c5f..41687bcf 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "realm", "description": "Realm is a mobile database: an alternative to SQLite and key-value stores", - "version": "2.2.14", + "version": "2.2.15", "license": "Apache-2.0", "homepage": "https://realm.io", "keywords": [ diff --git a/src/RealmJS.xcodeproj/project.pbxproj b/src/RealmJS.xcodeproj/project.pbxproj index 32b451ac..1f91bf63 100644 --- a/src/RealmJS.xcodeproj/project.pbxproj +++ b/src/RealmJS.xcodeproj/project.pbxproj @@ -961,7 +961,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 2.2.14; + CURRENT_PROJECT_VERSION = 2.2.15; CXX = "$(SRCROOT)/../scripts/ccache-clang++.sh"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -1025,7 +1025,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 2.2.14; + CURRENT_PROJECT_VERSION = 2.2.15; CXX = "$(SRCROOT)/../scripts/ccache-clang++.sh"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO;