Skip to content

Commit

Permalink
Update to the latest API Spec.
Browse files Browse the repository at this point in the history
Database
* getDocument(id) will return null if document is deleted or doesn’t exists.
* contains(id) will return false if document is deleted or doesn’t exist
* No Predicate Query
* No allDocuments()

Document
* Change edit() to toMutable().
* MutableDocument.toMutable() should also copy the MutableDocument.

Dictionary and Array
* Add Dictionary.toMutable() and Array.toMutable().
* Rename Dictionary.setObject(key, value) to Dictionary.setValue(key, value) for all platforms. Currently Objective-C has both setObject() and setValue() as we need to review if it’s appropriate to override setValue() as it is a part of KVO.
* Rename Array.set/add/insertObject(index) to Array.set/add/insertValue(index) for all platforms.
* Dictionary.setValue(key, null) will set null value in all platforms.
* Dictionary.getBoolean(key) and Array.getBoolean(index) will have the following behavior for all platform (I understand that LiteCore implements this behavior):
	if (value == null || value == NSNull)
		return false
	else if (value is number)
		return number != 0
	else
		return true

MutableFragment
* Add type setters

Query
* Change run() to execute()
* Meta
    * Removed Expression.meta(). Use Meta.id and Meta.sequence directly to inline with Function.
    * Removed Expression.notLessThan, notLessThanOrEqualTo, not GreaterThan, notGreaterThanOrEqualTo, notLike, notRegex, notMatch, notBetween, notIn
    * Make sure to not Remove IS and ISNOT
* ArrayExpression
    * Move Array related expressions (Any, Every, AnyAndEvery) into its own class: ArrayExpression + ArrayExpressionIn + ArrayExpressionSatisfies.
* Array Functions
    * Moved array related functions from Function to ArrayFunction.
    * See: couchbaselabs/couchbase-lite-api-spec@7e1174a
* PropertyExpression
    * Extract into its own file instead of having it nested in Expression class.
* Function
    * Not extends Expression. Each function method returns Expression.
* FullText:
    * Have FullTextExpression and FullTextFunction.
    * FullTextExpression has a static index(indexName) method for creating FullTextExpression object with the given index name.
    * Moved Expression.match(object) to FullTextExpression.match(text). Support only match string now.
    * Moved Function.rank(object) to FullTextFunction.rank(indexName)
    * See: couchbaselabs/couchbase-lite-api-spec@7e1174a
* SelectResult
    * Add SelectResult.property(property)
* Query now supports add/remove change listener. When a new listener is added, the listener will get first notified with the current query result.
* Query.setParameters() and getParameters() now have copy behavior. When setting a new Parameters, if there is a change listener added, re-run the query and notify.
* Change Parameters.setObject(name, value) to setValue(name, value).

Index
* Change Index.ValueIndexOn() and Index.FTSIndexOn() to  Index.valueIndex(items) and Index.fullTextIndex(items).
* Index.fullTextIndex(items) allows to set multiple items. Rename FTSIndex to FullTextIndex and FTSIndexItem to FullTextIndexItem.
* Add FullTextIndexItem.property(name) and remove FullTextIndexItem.expression().
* Add ValueIndexItem.property(name).

LiveQuery
* No LiveQuery. Query itself can add/remove change listeners.

ChangeListener
* addChangeListener(listener) returns ListenerToken. ListenerToken is an opaque interface with no methods.
* removeChangeListener(token) takes listener token.
* Rename Database.addChangeListener(documentID, listener) to Database.addDocumentChangeListener(id, listener).
* Add {Database, Query, Replicator}.add{Document}ChangeListener(id}, queue, listener) in all platforms.
    * Java: Executor
    * .NET: TaskFactory
    * iOS: DispatchQueue
* DatabaseChange doesn’t have .external property. We could add this later based on demand in 2.x.

ReplicatorConfiguration
* Flatten Filter
    * Move Filter.channels and Filter.documentIDs to the top level of ReplicatorConfiguration
    * couchbaselabs/couchbase-lite-api-spec@6b2795e

SessionAuthenticator
* Make expires type safe
    * Have two constructors instead of one, one for expires Date and one for expires string.
    * couchbaselabs/couchbase-lite-api-spec@f45d318

Default Conflict Resolver Algorithm
* Delete always wins.
* Longest generation wins or Max RevID wins if the generations are the same.

Document Equality (Pending, not included in this commit)
* Two documents are equals when they are from the same database, they have the same ID, and they have the same content.

#1960
  • Loading branch information
pasin committed Nov 22, 2017
1 parent ac1bc88 commit 36e4b98
Show file tree
Hide file tree
Showing 158 changed files with 4,823 additions and 3,832 deletions.
340 changes: 229 additions & 111 deletions CouchbaseLite.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

123 changes: 69 additions & 54 deletions Objective-C/CBLArray.h
Expand Up @@ -11,6 +11,8 @@
@class CBLBlob;
@class CBLDictionary;
@class CBLArray;
@class CBLMutableArray;


NS_ASSUME_NONNULL_BEGIN

Expand All @@ -21,55 +23,62 @@ NS_ASSUME_NONNULL_BEGIN
@property (readonly) NSUInteger count;

/**
Gets value as a CBLArray, which is a mapping object of an array value.
Returns nil if the value doesn't exists, or its value is not an array.
Gets value at the given index as an object. The object types are CBLBlob,
CBLArray, CBLDictionary, NSNumber, or NSString based on the underlying
data type; or nil if the value is nil.
@param index The index.
@return The CBLArray object or nil.
@return The object or nil.
*/
- (nullable CBLArray*) arrayAtIndex: (NSUInteger)index;
- (nullable id) objectAtIndex: (NSUInteger)index;

/**
Get value at the given index as a CBLBlob.
Returns nil if the value doesn't exist, or its value is not a CBLBlob.
/*
Gets value at the given index. The object types are CBLBlob,
CBLArray, CBLDictionary, NSNumber, or NSString based on the underlying
data type; or nil if the value is nil.
@param index The index.
@return The CBLBlob object or nil.
@return The object or nil.
*/
- (nullable CBLBlob*) blobAtIndex: (NSUInteger)index;
- (nullable id) valueAtIndex: (NSUInteger)index;

/**
Gets value at the given index as a boolean.
Returns YES if the value exists, and is either `true` or a nonzero number.
/**
Gets value at the given index as a string.
Returns nil if the value doesn't exist, or its value is not a string.
@param index The index.
@return The boolean value.
@return The NSString object or nil.
*/
- (BOOL) booleanAtIndex: (NSUInteger)index;
- (nullable NSString*) stringAtIndex: (NSUInteger)index;

/**
Gets value at the given index as an NSDate.
JSON does not directly support dates, so the actual property value must be a string, which is
then parsed according to the ISO-8601 date format (the default used in JSON.)
Returns nil if the value doesn't exist, is not a string, or is not parseable as a date.
NOTE: This is not a generic date parser! It only recognizes the ISO-8601 format, with or
without milliseconds.
Gets value at the given index as a number.
Returns nil if the value doesn't exist, or its value is not a number.
@param index The index.
@return The NSDate object or nil.
@return The NSNumber object or nil.
*/
- (nullable NSDate*) dateAtIndex: (NSUInteger)index;
- (nullable NSNumber*) numberAtIndex: (NSUInteger)index;

/**
Get value at the given index as a CBLDictionary, which is a mapping object of
a dictionary value.
Returns nil if the value doesn't exists, or its value is not a dictionary.
Gets value at the given index as an integer value.
Floating point values will be rounded. The value `true` is returned as 1, `false` as 0.
Returns 0 if the value doesn't exist or does not have a numeric value.
@param index The index.
@return The CBLDictionary object or nil.
@return The integer value.
*/
- (nullable CBLDictionary*) dictionaryAtIndex: (NSUInteger)index;
- (NSInteger) integerAtIndex: (NSUInteger)index;

/**
Gets value at the given index as a long long value.
Floating point values will be rounded. The value `true` is returned as 1, `false` as 0.
Returns 0 if the value doesn't exist or does not have a numeric value.
@param index The index.
@return The long long value.
*/
- (long long) longLongAtIndex: (NSUInteger)index;

/**
Gets value at the given index as a float value.
Expand All @@ -81,7 +90,7 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (float) floatAtIndex: (NSUInteger)index;

/**
/**
Gets value at the given index as a double value.
Integers will be converted to double. The value `true` is returned as 1.0, `false` as 0.0.
Returns 0.0 if the property doesn't exist or does not have a numeric value.
Expand All @@ -91,55 +100,59 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (double) doubleAtIndex: (NSUInteger)index;

/**
Gets value at the given index as an integer value.
Floating point values will be rounded. The value `true` is returned as 1, `false` as 0.
Returns 0 if the value doesn't exist or does not have a numeric value.
/**
Gets value at the given index as a boolean.
Returns YES if the value exists, and is either `true` or a nonzero number.
@param index The index.
@return The integer value.
@return The boolean value.
*/
- (NSInteger) integerAtIndex: (NSUInteger)index;
- (BOOL) booleanAtIndex: (NSUInteger)index;

/**
Gets value at the given index as a long long value.
Floating point values will be rounded. The value `true` is returned as 1, `false` as 0.
Returns 0 if the value doesn't exist or does not have a numeric value.
Gets value at the given index as an NSDate.
JSON does not directly support dates, so the actual property value must be a string, which is
then parsed according to the ISO-8601 date format (the default used in JSON.)
Returns nil if the value doesn't exist, is not a string, or is not parseable as a date.
NOTE: This is not a generic date parser! It only recognizes the ISO-8601 format, with or
without milliseconds.
@param index The index.
@return The long long value.
@return The NSDate object or nil.
*/
- (long long) longLongAtIndex: (NSUInteger)index;
- (nullable NSDate*) dateAtIndex: (NSUInteger)index;

/**
Gets value at the given index as a number.
Returns nil if the value doesn't exist, or its value is not a number.
/**
Get value at the given index as a CBLBlob.
Returns nil if the value doesn't exist, or its value is not a CBLBlob.
@param index The index.
@return The NSNumber object or nil.
@return The CBLBlob object or nil.
*/
- (nullable NSNumber*) numberAtIndex: (NSUInteger)index;
- (nullable CBLBlob*) blobAtIndex: (NSUInteger)index;

/**
Gets value at the given index as an object. The object types are CBLBlob,
CBLArray, CBLDictionary, NSNumber, or NSString based on the underlying
data type; or nil if the value is nil.
Gets value as a CBLArray, which is a mapping object of an array value.
Returns nil if the value doesn't exists, or its value is not an array.
@param index The index.
@return The object or nil.
@return The CBLArray object or nil.
*/
- (nullable id) objectAtIndex: (NSUInteger)index;
- (nullable CBLArray*) arrayAtIndex: (NSUInteger)index;

/**
Gets value at the given index as a string.
Returns nil if the value doesn't exist, or its value is not a string.
Get value at the given index as a CBLDictionary, which is a mapping object of
a dictionary value.
Returns nil if the value doesn't exists, or its value is not a dictionary.
@param index The index.
@return The NSString object or nil.
@return The CBLDictionary object or nil.
*/
- (nullable NSString*) stringAtIndex: (NSUInteger)index;
- (nullable CBLDictionary*) dictionaryAtIndex: (NSUInteger)index;

/**
#pragma mark - Data

/**
Gets content of the current object as an NSArray. The values contained in the returned
NSArray object are all JSON based values.
Expand All @@ -154,6 +167,8 @@ NS_ASSUME_NONNULL_BEGIN

- (instancetype) init NS_UNAVAILABLE;

- (CBLMutableArray*) toMutable;

@end

NS_ASSUME_NONNULL_END
61 changes: 38 additions & 23 deletions Objective-C/CBLArray.mm
Expand Up @@ -101,34 +101,33 @@ static id _getObject(MArray<id> &array, NSUInteger index, Class asClass =nil) {
return obj;
}


- (nullable CBLArray*) arrayAtIndex: (NSUInteger)index {
return _getObject(_array, index, [CBLArray class]);
- (nullable id) objectAtIndex: (NSUInteger)index {
return _getObject(_array, index);
}


- (nullable CBLBlob*) blobAtIndex: (NSUInteger)index {
return _getObject(_array, index, [CBLBlob class]);
- (nullable id) valueAtIndex: (NSUInteger)index {
return _getObject(_array, index);
}


- (BOOL) booleanAtIndex: (NSUInteger)index {
return asBool(_get(_array, index), _array);
- (nullable NSString*) stringAtIndex: (NSUInteger)index {
return _getObject(_array, index, [NSString class]);
}


- (nullable NSDate*) dateAtIndex: (NSUInteger)index {
return asDate(_getObject(_array, index));
- (nullable NSNumber*) numberAtIndex: (NSUInteger)index {
return _getObject(_array, index, [NSNumber class]);
}


- (nullable CBLDictionary*) dictionaryAtIndex: (NSUInteger)index {
return _getObject(_array, index, [CBLDictionary class]);
- (NSInteger) integerAtIndex: (NSUInteger)index {
return asInteger(_get(_array, index), _array);
}


- (double) doubleAtIndex: (NSUInteger)index {
return asDouble(_get(_array, index), _array);
- (long long) longLongAtIndex: (NSUInteger)index {
return asLongLong(_get(_array, index), _array);
}


Expand All @@ -137,28 +136,33 @@ - (float) floatAtIndex: (NSUInteger)index {
}


- (NSInteger) integerAtIndex: (NSUInteger)index {
return asInteger(_get(_array, index), _array);
- (double) doubleAtIndex: (NSUInteger)index {
return asDouble(_get(_array, index), _array);
}


- (long long) longLongAtIndex: (NSUInteger)index {
return asLongLong(_get(_array, index), _array);
- (BOOL) booleanAtIndex: (NSUInteger)index {
return asBool(_get(_array, index), _array);
}


- (nullable NSNumber*) numberAtIndex: (NSUInteger)index {
return _getObject(_array, index, [NSNumber class]);
- (nullable NSDate*) dateAtIndex: (NSUInteger)index {
return asDate(_getObject(_array, index));
}


- (nullable NSString*) stringAtIndex: (NSUInteger)index {
return _getObject(_array, index, [NSString class]);
- (nullable CBLBlob*) blobAtIndex: (NSUInteger)index {
return _getObject(_array, index, [CBLBlob class]);
}


- (nullable id) objectAtIndex: (NSUInteger)index {
return _getObject(_array, index);
- (nullable CBLArray*) arrayAtIndex: (NSUInteger)index {
return _getObject(_array, index, [CBLArray class]);
}


- (nullable CBLDictionary*) dictionaryAtIndex: (NSUInteger)index {
return _getObject(_array, index, [CBLDictionary class]);
}


Expand All @@ -167,6 +171,9 @@ - (NSUInteger) count {
}


#pragma mark - Data


- (NSArray*) toArray {
auto count = _array.count();
NSMutableArray* result = [NSMutableArray arrayWithCapacity: count];
Expand All @@ -176,6 +183,14 @@ - (NSArray*) toArray {
}


#pragma mark - Mutable


- (CBLMutableArray*) toMutable {
return [self mutableCopy];
}


- (id) cbl_toPlainObject {
return [self toArray];
}
Expand Down
18 changes: 11 additions & 7 deletions Objective-C/CBLConflictResolver.m
Expand Up @@ -15,9 +15,18 @@
@implementation CBLDefaultConflictResolver

- (nullable CBLDocument*) resolve: (CBLConflict*)conflict {
// Default resolution algorithm is "most active wins", i.e. higher generation number.
// Default resolution algorithm:
// 1. DELETE always wins.
// 2. Most active wins (Higher generation number).
// 3. Higher RevID wins.
CBLDocument *mine = conflict.mine, *theirs = conflict.theirs;
if (mine.generation >= theirs.generation) // hope I die before I get old
if (theirs.isDeleted)
return theirs;
else if (mine.isDeleted)
return mine;
else if (mine.generation >= theirs.generation) // hope I die before I get old
return mine;
else if ([mine.revID compare: theirs.revID] > 0)
return mine;
else
return theirs;
Expand All @@ -26,14 +35,10 @@ - (nullable CBLDocument*) resolve: (CBLConflict*)conflict {
@end




@implementation CBLConflict


@synthesize mine=_mine, theirs=_theirs, base=_base;


- (instancetype) initWithMine: (CBLDocument*)mine
theirs: (CBLDocument*)theirs
base: (CBLDocument*)base
Expand All @@ -47,5 +52,4 @@ - (instancetype) initWithMine: (CBLDocument*)mine
return self;
}


@end

0 comments on commit 36e4b98

Please sign in to comment.