Skip to content

Commit

Permalink
MDL-54592 cachestore_mongodb: MongoDB cache store use new driver.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
vmdef committed Mar 15, 2019
1 parent b3c0e79 commit 2a944b5
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 76 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -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.*
Expand Down
1 change: 1 addition & 0 deletions .stylelintignore
Original file line number Diff line number Diff line change
Expand Up @@ -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.*
Expand Down
14 changes: 14 additions & 0 deletions cache/stores/mongodb/MongoDB/readme_moodle.txt
Original file line number Diff line number Diff line change
@@ -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.

2 changes: 1 addition & 1 deletion cache/stores/mongodb/addinstanceform.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ protected function configuration_definition() {
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')));
}

Expand Down
129 changes: 54 additions & 75 deletions cache/stores/mongodb/lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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.
*
Expand Down Expand Up @@ -148,16 +142,11 @@ public function __construct($name, array $configuration = array()) {
$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.
}
}

Expand All @@ -166,7 +155,7 @@ public function __construct($name, array $configuration = array()) {
* @return bool
*/
public static function are_requirements_met() {
return class_exists('MongoClient') || class_exists('Mongo');
return version_compare(phpversion('mongodb'), '1.5', 'ge');
}

/**
Expand Down Expand Up @@ -203,25 +192,26 @@ public function initialise(cache_definition $definition) {
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);
}

/**
* Returns true if this store instance has been initialised.
* @return bool
*/
public function is_initialised() {
return ($this->database instanceof MongoDB);
return ($this->database instanceof MongoDB\Database);
}

/**
Expand Down Expand Up @@ -319,24 +309,20 @@ public function set($key, $data) {
}
$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'])) {
return false;
}
return true;
try {
$this->collection->insertOne($record, $options);
} catch (MongoDB\Exception\Exception $e) {
return false;
}
// Who knows?
return false;

return true;
}

/**
Expand Down Expand Up @@ -373,27 +359,23 @@ public function delete($key) {
$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.
return false;
}
return true;

$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;
}

if (empty($result->getDeletedCount())) {
return false;
}
// Who knows?
return false;

return true;
}

/**
Expand Down Expand Up @@ -502,16 +484,14 @@ public function instance_deleted() {
$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;
Expand Down Expand Up @@ -564,7 +544,6 @@ public static function initialise_test_instance(cache_definition $definition) {
return $store;
}


/**
* Generates an instance of the cache store that can be used for testing.
*
Expand All @@ -577,7 +556,7 @@ public static function unit_test_configuration() {

// 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;
Expand Down
10 changes: 10 additions & 0 deletions cache/stores/mongodb/thirdpartylibs.xml
Original file line number Diff line number Diff line change
@@ -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 changes: 5 additions & 0 deletions cache/upgrade.txt
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
1 change: 1 addition & 0 deletions lib/classes/component.php
Original file line number Diff line number Diff line change
Expand Up @@ -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',
);

/**
Expand Down

0 comments on commit 2a944b5

Please sign in to comment.