Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Allow TDViewCompiler to run on view fns in design docs

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...
commit c79d5535e8976ffaf4c8c32d9c576d6c2dc85427 1 parent 9b0f918
@snej snej authored
Showing with 55 additions and 25 deletions.
  1. +5 −0 Demo-Mac/DemoAppController.m
  2. +50 −25 Source/TDRouter+Handlers.m
View
5 Demo-Mac/DemoAppController.m
@@ -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];
}
View
75 Source/TDRouter+Handlers.m
@@ -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])
@@ -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)
Please sign in to comment.
Something went wrong with that request. Please try again.