Merge branch 'refactor/unify-datatabase-files'

This commit is contained in:
Álvaro González 2026-02-14 19:17:16 +01:00
commit 865142e158
10 changed files with 30191 additions and 458 deletions

View file

@ -1,6 +1,5 @@
import 'corpus_database_interface.dart'; import 'corpus_database_interface.dart';
import 'formulas_database.dart' import 'formulas_database.dart';
if (dart.library.html) 'formulas_database_web.dart';
import 'package:d4rt_formulas/formula_models.dart' as models; import 'package:d4rt_formulas/formula_models.dart' as models;
// Extension to add corpus loading/saving functionality to FormulasDatabase // Extension to add corpus loading/saving functionality to FormulasDatabase

View file

@ -1,8 +1,9 @@
import 'package:drift/drift.dart'; import 'package:drift/drift.dart';
import 'package:drift/native.dart';
import 'package:path/path.dart' as p; import 'formulas_database_unsupported.dart'
import 'package:path_provider/path_provider.dart'; if (dart.library.html) 'formulas_database_web.dart'
import 'dart:io'; if (dart.library.ffi) 'formulas_database_native.dart';
part 'formulas_database.g.dart'; part 'formulas_database.g.dart';
@ -14,7 +15,7 @@ class FormulaElements extends Table {
@DriftDatabase(tables: [FormulaElements]) @DriftDatabase(tables: [FormulaElements])
class FormulasDatabase extends _$FormulasDatabase { class FormulasDatabase extends _$FormulasDatabase {
FormulasDatabase() : super(_openConnection()); FormulasDatabase() : super(openConnection());
@override @override
int get schemaVersion => 1; int get schemaVersion => 1;
@ -44,29 +45,8 @@ class FormulasDatabase extends _$FormulasDatabase {
Future<void> deleteFormulaElement(int id) { Future<void> deleteFormulaElement(int id) {
return (delete(formulaElements)..where((tbl) => tbl.id.equals(id))).go(); return (delete(formulaElements)..where((tbl) => tbl.id.equals(id))).go();
} }
// Additional helper methods for direct access to the table // Additional helper methods for direct access to the table
SimpleSelectStatement get allFormulaElements => select(formulaElements); SimpleSelectStatement get allFormulaElements => select(formulaElements);
} }
LazyDatabase _openConnection() {
return LazyDatabase(() async {
// Determine the platform-specific database directory
Directory dbDirectory;
if (Platform.isLinux || Platform.isWindows || Platform.isMacOS) {
final appSupportDir = await getApplicationSupportDirectory();
dbDirectory = Directory(p.join(appSupportDir.path, 'd4rt_formulas'));
} else {
dbDirectory = await getApplicationDocumentsDirectory();
}
// Ensure the directory exists
await dbDirectory.create(recursive: true);
// Create the database file in the platform-specific directory
final file = File(p.join(dbDirectory.path, 'formulas.sqlite'));
return NativeDatabase.createInBackground(file);
});
}

View file

@ -0,0 +1,28 @@
import 'package:drift/drift.dart';
import 'package:drift/native.dart';
import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart';
import 'dart:io';
LazyDatabase openConnection() {
return LazyDatabase(() async {
// Determine the platform-specific database directory
Directory dbDirectory;
if (Platform.isLinux || Platform.isWindows || Platform.isMacOS) {
final appSupportDir = await getApplicationSupportDirectory();
dbDirectory = Directory(p.join(appSupportDir.path, 'd4rt_formulas'));
} else {
dbDirectory = await getApplicationDocumentsDirectory();
}
// Ensure the directory exists
await dbDirectory.create(recursive: true);
// Create the database file in the platform-specific directory
final file = File(p.join(dbDirectory.path, 'formulas.sqlite'));
return NativeDatabase.createInBackground(file);
});
}

View file

@ -0,0 +1,6 @@
import 'package:drift/drift.dart';
LazyDatabase openConnection() {
throw UnsupportedError('This platform is not supported for FormulasDatabase');
}

View file

@ -1,56 +1,16 @@
import 'package:drift/drift.dart'; import 'package:drift/drift.dart';
import 'package:drift/web.dart'; import 'package:drift/wasm.dart';
part 'formulas_database_web.g.dart';
// Define the FORMULAELEMENT table to store both formulas and units as text LazyDatabase openConnection() {
class FormulaElements extends Table {
IntColumn get id => integer().autoIncrement()();
TextColumn get elementText => text()();
}
@DriftDatabase(tables: [FormulaElements])
class FormulasDatabase extends _$FormulasDatabase {
FormulasDatabase() : super(_openConnection());
@override
int get schemaVersion => 1;
// Method to insert a new formula element (either formula or unit)
Future<int> insertFormulaElement(String elementText) {
return into(formulaElements).insert(FormulaElementsCompanion.insert(elementText: elementText));
}
// Method to get all formula elements
Future<List<FormulaElement>> getAllFormulaElements() {
return select(formulaElements).get();
}
// Method to get a formula element by ID
Future<FormulaElement?> getFormulaElementById(int id) {
return (select(formulaElements)..where((tbl) => tbl.id.equals(id))).getSingleOrNull();
}
// Method to update a formula element
Future<void> updateFormulaElement(int id, String newElementText) {
return (update(formulaElements)..where((tbl) => tbl.id.equals(id)))
.write(FormulaElementsCompanion.insert(elementText: newElementText));
}
// Method to delete a formula element
Future<void> deleteFormulaElement(int id) {
return (delete(formulaElements)..where((tbl) => tbl.id.equals(id))).go();
}
// Additional helper methods for direct access to the table
SimpleSelectStatement get allFormulaElements => select(formulaElements);
}
LazyDatabase _openConnection() {
return LazyDatabase(() async { return LazyDatabase(() async {
// For web, use the web implementation final db = await WasmDatabase.open(
return WebDatabase.withStorage( databaseName: 'd4rt_formulas',
await DriftWebStorage.indexedDb('formulas_db'), sqlite3Uri: Uri.parse('sqlite3.wasm'),
driftWorkerUri: Uri.parse('drift_worker.js'),
); );
return db.resolvedExecutor;
}); });
} }

View file

@ -1,378 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'formulas_database_web.dart';
// ignore_for_file: type=lint
class $FormulaElementsTable extends FormulaElements
with TableInfo<$FormulaElementsTable, FormulaElement> {
@override
final GeneratedDatabase attachedDatabase;
final String? _alias;
$FormulaElementsTable(this.attachedDatabase, [this._alias]);
static const VerificationMeta _idMeta = const VerificationMeta('id');
@override
late final GeneratedColumn<int> id = GeneratedColumn<int>(
'id',
aliasedName,
false,
hasAutoIncrement: true,
type: DriftSqlType.int,
requiredDuringInsert: false,
defaultConstraints: GeneratedColumn.constraintIsAlways(
'PRIMARY KEY AUTOINCREMENT',
),
);
static const VerificationMeta _elementTextMeta = const VerificationMeta(
'elementText',
);
@override
late final GeneratedColumn<String> elementText = GeneratedColumn<String>(
'element_text',
aliasedName,
false,
type: DriftSqlType.string,
requiredDuringInsert: true,
);
@override
List<GeneratedColumn> get $columns => [id, elementText];
@override
String get aliasedName => _alias ?? actualTableName;
@override
String get actualTableName => $name;
static const String $name = 'formula_elements';
@override
VerificationContext validateIntegrity(
Insertable<FormulaElement> instance, {
bool isInserting = false,
}) {
final context = VerificationContext();
final data = instance.toColumns(true);
if (data.containsKey('id')) {
context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta));
}
if (data.containsKey('element_text')) {
context.handle(
_elementTextMeta,
elementText.isAcceptableOrUnknown(
data['element_text']!,
_elementTextMeta,
),
);
} else if (isInserting) {
context.missing(_elementTextMeta);
}
return context;
}
@override
Set<GeneratedColumn> get $primaryKey => {id};
@override
FormulaElement map(Map<String, dynamic> data, {String? tablePrefix}) {
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
return FormulaElement(
id: attachedDatabase.typeMapping.read(
DriftSqlType.int,
data['${effectivePrefix}id'],
)!,
elementText: attachedDatabase.typeMapping.read(
DriftSqlType.string,
data['${effectivePrefix}element_text'],
)!,
);
}
@override
$FormulaElementsTable createAlias(String alias) {
return $FormulaElementsTable(attachedDatabase, alias);
}
}
class FormulaElement extends DataClass implements Insertable<FormulaElement> {
final int id;
final String elementText;
const FormulaElement({required this.id, required this.elementText});
@override
Map<String, Expression> toColumns(bool nullToAbsent) {
final map = <String, Expression>{};
map['id'] = Variable<int>(id);
map['element_text'] = Variable<String>(elementText);
return map;
}
FormulaElementsCompanion toCompanion(bool nullToAbsent) {
return FormulaElementsCompanion(
id: Value(id),
elementText: Value(elementText),
);
}
factory FormulaElement.fromJson(
Map<String, dynamic> json, {
ValueSerializer? serializer,
}) {
serializer ??= driftRuntimeOptions.defaultSerializer;
return FormulaElement(
id: serializer.fromJson<int>(json['id']),
elementText: serializer.fromJson<String>(json['elementText']),
);
}
@override
Map<String, dynamic> toJson({ValueSerializer? serializer}) {
serializer ??= driftRuntimeOptions.defaultSerializer;
return <String, dynamic>{
'id': serializer.toJson<int>(id),
'elementText': serializer.toJson<String>(elementText),
};
}
FormulaElement copyWith({int? id, String? elementText}) => FormulaElement(
id: id ?? this.id,
elementText: elementText ?? this.elementText,
);
FormulaElement copyWithCompanion(FormulaElementsCompanion data) {
return FormulaElement(
id: data.id.present ? data.id.value : this.id,
elementText: data.elementText.present
? data.elementText.value
: this.elementText,
);
}
@override
String toString() {
return (StringBuffer('FormulaElement(')
..write('id: $id, ')
..write('elementText: $elementText')
..write(')'))
.toString();
}
@override
int get hashCode => Object.hash(id, elementText);
@override
bool operator ==(Object other) =>
identical(this, other) ||
(other is FormulaElement &&
other.id == this.id &&
other.elementText == this.elementText);
}
class FormulaElementsCompanion extends UpdateCompanion<FormulaElement> {
final Value<int> id;
final Value<String> elementText;
const FormulaElementsCompanion({
this.id = const Value.absent(),
this.elementText = const Value.absent(),
});
FormulaElementsCompanion.insert({
this.id = const Value.absent(),
required String elementText,
}) : elementText = Value(elementText);
static Insertable<FormulaElement> custom({
Expression<int>? id,
Expression<String>? elementText,
}) {
return RawValuesInsertable({
if (id != null) 'id': id,
if (elementText != null) 'element_text': elementText,
});
}
FormulaElementsCompanion copyWith({
Value<int>? id,
Value<String>? elementText,
}) {
return FormulaElementsCompanion(
id: id ?? this.id,
elementText: elementText ?? this.elementText,
);
}
@override
Map<String, Expression> toColumns(bool nullToAbsent) {
final map = <String, Expression>{};
if (id.present) {
map['id'] = Variable<int>(id.value);
}
if (elementText.present) {
map['element_text'] = Variable<String>(elementText.value);
}
return map;
}
@override
String toString() {
return (StringBuffer('FormulaElementsCompanion(')
..write('id: $id, ')
..write('elementText: $elementText')
..write(')'))
.toString();
}
}
abstract class _$FormulasDatabase extends GeneratedDatabase {
_$FormulasDatabase(QueryExecutor e) : super(e);
$FormulasDatabaseManager get managers => $FormulasDatabaseManager(this);
late final $FormulaElementsTable formulaElements = $FormulaElementsTable(
this,
);
@override
Iterable<TableInfo<Table, Object?>> get allTables =>
allSchemaEntities.whereType<TableInfo<Table, Object?>>();
@override
List<DatabaseSchemaEntity> get allSchemaEntities => [formulaElements];
}
typedef $$FormulaElementsTableCreateCompanionBuilder =
FormulaElementsCompanion Function({
Value<int> id,
required String elementText,
});
typedef $$FormulaElementsTableUpdateCompanionBuilder =
FormulaElementsCompanion Function({
Value<int> id,
Value<String> elementText,
});
class $$FormulaElementsTableFilterComposer
extends Composer<_$FormulasDatabase, $FormulaElementsTable> {
$$FormulaElementsTableFilterComposer({
required super.$db,
required super.$table,
super.joinBuilder,
super.$addJoinBuilderToRootComposer,
super.$removeJoinBuilderFromRootComposer,
});
ColumnFilters<int> get id => $composableBuilder(
column: $table.id,
builder: (column) => ColumnFilters(column),
);
ColumnFilters<String> get elementText => $composableBuilder(
column: $table.elementText,
builder: (column) => ColumnFilters(column),
);
}
class $$FormulaElementsTableOrderingComposer
extends Composer<_$FormulasDatabase, $FormulaElementsTable> {
$$FormulaElementsTableOrderingComposer({
required super.$db,
required super.$table,
super.joinBuilder,
super.$addJoinBuilderToRootComposer,
super.$removeJoinBuilderFromRootComposer,
});
ColumnOrderings<int> get id => $composableBuilder(
column: $table.id,
builder: (column) => ColumnOrderings(column),
);
ColumnOrderings<String> get elementText => $composableBuilder(
column: $table.elementText,
builder: (column) => ColumnOrderings(column),
);
}
class $$FormulaElementsTableAnnotationComposer
extends Composer<_$FormulasDatabase, $FormulaElementsTable> {
$$FormulaElementsTableAnnotationComposer({
required super.$db,
required super.$table,
super.joinBuilder,
super.$addJoinBuilderToRootComposer,
super.$removeJoinBuilderFromRootComposer,
});
GeneratedColumn<int> get id =>
$composableBuilder(column: $table.id, builder: (column) => column);
GeneratedColumn<String> get elementText => $composableBuilder(
column: $table.elementText,
builder: (column) => column,
);
}
class $$FormulaElementsTableTableManager
extends
RootTableManager<
_$FormulasDatabase,
$FormulaElementsTable,
FormulaElement,
$$FormulaElementsTableFilterComposer,
$$FormulaElementsTableOrderingComposer,
$$FormulaElementsTableAnnotationComposer,
$$FormulaElementsTableCreateCompanionBuilder,
$$FormulaElementsTableUpdateCompanionBuilder,
(
FormulaElement,
BaseReferences<
_$FormulasDatabase,
$FormulaElementsTable,
FormulaElement
>,
),
FormulaElement,
PrefetchHooks Function()
> {
$$FormulaElementsTableTableManager(
_$FormulasDatabase db,
$FormulaElementsTable table,
) : super(
TableManagerState(
db: db,
table: table,
createFilteringComposer: () =>
$$FormulaElementsTableFilterComposer($db: db, $table: table),
createOrderingComposer: () =>
$$FormulaElementsTableOrderingComposer($db: db, $table: table),
createComputedFieldComposer: () =>
$$FormulaElementsTableAnnotationComposer($db: db, $table: table),
updateCompanionCallback:
({
Value<int> id = const Value.absent(),
Value<String> elementText = const Value.absent(),
}) => FormulaElementsCompanion(id: id, elementText: elementText),
createCompanionCallback:
({
Value<int> id = const Value.absent(),
required String elementText,
}) => FormulaElementsCompanion.insert(
id: id,
elementText: elementText,
),
withReferenceMapper: (p0) => p0
.map((e) => (e.readTable(table), BaseReferences(db, table, e)))
.toList(),
prefetchHooksCallback: null,
),
);
}
typedef $$FormulaElementsTableProcessedTableManager =
ProcessedTableManager<
_$FormulasDatabase,
$FormulaElementsTable,
FormulaElement,
$$FormulaElementsTableFilterComposer,
$$FormulaElementsTableOrderingComposer,
$$FormulaElementsTableAnnotationComposer,
$$FormulaElementsTableCreateCompanionBuilder,
$$FormulaElementsTableUpdateCompanionBuilder,
(
FormulaElement,
BaseReferences<
_$FormulasDatabase,
$FormulaElementsTable,
FormulaElement
>,
),
FormulaElement,
PrefetchHooks Function()
>;
class $FormulasDatabaseManager {
final _$FormulasDatabase _db;
$FormulasDatabaseManager(this._db);
$$FormulaElementsTableTableManager get formulaElements =>
$$FormulaElementsTableTableManager(_db, _db.formulaElements);
}

View file

@ -1,6 +1,6 @@
import 'package:get_it/get_it.dart'; import 'package:get_it/get_it.dart';
import 'database/formulas_database.dart'
if (dart.library.html) 'database/formulas_database_web.dart'; import 'database/formulas_database.dart';
GetIt locator = GetIt.instance; GetIt locator = GetIt.instance;

30129
web/drift_worker.js Normal file

File diff suppressed because one or more lines are too long

BIN
web/sqlite3.wasm Normal file

Binary file not shown.

9
web/worker.dart Normal file
View file

@ -0,0 +1,9 @@
import 'package:drift/wasm.dart';
/// This Dart program is the entrypoint of a web worker that will be compiled to
/// JavaScript by running `build_runner build`. The resulting JavaScript file
/// (`shared_worker.dart.js`) is part of the build result and will be shipped
/// with the rest of the application when running or building a Flutter web app.
void main() {
return WasmDatabase.workerMainForOpen();
}