Index: data_search/data_search.admin.inc
===================================================================
RCS file: data_search/data_search.admin.inc
diff -N data_search/data_search.admin.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ data_search/data_search.admin.inc	21 Aug 2009 19:57:32 -0000
@@ -0,0 +1,72 @@
+<?php
+// $Id$
+
+/**
+ * Views handler configuration form.
+ */
+function data_search_admin_form(&$form_state, $table) {
+  $schema = $table->get('table_schema');
+  $meta = $table->get('meta');
+
+  $form = array();
+
+  // Keep table.
+  $form['#table'] = $table;
+
+  // Existing fields.
+  $form['fields'] = array('#tree' => TRUE);
+  if (isset($schema['fields'])) {
+    $enabled_fields = data_search_get_fields($table);
+    foreach ($schema['fields'] as $field_name => $field) {
+      $form['fields'][$field_name] = array();
+      $form['fields'][$field_name]['name'] = array('#value' => $field_name);
+      $form['fields'][$field_name]['search'] = array(
+        '#type' => 'checkbox',
+        '#default_value' => in_array($field_name, $enabled_fields),
+      );
+    }
+  }
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Save'),
+  );
+  return $form;
+}
+
+/**
+ * Submit handler for search form.
+ */
+function data_search_admin_form_submit(&$form, &$form_state) {
+  $table = $form['#table'];
+  $meta = $table->get('meta');
+  if (isset($form_state['values']['fields'])) {
+    foreach ($form_state['values']['fields'] as $field_name => $settings) {
+      foreach ($settings as $setting => $value) {
+        $meta['fields'][$field_name][$setting] = $value;
+      }
+    }
+  }
+  $table->update(array('meta' => $meta));
+  views_invalidate_cache();  
+}
+
+/**
+ * Theme data_search_admin_form.
+ */
+function theme_data_search_admin_form($form) {
+
+  // Format existing fields.
+  $rows = array();
+  foreach (element_children($form['fields']) as $e) {
+    $row = array();
+    foreach (element_children($form['fields'][$e]) as $f) {
+      $row[] = drupal_render($form['fields'][$e][$f]);
+    }
+    $rows[] = $row;
+  }
+
+  $header = array(t('Name'), t('Search index'));
+  $output .= theme('table', $header, $rows);
+  $output .= drupal_render($form);
+  return $output;
+}
Index: data_search/data_search.info
===================================================================
RCS file: data_search/data_search.info
diff -N data_search/data_search.info
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ data_search/data_search.info	21 Aug 2009 19:57:32 -0000
@@ -0,0 +1,7 @@
+; $Id$
+name = "Data Search"
+description = "Provides search and views search integration for Data tables."
+package = Data
+dependencies[] = data
+dependencies[] = search
+core = 6.x
\ No newline at end of file
Index: data_search/data_search.install
===================================================================
RCS file: data_search/data_search.install
diff -N data_search/data_search.install
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ data_search/data_search.install	21 Aug 2009 19:57:32 -0000
@@ -0,0 +1,12 @@
+<?php
+// $Id$
+
+/**
+ * Implementation of hook_install().
+ */
+function data_search_install() {
+  // Adjust length of type columns for data tables with names of a max length of 64.
+  db_query("ALTER TABLE {search_dataset} CHANGE COLUMN type type VARCHAR(64)");
+  db_query("ALTER TABLE {search_index} CHANGE COLUMN type type VARCHAR(64)");
+  db_query("ALTER TABLE {search_node_links} CHANGE COLUMN type type VARCHAR(64)");
+}
Index: data_search/data_search.module
===================================================================
RCS file: data_search/data_search.module
diff -N data_search/data_search.module
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ data_search/data_search.module	21 Aug 2009 19:57:32 -0000
@@ -0,0 +1,139 @@
+<?php
+// $Id$
+
+/**
+ * Implementation of hook_menu()
+ */
+function data_search_menu() {
+  $items = array();
+  $items['admin/content/data/edit/%data_ui_table/search'] = array(
+    'title' => 'Configure search',
+    'description' => 'Administer data tables.',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('data_search_admin_form', 4),
+    'file' => 'data_search.admin.inc',
+    'access arguments' => array('administer data tables'),
+    'type' => MENU_LOCAL_TASK,
+  );
+  return $items;
+}
+
+/**
+ * Implementation of hook_theme()
+ */
+function data_search_theme() {
+  return array(
+    'data_search_admin_form' => array(
+      'arguments' => array('form' => array()),
+    ),
+  );
+}
+
+/**
+ * Implementation of hook_views_data_alter().
+ */
+function data_search_views_data_alter(&$data) {
+  $tables = data_search_get_tables();
+  foreach ($tables as $table) {
+    $name = $table->get('name');
+    $schema = $table->get('table_schema');
+    $base_field = current($schema['primary key']);
+
+    // Explain how the search index joins to data tables.
+    $data['search_index']['table']['join'][$name] = array(
+      'left_field' => $base_field,
+      'field' => 'sid',
+    );
+  }
+}
+
+/**
+ * Implementation of hook_update_index().
+ */
+function data_search_update_index() {
+  $limit = (int)variable_get('search_cron_limit', 100);
+
+  $tables = data_search_get_tables();
+  foreach ($tables as $table) {
+    $name = $table->get('name');
+    $schema = $table->get('table_schema');
+
+    $fields = data_search_get_fields($table);
+    $fields = implode(', ', $fields);
+    $base_field = current($schema['primary key']);
+
+    $result = db_query_range("SELECT dt.{$base_field} id FROM {{$name}} dt LEFT JOIN {search_dataset} d ON d.type = '{$name}' AND d.sid = dt.{$base_field} WHERE d.sid IS NULL OR d.reindex <> 0 ORDER BY d.reindex ASC, dt.{$base_field} ASC", 0, $limit);
+
+    while ($row = db_fetch_object($result)) {
+      $values = db_fetch_array(db_query("SELECT {$fields} FROM {{$name}} WHERE {$base_field} = '%s'", $row->id));
+      $fulltext = '';
+      foreach ($values as $field => $value) {
+        $fulltext .= "{$value}\n\n";
+      }
+      search_index($row->id, $name, $fulltext);
+    }
+    // Delete orphaned data search records, no nodeapi to take care of this as it occurs.
+    db_query("DELETE sd, si, snl FROM {search_dataset} sd LEFT JOIN {{$name}} dt ON sd.type = '{$name}' AND sd.sid = dt.{$base_field} LEFT JOIN {search_index} si ON sd.sid = si.sid AND sd.type = si.type LEFT JOIN {search_node_links} snl ON sd.sid = snl.sid AND sd.type = snl.type WHERE dt.{$base_field} IS NULL");
+  }
+}
+
+/**
+ * Implementation of hook_search().
+ */
+function data_search_search($op = 'search', $keys = NULL) {
+  switch ($op) {
+    case 'name':
+      return t('Data');
+
+    case 'reset':
+      $tables = data_search_get_tables();
+      foreach ($tables as $table) {
+        $name = $table->get('name');
+        db_query("UPDATE {search_dataset} SET reindex = %d WHERE type = '%s'", time(), $name);
+      }
+      return;
+
+    case 'status':
+      $total = $remaining = 0;
+      $tables = data_search_get_tables();
+      foreach ($tables as $table) {
+        $name = $table->get('name');
+        $schema = $table->get('table_schema');
+        $base_field = current($schema['primary key']);
+
+        $total = $total + db_result(db_query("SELECT COUNT(*) FROM {{$name}}"));
+        $remaining = $remaining + db_result(db_query("SELECT COUNT(*) FROM {{$name}} dt LEFT JOIN {search_dataset} d ON d.type = '{$name}' AND d.sid = dt.{$base_field} WHERE (d.sid IS NULL OR d.reindex <> 0)"));
+      }
+      return array('remaining' => $remaining, 'total' => $total);
+  }
+}
+
+/**
+ * Gather all tables which might be eligible for searching.
+ */
+function data_search_get_tables() {
+  $tables = array();
+  foreach (data_get_all_tables() as $table) {
+    $schema = $table->get('table_schema');
+    $fields = data_search_get_fields($table);
+    if (isset($schema['primary key']) && count($schema['primary key']) >= 1 && !empty($fields)) {
+      $tables[] = $table;
+    }
+  }
+  return $tables;
+}
+
+/**
+ * Gather all fields for a particular table which should be added to the search index.
+ */
+function data_search_get_fields($table) {
+  $fields = array();
+  $schema = $table->get('table_schema');
+  $meta = $table->get('meta');
+  foreach (array_keys($schema['fields']) as $field_name) {
+    if (!empty($meta['fields'][$field_name]['search'])) {
+      $fields[] = $field_name;
+    }
+  }
+  return $fields;
+}
