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); Route({ required this.segments, required this.duration, }); // from trip API request factory Route.fromJson(Map json) => Route( segments: json["LegList"]["Leg"].map((leg) => Segment.fromJson(leg)), duration: json["LegList"]["Leg"][-1]["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 { final Station startPoint; final Station endPoint; final DateTime startTime; final DateTime endTime; final Vehicle vehicle; Segment({ required this.startPoint, required this.endPoint, required this.startTime, required this.endTime, required this.vehicle, }); factory Segment.fromJson(Map json) => Segment( startPoint: Station.fromJson(json["Origin"]), endPoint: Station.fromJson(json["Destination"]), startTime: json["Origin"]["rtTime"], 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 stationId; final String name; List? transportLines; // could be normalized away Station({ required this.stationId, required this.name, required this.transportLines, //TODO: make extra db table }); factory Station.fromJson(Map json) => Station( stationId: json["id"] as String? ?? json["extId"] as String, name: json["name"], transportLines: json.containsKey("productAtStop") ? json["productAtStop"].map( (jsonLine) => Line.fromJson(jsonLine as Map), ) : const [], ); void initStationTable(Database database) async { database.execute("""CREATE TABLE IF NOT EXISTS station( stationid TEXT PRIMARY KEY, name TEXT ); """); } } class Vehicle { final String vehicleId; final Line line; Vehicle({ 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( 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 lineId; Station? destination; Station? direction; final VehicleType mode; final String name; Color? fgColor; Color? bgColor; Line({ required this.lineId, required this.name, required this.mode, this.fgColor, this.bgColor, }); // TODO: EXPLAIN!!!!!!!!!!!! static const _vehicleTypeAsCatCode = [ VehicleType.metro, VehicleType.subway, VehicleType.PLACEHOLDER, VehicleType.bus, ]; factory Line.fromJson(Map json) => Line( 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 ); 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 { String? id; final Vehicle vehicle; final Station station; final DateTime departureTime; Departure({ required this.vehicle, 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 { final int r; final int g; final int b; Color({ required this.r, required this.g, required this.b, }); factory Color.fromJson(Map json) => Color( r: json["r"], g: json["g"], b: json["b"], ); } enum VehicleType { bus, tram, metro, subway, regionalTrain, PLACEHOLDER, }