Skip to content

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
...
  • 5 commits
  • 12 files changed
  • 0 commit comments
  • 2 contributors
Commits on Apr 09, 2012
@jchris jchris if the URL contains basic-auth credentials, use them without waiting …
…for 401 challenge
78c20bd
Commits on Apr 11, 2012
@snej snej Fix build break (missing TDBase64.h)
Build was broken by previous commit 78c20bd.
Replace use of TDBase64 (which exists in Syncpoint but not the other branches) with RESTBase64.

Change-Id: Ic155d8e9761e244a8cdcc0a00982d1ad98ec8caa
863d676
@snej snej Make change tracker work with URLs without an explicit port
Use port 80 if _databaseURL.port is 0 (unspecified).
I have no idea why I have to keep making this fix over and over! Somehow it didn't make it into this branch of this class...

Change-Id: I109fa014c09bd2bc0bc51f549a53c2227f0d1ab0
9a3ada3
Commits on Apr 18, 2012
@snej snej Merge remote-tracking branch 'refs/remotes/origin/touchdb' into syncp…
…oint

Conflicts:
	REST/RESTResource.m
2b4591c
Commits on May 04, 2012
@snej snej Fixed a bunch of memory leaks and refcount cycles.
Most of these only become apparent when trying to close a CouchServer or TDServer.
d7021c8
View
4 Couch/CouchDatabase.m
@@ -157,6 +157,10 @@ - (void) clearDocumentCache {
[_docCache forgetAllResources];
}
+- (void) unretainDocumentCache {
+ [_docCache unretainResources];
+}
+
#pragma mark -
#pragma mark BATCH CHANGES
View
1 Couch/CouchInternal.h
@@ -38,6 +38,7 @@ typedef void (^OnDatabaseChangeBlock)(CouchDocument*, BOOL externalChange);
- (void) beginDocumentOperation: (CouchResource*)resource;
- (void) endDocumentOperation: (CouchResource*)resource;
- (void) onChange: (OnDatabaseChangeBlock)block; // convenience for unit tests
+- (void) unretainDocumentCache;
@end
View
12 Couch/CouchQuery.h
@@ -35,7 +35,7 @@ typedef enum {
NSString* _startKeyDocID;
NSString* _endKeyDocID;
CouchStaleness _stale;
- BOOL _descending, _prefetch;
+ BOOL _descending, _prefetch, _sequences;
NSArray *_keys;
NSUInteger _groupLevel;
}
@@ -80,6 +80,8 @@ typedef enum {
These can be accessed via CouchQueryRow's -documentContents property. */
@property BOOL prefetch;
+@property BOOL sequences;
+
/** Starts an asynchronous query of the CouchDB view.
When complete, the operation's resultObject will be the CouchQueryEnumerator. */
@@ -122,7 +124,7 @@ typedef enum {
@interface CouchQueryEnumerator : NSEnumerator <NSCopying>
{
@private
- CouchQuery* _query;
+ CouchDatabase* _database;
NSArray* _rows;
NSUInteger _totalCount;
NSUInteger _nextRow;
@@ -151,11 +153,10 @@ typedef enum {
@interface CouchQueryRow : NSObject
{
@private
- CouchQuery* _query;
+ CouchDatabase* _database;
id _result;
}
-@property (readonly) CouchQuery* query;
@property (readonly) id key;
@property (readonly) id value;
@@ -187,4 +188,7 @@ typedef enum {
/** Convenience for use in keypaths. Returns the key at the given index. */
@property (readonly) id key0, key1, key2, key3;
+/** The local sequence number of the associated doc/revision.
+ Valid only if the 'sequences' and 'prefetch' properties were set in the query; otherwise returns 0. */
+@property (readonly) UInt64 localSequence;
@end
View
65 Couch/CouchQuery.m
@@ -23,12 +23,12 @@
@interface CouchQueryEnumerator ()
-- (id) initWithQuery: (CouchQuery*)query result: (NSDictionary*)result;
+- (id) initWithDatabase: (CouchDatabase*)db result: (NSDictionary*)result;
@end
@interface CouchQueryRow ()
-- (id) initWithQuery: (CouchQuery*)query result: (id)result;
+- (id) initWithDatabase: (CouchDatabase*)db result: (id)result;
@end
@@ -69,7 +69,7 @@ - (void) dealloc
@synthesize limit=_limit, skip=_skip, descending=_descending, startKey=_startKey, endKey=_endKey,
prefetch=_prefetch, keys=_keys, groupLevel=_groupLevel, startKeyDocID=_startKeyDocID,
- endKeyDocID=_endKeyDocID, stale=_stale;
+ endKeyDocID=_endKeyDocID, stale=_stale, sequences=_sequences;
- (CouchDesignDocument*) designDocument {
@@ -111,6 +111,8 @@ - (NSMutableDictionary*) requestParams {
[params setObject: @"true" forKey: @"?descending"];
if (_prefetch)
[params setObject: @"true" forKey: @"?include_docs"];
+ if (_sequences)
+ [params setObject: @"true" forKey: @"?local_seq"];
if (_groupLevel > 0)
[params setObject: [NSNumber numberWithUnsignedLong: _groupLevel] forKey: @"?group_level"];
[params setObject: @"true" forKey: @"?update_seq"];
@@ -148,8 +150,8 @@ - (NSError*) operation: (RESTOperation*)op willCompleteWithError: (NSError*)erro
NSArray* rows = $castIf(NSArray, [result objectForKey: @"rows"]);
if (rows) {
[self cacheResponse: op];
- op.resultObject = [[[CouchQueryEnumerator alloc] initWithQuery: self
- result: result] autorelease];
+ op.resultObject = [[[CouchQueryEnumerator alloc] initWithDatabase: self.database
+ result: result] autorelease];
} else {
Warn(@"Couldn't parse rows from CouchDB view response");
error = [RESTOperation errorWithHTTPStatus: 502 message: nil URL: self.URL];
@@ -269,7 +271,8 @@ - (NSError*) operation: (RESTOperation*)op willCompleteWithError: (NSError*)erro
if (rows && ![rows isEqual: _rows]) {
COUCHLOG(@"CouchLiveQuery: ...Rows changed! (now %lu)", (unsigned long)rows.count);
self.rows = rows; // Triggers KVO notification
- self.prefetch = NO; // (prefetch disables conditional GET shortcut on next fetch)
+ if (!self.sequences)
+ self.prefetch = NO; // (prefetch disables conditional GET shortcut on next fetch)
// If this query isn't up-to-date (race condition where the db updated again after sending
// the response), start another fetch.
@@ -293,19 +296,19 @@ @implementation CouchQueryEnumerator
@synthesize totalCount=_totalCount, sequenceNumber=_sequenceNumber;
-- (id) initWithQuery: (CouchQuery*)query
- rows: (NSArray*)rows
- totalCount: (NSUInteger)totalCount
- sequenceNumber: (NSUInteger)sequenceNumber
+- (id) initWithDatabase: (CouchDatabase*)database
+ rows: (NSArray*)rows
+ totalCount: (NSUInteger)totalCount
+ sequenceNumber: (NSUInteger)sequenceNumber
{
- NSParameterAssert(query);
+ NSParameterAssert(database);
self = [super init];
if (self ) {
if (!rows) {
[self release];
return nil;
}
- _query = [query retain];
+ _database = database;
_rows = [rows retain];
_totalCount = totalCount;
_sequenceNumber = sequenceNumber;
@@ -313,24 +316,23 @@ - (id) initWithQuery: (CouchQuery*)query
return self;
}
-- (id) initWithQuery: (CouchQuery*)query result: (NSDictionary*)result {
- return [self initWithQuery: query
- rows: $castIf(NSArray, [result objectForKey: @"rows"])
- totalCount: [[result objectForKey: @"total_rows"] intValue]
- sequenceNumber: [[result objectForKey: @"update_seq"] intValue]];
+- (id) initWithDatabase: (CouchDatabase*)db result: (NSDictionary*)result {
+ return [self initWithDatabase: db
+ rows: $castIf(NSArray, [result objectForKey: @"rows"])
+ totalCount: [[result objectForKey: @"total_rows"] intValue]
+ sequenceNumber: [[result objectForKey: @"update_seq"] intValue]];
}
- (id) copyWithZone: (NSZone*)zone {
- return [[[self class] alloc] initWithQuery: _query
- rows: _rows
- totalCount: _totalCount
- sequenceNumber: _sequenceNumber];
+ return [[[self class] alloc] initWithDatabase: _database
+ rows: _rows
+ totalCount: _totalCount
+ sequenceNumber: _sequenceNumber];
}
- (void) dealloc
{
- [_query release];
[_rows release];
[super dealloc];
}
@@ -352,8 +354,8 @@ - (NSUInteger) count {
- (CouchQueryRow*) rowAtIndex: (NSUInteger)index {
- return [[[CouchQueryRow alloc] initWithQuery: _query
- result: [_rows objectAtIndex:index]]
+ return [[[CouchQueryRow alloc] initWithDatabase: _database
+ result: [_rows objectAtIndex:index]]
autorelease];
}
@@ -378,7 +380,7 @@ - (id) nextObject {
@implementation CouchQueryRow
-- (id) initWithQuery: (CouchQuery*)query result: (id)result {
+- (id) initWithDatabase: (CouchDatabase*)database result: (id)result {
self = [super init];
if (self) {
if (![result isKindOfClass: [NSDictionary class]]) {
@@ -386,7 +388,7 @@ - (id) initWithQuery: (CouchQuery*)query result: (id)result {
[self release];
return nil;
}
- _query = [query retain];
+ _database = database;
_result = [result retain];
}
return self;
@@ -394,14 +396,11 @@ - (id) initWithQuery: (CouchQuery*)query result: (id)result {
- (void)dealloc {
- [_query release];
[_result release];
[super dealloc];
}
-@synthesize query=_query;
-
- (id) key {return [_result objectForKey: @"key"];}
- (id) value {return [_result objectForKey: @"value"];}
- (NSString*) sourceDocumentID {return [_result objectForKey: @"id"];}
@@ -451,12 +450,18 @@ - (CouchDocument*) document {
NSString* docID = self.documentID;
if (!docID)
return nil;
- CouchDocument* doc = [_query.database documentWithID: docID];
+ CouchDocument* doc = [_database documentWithID: docID];
[doc loadCurrentRevisionFrom: self];
return doc;
}
+- (UInt64) localSequence {
+ id seq = [self.documentProperties objectForKey: @"_local_seq"];
+ return $castIf(NSNumber, seq).unsignedLongLongValue;
+}
+
+
- (NSString*) description {
return [NSString stringWithFormat: @"%@[key=%@; value=%@; id=%@]",
[self class],
View
3 Couch/CouchServer.h
@@ -36,6 +36,9 @@
/** Without a URL, connects to localhost on default port 5984. */
- (id) init;
+/** Releases all resources used by the CouchServer instance. */
+- (void) close;
+
/** Fetches the server's current version string. (Synchronous) */
- (NSString*) getVersion: (NSError**)outError;
View
10 Couch/CouchServer.m
@@ -53,6 +53,14 @@ - (void)dealloc {
}
+- (void) close {
+ [_replicationsQuery release];
+ _replicationsQuery = nil;
+ for (CouchDatabase* db in _dbCache.allCachedResources)
+ [db unretainDocumentCache];
+}
+
+
- (RESTResource*) childWithPath: (NSString*)name {
return [[[CouchResource alloc] initWithParent: self relativePath: name] autorelease];
}
@@ -122,7 +130,7 @@ - (CouchLiveQuery*) replicationsQuery {
if (!_replicationsQuery) {
CouchDatabase* replicatorDB = [self replicatorDatabase];
replicatorDB.tracksChanges = YES;
- _replicationsQuery = [[replicatorDB getAllDocuments] asLiveQuery];
+ _replicationsQuery = [[[replicatorDB getAllDocuments] asLiveQuery] retain];
[_replicationsQuery wait];
}
return _replicationsQuery;
View
2 Couch/CouchSocketChangeTracker.m
@@ -61,7 +61,7 @@ - (BOOL) start {
_trackingOutput = (NSOutputStream*)cfOutputStream;
#else
[NSStream getStreamsToHost: [NSHost hostWithName: _databaseURL.host]
- port: _databaseURL.port.intValue
+ port: _databaseURL.port.intValue ?: 80
inputStream: &_trackingInput outputStream: &_trackingOutput];
if (!_trackingOutput)
return NO;
View
3 Couch/CouchTouchDBServer.h
@@ -28,6 +28,9 @@
/** Preferred initializer. Starts up an in-process server that stores its data in the default location (in the app's Application Support directory). */
- (id)init;
+/** Shuts down the TouchDB server. */
+- (void) close;
+
/** Starts up a server that stores its data at the given path.
@param serverPath The filesystem path to the server directory. If it doesn't already exist it will be created. */
- (id) initWithServerPath: (NSString*)serverPath;
View
15 Couch/CouchTouchDBServer.m
@@ -60,9 +60,11 @@ - (id) initWithServerPath: (NSString*)serverPath {
self = [super initWithURL: rootURL];
if (self) {
- _touchServer = [server retain];
+ _touchServer = server;
if (!server)
_error = [error retain];
+ } else {
+ [server release];
}
return self;
}
@@ -78,8 +80,7 @@ - (id) initWithURL:(NSURL *)url {
- (void) dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
- [_touchServer close];
- [_touchServer release];
+ [self close];
[_error release];
[super dealloc];
}
@@ -99,6 +100,14 @@ - (void) tellTDDatabaseNamed: (NSString*)dbName to: (void (^)(TDDatabase*))block
}
+- (void) close {
+ [super close];
+ [_touchServer close];
+ [_touchServer release];
+ _touchServer = nil;
+}
+
+
#pragma mark - ACTIVITY:
// I don't have to resort to polling the /_activity URL; I can listen for direct notifications
View
2 CouchCocoa.xcodeproj/project.pbxproj
@@ -1790,7 +1790,6 @@
"\"$(SRCROOT)/../build/Syncpoint/Build/Products/Debug\"",
);
ONLY_ACTIVE_ARCH = NO;
- OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = CouchCocoa;
PUBLIC_HEADERS_FOLDER_PATH = CouchCocoa;
SKIP_INSTALL = YES;
@@ -1812,7 +1811,6 @@
"\"$(SRCROOT)/../build/Syncpoint/Build/Products/Debug\"",
);
ONLY_ACTIVE_ARCH = NO;
- OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = CouchCocoa;
PUBLIC_HEADERS_FOLDER_PATH = CouchCocoa;
SKIP_INSTALL = YES;
View
6 REST/RESTCache.h
@@ -55,4 +55,10 @@
/** Removes all resources from the cache. */
- (void) forgetAllResources;
+/** Removes retained references to objects.
+ All objects that don't have anything else retaining them will be removed from the cache. */
+- (void) unretainResources;
+
+- (NSArray*) allCachedResources;
+
@end
View
10 REST/RESTCache.m
@@ -100,6 +100,16 @@ - (void) resourceBeingDealloced:(RESTResource*)resource {
}
+- (NSArray*) allCachedResources {
+ return _map.allValues;
+}
+
+
+- (void) unretainResources {
+ [_cache removeAllObjects];
+}
+
+
- (void) forgetAllResources {
[_map removeAllObjects];
[_cache removeAllObjects];

No commit comments for this range

Something went wrong with that request. Please try again.