feat(database): add functions for DB and DB-table creation

This commit is contained in:
fbachus
2026-06-06 01:22:36 +02:00
parent 5fd3e8faad
commit 7cfc415f9f
4 changed files with 279 additions and 24 deletions
+3
View File
@@ -1,9 +1,12 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'api_handler.dart'; import 'api_handler.dart';
import 'transport_helper.dart';
void main() async { void main() async {
await dotenv.load(); await dotenv.load();
const String dbName = "oeffimasterTransportDb";
initDB(dbName);
runApp(const MyApp()); runApp(const MyApp());
} }
+99 -17
View File
@@ -1,3 +1,24 @@
import 'package:sqflite/sqflite.dart';
void initDB(dbName) async {
var databasesPath = await getDatabasesPath();
var path = databasesPath + dbName;
var db = await openDatabase(path);
// var db = await openDatabase('/var/db/oeffimaster/transport_db.db');
// TODO: Make sure the directory exists
// TODO: future optimisation: batch transactions
// TODO: create tables for all classes
// - [] route
// - [] segment
// - [] station
// - [] vehicle
// - [] line
// - [] departure
}
class Route { class Route {
List<Segment> segments = List.empty(); List<Segment> segments = List.empty();
Duration duration = Duration(minutes: 0); Duration duration = Duration(minutes: 0);
@@ -15,6 +36,10 @@ class Route {
json["LegList"]["Leg"][0]["Origin"]["time"], json["LegList"]["Leg"][0]["Origin"]["time"],
); );
// TODO: do we need route in the database???? // what beyond and ID is needed?
void initRouteTable(Database database) async {
database.execute("CREATE TABLE IF NOT EXISTS route();");
}
} }
class Segment { class Segment {
@@ -39,22 +64,36 @@ class Segment {
endTime: json["Destination"]["rtTime"], endTime: json["Destination"]["rtTime"],
vehicle: Vehicle.fromJson(json["Product"]), vehicle: Vehicle.fromJson(json["Product"]),
); );
void initSegmentTable(Database database) async {
database.execute("""
CREATE TABLE IF NOT EXISTS segment(
startpoint TEXT,
endpoint TEXT,
starttime TEXT,
endtime TEXT,
vehicle INTEGER,
FOREIGN KEY(startpoint) REFERENCES station(stationid),
FOREIGN KEY(endpoint) REFERENCES station(stationid)
FOREIGN KEY(vehicle) REFERENCES vehicle(vehicleid)
);
""");
}
} }
class Station { class Station {
final String id; final String stationId;
final String name; final String name;
List<Line>? transportLines; List<Line>? transportLines; // could be normalized away
List<Departure>? departures;
Station({ Station({
required this.id, required this.stationId,
required this.name, required this.name,
required this.transportLines required this.transportLines, //TODO: make extra db table
}); });
factory Station.fromJson(Map<String, dynamic> json) => Station( factory Station.fromJson(Map<String, dynamic> json) => Station(
id: json["id"] as String? ?? json["extId"] as String, stationId: json["id"] as String? ?? json["extId"] as String,
name: json["name"], name: json["name"],
transportLines: json.containsKey("productAtStop") transportLines: json.containsKey("productAtStop")
? json["productAtStop"].map( ? json["productAtStop"].map(
@@ -62,27 +101,44 @@ class Station {
) )
: const [], : const [],
); );
void initStationTable(Database database) async {
database.execute("""CREATE TABLE IF NOT EXISTS station(
stationid TEXT PRIMARY KEY,
name TEXT
);
""");
}
} }
class Vehicle { class Vehicle {
final String id; final String vehicleId;
final Line line; final Line line;
Vehicle({ Vehicle({
required this.id, required this.vehicleId,
required this.line, required this.line,
}); });
// we can use the "product" class from within any JSON response // we can use the "product" class from within any JSON response
// (within hafas API, on the appropriate level) // (within hafas API, on the appropriate level)
factory Vehicle.fromJson(Map<String, dynamic> json) => Vehicle( factory Vehicle.fromJson(Map<String, dynamic> json) => Vehicle(
id: json["matchId"], vehicleId: json["matchId"],
line: Line.fromJson(json), line: Line.fromJson(json),
); );
void initVehicleTable(Database database) async {
database.execute("""CREATE TABLE IF NOT EXISTS vehicle(
vehicleid TEXT PRIMARY KEY,
line TEXT,
FOREIGN KEY(line) REFERENCES line(lineid)
);
""");
}
} }
class Line { class Line {
final String id; final String lineId;
Station? destination; Station? destination;
Station? direction; Station? direction;
final VehicleType mode; final VehicleType mode;
@@ -91,7 +147,7 @@ class Line {
Color? bgColor; Color? bgColor;
Line({ Line({
required this.id, required this.lineId,
required this.name, required this.name,
required this.mode, required this.mode,
this.fgColor, this.fgColor,
@@ -103,18 +159,32 @@ class Line {
VehicleType.metro, VehicleType.metro,
VehicleType.subway, VehicleType.subway,
VehicleType.PLACEHOLDER, VehicleType.PLACEHOLDER,
VehicleType.bus VehicleType.bus,
]; ];
factory Line.fromJson(Map<String, dynamic> json) => Line( factory Line.fromJson(Map<String, dynamic> json) => Line(
id: json["lineId"], lineId: json["lineId"],
name: json["name"], name: json["name"],
mode: _vehicleTypeAsCatCode[int.parse(json["catCode"])], mode: _vehicleTypeAsCatCode[int.parse(json["catCode"])],
fgColor: Color.fromJson(json["foregroundColor"]) as Color? fgColor:
?? Color(r: 255, g: 255, b: 255), // fallback Color.fromJson(json["foregroundColor"]) as Color? ??
bgColor: Color.fromJson(json["backgroundColor"]) as Color? Color(r: 255, g: 255, b: 255), // fallback
?? Color(r: 50, g: 50, b: 50), // fallback bgColor:
Color.fromJson(json["backgroundColor"]) as Color? ??
Color(r: 50, g: 50, b: 50), // fallback
); );
void initLineTable(Database database) async {
database.execute("""CREATE TABLE IF NOT EXISTS line(
lineid TEXT PRIMARY KEY,
destination TEXT,
direction TEXT,
mode TEXT,
name TEXT,
fgcolor TEXT,
bgcolor TEXT
);
""");
}
} }
class Departure { class Departure {
@@ -128,6 +198,18 @@ class Departure {
required this.station, required this.station,
required this.departureTime, required this.departureTime,
}); });
void initDepartureTable(Database database) async {
database.execute("""CREATE TABLE IF NOT EXISTS departure(
departureid INTEGER,
vehicle TEXT,
station TEXT,
departuretime TEXT
FOREIGN KEY(vehicle) REFERENCES vehicle(vehicleid),
FOREIGN KEY(station) REFERENCES station(stationid)
);
""");
}
} }
class Color { class Color {
+174 -6
View File
@@ -33,6 +33,14 @@ 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: bf394f466ba9205f1812a0433b392d6af280f155f56651eda7c18cc32ed493b8
url: "https://pub.dev"
source: hosted
version: "1.2.1"
collection: collection:
dependency: transitive dependency: transitive
description: description:
@@ -41,6 +49,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.19.1" version: "1.19.1"
crypto:
dependency: transitive
description:
name: crypto
sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf
url: "https://pub.dev"
source: hosted
version: "3.0.7"
cupertino_icons: cupertino_icons:
dependency: "direct main" dependency: "direct main"
description: description:
@@ -57,6 +73,22 @@ 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: "6d7fd89431262d8f3125e81b50d3847a091d846eafcd4fdb88dd06f36d705a45"
url: "https://pub.dev"
source: hosted
version: "2.2.0"
file:
dependency: transitive
description:
name: file
sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
url: "https://pub.dev"
source: hosted
version: "7.0.1"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
@@ -83,6 +115,22 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
glob:
dependency: transitive
description:
name: glob
sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de
url: "https://pub.dev"
source: hosted
version: "2.1.3"
hooks:
dependency: transitive
description:
name: hooks
sha256: "9a62a50b50b769a737bc0a8ff381f333529df3ab746b2f6b02e83760231455ba"
url: "https://pub.dev"
source: hosted
version: "2.0.2"
http: http:
dependency: "direct main" dependency: "direct main"
description: description:
@@ -131,6 +179,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.1.0" version: "6.1.0"
logging:
dependency: transitive
description:
name: logging
sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61
url: "https://pub.dev"
source: hosted
version: "1.3.0"
matcher: matcher:
dependency: transitive dependency: transitive
description: description:
@@ -151,10 +207,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: meta name: meta
sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" sha256: "1741988757a65eb6b36abe716829688cf01910bbf91c34354ff7ec1c3de2b349"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.17.0" version: "1.18.0"
native_toolchain_c:
dependency: transitive
description:
name: native_toolchain_c
sha256: f59351d28f49520cd3a74eb1f41c5f19ae15e53c65a3231d14af672e46510a96
url: "https://pub.dev"
source: hosted
version: "0.19.1"
path: path:
dependency: transitive dependency: transitive
description: description:
@@ -163,6 +227,38 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.9.1" version: "1.9.1"
platform:
dependency: transitive
description:
name: platform
sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984"
url: "https://pub.dev"
source: hosted
version: "3.1.6"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
url: "https://pub.dev"
source: hosted
version: "2.1.8"
pub_semver:
dependency: transitive
description:
name: pub_semver
sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585"
url: "https://pub.dev"
source: hosted
version: "2.2.0"
record_use:
dependency: transitive
description:
name: record_use
sha256: "2551bd8eecfe95d14ae75f6021ad0248be5c27f138c2ec12fcb52b500b3ba1ed"
url: "https://pub.dev"
source: hosted
version: "0.6.0"
sky_engine: sky_engine:
dependency: transitive dependency: transitive
description: flutter description: flutter
@@ -176,6 +272,62 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.10.2" version: "1.10.2"
sqflite:
dependency: "direct main"
description:
name: sqflite
sha256: "58a799e6ac17dd32fbab93813d39ed835a75ccc0f8f85b8955fe318c6712b082"
url: "https://pub.dev"
source: hosted
version: "2.4.3"
sqflite_android:
dependency: transitive
description:
name: sqflite_android
sha256: d0548f9d7422a2dae99ec6f8b0a3074463b132d216fa5ba0d230eeefc901983b
url: "https://pub.dev"
source: hosted
version: "2.4.3"
sqflite_common:
dependency: transitive
description:
name: sqflite_common
sha256: cce558075afe2a83f3fd7fc123acd6b090683e4f23910d44fbb31ecd7800b014
url: "https://pub.dev"
source: hosted
version: "2.5.9"
sqflite_common_ffi:
dependency: "direct dev"
description:
name: sqflite_common_ffi
sha256: "3ddad0ec96ad411d5fea45b4912c3cd5743436c9e1890c26a6e688a32d901cae"
url: "https://pub.dev"
source: hosted
version: "2.4.1"
sqflite_darwin:
dependency: transitive
description:
name: sqflite_darwin
sha256: "164a5d73ab87a134566057219988bafde837029a64264e61f1f04376ef3cfcd2"
url: "https://pub.dev"
source: hosted
version: "2.4.3"
sqflite_platform_interface:
dependency: transitive
description:
name: sqflite_platform_interface
sha256: f84939f84350d92d04416f8bc4dc52d3896aec7716cc9e80cf0146342139dc50
url: "https://pub.dev"
source: hosted
version: "2.4.1"
sqlite3:
dependency: "direct dev"
description:
name: sqlite3
sha256: "9488c7d2cdb1091c91cacf7e207cff81b28bff8e366f042bad3afe7d34afe189"
url: "https://pub.dev"
source: hosted
version: "3.3.2"
stack_trace: stack_trace:
dependency: transitive dependency: transitive
description: description:
@@ -200,6 +352,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.4.1" version: "1.4.1"
synchronized:
dependency: transitive
description:
name: synchronized
sha256: "93b153dcb6a26dcddee6ca087dd634b53e38c10b5aa163e8e49501a776456153"
url: "https://pub.dev"
source: hosted
version: "3.4.1"
term_glyph: term_glyph:
dependency: transitive dependency: transitive
description: description:
@@ -212,10 +372,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: test_api name: test_api
sha256: "8161c84903fd860b26bfdefb7963b3f0b68fee7adea0f59ef805ecca346f0c7a" sha256: "949a932224383300f01be9221c39180316445ecb8e7547f70a41a35bf421fb9e"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.10" version: "0.7.11"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:
@@ -248,6 +408,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.1" version: "1.1.1"
yaml:
dependency: transitive
description:
name: yaml
sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce
url: "https://pub.dev"
source: hosted
version: "3.1.3"
sdks: sdks:
dart: ">=3.11.5 <4.0.0" dart: ">=3.12.0 <4.0.0"
flutter: ">=3.18.0-18.0.pre.54" flutter: ">=3.44.0"
+3 -1
View File
@@ -36,11 +36,13 @@ dependencies:
cupertino_icons: ^1.0.8 cupertino_icons: ^1.0.8
flutter_dotenv: ^6.0.1 flutter_dotenv: ^6.0.1
http: ^1.6.0 http: ^1.6.0
sqflite: ^2.4.2+1
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter
sqlite3: ^3.3.0
sqflite_common_ffi: ^2.4.0+3
# The "flutter_lints" package below contains a set of recommended lints to # The "flutter_lints" package below contains a set of recommended lints to
# encourage good coding practices. The lint set provided by the package is # encourage good coding practices. The lint set provided by the package is
# activated in the `analysis_options.yaml` file located at the root of your # activated in the `analysis_options.yaml` file located at the root of your