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
|
@ -97,3 +97,10 @@ build/
|
|||
# node.js
|
||||
node_modules/
|
||||
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
|
||||
- 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)
|
||||
|
||||
### iOS
|
||||
- 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.
|
||||
- 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.
|
||||
- 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
|
||||
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:
|
||||
|
||||
- `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
|
||||
|
||||
### ObjectSchema
|
||||
|
|
|
@ -7,13 +7,24 @@
|
|||
# Some modules have their own node_modules with overlap
|
||||
.*/node_modules/node-haste/.*
|
||||
|
||||
# Ignore react-tools where there are overlaps, but don't ignore anything that
|
||||
# react-native relies on
|
||||
.*/node_modules/react-tools/src/vendor/core/ExecutionEnvironment.js
|
||||
.*/node_modules/react-tools/src/browser/eventPlugins/ResponderEventPlugin.js
|
||||
.*/node_modules/react-tools/src/browser/ui/React.js
|
||||
.*/node_modules/react-tools/src/core/ReactInstanceHandles.js
|
||||
.*/node_modules/react-tools/src/event/EventPropagators.js
|
||||
# Ugh
|
||||
.*/node_modules/babel.*
|
||||
.*/node_modules/babylon.*
|
||||
.*/node_modules/invariant.*
|
||||
|
||||
# Ignore react and fbjs where there are overlaps, but don't ignore
|
||||
# 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
|
||||
.*/node_modules/commoner/test/.*
|
||||
|
@ -22,7 +33,10 @@
|
|||
.*/react-tools/node_modules/commoner/lib/reader.js
|
||||
|
||||
# Ignore jest
|
||||
.*/react-native/node_modules/jest-cli/.*
|
||||
.*/node_modules/jest-cli/.*
|
||||
|
||||
# Ignore Website
|
||||
.*/website/.*
|
||||
|
||||
[include]
|
||||
|
||||
|
@ -32,13 +46,18 @@ node_modules/react-native/Libraries/react-native/react-native-interface.js
|
|||
[options]
|
||||
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=$FlowFixMe
|
||||
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\\)*\\$FlowIssue\\((\\(>=0\\.\\(1[0-3]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)? #[0-9]+
|
||||
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-8]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)? #[0-9]+
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
|
||||
|
||||
[version]
|
||||
0.13.1
|
||||
0.18.1
|
||||
|
|
|
@ -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
|
|
@ -0,0 +1 @@
|
|||
{}
|
|
@ -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')
|
||||
}
|
|
@ -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.**
|
|
@ -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>
|
|
@ -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" }
|
||||
}
|
||||
}
|
|
@ -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
|
Binary file not shown.
|
@ -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
|
|
@ -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 "$@"
|
|
@ -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
|
|
@ -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');
|
||||
|
||||
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: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'stretch',
|
||||
backgroundColor: '#ffffff',
|
||||
backgroundColor: '#fff',
|
||||
},
|
||||
navigator: {
|
||||
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: {
|
||||
borderColor: "#c8c7cc",
|
||||
borderColor: '#c8c7cc',
|
||||
borderBottomWidth: 0.5,
|
||||
alignItems: 'stretch',
|
||||
alignSelf: 'stretch',
|
||||
justifyContent: 'center',
|
||||
flexDirection: 'row',
|
||||
flex: 1,
|
||||
height: 44,
|
||||
|
@ -34,20 +71,26 @@ module.exports = React.StyleSheet.create({
|
|||
listItemCheckbox: {
|
||||
borderColor: '#ccc',
|
||||
borderWidth: 1,
|
||||
textAlign: 'center',
|
||||
width: 16,
|
||||
height: 16,
|
||||
lineHeight: 14,
|
||||
},
|
||||
listItemCheckboxText: {
|
||||
width: 14,
|
||||
height: 14,
|
||||
fontSize: iOS ? 14 : 10,
|
||||
textAlign: 'center',
|
||||
},
|
||||
listItemCount: {
|
||||
borderColor: '#ccc',
|
||||
borderWidth: 1,
|
||||
borderRadius: 8,
|
||||
textAlign: 'center',
|
||||
fontSize: 12,
|
||||
width: 24,
|
||||
height: 18,
|
||||
lineHeight: 16,
|
||||
},
|
||||
listItemCountText: {
|
||||
backgroundColor: 'transparent',
|
||||
fontSize: iOS ? 12 : 11,
|
||||
textAlign: 'center',
|
||||
},
|
||||
listItemInput: {
|
||||
fontFamily: 'System',
|
||||
|
@ -56,16 +99,17 @@ module.exports = React.StyleSheet.create({
|
|||
flex: 1,
|
||||
},
|
||||
listItemText: {
|
||||
alignSelf: 'center',
|
||||
fontFamily: 'System',
|
||||
fontSize: 15,
|
||||
flexDirection: 'column',
|
||||
flex: 1,
|
||||
lineHeight: 30,
|
||||
},
|
||||
listItemTextSpecial: {
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
listItemDelete: {
|
||||
backgroundColor: 'transparent',
|
||||
paddingLeft: 12,
|
||||
paddingRight: 12,
|
||||
flexDirection: 'column',
|
||||
|
|
|
@ -10,7 +10,13 @@ const TodoListView = require('./todo-listview');
|
|||
const realm = require('./realm');
|
||||
const styles = require('./styles');
|
||||
|
||||
const { NavigatorIOS } = React;
|
||||
const {
|
||||
Navigator,
|
||||
StatusBarIOS,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} = React;
|
||||
|
||||
class TodoApp extends React.Component {
|
||||
constructor(props) {
|
||||
|
@ -25,6 +31,12 @@ class TodoApp extends React.Component {
|
|||
|
||||
// This is a Results object, which will live-update.
|
||||
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 = {};
|
||||
}
|
||||
|
||||
|
@ -33,6 +45,12 @@ class TodoApp extends React.Component {
|
|||
return refs.listItemView || refs.listView;
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
if (StatusBarIOS) {
|
||||
StatusBarIOS.setStyle('light-content');
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
let extraItems = [
|
||||
{name: 'Complete', items: realm.objects('Todo', 'done = true')},
|
||||
|
@ -46,16 +64,31 @@ class TodoApp extends React.Component {
|
|||
ref: 'listView',
|
||||
items: this.todoLists,
|
||||
extraItems: extraItems,
|
||||
onPressItem: (list) => this._onPressTodoList(list),
|
||||
onPressItem: this._onPressTodoList,
|
||||
},
|
||||
backButtonTitle: 'Lists',
|
||||
rightButtonTitle: 'Add',
|
||||
onRightButtonPress: () => this._addNewTodoList(),
|
||||
onRightButtonPress: this._addNewTodoList,
|
||||
};
|
||||
|
||||
return (
|
||||
<NavigatorIOS ref="nav" initialRoute={route} style={styles.navigator} />
|
||||
let navigationBar = (
|
||||
<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) {
|
||||
|
@ -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;
|
||||
|
|
|
@ -38,10 +38,12 @@ class TodoItem extends TodoListItem {
|
|||
return (
|
||||
<TouchableWithoutFeedback onPress={this._onPressCheckbox}>
|
||||
<View style={styles.listItemLeftSide}>
|
||||
<Text style={styles.listItemCheckbox}>
|
||||
<View style={styles.listItemCheckbox}>
|
||||
<Text style={styles.listItemCheckboxText}>
|
||||
{this.done ? '✓' : ''}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -8,7 +8,15 @@ const React = require('react-native');
|
|||
const realm = require('./realm');
|
||||
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 {
|
||||
constructor(props) {
|
||||
|
@ -90,7 +98,7 @@ class TodoListItem extends React.Component {
|
|||
return (
|
||||
<TouchableWithoutFeedback onPress={this.props.onPressDelete}>
|
||||
<View style={styles.listItemDelete}>
|
||||
<Text>𐄂</Text>
|
||||
<Text>{iOS ? '𐄂' : '×'}</Text>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
);
|
||||
|
|
|
@ -162,10 +162,12 @@ class TodoListExtraItem extends TodoListItem {
|
|||
renderLeftSide() {
|
||||
return (
|
||||
<View style={styles.listItemLeftSide}>
|
||||
<Text style={styles.listItemCount}>
|
||||
<View style={styles.listItemCount}>
|
||||
<Text style={styles.listItemCountText}>
|
||||
{this.props.item.items.length}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
|
@ -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
|
|
@ -0,0 +1 @@
|
|||
*.orig
|
|
@ -4,11 +4,16 @@
|
|||
"private": true,
|
||||
"main": "lib/index.js",
|
||||
"files": [
|
||||
"android",
|
||||
"lib",
|
||||
"react-native",
|
||||
"scripts",
|
||||
"src",
|
||||
"vendor",
|
||||
"RealmJS.xcodeproj"
|
||||
]
|
||||
],
|
||||
"scripts": {
|
||||
"test": "scripts/test.sh",
|
||||
"prepublish": "scripts/prepublish.sh"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
android/
|
||||
|
||||
*.orig
|
|
@ -0,0 +1 @@
|
|||
downloads/
|
|
@ -0,0 +1,5 @@
|
|||
build/
|
||||
|
||||
.idea
|
||||
.gradle
|
||||
local.properties
|
|
@ -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'
|
||||
}
|
|
@ -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
|
Binary file not shown.
|
@ -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
|
|
@ -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 "$@"
|
|
@ -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
|
|
@ -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'
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
core/
|
|
@ -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)
|
|
@ -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
|
|
@ -0,0 +1 @@
|
|||
JavaScriptCore/
|
|
@ -0,0 +1 @@
|
|||
../../../../../src/
|
|
@ -0,0 +1 @@
|
|||
../../../../../vendor
|
|
@ -0,0 +1 @@
|
|||
*.orig
|
|
@ -3,7 +3,7 @@
|
|||
set -e
|
||||
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}"
|
||||
|
||||
|
|
|
@ -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 -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
|
||||
# different Xcode version
|
||||
pkill Simulator 2>/dev/null || true
|
||||
|
@ -11,20 +21,37 @@ while pgrep -q Simulator; do
|
|||
pkill -9 Simulator 2>/dev/null || true
|
||||
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\}')"
|
||||
TARGET=$1
|
||||
CONFIGURATION=${2:-"Debug"}
|
||||
PACKAGER_OUT="packager_out.txt"
|
||||
# Inform the prepublish script to skip building Android modules.
|
||||
export SKIP_ANDROID_BUILD=1
|
||||
fi
|
||||
|
||||
function start_packager()
|
||||
{
|
||||
rm -f $PACKAGER_OUT
|
||||
sh ./node_modules/react-native/packager/packager.sh | tee packager_out.txt &
|
||||
while :;
|
||||
do
|
||||
if grep -Fxq "React packager ready." packager_out.txt
|
||||
then
|
||||
PACKAGER_OUT="$SRCROOT/packager_out.txt"
|
||||
LOGCAT_OUT="$SRCROOT/logcat_out.txt"
|
||||
|
||||
cleanup() {
|
||||
# Kill all child processes.
|
||||
pkill -P $$ || true
|
||||
pkill node || true
|
||||
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
|
||||
else
|
||||
echo "Waiting for packager."
|
||||
|
@ -33,44 +60,87 @@ function start_packager()
|
|||
done
|
||||
}
|
||||
|
||||
function kill_packager()
|
||||
{
|
||||
rm -f $PACKAGER_OUT
|
||||
pkill node || true
|
||||
unlock_device() {
|
||||
adb shell input keyevent 82
|
||||
}
|
||||
|
||||
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
|
||||
elif [ "$TARGET" = "react-tests" ]; then
|
||||
;;
|
||||
"react-tests")
|
||||
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
|
||||
unzip -q ../../target=node_modules/react_tests_node_modules.zip
|
||||
fi
|
||||
|
||||
npm update react-native
|
||||
open_chrome
|
||||
start_packager
|
||||
popd
|
||||
|
||||
xcodebuild -scheme RealmReact -configuration "$CONFIGURATION" -sdk iphonesimulator $DESTINATION build test
|
||||
elif [ "$TARGET" = "react-example" ]; then
|
||||
;;
|
||||
"react-example")
|
||||
pushd examples/ReactExample
|
||||
|
||||
if [ -f ../../target=node_modules/react_example_node_modules.zip ]; then
|
||||
unzip -q ../../target=node_modules/react_example_node_modules.zip
|
||||
fi
|
||||
|
||||
npm update react-native
|
||||
start_packager
|
||||
|
||||
cd ios
|
||||
pushd ios
|
||||
xcodebuild -scheme ReactExample -configuration "$CONFIGURATION" -sdk iphonesimulator build $DESTINATION
|
||||
popd
|
||||
else
|
||||
echo "Invalid target '${TARGET}'"
|
||||
fi
|
||||
;;
|
||||
"react-tests-android")
|
||||
if [[ $CONFIGURATION == 'Debug' ]]; then
|
||||
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
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
*.orig
|
|
@ -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());
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
||||
*/
|
||||
|
||||
#import "js_init.h"
|
||||
#import "js_realm.hpp"
|
||||
#import "js_object.hpp"
|
||||
#import "js_util.hpp"
|
||||
#import "js_schema.hpp"
|
||||
#import "platform.hpp"
|
||||
#include "js_init.h"
|
||||
#include "js_realm.hpp"
|
||||
#include "js_object.hpp"
|
||||
#include "js_util.hpp"
|
||||
#include "js_schema.hpp"
|
||||
#include "platform.hpp"
|
||||
|
||||
#include "shared_realm.hpp"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
|
||||
extern "C" {
|
||||
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
* Proprietary and Confidential
|
||||
*/
|
||||
|
||||
#import <JavaScriptCore/JavaScriptCore.h>
|
||||
#pragma once
|
||||
|
||||
#include <JavaScriptCore/JSBase.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include "js_util.hpp"
|
||||
#include "object_accessor.hpp"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
using RJSAccessor = realm::NativeAccessor<JSValueRef, JSContextRef>;
|
||||
using namespace realm;
|
||||
|
||||
|
|
|
@ -2,9 +2,11 @@
|
|||
* Proprietary and Confidential
|
||||
*/
|
||||
|
||||
#import "js_util.hpp"
|
||||
#import "shared_realm.hpp"
|
||||
#import "list.hpp"
|
||||
#pragma once
|
||||
|
||||
#include "js_util.hpp"
|
||||
#include "shared_realm.hpp"
|
||||
#include "list.hpp"
|
||||
|
||||
JSClassRef RJSListClass();
|
||||
JSObjectRef RJSListCreate(JSContextRef ctx, realm::List &list);
|
||||
|
|
|
@ -2,15 +2,15 @@
|
|||
* Proprietary and Confidential
|
||||
*/
|
||||
|
||||
#import "js_util.hpp"
|
||||
#import "js_object.hpp"
|
||||
#import "js_results.hpp"
|
||||
#import "js_schema.hpp"
|
||||
#import "js_list.hpp"
|
||||
#import "js_realm.hpp"
|
||||
#include "js_util.hpp"
|
||||
#include "js_object.hpp"
|
||||
#include "js_results.hpp"
|
||||
#include "js_schema.hpp"
|
||||
#include "js_list.hpp"
|
||||
#include "js_realm.hpp"
|
||||
|
||||
#import "object_store.hpp"
|
||||
#import "object_accessor.hpp"
|
||||
#include "object_store.hpp"
|
||||
#include "object_accessor.hpp"
|
||||
|
||||
using RJSAccessor = realm::NativeAccessor<JSValueRef, JSContextRef>;
|
||||
using namespace realm;
|
||||
|
@ -63,6 +63,10 @@ JSObjectRef RJSObjectCreate(JSContextRef ctx, Object object) {
|
|||
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) {
|
||||
JSObjectRef object = RJSValidatedValueToObject(ctx, dict);
|
||||
JSStringRef propStr = RJSStringForString(prop_name);
|
||||
|
@ -218,8 +222,6 @@ template<> JSValueRef RJSAccessor::from_datetime(JSContextRef ctx, DateTime dt)
|
|||
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) {
|
||||
JSObjectRef object = RJSValidatedValueToObject(ctx, val);
|
||||
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) {
|
||||
return RJSListCreate(ctx, list);
|
||||
}
|
||||
|
||||
}
|
|
@ -2,7 +2,9 @@
|
|||
* Proprietary and Confidential
|
||||
*/
|
||||
|
||||
#import "js_util.hpp"
|
||||
#pragma once
|
||||
|
||||
#include "js_util.hpp"
|
||||
|
||||
namespace realm {
|
||||
class Object;
|
||||
|
|
|
@ -2,18 +2,19 @@
|
|||
* Proprietary and Confidential
|
||||
*/
|
||||
|
||||
#import "js_realm.hpp"
|
||||
#import "js_object.hpp"
|
||||
#import "js_results.hpp"
|
||||
#import "js_list.hpp"
|
||||
#import "js_schema.hpp"
|
||||
#import "platform.hpp"
|
||||
#include "js_realm.hpp"
|
||||
#include "js_object.hpp"
|
||||
#include "js_results.hpp"
|
||||
#include "js_list.hpp"
|
||||
#include "js_schema.hpp"
|
||||
#include "platform.hpp"
|
||||
|
||||
#import "shared_realm.hpp"
|
||||
#import "object_accessor.hpp"
|
||||
#import "binding_context.hpp"
|
||||
#include "shared_realm.hpp"
|
||||
#include "object_accessor.hpp"
|
||||
#include "binding_context.hpp"
|
||||
|
||||
#import <set>
|
||||
#include <set>
|
||||
#include <cassert>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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() {
|
||||
if (s_defaultPath.size() == 0) {
|
||||
s_defaultPath = realm::default_realm_file_directory() + "/default.realm";
|
||||
}
|
||||
return s_defaultPath;
|
||||
}
|
||||
void RJSSetDefaultPath(std::string path) {
|
||||
|
@ -158,7 +163,7 @@ JSObjectRef RealmConstructor(JSContextRef ctx, JSObjectRef constructor, size_t a
|
|||
static JSStringRef schemaString = JSStringCreateWithUTF8CString("schema");
|
||||
JSValueRef schemaValue = RJSValidatedPropertyValue(ctx, object, schemaString);
|
||||
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");
|
||||
|
@ -179,7 +184,7 @@ JSObjectRef RealmConstructor(JSContextRef ctx, JSObjectRef constructor, size_t a
|
|||
ensure_directory_exists_for_file(config.path);
|
||||
SharedRealm realm = Realm::get_shared_realm(config);
|
||||
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;
|
||||
RJSPrototypes(realm.get()) = prototypes;
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
* Proprietary and Confidential
|
||||
*/
|
||||
|
||||
#import "js_util.hpp"
|
||||
#pragma once
|
||||
|
||||
#include "js_util.hpp"
|
||||
#include <map>
|
||||
|
||||
namespace realm {
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
* Proprietary and Confidential
|
||||
*/
|
||||
|
||||
#import "js_results.hpp"
|
||||
#import "js_object.hpp"
|
||||
#import "object_accessor.hpp"
|
||||
#import "results.hpp"
|
||||
#import "parser.hpp"
|
||||
#import "query_builder.hpp"
|
||||
#include "js_results.hpp"
|
||||
#include "js_object.hpp"
|
||||
#include "object_accessor.hpp"
|
||||
#include "results.hpp"
|
||||
#include "parser.hpp"
|
||||
#include "query_builder.hpp"
|
||||
|
||||
using namespace realm;
|
||||
|
||||
|
@ -46,7 +46,7 @@ bool ResultsSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef proper
|
|||
try {
|
||||
std::string indexStr = RJSStringForJSString(propertyName);
|
||||
if (indexStr != "length") {
|
||||
std::stol(RJSStringForJSString(propertyName));
|
||||
stot<long>(RJSStringForJSString(propertyName));
|
||||
}
|
||||
|
||||
// attempts to assign to 'length' or an index should throw an exception
|
||||
|
|
|
@ -2,7 +2,10 @@
|
|||
* Proprietary and Confidential
|
||||
*/
|
||||
|
||||
#import "js_util.hpp"
|
||||
#pragma once
|
||||
|
||||
#include "js_util.hpp"
|
||||
#include <memory>
|
||||
|
||||
namespace realm {
|
||||
class Realm;
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
* Proprietary and Confidential
|
||||
*/
|
||||
|
||||
#import "js_schema.hpp"
|
||||
#import "object_store.hpp"
|
||||
#include "js_schema.hpp"
|
||||
#include "object_store.hpp"
|
||||
|
||||
namespace realm {
|
||||
struct SchemaWrapper {
|
||||
|
|
|
@ -2,8 +2,10 @@
|
|||
* Proprietary and Confidential
|
||||
*/
|
||||
|
||||
#import "js_util.hpp"
|
||||
#import <map>
|
||||
#pragma once
|
||||
|
||||
#include "js_util.hpp"
|
||||
#include <map>
|
||||
|
||||
namespace realm {
|
||||
class Schema;
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
* Proprietary and Confidential
|
||||
*/
|
||||
|
||||
#import "js_util.hpp"
|
||||
#include "js_util.hpp"
|
||||
#include <JavaScriptCore/JSStringRef.h>
|
||||
|
||||
using namespace realm;
|
||||
|
||||
|
@ -32,7 +33,7 @@ std::string RJSStringForJSString(JSStringRef jsString) {
|
|||
}
|
||||
|
||||
std::string RJSStringForValue(JSContextRef ctx, JSValueRef value) {
|
||||
JSValueRef exception = NULL;
|
||||
JSValueRef exception = nullptr;
|
||||
JSStringRef jsString = JSValueToStringCopy(ctx, value, &exception);
|
||||
if (!jsString) {
|
||||
throw RJSException(ctx, exception);
|
||||
|
|
|
@ -2,12 +2,22 @@
|
|||
* 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 <sstream>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <cmath>
|
||||
#include "property.hpp"
|
||||
#include "schema.hpp"
|
||||
|
||||
|
||||
template<typename T>
|
||||
inline void RJSFinalize(JSObjectRef object) {
|
||||
delete static_cast<T>(JSObjectGetPrivate(object));
|
||||
|
@ -173,8 +183,19 @@ static inline size_t RJSValidatedListLength(JSContextRef ctx, JSObjectRef object
|
|||
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) {
|
||||
long index = std::stol(indexStr);
|
||||
long index = stot<long>(indexStr);
|
||||
if (index < 0) {
|
||||
throw std::out_of_range(std::string("Index ") + indexStr + " cannot be less than zero.");
|
||||
}
|
||||
|
|
|
@ -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
|
||||
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_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_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_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); }
|
||||
|
@ -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_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 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
|
||||
bool optimize_table() { return true; }
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include <cstdlib>
|
||||
#include <vector>
|
||||
#include <stddef.h>
|
||||
|
||||
namespace realm {
|
||||
class IndexSet {
|
||||
|
|
|
@ -68,7 +68,7 @@ Query List::get_query() {
|
|||
void List::verify_valid_row(std::size_t row_ndx, bool insertion) {
|
||||
size_t size = m_link_view->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) :
|
||||
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) :
|
||||
|
@ -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 + "'";
|
||||
}
|
||||
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/link_view.hpp>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace realm {
|
||||
class ObjectSchemaValidationException;
|
||||
class Schema;
|
||||
|
@ -233,6 +235,13 @@ namespace realm {
|
|||
private:
|
||||
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) */
|
||||
|
|
|
@ -227,7 +227,7 @@ template<> struct action< or_op >
|
|||
template<> struct action< rule > { \
|
||||
static void apply( const input & in, ParserState & state ) { \
|
||||
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(sq_string_content, Expression::Type::String)
|
||||
|
@ -334,7 +334,7 @@ Predicate parse(const std::string &query)
|
|||
return std::move(out_predicate);
|
||||
}
|
||||
|
||||
void analyzeGrammar()
|
||||
void analyze_grammar()
|
||||
{
|
||||
analyze<pred>();
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ struct Expression
|
|||
{
|
||||
enum class Type { None, Number, String, KeyPath, Argument, True, False } type = Type::None;
|
||||
std::string s;
|
||||
Expression(Type t = Type::None, std::string s = "") : type(t), s(s) {}
|
||||
};
|
||||
|
||||
struct Predicate
|
||||
|
@ -78,8 +79,8 @@ struct Predicate
|
|||
|
||||
Predicate parse(const std::string &query);
|
||||
|
||||
void analyzeGrammar();
|
||||
bool testGrammar();
|
||||
void analyze_grammar();
|
||||
bool test_grammar();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,28 +29,41 @@ namespace realm {
|
|||
namespace query_builder {
|
||||
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
|
||||
// this should be used iff the condition being false indicates a bug in the caller
|
||||
// of the function checking its preconditions
|
||||
#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
|
||||
struct TrueExpression : realm::Expression {
|
||||
size_t find_first(size_t start, size_t end) const override
|
||||
class TrueExpression : public realm::Expression {
|
||||
public:
|
||||
virtual size_t find_first(size_t start, size_t end) const
|
||||
{
|
||||
if (start != end)
|
||||
return start;
|
||||
|
||||
return not_found;
|
||||
}
|
||||
void set_table() override {}
|
||||
const Table* get_table() const override { return nullptr; }
|
||||
virtual void set_table(const Table* table) {}
|
||||
virtual const Table* get_table() const { return nullptr; }
|
||||
};
|
||||
|
||||
struct FalseExpression : realm::Expression {
|
||||
size_t find_first(size_t, size_t) const override { return not_found; }
|
||||
void set_table() override {}
|
||||
const Table* get_table() const override { return nullptr; }
|
||||
class FalseExpression : public realm::Expression {
|
||||
public:
|
||||
virtual size_t find_first(size_t, size_t) const { return not_found; }
|
||||
virtual void set_table(const Table* table) {}
|
||||
virtual const Table* get_table() const { return nullptr; }
|
||||
};
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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) {
|
||||
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();
|
||||
}
|
||||
};
|
||||
|
@ -299,7 +312,7 @@ struct ValueGetter<bool, TableGetter> {
|
|||
static bool convert(TableGetter&&, const parser::Expression & value, Arguments &args)
|
||||
{
|
||||
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) {
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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) {
|
||||
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)
|
||||
{
|
||||
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.");
|
||||
}
|
||||
|
@ -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;
|
||||
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>
|
||||
|
|
|
@ -69,7 +69,7 @@ class ArgumentConverter : public Arguments
|
|||
|
||||
ValueType &argument_at(size_t index) {
|
||||
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];
|
||||
}
|
||||
|
|
|
@ -134,7 +134,7 @@ static std::vector<std::string> invalid_queries = {
|
|||
namespace realm {
|
||||
namespace parser {
|
||||
|
||||
bool testGrammar()
|
||||
bool test_grammar()
|
||||
{
|
||||
bool success = true;
|
||||
for (auto &query : valid_queries) {
|
||||
|
|
|
@ -36,19 +36,19 @@ using namespace realm;
|
|||
|
||||
Results::Results(SharedRealm r, const ObjectSchema &o, Query q, SortOrder s)
|
||||
: m_realm(std::move(r))
|
||||
, m_object_schema(&o)
|
||||
, m_query(std::move(q))
|
||||
, m_table(m_query.get_table().get())
|
||||
, m_sort(std::move(s))
|
||||
, m_mode(Mode::Query)
|
||||
, m_object_schema(&o)
|
||||
{
|
||||
}
|
||||
|
||||
Results::Results(SharedRealm r, const ObjectSchema &o, Table& table)
|
||||
: m_realm(std::move(r))
|
||||
, m_object_schema(&o)
|
||||
, m_table(&table)
|
||||
, m_mode(Mode::Table)
|
||||
, m_object_schema(&o)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -135,9 +135,10 @@ public:
|
|||
// The input index parameter was out of bounds
|
||||
struct OutOfBoundsIndexException : public std::out_of_range
|
||||
{
|
||||
OutOfBoundsIndexException(size_t r, size_t c) : requested(r), valid_count(c),
|
||||
std::out_of_range((std::string)"Requested index " + std::to_string(r) +
|
||||
" greater than max " + std::to_string(c)) {}
|
||||
OutOfBoundsIndexException(size_t r, size_t c) :
|
||||
std::out_of_range((std::string)"Requested index " + to_string(r) +
|
||||
" greater than max " + to_string(c)),
|
||||
requested(r), valid_count(c) {}
|
||||
const size_t requested;
|
||||
const size_t valid_count;
|
||||
};
|
||||
|
@ -150,7 +151,7 @@ public:
|
|||
// The input Row object belongs to a different table
|
||||
struct IncorrectTableException : public std::runtime_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 actual;
|
||||
};
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace realm {
|
||||
class ObjectSchema;
|
||||
|
|
|
@ -18,10 +18,13 @@
|
|||
|
||||
#include "shared_realm.hpp"
|
||||
|
||||
#if __APPLE__
|
||||
#include "external_commit_helper.hpp"
|
||||
#endif
|
||||
|
||||
#include "binding_context.hpp"
|
||||
#include "schema.hpp"
|
||||
#include "transact_log_handler.hpp"
|
||||
#include "impl/transact_log_handler.hpp"
|
||||
|
||||
#include <realm/commit_log.hpp>
|
||||
#include <realm/group_shared.hpp>
|
||||
|
@ -84,6 +87,10 @@ Realm::Realm(Config config)
|
|||
throw RealmFileException(RealmFileException::Kind::Exists, ex.get_path(),
|
||||
"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) {
|
||||
throw RealmFileException(RealmFileException::Kind::AccessError, ex.get_path(),
|
||||
"Unable to open a realm at path '" + ex.get_path() + "'");
|
||||
|
@ -101,9 +108,11 @@ Realm::Realm(Config config)
|
|||
}
|
||||
|
||||
Realm::~Realm() {
|
||||
#if __APPLE__
|
||||
if (m_notifier) { // might not exist yet if an error occurred during init
|
||||
m_notifier->remove_realm(this);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
Group *Realm::read_group()
|
||||
|
@ -154,11 +163,15 @@ SharedRealm Realm::get_shared_realm(Config config)
|
|||
// FIXME - need to validate that schemas match
|
||||
realm->m_config.schema = std::make_unique<Schema>(*existing->m_config.schema);
|
||||
|
||||
#if __APPLE__
|
||||
realm->m_notifier = existing->m_notifier;
|
||||
realm->m_notifier->add_realm(realm.get());
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
#if __APPLE__
|
||||
realm->m_notifier = std::make_shared<ExternalCommitHelper>(realm.get());
|
||||
#endif
|
||||
|
||||
// otherwise get the schema from the 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;
|
||||
transaction::commit(*m_shared_group, *m_history, m_binding_context.get());
|
||||
#if __APPLE__
|
||||
m_notifier->notify_others();
|
||||
#endif
|
||||
}
|
||||
|
||||
void Realm::cancel_transaction()
|
||||
|
@ -398,15 +413,17 @@ uint64_t Realm::get_schema_version(const realm::Realm::Config &config)
|
|||
|
||||
void Realm::close()
|
||||
{
|
||||
#if __APPLE__
|
||||
if (m_notifier) {
|
||||
m_notifier->remove_realm(this);
|
||||
}
|
||||
m_notifier = nullptr;
|
||||
#endif
|
||||
|
||||
m_group = nullptr;
|
||||
m_shared_group = nullptr;
|
||||
m_history = nullptr;
|
||||
m_read_only_group = nullptr;
|
||||
m_notifier = nullptr;
|
||||
m_binding_context = nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
|
||||
namespace realm {
|
||||
class ClientHistory;
|
||||
|
@ -124,7 +125,9 @@ namespace realm {
|
|||
|
||||
Group *m_group = nullptr;
|
||||
|
||||
#if __APPLE__
|
||||
std::shared_ptr<_impl::ExternalCommitHelper> m_notifier;
|
||||
#endif
|
||||
|
||||
public:
|
||||
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
|
||||
*/
|
||||
|
||||
|
||||
#ifndef REALM_PLATFORM_HPP
|
||||
#define REALM_PLATFORM_HPP
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace realm {
|
||||
extern std::string s_default_realm_directory;
|
||||
|
||||
namespace realm {
|
||||
//
|
||||
// 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
|
||||
std::string default_realm_file_directory();
|
||||
|
||||
// create the directories for the given filename
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
#endif /* REALM_PLATFORM_HPP */
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Proprietary and Confidential
|
||||
*/
|
||||
|
||||
#import "rpc.hpp"
|
||||
#include "rpc.hpp"
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <map>
|
||||
|
@ -18,6 +18,7 @@
|
|||
#include "object_accessor.hpp"
|
||||
#include "shared_realm.hpp"
|
||||
#include "results.hpp"
|
||||
#include <cassert>
|
||||
|
||||
using RJSAccessor = realm::NativeAccessor<JSValueRef, JSContextRef>;
|
||||
using namespace realm_js;
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#import "json.hpp"
|
||||
#import <JavaScriptCore/JavaScriptCore.h>
|
||||
#include "json.hpp"
|
||||
#include <JavaScriptCore/JSBase.h>
|
||||
|
||||
namespace realm {
|
||||
class ObjectSchema;
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
@implementation GrammerTests
|
||||
|
||||
- (void)testGrammer {
|
||||
realm::parser::analyzeGrammar();
|
||||
XCTAssertTrue(realm::parser::testGrammar());
|
||||
realm::parser::analyze_grammar();
|
||||
XCTAssertTrue(realm::parser::test_grammar());
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -62,7 +62,8 @@ function runQuerySuite(suite) {
|
|||
return args;
|
||||
}
|
||||
|
||||
for (var test of suite.tests) {
|
||||
for (var index in suite.tests) {
|
||||
var test = suite.tests[index];
|
||||
if (test[0] == "QueryCount") {
|
||||
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);
|
||||
|
|
|
@ -95,9 +95,8 @@ module.exports = BaseTest.extend({
|
|||
var newPath = util.realmPathForFile('default2.realm');
|
||||
Realm.defaultPath = newPath;
|
||||
defaultRealm = new Realm({schema: []});
|
||||
TestCase.assertEqual(defaultRealm.path, newPath);
|
||||
TestCase.assertEqual(Realm.defaultPath, newPath);
|
||||
|
||||
TestCase.assertEqual(defaultRealm.path, newPath, "should use updated default realm path");
|
||||
TestCase.assertEqual(Realm.defaultPath, newPath, "defaultPath should have been updated");
|
||||
},
|
||||
|
||||
testRealmCreate: function() {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
apply plugin: 'android-sdk-manager'
|
||||
apply plugin: "com.android.application"
|
||||
|
||||
/**
|
||||
|
@ -54,7 +55,7 @@ android {
|
|||
buildToolsVersion "23.0.1"
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.reacttests"
|
||||
applicationId "io.realm.react.testapp"
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 22
|
||||
versionCode 1
|
||||
|
@ -72,7 +73,8 @@ android {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
compile fileTree(dir: "libs", include: ["*.jar"])
|
||||
compile "com.android.support:appcompat-v7:23.0.1"
|
||||
compile "com.facebook.react:react-native:0.14.+"
|
||||
compile 'com.android.support:appcompat-v7:23.0.1'
|
||||
compile 'com.facebook.react:react-native:0.18.0'
|
||||
compile project(':realm')
|
||||
compile project(':react-native-fs')
|
||||
}
|
||||
|
|
Binary file not shown.
|
@ -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
|
|
@ -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…
Reference in New Issue