sqlite3.dart
sqlite3.dart copied to clipboard
How to read the bytes of a VirtualFileSystemFile?
Hi, I'm trying to access the bytes of my sqlite database file. How do I do that on the web? xOpen and xRead are super confusing and I can't find an example.
Working none-web implementation
import 'dart:async';
import 'dart:io';
import 'dart:typed_data';
import 'package:path_provider/path_provider.dart';
import 'package:sqlite3/common.dart';
import 'package:sqlite3/sqlite3.dart';
Future<CommonDatabase> loadDb() async {
final applicationDir = await getApplicationDocumentsDirectory();
final file = File(applicationDir.path + '/foobar.db');
return sqlite3.open(file.path);
}
Future<Uint8List> dbBytes() async {
final applicationDir = await getApplicationDocumentsDirectory();
final file = File(applicationDir.path + '/foobar.db');
return file.readAsBytes();
}
Not working web implementation
import 'dart:async';
import 'dart:io';
import 'dart:typed_data';
import 'package:sqlite3/wasm.dart';
Future<CommonDatabase> loadDb() async {
final sqlite = await WasmSqlite3.loadFromUrl(Uri.parse('sqlite3.wasm'));
final fileSystem = await IndexedDbFileSystem.open(dbName: 'foobar');
sqlite.registerVirtualFileSystem(fileSystem, makeDefault: true);
return sqlite.open('foobar.db', mode: OpenMode.readWriteCreate);
}
Future<Uint8List> dbBytes() async {
final fileSystem = await IndexedDbFileSystem.open(dbName: 'foobar');
final open = fileSystem.xOpen(
Sqlite3Filename('foobar.db'), SqlFlag.SQLITE_OPEN_READONLY);
print(open.file);
return (open.file as File).readAsBytes();
}
Thanks!
There's a somewhat-related example here.
We're not using dart:io files on the web and instead mirror structures used by sqlite3 internally, which is also the reason the methods are named the way they are. So the way to go is to xOpen the file as you're doing it, and then call xRead with a Uint8List that you've allocated (you can use xFileSize() to get the current size) to read bytes from the file into a buffer. Then you just need to xClose() the file after you're done. I didn't test this, but I imagine something like this should work:
Future<Uint8List> dbBytes() async {
final fileSystem = await IndexedDbFileSystem.open(dbName: 'foobar');
final open = fileSystem.xOpen(
Sqlite3Filename('foobar.db'), SqlFlag.SQLITE_OPEN_READONLY);
final buffer = Uint8List(open.xFileSize());
file.xRead(buffer, 0); // read from offset 0 (entire file)
file.xClose();
fileSystem.close();
}