You are here

biblio.install in Bibliography Module 6.2

Install, update, and uninstall functions for the biblio module.

File

biblio.install
View source
<?php

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

// @todo: Add reference to Drupal version and time of last edit?

/**
 * Implements hook_install().
 */
function biblio_install() {
  $result = array();

  // Create the database tables that will store data for the biblio module.
  $result[] = drupal_install_schema('biblio');

  // There are numerous bibliographic types. Initialize the {biblio_types} table
  // with an initial list of bibliographic types.
  $result[] = _biblio_add_bibliographic_types();

  // Each type of biblio publication (for example, a book) may have one or more
  // fields associated with it, such as title, ISBN number, etc. Hence, set up
  // definition parameters about how a title, ISBN, etc. are defined as a custom
  // biblio field.
  $result[] = _biblio_add_field_definitions();

  // With the types of custom biblio fields now defined, we need to set which
  // custom biblio fields are to be used with each bibliographic type and adjust
  // the field labels as appropriate.
  $result[] = _biblio_types_customize_fields();

  // Drupal hooks are processed by modules as they are set in the system table
  // in order of the module weight.  Those with heavier wights are called later
  // in the sequence.  Increase the weight of this module for a later call.
  $result[] = _biblio_set_module_system_weight();
  if (count($result) == count(array_filter($result))) {
    drupal_set_message(t('The biblio module has successfully added its tables to the database.'));
  }
  else {
    drupal_set_message(t('Drupal encountered some errors while attempting to install the database tables for the biblio module.'), 'error');
  }
}

/**
 * Implements hook_enable().
 */
function biblio_enable() {
  if (module_exists('taxonomy')) {
    _biblio_enable_vocabularies();
  }

  // Adjust the weight of the biblio module in the collection of modules.
  _biblio_set_module_system_weight();
}

/**
 * Helper function to enable vocabularies for the biblio module.
 */
function _biblio_enable_vocabularies() {
  $vids = variable_get('biblio_vocabularies', array());
  foreach ($vids as $vid) {
    if ($voc = taxonomy_vocabulary_load($vid)) {
      $voc = (array) $voc;
      $voc['nodes']['biblio'] = 1;
      taxonomy_save_vocabulary($voc);
    }
  }
}

/**
 * Implements hook_disable().
 */
function biblio_disable() {
  if (module_exists('taxonomy')) {
    $voc = taxonomy_get_vocabularies();
    foreach ($voc as $vid => $vocabulary) {
      if (isset($vocabulary->nodes['biblio'])) {
        $vids[] = $vid;
      }
    }
    variable_set('biblio_vocabularies', $vids);
  }
}

/**
 * Implements hook_uninstall().
 */
function biblio_uninstall() {
  $batch = array(
    'title' => t('Remove all Biblio nodes'),
    'operations' => array(
      array(
        'biblio_batch_uninstall',
        array(),
      ),
    ),
    'progress_message' => t('Deleteing Biblio nodes...'),
    'finished' => 'biblio_batch_uninstall_finished',
    'file' => drupal_get_path('module', 'biblio') . '/biblio.install',
  );
  batch_set($batch);
}
function biblio_batch_uninstall(&$context) {
  $limit = 5;
  if (empty($context['sandbox'])) {
    $context['sandbox']['progress'] = 0;
    $context['sandbox']['current_node'] = 0;
    $context['sandbox']['max'] = db_result(db_query("SELECT COUNT(DISTINCT nid) FROM {node} WHERE type='biblio'"));
    $context['sandbox']['itters'] = $context['sandbox']['max'] / $limit;
    $context['sandbox']['eta'] = 0;
  }

  // Bail out if the cache is empty.
  if ($context['sandbox']['max'] == 0) {
    $context['finished'] = 1;
    return;
  }
  timer_start('biblio_delete');
  $current = $context['sandbox']['current_node'];
  $sql = "SELECT nid FROM {node} WHERE nid > %d and type='biblio' ORDER BY nid ASC";
  $result = db_query_range($sql, $current, 0, $limit);
  while ($row = db_fetch_object($result)) {
    $node = node_delete($row->nid);
    if (function_exists('search_wipe')) {
      search_wipe($row->nid, 'node');
    }
    $context['sandbox']['progress']++;
    $context['sandbox']['current_node'] = $row->nid;
  }
  $looptime = timer_stop('biblio_delete');
  $context['sandbox']['eta'] += $looptime['time'];
  $itters = $context['sandbox']['progress'] / $limit;
  if ($itters) {
    $average_time = $context['sandbox']['eta'] / $itters;
    $eta = ($context['sandbox']['itters'] * $average_time - $average_time * $itters) / 1000;
    if ($eta >= 60) {
      $min = (int) $eta / 60;
    }
    else {
      $min = 0;
    }
    $sec = $eta % 60;
    $eta = sprintf("%d:%02d", $min, $sec);
    $progress = sprintf("%d / %d", $context['sandbox']['progress'], $context['sandbox']['max']);
    $context['message'] = t('<br>Biblio nodes deleted: %progress <br> Time remaining: %eta min.<br>', array(
      '%progress' => $progress,
      '%eta' => $eta,
    ));
  }
  if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
    $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
  }
}
function biblio_batch_uninstall_finished($success, $results, $operations) {
  if ($success) {
    if (module_exists('taxonomy')) {
      $voc = taxonomy_get_vocabularies();
      foreach ($voc as $vid => $vocabulary) {
        if ($vocabulary->module == 'biblio') {
          taxonomy_del_vocabulary($vid);
        }
      }
    }
    $result = db_query("SELECT * FROM {variable} WHERE name LIKE 'biblio_%'");
    while ($var = db_fetch_object($result)) {
      variable_del($var->name);
    }
    drupal_uninstall_schema('biblio');
    cache_clear_all();
  }
}

/**
 * Implements hook_requirements().
 */
function biblio_requirements($phase) {
  $requirements = array();
  $message = '';

  // Ensure translations do not break at install time.
  $t = get_t();

  // @todo: When is this requirement check called?
  if ($phase == 'runtime') {
    $dir = drupal_get_path('module', 'biblio');
    $files = file_scan_directory($dir, '..*.inc$', array(
      '.',
      '..',
    ), 0, FALSE);
    if (count($files)) {
      $message = $t('There is a problem with your Biblio installation! There should not be any ".inc" files in the %biblio directory.  You probably forgot to delete the old biblio files when you upgraded the module.  You should remove the following files from that directory...', array(
        '%biblio' => $dir,
      ));
      $message .= "<ul>";
      foreach ($files as $file) {
        $message .= "<li>" . $file->basename;
      }
      $message .= "</ul>";
    }
    $requirements['biblio'] = array(
      'title' => $t('Biblio'),
      'value' => BIBLIO_VERSION,
      'severity' => empty($message) ? REQUIREMENT_OK : REQUIREMENT_ERROR,
      'description' => $message,
    );
  }
  return $requirements;
}

/**
 * Helper function to adjust the system weight value of biblio module.
 */
function _biblio_set_module_system_weight() {
  return update_sql("UPDATE {system} SET weight = 9 WHERE name = 'biblio'");
}

/**
 * Helper function to enable the keyword vocabulary for the biblio module.
 */
function _biblio_enable_keyword_vocabulary() {
  if ($vocabulary = taxonomy_vocabulary_load(variable_get('biblio_keyword_vocabulary', 0))) {

    // Existing install. Add back forum node type, if the biblio vocabulary
    // still exists. Keep all other node types intact there.
    $vocabulary = (array) $vocabulary;
    $vocabulary['nodes']['biblio'] = 1;
    taxonomy_save_vocabulary($vocabulary);
  }
  return $vocabulary['vid'];
}

/**
 * Helper function to eneable the collection vocabulary for the biblio modules.
 */
function _biblio_enable_collection_vocabulary() {
  if ($vocabulary = taxonomy_vocabulary_load(variable_get('biblio_collection_vocabulary', 0))) {

    // Existing install. Add back forum node type, if the biblio vocabulary
    // still exists. Keep all other node types intact there.
    $vocabulary = (array) $vocabulary;
    $vocabulary['nodes']['biblio'] = 1;
    taxonomy_save_vocabulary($vocabulary);
  }
  else {

    // Create the forum vocabulary if it does not exist. Assign the vocabulary a
    // low weight so it will appear first in forum topic create and edit forms.
    $vocabulary = array(
      'name' => 'Biblio Collections',
      'description' => 'You may organize your publications into collections by adding a collection names to this vocabulary',
      'help' => '',
      'nodes' => array(
        'biblio' => 1,
      ),
      'hierarchy' => 0,
      'relations' => 1,
      'tags' => 0,
      'multiple' => 1,
      'required' => 0,
      'weight' => 0,
      'module' => 'biblio',
    );
    taxonomy_save_vocabulary($vocabulary);
    variable_set('biblio_collection_vocabulary', $vocabulary['vid']);
    $default_collection = array(
      'name' => t('Default'),
      'description' => t("This is the collection that all biblio entries will be a part of if no other collection is selected. Deleting this term will render all your biblio entries inaccessable. (You've been warned!)"),
      'parent' => array(),
      'relations' => array(),
      'synonyms' => '',
      'weight' => 0,
      'vid' => variable_get('biblio_collection_vocabulary', 0),
    );
    taxonomy_save_term($default_collection);
  }
  return $vocabulary['vid'];
}

/**
 * Helper function to transfer biblio_keyword data to taxonomy vocabulary.
 * This function copies keywords from the biblio_keyword column of the biblio
 * table to a taxonomy vocabulary.
 *
 * @return array
 *   An associative array with two elements:
 *   - success: A boolean indicating success of the process.
 *   - query: A message about the condition of the process.
 */
function _biblio_add_keywords() {
  set_time_limit(300);
  $kw_sep = variable_get('biblio_keyword_sep', ',');
  $vid = ($vid = variable_get('biblio_keyword_vocabulary', 0)) ? $vid : _biblio_enable_keyword_vocabulary();
  if ($vid) {
    $db_result = db_query("SELECT b.biblio_keywords, b.nid, b.vid FROM {biblio} b");
    $result = array();
    while ($row = db_fetch_object($db_result)) {
      foreach (explode($kw_sep, $row->biblio_keywords) as $keyword) {
        $result[] = array(
          'value' => trim($keyword),
          'nid' => $row->nid,
          'vid' => $row->vid,
        );
      }
      db_query('DELETE tn.* FROM {term_node} tn INNER JOIN {term_data} td ON tn.tid = td.tid WHERE nid = %d AND td.vid = %d', $row->nid, $vid);
    }
    $inserted = array();
    $count = 0;
    foreach ($result as $keywords) {

      // See if the term exists in the chosen vocabulary and return the tid;
      // otherwise, add a new record.
      $possibilities = taxonomy_get_term_by_name($keywords['value']);

      // Used in determining a tid match (if any).
      $term_tid = NULL;
      foreach ($possibilities as $possibility) {
        if ($possibility->vid == $vid) {
          $term_tid = $possibility->tid;
        }
      }
      if (!$term_tid) {
        $term = array(
          'vid' => $vid,
          'name' => $keywords['value'],
        );
        $status = taxonomy_save_term($term);
        $term_tid = $term['tid'];
      }

      // Defend against duplicate and differently capitalized tags
      if (!isset($inserted[$keywords['vid']][$term_tid])) {
        db_query('INSERT INTO {term_node} (nid, vid, tid) VALUES (%d, %d, %d)', $keywords['nid'], $keywords['vid'], $term_tid);
        $inserted[$keywords['vid']][$term_tid] = TRUE;
        $count++;
      }
    }
    return array(
      'success' => TRUE,
      'query' => 'Added ' . $count . ' keywords to the biblio/taxonomy keyword vocabulary',
    );
  }
  return array(
    'success' => FALSE,
    'query' => 'Biblio keyword vocabulary not available',
  );
}
function biblio_db_field_exists($table, $column) {
  $sql = "SELECT 1 FROM information_schema.columns WHERE table_name='%s' and column_name='%s'";
  return (bool) db_result(db_query($sql, $table, $column));
}

/**
 * Implements hook_schema().
 *
 * The indentation in biblio_schema() slighlty varies from Drupal coding
 * conventions, but has been adjusted so all indetion here is consistent.
 *
 * @return array
 *   An associative array with data base table schemas defined for the biblio
 *   module keyed by the name of the data base tble.
 */
function biblio_schema() {
  $schema['biblio'] = array(
    // @todo: Missing description?
    'fields' => array(
      'nid' => array(
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'description' => '',
      ),
      'vid' => array(
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'description' => '',
      ),
      'biblio_type' => array(
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'description' => '',
      ),
      'biblio_number' => array(
        'type' => 'varchar',
        'not null' => FALSE,
        'length' => '128',
        'description' => '',
      ),
      'biblio_other_number' => array(
        'type' => 'varchar',
        'not null' => FALSE,
        'length' => '128',
        'description' => '',
      ),
      'biblio_sort_title' => array(
        'type' => 'varchar',
        'not null' => FALSE,
        'length' => '64',
        'description' => 'A normalized version of the title, used for sorting on titles. (only first 64 characters saved)',
      ),
      'biblio_secondary_title' => array(
        'type' => 'varchar',
        'not null' => FALSE,
        'length' => '255',
        'description' => '',
      ),
      'biblio_tertiary_title' => array(
        'type' => 'varchar',
        'not null' => FALSE,
        'length' => '255',
        'description' => '',
      ),
      'biblio_edition' => array(
        'type' => 'varchar',
        'not null' => FALSE,
        'length' => '255',
        'description' => '',
      ),
      'biblio_publisher' => array(
        'type' => 'varchar',
        'not null' => FALSE,
        'length' => '255',
        'description' => '',
      ),
      'biblio_place_published' => array(
        'type' => 'varchar',
        'not null' => FALSE,
        'length' => '255',
        'description' => '',
      ),
      'biblio_year' => array(
        'type' => 'int',
        'not null' => TRUE,
        'default' => 9999,
        'description' => '',
      ),
      'biblio_volume' => array(
        'type' => 'varchar',
        'not null' => FALSE,
        'length' => '128',
        'description' => '',
      ),
      'biblio_pages' => array(
        'type' => 'varchar',
        'not null' => FALSE,
        'length' => '128',
        'description' => '',
      ),
      'biblio_date' => array(
        'type' => 'varchar',
        'not null' => FALSE,
        'length' => '64',
        'description' => '',
      ),
      'biblio_isbn' => array(
        'type' => 'varchar',
        'not null' => FALSE,
        'length' => '128',
        'description' => '',
      ),
      'biblio_lang' => array(
        'type' => 'varchar',
        'not null' => FALSE,
        'length' => '24',
        'default' => 'eng',
        'description' => '',
      ),
      'biblio_abst_e' => array(
        'type' => 'text',
        'not null' => FALSE,
        'description' => '',
      ),
      'biblio_abst_f' => array(
        'not null' => FALSE,
        'type' => 'text',
        'description' => '',
      ),
      'biblio_full_text' => array(
        'type' => 'int',
        'not null' => FALSE,
        'default' => 0,
        'description' => '',
      ),
      'biblio_url' => array(
        'type' => 'varchar',
        'not null' => FALSE,
        'length' => '255',
        'description' => '',
      ),
      'biblio_issue' => array(
        'type' => 'varchar',
        'not null' => FALSE,
        'length' => '128',
        'description' => '',
      ),
      'biblio_type_of_work' => array(
        'type' => 'varchar',
        'not null' => FALSE,
        'length' => '128',
        'description' => '',
      ),
      'biblio_accession_number' => array(
        'type' => 'varchar',
        'not null' => FALSE,
        'length' => '128',
        'description' => '',
      ),
      'biblio_call_number' => array(
        'type' => 'varchar',
        'not null' => FALSE,
        'length' => '128',
        'description' => '',
      ),
      'biblio_notes' => array(
        'type' => 'text',
        'not null' => FALSE,
        'description' => '',
      ),
      'biblio_custom1' => array(
        'type' => 'text',
        'not null' => FALSE,
        'description' => '',
      ),
      'biblio_custom2' => array(
        'type' => 'text',
        'not null' => FALSE,
        'description' => '',
      ),
      'biblio_custom3' => array(
        'type' => 'text',
        'not null' => FALSE,
        'description' => '',
      ),
      'biblio_custom4' => array(
        'type' => 'text',
        'not null' => FALSE,
        'description' => '',
      ),
      'biblio_custom5' => array(
        'type' => 'text',
        'not null' => FALSE,
        'description' => '',
      ),
      'biblio_custom6' => array(
        'type' => 'text',
        'not null' => FALSE,
        'description' => '',
      ),
      'biblio_custom7' => array(
        'type' => 'text',
        'not null' => FALSE,
        'description' => '',
      ),
      'biblio_research_notes' => array(
        'type' => 'text',
        'not null' => FALSE,
        'description' => '',
      ),
      'biblio_number_of_volumes' => array(
        'type' => 'varchar',
        'not null' => FALSE,
        'length' => '128',
        'description' => '',
      ),
      'biblio_short_title' => array(
        'type' => 'varchar',
        'not null' => FALSE,
        'length' => '255',
        'description' => '',
      ),
      'biblio_alternate_title' => array(
        'type' => 'varchar',
        'not null' => FALSE,
        'length' => '255',
        'description' => '',
      ),
      'biblio_original_publication' => array(
        'type' => 'varchar',
        'not null' => FALSE,
        'length' => '255',
        'description' => '',
      ),
      'biblio_reprint_edition' => array(
        'type' => 'varchar',
        'not null' => FALSE,
        'length' => '255',
        'description' => '',
      ),
      'biblio_translated_title' => array(
        'type' => 'varchar',
        'not null' => FALSE,
        'length' => '255',
        'description' => '',
      ),
      'biblio_section' => array(
        'type' => 'varchar',
        'not null' => FALSE,
        'length' => '128',
        'description' => '',
      ),
      'biblio_citekey' => array(
        'type' => 'varchar',
        'not null' => FALSE,
        'length' => '255',
        'description' => '',
      ),
      'biblio_coins' => array(
        'type' => 'text',
        'not null' => FALSE,
        'description' => '',
      ),
      'biblio_doi' => array(
        'type' => 'varchar',
        'not null' => FALSE,
        'length' => '255',
        'description' => '',
      ),
      'biblio_issn' => array(
        'type' => 'varchar',
        'not null' => FALSE,
        'length' => '128',
        'description' => '',
      ),
      'biblio_auth_address' => array(
        'type' => 'text',
        'not null' => FALSE,
        'description' => '',
      ),
      'biblio_remote_db_name' => array(
        'type' => 'varchar',
        'not null' => FALSE,
        'length' => '255',
        'description' => '',
      ),
      'biblio_remote_db_provider' => array(
        'type' => 'varchar',
        'not null' => FALSE,
        'length' => '255',
        'description' => '',
      ),
      'biblio_label' => array(
        'type' => 'varchar',
        'not null' => FALSE,
        'length' => '255',
        'description' => '',
      ),
      'biblio_access_date' => array(
        'type' => 'varchar',
        'not null' => FALSE,
        'length' => '255',
        'description' => '',
      ),
      'biblio_refereed' => array(
        'type' => 'varchar',
        'not null' => FALSE,
        'length' => '20',
        'description' => '',
      ),
      'biblio_md5' => array(
        'type' => 'varchar',
        'not null' => FALSE,
        'length' => '32',
        'description' => '',
      ),
      'biblio_formats' => array(
        'type' => 'blob',
        'not null' => FALSE,
        'description' => '',
        'serialize' => TRUE,
      ),
    ),
    'foreign keys' => array(
      'node_revision' => array(
        'table' => 'node_revision',
        'columns' => array(
          'vid' => 'vid',
        ),
      ),
      'node' => array(
        'table' => 'node',
        'columns' => array(
          'nid' => 'nid',
        ),
      ),
      'biblio_type' => array(
        'table' => 'biblio_types',
        'columns' => array(
          'biblio_type' => 'tid',
        ),
      ),
    ),
    'primary key' => array(
      'vid',
    ),
    'indexes' => array(
      'nid' => array(
        'nid',
      ),
      'md5' => array(
        'biblio_md5',
      ),
      'year' => array(
        'biblio_year',
      ),
      'title_sort' => array(
        'biblio_sort_title',
      ),
      'date' => array(
        'biblio_date',
      ),
    ),
  );
  $schema['biblio_fields'] = array(
    // @todo: Missing description?
    'fields' => array(
      'fid' => array(
        'type' => 'int',
        'not null' => TRUE,
        'unsigned' => TRUE,
        'default' => 0,
        'description' => '{biblio_fields}.fid of the node',
      ),
      'name' => array(
        'type' => 'varchar',
        'length' => '128',
        'not null' => TRUE,
        'default' => '',
      ),
      'type' => array(
        'type' => 'varchar',
        'length' => '128',
        'not null' => TRUE,
        'default' => 'textfield',
      ),
      'size' => array(
        'type' => 'int',
        'not null' => TRUE,
        'unsigned' => TRUE,
        'default' => 60,
      ),
      'maxsize' => array(
        'type' => 'int',
        'not null' => TRUE,
        'unsigned' => TRUE,
        'default' => 255,
      ),
    ),
    'primary key' => array(
      'fid',
    ),
  );
  $schema['biblio_field_type'] = array(
    'description' => 'Relational table linking {biblio_fields} with {biblio_field_type_data}',
    'fields' => array(
      'tid' => array(
        'type' => 'int',
        'not null' => TRUE,
        'unsigned' => TRUE,
        'default' => 0,
        'description' => '{biblio_types}.tid of the node',
      ),
      'fid' => array(
        'type' => 'int',
        'not null' => TRUE,
        'unsigned' => TRUE,
        'default' => 0,
        'description' => '{biblio_fields}.fid of the node',
      ),
      'ftdid' => array(
        'type' => 'int',
        'not null' => TRUE,
        'unsigned' => TRUE,
        'default' => 0,
        'description' => '{biblio_field_type_data}.ftdid of the node, points to the current data, default or custom',
      ),
      'cust_tdid' => array(
        'type' => 'int',
        'not null' => TRUE,
        'unsigned' => TRUE,
        'default' => 0,
        'description' => 'This always points to the custom data for this field. Stored so we can switch back an forth between default and custom',
      ),
      'common' => array(
        'type' => 'int',
        'not null' => TRUE,
        'unsigned' => TRUE,
        'default' => 0,
      ),
      'autocomplete' => array(
        'type' => 'int',
        'not null' => TRUE,
        'unsigned' => TRUE,
        'default' => 0,
      ),
      'required' => array(
        'type' => 'int',
        'not null' => TRUE,
        'unsigned' => TRUE,
        'default' => 0,
        'description' => 'Is input required for this field',
      ),
      'weight' => array(
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'description' => 'The weight (location) of the field on the input form',
      ),
      'visible' => array(
        'type' => 'int',
        'not null' => TRUE,
        'unsigned' => TRUE,
        'default' => 0,
        'description' => 'Determines if the field is visible on the input form',
      ),
    ),
    'primary key' => array(
      'tid',
      'fid',
    ),
    'indexes' => array(
      'tid' => array(
        'tid',
      ),
    ),
  );
  $schema['biblio_field_type_data'] = array(
    'description' => 'Data used to build the form elements on the input form',
    'fields' => array(
      'ftdid' => array(
        'type' => 'int',
        'not null' => TRUE,
        'unsigned' => TRUE,
        'default' => 0,
        'description' => '{biblio_field_type_data}.ftdid of the node',
      ),
      'title' => array(
        'type' => 'varchar',
        'length' => '128',
        'not null' => TRUE,
        'default' => '',
        'description' => 'The title, which will be displayed on the form, for a given field',
      ),
      'hint' => array(
        'type' => 'varchar',
        'length' => '255',
        'not null' => FALSE,
        'description' => 'The hint text printed below the input widget',
      ),
    ),
    'primary key' => array(
      'ftdid',
    ),
  );
  $schema['biblio_types'] = array(
    // @todo: Missing description?
    'fields' => array(
      'tid' => array(
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'description' => '{biblio_types}.tid of the publication type',
      ),
      'name' => array(
        'type' => 'varchar',
        'length' => '64',
        'not null' => TRUE,
        'default' => '',
        'description' => 'The name of the publication type',
      ),
      'description' => array(
        'type' => 'varchar',
        'not null' => FALSE,
        'length' => '255',
        'description' => 'Description of the publication type',
      ),
      'weight' => array(
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'description' => 'Controls the order the types are listed in',
      ),
      'visible' => array(
        'type' => 'int',
        'not null' => TRUE,
        'unsigned' => TRUE,
        'default' => 1,
        'description' => 'Determines if the publication type is visible in the list',
      ),
    ),
    'primary key' => array(
      'tid',
    ),
  );
  $schema['biblio_contributor'] = array(
    'description' => 'Relational table linking authors to biblio entries',
    'fields' => array(
      'nid' => array(
        'type' => 'int',
        'not null' => TRUE,
        'unsigned' => TRUE,
        'default' => 0,
        'description' => '{node}.nid of the node',
      ),
      'vid' => array(
        'type' => 'int',
        'not null' => TRUE,
        'unsigned' => TRUE,
        'default' => 0,
        'description' => '{node}.vid of the node',
      ),
      'cid' => array(
        'type' => 'int',
        'not null' => TRUE,
        'unsigned' => TRUE,
        'default' => 0,
        'description' => '{biblio_contributor_data}.cid of the node',
      ),
      'auth_type' => array(
        'type' => 'int',
        'not null' => TRUE,
        'unsigned' => TRUE,
        'default' => 1,
        'description' => '{biblio_contributor_type}.auth_type of the node',
      ),
      'auth_category' => array(
        'type' => 'int',
        'not null' => TRUE,
        'unsigned' => TRUE,
        'default' => 1,
        'description' => '',
      ),
      'rank' => array(
        'type' => 'int',
        'not null' => TRUE,
        'unsigned' => TRUE,
        'default' => 0,
        'description' => 'Position of the author name on the publication (first,second,third...)',
      ),
      'merge_cid' => array(
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'unsigned' => TRUE,
        'description' => '',
      ),
    ),
    'foreign keys' => array(
      'node_revision' => array(
        'table' => 'node_revision',
        'columns' => array(
          'vid' => 'vid',
        ),
      ),
      'node' => array(
        'table' => 'node',
        'columns' => array(
          'nid' => 'nid',
        ),
      ),
      'biblio_contributor_data' => array(
        'table' => 'biblio_contributor_data',
        'columns' => array(
          'cid' => 'cid',
        ),
      ),
      'biblio_contributor_type' => array(
        'table' => 'biblio_contributor_type',
        'columns' => array(
          'auth_type' => 'auth_type',
        ),
      ),
      'biblio_contributor_category' => array(
        'table' => 'biblio_contributor_type',
        'columns' => array(
          'auth_category' => 'auth_category',
        ),
      ),
    ),
    'primary key' => array(
      'vid',
      'cid',
      'auth_type',
      'rank',
    ),
  );
  $schema['biblio_contributor_data'] = array(
    'description' => 'Contains Author information for each publication',
    'fields' => array(
      'cid' => array(
        'type' => 'serial',
        'not null' => TRUE,
        'unsigned' => TRUE,
        'description' => 'Primary Key: Author ID',
      ),
      'aka' => array(
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'unsigned' => TRUE,
        'description' => 'Also known as, links this author entry with others so you can have variation on the name, but listing by cid will find all other (aka) author entries',
      ),
      'alt_form' => array(
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'unsigned' => TRUE,
        'description' => 'Alternate form of an author name, this value points to the desired form (cid), this form is kept in the database so  that future imports of the same name will not create a new author.',
      ),
      'drupal_uid' => array(
        'type' => 'int',
        'not null' => FALSE,
        'unsigned' => TRUE,
        'description' => 'Drupal User ID',
      ),
      'name' => array(
        'type' => 'varchar',
        'length' => '255',
        'not null' => TRUE,
        'default' => '',
        'description' => 'Full name',
      ),
      'lastname' => array(
        'type' => 'varchar',
        'length' => '255',
        'not null' => TRUE,
        'default' => '',
        'description' => 'Author last name',
      ),
      'firstname' => array(
        'type' => 'varchar',
        'length' => '128',
        'not null' => FALSE,
        'default' => '',
        'description' => 'Author first name',
      ),
      'prefix' => array(
        'type' => 'varchar',
        'length' => '128',
        'not null' => FALSE,
        'default' => '',
        'description' => 'Author name prefix',
      ),
      'suffix' => array(
        'type' => 'varchar',
        'length' => '128',
        'not null' => FALSE,
        'default' => '',
        'description' => 'Author name suffix',
      ),
      'initials' => array(
        'type' => 'varchar',
        'length' => '10',
        'not null' => FALSE,
        'default' => '',
        'description' => 'Author initials (including first name initial)',
      ),
      'affiliation' => array(
        'type' => 'varchar',
        'length' => '255',
        'not null' => FALSE,
        'default' => '',
        'description' => 'Author affiliation or address',
      ),
      'literal' => array(
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'unsigned' => TRUE,
        'description' => 'Determines if the author name is allowed to be reformated by the variaous styles or should be used literally.',
      ),
      'md5' => array(
        'type' => 'varchar',
        'length' => '32',
        'not null' => FALSE,
        'description' => '',
      ),
    ),
    'foreign keys' => array(
      'biblio_contributor' => array(
        'table' => 'biblio_contributor',
        'columns' => array(
          'cid' => 'cid',
        ),
      ),
      'node_author' => array(
        'table' => 'users',
        'columns' => array(
          'drupal_uid' => 'uid',
        ),
      ),
    ),
    'primary key' => array(
      'cid',
    ),
    'indexes' => array(
      'name' => array(
        'name',
      ),
      'lastname' => array(
        'lastname',
      ),
      'firstname' => array(
        'firstname',
      ),
      'initials' => array(
        'initials',
      ),
    ),
  );
  $schema['biblio_contributor_aka_data'] = $schema['biblio_contributor_data'];
  $schema['biblio_contributor_aka_data']['description'] = 'Contains Alternate Author information for each publication';
  $schema['biblio_contributor_type'] = array(
    'description' => 'Contains definitions of the contributor types',
    'fields' => array(
      'auth_category' => array(
        'type' => 'int',
        'not null' => TRUE,
        'unsigned' => TRUE,
        'default' => 0,
        'description' => 'There are 5 catagoies of author: Primary, Secondary, Tertiery, Subsidary and Corporate  ',
      ),
      'biblio_type' => array(
        'type' => 'int',
        'not null' => TRUE,
        'unsigned' => TRUE,
        'default' => 0,
        'description' => '',
      ),
      'auth_type' => array(
        'type' => 'int',
        'not null' => TRUE,
        'unsigned' => TRUE,
        'default' => 0,
        'description' => 'This is the pulication type specific verion of a particular catagory',
      ),
    ),
    'foreign keys' => array(
      'biblio' => array(
        'table' => 'biblio',
        'columns' => array(
          'biblio_type' => 'biblio_type',
        ),
      ),
      'biblio_contributor_type' => array(
        'table' => 'biblio_contributor',
        'columns' => array(
          'auth_type' => 'auth_type',
        ),
      ),
      'biblio_contributor_category' => array(
        'table' => 'biblio_contributor',
        'columns' => array(
          'auth_category' => 'auth_category',
        ),
      ),
    ),
    'primary key' => array(
      'auth_category',
      'biblio_type',
      'auth_type',
    ),
  );
  $schema['biblio_contributor_type_data'] = array(
    'description' => 'Data used to build the form elements on the input form',
    'fields' => array(
      'auth_type' => array(
        'type' => 'serial',
        'not null' => TRUE,
        'unsigned' => TRUE,
        'description' => '{biblio_contributor_type_data} ctdid of the node',
      ),
      'title' => array(
        'type' => 'varchar',
        'length' => '128',
        'not null' => TRUE,
        'default' => '',
        'description' => 'The title, which will be displayed on the form, for a given field',
      ),
      'hint' => array(
        'type' => 'varchar',
        'length' => '255',
        'not null' => FALSE,
        'description' => 'The hint text printed below the input widget',
      ),
    ),
    'primary key' => array(
      'auth_type',
    ),
  );
  $schema['biblio_keyword'] = array(
    'description' => t('Relational table linking keywords to biblio nodes'),
    'fields' => array(
      'kid' => array(
        'type' => 'int',
        'not null' => TRUE,
        'unsigned' => TRUE,
        'default' => 0,
        'description' => t('Primary Key: The {biblio_keyword_data}.kid of the keyword of the node.'),
      ),
      'nid' => array(
        'type' => 'int',
        'not null' => TRUE,
        'unsigned' => TRUE,
        'default' => 0,
        'description' => t('The {node}.nid of the node.'),
      ),
      'vid' => array(
        'type' => 'int',
        'not null' => TRUE,
        'unsigned' => TRUE,
        'default' => 0,
        'description' => 'Primary Key: The {node}.vid of the node.',
      ),
    ),
    'foreign keys' => array(
      'node_revision' => array(
        'table' => 'node_revision',
        'columns' => array(
          'vid' => 'vid',
        ),
      ),
      'node' => array(
        'table' => 'node',
        'columns' => array(
          'nid' => 'nid',
        ),
      ),
      'keyword' => array(
        'table' => 'biblio_keyword_data',
        'columns' => array(
          'kid' => 'kid',
        ),
      ),
    ),
    'primary key' => array(
      'kid',
      'vid',
    ),
    'indexes' => array(
      'vid' => array(
        'vid',
      ),
      'nid' => array(
        'nid',
      ),
    ),
  );
  $schema['biblio_keyword_data'] = array(
    'description' => t('Stores the keywords related to nodes.'),
    'fields' => array(
      'kid' => array(
        'type' => 'serial',
        'not null' => TRUE,
        'unsigned' => TRUE,
        'description' => t('Primary Key: The id of the keyword assigned to the node'),
      ),
      'word' => array(
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
        'description' => t('The keyword'),
      ),
    ),
    'primary key' => array(
      'kid',
    ),
    'indexes' => array(
      'kword' => array(
        'word',
      ),
    ),
  );
  $schema['biblio_collection'] = array(
    'description' => t('Relational table grouping biblio nodes into collections'),
    'fields' => array(
      'cid' => array(
        'type' => 'int',
        'not null' => TRUE,
        'unsigned' => TRUE,
        'default' => 0,
        'description' => t('Primary Key: The {biblio_collection_data}.cid of the collection'),
      ),
      'vid' => array(
        'type' => 'int',
        'not null' => TRUE,
        'unsigned' => TRUE,
        'default' => 0,
        'description' => t('Primary Key: The {node}.vid of the node.'),
      ),
      'pid' => array(
        'type' => 'int',
        'not null' => TRUE,
        'unsigned' => TRUE,
        'default' => 0,
        'description' => t('The parent id of the collection'),
      ),
      'nid' => array(
        'type' => 'int',
        'not null' => TRUE,
        'unsigned' => TRUE,
        'default' => 0,
        'description' => t('The {node}.nid of the node.'),
      ),
    ),
    'primary key' => array(
      'cid',
      'vid',
    ),
    'indexes' => array(
      'pid' => array(
        'pid',
      ),
      'nid' => array(
        'nid',
      ),
    ),
  );
  $schema['biblio_collection_type'] = array(
    'description' => t('Descriptions of the collections.'),
    'fields' => array(
      'cid' => array(
        'type' => 'int',
        'not null' => TRUE,
        'unsigned' => TRUE,
        'default' => 0,
        'description' => t('Primary Key: The id of the collection'),
      ),
      'name' => array(
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
        'description' => t('The name of the collection'),
      ),
      'description' => array(
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
        'description' => t('The description of the collection'),
      ),
    ),
    'primary key' => array(
      'cid',
    ),
    'indexes' => array(
      'name' => array(
        'name',
      ),
    ),
  );
  $schema['biblio_duplicates'] = array(
    'description' => t('Relational table linking possible duplicate biblio nodes'),
    'fields' => array(
      'vid' => array(
        'type' => 'int',
        'not null' => TRUE,
        'unsigned' => TRUE,
        'default' => 0,
        'description' => t('Primary Key: The {biblio}.nid of the original node'),
      ),
      'did' => array(
        'type' => 'int',
        'not null' => TRUE,
        'unsigned' => TRUE,
        'default' => 0,
        'description' => t('The {biblio}.nid of the newly imported node which may be a duplicate.'),
      ),
      'type' => array(
        'type' => 'int',
        'not null' => TRUE,
        'unsigned' => TRUE,
        'default' => 0,
        'description' => t('The type of duplicate 0=biblio, 1=author.'),
      ),
    ),
    'primary key' => array(
      'vid',
      'did',
    ),
    'indexes' => array(
      'did' => array(
        'vid',
      ),
    ),
  );
  $schema['biblio_import_cache'] = array(
    'description' => 'tables used for caching data imported from file and then batch processed',
    'fields' => array(
      'id' => array(
        'type' => 'serial',
        'not null' => TRUE,
        'unsigned' => TRUE,
      ),
      'session_id' => array(
        'type' => 'varchar',
        'length' => 45,
        'not null' => TRUE,
      ),
      'data' => array(
        'description' => t('A collection of data to cache.'),
        'type' => 'blob',
        'not null' => FALSE,
        'size' => 'big',
      ),
    ),
    'primary key' => array(
      'id',
    ),
  );
  $schema['biblio_type_maps'] = array(
    'description' => 'Table used to store the mapping information between various file formats and the biblio schema',
    'fields' => array(
      'format' => array(
        'description' => 'The import/export file format',
        'type' => 'varchar',
        'length' => 128,
        'not null' => TRUE,
      ),
      'type_map' => array(
        'description' => 'The mapping between the publication types in the file format and biblio',
        'type' => 'text',
        'not null' => FALSE,
      ),
      'type_names' => array(
        'description' => 'The human readable names of the publication types',
        'type' => 'text',
        'not null' => FALSE,
      ),
      'field_map' => array(
        'description' => 'The mapping between the fields in the file format and biblio',
        'type' => 'text',
        'not null' => FALSE,
      ),
      'export_map' => array(
        'description' => 'which fields are exported',
        'type' => 'text',
        'not null' => FALSE,
      ),
    ),
    'primary key' => array(
      'format',
    ),
  );
  $schema['cache_biblio_csl_object'] = drupal_get_schema_unprocessed('system', 'cache');
  $schema['cache_biblio_csl_object']['description'] = 'Cache table for biblio to store pre-built csl objects.';
  $schema['cache_biblio_csl_object']['fields']['serialized']['default'] = 1;
  return $schema;
}

/**
 * Helper function to reset all field defintions to their defaults.
 *
 * @see biblio_admin_types_reset_form_submit()
 */
function biblio_reset_types() {
  $result = array();
  db_drop_table($result, 'biblio_field_type_data');
  db_drop_table($result, 'biblio_field_type');
  db_drop_table($result, 'biblio_fields');
  db_drop_table($result, 'biblio_contributor_type');
  db_drop_table($result, 'biblio_contributor_type_data');
  $schema = biblio_schema();
  db_create_table($result, 'biblio_field_type_data', $schema['biblio_field_type_data']);
  db_create_table($result, 'biblio_field_type', $schema['biblio_field_type']);
  db_create_table($result, 'biblio_fields', $schema['biblio_fields']);
  db_create_table($result, 'biblio_contributor_type', $schema['biblio_contributor_type']);
  db_create_table($result, 'biblio_contributor_type_data', $schema['biblio_contributor_type_data']);

  // Also reset the custom field type ID
  variable_set('biblio_last_ftdid', 100);
  _biblio_add_field_definitions();
  _biblio_types_customize_fields();
}

/**
 * Defines data for initial collection of biblio publication types.
 *
 * @return array
 *   An array of publication types where each publication type is an array that
 *   includes (in order) data about:
 *   - tid: The ID of the publication type.
 *   - name: The name of the publication type.
 *   - description: Controls the order the types are listed in.
 *   - weight: Controls the order the types are listed in.
 */
function _biblio_data_bibliographic_types() {
  $types = array();

  // Definitions about types of bibliographic material.
  $types[] = array(
    100,
    'Book',
    NULL,
    1,
  );
  $types[] = array(
    101,
    'Book Chapter',
    NULL,
    2,
  );
  $types[] = array(
    102,
    'Journal Article',
    NULL,
    3,
  );
  $types[] = array(
    131,
    'Journal',
    NULL,
    3,
  );
  $types[] = array(
    103,
    'Conference Paper',
    NULL,
    4,
  );
  $types[] = array(
    104,
    'Conference Proceedings',
    NULL,
    5,
  );
  $types[] = array(
    105,
    'Newspaper Article',
    NULL,
    6,
  );
  $types[] = array(
    106,
    'Magazine Article',
    NULL,
    7,
  );
  $types[] = array(
    107,
    'Web Article',
    NULL,
    8,
  );
  $types[] = array(
    132,
    'Website',
    NULL,
    8,
  );
  $types[] = array(
    133,
    'Web service',
    NULL,
    8,
  );
  $types[] = array(
    134,
    'Web project page',
    NULL,
    8,
  );
  $types[] = array(
    108,
    'Thesis',
    NULL,
    9,
  );
  $types[] = array(
    109,
    'Report',
    NULL,
    10,
  );
  $types[] = array(
    110,
    'Film',
    NULL,
    11,
  );
  $types[] = array(
    111,
    'Broadcast',
    NULL,
    12,
  );
  $types[] = array(
    112,
    'Artwork',
    NULL,
    13,
  );
  $types[] = array(
    113,
    'Software',
    NULL,
    14,
  );
  $types[] = array(
    114,
    'Audiovisual',
    NULL,
    15,
  );
  $types[] = array(
    115,
    'Hearing',
    NULL,
    16,
  );
  $types[] = array(
    116,
    'Case',
    NULL,
    17,
  );
  $types[] = array(
    117,
    'Bill',
    NULL,
    18,
  );
  $types[] = array(
    118,
    'Statute',
    NULL,
    19,
  );
  $types[] = array(
    119,
    'Patent',
    NULL,
    20,
  );
  $types[] = array(
    120,
    'Personal',
    NULL,
    21,
  );
  $types[] = array(
    121,
    'Manuscript',
    NULL,
    22,
  );
  $types[] = array(
    122,
    'Map',
    NULL,
    23,
  );
  $types[] = array(
    123,
    'Chart',
    NULL,
    24,
  );
  $types[] = array(
    124,
    'Unpublished',
    NULL,
    25,
  );
  $types[] = array(
    125,
    'Database',
    NULL,
    26,
  );
  $types[] = array(
    126,
    'Government Report',
    NULL,
    27,
  );
  $types[] = array(
    127,
    'Classical',
    NULL,
    28,
  );
  $types[] = array(
    128,
    'Legal Ruling',
    NULL,
    29,
  );
  $types[] = array(
    129,
    'Miscellaneous',
    NULL,
    30,
  );
  $types[] = array(
    130,
    'Miscellaneous Section',
    NULL,
    31,
  );
  $types[] = array(
    135,
    'Presentation',
    NULL,
    8,
  );
  return $types;
}

/**
 * Populates {biblio_types} table with initial bibliographvic type data.
 *
 * @return array
 *   An array of arrays with data summarizing attempts to insert records into
 *   {biblio_types} table where each array has the following key/value pairs:
 *   - success: A boolean indicating whether the query succeeded.
 *   - query: The SQL query(s) executed, passed through check_plain().
 */
function _biblio_add_bibliographic_types() {
  $result = array();
  $types = _biblio_data_bibliographic_types();
  foreach ($types as $record) {
    $result[] = update_sql("INSERT INTO {biblio_types} (tid, name, description, weight) VALUES ('" . implode("', '", $record) . "')");
  }
  return $result;
}

/**
 * Adds biblio field definitions to fields tables based upon data in a CSV file.
 *
 * This function reads data from the CSV file biblio.field.link.data.csv and
 * uses that information to create field type definitions as well as contributor
 * type definition records in the appropriate field-related tables for the
 * biblio module.
 *
 * @return array
 *   An array of data summarizing attempts to add custom field data to tables
 *   with the following keys:
 *   - success: A boolean indicating success in this operation.
 *   - query: A message string with further information about operation success.
 */
function _biblio_add_field_definitions() {
  global $db_type;
  $csv_file = drupal_get_path('module', 'biblio') . '/misc/biblio.field.link.data.csv';

  // Immediately return if handle to CSV file cannot be obtained.
  if (($handle = fopen($csv_file, "r")) === FALSE) {
    $result = array(
      'success' => FALSE,
      'query' => 'Could not open CSV file ' . $csv_file,
    );
    return $result;
  }

  // Get the column names of all three biblio tables used for defining fields.
  $schema = biblio_schema();
  $fields_columns = array_keys($schema['biblio_fields']['fields']);
  $field_type_columns = array_keys($schema['biblio_field_type']['fields']);
  $field_type_data_columns = array_keys($schema['biblio_field_type_data']['fields']);

  // @todo: Add comment explaining these non-obvious queries.
  if ($db_type == 'mysql' or $db_type == 'mysqli') {
    db_query("/*!40000 ALTER TABLE {biblio_field_type_data} DISABLE KEYS */;");
    db_query("/*!40000 ALTER TABLE {biblio_fields} DISABLE KEYS */;");
  }

  // Prepare array keyed by IDs of bibliographic types.
  $biblio_types = array();
  foreach (_biblio_data_bibliographic_types() as $key => $type) {
    $biblio_types[$type[0]] = $type[1];
  }

  // The first line of CSV files contains the field names.
  $header = fgetcsv($handle, 10000, ",");
  while (($row = fgetcsv($handle, 10000, ",")) !== FALSE) {
    $column = 0;

    // Add data for both the default biblio type (0) and all other biblio types
    // defined in _biblio_data_bibliographic_types().
    foreach (array_merge(array(
      0,
    ), array_keys($biblio_types)) as $t) {
      $field_type_values = array(
        $t,
        // tid: ID of the bibliographic type.
        $row[0],
        // fid: {biblio_fields}.fid of the node.
        $row[0],
        // ftdid: {biblio_field_type_data}.ftdid of the node, points to the current data, default or custom.
        $row[0],
        // cust_tdid: This always points to the custom data for this field. Stored so we can switch back an forth between default and custom.
        $row[3],
        // common:
        $row[4],
        // autocomplete:
        $row[5],
        // required: Is input required for this field?
        $row[6],
        // weight: The weight (location) of the field on the input form.
        $row[7],
      );
      db_query("INSERT INTO {biblio_field_type} (" . implode(", ", $field_type_columns) . ") " . "VALUES ('" . implode("', '", $field_type_values) . "')");
    }
    $field_type_data_values = array(
      $row[0],
      // ftdid: ID of this type of field.
      $row[1],
      // title: The title, which will be displayed on the form, for a given field.
      $row[2],
    );
    db_query("INSERT INTO {biblio_field_type_data} (" . implode(", ", $field_type_data_columns) . ") " . "VALUES('" . implode("', '", $field_type_data_values) . "')");
    $fields_values = array(
      $row[0],
      // fid: ID of this type of field.
      $row[8],
      // name: Name of this type of field.
      $row[9],
      // type: Type of form element for entering data for this field.
      $row[10],
      // size: Default size of this form element.
      $row[11],
    );
    db_query("INSERT INTO {biblio_fields} (" . implode(", ", $fields_columns) . ") " . "VALUES('" . implode("', '", $fields_values) . "')");

    // If appropriate, add contributor_type to tables.
    if ($row[9] == 'contrib_widget') {

      // Use field name without trailing 's' as initial guess for author type.
      $auth_type = substr($row[1], -1, 1) == 's' ? substr($row[1], 0, -1) : $row[1];
      db_query("INSERT INTO {biblio_contributor_type_data} (auth_type, title) VALUES (%d, '%s')", $row[0], $auth_type);
      db_query("INSERT INTO {biblio_contributor_type} (auth_category, biblio_type, auth_type) VALUES (%d, %d, %d)", $row[0], 0, $row[0]);
    }
  }
  fclose($handle);

  // @todo: Add comment explaining this non-obvious step about keys.
  if ($db_type == 'mysql' or $db_type == 'mysqli') {
    db_query("/*!40000 ALTER TABLE {biblio_field_type_data} ENABLE KEYS */;");
    db_query("/*!40000 ALTER TABLE {biblio_fields} ENABLE KEYS */;");
  }
  $result = array(
    'success' => TRUE,
    'query' => 'Added field titles and default values',
  );
  return $result;
}

/**
 * Creates customized fields for bibliographic types based on a CSV data file.
 *
 * This function reads data from the CSV file biblio.field.type.data.csv and
 * uses that information to create custom fields that can be used by various
 * types of biblio content.
 *
 * @return array
 *   An array of data summarizing attempts to add custom field data to tables
 *   with the following keys:
 *   - success: A boolean indicating success in this operation.
 *   - query: A message string with further information about operation success.
 */
function _biblio_types_customize_fields() {

  // Set the name of the CSV file with biblio field type mapping data.
  $csv_file = drupal_get_path('module', 'biblio') . '/misc/biblio.field.type.data.csv';

  // Immediately return if handle to CSV file cannot be obtained.
  if (($handle = fopen($csv_file, "r")) === FALSE) {
    $result = array(
      'success' => FALSE,
      'query' => 'Could not open CSV file ' . $csv_file,
    );
    return $result;
  }

  // Default for first contributor_type_data ID.
  $next_ctdid = 10;

  // Determine the column names defined in the {biblio_field_type_data} table.
  $schema = biblio_schema();
  $fieldnames = array_keys($schema['biblio_field_type_data']['fields']);

  // Create array for mapping biblio field machine names to their field IDs.
  $field_map = array();
  $resource = db_query("SELECT fid, name FROM {biblio_fields}");
  while ($row = db_fetch_object($resource)) {
    $field_map[$row->name] = $row->fid;
  }

  // Create array to map contributor field machine names to their field IDs.
  $contributor_map = array();
  $resource = db_query("SELECT fid, name FROM {biblio_fields} WHERE type = 'contrib_widget'");
  while ($row = db_fetch_object($resource)) {
    $contributor_map[$row->name] = $row->fid;
  }

  // Build field ID map array to speed field customization process.
  _biblio_field_id_by_name(NULL, NULL, NULL, array(
    'tablename' => 'biblio_field_type_data',
    'name_column' => 'title',
    'id_column' => 'ftdid',
  ));
  _biblio_field_id_by_name(NULL, NULL, NULL, array(
    'tablename' => 'biblio_contributor_type_data',
    'name_column' => 'title',
    'id_column' => 'auth_type',
  ));

  // First line of the CSV file contains the machine names of field types.
  $header = fgetcsv($handle, 10000, ",");

  // The second line has the default titles if none are set.
  $generic = fgetcsv($handle, 10000, ",");

  // Process all remaining rows in the CSV file.
  while (($row = fgetcsv($handle, 10000, ",")) !== FALSE) {
    $column = 0;
    if (empty($row[1])) {
      continue;
    }
    foreach ($header as $key => $field_name) {
      if (!empty($field_name) && $field_name != 'tid') {

        // @todo: Add comment about what this non-obvious condition this is for
        if (!empty($row[$column]) && $row[$column] != "~" && isset($field_map[$field_name])) {

          // Determine the value for ftdid field.
          $ftd[0] = ($existing_id = _biblio_field_id_by_name('biblio_field_type_data', $row[$column])) ? $existing_id : variable_get('biblio_last_ftdid', 100);

          // Determine the value for the title field.
          $ftd[1] = trim($row[$column]);

          // Default the value of the hint field to empty.
          $ftd[2] = "";
          $sql = "UPDATE {biblio_field_type} " . "SET ftdid = %d, cust_tdid = %d, visible = %d " . "WHERE tid = %d AND fid = %d ";
          db_query($sql, $ftd[0], $ftd[0], 1, $row[1], $field_map[$field_name]);
          if (!$existing_id) {

            // If this title does not already exist, then insert it.
            db_query("INSERT INTO {biblio_field_type_data} (" . implode(", ", $fieldnames) . ") " . "VALUES (%d, '%s', '%s')", $ftd);

            // Cache the new ftd value for future use.
            _biblio_field_id_by_name('biblio_field_type_data', $row[$column], $ftd[0]);

            // Incrment by one the ID for field type data.
            variable_set('biblio_last_ftdid', $ftd[0] + 1);
          }

          // Also populate contributor_type* tables.
          if (substr($field_name, -7, 7) == 'authors' && $row[$column] != '~') {
            $type = $contributor_map[$field_name];
            $title = trim($row[$column]);
            $biblio_type = $row[1];
            $ctdid = ($eid = _biblio_field_id_by_name('biblio_contributor_type_data', $title)) ? $eid : $next_ctdid;
            $sql = "UPDATE {biblio_contributor_type} SET auth_type=%d where auth_category=%d and biblio_type=%d";
            db_query($sql, $ctdid, $type, $biblio_type);
            if (!$eid) {
              $sql = "INSERT INTO {biblio_contributor_type_data} (auth_type, title) VALUES (%d, '%s')";
              db_query($sql, $ctdid, $title);

              // Cache the new contributor_type_data value for future use.
              _biblio_field_id_by_name('biblio_contributor_type_data', $title, $ctdid);

              // Increment the contributor_data_type counter.
              $next_ctdid++;
            }
          }
        }
        elseif ($row[$column] == "~" && isset($field_map[$field_name])) {

          // Turn off the visibility for this (~) field type.
          db_query("UPDATE {biblio_field_type}\n                    SET visible = 0\n                    WHERE tid = %d AND fid = %d ", $row[1], $field_map[$field_name]);
        }
        elseif (empty($row[$column]) && isset($field_map[$field_name])) {
          db_query("UPDATE {biblio_field_type}\n                    SET visible = 1\n                    WHERE tid = %d AND fid = %d ", $row[1], $field_map[$field_name]);
        }
      }
      $column++;
    }
  }
  fclose($handle);
  $result = array(
    'success' => TRUE,
    'query' => 'Added type specific field titles',
  );
  return $result;
}

/**
 * Maps CSV field data to table column names for fields in the biblio module.
 *
 * This function does what ...
 *
 * @param string $table
 *   The name of the database table.
 * @param string $csv_field
 *   The name of the field in input data file.
 * @param string $sql_field
 *   (optional) Name of the sql field that maps to $csv_field.
 * @param array $build
 *   (optional) An associative array with the following keys:
 *   - tablename: The name of the biblio table.
 *   - name_column: The label for this field from the CSV file.
 *   - id_column: The column name in SQL table for this field.
 *
 * return string|false
 *
 */
function _biblio_field_id_by_name($table, $csv_field, $sql_field = NULL, $build = NULL) {
  static $fields = NULL;

  // Reset the static $fields variable with data from the database table.
  if (!empty($build)) {
    unset($fields[$build['tablename']]);
    $sql = "SELECT " . $build['name_column'] . ", " . $build['id_column'] . " " . "FROM {" . $build['tablename'] . "}";
    $resource = db_query($sql);
    while ($row = db_fetch_array($resource)) {
      $fields[$build['tablename']][$row[$build['name_column']]] = $row[$build['id_column']];
    }
    return;
  }
  $name = trim($csv_field);
  if (isset($fields[$table][$name])) {
    return $fields[$table][$name];
  }
  if ($sql_field) {
    $fields[$table][$name] = $sql_field;
  }
  return FALSE;
}

/*
 * Removed updates 1 - 20 since they dated back to ver. 5-1.2
 */

/**
 * Update ...
 */
function biblio_update_21() {
  $result = array();
  $result[] = update_sql("ALTER TABLE {biblio}  ADD  `biblio_doi` varchar(100) default NULL;");
  $result[] = update_sql("ALTER TABLE {biblio}  ADD  `biblio_issn` varchar(24) default NULL;");
  $result[] = update_sql("INSERT INTO {biblio_fields} (`fid`,`name`,`title`,`common`,`type`,`size`,`maxsize`,`hint`,`required`,`visible`,`autocomplete`,`weight`) VALUES\n                        (45,'biblio_issn','ISSN Number',1,'textfield',24,24,'',0,0,0,150),\n                        (46,'biblio_doi','DOI',1,'textfield',60,255,'',0,0,0,159);");
  $result[] = update_sql("UPDATE {biblio_fields}  SET  title = 'ISBN Number' WHERE name = 'biblio_isbn';");
  return $result;
}

/**
 * Update ...
 */
function biblio_update_22() {
  global $db_type;
  $result = array();
  if ($db_type == 'pgsql') {
    $result[] = update_sql("alter table {biblio} alter column `biblio_custom1` type text ;");
    $result[] = update_sql("alter table {biblio} alter column `biblio_custom2` type text ;");
    $result[] = update_sql("alter table {biblio} alter column `biblio_custom3` type text ;");
    $result[] = update_sql("alter table {biblio} alter column `biblio_custom4` type text ;");
    $result[] = update_sql("alter table {biblio} alter column `biblio_custom5` type text ;");
    $result[] = update_sql("alter table {biblio} alter column `biblio_custom6` type text ;");
    $result[] = update_sql("alter table {biblio} alter column `biblio_custom7` type text ;");
  }
  else {
    $result[] = update_sql("alter table {biblio} modify `biblio_custom1` text ;");
    $result[] = update_sql("alter table {biblio} modify `biblio_custom2` text ;");
    $result[] = update_sql("alter table {biblio} modify `biblio_custom3` text ;");
    $result[] = update_sql("alter table {biblio} modify `biblio_custom4` text ;");
    $result[] = update_sql("alter table {biblio} modify `biblio_custom5` text ;");
    $result[] = update_sql("alter table {biblio} modify `biblio_custom6` text ;");
    $result[] = update_sql("alter table {biblio} modify `biblio_custom7` text ;");
  }
  $result[] = update_sql("UPDATE {biblio_fields}  SET  type = 'textarea',size=60,maxsize=65535 WHERE name LIKE 'biblio_custom%';");
  $result[] = update_sql("ALTER TABLE {biblio}  ADD  `biblio_auth_address` text ;");
  $result[] = update_sql("ALTER TABLE {biblio}  ADD  `biblio_remote_db_name` varchar(255) default NULL;");
  $result[] = update_sql("ALTER TABLE {biblio}  ADD  `biblio_remote_db_provider` varchar(255) default NULL;");
  $result[] = update_sql("ALTER TABLE {biblio}  ADD  `biblio_label` varchar(255) default NULL;");
  $result[] = update_sql("ALTER TABLE {biblio}  ADD  `biblio_access_date` varchar(255) default NULL;");
  $result[] = update_sql("INSERT INTO {biblio_fields} (`fid`,`name`,`title`,`common`,`type`,`size`,`maxsize`,`hint`,`required`,`visible`,`autocomplete`,`weight`) VALUES\n                        (47,'biblio_auth_address','Author Address',0,'textarea',60,65535,'',0,0,0,178),\n                        (48,'biblio_remote_db_name','Remote Database Name',0,'textfield',60,255,'',0,0,0,176),\n                        (49,'biblio_remote_db_provider','Remote Database Provider',0,'textfield',60,255,'',0,0,0,177),\n                        (50,'biblio_label','Label',0,'textfield',60,255,'',0,0,0,178),\n                        (51,'biblio_access_date','Access Date',0,'textfield',60,255,'',0,0,0,179)\n                        ;");
  return $result;
}

/**
 * Update ...
 */
function biblio_update_23() {
  $result = array();
  $result[] = update_sql("UPDATE {biblio}  SET  biblio_year = 9999 WHERE biblio_year = 0 ;");
  return $result;
}

/**
 * Update ...
 */
function biblio_update_24() {
  $result = array();
  $result[] = update_sql("UPDATE {biblio}  SET  biblio_year = 9998 WHERE biblio_year = 1 ;");
  $result[] = update_sql("UPDATE {biblio_fields} SET size = 9 WHERE name = 'biblio_year';");
  $result[] = update_sql("UPDATE {biblio_fields} SET maxsize = 9 WHERE name = 'biblio_year';");
  return $result;
}

/**
 * Update ...
 */
function biblio_update_25() {
  $result = array();
  $result[] = update_sql("UPDATE {biblio_fields} SET hint = '(YYYY, In Press or Submitted)' WHERE name = 'biblio_year';");
  return $result;
}

/**
 * Update ...
 */
function biblio_update_26() {
  $result = array();
  $result[] = update_sql("UPDATE {biblio}  SET  biblio_year = 9997 WHERE biblio_year = 9999 ;");
  $result[] = update_sql("UPDATE {biblio}  SET  biblio_year = 9999 WHERE biblio_year = 9998 ;");
  $result[] = update_sql("UPDATE {biblio}  SET  biblio_year = 9998 WHERE biblio_year = 9997 ;");
  $result[] = update_sql("UPDATE {biblio_fields} SET hint = '(Submitted, In Press or YYYY)' WHERE name = 'biblio_year';");
  return $result;
}

/**
 * Update ...
 */
function biblio_update_27() {
  global $db_type;
  $result = array();
  if ($db_type == 'pgsql') {
    $result[] = update_sql("ALTER TABLE {biblio_fields}  ALTER COLUMN hint TYPE varchar(255);");
  }
  else {
    $result[] = update_sql("ALTER TABLE {biblio_fields}  MODIFY hint varchar(255);");
  }
  return $result;
}

/**
 *
 */
function _biblio_move_field_data(&$result) {
  $schema = biblio_schema();

  // update default settings (tid=0) in biblio_field_type from old biblio_fields
  $result[] = update_sql("UPDATE {biblio_field_type_data} ftd, {biblio_field_type} ft\n    INNER JOIN {biblio_fields} f ON f.fid = ft.fid /* add biblio_fields.name */\n    INNER JOIN {biblio_fields_old} fo ON fo.name=f.name /* link to old biblio_fields by name */\n    SET ftd.title=fo.title, ftd.hint=fo.hint, ft.common=fo.common, ft.autocomplete=fo.autocomplete, ft.required=fo.required, ft.weight=fo.weight, ft.visible=fo.visible\n    WHERE ft.ftdid=ftd.ftdid AND ft.tid=0");

  // add new field types from old biblio_type_details
  $db_result = db_query("SELECT old.*,f.fid as fidnew FROM\n    /* biblio_type_details augmented by field name (biblio_*) */\n    (SELECT otd.*,fo.name FROM {biblio_type_details} otd\n     INNER JOIN {biblio_fields_old} fo ON otd.fid=fo.fid) old\n    /* left join: all entries from biblio_type_details are matched to existing entries in biblio_field_type_data */\n    LEFT JOIN {biblio_field_type_data} ftd ON old.title=ftd.title\n    /* add matching fids (fidnew) from new biblio_fields based on field name */\n    INNER JOIN {biblio_fields} f ON f.name=old.name\n    /* consider only those entries in biblio_type_details which have no match in biblio_field_type_data yet */\n    WHERE ftd.title IS NULL");
  while ($row = db_fetch_array($db_result)) {

    // check for presence of this field_type
    $fieldtype = db_fetch_array(db_query("SELECT * FROM {biblio_field_type_data} WHERE title='%s'", $row['title']));
    if (!is_array($fieldtype)) {
      $new_ftdid = variable_get('biblio_last_ftdid', 100);
      variable_set('biblio_last_ftdid', $new_ftdid + 1);
      $fieldtype = array(
        'ftdid' => $new_ftdid,
        'title' => $row['title'],
        'hint' => $row['hint'],
      );

      // write_record may not work if module is diabled.

      //drupal_write_record('biblio_field_type_data',$fieldtype);
      db_query("INSERT INTO {biblio_field_type_data} (ftdid, title, hint) VALUES(%d, '%s', '%s')", $fieldtype['ftdid'], $fieldtype['title'], $fieldtype['hint']);
    }

    // update ftdid in linking table to new field type
    $ftdid = $fieldtype['ftdid'];
    update_sql("UPDATE {biblio_field_type} SET ftdid={$ftdid}, cust_tdid={$ftdid} WHERE tid={$row['tid']} AND fid={$row['fidnew']}");
  }

  // update biblio_field_type (linking table) with overrides from old biblio_type_details
  $result[] = update_sql("UPDATE {biblio_field_type} ft\n    INNER JOIN {biblio_field_type_data} ftd ON ft.ftdid=ftd.ftdid\n    /* link to old biblio_type_details based on field title and publication type */\n    INNER JOIN {biblio_type_details} otd ON otd.title=ftd.title AND otd.tid=ft.tid\n    SET ft.required=otd.required, ft.weight=otd.weight");

  // update auth_type associated to (auth_category,biblio_type) from old biblio_type_details
  $result[] = update_sql("UPDATE {biblio_contributor_type} ct\n    INNER JOIN\n      /* select contributor fields from biblio_type_details (fid <= 4) and augment with new ctd.auth_type */\n      (SELECT tid,IF(fid=4,5,fid) AS auth_category,ctd.auth_type FROM {biblio_type_details} b\n        INNER JOIN {biblio_contributor_type_data} ctd ON b.title=ctd.title WHERE b.fid <= 4) otd\n      /* match on publication type and auth_category, fid=4 (corp. author) changed to catagory 5 */\n      ON otd.tid=ct.biblio_type AND otd.auth_category=ct.auth_category\n    SET ct.auth_type=otd.auth_type");
  return $result;
}

/**
 * Generates md5 hash values for biblio content.
 *
 * This function generates md5 hashes for all biblio content in the database.
 * These hashes are NOT used for security purposes, but rather to detect
 * potential duplicate entries when adding or importing new biblio content.
 *
 * @return array
 *  A result array with two keys: 'success' and 'query'.
 */
function biblio_md5_generate() {

  // this query assumes that the primary author (and only this) has rank=0
  $res = db_query("SELECT n.nid,n.vid, n.title, b.biblio_year, cd.lastname\n                   FROM {node} n INNER JOIN {biblio} b ON n.vid = b.vid\n                   INNER JOIN {biblio_contributor} c ON c.vid = b.vid\n                   INNER JOIN {biblio_contributor_data} cd ON cd.cid = c.cid\n                   WHERE c.rank = 0 AND c.auth_type = 1 AND n.type = 'biblio'");
  $count = 0;
  while ($node = db_fetch_object($res)) {
    $hash_string = str_replace(' ', '', drupal_strtolower($node->title));
    $hash_string .= str_replace(' ', '', drupal_strtolower($node->lastname));
    $hash_string .= $node->biblio_year;
    $md5 = md5($hash_string);
    db_query("UPDATE {biblio} SET biblio_md5 = '{$md5}' WHERE vid = {$node->vid}");
    $count++;
  }
  return array(
    'success' => TRUE,
    'query' => "Generated checksums for {$count} nodes",
  );
}

/**
 * Parses author name into components and populates array of name components.
 *
 * This parses the old (pre 6.x) format author entry, splits in on
 * the semicolons and adds new elements to the biblio_contributors array.
 *
 * @param array $biblio_contributors
 *   An array passed in by reference.
 * @param string $authors
 *   The author string in pre-Drupal 6 format.
 * @param integer $cat
 *   (optional) The type of author (Primary, Secondary, Tertiary, Corporate) as
 *   an integer ID.  The default is 1 (Primary).
 */
function _biblio_parse_authors(&$biblio_contributors, $authors, $cat = 1) {
  $authors = str_ireplace(" and ", "; ", $authors);
  $authors = str_ireplace(" & ", "; ", $authors);
  $author_array = explode(';', $authors);
  $rank = 0;
  foreach ($author_array as $author) {

    // Insert spaces after firstname initials, if neccessary.
    $author = preg_replace("/\\.([^\\s-])/", ". \\1", trim($author));
    $biblio_contributors[$cat][] = array(
      'name' => $author,
      'auth_type' => $cat,
      'rank' => $rank++,
    );
  }
}

/**
 * Moves author data into biblio_contributor* tables.
 *
 * This function ...
 *
 * @return array
 *   An associative array.
 */
function _biblio_move_authors(&$result) {
  $disable = FALSE;

  // If the biblio module is disabled, enable it so drupal_get_schema will work.
  if (!module_exists('biblio')) {
    module_enable(array(
      'biblio',
    ));
    $disable = TRUE;
  }
  drupal_get_schema('biblio_contributor', TRUE);
  drupal_get_schema('biblio_contributor_data', TRUE);

  // Tthis update will move author information from existing {biblio} table to
  // the new {biblio_contributor_data} table and create the appropriate cross-
  // reference links in the {biblio_contributor) table.
  require_once drupal_get_path('module', 'biblio') . '/includes/biblio.contributors.inc';
  $res = db_query("SELECT nid,vid,biblio_authors, biblio_secondary_authors,biblio_tertiary_authors,biblio_corp_author FROM {biblio}");
  $count = 0;
  $count_success = 0;
  while ($biblio = db_fetch_array($res)) {
    $biblio_contributors = array();
    if (!empty($biblio['biblio_authors'])) {
      _biblio_parse_authors($biblio_contributors, $biblio['biblio_authors'], 1);
    }
    if (!empty($biblio['biblio_secondary_authors'])) {
      _biblio_parse_authors($biblio_contributors, $biblio['biblio_secondary_authors'], 2);
    }
    if (!empty($biblio['biblio_tertiary_authors'])) {
      _biblio_parse_authors($biblio_contributors, $biblio['biblio_tertiary_authors'], 3);
    }
    if (!empty($biblio['biblio_corp_author'])) {
      _biblio_parse_authors($biblio_contributors, $biblio['biblio_corp_author'], 5);
    }
    $biblio_contributors = biblio_parse_contributors($biblio_contributors);
    if (_biblio_save_contributors($biblio_contributors, $biblio['nid'], $biblio['vid'])) {
      $count_success++;
    }
    $count++;
  }

  // Change auth_type to match overrides set in old biblio_type_details.
  update_sql("UPDATE {biblio_contributor} c\n    /* augment by biblio_type from biblio */\n    INNER JOIN {biblio} b ON c.nid=b.nid AND c.vid=b.vid\n    /* augment by old config settings */\n    INNER JOIN\n      (SELECT tid,if(fid=4,5,fid) as auth_type,title FROM\n        /* select (tid,fid) specific titles from 5.x: biblio_fields_old contains the defaults, biblio_type_details the overrides */\n        (SELECT tid,fid,title FROM {biblio_type_details} WHERE fid<=4\n         UNION SELECT tid,fid,title FROM {biblio_fields_old}, {biblio_types} WHERE fid<=4 AND tid>=100) t\n       /* grouping by tid,fid removes the duplicate default title if an override is available */\n       GROUP BY tid,fid) otd\n    /* match old config (otd) and newly imported (with type 1,2,3,5 see above) on biblio_type and auth_type */\n    ON otd.tid=b.biblio_type AND otd.auth_type=c.auth_type\n    /* augment with new auth_type based on title */\n    INNER JOIN {biblio_contributor_type_data} ctd ON ctd.title=otd.title\n    /* update auth_type in biblio_contributor table */\n    SET c.auth_type=ctd.auth_type");
  if ($count_success == $count) {
    $message = 'Moved authors from ' . $count_success . ' / ' . $count . ' publications to the new database structure';
    $contributors = array(
      1 => 'biblio_authors',
      2 => 'biblio_secondary_authors',
      3 => 'biblio_tertiary_authors',
      4 => 'biblio_subsidiary_authors',
      5 => 'biblio_corp_author',
    );

    // If the authors were sucessfully moved, remove obsolete D5 columns from
    // {biblio} table (if they are still present).
    foreach ($contributors as $column) {
      if (db_column_exists('biblio', $column)) {
        db_drop_field($result, 'biblio', $column);
      }
    }
  }
  else {
    $count_fail = $count - $count_success;
    $message = 'There was a problem moving authors from ' . $count_fail . ' / ' . $count . ' publications to the new database structure. The existing author fields have been ' . 'retained in the database, go to the "admin/settings/biblio/author" page to try again.';
  }
  $result[] = array(
    'success' => $count_success == $count,
    'query' => $message,
  );

  // If the biblio module started as disabled, then set it back to that state.
  if ($disable) {
    module_disable(array(
      'biblio',
    ));
  }
  return;
}

/**
 * Update ...
 *
 * This update function ...
 *
 * @return array
 *   An array of associative arrays with 'success' and 'query' keys.
 */
function biblio_update_6000() {
  $result = array();
  $schema = biblio_schema();

  // modifications to biblio main table
  db_add_field($result, 'biblio', 'biblio_md5', array(
    'type' => 'varchar',
    'length' => '32',
  ));
  db_add_index($result, 'biblio', 'md5', array(
    'biblio_md5',
  ));
  $result[] = update_sql("ALTER TABLE {biblio} MODIFY biblio_year int NOT NULL DEFAULT '9999' ");
  $result[] = update_sql("ALTER TABLE {biblio}  MODIFY biblio_citekey varchar(255) ");
  $result[] = update_sql("CREATE TABLE {biblio_u5} (\n      `upgrade from 5` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,\n      PRIMARY KEY (`upgrade from 5`))");

  // move biblio_fields to biblio_fields_old for later usage
  $result[] = update_sql("ALTER TABLE {biblio_fields} RENAME TO {biblio_fields_old}");
  $result[] = update_sql("UPDATE {biblio_fields_old} SET name='biblio_corp_authors' WHERE name='biblio_corp_author'");

  // drop obsolete tables
  db_drop_table($result, 'biblio_author_index');
  db_drop_table($result, 'biblio_has_author');

  // create new tables
  db_create_table($result, 'biblio_fields', $schema['biblio_fields']);
  db_create_table($result, 'biblio_field_type', $schema['biblio_field_type']);
  db_create_table($result, 'biblio_field_type_data', $schema['biblio_field_type_data']);
  db_create_table($result, 'biblio_contributor', $schema['biblio_contributor']);
  db_create_table($result, 'biblio_contributor_data', $schema['biblio_contributor_data']);
  db_create_table($result, 'biblio_contributor_type', $schema['biblio_contributor_type']);
  db_create_table($result, 'biblio_contributor_type_data', $schema['biblio_contributor_type_data']);
  db_create_table($result, 'biblio_keyword', $schema['biblio_keyword']);
  db_create_table($result, 'biblio_keyword_data', $schema['biblio_keyword_data']);
  db_create_table($result, 'biblio_collection', $schema['biblio_collection']);
  db_create_table($result, 'biblio_collection_type', $schema['biblio_collection_type']);
  db_create_table($result, 'biblio_duplicates', $schema['biblio_duplicates']);

  // Fill the biblio_field* tables with default definition records.
  $result[] = _biblio_add_field_definitions();
  $result[] = _biblio_types_customize_fields();

  // move data
  _biblio_move_field_data($result);
  _biblio_move_authors($result);
  db_drop_table($result, 'biblio_fields_old');
  db_drop_table($result, 'biblio_type_details');
  $result[] = biblio_md5_generate();
  return $result;
}

/**
 * Update ...
 *
 * This update function ...
 *
 * @return array
 *   An array of associative arrays with 'success' and 'query' keys.
 */
function biblio_update_6011() {
  $result = array();
  $schema = biblio_schema();
  if (!db_table_exists('biblio_import_cache')) {
    db_create_table($result, 'biblio_import_cache', $schema['biblio_import_cache']);
  }
  return $result;
}

/**
 * Update ...
 *
 * This update function ...
 *
 * @return array
 *   An array of associative arrays with 'success' and 'query' keys.
 */
function biblio_update_6013() {
  $result = array();
  if (!db_column_exists('biblio_contributor', 'auth_category')) {

    // we don't need to do this if upgrading from 5.x
    db_add_field($result, 'biblio_contributor', 'auth_category', array(
      'type' => 'int',
      'not null' => TRUE,
      'unsigned' => TRUE,
      'default' => 1,
    ));
    $result[] = update_sql("UPDATE {biblio} b\n                          INNER JOIN {biblio_contributor} bc on b.vid = bc.vid\n                          LEFT JOIN  {biblio_contributor_type} bct on b.biblio_type = bct.biblio_type and bct.auth_type = bc.auth_type\n                          SET bc.auth_category=bct.auth_catagory");
    $result[] = update_sql("ALTER TABLE {biblio_contributor_type} CHANGE COLUMN auth_catagory auth_category INTEGER UNSIGNED NOT NULL DEFAULT 0,\n                          DROP PRIMARY KEY,\n                          ADD PRIMARY KEY USING BTREE(auth_category, biblio_type, auth_type)");
  }
  $result[] = update_sql("UPDATE {biblio_fields} SET maxsize=20 WHERE name='biblio_year'");
  return $result;
}

/**
 * Update ...
 *
 * This update function ...
 *
 * @return array
 *   An array of associative arrays with 'success' and 'query' keys.
 */
function biblio_update_6014() {
  $result = array();
  $contributors = array(
    2 => 'biblio_secondary_authors',
    3 => 'biblio_tertiary_authors',
    4 => 'biblio_subsidiary_authors',
    5 => 'biblio_corp_authors',
  );
  if (db_result(db_query('SELECT COUNT(*) FROM {biblio_fields} WHERE type="contrib_widget"')) == 1) {

    // create space for new contributor fields
    $result[] = update_sql("UPDATE {biblio_fields} f SET fid=fid + 4 WHERE fid>1 ORDER BY fid DESC");
    $result[] = update_sql("UPDATE {biblio_fields} f SET name='biblio_authors' WHERE fid=1");

    // add new contributor fields
    $row = array(
      'fid' => 0,
      'name' => '',
      'type' => 'contrib_widget',
      'size' => 60,
      'maxsize' => 255,
    );
    foreach ($contributors as $fid => $name) {
      $row['fid'] = $fid;
      $row['name'] = $name;
      $values[] = "('" . implode("', '", $row) . "')";
    }
    $result[] = update_sql('INSERT INTO {biblio_fields} VALUES ' . implode(', ', $values));

    // create space for new fields in field_type_data
    $result[] = update_sql("UPDATE {biblio_field_type_data} f SET ftdid=ftdid + 4 WHERE ftdid>1 AND ftdid<100 ORDER BY ftdid DESC");

    // add new field titles from author type + appended 's'
    $result[] = update_sql("INSERT INTO {biblio_field_type_data}\n                            SELECT auth_type AS ftdid, CONCAT(TRIM(ctd.title),'s') AS title, NULL AS hint\n                            FROM {biblio_contributor_type_data} ctd WHERE auth_type>1 AND auth_type<6");

    // create space for new fields in linking table
    $result[] = update_sql("UPDATE {biblio_field_type} ft SET fid=fid+4 WHERE fid>1 ORDER BY fid DESC");

    // shift ftdid and cust_tdid for non-custom ftids
    $result[] = update_sql("UPDATE {biblio_field_type} ft SET ftdid=ftdid+4 WHERE ftdid>1 AND ftdid<100");
    $result[] = update_sql("UPDATE {biblio_field_type} ft SET cust_tdid=cust_tdid+4 WHERE cust_tdid>1 AND ftdid<100");

    // add linking data for new fields
    $result[] = update_sql("INSERT INTO {biblio_field_type}\n                            SELECT tid,ftd.ftdid,ftd.ftdid,ftd.ftdid,1,1,1,2 AS weight,1\n                            FROM {biblio_field_type} ft, {biblio_field_type_data} ftd\n                            WHERE ft.fid=1 AND ftd.ftdid > 1 AND ftd.ftdid < 6");

    // add default linking for author categories => author types
    $result[] = update_sql("INSERT INTO {biblio_contributor_type}\n                            SELECT auth_type,0,auth_type FROM {biblio_contributor_type_data} ctd WHERE auth_type<10");
  }

  // remove obsolete D5 columns from biblio table (if they are present)
  return $result;
}

/**
 * Update ...
 *
 * This update function ...
 *
 * @return array
 *   An array of associative arrays with 'success' and 'query' keys.
 */
function biblio_update_6015() {
  require_once drupal_get_path('module', 'biblio') . '/includes/biblio.keywords.inc';
  $result = array();
  if ($vid = variable_get('biblio_freetagging_vocab', 0)) {
    variable_set('biblio_keyword_vocabulary', $vid);
  }
  variable_del('biblio_freetagging_vocab');
  $result[] = update_sql("ALTER TABLE {biblio_keyword_data} MODIFY COLUMN kid INTEGER UNSIGNED NOT NULL AUTO_INCREMENT");
  $db_result = db_query('SELECT t.nid, t.vid, td.name as biblio_keywords FROM {term_node} t left join {term_data} td on t.tid=td.tid where td.vid=%d', variable_get('biblio_keyword_vocabulary', -1));
  $count = 0;
  while ($node = db_fetch_object($db_result)) {
    biblio_insert_keywords($node, TRUE);
    $count++;
  }
  $result[] = array(
    'success' => TRUE,
    'query' => "Copied {$count} keywords to the new database stucture from taxonomy",
  );
  $count = 0;
  $db_result = db_query('SELECT nid,vid,biblio_keywords FROM {biblio} where biblio_keywords != "" ');
  while ($node = db_fetch_object($db_result)) {
    biblio_insert_keywords($node, TRUE);
    $count++;
  }
  $result[] = array(
    'success' => TRUE,
    'query' => "Moved " . $count . " keywords to the new database stucture",
  );
  db_drop_field($result, 'biblio', 'biblio_keywords');
  return $result;
}

/**
 * Update ...
 *
 * This update function ...
 *
 * @return array
 *   An array of associative arrays with 'success' and 'query' keys.
 */
function biblio_update_6016() {
  $result = array();
  $result[] = update_sql("ALTER TABLE {biblio}\n                          MODIFY COLUMN biblio_number             VARCHAR(24),\n                          MODIFY COLUMN biblio_section            VARCHAR(24),\n                          MODIFY COLUMN biblio_volume             VARCHAR(24),\n                          MODIFY COLUMN biblio_number_of_volumes  VARCHAR(24),\n                          MODIFY COLUMN biblio_issue              VARCHAR(24),\n                          MODIFY COLUMN biblio_doi                VARCHAR(255)");
  return $result;
}

/**
 * Update ...
 *
 * This update function ...
 *
 * @return array
 *   An array of associaive arrays with 'success' and 'query' keys.
 */
function biblio_update_6017() {
  if (!db_column_exists('biblio_contributor_data', 'aka')) {

    // we don't need to do this if upgrading from 5.x
    $result = array();
    $result[] = update_sql("ALTER TABLE {biblio_contributor_data} ADD COLUMN aka INTEGER UNSIGNED ");
    return $result;
  }
}

/**
 * Update ...
 *
 * This update function ...
 *
 * @return array
 *   An array of associaive arrays with 'success' and 'query' keys.
 */
function biblio_update_6018() {
  $result = array();
  $result[] = update_sql("UPDATE {biblio_contributor_data} SET aka = cid WHERE aka = 0 OR aka IS NULL");
  if (!db_table_exists('biblio_u5')) {

    // we don't need to do this if upgrading from 5.x
    db_drop_primary_key($result, 'biblio_contributor_data');
    db_add_primary_key($result, 'biblio_contributor_data', array(
      'cid',
      'aka',
    ));
  }
  $result[] = update_sql("UPDATE {biblio_field_type_data} SET title = 'Keywords' WHERE title = 'Key Words' ");
  if (db_table_exists('biblio_u5')) {
    db_drop_table($result, 'biblio_u5');
  }
  return $result;
}

/**
 * Update ...
 *
 * This update function ...
 *
 * @return array
 *   An array of associaive arrays with 'success' and 'query' keys.
 */
function biblio_update_6019() {
  $result = array();
  $result[] = update_sql("UPDATE {biblio_fields} SET maxsize = 1000 WHERE name = 'biblio_keywords' ");
  return $result;
}

/**
 * Update ...
 *
 * This update function ...
 *
 * @return array
 *   An array of associaive arrays with 'success' and 'query' keys.
 */
function biblio_update_6020() {

  // add new 'access biblio content' permission to any role which has 'access content'
  $result = array();
  $dbresult = db_query('SELECT p.* FROM {permission} p');
  while ($role = db_fetch_object($dbresult)) {
    if (strpos($role->perm, 'access content') !== FALSE) {
      $role->perm = 'access biblio content, ' . $role->perm;
      $result[] = update_sql("UPDATE {permission} SET perm = '{$role->perm}' WHERE rid = {$role->rid}");
    }
  }
  return $result;
}

/**
 * Update ...
 *
 * This update function ...
 *
 * @return array
 *   An array of associaive arrays with 'success' and 'query' keys.
 */
function biblio_update_6021() {
  $result = array();
  db_change_field($result, 'biblio', 'biblio_number', 'biblio_number', array(
    'type' => 'varchar',
    'length' => '128',
  ));
  db_change_field($result, 'biblio', 'biblio_other_number', 'biblio_other_number', array(
    'type' => 'varchar',
    'length' => '128',
  ));
  db_change_field($result, 'biblio', 'biblio_volume', 'biblio_volume', array(
    'type' => 'varchar',
    'length' => '128',
  ));
  db_change_field($result, 'biblio', 'biblio_isbn', 'biblio_isbn', array(
    'type' => 'varchar',
    'length' => '128',
  ));
  db_change_field($result, 'biblio', 'biblio_issue', 'biblio_issue', array(
    'type' => 'varchar',
    'length' => '128',
  ));
  db_change_field($result, 'biblio', 'biblio_type_of_work', 'biblio_type_of_work', array(
    'type' => 'varchar',
    'length' => '128',
  ));
  db_change_field($result, 'biblio', 'biblio_accession_number', 'biblio_accession_number', array(
    'type' => 'varchar',
    'length' => '128',
  ));
  db_change_field($result, 'biblio', 'biblio_call_number', 'biblio_call_number', array(
    'type' => 'varchar',
    'length' => '128',
  ));
  db_change_field($result, 'biblio', 'biblio_number_of_volumes', 'biblio_number_of_volumes', array(
    'type' => 'varchar',
    'length' => '128',
  ));
  db_change_field($result, 'biblio', 'biblio_section', 'biblio_section', array(
    'type' => 'varchar',
    'length' => '128',
  ));
  db_change_field($result, 'biblio', 'biblio_issn', 'biblio_issn', array(
    'type' => 'varchar',
    'length' => '128',
  ));
  return $result;
}

/**
 * Update ...
 *
 * This update function ...
 *
 * @return array
 *   An array of associative arrays with 'success' and 'query' keys.
 */
function biblio_update_6022() {
  $result = array();
  $result[] = update_sql("UPDATE {biblio_fields} SET maxsize = 128 WHERE name = 'biblio_number'\n                          OR name = 'biblio_other_number'\n                          OR name = 'biblio_volume'\n                          OR name = 'biblio_isbn'\n                          OR name = 'biblio_issue'\n                          OR name = 'biblio_type_of_work'\n                          OR name = 'biblio_accession_number'\n                          OR name = 'biblio_call_number'\n                          OR name = 'biblio_number_of_volumes'\n                          OR name = 'biblio_section'\n                          OR name = 'biblio_issn' ");
  return $result;
}

/*
 * Update ...
 *
 * Add the new field -refereed- on the biblio table
 *
 * @return array
 *   An array of associative arrays with 'success' and 'query' keys.
 */
function biblio_update_6024() {
  $result = array();
  db_add_field($result, 'biblio', 'biblio_refereed', array(
    'type' => 'varchar',
    'length' => '20',
  ));

  /* add the field data for -refereed- on the biblo_fields table
     you need to get the last inserted record from biblio_fields and increment it by one
     so you don't step on customized fields added via the user online interface */
  $sql = 'SELECT fid FROM {biblio_fields} ORDER BY fid DESC LIMIT 1';
  $lastfid = db_result(db_query($sql));
  $newfid = $lastfid + 1;
  $result[] = update_sql("INSERT INTO {biblio_fields} (fid, name, type, size, maxsize) VALUES\n                        ({$newfid}, 'biblio_refereed', 'select', 0, 125)");

  /*use the same fid and insert an entry in the biblio_field_type_data */
  $result[] = update_sql("INSERT INTO {biblio_field_type_data}\n       (ftdid, title, hint) VALUES ({$newfid}, 'Refereed Designation', NULL)");

  /* get a list of unique tids from the biblio_field_type table.  You want to
     insert a tid,fid using the new fid for every available tid */
  $newsql = "SELECT DISTINCT tid FROM {biblio_field_type} ORDER BY tid DESC";
  $tidlist = db_query($newsql);
  while ($db_result = db_fetch_array($tidlist)) {
    $newtid = $db_result['tid'];
    db_query('INSERT INTO {biblio_field_type}
      (tid, fid, ftdid, cust_tdid, common, autocomplete, required, weight, visible)
       VALUES (%d, %d, %d, %d, %d, %d, %d, %d, %d)', $newtid, $newfid, $newfid, $newfid, 1, 1, 0, 1, 1);
  }
  return $result;
}

/**
 * Update ...
 *
 * This update function ...
 *
 * @return array
 *   An array of associaive arrays with 'success' and 'query' keys.
 */
function biblio_update_6025() {
  $result = array();
  $schema = biblio_schema();
  db_create_table($result, 'biblio_type_maps', $schema['biblio_type_maps']);
  return $result;
}

/**
 * Update ...
 *
 * This update function ...
 *
 * @return array
 *   An array of associaive arrays with 'success' and 'query' keys.
 */
function biblio_update_6026() {
  $result = array();

  // Move custom block titles stored in variable "biblio_block_title" to the
  // block table if the title has not already been overriden.
  $custom_title = variable_get('biblio_block_title', '');
  if (!empty($custom_title)) {
    $db_result = db_query("SELECT bid,title FROM {blocks} b where module='biblio'");
    while ($block = db_fetch_object($db_result)) {
      if (empty($block->title)) {
        $block->title = $custom_title;
        $result[] = update_sql("UPDATE {blocks} SET title='" . $block->title . "' WHERE bid=" . $block->bid);
      }
    }
    variable_del('biblio_block_title');
  }
  return $result;
}

/**
 * Update ...
 *
 * This update function ...
 *
 * @return array
 *   An array of associaive arrays with 'success' and 'query' keys.
 */
function biblio_update_6027() {

  // Renunmber the author rank such that it is zero based across all categories.
  // This only needs to be performed on biblio entries that actually have
  // auth_categories other than 1.
  require_once drupal_get_path('module', 'biblio') . '/includes/biblio.contributors.inc';
  $result = array();
  $count = 0;
  $db_result = db_query("SELECT DISTINCT(vid),nid FROM {biblio_contributor} WHERE auth_category IN (2,3,4,5) ");
  $db_count_result = db_query("SELECT COUNT(DISTINCT(vid)) FROM {biblio_contributor} WHERE auth_category IN (2,3,4,5) ");
  $count_success = db_result($db_count_result);
  while ($node = db_fetch_object($db_result)) {
    $contributors = biblio_load_contributors($node->vid);
    _biblio_save_contributors($contributors, $node->nid, $node->vid, $update = FALSE);
    $count++;
  }
  $message = "Reordered the authors on {$count}/{$count_success} nodes";
  $result[] = array(
    'success' => $count_success == $count,
    'query' => $message,
  );
  return $result;
}

/**
 * Update ...
 *
 * This update function ...
 *
 * @return array
 *   An array of associaive arrays with 'success' and 'query' keys.
 */
function biblio_update_6028() {
  $result = array();
  $table = drupal_get_schema_unprocessed('system', 'cache');
  $table['description'] = 'Cache table for biblio to store pre-built csl objects';
  $table['fields']['serialized']['default'] = 1;
  db_create_table($result, 'cache_biblio_csl_object', $table);
  return $resultt;
}

/**
 * Update ...
 *
 * This update function ...
 *
 * @return array
 *   An array of associaive arrays with 'success' and 'query' keys.
 */
function biblio_update_6029() {
  $result = array();
  $spec = array(
    'type' => 'blob',
    'not null' => FALSE,
    'default' => NULL,
    'size' => 'big',
    'description' => 'Stores the mapping between biblio fields and external file formats',
  );
  db_add_field($result, 'biblio_type_maps', 'export_map', $spec);
  return $result;
}

/**
 * Update ...
 *
 * This update function ...
 *
 * @return array
 *   An array of associaive arrays with 'success' and 'query' keys.
 */
function biblio_update_6030() {
  $result = array();
  $spec = array(
    'type' => 'int',
    'not null' => TRUE,
    'default' => 0,
    'unsigned' => TRUE,
    'description' => 'Determines if the author name is allowed to be reformated by the variaous styles or should be used literally.',
  );
  db_add_field($result, 'biblio_contributor_data', 'literal', $spec);
  return $result;
}

/**
 * Update ...
 *
 * This update function ...
 *
 * @return array
 *   An array of associaive arrays with 'success' and 'query' keys.
 */
function biblio_update_6031() {
  $result = array();
  $types[] = array(
    131,
    'Journal',
    NULL,
    3,
  );
  $types[] = array(
    132,
    'Web site',
    NULL,
    8,
  );
  $types[] = array(
    133,
    'Web service',
    'e.g. Google, Yahoo',
    8,
  );
  $types[] = array(
    134,
    'Web project page',
    NULL,
    8,
  );
  $types[] = array(
    135,
    'Presentation',
    NULL,
    8,
  );
  $types[] = array(
    136,
    'Newspaper',
    NULL,
    8,
  );
  foreach ($types as $record) {
    $result[] = update_sql("INSERT INTO {biblio_types} (tid, name, description, weight) VALUES ('" . implode("', '", $record) . "')");
  }
  $result[] = update_sql("DELETE FROM {biblio_types} WHERE tid=-1");
  return $result;
}

/**
 * Update ...
 *
 * This update function ...
 *
 * @return array
 *   An array of associaive arrays with 'success' and 'query' keys.
 */
function biblio_update_6032() {
  $result = array();
  $spec = array(
    'type' => 'varchar',
    'length' => '255',
    'not null' => TRUE,
    'default' => '',
    'description' => 'Full name',
  );
  db_change_field($result, 'biblio_contributor_data', 'name', 'name', $spec);
  return $result;
}

/**
 * Update ...
 *
 * This update function ...
 *
 * @return array
 *   An array of associaive arrays with 'success' and 'query' keys.
 */
function biblio_update_6033() {
  $result = array();
  $spec = array(
    'type' => 'varchar',
    'not null' => FALSE,
    'length' => '64',
    'description' => 'A normalized version of the title, used for sorting on titles. (only first 64 characters saved)',
  );
  db_add_field($result, 'biblio', 'biblio_sort_title', $spec);
  cache_clear_all();
  return $result;
}

/**
 * Update ...
 *
 * Populates the  new "biblio_sort_title" column, which is used for title sorting.
 *
 * @param $sandbox
 *
 *
 * @return array
 *   An array of associaive arrays with 'success' and 'query' keys.
 */
function biblio_update_6034(&$sandbox) {
  $ret = array();
  module_load_include('inc', 'biblio', '/includes/biblio.util');
  if (!isset($sandbox['max'])) {
    $sandbox['max'] = db_result(db_query("SELECT COUNT(DISTINCT vid) FROM {node} n WHERE n.type = '%s'", array(
      'biblio',
    )));
    $sandbox['current_vid'] = 0;
  }
  $result = db_query("SELECT vid, title FROM {node} n WHERE n.type='biblio' and vid>%d ORDER BY vid ASC LIMIT 20", $sandbox['current_vid']);
  while ($node = db_fetch_object($result)) {
    $node->biblio_sort_title = biblio_normalize_title($node->title);
    db_query("UPDATE {biblio} SET biblio_sort_title='" . $node->biblio_sort_title . "' WHERE vid=" . $node->vid);
    $sandbox['progress']++;
    $sandbox['current_vid'] = $node->vid;
  }
  $ret['#finished'] = empty($sandbox['max']) ? 1 : $sandbox['progress'] / $sandbox['max'];
  if ($ret['#finished'] === 1) {
    $ret[] = array(
      'success' => TRUE,
      'query' => t('!num Biblio Sort Titles were updated', array(
        '!num' => $sandbox['progress'],
      )),
    );
  }
  return $ret;
}

/**
 *
 *
 * @param $range
 *
 *
 * @return array
 *   An array of associaive arrays with 'success' and 'query' keys.
 */
function _biblio_update_field_link_data($range) {
  $result = array();
  $schema = biblio_schema();
  $field_type_columns = array_keys($schema['biblio_field_type']['fields']);
  $csv_file = drupal_get_path('module', 'biblio') . '/misc/biblio.field.link.data.csv';
  if ($handle = fopen($csv_file, "r")) {
    $header = fgetcsv($handle, 10000, ",");

    // the first line has the field names
    while (($row = fgetcsv($handle, 10000, ",")) !== FALSE) {
      $column = 0;

      // add link data for default biblio type (0) and all other defined types (100-130)
      foreach (range($range[0], $range[1]) as $t) {
        $field_type_values = array(
          $t,
          $row[0],
          $row[0],
          $row[0],
          $row[3],
          $row[4],
          $row[5],
          $row[6],
          $row[7],
        );
        $result[] = update_sql("INSERT INTO {biblio_field_type} (" . implode(", ", $field_type_columns) . ") " . "VALUES ('" . implode("', '", $field_type_values) . "')");
      }
    }
  }
  return $result;
}

/**
 * Update ...
 *
 * This update function ...
 *
 * @return array
 *   An array of associaive arrays with 'success' and 'query' keys.
 */
function biblio_update_6035() {
  $result = _biblio_update_field_link_data(array(
    131,
    136,
  ));
  cache_clear_all();
  return $result;
}

/**
 * Update ...
 *
 * This update function ...
 *
 * @return array
 *   An array of associaive arrays with 'success' and 'query' keys.
 */
function biblio_update_6036() {
  $result = array();
  $spec = array(
    'type' => 'varchar',
    'not null' => FALSE,
    'length' => '64',
    'description' => '',
  );
  db_change_field($result, 'biblio', 'biblio_date', 'biblio_date', $spec);
  return $result;
}

/**
 * Update ...
 *
 * This update function ...
 *
 * @return array
 *   An array of associaive arrays with 'success' and 'query' keys.
 */
function biblio_update_6037() {
  $result = array();
  $spec = array(
    'type' => 'blob',
    'not null' => FALSE,
    'description' => '',
    'serialize' => TRUE,
  );
  db_add_field($result, 'biblio', 'biblio_formats', $spec);
  return $result;
}

/**
 * Widen the biblio_contributor_data.lastname column to 255 characters
 *
 * This update function ...
 *
 * @return array
 *   An array of associaive arrays with 'success' and 'query' keys.
 */
function biblio_update_6038() {
  $result = array();
  $spec = array(
    'type' => 'varchar',
    'length' => '255',
    'not null' => TRUE,
    'default' => '',
    'description' => 'Author last name',
  );
  db_change_field($result, 'biblio_contributor_data', 'lastname', 'lastname', $spec);
  return $result;
}
function biblio_update_6039() {
  $result = array();
  $type_map = array(
    'description' => 'The mapping between the publication types in the file format and biblio',
    'type' => 'text',
    'not null' => FALSE,
  );
  $type_names = array(
    'description' => 'The human readable names of the publication types',
    'type' => 'text',
    'not null' => FALSE,
  );
  $field_map = array(
    'description' => 'The mapping between the fields in the file format and biblio',
    'type' => 'text',
    'not null' => FALSE,
  );
  $export_map = array(
    'description' => 'which fields are exported',
    'type' => 'text',
    'not null' => FALSE,
  );
  db_change_field($result, 'biblio_type_maps', 'type_map', 'type_map', $type_map);
  db_change_field($result, 'biblio_type_maps', 'type_names', 'type_names', $type_names);
  db_change_field($result, 'biblio_type_maps', 'field_map', 'field_map', $field_map);
  db_change_field($result, 'biblio_type_maps', 'export_map', 'export_map', $export_map);
  return $result;
}
function biblio_update_6040() {
  $result = array();
  $schema = biblio_schema();
  $table = $schema['biblio_contributor_data'];
  $table['description'] = 'Contains Alternate Author information for each publication';
  db_create_table($result, 'biblio_contributor_aka_data', $table);
  return $result;
}
function biblio_update_6041() {
  $result = array();
  $spec = array(
    'type' => 'int',
    'not null' => TRUE,
    'default' => 0,
    'unsigned' => TRUE,
    'description' => '',
  );
  db_add_field($result, 'biblio_contributor', 'merge_cid', $spec);
  db_add_index($result, 'biblio_contributor_data', 'name', array(
    'name',
  ));
  return $result;
}
function biblio_update_6042() {
  $result = array();
  $spec = array(
    'type' => 'int',
    'not null' => TRUE,
    'default' => 0,
    'unsigned' => TRUE,
    'description' => '',
  );
  db_add_field($result, 'biblio_contributor_data', 'alt_form', $spec);
  return $result;
}
function biblio_update_6043() {
  $result = array();
  if (!biblio_db_field_exists('biblio_contributor_aka_data', 'alt_form')) {
    $spec = array(
      'type' => 'int',
      'not null' => TRUE,
      'default' => 0,
      'unsigned' => TRUE,
      'description' => '',
    );
    db_add_field($result, 'biblio_contributor_aka_data', 'alt_form', $spec);
  }
  return $result;
}

Functions

Namesort descending Description
biblio_batch_uninstall
biblio_batch_uninstall_finished
biblio_db_field_exists
biblio_disable Implements hook_disable().
biblio_enable Implements hook_enable().
biblio_install Implements hook_install().
biblio_md5_generate Generates md5 hash values for biblio content.
biblio_requirements Implements hook_requirements().
biblio_reset_types Helper function to reset all field defintions to their defaults.
biblio_schema Implements hook_schema().
biblio_uninstall Implements hook_uninstall().
biblio_update_21 Update ...
biblio_update_22 Update ...
biblio_update_23 Update ...
biblio_update_24 Update ...
biblio_update_25 Update ...
biblio_update_26 Update ...
biblio_update_27 Update ...
biblio_update_6000 Update ...
biblio_update_6011 Update ...
biblio_update_6013 Update ...
biblio_update_6014 Update ...
biblio_update_6015 Update ...
biblio_update_6016 Update ...
biblio_update_6017 Update ...
biblio_update_6018 Update ...
biblio_update_6019 Update ...
biblio_update_6020 Update ...
biblio_update_6021 Update ...
biblio_update_6022 Update ...
biblio_update_6024
biblio_update_6025 Update ...
biblio_update_6026 Update ...
biblio_update_6027 Update ...
biblio_update_6028 Update ...
biblio_update_6029 Update ...
biblio_update_6030 Update ...
biblio_update_6031 Update ...
biblio_update_6032 Update ...
biblio_update_6033 Update ...
biblio_update_6034 Update ...
biblio_update_6035 Update ...
biblio_update_6036 Update ...
biblio_update_6037 Update ...
biblio_update_6038 Widen the biblio_contributor_data.lastname column to 255 characters
biblio_update_6039
biblio_update_6040
biblio_update_6041
biblio_update_6042
biblio_update_6043
_biblio_add_bibliographic_types Populates {biblio_types} table with initial bibliographvic type data.
_biblio_add_field_definitions Adds biblio field definitions to fields tables based upon data in a CSV file.
_biblio_add_keywords Helper function to transfer biblio_keyword data to taxonomy vocabulary.
_biblio_data_bibliographic_types Defines data for initial collection of biblio publication types.
_biblio_enable_collection_vocabulary Helper function to eneable the collection vocabulary for the biblio modules.
_biblio_enable_keyword_vocabulary Helper function to enable the keyword vocabulary for the biblio module.
_biblio_enable_vocabularies Helper function to enable vocabularies for the biblio module.
_biblio_field_id_by_name Maps CSV field data to table column names for fields in the biblio module.
_biblio_move_authors Moves author data into biblio_contributor* tables.
_biblio_move_field_data
_biblio_parse_authors Parses author name into components and populates array of name components.
_biblio_set_module_system_weight Helper function to adjust the system weight value of biblio module.
_biblio_types_customize_fields Creates customized fields for bibliographic types based on a CSV data file.
_biblio_update_field_link_data