Replace database import with CSV import
This commit is contained in:
parent
36b8ce37ad
commit
98991a3d02
|
@ -17,7 +17,7 @@ class MyDatabase extends _$MyDatabase {
|
||||||
MyDatabase() : super(_openConnection());
|
MyDatabase() : super(_openConnection());
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get schemaVersion => 3;
|
int get schemaVersion => 1;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
MigrationStrategy get migration => MigrationStrategy(
|
MigrationStrategy get migration => MigrationStrategy(
|
||||||
|
@ -27,41 +27,7 @@ class MyDatabase extends _$MyDatabase {
|
||||||
var data = await (db.select(db.settings)..limit(1)).get();
|
var data = await (db.select(db.settings)..limit(1)).get();
|
||||||
if (data.isEmpty) await db.into(db.settings).insert(defaultSettings);
|
if (data.isEmpty) await db.into(db.settings).insert(defaultSettings);
|
||||||
},
|
},
|
||||||
onUpgrade: (Migrator m, int from, int to) async {
|
onUpgrade: (Migrator m, int from, int to) async {},
|
||||||
if (from == 1) {
|
|
||||||
await m.create(db.gymSets);
|
|
||||||
await db.customInsert('''
|
|
||||||
INSERT INTO gym_sets(id, name, reps, weight, created, unit, hidden, image, sets, minutes, seconds, steps)
|
|
||||||
SELECT id, name, reps, weight, created, unit, hidden, image, sets, minutes, seconds, steps FROM sets
|
|
||||||
''');
|
|
||||||
await m.addColumn(settings, settings.darkColor);
|
|
||||||
await db.customStatement('''
|
|
||||||
UPDATE settings SET dark_color = darkColor
|
|
||||||
''');
|
|
||||||
await m.addColumn(settings, settings.lightColor);
|
|
||||||
await db.customStatement('''
|
|
||||||
UPDATE settings SET light_color = lightColor
|
|
||||||
''');
|
|
||||||
await m.addColumn(settings, settings.showDate);
|
|
||||||
await db.customStatement('''
|
|
||||||
UPDATE settings SET show_date = showDate
|
|
||||||
''');
|
|
||||||
await m.addColumn(settings, settings.showSets);
|
|
||||||
await db.customStatement('''
|
|
||||||
UPDATE settings SET show_sets = showSets
|
|
||||||
''');
|
|
||||||
await m.addColumn(settings, settings.showUnit);
|
|
||||||
await db.customStatement('''
|
|
||||||
UPDATE settings SET show_unit = showUnit
|
|
||||||
''');
|
|
||||||
}
|
|
||||||
if (from == 2) {
|
|
||||||
await m.addColumn(settings, settings.noSound);
|
|
||||||
await db.customStatement('''
|
|
||||||
UPDATE settings SET no_sound = noSound
|
|
||||||
''');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
51
lib/delete_all_sets.dart
Normal file
51
lib/delete_all_sets.dart
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:fmassive/main.dart';
|
||||||
|
import 'package:moor/moor.dart';
|
||||||
|
|
||||||
|
class DeleteAllSets extends StatelessWidget {
|
||||||
|
const DeleteAllSets({
|
||||||
|
super.key,
|
||||||
|
required this.mounted,
|
||||||
|
});
|
||||||
|
|
||||||
|
final bool mounted;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Center(
|
||||||
|
child: ElevatedButton(
|
||||||
|
child: const Text("Delete all sets"),
|
||||||
|
onPressed: () async {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return AlertDialog(
|
||||||
|
title: const Text("Delete all sets"),
|
||||||
|
content: const Text(
|
||||||
|
"This will irreversibly destroy all your gym set data. Are you sure?"),
|
||||||
|
actions: <Widget>[
|
||||||
|
ElevatedButton(
|
||||||
|
child: const Text('Cancel'),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
child: const Text('Delete'),
|
||||||
|
onPressed: () async {
|
||||||
|
await db.gymSets.delete().go();
|
||||||
|
if (!mounted) return;
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
const SnackBar(content: Text('Deleted all sets')));
|
||||||
|
final navigator = Navigator.of(context);
|
||||||
|
navigator.pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,14 +1,15 @@
|
||||||
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:csv/csv.dart';
|
||||||
import 'package:file_picker/file_picker.dart';
|
import 'package:file_picker/file_picker.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/material.dart' as material;
|
import 'package:flutter/material.dart' as material;
|
||||||
import 'package:fmassive/database.dart';
|
import 'package:fmassive/database.dart';
|
||||||
|
import 'package:fmassive/delete_all_sets.dart';
|
||||||
import 'package:fmassive/main.dart';
|
import 'package:fmassive/main.dart';
|
||||||
import 'package:fmassive/sound_picker.dart';
|
import 'package:fmassive/sound_picker.dart';
|
||||||
import 'package:moor/moor.dart';
|
import 'package:moor/moor.dart';
|
||||||
import 'package:path/path.dart';
|
|
||||||
import 'package:sqflite/sqflite.dart';
|
|
||||||
|
|
||||||
class SettingsPage extends StatelessWidget {
|
class SettingsPage extends StatelessWidget {
|
||||||
const SettingsPage({super.key, required this.search});
|
const SettingsPage({super.key, required this.search});
|
||||||
|
@ -63,7 +64,8 @@ class _SettingsPageState extends State<_SettingsPage> {
|
||||||
{'title': 'Show Unit', 'value': settings.showUnit},
|
{'title': 'Show Unit', 'value': settings.showUnit},
|
||||||
{'title': 'Steps', 'value': settings.steps},
|
{'title': 'Steps', 'value': settings.steps},
|
||||||
{'title': 'Sound', 'value': settings.sound},
|
{'title': 'Sound', 'value': settings.sound},
|
||||||
{'title': 'Import', 'value': settings.sound},
|
{'title': 'Import', 'value': null},
|
||||||
|
{'title': 'Delete all sets', 'value': null},
|
||||||
]
|
]
|
||||||
.where((item) => (item['title'] as String)
|
.where((item) => (item['title'] as String)
|
||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
|
@ -78,32 +80,47 @@ class _SettingsPageState extends State<_SettingsPage> {
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final item = filteredItems[index];
|
final item = filteredItems[index];
|
||||||
|
|
||||||
|
if (item['title'] == 'Delete all sets')
|
||||||
|
return DeleteAllSets(mounted: mounted);
|
||||||
|
|
||||||
if (item['title'] == 'Import')
|
if (item['title'] == 'Import')
|
||||||
return Center(
|
return Center(
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
onPressed: () async {
|
child: const Text("Import"),
|
||||||
final result =
|
onPressed: () async {
|
||||||
await FilePicker.platform.pickFiles(
|
final result = await FilePicker.platform.pickFiles(
|
||||||
type: FileType.any,
|
type: FileType.custom,
|
||||||
);
|
allowedExtensions: ['csv']);
|
||||||
if (result == null) return;
|
if (result == null) return;
|
||||||
|
|
||||||
final file = File(result.files.single.path!);
|
final file = File(result.files.single.path!);
|
||||||
final path = await getDatabasesPath();
|
final input = file.openRead();
|
||||||
final to = join(path, 'massive.db');
|
final fields = await input
|
||||||
await db.close();
|
.transform(utf8.decoder)
|
||||||
await file.copy(to);
|
.transform(const CsvToListConverter(eol: "\n"))
|
||||||
print('Migrating...');
|
.skip(1)
|
||||||
db = MyDatabase();
|
.toList();
|
||||||
// ignore: invalid_use_of_protected_member, invalid_use_of_visible_for_testing_member
|
final gymSets = fields.map((row) => GymSetsCompanion(
|
||||||
final migrator = db.createMigrator();
|
id: Value(int.tryParse(row[0]) ?? 0),
|
||||||
await migrator.createAll();
|
name: Value(row[1]),
|
||||||
await db.update(db.settings).write(
|
reps: Value(int.tryParse(row[2]) ?? 0),
|
||||||
const SettingsCompanion(
|
weight: Value(double.tryParse(row[3]) ?? 0),
|
||||||
sound: Value(null)));
|
created: Value(row[4]),
|
||||||
print('Migrated.');
|
unit: Value(row[5]),
|
||||||
},
|
hidden: Value(row[6] == 'true'),
|
||||||
child: const Text("Import")));
|
image: Value(row[7]),
|
||||||
|
sets: Value(int.tryParse(row[8]) ?? 0),
|
||||||
|
minutes: Value(int.tryParse(row[9]) ?? 0),
|
||||||
|
seconds: Value(int.tryParse(row[10]) ?? 0),
|
||||||
|
steps: Value(row[11]),
|
||||||
|
));
|
||||||
|
await db.batch(
|
||||||
|
(batch) => batch.insertAll(db.gymSets, gymSets));
|
||||||
|
if (!mounted) return;
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
const SnackBar(content: Text('Imported data')));
|
||||||
|
},
|
||||||
|
));
|
||||||
|
|
||||||
if (item['title'] == 'Sound') {
|
if (item['title'] == 'Sound') {
|
||||||
return Center(
|
return Center(
|
||||||
|
|
|
@ -241,6 +241,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.3"
|
version: "3.0.3"
|
||||||
|
csv:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: csv
|
||||||
|
sha256: "63ed2871dd6471193dffc52c0e6c76fb86269c00244d244297abbb355c84a86e"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "5.1.1"
|
||||||
cupertino_icons:
|
cupertino_icons:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -47,6 +47,7 @@ dependencies:
|
||||||
intl: ^0.18.0
|
intl: ^0.18.0
|
||||||
permission_handler: ^11.0.1
|
permission_handler: ^11.0.1
|
||||||
infinite_scroll_pagination: ^4.0.0
|
infinite_scroll_pagination: ^4.0.0
|
||||||
|
csv: ^5.1.1
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user