Skip to content
This repository has been archived by the owner on Mar 9, 2022. It is now read-only.

Commit

Permalink
Allow TDViewCompiler to run on view fns in design docs
Browse files Browse the repository at this point in the history
It used to only be called for temporary views. Now if there's a view that's defined in a design doc, but there's no TDView for it, or the TDView has no map block yet, invoke the compiler.

With this, and defining one JS function's block in the demo app, we now pass the view_collation_raw.js unit test :)
  • Loading branch information
snej committed Jan 10, 2012
1 parent 9b0f918 commit c79d553
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 25 deletions.
5 changes: 5 additions & 0 deletions Demo-Mac/DemoAppController.m
Expand Up @@ -221,6 +221,11 @@ - (TDMapBlock) compileMapFunction: (NSString*)mapSource language:(NSString *)lan
if ($equal([doc objectForKey: @"a"], $object(4)))
emit(nil, [doc objectForKey: @"b"]);
};
} else if ($equal(mapSource, @"(function (doc) {emit(doc.foo, null);})") ||
$equal(mapSource, @"function(doc) { emit(doc.foo, null); }")) {
mapBlock = ^(NSDictionary* doc, TDMapEmitBlock emit) {
emit([doc objectForKey: @"foo"], nil);
};
}
return [[mapBlock copy] autorelease];
}
Expand Down
75 changes: 50 additions & 25 deletions Source/TDRouter+Handlers.m
Expand Up @@ -636,11 +636,55 @@ - (TDStatus) do_DELETE: (TDDatabase*)db docID: (NSString*)docID attachment: (NSS
#pragma mark - VIEW QUERIES:


- (TDView*) compileView: (NSString*)viewName fromProperties: (NSDictionary*)viewProps {
NSString* language = [viewProps objectForKey: @"language"] ?: @"javascript";
NSString* mapSource = [viewProps objectForKey: @"map"];
if (!mapSource)
return nil;
TDMapBlock mapBlock = [[TDView compiler] compileMapFunction: mapSource language: language];
if (!mapBlock) {
Warn(@"View %@ has unknown map function: %@", viewName, mapSource);
return nil;
}
NSString* reduceSource = [viewProps objectForKey: @"reduce"];
TDReduceBlock reduceBlock = NULL;
if (reduceSource) {
reduceBlock =[[TDView compiler] compileReduceFunction: reduceSource language: language];
if (!reduceBlock) {
Warn(@"View %@ has unknown reduce function: %@", viewName, reduceSource);
return nil;
}
}

TDView* view = [_db viewNamed: viewName];
[view setMapBlock: mapBlock reduceBlock: reduceBlock version: @"1"];

NSDictionary* options = $castIf(NSDictionary, [viewProps objectForKey: @"options"]);
if ($equal([options objectForKey: @"collation"], @"raw"))
view.collation = kTDViewCollationRaw;
return view;
}


- (TDStatus) queryDesignDoc: (NSString*)designDoc view: (NSString*)viewName keys: (NSArray*)keys {
viewName = $sprintf(@"%@/%@", designDoc, viewName);
TDView* view = [_db existingViewNamed: viewName];
if (!view)
return 404;
NSString* tdViewName = $sprintf(@"%@/%@", designDoc, viewName);
TDView* view = [_db existingViewNamed: tdViewName];
if (!view || !view.mapBlock) {
// No TouchDB view is defined, or it hasn't had a map block assigned;
// see if there's a CouchDB view definition we can compile:
TDRevision* rev = [_db getDocumentWithID: [@"_design/" stringByAppendingString: designDoc]
revisionID: nil options: 0];
if (!rev)
return 404;
NSDictionary* views = $castIf(NSDictionary, [rev.properties objectForKey: @"views"]);
NSDictionary* viewProps = $castIf(NSDictionary, [views objectForKey: viewName]);
if (!viewProps)
return 404;
// If there is a CouchDB view, see if it can be compiled from source:
view = [self compileView: tdViewName fromProperties: viewProps];
if (!view)
return 500;
}

TDQueryOptions options;
if (![self getQueryOptions: &options])
Expand Down Expand Up @@ -686,31 +730,12 @@ - (TDStatus) do_POST_temp_view: (TDDatabase*)db {
if (![self getQueryOptions: &options])
return 400;

TDView* view = [_db viewNamed: @"@@TEMP@@"];
TDView* view = [self compileView: @"@@TEMP@@" fromProperties: props];
if (!view)
return 500;
@try {
NSString* language = [props objectForKey: @"language"] ?: @"javascript";
NSString* mapSource = [props objectForKey: @"map"];
TDMapBlock mapBlock = [[TDView compiler] compileMapFunction: mapSource language: language];
if (!mapBlock) {
Warn(@"Unknown map function source: %@", mapSource);
return 500;
}
NSString* reduceSource = [props objectForKey: @"reduce"];
TDReduceBlock reduceBlock = NULL;
if (reduceSource) {
reduceBlock =[[TDView compiler] compileReduceFunction: reduceSource language: language];
if (!reduceBlock) {
Warn(@"Unknown reduce function source: %@", reduceSource);
return 500;
}
}

[view setMapBlock: mapBlock reduceBlock: reduceBlock version: @"1"];
if (reduceBlock)
if (view.reduceBlock)
options.reduce = YES;

TDStatus status;
NSArray* rows = [view queryWithOptions: &options status: &status];
if (!rows)
Expand Down

0 comments on commit c79d553

Please sign in to comment.