TypeConverter not generated for field.
I encountered problems while creating and using TypeConverter with the floor library.
The problem is as follows:
I have an entity called Coil which contains a couple of fields.
@entity
class Coil {
@primaryKey
final int? id;
String coilName;
String coilDesc;
CapacitorBank mmcBank;
final String coilType;
double resonantFrequency;
Coil({
this.id,
this.coilName = "",
this.coilDesc = "",
this.coilType = "",
this.resonantFrequency = 0.0,
CapacitorBank? capBank,
}) : mmcBank = capBank ?? CapacitorBank();
}
Note mmcBank and capBank
CapacitorBank class has the following fields:
/// This refers to MMC
class CapacitorBank {
int seriesCapacitorCount;
int parallelCapacitorCount;
double capacitance;
CapacitorBank({
this.capacitance = 0.0,
this.seriesCapacitorCount = 0,
this.parallelCapacitorCount = 0,
});
factory CapacitorBank.fromDatabase(String databaseValue) {
var valuesList = databaseValue.split(",");
return CapacitorBank(
capacitance: double.parse(
valuesList.elementAt(0),
),
seriesCapacitorCount: int.parse(
valuesList.elementAt(1),
),
parallelCapacitorCount: int.parse(
valuesList.elementAt(2),
),
);
}
String toDatabaseString() =>
"$capacitance,$seriesCapacitorCount,$parallelCapacitorCount,";
}
CapacitorBank is a separate class and I need to save it inside the database. As I can see, floor does not support database relations fully so I had to come up with another solution to this problem. I came up with a solution to use type converters.
I wanted to save variables from CapacitorBank like array inside mmcBank field inside the Coil table.
Here is the type converter I use to do so:
class CapacitorBankConverter extends TypeConverter<CapacitorBank, String> {
@override
CapacitorBank decode(String databaseValue) {
return CapacitorBank.fromDatabase(databaseValue);
}
@override
String encode(CapacitorBank value) {
return value.toDatabaseString();
}
}
At first, everything worked fine while I was inserting some values inside database under mmcBank field but when I tried to retrieve this data, it was returning me only default values provided with the CapacitorBank constructor.
I looked at coil_database.g.dart file to investigate what is causing this and found out that type converters are not generated for queries.
This is my dao file:
@dao
abstract class CoilDao {
@insert
Future<void> insertCoil(Coil coil);
@delete
Future<void> deleteCoil(Coil coil);
@update
Future<void> updateCoil(Coil coil);
@Query("SELECT * FROM Coil")
Stream<List<Coil>> getCoils();
}
As you can see I have function getCoils() which returns everything from Coil table.
When I looked for that function inside coil_database.g.dart it was generated like this:
@override
Stream<List<Coil>> getCoils() {
return _queryAdapter.queryListStream('SELECT * FROM Coil',
mapper: (Map<String, Object?> row) => Coil(
id: row['id'] as int?,
coilName: row['coilName'] as String,
coilDesc: row['coilDesc'] as String,
coilType: row['coilType'] as String,
resonantFrequency: row['resonantFrequency'] as double),
queryableName: 'Coil',
isView: false);
}
Problem is that inside the function, the query does not return mmcBank field.
Line that is missing inside this file is:
capBank: _capacitorBankConverter.decode(row['mmcBank'] as String)
@BojanDolic Yes, it's true, the floor_generator doesn't take into account constructor parameters that are not declared as a class field. Frankly, I more prefer to keep entity constructors simple. In your case, I would recommend adding a factory as shown below:
Coil(
this.id,
this.coilName,
this.coilDesc,
this.coilType,
this.resonantFrequency,
this.mmcBank,
);
factory Coil.capBank({
int? id,
String? coilName,
String? coilDesc,
String? coilType,
double? resonantFrequency,
CapacitorBank? capBank,
}) {
return Coil(
id,
coilName ?? '',
coilDesc ?? '',
coilType ?? '',
resonantFrequency ?? 0.0,
capBank ?? CapacitorBank(),
);
}
It should solve the problem completely.
Closed due inactivity