mirror of
https://github.com/immich-app/isar.git
synced 2026-09-30 13:23:02 +08:00
Fixes
This commit is contained in:
@@ -1,3 +1,16 @@
|
||||
## 3.1.0
|
||||
|
||||
### Breaking
|
||||
|
||||
Sorry for this breaking change. Unfortunately, it was necessary to fix stability issues on Android.
|
||||
|
||||
- `directory` is now required for `Isar.open()` and `Isar.openSync()`
|
||||
|
||||
### Fixes
|
||||
|
||||
- Fixed a crash that occasionally occurred when opening Isar
|
||||
- Fixed a schema migration issue
|
||||
|
||||
## 3.0.6
|
||||
|
||||
### Fixes
|
||||
|
||||
@@ -87,7 +87,7 @@ abstract class Isar {
|
||||
/// Open a new Isar instance.
|
||||
static Future<Isar> open(
|
||||
List<CollectionSchema<dynamic>> schemas, {
|
||||
String? directory,
|
||||
required String directory,
|
||||
String name = defaultName,
|
||||
int maxSizeMiB = Isar.defaultMaxSizeMiB,
|
||||
bool relaxedDurability = true,
|
||||
@@ -117,7 +117,7 @@ abstract class Isar {
|
||||
/// Open a new Isar instance.
|
||||
static Isar openSync(
|
||||
List<CollectionSchema<dynamic>> schemas, {
|
||||
String? directory,
|
||||
required String directory,
|
||||
String name = defaultName,
|
||||
int maxSizeMiB = Isar.defaultMaxSizeMiB,
|
||||
bool relaxedDurability = true,
|
||||
|
||||
@@ -72,7 +72,7 @@ void _initializeInstance(
|
||||
|
||||
Future<Isar> openIsar({
|
||||
required List<CollectionSchema<dynamic>> schemas,
|
||||
String? directory,
|
||||
required String directory,
|
||||
required String name,
|
||||
required int maxSizeMiB,
|
||||
required bool relaxedDurability,
|
||||
@@ -83,7 +83,7 @@ Future<Isar> openIsar({
|
||||
|
||||
return using((Arena alloc) async {
|
||||
final namePtr = name.toCString(alloc);
|
||||
final dirPtr = directory?.toCString(alloc) ?? nullptr;
|
||||
final dirPtr = directory.toCString(alloc);
|
||||
|
||||
final schemasJson = getSchemas(schemas).map((e) => e.toJson());
|
||||
final schemaStrPtr = jsonEncode(schemasJson.toList()).toCString(alloc);
|
||||
@@ -118,7 +118,7 @@ Future<Isar> openIsar({
|
||||
|
||||
Isar openIsarSync({
|
||||
required List<CollectionSchema<dynamic>> schemas,
|
||||
String? directory,
|
||||
required String directory,
|
||||
required String name,
|
||||
required int maxSizeMiB,
|
||||
required bool relaxedDurability,
|
||||
@@ -128,7 +128,7 @@ Isar openIsarSync({
|
||||
IC.isar_connect_dart_api(NativeApi.postCObject.cast());
|
||||
return using((Arena alloc) {
|
||||
final namePtr = name.toCString(alloc);
|
||||
final dirPtr = directory?.toCString(alloc) ?? nullptr;
|
||||
final dirPtr = directory.toCString(alloc);
|
||||
|
||||
final schemasJson = getSchemas(schemas).map((e) => e.toJson());
|
||||
final schemaStrPtr = jsonEncode(schemasJson.toList()).toCString(alloc);
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
use jni::objects::{JClass, JString};
|
||||
use jni::JNIEnv;
|
||||
use once_cell::sync::OnceCell;
|
||||
|
||||
static PATH: OnceCell<String> = OnceCell::new();
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Java_dev_isar_isar_1flutter_1libs_IsarInitializer_initializePath(
|
||||
env: JNIEnv,
|
||||
_class: JClass,
|
||||
path: JString,
|
||||
) {
|
||||
let java_str = env.get_string(path).unwrap();
|
||||
let path = java_str.to_str().unwrap();
|
||||
let _ = PATH.set(path.to_string());
|
||||
}
|
||||
|
||||
pub fn get_dir() -> Option<String> {
|
||||
PATH.get().map(|s| s.to_string())
|
||||
}
|
||||
|
||||
pub fn get_app_id() -> Option<String> {
|
||||
None
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
use objc::runtime::Object;
|
||||
use objc::{class, msg_send, sel, sel_impl};
|
||||
use objc_foundation::{INSString, NSArray, NSString};
|
||||
use std::os::raw::c_ulong;
|
||||
|
||||
#[allow(improper_ctypes)]
|
||||
#[allow(dead_code)]
|
||||
extern "C" {
|
||||
pub fn NSSearchPathForDirectoriesInDomains(
|
||||
directory: c_ulong,
|
||||
domain_mask: c_ulong,
|
||||
expand_tilde: bool,
|
||||
) -> *mut NSArray<*mut NSString>;
|
||||
}
|
||||
|
||||
const APPLICATION_SUPPORT_DIRECTORY: u8 = 14;
|
||||
|
||||
pub fn get_dir() -> Option<String> {
|
||||
unsafe {
|
||||
let directories =
|
||||
NSSearchPathForDirectoriesInDomains(APPLICATION_SUPPORT_DIRECTORY as c_ulong, 1, true);
|
||||
let first_object: &mut NSString = msg_send![directories, firstObject];
|
||||
Some(first_object.as_str().to_string())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_app_id() -> Option<String> {
|
||||
if cfg!(target_os = "ios") {
|
||||
return None;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let bundle_cls = class!(NSBundle);
|
||||
let main_bundle: &mut Object = msg_send![bundle_cls, mainBundle];
|
||||
let bundle_id: &mut NSString = msg_send![main_bundle, bundleIdentifier];
|
||||
Some(bundle_id.as_str().to_string())
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
use once_cell::sync::OnceCell;
|
||||
use std::env::current_exe;
|
||||
use std::fs::create_dir_all;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[cfg(any(target_os = "ios", target_os = "macos"))]
|
||||
mod apple;
|
||||
#[cfg(any(target_os = "ios", target_os = "macos"))]
|
||||
use self::apple::*;
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
pub mod android;
|
||||
#[cfg(target_os = "android")]
|
||||
use self::android::*;
|
||||
|
||||
#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "android")))]
|
||||
mod other;
|
||||
#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "android")))]
|
||||
use self::other::*;
|
||||
|
||||
static DIR: OnceCell<Option<String>> = OnceCell::new();
|
||||
|
||||
pub fn get_app_dir() -> Option<&'static str> {
|
||||
DIR.get_or_init(|| -> Option<String> {
|
||||
let mut dir = PathBuf::from(get_dir()?);
|
||||
if let Some(app_id) = get_app_id() {
|
||||
if app_id.is_empty() {
|
||||
let exe_path = current_exe().ok()?;
|
||||
let exe = exe_path.iter().last()?.to_str()?;
|
||||
dir.push(exe);
|
||||
} else {
|
||||
dir.push(&app_id);
|
||||
}
|
||||
}
|
||||
|
||||
create_dir_all(&dir).ok()?;
|
||||
|
||||
Some(dir.to_str()?.to_string())
|
||||
})
|
||||
.as_deref()
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
pub fn get_dir() -> Option<String> {
|
||||
Some(dirs::config_dir()?.to_str()?.to_string())
|
||||
}
|
||||
|
||||
pub fn get_app_id() -> Option<String> {
|
||||
Some(String::new())
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
use crate::app_dir::get_app_dir;
|
||||
use crate::dart::{dart_post_int, DartPort};
|
||||
use crate::error::DartErrCode;
|
||||
use crate::from_c_str;
|
||||
@@ -38,7 +37,7 @@ pub unsafe extern "C" fn isar_instance_create(
|
||||
) -> i64 {
|
||||
let open = || -> Result<()> {
|
||||
let name = from_c_str(name).unwrap().unwrap();
|
||||
let path = from_c_str(path).unwrap().or_else(get_app_dir);
|
||||
let path = from_c_str(path).unwrap();
|
||||
let schema_json = from_c_str(schema_json).unwrap().unwrap();
|
||||
let schema = Schema::from_json(schema_json.as_bytes())?;
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ use unicode_segmentation::UnicodeSegmentation;
|
||||
#[macro_use]
|
||||
mod error;
|
||||
|
||||
pub mod app_dir;
|
||||
pub mod c_object_set;
|
||||
pub mod crud;
|
||||
mod dart;
|
||||
|
||||
@@ -1,16 +1,3 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="dev.isar.isar_flutter_libs">
|
||||
|
||||
<application>
|
||||
<provider
|
||||
android:name="androidx.startup.InitializationProvider"
|
||||
tools:node="merge"
|
||||
android:authorities="${applicationId}.androidx-startup"
|
||||
android:exported="false">
|
||||
<meta-data
|
||||
android:name="dev.isar.isar_flutter_libs.IsarInitializer"
|
||||
android:value="androidx.startup" />
|
||||
</provider>
|
||||
</application>
|
||||
</manifest>
|
||||
package="dev.isar.isar_flutter_libs" />
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
package dev.isar.isar_flutter_libs;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.startup.Initializer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class IsarInitializer implements Initializer<Void> {
|
||||
|
||||
@Override
|
||||
public Void create(Context context) {
|
||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
|
||||
System.loadLibrary("isar");
|
||||
initializePath(context.getFilesDir().getAbsolutePath());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Class<? extends Initializer<?>>> dependencies() {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
private static native void initializePath(String path);
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
import 'package:isar_test/isar_test.dart';
|
||||
|
||||
@@ -126,7 +126,7 @@ Future<Isar> openTempIsar(
|
||||
schemas: schemas,
|
||||
name: name ?? getRandomName(),
|
||||
maxSizeMiB: maxSizeMiB,
|
||||
directory: directory ?? testTempPath,
|
||||
directory: testTempPath ?? '',
|
||||
compactOnLaunch: compactOnLaunch,
|
||||
);
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ bool get syncTest => Zone.current[#syncTest] as bool? ?? false;
|
||||
|
||||
Future<Isar> tOpen({
|
||||
required List<CollectionSchema<dynamic>> schemas,
|
||||
String? directory,
|
||||
required String directory,
|
||||
String name = Isar.defaultName,
|
||||
int maxSizeMiB = Isar.defaultMaxSizeMiB,
|
||||
bool relaxedDurability = true,
|
||||
|
||||
Reference in New Issue
Block a user