con drift

This commit is contained in:
Your Name 2026-02-07 17:01:37 +01:00
parent 20a981ad9f
commit 5ef88beef5
15 changed files with 1200 additions and 26 deletions

View file

@ -1,7 +1,20 @@
FROM ghcr.io/cirruslabs/flutter:stable FROM ghcr.io/cirruslabs/flutter:stable
# Install cmake, ninja, clang, pkg-config for flutter linux # Install cmake, ninja, clang, pkg-config, and other tools for flutter linux
RUN apt-get update && apt-get install -y cmake ninja-build clang pkg-config libgtk-3-dev liblzma-dev RUN apt-get update && apt-get install -y \
cmake \
ninja-build \
clang \
pkg-config \
libgtk-3-dev \
liblzma-dev \
binutils-dev \
build-essential \
lld \
binutils
# Create symlinks for the linker to ensure it's accessible
RUN ln -sf /usr/bin/ld.lld /usr/bin/ld
WORKDIR /app WORKDIR /app

View file

@ -0,0 +1,15 @@
import 'package:get_it/get_it.dart';
// Conditionally import the correct database file based on platform
import 'formulas_database.dart'
if (dart.library.html) 'formulas_database_web.dart';
GetIt locator = GetIt.instance;
void setupLocator() {
locator.registerSingleton<FormulasDatabase>(FormulasDatabase());
}
FormulasDatabase getDatabase() {
return locator<FormulasDatabase>();
}

View file

@ -0,0 +1,56 @@
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';
part 'formulas_database.g.dart';
// Define the formulas table with a single text column for formula descriptions
class Formulas extends Table {
IntColumn get id => integer().autoIncrement()();
TextColumn get formula => text()();
}
@DriftDatabase(tables: [Formulas])
class FormulasDatabase extends _$FormulasDatabase {
FormulasDatabase() : super(_openConnection());
@override
int get schemaVersion => 1;
// Method to insert a new formula
Future<int> insertFormula(String formulaText) {
return into(formulas).insert(FormulasCompanion.insert(formula: formulaText));
}
// Method to get all formulas
Future<List<Formula>> getAllFormulas() {
return select(formulas).get();
}
// Method to get a formula by ID
Future<Formula?> getFormulaById(int id) {
return (select(formulas)..where((tbl) => tbl.id.equals(id))).getSingleOrNull();
}
// Method to update a formula
Future<void> updateFormula(int id, String newFormula) {
return (update(formulas)..where((tbl) => tbl.id.equals(id)))
.write(FormulasCompanion.insert(formula: newFormula));
}
// Method to delete a formula
Future<void> deleteFormula(int id) {
return (delete(formulas)..where((tbl) => tbl.id.equals(id))).go();
}
}
LazyDatabase _openConnection() {
return LazyDatabase(() async {
// For native platforms (Linux, Windows, macOS, Android, iOS)
final dbFolder = await getApplicationDocumentsDirectory();
final file = File(p.join(dbFolder.path, 'formulas.sqlite'));
return NativeDatabase.createInBackground(file);
});
}

View file

@ -0,0 +1,338 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'formulas_database.dart';
// ignore_for_file: type=lint
class $FormulasTable extends Formulas with TableInfo<$FormulasTable, Formula> {
@override
final GeneratedDatabase attachedDatabase;
final String? _alias;
$FormulasTable(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 _formulaMeta = const VerificationMeta(
'formula',
);
@override
late final GeneratedColumn<String> formula = GeneratedColumn<String>(
'formula',
aliasedName,
false,
type: DriftSqlType.string,
requiredDuringInsert: true,
);
@override
List<GeneratedColumn> get $columns => [id, formula];
@override
String get aliasedName => _alias ?? actualTableName;
@override
String get actualTableName => $name;
static const String $name = 'formulas';
@override
VerificationContext validateIntegrity(
Insertable<Formula> 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('formula')) {
context.handle(
_formulaMeta,
formula.isAcceptableOrUnknown(data['formula']!, _formulaMeta),
);
} else if (isInserting) {
context.missing(_formulaMeta);
}
return context;
}
@override
Set<GeneratedColumn> get $primaryKey => {id};
@override
Formula map(Map<String, dynamic> data, {String? tablePrefix}) {
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
return Formula(
id: attachedDatabase.typeMapping.read(
DriftSqlType.int,
data['${effectivePrefix}id'],
)!,
formula: attachedDatabase.typeMapping.read(
DriftSqlType.string,
data['${effectivePrefix}formula'],
)!,
);
}
@override
$FormulasTable createAlias(String alias) {
return $FormulasTable(attachedDatabase, alias);
}
}
class Formula extends DataClass implements Insertable<Formula> {
final int id;
final String formula;
const Formula({required this.id, required this.formula});
@override
Map<String, Expression> toColumns(bool nullToAbsent) {
final map = <String, Expression>{};
map['id'] = Variable<int>(id);
map['formula'] = Variable<String>(formula);
return map;
}
FormulasCompanion toCompanion(bool nullToAbsent) {
return FormulasCompanion(id: Value(id), formula: Value(formula));
}
factory Formula.fromJson(
Map<String, dynamic> json, {
ValueSerializer? serializer,
}) {
serializer ??= driftRuntimeOptions.defaultSerializer;
return Formula(
id: serializer.fromJson<int>(json['id']),
formula: serializer.fromJson<String>(json['formula']),
);
}
@override
Map<String, dynamic> toJson({ValueSerializer? serializer}) {
serializer ??= driftRuntimeOptions.defaultSerializer;
return <String, dynamic>{
'id': serializer.toJson<int>(id),
'formula': serializer.toJson<String>(formula),
};
}
Formula copyWith({int? id, String? formula}) =>
Formula(id: id ?? this.id, formula: formula ?? this.formula);
Formula copyWithCompanion(FormulasCompanion data) {
return Formula(
id: data.id.present ? data.id.value : this.id,
formula: data.formula.present ? data.formula.value : this.formula,
);
}
@override
String toString() {
return (StringBuffer('Formula(')
..write('id: $id, ')
..write('formula: $formula')
..write(')'))
.toString();
}
@override
int get hashCode => Object.hash(id, formula);
@override
bool operator ==(Object other) =>
identical(this, other) ||
(other is Formula &&
other.id == this.id &&
other.formula == this.formula);
}
class FormulasCompanion extends UpdateCompanion<Formula> {
final Value<int> id;
final Value<String> formula;
const FormulasCompanion({
this.id = const Value.absent(),
this.formula = const Value.absent(),
});
FormulasCompanion.insert({
this.id = const Value.absent(),
required String formula,
}) : formula = Value(formula);
static Insertable<Formula> custom({
Expression<int>? id,
Expression<String>? formula,
}) {
return RawValuesInsertable({
if (id != null) 'id': id,
if (formula != null) 'formula': formula,
});
}
FormulasCompanion copyWith({Value<int>? id, Value<String>? formula}) {
return FormulasCompanion(
id: id ?? this.id,
formula: formula ?? this.formula,
);
}
@override
Map<String, Expression> toColumns(bool nullToAbsent) {
final map = <String, Expression>{};
if (id.present) {
map['id'] = Variable<int>(id.value);
}
if (formula.present) {
map['formula'] = Variable<String>(formula.value);
}
return map;
}
@override
String toString() {
return (StringBuffer('FormulasCompanion(')
..write('id: $id, ')
..write('formula: $formula')
..write(')'))
.toString();
}
}
abstract class _$FormulasDatabase extends GeneratedDatabase {
_$FormulasDatabase(QueryExecutor e) : super(e);
$FormulasDatabaseManager get managers => $FormulasDatabaseManager(this);
late final $FormulasTable formulas = $FormulasTable(this);
@override
Iterable<TableInfo<Table, Object?>> get allTables =>
allSchemaEntities.whereType<TableInfo<Table, Object?>>();
@override
List<DatabaseSchemaEntity> get allSchemaEntities => [formulas];
}
typedef $$FormulasTableCreateCompanionBuilder =
FormulasCompanion Function({Value<int> id, required String formula});
typedef $$FormulasTableUpdateCompanionBuilder =
FormulasCompanion Function({Value<int> id, Value<String> formula});
class $$FormulasTableFilterComposer
extends Composer<_$FormulasDatabase, $FormulasTable> {
$$FormulasTableFilterComposer({
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 formula => $composableBuilder(
column: $table.formula,
builder: (column) => ColumnFilters(column),
);
}
class $$FormulasTableOrderingComposer
extends Composer<_$FormulasDatabase, $FormulasTable> {
$$FormulasTableOrderingComposer({
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 formula => $composableBuilder(
column: $table.formula,
builder: (column) => ColumnOrderings(column),
);
}
class $$FormulasTableAnnotationComposer
extends Composer<_$FormulasDatabase, $FormulasTable> {
$$FormulasTableAnnotationComposer({
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 formula =>
$composableBuilder(column: $table.formula, builder: (column) => column);
}
class $$FormulasTableTableManager
extends
RootTableManager<
_$FormulasDatabase,
$FormulasTable,
Formula,
$$FormulasTableFilterComposer,
$$FormulasTableOrderingComposer,
$$FormulasTableAnnotationComposer,
$$FormulasTableCreateCompanionBuilder,
$$FormulasTableUpdateCompanionBuilder,
(
Formula,
BaseReferences<_$FormulasDatabase, $FormulasTable, Formula>,
),
Formula,
PrefetchHooks Function()
> {
$$FormulasTableTableManager(_$FormulasDatabase db, $FormulasTable table)
: super(
TableManagerState(
db: db,
table: table,
createFilteringComposer: () =>
$$FormulasTableFilterComposer($db: db, $table: table),
createOrderingComposer: () =>
$$FormulasTableOrderingComposer($db: db, $table: table),
createComputedFieldComposer: () =>
$$FormulasTableAnnotationComposer($db: db, $table: table),
updateCompanionCallback:
({
Value<int> id = const Value.absent(),
Value<String> formula = const Value.absent(),
}) => FormulasCompanion(id: id, formula: formula),
createCompanionCallback:
({
Value<int> id = const Value.absent(),
required String formula,
}) => FormulasCompanion.insert(id: id, formula: formula),
withReferenceMapper: (p0) => p0
.map((e) => (e.readTable(table), BaseReferences(db, table, e)))
.toList(),
prefetchHooksCallback: null,
),
);
}
typedef $$FormulasTableProcessedTableManager =
ProcessedTableManager<
_$FormulasDatabase,
$FormulasTable,
Formula,
$$FormulasTableFilterComposer,
$$FormulasTableOrderingComposer,
$$FormulasTableAnnotationComposer,
$$FormulasTableCreateCompanionBuilder,
$$FormulasTableUpdateCompanionBuilder,
(Formula, BaseReferences<_$FormulasDatabase, $FormulasTable, Formula>),
Formula,
PrefetchHooks Function()
>;
class $FormulasDatabaseManager {
final _$FormulasDatabase _db;
$FormulasDatabaseManager(this._db);
$$FormulasTableTableManager get formulas =>
$$FormulasTableTableManager(_db, _db.formulas);
}

View file

@ -0,0 +1,54 @@
import 'package:drift/drift.dart';
import 'package:drift/web.dart';
import 'package:path_provider/path_provider.dart';
part 'formulas_database_web.g.dart';
// Define the formulas table with a single text column for formula descriptions
class Formulas extends Table {
IntColumn get id => integer().autoIncrement()();
TextColumn get formula => text()();
}
@DriftDatabase(tables: [Formulas])
class FormulasDatabase extends _$FormulasDatabase {
FormulasDatabase() : super(_openConnection());
@override
int get schemaVersion => 1;
// Method to insert a new formula
Future<int> insertFormula(String formulaText) {
return into(formulas).insert(FormulasCompanion.insert(formula: formulaText));
}
// Method to get all formulas
Future<List<Formula>> getAllFormulas() {
return select(formulas).get();
}
// Method to get a formula by ID
Future<Formula?> getFormulaById(int id) {
return (select(formulas)..where((tbl) => tbl.id.equals(id))).getSingleOrNull();
}
// Method to update a formula
Future<void> updateFormula(int id, String newFormula) {
return (update(formulas)..where((tbl) => tbl.id.equals(id)))
.write(FormulasCompanion.insert(formula: newFormula));
}
// Method to delete a formula
Future<void> deleteFormula(int id) {
return (delete(formulas)..where((tbl) => tbl.id.equals(id))).go();
}
}
LazyDatabase _openConnection() {
return LazyDatabase(() async {
// For web, use the web implementation
return WebDatabase.withStorage(
await DriftWebStorage.indexedDb('formulas_db'),
);
});
}

View file

@ -0,0 +1,338 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'formulas_database_web.dart';
// ignore_for_file: type=lint
class $FormulasTable extends Formulas with TableInfo<$FormulasTable, Formula> {
@override
final GeneratedDatabase attachedDatabase;
final String? _alias;
$FormulasTable(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 _formulaMeta = const VerificationMeta(
'formula',
);
@override
late final GeneratedColumn<String> formula = GeneratedColumn<String>(
'formula',
aliasedName,
false,
type: DriftSqlType.string,
requiredDuringInsert: true,
);
@override
List<GeneratedColumn> get $columns => [id, formula];
@override
String get aliasedName => _alias ?? actualTableName;
@override
String get actualTableName => $name;
static const String $name = 'formulas';
@override
VerificationContext validateIntegrity(
Insertable<Formula> 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('formula')) {
context.handle(
_formulaMeta,
formula.isAcceptableOrUnknown(data['formula']!, _formulaMeta),
);
} else if (isInserting) {
context.missing(_formulaMeta);
}
return context;
}
@override
Set<GeneratedColumn> get $primaryKey => {id};
@override
Formula map(Map<String, dynamic> data, {String? tablePrefix}) {
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
return Formula(
id: attachedDatabase.typeMapping.read(
DriftSqlType.int,
data['${effectivePrefix}id'],
)!,
formula: attachedDatabase.typeMapping.read(
DriftSqlType.string,
data['${effectivePrefix}formula'],
)!,
);
}
@override
$FormulasTable createAlias(String alias) {
return $FormulasTable(attachedDatabase, alias);
}
}
class Formula extends DataClass implements Insertable<Formula> {
final int id;
final String formula;
const Formula({required this.id, required this.formula});
@override
Map<String, Expression> toColumns(bool nullToAbsent) {
final map = <String, Expression>{};
map['id'] = Variable<int>(id);
map['formula'] = Variable<String>(formula);
return map;
}
FormulasCompanion toCompanion(bool nullToAbsent) {
return FormulasCompanion(id: Value(id), formula: Value(formula));
}
factory Formula.fromJson(
Map<String, dynamic> json, {
ValueSerializer? serializer,
}) {
serializer ??= driftRuntimeOptions.defaultSerializer;
return Formula(
id: serializer.fromJson<int>(json['id']),
formula: serializer.fromJson<String>(json['formula']),
);
}
@override
Map<String, dynamic> toJson({ValueSerializer? serializer}) {
serializer ??= driftRuntimeOptions.defaultSerializer;
return <String, dynamic>{
'id': serializer.toJson<int>(id),
'formula': serializer.toJson<String>(formula),
};
}
Formula copyWith({int? id, String? formula}) =>
Formula(id: id ?? this.id, formula: formula ?? this.formula);
Formula copyWithCompanion(FormulasCompanion data) {
return Formula(
id: data.id.present ? data.id.value : this.id,
formula: data.formula.present ? data.formula.value : this.formula,
);
}
@override
String toString() {
return (StringBuffer('Formula(')
..write('id: $id, ')
..write('formula: $formula')
..write(')'))
.toString();
}
@override
int get hashCode => Object.hash(id, formula);
@override
bool operator ==(Object other) =>
identical(this, other) ||
(other is Formula &&
other.id == this.id &&
other.formula == this.formula);
}
class FormulasCompanion extends UpdateCompanion<Formula> {
final Value<int> id;
final Value<String> formula;
const FormulasCompanion({
this.id = const Value.absent(),
this.formula = const Value.absent(),
});
FormulasCompanion.insert({
this.id = const Value.absent(),
required String formula,
}) : formula = Value(formula);
static Insertable<Formula> custom({
Expression<int>? id,
Expression<String>? formula,
}) {
return RawValuesInsertable({
if (id != null) 'id': id,
if (formula != null) 'formula': formula,
});
}
FormulasCompanion copyWith({Value<int>? id, Value<String>? formula}) {
return FormulasCompanion(
id: id ?? this.id,
formula: formula ?? this.formula,
);
}
@override
Map<String, Expression> toColumns(bool nullToAbsent) {
final map = <String, Expression>{};
if (id.present) {
map['id'] = Variable<int>(id.value);
}
if (formula.present) {
map['formula'] = Variable<String>(formula.value);
}
return map;
}
@override
String toString() {
return (StringBuffer('FormulasCompanion(')
..write('id: $id, ')
..write('formula: $formula')
..write(')'))
.toString();
}
}
abstract class _$FormulasDatabase extends GeneratedDatabase {
_$FormulasDatabase(QueryExecutor e) : super(e);
$FormulasDatabaseManager get managers => $FormulasDatabaseManager(this);
late final $FormulasTable formulas = $FormulasTable(this);
@override
Iterable<TableInfo<Table, Object?>> get allTables =>
allSchemaEntities.whereType<TableInfo<Table, Object?>>();
@override
List<DatabaseSchemaEntity> get allSchemaEntities => [formulas];
}
typedef $$FormulasTableCreateCompanionBuilder =
FormulasCompanion Function({Value<int> id, required String formula});
typedef $$FormulasTableUpdateCompanionBuilder =
FormulasCompanion Function({Value<int> id, Value<String> formula});
class $$FormulasTableFilterComposer
extends Composer<_$FormulasDatabase, $FormulasTable> {
$$FormulasTableFilterComposer({
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 formula => $composableBuilder(
column: $table.formula,
builder: (column) => ColumnFilters(column),
);
}
class $$FormulasTableOrderingComposer
extends Composer<_$FormulasDatabase, $FormulasTable> {
$$FormulasTableOrderingComposer({
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 formula => $composableBuilder(
column: $table.formula,
builder: (column) => ColumnOrderings(column),
);
}
class $$FormulasTableAnnotationComposer
extends Composer<_$FormulasDatabase, $FormulasTable> {
$$FormulasTableAnnotationComposer({
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 formula =>
$composableBuilder(column: $table.formula, builder: (column) => column);
}
class $$FormulasTableTableManager
extends
RootTableManager<
_$FormulasDatabase,
$FormulasTable,
Formula,
$$FormulasTableFilterComposer,
$$FormulasTableOrderingComposer,
$$FormulasTableAnnotationComposer,
$$FormulasTableCreateCompanionBuilder,
$$FormulasTableUpdateCompanionBuilder,
(
Formula,
BaseReferences<_$FormulasDatabase, $FormulasTable, Formula>,
),
Formula,
PrefetchHooks Function()
> {
$$FormulasTableTableManager(_$FormulasDatabase db, $FormulasTable table)
: super(
TableManagerState(
db: db,
table: table,
createFilteringComposer: () =>
$$FormulasTableFilterComposer($db: db, $table: table),
createOrderingComposer: () =>
$$FormulasTableOrderingComposer($db: db, $table: table),
createComputedFieldComposer: () =>
$$FormulasTableAnnotationComposer($db: db, $table: table),
updateCompanionCallback:
({
Value<int> id = const Value.absent(),
Value<String> formula = const Value.absent(),
}) => FormulasCompanion(id: id, formula: formula),
createCompanionCallback:
({
Value<int> id = const Value.absent(),
required String formula,
}) => FormulasCompanion.insert(id: id, formula: formula),
withReferenceMapper: (p0) => p0
.map((e) => (e.readTable(table), BaseReferences(db, table, e)))
.toList(),
prefetchHooksCallback: null,
),
);
}
typedef $$FormulasTableProcessedTableManager =
ProcessedTableManager<
_$FormulasDatabase,
$FormulasTable,
Formula,
$$FormulasTableFilterComposer,
$$FormulasTableOrderingComposer,
$$FormulasTableAnnotationComposer,
$$FormulasTableCreateCompanionBuilder,
$$FormulasTableUpdateCompanionBuilder,
(Formula, BaseReferences<_$FormulasDatabase, $FormulasTable, Formula>),
Formula,
PrefetchHooks Function()
>;
class $FormulasDatabaseManager {
final _$FormulasDatabase _db;
$FormulasDatabaseManager(this._db);
$$FormulasTableTableManager get formulas =>
$$FormulasTableTableManager(_db, _db.formulas);
}

View file

@ -1,32 +1,45 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'database/database_service.dart';
import 'ai/formula_list.dart'; import 'ai/formula_list.dart';
import 'corpus.dart'; import 'corpus.dart';
import 'defaults/default_corpus.dart'; import 'defaults/default_corpus.dart';
void main() { void main() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
runApp(MaterialApp(
home: FutureBuilder<Corpus>( // Setup service locator and initialize the database
future: createDefaultCorpus(), setupLocator();
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) { runApp(const MyApp());
if (snapshot.hasError) { }
return Center(child: Text('Error loading units: ${snapshot.error}'));
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: FutureBuilder<Corpus>(
future: createDefaultCorpus(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
return Center(child: Text('Error loading units: ${snapshot.error}'));
}
return Scaffold(
appBar: AppBar(title: const Text('Formulas')),
body: FormulaList(
corpus: snapshot.data!,
formulas: snapshot.data!.getFormulas(),
),
);
} }
return Scaffold( return const Center(child: CircularProgressIndicator());
appBar: AppBar(title: const Text('Formulas')), },
body: FormulaList( ),
corpus: snapshot.data!, );
formulas: snapshot.data!.getFormulas(), }
),
);
}
return const Center(child: CircularProgressIndicator());
},
),
));
} }

View file

@ -6,9 +6,13 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <sqlite3_flutter_libs/sqlite3_flutter_libs_plugin.h>
#include <url_launcher_linux/url_launcher_plugin.h> #include <url_launcher_linux/url_launcher_plugin.h>
void fl_register_plugins(FlPluginRegistry* registry) { void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) sqlite3_flutter_libs_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "Sqlite3FlutterLibsPlugin");
sqlite3_flutter_libs_plugin_register_with_registrar(sqlite3_flutter_libs_registrar);
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);

View file

@ -3,6 +3,7 @@
# #
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
sqlite3_flutter_libs
url_launcher_linux url_launcher_linux
) )

View file

@ -5,8 +5,10 @@
import FlutterMacOS import FlutterMacOS
import Foundation import Foundation
import sqlite3_flutter_libs
import url_launcher_macos import url_launcher_macos
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
Sqlite3FlutterLibsPlugin.register(with: registry.registrar(forPlugin: "Sqlite3FlutterLibsPlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
} }

View file

@ -49,6 +49,70 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.2" version: "2.1.2"
build:
dependency: transitive
description:
name: build
sha256: ce76b1d48875e3233fde17717c23d1f60a91cc631597e49a400c89b475395b1d
url: "https://pub.dev"
source: hosted
version: "3.1.0"
build_config:
dependency: transitive
description:
name: build_config
sha256: "4f64382b97504dc2fcdf487d5aae33418e08b4703fc21249e4db6d804a4d0187"
url: "https://pub.dev"
source: hosted
version: "1.2.0"
build_daemon:
dependency: transitive
description:
name: build_daemon
sha256: bf05f6e12cfea92d3c09308d7bcdab1906cd8a179b023269eed00c071004b957
url: "https://pub.dev"
source: hosted
version: "4.1.1"
build_resolvers:
dependency: transitive
description:
name: build_resolvers
sha256: d1d57f7807debd7349b4726a19fd32ec8bc177c71ad0febf91a20f84cd2d4b46
url: "https://pub.dev"
source: hosted
version: "3.0.3"
build_runner:
dependency: "direct dev"
description:
name: build_runner
sha256: b24597fceb695969d47025c958f3837f9f0122e237c6a22cb082a5ac66c3ca30
url: "https://pub.dev"
source: hosted
version: "2.7.1"
build_runner_core:
dependency: transitive
description:
name: build_runner_core
sha256: "066dda7f73d8eb48ba630a55acb50c4a84a2e6b453b1cb4567f581729e794f7b"
url: "https://pub.dev"
source: hosted
version: "9.3.1"
built_collection:
dependency: transitive
description:
name: built_collection
sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100"
url: "https://pub.dev"
source: hosted
version: "5.1.1"
built_value:
dependency: transitive
description:
name: built_value
sha256: "7931c90b84bc573fef103548e354258ae4c9d28d140e41961df6843c5d60d4d8"
url: "https://pub.dev"
source: hosted
version: "8.12.3"
characters: characters:
dependency: transitive dependency: transitive
description: description:
@ -65,6 +129,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.4.0" version: "1.4.0"
checked_yaml:
dependency: transitive
description:
name: checked_yaml
sha256: "959525d3162f249993882720d52b7e0c833978df229be20702b33d48d91de70f"
url: "https://pub.dev"
source: hosted
version: "2.0.4"
cli_config: cli_config:
dependency: transitive dependency: transitive
description: description:
@ -73,6 +145,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.2.0" version: "0.2.0"
cli_util:
dependency: transitive
description:
name: cli_util
sha256: ff6785f7e9e3c38ac98b2fb035701789de90154024a75b6cb926445e83197d1c
url: "https://pub.dev"
source: hosted
version: "0.4.2"
clock: clock:
dependency: transitive dependency: transitive
description: description:
@ -81,6 +161,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.2" version: "1.1.2"
code_assets:
dependency: transitive
description:
name: code_assets
sha256: "83ccdaa064c980b5596c35dd64a8d3ecc68620174ab9b90b6343b753aa721687"
url: "https://pub.dev"
source: hosted
version: "1.0.0"
code_builder:
dependency: transitive
description:
name: code_builder
sha256: "6a6cab2ba4680d6423f34a9b972a4c9a94ebe1b62ecec4e1a1f2cba91fd1319d"
url: "https://pub.dev"
source: hosted
version: "4.11.1"
collection: collection:
dependency: "direct main" dependency: "direct main"
description: description:
@ -129,6 +225,30 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.1.9" version: "0.1.9"
dart_style:
dependency: transitive
description:
name: dart_style
sha256: "8a0e5fba27e8ee025d2ffb4ee820b4e6e2cf5e4246a6b1a477eb66866947e0bb"
url: "https://pub.dev"
source: hosted
version: "3.1.1"
drift:
dependency: "direct main"
description:
name: drift
sha256: "83290a32ae006a7535c5ecf300722cb77177250d9df4ee2becc5fa8a36095114"
url: "https://pub.dev"
source: hosted
version: "2.29.0"
drift_dev:
dependency: "direct dev"
description:
name: drift_dev
sha256: "6019f827544e77524ffd5134ae0cb75dfd92ef5ef3e269872af92840c929cd43"
url: "https://pub.dev"
source: hosted
version: "2.29.0"
equatable: equatable:
dependency: transitive dependency: transitive
description: description:
@ -145,6 +265,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.3.3" version: "1.3.3"
ffi:
dependency: transitive
description:
name: ffi
sha256: d07d37192dbf97461359c1518788f203b0c9102cfd2c35a716b823741219542c
url: "https://pub.dev"
source: hosted
version: "2.1.5"
file: file:
dependency: transitive dependency: transitive
description: description:
@ -153,6 +281,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "7.0.1" version: "7.0.1"
fixnum:
dependency: transitive
description:
name: fixnum
sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be
url: "https://pub.dev"
source: hosted
version: "1.1.1"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
@ -240,6 +376,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.0.0" version: "4.0.0"
get_it:
dependency: "direct main"
description:
name: get_it
sha256: ae78de7c3f2304b8d81f2bb6e320833e5e81de942188542328f074978cc0efa9
url: "https://pub.dev"
source: hosted
version: "8.3.0"
glob: glob:
dependency: transitive dependency: transitive
description: description:
@ -248,6 +392,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.3" version: "2.1.3"
graphs:
dependency: transitive
description:
name: graphs
sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0"
url: "https://pub.dev"
source: hosted
version: "2.3.2"
highlight: highlight:
dependency: transitive dependency: transitive
description: description:
@ -264,6 +416,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.3" version: "2.2.3"
hooks:
dependency: transitive
description:
name: hooks
sha256: "7a08a0d684cb3b8fb604b78455d5d352f502b68079f7b80b831c62220ab0a4f6"
url: "https://pub.dev"
source: hosted
version: "1.0.1"
http: http:
dependency: transitive dependency: transitive
description: description:
@ -304,6 +464,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.2" version: "0.7.2"
json_annotation:
dependency: transitive
description:
name: json_annotation
sha256: "805fa86df56383000f640384b282ce0cb8431f1a7a2396de92fb66186d8c57df"
url: "https://pub.dev"
source: hosted
version: "4.10.0"
leak_tracker: leak_tracker:
dependency: transitive dependency: transitive
description: description:
@ -400,6 +568,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.4" version: "1.0.4"
native_toolchain_c:
dependency: transitive
description:
name: native_toolchain_c
sha256: "89e83885ba09da5fdf2cdacc8002a712ca238c28b7f717910b34bcd27b0d03ac"
url: "https://pub.dev"
source: hosted
version: "0.17.4"
nested: nested:
dependency: transitive dependency: transitive
description: description:
@ -416,6 +592,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.2" version: "2.0.2"
objective_c:
dependency: transitive
description:
name: objective_c
sha256: "100a1c87616ab6ed41ec263b083c0ef3261ee6cd1dc3b0f35f8ddfa4f996fe52"
url: "https://pub.dev"
source: hosted
version: "9.3.0"
package_config: package_config:
dependency: transitive dependency: transitive
description: description:
@ -425,7 +609,7 @@ packages:
source: hosted source: hosted
version: "2.2.0" version: "2.2.0"
path: path:
dependency: transitive dependency: "direct main"
description: description:
name: path name: path
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
@ -440,6 +624,54 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.0" version: "1.1.0"
path_provider:
dependency: "direct main"
description:
name: path_provider
sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd"
url: "https://pub.dev"
source: hosted
version: "2.1.5"
path_provider_android:
dependency: transitive
description:
name: path_provider_android
sha256: f2c65e21139ce2c3dad46922be8272bb5963516045659e71bb16e151c93b580e
url: "https://pub.dev"
source: hosted
version: "2.2.22"
path_provider_foundation:
dependency: transitive
description:
name: path_provider_foundation
sha256: "2a376b7d6392d80cd3705782d2caa734ca4727776db0b6ec36ef3f1855197699"
url: "https://pub.dev"
source: hosted
version: "2.6.0"
path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
url: "https://pub.dev"
source: hosted
version: "2.2.1"
path_provider_platform_interface:
dependency: transitive
description:
name: path_provider_platform_interface
sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
url: "https://pub.dev"
source: hosted
version: "2.1.2"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7
url: "https://pub.dev"
source: hosted
version: "2.3.0"
petitparser: petitparser:
dependency: transitive dependency: transitive
description: description:
@ -448,6 +680,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "7.0.1" version: "7.0.1"
platform:
dependency: transitive
description:
name: platform
sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984"
url: "https://pub.dev"
source: hosted
version: "3.1.6"
plugin_platform_interface: plugin_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -480,6 +720,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.0" version: "2.2.0"
pubspec_parse:
dependency: transitive
description:
name: pubspec_parse
sha256: "0560ba233314abbed0a48a2956f7f022cce7c3e1e73df540277da7544cad4082"
url: "https://pub.dev"
source: hosted
version: "1.5.0"
recase:
dependency: transitive
description:
name: recase
sha256: e4eb4ec2dcdee52dcf99cb4ceabaffc631d7424ee55e56f280bc039737f89213
url: "https://pub.dev"
source: hosted
version: "4.1.0"
resource_portable: resource_portable:
dependency: "direct main" dependency: "direct main"
description: description:
@ -533,6 +789,14 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
source_gen:
dependency: transitive
description:
name: source_gen
sha256: "800f12fb87434defa13432ab37e33051b43b290a174e15259563b043cda40c46"
url: "https://pub.dev"
source: hosted
version: "4.0.0"
source_map_stack_trace: source_map_stack_trace:
dependency: transitive dependency: transitive
description: description:
@ -557,6 +821,30 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.10.1" version: "1.10.1"
sqlite3:
dependency: transitive
description:
name: sqlite3
sha256: "3145bd74dcdb4fd6f5c6dda4d4e4490a8087d7f286a14dee5d37087290f0f8a2"
url: "https://pub.dev"
source: hosted
version: "2.9.4"
sqlite3_flutter_libs:
dependency: "direct main"
description:
name: sqlite3_flutter_libs
sha256: "1e800ebe7f85a80a66adacaa6febe4d5f4d8b75f244e9838a27cb2ffc7aec08d"
url: "https://pub.dev"
source: hosted
version: "0.5.41"
sqlparser:
dependency: transitive
description:
name: sqlparser
sha256: "162435ede92bcc793ea939fdc0452eef0a73d11f8ed053b58a89792fba749da5"
url: "https://pub.dev"
source: hosted
version: "0.42.1"
stack_trace: stack_trace:
dependency: transitive dependency: transitive
description: description:
@ -573,6 +861,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.4" version: "2.1.4"
stream_transform:
dependency: transitive
description:
name: stream_transform
sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871
url: "https://pub.dev"
source: hosted
version: "2.1.1"
string_scanner: string_scanner:
dependency: transitive dependency: transitive
description: description:
@ -613,6 +909,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.6.12" version: "0.6.12"
timing:
dependency: transitive
description:
name: timing
sha256: "62ee18aca144e4a9f29d212f5a4c6a053be252b895ab14b5821996cff4ed90fe"
url: "https://pub.dev"
source: hosted
version: "1.0.2"
tuple: tuple:
dependency: transitive dependency: transitive
description: description:
@ -773,6 +1077,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.2.1" version: "1.2.1"
xdg_directories:
dependency: transitive
description:
name: xdg_directories
sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15"
url: "https://pub.dev"
source: hosted
version: "1.1.0"
xml: xml:
dependency: transitive dependency: transitive
description: description:
@ -791,4 +1103,4 @@ packages:
version: "3.1.3" version: "3.1.3"
sdks: sdks:
dart: ">=3.10.4 <4.0.0" dart: ">=3.10.4 <4.0.0"
flutter: ">=3.38.0" flutter: ">=3.38.4"

View file

@ -41,6 +41,13 @@ dependencies:
flutter_markdown_latex: flutter_markdown_latex:
flutter_code_editor: flutter_code_editor:
# Drift dependencies for database support
drift: ^2.18.0
sqlite3_flutter_libs: ^0.5.9
path_provider: ^2.1.1
path: ^1.8.3
get_it: ^8.0.2
collection: any collection: any
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
@ -54,6 +61,10 @@ dev_dependencies:
flutter_lints: flutter_lints:
test: test:
# Drift build dependencies
drift_dev: ^2.18.0
build_runner: ^2.4.7
# For information on the generic Dart part of this file, see the # For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec # following page: https://dart.dev/tools/pub/pubspec

13
test/database_test.dart Normal file
View file

@ -0,0 +1,13 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:d4rt_formulas/database/database_service.dart';
void main() {
setUp(() {
setupLocator();
});
test('Database service can be initialized', () {
final database = getDatabase();
expect(database, isNotNull);
});
}

View file

@ -6,9 +6,12 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <sqlite3_flutter_libs/sqlite3_flutter_libs_plugin.h>
#include <url_launcher_windows/url_launcher_windows.h> #include <url_launcher_windows/url_launcher_windows.h>
void RegisterPlugins(flutter::PluginRegistry* registry) { void RegisterPlugins(flutter::PluginRegistry* registry) {
Sqlite3FlutterLibsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("Sqlite3FlutterLibsPlugin"));
UrlLauncherWindowsRegisterWithRegistrar( UrlLauncherWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("UrlLauncherWindows")); registry->GetRegistrarForPlugin("UrlLauncherWindows"));
} }

View file

@ -3,6 +3,7 @@
# #
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
sqlite3_flutter_libs
url_launcher_windows url_launcher_windows
) )