diff --git a/lib/transport_helper.dart b/lib/transport_helper.dart index 2694410..e521198 100644 --- a/lib/transport_helper.dart +++ b/lib/transport_helper.dart @@ -48,18 +48,22 @@ class DbHelper { class Route { // TODO: add last_viewed, last_modified and such int? id; + String? startStation; + String? endStation; List segments = List.empty(); Duration duration = Duration(minutes: 0); Route({ this.id, + this.startStation, + this.endStation, required this.segments, required this.duration, }); /// toMap for Route but it's just route ids for now Map toMapRoute() { - return {"id": id}; + return {"id": id, "startstation": startStation, "endstation": endStation}; } /// toMap for routesegments relational table @@ -76,12 +80,22 @@ class Route { return tmp; } + factory Route.empty(Station start) { + return Route( + startStation: start.name, + segments: List.empty(), + duration: Duration(minutes: 0), + ); + } + factory Route.fromMap( Map routeMaps, List segmentMaps, ) { return Route( id: routeMaps["id"] as int, + startStation: routeMaps["startstation"] as String?, + endStation: routeMaps["endstation"] as String?, segments: segmentMaps, duration: Duration(minutes: 0), ); @@ -100,10 +114,57 @@ class Route { return newRoute; } + /// 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); + } else { + // if the route has no segments yet, at least the startStation should remain, + // otherwise delete the thing + // having a startStation makes the first step faster at least + // no need to put a mostly empty route into the db though + endStation = null; + duration = Duration(minutes: 0); + } + } + + void addSegment(Segment newSeg) { + segments.add(newSeg); + dbInsertLastRouteSegment(); + } + + void removeLastSegment() { + dbDeleteLastRouteSegment(); + segments.removeLast(); + } + + void _removeSegment(int idx) { + segments.removeAt(idx); + } + + 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)) { + segments[idx] = replacement; + dbUpdateRouteSegments(); + } else if (idx >= segments.length) { + addSegment(replacement); + } else { + throw "startTime for Segment does not fit"; //TODO: can do this better and maybe we should allow this + } + } + static void initRouteTable() async { Database database = DbHelper.db; database.execute("""CREATE TABLE IF NOT EXISTS route( id INTEGER PRIMARY KEY AUTOINCREMENT, + startstation TEXT, + endstation TEXT, + FOREIGN KEY (startstation) REFERENCES station(name) + FOREIGN KEY (endstation) REFERENCES station(name) ); """); } @@ -157,13 +218,19 @@ class Route { ); } + void dbInsertLastRouteSegment() async { + Database database = DbHelper.db; + var lastRouteSegment = toMapRouteSegments().last; + database.insert("routesegments", lastRouteSegment); + } + void dbInsertRouteSegments() async { Database database = DbHelper.db; var routeSegments = toMapRouteSegments(); for (var i = 0; i < routeSegments.length; i++) { database.insert( "routesegments", - routeSegments[i], + routeSegments[i], //TODO: does this work? ); } } @@ -202,6 +269,15 @@ class Route { assert(result == 0); } + void dbDeleteRouteSegment(int idx) { + Database database = DbHelper.db; + database.delete( + "routesegments", + where: "route = ? AND segmentorder = ?", + whereArgs: [id, idx], // TODO: test the index + ); + } + void dbDeleteLastRouteSegment() { Database database = DbHelper.db; database.delete( @@ -277,6 +353,14 @@ class Segment { return tmp; } + bool fitsBetween(Segment prev, Segment next) { + return startTime.isAfter(prev.endTime) && endTime.isBefore(next.startTime); + } + + bool sameEndpoints(Segment other) { + return startPoint == other.startPoint && endPoint == other.endPoint; + } + static void initSegmentTable() async { Database database = DbHelper.db; String station = Station.tableName; @@ -360,6 +444,7 @@ class Station { .toList(); } + //TODO: usage factory Station.fromMap( Map map, { List? stationLines, @@ -790,4 +875,4 @@ enum VehicleType { subway, regionalTrain, PLACEHOLDER, -} +} \ No newline at end of file