Index: resources/comment_resource.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/services/resources/comment_resource.inc,v
retrieving revision 1.1.2.5
diff -u -p -r1.1.2.5 comment_resource.inc
--- resources/comment_resource.inc	30 Jan 2011 18:55:10 -0000	1.1.2.5
+++ resources/comment_resource.inc	16 Feb 2011 19:11:04 -0000
@@ -86,6 +86,41 @@ function _comment_resource_definition() 
           ),
         ),
       ),
+
+      'index' => array(
+        'file' => array('type' => 'inc', 'module' => 'services', 'name' => 'resources/comment_resource'),
+        'callback' => '_comment_resource_index',
+        'args' => array(
+          array(
+            'name' => 'page',
+            'optional' => TRUE,
+            'type' => 'int',
+            'description' => 'The zero-based index of the page to get, defaults to 0.',
+            'default value' => 0,
+            'source' => array('param' => 'page'),
+          ),
+          array(
+            'name' => 'fields',
+            'optional' => TRUE,
+            'type' => 'string',
+            'description' => 'The fields to get.',
+            'default value' => '*',
+            'source' => array('param' => 'fields'),
+          ),
+          array(
+            'name' => 'parameters',
+            'optional' => TRUE,
+            'type' => 'struct',
+            'description' => 'Parameters',
+            'default value' => NULL,
+            'source' => array('param' => 'parameters'),
+          ),
+        ),
+        'access callback' => '_comment_resource_access',
+        'access arguments' => array('view'),
+        'access arguments append' => TRUE,
+      ),
+
       'actions' => array(
         'loadNodeComments' => array(
           'file' => array('type' => 'inc', 'module' => 'services', 'name' => 'resources/comment_resource'),
@@ -271,6 +306,66 @@ function _comment_resource_delete($cid) 
 }
 
 /**
+ * Return an array of optionally paged cids baed on a set of criteria.
+ *
+ * An example request might look like
+ *
+ * http://domain/endpoint/comment?fields=cid,nid&parameters[nid]=7&parameters[uid]=2
+ *
+ * This would return an array of objects with only cid and nid defined, where
+ * nid = 7 and uid = 1.
+ *
+ * @param $page
+ *   Page number of results to return (in pages of 20).
+ * @param $fields
+ *   The fields you want returned.
+ * @param $parameters
+ *   An array of fields and values used to build a sql WHERE clause indicating
+ *   what items should be deleted.
+ * @return
+ *   An array of comment objects.
+ *
+ * @see _node_resource_index() for more notes
+ **/
+function _comment_resource_index($page = 0, $fields = '*', $parameters = array()) {
+  $parameters = (array) $parameters;
+  $schema = drupal_get_schema('comments');
+  $where = array();
+  $fields = db_escape_string($fields);
+
+  // Limit to published comments if user doesn't have 'administer comments'
+  // permissions.
+  if (!user_access('administer comments')) {
+    $parameters['status'] = COMMENT_PUBLISHED;
+  }
+
+  // Build an array of fields with the appropriate placeholders for use in
+  // db_query().
+  foreach ($parameters as $field => $value) {
+    $where[] = $field . ' = ' . db_type_placeholder($schema['fields'][$field]['type']);
+  }
+
+  // Now implode that array into an actual WHERE clause.
+  $where = !empty($where) ? ' WHERE '. implode(' AND ', $where) : '';
+
+  // Run through db_rewrite_sql to make sure proper access checks are applied.
+  $sql = "SELECT $fields FROM {comments} c $where ORDER BY nid, pid, cid";
+  $sql = db_rewrite_sql($sql);
+  $result = db_query_range($sql, $parameters, $page * 20, 20);
+
+  // Put together array of matching comments to return.
+  $comments = array();
+  while ($comment = db_fetch_object($result)) {
+    if ($uri = services_resource_uri(array('comment', $comment->cid))) {
+      $comment->uri = $uri;
+    }
+    $comments[] = $comment;
+  }
+
+  return $comments;
+}
+
+/**
  * Returns the comments of a specified node.
  *
  * @param $nid
@@ -361,6 +456,6 @@ function _comment_resource_access($op = 
  **/
 function _comment_resource_node_access($op = 'view', $args = array()) {
   module_load_include('inc', 'services', 'resources/node_resource');
-  
+
   return _node_resource_access($op, $args);
 }
Index: resources/file_resource.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/services/resources/file_resource.inc,v
retrieving revision 1.1.2.4
diff -u -p -r1.1.2.4 file_resource.inc
--- resources/file_resource.inc	10 Dec 2010 22:05:19 -0000	1.1.2.4
+++ resources/file_resource.inc	16 Feb 2011 19:11:04 -0000
@@ -69,6 +69,41 @@ function _file_resource_definition() {
           ),
         ),
       ),
+
+      'index' => array(
+        'file' => array('type' => 'inc', 'module' => 'services', 'name' => 'resources/file_resource'),
+        'callback' => '_file_resource_index',
+        'args' => array(
+          array(
+            'name' => 'page',
+            'optional' => TRUE,
+            'type' => 'int',
+            'description' => 'The zero-based index of the page to get, defaults to 0.',
+            'default value' => 0,
+            'source' => array('param' => 'page'),
+          ),
+          array(
+            'name' => 'fields',
+            'optional' => TRUE,
+            'type' => 'string',
+            'description' => 'The fields to get.',
+            'default value' => '*',
+            'source' => array('param' => 'fields'),
+          ),
+          array(
+            'name' => 'parameters',
+            'optional' => TRUE,
+            'type' => 'struct',
+            'description' => 'Parameters',
+            'default value' => NULL,
+            'source' => array('param' => 'parameters'),
+          ),
+        ),
+        'access callback' => '_file_resource_access',
+        'access arguments' => array('view'),
+        'access arguments append' => TRUE,
+      ),
+
       'actions' => array(
         'nodeFiles' => array(
           'help'   => t('This method returns the files on a given node.'),
@@ -199,7 +234,7 @@ function _file_resource_retrieve($fid, $
       $binaryfile = fopen($filepath, 'rb');
       $file['file'] = base64_encode(fread($binaryfile, filesize($filepath)));
       fclose($binaryfile);
-    }    
+    }
     return $file;
   }
   else {
@@ -268,6 +303,60 @@ function _file_resource_delete($fid) {
 }
 
 /**
+ * Return an array of optionally paged fids baed on a set of criteria.
+ *
+ * An example request might look like
+ *
+ * http://domain/endpoint/file?fields=fid,filename&parameters[fid]=7&parameters[uid]=1
+ *
+ * This would return an array of objects with only fid and filename defined, where
+ * fid = 7 and uid = 1.
+ *
+ * @param $page
+ *   Page number of results to return (in pages of 20).
+ * @param $fields
+ *   The fields you want returned.
+ * @param $parameters
+ *   An array of fields and values used to build a sql WHERE clause indicating
+ *   what items should be deleted.
+ * @return
+ *   An array of file objects.
+ *
+ * @see _node_resource_index() for more notes
+ **/
+function _file_resource_index($page = 0, $fields = '*', $parameters = array()) {
+  $parameters = (array) $parameters;
+  $schema = drupal_get_schema('files');
+  $where = array();
+  $fields = db_escape_string($fields);
+
+  // Build an array of fields with the appropriate placeholders for use in
+  // db_query().
+  foreach ($parameters as $field => $value) {
+    $where[] = $field . ' = ' . db_type_placeholder($schema['fields'][$field]['type']);
+  }
+
+  // Now implode that array into an actual WHERE clause.
+  $where = !empty($where) ? ' WHERE '. implode(' AND ', $where) : '';
+
+  // Run through db_rewrite_sql to make sure proper access checks are applied.
+  $sql = "SELECT $fields FROM {files} f $where ORDER BY timestamp DESC";
+  $sql = db_rewrite_sql($sql);
+  $result = db_query_range($sql, $parameters, $page * 20, 20);
+
+  // Put together array of matching files to return.
+  $files = array();
+  while ($file = db_fetch_object($result)) {
+    if ($uri = services_resource_uri(array('file', $file->fid))) {
+      $file->uri = $uri;
+    }
+    $files[] = $file;
+  }
+
+  return $files;
+}
+
+/**
  * Access check callback for file controllers.
  */
 function _file_resource_access($op = 'view', $args = array()) {
Index: resources/taxonomy_resource.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/services/resources/taxonomy_resource.inc,v
retrieving revision 1.1.2.5
diff -u -p -r1.1.2.5 taxonomy_resource.inc
--- resources/taxonomy_resource.inc	18 Jan 2011 21:08:12 -0000	1.1.2.5
+++ resources/taxonomy_resource.inc	16 Feb 2011 19:11:04 -0000
@@ -81,6 +81,39 @@ function _taxonomy_resource_definition()
         'access arguments append' => TRUE,
         'file' => array('type' => 'inc', 'module' => 'services', 'name' => 'resources/taxonomy_resource'),
       ),
+      'index' => array(
+        'file' => array('type' => 'inc', 'module' => 'services', 'name' => 'resources/taxonomy_resource'),
+        'callback' => '_taxonomy_term_resource_index',
+        'args' => array(
+          array(
+            'name' => 'page',
+            'optional' => TRUE,
+            'type' => 'int',
+            'description' => 'The zero-based index of the page to get, defaults to 0.',
+            'default value' => 0,
+            'source' => array('param' => 'page'),
+          ),
+          array(
+            'name' => 'fields',
+            'optional' => TRUE,
+            'type' => 'string',
+            'description' => 'The fields to get.',
+            'default value' => '*',
+            'source' => array('param' => 'fields'),
+          ),
+          array(
+            'name' => 'parameters',
+            'optional' => TRUE,
+            'type' => 'struct',
+            'description' => 'Parameters',
+            'default value' => NULL,
+            'source' => array('param' => 'parameters'),
+          ),
+        ),
+        'access callback' => '_taxonomy_resource_access',
+        'access arguments' => array('view'),
+        'access arguments append' => TRUE,
+      ),
       'actions' => array(
         'selectNodes' => array(
           'file' => array('type' => 'inc', 'module' => 'services', 'name' => 'resources/taxonomy_resource'),
@@ -212,6 +245,39 @@ function _taxonomy_resource_definition()
         'access arguments append' => TRUE,
         'file' => array('type' => 'inc', 'module' => 'services', 'name' => 'resources/taxonomy_resource'),
       ),
+      'index' => array(
+        'file' => array('type' => 'inc', 'module' => 'services', 'name' => 'resources/taxonomy_resource'),
+        'callback' => '_taxonomy_vocabulary_resource_index',
+        'args' => array(
+          array(
+            'name' => 'page',
+            'optional' => TRUE,
+            'type' => 'int',
+            'description' => 'The zero-based index of the page to get, defaults to 0.',
+            'default value' => 0,
+            'source' => array('param' => 'page'),
+          ),
+          array(
+            'name' => 'fields',
+            'optional' => TRUE,
+            'type' => 'string',
+            'description' => 'The fields to get.',
+            'default value' => '*',
+            'source' => array('param' => 'fields'),
+          ),
+          array(
+            'name' => 'parameters',
+            'optional' => TRUE,
+            'type' => 'struct',
+            'description' => 'Parameters',
+            'default value' => NULL,
+            'source' => array('param' => 'parameters'),
+          ),
+        ),
+        'access callback' => '_taxonomy_resource_access',
+        'access arguments' => array('view'),
+        'access arguments append' => TRUE,
+      ),
       'actions' =>array(
         'getTree' => array(
           'file' => array('type' => 'inc', 'module' => 'services', 'name' => 'resources/taxonomy_resource'),
@@ -312,6 +378,61 @@ function _taxonomy_term_resource_delete(
   return taxonomy_del_term($tid);
 }
 
+/**
+ * Return an array of optionally paged tids baed on a set of criteria.
+ *
+ * An example request might look like
+ *
+ * http://domain/endpoint/taxonomy_term?fields=tid,name&parameters[tid]=7&parameters[vid]=1
+ *
+ * This would return an array of objects with only tid and name defined, where
+ * tid = 7 and vid = 1.
+ *
+ * @param $page
+ *   Page number of results to return (in pages of 20).
+ * @param $fields
+ *   The fields you want returned.
+ * @param $parameters
+ *   An array of fields and values used to build a sql WHERE clause indicating
+ *   what items should be returned.
+ * @return
+ *   An array of term objects.
+ *
+ * @see _node_resource_index() for more notes
+ **/
+function _taxonomy_term_resource_index($page = 0, $fields = '*', $parameters = array()) {
+  $parameters = (array) $parameters;
+  $schema = drupal_get_schema('term_data');
+  $where = array();
+  $fields = db_escape_string($fields);
+
+  // Build an array of fields with the appropriate placeholders for use in
+  // db_query().
+  foreach ($parameters as $field => $value) {
+    $where[] = $field . ' = ' . db_type_placeholder($schema['fields'][$field]['type']);
+  }
+
+  // Now implode that array into an actual WHERE clause.
+  $where = !empty($where) ? ' WHERE '. implode(' AND ', $where) : '';
+
+  // Run through db_rewrite_sql to make sure proper access checks are applied.
+  $sql = "SELECT $fields FROM {term_data} t $where ORDER BY vid, weight, name";
+  $sql = db_rewrite_sql($sql);
+  $result = db_query_range($sql, $parameters, $page * 20, 20);
+
+  // Put together array of matching terms to return.
+  $terms = array();
+  while ($term = db_fetch_object($result)) {
+    if ($uri = services_resource_uri(array('taxonomy_term', $term->tid))) {
+      $term->uri = $uri;
+    }
+    $terms[] = $term;
+  }
+
+  return $terms;
+}
+
+
 
 /**
  * Return the results of taxonomy_vocabulary_load() for a specified vocabulary id.
@@ -393,6 +514,69 @@ function _taxonomy_vocabulary_resource_d
   return taxonomy_del_vocabulary($vid);
 }
 
+/**
+ * Return an array of optionally paged vids baed on a set of criteria.
+ *
+ * An example request might look like
+ *
+ * http://domain/endpoint/taxonomy_vocabulary?fields=vid,name&parameters[vid]=2
+ *
+ * This would return an array of objects with only vid and name defined, where
+ * vid = 2.
+ *
+ * @param $page
+ *   Page number of results to return (in pages of 20).
+ * @param $fields
+ *   The fields you want returned.
+ * @param $parameters
+ *   An array of fields and values used to build a sql WHERE clause indicating
+ *   what items should be returned.
+ * @return
+ *   An array of vocabulary objects.
+ *
+ * @todo
+ *   Support node types as parameters.
+ *
+ * @see _node_resource_index() for more notes
+ **/
+function _taxonomy_vocabulary_resource_index($page = 0, $fields = '*', $parameters = array()) {
+  $parameters = (array) $parameters;
+  $schema = drupal_get_schema('vocabulary');
+  $where = array();
+  $fields = db_escape_string($fields);
+
+  // Build an array of fields with the appropriate placeholders for use in
+  // db_query().
+  foreach ($parameters as $field => $value) {
+    $where[] = $field . ' = ' . db_type_placeholder($schema['fields'][$field]['type']);
+  }
+
+  // Now implode that array into an actual WHERE clause.
+  $where = !empty($where) ? ' WHERE '. implode(' AND ', $where) : '';
+
+  // Run through db_rewrite_sql to make sure proper access checks are applied.
+  $sql = "SELECT $fields FROM {vocabulary} v $where ORDER BY weight, name";
+  $sql = db_rewrite_sql($sql);
+  $result = db_query_range($sql, $parameters, $page * 20, 20);
+
+  // Put together array of matching vocabularies to return.
+  $vocabs = array();
+  while ($vocab = db_fetch_object($result)) {
+    // Add in the relevant node types
+    $sql = "SELECT type FROM {vocabulary_node_types} t WHERE vid=%d";
+    $type_result = db_query($sql, $vocab->vid);
+    while ($row = db_fetch_object($type_result)) {
+      $vocab->nodes[$row->type] = $row->type;
+    }
+    if ($uri = services_resource_uri(array('taxonomy_vocabulary', $vocab->vid))) {
+      $vocab->uri = $uri;
+    }
+    $vocabs[] = $vocab;
+  }
+
+  return $vocabs;
+}
+
 
 
 /**
Index: tests/functional/ServicesEndpointTests.test
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/services/tests/functional/ServicesEndpointTests.test,v
retrieving revision 1.1.2.4
diff -u -p -r1.1.2.4 ServicesEndpointTests.test
--- tests/functional/ServicesEndpointTests.test	24 Dec 2010 17:53:52 -0000	1.1.2.4
+++ tests/functional/ServicesEndpointTests.test	16 Feb 2011 19:11:04 -0000
@@ -223,6 +223,9 @@ require_once('ServicesWebTestCase.php') 
           'delete' => array(
             'enabled' => 1,
           ),
+          'index' => array(
+            'enabled' => 1,
+          ),
         ),
         'actions' => array(
           'selectNodes' => array(
@@ -245,6 +248,9 @@ require_once('ServicesWebTestCase.php') 
           'delete' => array(
             'enabled' => 1,
           ),
+          'index' => array(
+            'enabled' => 1,
+          ),
         ),
         'actions' => array(
           'getTree' => array(
@@ -295,6 +301,9 @@ require_once('ServicesWebTestCase.php') 
           'delete' => array(
             'enabled' => 1,
           ),
+          'index' => array(
+            'enabled' => 1,
+          ),
         ),
         'actions' => array(
           'loadNodeComments' => array(
@@ -320,6 +329,9 @@ require_once('ServicesWebTestCase.php') 
           'delete' => array(
             'enabled' => 1,
           ),
+          'index' => array(
+            'enabled' => 1,
+          ),
         ),
         'actions' => array(
           'nodeFiles' => array(
@@ -341,9 +353,9 @@ require_once('ServicesWebTestCase.php') 
     services_endpoint_save($endpoint);
     $endpoint = services_endpoint_load($endpoint->name);
     if($endpoint->name == $edit['name']) {
-      $this->pass('Endpoint successfully created');  
+      $this->pass('Endpoint successfully created');
     } else {
-       $this->fail('Endpoint creation failed');  
+       $this->fail('Endpoint creation failed');
     }
      $this->servicesGet($endpoint->path);
      return $endpoint;
@@ -353,7 +365,7 @@ require_once('ServicesWebTestCase.php') 
  *
  */
   public function services_build_postfields($data = array()) {
-    $post_data = '';  
+    $post_data = '';
     if (is_array($data) && !empty($data)) {
       array_walk($data, array($this, 'services_flatten_fields'));
       $post_data = implode('&', $data);
@@ -366,7 +378,7 @@ require_once('ServicesWebTestCase.php') 
   }
 /**
  * Modifies our array data so we can turn it into a querystring
- * 
+ *
  * @param string $item - array value
  * @param string $key  - key of the array element
  */
Index: tests/functional/ServicesResourceCommentTests.test
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/services/tests/functional/Attic/ServicesResourceCommentTests.test,v
retrieving revision 1.1.2.1
diff -u -p -r1.1.2.1 ServicesResourceCommentTests.test
--- tests/functional/ServicesResourceCommentTests.test	19 Jan 2011 00:34:49 -0000	1.1.2.1
+++ tests/functional/ServicesResourceCommentTests.test	16 Feb 2011 19:11:04 -0000
@@ -52,6 +52,28 @@ class ServicesResourceCommentTests exten
   }
 
   /**
+   * Test index method.
+   */
+  public function testCommentIndex() {
+    // Create node with commenting.
+    $settings = array('comment' => 1);
+    $node = $this->drupalCreateNode($settings);
+
+    $comment = array(
+      'uid' => $this->privileged_user->uid,
+      'nid' => $node->nid,
+      'subject' => $this->randomString(),
+      'comment' => $this->randomString(),
+    );
+
+    $cid = comment_save((array) $comment);
+    $comment['cid'] = $cid;
+
+    $responseArray = $this->servicesGet($this->endpoint->path . '/comment');
+    $this->assertTrue($comment['comment'] == $responseArray['body'][0]->comment, t('Successfully received Comment info'), 'TaxonomyVocabularyResource: Index');
+  }
+
+  /**
    * Test create method.
    */
   function testCommentCreate() {
Index: tests/functional/ServicesResourceTaxonomyTests.test
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/services/tests/functional/Attic/ServicesResourceTaxonomyTests.test,v
retrieving revision 1.1.2.1
diff -u -p -r1.1.2.1 ServicesResourceTaxonomyTests.test
--- tests/functional/ServicesResourceTaxonomyTests.test	19 Jan 2011 00:34:49 -0000	1.1.2.1
+++ tests/functional/ServicesResourceTaxonomyTests.test	16 Feb 2011 19:11:04 -0000
@@ -51,6 +51,21 @@ class ServicesResourceTaxonomyTests exte
   }
 
   /**
+   * Test taxonomy vocabulary index method.
+   */
+  public function testVocabularyIndex() {
+    // Create and log in our privileged user.
+    $this->privilegedUser = $this->drupalCreateUser(array(
+      'administer taxonomy',
+    ));
+    $this->drupalLogin($this->privilegedUser);
+
+    $vocabulary = $this->createVocabulary();
+    $responseArray = $this->servicesGet($this->endpoint->path . '/taxonomy_vocabulary');
+    $this->assertTrue($vocabulary['name'] == $responseArray['body'][0]->name, t('Successfully received Vocabulary info'), 'TaxonomyVocabularyResource: Index');
+  }
+
+  /**
    * Test taxonomy vocabulary create method.
    */
   function testVocabularyCreate() {
@@ -184,6 +199,24 @@ class ServicesResourceTaxonomyTests exte
   }
 
   /**
+   * Test taxonomy term index method.
+   */
+  public function testTermIndex() {
+    // Create and log in our privileged user.
+    $this->privilegedUser = $this->drupalCreateUser(array(
+      'administer taxonomy',
+    ));
+    $this->drupalLogin($this->privilegedUser);
+
+    $vocabulary = $this->createVocabulary();
+
+    $term = $this->createTerm($vocabulary['vid']);
+
+    $responseArray = $this->servicesGet($this->endpoint->path . '/taxonomy_term');
+    $this->assertTrue($term['name'] == $responseArray['body'][0]->name, t('Successfully received Term info'), 'TaxonomyTermResource: Index');
+  }
+
+  /**
    * Test taxonomy term create method.
    */
   function testTermCreate() {
Index: tests/functional/ServicesWebTestCase.php
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/services/tests/functional/Attic/ServicesWebTestCase.php,v
retrieving revision 1.1.2.4
diff -u -p -r1.1.2.4 ServicesWebTestCase.php
--- tests/functional/ServicesWebTestCase.php	19 Jan 2011 00:25:40 -0000	1.1.2.4
+++ tests/functional/ServicesWebTestCase.php	16 Feb 2011 19:11:05 -0000
@@ -214,6 +214,9 @@ class ServicesWebTestCase extends Drupal
           'delete' => array(
             'enabled' => 1,
           ),
+          'index' => array(
+            'enabled' => 1,
+          ),
         ),
         'actions' => array(
           'selectNodes' => array(
@@ -236,6 +239,9 @@ class ServicesWebTestCase extends Drupal
           'delete' => array(
             'enabled' => 1,
           ),
+          'index' => array(
+            'enabled' => 1,
+          ),
         ),
         'actions' => array(
           'getTree' => array(
@@ -286,6 +292,9 @@ class ServicesWebTestCase extends Drupal
           'delete' => array(
             'enabled' => 1,
           ),
+          'index' => array(
+            'enabled' => 1,
+          ),
         ),
         'actions' => array(
           'loadNodeComments' => array(
@@ -311,6 +320,9 @@ class ServicesWebTestCase extends Drupal
           'delete' => array(
             'enabled' => 1,
           ),
+          'index' => array(
+            'enabled' => 1,
+          ),
         ),
         'actions' => array(
           'nodeFiles' => array(
