MDL-54592 cachestore_mongodb: MongoDB cache store use new driver.

The scope of this change is limited to modifying the MongoDB cache
plugin to use the new version of the driver that accepts PHP 7.x
versions. Following the instructions in the official MongoDB
documentation, https://docs.mongodb.com/php-library/current/, the
MongoDB PHP Library was included and used.
This commit is contained in:
Víctor Déniz Falcón 2019-03-14 11:14:31 +00:00
parent b3c0e79678
commit 2a944b5b41
8 changed files with 86 additions and 75 deletions

View File

@ -6,6 +6,7 @@ vendor/
admin/tool/policy/amd/src/jquery-eu-cookie-law-popup.js
admin/tool/usertours/amd/src/tour.js
auth/cas/CAS/
cache/stores/mongodb/MongoDB/
enrol/lti/ims-blti/
filter/algebra/AlgParser.pm
filter/tex/mimetex.*

View File

@ -9,6 +9,7 @@ vendor/
admin/tool/policy/amd/src/jquery-eu-cookie-law-popup.js
admin/tool/usertours/amd/src/tour.js
auth/cas/CAS/
cache/stores/mongodb/MongoDB/
enrol/lti/ims-blti/
filter/algebra/AlgParser.pm
filter/tex/mimetex.*

View File

@ -0,0 +1,14 @@
MongoDB PHP
-----------
Downloaded from https://github.com/mongodb/mongo-php-library
Last commit on download: aac8e54009196f6544e50baf9b63dcf0eab3bbdf
This version (1.4) requires PHP mongodb extension >= 1.5
Import procedure:
- Copy all the files and folders from the folder mongodb/src in this directory.
- Copy the license file from the project root.

View File

@ -51,7 +51,7 @@ class cachestore_mongodb_addinstance_form extends cachestore_addinstance_form {
global $OUTPUT;
$form = $this->_form;
if (!class_exists('MongoClient')) {
if (!version_compare(phpversion('mongodb'), '1.5', 'ge')) {
$form->addElement('html', $OUTPUT->notification(get_string('pleaseupgrademongo', 'cachestore_mongodb')));
}

View File

@ -26,13 +26,15 @@
defined('MOODLE_INTERNAL') || die();
require_once('MongoDB/functions.php');
/**
* The MongoDB Cache store.
*
* This cache store uses the MongoDB Native Driver.
* This cache store uses the MongoDB Native Driver and the MongoDB PHP Library.
* For installation instructions have a look at the following two links:
* - {@link http://www.php.net/manual/en/mongo.installation.php}
* - {@link http://www.mongodb.org/display/DOCS/PHP+Language+Center}
* - {@link http://php.net/manual/en/set.mongodb.php}
* - {@link https://docs.mongodb.com/ecosystem/drivers/php/}
*
* @copyright 2012 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
@ -65,19 +67,19 @@ class cachestore_mongodb extends cache_store implements cache_is_configurable {
/**
* The Connection object
* @var Mongo
* @var MongoDB/Client
*/
protected $connection = false;
/**
* The Database Object
* @var MongoDB
* @var MongoDB/Database
*/
protected $database;
/**
* The Collection object
* @var MongoCollection
* @var MongoDB/Collection
*/
protected $collection;
@ -105,14 +107,6 @@ class cachestore_mongodb extends cache_store implements cache_is_configurable {
*/
protected $isready = false;
/**
* Set to true if the Mongo extension is < version 1.3.
* If this is the case we must use the legacy Mongo class instead of MongoClient.
* Mongo is backwards compatible, although obviously deprecated.
* @var bool
*/
protected $legacymongo = false;
/**
* Constructs a new instance of the Mongo store.
*
@ -148,16 +142,11 @@ class cachestore_mongodb extends cache_store implements cache_is_configurable {
$this->extendedmode = $configuration['extendedmode'];
}
// Test if the MongoClient class exists, if not we need to switch to legacy classes.
$this->legacymongo = (!class_exists('MongoClient'));
// MongoClient from Mongo 1.3 onwards. Mongo for earlier versions.
$class = ($this->legacymongo) ? 'Mongo' : 'MongoClient';
try {
$this->connection = new $class($this->server, $this->options);
$this->connection = new MongoDB\Client($this->server, $this->options);
$this->isready = true;
} catch (MongoConnectionException $e) {
// We only want to catch MongoConnectionExceptions here.
} catch (MongoDB\Driver\Exception\RuntimeException $e) {
// We only want to catch RuntimeException here.
}
}
@ -166,7 +155,7 @@ class cachestore_mongodb extends cache_store implements cache_is_configurable {
* @return bool
*/
public static function are_requirements_met() {
return class_exists('MongoClient') || class_exists('Mongo');
return version_compare(phpversion('mongodb'), '1.5', 'ge');
}
/**
@ -203,17 +192,18 @@ class cachestore_mongodb extends cache_store implements cache_is_configurable {
if ($this->is_initialised()) {
throw new coding_exception('This mongodb instance has already been initialised.');
}
$this->database = $this->connection->selectDB($this->databasename);
$this->database = $this->connection->selectDatabase($this->databasename);
$this->definitionhash = 'm'.$definition->generate_definition_hash();
$this->collection = $this->database->selectCollection($this->definitionhash);
$options = array('name' => 'idx_key');
if ($this->legacymongo) {
$options['safe'] = $this->usesafe;
} else {
$options['w'] = $this->usesafe ? 1 : 0;
}
$this->collection->ensureIndex(array('key' => 1), $options);
$w = $this->usesafe ? 1 : 0;
$wc = new MongoDB\Driver\WriteConcern($w);
$options['writeConcern'] = $wc;
$this->collection->createIndex(array('key' => 1), $options);
}
/**
@ -221,7 +211,7 @@ class cachestore_mongodb extends cache_store implements cache_is_configurable {
* @return bool
*/
public function is_initialised() {
return ($this->database instanceof MongoDB);
return ($this->database instanceof MongoDB\Database);
}
/**
@ -319,25 +309,21 @@ class cachestore_mongodb extends cache_store implements cache_is_configurable {
}
$record['data'] = serialize($data);
$options = array('upsert' => true);
if ($this->legacymongo) {
$options['safe'] = $this->usesafe;
} else {
$options['w'] = $this->usesafe ? 1 : 0;
}
$w = $this->usesafe ? 1 : 0;
$wc = new MongoDB\Driver\WriteConcern($w);
$options['writeConcern'] = $wc;
$this->delete($key);
$result = $this->collection->insert($record, $options);
if ($result === true) {
// Safe mode is off.
return true;
} else if (is_array($result)) {
if (empty($result['ok']) || isset($result['err'])) {
try {
$this->collection->insertOne($record, $options);
} catch (MongoDB\Exception\Exception $e) {
return false;
}
return true;
}
// Who knows?
return false;
}
/**
* Sets many items in the cache in a single transaction.
@ -373,29 +359,25 @@ class cachestore_mongodb extends cache_store implements cache_is_configurable {
$criteria = $key;
}
$options = array('justOne' => false);
if ($this->legacymongo) {
$options['safe'] = $this->usesafe;
} else {
$options['w'] = $this->usesafe ? 1 : 0;
}
$result = $this->collection->remove($criteria, $options);
if ($result === true) {
// Safe mode.
return true;
} else if (is_array($result)) {
if (empty($result['ok']) || isset($result['err'])) {
return false;
} else if (empty($result['n'])) {
// Nothing was removed.
$w = $this->usesafe ? 1 : 0;
$wc = new MongoDB\Driver\WriteConcern($w);
$options['writeConcern'] = $wc;
try {
$result = $this->collection->deleteOne($criteria, $options);
} catch (\MongoDB\Exception $e) {
return false;
}
return true;
}
// Who knows?
if (empty($result->getDeletedCount())) {
return false;
}
return true;
}
/**
* Deletes several keys from the cache in a single action.
*
@ -502,16 +484,14 @@ class cachestore_mongodb extends cache_store implements cache_is_configurable {
$connection = $this->connection;
} else {
try {
// MongoClient from Mongo 1.3 onwards. Mongo for earlier versions.
$class = ($this->legacymongo) ? 'Mongo' : 'MongoClient';
$connection = new $class($this->server, $this->options);
} catch (MongoConnectionException $e) {
// We only want to catch MongoConnectionExceptions here.
$connection = new MongoDB\Client($this->server, $this->options);
} catch (MongoDB\Driver\Exception\RuntimeException $e) {
// We only want to catch RuntimeException here.
// If the server cannot be connected to we cannot clean it.
return;
}
}
$database = $connection->selectDB($this->databasename);
$database = $connection->selectDatabase($this->databasename);
$database->drop();
$connection = null;
$database = null;
@ -564,7 +544,6 @@ class cachestore_mongodb extends cache_store implements cache_is_configurable {
return $store;
}
/**
* Generates an instance of the cache store that can be used for testing.
*
@ -577,7 +556,7 @@ class cachestore_mongodb extends cache_store implements cache_is_configurable {
// If the configuration is not defined correctly, return only the configuration know about.
if (defined('TEST_CACHESTORE_MONGODB_TESTSERVER')) {
$configuration['servers'] = explode("\n", TEST_CACHESTORE_MONGODB_TESTSERVER);
$configuration['server'] = TEST_CACHESTORE_MONGODB_TESTSERVER;
}
return $configuration;

10
cache/stores/mongodb/thirdpartylibs.xml vendored Normal file
View File

@ -0,0 +1,10 @@
<?xml version="1.0"?>
<libraries>
<library>
<location>MongoDB</location>
<name>MongoDB PHP Library</name>
<license>Apache</license>
<version>1.4</version>
<licenseversion>2.0</licenseversion>
</library>
</libraries>

5
cache/upgrade.txt vendored
View File

@ -1,6 +1,11 @@
This files describes API changes in /cache/stores/* - cache store plugins.
Information provided here is intended especially for developers.
=== 3.7 ===
* Upgraded MongoDB cache store to use the new lower level PHP-driver and MongoDB PHP Library.
* The mongodb extension has replaced the old mongo extension. The mongodb pecl extension >= 1.5 must be installed to use MongoDB
cache store.
=== 3.6 ===
* The `cache::now()` function now takes an optional boolean parameter to indicate that the cache should return a more
accurate time, generated by the PHP `microtime` function.

View File

@ -86,6 +86,7 @@ class core_component {
'Phpml' => 'lib/mlbackend/php/phpml/src/Phpml',
'PHPMailer\\PHPMailer' => 'lib/phpmailer/src',
'RedeyeVentures\\GeoPattern' => 'lib/geopattern-php/GeoPattern',
'MongoDB' => 'cache/stores/mongodb/MongoDB',
);
/**