Bundle libtamerye

aww yiss!
This commit is contained in:
2026-06-09 00:11:15 +09:00
parent 7bbba073ef
commit 769d3fad9e
9 changed files with 210 additions and 11 deletions
+1
View File
@@ -26,3 +26,4 @@ result-*
*.sqlite
*.sqlite-journal
assets/kanjivg
assets/*.so
Generated
+84 -1
View File
@@ -1,5 +1,42 @@
{
"nodes": {
"crane": {
"locked": {
"lastModified": 1780532242,
"narHash": "sha256-D+BsdpxmtUwtqGoY0IXPhHgTlmqgcZKCEo1oMyn7ep0=",
"owner": "ipetkov",
"repo": "crane",
"rev": "59a82a1222dd3b2080b5cc52a1a2e8d5f1b77f37",
"type": "github"
},
"original": {
"owner": "ipetkov",
"repo": "crane",
"type": "github"
}
},
"nix-sqlite": {
"inputs": {
"nixpkgs": [
"tamerye",
"nixpkgs"
]
},
"locked": {
"lastModified": 1780571864,
"narHash": "sha256-IMCP9CzJc1zCSRoLcNE6qCCiQL/Y7kPCQqZzc89nsA0=",
"ref": "main",
"rev": "874e22c2e785d32cdd7ddabb5c936227ed2223d3",
"revCount": 29,
"type": "git",
"url": "https://git.pvv.ntnu.no/mugiten/nix-custom-sqlite.git"
},
"original": {
"ref": "main",
"type": "git",
"url": "https://git.pvv.ntnu.no/mugiten/nix-custom-sqlite.git"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1779560665,
@@ -17,7 +54,53 @@
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs"
"nixpkgs": "nixpkgs",
"tamerye": "tamerye"
}
},
"rust-overlay": {
"inputs": {
"nixpkgs": [
"tamerye",
"nixpkgs"
]
},
"locked": {
"lastModified": 1780543271,
"narHash": "sha256-oPJ7eJN1sM37v92Rp/eyQL7/rUm0BOvXEBAoq/zN0cM=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "c30ca201c5093540cf792f6982f81ba1aa0f3514",
"type": "github"
},
"original": {
"owner": "oxalica",
"repo": "rust-overlay",
"type": "github"
}
},
"tamerye": {
"inputs": {
"crane": "crane",
"nix-sqlite": "nix-sqlite",
"nixpkgs": [
"nixpkgs"
],
"rust-overlay": "rust-overlay"
},
"locked": {
"lastModified": 1780968337,
"narHash": "sha256-uhbUbnXsmNPAtVm9tD3HrWUSjNRV7pK+E/zre0KkFuY=",
"ref": "main",
"rev": "9adfd813e647c0f5a00a560b985aba2992f3a23a",
"revCount": 35,
"type": "git",
"url": "https://git.pvv.ntnu.no/Mugiten/tamerye.git"
},
"original": {
"ref": "main",
"type": "git",
"url": "https://git.pvv.ntnu.no/Mugiten/tamerye.git"
}
}
},
+16 -4
View File
@@ -1,6 +1,14 @@
{
inputs.nixpkgs.url = "nixpkgs/nixos-unstable";
outputs = { self, nixpkgs }: let
inputs = {
nixpkgs.url = "nixpkgs/nixos-unstable";
tamerye = {
url = "git+https://git.pvv.ntnu.no/Mugiten/tamerye.git?ref=main";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = { self, tamerye, nixpkgs }: let
inherit (nixpkgs) lib;
systems = [
"x86_64-linux"
@@ -16,6 +24,9 @@
android_sdk.accept_license = true;
allowUnfree = true;
};
overlays = [
tamerye.overlays.default
];
};
androidPkgs = (pkgs.androidenv.composeAndroidPackages {
buildToolsVersions = [ "35.0.0" "36.1.0" ];
@@ -37,7 +48,7 @@
androidPkgs.androidsdk
jdk'
pkgs.sqlite-interactive
pkgs.tamerye-sqlite-cli
pkgs.sqldiff
];
env = {
@@ -50,8 +61,9 @@
];
FLUTTER_SDK = "${flutter'}";
JAVA_HOME = "${jdk'}/lib/openjdk";
LIBSQLITE_PATH = "${pkgs.sqlite.out}/lib/libsqlite3.so";
LIBSQLITE_PATH = "${pkgs.tamerye-sqlite}/lib/libsqlite3.so";
JADB_PATH = "./assets/jadb.sqlite";
NIX_LIBTAMERYE_PATH = "${pkgs.tamerye-sqlite-android-shared-lib}/lib/libtamerye.so";
};
};
});
+42
View File
@@ -0,0 +1,42 @@
import 'dart:io';
import 'package:code_assets/code_assets.dart';
import 'package:hooks/hooks.dart';
void main(final List<String> args) {
build(args, (input, output) async {
// final targetOS = input.config.code.targetOS;
// final arch = input.config.code.targetArchitecture;
// final (osName, fileName) = switch (targetOS) {
// OS.linux => ('linux', 'vec0.so'),
// OS.macOS => ('macos', 'vec0.dylib'),
// OS.windows => ('windows', 'vec0.dll'),
// _ => throw UnsupportedError('Unsupported target os $targetOS'),
// };
// final archName = switch (arch) {
// Architecture.x64 => 'x86_64',
// Architecture.arm64 => 'aarch64',
// _ => throw UnsupportedError('Unsupported target architecture $arch'),
// };
final libtameryePath = Platform.environment['NIX_LIBTAMERYE_PATH'] ?? 'assets/libtamerye.so';
if (!File(libtameryePath).existsSync()) {
throw Exception('Could not find libtamerye at path: $libtameryePath. Please set the NIX_LIBTAMERYE_PATH environment variable to the correct path.');
}
final targetFilePath = input.outputDirectory.resolve('libtamerye.so');
final targetFile = File(targetFilePath.toFilePath());
await targetFile.create(recursive: true);
await File(libtameryePath).copy(targetFile.path);
output.assets.code.add(
CodeAsset(
package: 'mugiten',
name: 'libtamerye.dart',
file: targetFilePath,
linkMode: DynamicLoadingBundled(),
),
);
});
}
+27
View File
@@ -0,0 +1,27 @@
// ignore_for_file: non_constant_identifier_names
import 'dart:ffi';
import 'package:sqlite3/sqlite3.dart';
@Native<Int Function(Pointer<Void>, Pointer<Void>, Pointer<Void>)>()
external int sqlite3_tamerye_init(
final Pointer<Void> db,
final Pointer<Void> pzErrMsg,
final Pointer<Void> pApi,
);
extension LoadVectorExtension on Sqlite3 {
void loadSqliteTameryeExtension() {
ensureExtensionLoaded(
SqliteExtension(
Native.addressOf<
NativeFunction<
Int Function(Pointer<Void>, Pointer<Void>, Pointer<Void>)
>
>(sqlite3_tamerye_init)
.cast(),
),
);
}
}
+16
View File
@@ -4,10 +4,13 @@ import 'dart:io';
import 'package:get_it/get_it.dart';
import 'package:jadb/search.dart';
import 'package:jadb/version.dart';
import 'package:mugiten/libtamerye.dart';
import 'package:mugiten/models/verify_tables.dart';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
import 'package:sqflite_common_ffi/sqflite_ffi.dart' show databaseFactoryFfi, sqfliteFfiInit;
import 'package:sqlite3/sqlite3.dart' show sqlite3;
export 'package:mugiten/services/database/database_reset.dart'
show resetDatabase;
@@ -65,6 +68,13 @@ Future<Database> openDatabaseWithoutMigrations(
final bool verifyTables = true,
}) async {
log('Opening database at $dbPath');
sqfliteFfiInit();
sqlite3.loadSqliteTameryeExtension();
databaseFactory = databaseFactoryFfi;
final Database database = await openDatabase(
dbPath,
version: schemaVersion,
@@ -81,6 +91,12 @@ Future<Database> openDatabaseWithoutMigrations(
log('Verifying mugiten tables...');
await verifyMugitenTablesWithDbConnection(db);
log('Verifying libtamerye has been loaded correctly...');
final result = await db.rawQuery("SELECT hiragana_to_katakana('ひらがな')");
if (result.isEmpty || result.first.values.first != 'ヒラガナ') {
throw Exception('libtamerye does not seem to be loaded correctly');
}
log('Database tables verified successfully');
}
},
+20 -4
View File
@@ -4,9 +4,13 @@ import 'dart:io';
import 'package:flutter/services.dart';
import 'package:jadb/search.dart';
import 'package:mugiten/libtamerye.dart';
import 'package:mugiten/services/database/database.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'package:sqflite_common_ffi/sqflite_ffi.dart'
show databaseFactoryFfi, sqfliteFfiInit;
import 'package:sqlite3/sqlite3.dart' show sqlite3;
/// Extracts the `jadb.sqlite` file from the assets into a writable directory
/// and returns its path.
@@ -125,10 +129,20 @@ Future<Database> resetDatabase(final String dbPath) async {
mugitenSchemaVersion,
);
sqfliteFfiInit();
sqlite3.loadSqliteTameryeExtension();
databaseFactory = databaseFactoryFfi;
final Database database = await openDatabase(
dbPath,
version: schemaVersion,
readOnly: false,
onConfigure: (final db) async {
// Enable foreign key constraints
await db.execute('PRAGMA foreign_keys=ON');
},
onUpgrade: (final db, final oldVersion, final newVersion) async {
assert(
oldVersion == 0,
@@ -139,10 +153,6 @@ Future<Database> resetDatabase(final String dbPath) async {
await applyMigrations(db, migrations);
log('Database upgrade complete');
},
onConfigure: (final db) async {
// Enable foreign key constraints
await db.execute('PRAGMA foreign_keys=ON');
},
onOpen: (final db) async {
log('Verifying jadb tables...');
await db.jadbVerifyTables();
@@ -151,6 +161,12 @@ Future<Database> resetDatabase(final String dbPath) async {
// TODO: verify mugiten tables for the exact schema version.
// await verifyMugitenTablesWithDbConnection(db);
log('Verifying libtamerye has been loaded correctly...');
final result = await db.rawQuery("SELECT hiragana_to_katakana('ひらがな')");
if (result.isEmpty || result.first.values.first != 'ヒラガナ') {
throw Exception('libtamerye does not seem to be loaded correctly');
}
log('Database tables verified successfully');
},
);
+2 -2
View File
@@ -98,7 +98,7 @@ packages:
source: hosted
version: "1.1.2"
code_assets:
dependency: transitive
dependency: "direct main"
description:
name: code_assets
sha256: bf394f466ba9205f1812a0433b392d6af280f155f56651eda7c18cc32ed493b8
@@ -369,7 +369,7 @@ packages:
source: hosted
version: "0.14.2"
hooks:
dependency: transitive
dependency: "direct main"
description:
name: hooks
sha256: "9a62a50b50b769a737bc0a8ff381f333529df3ab746b2f6b02e83760231455ba"
+2
View File
@@ -50,6 +50,8 @@ dependencies:
sqlite3: ^3.0.0
sqlite3_flutter_libs: ^0.6.0+eol
url_launcher: ^6.3.1
code_assets: ^1.2.1
hooks: ^2.0.2
dev_dependencies:
flutter_test: