Permalink
Browse files

MDL-13943 improved perf when sending multiple grades into grade_update()

  • Loading branch information...
1 parent 931ad96 commit 2b47d8926ae706eb24b67b56ecca3e78b16070e4 skodak committed Mar 16, 2008
Showing with 81 additions and 16 deletions.
  1. +6 −2 lib/grade/grade_item.php
  2. +75 −14 lib/gradelib.php
View
8 lib/grade/grade_item.php
@@ -1460,9 +1460,10 @@ function update_final_grade($userid, $finalgrade=false, $source=NULL, $feedback=
* @param int $usermodified - user which did the grading
* @param int $dategraded
* @param int $datesubmitted
+ * @param object $grade object - usefull for bulk upgrades
* @return boolean success
*/
- function update_raw_grade($userid, $rawgrade=false, $source=NULL, $feedback=false, $feedbackformat=FORMAT_MOODLE, $usermodified=null, $dategraded=null, $datesubmitted=null) {
+ function update_raw_grade($userid, $rawgrade=false, $source=NULL, $feedback=false, $feedbackformat=FORMAT_MOODLE, $usermodified=null, $dategraded=null, $datesubmitted=null, $grade=null) {
global $USER;
$result = true;
@@ -1472,7 +1473,10 @@ function update_raw_grade($userid, $rawgrade=false, $source=NULL, $feedback=fals
return false;
}
- $grade = new grade_grade(array('itemid'=>$this->id, 'userid'=>$userid));
+ if (is_null($grade)) {
+ //fetch from db
+ $grade = new grade_grade(array('itemid'=>$this->id, 'userid'=>$userid));
+ }
$grade->grade_item =& $this; // prevent db fetching of this grade_item
if (empty($usermodified)) {
View
89 lib/gradelib.php
@@ -63,7 +63,7 @@
* @param mixed $itemdetails object or array describing the grading item, NULL if no change
*/
function grade_update($source, $courseid, $itemtype, $itemmodule, $iteminstance, $itemnumber, $grades=NULL, $itemdetails=NULL) {
- global $USER;
+ global $USER, $CFG;
// only following grade_item properties can be changed in this function
$allowed = array('itemname', 'idnumber', 'gradetype', 'grademax', 'grademin', 'scaleid', 'multfactor', 'plusfactor', 'deleted', 'hidden');
@@ -150,7 +150,7 @@ function grade_update($source, $courseid, $itemtype, $itemmodule, $iteminstance,
$grade_item->{$k} = $v;
$update = true;
}
-
+
} else {
if ($grade_item->{$k} != $v) {
$grade_item->{$k} = $v;
@@ -183,22 +183,79 @@ function grade_update($source, $courseid, $itemtype, $itemmodule, $iteminstance,
/// Finally start processing of grades
if (is_object($grades)) {
- $grades = array($grades);
+ $grades = array($grades->userid=>$grades);
} else {
if (array_key_exists('userid', $grades)) {
- $grades = array($grades);
+ $grades = array($grades['userid']=>$grades);
+ }
+ }
+
+/// normalize and verify grade array
+ foreach($grades as $k=>$g) {
+ if (!is_array($g)) {
+ $g = (array)$g;
+ $grades[$k] = $g;
}
+
+ if (empty($g['userid']) or $k != $g['userid']) {
+ debugging('Incorrect grade array index, must be user id! Grade ignored.');
+ unset($grades[$k]);
+ }
+ }
+
+ if (empty($grades)) {
+ return GRADE_UPDATE_FAILED;
+ }
+
+ $count = count($grades);
+ if ($count == 1) {
+ reset($grades);
+ $uid = key($grades);
+ $sql = "SELECT * FROM {$CFG->prefix}grade_grades WHERE itemid = $grade_item->id AND userid = $uid";
+
+ } else if ($count < 200) {
+ $uids = implode(',', array_keys($grades));
+ $sql = "SELECT * FROM {$CFG->prefix}grade_grades WHERE itemid = $grade_item->id AND userid IN ($uids)";
+
+ } else {
+ $sql = "SELECT * FROM {$CFG->prefix}grade_grades WHERE itemid = $grade_item->id";
}
+ $rs = get_recordset_sql($sql);
+
$failed = false;
- foreach ($grades as $grade) {
- $grade = (array)$grade;
- if (empty($grade['userid'])) {
- $failed = true;
- debugging('Invalid userid in grade submitted');
- continue;
- } else {
- $userid = $grade['userid'];
+
+ while (count($grades) > 0) {
+ $grade_grade = null;
+ $grade = null;
+
+ while ($rs and !rs_EOF($rs)) {
+ if (!$gd = rs_fetch_next_record($rs)) {
+ break;
+ }
+ $userid = $gd->userid;
+ if (!isset($grades[$userid])) {
+ // this grade not requested, continue
+ continue;
+ }
+ // existing grade requested
+ $grade = $grades[$userid];
+ $grade_grade = new grade_grade($gd, false);
+ unset($grades[$userid]);
+ break;
+ }
+
+ if (is_null($grade_grade)) {
+ if (count($grades) == 0) {
+ // no more grades to process
+ break;
+ }
+
+ $grade = reset($grades);
+ $userid = $grade['userid'];
+ $grade_grade = new grade_grade(array('itemid'=>$grade_item->id, 'userid'=>$userid), false);
+ $grade_grade->load_optional_fields(); // add feedback and info too
+ unset($grades[$userid]);
}
$rawgrade = false;
@@ -233,11 +290,15 @@ function grade_update($source, $courseid, $itemtype, $itemmodule, $iteminstance,
}
// update or insert the grade
- if (!$grade_item->update_raw_grade($userid, $rawgrade, $source, $feedback, $feedbackformat, $usermodified, $dategraded, $datesubmitted)) {
+ if (!$grade_item->update_raw_grade($userid, $rawgrade, $source, $feedback, $feedbackformat, $usermodified, $dategraded, $datesubmitted, $grade_grade)) {
$failed = true;
}
}
+ if ($rs) {
+ rs_close($rs);
+ }
+
if (!$failed) {
return GRADE_UPDATE_OK;
} else {
@@ -360,7 +421,7 @@ function grade_get_grades($courseid, $itemtype, $itemmodule, $iteminstance, $use
$grade->grade = null;
$grade->str_grade = '-';
$grade->str_long_grade = $grade->str_grade;
-
+
} else if (in_array($grade_item->id, $needsupdate)) {
$grade->grade = false;
$grade->str_grade = get_string('error');

0 comments on commit 2b47d89

Please sign in to comment.