[sdks/android] Build Mentat Android SDK in TaskCluster; publish org.mozilla.mentat to nalexander's personal Bintray repo.
I haven't had this reviewed thoroughly, but it mostly works.
This commit is contained in:
commit
fba378ee39
28 changed files with 591 additions and 137 deletions
80
.taskcluster.yml
Normal file
80
.taskcluster.yml
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
version: 0
|
||||||
|
allowPullRequests: public
|
||||||
|
tasks:
|
||||||
|
####################################################################################################
|
||||||
|
# Task: Pull requests
|
||||||
|
####################################################################################################
|
||||||
|
- provisionerId: '{{ taskcluster.docker.provisionerId }}'
|
||||||
|
workerType: '{{ taskcluster.docker.workerType }}'
|
||||||
|
extra:
|
||||||
|
github:
|
||||||
|
env: true
|
||||||
|
events:
|
||||||
|
- pull_request.opened
|
||||||
|
- pull_request.edited
|
||||||
|
- pull_request.synchronize
|
||||||
|
- pull_request.reopened
|
||||||
|
- push
|
||||||
|
scopes:
|
||||||
|
- "queue:create-task:aws-provisioner-v1/github-worker"
|
||||||
|
- "queue:scheduler-id:taskcluster-github"
|
||||||
|
payload:
|
||||||
|
maxRunTime: 3600
|
||||||
|
deadline: "{{ '2 hours' | $fromNow }}"
|
||||||
|
image: 'mozillamobile/mentat:1.1'
|
||||||
|
command:
|
||||||
|
- /bin/bash
|
||||||
|
- '--login'
|
||||||
|
- '-cx'
|
||||||
|
- >-
|
||||||
|
export TERM=dumb
|
||||||
|
&& git fetch {{ event.head.repo.url }} {{ event.head.repo.branch }}
|
||||||
|
&& git config advice.detachedHead false
|
||||||
|
&& git checkout {{event.head.sha}}
|
||||||
|
&& python automation/taskcluster/decision_task_pull_request.py
|
||||||
|
features:
|
||||||
|
taskclusterProxy: true
|
||||||
|
metadata:
|
||||||
|
name: Mentat Android SDK - Pull Request
|
||||||
|
description: Building and testing the Mentat Android SDK - triggered by a pull request.
|
||||||
|
owner: '{{ event.head.user.email }}'
|
||||||
|
source: '{{ event.head.repo.url }}'
|
||||||
|
####################################################################################################
|
||||||
|
# Task: Release
|
||||||
|
####################################################################################################
|
||||||
|
- provisionerId: '{{ taskcluster.docker.provisionerId }}'
|
||||||
|
workerType: '{{ taskcluster.docker.workerType }}'
|
||||||
|
extra:
|
||||||
|
github:
|
||||||
|
events:
|
||||||
|
- release
|
||||||
|
scopes:
|
||||||
|
- "secrets:get:project/mentat/publish"
|
||||||
|
payload:
|
||||||
|
maxRunTime: 3600
|
||||||
|
deadline: "{{ '2 hours' | $fromNow }}"
|
||||||
|
image: 'mozillamobile/mentat:1.1'
|
||||||
|
command:
|
||||||
|
- /bin/bash
|
||||||
|
- '--login'
|
||||||
|
- '-cx'
|
||||||
|
- >-
|
||||||
|
export TERM=dumb
|
||||||
|
&& git fetch origin --tags
|
||||||
|
&& git config advice.detachedHead false
|
||||||
|
&& git checkout {{ event.version }}
|
||||||
|
&& python automation/taskcluster/release/fetch-bintray-api-key.py
|
||||||
|
&& cd sdks/android/Mentat
|
||||||
|
&& ./gradlew --no-daemon clean library:assembleRelease
|
||||||
|
&& ./gradlew bintrayUpload --debug
|
||||||
|
features:
|
||||||
|
taskclusterProxy: true
|
||||||
|
metadata:
|
||||||
|
name: Mentat Android SDK - Release ({{ event.version }})
|
||||||
|
description: Building and publishing release versions.
|
||||||
|
owner: '{{ event.head.user.email }}'
|
||||||
|
source: '{{ event.head.repo.url }}'
|
21
CHANGELOG.md
Normal file
21
CHANGELOG.md
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
# 0.10 (2018-07-26)
|
||||||
|
|
||||||
|
* sdks/android compiled against:
|
||||||
|
* Kotlin standard library 1.2.41
|
||||||
|
|
||||||
|
* **API changes**:
|
||||||
|
* `store_open{_encrypted}` now accepts an error parameter; corresponding constructors changed to be factory functions.
|
||||||
|
|
||||||
|
* [Commits](https://github.com/mozilla/mentat/compare/v0.9.0...v0.10.0)
|
||||||
|
|
||||||
|
# 0.9 (2018-07-25)
|
||||||
|
|
||||||
|
* sdks/android compiled against:
|
||||||
|
* Kotlin standard library 1.2.41
|
||||||
|
|
||||||
|
* **API changes**:
|
||||||
|
* Mentat partitions now enforce their integrity, denying entids that aren't already known.
|
||||||
|
|
||||||
|
* **sdks/android**: First version published to nalexander's personal bintray repository.
|
||||||
|
* Various bugfixes and refactorings (see commits below for details)
|
||||||
|
* [Commits](https://github.com/mozilla/mentat/compare/v0.8.1...v0.9.0)
|
|
@ -12,7 +12,7 @@ authors = [
|
||||||
"Thom Chiovoloni <tchiovoloni@mozilla.com>",
|
"Thom Chiovoloni <tchiovoloni@mozilla.com>",
|
||||||
]
|
]
|
||||||
name = "mentat"
|
name = "mentat"
|
||||||
version = "0.8.1"
|
version = "0.10.0"
|
||||||
build = "build/version.rs"
|
build = "build/version.rs"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
|
95
automation/docker/Dockerfile
Normal file
95
automation/docker/Dockerfile
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
FROM mozillamobile/android-components:1.4
|
||||||
|
|
||||||
|
MAINTAINER Nick Alexander "nalexander@mozilla.com"
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------------------------------------------------------
|
||||||
|
#-- Configuration -----------------------------------------------------------------------------------------------------
|
||||||
|
#----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ENV ANDROID_NDK_VERSION "r17b"
|
||||||
|
ENV PROJECT_REPOSITORY "https://github.com/mozilla/mentat.git"
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------------------------------------------------------
|
||||||
|
#-- System ------------------------------------------------------------------------------------------------------------
|
||||||
|
#----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
RUN apt-get update -qq
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------------------------------------------------------
|
||||||
|
#-- Android NDK (Android SDK comes from base `android-components` image) ----------------------------------------------
|
||||||
|
#----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
RUN mkdir -p /build
|
||||||
|
WORKDIR /build
|
||||||
|
|
||||||
|
# ENV ANDROID_HOME /build/android-sdk
|
||||||
|
# ENV ANDROID_SDK_HOME /build/android-sdk
|
||||||
|
ENV ANDROID_NDK_HOME /build/android-ndk
|
||||||
|
# ENV PATH ${PATH}:${ANDROID_NDK_HOME}/tools:${ANDROID_SDK_HOME}/tools/bin:${ANDROID_SDK_HOME}/platform-tools:/opt/tools:${ANDROID_SDK_HOME}/build-tools/${ANDROID_BUILD_TOOLS}
|
||||||
|
|
||||||
|
RUN curl -L https://dl.google.com/android/repository/android-ndk-${ANDROID_NDK_VERSION}-linux-x86_64.zip > ndk.zip \
|
||||||
|
&& unzip ndk.zip -d /build \
|
||||||
|
&& rm ndk.zip \
|
||||||
|
&& mv /build/android-ndk-${ANDROID_NDK_VERSION} ${ANDROID_NDK_HOME}
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------------------------------------------------------
|
||||||
|
#-- Rust (cribbed from https://github.com/rust-lang-nursery/docker-rust/blob/ced83778ec6fea7f63091a484946f95eac0ee611/1.27.1/stretch/Dockerfile)
|
||||||
|
#-- Rust after the Android NDK since Rust rolls forward more frequently.
|
||||||
|
#----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ENV RUSTUP_HOME=/usr/local/rustup \
|
||||||
|
CARGO_HOME=/usr/local/cargo \
|
||||||
|
PATH=/usr/local/cargo/bin:$PATH \
|
||||||
|
RUST_VERSION=1.27.1
|
||||||
|
|
||||||
|
RUN set -eux; \
|
||||||
|
rustArch='x86_64-unknown-linux-gnu'; rustupSha256='4d382e77fd6760282912d2d9beec5e260ec919efd3cb9bdb64fe1207e84b9d91'; \
|
||||||
|
url="https://static.rust-lang.org/rustup/archive/1.12.0/${rustArch}/rustup-init"; \
|
||||||
|
wget "$url"; \
|
||||||
|
echo "${rustupSha256} *rustup-init" | sha256sum -c -; \
|
||||||
|
chmod +x rustup-init; \
|
||||||
|
./rustup-init -y --no-modify-path --default-toolchain $RUST_VERSION; \
|
||||||
|
rm rustup-init; \
|
||||||
|
chmod -R a+w $RUSTUP_HOME $CARGO_HOME; \
|
||||||
|
rustup --version; \
|
||||||
|
cargo --version; \
|
||||||
|
rustc --version; \
|
||||||
|
rustup target add i686-linux-android; \
|
||||||
|
rustup target add arm-linux-androideabi; \
|
||||||
|
rustup target add aarch64-linux-android
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------------------------------------------------------
|
||||||
|
#-- Project -----------------------------------------------------------------------------------------------------------
|
||||||
|
#----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
RUN git clone $PROJECT_REPOSITORY
|
||||||
|
|
||||||
|
WORKDIR /build/mentat
|
||||||
|
|
||||||
|
# Temporary.
|
||||||
|
RUN git fetch origin build-android-sdk && git checkout origin/build-android-sdk && git show-ref HEAD
|
||||||
|
|
||||||
|
# Populate dependencies.
|
||||||
|
RUN ./sdks/android/Mentat/gradlew --no-daemon -p sdks/android/Mentat tasks
|
||||||
|
|
||||||
|
# Cache toolchains.
|
||||||
|
RUN ./sdks/android/Mentat/gradlew --no-daemon -p sdks/android/Mentat generateToolchains
|
||||||
|
|
||||||
|
# Build Rust.
|
||||||
|
RUN ./sdks/android/Mentat/gradlew --no-daemon -p sdks/android/Mentat cargoBuild
|
||||||
|
|
||||||
|
# Actually build. In the future, we might also test and lint (to cache additional dependencies).
|
||||||
|
RUN ./sdks/android/Mentat/gradlew --no-daemon -p sdks/android/Mentat assemble
|
||||||
|
|
||||||
|
# Drop built Rust artifacts.
|
||||||
|
RUN cargo clean
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------------------------------------------------------
|
||||||
|
# -- Cleanup ----------------------------------------------------------------------------------------------------------
|
||||||
|
#----------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
RUN apt-get clean
|
122
automation/taskcluster/decision_task_pull_request.py
Normal file
122
automation/taskcluster/decision_task_pull_request.py
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import taskcluster
|
||||||
|
import re
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
Decision task for pull requests
|
||||||
|
"""
|
||||||
|
|
||||||
|
TASK_ID = os.environ.get('TASK_ID')
|
||||||
|
REPO_URL = os.environ.get('GITHUB_HEAD_REPO_URL')
|
||||||
|
BRANCH = os.environ.get('GITHUB_HEAD_BRANCH')
|
||||||
|
COMMIT = os.environ.get('GITHUB_HEAD_SHA')
|
||||||
|
|
||||||
|
def fetch_module_names():
|
||||||
|
process = subprocess.Popen(["./gradlew", "--no-daemon", "printModules"], stdout=subprocess.PIPE,
|
||||||
|
cwd=os.path.join(os.getcwd(), "sdks", "android", "Mentat"))
|
||||||
|
(output, err) = process.communicate()
|
||||||
|
exit_code = process.wait()
|
||||||
|
|
||||||
|
if exit_code is not 0:
|
||||||
|
print "Gradle command returned error:", exit_code
|
||||||
|
|
||||||
|
return re.findall('module: (.*)', output, re.M)
|
||||||
|
|
||||||
|
|
||||||
|
def schedule_task(queue, taskId, task):
|
||||||
|
print "TASK", taskId
|
||||||
|
print json.dumps(task, indent=4, separators=(',', ': '))
|
||||||
|
|
||||||
|
result = queue.createTask(taskId, task)
|
||||||
|
print "RESULT", taskId
|
||||||
|
print json.dumps(result, indent=4, separators=(',', ': '))
|
||||||
|
|
||||||
|
|
||||||
|
def create_task(name, description, command):
|
||||||
|
created = datetime.datetime.now()
|
||||||
|
expires = taskcluster.fromNow('1 year')
|
||||||
|
deadline = taskcluster.fromNow('1 day')
|
||||||
|
|
||||||
|
return {
|
||||||
|
"workerType": 'github-worker',
|
||||||
|
"taskGroupId": TASK_ID,
|
||||||
|
"expires": taskcluster.stringDate(expires),
|
||||||
|
"retries": 5,
|
||||||
|
"created": taskcluster.stringDate(created),
|
||||||
|
"tags": {},
|
||||||
|
"priority": "lowest",
|
||||||
|
"schedulerId": "taskcluster-github",
|
||||||
|
"deadline": taskcluster.stringDate(deadline),
|
||||||
|
"dependencies": [ TASK_ID ],
|
||||||
|
"routes": [],
|
||||||
|
"scopes": [],
|
||||||
|
"requires": "all-completed",
|
||||||
|
"payload": {
|
||||||
|
"features": {},
|
||||||
|
"maxRunTime": 7200,
|
||||||
|
"image": "mozillamobile/mentat:1.1",
|
||||||
|
"command": [
|
||||||
|
"/bin/bash",
|
||||||
|
"--login",
|
||||||
|
"-cx",
|
||||||
|
"export TERM=dumb && git fetch %s %s && git config advice.detachedHead false && git checkout %s && cd sdks/android/Mentat && ./gradlew --no-daemon clean %s" % (REPO_URL, BRANCH, COMMIT, command)
|
||||||
|
],
|
||||||
|
"artifacts": {},
|
||||||
|
"deadline": taskcluster.stringDate(deadline)
|
||||||
|
},
|
||||||
|
"provisionerId": "aws-provisioner-v1",
|
||||||
|
"metadata": {
|
||||||
|
"name": name,
|
||||||
|
"description": description,
|
||||||
|
"owner": "nalexander@mozilla.com",
|
||||||
|
"source": "https://github.com/mozilla/mentat"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def create_module_task(module):
|
||||||
|
return create_task(
|
||||||
|
name='Mentat Android SDK - Module ' + module,
|
||||||
|
description='Building and testing module ' + module,
|
||||||
|
command=" ".join(map(lambda x: module + ":" + x, ['assemble', 'test', 'lint'])))
|
||||||
|
|
||||||
|
|
||||||
|
# def create_detekt_task():
|
||||||
|
# return create_task(
|
||||||
|
# name='Android Components - detekt',
|
||||||
|
# description='Running detekt over all modules',
|
||||||
|
# command='detektCheck')
|
||||||
|
|
||||||
|
|
||||||
|
# def create_ktlint_task():
|
||||||
|
# return create_task(
|
||||||
|
# name='Android Components - ktlint',
|
||||||
|
# description='Running ktlint over all modules',
|
||||||
|
# command='ktlint')
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
queue = taskcluster.Queue({ 'baseUrl': 'http://taskcluster/queue/v1' })
|
||||||
|
|
||||||
|
modules = fetch_module_names()
|
||||||
|
|
||||||
|
if len(modules) == 0:
|
||||||
|
print "Could not get module names from gradle"
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
for module in modules:
|
||||||
|
task = create_module_task(module)
|
||||||
|
task_id = taskcluster.slugId()
|
||||||
|
schedule_task(queue, task_id, task)
|
||||||
|
|
||||||
|
# schedule_task(queue, taskcluster.slugId(), create_detekt_task())
|
||||||
|
# schedule_task(queue, taskcluster.slugId(), create_ktlint_task())
|
28
automation/taskcluster/release/fetch-bintray-api-key.py
Normal file
28
automation/taskcluster/release/fetch-bintray-api-key.py
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
import os
|
||||||
|
import taskcluster
|
||||||
|
|
||||||
|
SECRET_NAME = 'project/mentat/publish'
|
||||||
|
TASKCLUSTER_BASE_URL = 'http://taskcluster/secrets/v1'
|
||||||
|
|
||||||
|
def fetch_publish_secrets(secret_name):
|
||||||
|
"""Fetch and return secrets from taskcluster's secret service"""
|
||||||
|
secrets = taskcluster.Secrets({'baseUrl': TASKCLUSTER_BASE_URL})
|
||||||
|
return secrets.get(secret_name)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Fetch the bintray user and api key from taskcluster's secret service
|
||||||
|
and save it to local.properties in the project root directory.
|
||||||
|
"""
|
||||||
|
data = fetch_publish_secrets(SECRET_NAME)
|
||||||
|
|
||||||
|
properties_file_path = os.path.join(os.path.dirname(__file__), '../../../sdks/android/Mentat/local.properties')
|
||||||
|
with open(properties_file_path, 'w') as properties_file:
|
||||||
|
properties_file.write("bintray.user=%s\n" % data['secret']['bintray_user'])
|
||||||
|
properties_file.write("bintray.apikey=%s\n" % data['secret']['bintray_apikey'])
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
|
@ -208,21 +208,19 @@ impl<'a, 'c> InProgressTransactResult<'a, 'c> {
|
||||||
/// A destructor `store_destroy` is provided for releasing the memory for this
|
/// A destructor `store_destroy` is provided for releasing the memory for this
|
||||||
/// pointer type.
|
/// pointer type.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn store_open(uri: *const c_char) -> *mut Store {
|
pub unsafe extern "C" fn store_open(uri: *const c_char, error: *mut ExternError) -> *mut Store {
|
||||||
assert_not_null!(uri);
|
assert_not_null!(uri);
|
||||||
let uri = c_char_to_string(uri);
|
let uri = c_char_to_string(uri);
|
||||||
let store = Store::open(&uri).expect("expected a store");
|
translate_result(Store::open(&uri), error)
|
||||||
Box::into_raw(Box::new(store))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Variant of store_open that opens an encrypted database.
|
/// Variant of store_open that opens an encrypted database.
|
||||||
#[cfg(feature = "sqlcipher")]
|
#[cfg(feature = "sqlcipher")]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn store_open_encrypted(uri: *const c_char, key: *const c_char) -> *mut Store {
|
pub unsafe extern "C" fn store_open_encrypted(uri: *const c_char, key: *const c_char, error: *mut ExternError) -> *mut Store {
|
||||||
let uri = c_char_to_string(uri);
|
let uri = c_char_to_string(uri);
|
||||||
let key = c_char_to_string(key);
|
let key = c_char_to_string(key);
|
||||||
let store = Store::open_with_key(&uri, &key).expect("expected a store");
|
translate_result(Store::open_with_key(&uri, &key), error)
|
||||||
Box::into_raw(Box::new(store))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: open empty
|
// TODO: open empty
|
||||||
|
|
|
@ -4,27 +4,32 @@ buildscript {
|
||||||
ext.kotlin_version = '1.2.41'
|
ext.kotlin_version = '1.2.41'
|
||||||
|
|
||||||
ext.library = [
|
ext.library = [
|
||||||
version: '0.3.1'
|
version: '0.10.0'
|
||||||
]
|
]
|
||||||
|
|
||||||
ext.build = [
|
ext.build = [
|
||||||
compileSdkVersion: 27,
|
compileSdkVersion: 27,
|
||||||
targetSdkVersion: 27,
|
targetSdkVersion: 27,
|
||||||
minSdkVersion: 19
|
minSdkVersion: 21, // So that we can publish for aarch64.
|
||||||
]
|
]
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
jcenter()
|
jcenter()
|
||||||
google()
|
google()
|
||||||
|
maven {
|
||||||
|
url "https://plugins.gradle.org/m2/"
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:3.1.2'
|
classpath 'com.android.tools.build:gradle:3.1.3'
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
|
|
||||||
// Publish.
|
// Publish.
|
||||||
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3'
|
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3'
|
||||||
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
|
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
|
||||||
|
|
||||||
|
classpath 'gradle.plugin.org.mozilla.rust-android-gradle:plugin:0.0.4'
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
// in the individual module build.gradle files
|
// in the individual module build.gradle files
|
||||||
}
|
}
|
||||||
|
@ -32,11 +37,19 @@ buildscript {
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
jcenter()
|
|
||||||
google()
|
google()
|
||||||
|
jcenter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task clean(type: Delete) {
|
task clean(type: Delete) {
|
||||||
delete rootProject.buildDir
|
delete rootProject.buildDir
|
||||||
}
|
}
|
||||||
|
|
||||||
|
task printModules {
|
||||||
|
doLast {
|
||||||
|
subprojects.each { p ->
|
||||||
|
println "module: " + p.path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
# Specifies the JVM arguments used for the daemon process.
|
# Specifies the JVM arguments used for the daemon process.
|
||||||
# The setting is particularly useful for tweaking memory settings.
|
# The setting is particularly useful for tweaking memory settings.
|
||||||
org.gradle.jvmargs=-Xmx1536m
|
org.gradle.jvmargs=-Xmx1536m
|
||||||
|
org.gradle.configureondemand=false
|
||||||
|
|
||||||
# When configured, Gradle will run in incubating parallel mode.
|
# When configured, Gradle will run in incubating parallel mode.
|
||||||
# This option should only be used with decoupled projects. More details, visit
|
# This option should only be used with decoupled projects. More details, visit
|
||||||
|
@ -17,10 +18,11 @@ org.gradle.jvmargs=-Xmx1536m
|
||||||
# org.gradle.parallel=true
|
# org.gradle.parallel=true
|
||||||
|
|
||||||
libGroupId=org.mozilla.mentat
|
libGroupId=org.mozilla.mentat
|
||||||
libRepositoryName=Mentat
|
libRepositoryName=mentat
|
||||||
libProjectName=mentat
|
libProjectName=mentat
|
||||||
libProjectDescription=A persistent, relational store inspired by Datomic and DataScript.
|
libProjectDescription=A persistent, relational store inspired by Datomic and DataScript.
|
||||||
libUrl=https://github.com/mozilla/mentat
|
libUrl=https://github.com/mozilla/mentat
|
||||||
libVcsUrl=https://github.com/mozilla/mentat.git
|
libVcsUrl=https://github.com/mozilla/mentat.git
|
||||||
|
|
||||||
libLicense=MPL-2.0
|
libLicense 'Apache-2.0'
|
||||||
|
libLicenseUrl 'http://www.apache.org/licenses/LICENSE-2.0.txt'
|
||||||
|
|
|
@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.7-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-4.5-all.zip
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
apply plugin: 'com.android.library'
|
apply plugin: 'com.android.library'
|
||||||
|
apply plugin: 'org.mozilla.rust-android-gradle.rust-android'
|
||||||
|
|
||||||
apply plugin: 'kotlin-android'
|
apply plugin: 'kotlin-android'
|
||||||
apply plugin: 'com.jfrog.bintray'
|
apply plugin: 'com.jfrog.bintray'
|
||||||
// Simply applying this plugin gets bintray to publish a pom file.
|
// Simply applying this plugin gets bintray to publish a pom file.
|
||||||
|
@ -31,71 +33,56 @@ android {
|
||||||
lintOptions {
|
lintOptions {
|
||||||
abortOnError false
|
abortOnError false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Help folks debugging by including symbols in our native libraries. Yes, this makes the
|
||||||
|
// resulting AAR very large. The Android ecosystem seems to be in flux around who is in charge
|
||||||
|
// of stripping native binaries, but for now let's provide symbols and see how consumers react.
|
||||||
|
packagingOptions {
|
||||||
|
doNotStrip "**/*.so"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cargo {
|
||||||
|
module = '../../../../ffi'
|
||||||
|
targetDirectory = '../../../../target'
|
||||||
|
targetInclude = 'libmentat_ffi.so'
|
||||||
|
|
||||||
|
targets = [
|
||||||
|
'x86',
|
||||||
|
'arm',
|
||||||
|
'arm64',
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
|
||||||
androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
|
|
||||||
exclude group: 'com.android.support', module: 'support-annotations'
|
|
||||||
})
|
|
||||||
androidTestImplementation 'com.android.support:support-annotations:27.1.1'
|
androidTestImplementation 'com.android.support:support-annotations:27.1.1'
|
||||||
androidTestImplementation 'com.android.support.test:runner:1.0.2'
|
androidTestImplementation 'com.android.support.test:runner:1.0.2'
|
||||||
androidTestImplementation 'com.android.support.test:rules:1.0.2'
|
androidTestImplementation 'com.android.support.test:rules:1.0.2'
|
||||||
implementation 'com.android.support:appcompat-v7:27.1.1'
|
|
||||||
implementation 'com.android.support.constraint:constraint-layout:1.1.0'
|
|
||||||
implementation 'com.android.support:design:27.1.1'
|
|
||||||
testImplementation 'junit:junit:4.12'
|
testImplementation 'junit:junit:4.12'
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||||
implementation 'net.java.dev.jna:jna:4.5.1'
|
implementation 'net.java.dev.jna:jna:4.5.2@aar'
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Publishing to jcenter/bintray.
|
afterEvaluate {
|
||||||
def libGroupId = properties.libGroupId
|
// The `cargoBuild` tasks isn't available until after evaluation.
|
||||||
def libRepoName = properties.libRepositoryName
|
android.libraryVariants.all { variant ->
|
||||||
def libProjectName = properties.libProjectName
|
def productFlavor = ""
|
||||||
def libProjectDescription = properties.libProjectDescription
|
variant.productFlavors.each {
|
||||||
def libUrl = properties.libUrl
|
productFlavor += "${it.name.capitalize()}"
|
||||||
def libVcsUrl = properties.libVcsUrl
|
|
||||||
def libLicense = properties.libLicense
|
|
||||||
|
|
||||||
Properties localProperties = null
|
|
||||||
if (project.rootProject.file('local.properties').canRead()) {
|
|
||||||
localProperties = new Properties()
|
|
||||||
localProperties.load(project.rootProject.file('local.properties').newDataInputStream())
|
|
||||||
}
|
}
|
||||||
|
def buildType = "${variant.buildType.name.capitalize()}"
|
||||||
version = rootProject.ext.library['version']
|
tasks["generate${productFlavor}${buildType}Assets"].dependsOn(tasks["cargoBuild"])
|
||||||
|
|
||||||
task sourcesJar(type: Jar) {
|
|
||||||
from android.sourceSets.main.java.srcDirs
|
|
||||||
classifier = 'sources'
|
|
||||||
}
|
|
||||||
|
|
||||||
artifacts {
|
|
||||||
archives sourcesJar
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
group = libGroupId
|
|
||||||
archivesBaseName = libProjectName
|
|
||||||
|
|
||||||
bintray {
|
|
||||||
user = localProperties != null ? localProperties.getProperty("bintray.user") : ""
|
|
||||||
key = localProperties != null ? localProperties.getProperty("bintray.apikey") : ""
|
|
||||||
|
|
||||||
configurations = ['archives']
|
|
||||||
pkg {
|
|
||||||
repo = libRepoName
|
|
||||||
name = libProjectName
|
|
||||||
userOrg = "grisha" // Temporary org name until package is on jcenter. Issue #725.
|
|
||||||
desc = libProjectDescription
|
|
||||||
websiteUrl = libUrl
|
|
||||||
vcsUrl = libVcsUrl
|
|
||||||
licenses = [libLicense]
|
|
||||||
publish = true
|
|
||||||
publicDownloadNumbers = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
archivesBaseName = 'mentat'
|
||||||
|
|
||||||
|
apply from: '../publish.gradle'
|
||||||
|
ext.configurePublish(
|
||||||
|
'org.mozilla.mentat',
|
||||||
|
'mentat',
|
||||||
|
'A persistent, embedded knowledge base.')
|
||||||
|
|
|
@ -71,7 +71,7 @@ public class FFIIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void openInMemoryStoreSucceeds() throws Exception {
|
public void openInMemoryStoreSucceeds() throws Exception {
|
||||||
Mentat mentat = new Mentat();
|
Mentat mentat = Mentat.open();
|
||||||
assertNotNull(mentat);
|
assertNotNull(mentat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ public class FFIIntegrationTest {
|
||||||
public void openStoreInLocationSucceeds() throws Exception {
|
public void openStoreInLocationSucceeds() throws Exception {
|
||||||
Context context = InstrumentationRegistry.getTargetContext();
|
Context context = InstrumentationRegistry.getTargetContext();
|
||||||
String path = context.getDatabasePath("test.db").getAbsolutePath();
|
String path = context.getDatabasePath("test.db").getAbsolutePath();
|
||||||
Mentat mentat = new Mentat(path);
|
Mentat mentat = Mentat.open(path);
|
||||||
assertNotNull(mentat);
|
assertNotNull(mentat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ public class FFIIntegrationTest {
|
||||||
|
|
||||||
public Mentat openAndInitializeCitiesStore() {
|
public Mentat openAndInitializeCitiesStore() {
|
||||||
if (this.mentat == null) {
|
if (this.mentat == null) {
|
||||||
this.mentat = new Mentat();
|
this.mentat = Mentat.open();
|
||||||
this.transactCitiesSchema(mentat);
|
this.transactCitiesSchema(mentat);
|
||||||
this.transactSeattleData(mentat);
|
this.transactSeattleData(mentat);
|
||||||
}
|
}
|
||||||
|
@ -177,7 +177,7 @@ public class FFIIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void transactingVocabularySucceeds() {
|
public void transactingVocabularySucceeds() {
|
||||||
Mentat mentat = new Mentat();
|
Mentat mentat = Mentat.open();
|
||||||
TxReport schemaReport = this.transactCitiesSchema(mentat);
|
TxReport schemaReport = this.transactCitiesSchema(mentat);
|
||||||
assertNotNull(schemaReport);
|
assertNotNull(schemaReport);
|
||||||
assertTrue(schemaReport.getTxId() > 0);
|
assertTrue(schemaReport.getTxId() > 0);
|
||||||
|
@ -185,7 +185,7 @@ public class FFIIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void transactingEntitiesSucceeds() {
|
public void transactingEntitiesSucceeds() {
|
||||||
Mentat mentat = new Mentat();
|
Mentat mentat = Mentat.open();
|
||||||
this.transactCitiesSchema(mentat);
|
this.transactCitiesSchema(mentat);
|
||||||
TxReport dataReport = this.transactSeattleData(mentat);
|
TxReport dataReport = this.transactSeattleData(mentat);
|
||||||
assertNotNull(dataReport);
|
assertNotNull(dataReport);
|
||||||
|
@ -363,7 +363,7 @@ public class FFIIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void bindingLongValueSucceeds() throws InterruptedException {
|
public void bindingLongValueSucceeds() throws InterruptedException {
|
||||||
Mentat mentat = new Mentat();
|
Mentat mentat = Mentat.open();
|
||||||
TxReport report = this.populateWithTypesSchema(mentat).dataReport;
|
TxReport report = this.populateWithTypesSchema(mentat).dataReport;
|
||||||
final Long aEntid = report.getEntidForTempId("a");
|
final Long aEntid = report.getEntidForTempId("a");
|
||||||
String query = "[:find ?e . :in ?long :where [?e :foo/long ?long]]";
|
String query = "[:find ?e . :in ?long :where [?e :foo/long ?long]]";
|
||||||
|
@ -384,7 +384,7 @@ public class FFIIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void bindingRefValueSucceeds() throws InterruptedException {
|
public void bindingRefValueSucceeds() throws InterruptedException {
|
||||||
Mentat mentat = new Mentat();
|
Mentat mentat = Mentat.open();
|
||||||
TxReport report = this.populateWithTypesSchema(mentat).dataReport;
|
TxReport report = this.populateWithTypesSchema(mentat).dataReport;
|
||||||
long stringEntid = mentat.entIdForAttribute(":foo/string");
|
long stringEntid = mentat.entIdForAttribute(":foo/string");
|
||||||
final Long bEntid = report.getEntidForTempId("b");
|
final Long bEntid = report.getEntidForTempId("b");
|
||||||
|
@ -406,7 +406,7 @@ public class FFIIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void bindingRefKwValueSucceeds() throws InterruptedException {
|
public void bindingRefKwValueSucceeds() throws InterruptedException {
|
||||||
Mentat mentat = new Mentat();
|
Mentat mentat = Mentat.open();
|
||||||
TxReport report = this.populateWithTypesSchema(mentat).dataReport;
|
TxReport report = this.populateWithTypesSchema(mentat).dataReport;
|
||||||
String refKeyword = ":foo/string";
|
String refKeyword = ":foo/string";
|
||||||
final Long bEntid = report.getEntidForTempId("b");
|
final Long bEntid = report.getEntidForTempId("b");
|
||||||
|
@ -428,7 +428,7 @@ public class FFIIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void bindingKwValueSucceeds() throws InterruptedException {
|
public void bindingKwValueSucceeds() throws InterruptedException {
|
||||||
Mentat mentat = new Mentat();
|
Mentat mentat = Mentat.open();
|
||||||
TxReport report = this.populateWithTypesSchema(mentat).dataReport;
|
TxReport report = this.populateWithTypesSchema(mentat).dataReport;
|
||||||
final Long aEntid = report.getEntidForTempId("a");
|
final Long aEntid = report.getEntidForTempId("a");
|
||||||
String query = "[:find ?e . :in ?kw :where [?e :foo/keyword ?kw]]";
|
String query = "[:find ?e . :in ?kw :where [?e :foo/keyword ?kw]]";
|
||||||
|
@ -449,7 +449,7 @@ public class FFIIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void bindingDateValueSucceeds() throws InterruptedException, ParseException {
|
public void bindingDateValueSucceeds() throws InterruptedException, ParseException {
|
||||||
Mentat mentat = new Mentat();
|
Mentat mentat = Mentat.open();
|
||||||
TxReport report = this.populateWithTypesSchema(mentat).dataReport;
|
TxReport report = this.populateWithTypesSchema(mentat).dataReport;
|
||||||
final Long aEntid = report.getEntidForTempId("a");
|
final Long aEntid = report.getEntidForTempId("a");
|
||||||
|
|
||||||
|
@ -493,7 +493,7 @@ public class FFIIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void bindingUuidValueSucceeds() throws InterruptedException {
|
public void bindingUuidValueSucceeds() throws InterruptedException {
|
||||||
Mentat mentat = new Mentat();
|
Mentat mentat = Mentat.open();
|
||||||
TxReport report = this.populateWithTypesSchema(mentat).dataReport;
|
TxReport report = this.populateWithTypesSchema(mentat).dataReport;
|
||||||
final Long aEntid = report.getEntidForTempId("a");
|
final Long aEntid = report.getEntidForTempId("a");
|
||||||
String query = "[:find ?e . :in ?uuid :where [?e :foo/uuid ?uuid]]";
|
String query = "[:find ?e . :in ?uuid :where [?e :foo/uuid ?uuid]]";
|
||||||
|
@ -515,7 +515,7 @@ public class FFIIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void bindingBooleanValueSucceeds() throws InterruptedException {
|
public void bindingBooleanValueSucceeds() throws InterruptedException {
|
||||||
Mentat mentat = new Mentat();
|
Mentat mentat = Mentat.open();
|
||||||
TxReport report = this.populateWithTypesSchema(mentat).dataReport;
|
TxReport report = this.populateWithTypesSchema(mentat).dataReport;
|
||||||
final Long aEntid = report.getEntidForTempId("a");
|
final Long aEntid = report.getEntidForTempId("a");
|
||||||
String query = "[:find ?e . :in ?bool :where [?e :foo/boolean ?bool]]";
|
String query = "[:find ?e . :in ?bool :where [?e :foo/boolean ?bool]]";
|
||||||
|
@ -537,7 +537,7 @@ public class FFIIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void bindingDoubleValueSucceeds() throws InterruptedException {
|
public void bindingDoubleValueSucceeds() throws InterruptedException {
|
||||||
Mentat mentat = new Mentat();
|
Mentat mentat = Mentat.open();
|
||||||
TxReport report = this.populateWithTypesSchema(mentat).dataReport;
|
TxReport report = this.populateWithTypesSchema(mentat).dataReport;
|
||||||
final Long aEntid = report.getEntidForTempId("a");
|
final Long aEntid = report.getEntidForTempId("a");
|
||||||
String query = "[:find ?e . :in ?double :where [?e :foo/double ?double]]";
|
String query = "[:find ?e . :in ?double :where [?e :foo/double ?double]]";
|
||||||
|
@ -558,7 +558,7 @@ public class FFIIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void typedValueConvertsToLong() throws InterruptedException {
|
public void typedValueConvertsToLong() throws InterruptedException {
|
||||||
Mentat mentat = new Mentat();
|
Mentat mentat = Mentat.open();
|
||||||
TxReport report = this.populateWithTypesSchema(mentat).dataReport;
|
TxReport report = this.populateWithTypesSchema(mentat).dataReport;
|
||||||
final Long aEntid = report.getEntidForTempId("a");
|
final Long aEntid = report.getEntidForTempId("a");
|
||||||
String query = "[:find ?v . :in ?e :where [?e :foo/long ?v]]";
|
String query = "[:find ?v . :in ?e :where [?e :foo/long ?v]]";
|
||||||
|
@ -580,7 +580,7 @@ public class FFIIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void typedValueConvertsToRef() throws InterruptedException {
|
public void typedValueConvertsToRef() throws InterruptedException {
|
||||||
Mentat mentat = new Mentat();
|
Mentat mentat = Mentat.open();
|
||||||
TxReport report = this.populateWithTypesSchema(mentat).dataReport;
|
TxReport report = this.populateWithTypesSchema(mentat).dataReport;
|
||||||
final Long aEntid = report.getEntidForTempId("a");
|
final Long aEntid = report.getEntidForTempId("a");
|
||||||
String query = "[:find ?e . :where [?e :foo/long 25]]";
|
String query = "[:find ?e . :where [?e :foo/long 25]]";
|
||||||
|
@ -602,7 +602,7 @@ public class FFIIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void typedValueConvertsToKeyword() throws InterruptedException {
|
public void typedValueConvertsToKeyword() throws InterruptedException {
|
||||||
Mentat mentat = new Mentat();
|
Mentat mentat = Mentat.open();
|
||||||
TxReport report = this.populateWithTypesSchema(mentat).dataReport;
|
TxReport report = this.populateWithTypesSchema(mentat).dataReport;
|
||||||
final Long aEntid = report.getEntidForTempId("a");
|
final Long aEntid = report.getEntidForTempId("a");
|
||||||
String query = "[:find ?v . :in ?e :where [?e :foo/keyword ?v]]";
|
String query = "[:find ?v . :in ?e :where [?e :foo/keyword ?v]]";
|
||||||
|
@ -624,7 +624,7 @@ public class FFIIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void typedValueConvertsToBoolean() throws InterruptedException {
|
public void typedValueConvertsToBoolean() throws InterruptedException {
|
||||||
Mentat mentat = new Mentat();
|
Mentat mentat = Mentat.open();
|
||||||
TxReport report = this.populateWithTypesSchema(mentat).dataReport;
|
TxReport report = this.populateWithTypesSchema(mentat).dataReport;
|
||||||
final Long aEntid = report.getEntidForTempId("a");
|
final Long aEntid = report.getEntidForTempId("a");
|
||||||
String query = "[:find ?v . :in ?e :where [?e :foo/boolean ?v]]";
|
String query = "[:find ?v . :in ?e :where [?e :foo/boolean ?v]]";
|
||||||
|
@ -646,7 +646,7 @@ public class FFIIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void typedValueConvertsToDouble() throws InterruptedException {
|
public void typedValueConvertsToDouble() throws InterruptedException {
|
||||||
Mentat mentat = new Mentat();
|
Mentat mentat = Mentat.open();
|
||||||
TxReport report = this.populateWithTypesSchema(mentat).dataReport;
|
TxReport report = this.populateWithTypesSchema(mentat).dataReport;
|
||||||
final Long aEntid = report.getEntidForTempId("a");
|
final Long aEntid = report.getEntidForTempId("a");
|
||||||
String query = "[:find ?v . :in ?e :where [?e :foo/double ?v]]";
|
String query = "[:find ?v . :in ?e :where [?e :foo/double ?v]]";
|
||||||
|
@ -668,7 +668,7 @@ public class FFIIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void typedValueConvertsToDate() throws InterruptedException, ParseException {
|
public void typedValueConvertsToDate() throws InterruptedException, ParseException {
|
||||||
Mentat mentat = new Mentat();
|
Mentat mentat = Mentat.open();
|
||||||
TxReport report = this.populateWithTypesSchema(mentat).dataReport;
|
TxReport report = this.populateWithTypesSchema(mentat).dataReport;
|
||||||
final Long aEntid = report.getEntidForTempId("a");
|
final Long aEntid = report.getEntidForTempId("a");
|
||||||
String query = "[:find ?v . :in ?e :where [?e :foo/instant ?v]]";
|
String query = "[:find ?v . :in ?e :where [?e :foo/instant ?v]]";
|
||||||
|
@ -693,7 +693,7 @@ public class FFIIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void typedValueConvertsToString() throws InterruptedException {
|
public void typedValueConvertsToString() throws InterruptedException {
|
||||||
Mentat mentat = new Mentat();
|
Mentat mentat = Mentat.open();
|
||||||
TxReport report = this.populateWithTypesSchema(mentat).dataReport;
|
TxReport report = this.populateWithTypesSchema(mentat).dataReport;
|
||||||
final Long aEntid = report.getEntidForTempId("a");
|
final Long aEntid = report.getEntidForTempId("a");
|
||||||
String query = "[:find ?v . :in ?e :where [?e :foo/string ?v]]";
|
String query = "[:find ?v . :in ?e :where [?e :foo/string ?v]]";
|
||||||
|
@ -715,7 +715,7 @@ public class FFIIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void typedValueConvertsToUUID() throws InterruptedException {
|
public void typedValueConvertsToUUID() throws InterruptedException {
|
||||||
Mentat mentat = new Mentat();
|
Mentat mentat = Mentat.open();
|
||||||
TxReport report = this.populateWithTypesSchema(mentat).dataReport;
|
TxReport report = this.populateWithTypesSchema(mentat).dataReport;
|
||||||
final Long aEntid = report.getEntidForTempId("a");
|
final Long aEntid = report.getEntidForTempId("a");
|
||||||
String query = "[:find ?v . :in ?e :where [?e :foo/uuid ?v]]";
|
String query = "[:find ?v . :in ?e :where [?e :foo/uuid ?v]]";
|
||||||
|
@ -738,7 +738,7 @@ public class FFIIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void valueForAttributeOfEntitySucceeds() throws InterruptedException {
|
public void valueForAttributeOfEntitySucceeds() throws InterruptedException {
|
||||||
Mentat mentat = new Mentat();
|
Mentat mentat = Mentat.open();
|
||||||
TxReport report = this.populateWithTypesSchema(mentat).dataReport;
|
TxReport report = this.populateWithTypesSchema(mentat).dataReport;
|
||||||
final Long aEntid = report.getEntidForTempId("a");
|
final Long aEntid = report.getEntidForTempId("a");
|
||||||
TypedValue value = mentat.valueForAttributeOfEntity(":foo/long", aEntid);
|
TypedValue value = mentat.valueForAttributeOfEntity(":foo/long", aEntid);
|
||||||
|
@ -748,7 +748,7 @@ public class FFIIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void entidForAttributeSucceeds() {
|
public void entidForAttributeSucceeds() {
|
||||||
Mentat mentat = new Mentat();
|
Mentat mentat = Mentat.open();
|
||||||
this.populateWithTypesSchema(mentat);
|
this.populateWithTypesSchema(mentat);
|
||||||
long entid = mentat.entIdForAttribute(":foo/long");
|
long entid = mentat.entIdForAttribute(":foo/long");
|
||||||
assertEquals(65540, entid);
|
assertEquals(65540, entid);
|
||||||
|
@ -756,7 +756,7 @@ public class FFIIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInProgressTransact() {
|
public void testInProgressTransact() {
|
||||||
Mentat mentat = new Mentat();
|
Mentat mentat = Mentat.open();
|
||||||
TxReport report = this.populateWithTypesSchema(mentat).dataReport;
|
TxReport report = this.populateWithTypesSchema(mentat).dataReport;
|
||||||
assertNotNull(report);
|
assertNotNull(report);
|
||||||
|
|
||||||
|
@ -764,7 +764,7 @@ public class FFIIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInProgressRollback() {
|
public void testInProgressRollback() {
|
||||||
Mentat mentat = new Mentat();
|
Mentat mentat = Mentat.open();
|
||||||
TxReport report = this.populateWithTypesSchema(mentat).dataReport;
|
TxReport report = this.populateWithTypesSchema(mentat).dataReport;
|
||||||
assertNotNull(report);
|
assertNotNull(report);
|
||||||
long aEntid = report.getEntidForTempId("a");
|
long aEntid = report.getEntidForTempId("a");
|
||||||
|
@ -782,7 +782,7 @@ public class FFIIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInProgressEntityBuilder() throws InterruptedException {
|
public void testInProgressEntityBuilder() throws InterruptedException {
|
||||||
Mentat mentat = new Mentat();
|
Mentat mentat = Mentat.open();
|
||||||
DBSetupResult reports = this.populateWithTypesSchema(mentat);
|
DBSetupResult reports = this.populateWithTypesSchema(mentat);
|
||||||
long bEntid = reports.dataReport.getEntidForTempId("b");
|
long bEntid = reports.dataReport.getEntidForTempId("b");
|
||||||
final long longEntid = reports.schemaReport.getEntidForTempId("l");
|
final long longEntid = reports.schemaReport.getEntidForTempId("l");
|
||||||
|
@ -862,7 +862,7 @@ public class FFIIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEntityBuilderForEntid() throws InterruptedException {
|
public void testEntityBuilderForEntid() throws InterruptedException {
|
||||||
Mentat mentat = new Mentat();
|
Mentat mentat = Mentat.open();
|
||||||
DBSetupResult reports = this.populateWithTypesSchema(mentat);
|
DBSetupResult reports = this.populateWithTypesSchema(mentat);
|
||||||
long bEntid = reports.dataReport.getEntidForTempId("b");
|
long bEntid = reports.dataReport.getEntidForTempId("b");
|
||||||
final long longEntid = reports.schemaReport.getEntidForTempId("l");
|
final long longEntid = reports.schemaReport.getEntidForTempId("l");
|
||||||
|
@ -942,7 +942,7 @@ public class FFIIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEntityBuilderForTempid() throws InterruptedException {
|
public void testEntityBuilderForTempid() throws InterruptedException {
|
||||||
Mentat mentat = new Mentat();
|
Mentat mentat = Mentat.open();
|
||||||
DBSetupResult reports = this.populateWithTypesSchema(mentat);
|
DBSetupResult reports = this.populateWithTypesSchema(mentat);
|
||||||
final long longEntid = reports.schemaReport.getEntidForTempId("l");
|
final long longEntid = reports.schemaReport.getEntidForTempId("l");
|
||||||
|
|
||||||
|
@ -998,7 +998,7 @@ public class FFIIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInProgressBuilderTransact() throws InterruptedException {
|
public void testInProgressBuilderTransact() throws InterruptedException {
|
||||||
Mentat mentat = new Mentat();
|
Mentat mentat = Mentat.open();
|
||||||
DBSetupResult reports = this.populateWithTypesSchema(mentat);
|
DBSetupResult reports = this.populateWithTypesSchema(mentat);
|
||||||
long aEntid = reports.dataReport.getEntidForTempId("a");
|
long aEntid = reports.dataReport.getEntidForTempId("a");
|
||||||
long bEntid = reports.dataReport.getEntidForTempId("b");
|
long bEntid = reports.dataReport.getEntidForTempId("b");
|
||||||
|
@ -1063,7 +1063,7 @@ public class FFIIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEntityBuilderTransact() throws InterruptedException {
|
public void testEntityBuilderTransact() throws InterruptedException {
|
||||||
Mentat mentat = new Mentat();
|
Mentat mentat = Mentat.open();
|
||||||
DBSetupResult reports = this.populateWithTypesSchema(mentat);
|
DBSetupResult reports = this.populateWithTypesSchema(mentat);
|
||||||
long aEntid = reports.dataReport.getEntidForTempId("a");
|
long aEntid = reports.dataReport.getEntidForTempId("a");
|
||||||
long bEntid = reports.dataReport.getEntidForTempId("b");
|
long bEntid = reports.dataReport.getEntidForTempId("b");
|
||||||
|
@ -1129,7 +1129,7 @@ public class FFIIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEntityBuilderRetract() throws InterruptedException {
|
public void testEntityBuilderRetract() throws InterruptedException {
|
||||||
Mentat mentat = new Mentat();
|
Mentat mentat = Mentat.open();
|
||||||
DBSetupResult reports = this.populateWithTypesSchema(mentat);
|
DBSetupResult reports = this.populateWithTypesSchema(mentat);
|
||||||
long bEntid = reports.dataReport.getEntidForTempId("b");
|
long bEntid = reports.dataReport.getEntidForTempId("b");
|
||||||
final long longEntid = reports.schemaReport.getEntidForTempId("l");
|
final long longEntid = reports.schemaReport.getEntidForTempId("l");
|
||||||
|
@ -1199,7 +1199,7 @@ public class FFIIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInProgressBuilderRetract() throws InterruptedException {
|
public void testInProgressBuilderRetract() throws InterruptedException {
|
||||||
Mentat mentat = new Mentat();
|
Mentat mentat = Mentat.open();
|
||||||
DBSetupResult reports = this.populateWithTypesSchema(mentat);
|
DBSetupResult reports = this.populateWithTypesSchema(mentat);
|
||||||
long bEntid = reports.dataReport.getEntidForTempId("b");
|
long bEntid = reports.dataReport.getEntidForTempId("b");
|
||||||
final long longEntid = reports.schemaReport.getEntidForTempId("l");
|
final long longEntid = reports.schemaReport.getEntidForTempId("l");
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="org.mozilla.mentat">
|
package="org.mozilla.mentat">
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
|
||||||
</manifest>
|
</manifest>
|
|
@ -42,7 +42,7 @@ public interface JNA extends Library {
|
||||||
class InProgressBuilder extends PointerType {}
|
class InProgressBuilder extends PointerType {}
|
||||||
class EntityBuilder extends PointerType {}
|
class EntityBuilder extends PointerType {}
|
||||||
|
|
||||||
Store store_open(String dbPath);
|
Store store_open(String dbPath, RustError.ByReference err);
|
||||||
|
|
||||||
void destroy(Pointer obj);
|
void destroy(Pointer obj);
|
||||||
void uuid_destroy(Pointer obj);
|
void uuid_destroy(Pointer obj);
|
||||||
|
|
|
@ -21,32 +21,39 @@ import com.sun.jna.Pointer;
|
||||||
* The raw pointer it holds is a pointer to a Store.
|
* The raw pointer it holds is a pointer to a Store.
|
||||||
*/
|
*/
|
||||||
public class Mentat extends RustObject<JNA.Store> {
|
public class Mentat extends RustObject<JNA.Store> {
|
||||||
|
|
||||||
static {
|
static {
|
||||||
System.loadLibrary("mentat_ffi");
|
System.loadLibrary("mentat_ffi");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Open a connection to a Store in a given location.<br/>
|
|
||||||
* If the store does not already exist, one will be created.
|
|
||||||
* @param dbPath The URI as a String of the store to open.
|
|
||||||
*/
|
|
||||||
public Mentat(String dbPath) {
|
|
||||||
this(JNA.INSTANCE.store_open(dbPath));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open a connection to an in-memory Store.
|
|
||||||
*/
|
|
||||||
public Mentat() {
|
|
||||||
this(JNA.INSTANCE.store_open(""));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new Mentat with the provided pointer to a Mentat Store
|
* Create a new Mentat with the provided pointer to a Mentat Store
|
||||||
* @param rawPointer A pointer to a Mentat Store.
|
* @param rawPointer A pointer to a Mentat Store.
|
||||||
*/
|
*/
|
||||||
public Mentat(JNA.Store rawPointer) { super(rawPointer); }
|
private Mentat(JNA.Store rawPointer) { super(rawPointer); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open a connection to an in-memory Mentat Store.
|
||||||
|
*/
|
||||||
|
public static Mentat open() {
|
||||||
|
return open("");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open a connection to a Store in a given location.
|
||||||
|
* <br/>
|
||||||
|
* If the store does not already exist, one will be created.
|
||||||
|
* @param dbPath The URI as a String of the store to open.
|
||||||
|
*/
|
||||||
|
public static Mentat open(String dbPath) {
|
||||||
|
RustError.ByReference err = new RustError.ByReference();
|
||||||
|
JNA.Store store = JNA.INSTANCE.store_open(dbPath, err);
|
||||||
|
if (!err.isSuccess()) {
|
||||||
|
err.logAndConsumeError("Mentat");
|
||||||
|
throw new RuntimeException("Failed to open store: " + dbPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Mentat(store);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an attribute to the cache. The {@link CacheDirection} determines how that attribute can be
|
* Add an attribute to the cache. The {@link CacheDirection} determines how that attribute can be
|
||||||
|
|
Binary file not shown.
|
@ -1 +0,0 @@
|
||||||
../../../../../../../../target/aarch64-linux-android/release/libmentat_ffi.so
|
|
Binary file not shown.
|
@ -1 +0,0 @@
|
||||||
../../../../../../../../target/armv7-linux-androideabi/release/libmentat_ffi.so
|
|
Binary file not shown.
|
@ -1 +0,0 @@
|
||||||
../../../../../../../../target/i686-linux-android/release/libmentat_ffi.so
|
|
|
@ -1,3 +0,0 @@
|
||||||
<resources>
|
|
||||||
<string name="app_name">Mentat</string>
|
|
||||||
</resources>
|
|
99
sdks/android/Mentat/publish.gradle
Normal file
99
sdks/android/Mentat/publish.gradle
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
def libRepoName = properties.libRepositoryName
|
||||||
|
def libUrl = properties.libUrl
|
||||||
|
def libVcsUrl = properties.libVcsUrl
|
||||||
|
def libLicense = properties.libLicense
|
||||||
|
def libLicenseUrl = properties.libLicenseUrl
|
||||||
|
|
||||||
|
ext.configurePublish = { groupIdArg, artifactIdArg, descriptionArg ->
|
||||||
|
apply plugin: 'com.github.dcendents.android-maven'
|
||||||
|
|
||||||
|
group = groupIdArg
|
||||||
|
|
||||||
|
install {
|
||||||
|
repositories.mavenInstaller {
|
||||||
|
pom {
|
||||||
|
project {
|
||||||
|
packaging 'aar'
|
||||||
|
groupId groupIdArg
|
||||||
|
artifactId artifactIdArg
|
||||||
|
|
||||||
|
name libRepoName
|
||||||
|
description descriptionArg
|
||||||
|
url libUrl
|
||||||
|
|
||||||
|
licenses {
|
||||||
|
license {
|
||||||
|
name libLicense
|
||||||
|
url libLicenseUrl
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
developers {
|
||||||
|
developer {
|
||||||
|
id 'nalexander'
|
||||||
|
name 'Nick Alexander'
|
||||||
|
email 'nalexander@mozilla.com'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scm {
|
||||||
|
connection libVcsUrl
|
||||||
|
developerConnection libVcsUrl
|
||||||
|
url libUrl
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
apply plugin: 'com.jfrog.bintray'
|
||||||
|
|
||||||
|
version = rootProject.ext.library['version']
|
||||||
|
|
||||||
|
task sourcesJar(type: Jar) {
|
||||||
|
from android.sourceSets.main.java.srcDirs
|
||||||
|
classifier = 'sources'
|
||||||
|
}
|
||||||
|
|
||||||
|
task javadoc(type: Javadoc) {
|
||||||
|
source = android.sourceSets.main.java.srcDirs
|
||||||
|
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
|
||||||
|
}
|
||||||
|
|
||||||
|
task javadocJar(type: Jar, dependsOn: javadoc) {
|
||||||
|
classifier = 'javadoc'
|
||||||
|
from javadoc.destinationDir
|
||||||
|
}
|
||||||
|
|
||||||
|
artifacts {
|
||||||
|
//archives javadocJar
|
||||||
|
archives sourcesJar
|
||||||
|
}
|
||||||
|
|
||||||
|
Properties localProperties = null;
|
||||||
|
if (project.rootProject.file('local.properties').canRead()) {
|
||||||
|
localProperties = new Properties()
|
||||||
|
localProperties.load(project.rootProject.file('local.properties').newDataInputStream())
|
||||||
|
}
|
||||||
|
|
||||||
|
bintray {
|
||||||
|
user = localProperties != null ? localProperties.getProperty("bintray.user") : ""
|
||||||
|
key = localProperties != null ? localProperties.getProperty("bintray.apikey") : ""
|
||||||
|
|
||||||
|
configurations = ['archives']
|
||||||
|
pkg {
|
||||||
|
repo = libRepoName
|
||||||
|
name = artifactIdArg
|
||||||
|
desc = descriptionArg
|
||||||
|
websiteUrl = libUrl
|
||||||
|
vcsUrl = libVcsUrl
|
||||||
|
licenses = [libLicense]
|
||||||
|
publish = true
|
||||||
|
publicDownloadNumbers = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -31,6 +31,8 @@ dependencies {
|
||||||
implementation project(':library')
|
implementation project(':library')
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||||
implementation "com.android.support:appcompat-v7:27.1.1"
|
implementation "com.android.support:appcompat-v7:27.1.1"
|
||||||
|
implementation 'com.android.support.constraint:constraint-layout:1.1.0'
|
||||||
|
implementation 'com.android.support:design:27.1.1'
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
|
|
|
@ -21,8 +21,9 @@ class MainActivity : AppCompatActivity() {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_main)
|
setContentView(R.layout.activity_main)
|
||||||
|
|
||||||
Mentat(this.getDatabasePath("test.db").absolutePath).use {
|
this.getDatabasePath("test.db").absoluteFile.parentFile.mkdirs();
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Mentat.open(this.getDatabasePath("test.db").absolutePath).use {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -58,8 +58,8 @@ open class Mentat: RustObject {
|
||||||
- Parameter storeURI: The URI as a String of the store to open.
|
- Parameter storeURI: The URI as a String of the store to open.
|
||||||
If no store URI is provided, an in-memory store will be opened.
|
If no store URI is provided, an in-memory store will be opened.
|
||||||
*/
|
*/
|
||||||
public convenience init(storeURI: String = "") {
|
public class func open(storeURI: String = "") throws -> Mentat {
|
||||||
self.init(raw: store_open(storeURI))
|
return Mentat(raw: try RustError.unwrap({err in store_open(storeURI, err) }))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -102,7 +102,7 @@ typedef NS_ENUM(NSInteger, ValueType) {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Store
|
// Store
|
||||||
struct Store*_Nonnull store_open(const char*_Nonnull uri);
|
struct Store*_Nonnull store_open(const char*_Nonnull uri, struct RustError* _Nonnull error);
|
||||||
|
|
||||||
// Destructors.
|
// Destructors.
|
||||||
void destroy(void* _Nullable obj);
|
void destroy(void* _Nullable obj);
|
||||||
|
|
13
src/store.rs
13
src/store.rs
|
@ -41,8 +41,6 @@ use mentat_db::{
|
||||||
#[cfg(feature = "syncable")]
|
#[cfg(feature = "syncable")]
|
||||||
use mentat_tolstoy::Syncer;
|
use mentat_tolstoy::Syncer;
|
||||||
|
|
||||||
use uuid::Uuid;
|
|
||||||
|
|
||||||
use conn::{
|
use conn::{
|
||||||
CacheAction,
|
CacheAction,
|
||||||
CacheDirection,
|
CacheDirection,
|
||||||
|
@ -51,7 +49,11 @@ use conn::{
|
||||||
InProgressRead,
|
InProgressRead,
|
||||||
Pullable,
|
Pullable,
|
||||||
Queryable,
|
Queryable,
|
||||||
Syncable
|
};
|
||||||
|
|
||||||
|
#[cfg(feature = "syncable")]
|
||||||
|
use conn::{
|
||||||
|
Syncable,
|
||||||
};
|
};
|
||||||
|
|
||||||
use errors::*;
|
use errors::*;
|
||||||
|
@ -238,6 +240,9 @@ impl Pullable for Store {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "syncable")]
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
#[cfg(feature = "syncable")]
|
#[cfg(feature = "syncable")]
|
||||||
impl Syncable for Store {
|
impl Syncable for Store {
|
||||||
fn sync(&mut self, server_uri: &String, user_uuid: &String) -> Result<()> {
|
fn sync(&mut self, server_uri: &String, user_uuid: &String) -> Result<()> {
|
||||||
|
@ -266,6 +271,8 @@ mod tests {
|
||||||
Duration,
|
Duration,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
use mentat_db::cache::{
|
use mentat_db::cache::{
|
||||||
SQLiteAttributeCache,
|
SQLiteAttributeCache,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue