Upsert conflict with id + uuid #1635
-
I am facing the following problem: I have some different tables which have both a regular ID as well as a UUID. For example: CREATE TABLE cars(
car_id INT NULL UNIQUE,
car_uuid TEXT NOT NULL PRIMARY KEY,
wheels INT NULL
);
CREATE TABLE boats(
boat_id INT NULL UNIQUE,
boat_uuid TEXT NOT NULL PRIMARY KEY,
is_sailboat INT NULL
); On the server backend, the normal IDs are used for identification (much better performance with large datasets), whereas in my Flutter app, the UUIDs are used. This ensures the client app can also add cars and boats without worrying about consistency on the server (which assigns them a 'normal' ID once pushed). When I receive a Car.fromJson(jsonEntry).toCompanion(true);
Boat.fromJson(jsonEntry).toCompanion(true); Now, I want to also handle upserts. In this case, when there is a conflict on the In reality, I have a number of tables that are identified this way, so I want to dynamically handle these operations (and write as little code per type as possible). As a result, I have a function which handles server data that looks a bit like: handleUpdate({required VehicleDatabase db, required String tableName, required Map<String, dynamic> entry}) {
Insertable<dynamic>? companion;
switch(tableName) {
case 'cars':
companion = Car.fromJson(entry);
break;
case 'boats':
companion = Boat.fromJson(entry);
break;
default:
throw new Exception(...);
}
TableInfo table = db.allTables.firstWhere((element) => element.actualTableName == tableName);
// this works fine for insertions
db.into(table).insertOnConflictUpdate(companion);
} I was trying to use the db.into(table).insert(companion, onConflict: DoUpdate((Table? old) {
// here, I want to return an inserable with all values from the new entry, but the UUID of the old entry
// no UUID would also work, but since it's the PK it's required
})); Does anyone have some insights on how I could achieve this? Thank you in advance! More concretely: On an insertion conflict, I would like to access the entry in the database that caused the conflict, and construct a new companion which uses its UUID and the other values from the companion which was to be inserted, all while dynamically determining which table I'm working on. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 12 replies
-
I haven't tried it, but something like this could work: db.into(table).insert(companion, onConflict: DoUpdate((Table? old) {
final oldId = (old as TableInfo).columnsByName['${tableName}_uuid'];
return RawValuesInsertable({
...companion.toColumns(false),
'${tableName}_uuid': oldId,
});
})); Essentially, the idea is to use the uuid column from the old table, but all other values from the companion. |
Beta Was this translation helpful? Give feedback.
-
Unfortunately, it still doesn't work... When I log During the insertion, though, it still errors, saying
|
Beta Was this translation helpful? Give feedback.
I haven't tried it, but something like this could work:
Essentially, the idea is to use the uuid column from the old table, but all other values from the companion.