Uploaded image for project: 'Moodle'
  1. Moodle
  2. MDL-85353

Add DB->upsert_record()

XMLWordPrintable

    • Icon: Improvement Improvement
    • Resolution: Unresolved
    • Icon: Minor Minor
    • None
    • 5.0
    • Database SQL/XMLDB
    • None

      There are cases where record id does not matter, plus there is some unique constraint and records might be added concurrently, see https://tracker.moodle.org/browse/MDL-84070

      I think that it would be better to add a new method to DML that inserts or updates record depending on its existence.

      example use:

      $preference = new stdClass();
      $preference->userid = $user->id;
      $preference->name = $name;
      $preference->value = $value;
      $DB->upsert_record('user_preferences', $preference, ['userid', 'name']); 

      Compared to:

      $retry = 0;
      $saved = false;
       
      while (!$saved && $retry++ < 2) {
          if ($preference = $DB->get_record('user_preferences', ['userid' => $user->id, 'name' => $name])) {
              if ($preference->value === $value && isset($user->preference[$name]) && $user->preference[$name] === $value) {
                  // Preference already set to this value.
                  return true;
              }
              $DB->set_field('user_preferences', 'value', $value, ['id' => $preference->id]);
              $saved = true;
          } else {
              $preference = new stdClass();
              $preference->userid = $user->id;
              $preference->name   = $name;
              $preference->value  = $value;
              try {
                  $DB->insert_record('user_preferences', $preference);
                  $saved = true;
              } catch (dml_write_exception $e) {
                  // We have an insert race, so just ignore and try again.
                  $saved = false;
              }
          }
      } 

      Benefits should hopefully be:

      1. faster - 1 db request only for PostgreSQL and MariaDB/MySQL
      2. safer - concurrent inserts should not cause errors
      3. easier to read code

            Unassigned Unassigned
            skodak Petr Skoda
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:

                Error rendering 'clockify-timesheets-time-tracking-reports:timer-sidebar'. Please contact your Jira administrators.