/** * Sends several key => value pairs to the cache. * * Using this function comes with potential performance implications. * Not all cache stores will support get_many/set_many operations and in order to replicate this functionality will call * the equivalent singular method for each item provided. * This should not deter you from using this function as there is a performance benefit in situations where the cache store * does support it, but you should be aware of this fact. * * <code> * // This code will add four entries to the cache, one for each url. * $cache->set_many(array( * 'main' => 'http://moodle.org', * 'docs' => 'http://docs.moodle.org', * 'tracker' => 'http://tracker.moodle.org', * 'qa' => ''http://qa.moodle.net' * )); * </code> * * @param array $keyvaluearray An array of key => value pairs to send to the cache. * @return int The number of items successfully set. It is up to the developer to check this matches the number of items. * ... if they care that is. */ public function set_many(array $keyvaluearray) { if ($this->loader !== false) { // We have a loader available set it there as well. // We have to let the loader do its own parsing of data as it may be unique. $this->loader->set_many($keyvaluearray); } $data = array(); $simulatettl = $this->has_a_ttl() && !$this->store_supports_native_ttl(); $usestaticaccelerationarray = $this->use_static_acceleration(); foreach ($keyvaluearray as $key => $value) { if (is_object($value) && $value instanceof cacheable_object) { $value = new cache_cached_object($value); } else { if (!is_scalar($value)) { // If data is an object it will be a reference. // If data is an array if may contain references. // We want to break references so that the cache cannot be modified outside of itself. // Call the function to unreference it (in the best way possible). $value = $this->unref($value); } } if ($simulatettl) { $value = new cache_ttl_wrapper($value, $this->definition->get_ttl()); } $data[$key] = array('key' => $this->parse_key($key), 'value' => $value); if ($usestaticaccelerationarray) { $this->static_acceleration_set($data[$key]['key'], $value); } } if ($this->perfdebug) { cache_helper::record_cache_set($this->storetype, $this->definition->get_id()); } return $this->store->set_many($data); }
/** * Runs a standard series of access and use tests on a cache instance. * * This function is great because we can use it to ensure all of the loaders perform exactly the same way. * * @param cache_loader $cache */ protected function run_on_cache(cache_loader $cache) { $key = 'testkey'; $datascalar = 'test data'; $dataarray = array('test' => 'data', 'part' => 'two'); $dataobject = (object) $dataarray; $this->assertTrue($cache->purge()); // Check all read methods. $this->assertFalse($cache->get($key)); $this->assertFalse($cache->has($key)); $result = $cache->get_many(array($key)); $this->assertCount(1, $result); $this->assertFalse(reset($result)); $this->assertFalse($cache->has_any(array($key))); $this->assertFalse($cache->has_all(array($key))); // Set the data. $this->assertTrue($cache->set($key, $datascalar)); // Setting it more than once should be permitted. $this->assertTrue($cache->set($key, $datascalar)); // Recheck the read methods. $this->assertEquals($datascalar, $cache->get($key)); $this->assertTrue($cache->has($key)); $result = $cache->get_many(array($key)); $this->assertCount(1, $result); $this->assertEquals($datascalar, reset($result)); $this->assertTrue($cache->has_any(array($key))); $this->assertTrue($cache->has_all(array($key))); // Delete it. $this->assertTrue($cache->delete($key)); // Check its gone. $this->assertFalse($cache->get($key)); $this->assertFalse($cache->has($key)); // Test arrays. $this->assertTrue($cache->set($key, $dataarray)); $this->assertEquals($dataarray, $cache->get($key)); // Test objects. $this->assertTrue($cache->set($key, $dataobject)); $this->assertEquals($dataobject, $cache->get($key)); $specobject = new cache_phpunit_dummy_object('red', 'blue'); $this->assertTrue($cache->set($key, $specobject)); $result = $cache->get($key); $this->assertInstanceOf('cache_phpunit_dummy_object', $result); $this->assertEquals('red_ptc_wfc', $result->property1); $this->assertEquals('blue_ptc_wfc', $result->property2); // Test set many. $cache->set_many(array('key1' => 'data1', 'key2' => 'data2')); $this->assertEquals('data1', $cache->get('key1')); $this->assertEquals('data2', $cache->get('key2')); $this->assertTrue($cache->delete('key1')); $this->assertTrue($cache->delete('key2')); // Test delete many. $this->assertTrue($cache->set('key1', 'data1')); $this->assertTrue($cache->set('key2', 'data2')); $this->assertEquals('data1', $cache->get('key1')); $this->assertEquals('data2', $cache->get('key2')); $this->assertEquals(2, $cache->delete_many(array('key1', 'key2'))); $this->assertFalse($cache->get('key1')); $this->assertFalse($cache->get('key2')); // Quick reference test. $obj = new stdClass(); $obj->key = 'value'; $ref =& $obj; $this->assertTrue($cache->set('obj', $obj)); $obj->key = 'eulav'; $var = $cache->get('obj'); $this->assertInstanceOf('stdClass', $var); $this->assertEquals('value', $var->key); $ref->key = 'eulav'; $var = $cache->get('obj'); $this->assertInstanceOf('stdClass', $var); $this->assertEquals('value', $var->key); $this->assertTrue($cache->delete('obj')); // Deep reference test. $obj1 = new stdClass(); $obj1->key = 'value'; $obj2 = new stdClass(); $obj2->key = 'test'; $obj3 = new stdClass(); $obj3->key = 'pork'; $obj1->subobj =& $obj2; $obj2->subobj =& $obj3; $this->assertTrue($cache->set('obj', $obj1)); $obj1->key = 'eulav'; $obj2->key = 'tset'; $obj3->key = 'krop'; $var = $cache->get('obj'); $this->assertInstanceOf('stdClass', $var); $this->assertEquals('value', $var->key); $this->assertInstanceOf('stdClass', $var->subobj); $this->assertEquals('test', $var->subobj->key); $this->assertInstanceOf('stdClass', $var->subobj->subobj); $this->assertEquals('pork', $var->subobj->subobj->key); $this->assertTrue($cache->delete('obj')); // Death reference test... basicaly we don't want this to die. $obj = new stdClass(); $obj->key = 'value'; $obj->self =& $obj; $this->assertTrue($cache->set('obj', $obj)); $var = $cache->get('obj'); $this->assertInstanceOf('stdClass', $var); $this->assertEquals('value', $var->key); // Reference test after retrieve. $obj = new stdClass(); $obj->key = 'value'; $this->assertTrue($cache->set('obj', $obj)); $var1 = $cache->get('obj'); $this->assertInstanceOf('stdClass', $var1); $this->assertEquals('value', $var1->key); $var1->key = 'eulav'; $this->assertEquals('eulav', $var1->key); $var2 = $cache->get('obj'); $this->assertInstanceOf('stdClass', $var2); $this->assertEquals('value', $var2->key); $this->assertTrue($cache->delete('obj')); }
/** * Runs a standard series of access and use tests on a cache instance. * * This function is great because we can use it to ensure all of the loaders perform exactly the same way. * * @param cache_loader $cache */ protected function run_on_cache(cache_loader $cache) { $key = 'contestkey'; $datascalars = array('test data', null); $dataarray = array('contest' => 'data', 'part' => 'two'); $dataobject = (object) $dataarray; foreach ($datascalars as $datascalar) { $this->assertTrue($cache->purge()); // Check all read methods. $this->assertFalse($cache->get($key)); $this->assertFalse($cache->has($key)); $result = $cache->get_many(array($key)); $this->assertCount(1, $result); $this->assertFalse(reset($result)); $this->assertFalse($cache->has_any(array($key))); $this->assertFalse($cache->has_all(array($key))); // Set the data. $this->assertTrue($cache->set($key, $datascalar)); // Setting it more than once should be permitted. $this->assertTrue($cache->set($key, $datascalar)); // Recheck the read methods. $this->assertEquals($datascalar, $cache->get($key)); $this->assertTrue($cache->has($key)); $result = $cache->get_many(array($key)); $this->assertCount(1, $result); $this->assertEquals($datascalar, reset($result)); $this->assertTrue($cache->has_any(array($key))); $this->assertTrue($cache->has_all(array($key))); // Delete it. $this->assertTrue($cache->delete($key)); // Check its gone. $this->assertFalse($cache->get($key)); $this->assertFalse($cache->has($key)); } // Test arrays. $this->assertTrue($cache->set($key, $dataarray)); $this->assertEquals($dataarray, $cache->get($key)); // Test objects. $this->assertTrue($cache->set($key, $dataobject)); $this->assertEquals($dataobject, $cache->get($key)); $specobject = new cache_phpunit_dummy_object('red', 'blue'); $this->assertTrue($cache->set($key, $specobject)); $result = $cache->get($key); $this->assertInstanceOf('cache_phpunit_dummy_object', $result); $this->assertEquals('red_ptc_wfc', $result->property1); $this->assertEquals('blue_ptc_wfc', $result->property2); // Test array of objects. $specobject = new cache_phpunit_dummy_object('red', 'blue'); $data = new cacheable_object_array(array(clone $specobject, clone $specobject, clone $specobject)); $this->assertTrue($cache->set($key, $data)); $result = $cache->get($key); $this->assertInstanceOf('cacheable_object_array', $result); $this->assertCount(3, $data); foreach ($result as $item) { $this->assertInstanceOf('cache_phpunit_dummy_object', $item); $this->assertEquals('red_ptc_wfc', $item->property1); $this->assertEquals('blue_ptc_wfc', $item->property2); } // Test set many. $cache->set_many(array('key1' => 'data1', 'key2' => 'data2', 'key3' => null)); $this->assertEquals('data1', $cache->get('key1')); $this->assertEquals('data2', $cache->get('key2')); $this->assertEquals(null, $cache->get('key3')); $this->assertTrue($cache->delete('key1')); $this->assertTrue($cache->delete('key2')); $this->assertTrue($cache->delete('key3')); $cache->set_many(array('key1' => array(1, 2, 3), 'key2' => array(3, 2, 1))); $this->assertInternalType('array', $cache->get('key1')); $this->assertInternalType('array', $cache->get('key2')); $this->assertCount(3, $cache->get('key1')); $this->assertCount(3, $cache->get('key2')); $this->assertInternalType('array', $cache->get_many(array('key1', 'key2'))); $this->assertCount(2, $cache->get_many(array('key1', 'key2'))); $this->assertEquals(2, $cache->delete_many(array('key1', 'key2'))); // Test delete many. $this->assertTrue($cache->set('key1', 'data1')); $this->assertTrue($cache->set('key2', 'data2')); $this->assertTrue($cache->set('key3', null)); $this->assertEquals('data1', $cache->get('key1')); $this->assertEquals('data2', $cache->get('key2')); $this->assertEquals(null, $cache->get('key3')); $this->assertEquals(3, $cache->delete_many(array('key1', 'key2', 'key3'))); $this->assertFalse($cache->get('key1')); $this->assertFalse($cache->get('key2')); $this->assertFalse($cache->get('key3')); // Quick reference test. $obj = new stdClass(); $obj->key = 'value'; $ref =& $obj; $this->assertTrue($cache->set('obj', $obj)); $obj->key = 'eulav'; $var = $cache->get('obj'); $this->assertInstanceOf('stdClass', $var); $this->assertEquals('value', $var->key); $ref->key = 'eulav'; $var = $cache->get('obj'); $this->assertInstanceOf('stdClass', $var); $this->assertEquals('value', $var->key); $this->assertTrue($cache->delete('obj')); // Deep reference test. $obj1 = new stdClass(); $obj1->key = 'value'; $obj2 = new stdClass(); $obj2->key = 'test'; $obj3 = new stdClass(); $obj3->key = 'pork'; $obj1->subobj =& $obj2; $obj2->subobj =& $obj3; $this->assertTrue($cache->set('obj', $obj1)); $obj1->key = 'eulav'; $obj2->key = 'tset'; $obj3->key = 'krop'; $var = $cache->get('obj'); $this->assertInstanceOf('stdClass', $var); $this->assertEquals('value', $var->key); $this->assertInstanceOf('stdClass', $var->subobj); $this->assertEquals('test', $var->subobj->key); $this->assertInstanceOf('stdClass', $var->subobj->subobj); $this->assertEquals('pork', $var->subobj->subobj->key); $this->assertTrue($cache->delete('obj')); // Death reference test... basicaly we don't want this to die. $obj = new stdClass(); $obj->key = 'value'; $obj->self =& $obj; $this->assertTrue($cache->set('obj', $obj)); $var = $cache->get('obj'); $this->assertInstanceOf('stdClass', $var); $this->assertEquals('value', $var->key); // Reference test after retrieve. $obj = new stdClass(); $obj->key = 'value'; $this->assertTrue($cache->set('obj', $obj)); $var1 = $cache->get('obj'); $this->assertInstanceOf('stdClass', $var1); $this->assertEquals('value', $var1->key); $var1->key = 'eulav'; $this->assertEquals('eulav', $var1->key); $var2 = $cache->get('obj'); $this->assertInstanceOf('stdClass', $var2); $this->assertEquals('value', $var2->key); $this->assertTrue($cache->delete('obj')); // Test strictness exceptions. try { $cache->get('exception', MUST_EXIST); $this->fail('Exception expected from cache::get using MUST_EXIST'); } catch (Exception $e) { $this->assertTrue(true); } try { $cache->get_many(array('exception1', 'exception2'), MUST_EXIST); $this->fail('Exception expected from cache::get_many using MUST_EXIST'); } catch (Exception $e) { $this->assertTrue(true); } $cache->set('test', 'test'); try { $cache->get_many(array('test', 'exception'), MUST_EXIST); $this->fail('Exception expected from cache::get_many using MUST_EXIST'); } catch (Exception $e) { $this->assertTrue(true); } }