/** * Tests creating and deleting a multi-field index when there are no existing entities. */ public function testEntityIndexCreateDeleteWithoutData() { // Add an entity index and ensure the update manager reports that as an // update to the entity type. $this->addEntityIndex(); $this->assertTrue($this->entityDefinitionUpdateManager->needsUpdates(), 'EntityDefinitionUpdateManager reports that updates are needed.'); $expected = array('entity_test_update' => array(t('Update the %entity_type entity type.', array('%entity_type' => $this->entityManager->getDefinition('entity_test_update')->getLabel())))); $this->assertEqual($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.'); // Run the update and ensure the new index is created. $this->entityDefinitionUpdateManager->applyUpdates(); $this->assertTrue($this->database->schema()->indexExists('entity_test_update', 'entity_test_update__new_index'), 'Index created.'); // Remove the index and ensure the update manager reports that as an // update to the entity type. $this->removeEntityIndex(); $this->assertTrue($this->entityDefinitionUpdateManager->needsUpdates(), 'EntityDefinitionUpdateManager reports that updates are needed.'); $expected = array('entity_test_update' => array(t('Update the %entity_type entity type.', array('%entity_type' => $this->entityManager->getDefinition('entity_test_update')->getLabel())))); $this->assertEqual($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.'); // Run the update and ensure the index is deleted. $this->entityDefinitionUpdateManager->applyUpdates(); $this->assertFalse($this->database->schema()->indexExists('entity_test_update', 'entity_test_update__new_index'), 'Index deleted.'); // Test that composite indexes are handled correctly when dropping and // re-creating one of their columns. $this->addEntityIndex(); $this->entityDefinitionUpdateManager->applyUpdates(); $storage_definition = $this->entityDefinitionUpdateManager->getFieldStorageDefinition('name', 'entity_test_update'); $this->entityDefinitionUpdateManager->updateFieldStorageDefinition($storage_definition); $this->assertTrue($this->database->schema()->indexExists('entity_test_update', 'entity_test_update__new_index'), 'Index created.'); $this->entityDefinitionUpdateManager->uninstallFieldStorageDefinition($storage_definition); $this->assertFalse($this->database->schema()->indexExists('entity_test_update', 'entity_test_update__new_index'), 'Index deleted.'); $this->entityDefinitionUpdateManager->installFieldStorageDefinition('name', 'entity_test_update', 'entity_test', $storage_definition); $this->assertTrue($this->database->schema()->indexExists('entity_test_update', 'entity_test_update__new_index'), 'Index created again.'); }
/** * Executes field storage definition updates if needed. * * @param array $entity_types * A list of entity type definitions to be processed. */ public function updateDefinitions(array $entity_types) { // Handle field storage definition creation, if needed. // @todo Generalize this code in https://www.drupal.org/node/2346013. // @todo Handle initial values in https://www.drupal.org/node/2346019. if ($this->updateManager->needsUpdates()) { foreach ($entity_types as $entity_type_id => $entity_type) { $storage_definitions = $this->entityManager->getFieldStorageDefinitions($entity_type_id); $installed_storage_definitions = $this->entityManager->getLastInstalledFieldStorageDefinitions($entity_type_id); foreach (array_diff_key($storage_definitions, $installed_storage_definitions) as $storage_definition) { /** @var $storage_definition \Drupal\Core\Field\FieldStorageDefinitionInterface */ if ($storage_definition->getProvider() == 'content_translation') { $this->updateManager->installFieldStorageDefinition($storage_definition->getName(), $entity_type_id, 'content_translation', $storage_definition); } } } } }
/** * Check that field schema is correctly handled with long-named fields. */ function testLongNameFieldIndexes() { $this->addLongNameBaseField(); $entity_type_id = 'entity_test_update'; $entity_type = $this->entityManager->getDefinition($entity_type_id); $definitions = EntityTestUpdate::baseFieldDefinitions($entity_type); $name = 'new_long_named_entity_reference_base_field'; $this->entityDefinitionUpdateManager->installFieldStorageDefinition($name, $entity_type_id, 'entity_test', $definitions[$name]); $this->assertFalse($this->entityDefinitionUpdateManager->needsUpdates(), 'Entity and field schema data are correctly detected.'); }
/** * Starts the database update batch process. * * @param \Symfony\Component\HttpFoundation\Request $request * The current request object. */ protected function triggerBatch(Request $request) { // During the update, bring the site offline so that schema changes do not // affect visiting users. $maintenance_mode = $this->config('system.maintenance')->get('enabled'); if (isset($maintenance_mode)) { $_SESSION['maintenance_mode'] = $maintenance_mode; } if (empty($_SESSION['maintenance_mode'])) { $this->state->set('system.maintenance_mode', TRUE); } $operations = array(); // Resolve any update dependencies to determine the actual updates that will // be run and the order they will be run in. $start = $this->getModuleUpdates(); $updates = update_resolve_dependencies($start); // Store the dependencies for each update function in an array which the // batch API can pass in to the batch operation each time it is called. (We // do not store the entire update dependency array here because it is // potentially very large.) $dependency_map = array(); foreach ($updates as $function => $update) { $dependency_map[$function] = !empty($update['reverse_paths']) ? array_keys($update['reverse_paths']) : array(); } // Determine updates to be performed. foreach ($updates as $function => $update) { if ($update['allowed']) { // Set the installed version of each module so updates will start at the // correct place. (The updates are already sorted, so we can simply base // this on the first one we come across in the above foreach loop.) if (isset($start[$update['module']])) { drupal_set_installed_schema_version($update['module'], $update['number'] - 1); unset($start[$update['module']]); } $operations[] = array('update_do_one', array($update['module'], $update['number'], $dependency_map[$function])); } } // Lastly, perform entity definition updates, which will update storage // schema if needed. If module update functions need to work with specific // entity schema they should call the entity update service for the specific // update themselves. // @see \Drupal\Core\Entity\EntityDefinitionUpdateManagerInterface::applyEntityUpdate() // @see \Drupal\Core\Entity\EntityDefinitionUpdateManagerInterface::applyFieldUpdate() if ($this->entityDefinitionUpdateManager->needsUpdates()) { $operations[] = array('update_entity_definitions', array()); } $batch['operations'] = $operations; $batch += array('title' => $this->t('Updating'), 'init_message' => $this->t('Starting updates'), 'error_message' => $this->t('An unrecoverable error has occurred. You can find the error message below. It is advised to copy it to the clipboard for reference.'), 'finished' => array('\\Drupal\\system\\Controller\\DbUpdateController', 'batchFinished')); batch_set($batch); return batch_process('update.php/results', Url::fromRoute('system.db_update', array('op' => 'start'))); }
/** * Tests creating and deleting a multi-field index when there are no existing entities. */ public function testEntityIndexCreateDeleteWithoutData() { // Add an entity index and ensure the update manager reports that as an // update to the entity type. $this->addEntityIndex(); $this->assertTrue($this->entityDefinitionUpdateManager->needsUpdates(), 'EntityDefinitionUpdateManager reports that updates are needed.'); $expected = array('entity_test_update' => array(t('Update the %entity_type entity type.', array('%entity_type' => $this->entityManager->getDefinition('entity_test_update')->getLabel())))); $this->assertIdentical($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.'); // Run the update and ensure the new index is created. $this->entityDefinitionUpdateManager->applyUpdates(); $this->assertTrue($this->database->schema()->indexExists('entity_test_update', 'entity_test_update__new_index'), 'Index created.'); // Remove the index and ensure the update manager reports that as an // update to the entity type. $this->removeEntityIndex(); $this->assertTrue($this->entityDefinitionUpdateManager->needsUpdates(), 'EntityDefinitionUpdateManager reports that updates are needed.'); $expected = array('entity_test_update' => array(t('Update the %entity_type entity type.', array('%entity_type' => $this->entityManager->getDefinition('entity_test_update')->getLabel())))); $this->assertIdentical($this->entityDefinitionUpdateManager->getChangeSummary(), $expected, 'EntityDefinitionUpdateManager reports the expected change summary.'); // Run the update and ensure the index is deleted. $this->entityDefinitionUpdateManager->applyUpdates(); $this->assertFalse($this->database->schema()->indexExists('entity_test_update', 'entity_test_update__new_index'), 'Index deleted.'); }