#456488 by yched: Only cache field data for current revision.
parent
538cfe9150
commit
e9c3a69612
|
@ -332,23 +332,31 @@ function _field_attach_form($obj_type, $object, &$form, $form_state) {
|
||||||
* set as an empty array.
|
* set as an empty array.
|
||||||
*/
|
*/
|
||||||
function _field_attach_load($obj_type, $objects, $age = FIELD_LOAD_CURRENT) {
|
function _field_attach_load($obj_type, $objects, $age = FIELD_LOAD_CURRENT) {
|
||||||
$queried_objects = array();
|
$load_current = $age == FIELD_LOAD_CURRENT;
|
||||||
|
|
||||||
$info = field_info_fieldable_types($obj_type);
|
$info = field_info_fieldable_types($obj_type);
|
||||||
$cacheable = isset($info['cacheable']) ? $info['cacheable'] : FALSE;
|
$cacheable = $load_current && $info['cacheable'];
|
||||||
|
|
||||||
|
$queried_objects = array();
|
||||||
|
|
||||||
// Fetch avaliable objects from cache.
|
// Fetch avaliable objects from cache.
|
||||||
foreach ($objects as $object) {
|
if ($cacheable) {
|
||||||
list($id, $vid, $bundle) = field_attach_extract_ids($obj_type, $object);
|
foreach ($objects as $id => $object) {
|
||||||
if ($cacheable && $cached = cache_get("field:$obj_type:$id:$vid", 'cache_field')) {
|
$cid = "field:$obj_type:$id";
|
||||||
foreach ($cached->data as $field_name => $items) {
|
if ($cached = cache_get($cid, 'cache_field')) {
|
||||||
$object->$field_name = $items;
|
foreach ($cached->data as $key => $value) {
|
||||||
|
$object->$key = $value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$queried_objects[$id] = $object;
|
$queried_objects[$id] = $objects[$id];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$queried_objects = $objects;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Fetch other objects from the database.
|
// Fetch other objects from the database.
|
||||||
if ($queried_objects) {
|
if ($queried_objects) {
|
||||||
|
@ -389,7 +397,7 @@ function _field_attach_load($obj_type, $objects, $age = FIELD_LOAD_CURRENT) {
|
||||||
foreach ($instances as $instance) {
|
foreach ($instances as $instance) {
|
||||||
$data[$instance['field_name']] = $queried_objects[$id]->{$instance['field_name']};
|
$data[$instance['field_name']] = $queried_objects[$id]->{$instance['field_name']};
|
||||||
}
|
}
|
||||||
$cid = "field:$obj_type:$id:$vid";
|
$cid = "field:$obj_type:$id";
|
||||||
cache_set($cid, $data, 'cache_field');
|
cache_set($cid, $data, 'cache_field');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -577,7 +585,7 @@ function _field_attach_insert($obj_type, &$object) {
|
||||||
|
|
||||||
list($id, $vid, $bundle, $cacheable) = field_attach_extract_ids($obj_type, $object);
|
list($id, $vid, $bundle, $cacheable) = field_attach_extract_ids($obj_type, $object);
|
||||||
if ($cacheable) {
|
if ($cacheable) {
|
||||||
cache_clear_all("field:$obj_type:$id:", 'cache_field', TRUE);
|
cache_clear_all("field:$obj_type:$id", 'cache_field');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -590,7 +598,6 @@ function _field_attach_insert($obj_type, &$object) {
|
||||||
* The object with fields to save.
|
* The object with fields to save.
|
||||||
*/
|
*/
|
||||||
function _field_attach_update($obj_type, &$object) {
|
function _field_attach_update($obj_type, &$object) {
|
||||||
|
|
||||||
_field_invoke('update', $obj_type, $object);
|
_field_invoke('update', $obj_type, $object);
|
||||||
|
|
||||||
// Let other modules act on updating the object, accumulating saved
|
// Let other modules act on updating the object, accumulating saved
|
||||||
|
@ -606,7 +613,7 @@ function _field_attach_update($obj_type, &$object) {
|
||||||
|
|
||||||
list($id, $vid, $bundle, $cacheable) = field_attach_extract_ids($obj_type, $object);
|
list($id, $vid, $bundle, $cacheable) = field_attach_extract_ids($obj_type, $object);
|
||||||
if ($cacheable) {
|
if ($cacheable) {
|
||||||
cache_clear_all("field:$obj_type:$id:$vid", 'cache_field');
|
cache_clear_all("field:$obj_type:$id", 'cache_field');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -631,7 +638,7 @@ function _field_attach_delete($obj_type, &$object) {
|
||||||
|
|
||||||
list($id, $vid, $bundle, $cacheable) = field_attach_extract_ids($obj_type, $object);
|
list($id, $vid, $bundle, $cacheable) = field_attach_extract_ids($obj_type, $object);
|
||||||
if ($cacheable) {
|
if ($cacheable) {
|
||||||
cache_clear_all("field:$obj_type:$id:", 'cache_field', TRUE);
|
cache_clear_all("field:$obj_type:$id", 'cache_field');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -653,11 +660,6 @@ function _field_attach_delete_revision($obj_type, &$object) {
|
||||||
$function = $module . '_field_attach_delete_revision';
|
$function = $module . '_field_attach_delete_revision';
|
||||||
$function($obj_type, $object);
|
$function($obj_type, $object);
|
||||||
}
|
}
|
||||||
|
|
||||||
list($id, $vid, $bundle, $cacheable) = field_attach_extract_ids($obj_type, $object);
|
|
||||||
if ($cacheable) {
|
|
||||||
cache_clear_all("field:$obj_type:$id:$vid", 'cache_field');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -816,7 +818,7 @@ function _field_attach_extract_ids($object_type, $object) {
|
||||||
// If no bundle key provided, then we assume a single bundle, named after the
|
// If no bundle key provided, then we assume a single bundle, named after the
|
||||||
// type of the object.
|
// type of the object.
|
||||||
$bundle = $info['bundle key'] ? $object->{$info['bundle key']} : $object_type;
|
$bundle = $info['bundle key'] ? $object->{$info['bundle key']} : $object_type;
|
||||||
$cacheable = isset($info['cacheable']) ? $info['cacheable'] : FALSE;
|
$cacheable = $info['cacheable'];
|
||||||
return array($id, $vid, $bundle, $cacheable);
|
return array($id, $vid, $bundle, $cacheable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,10 +67,8 @@ class FieldAttachTestCase extends DrupalWebTestCase {
|
||||||
// Preparation: create three revisions and store them in $revision array.
|
// Preparation: create three revisions and store them in $revision array.
|
||||||
for ($revision_id = 0; $revision_id < 3; $revision_id++) {
|
for ($revision_id = 0; $revision_id < 3; $revision_id++) {
|
||||||
$revision[$revision_id] = field_test_create_stub_entity(0, $revision_id, $this->instance['bundle']);
|
$revision[$revision_id] = field_test_create_stub_entity(0, $revision_id, $this->instance['bundle']);
|
||||||
// Note: we try to insert one extra value ('<=' instead of '<').
|
// Note: we try to insert one extra value.
|
||||||
for ($delta = 0; $delta <= $this->field['cardinality']; $delta++) {
|
$values[$revision_id] = $this->_generateTestFieldValues($this->field['cardinality'] + 1);
|
||||||
$values[$revision_id][$delta]['value'] = mt_rand(1, 127);
|
|
||||||
}
|
|
||||||
$current_revision = $revision_id;
|
$current_revision = $revision_id;
|
||||||
// If this is the first revision do an insert.
|
// If this is the first revision do an insert.
|
||||||
if (!$revision_id) {
|
if (!$revision_id) {
|
||||||
|
@ -204,7 +202,7 @@ class FieldAttachTestCase extends DrupalWebTestCase {
|
||||||
// Add some real data.
|
// Add some real data.
|
||||||
field_cache_clear();
|
field_cache_clear();
|
||||||
$entity = clone($entity_init);
|
$entity = clone($entity_init);
|
||||||
$values = array(0 => array('value' => mt_rand(1, 127)));
|
$values = $this->_generateTestFieldValues(1);
|
||||||
$entity->{$this->field_name} = $values;
|
$entity->{$this->field_name} = $values;
|
||||||
field_attach_insert($entity_type, $entity);
|
field_attach_insert($entity_type, $entity);
|
||||||
|
|
||||||
|
@ -268,10 +266,7 @@ class FieldAttachTestCase extends DrupalWebTestCase {
|
||||||
$entity = field_test_create_stub_entity(0, 0, $this->instance['bundle']);
|
$entity = field_test_create_stub_entity(0, 0, $this->instance['bundle']);
|
||||||
|
|
||||||
// Populate values to be displayed.
|
// Populate values to be displayed.
|
||||||
$values = array();
|
$values = $this->_generateTestFieldValues($this->field['cardinality']);
|
||||||
for ($delta = 0; $delta < $this->field['cardinality']; $delta++) {
|
|
||||||
$values[$delta]['value'] = mt_rand(1, 127);
|
|
||||||
}
|
|
||||||
$entity->{$this->field_name} = $values;
|
$entity->{$this->field_name} = $values;
|
||||||
|
|
||||||
// Simple formatter, label displayed.
|
// Simple formatter, label displayed.
|
||||||
|
@ -318,7 +313,6 @@ class FieldAttachTestCase extends DrupalWebTestCase {
|
||||||
'full' => array(
|
'full' => array(
|
||||||
'label' => 'above',
|
'label' => 'above',
|
||||||
'type' => 'hidden',
|
'type' => 'hidden',
|
||||||
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
field_update_instance($this->instance);
|
field_update_instance($this->instance);
|
||||||
|
@ -366,10 +360,7 @@ class FieldAttachTestCase extends DrupalWebTestCase {
|
||||||
$rev[0] = field_test_create_stub_entity(0, 0, $this->instance['bundle']);
|
$rev[0] = field_test_create_stub_entity(0, 0, $this->instance['bundle']);
|
||||||
|
|
||||||
// Create revision 0
|
// Create revision 0
|
||||||
$values = array();
|
$values = $this->_generateTestFieldValues($this->field['cardinality']);
|
||||||
for ($delta = 0; $delta < $this->field['cardinality']; $delta++) {
|
|
||||||
$values[$delta]['value'] = mt_rand(1, 127);
|
|
||||||
}
|
|
||||||
$rev[0]->{$this->field_name} = $values;
|
$rev[0]->{$this->field_name} = $values;
|
||||||
field_attach_insert($entity_type, $rev[0]);
|
field_attach_insert($entity_type, $rev[0]);
|
||||||
|
|
||||||
|
@ -412,7 +403,7 @@ class FieldAttachTestCase extends DrupalWebTestCase {
|
||||||
}
|
}
|
||||||
$read = field_test_create_stub_entity(0, 2, $this->instance['bundle']);
|
$read = field_test_create_stub_entity(0, 2, $this->instance['bundle']);
|
||||||
field_attach_load($entity_type, array(0 => $read));
|
field_attach_load($entity_type, array(0 => $read));
|
||||||
$this->assertIdentical($read->{$this->field_name}, array(), "The test object current revision is deleted.");
|
$this->assertIdentical($read->{$this->field_name}, array(), t('The test object current revision is deleted.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
function testFieldAttachCreateRenameBundle() {
|
function testFieldAttachCreateRenameBundle() {
|
||||||
|
@ -427,10 +418,7 @@ class FieldAttachTestCase extends DrupalWebTestCase {
|
||||||
|
|
||||||
// Save an object with data in the field.
|
// Save an object with data in the field.
|
||||||
$entity = field_test_create_stub_entity(0, 0, $this->instance['bundle']);
|
$entity = field_test_create_stub_entity(0, 0, $this->instance['bundle']);
|
||||||
$values = array();
|
$values = $this->_generateTestFieldValues($this->field['cardinality']);
|
||||||
for ($delta = 0; $delta < $this->field['cardinality']; $delta++) {
|
|
||||||
$values[$delta]['value'] = mt_rand(1, 127);
|
|
||||||
}
|
|
||||||
$entity->{$this->field_name} = $values;
|
$entity->{$this->field_name} = $values;
|
||||||
$entity_type = 'test_entity';
|
$entity_type = 'test_entity';
|
||||||
field_attach_insert($entity_type, $entity);
|
field_attach_insert($entity_type, $entity);
|
||||||
|
@ -484,12 +472,9 @@ class FieldAttachTestCase extends DrupalWebTestCase {
|
||||||
|
|
||||||
// Save an object with data for both fields
|
// Save an object with data for both fields
|
||||||
$entity = field_test_create_stub_entity(0, 0, $this->instance['bundle']);
|
$entity = field_test_create_stub_entity(0, 0, $this->instance['bundle']);
|
||||||
$values = array();
|
$values = $this->_generateTestFieldValues($this->field['cardinality']);
|
||||||
for ($delta = 0; $delta < $this->field['cardinality']; $delta++) {
|
|
||||||
$values[$delta]['value'] = mt_rand(1, 127);
|
|
||||||
}
|
|
||||||
$entity->{$this->field_name} = $values;
|
$entity->{$this->field_name} = $values;
|
||||||
$entity->{$field_name} = array(0 => array('value' => 99));
|
$entity->{$field_name} = $this->_generateTestFieldValues(1);
|
||||||
$entity_type = 'test_entity';
|
$entity_type = 'test_entity';
|
||||||
field_attach_insert($entity_type, $entity);
|
field_attach_insert($entity_type, $entity);
|
||||||
|
|
||||||
|
@ -519,55 +504,72 @@ class FieldAttachTestCase extends DrupalWebTestCase {
|
||||||
*/
|
*/
|
||||||
function testFieldAttachCache() {
|
function testFieldAttachCache() {
|
||||||
// Initialize random values and a test entity.
|
// Initialize random values and a test entity.
|
||||||
$entity_init = field_test_create_stub_entity(0, 0, $this->instance['bundle']);
|
$entity = field_test_create_stub_entity(1, 1, $this->instance['bundle']);
|
||||||
$values = array();
|
$values = $this->_generateTestFieldValues($this->field['cardinality']);
|
||||||
for ($delta = 0; $delta < $this->field['cardinality']; $delta++) {
|
|
||||||
$values[$delta]['value'] = mt_rand(1, 127);
|
|
||||||
}
|
|
||||||
|
|
||||||
$noncached_type = 'test_entity';
|
$noncached_type = 'test_entity';
|
||||||
$cached_type = 'test_cacheable_entity';
|
$cached_type = 'test_cacheable_entity';
|
||||||
|
|
||||||
|
|
||||||
// Test non-cached object type.
|
// Non-cacheable entity type.
|
||||||
$cid = "field:$noncached_type:0:0";
|
$cid = "field:$noncached_type:{$entity->ftid}";
|
||||||
|
|
||||||
// Confirm no initial cache entry.
|
// Check that no initial cache entry is present.
|
||||||
$this->assertFalse(cache_get($cid, 'cache_field'), 'Non-cached: no initial cache entry');
|
$this->assertFalse(cache_get($cid, 'cache_field'), t('Non-cached: no initial cache entry'));
|
||||||
|
|
||||||
// Save, and confirm no cache entry.
|
// Save, and check that no cache entry is present.
|
||||||
$entity = clone($entity_init);
|
|
||||||
$entity->{$this->field_name} = $values;
|
$entity->{$this->field_name} = $values;
|
||||||
field_attach_insert($noncached_type, $entity);
|
field_attach_insert($noncached_type, $entity);
|
||||||
$this->assertFalse(cache_get($cid, 'cache_field'), 'Non-cached: no cache entry on save');
|
$this->assertFalse(cache_get($cid, 'cache_field'), t('Non-cached: no cache entry on insert'));
|
||||||
|
|
||||||
// Load, and confirm no cache entry.
|
// Load, and check that no cache entry is present.
|
||||||
$entity = clone($entity_init);
|
field_attach_load($noncached_type, array($entity->ftid => $entity));
|
||||||
field_attach_load($noncached_type, array(0 => $entity));
|
$this->assertFalse(cache_get($cid, 'cache_field'), t('Non-cached: no cache entry on load'));
|
||||||
$this->assertFalse(cache_get($cid, 'cache_field'), 'Non-cached: no cache entry on load');
|
|
||||||
|
|
||||||
|
|
||||||
// Test cached object type.
|
// Cacheable entity type.
|
||||||
$cid = "field:$cached_type:0:0";
|
$cid = "field:$cached_type:{$entity->ftid}";
|
||||||
|
|
||||||
// Confirm no initial cache entry.
|
// Check that no initial cache entry is present.
|
||||||
$this->assertFalse(cache_get($cid, 'cache_field'), 'Cached: no initial cache entry');
|
$this->assertFalse(cache_get($cid, 'cache_field'), t('Cached: no initial cache entry'));
|
||||||
|
|
||||||
// Save, and confirm no cache entry.
|
// Save, and check that no cache entry is present.
|
||||||
$entity = clone($entity_init);
|
|
||||||
$entity->{$this->field_name} = $values;
|
$entity->{$this->field_name} = $values;
|
||||||
field_attach_insert($cached_type, $entity);
|
field_attach_insert($cached_type, $entity);
|
||||||
$this->assertFalse(cache_get($cid, 'cache_field'), 'Cached: no cache entry on save');
|
$this->assertFalse(cache_get($cid, 'cache_field'), t('Cached: no cache entry on insert'));
|
||||||
|
|
||||||
// Load, and confirm cache entry.
|
// Load, and check that a cache entry is present with the expected values.
|
||||||
$entity = clone($entity_init);
|
field_attach_load($cached_type, array($entity->ftid => $entity));
|
||||||
field_attach_load($cached_type, array(0 => $entity));
|
|
||||||
$cache = cache_get($cid, 'cache_field');
|
$cache = cache_get($cid, 'cache_field');
|
||||||
$this->assertEqual($cache->data[$this->field_name], $values, 'Cached: correct cache entry on load');
|
$this->assertEqual($cache->data[$this->field_name], $values, t('Cached: correct cache entry on load'));
|
||||||
|
|
||||||
// Delete, and confirm no cache entry.
|
// Update with different values, and check that the cache entry is wiped.
|
||||||
|
$values = $this->_generateTestFieldValues($this->field['cardinality']);
|
||||||
|
$entity->{$this->field_name} = $values;
|
||||||
|
field_attach_update($cached_type, $entity);
|
||||||
|
$this->assertFalse(cache_get($cid, 'cache_field'), t('Cached: no cache entry on update'));
|
||||||
|
|
||||||
|
// Load, and check that a cache entry is present with the expected values.
|
||||||
|
field_attach_load($cached_type, array($entity->ftid => $entity));
|
||||||
|
$cache = cache_get($cid, 'cache_field');
|
||||||
|
$this->assertEqual($cache->data[$this->field_name], $values, t('Cached: correct cache entry on load'));
|
||||||
|
|
||||||
|
// Create a new revision, and check that the cache entry is wiped.
|
||||||
|
$values = $this->_generateTestFieldValues($this->field['cardinality']);
|
||||||
|
$entity->{$this->field_name} = $values;
|
||||||
|
$entity->ftvid = 2;
|
||||||
|
field_attach_update($cached_type, $entity);
|
||||||
|
$cache = cache_get($cid, 'cache_field');
|
||||||
|
$this->assertFalse(cache_get($cid, 'cache_field'), t('Cached: no cache entry on new revision creation'));
|
||||||
|
|
||||||
|
// Load, and check that a cache entry is present with the expected values.
|
||||||
|
field_attach_load($cached_type, array($entity->ftid => $entity));
|
||||||
|
$cache = cache_get($cid, 'cache_field');
|
||||||
|
$this->assertEqual($cache->data[$this->field_name], $values, t('Cached: correct cache entry on load'));
|
||||||
|
|
||||||
|
// Delete, and check that the cache entry is wiped.
|
||||||
field_attach_delete($cached_type, $entity);
|
field_attach_delete($cached_type, $entity);
|
||||||
$this->assertFalse(cache_get($cid, 'cache_field'), 'Cached: no cache entry on save');
|
$this->assertFalse(cache_get($cid, 'cache_field'), t('Cached: no cache entry after delete'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify that field_attach_validate() invokes the correct
|
// Verify that field_attach_validate() invokes the correct
|
||||||
|
@ -657,6 +659,23 @@ class FieldAttachTestCase extends DrupalWebTestCase {
|
||||||
}
|
}
|
||||||
$this->assertIdentical($entity->{$this->field_name}, $expected_values, 'Submit filters empty values');
|
$this->assertIdentical($entity->{$this->field_name}, $expected_values, 'Submit filters empty values');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate random values for a field_test field.
|
||||||
|
*
|
||||||
|
* @param $cardinality
|
||||||
|
* Number of values to generate.
|
||||||
|
* @return
|
||||||
|
* An array of random values, in the format expected for field values.
|
||||||
|
*/
|
||||||
|
function _generateTestFieldValues($cardinality) {
|
||||||
|
$values = array();
|
||||||
|
for ($i = 0; $i < $cardinality; $i++) {
|
||||||
|
// field_test fields treat 0 as 'empty value'.
|
||||||
|
$values[$i]['value'] = mt_rand(1, 127);
|
||||||
|
}
|
||||||
|
return $values;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class FieldInfoTestCase extends DrupalWebTestCase {
|
class FieldInfoTestCase extends DrupalWebTestCase {
|
||||||
|
|
Loading…
Reference in New Issue