From 695f6f3c232c2a01c16a978b57be20c6fb8afbf7 Mon Sep 17 00:00:00 2001 From: sam marshall Date: Fri, 17 May 2013 16:43:51 +0100 Subject: [PATCH] MDL-39723 Remove unnecessary queries for COURSE, SITE --- course/format/lib.php | 2 +- lib/datalib.php | 24 ++++++++++++++++++++++++ lib/tests/datalib_test.php | 26 ++++++++++++++++++++++++++ lib/upgrade.txt | 5 +++++ 4 files changed, 56 insertions(+), 1 deletion(-) diff --git a/course/format/lib.php b/course/format/lib.php index a12f1878f98..5723eff8668 100644 --- a/course/format/lib.php +++ b/course/format/lib.php @@ -235,7 +235,7 @@ abstract class format_base { return null; } if ($this->course === false) { - $this->course = $DB->get_record('course', array('id' => $this->courseid)); + $this->course = get_course($this->courseid); $options = $this->get_format_options(); foreach ($options as $optionname => $optionvalue) { if (!isset($this->course->$optionname)) { diff --git a/lib/datalib.php b/lib/datalib.php index 7db9ebac5e5..3f918e8f284 100644 --- a/lib/datalib.php +++ b/lib/datalib.php @@ -556,6 +556,30 @@ function get_site() { } } +/** + * Gets a course object from database. If the course id corresponds to an + * already-loaded $COURSE or $SITE object, then the loaded object will be used, + * saving a database query. + * + * If it reuses an existing object, by default the object will be cloned. This + * means you can modify the object safely without affecting other code. + * + * @param int $courseid Course id + * @param bool $clone If true (default), makes a clone of the record + * @return stdClass A course object + * @throws dml_exception If not found in database + */ +function get_course($courseid, $clone = true) { + global $DB, $COURSE, $SITE; + if (!empty($COURSE->id) && $COURSE->id == $courseid) { + return $clone ? clone($COURSE) : $COURSE; + } else if (!empty($SITE->id) && $SITE->id == $courseid) { + return $clone ? clone($SITE) : $SITE; + } else { + return $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST); + } +} + /** * Returns list of courses, for whole site, or category * diff --git a/lib/tests/datalib_test.php b/lib/tests/datalib_test.php index cce2090f444..8a97db4acd0 100644 --- a/lib/tests/datalib_test.php +++ b/lib/tests/datalib_test.php @@ -267,4 +267,30 @@ class datalib_testcase extends advanced_testcase { get_admins(); // This should make just one query. $this->assertEquals($odlread+1, $DB->perf_get_reads()); } + + public function test_get_course() { + global $DB, $PAGE, $SITE; + + $this->resetAfterTest(true); + + // First test course will be current course ($COURSE). + $course1obj = $this->getDataGenerator()->create_course(array('shortname' => 'FROGS')); + $PAGE->set_course($course1obj); + + // Second test course is not current course. + $course2obj = $this->getDataGenerator()->create_course(array('shortname' => 'ZOMBIES')); + + // Check it does not make any queries when requesting the $COURSE/$SITE + $before = $DB->perf_get_queries(); + $result = get_course($course1obj->id); + $this->assertEquals($before, $DB->perf_get_queries()); + $this->assertEquals('FROGS', $result->shortname); + $result = get_course($SITE->id); + $this->assertEquals($before, $DB->perf_get_queries()); + + // Check it makes 1 query to request other courses. + $result = get_course($course2obj->id); + $this->assertEquals('ZOMBIES', $result->shortname); + $this->assertEquals($before + 1, $DB->perf_get_queries()); + } } diff --git a/lib/upgrade.txt b/lib/upgrade.txt index b9999554ef6..e33f0c83548 100644 --- a/lib/upgrade.txt +++ b/lib/upgrade.txt @@ -1,6 +1,11 @@ This files describes API changes in core libraries and APIs, information provided here is intended especially for developers. +=== 2.5.1 === + +* New get_course() function for use when obtaining the course record from database. Will + reuse existing $COURSE or $SITE globals if possible to improve performance. + === 2.5 === * The database drivers (moodle_database and subclasses) aren't using anymore the ::columns property