Browse Source

Batch the update

pull/829/head
Seth Shaw 4 years ago
parent
commit
a8f8e40371
  1. 170
      modules/islandora_core_feature/islandora_core_feature.install

170
modules/islandora_core_feature/islandora_core_feature.install

@ -10,9 +10,10 @@ use Drupal\field\Entity\FieldStorageConfig;
/** /**
* Updates Media file size field storage for larger files. * Updates Media file size field storage for larger files.
*/ */
function islandora_core_feature_update_8001() { function islandora_core_feature_update_8001(&$sandbox) {
$entity_type = 'media'; $entity_type = 'media';
$field_name = 'field_file_size'; $field_name = 'field_file_size';
$database = \Drupal::database(); $database = \Drupal::database();
@ -21,82 +22,113 @@ function islandora_core_feature_update_8001() {
"{$entity_type}_revision__{$field_name}", "{$entity_type}_revision__{$field_name}",
]; ];
foreach ($tables as $table) { if (!isset($sandbox['progress'])) {
$sandbox['upper_limit'] = 0;
foreach ($tables as $table) {
// Move the existing data out of the way. // Record size of the table for future use.
$database->schema()->renameTable($table, $table . '_o'); $sandbox[$table]['size'] = $database->select($table)
->countQuery()
// Create replacement tables. ->execute()
$database->schema()->createTable($table, [ ->fetchField();
'fields' => [ if ($sandbox[$table]['size'] > $sandbox['upper_limit']) {
'bundle' => [ $sandbox['upper_limit'] = $sandbox[$table]['size'];
'type' => 'varchar', }
'not null' => TRUE, // Move the existing data out of the way.
'length' => 128, $database->schema()->renameTable($table, $table . '_o');
'default' => ' ',
],
'deleted' => [
'type' => 'int',
'size' => 'tiny',
'not null' => TRUE,
'default' => 0,
],
'entity_id' => [
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'length' => 10,
// Create replacement tables.
$database->schema()->createTable($table, [
'fields' => [
'bundle' => [
'type' => 'varchar',
'not null' => TRUE,
'length' => 128,
'default' => ' ',
],
'deleted' => [
'type' => 'int',
'size' => 'tiny',
'not null' => TRUE,
'default' => 0,
],
'entity_id' => [
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'length' => 10,
],
'revision_id' => [
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'length' => 10,
],
'langcode' => [
'type' => 'varchar',
'not null' => TRUE,
'length' => 32,
'default' => ' ',
],
'delta' => [
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'length' => 10,
],
'field_file_size_value' => [
'type' => 'int',
'size' => 'big',
'unsigned' => TRUE,
'not null' => TRUE,
],
], ],
'revision_id' => [ 'primary key' => ['entity_id', 'deleted', 'delta', 'langcode'],
'type' => 'int', 'indexes' => ['bundle' => ['bundle'], 'revision_id' => ['revision_id']],
'unsigned' => TRUE, ]);
'not null' => TRUE,
'length' => 10, }
],
'langcode' => [ // Update field storage configuration.
'type' => 'varchar', $config = \Drupal::configFactory()
'not null' => TRUE, ->getEditable("field.storage.{$entity_type}.{$field_name}");
'length' => 32, $config->set('settings.size', 'big');
'default' => ' ', $config->set('settings.unsigned', TRUE);
], $config->save(TRUE);
'delta' => [
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'length' => 10,
],
'field_file_size_value' => [
'type' => 'int',
'size' => 'big',
'unsigned' => TRUE,
'not null' => TRUE,
],
],
'primary key' => ['entity_id', 'deleted', 'delta', 'langcode'],
'indexes' => ['bundle' => ['bundle'], 'revision_id' => ['revision_id']],
]);
}
// Update field storage configuration. // Make sure the new config persists.
$config = \Drupal::configFactory() FieldStorageConfig::loadByName($entity_type, $field_name)->save();
->getEditable("field.storage.{$entity_type}.{$field_name}");
$config->set('settings.size', 'big');
$config->set('settings.unsigned', TRUE);
$config->save(TRUE);
// Make sure the new config persists. // Track batch reload progress.
FieldStorageConfig::loadByName($entity_type, $field_name)->save(); $sandbox['progress'] = 0;
}
// Arbitrary, hopefully reasonable, batch size per table.
$limit = 500;
// Reload the data and clean up. // Reload the data and clean up.
foreach ($tables as $table) { foreach ($tables as $table) {
$query = $database->select($table . '_o', 'o')->fields('o'); if (!isset($sandbox[$table]['done'])) {
$database->insert($table)->from($query)->execute(); $query = $database->select($table . '_o', 'o')->fields('o')
$database->schema()->dropTable($table . '_o'); ->orderBy('o.entity_id', 'ASC')
->orderBy('o.revision_id', 'ASC')
->orderBy('o.delta', 'ASC')
->range($sandbox['progress'], $sandbox['progress'] + $limit);
$database->insert($table)->from($query)->execute();
$database->schema()->dropTable($table . '_o');
if ($sandbox['progress'] + $limit >= $progress[$table]['size']) {
$sandbox[$table]['done'] = TRUE;
}
}
} }
return t('Length of @entity-type.@field-name updated to an unsigned big int', [ $sandbox['progress'] = $sandbox['progress'] + $limit;
'@entity-type' => $entity_type, $sandbox['#finished'] = $sandbox['progress'] >= $sandbox['upper_limit'] ? 1 : $sandbox['progress'] / $sandbox['upper_limit'];
'@field-name' => $field_name, if ($sandbox['#finished'] == 1) {
]); return t('Length of @entity-type.@field-name updated to an unsigned big int', [
'@entity-type' => $entity_type,
'@field-name' => $field_name,
]);
}
} }

Loading…
Cancel
Save