[官网文档翻译]Flutter持久化库drift - 支持的平台

11,046 阅读4分钟

「这是我参与11月更文挑战的第28天,活动详情查看:2021最后一次更文挑战」。

Flutter持久化库drift(原moor)官方文档翻译汇总 - 掘金 (juejin.cn)

本文翻译自 drift 的 官方文档 Supported platforms (simonbinder.eu)

肉翻多有不足,不吝赐教。


重要通知: moor 已改名为 drift 。更多信息[中文]。

支持的平台

drift 支持所有的平台,如何使用它们

因为是基于 sqlite3 数据库构建,所以 drift 几乎可以运行在所有的 Dart 平台上。从最初的发布到现在, Dart 和 Flutter 生态发生了很大的变化。为了在使用时消除不同的 drift 包的混淆,该文档列出了所有支持的平台和在这些平台上如何在构建应用时使用 drift 的方式。

移动端(Android 和 iOS)

对于移动端有两种 drift 的实现可以使用:

使用 moor_flutter

最初的 moor_flutter 包使用 sqflite,仅在 Android 和 iOS 上可以运转。对于新的工程,我们一般建议更新的基于 ffi 的实现,但是 moor_flutter 也会继续维护和支持。

使用 drift/native

package:drift/native.dart 的新的实现使用 dart:ffi 来绑定 sqlite3 原生的 api。对于如开始指南[中文]中描述的新工程,建议使用这种方式。

要确保应用装载了最新版本的 sqlite3,使用 package:drift/native.dart 时还需要添加 sqlite3_flutter_libs 的依赖。

ffi 和 Android 的一个注意事项 对于新的 Android 应用,package:drift/native.dart 是建议使用的 drift 实现。尽管如此,在一些问题上还是会有一些小问题需要意识到:

  • 使用 sqlite3_flutter_libs 会包含为 32位 x86 设备预构建的二进制文件,这个文件可能并不需要。可以在 build.gradle 中应用一个 过滤器 来移除这些二进制文件。
  • 在一些 Android 6.0.1 设备上打开libsqlite3.so 失败。 可以通过设置 gradle.properties 文件中的 android.bundle.enableUncompressedNativeLibs=false 来修复。注意这会增加应用的磁盘使用。详细内容可以看下此 issue  。
  • 复杂查询的内存溢出错误:因为在 Android 上 普通的临时目录不可用,需要通知 sqlite3 存储数据的正确目录。 参考此评论 的示例如何实现。

Web

主要文章:Web[中文]

对于运行在 Web 中的应用,可以使用 drift 的试验性的 web 实现,位于 package:drift/web.dart 。 因为它绑定了 sql.js ,需要特殊的准备步骤。 详细内容请阅读主要文章。

桌面端

通过使用 package:drift/native.dartNativeDatabase, drift 也支持所有可运行 Dart 的主流的桌面操作系统。根据操作系统,可能需要进一步的准备工作:

Windows

在 Windows 上,可以下载 sqlite ,然后解压到在环境变量PATH 中指定的目录来使用 drift。

也可以在应用中装载一个自定义的 sqlite3.dll,详细内容参考以下部分。

Linux

在大多数 Linux 的发行版中,安装的是 libsqlite3.so 。 如果只需要使用 drift 来开发,可以只安装 sqlite3 库。在 Ubuntu 和 其它基于 Debian 的发行版中,可以安装 libsqlite3-dev 包。实际上,每个发行版上都会有 sqlite 的预构建包。

也可以在应用中装载一个自定义的 sqlite3.so,详细内容参考以下部分。

MacOS

这个简单,只需要使用 package:drift/native.dart 中的 NativeDatabase。不需要其它准备。

如果需要一个自定义的 sqlite3 库,或者为了确保应用一直使用特定版本的 sqlite3,可以在应用中加载相应的版本。如果依赖 sqlite3_flutter_libs , drift 会自动使用 macOS 上通常会比 sqlite3 更新的版本。

绑定 sqlite 到应用

如果不想使用操作系统上的 sqlite3 (或不可用),也可以在应用中装载 sqlite3。最好的方式依赖于如何装载应用。这里假定要在应用的可执行文件同目录下动态安装 sqlite 库。

下面的示例展示了如何在 Linux 通过使用自定义的 sqlite3.so (假定在可执行文件同目录)来绑定:

import 'dart:ffi';
import 'dart:io';
import 'package:sqlite3/sqlite3.dart';
import 'package:sqlite3/open.dart';

void main() {
  open.overrideFor(OperatingSystem.linux, _openOnLinux);

  // 设置所有覆写之后,就可以使用 drift 了!
}

DynamicLibrary _openOnLinux() {
  final scriptDir = File(Platform.script.toFilePath()).parent;
  final libraryNextToScript = File('${scriptDir.path}/sqlite3.so');
  return DynamicLibrary.open(libraryNextToScript.path);
}
// _openOnWindows 会同样通过打开 `sqlite3.dll` 实现。

确保在设置指定平台的覆写之后使用 drift。如果在另一个 isolate 中使用 drift ,也需要在后台 isolate 中应用 开始的覆写。 可以在使用 drift api 之前在 isoalte 的入口点调用这些覆写。


以下内容摘指评论区:

多谢 huihuh

windows dart直接跑drift demo 失败。
然后本地随便找了一个sqlite3.dll 丢到 example 文件夹下,

  DynamicLibrary _openOnWindows()
  { 
    final scriptDir = File(Platform.script.toFilePath()).parent;
    final libraryNextToScript = File('${scriptDir.path}/sqlite3.dll'); 
    return DynamicLibrary.open(libraryNextToScript.path); 
  }

在初始化DataBase前绑定sqlite3.dll。

open.overrideFor(OperatingSystem.windows, _openOnWindows);

成功运行