Skip to main content
code indentation
Source Link
berliner
  • 2.9k
  • 1
  • 21
  • 29

Thank you every one for your answers that allowed me to build the following (imperfect) solution.

List deleted fields waiting to be purged:

drush php:eval "var_dump(\Drupal::state()->get('field.storage.deleted'))"

If the result is not an empty array, create the missing field_deleted_data_* tables:

drush php:eval '$deleted_field_storage_configs = \Drupal::state()->get("field.storage.deleted");
$database = \Drupal::database();

foreach($deleted_field_storage_configs as $field_storage_config) {
  $table_name = "field_deleted_data_" . substr(hash("sha256", $field_storage_config->getUniqueStorageIdentifier()), 0, 10);

  $sql_query = "CREATE TABLE IF NOT EXISTS `" . $table_name . "` (
    `bundle` varchar(128) CHARACTER SET ascii NOT NULL DEFAULT '\'\'',
    `deleted` tinyint(4) NOT NULL DEFAULT '\''0'\'',
    `entity_id` int(10) unsigned NOT NULL,
    `revision_id` int(10) unsigned NOT NULL,
    `langcode` varchar(32) CHARACTER SET ascii NOT NULL DEFAULT '\'\'',
    `delta` int(10) unsigned NOT NULL,
    `content_translation_source_value` varchar(12) CHARACTER SET ascii NOT NULL,
    PRIMARY KEY (`entity_id`,`deleted`,`delta`,`langcode`),
    KEY `bundle` (`bundle`),
    KEY `revision_id` (`revision_id`) );";

  $database->query($sql_query);
}
'

Remove the fields:

vendor/bin/drush php-eval 'field_purge_batch(1000);'

Check that no more fields are waiting to be purged:

drush php:eval "var_dump(\Drupal::state()->get('field.storage.deleted'))"

You can now safely remove field_deleted_data_* tables that are still present in the Drupal database.

To perfect this solution:

I based the table name computation on the code of the SqlContentEntityStorage::readFieldItemsToPurge() method.

The better way to do this would be to find a way to get the SqlContentEntityStorage and field storage definition to have the good version of table name computation:

    $storage_definition = $field_definition->getFieldStorageDefinition();
    $table_mapping = $this->getTableMapping();
    $table_name = $table_mapping->getDedicatedDataTableName($storage_definition, $storage_definition->isDeleted());

Thank you every one for your answers that allowed me to build the following (imperfect) solution.

List deleted fields waiting to be purged:

drush php:eval "var_dump(\Drupal::state()->get('field.storage.deleted'))"

If the result is not an empty array, create the missing field_deleted_data_* tables:

drush php:eval '$deleted_field_storage_configs = \Drupal::state()->get("field.storage.deleted");
$database = \Drupal::database();

foreach($deleted_field_storage_configs as $field_storage_config) {
  $table_name = "field_deleted_data_" . substr(hash("sha256", $field_storage_config->getUniqueStorageIdentifier()), 0, 10);

  $sql_query = "CREATE TABLE IF NOT EXISTS `" . $table_name . "` (
    `bundle` varchar(128) CHARACTER SET ascii NOT NULL DEFAULT '\'\'',
    `deleted` tinyint(4) NOT NULL DEFAULT '\''0'\'',
    `entity_id` int(10) unsigned NOT NULL,
    `revision_id` int(10) unsigned NOT NULL,
    `langcode` varchar(32) CHARACTER SET ascii NOT NULL DEFAULT '\'\'',
    `delta` int(10) unsigned NOT NULL,
    `content_translation_source_value` varchar(12) CHARACTER SET ascii NOT NULL,
    PRIMARY KEY (`entity_id`,`deleted`,`delta`,`langcode`),
    KEY `bundle` (`bundle`),
    KEY `revision_id` (`revision_id`) );";

  $database->query($sql_query);
}
'

Remove the fields:

vendor/bin/drush php-eval 'field_purge_batch(1000);'

Check that no more fields are waiting to be purged:

drush php:eval "var_dump(\Drupal::state()->get('field.storage.deleted'))"

You can now safely remove field_deleted_data_* tables that are still present in the Drupal database.

To perfect this solution:

I based the table name computation on the code of the SqlContentEntityStorage::readFieldItemsToPurge() method.

The better way to do this would be to find a way to get the SqlContentEntityStorage and field storage definition to have the good version of table name computation:

    $storage_definition = $field_definition->getFieldStorageDefinition();
    $table_mapping = $this->getTableMapping();
    $table_name = $table_mapping->getDedicatedDataTableName($storage_definition, $storage_definition->isDeleted());

Thank you every one for your answers that allowed me to build the following (imperfect) solution.

List deleted fields waiting to be purged:

drush php:eval "var_dump(\Drupal::state()->get('field.storage.deleted'))"

If the result is not an empty array, create the missing field_deleted_data_* tables:

drush php:eval '$deleted_field_storage_configs = \Drupal::state()->get("field.storage.deleted");
$database = \Drupal::database();

foreach($deleted_field_storage_configs as $field_storage_config) {
  $table_name = "field_deleted_data_" . substr(hash("sha256", $field_storage_config->getUniqueStorageIdentifier()), 0, 10);

  $sql_query = "CREATE TABLE IF NOT EXISTS `" . $table_name . "` (
    `bundle` varchar(128) CHARACTER SET ascii NOT NULL DEFAULT '\'\'',
    `deleted` tinyint(4) NOT NULL DEFAULT '\''0'\'',
    `entity_id` int(10) unsigned NOT NULL,
    `revision_id` int(10) unsigned NOT NULL,
    `langcode` varchar(32) CHARACTER SET ascii NOT NULL DEFAULT '\'\'',
    `delta` int(10) unsigned NOT NULL,
    `content_translation_source_value` varchar(12) CHARACTER SET ascii NOT NULL,
    PRIMARY KEY (`entity_id`,`deleted`,`delta`,`langcode`),
    KEY `bundle` (`bundle`),
    KEY `revision_id` (`revision_id`) );";

  $database->query($sql_query);
}
'

Remove the fields:

vendor/bin/drush php-eval 'field_purge_batch(1000);'

Check that no more fields are waiting to be purged:

drush php:eval "var_dump(\Drupal::state()->get('field.storage.deleted'))"

You can now safely remove field_deleted_data_* tables that are still present in the Drupal database.

To perfect this solution:

I based the table name computation on the code of the SqlContentEntityStorage::readFieldItemsToPurge() method.

The better way to do this would be to find a way to get the SqlContentEntityStorage and field storage definition to have the good version of table name computation:

$storage_definition = $field_definition->getFieldStorageDefinition();
$table_mapping = $this->getTableMapping();
$table_name = $table_mapping->getDedicatedDataTableName($storage_definition, $storage_definition->isDeleted());
Source Link
Biapy
  • 111
  • 2

Thank you every one for your answers that allowed me to build the following (imperfect) solution.

List deleted fields waiting to be purged:

drush php:eval "var_dump(\Drupal::state()->get('field.storage.deleted'))"

If the result is not an empty array, create the missing field_deleted_data_* tables:

drush php:eval '$deleted_field_storage_configs = \Drupal::state()->get("field.storage.deleted");
$database = \Drupal::database();

foreach($deleted_field_storage_configs as $field_storage_config) {
  $table_name = "field_deleted_data_" . substr(hash("sha256", $field_storage_config->getUniqueStorageIdentifier()), 0, 10);

  $sql_query = "CREATE TABLE IF NOT EXISTS `" . $table_name . "` (
    `bundle` varchar(128) CHARACTER SET ascii NOT NULL DEFAULT '\'\'',
    `deleted` tinyint(4) NOT NULL DEFAULT '\''0'\'',
    `entity_id` int(10) unsigned NOT NULL,
    `revision_id` int(10) unsigned NOT NULL,
    `langcode` varchar(32) CHARACTER SET ascii NOT NULL DEFAULT '\'\'',
    `delta` int(10) unsigned NOT NULL,
    `content_translation_source_value` varchar(12) CHARACTER SET ascii NOT NULL,
    PRIMARY KEY (`entity_id`,`deleted`,`delta`,`langcode`),
    KEY `bundle` (`bundle`),
    KEY `revision_id` (`revision_id`) );";

  $database->query($sql_query);
}
'

Remove the fields:

vendor/bin/drush php-eval 'field_purge_batch(1000);'

Check that no more fields are waiting to be purged:

drush php:eval "var_dump(\Drupal::state()->get('field.storage.deleted'))"

You can now safely remove field_deleted_data_* tables that are still present in the Drupal database.

To perfect this solution:

I based the table name computation on the code of the SqlContentEntityStorage::readFieldItemsToPurge() method.

The better way to do this would be to find a way to get the SqlContentEntityStorage and field storage definition to have the good version of table name computation:

    $storage_definition = $field_definition->getFieldStorageDefinition();
    $table_mapping = $this->getTableMapping();
    $table_name = $table_mapping->getDedicatedDataTableName($storage_definition, $storage_definition->isDeleted());