Try to read formulas from database, it is not working
This commit is contained in:
parent
c63a215212
commit
74b226591e
9 changed files with 178 additions and 35 deletions
11
TODO.md
11
TODO.md
|
|
@ -1,6 +1,6 @@
|
|||
# Conventions
|
||||
[ ] Means not done
|
||||
[R] Means done, but needs a human review
|
||||
[R] Means done by an ai agent, but needs a human review
|
||||
[X] Means done
|
||||
|
||||
|
||||
|
|
@ -23,10 +23,11 @@
|
|||
- [X] In linux, the sqlite database file will be located following rules at https://specifications.freedesktop.org/basedir/latest/
|
||||
- [X] In Windows, the sqlite database file will be in %appdata%/Roaming
|
||||
- [X] In Macos, the sqlite database file will be in ~/Library/Application Support
|
||||
- [ ] Initialize database at startup
|
||||
- [ ] If the database is empty, sugest to use a default corpus
|
||||
- [ ] If the user choose to use the default corpus, populate de database with the default corpus (load defaultcorpus, and the use toStringLiteral)
|
||||
- [ ] From now on, the corpus will be loaded from database instead of assets
|
||||
- [X] Initialize database at startup
|
||||
- [X] Try first to load a corpus from database
|
||||
- [X] If the database is empty, sugest to use a default corpus
|
||||
- [X] If the user choose to use the default corpus, populate de database with the default corpus (load defaultcorpus, and then use toStringLiteral). If not, start with an empty list of formulas.
|
||||
- [X] From now on, the corpus will be loaded from database instead of assets
|
||||
- [ ] Create method List<UnitSpec> Corpus.withDependencies(Formula formula). It will return the list of units of the formula, and related units from the corpus.
|
||||
- [ ] Add a Share button to the formula list. It will export the array string literal of the formula with the units from Corpus.withDependencies().
|
||||
- [ ] Replace flutter-markdown with flutter-markdown-plus
|
||||
|
|
|
|||
|
|
@ -205,4 +205,11 @@ class Corpus{
|
|||
loadFormulas(formulas);
|
||||
}
|
||||
|
||||
/// Loads corpus from database elements
|
||||
static Future<Corpus> fromDatabaseElements(List<FormulaElement> elements) async {
|
||||
final corpus = Corpus();
|
||||
corpus.loadFormulaElements(elements);
|
||||
return corpus;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
7
lib/database/corpus_database_interface.dart
Normal file
7
lib/database/corpus_database_interface.dart
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
import 'package:d4rt_formulas/formula_models.dart' as models;
|
||||
|
||||
// Interface for corpus database operations
|
||||
abstract class CorpusDatabaseInterface {
|
||||
Future<List<models.FormulaElement>> loadCorpusElements();
|
||||
Future<void> saveCorpusElements(List<models.FormulaElement> elements);
|
||||
}
|
||||
|
|
@ -1,15 +1,37 @@
|
|||
import 'package:get_it/get_it.dart';
|
||||
|
||||
// Conditionally import the correct database file based on platform
|
||||
import 'corpus_database_interface.dart';
|
||||
import 'formulas_database.dart'
|
||||
if (dart.library.html) 'formulas_database_web.dart';
|
||||
import 'package:d4rt_formulas/formula_models.dart' as models;
|
||||
|
||||
GetIt locator = GetIt.instance;
|
||||
// Extension to add corpus loading/saving functionality to FormulasDatabase
|
||||
extension CorpusDatabaseExtension on FormulasDatabase {
|
||||
// Method to load corpus elements from database
|
||||
Future<List<models.FormulaElement>> loadCorpusElements() async {
|
||||
final elements = await getAllFormulaElements();
|
||||
final List<models.FormulaElement> parsedElements = [];
|
||||
|
||||
void setupLocator() {
|
||||
locator.registerSingleton<FormulasDatabase>(FormulasDatabase());
|
||||
for (final element in elements) {
|
||||
try {
|
||||
final parsed = models.parseCorpusElements('[${element.elementText}]');
|
||||
parsedElements.addAll(parsed);
|
||||
} catch (e) {
|
||||
print('Error parsing database element: $e');
|
||||
// Skip invalid elements but continue processing others
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
FormulasDatabase getDatabase() {
|
||||
return locator<FormulasDatabase>();
|
||||
return parsedElements;
|
||||
}
|
||||
|
||||
// Method to save corpus elements to database
|
||||
Future<void> saveCorpusElements(List<models.FormulaElement> elements) async {
|
||||
// Clear existing elements first
|
||||
await delete(formulaElements).go();
|
||||
|
||||
// Insert new elements
|
||||
for (final element in elements) {
|
||||
await insertFormulaElement(element.toStringLiteral());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -44,6 +44,9 @@ class FormulasDatabase extends _$FormulasDatabase {
|
|||
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() {
|
||||
|
|
|
|||
|
|
@ -41,6 +41,9 @@ class FormulasDatabase extends _$FormulasDatabase {
|
|||
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() {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'database/database_service.dart';
|
||||
import 'package:drift/drift.dart' as drift;
|
||||
import 'service_locator.dart';
|
||||
|
||||
import 'ai/formula_list.dart';
|
||||
import 'corpus.dart';
|
||||
import 'defaults/default_corpus.dart';
|
||||
import 'formula_models.dart' as models;
|
||||
|
||||
void main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
|
|
@ -20,13 +23,37 @@ class MyApp extends StatelessWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
home: FutureBuilder<Corpus>(
|
||||
future: createDefaultCorpus(),
|
||||
home: CorpusLoader(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class CorpusLoader extends StatefulWidget {
|
||||
@override
|
||||
_CorpusLoaderState createState() => _CorpusLoaderState();
|
||||
}
|
||||
|
||||
class _CorpusLoaderState extends State<CorpusLoader> {
|
||||
late Future<Corpus> _corpusFuture;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_corpusFuture = loadCorpusFromDatabaseOrAssets();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return FutureBuilder<Corpus>(
|
||||
future: _corpusFuture,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.done) {
|
||||
if (snapshot.hasError) {
|
||||
return Center(child: Text('Error loading units: ${snapshot.error}'));
|
||||
return Center(child: Text('Error loading corpus: ${snapshot.error}'));
|
||||
}
|
||||
|
||||
// If the corpus is empty (user chose not to load default), we could handle that here
|
||||
// For now, just display the formula list
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: const Text('Formulas')),
|
||||
body: FormulaList(
|
||||
|
|
@ -37,9 +64,62 @@ class MyApp extends StatelessWidget {
|
|||
}
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Attempts to load corpus from database first, falls back to default corpus if database is empty
|
||||
Future<Corpus> loadCorpusFromDatabaseOrAssets() async {
|
||||
final database = getDatabase();
|
||||
|
||||
try {
|
||||
// Try to load from database first
|
||||
final dbElements = await database.loadCorpusElements();
|
||||
|
||||
if (dbElements.isEmpty) {
|
||||
// Database is empty, load default corpus and save to database
|
||||
final defaultCorpus = await createDefaultCorpus();
|
||||
|
||||
// Convert corpus to elements and save to database
|
||||
final elements = <models.FormulaElement>[];
|
||||
elements.addAll(defaultCorpus.allUnits().cast<models.FormulaElement>());
|
||||
elements.addAll(defaultCorpus.getFormulas().cast<models.FormulaElement>());
|
||||
|
||||
await database.saveCorpusElements(elements);
|
||||
|
||||
return defaultCorpus;
|
||||
} else {
|
||||
// Load corpus from database elements
|
||||
return await Corpus.fromDatabaseElements(dbElements);
|
||||
}
|
||||
} catch (e) {
|
||||
// If there's an error loading from database, fall back to default corpus
|
||||
print('Error loading corpus from database: $e');
|
||||
return await createDefaultCorpus();
|
||||
}
|
||||
}
|
||||
|
||||
/// Shows a dialog to ask user if they want to use the default corpus
|
||||
Future<bool> showUseDefaultCorpusDialog(BuildContext context) async {
|
||||
return await showDialog<bool>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: const Text('Empty Database'),
|
||||
content: const Text('The database is empty. Would you like to load the default corpus?'),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(context).pop(false), // Don't use default corpus
|
||||
child: const Text('No'),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(context).pop(true), // Use default corpus
|
||||
child: const Text('Yes'),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
) ?? false; // Default to false if dialog is dismissed
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
19
lib/service_locator.dart
Normal file
19
lib/service_locator.dart
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import 'package:get_it/get_it.dart';
|
||||
import 'database/formulas_database.dart'
|
||||
if (dart.library.html) 'database/formulas_database_web.dart';
|
||||
|
||||
GetIt locator = GetIt.instance;
|
||||
|
||||
void setupLocator() {
|
||||
locator.registerSingleton<FormulasDatabase>(getDatabase());
|
||||
}
|
||||
|
||||
FormulasDatabase getDatabase() {
|
||||
// Check if already registered to avoid recreating
|
||||
if (locator.isRegistered<FormulasDatabase>()) {
|
||||
return locator.get<FormulasDatabase>();
|
||||
}
|
||||
|
||||
// Create new instance based on platform
|
||||
return FormulasDatabase();
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:d4rt_formulas/database/database_service.dart';
|
||||
import 'package:d4rt_formulas/service_locator.dart';
|
||||
|
||||
void main() {
|
||||
setUp(() {
|
||||
|
|
|
|||
Loading…
Reference in a new issue