-
Improvement
-
Resolution: Unresolved
-
Minor
-
None
-
Future Dev
This is mostly a convenience to make code simpler, but on some db's we can also make this a single query.
There seems to be some feelings that this wouldn't be a good thing so this tracker might just end up as a place to document those for future curious people.
I can see plenty of valid use cases where you don't start off with an record and id and have to first do a query to find it, but you only want to change some fields and don't need anything else.
This has a few benefits:
1) to make code simpler in places and avoid a bunch of repetitive boilerplate
2) where possible in some db drivers save a db call. Plenty of moodle code makes assumptions that these are effectively atomic and don't bother with a transaction which creates micro race conditions.
3) If 2 is done, this improves things with read replicas, ie you don't read from the replica and then write to the primary
Rough idea would be to pass in a set of where conditions, and a set of fields to update.
$conditions = [
|
'user' => $USER->id,
|
];
|
$data = [
|
'lastmod' => time(),
|
];
|
$DB->upsert('table', $conditions, $data);
|
|
|
|
// a rough default implementation:
|
function upsert($table, $conditions, $data) {
|
$current = $DB->get_records($table, $conditions);
|
if ($current) {
|
$data['id'] = $current[0]->id;
|
$DB->update_record($table, $data);
|
} else {
|
$DB->insert_record('table', $data);
|
}
|
}
|