field_sql_storage.install

Install, update and uninstall functions for the field_sql_storage module.

File

modules/field/modules/field_sql_storage/field_sql_storage.install

View source
<?php


/**
 * @file
 * Install, update and uninstall functions for the field_sql_storage module.
 */

/**
 * Implements hook_schema().
 */
function field_sql_storage_schema() {
    $schema = array();
    // Dynamic (data) tables.
    if (db_table_exists('field_config')) {
        $fields = field_read_fields(array(), array(
            'include_deleted' => TRUE,
            'include_inactive' => TRUE,
        ));
        drupal_load('module', 'field_sql_storage');
        foreach ($fields as $field) {
            if ($field['storage']['type'] == 'field_sql_storage') {
                $schema += _field_sql_storage_schema($field);
            }
        }
    }
    return $schema;
}

/**
 * Utility function: write field data directly to SQL storage.
 *
 * This function can be used for databases whose schema is at field module
 * version 7000 or higher.
 *
 * @ingroup update_api
 */
function _update_7000_field_sql_storage_write($entity_type, $bundle, $entity_id, $revision_id, $field_name, $data) {
    $table_name = "field_data_{$field_name}";
    $revision_name = "field_revision_{$field_name}";
    db_delete($table_name)->condition('entity_type', $entity_type)
        ->condition('entity_id', $entity_id)
        ->execute();
    db_delete($revision_name)->condition('entity_type', $entity_type)
        ->condition('entity_id', $entity_id)
        ->condition('revision_id', $revision_id)
        ->execute();
    $columns = array();
    foreach ($data as $langcode => $items) {
        foreach ($items as $delta => $item) {
            $record = array(
                'entity_type' => $entity_type,
                'entity_id' => $entity_id,
                'revision_id' => $revision_id,
                'bundle' => $bundle,
                'delta' => $delta,
                'language' => $langcode,
            );
            foreach ($item as $column => $value) {
                $record[_field_sql_storage_columnname($field_name, $column)] = $value;
            }
            $records[] = $record;
            // Record the columns used.
            $columns += $record;
        }
    }
    if ($columns) {
        $query = db_insert($table_name)->fields(array_keys($columns));
        $revision_query = db_insert($revision_name)->fields(array_keys($columns));
        foreach ($records as $record) {
            $query->values($record);
            if ($revision_id) {
                $revision_query->values($record);
            }
        }
        $query->execute();
        $revision_query->execute();
    }
}

/**
 * @addtogroup updates-6.x-to-7.x
 * @{
 */

/**
 * Field SQL storage update version placeholder.
 */
function field_sql_storage_update_7000() {
    // Some update helper functions (such as
    // _update_7000_field_sql_storage_write()) modify the database directly. They
    // can be used safely only if the database schema matches the field module
    // schema established for Drupal 7.0 (i.e. version 7000). This function exists
    // solely to set the schema version to 7000, so that update functions calling
    // those helpers can do so safely by declaring a dependency on
    // field_sql_storage_update_7000().
}

/**
 * Remove the field_config_entity_type table and store 'entity_type' strings.
 */
function field_sql_storage_update_7001(&$sandbox) {
    if (!isset($sandbox['progress'])) {
        // Collect current etids.
        $sandbox['etids'] = db_query('SELECT etid, type FROM {field_config_entity_type}')->fetchAllKeyed();
        // Collect affected tables: field data, field revision data, 'deleted'
        // tables.
        $sandbox['tables'] = array();
        $results = db_select('field_config', 'fc', array(
            'fetch' => PDO::FETCH_ASSOC,
        ))->fields('fc')
            ->condition('storage_module', 'field_sql_storage')
            ->execute();
        foreach ($results as $field) {
            if ($field['deleted']) {
                $sandbox['tables']["field_deleted_data_{$field['id']}"] = 'data';
                $sandbox['tables']["field_deleted_revision_{$field['id']}"] = 'revision';
            }
            else {
                $sandbox['tables']["field_data_{$field['field_name']}"] = 'data';
                $sandbox['tables']["field_revision_{$field['field_name']}"] = 'revision';
            }
        }
        reset($sandbox['tables']);
        $sandbox['total'] = count($sandbox['tables']);
        $sandbox['progress'] = 0;
    }
    if ($sandbox['tables']) {
        // Grab the next table to process.
        $table = key($sandbox['tables']);
        $type = array_shift($sandbox['tables']);
        if (db_table_exists($table)) {
            // Add the 'entity_type' column.
            if (!db_field_exists($table, 'entity_type')) {
                $column = array(
                    'type' => 'varchar',
                    'length' => 128,
                    'not null' => TRUE,
                    'default' => '',
                    'description' => 'The entity type this data is attached to.',
                );
                db_add_field($table, 'entity_type', $column);
                // Populate the 'entity_type' column based on the 'etid' column.
                foreach ($sandbox['etids'] as $etid => $entity_type) {
                    db_update($table)->fields(array(
                        'entity_type' => $entity_type,
                    ))
                        ->condition('etid', $etid)
                        ->execute();
                }
                // Index the new column.
                db_add_index($table, 'entity_type', array(
                    'entity_type',
                ));
            }
            // Use the 'entity_type' column in the primary key.
            db_drop_primary_key($table);
            $primary_keys = array(
                'data' => array(
                    'entity_type',
                    'entity_id',
                    'deleted',
                    'delta',
                    'language',
                ),
                'revision' => array(
                    'entity_type',
                    'entity_id',
                    'revision_id',
                    'deleted',
                    'delta',
                    'language',
                ),
            );
            db_add_primary_key($table, $primary_keys[$type]);
            // Drop the 'etid' column.
            if (db_field_exists($table, 'etid')) {
                db_drop_field($table, 'etid');
            }
        }
        // Report progress.
        $sandbox['progress']++;
        $sandbox['#finished'] = min(0.99, $sandbox['progress'] / $sandbox['total']);
    }
    else {
        // No more tables left: drop the field_config_entity_type table.
        db_drop_table('field_config_entity_type');
        // Drop the previous 'field_sql_storage_ENTITYTYPE_etid' system variables.
        foreach ($sandbox['etids'] as $etid => $entity_type) {
            variable_del('field_sql_storage_' . $entity_type . '_etid');
        }
        // We're done.
        $sandbox['#finished'] = 1;
    }
}

/**
 * Fix primary keys in field revision data tables.
 */
function field_sql_storage_update_7002() {
    $results = db_select('field_config', 'fc', array(
        'fetch' => PDO::FETCH_ASSOC,
    ))->fields('fc')
        ->condition('storage_module', 'field_sql_storage')
        ->execute();
    foreach ($results as $field) {
        // Revision tables of deleted fields do not need to be fixed, since no new
        // data is written to them.
        if (!$field['deleted']) {
            $table = "field_revision_{$field['field_name']}";
            db_drop_primary_key($table);
            db_add_primary_key($table, array(
                'entity_type',
                'entity_id',
                'revision_id',
                'deleted',
                'delta',
                'language',
            ));
        }
    }
}

/**
 * @} End of "addtogroup updates-6.x-to-7.x".
 */

Functions

Title Deprecated Summary
field_sql_storage_schema Implements hook_schema().
field_sql_storage_update_7000 Field SQL storage update version placeholder.
field_sql_storage_update_7001 Remove the field_config_entity_type table and store 'entity_type' strings.
field_sql_storage_update_7002 Fix primary keys in field revision data tables.
_update_7000_field_sql_storage_write Utility function: write field data directly to SQL storage.

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.