Web 上的 Flutter 漂移 不支持的操作:不支持的无效类型 InvalidType(<invalid>) (InvalidType)

问题描述 投票:0回答:1

我已经设置了我的 flutter web 项目,其中包含用于数据存储的漂移。但是,当我尝试按照文档here运行此命令时,我收到不支持的类型错误。作为样本:

../../../AppData/Local/Pub/Cache/hosted/pub.dev/ffi-2.1.2/lib/src/utf16.dart:68:22: Error: 'Pointer' isn't a type.
  static int _length(Pointer<Uint16> codeUnits) {
                     ^^^^^^^
../../../AppData/Local/Pub/Cache/hosted/pub.dev/ffi-2.1.2/lib/src/utf16.dart:93:33: Error: 'Allocator' isn't a type.
  Pointer<Utf16> toNativeUtf16({Allocator allocator = malloc}) {
                                ^^^^^^^^^
../../../AppData/Local/Pub/Cache/hosted/pub.dev/ffi-2.1.2/lib/src/utf16.dart:95:19: Error: 'Uint16' isn't a type.
    final Pointer<Uint16> result = allocator<Uint16>(units.length + 1);
                  ^^^^^^
../../../AppData/Local/Pub/Cache/hosted/pub.dev/ffi-2.1.2/lib/src/utf16.dart:95:11: Error: 'Pointer' isn't a type.
    final Pointer<Uint16> result = allocator<Uint16>(units.length + 1);
          ^^^^^^^
../../../AppData/Local/Pub/Cache/hosted/pub.dev/ffi-2.1.2/lib/src/utf16.dart:95:46: Error: 'Uint16' isn't a type.
    final Pointer<Uint16> result = allocator<Uint16>(units.length + 1);
                                             ^^^^^^

我的database.dart 文件如下所示:

import 'package:drift/drift.dart';

import 'dart:io';
import 'package:drift/native.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as p;

import 'package:sqlite3/sqlite3.dart';
import 'package:sqlite3_flutter_libs/sqlite3_flutter_libs.dart';

import 'dart:async';

import 'package:drift/wasm.dart';
import 'package:flutter/foundation.dart';

part 'database.g.dart';

class TodoItems extends Table {
  IntColumn get id => integer().autoIncrement()();
  TextColumn get title => text().withLength(min: 6, max: 32)();
  TextColumn get content => text().named('body')();
  IntColumn get category =>
      integer().nullable().references(TodoCategory, #id)();
  DateTimeColumn get createdAt => dateTime().nullable()();
}

class TodoCategory extends Table {
  IntColumn get id => integer().autoIncrement()();
  TextColumn get description => text()();
}

@DriftDatabase(tables: [TodoItems, TodoCategory])
class AppDatabase extends _$AppDatabase {
  AppDatabase() : super(_connect());

  @override
  int get schemaVersion => 1;
}


DatabaseConnection _connect() {
  return DatabaseConnection.delayed(Future(() async {
    final db = await WasmDatabase.open(
      databaseName: 'sample',
      sqlite3Uri: Uri.parse('sqlite3.wasm'),
      driftWorkerUri: Uri.parse('drift_worker.js'),
    );

    if (db.missingFeatures.isNotEmpty) {
      debugPrint('Using ${db.chosenImplementation} due to unsupported '
          'browser features: ${db.missingFeatures}');
    }

    return db.resolvedExecutor;
  }));
}

我在 web 中的文件夹结构分别包含来自版本

drift
sqlitelibs
的文件 drift_worker.jssqlite3.wasm

我的代码仍然会抛出上面列出的所有错误。

flutter sqlite drift
1个回答
0
投票

发生错误是因为

dart:ffi
package:drift/native.dart
的传递导入。该库无法导入到要编译到网络的文件上。

漂移存储库包括此示例以及基于条件导入的解决方案。这涉及四个单独的文件:

connection.dart
unsupported.dart
native.dart
web.dart
。它们看起来像这样:

连接.dart

export 'unsupported.dart'
    if (dart.library.js) 'web.dart'
    if (dart.library.ffi) 'native.dart';

不支持.dart

DatabaseConnection connect() {
  throw UnsupportedError('No database available on this platform!');
}

web.dart

DatabaseConnection connect() {
  return DatabaseConnection.delayed(Future(() async {
    final db = await WasmDatabase.open(
      databaseName: 'todo-app',
      sqlite3Uri: Uri.parse('sqlite3.wasm'),
      driftWorkerUri: Uri.parse('drift_worker.js'),
    );

    if (db.missingFeatures.isNotEmpty) {
      debugPrint('Using ${db.chosenImplementation} due to unsupported '
          'browser features: ${db.missingFeatures}');
    }

    return db.resolvedExecutor;
  }));
}

native.dart

DatabaseConnection connect() {
  return DatabaseConnection.delayed(Future(() async {
    if (Platform.isAndroid) {
      await applyWorkaroundToOpenSqlite3OnOldAndroidVersions();

      final cachebase = (await getTemporaryDirectory()).path;

      // We can't access /tmp on Android, which sqlite3 would try by default.
      // Explicitly tell it about the correct temporary directory.
      sqlite3.tempDirectory = cachebase;
    }

    return NativeDatabase.createBackgroundConnection(
      await databaseFile,
    );
  }));
}

对于数据库定义,导入

connection.dart
并定义如下构造函数:
AppDatabase() : super(connect());
。这将使编译器在
connect()
native.dart
中查找
web.dart
的方法,具体取决于您要编译到的平台。另一个文件永远不会导入,避免编译错误。

© www.soinside.com 2019 - 2024. All rights reserved.