I'm developing a mobile application that needs to store locally on user's device some information about the places he visited. These are my model classes:
class Place extends Equatable {
final String placeId;
final double latitude;
final double longitude;
final String formattedAddress;
final String name;
const Place({
@required this.placeId,
@required this.latitude,
@required this.longitude,
@required this.formattedAddress,
@required this.name,
});
}
class Trip extends Equatable {
final int tripId;
final String reason;
final DateTime startingTime;
final DateTime arrivalTime;
final Place source;
final Place destination;
Trip({
@required this.tripId,
@required this.reason,
@required this.startingTime,
@required this.arrivalTime,
@required this.source,
@required this.destination,
});
}
To store these information I'm using the package sqflite and to keep my code modular and well organized I created Data Access Objects (DAOs) for the two objects and I have a DatabaseHelper class to create the database and to abstract all the CRUD operations.
Despite this, I don't understand how can I store complex object like Trip in my database and how can I build a Trip object from a database row.
An object like Place only has fields that are primitive types, fully supported by sqflite. On the other hand Trip has two fields (source and destination) which are of type Place.
So what is the best way to serialize and deserialize an object like Trip?
This is my PlaceDao object:
class PlaceDao implements Dao<Place> {
final tableName = 'places';
final columnPlaceId = 'placeId';
final columnLatitude = 'latitude';
final columnLongitude = 'longitude';
final columnFormattedAddress = 'formattedAddress';
final columnName = 'name';
@override
String get createTableQuery {
return '''
CREATE TABLE $tableName (
$columnPlaceId TEXT PRIMARY KEY,
$columnLatitude REAL NOT NULL,
$columnLongitude REAL NOT NULL,
$columnFormattedAddress TEXT NOT NULL,
$columnName TEXT NOT NULL
)''';
}
@override
List<Place> fromList(List<Map<String, dynamic>> mapsList) {
return mapsList.map((map) => fromMap(map)).toList();
}
@override
Place fromMap(Map<String, dynamic> map) {
return Place(
placeId: map[columnPlaceId],
latitude: map[columnLatitude],
longitude: map[columnLongitude],
formattedAddress: map[columnFormattedAddress],
name: map[columnName],
);
}
@override
Map<String, dynamic> toMap(Place place) {
return {
columnPlaceId: place.placeId,
columnLatitude: place.latitude,
columnLongitude: place.longitude,
columnFormattedAddress: place.formattedAddress,
columnName: place.name,
};
}
}
I don't undesrstand how can I return a Trip object in my fromMap() in the TripDao class, since in the table for my trips I only store the placeId for the source and destination fields, because they are foreign keys.
Suppose this is my TripDao class:
class TripDao implements Dao<Trip> {
final tableName = 'trips';
final columnTripId = 'tripId';
final columnReason = 'reason';
final columnStartingTime = 'startingTime';
final columnArrivalTime = 'arrivalTime';
final columnSourceId = 'sourceId';
final columnDestinationId = 'destinationId';
@override
String get createTableQuery {
return '''
CREATE TABLE $tableName (
$columnTripId INTEGER PRIMARY KEY AUTOINCREMENT,
$columnReason TEXT NOT NULL,
$columnStartingTime INTEGER NOT NULL,
$columnArrivalTime INTEGER NOT NULL,
$columnSourceId INTEGER NOT NULL,
$columnDestinationId INTEGER NOT NULL
)''';
}
@override
List<Trip> fromList(List<Map<String, dynamic>> mapsList) {
// ?????????????????????????????
}
@override
Trip fromMap(Map<String, dynamic> map) {
return Trip(
tripId: map[columnTripId],
reason: map[columnReason],
startingTime: null,
arrivalTime: null,
source: null, //<-- ?????????????????????????????
destination: null, //<-- ?????????????????????????????
);
}
@override
Map<String, dynamic> toMap(Trip trip) {
return {
columnTripId: trip.tripId,
columnReason: trip.reason,
columnStartingTime: null,
columnArrivalTime: null,
columnSourceId: trip.source.placeId,
columnDestinationId: trip.destination.placeId,
};
}
}