MDL-41436 implement new increment_revision_number() function
This is intended as a revision counter for local modinfo caching. It should be a lot more reliable and faster than doing it in PHP. Please note you need to invalidate all course caches after using this.
This commit is contained in:
committed by
Marina Glancy
parent
44ddd2a115
commit
d82993dc7f
@@ -1232,6 +1232,36 @@ function update_timezone_records($timezones) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment standard revision field.
|
||||
*
|
||||
* The revision are based on current time and are incrementing.
|
||||
* There is a protection for runaway revisions, it may not go further than
|
||||
* one hour into future.
|
||||
*
|
||||
* The field has to be XMLDB_TYPE_INTEGER with size 10.
|
||||
*
|
||||
* @param string $table
|
||||
* @param string $field name of the field containing revision
|
||||
* @param string $select use empty string when updating all records
|
||||
* @param array $params optional select parameters
|
||||
*/
|
||||
function increment_revision_number($table, $field, $select, array $params = null) {
|
||||
global $DB;
|
||||
|
||||
$now = time();
|
||||
$sql = "UPDATE {{$table}}
|
||||
SET $field = (CASE
|
||||
WHEN $field IS NULL THEN $now
|
||||
WHEN $field < $now THEN $now
|
||||
WHEN $field > $now + 3600 THEN $now
|
||||
ELSE $field + 1 END)";
|
||||
if ($select) {
|
||||
$sql = $sql . " WHERE $select";
|
||||
}
|
||||
$DB->execute($sql, $params);
|
||||
}
|
||||
|
||||
|
||||
/// MODULE FUNCTIONS /////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -289,4 +289,58 @@ class core_datalib_testcase extends advanced_testcase {
|
||||
$this->assertSame('ZOMBIES', $result->shortname);
|
||||
$this->assertEquals($before + 1, $DB->perf_get_queries());
|
||||
}
|
||||
|
||||
public function test_increment_revision_number() {
|
||||
global $DB;
|
||||
$this->resetAfterTest();
|
||||
|
||||
// Let's abuse course.timemodified column for now.
|
||||
$course1 = $this->getDataGenerator()->create_course();
|
||||
$course2 = $this->getDataGenerator()->create_course();
|
||||
$DB->set_field('course', 'timemodified', 1, array());
|
||||
|
||||
$record1 = $DB->get_record('course', array('id'=>$course1->id));
|
||||
$record2 = $DB->get_record('course', array('id'=>$course2->id));
|
||||
$this->assertEquals(1, $record1->timemodified);
|
||||
$this->assertEquals(1, $record2->timemodified);
|
||||
|
||||
// Incrementing some lower value.
|
||||
$now = time();
|
||||
increment_revision_number('course', 'timemodified', 'id = :id', array('id'=>$course1->id));
|
||||
$record1 = $DB->get_record('course', array('id'=>$course1->id));
|
||||
$record2 = $DB->get_record('course', array('id'=>$course2->id));
|
||||
$this->assertGreaterThanOrEqual($now, $record1->timemodified);
|
||||
$this->assertLessThanOrEqual($now+1, $record1->timemodified);
|
||||
$this->assertEquals(1, $record2->timemodified);
|
||||
|
||||
// Incrementing in the same second.
|
||||
$rev1 = $DB->get_field('course', 'timemodified', array('id'=>$course1->id));
|
||||
$now = time();
|
||||
increment_revision_number('course', 'timemodified', 'id = :id', array('id'=>$course1->id));
|
||||
$this->assertGreaterThan($rev1, $rev1 = $DB->get_field('course', 'timemodified', array('id'=>$course1->id)));
|
||||
increment_revision_number('course', 'timemodified', 'id = :id', array('id'=>$course1->id));
|
||||
$this->assertGreaterThan($rev1, $rev1 = $DB->get_field('course', 'timemodified', array('id'=>$course1->id)));
|
||||
increment_revision_number('course', 'timemodified', 'id = :id', array('id'=>$course1->id));
|
||||
$this->assertGreaterThan($rev1, $rev1 = $DB->get_field('course', 'timemodified', array('id'=>$course1->id)));
|
||||
$this->assertGreaterThan($now+2, $rev1);
|
||||
|
||||
// Recovering from runaway revision.
|
||||
$DB->set_field('course', 'timemodified', time()+60*60*60, array('id'=>$course2->id));
|
||||
$record2 = $DB->get_record('course', array('id'=>$course2->id));
|
||||
$this->assertGreaterThan(time(), $record2->timemodified);
|
||||
increment_revision_number('course', 'timemodified', 'id = :id', array('id'=>$course2->id));
|
||||
$record2b = $DB->get_record('course', array('id'=>$course2->id));
|
||||
$this->assertLessThan($record2->timemodified, $record2b->timemodified);
|
||||
$this->assertGreaterThanOrEqual(time(), $record2b->timemodified);
|
||||
|
||||
// Update all revisions.
|
||||
$now = time();
|
||||
$DB->set_field('course', 'timemodified', 1, array());
|
||||
increment_revision_number('course', 'timemodified', '');
|
||||
$record1 = $DB->get_record('course', array('id'=>$course1->id));
|
||||
$record2 = $DB->get_record('course', array('id'=>$course2->id));
|
||||
$this->assertGreaterThanOrEqual($now, $record1->timemodified);
|
||||
$this->assertLessThanOrEqual($now+1, $record1->timemodified);
|
||||
$this->assertEquals($record1->timemodified, $record2->timemodified);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user