refactor: Remove moor
This commit is contained in:
parent
39b8876837
commit
9ef0c71f81
18 changed files with 9 additions and 501 deletions
|
|
@ -1,121 +0,0 @@
|
|||
// file from https://gist.github.com/simolus3/5097bbd80ce59f9b957961fe851fd95a#file-cipher_db-dart
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:ffi';
|
||||
import 'dart:io';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:moor/backends.dart';
|
||||
import 'package:moor/ffi.dart';
|
||||
import 'package:moor/moor.dart';
|
||||
import 'package:sqlite3/open.dart';
|
||||
|
||||
/// Tells `moor_ffi` to use `sqlcipher` instead of the regular `sqlite3`.
|
||||
///
|
||||
/// This needs to be called before using `moor`, for instance in the `main`
|
||||
/// method.
|
||||
void init() {
|
||||
const sharedLibraryName = 'libsqlcipher.so';
|
||||
|
||||
open.overrideFor(OperatingSystem.android, () {
|
||||
try {
|
||||
return DynamicLibrary.open(sharedLibraryName);
|
||||
} catch (_) {
|
||||
// On some (especially old) Android devices, we somehow can't dlopen
|
||||
// libraries shipped with the apk. We need to find the full path of the
|
||||
// library (/data/data/<id>/lib/libsqlite3.so) and open that one.
|
||||
// For details, see https://github.com/simolus3/moor/issues/420
|
||||
final appIdAsBytes = File('/proc/self/cmdline').readAsBytesSync();
|
||||
|
||||
// app id ends with the first \0 character in here.
|
||||
final endOfAppId = max(appIdAsBytes.indexOf(0), 0);
|
||||
final appId = String.fromCharCodes(appIdAsBytes.sublist(0, endOfAppId));
|
||||
|
||||
return DynamicLibrary.open('/data/data/$appId/lib/$sharedLibraryName');
|
||||
}
|
||||
});
|
||||
|
||||
open.overrideFor(OperatingSystem.iOS, () => DynamicLibrary.executable());
|
||||
}
|
||||
|
||||
class VmDatabaseEncrypted extends DelegatedDatabase {
|
||||
/// Creates a database that will store its result in the [file], creating it
|
||||
/// if it doesn't exist.
|
||||
factory VmDatabaseEncrypted(
|
||||
File file, {
|
||||
String password = '',
|
||||
bool logStatements = false,
|
||||
}) {
|
||||
final vmDatabase = VmDatabase(file, logStatements: logStatements);
|
||||
return VmDatabaseEncrypted._(vmDatabase, password);
|
||||
}
|
||||
|
||||
factory VmDatabaseEncrypted.memory({
|
||||
String password = '',
|
||||
bool logStatements = false,
|
||||
}) {
|
||||
final vmDatabase = VmDatabase.memory(logStatements: logStatements);
|
||||
return VmDatabaseEncrypted._(vmDatabase, password);
|
||||
}
|
||||
|
||||
VmDatabaseEncrypted._(
|
||||
VmDatabase vmDatabase,
|
||||
String password,
|
||||
) : super(
|
||||
_VmEncryptedDelegate(vmDatabase.delegate, password),
|
||||
logStatements: vmDatabase.logStatements,
|
||||
isSequential: vmDatabase.isSequential,
|
||||
);
|
||||
}
|
||||
|
||||
class _VmEncryptedDelegate extends DatabaseDelegate {
|
||||
final String password;
|
||||
final DatabaseDelegate delegate;
|
||||
|
||||
_VmEncryptedDelegate(
|
||||
this.delegate,
|
||||
this.password,
|
||||
);
|
||||
|
||||
@override
|
||||
Future<void> open(QueryExecutorUser db) async {
|
||||
await delegate.open(db);
|
||||
final keyLiteral = const StringType().mapToSqlConstant(password);
|
||||
await delegate.runCustom('PRAGMA KEY = $keyLiteral', const []);
|
||||
return Future.value();
|
||||
}
|
||||
|
||||
@override
|
||||
FutureOr<bool> get isOpen => delegate.isOpen;
|
||||
|
||||
@override
|
||||
Future<void> runBatched(BatchedStatements statements) {
|
||||
return delegate.runBatched(statements);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> runCustom(String statement, List args) {
|
||||
return delegate.runCustom(statement, args);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<int> runInsert(String statement, List args) {
|
||||
return delegate.runInsert(statement, args);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<QueryResult> runSelect(String statement, List args) {
|
||||
return delegate.runSelect(statement, args);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<int> runUpdate(String statement, List args) {
|
||||
return delegate.runUpdate(statement, args);
|
||||
}
|
||||
|
||||
@override
|
||||
TransactionDelegate get transactionDelegate => delegate.transactionDelegate;
|
||||
|
||||
@override
|
||||
DbVersionDelegate get versionDelegate => delegate.versionDelegate;
|
||||
}
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
import 'dart:ffi';
|
||||
import 'dart:io';
|
||||
import 'dart:isolate';
|
||||
import 'package:matrix/matrix.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:sqflite/sqflite.dart' show getDatabasesPath;
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:moor/moor.dart';
|
||||
import 'package:moor/isolate.dart';
|
||||
import '../platform_infos.dart';
|
||||
import 'cipher_db.dart' as cipher;
|
||||
import 'package:moor/ffi.dart' as moor;
|
||||
import 'package:sqlite3/open.dart';
|
||||
|
||||
bool _inited = false;
|
||||
|
||||
// see https://moor.simonbinder.eu/docs/advanced-features/isolates/
|
||||
void _startBackground(_IsolateStartRequest request) {
|
||||
// this is the entry point from the background isolate! Let's create
|
||||
// the database from the path we received
|
||||
|
||||
if (!_inited) {
|
||||
cipher.init();
|
||||
_inited = true;
|
||||
}
|
||||
final executor = cipher.VmDatabaseEncrypted(File(request.targetPath),
|
||||
password: request.password, logStatements: request.logStatements);
|
||||
// we're using MoorIsolate.inCurrent here as this method already runs on a
|
||||
// background isolate. If we used MoorIsolate.spawn, a third isolate would be
|
||||
// started which is not what we want!
|
||||
final moorIsolate = MoorIsolate.inCurrent(
|
||||
() => DatabaseConnection.fromExecutor(executor),
|
||||
);
|
||||
// inform the starting isolate about this, so that it can call .connect()
|
||||
request.sendMoorIsolate.send(moorIsolate);
|
||||
}
|
||||
|
||||
// used to bundle the SendPort and the target path, since isolate entry point
|
||||
// functions can only take one parameter.
|
||||
class _IsolateStartRequest {
|
||||
final SendPort sendMoorIsolate;
|
||||
final String targetPath;
|
||||
final String password;
|
||||
final bool logStatements;
|
||||
|
||||
_IsolateStartRequest(
|
||||
this.sendMoorIsolate, this.targetPath, this.password, this.logStatements);
|
||||
}
|
||||
|
||||
Future<Database> constructDb(
|
||||
{bool logStatements = false,
|
||||
String filename = 'database.sqlite',
|
||||
String password = ''}) async {
|
||||
if (PlatformInfos.isMobile || Platform.isMacOS) {
|
||||
Logs().v('[Moor] using encrypted moor');
|
||||
final dbFolder = await getDatabasesPath();
|
||||
final targetPath = p.join(dbFolder, filename);
|
||||
final receivePort = ReceivePort();
|
||||
await Isolate.spawn(
|
||||
_startBackground,
|
||||
_IsolateStartRequest(
|
||||
receivePort.sendPort, targetPath, password, logStatements),
|
||||
);
|
||||
final isolate = (await receivePort.first as MoorIsolate);
|
||||
return Database.connect(await isolate.connect());
|
||||
} else if (Platform.isLinux) {
|
||||
Logs().v('[Moor] using Linux desktop moor');
|
||||
final appDocDir = await getApplicationSupportDirectory();
|
||||
return Database(moor.VmDatabase(File('${appDocDir.path}/$filename')));
|
||||
} else if (Platform.isWindows) {
|
||||
Logs().v('[Moor] using Windows desktop moor');
|
||||
open.overrideFor(OperatingSystem.windows, _openOnWindows);
|
||||
return Database(moor.VmDatabase.memory());
|
||||
}
|
||||
throw Exception('Platform not supported');
|
||||
}
|
||||
|
||||
DynamicLibrary _openOnWindows() {
|
||||
final exePath =
|
||||
File(Platform.resolvedExecutable.replaceAll('fluffychat.exe', ''));
|
||||
final libraryNextToScript = File('${exePath.path}/sqlite3.dll');
|
||||
return DynamicLibrary.open(libraryNextToScript.path);
|
||||
}
|
||||
|
||||
Future<String> getLocalstorage(String key) async {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
export 'unsupported.dart'
|
||||
if (dart.library.html) 'web.dart'
|
||||
if (dart.library.io) 'mobile.dart';
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
import 'package:matrix/matrix.dart';
|
||||
|
||||
Future<Database> constructDb(
|
||||
{bool logStatements = false,
|
||||
String filename = 'database.sqlite',
|
||||
String password = ''}) async {
|
||||
throw 'Platform not supported';
|
||||
}
|
||||
|
||||
Future<String> getLocalstorage(String key) async {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
import 'package:matrix/matrix.dart';
|
||||
import 'package:moor/moor_web.dart';
|
||||
import 'dart:html';
|
||||
|
||||
Future<Database> constructDb(
|
||||
{bool logStatements = false,
|
||||
String filename = 'database.sqlite',
|
||||
String password = ''}) async {
|
||||
Logs().v('[Moor] Using moor web');
|
||||
return Database(WebDatabase.withStorage(
|
||||
await MoorWebStorage.indexedDbIfSupported(filename),
|
||||
logStatements: logStatements));
|
||||
}
|
||||
|
||||
Future<String> getLocalstorage(String key) async {
|
||||
return window.localStorage[key];
|
||||
}
|
||||
|
|
@ -1,44 +1,9 @@
|
|||
import 'package:matrix/matrix.dart';
|
||||
import 'package:fluffychat/utils/platform_infos.dart';
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
import 'package:localstorage/localstorage.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'dart:async';
|
||||
import 'dart:core';
|
||||
import './database/shared.dart';
|
||||
import '../config/setting_keys.dart';
|
||||
import 'package:random_string/random_string.dart';
|
||||
|
||||
Future<Database> getDatabase(Client client) async {
|
||||
while (_generateDatabaseLock) {
|
||||
await Future.delayed(Duration(milliseconds: 50));
|
||||
}
|
||||
_generateDatabaseLock = true;
|
||||
try {
|
||||
if (_db != null) return _db;
|
||||
final store = Store();
|
||||
var password = await store.getItem(SettingKeys.databasePassword);
|
||||
var newPassword = false;
|
||||
if (password == null || password.isEmpty) {
|
||||
newPassword = true;
|
||||
password = randomString(255);
|
||||
}
|
||||
_db = await constructDb(
|
||||
logStatements: false,
|
||||
filename: 'moor.sqlite',
|
||||
password: password,
|
||||
);
|
||||
if (newPassword) {
|
||||
await store.setItem(SettingKeys.databasePassword, password);
|
||||
}
|
||||
return _db;
|
||||
} finally {
|
||||
_generateDatabaseLock = false;
|
||||
}
|
||||
}
|
||||
|
||||
Database _db;
|
||||
bool _generateDatabaseLock = false;
|
||||
|
||||
// see https://github.com/mogol/flutter_secure_storage/issues/161#issuecomment-704578453
|
||||
class AsyncMutex {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue