Skip to content

Commit

Permalink
Modifications to support couch 0.9.
Browse files Browse the repository at this point in the history
  • Loading branch information
objectiveous committed Mar 25, 2009
1 parent 56d085c commit 27567a1
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 55 deletions.
5 changes: 4 additions & 1 deletion Classes/SBCouchDesignDocument.h
Expand Up @@ -15,7 +15,7 @@
Couple a facts about couchDB are important to understand when working with this class.
1] Design documents currently get stored in database/_design.
2] Views get executed via HTTP GET calls to database/_view
2] Views get executed via HTTP GET calls to database/_design/DesignName/_view/viewName
Now, given that SBCouchDocument and SBCouchView are intend to be Resources in the REST sense
of the word both these types (SBCouchDocument and SBCouchView) have an identity property which
Expand Down Expand Up @@ -55,4 +55,7 @@
- (SBCouchView*)view:(NSString*)viewName;
- (NSString*)language;
- (NSDictionary*)views;
/// Returns the name of the design document which is the last path part. For example, given a SBCouchDesignDocument
/// with an identity of _design/docName, a call to designDocumentName would yield docName.
- (NSString*)designDocumentName;
@end
96 changes: 51 additions & 45 deletions Classes/SBCouchDesignDocument.m
Expand Up @@ -12,6 +12,8 @@

@interface SBCouchDesignDocument (Private)
-(void) createAndAddView:(NSDictionary*)viewDictionary withName:(NSString*)viewName;
-(void) reifyViews; // for example, if include docs is used when fetching all design docs, one wants to actually have real view objects.
-(void) copyViews:(NSDictionary*)viewDictionary;
@end

@implementation SBCouchDesignDocument
Expand Down Expand Up @@ -43,57 +45,56 @@ -(id)initWithDictionary:(NSDictionary*)aDictionary couchDatabase:(SBCouchDatabas
SBOrderedDictionary *views = [SBOrderedDictionary dictionaryWithCapacity:5];
[self setObject:views forKey:@"views"];
self.couchDatabase = aCouchDatabaseOrNil;
// Copy all the keys from the NSDictionary *except* for doc. If doc is shows up
// include_docs=true was used in the GET and we need to create proper SBCouchView
// documents.
for(id key in aDictionary){
if([@"doc" isEqualToString:key])
continue;

NSDictionary *valueObject = [aDictionary objectForKey:@"value"];
if(valueObject){
id rev = [valueObject objectForKey:@"rev"];
[self setObject:rev forKey:@"_rev"];
}

id o = [aDictionary objectForKey:key];
id someObject = [o copy];
if([@"views" isEqualToString:key]){
NSMutableDictionary *viewDictionary = [self objectForKey:@"views"];
// Do a straight ahead copy;
for(id key in aDictionary){
// When aDictionary is actually an instance of SBCouchDocument, we need to
// make copies of the SBCouchViews held in the views key.
if([key isEqualToString:@"views"]){
[self copyViews:[aDictionary objectForKey:key]];
}else{
[self setObject:[aDictionary objectForKey:key] forKey:key];
}
}
[self reifyViews];
}
NSLog(@" --> %i ", [[self views] count]);
return self;
}

for(id viewKey in someObject){
SBCouchView *view = [someObject objectForKey:viewKey];

[viewDictionary setObject:[view copy] forKey:viewKey];
}
-(void) copyViews:(NSDictionary*)viewDictionary{
for(id viewName in viewDictionary){
SBCouchView *view = [viewDictionary objectForKey:viewName];
//if(! [view isKindOfClass:[SBCouchView class]])
// continue;
//XXX SBCouchView should really have a copy method.
[self createAndAddView:view withName:viewName];
}
}

}else{
[self setObject:someObject forKey:key];
}
-(void) reifyViews{
id doc = [self objectForKey:@"doc"];
if(doc){
if([doc objectForKey:COUCH_KEY_LANGUAGE])
[self setObject:[doc objectForKey:COUCH_KEY_LANGUAGE] forKey:COUCH_KEY_LANGUAGE];

if([doc objectForKey:@"_rev"]){
[self setObject:[doc objectForKey:@"_rev"] forKey:@"_rev"];
[self setObject:[doc objectForKey:@"_rev"] forKey:@"rev"];
}

id doc = [aDictionary objectForKey:@"doc"];
if(doc){
//[self setObject:[aDictionary objectForKey:key] forKey:key];
// XXX DONT MAKE ASSUMTIONS
if([doc objectForKey:COUCH_KEY_LANGUAGE])
[self setObject:[doc objectForKey:COUCH_KEY_LANGUAGE] forKey:COUCH_KEY_LANGUAGE];

id views = [doc objectForKey:COUCH_KEY_VIEWS];
if(views){
NSMutableDictionary *v = [NSMutableDictionary dictionaryWithCapacity:2];
[self setObject:v forKey:COUCH_KEY_VIEWS];

id views = [doc objectForKey:COUCH_KEY_VIEWS];
if(views){
NSMutableDictionary *v = [NSMutableDictionary dictionaryWithCapacity:2];
[self setObject:v forKey:COUCH_KEY_VIEWS];

for(id viewName in views){
SBCouchView *childView = [views objectForKey:viewName];
[self createAndAddView:childView withName:viewName];
}
for(id viewName in views){
SBCouchView *childView = [views objectForKey:viewName];
[self createAndAddView:childView withName:viewName];
}
}
}
return self;
}

}

-(void)dealloc{
[super dealloc];
}
Expand All @@ -103,7 +104,7 @@ -(void) createAndAddView:(NSDictionary*)viewDictionary withName:(NSString*)viewN
SBCouchView *view = [[[SBCouchView alloc] initWithName:viewName couchDatabase:self.couchDatabase dictionary:viewDictionary ] autorelease];

// Once CouchDB 0.9 is released, _view will be something like _design/designName/_view/viewName
NSString *viewIdentity = [NSString stringWithFormat:@"_view/%@/%@", [[self identity] lastPathComponent], view.name];
NSString *viewIdentity = [NSString stringWithFormat:@"_design/%@/_view/%@", [[self identity] lastPathComponent], view.name];
view.identity = viewIdentity;
[self addView:view withName:view.name];
}
Expand Down Expand Up @@ -132,6 +133,11 @@ -(SBCouchView*)view:(NSString*)viewName{
return [[self views] objectForKey:viewName];
}

- (NSString*)designDocumentName{
if(self.identity)
return [self.identity lastPathComponent];
return nil;
}
#pragma mark -
- (id)copy{
// I don't think this will work as it doesn't actually do a deep copy
Expand Down
47 changes: 39 additions & 8 deletions Classes/SBCouchDocument.m
Expand Up @@ -51,7 +51,11 @@ -(void)dealloc{

#pragma mark -
-(NSArray*)revs{
return [self objectForKey:@"_revs"];
id revisionDict = [self objectForKey:COUCH_KEY_REVISIONS];
NSLog(@"%@", revisionDict);

NSArray *ids = [revisionDict objectForKey:COUCH_KEY_IDS];
return ids;
}


Expand Down Expand Up @@ -98,30 +102,44 @@ -(SBOrderedDictionary*) makeDictionaryOrderly:(NSDictionary*)aDictionary{

-(NSString*)previousRevision{
NSUInteger index = [self revisionIndex];
if(index == NSNotFound)
if(index == NSNotFound || index == 0)
return nil;

id previousR = [[self revs] objectAtIndex:index-1];

/*
Old revision work 0.9
if([[self revs] count] > index){
return [[self revs] objectAtIndex:index+1];
}
return nil;
*/
}

-(NSInteger)revisionIndex{
NSArray *revArray = [self revs];
if([revArray count] <= 0)
return NSNotFound;

NSString *thisRevision = [self objectForKey:@"_rev"];
NSString *thisRevision = [self objectForKey:COUCH_KEY_REV];
// XXX
// strip leading x- value from _rev. Not sure how these work leading values work yet.
// the API just changed.
NSArray *revisonParts = [thisRevision componentsSeparatedByString:@"-"];
NSString *indexPart = [revisonParts objectAtIndex:0];
NSString *versionPart = [revisonParts objectAtIndex:1];

BOOL inThere = [revArray containsObject:thisRevision];
BOOL inThere = [revArray containsObject:versionPart];
if(! inThere)
return NSNotFound;

//NSUInteger index = [revArray indexOfObject:versionPart];
//return index;

NSUInteger index = [revArray indexOfObject:thisRevision];
NSInteger index = [indexPart integerValue];
return index;

}


Expand All @@ -143,7 +161,7 @@ -(NSArray*) convertArrayContents:(NSArray*)anArray{
}

-(NSInteger)numberOfRevisions{
NSDictionary *revs = [self objectForKey:@"_revs"];
NSDictionary *revs = [self objectForKey:COUCH_KEY_REVISIONS];
return [revs count];
}

Expand All @@ -162,7 +180,18 @@ - (NSString *)description{


- (NSString*)revision {
return [self objectForKey:@"_rev"];
// pre 0.9 code
//return [self objectForKey:@"_rev"];

NSString *thisRevision = [self objectForKey:COUCH_KEY_REV];
// XXX
// strip leading x- value from _rev. Not sure how these work leading values work yet.
// the API just changed.
NSArray *revisonParts = [thisRevision componentsSeparatedByString:@"-"];
NSString *indexPart = [revisonParts objectAtIndex:0];
NSString *versionPart = [revisonParts objectAtIndex:1];
return versionPart;

}

- (NSString*)identity {
Expand All @@ -177,8 +206,10 @@ - (void)setIdentity:(NSString*)someId {
[self setObject:someId forKey:@"_id"];
}

// XXX This is a mess. Which is it _rev or rev?
- (void)setRevision:(NSString*)aRevision {
[self setObject:aRevision forKey:@"_rev"];
[self setObject:aRevision forKey:@"rev"];
}

- (void)detach{
Expand Down
2 changes: 1 addition & 1 deletion Classes/SBCouchEnumerator.m
Expand Up @@ -137,7 +137,7 @@ - (NSArray *)allObjects{
-(void)fetchNextPage{
// contruct a new URL using our own copy of the query options
// View URLs are expected to have names like
// _view/designdocName/viewName?xx=xx && _all_docs
// _design/designdocName/_view/viewName?xx=xx && _all_docs
// This format will be changing in the 0.9 release of CouchDB
NSDictionary *etf;
NSString *contructedUrl;
Expand Down

0 comments on commit 27567a1

Please sign in to comment.