Skip to content

Commit

Permalink
MDL-42065 core_grade: Modified some grade_item queries for improved p…
Browse files Browse the repository at this point in the history
…erformance

* Modified 2 queries in grade_item::depends_on to improve performance
* Added additional unit tests to cover those queries better
  • Loading branch information
samchaffee committed Oct 9, 2013
1 parent 56cc9b3 commit 87a26cc
Show file tree
Hide file tree
Showing 3 changed files with 230 additions and 12 deletions.
12 changes: 8 additions & 4 deletions lib/grade/grade_item.php
Expand Up @@ -1372,18 +1372,20 @@ public function depends_on($reset_cache=false) {

if ($grade_category->aggregatesubcats) {
// return all children excluding category items
$params[] = $this->courseid;
$params[] = '%/' . $grade_category->id . '/%';
$sql = "SELECT gi.id
FROM {grade_items} gi
JOIN {grade_categories} gc ON gi.categoryid = gc.id
WHERE $gtypes
$outcomes_sql
AND gi.categoryid IN (
SELECT gc.id
FROM {grade_categories} gc
WHERE gc.path LIKE ?)";
AND gi.courseid = ?
AND gc.path LIKE ?";
} else {
$params[] = $grade_category->id;
$params[] = $this->courseid;
$params[] = $grade_category->id;
$params[] = $this->courseid;
if (empty($CFG->grade_includescalesinaggregation)) {
$params[] = GRADE_TYPE_VALUE;
} else {
Expand All @@ -1394,13 +1396,15 @@ public function depends_on($reset_cache=false) {
FROM {grade_items} gi
WHERE $gtypes
AND gi.categoryid = ?
AND gi.courseid = ?
$outcomes_sql
UNION
SELECT gi.id
FROM {grade_items} gi, {grade_categories} gc
WHERE (gi.itemtype = 'category' OR gi.itemtype = 'course') AND gi.iteminstance=gc.id
AND gc.parent = ?
AND gi.courseid = ?
AND $gtypes
$outcomes_sql";
}
Expand Down
193 changes: 186 additions & 7 deletions lib/grade/tests/fixtures/lib.php
Expand Up @@ -167,13 +167,13 @@ private function load_scales() {
* category structure:
course category
|
+--------+-------------+
| |
unittestcategory1 level1category
|
+--------+-------------+
| |
unittestcategory2 unittestcategory3
+--------+-------------+-----------------------+
| | |
unittestcategory1 level1category aggregatesubcatscategory
| |
+--------+-------------+ +------------+---------------+
| | | |
unittestcategory2 unittestcategory3 unittestcategory5 unittestcategory6
*/
private function load_grade_categories() {
global $DB;
Expand Down Expand Up @@ -253,6 +253,61 @@ private function load_grade_categories() {
$grade_category->path = '/'.$course_category->id.'/'.$grade_category->id.'/';
$DB->update_record('grade_categories', $grade_category);
$this->grade_categories[3] = $grade_category;

$grade_category = new stdClass();

$grade_category->fullname = 'aggregatesubcatscategory';
$grade_category->courseid = $this->course->id;
$grade_category->aggregation = GRADE_AGGREGATE_MEAN;
$grade_category->aggregateonlygraded = 1;
$grade_category->aggregatesubcats = 1;
$grade_category->keephigh = 0;
$grade_category->droplow = 0;
$grade_category->parent = $course_category->id;
$grade_category->timecreated = time();
$grade_category->timemodified = time();
$grade_category->depth = 2;

$grade_category->id = $DB->insert_record('grade_categories', $grade_category);
$grade_category->path = '/'.$course_category->id.'/'.$grade_category->id.'/';
$DB->update_record('grade_categories', $grade_category);
$this->grade_categories[4] = $grade_category;

$grade_category = new stdClass();

$grade_category->fullname = 'unittestcategory5';
$grade_category->courseid = $this->course->id;
$grade_category->aggregation = GRADE_AGGREGATE_MEAN;
$grade_category->aggregateonlygraded = 1;
$grade_category->keephigh = 0;
$grade_category->droplow = 0;
$grade_category->parent = $this->grade_categories[4]->id;
$grade_category->timecreated = time();
$grade_category->timemodified = time();
$grade_category->depth = 3;

$grade_category->id = $DB->insert_record('grade_categories', $grade_category);
$grade_category->path = $this->grade_categories[4]->path.$grade_category->id.'/';
$DB->update_record('grade_categories', $grade_category);
$this->grade_categories[5] = $grade_category;

$grade_category = new stdClass();

$grade_category->fullname = 'unittestcategory6';
$grade_category->courseid = $this->course->id;
$grade_category->aggregation = GRADE_AGGREGATE_MEAN;
$grade_category->aggregateonlygraded = 1;
$grade_category->keephigh = 0;
$grade_category->droplow = 0;
$grade_category->parent = $this->grade_categories[4]->id;
$grade_category->timecreated = time();
$grade_category->timemodified = time();
$grade_category->depth = 3;

$grade_category->id = $DB->insert_record('grade_categories', $grade_category);
$grade_category->path = $this->grade_categories[4]->path.$grade_category->id.'/';
$DB->update_record('grade_categories', $grade_category);
$this->grade_categories[6] = $grade_category;
}

/**
Expand Down Expand Up @@ -490,6 +545,7 @@ protected function load_grade_items() {
$grade_item->iteminfo = 'Manual grade item 10 used for unit testing';
$grade_item->timecreated = time();
$grade_item->timemodified = time();
$grade_item->sortorder = 10;

$grade_item->id = $DB->insert_record('grade_items', $grade_item);
$this->grade_items[10] = $grade_item;
Expand All @@ -516,6 +572,107 @@ protected function load_grade_items() {

$grade_item->id = $DB->insert_record('grade_items', $grade_item);
$this->grade_items[11] = $grade_item;

// id = 12
$grade_item = new stdClass();

$grade_item->courseid = $this->course->id;
$grade_item->iteminstance = $this->grade_categories[4]->id;
$grade_item->itemname = 'unittestgradeitemaggregatesubcats';
$grade_item->itemtype = 'category';
$grade_item->gradetype = GRADE_TYPE_VALUE;
$grade_item->needsupdate = true;
$grade_item->grademin = 0;
$grade_item->grademax = 100;
$grade_item->iteminfo = 'Grade item 12 used for unit testing';
$grade_item->timecreated = time();
$grade_item->timemodified = time();
$grade_item->sortorder = 12;

$grade_item->id = $DB->insert_record('grade_items', $grade_item);
$this->grade_items[12] = $grade_item;

// id = 13
$grade_item = new stdClass();

$grade_item->courseid = $this->course->id;
$grade_item->iteminstance = $this->grade_categories[5]->id;
$grade_item->itemname = 'unittestgradeitemcategory5';
$grade_item->itemtype = 'category';
$grade_item->gradetype = GRADE_TYPE_VALUE;
$grade_item->needsupdate = true;
$grade_item->grademin = 0;
$grade_item->grademax = 100;
$grade_item->iteminfo = 'Grade item 13 used for unit testing';
$grade_item->timecreated = time();
$grade_item->timemodified = time();
$grade_item->sortorder = 13;

$grade_item->id = $DB->insert_record('grade_items', $grade_item);
$this->grade_items[13] = $grade_item;

// id = 14
$grade_item = new stdClass();

$grade_item->courseid = $this->course->id;
$grade_item->iteminstance = $this->grade_categories[6]->id;
$grade_item->itemname = 'unittestgradeitemcategory6';
$grade_item->itemtype = 'category';
$grade_item->gradetype = GRADE_TYPE_VALUE;
$grade_item->needsupdate = true;
$grade_item->grademin = 0;
$grade_item->grademax = 100;
$grade_item->iteminfo = 'Grade item 14 used for unit testing';
$grade_item->timecreated = time();
$grade_item->timemodified = time();
$grade_item->sortorder = 14;

$grade_item->id = $DB->insert_record('grade_items', $grade_item);
$this->grade_items[14] = $grade_item;

// Manual grade_item
// id = 15
$grade_item = new stdClass();

$grade_item->courseid = $this->course->id;
$grade_item->categoryid = $this->grade_categories[5]->id;
$grade_item->itemname = 'manual grade_item';
$grade_item->itemtype = 'manual';
$grade_item->itemnumber = 0;
$grade_item->needsupdate = false;
$grade_item->gradetype = GRADE_TYPE_VALUE;
$grade_item->grademin = 0;
$grade_item->grademax = 100;
$grade_item->iteminfo = 'Manual grade item 15 used for unit testing';
$grade_item->timecreated = time();
$grade_item->timemodified = time();
$grade_item->sortorder = 15;

$grade_item->id = $DB->insert_record('grade_items', $grade_item);
$this->grade_items[15] = $grade_item;

// Manual grade_item
// id = 16
$grade_item = new stdClass();

$grade_item->courseid = $this->course->id;
$grade_item->categoryid = $this->grade_categories[6]->id;
$grade_item->itemname = 'manual grade_item';
$grade_item->itemtype = 'manual';
$grade_item->itemnumber = 0;
$grade_item->needsupdate = false;
$grade_item->gradetype = GRADE_TYPE_SCALE;
$grade_item->grademin = 0;
$grade_item->grademax = 100;
$grade_item->iteminfo = 'Manual grade item 16 used for unit testing';
$grade_item->timecreated = time();
$grade_item->timemodified = time();
$grade_item->sortorder = 16;

$grade_item->id = $DB->insert_record('grade_items', $grade_item);
$this->grade_items[16] = $grade_item;

// $this->grade_items[17] loaded in load_grade_outcomes() in order to use an outcome id.
}

/**
Expand Down Expand Up @@ -792,5 +949,27 @@ private function load_grade_outcomes() {

$grade_outcome->id = $DB->insert_record('grade_outcomes', $grade_outcome);
$this->grade_outcomes[] = $grade_outcome;

// Manual grade_item with outcome
// id = 17
$grade_item = new stdClass();

$grade_item->courseid = $this->course->id;
$grade_item->categoryid = $this->grade_categories[6]->id;
$grade_item->itemname = 'manual grade_item';
$grade_item->itemtype = 'manual';
$grade_item->itemnumber = 0;
$grade_item->needsupdate = false;
$grade_item->gradetype = GRADE_TYPE_SCALE;
$grade_item->grademin = 0;
$grade_item->grademax = 100;
$grade_item->iteminfo = 'Manual grade item 16 with outcome used for unit testing';
$grade_item->timecreated = time();
$grade_item->timemodified = time();
$grade_item->outcomeid = $this->grade_outcomes[2]->id;
$grade_item->sortorder = 17;

$grade_item->id = $DB->insert_record('grade_items', $grade_item);
$this->grade_items[17] = $grade_item;
}
}
37 changes: 36 additions & 1 deletion lib/grade/tests/grade_item_test.php
Expand Up @@ -100,7 +100,7 @@ protected function sub_test_grade_item_insert() {
$last_grade_item = end($this->grade_items);

$this->assertEquals($grade_item->id, $last_grade_item->id + 1);
$this->assertEquals(12, $grade_item->sortorder);
$this->assertEquals(18, $grade_item->sortorder);

// Keep our reference collection the same as what is in the database.
$this->grade_items[] = $grade_item;
Expand Down Expand Up @@ -460,6 +460,10 @@ protected function sub_test_grade_item_fetch_course_item() {
}

protected function sub_test_grade_item_depends_on() {
global $CFG;

$origenableoutcomes = $CFG->enableoutcomes;
$CFG->enableoutcomes = 0;
$grade_item = new grade_item($this->grade_items[1], false);

// Calculated grade dependency.
Expand All @@ -480,6 +484,37 @@ protected function sub_test_grade_item_depends_on() {
sort($deps, SORT_NUMERIC); // For comparison.
$res = array($this->grade_items[4]->id, $this->grade_items[5]->id);
$this->assertEquals($res, $deps);

$CFG->enableoutcomes = 1;
$origgradeincludescalesinaggregation = $CFG->grade_includescalesinaggregation;
$CFG->grade_includescalesinaggregation = 1;

// Item in category with aggregate sub categories + $CFG->grade_includescalesinaggregation = 1.
$grade_item = new grade_item($this->grade_items[12], false);
$deps = $grade_item->depends_on();
sort($deps, SORT_NUMERIC);
$res = array($this->grade_items[15]->id, $this->grade_items[16]->id);
$this->assertEquals($res, $deps);

// Item in category with aggregate sub categories + $CFG->grade_includescalesinaggregation = 0.
$CFG->grade_includescalesinaggregation = 0;
$grade_item = new grade_item($this->grade_items[12], false);
$deps = $grade_item->depends_on();
sort($deps, SORT_NUMERIC);
$res = array($this->grade_items[15]->id);
$this->assertEquals($res, $deps);
$CFG->grade_includescalesinaggregation = 1;

// Outcome item in category with with aggregate sub categories.
$CFG->enableoutcomes = 0;
$grade_item = new grade_item($this->grade_items[12], false);
$deps = $grade_item->depends_on();
sort($deps, SORT_NUMERIC);
$res = array($this->grade_items[15]->id, $this->grade_items[16]->id, $this->grade_items[17]->id);
$this->assertEquals($res, $deps);

$CFG->enableoutcomes = $origenableoutcomes;
$CFG->grade_includescalesinaggregation = $origgradeincludescalesinaggregation;
}

protected function sub_test_refresh_grades() {
Expand Down

0 comments on commit 87a26cc

Please sign in to comment.