From 90cacdd6c7ccc28e1ecc726dc6dcacbd06542eec Mon Sep 17 00:00:00 2001 From: Kenneth Geisshirt Date: Wed, 14 Mar 2018 15:09:45 +0100 Subject: [PATCH 01/10] Fixing TS definition for open_ssl_verify_callback. --- CHANGELOG.md | 2 +- lib/index.d.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b4d9152b..1c4a93ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ X.Y.Z Release notes * Added an optional user as argument to `Realm.automaticSyncConfiguration` (#1708). ### Bug fixes -* None. +* Fixed from TypeScript defintion for `open_ssl_verify_callback` configuration option (#1652). ### Internal * None. diff --git a/lib/index.d.ts b/lib/index.d.ts index 22008460..d289f08b 100644 --- a/lib/index.d.ts +++ b/lib/index.d.ts @@ -369,7 +369,7 @@ declare namespace Realm.Sync { } type ErrorCallback = (session: Session, error: SyncError) => void; - type SSLVerifyCallback = (serverAddress: string, serverPort: number, pemCertificate: string, preverifyOk: number, depth: number) => boolean; + type SSLVerifyCallback = (serverAddress: string, serverPort: number, pemCertificate: string, acceptedByOpenSSL: boolean, depth: number) => boolean; interface SyncConfiguration { user: User; From 591aa9fee7b95af163ab4853d823d4553d9a8827 Mon Sep 17 00:00:00 2001 From: James Stone Date: Tue, 10 Apr 2018 16:37:41 -0700 Subject: [PATCH 02/10] Initial work for unnamed backlink queries and @links.@count tests --- docs/tutorials/query-language.md | 18 +++++++++++ src/js_results.hpp | 4 +-- tests/js/linkingobjects-tests.js | 51 ++++++++++++++++++++++++-------- 3 files changed, 58 insertions(+), 15 deletions(-) diff --git a/docs/tutorials/query-language.md b/docs/tutorials/query-language.md index 57cb0b9a..6def6a3a 100644 --- a/docs/tutorials/query-language.md +++ b/docs/tutorials/query-language.md @@ -95,3 +95,21 @@ Example: // 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'); ``` + +### Backlink queries + +Other objects can link to an object and you can query on that releationship using the `@links` and `@links.ClassName.PropertyName` syntax. +If the relationship of the LinkingObject is named, use the name in the query just like you would use any other property for readability. +If the relationship is not named, you can use the `@links.ClassName.PropertyName` syntax where `ClassName.PropertyName` describes the forward relationship. + +Example: +```JS +// Find contacts where someone from SF has them as friends +realm.objects('Contact').filtered('@links.Contact.friends.city == "SF"'); + +// Find contacts with no incomming links (across all linked properties) +let isolated = realm.objects('Contact').filtered('@links.@count == 0'); + +// Find contacts with no incoming friend links +let lonely = realm.objects('Contact').filtered('@links.Contact.friends.@count == 0'); +``` diff --git a/src/js_results.hpp b/src/js_results.hpp index e9f73294..5e11c94a 100644 --- a/src/js_results.hpp +++ b/src/js_results.hpp @@ -160,8 +160,7 @@ inline void alias_backlinks(parser::KeyPathMapping &mapping, const realm::Shared if (property.type == realm::PropertyType::LinkingObjects) { auto target_object_schema = schema.find(property.object_type); const TableRef table = ObjectStore::table_for_object_type(realm->read_group(), it->name); - const TableRef target_table = ObjectStore::table_for_object_type(realm->read_group(), target_object_schema->name); - std::string native_name = "@links." + std::string(target_table->get_name()) + "." + property.link_origin_property_name; + std::string native_name = "@links." + target_object_schema->name + "." + property.link_origin_property_name; mapping.add_mapping(table, property.name, native_name); } } @@ -181,6 +180,7 @@ typename T::Object ResultsClass::create_filtered(ContextType ctx, const U &co auto const &object_schema = collection.get_object_schema(); DescriptorOrdering ordering; parser::KeyPathMapping mapping; + mapping.set_backlink_class_prefix(ObjectStore::table_name_for_object_type("")); alias_backlinks(mapping, realm); parser::ParserResult result = parser::parse(query_string); diff --git a/tests/js/linkingobjects-tests.js b/tests/js/linkingobjects-tests.js index 520513a4..a7e6fb6d 100644 --- a/tests/js/linkingobjects-tests.js +++ b/tests/js/linkingobjects-tests.js @@ -109,24 +109,49 @@ module.exports = { let english = realm.create('Language', {name: 'English'}); let french = realm.create('Language', {name: 'French'}); let danish = realm.create('Language', {name: 'Danish'}); + let latin = realm.create('Language', {name: 'Latin'}); let canada = realm.create('Country', {name: 'Canada', languages: [english, french]}); let denmark = realm.create('Country', {name: 'Denmark', languages: [danish, english]}); let france = realm.create('Country', {name: 'France', languages: [french, english]}); }); let languages = realm.objects('Language'); - let spokenInThreeCountries = languages.filtered('spokenIn.@count == 3'); - TestCase.assertEqual(spokenInThreeCountries.length, 1); - TestCase.assertEqual(spokenInThreeCountries[0].name, 'English'); - let spokenInTwoCountries = languages.filtered('spokenIn.@count == 2'); - TestCase.assertEqual(spokenInTwoCountries.length, 1); - TestCase.assertEqual(spokenInTwoCountries[0].name, 'French') - let spokenInOneCountry = languages.filtered('spokenIn.@count == 1'); - TestCase.assertEqual(spokenInOneCountry.length, 1); - TestCase.assertEqual(spokenInOneCountry[0].name, 'Danish') - let languagesSpokenInCanada = languages.filtered('spokenIn.name ==[c] "canada"'); - TestCase.assertEqual(languagesSpokenInCanada.length, 2); - TestCase.assertEqual(languagesSpokenInCanada[0].name, 'English'); - TestCase.assertEqual(languagesSpokenInCanada[1].name, 'French'); + { + let spokenInThreeCountries = languages.filtered('spokenIn.@count == 3'); + TestCase.assertEqual(spokenInThreeCountries.length, 1); + TestCase.assertEqual(spokenInThreeCountries[0].name, 'English'); + let spokenInTwoCountries = languages.filtered('spokenIn.@count == 2'); + TestCase.assertEqual(spokenInTwoCountries.length, 1); + TestCase.assertEqual(spokenInTwoCountries[0].name, 'French') + let spokenInOneCountry = languages.filtered('spokenIn.@count == 1'); + TestCase.assertEqual(spokenInOneCountry.length, 1); + TestCase.assertEqual(spokenInOneCountry[0].name, 'Danish') + let languagesSpokenInCanada = languages.filtered('spokenIn.name ==[c] "canada"'); + TestCase.assertEqual(languagesSpokenInCanada.length, 2); + TestCase.assertEqual(languagesSpokenInCanada[0].name, 'English'); + TestCase.assertEqual(languagesSpokenInCanada[1].name, 'French'); + } + // check the same but using the unnamed relationship which is available to users + { + let spokenInThreeCountries = languages.filtered('@links.Country.languages.@count == 3'); + TestCase.assertEqual(spokenInThreeCountries.length, 1); + TestCase.assertEqual(spokenInThreeCountries[0].name, 'English'); + let spokenInTwoCountries = languages.filtered('@links.Country.languages.@count == 2'); + TestCase.assertEqual(spokenInTwoCountries.length, 1); + TestCase.assertEqual(spokenInTwoCountries[0].name, 'French') + let spokenInOneCountry = languages.filtered('@links.Country.languages.@count == 1'); + TestCase.assertEqual(spokenInOneCountry.length, 1); + TestCase.assertEqual(spokenInOneCountry[0].name, 'Danish') + let languagesSpokenInCanada = languages.filtered('@links.Country.languages.name ==[c] "canada"'); + TestCase.assertEqual(languagesSpokenInCanada.length, 2); + TestCase.assertEqual(languagesSpokenInCanada[0].name, 'English'); + TestCase.assertEqual(languagesSpokenInCanada[1].name, 'French'); + } + let notSpokenInAnyCountry = languages.filtered('@links.@count == 0'); // no incoming links over any relationships to the object + TestCase.assertEqual(notSpokenInAnyCountry.length, 1); + TestCase.assertEqual(notSpokenInAnyCountry[0].name, 'Latin'); + let notSpokenMethod2 = languages.filtered('@links.Country.languages.@count == 0'); // links of a specific relationship are 0 + TestCase.assertEqual(notSpokenMethod2.length, 1); + TestCase.assertEqual(notSpokenMethod2[0].name, 'Latin'); }, testMethod: function() { From 5cfc3c12eece7d4c4eab2a8a4ffbf7145b3cf54f Mon Sep 17 00:00:00 2001 From: Kenneth Geisshirt Date: Wed, 18 Apr 2018 14:07:19 +0200 Subject: [PATCH 03/10] Use a single object instead of multiple arguments. --- lib/index.d.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/index.d.ts b/lib/index.d.ts index f0d5b0f9..95ffc299 100644 --- a/lib/index.d.ts +++ b/lib/index.d.ts @@ -368,8 +368,16 @@ declare namespace Realm.Sync { code: number; } + interface SSLVerifyObject { + serverAddress: string; + serverPort: number; + pemCertificate: string; + acceptedByOpenSSL: boolean; + depth: number; + } + type ErrorCallback = (session: Session, error: SyncError) => void; - type SSLVerifyCallback = (serverAddress: string, serverPort: number, pemCertificate: string, acceptedByOpenSSL: boolean, depth: number) => boolean; + type SSLVerifyCallback = (sslVerifyObject: SSLVerifyObject) => boolean; interface SyncConfiguration { user: User; From 29ad083f253b0ca297006e71618c2325f766baa1 Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Fri, 4 May 2018 14:11:20 -0700 Subject: [PATCH 04/10] Track Realms seen in the notifier by id rather than path If a Realm is deleted and then a new one is created at the same path it needs to be treated as a new Realm. --- lib/notifier.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/notifier.js b/lib/notifier.js index 0add6bf6..0e8c6cf4 100644 --- a/lib/notifier.js +++ b/lib/notifier.js @@ -45,11 +45,11 @@ class FunctionListener { return this.regexStr === regex && this.event === event && this.fn === fn; } - onavailable(path) { + onavailable(path, id) { if (this.regex.test(path)) { - if (this.event === 'available' && !this.seen[path]) { + if (this.event === 'available' && !this.seen[id]) { this.fn(path); - this.seen[path] = true; + this.seen[id] = true; } return this.event === 'change'; } @@ -103,11 +103,11 @@ class OutOfProcListener { return this.regexStr === regex && this.worker === worker; } - onavailable(path) { + onavailable(path, id) { if (this.regex.test(path)) { - if (!this.seen[path]) { + if (!this.seen[id]) { this.worker.onavailable(path); - this.seen[path] = true; + this.seen[id] = true; } return true; } @@ -161,10 +161,11 @@ class Listener { changes.release(); } - available(virtualPath) { + available(virtualPath, id) { let watch = false; + id = id || virtualPath; for (const callback of this.callbacks) { - if (callback.onavailable(virtualPath)) { + if (callback.onavailable(virtualPath, id)) { watch = true; } } From 01a6a53a626f226f5df30755af2f059c5b168860 Mon Sep 17 00:00:00 2001 From: Kenneth Geisshirt Date: Mon, 7 May 2018 11:26:29 +0200 Subject: [PATCH 05/10] Typo --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f8a41c00..b83f1477 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,7 @@ X.Y.Z Release notes * None. ### Bug fixes -* Fixed from TypeScript defintion for `open_ssl_verify_callback` configuration option (#1652). +* Fixed TypeScript defintion for `open_ssl_verify_callback` configuration option (#1652). ### Internal * Updated to Relm Sync 3.3.0. From 35e8f03c99ba35080084939aa8229820a920dc12 Mon Sep 17 00:00:00 2001 From: Brian Munkholm Date: Mon, 7 May 2018 12:01:43 +0200 Subject: [PATCH 06/10] Small readme updates --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index af98d038..e6f93df5 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ The API reference is located at [realm.io/docs/javscript/latest/api/](https://re In case you don't want to use the precompiled version on npm, you can build Realm yourself from source. You’ll need an Internet connection the first time you build in order to download the core library. Prerequisites: -- Node: 4.0 <= version < 7.0 +- Node: 4.0 <= version < 7.0 and python2.7 (3.x won't work) - Xcode 7.2+ - Android SDK 23+ - Android NDK 10e @@ -52,17 +52,17 @@ git submodule update --init --recursive ```Note: If you have cloned the repo previously make sure you remove your node_modules directory since it may contain stale dependencies which may cause the build to fail.``` -To build for iOS: +### Building for iOS: - Open `react-native/ios/RealmReact.xcodeproj` - Select `RealmReact.framework` as the build target - Build -To build for Android: +### Building for Android: - `cd react-native/android` - `./gradlew publishAndroid` - The compiled version of the Android module is here: `/android` -To build for nodejs: +### Building for nodejs: ``` npm install --build-from-source=realm @@ -70,7 +70,7 @@ npm install --build-from-source=realm - On Windows you will need to setup the environment for node-gyp - - Option 1: Install windows-build-tools node package + * Option 1: Install windows-build-tools node package - Open an elevated command prompt (As Administrator) From 0b8dffc4b1a677fbc8e2b7e7a187d1a870939a46 Mon Sep 17 00:00:00 2001 From: Brian Munkholm Date: Mon, 7 May 2018 14:01:16 +0200 Subject: [PATCH 07/10] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e6f93df5..91b6a56d 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ The API reference is located at [realm.io/docs/javscript/latest/api/](https://re In case you don't want to use the precompiled version on npm, you can build Realm yourself from source. You’ll need an Internet connection the first time you build in order to download the core library. Prerequisites: -- Node: 4.0 <= version < 7.0 and python2.7 (3.x won't work) +- Node: 4.0 <= version < 7.0 - Xcode 7.2+ - Android SDK 23+ - Android NDK 10e @@ -63,6 +63,7 @@ git submodule update --init --recursive - The compiled version of the Android module is here: `/android` ### Building for nodejs: +Be sure you have python2.7 as the default python. 3.x won't work, and it's not enough to use `--python=python2.7` as parameter to npm. ``` npm install --build-from-source=realm From 2bd30dcaf6a4ef316bad6747c43e7fac95ad23ed Mon Sep 17 00:00:00 2001 From: Brian Munkholm Date: Mon, 7 May 2018 14:37:16 +0200 Subject: [PATCH 08/10] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 91b6a56d..1df91193 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ Prerequisites: - Node: 4.0 <= version < 7.0 - Xcode 7.2+ - Android SDK 23+ -- Android NDK 10e +- [Android NDK 10e](https://developer.android.com/ndk/downloads/older_releases) First clone this repository: From 649b7545f97534e8a162d9a23b2ae50ee05a0ffc Mon Sep 17 00:00:00 2001 From: Kenneth Geisshirt Date: Mon, 7 May 2018 14:50:07 +0200 Subject: [PATCH 09/10] [2.4.1] Bump version --- CHANGELOG.md | 4 ++-- dependencies.list | 2 +- package.json | 2 +- src/RealmJS.xcodeproj/project.pbxproj | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b83f1477..0e445804 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -X.Y.Z Release notes +2.4.1 Release notes (2018-5-7) ============================================================= ### Compatibility * Sync protocol: 24 @@ -10,7 +10,7 @@ X.Y.Z Release notes * None. ### Enhancements -* None. +* Added minimal support for Realm deletions to the Global Notifier (realm-js-private #443). ### Bug fixes * Fixed TypeScript defintion for `open_ssl_verify_callback` configuration option (#1652). diff --git a/dependencies.list b/dependencies.list index a0c22ddf..fa5fb491 100644 --- a/dependencies.list +++ b/dependencies.list @@ -1,5 +1,5 @@ PACKAGE_NAME=realm-js -VERSION=2.4.0 +VERSION=2.4.1 REALM_CORE_VERSION=5.6.0 REALM_SYNC_VERSION=3.3.0 REALM_OBJECT_SERVER_VERSION=3.0.0 diff --git a/package.json b/package.json index fa0b1379..1f54d708 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.4.0", + "version": "2.4.1", "license": "Apache-2.0", "homepage": "https://realm.io", "keywords": [ diff --git a/src/RealmJS.xcodeproj/project.pbxproj b/src/RealmJS.xcodeproj/project.pbxproj index 7ca13e1e..4995fb1d 100644 --- a/src/RealmJS.xcodeproj/project.pbxproj +++ b/src/RealmJS.xcodeproj/project.pbxproj @@ -969,7 +969,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 2.4.0; + CURRENT_PROJECT_VERSION = 2.4.1; CXX = "$(SRCROOT)/../scripts/ccache-clang++.sh"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -1033,7 +1033,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 2.4.0; + CURRENT_PROJECT_VERSION = 2.4.1; CXX = "$(SRCROOT)/../scripts/ccache-clang++.sh"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; From 30c6779b9fa58c0c7fc3e2bf0458debbbd245a82 Mon Sep 17 00:00:00 2001 From: Kenneth Geisshirt Date: Tue, 8 May 2018 10:05:26 +0200 Subject: [PATCH 10/10] Download Linux tar.gz too --- scripts/download-realm.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/download-realm.js b/scripts/download-realm.js index b097a70e..adbfb80d 100644 --- a/scripts/download-realm.js +++ b/scripts/download-realm.js @@ -191,6 +191,10 @@ function getSyncRequirements(dependencies, options, required = {}) { return required; }); } + case 'linux': + required.SYNC_ARCHIVE = `realm-sync-Release-v${dependencies.REALM_SYNC_VERSION}-Linux-devel.tar.gz`; + required.SYNC_ARCHIVE_ROOT = `realm-sync-Release-v${dependencies.REALM_SYNC_VERSION}`; + return Promise.resolve(required); default: return Promise.reject(new Error(`Unsupported sync platform '${options.platform}'`)); }