From 7cfc415f9fe0686533fcb1e160200500d209ad99 Mon Sep 17 00:00:00 2001 From: fbachus Date: Sat, 6 Jun 2026 01:17:49 +0200 Subject: [PATCH] feat(database): add functions for DB and DB-table creation --- lib/main.dart | 3 + lib/transport_helper.dart | 116 ++++++++++++++++++++---- pubspec.lock | 180 ++++++++++++++++++++++++++++++++++++-- pubspec.yaml | 4 +- 4 files changed, 279 insertions(+), 24 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index bf0fe50..1488a68 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,9 +1,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'api_handler.dart'; +import 'transport_helper.dart'; void main() async { await dotenv.load(); + const String dbName = "oeffimasterTransportDb"; + initDB(dbName); runApp(const MyApp()); } diff --git a/lib/transport_helper.dart b/lib/transport_helper.dart index bdf06fa..522c0b0 100644 --- a/lib/transport_helper.dart +++ b/lib/transport_helper.dart @@ -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 { List segments = List.empty(); Duration duration = Duration(minutes: 0); @@ -15,6 +36,10 @@ class Route { 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 { @@ -39,22 +64,36 @@ class Segment { endTime: json["Destination"]["rtTime"], 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 { - final String id; + final String stationId; final String name; - List? transportLines; - List? departures; + List? transportLines; // could be normalized away Station({ - required this.id, + required this.stationId, required this.name, - required this.transportLines + required this.transportLines, //TODO: make extra db table }); factory Station.fromJson(Map json) => Station( - id: json["id"] as String? ?? json["extId"] as String, + stationId: json["id"] as String? ?? json["extId"] as String, name: json["name"], transportLines: json.containsKey("productAtStop") ? json["productAtStop"].map( @@ -62,27 +101,44 @@ class Station { ) : const [], ); + + void initStationTable(Database database) async { + database.execute("""CREATE TABLE IF NOT EXISTS station( + stationid TEXT PRIMARY KEY, + name TEXT + ); + """); + } } class Vehicle { - final String id; + final String vehicleId; final Line line; Vehicle({ - required this.id, + required this.vehicleId, required this.line, }); // we can use the "product" class from within any JSON response // (within hafas API, on the appropriate level) factory Vehicle.fromJson(Map json) => Vehicle( - id: json["matchId"], + vehicleId: json["matchId"], 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 { - final String id; + final String lineId; Station? destination; Station? direction; final VehicleType mode; @@ -91,7 +147,7 @@ class Line { Color? bgColor; Line({ - required this.id, + required this.lineId, required this.name, required this.mode, this.fgColor, @@ -103,18 +159,32 @@ class Line { VehicleType.metro, VehicleType.subway, VehicleType.PLACEHOLDER, - VehicleType.bus + VehicleType.bus, ]; factory Line.fromJson(Map json) => Line( - id: json["lineId"], + lineId: json["lineId"], name: json["name"], mode: _vehicleTypeAsCatCode[int.parse(json["catCode"])], - fgColor: Color.fromJson(json["foregroundColor"]) as Color? - ?? Color(r: 255, g: 255, b: 255), // fallback - bgColor: Color.fromJson(json["backgroundColor"]) as Color? - ?? Color(r: 50, g: 50, b: 50), // fallback + fgColor: + Color.fromJson(json["foregroundColor"]) as Color? ?? + Color(r: 255, g: 255, b: 255), // 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 { @@ -128,6 +198,18 @@ class Departure { required this.station, 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 { diff --git a/pubspec.lock b/pubspec.lock index ede043e..43f988f 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -33,6 +33,14 @@ packages: url: "https://pub.dev" source: hosted 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: dependency: transitive description: @@ -41,6 +49,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.19.1" + crypto: + dependency: transitive + description: + name: crypto + sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf + url: "https://pub.dev" + source: hosted + version: "3.0.7" cupertino_icons: dependency: "direct main" description: @@ -57,6 +73,22 @@ packages: url: "https://pub.dev" source: hosted 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: dependency: "direct main" description: flutter @@ -83,6 +115,22 @@ packages: description: flutter source: sdk 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: dependency: "direct main" description: @@ -131,6 +179,14 @@ packages: url: "https://pub.dev" source: hosted version: "6.1.0" + logging: + dependency: transitive + description: + name: logging + sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 + url: "https://pub.dev" + source: hosted + version: "1.3.0" matcher: dependency: transitive description: @@ -151,10 +207,18 @@ packages: dependency: transitive description: name: meta - sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" + sha256: "1741988757a65eb6b36abe716829688cf01910bbf91c34354ff7ec1c3de2b349" url: "https://pub.dev" 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: dependency: transitive description: @@ -163,6 +227,38 @@ packages: url: "https://pub.dev" source: hosted 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: dependency: transitive description: flutter @@ -176,6 +272,62 @@ packages: url: "https://pub.dev" source: hosted 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: dependency: transitive description: @@ -200,6 +352,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.1" + synchronized: + dependency: transitive + description: + name: synchronized + sha256: "93b153dcb6a26dcddee6ca087dd634b53e38c10b5aa163e8e49501a776456153" + url: "https://pub.dev" + source: hosted + version: "3.4.1" term_glyph: dependency: transitive description: @@ -212,10 +372,10 @@ packages: dependency: transitive description: name: test_api - sha256: "8161c84903fd860b26bfdefb7963b3f0b68fee7adea0f59ef805ecca346f0c7a" + sha256: "949a932224383300f01be9221c39180316445ecb8e7547f70a41a35bf421fb9e" url: "https://pub.dev" source: hosted - version: "0.7.10" + version: "0.7.11" typed_data: dependency: transitive description: @@ -248,6 +408,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.1" + yaml: + dependency: transitive + description: + name: yaml + sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce + url: "https://pub.dev" + source: hosted + version: "3.1.3" sdks: - dart: ">=3.11.5 <4.0.0" - flutter: ">=3.18.0-18.0.pre.54" + dart: ">=3.12.0 <4.0.0" + flutter: ">=3.44.0" diff --git a/pubspec.yaml b/pubspec.yaml index 67d7205..3c24ee4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -36,11 +36,13 @@ dependencies: cupertino_icons: ^1.0.8 flutter_dotenv: ^6.0.1 http: ^1.6.0 - + sqflite: ^2.4.2+1 dev_dependencies: flutter_test: 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 # 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