Public Access
feat(transport_helper): store full departures inside segment
build out fromMap constructor so that departure and vehicle objects are
created from db query
rename vehicle.id to vehicle.vehicleid to conform with the rule that
id=internal & type int | {tablename}id=api_id & type String
This commit is contained in:
+116
-53
@@ -119,9 +119,11 @@ class Route {
|
|||||||
/// recalculate some technically redundant data for fast and easy access
|
/// recalculate some technically redundant data for fast and easy access
|
||||||
void sync() async {
|
void sync() async {
|
||||||
if (segments.isNotEmpty) {
|
if (segments.isNotEmpty) {
|
||||||
startStation = segments.first.startPoint.name;
|
startStation = segments.first.start.stationName;
|
||||||
endStation = segments.last.endPoint.name;
|
endStation = segments.last.end.stationName;
|
||||||
duration = segments.first.startTime.difference(segments.last.endTime);
|
duration = segments.first.start.departureTime.difference(
|
||||||
|
segments.last.end.arrivalTime,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
// if the route has no segments yet, at least the startStation should remain,
|
// if the route has no segments yet, at least the startStation should remain,
|
||||||
// otherwise delete the thing
|
// otherwise delete the thing
|
||||||
@@ -154,7 +156,9 @@ class Route {
|
|||||||
void replaceSegment(int idx, Segment replacement) {
|
void replaceSegment(int idx, Segment replacement) {
|
||||||
if ((idx < segments.length - 1 &&
|
if ((idx < segments.length - 1 &&
|
||||||
replacement._fitsBetween(segments[idx - 1], segments[idx + 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;
|
segments[idx] = replacement;
|
||||||
_dbUpdateRouteSegments();
|
_dbUpdateRouteSegments();
|
||||||
} else if (idx >= segments.length) {
|
} else if (idx >= segments.length) {
|
||||||
@@ -314,30 +318,28 @@ class Segment {
|
|||||||
// TODO: add attribute for departures on the way?
|
// TODO: add attribute for departures on the way?
|
||||||
int? id;
|
int? id;
|
||||||
String ref;
|
String ref;
|
||||||
Station startPoint;
|
Departure start;
|
||||||
Station endPoint;
|
Departure end;
|
||||||
DateTime startTime;
|
// Station startPoint;
|
||||||
DateTime endTime;
|
// Station endPoint;
|
||||||
|
// DateTime startTime;
|
||||||
|
// DateTime endTime;
|
||||||
Vehicle vehicle;
|
Vehicle vehicle;
|
||||||
|
|
||||||
Segment({
|
Segment({
|
||||||
this.id, // might throw errors - needs testing, I guess
|
this.id, // might throw errors - needs testing, I guess
|
||||||
required this.ref,
|
required this.ref,
|
||||||
required this.startPoint,
|
required this.start,
|
||||||
required this.endPoint,
|
required this.end,
|
||||||
required this.startTime,
|
|
||||||
required this.endTime,
|
|
||||||
required this.vehicle,
|
required this.vehicle,
|
||||||
});
|
});
|
||||||
|
|
||||||
Map<String, Object?> toMap() {
|
Map<String, Object?> toMap() {
|
||||||
return {
|
return {
|
||||||
"ref": ref,
|
"ref": ref,
|
||||||
"startpoint": startPoint.id,
|
"startid": start.id,
|
||||||
"endpoint": endPoint.id,
|
"endid": end.id,
|
||||||
"starttime": startTime,
|
"vehicleid": vehicle.vehicleid,
|
||||||
"endtime": endTime,
|
|
||||||
"vehicle": vehicle.id,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,62 +347,123 @@ class Segment {
|
|||||||
return Segment(
|
return Segment(
|
||||||
id: map["id"] as int,
|
id: map["id"] as int,
|
||||||
ref: map["ref"] as String,
|
ref: map["ref"] as String,
|
||||||
startPoint: map["startPoint"] as Station,
|
start: Departure.fromMap(
|
||||||
endPoint: map["endPoint"] as Station,
|
map["start"] as Map<String, Object>,
|
||||||
startTime: map["startTime"] as DateTime,
|
),
|
||||||
endTime: map["endTime"] as DateTime,
|
end: Departure.fromMap(
|
||||||
vehicle: map["vehicle"] as Vehicle,
|
map["end"] as Map<String, Object>,
|
||||||
|
),
|
||||||
|
vehicle: Vehicle.fromMap(map["vehicle"] as Map<String, Object>),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
factory Segment.fromJson(Map<String, dynamic> json) {
|
factory Segment.fromJson(Map<String, dynamic> json) {
|
||||||
Segment tmp = Segment(
|
Segment tmp = Segment(
|
||||||
ref: json["JourneyDetail"]["ref"],
|
ref: json["JourneyDetail"]["ref"],
|
||||||
startPoint: Station.fromJson(json["Origin"]),
|
start: Departure.fromJson(json["Origin"]),
|
||||||
endPoint: Station.fromJson(json["Destination"]),
|
end: Departure.fromJson(json["Destination"]),
|
||||||
startTime: json["Origin"]["rtTime"],
|
|
||||||
endTime: json["Destination"]["rtTime"],
|
|
||||||
vehicle: Vehicle.fromJson(json["Product"]),
|
vehicle: Vehicle.fromJson(json["Product"]),
|
||||||
);
|
);
|
||||||
tmp.dbInsert();
|
tmp.dbInsert();
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<Segment> 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) {
|
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) {
|
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 {
|
static void initSegmentTable() async {
|
||||||
Database database = DbHelper.db;
|
Database database = DbHelper.db;
|
||||||
String station = Station.tableName;
|
String station = Station.tableName;
|
||||||
String vehicle = Vehicle.tableName;
|
String vehicle = Vehicle.tableName;
|
||||||
|
String departure = Departure.tableName;
|
||||||
database.execute("""
|
database.execute("""
|
||||||
CREATE TABLE IF NOT EXISTS '$tableName'(
|
CREATE TABLE IF NOT EXISTS '$tableName'(
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
ref TEXT,
|
ref TEXT,
|
||||||
startpoint TEXT,
|
startid TEXT,
|
||||||
endpoint TEXT,
|
endid TEXT,
|
||||||
starttime TEXT,
|
vehicleid INTEGER,
|
||||||
endtime TEXT,
|
FOREIGN KEY(startid) REFERENCES '$departure'(stationid),
|
||||||
vehicle INTEGER,
|
FOREIGN KEY(endid) REFERENCES '$departure'(stationid),
|
||||||
FOREIGN KEY(startpoint) REFERENCES '$station'(stationid),
|
FOREIGN KEY(vehicleid) REFERENCES '$vehicle'(vehicleid)
|
||||||
FOREIGN KEY(endpoint) REFERENCES '$station'(stationid),
|
|
||||||
FOREIGN KEY(vehicle) REFERENCES '$vehicle'(vehicleid)
|
|
||||||
);
|
);
|
||||||
""");
|
""");
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<Segment> dbGet(int id) async {
|
static Future<Segment> dbGet(int id) async {
|
||||||
Database database = DbHelper.db;
|
Database database = DbHelper.db;
|
||||||
var tmp = await database.query(tableName, where: "id = ?", whereArgs: [id]);
|
String vehicle = Vehicle.tableName;
|
||||||
var seg = tmp.map((x) => Segment.fromMap(x));
|
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
|
// 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");
|
assert(tmp.length < 2, "found more than one segment for id $id");
|
||||||
return seg.first;
|
// 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<List<Segment>> dbGetAll() async {
|
static Future<List<Segment>> dbGetAll() async {
|
||||||
@@ -423,7 +486,7 @@ class Segment {
|
|||||||
id = await database.update(
|
id = await database.update(
|
||||||
tableName,
|
tableName,
|
||||||
toMap(),
|
toMap(),
|
||||||
where: "rowid =?",
|
where: "id =?",
|
||||||
whereArgs: [id],
|
whereArgs: [id],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -432,7 +495,7 @@ class Segment {
|
|||||||
Database database = DbHelper.db;
|
Database database = DbHelper.db;
|
||||||
database.delete(
|
database.delete(
|
||||||
tableName,
|
tableName,
|
||||||
where: "rowid = ?",
|
where: "id = ?",
|
||||||
whereArgs: [id],
|
whereArgs: [id],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -587,19 +650,19 @@ class Station {
|
|||||||
class Vehicle {
|
class Vehicle {
|
||||||
static const String tableName = "vehicle";
|
static const String tableName = "vehicle";
|
||||||
|
|
||||||
String id;
|
String vehicleid;
|
||||||
String name;
|
String name;
|
||||||
String vehicleLineId;
|
String vehicleLineId;
|
||||||
|
|
||||||
Vehicle({
|
Vehicle({
|
||||||
required this.id,
|
required this.vehicleid,
|
||||||
required this.name,
|
required this.name,
|
||||||
required this.vehicleLineId,
|
required this.vehicleLineId,
|
||||||
});
|
});
|
||||||
|
|
||||||
Map<String, Object?> _toMap() {
|
Map<String, Object?> _toMap() {
|
||||||
return {
|
return {
|
||||||
"id": id,
|
"id": vehicleid,
|
||||||
"name": name,
|
"name": name,
|
||||||
"line": vehicleLineId,
|
"line": vehicleLineId,
|
||||||
};
|
};
|
||||||
@@ -609,7 +672,7 @@ class Vehicle {
|
|||||||
Map<String, Object?> map,
|
Map<String, Object?> map,
|
||||||
) {
|
) {
|
||||||
return Vehicle(
|
return Vehicle(
|
||||||
id: map["id"] as String,
|
vehicleid: map["id"] as String,
|
||||||
name: map["name"] as String,
|
name: map["name"] as String,
|
||||||
vehicleLineId: map["line"] as String,
|
vehicleLineId: map["line"] as String,
|
||||||
);
|
);
|
||||||
@@ -618,7 +681,7 @@ class Vehicle {
|
|||||||
// 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["num"],
|
vehicleid: json["num"],
|
||||||
name: json["name"],
|
name: json["name"],
|
||||||
vehicleLineId: Line.fromJson(json).lineId,
|
vehicleLineId: Line.fromJson(json).lineId,
|
||||||
);
|
);
|
||||||
@@ -627,7 +690,7 @@ class Vehicle {
|
|||||||
Database database = DbHelper.db;
|
Database database = DbHelper.db;
|
||||||
String line = Line.tableName;
|
String line = Line.tableName;
|
||||||
database.execute("""CREATE TABLE IF NOT EXISTS '$tableName'(
|
database.execute("""CREATE TABLE IF NOT EXISTS '$tableName'(
|
||||||
id TEXT PRIMARY KEY,
|
vehicleid TEXT PRIMARY KEY,
|
||||||
name TEXT,
|
name TEXT,
|
||||||
line TEXT,
|
line TEXT,
|
||||||
FOREIGN KEY(line) REFERENCES '$line'(lineid)
|
FOREIGN KEY(line) REFERENCES '$line'(lineid)
|
||||||
@@ -656,12 +719,12 @@ class Vehicle {
|
|||||||
|
|
||||||
void dbUpdate() async {
|
void dbUpdate() async {
|
||||||
Database database = DbHelper.db;
|
Database database = DbHelper.db;
|
||||||
database.update(tableName, _toMap(), where: "id=?", whereArgs: [id]);
|
database.update(tableName, _toMap(), where: "id=?", whereArgs: [vehicleid]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dbDelete() async {
|
void dbDelete() async {
|
||||||
Database database = DbHelper.db;
|
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:
|
direction:
|
||||||
json["direction"] ??
|
json["direction"] ??
|
||||||
json["Directions"]["Direction"][0]["value"], // this is not healthy
|
json["Directions"]["Direction"][0]["value"], // this is not healthy
|
||||||
vehicleId: vehicle.id,
|
vehicleId: vehicle.vehicleid,
|
||||||
vehicleName: vehicle.name,
|
vehicleName: vehicle.name,
|
||||||
stationId: station.id,
|
stationId: station.id,
|
||||||
stationName: station.name,
|
stationName: station.name,
|
||||||
@@ -908,8 +971,8 @@ class Departure {
|
|||||||
stationname TEXT,
|
stationname TEXT,
|
||||||
arrivaltime TEXT,
|
arrivaltime TEXT,
|
||||||
departuretime TEXT,
|
departuretime TEXT,
|
||||||
FOREIGN KEY(vehicle) REFERENCES '$vehicle'(id),
|
FOREIGN KEY(vehicle) REFERENCES '$vehicle'(vehicleid),
|
||||||
FOREIGN KEY(station) REFERENCES '$station'(id)
|
FOREIGN KEY(station) REFERENCES '$station'(stationid)
|
||||||
);
|
);
|
||||||
""");
|
""");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user