Merge branch 'master' into cm/bug/java9
# Conflicts: # CHANGELOG.md
This commit is contained in:
commit
f418ae95d5
14
CHANGELOG.md
14
CHANGELOG.md
|
@ -1,4 +1,11 @@
|
||||||
X.Y.Z Release notes
|
2.4.2 Release notes (YYYY-MM-DD)
|
||||||
|
=============================================================
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
* Building React Native Android projects using Java version 9 used deprecated API's (#1779).
|
||||||
|
|
||||||
|
|
||||||
|
2.4.1 Release notes (2018-5-7)
|
||||||
=============================================================
|
=============================================================
|
||||||
### Compatibility
|
### Compatibility
|
||||||
* Sync protocol: 24
|
* Sync protocol: 24
|
||||||
|
@ -10,11 +17,10 @@ X.Y.Z Release notes
|
||||||
* None.
|
* None.
|
||||||
|
|
||||||
### Enhancements
|
### Enhancements
|
||||||
* None.
|
* Added minimal support for Realm deletions to the Global Notifier (realm-js-private #443).
|
||||||
|
|
||||||
### Bug fixes
|
### Bug fixes
|
||||||
|
* Fixed TypeScript defintion for `open_ssl_verify_callback` configuration option (#1652).
|
||||||
* Building React Native Android projects using Java version 9 used deprecated API's (#1779).
|
|
||||||
|
|
||||||
### Internal
|
### Internal
|
||||||
* Updated to Relm Sync 3.3.0.
|
* Updated to Relm Sync 3.3.0.
|
||||||
|
|
11
README.md
11
README.md
|
@ -36,7 +36,7 @@ Prerequisites:
|
||||||
- Node: 4.0 <= version < 7.0
|
- Node: 4.0 <= version < 7.0
|
||||||
- Xcode 7.2+
|
- Xcode 7.2+
|
||||||
- Android SDK 23+
|
- Android SDK 23+
|
||||||
- Android NDK 10e
|
- [Android NDK 10e](https://developer.android.com/ndk/downloads/older_releases)
|
||||||
|
|
||||||
First clone this repository:
|
First clone this repository:
|
||||||
|
|
||||||
|
@ -52,17 +52,18 @@ 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.```
|
```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`
|
- Open `react-native/ios/RealmReact.xcodeproj`
|
||||||
- Select `RealmReact.framework` as the build target
|
- Select `RealmReact.framework` as the build target
|
||||||
- Build
|
- Build
|
||||||
|
|
||||||
To build for Android:
|
### Building for Android:
|
||||||
- `cd react-native/android`
|
- `cd react-native/android`
|
||||||
- `./gradlew publishAndroid`
|
- `./gradlew publishAndroid`
|
||||||
- The compiled version of the Android module is here: `<project-root>/android`
|
- The compiled version of the Android module is here: `<project-root>/android`
|
||||||
|
|
||||||
To build for nodejs:
|
### 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
|
npm install --build-from-source=realm
|
||||||
|
@ -70,7 +71,7 @@ npm install --build-from-source=realm
|
||||||
|
|
||||||
- On Windows you will need to setup the environment for node-gyp
|
- 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)
|
- Open an elevated command prompt (As Administrator)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
PACKAGE_NAME=realm-js
|
PACKAGE_NAME=realm-js
|
||||||
VERSION=2.4.0
|
VERSION=2.4.1
|
||||||
REALM_CORE_VERSION=5.6.0
|
REALM_CORE_VERSION=5.6.0
|
||||||
REALM_SYNC_VERSION=3.3.0
|
REALM_SYNC_VERSION=3.3.0
|
||||||
REALM_OBJECT_SERVER_VERSION=3.0.0
|
REALM_OBJECT_SERVER_VERSION=3.0.0
|
||||||
|
|
|
@ -95,3 +95,21 @@ Example:
|
||||||
// Find contacts with friends above 21 in SF
|
// 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');
|
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');
|
||||||
|
```
|
||||||
|
|
|
@ -376,8 +376,16 @@ declare namespace Realm.Sync {
|
||||||
code: number;
|
code: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface SSLVerifyObject {
|
||||||
|
serverAddress: string;
|
||||||
|
serverPort: number;
|
||||||
|
pemCertificate: string;
|
||||||
|
acceptedByOpenSSL: boolean;
|
||||||
|
depth: number;
|
||||||
|
}
|
||||||
|
|
||||||
type ErrorCallback = (session: Session, error: SyncError) => void;
|
type ErrorCallback = (session: Session, error: SyncError) => void;
|
||||||
type SSLVerifyCallback = (serverAddress: string, serverPort: number, pemCertificate: string, preverifyOk: number, depth: number) => boolean;
|
type SSLVerifyCallback = (sslVerifyObject: SSLVerifyObject) => boolean;
|
||||||
|
|
||||||
interface SyncConfiguration {
|
interface SyncConfiguration {
|
||||||
user: User;
|
user: User;
|
||||||
|
|
|
@ -45,11 +45,11 @@ class FunctionListener {
|
||||||
return this.regexStr === regex && this.event === event && this.fn === fn;
|
return this.regexStr === regex && this.event === event && this.fn === fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
onavailable(path) {
|
onavailable(path, id) {
|
||||||
if (this.regex.test(path)) {
|
if (this.regex.test(path)) {
|
||||||
if (this.event === 'available' && !this.seen[path]) {
|
if (this.event === 'available' && !this.seen[id]) {
|
||||||
this.fn(path);
|
this.fn(path);
|
||||||
this.seen[path] = true;
|
this.seen[id] = true;
|
||||||
}
|
}
|
||||||
return this.event === 'change';
|
return this.event === 'change';
|
||||||
}
|
}
|
||||||
|
@ -103,11 +103,11 @@ class OutOfProcListener {
|
||||||
return this.regexStr === regex && this.worker === worker;
|
return this.regexStr === regex && this.worker === worker;
|
||||||
}
|
}
|
||||||
|
|
||||||
onavailable(path) {
|
onavailable(path, id) {
|
||||||
if (this.regex.test(path)) {
|
if (this.regex.test(path)) {
|
||||||
if (!this.seen[path]) {
|
if (!this.seen[id]) {
|
||||||
this.worker.onavailable(path);
|
this.worker.onavailable(path);
|
||||||
this.seen[path] = true;
|
this.seen[id] = true;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -161,10 +161,11 @@ class Listener {
|
||||||
changes.release();
|
changes.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
available(virtualPath) {
|
available(virtualPath, id) {
|
||||||
let watch = false;
|
let watch = false;
|
||||||
|
id = id || virtualPath;
|
||||||
for (const callback of this.callbacks) {
|
for (const callback of this.callbacks) {
|
||||||
if (callback.onavailable(virtualPath)) {
|
if (callback.onavailable(virtualPath, id)) {
|
||||||
watch = true;
|
watch = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "realm",
|
"name": "realm",
|
||||||
"description": "Realm is a mobile database: an alternative to SQLite and key-value stores",
|
"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",
|
"license": "Apache-2.0",
|
||||||
"homepage": "https://realm.io",
|
"homepage": "https://realm.io",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
|
|
@ -191,6 +191,10 @@ function getSyncRequirements(dependencies, options, required = {}) {
|
||||||
return 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:
|
default:
|
||||||
return Promise.reject(new Error(`Unsupported sync platform '${options.platform}'`));
|
return Promise.reject(new Error(`Unsupported sync platform '${options.platform}'`));
|
||||||
}
|
}
|
||||||
|
|
|
@ -969,7 +969,7 @@
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
CURRENT_PROJECT_VERSION = 2.4.0;
|
CURRENT_PROJECT_VERSION = 2.4.1;
|
||||||
CXX = "$(SRCROOT)/../scripts/ccache-clang++.sh";
|
CXX = "$(SRCROOT)/../scripts/ccache-clang++.sh";
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
@ -1033,7 +1033,7 @@
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
CURRENT_PROJECT_VERSION = 2.4.0;
|
CURRENT_PROJECT_VERSION = 2.4.1;
|
||||||
CXX = "$(SRCROOT)/../scripts/ccache-clang++.sh";
|
CXX = "$(SRCROOT)/../scripts/ccache-clang++.sh";
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
ENABLE_NS_ASSERTIONS = NO;
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
|
|
|
@ -160,8 +160,7 @@ inline void alias_backlinks(parser::KeyPathMapping &mapping, const realm::Shared
|
||||||
if (property.type == realm::PropertyType::LinkingObjects) {
|
if (property.type == realm::PropertyType::LinkingObjects) {
|
||||||
auto target_object_schema = schema.find(property.object_type);
|
auto target_object_schema = schema.find(property.object_type);
|
||||||
const TableRef table = ObjectStore::table_for_object_type(realm->read_group(), it->name);
|
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." + target_object_schema->name + "." + property.link_origin_property_name;
|
||||||
std::string native_name = "@links." + std::string(target_table->get_name()) + "." + property.link_origin_property_name;
|
|
||||||
mapping.add_mapping(table, property.name, native_name);
|
mapping.add_mapping(table, property.name, native_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -181,6 +180,7 @@ typename T::Object ResultsClass<T>::create_filtered(ContextType ctx, const U &co
|
||||||
auto const &object_schema = collection.get_object_schema();
|
auto const &object_schema = collection.get_object_schema();
|
||||||
DescriptorOrdering ordering;
|
DescriptorOrdering ordering;
|
||||||
parser::KeyPathMapping mapping;
|
parser::KeyPathMapping mapping;
|
||||||
|
mapping.set_backlink_class_prefix(ObjectStore::table_name_for_object_type(""));
|
||||||
alias_backlinks(mapping, realm);
|
alias_backlinks(mapping, realm);
|
||||||
|
|
||||||
parser::ParserResult result = parser::parse(query_string);
|
parser::ParserResult result = parser::parse(query_string);
|
||||||
|
|
|
@ -109,24 +109,49 @@ module.exports = {
|
||||||
let english = realm.create('Language', {name: 'English'});
|
let english = realm.create('Language', {name: 'English'});
|
||||||
let french = realm.create('Language', {name: 'French'});
|
let french = realm.create('Language', {name: 'French'});
|
||||||
let danish = realm.create('Language', {name: 'Danish'});
|
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 canada = realm.create('Country', {name: 'Canada', languages: [english, french]});
|
||||||
let denmark = realm.create('Country', {name: 'Denmark', languages: [danish, english]});
|
let denmark = realm.create('Country', {name: 'Denmark', languages: [danish, english]});
|
||||||
let france = realm.create('Country', {name: 'France', languages: [french, english]});
|
let france = realm.create('Country', {name: 'France', languages: [french, english]});
|
||||||
});
|
});
|
||||||
let languages = realm.objects('Language');
|
let languages = realm.objects('Language');
|
||||||
let spokenInThreeCountries = languages.filtered('spokenIn.@count == 3');
|
{
|
||||||
TestCase.assertEqual(spokenInThreeCountries.length, 1);
|
let spokenInThreeCountries = languages.filtered('spokenIn.@count == 3');
|
||||||
TestCase.assertEqual(spokenInThreeCountries[0].name, 'English');
|
TestCase.assertEqual(spokenInThreeCountries.length, 1);
|
||||||
let spokenInTwoCountries = languages.filtered('spokenIn.@count == 2');
|
TestCase.assertEqual(spokenInThreeCountries[0].name, 'English');
|
||||||
TestCase.assertEqual(spokenInTwoCountries.length, 1);
|
let spokenInTwoCountries = languages.filtered('spokenIn.@count == 2');
|
||||||
TestCase.assertEqual(spokenInTwoCountries[0].name, 'French')
|
TestCase.assertEqual(spokenInTwoCountries.length, 1);
|
||||||
let spokenInOneCountry = languages.filtered('spokenIn.@count == 1');
|
TestCase.assertEqual(spokenInTwoCountries[0].name, 'French')
|
||||||
TestCase.assertEqual(spokenInOneCountry.length, 1);
|
let spokenInOneCountry = languages.filtered('spokenIn.@count == 1');
|
||||||
TestCase.assertEqual(spokenInOneCountry[0].name, 'Danish')
|
TestCase.assertEqual(spokenInOneCountry.length, 1);
|
||||||
let languagesSpokenInCanada = languages.filtered('spokenIn.name ==[c] "canada"');
|
TestCase.assertEqual(spokenInOneCountry[0].name, 'Danish')
|
||||||
TestCase.assertEqual(languagesSpokenInCanada.length, 2);
|
let languagesSpokenInCanada = languages.filtered('spokenIn.name ==[c] "canada"');
|
||||||
TestCase.assertEqual(languagesSpokenInCanada[0].name, 'English');
|
TestCase.assertEqual(languagesSpokenInCanada.length, 2);
|
||||||
TestCase.assertEqual(languagesSpokenInCanada[1].name, 'French');
|
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() {
|
testMethod: function() {
|
||||||
|
|
Loading…
Reference in New Issue