davidmartos96 / go-flutter-plugin-sqlcipher

2 stars 1 forks source link

hover: Go build failed: exit status 2 #1

Open jlcool opened 4 years ago

jlcool commented 4 years ago

ld: warning: directory not found for option '-Lbuild/outputs/darwin' ld: warning: directory not found for option '-Fbuild/outputs/darwin' ld: library not found for -lcrypto clang: error: linker command failed with exit code 1 (use -v to see invocation) hover: Go build failed: exit status 2

davidmartos96 commented 4 years ago

Sorry @jlcool but I stopped working on this. I've never tried it on macos. If you want to use SqlCipher on desktop, this is what I'm using now.

  1. Install moor_ffi
  2. Override the sqflite native library in main
  3. Use a custom DelegatedDatabase to open moor db with password
  4. Bundle the native sqlcipher libraries in the project (.so, .dylib and .dll files)

It works great on Linux and Windows. I don't own a Mac. But if you are able to run it on Mac with my setup it would be great to know :smile:

import 'package:moor_ffi/open_helper.dart';

Future<void> main() async {
  debugDefaultTargetPlatformOverride = TargetPlatform.fuchsia;

  open.overrideForAll(sqlcipherOpen);

  runApp(MyApp());
}

DynamicLibrary sqlcipherOpen() {
  return _dlopenPlatformSpecific(
    'sqlcipher',
    path: p.join(
      Directory(Platform.resolvedExecutable).parent.path,
      "./", // End with slash
    ),
  );
}

DynamicLibrary _dlopenPlatformSpecific(String name, {String path}) {
  final String fullPath = _platformPath(name, path: path);
  return DynamicLibrary.open(fullPath);
}

String _platformPath(String name, {String path = ''}) {
  if (Platform.isMacOS) {
    return "${path}lib$name.dylib";
  }
  if (Platform.isLinux || Platform.isAndroid) {
    return "${path}lib$name.so";
  }
  if (Platform.isWindows) {
    return "$path$name.dll";
  }
  throw Exception("Platform not implemented");
}
class MyDatabase extends _$MyDatabase {
  // we tell the database where to store the data with this constructor
  MyDatabase(Directory directory)
      : super(
          VmDatabaseEncrypted(
            File(path.join(directory.path, "$DB_NAME")),
            password: "mypassword",
            logStatements: true,
          ),
        );
import 'dart:async';

import 'dart:io';

import 'package:moor/backends.dart';
import 'package:moor/moor.dart';
import 'package:moor_ffi/moor_ffi.dart';

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,
    this.password,
  ) : super(
          _VmEncryptedDelegate(vmDatabase.delegate, password),
          logStatements: vmDatabase.logStatements,
          isSequential: vmDatabase.isSequential,
        );

  final String password;
}

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);
    await delegate.runCustom('PRAGMA KEY = "$password"', <dynamic>[]);
    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 runUpdate(statement, args);
  }

  @override
  TransactionDelegate get transactionDelegate => delegate.transactionDelegate;

  @override
  DbVersionDelegate get versionDelegate => delegate.versionDelegate;
}
jlcool commented 4 years ago

Thank you for your reply,This change is a little big. I hope to use it directly on the existing code

jlcool commented 4 years ago

https://github.com/xeodou/go-sqlcipher/issues/10 It can be solved, but there are new problems

davidmartos96 commented 4 years ago

What other problems? Didn't the LD_LIBRARY_PATH work?

davidmartos96 commented 4 years ago

I tried again this plugin and I managed to run it again on Linux. You can try the steps below to see if you can run it on macos

  1. git clone -b flutter-go https://github.com/davidmartos96/sqflite_sqlcipher sqlcipher_flutter_go

  2. cd sqlcipher_flutter_go/sqflite/example

  3. flutter packages get

  4. hover run -t lib/main.dart

Also, important to note. When I was playing with this I was using sqflite version 1.1.7+3

jlcool commented 4 years ago

file is not a database,Try later git clone -b flutter-go https://github.com/davidmartos96/sqflite_sqlcipher sqlcipher_flutter_go

jlcool commented 4 years ago

Because of the problem of using sqlcipher4 by default, how can I change it to sqlcipher3

jlcool commented 4 years ago

Or how to upgrade sqlcipher3 to sqlcipher4 in flutter

davidmartos96 commented 4 years ago

Are you trying to open an existing encrypted database? Or is the db created from scratch.

If you are able to migrate the data to SqlCipher 4 I would suggest to do so. First make sure that you have SqlCipher 4 in your machine. Run the following: sqlcipher PRAGMA cipher_version

To turn an SqlCipher 3 database into version 4 you can use PRAGMA cipher_migrate from command line. There is more information in the SqlCipher official forum. I would recommend you to try the sample the I've included above to see if it works.

jlcool commented 4 years ago

Whether it can be completed in flutter? How to ensure that the new version uses the old version of the database when the user upgrades the application

jlcool commented 4 years ago

I now upgrade the new version by creating a new database to use SqlCipher 4

davidmartos96 commented 4 years ago

I now upgrade the new version by creating a new database to use SqlCipher 4

That would be the easiest if you are able to do so. It should work in Linux and Windows with the sqflite version I posted above.

davidmartos96 commented 4 years ago

If you really need to migrate the users databases you would need to modify the go_flutter plugin to do something similar to the Java implementation of the Flutter plugin sqflite_sqlcipher, which calls PRAGMA cipher_migrate internally

davidmartos96 commented 4 years ago

Also, what is your current setup? Do you have a mobile Flutter app with sqflite_sqlcipher that you want to use with Go Flutter now? Do you have users in the desktop app already?

jlcool commented 4 years ago

yes,I have a mobile Flutter app with sqlcipher3,and now desktop has to use sqlcipher4 It's impossible to unify, but it's not a big problem