mirror of
https://github.com/status-im/realm-js.git
synced 2025-01-11 06:46:03 +00:00
Merge branch 'master' into sk-listview-merge
* master: (207 commits) Convert to using new React Native MainActivity template Create RealmReactPackage for our Android plugin Fix doc for Android NPM ignore react-native/android folder Skip building Android module under Xcode Skip building Android module for iOS tests gitignore Android downloads folder Update README with instructions to run on Android Use un-patched RN for Android by installing hook into JSC cleanup build system Use Realm in node_modules for ReactTests on Android Change Demo => ReactTests adding a 'publishAndroid' task to generate the AAR with prebuilt .so files Adjust POM_NAME Use consistent package naming Remove old Demo files Add copyright to JNI file Cleanup platform.hpp Make our Android module buildable as a dependency Add `npm test` command ...
This commit is contained in:
commit
3e1889d342
7
.gitignore
vendored
7
.gitignore
vendored
@ -97,3 +97,10 @@ build/
|
|||||||
# node.js
|
# node.js
|
||||||
node_modules/
|
node_modules/
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
|
|
||||||
|
# Android/IJ
|
||||||
|
/android/
|
||||||
|
.idea
|
||||||
|
.gradle
|
||||||
|
local.properties
|
||||||
|
|
||||||
|
13
README.md
13
README.md
@ -12,12 +12,21 @@ The ReactNative example project is in the `examples/ReactExample` directory. You
|
|||||||
## ReactNative Project Setup
|
## ReactNative Project Setup
|
||||||
- Create a new ReactNative project: `react-native init <project-name>`
|
- Create a new ReactNative project: `react-native init <project-name>`
|
||||||
- Change directories into the new project (`cd <project-name>`) and add the `realm` dependency: `npm install --save git+ssh://git@github.com/realm/realm-js.git#beta` (please note it's **essential** to leave the `#beta` at the end)
|
- Change directories into the new project (`cd <project-name>`) and add the `realm` dependency: `npm install --save git+ssh://git@github.com/realm/realm-js.git#beta` (please note it's **essential** to leave the `#beta` at the end)
|
||||||
|
|
||||||
|
### iOS
|
||||||
- Open the generated Xcode project (`ios/<project-name>.xcodeproj`)
|
- Open the generated Xcode project (`ios/<project-name>.xcodeproj`)
|
||||||
- Making sure the top-level project is selected in the sidebar, change the `iOS Deployment Target` to at least `8.0` in the project settings.
|
- Making sure the top-level project is selected in the sidebar, change the `iOS Deployment Target` to at least `8.0` in the project settings.
|
||||||
- Right-click the `Libraries` group in the sidebar and click `Add Files to “<project-name>”`. Select `node_modules/realm/RealmJS.xcodeproj` from the dialog.
|
- Right-click the `Libraries` group in the sidebar and click `Add Files to “<project-name>”`. Select `node_modules/realm/RealmJS.xcodeproj` from the dialog.
|
||||||
- Drag `RealmReact.framework` from the `Products` directory under `RealmJS.xcodeproj` into the `Embedded Binaries` section in the `General` tab for your app's target settings.
|
- Drag `RealmReact.framework` from the `Products` directory under `RealmJS.xcodeproj` into the `Embedded Binaries` section in the `General` tab for your app's target settings.
|
||||||
- In the `Build Phases` tab for your app's target settings, make sure `RealmReact.framework` is added to the `Link Binary with Library` build phase.
|
- In the `Build Phases` tab for your app's target settings, make sure `RealmReact.framework` is added to the `Link Binary with Library` build phase.
|
||||||
- You can now `require('realm')` in your app's JS to use Realm!
|
- You can now `require('realm')` in your iOS app's JS to use Realm!
|
||||||
|
|
||||||
|
### Android
|
||||||
|
- Run this command from the project directory: `react-native link realm`
|
||||||
|
- Open `MainActivity.java` inside your project:
|
||||||
|
- Add `import io.realm.react.RealmReactPackage;` under the other imports.
|
||||||
|
- Add `new RealmReactPackage()` to the list returned by the `getPackages()` method.
|
||||||
|
- You can now `require('realm')` in your Android app's JS to use Realm!
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
Start with creating a `realm` by passing it an array of `objectSchema` (object types and their properties) for each type of object it will contain:
|
Start with creating a `realm` by passing it an array of `objectSchema` (object types and their properties) for each type of object it will contain:
|
||||||
@ -96,7 +105,7 @@ You can see more examples of how to use these APIs in the [ReactExample](https:/
|
|||||||
The `realmConfig` passed to the constructor can contain the following:
|
The `realmConfig` passed to the constructor can contain the following:
|
||||||
|
|
||||||
- `schema` – required when first accessing a realm - array of `ObjectSchema` or object constructors (see below)
|
- `schema` – required when first accessing a realm - array of `ObjectSchema` or object constructors (see below)
|
||||||
- `path` – optional - defaults to `Realm.defaultPath` (which initially is `'Documents/default.realm'`)
|
- `path` – optional - defaults to `Realm.defaultPath` (which initially is `'Documents/default.realm'` for iOS and inside the [internal storage](http://developer.android.com/reference/android/content/Context.html#getFilesDir()) `/data/data/<packagename>/files/` for Android)
|
||||||
- `schemaVersion` – optional - defaults to `0` but must be specified and incremented after changing the schema
|
- `schemaVersion` – optional - defaults to `0` but must be specified and incremented after changing the schema
|
||||||
|
|
||||||
### ObjectSchema
|
### ObjectSchema
|
||||||
|
@ -7,13 +7,24 @@
|
|||||||
# Some modules have their own node_modules with overlap
|
# Some modules have their own node_modules with overlap
|
||||||
.*/node_modules/node-haste/.*
|
.*/node_modules/node-haste/.*
|
||||||
|
|
||||||
# Ignore react-tools where there are overlaps, but don't ignore anything that
|
# Ugh
|
||||||
# react-native relies on
|
.*/node_modules/babel.*
|
||||||
.*/node_modules/react-tools/src/vendor/core/ExecutionEnvironment.js
|
.*/node_modules/babylon.*
|
||||||
.*/node_modules/react-tools/src/browser/eventPlugins/ResponderEventPlugin.js
|
.*/node_modules/invariant.*
|
||||||
.*/node_modules/react-tools/src/browser/ui/React.js
|
|
||||||
.*/node_modules/react-tools/src/core/ReactInstanceHandles.js
|
# Ignore react and fbjs where there are overlaps, but don't ignore
|
||||||
.*/node_modules/react-tools/src/event/EventPropagators.js
|
# anything that react-native relies on
|
||||||
|
.*/node_modules/fbjs-haste/.*/__tests__/.*
|
||||||
|
.*/node_modules/fbjs-haste/__forks__/Map.js
|
||||||
|
.*/node_modules/fbjs-haste/__forks__/Promise.js
|
||||||
|
.*/node_modules/fbjs-haste/__forks__/fetch.js
|
||||||
|
.*/node_modules/fbjs-haste/core/ExecutionEnvironment.js
|
||||||
|
.*/node_modules/fbjs-haste/core/isEmpty.js
|
||||||
|
.*/node_modules/fbjs-haste/crypto/crc32.js
|
||||||
|
.*/node_modules/fbjs-haste/stubs/ErrorUtils.js
|
||||||
|
.*/node_modules/react-haste/React.js
|
||||||
|
.*/node_modules/react-haste/renderers/dom/ReactDOM.js
|
||||||
|
.*/node_modules/react-haste/renderers/shared/event/eventPlugins/ResponderEventPlugin.js
|
||||||
|
|
||||||
# Ignore commoner tests
|
# Ignore commoner tests
|
||||||
.*/node_modules/commoner/test/.*
|
.*/node_modules/commoner/test/.*
|
||||||
@ -22,7 +33,10 @@
|
|||||||
.*/react-tools/node_modules/commoner/lib/reader.js
|
.*/react-tools/node_modules/commoner/lib/reader.js
|
||||||
|
|
||||||
# Ignore jest
|
# Ignore jest
|
||||||
.*/react-native/node_modules/jest-cli/.*
|
.*/node_modules/jest-cli/.*
|
||||||
|
|
||||||
|
# Ignore Website
|
||||||
|
.*/website/.*
|
||||||
|
|
||||||
[include]
|
[include]
|
||||||
|
|
||||||
@ -32,13 +46,18 @@ node_modules/react-native/Libraries/react-native/react-native-interface.js
|
|||||||
[options]
|
[options]
|
||||||
module.system=haste
|
module.system=haste
|
||||||
|
|
||||||
|
munge_underscores=true
|
||||||
|
|
||||||
|
module.name_mapper='^image![a-zA-Z0-9$_-]+$' -> 'GlobalImageStub'
|
||||||
|
module.name_mapper='^[./a-zA-Z0-9$_-]+\.png$' -> 'RelativeImageStub'
|
||||||
|
|
||||||
suppress_type=$FlowIssue
|
suppress_type=$FlowIssue
|
||||||
suppress_type=$FlowFixMe
|
suppress_type=$FlowFixMe
|
||||||
suppress_type=$FixMe
|
suppress_type=$FixMe
|
||||||
|
|
||||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(1[0-3]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
|
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(1[0-8]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
|
||||||
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(1[0-3]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)? #[0-9]+
|
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(1[0-8]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)? #[0-9]+
|
||||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
|
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
|
||||||
|
|
||||||
[version]
|
[version]
|
||||||
0.13.1
|
0.18.1
|
||||||
|
28
examples/ReactExample/.gitignore
vendored
28
examples/ReactExample/.gitignore
vendored
@ -1,28 +0,0 @@
|
|||||||
# OSX
|
|
||||||
#
|
|
||||||
.DS_Store
|
|
||||||
|
|
||||||
# Xcode
|
|
||||||
#
|
|
||||||
build/
|
|
||||||
*.pbxuser
|
|
||||||
!default.pbxuser
|
|
||||||
*.mode1v3
|
|
||||||
!default.mode1v3
|
|
||||||
*.mode2v3
|
|
||||||
!default.mode2v3
|
|
||||||
*.perspectivev3
|
|
||||||
!default.perspectivev3
|
|
||||||
xcuserdata
|
|
||||||
*.xccheckout
|
|
||||||
*.moved-aside
|
|
||||||
DerivedData
|
|
||||||
*.hmap
|
|
||||||
*.ipa
|
|
||||||
*.xcuserstate
|
|
||||||
project.xcworkspace
|
|
||||||
|
|
||||||
# node.js
|
|
||||||
#
|
|
||||||
node_modules/
|
|
||||||
npm-debug.log
|
|
1
examples/ReactExample/.watchmanconfig
Normal file
1
examples/ReactExample/.watchmanconfig
Normal file
@ -0,0 +1 @@
|
|||||||
|
{}
|
78
examples/ReactExample/android/app/build.gradle
Normal file
78
examples/ReactExample/android/app/build.gradle
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
apply plugin: "com.android.application"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The react.gradle file registers two tasks: bundleDebugJsAndAssets and bundleReleaseJsAndAssets.
|
||||||
|
* These basically call `react-native bundle` with the correct arguments during the Android build
|
||||||
|
* cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the
|
||||||
|
* bundle directly from the development server. Below you can see all the possible configurations
|
||||||
|
* and their defaults. If you decide to add a configuration block, make sure to add it before the
|
||||||
|
* `apply from: "react.gradle"` line.
|
||||||
|
*
|
||||||
|
* project.ext.react = [
|
||||||
|
* // the name of the generated asset file containing your JS bundle
|
||||||
|
* bundleAssetName: "index.android.bundle",
|
||||||
|
*
|
||||||
|
* // the entry file for bundle generation
|
||||||
|
* entryFile: "index.android.js",
|
||||||
|
*
|
||||||
|
* // whether to bundle JS and assets in debug mode
|
||||||
|
* bundleInDebug: false,
|
||||||
|
*
|
||||||
|
* // whether to bundle JS and assets in release mode
|
||||||
|
* bundleInRelease: true,
|
||||||
|
*
|
||||||
|
* // the root of your project, i.e. where "package.json" lives
|
||||||
|
* root: "../../",
|
||||||
|
*
|
||||||
|
* // where to put the JS bundle asset in debug mode
|
||||||
|
* jsBundleDirDebug: "$buildDir/intermediates/assets/debug",
|
||||||
|
*
|
||||||
|
* // where to put the JS bundle asset in release mode
|
||||||
|
* jsBundleDirRelease: "$buildDir/intermediates/assets/release",
|
||||||
|
*
|
||||||
|
* // where to put drawable resources / React Native assets, e.g. the ones you use via
|
||||||
|
* // require('./image.png')), in debug mode
|
||||||
|
* resourcesDirDebug: "$buildDir/intermediates/res/merged/debug",
|
||||||
|
*
|
||||||
|
* // where to put drawable resources / React Native assets, e.g. the ones you use via
|
||||||
|
* // require('./image.png')), in release mode
|
||||||
|
* resourcesDirRelease: "$buildDir/intermediates/res/merged/release",
|
||||||
|
*
|
||||||
|
* // by default the gradle tasks are skipped if none of the JS files or assets change; this means
|
||||||
|
* // that we don't look at files in android/ or ios/ to determine whether the tasks are up to
|
||||||
|
* // date; if you have any other folders that you want to ignore for performance reasons (gradle
|
||||||
|
* // indexes the entire tree), add them here. Alternatively, if you have JS files in android/
|
||||||
|
* // for example, you might want to remove it from here.
|
||||||
|
* inputExcludes: ["android/**", "ios/**"]
|
||||||
|
* ]
|
||||||
|
*/
|
||||||
|
|
||||||
|
apply from: "react.gradle"
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion 23
|
||||||
|
buildToolsVersion "23.0.1"
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
applicationId "io.realm.react.example"
|
||||||
|
minSdkVersion 16
|
||||||
|
targetSdkVersion 22
|
||||||
|
versionCode 1
|
||||||
|
versionName "1.0"
|
||||||
|
ndk {
|
||||||
|
abiFilters "armeabi-v7a", "x86"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
minifyEnabled false // Set this to true to enable Proguard
|
||||||
|
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile 'com.android.support:appcompat-v7:23.0.1'
|
||||||
|
compile 'com.facebook.react:react-native:0.18.0'
|
||||||
|
compile project(':realm')
|
||||||
|
}
|
60
examples/ReactExample/android/app/proguard-rules.pro
vendored
Normal file
60
examples/ReactExample/android/app/proguard-rules.pro
vendored
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
# Add project specific ProGuard rules here.
|
||||||
|
# By default, the flags in this file are appended to flags specified
|
||||||
|
# in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
|
||||||
|
# You can edit the include path and order by changing the proguardFiles
|
||||||
|
# directive in build.gradle.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
|
# Add any project specific keep options here:
|
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following
|
||||||
|
# and specify the fully qualified class name to the JavaScript interface
|
||||||
|
# class:
|
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
|
# public *;
|
||||||
|
#}
|
||||||
|
|
||||||
|
# Disabling obfuscation is useful if you collect stack traces from production crashes
|
||||||
|
# (unless you are using a system that supports de-obfuscate the stack traces).
|
||||||
|
-dontobfuscate
|
||||||
|
|
||||||
|
# React Native
|
||||||
|
|
||||||
|
# Keep our interfaces so they can be used by other ProGuard rules.
|
||||||
|
# See http://sourceforge.net/p/proguard/bugs/466/
|
||||||
|
-keep,allowobfuscation @interface com.facebook.proguard.annotations.DoNotStrip
|
||||||
|
-keep,allowobfuscation @interface com.facebook.proguard.annotations.KeepGettersAndSetters
|
||||||
|
|
||||||
|
# Do not strip any method/class that is annotated with @DoNotStrip
|
||||||
|
-keep @com.facebook.proguard.annotations.DoNotStrip class *
|
||||||
|
-keepclassmembers class * {
|
||||||
|
@com.facebook.proguard.annotations.DoNotStrip *;
|
||||||
|
}
|
||||||
|
|
||||||
|
-keepclassmembers @com.facebook.proguard.annotations.KeepGettersAndSetters class * {
|
||||||
|
void set*(***);
|
||||||
|
*** get*();
|
||||||
|
}
|
||||||
|
|
||||||
|
-keep class * extends com.facebook.react.bridge.JavaScriptModule { *; }
|
||||||
|
-keep class * extends com.facebook.react.bridge.NativeModule { *; }
|
||||||
|
-keepclassmembers class * { @com.facebook.react.uimanager.UIProp <fields>; }
|
||||||
|
-keepclassmembers class * { @com.facebook.react.uimanager.ReactProp <methods>; }
|
||||||
|
-keepclassmembers class * { @com.facebook.react.uimanager.ReactPropGroup <methods>; }
|
||||||
|
|
||||||
|
# okhttp
|
||||||
|
|
||||||
|
-keepattributes Signature
|
||||||
|
-keepattributes *Annotation*
|
||||||
|
-keep class com.squareup.okhttp.** { *; }
|
||||||
|
-keep interface com.squareup.okhttp.** { *; }
|
||||||
|
-dontwarn com.squareup.okhttp.**
|
||||||
|
|
||||||
|
# okio
|
||||||
|
|
||||||
|
-keep class sun.misc.Unsafe { *; }
|
||||||
|
-dontwarn java.nio.file.*
|
||||||
|
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
|
||||||
|
-dontwarn okio.**
|
87
examples/ReactExample/android/app/react.gradle
Normal file
87
examples/ReactExample/android/app/react.gradle
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
import org.apache.tools.ant.taskdefs.condition.Os
|
||||||
|
|
||||||
|
def config = project.hasProperty("react") ? project.react : [];
|
||||||
|
|
||||||
|
def bundleAssetName = config.bundleAssetName ?: "index.android.bundle"
|
||||||
|
def entryFile = config.entryFile ?: "index.android.js"
|
||||||
|
|
||||||
|
// because elvis operator
|
||||||
|
def elvisFile(thing) {
|
||||||
|
return thing ? file(thing) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
def reactRoot = elvisFile(config.root) ?: file("../../")
|
||||||
|
def jsBundleDirDebug = elvisFile(config.jsBundleDirDebug) ?:
|
||||||
|
file("$buildDir/intermediates/assets/debug")
|
||||||
|
def jsBundleDirRelease = elvisFile(config.jsBundleDirRelease) ?:
|
||||||
|
file("$buildDir/intermediates/assets/release")
|
||||||
|
def resourcesDirDebug = elvisFile(config.resourcesDirDebug) ?:
|
||||||
|
file("$buildDir/intermediates/res/merged/debug")
|
||||||
|
def resourcesDirRelease = elvisFile(config.resourcesDirRelease) ?:
|
||||||
|
file("$buildDir/intermediates/res/merged/release")
|
||||||
|
def inputExcludes = config.inputExcludes ?: ["android/**", "ios/**"]
|
||||||
|
|
||||||
|
def jsBundleFileDebug = file("$jsBundleDirDebug/$bundleAssetName")
|
||||||
|
def jsBundleFileRelease = file("$jsBundleDirRelease/$bundleAssetName")
|
||||||
|
|
||||||
|
task bundleDebugJsAndAssets(type: Exec) {
|
||||||
|
// create dirs if they are not there (e.g. the "clean" task just ran)
|
||||||
|
doFirst {
|
||||||
|
jsBundleDirDebug.mkdirs()
|
||||||
|
resourcesDirDebug.mkdirs()
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up inputs and outputs so gradle can cache the result
|
||||||
|
inputs.files fileTree(dir: reactRoot, excludes: inputExcludes)
|
||||||
|
outputs.dir jsBundleDirDebug
|
||||||
|
outputs.dir resourcesDirDebug
|
||||||
|
|
||||||
|
// set up the call to the react-native cli
|
||||||
|
workingDir reactRoot
|
||||||
|
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
|
||||||
|
commandLine "cmd", "/c", "react-native", "bundle", "--platform", "android", "--dev", "true", "--entry-file",
|
||||||
|
entryFile, "--bundle-output", jsBundleFileDebug, "--assets-dest", resourcesDirDebug
|
||||||
|
} else {
|
||||||
|
commandLine "react-native", "bundle", "--platform", "android", "--dev", "true", "--entry-file",
|
||||||
|
entryFile, "--bundle-output", jsBundleFileDebug, "--assets-dest", resourcesDirDebug
|
||||||
|
}
|
||||||
|
|
||||||
|
enabled config.bundleInDebug ?: false
|
||||||
|
}
|
||||||
|
|
||||||
|
task bundleReleaseJsAndAssets(type: Exec) {
|
||||||
|
// create dirs if they are not there (e.g. the "clean" task just ran)
|
||||||
|
doFirst {
|
||||||
|
jsBundleDirRelease.mkdirs()
|
||||||
|
resourcesDirRelease.mkdirs()
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up inputs and outputs so gradle can cache the result
|
||||||
|
inputs.files fileTree(dir: reactRoot, excludes: inputExcludes)
|
||||||
|
outputs.dir jsBundleDirRelease
|
||||||
|
outputs.dir resourcesDirRelease
|
||||||
|
|
||||||
|
// set up the call to the react-native cli
|
||||||
|
workingDir reactRoot
|
||||||
|
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
|
||||||
|
commandLine "cmd","/c", "react-native", "bundle", "--platform", "android", "--dev", "false", "--entry-file",
|
||||||
|
entryFile, "--bundle-output", jsBundleFileRelease, "--assets-dest", resourcesDirRelease
|
||||||
|
} else {
|
||||||
|
commandLine "react-native", "bundle", "--platform", "android", "--dev", "false", "--entry-file",
|
||||||
|
entryFile, "--bundle-output", jsBundleFileRelease, "--assets-dest", resourcesDirRelease
|
||||||
|
}
|
||||||
|
|
||||||
|
enabled config.bundleInRelease ?: true
|
||||||
|
}
|
||||||
|
|
||||||
|
gradle.projectsEvaluated {
|
||||||
|
// hook bundleDebugJsAndAssets into the android build process
|
||||||
|
bundleDebugJsAndAssets.dependsOn mergeDebugResources
|
||||||
|
bundleDebugJsAndAssets.dependsOn mergeDebugAssets
|
||||||
|
processDebugResources.dependsOn bundleDebugJsAndAssets
|
||||||
|
|
||||||
|
// hook bundleReleaseJsAndAssets into the android build process
|
||||||
|
bundleReleaseJsAndAssets.dependsOn mergeReleaseResources
|
||||||
|
bundleReleaseJsAndAssets.dependsOn mergeReleaseAssets
|
||||||
|
processReleaseResources.dependsOn bundleReleaseJsAndAssets
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="io.realm.react.example">
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
|
||||||
|
<application
|
||||||
|
android:allowBackup="true"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:icon="@mipmap/ic_launcher"
|
||||||
|
android:theme="@style/AppTheme">
|
||||||
|
<activity
|
||||||
|
android:name=".MainActivity"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
@ -0,0 +1,43 @@
|
|||||||
|
package io.realm.react.example;
|
||||||
|
|
||||||
|
import com.facebook.react.ReactActivity;
|
||||||
|
import com.facebook.react.ReactPackage;
|
||||||
|
import com.facebook.react.shell.MainReactPackage;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import io.realm.react.RealmReactPackage;
|
||||||
|
|
||||||
|
public class MainActivity extends ReactActivity {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the main component registered from JavaScript.
|
||||||
|
* This is used to schedule rendering of the component.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected String getMainComponentName() {
|
||||||
|
return "ReactExample";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether dev mode should be enabled.
|
||||||
|
* This enables e.g. the dev menu.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected boolean getUseDeveloperSupport() {
|
||||||
|
return BuildConfig.DEBUG;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of packages used by the app. If the app uses additional views
|
||||||
|
* or modules besides the default ones, add more packages here.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected List<ReactPackage> getPackages() {
|
||||||
|
return Arrays.<ReactPackage>asList(
|
||||||
|
new MainReactPackage(),
|
||||||
|
new RealmReactPackage()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 3.3 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
Binary file not shown.
After Width: | Height: | Size: 4.7 KiB |
Binary file not shown.
After Width: | Height: | Size: 7.5 KiB |
@ -0,0 +1,3 @@
|
|||||||
|
<resources>
|
||||||
|
<string name="app_name">ReactExample</string>
|
||||||
|
</resources>
|
@ -0,0 +1,8 @@
|
|||||||
|
<resources>
|
||||||
|
|
||||||
|
<!-- Base application theme. -->
|
||||||
|
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
|
||||||
|
<!-- Customize your theme here. -->
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</resources>
|
24
examples/ReactExample/android/build.gradle
Normal file
24
examples/ReactExample/android/build.gradle
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
|
|
||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath 'com.android.tools.build:gradle:1.3.1'
|
||||||
|
|
||||||
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
|
// in the individual module build.gradle files
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allprojects {
|
||||||
|
repositories {
|
||||||
|
mavenLocal()
|
||||||
|
jcenter()
|
||||||
|
jcenter {
|
||||||
|
url "http://dl.bintray.com/mkonicek/maven"
|
||||||
|
}
|
||||||
|
maven { url "https://jitpack.io" }
|
||||||
|
}
|
||||||
|
}
|
20
examples/ReactExample/android/gradle.properties
Normal file
20
examples/ReactExample/android/gradle.properties
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# Project-wide Gradle settings.
|
||||||
|
|
||||||
|
# IDE (e.g. Android Studio) users:
|
||||||
|
# Gradle settings configured through the IDE *will override*
|
||||||
|
# any settings specified in this file.
|
||||||
|
|
||||||
|
# For more details on how to configure your build environment visit
|
||||||
|
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||||
|
|
||||||
|
# Specifies the JVM arguments used for the daemon process.
|
||||||
|
# The setting is particularly useful for tweaking memory settings.
|
||||||
|
# Default value: -Xmx10248m -XX:MaxPermSize=256m
|
||||||
|
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
||||||
|
|
||||||
|
# When configured, Gradle will run in incubating parallel mode.
|
||||||
|
# This option should only be used with decoupled projects. More details, visit
|
||||||
|
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||||
|
# org.gradle.parallel=true
|
||||||
|
|
||||||
|
android.useDeprecatedNdk=true
|
BIN
examples/ReactExample/android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
examples/ReactExample/android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
5
examples/ReactExample/android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
5
examples/ReactExample/android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip
|
164
examples/ReactExample/android/gradlew
vendored
Executable file
164
examples/ReactExample/android/gradlew
vendored
Executable file
@ -0,0 +1,164 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
##
|
||||||
|
## Gradle start up script for UN*X
|
||||||
|
##
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS=""
|
||||||
|
|
||||||
|
APP_NAME="Gradle"
|
||||||
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
MAX_FD="maximum"
|
||||||
|
|
||||||
|
warn ( ) {
|
||||||
|
echo "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
die ( ) {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# OS specific support (must be 'true' or 'false').
|
||||||
|
cygwin=false
|
||||||
|
msys=false
|
||||||
|
darwin=false
|
||||||
|
case "`uname`" in
|
||||||
|
CYGWIN* )
|
||||||
|
cygwin=true
|
||||||
|
;;
|
||||||
|
Darwin* )
|
||||||
|
darwin=true
|
||||||
|
;;
|
||||||
|
MINGW* )
|
||||||
|
msys=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# For Cygwin, ensure paths are in UNIX format before anything is touched.
|
||||||
|
if $cygwin ; then
|
||||||
|
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
PRG="$0"
|
||||||
|
# Need this for relative symlinks.
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG=`dirname "$PRG"`"/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
SAVED="`pwd`"
|
||||||
|
cd "`dirname \"$PRG\"`/" >&-
|
||||||
|
APP_HOME="`pwd -P`"
|
||||||
|
cd "$SAVED" >&-
|
||||||
|
|
||||||
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
# Determine the Java command to use to start the JVM.
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
fi
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD="java"
|
||||||
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increase the maximum file descriptors if we can.
|
||||||
|
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||||
|
MAX_FD_LIMIT=`ulimit -H -n`
|
||||||
|
if [ $? -eq 0 ] ; then
|
||||||
|
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||||
|
MAX_FD="$MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
ulimit -n $MAX_FD
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Darwin, add options to specify how the application appears in the dock
|
||||||
|
if $darwin; then
|
||||||
|
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin, switch paths to Windows format before running java
|
||||||
|
if $cygwin ; then
|
||||||
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
|
|
||||||
|
# We build the pattern for arguments to be converted via cygpath
|
||||||
|
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||||
|
SEP=""
|
||||||
|
for dir in $ROOTDIRSRAW ; do
|
||||||
|
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||||
|
SEP="|"
|
||||||
|
done
|
||||||
|
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||||
|
# Add a user-defined pattern to the cygpath arguments
|
||||||
|
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||||
|
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||||
|
fi
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
i=0
|
||||||
|
for arg in "$@" ; do
|
||||||
|
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||||
|
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||||
|
|
||||||
|
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||||
|
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||||
|
else
|
||||||
|
eval `echo args$i`="\"$arg\""
|
||||||
|
fi
|
||||||
|
i=$((i+1))
|
||||||
|
done
|
||||||
|
case $i in
|
||||||
|
(0) set -- ;;
|
||||||
|
(1) set -- "$args0" ;;
|
||||||
|
(2) set -- "$args0" "$args1" ;;
|
||||||
|
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
|
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
|
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
|
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
|
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
|
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
|
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||||
|
function splitJvmOpts() {
|
||||||
|
JVM_OPTS=("$@")
|
||||||
|
}
|
||||||
|
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||||
|
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||||
|
|
||||||
|
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
90
examples/ReactExample/android/gradlew.bat
vendored
Normal file
90
examples/ReactExample/android/gradlew.bat
vendored
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
@if "%DEBUG%" == "" @echo off
|
||||||
|
@rem ##########################################################################
|
||||||
|
@rem
|
||||||
|
@rem Gradle startup script for Windows
|
||||||
|
@rem
|
||||||
|
@rem ##########################################################################
|
||||||
|
|
||||||
|
@rem Set local scope for the variables with windows NT shell
|
||||||
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
set DEFAULT_JVM_OPTS=
|
||||||
|
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
|
set APP_BASE_NAME=%~n0
|
||||||
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Find java.exe
|
||||||
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
|
set JAVA_EXE=java.exe
|
||||||
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
|
if "%ERRORLEVEL%" == "0" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:findJavaFromJavaHome
|
||||||
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
|
if exist "%JAVA_EXE%" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:init
|
||||||
|
@rem Get command-line arguments, handling Windowz variants
|
||||||
|
|
||||||
|
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||||
|
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||||
|
|
||||||
|
:win9xME_args
|
||||||
|
@rem Slurp the command line arguments.
|
||||||
|
set CMD_LINE_ARGS=
|
||||||
|
set _SKIP=2
|
||||||
|
|
||||||
|
:win9xME_args_slurp
|
||||||
|
if "x%~1" == "x" goto execute
|
||||||
|
|
||||||
|
set CMD_LINE_ARGS=%*
|
||||||
|
goto execute
|
||||||
|
|
||||||
|
:4NT_args
|
||||||
|
@rem Get arguments from the 4NT Shell from JP Software
|
||||||
|
set CMD_LINE_ARGS=%$
|
||||||
|
|
||||||
|
:execute
|
||||||
|
@rem Setup the command line
|
||||||
|
|
||||||
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
@rem Execute Gradle
|
||||||
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||||
|
|
||||||
|
:end
|
||||||
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||||
|
|
||||||
|
:fail
|
||||||
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
|
rem the _cmd.exe /c_ return code!
|
||||||
|
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||||
|
exit /b 1
|
||||||
|
|
||||||
|
:mainEnd
|
||||||
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
||||||
|
:omega
|
6
examples/ReactExample/android/settings.gradle
Normal file
6
examples/ReactExample/android/settings.gradle
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
rootProject.name = 'ReactExample'
|
||||||
|
|
||||||
|
include ':app'
|
||||||
|
|
||||||
|
include ':realm'
|
||||||
|
project(':realm').projectDir = new File(rootProject.projectDir, '../node_modules/realm/android')
|
@ -6,21 +6,58 @@
|
|||||||
|
|
||||||
const React = require('react-native');
|
const React = require('react-native');
|
||||||
|
|
||||||
module.exports = React.StyleSheet.create({
|
const { Navigator, Platform, StyleSheet } = React;
|
||||||
|
const { NavBarHeight, TotalNavHeight } = Navigator.NavigationBar.Styles.General;
|
||||||
|
|
||||||
|
const iOS = (Platform.OS == 'ios');
|
||||||
|
|
||||||
|
module.exports = StyleSheet.create({
|
||||||
container: {
|
container: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'stretch',
|
alignItems: 'stretch',
|
||||||
backgroundColor: '#ffffff',
|
backgroundColor: '#fff',
|
||||||
},
|
},
|
||||||
navigator: {
|
navigator: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
},
|
},
|
||||||
|
navBar: {
|
||||||
|
backgroundColor: '#f0727d',
|
||||||
|
},
|
||||||
|
navBarView: {
|
||||||
|
alignItems: 'center',
|
||||||
|
flexDirection: 'row',
|
||||||
|
height: NavBarHeight,
|
||||||
|
},
|
||||||
|
navBarLeftArrow: {
|
||||||
|
color: '#fff',
|
||||||
|
fontSize: 40,
|
||||||
|
fontWeight: '200',
|
||||||
|
letterSpacing: 2,
|
||||||
|
marginTop: -6,
|
||||||
|
},
|
||||||
|
navBarLeftButton: {
|
||||||
|
paddingLeft: 8,
|
||||||
|
},
|
||||||
|
navBarRightButton: {
|
||||||
|
paddingRight: 8,
|
||||||
|
},
|
||||||
|
navBarText: {
|
||||||
|
color: '#fff',
|
||||||
|
fontSize: 18,
|
||||||
|
},
|
||||||
|
navBarTitleText: {
|
||||||
|
fontWeight: '500',
|
||||||
|
},
|
||||||
|
navScene: {
|
||||||
|
top: TotalNavHeight,
|
||||||
|
},
|
||||||
listItem: {
|
listItem: {
|
||||||
borderColor: "#c8c7cc",
|
borderColor: '#c8c7cc',
|
||||||
borderBottomWidth: 0.5,
|
borderBottomWidth: 0.5,
|
||||||
alignItems: 'stretch',
|
alignItems: 'stretch',
|
||||||
alignSelf: 'stretch',
|
alignSelf: 'stretch',
|
||||||
|
justifyContent: 'center',
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
flex: 1,
|
flex: 1,
|
||||||
height: 44,
|
height: 44,
|
||||||
@ -34,20 +71,26 @@ module.exports = React.StyleSheet.create({
|
|||||||
listItemCheckbox: {
|
listItemCheckbox: {
|
||||||
borderColor: '#ccc',
|
borderColor: '#ccc',
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
textAlign: 'center',
|
|
||||||
width: 16,
|
width: 16,
|
||||||
height: 16,
|
height: 16,
|
||||||
lineHeight: 14,
|
},
|
||||||
|
listItemCheckboxText: {
|
||||||
|
width: 14,
|
||||||
|
height: 14,
|
||||||
|
fontSize: iOS ? 14 : 10,
|
||||||
|
textAlign: 'center',
|
||||||
},
|
},
|
||||||
listItemCount: {
|
listItemCount: {
|
||||||
borderColor: '#ccc',
|
borderColor: '#ccc',
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
borderRadius: 8,
|
borderRadius: 8,
|
||||||
textAlign: 'center',
|
|
||||||
fontSize: 12,
|
|
||||||
width: 24,
|
width: 24,
|
||||||
height: 18,
|
height: 18,
|
||||||
lineHeight: 16,
|
},
|
||||||
|
listItemCountText: {
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
fontSize: iOS ? 12 : 11,
|
||||||
|
textAlign: 'center',
|
||||||
},
|
},
|
||||||
listItemInput: {
|
listItemInput: {
|
||||||
fontFamily: 'System',
|
fontFamily: 'System',
|
||||||
@ -56,16 +99,17 @@ module.exports = React.StyleSheet.create({
|
|||||||
flex: 1,
|
flex: 1,
|
||||||
},
|
},
|
||||||
listItemText: {
|
listItemText: {
|
||||||
|
alignSelf: 'center',
|
||||||
fontFamily: 'System',
|
fontFamily: 'System',
|
||||||
fontSize: 15,
|
fontSize: 15,
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
flex: 1,
|
flex: 1,
|
||||||
lineHeight: 30,
|
|
||||||
},
|
},
|
||||||
listItemTextSpecial: {
|
listItemTextSpecial: {
|
||||||
fontStyle: 'italic',
|
fontStyle: 'italic',
|
||||||
},
|
},
|
||||||
listItemDelete: {
|
listItemDelete: {
|
||||||
|
backgroundColor: 'transparent',
|
||||||
paddingLeft: 12,
|
paddingLeft: 12,
|
||||||
paddingRight: 12,
|
paddingRight: 12,
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
|
@ -10,7 +10,13 @@ const TodoListView = require('./todo-listview');
|
|||||||
const realm = require('./realm');
|
const realm = require('./realm');
|
||||||
const styles = require('./styles');
|
const styles = require('./styles');
|
||||||
|
|
||||||
const { NavigatorIOS } = React;
|
const {
|
||||||
|
Navigator,
|
||||||
|
StatusBarIOS,
|
||||||
|
Text,
|
||||||
|
TouchableOpacity,
|
||||||
|
View,
|
||||||
|
} = React;
|
||||||
|
|
||||||
class TodoApp extends React.Component {
|
class TodoApp extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@ -25,6 +31,12 @@ class TodoApp extends React.Component {
|
|||||||
|
|
||||||
// This is a Results object, which will live-update.
|
// This is a Results object, which will live-update.
|
||||||
this.todoLists = todoLists;
|
this.todoLists = todoLists;
|
||||||
|
|
||||||
|
// Bind all the methods that we will be passing as props.
|
||||||
|
this.renderScene = this.renderScene.bind(this);
|
||||||
|
this._addNewTodoList = this._addNewTodoList.bind(this);
|
||||||
|
this._onPressTodoList = this._onPressTodoList.bind(this);
|
||||||
|
|
||||||
this.state = {};
|
this.state = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,6 +45,12 @@ class TodoApp extends React.Component {
|
|||||||
return refs.listItemView || refs.listView;
|
return refs.listItemView || refs.listView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentWillMount() {
|
||||||
|
if (StatusBarIOS) {
|
||||||
|
StatusBarIOS.setStyle('light-content');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let extraItems = [
|
let extraItems = [
|
||||||
{name: 'Complete', items: realm.objects('Todo', 'done = true')},
|
{name: 'Complete', items: realm.objects('Todo', 'done = true')},
|
||||||
@ -46,16 +64,31 @@ class TodoApp extends React.Component {
|
|||||||
ref: 'listView',
|
ref: 'listView',
|
||||||
items: this.todoLists,
|
items: this.todoLists,
|
||||||
extraItems: extraItems,
|
extraItems: extraItems,
|
||||||
onPressItem: (list) => this._onPressTodoList(list),
|
onPressItem: this._onPressTodoList,
|
||||||
},
|
},
|
||||||
backButtonTitle: 'Lists',
|
backButtonTitle: 'Lists',
|
||||||
rightButtonTitle: 'Add',
|
rightButtonTitle: 'Add',
|
||||||
onRightButtonPress: () => this._addNewTodoList(),
|
onRightButtonPress: this._addNewTodoList,
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
let navigationBar = (
|
||||||
<NavigatorIOS ref="nav" initialRoute={route} style={styles.navigator} />
|
<Navigator.NavigationBar routeMapper={RouteMapper} style={styles.navBar} />
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Navigator
|
||||||
|
ref="nav"
|
||||||
|
initialRoute={route}
|
||||||
|
navigationBar={navigationBar}
|
||||||
|
renderScene={this.renderScene}
|
||||||
|
sceneStyle={styles.navScene}
|
||||||
|
style={styles.navigator}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderScene(route) {
|
||||||
|
return <route.component {...route.passProps} />
|
||||||
}
|
}
|
||||||
|
|
||||||
_addNewTodoItem(list) {
|
_addNewTodoItem(list) {
|
||||||
@ -125,4 +158,50 @@ class TodoApp extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const RouteMapper = {
|
||||||
|
LeftButton(route, navigator, index, navState) {
|
||||||
|
if (index == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
let prevRoute = navState.routeStack[index - 1];
|
||||||
|
return (
|
||||||
|
<TouchableOpacity onPress={() => navigator.pop()}>
|
||||||
|
<View style={[styles.navBarView, styles.navBarLeftButton]}>
|
||||||
|
<Text style={styles.navBarLeftArrow}>‹</Text>
|
||||||
|
<Text style={styles.navBarText}>
|
||||||
|
{prevRoute.backButtonTitle || prevRoute.title || 'Back'}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</TouchableOpacity>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
RightButton(route) {
|
||||||
|
if (!route.rightButtonTitle) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TouchableOpacity onPress={route.onRightButtonPress}>
|
||||||
|
<View style={[styles.navBarView, styles.navBarRightButton]}>
|
||||||
|
<Text style={styles.navBarText}>
|
||||||
|
{route.rightButtonTitle}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</TouchableOpacity>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
Title(route) {
|
||||||
|
return (
|
||||||
|
<View style={styles.navBarView}>
|
||||||
|
<Text style={[styles.navBarText, styles.navBarTitleText]}>
|
||||||
|
{route.title}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = TodoApp;
|
module.exports = TodoApp;
|
||||||
|
@ -38,10 +38,12 @@ class TodoItem extends TodoListItem {
|
|||||||
return (
|
return (
|
||||||
<TouchableWithoutFeedback onPress={this._onPressCheckbox}>
|
<TouchableWithoutFeedback onPress={this._onPressCheckbox}>
|
||||||
<View style={styles.listItemLeftSide}>
|
<View style={styles.listItemLeftSide}>
|
||||||
<Text style={styles.listItemCheckbox}>
|
<View style={styles.listItemCheckbox}>
|
||||||
|
<Text style={styles.listItemCheckboxText}>
|
||||||
{this.done ? '✓' : ''}
|
{this.done ? '✓' : ''}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
|
</View>
|
||||||
</TouchableWithoutFeedback>
|
</TouchableWithoutFeedback>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,15 @@ const React = require('react-native');
|
|||||||
const realm = require('./realm');
|
const realm = require('./realm');
|
||||||
const styles = require('./styles');
|
const styles = require('./styles');
|
||||||
|
|
||||||
const { Text, TextInput, TouchableWithoutFeedback, View } = React;
|
const {
|
||||||
|
Platform,
|
||||||
|
Text,
|
||||||
|
TextInput,
|
||||||
|
TouchableWithoutFeedback,
|
||||||
|
View,
|
||||||
|
} = React;
|
||||||
|
|
||||||
|
const iOS = (Platform.OS == 'ios');
|
||||||
|
|
||||||
class TodoListItem extends React.Component {
|
class TodoListItem extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@ -90,7 +98,7 @@ class TodoListItem extends React.Component {
|
|||||||
return (
|
return (
|
||||||
<TouchableWithoutFeedback onPress={this.props.onPressDelete}>
|
<TouchableWithoutFeedback onPress={this.props.onPressDelete}>
|
||||||
<View style={styles.listItemDelete}>
|
<View style={styles.listItemDelete}>
|
||||||
<Text>𐄂</Text>
|
<Text>{iOS ? '𐄂' : '×'}</Text>
|
||||||
</View>
|
</View>
|
||||||
</TouchableWithoutFeedback>
|
</TouchableWithoutFeedback>
|
||||||
);
|
);
|
||||||
|
@ -162,10 +162,12 @@ class TodoListExtraItem extends TodoListItem {
|
|||||||
renderLeftSide() {
|
renderLeftSide() {
|
||||||
return (
|
return (
|
||||||
<View style={styles.listItemLeftSide}>
|
<View style={styles.listItemLeftSide}>
|
||||||
<Text style={styles.listItemCount}>
|
<View style={styles.listItemCount}>
|
||||||
|
<Text style={styles.listItemCountText}>
|
||||||
{this.props.item.items.length}
|
{this.props.item.items.length}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
examples/ReactExample/index.android.js
Normal file
10
examples/ReactExample/index.android.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
/* Copyright 2015 Realm Inc - All Rights Reserved
|
||||||
|
* Proprietary and Confidential
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const React = require('react-native');
|
||||||
|
const TodoApp = require('./components/todo-app');
|
||||||
|
|
||||||
|
React.AppRegistry.registerComponent('ReactExample', () => TodoApp);
|
14
examples/ReactExample/run-android.sh
Executable file
14
examples/ReactExample/run-android.sh
Executable file
@ -0,0 +1,14 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -o pipefail
|
||||||
|
set -e
|
||||||
|
|
||||||
|
PATH="/opt/android-sdk-linux/platform-tools:$PATH"
|
||||||
|
|
||||||
|
rm -rf node_modules/realm
|
||||||
|
npm install realm
|
||||||
|
|
||||||
|
adb reverse tcp:8081 tcp:8081
|
||||||
|
adb forward tcp:8082 tcp:8082
|
||||||
|
|
||||||
|
react-native run-android
|
1
lib/.npmignore
Normal file
1
lib/.npmignore
Normal file
@ -0,0 +1 @@
|
|||||||
|
*.orig
|
@ -4,11 +4,16 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"files": [
|
"files": [
|
||||||
|
"android",
|
||||||
"lib",
|
"lib",
|
||||||
"react-native",
|
"react-native",
|
||||||
"scripts",
|
"scripts",
|
||||||
"src",
|
"src",
|
||||||
"vendor",
|
"vendor",
|
||||||
"RealmJS.xcodeproj"
|
"RealmJS.xcodeproj"
|
||||||
]
|
],
|
||||||
|
"scripts": {
|
||||||
|
"test": "scripts/test.sh",
|
||||||
|
"prepublish": "scripts/prepublish.sh"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
3
react-native/.npmignore
Normal file
3
react-native/.npmignore
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
android/
|
||||||
|
|
||||||
|
*.orig
|
1
react-native/android/.gitignore
vendored
Normal file
1
react-native/android/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
downloads/
|
5
react-native/android/.npmignore
Normal file
5
react-native/android/.npmignore
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
build/
|
||||||
|
|
||||||
|
.idea
|
||||||
|
.gradle
|
||||||
|
local.properties
|
289
react-native/android/build.gradle
Normal file
289
react-native/android/build.gradle
Normal file
@ -0,0 +1,289 @@
|
|||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath 'com.android.tools.build:gradle:1.3.1'
|
||||||
|
classpath 'de.undercouch:gradle-download-task:1.2'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allprojects {
|
||||||
|
repositories {
|
||||||
|
mavenLocal()
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
apply plugin: 'com.android.library'
|
||||||
|
apply plugin: 'maven'
|
||||||
|
apply plugin: 'signing'
|
||||||
|
apply plugin: 'de.undercouch.download'
|
||||||
|
|
||||||
|
import de.undercouch.gradle.tasks.download.Download
|
||||||
|
import org.apache.tools.ant.taskdefs.condition.Os
|
||||||
|
import org.apache.tools.ant.filters.ReplaceTokens
|
||||||
|
|
||||||
|
// We download various C++ open-source dependencies into downloads.
|
||||||
|
// We then copy both the downloaded code and our custom makefiles and headers into third-party-ndk.
|
||||||
|
// After that we build native code from src/main/jni with module path pointing at third-party-ndk.
|
||||||
|
|
||||||
|
def downloadsDir = new File("$projectDir/downloads")
|
||||||
|
def jscDownloadDir = new File("$projectDir/src/main/jni/jsc")
|
||||||
|
def coreDownloadDir = new File("$projectDir/src/main/jni")
|
||||||
|
ext.coreVersion = '0.95.6'
|
||||||
|
def publishDir = new File("$projectDir/../../android/")
|
||||||
|
|
||||||
|
|
||||||
|
task createNativeDepsDirectories {
|
||||||
|
downloadsDir.mkdirs()
|
||||||
|
}
|
||||||
|
|
||||||
|
task downloadJSCHeaders(type: Download) {
|
||||||
|
def jscAPIBaseURL = 'https://svn.webkit.org/repository/webkit/!svn/bc/174650/trunk/Source/JavaScriptCore/API/'
|
||||||
|
def jscHeaderFiles = ['JSBase.h', 'JSContextRef.h', 'JSObjectRef.h', 'JSRetainPtr.h', 'JSStringRef.h', 'JSValueRef.h', 'WebKitAvailability.h']
|
||||||
|
|
||||||
|
def output = new File(jscDownloadDir, 'JavaScriptCore')
|
||||||
|
output.mkdirs()
|
||||||
|
src(jscHeaderFiles.collect { headerName -> "$jscAPIBaseURL$headerName" })
|
||||||
|
onlyIfNewer true
|
||||||
|
overwrite false
|
||||||
|
dest output
|
||||||
|
}
|
||||||
|
|
||||||
|
task downloadRealmCore(type: Download) {
|
||||||
|
src "http://static.realm.io/downloads/core/realm-core-android-${project.coreVersion}.tar.gz"
|
||||||
|
onlyIfNewer true
|
||||||
|
overwrite false
|
||||||
|
dest new File(downloadsDir, "realm-core-android-${project.coreVersion}.tar.gz")
|
||||||
|
}
|
||||||
|
|
||||||
|
task prepareRealmCore(dependsOn: downloadRealmCore, type:Copy) {
|
||||||
|
from tarTree(downloadRealmCore.dest)
|
||||||
|
into "$coreDownloadDir/core"
|
||||||
|
//Fixing Core file naming 'arm-*' to 'armeabi-*'
|
||||||
|
doLast {
|
||||||
|
exec {
|
||||||
|
workingDir = "$coreDownloadDir/core"
|
||||||
|
commandLine = [
|
||||||
|
"bash",
|
||||||
|
"-c",
|
||||||
|
"find . -name \"*-arm-*\" -exec sh -c \"echo {} | sed -e s/arm/armeabi/g | xargs mv {} \" \\;"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def getNdkBuildName() {
|
||||||
|
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
|
||||||
|
return "ndk-build.cmd"
|
||||||
|
} else {
|
||||||
|
return "ndk-build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def findNdkBuildFullPath() {
|
||||||
|
// we allow to provide full path to ndk-build tool
|
||||||
|
if (hasProperty('ndk.command')) {
|
||||||
|
return property('ndk.command')
|
||||||
|
}
|
||||||
|
// or just a path to the containing directory
|
||||||
|
if (hasProperty('ndk.path')) {
|
||||||
|
def ndkDir = property('ndk.path')
|
||||||
|
return new File(ndkDir, getNdkBuildName()).getAbsolutePath()
|
||||||
|
}
|
||||||
|
if (System.getenv('ANDROID_NDK') != null) {
|
||||||
|
def ndkDir = System.getenv('ANDROID_NDK')
|
||||||
|
return new File(ndkDir, getNdkBuildName()).getAbsolutePath()
|
||||||
|
}
|
||||||
|
def ndkDir = android.hasProperty('plugin') ? android.plugin.ndkFolder :
|
||||||
|
plugins.getPlugin('com.android.library').sdkHandler.getNdkFolder()
|
||||||
|
if (ndkDir) {
|
||||||
|
return new File(ndkDir, getNdkBuildName()).getAbsolutePath()
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
def getNdkBuildFullPath() {
|
||||||
|
def ndkBuildFullPath = findNdkBuildFullPath()
|
||||||
|
if (ndkBuildFullPath == null) {
|
||||||
|
throw new GradleScriptException(
|
||||||
|
"ndk-build binary cannot be found, check if you've set " +
|
||||||
|
"\$ANDROID_NDK environment variable correctly or if ndk.dir is " +
|
||||||
|
"setup in local.properties",
|
||||||
|
null)
|
||||||
|
}
|
||||||
|
if (!new File(ndkBuildFullPath).canExecute()) {
|
||||||
|
throw new GradleScriptException(
|
||||||
|
"ndk-build binary " + ndkBuildFullPath + " doesn't exist or isn't executable.\n" +
|
||||||
|
"Check that the \$ANDROID_NDK environment variable, or ndk.dir in local.proerties, is set correctly.\n" +
|
||||||
|
"(On Windows, make sure you escape backslashes in local.properties or use forward slashes, e.g. C:\\\\ndk or C:/ndk rather than C:\\ndk)",
|
||||||
|
null)
|
||||||
|
}
|
||||||
|
return ndkBuildFullPath
|
||||||
|
}
|
||||||
|
|
||||||
|
task buildReactNdkLib(dependsOn: [downloadJSCHeaders,prepareRealmCore], type: Exec) {
|
||||||
|
inputs.file('src/main/jni')
|
||||||
|
outputs.dir("$buildDir/realm-react-ndk/all")
|
||||||
|
commandLine getNdkBuildFullPath(),
|
||||||
|
'NDK_PROJECT_PATH=null',
|
||||||
|
"NDK_APPLICATION_MK=$projectDir/src/main/jni/Application.mk",
|
||||||
|
'NDK_OUT=' + temporaryDir,
|
||||||
|
"NDK_LIBS_OUT=$buildDir/realm-react-ndk/all",
|
||||||
|
'-C', file('src/main/jni').absolutePath,
|
||||||
|
'NDK_LOG=1',
|
||||||
|
'NDK_DEBUG=' + (DEBUG_BUILD.toBoolean() ? '1' : '0'),
|
||||||
|
'--jobs', Runtime.runtime.availableProcessors(),
|
||||||
|
'V=1'
|
||||||
|
}
|
||||||
|
|
||||||
|
task cleanReactNdkLib(type: Exec) {
|
||||||
|
commandLine getNdkBuildFullPath(),
|
||||||
|
'-C', file('src/main/jni').absolutePath,
|
||||||
|
'clean'
|
||||||
|
}
|
||||||
|
|
||||||
|
task packageReactNdkLibs(dependsOn: buildReactNdkLib, type: Copy) {
|
||||||
|
from "$buildDir/realm-react-ndk/all"
|
||||||
|
exclude '**/libjsc.so'
|
||||||
|
exclude '**/gdbserver'
|
||||||
|
exclude '**/gdb.setup'
|
||||||
|
into "$buildDir/realm-react-ndk/exported"
|
||||||
|
}
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion 23
|
||||||
|
buildToolsVersion "23.0.1"
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
minSdkVersion 16
|
||||||
|
targetSdkVersion 23
|
||||||
|
versionCode 1
|
||||||
|
versionName "1.0"
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceSets.main {
|
||||||
|
jni.srcDirs = []
|
||||||
|
jniLibs.srcDir "$buildDir/realm-react-ndk/exported"
|
||||||
|
res.srcDirs = ['src/main/res/devsupport', 'src/main/res/shell']
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType(JavaCompile) {
|
||||||
|
compileTask -> compileTask.dependsOn packageReactNdkLibs
|
||||||
|
}
|
||||||
|
|
||||||
|
clean.dependsOn cleanReactNdkLib
|
||||||
|
|
||||||
|
lintOptions {
|
||||||
|
abortOnError false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task publishAndroid(dependsOn: packageReactNdkLibs, type: Copy) {
|
||||||
|
// Copy task can only have one top level
|
||||||
|
into "$publishDir"
|
||||||
|
|
||||||
|
// copy java source
|
||||||
|
into ('/src/main') {
|
||||||
|
from "$projectDir/src/main"
|
||||||
|
exclude '**/jni/**'
|
||||||
|
}
|
||||||
|
|
||||||
|
// add compiled shared object
|
||||||
|
into ('/src/main/jniLibs') {
|
||||||
|
from "$buildDir/realm-react-ndk/exported/"
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy gradle wrapper files
|
||||||
|
FileTree gradleWrapper = fileTree(projectDir).include('gradlew*').include('gradle/**')
|
||||||
|
into ('/') {
|
||||||
|
from gradleWrapper
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy and rename template build.gradle
|
||||||
|
|
||||||
|
into ('/') {
|
||||||
|
from "$projectDir/publish_android_template"
|
||||||
|
rename { String fileName ->
|
||||||
|
'build.gradle'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// publishing into maven local
|
||||||
|
|
||||||
|
def configureRealmReactNativePom(def pom) {
|
||||||
|
pom.project {
|
||||||
|
name POM_NAME
|
||||||
|
artifactId POM_ARTIFACT_ID
|
||||||
|
packaging POM_PACKAGING
|
||||||
|
description POM_DESCRIPTION
|
||||||
|
url 'https://github.com/realm/realm-js'
|
||||||
|
|
||||||
|
issueManagement {
|
||||||
|
system 'github'
|
||||||
|
url 'https://github.com/realm/realm-js/issues'
|
||||||
|
}
|
||||||
|
|
||||||
|
scm {
|
||||||
|
url 'scm:https://github.com/realm/realm-js'
|
||||||
|
connection 'scm:git@github.com:realm/realm-js.git'
|
||||||
|
developerConnection 'scm:git@github.com:realm/realm-js.git'
|
||||||
|
}
|
||||||
|
|
||||||
|
licenses {
|
||||||
|
license {
|
||||||
|
name 'The Apache Software License, Version 2.0'
|
||||||
|
url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
|
||||||
|
distribution 'repo'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
afterEvaluate { project ->
|
||||||
|
task androidSourcesJar(type: Jar) {
|
||||||
|
classifier = 'sources'
|
||||||
|
from android.sourceSets.main.java.srcDirs
|
||||||
|
include '**/*.java'
|
||||||
|
}
|
||||||
|
|
||||||
|
android.libraryVariants.all { variant ->
|
||||||
|
def name = variant.name.capitalize()
|
||||||
|
task "jar${name}"(type: Jar, dependsOn: variant.javaCompile) {
|
||||||
|
from variant.javaCompile.destinationDir
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
artifacts {
|
||||||
|
archives androidSourcesJar
|
||||||
|
}
|
||||||
|
|
||||||
|
version = VERSION_NAME
|
||||||
|
group = GROUP
|
||||||
|
|
||||||
|
signing {
|
||||||
|
required { false }
|
||||||
|
sign configurations.archives
|
||||||
|
}
|
||||||
|
|
||||||
|
task installArchives(type: Upload) {
|
||||||
|
configuration = configurations.archives
|
||||||
|
repositories.mavenDeployer {
|
||||||
|
beforeDeployment {
|
||||||
|
MavenDeployment deployment -> signing.signPom(deployment)
|
||||||
|
}
|
||||||
|
|
||||||
|
repository url: "file://${System.properties['user.home']}/.m2/repository"
|
||||||
|
configureRealmReactNativePom pom
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
|
compile 'org.nanohttpd:nanohttpd:2.2.0'
|
||||||
|
compile 'com.facebook.react:react-native:0.18.0'
|
||||||
|
}
|
9
react-native/android/gradle.properties
Normal file
9
react-native/android/gradle.properties
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
VERSION_NAME=0.0.1-SNAPSHOT
|
||||||
|
GROUP=io.realm.react
|
||||||
|
|
||||||
|
POM_NAME=RealmReactAndroid
|
||||||
|
POM_ARTIFACT_ID=realm-react-native
|
||||||
|
POM_PACKAGING=aar
|
||||||
|
POM_DESCRIPTION=Android Realm React Native module. Realm is a mobile database: a replacement for SQLite & ORMs
|
||||||
|
DEBUG_BUILD=true
|
||||||
|
android.useDeprecatedNdk=true
|
BIN
react-native/android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
react-native/android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
6
react-native/android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
6
react-native/android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#Wed Feb 10 01:35:36 GMT 2016
|
||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-bin.zip
|
164
react-native/android/gradlew
vendored
Executable file
164
react-native/android/gradlew
vendored
Executable file
@ -0,0 +1,164 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
##
|
||||||
|
## Gradle start up script for UN*X
|
||||||
|
##
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS=""
|
||||||
|
|
||||||
|
APP_NAME="Gradle"
|
||||||
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
MAX_FD="maximum"
|
||||||
|
|
||||||
|
warn ( ) {
|
||||||
|
echo "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
die ( ) {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# OS specific support (must be 'true' or 'false').
|
||||||
|
cygwin=false
|
||||||
|
msys=false
|
||||||
|
darwin=false
|
||||||
|
case "`uname`" in
|
||||||
|
CYGWIN* )
|
||||||
|
cygwin=true
|
||||||
|
;;
|
||||||
|
Darwin* )
|
||||||
|
darwin=true
|
||||||
|
;;
|
||||||
|
MINGW* )
|
||||||
|
msys=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# For Cygwin, ensure paths are in UNIX format before anything is touched.
|
||||||
|
if $cygwin ; then
|
||||||
|
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
PRG="$0"
|
||||||
|
# Need this for relative symlinks.
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG=`dirname "$PRG"`"/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
SAVED="`pwd`"
|
||||||
|
cd "`dirname \"$PRG\"`/" >&-
|
||||||
|
APP_HOME="`pwd -P`"
|
||||||
|
cd "$SAVED" >&-
|
||||||
|
|
||||||
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
# Determine the Java command to use to start the JVM.
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
fi
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD="java"
|
||||||
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increase the maximum file descriptors if we can.
|
||||||
|
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||||
|
MAX_FD_LIMIT=`ulimit -H -n`
|
||||||
|
if [ $? -eq 0 ] ; then
|
||||||
|
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||||
|
MAX_FD="$MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
ulimit -n $MAX_FD
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Darwin, add options to specify how the application appears in the dock
|
||||||
|
if $darwin; then
|
||||||
|
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin, switch paths to Windows format before running java
|
||||||
|
if $cygwin ; then
|
||||||
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
|
|
||||||
|
# We build the pattern for arguments to be converted via cygpath
|
||||||
|
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||||
|
SEP=""
|
||||||
|
for dir in $ROOTDIRSRAW ; do
|
||||||
|
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||||
|
SEP="|"
|
||||||
|
done
|
||||||
|
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||||
|
# Add a user-defined pattern to the cygpath arguments
|
||||||
|
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||||
|
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||||
|
fi
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
i=0
|
||||||
|
for arg in "$@" ; do
|
||||||
|
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||||
|
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||||
|
|
||||||
|
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||||
|
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||||
|
else
|
||||||
|
eval `echo args$i`="\"$arg\""
|
||||||
|
fi
|
||||||
|
i=$((i+1))
|
||||||
|
done
|
||||||
|
case $i in
|
||||||
|
(0) set -- ;;
|
||||||
|
(1) set -- "$args0" ;;
|
||||||
|
(2) set -- "$args0" "$args1" ;;
|
||||||
|
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
|
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
|
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
|
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
|
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
|
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
|
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||||
|
function splitJvmOpts() {
|
||||||
|
JVM_OPTS=("$@")
|
||||||
|
}
|
||||||
|
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||||
|
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||||
|
|
||||||
|
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
90
react-native/android/gradlew.bat
vendored
Normal file
90
react-native/android/gradlew.bat
vendored
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
@if "%DEBUG%" == "" @echo off
|
||||||
|
@rem ##########################################################################
|
||||||
|
@rem
|
||||||
|
@rem Gradle startup script for Windows
|
||||||
|
@rem
|
||||||
|
@rem ##########################################################################
|
||||||
|
|
||||||
|
@rem Set local scope for the variables with windows NT shell
|
||||||
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
set DEFAULT_JVM_OPTS=
|
||||||
|
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
|
set APP_BASE_NAME=%~n0
|
||||||
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Find java.exe
|
||||||
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
|
set JAVA_EXE=java.exe
|
||||||
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
|
if "%ERRORLEVEL%" == "0" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:findJavaFromJavaHome
|
||||||
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
|
if exist "%JAVA_EXE%" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:init
|
||||||
|
@rem Get command-line arguments, handling Windowz variants
|
||||||
|
|
||||||
|
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||||
|
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||||
|
|
||||||
|
:win9xME_args
|
||||||
|
@rem Slurp the command line arguments.
|
||||||
|
set CMD_LINE_ARGS=
|
||||||
|
set _SKIP=2
|
||||||
|
|
||||||
|
:win9xME_args_slurp
|
||||||
|
if "x%~1" == "x" goto execute
|
||||||
|
|
||||||
|
set CMD_LINE_ARGS=%*
|
||||||
|
goto execute
|
||||||
|
|
||||||
|
:4NT_args
|
||||||
|
@rem Get arguments from the 4NT Shell from JP Software
|
||||||
|
set CMD_LINE_ARGS=%$
|
||||||
|
|
||||||
|
:execute
|
||||||
|
@rem Setup the command line
|
||||||
|
|
||||||
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
@rem Execute Gradle
|
||||||
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||||
|
|
||||||
|
:end
|
||||||
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||||
|
|
||||||
|
:fail
|
||||||
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
|
rem the _cmd.exe /c_ return code!
|
||||||
|
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||||
|
exit /b 1
|
||||||
|
|
||||||
|
:mainEnd
|
||||||
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
||||||
|
:omega
|
33
react-native/android/publish_android_template
Normal file
33
react-native/android/publish_android_template
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath 'com.android.tools.build:gradle:1.3.1'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allprojects {
|
||||||
|
repositories {
|
||||||
|
mavenLocal()
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
apply plugin: 'com.android.library'
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion 23
|
||||||
|
buildToolsVersion "23.0.1"
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
minSdkVersion 16
|
||||||
|
targetSdkVersion 22
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
|
compile 'org.nanohttpd:nanohttpd:2.2.0'
|
||||||
|
compile 'com.facebook.react:react-native:0.18.0'
|
||||||
|
}
|
3
react-native/android/src/main/AndroidManifest.xml
Normal file
3
react-native/android/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="io.realm.react">
|
||||||
|
<application />
|
||||||
|
</manifest>
|
@ -0,0 +1,129 @@
|
|||||||
|
package io.realm.react;
|
||||||
|
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.facebook.react.bridge.ReactApplicationContext;
|
||||||
|
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||||
|
import com.facebook.soloader.SoLoader;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.IllegalStateException;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
|
||||||
|
import fi.iki.elonen.NanoHTTPD;
|
||||||
|
|
||||||
|
public class RealmReactModule extends ReactContextBaseJavaModule {
|
||||||
|
private static final int DEFAULT_PORT = 8082;
|
||||||
|
|
||||||
|
private AndroidWebServer webServer;
|
||||||
|
private Handler handler = new Handler(Looper.getMainLooper());
|
||||||
|
|
||||||
|
static {
|
||||||
|
SoLoader.loadLibrary("realmreact");
|
||||||
|
}
|
||||||
|
|
||||||
|
public RealmReactModule(ReactApplicationContext reactContext) {
|
||||||
|
super(reactContext);
|
||||||
|
|
||||||
|
String fileDir;
|
||||||
|
try {
|
||||||
|
fileDir = reactContext.getFilesDir().getCanonicalPath();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
setDefaultRealmFileDirectory(fileDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "Realm";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> getConstants() {
|
||||||
|
// FIXME: Only start web server when in Chrome debug mode!
|
||||||
|
startWebServer();
|
||||||
|
return Collections.EMPTY_MAP;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCatalystInstanceDestroy() {
|
||||||
|
stopWebServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startWebServer() {
|
||||||
|
setupChromeDebugModeRealmJsContext();
|
||||||
|
webServer = new AndroidWebServer(DEFAULT_PORT);
|
||||||
|
try {
|
||||||
|
webServer.start();
|
||||||
|
Log.i("Realm", "Starting the debugging WebServer, Host: " + webServer.getHostname() + " Port: " + webServer.getListeningPort());
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stopWebServer() {
|
||||||
|
if (webServer != null) {
|
||||||
|
Log.i("Realm", "Stopping the webserver");
|
||||||
|
webServer.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AndroidWebServer extends NanoHTTPD {
|
||||||
|
public AndroidWebServer(int port) {
|
||||||
|
super(port);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AndroidWebServer(String hostname, int port) {
|
||||||
|
super(hostname, port);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Response serve(IHTTPSession session) {
|
||||||
|
final String cmdUri = session.getUri();
|
||||||
|
final HashMap<String, String> map = new HashMap<String, String>();
|
||||||
|
try {
|
||||||
|
session.parseBody(map);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (ResponseException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
final String json = map.get("postData");
|
||||||
|
final String[] jsonResponse = new String[1];
|
||||||
|
final CountDownLatch latch = new CountDownLatch(1);
|
||||||
|
// Process the command on the UI thread
|
||||||
|
handler.post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
jsonResponse[0] = processChromeDebugCommand(cmdUri, json);
|
||||||
|
latch.countDown();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
latch.await();
|
||||||
|
Response response = newFixedLengthResponse(jsonResponse[0]);
|
||||||
|
response.addHeader("Access-Control-Allow-Origin", "http://localhost:8081");
|
||||||
|
return response;
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fileDir: path of the internal storage of the application
|
||||||
|
private native void setDefaultRealmFileDirectory(String fileDir);
|
||||||
|
|
||||||
|
// responsible for creating the rpcServer that will accept the chrome Websocket command
|
||||||
|
private native long setupChromeDebugModeRealmJsContext();
|
||||||
|
|
||||||
|
// this receives one command from Chrome debug then return the processing we should post back
|
||||||
|
private native String processChromeDebugCommand(String cmd, String args);
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package io.realm.react;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.facebook.react.ReactPackage;
|
||||||
|
import com.facebook.react.bridge.NativeModule;
|
||||||
|
import com.facebook.react.bridge.ReactApplicationContext;
|
||||||
|
import com.facebook.react.bridge.JavaScriptModule;
|
||||||
|
import com.facebook.react.uimanager.ViewManager;
|
||||||
|
|
||||||
|
public class RealmReactPackage implements ReactPackage {
|
||||||
|
@Override
|
||||||
|
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
|
||||||
|
return Collections.<NativeModule>singletonList(new RealmReactModule(reactContext));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Class<? extends JavaScriptModule>> createJSModules() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
1
react-native/android/src/main/jni/.npmignore
Normal file
1
react-native/android/src/main/jni/.npmignore
Normal file
@ -0,0 +1 @@
|
|||||||
|
core/
|
54
react-native/android/src/main/jni/Android.mk
Normal file
54
react-native/android/src/main/jni/Android.mk
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
LOCAL_PATH:= $(call my-dir)
|
||||||
|
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
LOCAL_MODULE := realm-android-$(TARGET_ARCH_ABI)
|
||||||
|
LOCAL_EXPORT_C_INCLUDES := core/include
|
||||||
|
LOCAL_SRC_FILES := core/librealm-android-$(TARGET_ARCH_ABI).a
|
||||||
|
include $(PREBUILT_STATIC_LIBRARY)
|
||||||
|
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
LOCAL_MODULE := libjsc
|
||||||
|
LOCAL_EXPORT_C_INCLUDES := jsc
|
||||||
|
include $(BUILD_SHARED_LIBRARY)
|
||||||
|
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
LOCAL_MODULE := librealmreact
|
||||||
|
|
||||||
|
LOCAL_SRC_FILES := \
|
||||||
|
src/js_list.cpp \
|
||||||
|
src/js_results.cpp \
|
||||||
|
src/js_init.cpp \
|
||||||
|
src/js_realm.cpp \
|
||||||
|
src/js_util.cpp \
|
||||||
|
src/js_object.cpp \
|
||||||
|
src/js_schema.cpp \
|
||||||
|
src/rpc.cpp \
|
||||||
|
src/android/platform.cpp \
|
||||||
|
src/android/io_realm_react_RealmReactModule.cpp \
|
||||||
|
src/android/jsc_override.cpp \
|
||||||
|
src/object-store/index_set.cpp \
|
||||||
|
src/object-store/list.cpp \
|
||||||
|
src/object-store/object_schema.cpp \
|
||||||
|
src/object-store/object_store.cpp \
|
||||||
|
src/object-store/results.cpp \
|
||||||
|
src/object-store/schema.cpp \
|
||||||
|
src/object-store/shared_realm.cpp \
|
||||||
|
src/object-store/parser/parser.cpp \
|
||||||
|
src/object-store/parser/query_builder.cpp \
|
||||||
|
src/object-store/impl/transact_log_handler.cpp \
|
||||||
|
vendor/base64.cpp
|
||||||
|
|
||||||
|
LOCAL_C_INCLUDES := src
|
||||||
|
LOCAL_C_INCLUDES += src/object-store
|
||||||
|
LOCAL_C_INCLUDES += src/object-store/parser
|
||||||
|
LOCAL_C_INCLUDES += vendor
|
||||||
|
LOCAL_C_INCLUDES += vendor/PEGTL
|
||||||
|
LOCAL_C_INCLUDES += $(JAVA_HOME)/include
|
||||||
|
LOCAL_C_INCLUDES += $(JAVA_HOME)/include/darwin
|
||||||
|
LOCAL_C_INCLUDES += core/include
|
||||||
|
|
||||||
|
LOCAL_ALLOW_UNDEFINED_SYMBOLS := true
|
||||||
|
|
||||||
|
LOCAL_STATIC_LIBRARIES := realm-android-$(TARGET_ARCH_ABI)
|
||||||
|
LOCAL_SHARED_LIBRARIES := libjsc
|
||||||
|
include $(BUILD_SHARED_LIBRARY)
|
20
react-native/android/src/main/jni/Application.mk
Normal file
20
react-native/android/src/main/jni/Application.mk
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
APP_BUILD_SCRIPT := Android.mk
|
||||||
|
|
||||||
|
APP_ABI := armeabi-v7a x86
|
||||||
|
APP_PLATFORM := android-9
|
||||||
|
|
||||||
|
APP_MK_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
|
||||||
|
|
||||||
|
NDK_MODULE_PATH := $(APP_MK_DIR)$(HOST_DIRSEP)$(THIRD_PARTY_NDK_DIR)$(HOST_DIRSEP)$(APP_MK_DIR)first-party
|
||||||
|
|
||||||
|
APP_STL := gnustl_static
|
||||||
|
APP_CPPFLAGS := -std=c++14
|
||||||
|
APP_CPPFLAGS += -frtti
|
||||||
|
APP_CPPFLAGS += -fexceptions
|
||||||
|
APP_CPPFLAGS += -DREALM_HAVE_CONFIG
|
||||||
|
|
||||||
|
# Make sure every shared lib includes a .note.gnu.build-id header
|
||||||
|
APP_LDFLAGS := -Wl,--build-id
|
||||||
|
APP_LDFLAGS += -llog
|
||||||
|
|
||||||
|
NDK_TOOLCHAIN_VERSION := 4.9
|
1
react-native/android/src/main/jni/jsc/.gitignore
vendored
Normal file
1
react-native/android/src/main/jni/jsc/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
JavaScriptCore/
|
1
react-native/android/src/main/jni/src
Symbolic link
1
react-native/android/src/main/jni/src
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../../src/
|
1
react-native/android/src/main/jni/vendor
Symbolic link
1
react-native/android/src/main/jni/vendor
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../../vendor
|
1
scripts/.npmignore
Normal file
1
scripts/.npmignore
Normal file
@ -0,0 +1 @@
|
|||||||
|
*.orig
|
@ -3,7 +3,7 @@
|
|||||||
set -e
|
set -e
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
: ${REALM_CORE_VERSION:=0.95.5} # set to "current" to always use the current build
|
: ${REALM_CORE_VERSION:=0.95.6} # set to "current" to always use the current build
|
||||||
|
|
||||||
echo "Downloading dependency: core ${REALM_CORE_VERSION}"
|
echo "Downloading dependency: core ${REALM_CORE_VERSION}"
|
||||||
|
|
||||||
|
13
scripts/prepublish.sh
Executable file
13
scripts/prepublish.sh
Executable file
@ -0,0 +1,13 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
cd "$(dirname "$0")/.."
|
||||||
|
|
||||||
|
if [ -n "$SKIP_ANDROID_BUILD" -o -n "$XCODE_VERSION_ACTUAL" ]; then
|
||||||
|
echo 'Skipped building Android module'
|
||||||
|
else
|
||||||
|
rm -rf android
|
||||||
|
(cd react-native/android && ./gradlew publishAndroid)
|
||||||
|
fi
|
132
scripts/test.sh
132
scripts/test.sh
@ -3,7 +3,17 @@
|
|||||||
set -o pipefail
|
set -o pipefail
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
while pgrep -q Simulator; do
|
TARGET="$1"
|
||||||
|
CONFIGURATION="${2:-"Debug"}"
|
||||||
|
DESTINATION=
|
||||||
|
PATH="/opt/android-sdk-linux/platform-tools:$PATH"
|
||||||
|
SRCROOT=$(cd "$(dirname "$0")/.." && pwd)
|
||||||
|
|
||||||
|
# Start current working directory at the root of the project.
|
||||||
|
cd "$SRCROOT"
|
||||||
|
|
||||||
|
if [[ $TARGET != *-android ]]; then
|
||||||
|
while pgrep -q Simulator; do
|
||||||
# Kill all the current simulator processes as they may be from a
|
# Kill all the current simulator processes as they may be from a
|
||||||
# different Xcode version
|
# different Xcode version
|
||||||
pkill Simulator 2>/dev/null || true
|
pkill Simulator 2>/dev/null || true
|
||||||
@ -11,20 +21,37 @@ while pgrep -q Simulator; do
|
|||||||
pkill -9 Simulator 2>/dev/null || true
|
pkill -9 Simulator 2>/dev/null || true
|
||||||
done
|
done
|
||||||
|
|
||||||
|
DESTINATION="-destination id=$(xcrun simctl list devices | grep -v unavailable | grep -m 1 -o '[0-9A-F\-]\{36\}')"
|
||||||
|
|
||||||
DESTINATION="-destination id=$(xcrun simctl list devices | grep -v unavailable | grep -m 1 -o '[0-9A-F\-]\{36\}')"
|
# Inform the prepublish script to skip building Android modules.
|
||||||
TARGET=$1
|
export SKIP_ANDROID_BUILD=1
|
||||||
CONFIGURATION=${2:-"Debug"}
|
fi
|
||||||
PACKAGER_OUT="packager_out.txt"
|
|
||||||
|
|
||||||
function start_packager()
|
PACKAGER_OUT="$SRCROOT/packager_out.txt"
|
||||||
{
|
LOGCAT_OUT="$SRCROOT/logcat_out.txt"
|
||||||
rm -f $PACKAGER_OUT
|
|
||||||
sh ./node_modules/react-native/packager/packager.sh | tee packager_out.txt &
|
cleanup() {
|
||||||
while :;
|
# Kill all child processes.
|
||||||
do
|
pkill -P $$ || true
|
||||||
if grep -Fxq "React packager ready." packager_out.txt
|
pkill node || true
|
||||||
then
|
rm -f "$PACKAGER_OUT" "$LOGCAT_OUT"
|
||||||
|
}
|
||||||
|
|
||||||
|
open_chrome() {
|
||||||
|
local dir
|
||||||
|
for dir in "$HOME/Applications" "/Applications"; do
|
||||||
|
if [ -d "$dir/Google Chrome.app" ]; then
|
||||||
|
open "$dir/Google Chrome.app"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
start_packager() {
|
||||||
|
./node_modules/react-native/packager/packager.sh | tee "$PACKAGER_OUT" &
|
||||||
|
|
||||||
|
while :; do
|
||||||
|
if grep -Fxq "React packager ready." "$PACKAGER_OUT"; then
|
||||||
break
|
break
|
||||||
else
|
else
|
||||||
echo "Waiting for packager."
|
echo "Waiting for packager."
|
||||||
@ -33,44 +60,87 @@ function start_packager()
|
|||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
function kill_packager()
|
unlock_device() {
|
||||||
{
|
adb shell input keyevent 82
|
||||||
rm -f $PACKAGER_OUT
|
|
||||||
pkill node || true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
kill_packager
|
# Cleanup now and also cleanup when this script exits.
|
||||||
|
cleanup
|
||||||
|
trap cleanup EXIT
|
||||||
|
|
||||||
if [ "$TARGET" = "realmjs" ]; then
|
case "$TARGET" in
|
||||||
|
"realmjs")
|
||||||
xcodebuild -scheme RealmJS -configuration "$CONFIGURATION" -sdk iphonesimulator $DESTINATION build test
|
xcodebuild -scheme RealmJS -configuration "$CONFIGURATION" -sdk iphonesimulator $DESTINATION build test
|
||||||
elif [ "$TARGET" = "react-tests" ]; then
|
;;
|
||||||
|
"react-tests")
|
||||||
pushd tests/react-test-app
|
pushd tests/react-test-app
|
||||||
|
|
||||||
if [ -d ~/Applications/Google\ Chrome.app ]; then
|
|
||||||
open ~/Applications/Google\ Chrome.app
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -f ../../target=node_modules/react_tests_node_modules.zip ]; then
|
if [ -f ../../target=node_modules/react_tests_node_modules.zip ]; then
|
||||||
unzip -q ../../target=node_modules/react_tests_node_modules.zip
|
unzip -q ../../target=node_modules/react_tests_node_modules.zip
|
||||||
fi
|
fi
|
||||||
|
|
||||||
npm update react-native
|
npm update react-native
|
||||||
|
open_chrome
|
||||||
start_packager
|
start_packager
|
||||||
popd
|
popd
|
||||||
|
|
||||||
xcodebuild -scheme RealmReact -configuration "$CONFIGURATION" -sdk iphonesimulator $DESTINATION build test
|
xcodebuild -scheme RealmReact -configuration "$CONFIGURATION" -sdk iphonesimulator $DESTINATION build test
|
||||||
elif [ "$TARGET" = "react-example" ]; then
|
;;
|
||||||
|
"react-example")
|
||||||
pushd examples/ReactExample
|
pushd examples/ReactExample
|
||||||
|
|
||||||
if [ -f ../../target=node_modules/react_example_node_modules.zip ]; then
|
if [ -f ../../target=node_modules/react_example_node_modules.zip ]; then
|
||||||
unzip -q ../../target=node_modules/react_example_node_modules.zip
|
unzip -q ../../target=node_modules/react_example_node_modules.zip
|
||||||
fi
|
fi
|
||||||
|
|
||||||
npm update react-native
|
npm update react-native
|
||||||
start_packager
|
start_packager
|
||||||
|
|
||||||
cd ios
|
pushd ios
|
||||||
xcodebuild -scheme ReactExample -configuration "$CONFIGURATION" -sdk iphonesimulator build $DESTINATION
|
xcodebuild -scheme ReactExample -configuration "$CONFIGURATION" -sdk iphonesimulator build $DESTINATION
|
||||||
popd
|
;;
|
||||||
else
|
"react-tests-android")
|
||||||
echo "Invalid target '${TARGET}'"
|
if [[ $CONFIGURATION == 'Debug' ]]; then
|
||||||
fi
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
kill_packager
|
[ -s "${HOME}/.nvm/nvm.sh" ] && . "${HOME}/.nvm/nvm.sh"
|
||||||
|
nvm use 5.4.0 || true
|
||||||
|
|
||||||
|
pushd react-native/android
|
||||||
|
./gradlew installarchives
|
||||||
|
popd
|
||||||
|
|
||||||
|
pushd tests/react-test-app
|
||||||
|
|
||||||
|
npm install
|
||||||
|
open_chrome
|
||||||
|
start_packager
|
||||||
|
./run-android.sh
|
||||||
|
|
||||||
|
# Despite the docs claiming -c to work, it doesn't, so `-T 1` alleviates that.
|
||||||
|
adb logcat -c
|
||||||
|
adb logcat -T 1 | tee "$LOGCAT_OUT" &
|
||||||
|
|
||||||
|
while :; do
|
||||||
|
if grep -q "__REALM_REACT_ANDROID_TESTS_COMPLETED__" "$LOGCAT_OUT"; then
|
||||||
|
break
|
||||||
|
else
|
||||||
|
echo "Waiting for tests."
|
||||||
|
sleep 2
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
rm -f tests.xml
|
||||||
|
adb pull /sdcard/tests.xml .
|
||||||
|
|
||||||
|
# Stop running child processes before printing results.
|
||||||
|
cleanup
|
||||||
|
echo "********* TESTS COMPLETED *********";
|
||||||
|
echo "********* File location: $(pwd)/tests.xml *********";
|
||||||
|
cat tests.xml
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Invalid target '${TARGET}'"
|
||||||
|
exit 1
|
||||||
|
esac
|
||||||
|
1
src/.npmignore
Normal file
1
src/.npmignore
Normal file
@ -0,0 +1 @@
|
|||||||
|
*.orig
|
49
src/android/io_realm_react_RealmReactModule.cpp
Normal file
49
src/android/io_realm_react_RealmReactModule.cpp
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/* Copyright 2016 Realm Inc - All Rights Reserved
|
||||||
|
* Proprietary and Confidential
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <jni.h>
|
||||||
|
#include <android/log.h>
|
||||||
|
|
||||||
|
#include "io_realm_react_RealmReactModule.h"
|
||||||
|
#include "rpc.hpp"
|
||||||
|
#include "platform.hpp"
|
||||||
|
|
||||||
|
static realm_js::RPCServer *s_rpc_server;
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL Java_io_realm_react_RealmReactModule_setDefaultRealmFileDirectory
|
||||||
|
(JNIEnv *env, jclass, jstring fileDir)
|
||||||
|
{
|
||||||
|
__android_log_print(ANDROID_LOG_VERBOSE, "JSRealm", "setDefaultRealmFileDirectory");
|
||||||
|
|
||||||
|
// Setting the internal storage path for the application
|
||||||
|
const char* strFileDir = env->GetStringUTFChars(fileDir, NULL);
|
||||||
|
realm::set_default_realm_file_directory(strFileDir);
|
||||||
|
env->ReleaseStringUTFChars(fileDir , strFileDir);
|
||||||
|
|
||||||
|
__android_log_print(ANDROID_LOG_DEBUG, "JSRealm", "Absolute path: %s", realm::default_realm_file_directory().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jlong JNICALL Java_io_realm_react_RealmReactModule_setupChromeDebugModeRealmJsContext
|
||||||
|
(JNIEnv *, jclass)
|
||||||
|
{
|
||||||
|
__android_log_print(ANDROID_LOG_VERBOSE, "JSRealm", "setupChromeDebugModeRealmJsContext");
|
||||||
|
if (s_rpc_server) {
|
||||||
|
delete s_rpc_server;
|
||||||
|
}
|
||||||
|
s_rpc_server = new realm_js::RPCServer();
|
||||||
|
return (jlong)s_rpc_server;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jstring JNICALL Java_io_realm_react_RealmReactModule_processChromeDebugCommand
|
||||||
|
(JNIEnv *env, jclass, jstring chrome_cmd, jstring chrome_args)
|
||||||
|
{
|
||||||
|
__android_log_print(ANDROID_LOG_VERBOSE, "JSRealm", "processChromeDebugCommand");
|
||||||
|
const char* cmd = env->GetStringUTFChars(chrome_cmd, NULL);
|
||||||
|
const char* args = env->GetStringUTFChars(chrome_args, NULL);
|
||||||
|
realm_js::json json = realm_js::json::parse(args);
|
||||||
|
realm_js::json response = s_rpc_server->perform_request(cmd, json);
|
||||||
|
env->ReleaseStringUTFChars(chrome_cmd, cmd);
|
||||||
|
env->ReleaseStringUTFChars(chrome_args, args);
|
||||||
|
return env->NewStringUTF(response.dump().c_str());
|
||||||
|
}
|
35
src/android/io_realm_react_RealmReactModule.h
Normal file
35
src/android/io_realm_react_RealmReactModule.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||||
|
#include <jni.h>
|
||||||
|
/* Header for class io_realm_react_RealmReactModule */
|
||||||
|
|
||||||
|
#ifndef _Included_io_realm_react_RealmReactModule
|
||||||
|
#define _Included_io_realm_react_RealmReactModule
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: io_realm_react_RealmReactModule
|
||||||
|
* Method: setDefaultRealmFileDirectory
|
||||||
|
*/
|
||||||
|
JNIEXPORT void JNICALL Java_io_realm_react_RealmReactModule_setDefaultRealmFileDirectory
|
||||||
|
(JNIEnv *, jclass, jstring);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: io_realm_react_RealmReactModule
|
||||||
|
* Method: setupChromeDebugModeRealmJsContext
|
||||||
|
*/
|
||||||
|
JNIEXPORT jlong JNICALL Java_io_realm_react_RealmReactModule_setupChromeDebugModeRealmJsContext
|
||||||
|
(JNIEnv *, jclass);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: io_realm_react_RealmReactModule
|
||||||
|
* Method: processChromeDebugCommand
|
||||||
|
*/
|
||||||
|
JNIEXPORT jstring JNICALL Java_io_realm_react_RealmReactModule_processChromeDebugCommand
|
||||||
|
(JNIEnv *, jclass, jstring, jstring);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
94
src/android/jsc_override.cpp
Normal file
94
src/android/jsc_override.cpp
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
/* Copyright 2016 Realm Inc - All Rights Reserved
|
||||||
|
* Proprietary and Confidential
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <mutex>
|
||||||
|
#include <JavaScriptCore/JSContextRef.h>
|
||||||
|
|
||||||
|
#include "js_init.h"
|
||||||
|
#include "shared_realm.hpp"
|
||||||
|
|
||||||
|
#if __arm__
|
||||||
|
#define HOOK_SIZE 8
|
||||||
|
#else
|
||||||
|
#define HOOK_SIZE 5
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void swap_function() __attribute__((constructor));
|
||||||
|
|
||||||
|
static JSGlobalContextRef create_context(JSContextGroupRef group, JSClassRef global_class)
|
||||||
|
{
|
||||||
|
static std::mutex s_mutex;
|
||||||
|
std::lock_guard<std::mutex> lock(s_mutex);
|
||||||
|
|
||||||
|
// Replace JSGlobalContextCreateInGroup with its original implementation and call it.
|
||||||
|
swap_function();
|
||||||
|
JSGlobalContextRef ctx = JSGlobalContextCreateInGroup(group, global_class);
|
||||||
|
|
||||||
|
// Reinstall the hook.
|
||||||
|
swap_function();
|
||||||
|
|
||||||
|
// Clear cache from previous instances.
|
||||||
|
realm::Realm::s_global_cache.clear();
|
||||||
|
|
||||||
|
RJSInitializeInContext(ctx);
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void swap_function()
|
||||||
|
{
|
||||||
|
static int8_t s_orig_code[HOOK_SIZE];
|
||||||
|
static bool s_swapped = false;
|
||||||
|
|
||||||
|
int8_t *orig_func = (int8_t*)&JSGlobalContextCreateInGroup;
|
||||||
|
int8_t *new_func = (int8_t*)&create_context;
|
||||||
|
|
||||||
|
#if __arm__
|
||||||
|
bool orig_thumb = (uintptr_t)orig_func % 4 != 0;
|
||||||
|
if (orig_thumb) {
|
||||||
|
orig_func--;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
size_t page_size = sysconf(_SC_PAGESIZE);
|
||||||
|
uintptr_t page_start = (uintptr_t)orig_func & ~(page_size - 1);
|
||||||
|
uintptr_t code_end = (uintptr_t)orig_func + HOOK_SIZE;
|
||||||
|
|
||||||
|
// Make this memory region writable.
|
||||||
|
mprotect((void*)page_start, code_end - page_start, PROT_READ | PROT_WRITE | PROT_EXEC);
|
||||||
|
|
||||||
|
if (s_swapped) {
|
||||||
|
// Copy original code back into place.
|
||||||
|
memcpy(orig_func, s_orig_code, HOOK_SIZE);
|
||||||
|
} else {
|
||||||
|
// Store the original code before replacing it.
|
||||||
|
memcpy(s_orig_code, orig_func, HOOK_SIZE);
|
||||||
|
|
||||||
|
#if __arm__
|
||||||
|
if (orig_thumb) {
|
||||||
|
// LDR PC, [PC, #0]; BX PC;
|
||||||
|
memcpy(orig_func, "\x00\x4f\x38\x47", 4);
|
||||||
|
memcpy(orig_func + 4, &new_func, 4);
|
||||||
|
} else {
|
||||||
|
// LDR PC, [PC, #0];
|
||||||
|
memcpy(orig_func, "\x00\xf0\x9f\xe5", 4);
|
||||||
|
memcpy(orig_func + 4, &new_func, 4);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int32_t jmp_offset = (int64_t)new_func - (int64_t)orig_func - HOOK_SIZE;
|
||||||
|
|
||||||
|
// Change original function to jump to our new one.
|
||||||
|
*orig_func = 0xE9; // JMP
|
||||||
|
*(int32_t*)(orig_func + 1) = jmp_offset;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
s_swapped = !s_swapped;
|
||||||
|
|
||||||
|
// Return this region to no longer being writable.
|
||||||
|
mprotect((void*)page_start, code_end - page_start, PROT_READ | PROT_EXEC);
|
||||||
|
}
|
34
src/android/platform.cpp
Normal file
34
src/android/platform.cpp
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/* Copyright 2015 Realm Inc - All Rights Reserved
|
||||||
|
* Proprietary and Confidential
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../platform.hpp"
|
||||||
|
#include "../js_init.h"
|
||||||
|
#include <string>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
std::string s_default_realm_directory;
|
||||||
|
|
||||||
|
namespace realm {
|
||||||
|
|
||||||
|
void set_default_realm_file_directory(std::string dir)
|
||||||
|
{
|
||||||
|
s_default_realm_directory = dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string default_realm_file_directory()
|
||||||
|
{
|
||||||
|
return s_default_realm_directory;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ensure_directory_exists_for_file(const std::string &fileName)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void remove_realm_files_from_directory(const std::string &directory)
|
||||||
|
{
|
||||||
|
std::string cmd = "rm " + s_default_realm_directory + "/*.realm " +
|
||||||
|
s_default_realm_directory + "/*.realm.lock";
|
||||||
|
system(cmd.c_str());
|
||||||
|
}
|
||||||
|
}
|
@ -2,15 +2,16 @@
|
|||||||
* Proprietary and Confidential
|
* Proprietary and Confidential
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import "js_init.h"
|
#include "js_init.h"
|
||||||
#import "js_realm.hpp"
|
#include "js_realm.hpp"
|
||||||
#import "js_object.hpp"
|
#include "js_object.hpp"
|
||||||
#import "js_util.hpp"
|
#include "js_util.hpp"
|
||||||
#import "js_schema.hpp"
|
#include "js_schema.hpp"
|
||||||
#import "platform.hpp"
|
#include "platform.hpp"
|
||||||
|
|
||||||
#include "shared_realm.hpp"
|
#include "shared_realm.hpp"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
|
@ -2,7 +2,9 @@
|
|||||||
* Proprietary and Confidential
|
* Proprietary and Confidential
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import <JavaScriptCore/JavaScriptCore.h>
|
#pragma once
|
||||||
|
|
||||||
|
#include <JavaScriptCore/JSBase.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
#include "js_util.hpp"
|
#include "js_util.hpp"
|
||||||
#include "object_accessor.hpp"
|
#include "object_accessor.hpp"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
using RJSAccessor = realm::NativeAccessor<JSValueRef, JSContextRef>;
|
using RJSAccessor = realm::NativeAccessor<JSValueRef, JSContextRef>;
|
||||||
using namespace realm;
|
using namespace realm;
|
||||||
|
|
||||||
|
@ -2,9 +2,11 @@
|
|||||||
* Proprietary and Confidential
|
* Proprietary and Confidential
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import "js_util.hpp"
|
#pragma once
|
||||||
#import "shared_realm.hpp"
|
|
||||||
#import "list.hpp"
|
#include "js_util.hpp"
|
||||||
|
#include "shared_realm.hpp"
|
||||||
|
#include "list.hpp"
|
||||||
|
|
||||||
JSClassRef RJSListClass();
|
JSClassRef RJSListClass();
|
||||||
JSObjectRef RJSListCreate(JSContextRef ctx, realm::List &list);
|
JSObjectRef RJSListCreate(JSContextRef ctx, realm::List &list);
|
||||||
|
@ -2,15 +2,15 @@
|
|||||||
* Proprietary and Confidential
|
* Proprietary and Confidential
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import "js_util.hpp"
|
#include "js_util.hpp"
|
||||||
#import "js_object.hpp"
|
#include "js_object.hpp"
|
||||||
#import "js_results.hpp"
|
#include "js_results.hpp"
|
||||||
#import "js_schema.hpp"
|
#include "js_schema.hpp"
|
||||||
#import "js_list.hpp"
|
#include "js_list.hpp"
|
||||||
#import "js_realm.hpp"
|
#include "js_realm.hpp"
|
||||||
|
|
||||||
#import "object_store.hpp"
|
#include "object_store.hpp"
|
||||||
#import "object_accessor.hpp"
|
#include "object_accessor.hpp"
|
||||||
|
|
||||||
using RJSAccessor = realm::NativeAccessor<JSValueRef, JSContextRef>;
|
using RJSAccessor = realm::NativeAccessor<JSValueRef, JSContextRef>;
|
||||||
using namespace realm;
|
using namespace realm;
|
||||||
@ -63,6 +63,10 @@ JSObjectRef RJSObjectCreate(JSContextRef ctx, Object object) {
|
|||||||
return jsObject;
|
return jsObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern JSObjectRef RJSDictForPropertyArray(JSContextRef ctx, const ObjectSchema &object_schema, JSObjectRef array);
|
||||||
|
|
||||||
|
namespace realm {
|
||||||
|
|
||||||
template<> bool RJSAccessor::dict_has_value_for_key(JSContextRef ctx, JSValueRef dict, const std::string &prop_name) {
|
template<> bool RJSAccessor::dict_has_value_for_key(JSContextRef ctx, JSValueRef dict, const std::string &prop_name) {
|
||||||
JSObjectRef object = RJSValidatedValueToObject(ctx, dict);
|
JSObjectRef object = RJSValidatedValueToObject(ctx, dict);
|
||||||
JSStringRef propStr = RJSStringForString(prop_name);
|
JSStringRef propStr = RJSStringForString(prop_name);
|
||||||
@ -218,8 +222,6 @@ template<> JSValueRef RJSAccessor::from_datetime(JSContextRef ctx, DateTime dt)
|
|||||||
return JSObjectMakeDate(ctx, 1, &time, NULL);
|
return JSObjectMakeDate(ctx, 1, &time, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern JSObjectRef RJSDictForPropertyArray(JSContextRef ctx, const ObjectSchema &object_schema, JSObjectRef array);
|
|
||||||
|
|
||||||
template<> size_t RJSAccessor::to_existing_object_index(JSContextRef ctx, JSValueRef &val) {
|
template<> size_t RJSAccessor::to_existing_object_index(JSContextRef ctx, JSValueRef &val) {
|
||||||
JSObjectRef object = RJSValidatedValueToObject(ctx, val);
|
JSObjectRef object = RJSValidatedValueToObject(ctx, val);
|
||||||
if (JSValueIsObjectOfClass(ctx, val, RJSObjectClass())) {
|
if (JSValueIsObjectOfClass(ctx, val, RJSObjectClass())) {
|
||||||
@ -254,3 +256,5 @@ template<> JSValueRef RJSAccessor::list_value_at_index(JSContextRef ctx, JSValue
|
|||||||
template<> JSValueRef RJSAccessor::from_list(JSContextRef ctx, List list) {
|
template<> JSValueRef RJSAccessor::from_list(JSContextRef ctx, List list) {
|
||||||
return RJSListCreate(ctx, list);
|
return RJSListCreate(ctx, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
@ -2,7 +2,9 @@
|
|||||||
* Proprietary and Confidential
|
* Proprietary and Confidential
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import "js_util.hpp"
|
#pragma once
|
||||||
|
|
||||||
|
#include "js_util.hpp"
|
||||||
|
|
||||||
namespace realm {
|
namespace realm {
|
||||||
class Object;
|
class Object;
|
||||||
|
@ -2,18 +2,19 @@
|
|||||||
* Proprietary and Confidential
|
* Proprietary and Confidential
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import "js_realm.hpp"
|
#include "js_realm.hpp"
|
||||||
#import "js_object.hpp"
|
#include "js_object.hpp"
|
||||||
#import "js_results.hpp"
|
#include "js_results.hpp"
|
||||||
#import "js_list.hpp"
|
#include "js_list.hpp"
|
||||||
#import "js_schema.hpp"
|
#include "js_schema.hpp"
|
||||||
#import "platform.hpp"
|
#include "platform.hpp"
|
||||||
|
|
||||||
#import "shared_realm.hpp"
|
#include "shared_realm.hpp"
|
||||||
#import "object_accessor.hpp"
|
#include "object_accessor.hpp"
|
||||||
#import "binding_context.hpp"
|
#include "binding_context.hpp"
|
||||||
|
|
||||||
#import <set>
|
#include <set>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
using namespace realm;
|
using namespace realm;
|
||||||
|
|
||||||
@ -104,8 +105,12 @@ std::map<std::string, JSValueRef> &RJSPrototypes(Realm *realm) {
|
|||||||
return static_cast<RJSRealmDelegate *>(realm->m_binding_context.get())->m_prototypes;
|
return static_cast<RJSRealmDelegate *>(realm->m_binding_context.get())->m_prototypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string s_defaultPath = realm::default_realm_file_directory() + "/default.realm";
|
// static std::string s_defaultPath = realm::default_realm_file_directory() + "/default.realm";
|
||||||
|
static std::string s_defaultPath = "";
|
||||||
std::string RJSDefaultPath() {
|
std::string RJSDefaultPath() {
|
||||||
|
if (s_defaultPath.size() == 0) {
|
||||||
|
s_defaultPath = realm::default_realm_file_directory() + "/default.realm";
|
||||||
|
}
|
||||||
return s_defaultPath;
|
return s_defaultPath;
|
||||||
}
|
}
|
||||||
void RJSSetDefaultPath(std::string path) {
|
void RJSSetDefaultPath(std::string path) {
|
||||||
@ -158,7 +163,7 @@ JSObjectRef RealmConstructor(JSContextRef ctx, JSObjectRef constructor, size_t a
|
|||||||
static JSStringRef schemaString = JSStringCreateWithUTF8CString("schema");
|
static JSStringRef schemaString = JSStringCreateWithUTF8CString("schema");
|
||||||
JSValueRef schemaValue = RJSValidatedPropertyValue(ctx, object, schemaString);
|
JSValueRef schemaValue = RJSValidatedPropertyValue(ctx, object, schemaString);
|
||||||
if (!JSValueIsUndefined(ctx, schemaValue)) {
|
if (!JSValueIsUndefined(ctx, schemaValue)) {
|
||||||
config.schema = std::make_unique<Schema>(RJSParseSchema(ctx, RJSValidatedValueToObject(ctx, schemaValue), defaults, prototypes));
|
config.schema.reset(new Schema(RJSParseSchema(ctx, RJSValidatedValueToObject(ctx, schemaValue), defaults, prototypes)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSStringRef schemaVersionString = JSStringCreateWithUTF8CString("schemaVersion");
|
static JSStringRef schemaVersionString = JSStringCreateWithUTF8CString("schemaVersion");
|
||||||
@ -179,7 +184,7 @@ JSObjectRef RealmConstructor(JSContextRef ctx, JSObjectRef constructor, size_t a
|
|||||||
ensure_directory_exists_for_file(config.path);
|
ensure_directory_exists_for_file(config.path);
|
||||||
SharedRealm realm = Realm::get_shared_realm(config);
|
SharedRealm realm = Realm::get_shared_realm(config);
|
||||||
if (!realm->m_binding_context) {
|
if (!realm->m_binding_context) {
|
||||||
realm->m_binding_context = std::make_unique<RJSRealmDelegate>(realm, JSContextGetGlobalContext(ctx));
|
realm->m_binding_context.reset(new RJSRealmDelegate(realm, JSContextGetGlobalContext(ctx)));
|
||||||
}
|
}
|
||||||
RJSDefaults(realm.get()) = defaults;
|
RJSDefaults(realm.get()) = defaults;
|
||||||
RJSPrototypes(realm.get()) = prototypes;
|
RJSPrototypes(realm.get()) = prototypes;
|
||||||
|
@ -2,7 +2,9 @@
|
|||||||
* Proprietary and Confidential
|
* Proprietary and Confidential
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import "js_util.hpp"
|
#pragma once
|
||||||
|
|
||||||
|
#include "js_util.hpp"
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
namespace realm {
|
namespace realm {
|
||||||
|
@ -2,12 +2,12 @@
|
|||||||
* Proprietary and Confidential
|
* Proprietary and Confidential
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import "js_results.hpp"
|
#include "js_results.hpp"
|
||||||
#import "js_object.hpp"
|
#include "js_object.hpp"
|
||||||
#import "object_accessor.hpp"
|
#include "object_accessor.hpp"
|
||||||
#import "results.hpp"
|
#include "results.hpp"
|
||||||
#import "parser.hpp"
|
#include "parser.hpp"
|
||||||
#import "query_builder.hpp"
|
#include "query_builder.hpp"
|
||||||
|
|
||||||
using namespace realm;
|
using namespace realm;
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ bool ResultsSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef proper
|
|||||||
try {
|
try {
|
||||||
std::string indexStr = RJSStringForJSString(propertyName);
|
std::string indexStr = RJSStringForJSString(propertyName);
|
||||||
if (indexStr != "length") {
|
if (indexStr != "length") {
|
||||||
std::stol(RJSStringForJSString(propertyName));
|
stot<long>(RJSStringForJSString(propertyName));
|
||||||
}
|
}
|
||||||
|
|
||||||
// attempts to assign to 'length' or an index should throw an exception
|
// attempts to assign to 'length' or an index should throw an exception
|
||||||
|
@ -2,7 +2,10 @@
|
|||||||
* Proprietary and Confidential
|
* Proprietary and Confidential
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import "js_util.hpp"
|
#pragma once
|
||||||
|
|
||||||
|
#include "js_util.hpp"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace realm {
|
namespace realm {
|
||||||
class Realm;
|
class Realm;
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
* Proprietary and Confidential
|
* Proprietary and Confidential
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import "js_schema.hpp"
|
#include "js_schema.hpp"
|
||||||
#import "object_store.hpp"
|
#include "object_store.hpp"
|
||||||
|
|
||||||
namespace realm {
|
namespace realm {
|
||||||
struct SchemaWrapper {
|
struct SchemaWrapper {
|
||||||
|
@ -2,8 +2,10 @@
|
|||||||
* Proprietary and Confidential
|
* Proprietary and Confidential
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import "js_util.hpp"
|
#pragma once
|
||||||
#import <map>
|
|
||||||
|
#include "js_util.hpp"
|
||||||
|
#include <map>
|
||||||
|
|
||||||
namespace realm {
|
namespace realm {
|
||||||
class Schema;
|
class Schema;
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
* Proprietary and Confidential
|
* Proprietary and Confidential
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import "js_util.hpp"
|
#include "js_util.hpp"
|
||||||
|
#include <JavaScriptCore/JSStringRef.h>
|
||||||
|
|
||||||
using namespace realm;
|
using namespace realm;
|
||||||
|
|
||||||
@ -32,7 +33,7 @@ std::string RJSStringForJSString(JSStringRef jsString) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string RJSStringForValue(JSContextRef ctx, JSValueRef value) {
|
std::string RJSStringForValue(JSContextRef ctx, JSValueRef value) {
|
||||||
JSValueRef exception = NULL;
|
JSValueRef exception = nullptr;
|
||||||
JSStringRef jsString = JSValueToStringCopy(ctx, value, &exception);
|
JSStringRef jsString = JSValueToStringCopy(ctx, value, &exception);
|
||||||
if (!jsString) {
|
if (!jsString) {
|
||||||
throw RJSException(ctx, exception);
|
throw RJSException(ctx, exception);
|
||||||
|
@ -2,12 +2,22 @@
|
|||||||
* Proprietary and Confidential
|
* Proprietary and Confidential
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <JavaScriptCore/JavaScriptCore.h>
|
#pragma once
|
||||||
|
|
||||||
|
#include <JavaScriptCore/JSContextRef.h>
|
||||||
|
#include <JavaScriptCore/JSObjectRef.h>
|
||||||
|
#include <JavaScriptCore/JSStringRef.h>
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <cmath>
|
||||||
#include "property.hpp"
|
#include "property.hpp"
|
||||||
#include "schema.hpp"
|
#include "schema.hpp"
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline void RJSFinalize(JSObjectRef object) {
|
inline void RJSFinalize(JSObjectRef object) {
|
||||||
delete static_cast<T>(JSObjectGetPrivate(object));
|
delete static_cast<T>(JSObjectGetPrivate(object));
|
||||||
@ -173,8 +183,19 @@ static inline size_t RJSValidatedListLength(JSContextRef ctx, JSObjectRef object
|
|||||||
return RJSValidatedValueToNumber(ctx, lengthValue);
|
return RJSValidatedValueToNumber(ctx, lengthValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T stot(const std::string s) {
|
||||||
|
std::istringstream iss(s);
|
||||||
|
T value;
|
||||||
|
iss >> value;
|
||||||
|
if (iss.fail()) {
|
||||||
|
throw std::invalid_argument("Cannot convert string '" + s + "'");
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
static inline size_t RJSValidatedPositiveIndex(std::string indexStr) {
|
static inline size_t RJSValidatedPositiveIndex(std::string indexStr) {
|
||||||
long index = std::stol(indexStr);
|
long index = stot<long>(indexStr);
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
throw std::out_of_range(std::string("Index ") + indexStr + " cannot be less than zero.");
|
throw std::out_of_range(std::string("Index ") + indexStr + " cannot be less than zero.");
|
||||||
}
|
}
|
||||||
|
15
src/object-store/README.md
Normal file
15
src/object-store/README.md
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# Realm Object Store
|
||||||
|
|
||||||
|
Cross-platform code used accross bindings. Binding developers can choose to use some or all the included functionality
|
||||||
|
- `object_store`/`schema`/`object_schema`/`property` - contains the structures and logic used to setup and modify realm files and their schema.
|
||||||
|
- `shared_realm` - wraps the object_store apis to provide transactions, notifications, realm caching, migrations, and other higher level functionality.
|
||||||
|
- `object_accessor`/`results`/`list` - accessor classes, object creation/update pipeline, and helpers for creating platform specific property getters and setters.
|
||||||
|
- `parser`/`query_builder` - cross platform query parser and query builder - requires and object_accessor specialization for argument support. Depends on https://github.com/ColinH/PEGTL
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
TBD
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
TBD
|
@ -293,10 +293,12 @@ public:
|
|||||||
|
|
||||||
// Things that just mark the field as modified
|
// Things that just mark the field as modified
|
||||||
bool set_int(size_t col, size_t row, int_fast64_t) { return mark_dirty(row, col); }
|
bool set_int(size_t col, size_t row, int_fast64_t) { return mark_dirty(row, col); }
|
||||||
|
bool set_int_unique(size_t col, size_t row, int_fast64_t) { return mark_dirty(row, col); }
|
||||||
bool set_bool(size_t col, size_t row, bool) { return mark_dirty(row, col); }
|
bool set_bool(size_t col, size_t row, bool) { return mark_dirty(row, col); }
|
||||||
bool set_float(size_t col, size_t row, float) { return mark_dirty(row, col); }
|
bool set_float(size_t col, size_t row, float) { return mark_dirty(row, col); }
|
||||||
bool set_double(size_t col, size_t row, double) { return mark_dirty(row, col); }
|
bool set_double(size_t col, size_t row, double) { return mark_dirty(row, col); }
|
||||||
bool set_string(size_t col, size_t row, StringData) { return mark_dirty(row, col); }
|
bool set_string(size_t col, size_t row, StringData) { return mark_dirty(row, col); }
|
||||||
|
bool set_string_unique(size_t col, size_t row, StringData) { return mark_dirty(row, col); }
|
||||||
bool set_binary(size_t col, size_t row, BinaryData) { return mark_dirty(row, col); }
|
bool set_binary(size_t col, size_t row, BinaryData) { return mark_dirty(row, col); }
|
||||||
bool set_date_time(size_t col, size_t row, DateTime) { return mark_dirty(row, col); }
|
bool set_date_time(size_t col, size_t row, DateTime) { return mark_dirty(row, col); }
|
||||||
bool set_table(size_t col, size_t row) { return mark_dirty(row, col); }
|
bool set_table(size_t col, size_t row) { return mark_dirty(row, col); }
|
||||||
@ -304,8 +306,6 @@ public:
|
|||||||
bool set_link(size_t col, size_t row, size_t, size_t) { return mark_dirty(row, col); }
|
bool set_link(size_t col, size_t row, size_t, size_t) { return mark_dirty(row, col); }
|
||||||
bool set_null(size_t col, size_t row) { return mark_dirty(row, col); }
|
bool set_null(size_t col, size_t row) { return mark_dirty(row, col); }
|
||||||
bool nullify_link(size_t col, size_t row, size_t) { return mark_dirty(row, col); }
|
bool nullify_link(size_t col, size_t row, size_t) { return mark_dirty(row, col); }
|
||||||
bool set_int_unique(size_t col, size_t row, int_fast64_t) { return mark_dirty(row, col); }
|
|
||||||
bool set_string_unique(size_t col, size_t row, StringData) { return mark_dirty(row, col); }
|
|
||||||
|
|
||||||
// Doesn't change any data
|
// Doesn't change any data
|
||||||
bool optimize_table() { return true; }
|
bool optimize_table() { return true; }
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
namespace realm {
|
namespace realm {
|
||||||
class IndexSet {
|
class IndexSet {
|
||||||
|
@ -68,7 +68,7 @@ Query List::get_query() {
|
|||||||
void List::verify_valid_row(std::size_t row_ndx, bool insertion) {
|
void List::verify_valid_row(std::size_t row_ndx, bool insertion) {
|
||||||
size_t size = m_link_view->size();
|
size_t size = m_link_view->size();
|
||||||
if (row_ndx > size || (!insertion && row_ndx == size)) {
|
if (row_ndx > size || (!insertion && row_ndx == size)) {
|
||||||
throw std::out_of_range(std::string("Index ") + std::to_string(row_ndx) + " is outside of range 0..." + std::to_string(size) + ".");
|
throw std::out_of_range(std::string("Index ") + to_string(row_ndx) + " is outside of range 0..." + to_string(size) + ".");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -520,7 +520,7 @@ bool ObjectStore::is_empty(const Group *group) {
|
|||||||
InvalidSchemaVersionException::InvalidSchemaVersionException(uint64_t old_version, uint64_t new_version) :
|
InvalidSchemaVersionException::InvalidSchemaVersionException(uint64_t old_version, uint64_t new_version) :
|
||||||
m_old_version(old_version), m_new_version(new_version)
|
m_old_version(old_version), m_new_version(new_version)
|
||||||
{
|
{
|
||||||
m_what = "Provided schema version " + std::to_string(old_version) + " is less than last set version " + std::to_string(new_version) + ".";
|
m_what = "Provided schema version " + to_string(old_version) + " is less than last set version " + to_string(new_version) + ".";
|
||||||
}
|
}
|
||||||
|
|
||||||
DuplicatePrimaryKeyValueException::DuplicatePrimaryKeyValueException(std::string const& object_type, Property const& property) :
|
DuplicatePrimaryKeyValueException::DuplicatePrimaryKeyValueException(std::string const& object_type, Property const& property) :
|
||||||
@ -589,7 +589,7 @@ MismatchedPropertiesException::MismatchedPropertiesException(std::string const&
|
|||||||
m_what = "Target object type for property '" + old_property.name + "' do not match. Old type '" + old_property.object_type + "', new type '" + new_property.object_type + "'";
|
m_what = "Target object type for property '" + old_property.name + "' do not match. Old type '" + old_property.object_type + "', new type '" + new_property.object_type + "'";
|
||||||
}
|
}
|
||||||
else if (new_property.is_nullable != old_property.is_nullable) {
|
else if (new_property.is_nullable != old_property.is_nullable) {
|
||||||
m_what = "Nullability for property '" + old_property.name + "' has changed from '" + std::to_string(old_property.is_nullable) + "' to '" + std::to_string(new_property.is_nullable) + "'.";
|
m_what = "Nullability for property '" + old_property.name + "' has changed from '" + to_string(old_property.is_nullable) + "' to '" + to_string(new_property.is_nullable) + "'.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,8 @@
|
|||||||
#include <realm/group.hpp>
|
#include <realm/group.hpp>
|
||||||
#include <realm/link_view.hpp>
|
#include <realm/link_view.hpp>
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
namespace realm {
|
namespace realm {
|
||||||
class ObjectSchemaValidationException;
|
class ObjectSchemaValidationException;
|
||||||
class Schema;
|
class Schema;
|
||||||
@ -233,6 +235,13 @@ namespace realm {
|
|||||||
private:
|
private:
|
||||||
std::string m_primary_key;
|
std::string m_primary_key;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
std::string to_string(T value) {
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << value;
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* defined(REALM_OBJECT_STORE_HPP) */
|
#endif /* defined(REALM_OBJECT_STORE_HPP) */
|
||||||
|
@ -227,7 +227,7 @@ template<> struct action< or_op >
|
|||||||
template<> struct action< rule > { \
|
template<> struct action< rule > { \
|
||||||
static void apply( const input & in, ParserState & state ) { \
|
static void apply( const input & in, ParserState & state ) { \
|
||||||
DEBUG_PRINT_TOKEN(in.string()); \
|
DEBUG_PRINT_TOKEN(in.string()); \
|
||||||
state.add_expression(Expression{type, in.string()}); }};
|
state.add_expression(Expression(type, in.string())); }};
|
||||||
|
|
||||||
EXPRESSION_ACTION(dq_string_content, Expression::Type::String)
|
EXPRESSION_ACTION(dq_string_content, Expression::Type::String)
|
||||||
EXPRESSION_ACTION(sq_string_content, Expression::Type::String)
|
EXPRESSION_ACTION(sq_string_content, Expression::Type::String)
|
||||||
@ -334,7 +334,7 @@ Predicate parse(const std::string &query)
|
|||||||
return std::move(out_predicate);
|
return std::move(out_predicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
void analyzeGrammar()
|
void analyze_grammar()
|
||||||
{
|
{
|
||||||
analyze<pred>();
|
analyze<pred>();
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ struct Expression
|
|||||||
{
|
{
|
||||||
enum class Type { None, Number, String, KeyPath, Argument, True, False } type = Type::None;
|
enum class Type { None, Number, String, KeyPath, Argument, True, False } type = Type::None;
|
||||||
std::string s;
|
std::string s;
|
||||||
|
Expression(Type t = Type::None, std::string s = "") : type(t), s(s) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Predicate
|
struct Predicate
|
||||||
@ -78,8 +79,8 @@ struct Predicate
|
|||||||
|
|
||||||
Predicate parse(const std::string &query);
|
Predicate parse(const std::string &query);
|
||||||
|
|
||||||
void analyzeGrammar();
|
void analyze_grammar();
|
||||||
bool testGrammar();
|
bool test_grammar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,28 +29,41 @@ namespace realm {
|
|||||||
namespace query_builder {
|
namespace query_builder {
|
||||||
using namespace parser;
|
using namespace parser;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T stot(const std::string s) {
|
||||||
|
std::istringstream iss(s);
|
||||||
|
T value;
|
||||||
|
iss >> value;
|
||||||
|
if (iss.fail()) {
|
||||||
|
throw std::invalid_argument("Cannot convert string '" + s + "'");
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
// check a precondition and throw an exception if it is not met
|
// check a precondition and throw an exception if it is not met
|
||||||
// this should be used iff the condition being false indicates a bug in the caller
|
// this should be used iff the condition being false indicates a bug in the caller
|
||||||
// of the function checking its preconditions
|
// of the function checking its preconditions
|
||||||
#define precondition(condition, message) if (!__builtin_expect(condition, 1)) { throw std::runtime_error(message); }
|
#define precondition(condition, message) if (!__builtin_expect(condition, 1)) { throw std::runtime_error(message); }
|
||||||
|
|
||||||
// FIXME: TrueExpression and FalseExpression should be supported by core in some way
|
// FIXME: TrueExpression and FalseExpression should be supported by core in some way
|
||||||
struct TrueExpression : realm::Expression {
|
class TrueExpression : public realm::Expression {
|
||||||
size_t find_first(size_t start, size_t end) const override
|
public:
|
||||||
|
virtual size_t find_first(size_t start, size_t end) const
|
||||||
{
|
{
|
||||||
if (start != end)
|
if (start != end)
|
||||||
return start;
|
return start;
|
||||||
|
|
||||||
return not_found;
|
return not_found;
|
||||||
}
|
}
|
||||||
void set_table() override {}
|
virtual void set_table(const Table* table) {}
|
||||||
const Table* get_table() const override { return nullptr; }
|
virtual const Table* get_table() const { return nullptr; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FalseExpression : realm::Expression {
|
class FalseExpression : public realm::Expression {
|
||||||
size_t find_first(size_t, size_t) const override { return not_found; }
|
public:
|
||||||
void set_table() override {}
|
virtual size_t find_first(size_t, size_t) const { return not_found; }
|
||||||
const Table* get_table() const override { return nullptr; }
|
virtual void set_table(const Table* table) {}
|
||||||
|
virtual const Table* get_table() const { return nullptr; }
|
||||||
};
|
};
|
||||||
|
|
||||||
using KeyPath = std::vector<std::string>;
|
using KeyPath = std::vector<std::string>;
|
||||||
@ -262,12 +275,12 @@ void add_link_constraint_to_query(realm::Query &query,
|
|||||||
|
|
||||||
auto link_argument(const PropertyExpression &propExpr, const parser::Expression &argExpr, Arguments &args)
|
auto link_argument(const PropertyExpression &propExpr, const parser::Expression &argExpr, Arguments &args)
|
||||||
{
|
{
|
||||||
return args.object_index_for_argument(std::stoi(argExpr.s));
|
return args.object_index_for_argument(stot<int>(argExpr.s));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto link_argument(const parser::Expression &argExpr, const PropertyExpression &propExpr, Arguments &args)
|
auto link_argument(const parser::Expression &argExpr, const PropertyExpression &propExpr, Arguments &args)
|
||||||
{
|
{
|
||||||
return args.object_index_for_argument(std::stoi(argExpr.s));
|
return args.object_index_for_argument(stot<int>(argExpr.s));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -289,7 +302,7 @@ struct ValueGetter<DateTime, TableGetter> {
|
|||||||
if (value.type != parser::Expression::Type::Argument) {
|
if (value.type != parser::Expression::Type::Argument) {
|
||||||
throw std::runtime_error("You must pass in a date argument to compare");
|
throw std::runtime_error("You must pass in a date argument to compare");
|
||||||
}
|
}
|
||||||
DateTime dt = args.datetime_for_argument(std::stoi(value.s));
|
DateTime dt = args.datetime_for_argument(stot<int>(value.s));
|
||||||
return dt.get_datetime();
|
return dt.get_datetime();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -299,7 +312,7 @@ struct ValueGetter<bool, TableGetter> {
|
|||||||
static bool convert(TableGetter&&, const parser::Expression & value, Arguments &args)
|
static bool convert(TableGetter&&, const parser::Expression & value, Arguments &args)
|
||||||
{
|
{
|
||||||
if (value.type == parser::Expression::Type::Argument) {
|
if (value.type == parser::Expression::Type::Argument) {
|
||||||
return args.bool_for_argument(std::stoi(value.s));
|
return args.bool_for_argument(stot<int>(value.s));
|
||||||
}
|
}
|
||||||
if (value.type != parser::Expression::Type::True && value.type != parser::Expression::Type::False) {
|
if (value.type != parser::Expression::Type::True && value.type != parser::Expression::Type::False) {
|
||||||
throw std::runtime_error("Attempting to compare bool property to a non-bool value");
|
throw std::runtime_error("Attempting to compare bool property to a non-bool value");
|
||||||
@ -313,9 +326,9 @@ struct ValueGetter<Double, TableGetter> {
|
|||||||
static Double convert(TableGetter&&, const parser::Expression & value, Arguments &args)
|
static Double convert(TableGetter&&, const parser::Expression & value, Arguments &args)
|
||||||
{
|
{
|
||||||
if (value.type == parser::Expression::Type::Argument) {
|
if (value.type == parser::Expression::Type::Argument) {
|
||||||
return args.double_for_argument(std::stoi(value.s));
|
return args.double_for_argument(stot<int>(value.s));
|
||||||
}
|
}
|
||||||
return std::stod(value.s);
|
return stot<double>(value.s);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -324,9 +337,9 @@ struct ValueGetter<Float, TableGetter> {
|
|||||||
static Float convert(TableGetter&&, const parser::Expression & value, Arguments &args)
|
static Float convert(TableGetter&&, const parser::Expression & value, Arguments &args)
|
||||||
{
|
{
|
||||||
if (value.type == parser::Expression::Type::Argument) {
|
if (value.type == parser::Expression::Type::Argument) {
|
||||||
return args.float_for_argument(std::stoi(value.s));
|
return args.float_for_argument(stot<int>(value.s));
|
||||||
}
|
}
|
||||||
return std::stof(value.s);
|
return stot<float>(value.s);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -335,9 +348,9 @@ struct ValueGetter<Int, TableGetter> {
|
|||||||
static Int convert(TableGetter&&, const parser::Expression & value, Arguments &args)
|
static Int convert(TableGetter&&, const parser::Expression & value, Arguments &args)
|
||||||
{
|
{
|
||||||
if (value.type == parser::Expression::Type::Argument) {
|
if (value.type == parser::Expression::Type::Argument) {
|
||||||
return args.long_for_argument(std::stoi(value.s));
|
return args.long_for_argument(stot<int>(value.s));
|
||||||
}
|
}
|
||||||
return std::stoll(value.s);
|
return stot<long long>(value.s);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -346,7 +359,7 @@ struct ValueGetter<String, TableGetter> {
|
|||||||
static std::string convert(TableGetter&&, const parser::Expression & value, Arguments &args)
|
static std::string convert(TableGetter&&, const parser::Expression & value, Arguments &args)
|
||||||
{
|
{
|
||||||
if (value.type == parser::Expression::Type::Argument) {
|
if (value.type == parser::Expression::Type::Argument) {
|
||||||
return args.string_for_argument(std::stoi(value.s));
|
return args.string_for_argument(stot<int>(value.s));
|
||||||
}
|
}
|
||||||
if (value.type != parser::Expression::Type::String) {
|
if (value.type != parser::Expression::Type::String) {
|
||||||
throw std::runtime_error("Attempting to compare String property to a non-String value");
|
throw std::runtime_error("Attempting to compare String property to a non-String value");
|
||||||
@ -360,7 +373,7 @@ struct ValueGetter<Binary, TableGetter> {
|
|||||||
static std::string convert(TableGetter&&, const parser::Expression & value, Arguments &args)
|
static std::string convert(TableGetter&&, const parser::Expression & value, Arguments &args)
|
||||||
{
|
{
|
||||||
if (value.type == parser::Expression::Type::Argument) {
|
if (value.type == parser::Expression::Type::Argument) {
|
||||||
return args.binary_for_argument(std::stoi(value.s));
|
return args.binary_for_argument(stot<int>(value.s));
|
||||||
}
|
}
|
||||||
throw std::runtime_error("Binary properties must be compared against a binary argument.");
|
throw std::runtime_error("Binary properties must be compared against a binary argument.");
|
||||||
}
|
}
|
||||||
@ -371,7 +384,7 @@ auto value_of_type_for_query(TableGetter&& tables, Value&& value, Arguments &arg
|
|||||||
{
|
{
|
||||||
const bool isColumn = std::is_same<PropertyExpression, typename std::remove_reference<Value>::type>::value;
|
const bool isColumn = std::is_same<PropertyExpression, typename std::remove_reference<Value>::type>::value;
|
||||||
using helper = std::conditional_t<isColumn, ColumnGetter<RetType, TableGetter>, ValueGetter<RetType, TableGetter>>;
|
using helper = std::conditional_t<isColumn, ColumnGetter<RetType, TableGetter>, ValueGetter<RetType, TableGetter>>;
|
||||||
return helper::convert(std::forward<TableGetter>(tables), std::forward<Value>(value), args);
|
return helper::convert(tables, value, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename A, typename B>
|
template <typename A, typename B>
|
||||||
|
@ -69,7 +69,7 @@ class ArgumentConverter : public Arguments
|
|||||||
|
|
||||||
ValueType &argument_at(size_t index) {
|
ValueType &argument_at(size_t index) {
|
||||||
if (index >= m_arguments.size()) {
|
if (index >= m_arguments.size()) {
|
||||||
throw std::out_of_range((std::string)"Argument index " + std::to_string(index) + " out of range 0.." + std::to_string(m_arguments.size()-1));
|
throw std::out_of_range((std::string)"Argument index " + to_string(index) + " out of range 0.." + to_string(m_arguments.size()-1));
|
||||||
}
|
}
|
||||||
return m_arguments[index];
|
return m_arguments[index];
|
||||||
}
|
}
|
||||||
|
@ -134,7 +134,7 @@ static std::vector<std::string> invalid_queries = {
|
|||||||
namespace realm {
|
namespace realm {
|
||||||
namespace parser {
|
namespace parser {
|
||||||
|
|
||||||
bool testGrammar()
|
bool test_grammar()
|
||||||
{
|
{
|
||||||
bool success = true;
|
bool success = true;
|
||||||
for (auto &query : valid_queries) {
|
for (auto &query : valid_queries) {
|
||||||
|
@ -36,19 +36,19 @@ using namespace realm;
|
|||||||
|
|
||||||
Results::Results(SharedRealm r, const ObjectSchema &o, Query q, SortOrder s)
|
Results::Results(SharedRealm r, const ObjectSchema &o, Query q, SortOrder s)
|
||||||
: m_realm(std::move(r))
|
: m_realm(std::move(r))
|
||||||
|
, m_object_schema(&o)
|
||||||
, m_query(std::move(q))
|
, m_query(std::move(q))
|
||||||
, m_table(m_query.get_table().get())
|
, m_table(m_query.get_table().get())
|
||||||
, m_sort(std::move(s))
|
, m_sort(std::move(s))
|
||||||
, m_mode(Mode::Query)
|
, m_mode(Mode::Query)
|
||||||
, m_object_schema(&o)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Results::Results(SharedRealm r, const ObjectSchema &o, Table& table)
|
Results::Results(SharedRealm r, const ObjectSchema &o, Table& table)
|
||||||
: m_realm(std::move(r))
|
: m_realm(std::move(r))
|
||||||
|
, m_object_schema(&o)
|
||||||
, m_table(&table)
|
, m_table(&table)
|
||||||
, m_mode(Mode::Table)
|
, m_mode(Mode::Table)
|
||||||
, m_object_schema(&o)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,9 +135,10 @@ public:
|
|||||||
// The input index parameter was out of bounds
|
// The input index parameter was out of bounds
|
||||||
struct OutOfBoundsIndexException : public std::out_of_range
|
struct OutOfBoundsIndexException : public std::out_of_range
|
||||||
{
|
{
|
||||||
OutOfBoundsIndexException(size_t r, size_t c) : requested(r), valid_count(c),
|
OutOfBoundsIndexException(size_t r, size_t c) :
|
||||||
std::out_of_range((std::string)"Requested index " + std::to_string(r) +
|
std::out_of_range((std::string)"Requested index " + to_string(r) +
|
||||||
" greater than max " + std::to_string(c)) {}
|
" greater than max " + to_string(c)),
|
||||||
|
requested(r), valid_count(c) {}
|
||||||
const size_t requested;
|
const size_t requested;
|
||||||
const size_t valid_count;
|
const size_t valid_count;
|
||||||
};
|
};
|
||||||
@ -150,7 +151,7 @@ public:
|
|||||||
// The input Row object belongs to a different table
|
// The input Row object belongs to a different table
|
||||||
struct IncorrectTableException : public std::runtime_error {
|
struct IncorrectTableException : public std::runtime_error {
|
||||||
IncorrectTableException(StringData e, StringData a, const std::string &error) :
|
IncorrectTableException(StringData e, StringData a, const std::string &error) :
|
||||||
expected(e), actual(a), std::runtime_error(error) {}
|
std::runtime_error(error), expected(e), actual(a) {}
|
||||||
const StringData expected;
|
const StringData expected;
|
||||||
const StringData actual;
|
const StringData actual;
|
||||||
};
|
};
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace realm {
|
namespace realm {
|
||||||
class ObjectSchema;
|
class ObjectSchema;
|
||||||
|
@ -18,10 +18,13 @@
|
|||||||
|
|
||||||
#include "shared_realm.hpp"
|
#include "shared_realm.hpp"
|
||||||
|
|
||||||
|
#if __APPLE__
|
||||||
#include "external_commit_helper.hpp"
|
#include "external_commit_helper.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "binding_context.hpp"
|
#include "binding_context.hpp"
|
||||||
#include "schema.hpp"
|
#include "schema.hpp"
|
||||||
#include "transact_log_handler.hpp"
|
#include "impl/transact_log_handler.hpp"
|
||||||
|
|
||||||
#include <realm/commit_log.hpp>
|
#include <realm/commit_log.hpp>
|
||||||
#include <realm/group_shared.hpp>
|
#include <realm/group_shared.hpp>
|
||||||
@ -84,6 +87,10 @@ Realm::Realm(Config config)
|
|||||||
throw RealmFileException(RealmFileException::Kind::Exists, ex.get_path(),
|
throw RealmFileException(RealmFileException::Kind::Exists, ex.get_path(),
|
||||||
"File at path '" + ex.get_path() + "' already exists.");
|
"File at path '" + ex.get_path() + "' already exists.");
|
||||||
}
|
}
|
||||||
|
catch (util::File::NotFound const& ex) {
|
||||||
|
throw RealmFileException(RealmFileException::Kind::NotFound, ex.get_path(),
|
||||||
|
"File at path '" + ex.get_path() + "' does not exist.");
|
||||||
|
}
|
||||||
catch (util::File::AccessError const& ex) {
|
catch (util::File::AccessError const& ex) {
|
||||||
throw RealmFileException(RealmFileException::Kind::AccessError, ex.get_path(),
|
throw RealmFileException(RealmFileException::Kind::AccessError, ex.get_path(),
|
||||||
"Unable to open a realm at path '" + ex.get_path() + "'");
|
"Unable to open a realm at path '" + ex.get_path() + "'");
|
||||||
@ -101,9 +108,11 @@ Realm::Realm(Config config)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Realm::~Realm() {
|
Realm::~Realm() {
|
||||||
|
#if __APPLE__
|
||||||
if (m_notifier) { // might not exist yet if an error occurred during init
|
if (m_notifier) { // might not exist yet if an error occurred during init
|
||||||
m_notifier->remove_realm(this);
|
m_notifier->remove_realm(this);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Group *Realm::read_group()
|
Group *Realm::read_group()
|
||||||
@ -154,11 +163,15 @@ SharedRealm Realm::get_shared_realm(Config config)
|
|||||||
// FIXME - need to validate that schemas match
|
// FIXME - need to validate that schemas match
|
||||||
realm->m_config.schema = std::make_unique<Schema>(*existing->m_config.schema);
|
realm->m_config.schema = std::make_unique<Schema>(*existing->m_config.schema);
|
||||||
|
|
||||||
|
#if __APPLE__
|
||||||
realm->m_notifier = existing->m_notifier;
|
realm->m_notifier = existing->m_notifier;
|
||||||
realm->m_notifier->add_realm(realm.get());
|
realm->m_notifier->add_realm(realm.get());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
#if __APPLE__
|
||||||
realm->m_notifier = std::make_shared<ExternalCommitHelper>(realm.get());
|
realm->m_notifier = std::make_shared<ExternalCommitHelper>(realm.get());
|
||||||
|
#endif
|
||||||
|
|
||||||
// otherwise get the schema from the group
|
// otherwise get the schema from the group
|
||||||
realm->m_config.schema = std::make_unique<Schema>(ObjectStore::schema_from_group(realm->read_group()));
|
realm->m_config.schema = std::make_unique<Schema>(ObjectStore::schema_from_group(realm->read_group()));
|
||||||
@ -290,7 +303,9 @@ void Realm::commit_transaction()
|
|||||||
|
|
||||||
m_in_transaction = false;
|
m_in_transaction = false;
|
||||||
transaction::commit(*m_shared_group, *m_history, m_binding_context.get());
|
transaction::commit(*m_shared_group, *m_history, m_binding_context.get());
|
||||||
|
#if __APPLE__
|
||||||
m_notifier->notify_others();
|
m_notifier->notify_others();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Realm::cancel_transaction()
|
void Realm::cancel_transaction()
|
||||||
@ -398,15 +413,17 @@ uint64_t Realm::get_schema_version(const realm::Realm::Config &config)
|
|||||||
|
|
||||||
void Realm::close()
|
void Realm::close()
|
||||||
{
|
{
|
||||||
|
#if __APPLE__
|
||||||
if (m_notifier) {
|
if (m_notifier) {
|
||||||
m_notifier->remove_realm(this);
|
m_notifier->remove_realm(this);
|
||||||
}
|
}
|
||||||
|
m_notifier = nullptr;
|
||||||
|
#endif
|
||||||
|
|
||||||
m_group = nullptr;
|
m_group = nullptr;
|
||||||
m_shared_group = nullptr;
|
m_shared_group = nullptr;
|
||||||
m_history = nullptr;
|
m_history = nullptr;
|
||||||
m_read_only_group = nullptr;
|
m_read_only_group = nullptr;
|
||||||
m_notifier = nullptr;
|
|
||||||
m_binding_context = nullptr;
|
m_binding_context = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
namespace realm {
|
namespace realm {
|
||||||
class ClientHistory;
|
class ClientHistory;
|
||||||
@ -124,7 +125,9 @@ namespace realm {
|
|||||||
|
|
||||||
Group *m_group = nullptr;
|
Group *m_group = nullptr;
|
||||||
|
|
||||||
|
#if __APPLE__
|
||||||
std::shared_ptr<_impl::ExternalCommitHelper> m_notifier;
|
std::shared_ptr<_impl::ExternalCommitHelper> m_notifier;
|
||||||
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::unique_ptr<BindingContext> m_binding_context;
|
std::unique_ptr<BindingContext> m_binding_context;
|
||||||
|
@ -1,29 +1,29 @@
|
|||||||
/* Copyright 2015 Realm Inc - All Rights Reserved
|
/* Copyright 2016 Realm Inc - All Rights Reserved
|
||||||
* Proprietary and Confidential
|
* Proprietary and Confidential
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
#ifndef REALM_PLATFORM_HPP
|
|
||||||
#define REALM_PLATFORM_HPP
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace realm {
|
extern std::string s_default_realm_directory;
|
||||||
|
|
||||||
|
namespace realm {
|
||||||
//
|
//
|
||||||
// These methods are used internally and must be implemented
|
// These methods are used internally and must be implemented
|
||||||
// separately for eadh platform
|
// separately for each platform
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// set the directory where realm files should be stored
|
||||||
|
void set_default_realm_file_directory(std::string dir);
|
||||||
|
|
||||||
// return the directory in which realm files can/should be written to
|
// return the directory in which realm files can/should be written to
|
||||||
std::string default_realm_file_directory();
|
std::string default_realm_file_directory();
|
||||||
|
|
||||||
// create the directories for the given filename
|
// create the directories for the given filename
|
||||||
void ensure_directory_exists_for_file(const std::string &file);
|
void ensure_directory_exists_for_file(const std::string &file);
|
||||||
|
|
||||||
// remoave all realm files in the given directory
|
// remove all realm files in the given directory
|
||||||
void remove_realm_files_from_directory(const std::string &directory);
|
void remove_realm_files_from_directory(const std::string &directory);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* REALM_PLATFORM_HPP */
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* Proprietary and Confidential
|
* Proprietary and Confidential
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import "rpc.hpp"
|
#include "rpc.hpp"
|
||||||
|
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
@ -18,6 +18,7 @@
|
|||||||
#include "object_accessor.hpp"
|
#include "object_accessor.hpp"
|
||||||
#include "shared_realm.hpp"
|
#include "shared_realm.hpp"
|
||||||
#include "results.hpp"
|
#include "results.hpp"
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
using RJSAccessor = realm::NativeAccessor<JSValueRef, JSContextRef>;
|
using RJSAccessor = realm::NativeAccessor<JSValueRef, JSContextRef>;
|
||||||
using namespace realm_js;
|
using namespace realm_js;
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#import "json.hpp"
|
#include "json.hpp"
|
||||||
#import <JavaScriptCore/JavaScriptCore.h>
|
#include <JavaScriptCore/JSBase.h>
|
||||||
|
|
||||||
namespace realm {
|
namespace realm {
|
||||||
class ObjectSchema;
|
class ObjectSchema;
|
||||||
|
@ -12,8 +12,8 @@
|
|||||||
@implementation GrammerTests
|
@implementation GrammerTests
|
||||||
|
|
||||||
- (void)testGrammer {
|
- (void)testGrammer {
|
||||||
realm::parser::analyzeGrammar();
|
realm::parser::analyze_grammar();
|
||||||
XCTAssertTrue(realm::parser::testGrammar());
|
XCTAssertTrue(realm::parser::test_grammar());
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -62,7 +62,8 @@ function runQuerySuite(suite) {
|
|||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var test of suite.tests) {
|
for (var index in suite.tests) {
|
||||||
|
var test = suite.tests[index];
|
||||||
if (test[0] == "QueryCount") {
|
if (test[0] == "QueryCount") {
|
||||||
var length = realm.objects.apply(realm, getArgs(2)).length;
|
var length = realm.objects.apply(realm, getArgs(2)).length;
|
||||||
TestCase.assertEqual(test[1], length, "Query '" + args[1] + "' on type '" + args[0] + "' expected " + test[1] + " results, got " + length);
|
TestCase.assertEqual(test[1], length, "Query '" + args[1] + "' on type '" + args[0] + "' expected " + test[1] + " results, got " + length);
|
||||||
|
@ -95,9 +95,8 @@ module.exports = BaseTest.extend({
|
|||||||
var newPath = util.realmPathForFile('default2.realm');
|
var newPath = util.realmPathForFile('default2.realm');
|
||||||
Realm.defaultPath = newPath;
|
Realm.defaultPath = newPath;
|
||||||
defaultRealm = new Realm({schema: []});
|
defaultRealm = new Realm({schema: []});
|
||||||
TestCase.assertEqual(defaultRealm.path, newPath);
|
TestCase.assertEqual(defaultRealm.path, newPath, "should use updated default realm path");
|
||||||
TestCase.assertEqual(Realm.defaultPath, newPath);
|
TestCase.assertEqual(Realm.defaultPath, newPath, "defaultPath should have been updated");
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
testRealmCreate: function() {
|
testRealmCreate: function() {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
apply plugin: 'android-sdk-manager'
|
||||||
apply plugin: "com.android.application"
|
apply plugin: "com.android.application"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -54,7 +55,7 @@ android {
|
|||||||
buildToolsVersion "23.0.1"
|
buildToolsVersion "23.0.1"
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.reacttests"
|
applicationId "io.realm.react.testapp"
|
||||||
minSdkVersion 16
|
minSdkVersion 16
|
||||||
targetSdkVersion 22
|
targetSdkVersion 22
|
||||||
versionCode 1
|
versionCode 1
|
||||||
@ -72,7 +73,8 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile fileTree(dir: "libs", include: ["*.jar"])
|
compile 'com.android.support:appcompat-v7:23.0.1'
|
||||||
compile "com.android.support:appcompat-v7:23.0.1"
|
compile 'com.facebook.react:react-native:0.18.0'
|
||||||
compile "com.facebook.react:react-native:0.14.+"
|
compile project(':realm')
|
||||||
|
compile project(':react-native-fs')
|
||||||
}
|
}
|
||||||
|
BIN
tests/react-test-app/android/app/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
tests/react-test-app/android/app/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
6
tests/react-test-app/android/app/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
6
tests/react-test-app/android/app/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#Wed Oct 21 11:34:03 PDT 2015
|
||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-all.zip
|
160
tests/react-test-app/android/app/gradlew
vendored
Executable file
160
tests/react-test-app/android/app/gradlew
vendored
Executable file
@ -0,0 +1,160 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
##
|
||||||
|
## Gradle start up script for UN*X
|
||||||
|
##
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS=""
|
||||||
|
|
||||||
|
APP_NAME="Gradle"
|
||||||
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
MAX_FD="maximum"
|
||||||
|
|
||||||
|
warn ( ) {
|
||||||
|
echo "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
die ( ) {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# OS specific support (must be 'true' or 'false').
|
||||||
|
cygwin=false
|
||||||
|
msys=false
|
||||||
|
darwin=false
|
||||||
|
case "`uname`" in
|
||||||
|
CYGWIN* )
|
||||||
|
cygwin=true
|
||||||
|
;;
|
||||||
|
Darwin* )
|
||||||
|
darwin=true
|
||||||
|
;;
|
||||||
|
MINGW* )
|
||||||
|
msys=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
PRG="$0"
|
||||||
|
# Need this for relative symlinks.
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG=`dirname "$PRG"`"/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
SAVED="`pwd`"
|
||||||
|
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||||
|
APP_HOME="`pwd -P`"
|
||||||
|
cd "$SAVED" >/dev/null
|
||||||
|
|
||||||
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
# Determine the Java command to use to start the JVM.
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
fi
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD="java"
|
||||||
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increase the maximum file descriptors if we can.
|
||||||
|
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||||
|
MAX_FD_LIMIT=`ulimit -H -n`
|
||||||
|
if [ $? -eq 0 ] ; then
|
||||||
|
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||||
|
MAX_FD="$MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
ulimit -n $MAX_FD
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Darwin, add options to specify how the application appears in the dock
|
||||||
|
if $darwin; then
|
||||||
|
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin, switch paths to Windows format before running java
|
||||||
|
if $cygwin ; then
|
||||||
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
|
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||||
|
|
||||||
|
# We build the pattern for arguments to be converted via cygpath
|
||||||
|
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||||
|
SEP=""
|
||||||
|
for dir in $ROOTDIRSRAW ; do
|
||||||
|
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||||
|
SEP="|"
|
||||||
|
done
|
||||||
|
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||||
|
# Add a user-defined pattern to the cygpath arguments
|
||||||
|
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||||
|
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||||
|
fi
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
i=0
|
||||||
|
for arg in "$@" ; do
|
||||||
|
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||||
|
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||||
|
|
||||||
|
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||||
|
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||||
|
else
|
||||||
|
eval `echo args$i`="\"$arg\""
|
||||||
|
fi
|
||||||
|
i=$((i+1))
|
||||||
|
done
|
||||||
|
case $i in
|
||||||
|
(0) set -- ;;
|
||||||
|
(1) set -- "$args0" ;;
|
||||||
|
(2) set -- "$args0" "$args1" ;;
|
||||||
|
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
|
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
|
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
|
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
|
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
|
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
|
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||||
|
function splitJvmOpts() {
|
||||||
|
JVM_OPTS=("$@")
|
||||||
|
}
|
||||||
|
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||||
|
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||||
|
|
||||||
|
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user