Permalink
Browse files

created proxies for CouchQueryEnumerator and CouchQueryRow. It seemed…

… more useful to have live references to the CouchDocument object behind a query row than to convert that document to a dictionary.
  • Loading branch information...
pegli committed Apr 13, 2012
1 parent 67c968a commit 671937fcf42de4729f24602504b99a3681e49b1d
@@ -41,6 +41,13 @@ - (id)isDeleted {
return [NSNumber numberWithBool:self.document.isDeleted];
}
+- (void)deleteDocument:(id)args {
+ RESTOperation * op = [self.document DELETE];
+ if (![op wait]) {
+ NSAssert(op.error.code == 404, @"Error deleting document: %@", op.error);
+ }
+}
+
// skip modelObject
#pragma mark REVISIONS:
@@ -8,9 +8,19 @@
#import "TiProxy.h"
-@class CouchQuery;
+@class CouchQuery, CouchQueryRow, CouchQueryEnumerator;
@interface CouchQueryProxy : TiProxy
@property (nonatomic, strong) CouchQuery * query;
+ (CouchQueryProxy *)proxyWith:(CouchQuery *)q;
@end
+
+@interface CouchQueryRowProxy :TiProxy
+@property (nonatomic, strong) CouchQueryRow * row;
++ (CouchQueryRowProxy *)proxyWith:(CouchQueryRow *)e;
+@end
+
+@interface CouchQueryEnumeratorProxy :TiProxy
+@property (nonatomic, strong) CouchQueryEnumerator * enumerator;
++ (CouchQueryEnumeratorProxy *)proxyWith:(CouchQueryEnumerator *)e;
+@end
@@ -8,6 +8,7 @@
#import "CouchQueryProxy.h"
#import "CouchDesignDocumentProxy.h"
+#import "CouchDocumentProxy.h"
#import <CouchCocoa/CouchQuery.h>
#import <CouchCocoa/RESTOperation.h>
@@ -26,17 +27,6 @@ + (CouchQueryProxy *)proxyWith:(CouchQuery *)q {
return q ? [[[CouchQueryProxy alloc] initWithCouchQuery:q] autorelease] : nil;
}
-- (NSDictionary *)toQueryResult:(CouchQueryEnumerator *)e {
- if (!e) return nil;
-
- NSMutableArray * result = [NSMutableArray arrayWithCapacity:[e count]];
- for (CouchQueryRow * row in e) {
- [result addObject:[NSDictionary dictionaryWithObjectsAndKeys:row.documentID, @"id", row.key, @"key", row.value, @"value", row.documentProperties, @"doc", nil]];
- }
-
- return [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedInteger:e.totalCount], @"total_rows", [NSNumber numberWithUnsignedInteger:self.query.skip], @"offset", result, @"rows", nil];
-}
-
#pragma mark PROPERTIES
- (id)designDocument {
@@ -139,18 +129,121 @@ - (void)start:(id)args {
RESTOperation * op = [self.query start];
if (cb) {
[op onCompletion:^() {
- [cb call:[NSArray arrayWithObject:[self toQueryResult:op.resultObject]] thisObject:nil];
+ [cb call:[NSArray arrayWithObject:[CouchQueryEnumeratorProxy proxyWith:op.resultObject]] thisObject:nil];
}];
}
}
//sync query
-- (id)fetchRows:(id)args {
- return [self toQueryResult:[self.query rows]];
+- (id)rows:(id)args {
+ return [CouchQueryEnumeratorProxy proxyWith:[self.query rows]];
+}
+
+- (id)rowsIfChanged:(id)args {
+ return [CouchQueryEnumeratorProxy proxyWith:[self.query rowsIfChanged]];
+}
+
+@end
+
+
+@implementation CouchQueryRowProxy
+@synthesize row;
+
+- (id)initWithCouchQueryRow:(CouchQueryRow *)r {
+ if (self = [super init]) {
+ self.row = r;
+ }
+ return self;
+}
+
++ (CouchQueryRowProxy *)proxyWith:(CouchQueryRow *)r {
+ return r ? [[[CouchQueryRowProxy alloc] initWithCouchQueryRow:r] autorelease] : nil;
+}
+
+#pragma mark PROPERTIES
+
+- (id)query {
+ return [CouchQueryProxy proxyWith:self.row.query];
+}
+
+- (id)key {
+ return self.row.key;
+}
+
+- (id)value {
+ return self.row.value;
+}
+
+- (id)documentID {
+ return self.row.documentID;
+}
+
+- (id)sourceDocumentID {
+ return self.row.sourceDocumentID;
+}
+
+- (id)documentRevision {
+ return self.row.documentRevision;
+}
+
+- (id)document {
+ return [CouchDocumentProxy proxyWith:self.row.document];
+}
+
+- (id)documentProperties {
+ return self.row.documentProperties;
+}
+
+#pragma mark METHODS
+
+- (id)keyAtIndex:(id)args {
+ NSNumber * index;
+ ENSURE_ARG_AT_INDEX(index, args, 0, NSNumber)
+ return [self.row keyAtIndex:[index unsignedIntegerValue]];
}
-- (id)fetchRowsIfChanged:(id)args {
- return [self toQueryResult:[self.query rowsIfChanged]];
+@end
+
+
+@implementation CouchQueryEnumeratorProxy
+@synthesize enumerator;
+
+- (id)initWithCouchQueryEnumerator:(CouchQueryEnumerator *)e {
+ if (self = [super init]) {
+ self.enumerator = e;
+ }
+ return self;
+}
+
++ (CouchQueryEnumeratorProxy *)proxyWith:(CouchQueryEnumerator *)e {
+ return e ? [[[CouchQueryEnumeratorProxy alloc] initWithCouchQueryEnumerator:e] autorelease] : nil;
+}
+
+#pragma mark PROPERTIES
+
+- (id)rowCount {
+ return [NSNumber numberWithUnsignedInteger:self.enumerator.count];
+}
+
+- (id)totalCount {
+ return [NSNumber numberWithUnsignedInteger:self.enumerator.totalCount];
+}
+
+- (id)sequenceNumber {
+ return [NSNumber numberWithUnsignedInteger:self.enumerator.sequenceNumber];
+}
+
+#pragma mark METHODS
+
+- (id)nextRow:(id)args {
+ return [CouchQueryRowProxy proxyWith:[self.enumerator nextRow]];
+}
+
+- (id)rowAtIndex:(id)args {
+ NSNumber * index;
+ ENSURE_ARG_AT_INDEX(index, args, 0, NSNumber)
+
+ return [CouchQueryRowProxy proxyWith:[self.enumerator rowAtIndex:[index unsignedIntegerValue]]];
}
@end
@@ -18,6 +18,12 @@ window.addEventListener('open', function(e) {
label.text = 'test03_savemultipledocuments complete';
require('test03_savemultipleunsaveddocuments').run_tests();
label.text = 'test03_savemultipleunsaveddocuments complete';
+ require('test03_deletemultipledocuments').run_tests();
+ label.text = 'test03_deletemultipledocuments complete';
+ require('test04_deletedocument').run_tests();
+ label.text = 'test04_deletedocument complete';
+ require('test05_alldocuments').run_tests();
+ label.text = 'test05_alldocuments complete';
}
catch (e) {
label.text = e;
@@ -27,10 +27,10 @@ exports.run_tests = function() {
var q = db.getAllDocuments();
assert(q, "getAllDocuments() returned nothing");
- var results = q.fetchRows();
- assert(results && results.rows, "getAllDocuments() query has no results");
- assert(results.rows.length == 1, "wrong number of documents: "+results.rows.length);
- assert(results.rows[0].doc._id === doc.documentID, "wrong document ID "+results.rows[0].doc._id);
+ var rows = q.rows();
+ assert(rows, "getAllDocuments() query has no rows");
+ assert(rows.rowCount == 1, "wrong number of documents: "+rows.rowCount);
+ assert(rows.rowAtIndex(0).documentID === doc.documentID, "wrong document ID "+rows.rowAtIndex(0).documentID);
db.deleteDatabase();
}
@@ -0,0 +1,33 @@
+Ti.include('test_utils.js')
+
+var _ = require('underscore'),
+ server = require('com.obscure.TiTouchDB');
+
+exports.run_tests = function() {
+ var db = server.databaseNamed('test03c');
+ db.create();
+
+ try {
+ var docs = [];
+ for (var i=0; i < 5; i++) {
+ var props = {
+ testName: 'deleteMultipleDocuments',
+ sequence: i
+ };
+ var doc = createDocWithProperties(db, props);
+ docs.push(doc);
+ }
+
+ db.deleteDocuments(docs);
+
+ _.each(docs, function(doc) {
+ assert(doc.isDeleted, "document was not deleted");
+ });
+ }
+ catch (e) {
+ db.deleteDatabase();
+ throw e;
+ }
+
+ db.deleteDatabase();
+}
@@ -0,0 +1,25 @@
+Ti.include('test_utils.js')
+
+var _ = require('underscore'),
+ server = require('com.obscure.TiTouchDB');
+
+exports.run_tests = function() {
+ var db = server.databaseNamed('test04');
+ db.create();
+
+ try {
+ var props = {
+ testName: 'testDeleteDocument'
+ };
+ var doc = createDocWithProperties(db, props);
+ assert(!doc.isDeleted, "initial doc should not be deleted");
+ doc.deleteDocument();
+ assert(doc.isDeleted, "doc should be deleted");
+ }
+ catch (e) {
+ db.deleteDatabase();
+ throw e;
+ }
+
+ db.deleteDatabase();
+}
@@ -0,0 +1,40 @@
+Ti.include('test_utils.js')
+
+var _ = require('underscore'),
+ server = require('com.obscure.TiTouchDB');
+
+exports.run_tests = function() {
+ var db = server.databaseNamed('test05');
+ db.create();
+
+ try {
+ var n = 5;
+ createDocuments(db, n);
+
+ db.clearDocumentCache();
+ var query = db.getAllDocuments();
+ assert(!query.designDocument, "getAllDocuments should not have a design doc");
+
+ var rows = query.rows();
+ assert(rows.rowCount === n, "incorrect number of rows");
+ assert(rows.totalCount === n, "incorrect totalCount in query result");
+
+ var c = 0;
+ while (row = rows.nextRow()) {
+ var doc = row.document;
+ assert(doc, "did not get doc from query row");
+ assert(doc.currentRevision.propertiesAreLoaded, "query row should have preloaded doc properties");
+ var props = doc.properties;
+ assert(props, "couldn't get doc properties");
+ assert(props.testName === 'someTest', "didn't get the right number of docs")
+ c++;
+ }
+ assert(c == n, "returned incorrect number of docs: "+c);
+ }
+ catch (e) {
+ db.deleteDatabase();
+ throw e;
+ }
+
+ db.deleteDatabase();
+}
@@ -20,4 +20,16 @@ function createDocWithProperties(db, props) {
assert(doc.documentID, "saved doc should have documentID");
return doc;
+}
+
+function createDocuments(db, n) {
+ var result = [];
+ for (var i=0; i < n; i++) {
+ var doc = createDocWithProperties(db, {
+ testName: 'someTest',
+ sequence: i
+ });
+ result.push(doc);
+ }
+ return result;
}

0 comments on commit 671937f

Please sign in to comment.