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,
};
}
}