Permalink
Browse files

Support for getting specific keys from a view

Added support for issuing a POST request to a view and adding the structure {"keys": ["key1", "key2", ...]} to the body, as per http://wiki.apache.org/couchdb/HTTP_view_API

Original patch by alexanderedge: #21
Cleanup & unit test by snej.
  • Loading branch information...
snej committed Jan 8, 2012
1 parent 03f9a66 commit 19014f025758c1be1db50d3fda9e0c6b4c5b2ad6
Showing with 40 additions and 6 deletions.
  1. +16 −2 Source/TDRouter+Handlers.m
  2. +1 −0 Source/TDView.h
  3. +14 −3 Source/TDView.m
  4. +9 −1 Source/TDView_Tests.m
View
@@ -636,15 +636,16 @@ - (TDStatus) do_DELETE: (TDDatabase*)db docID: (NSString*)docID attachment: (NSS
#pragma mark - VIEW QUERIES: #pragma mark - VIEW QUERIES:
- (TDStatus) do_GET: (TDDatabase*)db designDocID: (NSString*)designDoc view: (NSString*)viewName { - (TDStatus) queryDesignDoc: (NSString*)designDoc view: (NSString*)viewName keys: (NSArray*)keys {
viewName = $sprintf(@"%@/%@", designDoc, viewName); viewName = $sprintf(@"%@/%@", designDoc, viewName);
TDView* view = [db existingViewNamed: viewName]; TDView* view = [_db existingViewNamed: viewName];
if (!view) if (!view)
return 404; return 404;
TDQueryOptions options; TDQueryOptions options;
if (![self getQueryOptions: &options]) if (![self getQueryOptions: &options])
return 400; return 400;
options.keys = keys;
TDStatus status; TDStatus status;
NSArray* rows = [view queryWithOptions: &options status: &status]; NSArray* rows = [view queryWithOptions: &options status: &status];
@@ -659,6 +660,19 @@ - (TDStatus) do_GET: (TDDatabase*)db designDocID: (NSString*)designDoc view: (NS
} }
- (TDStatus) do_GET: (TDDatabase*)db designDocID: (NSString*)designDoc view: (NSString*)viewName {
return [self queryDesignDoc: designDoc view: viewName keys: nil];
}
- (TDStatus) do_POST: (TDDatabase*)db designDocID: (NSString*)designDoc view: (NSString*)viewName {
NSArray* keys = $castIf(NSArray, [self.bodyAsDictionary objectForKey: @"keys"]);
if (!keys)
return 400;
return [self queryDesignDoc: designDoc view: viewName keys: keys];
}
- (TDStatus) do_POST_temp_view: (TDDatabase*)db { - (TDStatus) do_POST_temp_view: (TDDatabase*)db {
if (![[_request valueForHTTPHeaderField: @"Content-Type"] hasPrefix: @"application/json"]) if (![[_request valueForHTTPHeaderField: @"Content-Type"] hasPrefix: @"application/json"])
return 415; return 415;
View
@@ -29,6 +29,7 @@ typedef id (^TDReduceBlock)(NSArray* keys, NSArray* values, BOOL rereduce);
typedef struct TDQueryOptions { typedef struct TDQueryOptions {
__unsafe_unretained id startKey; __unsafe_unretained id startKey;
__unsafe_unretained id endKey; __unsafe_unretained id endKey;
__unsafe_unretained NSArray* keys;
unsigned skip; unsigned skip;
unsigned limit; unsigned limit;
unsigned groupLevel; unsigned groupLevel;
View
@@ -25,9 +25,9 @@
const TDQueryOptions kDefaultTDQueryOptions = { const TDQueryOptions kDefaultTDQueryOptions = {
nil, nil, .limit = UINT_MAX,
0, UINT_MAX, 0, 0, .inclusiveEnd = YES
NO, NO, NO, YES, NO, NO // everything else will default to nil/0/NO
}; };
@@ -277,6 +277,17 @@ - (FMResultSet*) resultSetWithOptions: (const TDQueryOptions*)options
[sql appendString: @" FROM maps, revs, docs WHERE maps.view_id=?"]; [sql appendString: @" FROM maps, revs, docs WHERE maps.view_id=?"];
NSMutableArray* args = $marray($object(_viewID)); NSMutableArray* args = $marray($object(_viewID));
if (options->keys) {
[sql appendString:@" AND key in ("];
NSString* item = @"?";
for (NSString * key in options->keys) {
[sql appendString: item];
item = @",?";
[args addObject: toJSONString(key)];
}
[sql appendString:@")"];
}
id minKey = options->startKey, maxKey = options->endKey; id minKey = options->startKey, maxKey = options->endKey;
BOOL inclusiveMin = YES, inclusiveMax = options->inclusiveEnd; BOOL inclusiveMin = YES, inclusiveMax = options->inclusiveEnd;
if (options->descending) { if (options->descending) {
View
@@ -190,7 +190,15 @@
rows = [view queryWithOptions: &options status: &status]; rows = [view queryWithOptions: &options status: &status];
expectedRows = $array($dict({@"id", @"44444"}, {@"key", @"four"})); expectedRows = $array($dict({@"id", @"44444"}, {@"key", @"four"}));
CAssertEqual(rows, expectedRows); CAssertEqual(rows, expectedRows);
}
// Specific keys:
options = kDefaultTDQueryOptions;
options.keys = $array(@"two", @"four");
rows = [view queryWithOptions: &options status: &status];
expectedRows = $array($dict({@"id", @"44444"}, {@"key", @"four"}),
$dict({@"id", @"22222"}, {@"key", @"two"}));
CAssertEqual(rows, expectedRows);
}
TestCase(TDView_AllDocsQuery) { TestCase(TDView_AllDocsQuery) {

0 comments on commit 19014f0

Please sign in to comment.