Index: apachesolr.admin.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/apachesolr/apachesolr.admin.inc,v
retrieving revision 1.1.2.32.2.10
diff -u -p -r1.1.2.32.2.10 apachesolr.admin.inc
--- apachesolr.admin.inc	26 Dec 2009 17:19:01 -0000	1.1.2.32.2.10
+++ apachesolr.admin.inc	19 Jan 2010 20:33:58 -0000
@@ -16,27 +16,6 @@ function apachesolr_settings() {
     drupal_set_message($requirements['apachesolr']['value'], $status);
   }
 
-  $form['apachesolr_host'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Solr host name'),
-    '#default_value' => variable_get('apachesolr_host', 'localhost'),
-    '#description' => t('Host name of your Solr server, e.g. <code>localhost</code> or <code>example.com</code>.'),
-    '#required' => TRUE,
-  );
-  $form['apachesolr_port'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Solr port'),
-    '#default_value' => variable_get('apachesolr_port', '8983'),
-    '#description' => t('Port on which the Solr server listens. The Jetty example server is 8983, while Tomcat is 8080 by default.'),
-    '#required' => TRUE,
-  );
-  $form['apachesolr_path'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Solr path'),
-    '#default_value' => variable_get('apachesolr_path', '/solr'),
-    '#description' => t('Path that identifies the Solr request handler to be used.'),
-  );
-
   $numbers = drupal_map_assoc(array(1, 5, 10, 20, 50, 100, 200));
   $form['apachesolr_cron_limit'] = array(
     '#type' => 'select',
@@ -86,6 +65,201 @@ function apachesolr_settings() {
 }
 
 /**
+ * Callback for configuring Solr servers.
+ */
+function apachesolr_settings_servers($server_id = NULL, $delete = NULL) {
+  $output = '';
+  $servers = variable_get('apachesolr_servers', array());
+  if ($delete == 'delete' && isset($servers[$server_id])) {
+    return drupal_get_form('apachesolr_settings_servers_delete', $server_id);
+  }
+  if (count($servers)) {
+    $header = array('#', t('Server name'), t('Host name'), t('Port'), t('Path'), t('Query server'), t('Index server'), array('data' => t('Operations'), 'colspan' => 2));
+    $rows = array();
+    foreach ($servers as $delta => $server) {
+      $row = array($delta, $server['name'], $server['host'], $server['port'], $server['path'], $server['query'] ? t('Yes') : t('No'), $server['index']  ? t('Yes') : t('No'), l(t('modify'), 'admin/settings/apachesolr/servers/'. $delta), l(t('delete'), 'admin/settings/apachesolr/servers/'. $delta .'/delete'));
+      if ($server_id == $delta) {
+        $rows[] = array(
+          'data' => $row,
+          'class' => 'apachesolr-servers-active-server',
+        );
+      }
+      else {
+        $rows[] = $row;
+      }
+    }
+    $element = array(
+      '#type' => 'fieldset',
+      '#title' => t('Solr servers currentlly configured on this site'),
+      '#collapsible' => TRUE,
+      '#collpased' => FALSE,
+      '#value' => theme('table', $header, $rows) . (!is_null($server_id) ? '<div class="apachesolr-servers-add">'. l(t('Add a new server'), 'admin/settings/apachesolr/servers') .'</div>' : ''),
+    );
+    $output .= theme('fieldset', $element);
+  }
+  else {
+    $output .= t('There are no Solr servers configured yet. Use the form bellow to enter a Solr server.');
+  }
+  return $output . drupal_get_form('apachesolr_settings_servers_form', $server_id);
+}
+
+/**
+ * Solr servers form
+ */
+function apachesolr_settings_servers_form($server_id) {
+  $server_id = is_null($server_id) ? 'add' : $server_id;
+  $servers = variable_get('apachesolr_servers', array());
+  $server = $server_id == 'add' ? array('name' => '', 'host' => 'localhost', 'port' => '8983', 'path' => '/solr', 'query' => TRUE, 'index' => FALSE) : $servers[$server_id];
+  $form = array();
+  $form['server_id'] = array(
+    '#type' => 'value',
+    '#value' => $server_id,
+  );
+  $form['container'] = array(
+    '#type' => 'fieldset',
+    '#title' => $server_id == 'add' ? t('Add a new Solr server') : t('Configuration for server #%no: %name', array('%no' => $server_id, '%name' => $server['name'])),
+    '#collapsible' => TRUE,
+    '#collpased' => FALSE,
+  );
+  $form['container']['apachesolr_server_name'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Server name'),
+    '#description' => t('Enter a maximum 50 characters internal name for this server. It will be use only for administrative reasons, to help dealing with more than one server.'),
+    '#default_value' => $server['name'],
+    '#required' => TRUE,
+    '#maxlength' => 50,
+  );
+  $form['container']['apachesolr_server_host'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Solr host name'),
+    '#description' => t('Host name of your Solr server, e.g. localhost or example.com.'),
+    '#default_value' => $server['host'],
+    '#required' => TRUE,
+  );
+  $form['container']['apachesolr_server_port'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Solr port'),
+    '#description' => t('Port on which the Solr server listens. The Jetty example server is 8983, while Tomcat is 8080 by default.'),
+    '#default_value' => $server['port'],
+    '#required' => TRUE,
+  );
+  $form['container']['apachesolr_server_path'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Solr path'),
+    '#description' => t('Path that identifies the Solr request handler to be used.'),
+    '#default_value' => $server['path'],
+  );
+  $form['container']['apachesolr_server_query'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('This server is used for queries'),
+    '#description' => t('Check this box in order to have this server acting as query server.'),
+    '#default_value' => $server['query'],
+  );
+  $form['container']['apachesolr_server_index'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('This server used for indexing'),
+    '#description' => t('Check this box if you want too use this server as index server. Note that you cannot configure more than one index server.'),
+    '#default_value' => $server['index'],
+  );
+  $form['container']['submit'] = array(
+    '#type' => 'submit',
+    '#value' => is_numeric($server_id) ? t('Save') : t('Add'),
+  );
+  return $form;
+}
+
+/**
+ * Solr servers form
+ */
+function apachesolr_settings_servers_form_submit($form_id, $form_values) {
+  $servers = variable_get('apachesolr_servers', array());
+  $server = array(
+    'name' => $form_values['apachesolr_server_name'],
+    'host' => $form_values['apachesolr_server_host'],
+    'port' => $form_values['apachesolr_server_port'],
+    'path' => $form_values['apachesolr_server_path'],
+    'query' => $form_values['apachesolr_server_query'],
+    'index' => $form_values['apachesolr_server_index'],
+  );
+  
+  // If this is an index server, remove the index attribute from the others.
+  if ($server['index']) {
+    foreach ($servers as $delta => $server_item) {
+      $servers[$delta]['index'] = FALSE;
+    }
+  }
+  
+  if ($form_values['server_id'] == 'add') {
+    $servers[] = $server;
+  }
+  else {
+    $servers[$form_values['server_id']] = $server;
+  }
+  
+  // Save servers into one single variable.
+  variable_set('apachesolr_servers', $servers);
+  
+  drupal_set_message(t('Server !host:!port!path was saved as %name', array('!host' => $server['host'], '!port' => $server['port'], '!path' => '/'. ltrim($server['path'], '/'), '%name' => $server['name'])));
+  return 'admin/settings/apachesolr/servers';
+}
+
+/**
+ * Solr server deleting confirmation page
+ */
+function apachesolr_settings_servers_delete($server_id) {
+  $servers = variable_get('apachesolr_servers', array());
+  $server = $servers[$server_id];
+  
+  $form['#redirect'] = 'admin/settings/apachesolr/servers';
+  $form['server_id'] = array(
+    '#type' =>  'value',
+    '#value' => $server_id,
+  );
+
+  $question = t('Are you sure you want to delete the Solr server %name?', array('%name' => $server['name']));
+  
+  $items = array(
+    t('Name: @name', array('@name' => $server['name'])),
+    t('Host: @host', array('@host' => $server['host'])),
+    t('Port: @port', array('@port' => $server['port'])),
+    t('Path: @path', array('@path' => $server['path'])),
+    t('Query server: @query', array('@query' => $server['query'] ? t('Yes') : t('No'))),
+    t('Index server: @index', array('@index' => $server['index'] ? t('Yes') : t('No'))),
+  );
+  $description = theme('item_list', $items, t('Solr server details:'));
+  
+  // Check if this is the only query server.
+  $query = 0;
+  foreach ($servers as $delta => $server_item) {
+    if ($delta != $server_id && $server_item['query']) {
+      $query++;
+    }
+  }
+
+  $items = array(); 
+  if ($server['index']) {
+    $items[] = t('This Solr server is the server used to index this site. If you will delete it than you\'ll have to configure other server as index server.');
+  }
+  if ($query == 0) {
+    $items[] = t('This Solr server is the only one configured to be queried for data. If you will delete it than you\'ll have to configure at least other server as query server.');
+  }
+  $items[] = t('This action cannot be undone.');
+  $description .= theme('item_list', $items, t('Warnings:'));
+  
+  return confirm_form($form, $question, 'admin/settings/apachesolr/servers', $description, t('Delete'), t('Cancel'));
+}
+
+/**
+ * Solr server delete callback handler.
+ */ 
+function apachesolr_settings_servers_delete_submit($form_id, $form_values) {
+  $servers = variable_get('apachesolr_servers', array());
+  $server = array_splice($servers, $form_values['server_id'], 1);
+  drupal_set_message(t('The Solr server %name (!host:!port!path) has been deleted.', array('%name' => $server[0]['name'], '!host' => $server[0]['host'], '!port' => $server[0]['port'], '!path' => '/'. ltrim($server[0]['path'], '/'))));
+  variable_set('apachesolr_servers', $servers);
+}
+
+/**
  * Validation function for the apachesolr_settings form.
  */
 function apachesolr_settings_validate($form_id, $form_values) {
@@ -101,7 +275,7 @@ function apachesolr_settings_validate($f
  */
 function apachesolr_index_page() {
   try {
-    $solr = apachesolr_get_solr();
+    $solr = apachesolr_get_solr('index');
     // TODO: possibly clear this every page view if we are running multi-site.
     if (apachesolr_index_updated()) {
       $solr->clearCache();
@@ -139,7 +313,7 @@ function apachesolr_index_page() {
 
 function apachesolr_index_report() {
   try {
-    $solr = apachesolr_get_solr();
+    $solr = apachesolr_get_solr('index');
     // TODO: possibly clear this every page view if we are running multi-site.
     if (apachesolr_index_updated()) {
       $solr->clearCache();
@@ -162,7 +336,7 @@ function apachesolr_index_report() {
   elseif (isset($data->index->numDocs)) {
     $not_found = t('Not indexed');
     try {
-      $solr = apachesolr_get_solr();
+      $solr = apachesolr_get_solr('index');
       // Note: we use 2 since 1 fails on Ubuntu Hardy.
       $data = $solr->getLuke(2);
       $output .= '<p>' . t('Number of terms in index: @num', array('@num' => $data->index->numTerms)) . "</p>\n";
@@ -413,7 +587,7 @@ function apachesolr_delete_index_confirm
  */
 function apachesolr_delete_index($type = NULL) {
   // Instantiate a new Solr object.
-  $solr = apachesolr_get_solr();
+  $solr = apachesolr_get_solr('index');
   if ($type) {
     $query = 'type:' . $type;
   }
@@ -602,7 +776,7 @@ function apachesolr_mlt_block_defaults($
  * @return array An array containing a the fields in the solr instance.
  */
 function apachesolr_mlt_get_fields() {
-  $solr = apachesolr_get_solr();
+  $solr = apachesolr_get_solr('index');
   $fields = $solr->getFields();
   $rows = array();
   foreach ($fields as $field_name => $field) {
Index: apachesolr.d6.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/apachesolr/Attic/apachesolr.d6.inc,v
retrieving revision 1.1.2.2
diff -u -p -r1.1.2.2 apachesolr.d6.inc
--- apachesolr.d6.inc	5 Nov 2009 17:17:21 -0000	1.1.2.2
+++ apachesolr.d6.inc	19 Jan 2010 20:33:58 -0000
@@ -77,3 +77,8 @@ function db_type_placeholder($type) {
   // will cause the query to fail.
   return 'unsupported type '. $type .'for db_type_placeholder';
 }
+
+function drupal_help_arg($arg = array()) {
+  // Note - the number of empty elements should be > MENU_MAX_PARTS.
+  return $arg + array('', '', '', '', '', '', '', '', '', '', '', '');
+}
Index: apachesolr.index.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/apachesolr/apachesolr.index.inc,v
retrieving revision 1.1.2.6.4.7
diff -u -p -r1.1.2.6.4.7 apachesolr.index.inc
--- apachesolr.index.inc	17 Dec 2009 12:47:48 -0000	1.1.2.6.4.7
+++ apachesolr.index.inc	19 Jan 2010 20:33:58 -0000
@@ -317,7 +317,7 @@ function apachesolr_nodeapi_mass_update(
   }
   $time = time();
   try {
-    $solr = apachesolr_get_solr();
+    $solr = apachesolr_get_solr('index');
     $solr->deleteMultipleById($ids);
     apachesolr_index_updated($time);
     foreach ($nodes as $node) {
@@ -343,7 +343,7 @@ function apachesolr_nodeapi_mass_delete(
     $nids[] = $node->nid;
   }
   try {
-    $solr = apachesolr_get_solr();
+    $solr = apachesolr_get_solr('index');
     $solr->deleteMultipleById($ids);
     apachesolr_index_updated($time);
     // There was no exception, so update the table.
Index: apachesolr.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/apachesolr/apachesolr.module,v
retrieving revision 1.1.2.12.2.161.2.11
diff -u -p -r1.1.2.12.2.161.2.11 apachesolr.module
--- apachesolr.module	2 Jan 2010 13:49:11 -0000	1.1.2.12.2.161.2.11
+++ apachesolr.module	19 Jan 2010 20:33:58 -0000
@@ -31,6 +31,14 @@ function apachesolr_menu($may_cache) {
       'type'                => MENU_DEFAULT_LOCAL_TASK,
     );
     $items[] = array(
+      'path'                => 'admin/settings/apachesolr/servers',
+      'title'               => t('Solr Servers'),
+      'callback'            => 'apachesolr_settings_servers',
+      'weight'              => -9,
+      'access'              => user_access('administer search'),
+      'type'                => MENU_LOCAL_TASK,
+    );
+    $items[] = array(
       'path'                => 'admin/settings/apachesolr/enabled-filters',
       'title'               => t('Enabled filters'),
       'callback'            => 'drupal_get_form',
@@ -134,7 +142,7 @@ function apachesolr_requirements($phase)
     $path = variable_get('apachesolr_path', '/solr');
     $ping = FALSE;
     try {
-      $solr = apachesolr_get_solr();
+      $solr = apachesolr_get_solr('index');
       $ping = @$solr->ping(variable_get('apachesolr_ping_timeout', 4));
       // If there is no $solr object, there is no server available, so don't continue.
       if (!$ping) {
@@ -362,7 +370,7 @@ function apachesolr_index_nodes($rows, $
 
   try {
     // Get the $solr object
-    $solr = apachesolr_get_solr();
+    $solr = apachesolr_get_solr('index');
     // If there is no server available, don't continue.
     if (!$solr->ping(variable_get('apachesolr_ping_timeout', 4))) {
       throw new Exception(t('No Solr instance available during indexing.'));
@@ -438,7 +446,7 @@ function apachesolr_delete_node_from_ind
     return FALSE;
   }
   try {
-    $solr = apachesolr_get_solr();
+    $solr = apachesolr_get_solr('index');
     $solr->deleteById(apachesolr_document_id($node->nid));
     apachesolr_index_updated(time());
     return TRUE;
@@ -474,7 +482,7 @@ function apachesolr_cron() {
   include_once(drupal_get_path('module', 'apachesolr') .'/apachesolr.index.inc');
   apachesolr_cron_check_node_table();
   try {
-    $solr = apachesolr_get_solr();
+    $solr = apachesolr_get_solr('index');
     // Optimize the index (by default once a day).
     $optimize_interval = variable_get('apachesolr_optimize_interval', 60 * 60 * 24);
     $last = variable_get('apachesolr_last_optimize', 0);
@@ -562,7 +570,7 @@ function _apachesolr_nodeapi_update($nod
  */
 function apachesolr_set_stats_message($text, $type = 'status', $repeat = FALSE) {
   try {
-    $solr = apachesolr_get_solr();
+    $solr = apachesolr_get_solr('index');
     $stats_summary = $solr->getStatsSummary();
     drupal_set_message(t($text, $stats_summary), $type, FALSE);
   }
@@ -1120,33 +1128,37 @@ function apachesolr_has_searched($search
  * Factory method for solr singleton object. Structure allows for an arbitrary
  * number of solr objects to be used based on the host, port, path combination.
  * Get an instance like this:
- *   $solr = apachesolr_get_solr();
+ *   $solr = apachesolr_get_solr('index');
+ *
+ * @param $service_type
+ *   String with values 'query' or 'index'. Is used for a selective server uses.
  */
-function apachesolr_get_solr($host = NULL, $port = NULL, $path = NULL) {
-  static $solr_cache;
+function apachesolr_get_solr($service_type = 'query') {
+  static $solr_cache = array();
 
-  if (empty($host)) {
-    $host = variable_get('apachesolr_host', 'localhost');
-  }
-  if (empty($port)) {
-    $port = variable_get('apachesolr_port', '8983');
-  }
-  if (empty($path)) {
-    $path = variable_get('apachesolr_path', '/solr');
-  }
-
-  if (empty($solr_cache[$host][$port][$path])) {
+  if (!isset($solr_cache[$service_type])) {
+    // Get the right server for this service type.
+    foreach (variable_get('apachesolr_servers', array()) as $delta => $server) {
+      /**
+       * WARNING: We will use the first "query" server as "query" server
+       * while load balancing is not yet implemented.
+       */
+      if ($server[$service_type]) {
+        break;
+      }
+    }
+    
     list($module, $filepath, $class) = variable_get('apachesolr_service_class', array('apachesolr', 'Drupal_Apache_Solr_Service.php', 'Drupal_Apache_Solr_Service'));
     include_once(drupal_get_path('module', $module) .'/'. $filepath);
     try {
-      $solr_cache[$host][$port][$path] = new $class($host, $port, $path);
+      $solr_cache[$service_type] = new $class($server['host'], $server['port'], $server['path']);
     }
     catch (Exception $e) {
       watchdog('Apache Solr', nl2br(check_plain($e->getMessage())), WATCHDOG_ERROR);
       return;
     }
   }
-  return $solr_cache[$host][$port][$path];
+  return $solr_cache[$service_type];
 }
 
 /**
@@ -1183,7 +1195,7 @@ function apachesolr_drupal_query($keys =
   include_once drupal_get_path('module', $module) .'/'. $class .'.php';
 
   try {
-    $query = new $class(apachesolr_get_solr(), $keys, $filters, $solrsort, $base_path);
+    $query = new $class(apachesolr_get_solr('query'), $keys, $filters, $solrsort, $base_path);
   }
   catch (Exception $e) {
     watchdog('Apache Solr', nl2br(check_plain($e->getMessage())), WATCHDOG_ERROR);
@@ -1413,7 +1425,7 @@ function apachesolr_cck_userreference_fi
 function apachesolr_mlt_suggestions($settings, $id) {
 
   try {
-    $solr = apachesolr_get_solr();
+    $solr = apachesolr_get_solr('query');
     $fields = array(
       'mlt_mintf' => 'mlt.mintf',
       'mlt_mindf' => 'mlt.mindf',
Index: apachesolr_search.admin.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/apachesolr/apachesolr_search.admin.inc,v
retrieving revision 1.1.2.21.2.1
diff -u -p -r1.1.2.21.2.1 apachesolr_search.admin.inc
--- apachesolr_search.admin.inc	22 Sep 2009 15:26:15 -0000	1.1.2.21.2.1
+++ apachesolr_search.admin.inc	19 Jan 2010 20:33:58 -0000
@@ -12,7 +12,7 @@
 function apachesolr_search_settings_page() {
   // try to fetch the schema fields
   try {
-    $solr = apachesolr_get_solr();
+    $solr = apachesolr_get_solr('index');
     $fields = $solr->getFields();
     $output .= drupal_get_form('apachesolr_search_settings_form', $fields);
   }
@@ -240,7 +240,7 @@ function apachesolr_search_type_boost_fo
     // Note - we omit a check on empty($old_excluded_types[$type]) so that
     // the admin can re-submit this page if the delete operation fails.
     if (!empty($new_excluded_types[$type])) {
-      $solr = apachesolr_get_solr();
+      $solr = apachesolr_get_solr('index');
       $solr->deleteByQuery("type:$type");
       apachesolr_index_updated(time());
     }
Index: apachesolr_search.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/apachesolr/apachesolr_search.module,v
retrieving revision 1.1.2.6.2.111.4.9
diff -u -p -r1.1.2.6.2.111.4.9 apachesolr_search.module
--- apachesolr_search.module	19 Dec 2009 10:32:38 -0000	1.1.2.6.2.111.4.9
+++ apachesolr_search.module	19 Jan 2010 20:33:58 -0000
@@ -212,7 +212,7 @@ function apachesolr_search_execute($keys
   }
 
   // This is the object that does the communication with the solr server.
-  $solr = apachesolr_get_solr();
+  $solr = apachesolr_get_solr('query');
   $params += apachesolr_search_basic_params($query);
   if ($keys) {
     $params += apachesolr_search_highlighting_params($query);
@@ -925,7 +925,7 @@ function apachesolr_search_make_default_
 
 function apachesolr_search_build_spellcheck($form_id, $form_values) {
   try {
-    $solr = apachesolr_get_solr();
+    $solr = apachesolr_get_solr('query');
     $params['spellcheck'] = 'true';
     $params['spellcheck.build'] = 'true';
     $response = $solr->search('solr', 0, 0, $params);
