diff --git a/lib/transport_helper.dart b/lib/transport_helper.dart index eb2becd..acda9b7 100644 --- a/lib/transport_helper.dart +++ b/lib/transport_helper.dart @@ -119,9 +119,11 @@ class Route { /// recalculate some technically redundant data for fast and easy access void sync() async { if (segments.isNotEmpty) { - startStation = segments.first.startPoint.name; - endStation = segments.last.endPoint.name; - duration = segments.first.startTime.difference(segments.last.endTime); + startStation = segments.first.start.stationName; + endStation = segments.last.end.stationName; + duration = segments.first.start.departureTime.difference( + segments.last.end.arrivalTime, + ); } else { // if the route has no segments yet, at least the startStation should remain, // otherwise delete the thing @@ -154,7 +156,9 @@ class Route { void replaceSegment(int idx, Segment replacement) { if ((idx < segments.length - 1 && replacement._fitsBetween(segments[idx - 1], segments[idx + 1])) || - replacement.startTime.isAfter(segments[idx - 1].endTime)) { + replacement.start.departureTime.isAfter( + segments[idx - 1].end.arrivalTime, + )) { segments[idx] = replacement; _dbUpdateRouteSegments(); } else if (idx >= segments.length) { @@ -314,30 +318,28 @@ class Segment { // TODO: add attribute for departures on the way? int? id; String ref; - Station startPoint; - Station endPoint; - DateTime startTime; - DateTime endTime; + Departure start; + Departure end; + // Station startPoint; + // Station endPoint; + // DateTime startTime; + // DateTime endTime; Vehicle vehicle; Segment({ this.id, // might throw errors - needs testing, I guess required this.ref, - required this.startPoint, - required this.endPoint, - required this.startTime, - required this.endTime, + required this.start, + required this.end, required this.vehicle, }); Map toMap() { return { "ref": ref, - "startpoint": startPoint.id, - "endpoint": endPoint.id, - "starttime": startTime, - "endtime": endTime, - "vehicle": vehicle.id, + "startid": start.id, + "endid": end.id, + "vehicleid": vehicle.vehicleid, }; } @@ -345,62 +347,123 @@ class Segment { return Segment( id: map["id"] as int, ref: map["ref"] as String, - startPoint: map["startPoint"] as Station, - endPoint: map["endPoint"] as Station, - startTime: map["startTime"] as DateTime, - endTime: map["endTime"] as DateTime, - vehicle: map["vehicle"] as Vehicle, + start: Departure.fromMap( + map["start"] as Map, + ), + end: Departure.fromMap( + map["end"] as Map, + ), + vehicle: Vehicle.fromMap(map["vehicle"] as Map), ); } factory Segment.fromJson(Map json) { Segment tmp = Segment( ref: json["JourneyDetail"]["ref"], - startPoint: Station.fromJson(json["Origin"]), - endPoint: Station.fromJson(json["Destination"]), - startTime: json["Origin"]["rtTime"], - endTime: json["Destination"]["rtTime"], + start: Departure.fromJson(json["Origin"]), + end: Departure.fromJson(json["Destination"]), vehicle: Vehicle.fromJson(json["Product"]), ); tmp.dbInsert(); return tmp; } + Future fromDepartures(Departure start, Departure end) async { + Segment tmp = Segment( + ref: start.ref, + start: start, + end: end, + vehicle: await Vehicle.dbGet(start.vehicleId), + ); + tmp.dbInsert(); + return tmp; + } + bool _fitsBetween(Segment prev, Segment next) { - return startTime.isAfter(prev.endTime) && endTime.isBefore(next.startTime); + return start.departureTime.isAfter(prev.end.arrivalTime) && + start.arrivalTime.isBefore(next.end.departureTime); } bool _sameEndpoints(Segment other) { - return startPoint == other.startPoint && endPoint == other.endPoint; + return start.stationId == other.start.stationId && + end.stationId == other.end.stationId; } static void initSegmentTable() async { Database database = DbHelper.db; String station = Station.tableName; String vehicle = Vehicle.tableName; + String departure = Departure.tableName; database.execute(""" CREATE TABLE IF NOT EXISTS '$tableName'( id INTEGER PRIMARY KEY AUTOINCREMENT, ref TEXT, - 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) + startid TEXT, + endid TEXT, + vehicleid INTEGER, + FOREIGN KEY(startid) REFERENCES '$departure'(stationid), + FOREIGN KEY(endid) REFERENCES '$departure'(stationid), + FOREIGN KEY(vehicleid) REFERENCES '$vehicle'(vehicleid) ); """); } static Future dbGet(int id) async { Database database = DbHelper.db; - var tmp = await database.query(tableName, where: "id = ?", whereArgs: [id]); - var seg = tmp.map((x) => Segment.fromMap(x)); - //since we are querying for the primary key, this list should never be > 1 - assert(seg.length < 2, "found more than one segment for id $id"); - return seg.first; + String vehicle = Vehicle.tableName; + String departure = Departure.tableName; + var tmp = await database.rawQuery( + """SELECT s.id, s.ref, s.startid, s.endid, s.vehicleid, + start.station as start_stationid, + start.stationname as start_stationname, start.arrivaltime as start_arrivaltime, + start.departuretime as start_departuretime, + end.station as end_stationid, end.stationname as end_stationname, + end.arrivaltime as end_arrivaltime, end.departuretime as end_departuretime, + v.name as vehiclename, v.line as vehicleline + FROM $tableName s + JOIN $departure start ON s.startid = start.id + JOIN $departure end ON s.endid = end.id + JOIN $vehicle v ON s.vehicleid = v.id; + """, + ); + // since we are querying for the primary key, this list should never be > 1 + assert(tmp.length < 2, "found more than one segment for id $id"); + // var seg = tmp.map((x) => Segment.fromMap(x)); + // return seg.first; + + var seg = tmp.first; + var fullMap = { + "id": seg["id"], + "ref": seg["ref"], + "start": { + "id": seg["startid"] as int, + "ref": seg["ref"] as String, + "direction": seg["direction"] as String, + "vehicle": seg["vehicleid"] as String, + "vehiclename": seg["vehiclename"] as String, + "station": seg["start_stationid"] as String, + "staionname": seg["start_stationname"] as String, + "arrivaltime": seg["start_arrivalTime"] as String, + "departuretime": seg["start_departuretime"] as String, + }, + "end": { + "id": seg["endid"] as int, + "ref": seg["ref"] as String, + "direction": seg["direction"] as String, + "vehicle": seg["vehicleid"] as String, + "vehiclename": seg["vehiclename"] as String, + "station": seg["end_stationid"] as String, + "staionname": seg["end_stationname"] as String, + "arrivaltime": seg["end_arrivalTime"] as String, + "departuretime": seg["end_departuretime"] as String, + }, + "vehicle": { + "id": seg["vehicleid"] as String, + "name": seg["vehiclename"] as String, + "line": seg["vehicleline"] as String, + }, + }; + return Segment.fromMap(fullMap); } static Future> dbGetAll() async { @@ -423,7 +486,7 @@ class Segment { id = await database.update( tableName, toMap(), - where: "rowid =?", + where: "id =?", whereArgs: [id], ); } @@ -432,7 +495,7 @@ class Segment { Database database = DbHelper.db; database.delete( tableName, - where: "rowid = ?", + where: "id = ?", whereArgs: [id], ); } @@ -587,19 +650,19 @@ class Station { class Vehicle { static const String tableName = "vehicle"; - String id; + String vehicleid; String name; String vehicleLineId; Vehicle({ - required this.id, + required this.vehicleid, required this.name, required this.vehicleLineId, }); Map _toMap() { return { - "id": id, + "id": vehicleid, "name": name, "line": vehicleLineId, }; @@ -609,7 +672,7 @@ class Vehicle { Map map, ) { return Vehicle( - id: map["id"] as String, + vehicleid: map["id"] as String, name: map["name"] as String, vehicleLineId: map["line"] as String, ); @@ -618,7 +681,7 @@ class Vehicle { // 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["num"], + vehicleid: json["num"], name: json["name"], vehicleLineId: Line.fromJson(json).lineId, ); @@ -627,7 +690,7 @@ class Vehicle { Database database = DbHelper.db; String line = Line.tableName; database.execute("""CREATE TABLE IF NOT EXISTS '$tableName'( - id TEXT PRIMARY KEY, + vehicleid TEXT PRIMARY KEY, name TEXT, line TEXT, FOREIGN KEY(line) REFERENCES '$line'(lineid) @@ -656,12 +719,12 @@ class Vehicle { void dbUpdate() async { Database database = DbHelper.db; - database.update(tableName, _toMap(), where: "id=?", whereArgs: [id]); + database.update(tableName, _toMap(), where: "id=?", whereArgs: [vehicleid]); } void dbDelete() async { Database database = DbHelper.db; - database.delete(tableName, where: "id = ?", whereArgs: [id]); + database.delete(tableName, where: "id = ?", whereArgs: [vehicleid]); } } @@ -882,7 +945,7 @@ class Departure { direction: json["direction"] ?? json["Directions"]["Direction"][0]["value"], // this is not healthy - vehicleId: vehicle.id, + vehicleId: vehicle.vehicleid, vehicleName: vehicle.name, stationId: station.id, stationName: station.name, @@ -908,8 +971,8 @@ class Departure { stationname TEXT, arrivaltime TEXT, departuretime TEXT, - FOREIGN KEY(vehicle) REFERENCES '$vehicle'(id), - FOREIGN KEY(station) REFERENCES '$station'(id) + FOREIGN KEY(vehicle) REFERENCES '$vehicle'(vehicleid), + FOREIGN KEY(station) REFERENCES '$station'(stationid) ); """); }