Skip to content

Commit

Permalink
Closes #398
Browse files Browse the repository at this point in the history
  • Loading branch information
borrrden committed Jun 10, 2015
1 parent 2319317 commit 874b4de
Show file tree
Hide file tree
Showing 10 changed files with 84 additions and 20 deletions.
17 changes: 8 additions & 9 deletions src/Couchbase.Lite.Shared/Database.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1469,7 +1469,7 @@ internal string FindCommonAncestor(RevisionInternal rev, IList<string> revIds)
return null;
}

internal RevisionList ChangesSince(long lastSeq, ChangesOptions options, FilterDelegate filter)
internal RevisionList ChangesSince(long lastSeq, ChangesOptions options, FilterDelegate filter, IDictionary<string, object> filterParams)
{
// http://wiki.apache.org/couchdb/HTTP_database_API#Changes
if (options == null)
Expand Down Expand Up @@ -1523,9 +1523,8 @@ internal RevisionList ChangesSince(long lastSeq, ChangesOptions options, FilterD
{
ExpandStoredJSONIntoRevisionWithAttachments(cursor.GetBlob(5), rev, options.GetContentOptions());
}
IDictionary<string, object> paramsFixMe = null;
// TODO: these should not be null
if (RunFilter(filter, paramsFixMe, rev))

if (RunFilter(filter, filterParams, rev))
{
changes.AddItem(rev);
}
Expand All @@ -1551,14 +1550,14 @@ internal RevisionList ChangesSince(long lastSeq, ChangesOptions options, FilterD
return changes;
}

internal bool RunFilter(FilterDelegate filter, IDictionary<string, object> paramsIgnored, RevisionInternal rev)
internal bool RunFilter(FilterDelegate filter, IDictionary<string, object> filterParams, RevisionInternal rev)
{
if (filter == null)
{
if (filter == null) {
return true;
}

var publicRev = new SavedRevision(this, rev);
return filter(publicRev, null);
return filter(publicRev, filterParams);
}

/// <exception cref="Couchbase.Lite.CouchbaseLiteException"></exception>
Expand Down Expand Up @@ -4847,7 +4846,7 @@ public void Dispose()
/// <summary>
/// A delegate that can be used to include/exclude <see cref="Couchbase.Lite.Revision"/>s during push <see cref="Couchbase.Lite.Replication"/>.
/// </summary>
public delegate Boolean FilterDelegate(SavedRevision revision, Dictionary<String, Object> filterParams);
public delegate Boolean FilterDelegate(SavedRevision revision, IDictionary<String, Object> filterParams);

/// <summary>
/// A delegate that can be run in a transaction on a <see cref="Couchbase.Lite.Database"/>.
Expand Down
6 changes: 3 additions & 3 deletions src/Couchbase.Lite.Shared/Replication/Pusher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ internal override void BeginReplicating()

var options = new ChangesOptions();
options.SetIncludeConflicts(true);
var changes = LocalDatabase.ChangesSince(lastSequenceLong, options, filter);
var changes = LocalDatabase.ChangesSince(lastSequenceLong, options, filter, FilterParams);
if (changes.Count > 0)
{
Batcher.QueueObjects(changes);
Expand Down Expand Up @@ -241,10 +241,10 @@ internal void OnChanged(Object sender, DatabaseChangeEventArgs args)
}

var rev = change.AddedRevision;
IDictionary<String, Object> paramsFixMe = null;
IDictionary<String, Object> paramsFixMe = FilterParams;

// TODO: these should not be null
if (LocalDatabase.RunFilter(filter, paramsFixMe, rev))
if (LocalDatabase.RunFilter(filter, FilterParams, rev))
{
AddToInbox(rev);
}
Expand Down
8 changes: 4 additions & 4 deletions src/Couchbase.Lite.Tests.Shared/CRUDOperationsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -137,17 +137,17 @@ public void TestCRUDOperations()
Assert.IsTrue(gotExpectedError);

// Check the changes feed, with and without filters:
var changeRevisions = database.ChangesSince(0, null, null);
var changeRevisions = database.ChangesSince(0, null, null, null);

Log.V(Tag, "Changes = " + changeRevisions);
Assert.AreEqual(1, changeRevisions.Count);

changeRevisions = database.ChangesSince(0, null,
(revision, items) => "updated!".Equals (revision.Properties.Get("status")));
(revision, items) => "updated!".Equals (revision.Properties.Get("status")), null);
Assert.AreEqual(1, changeRevisions.Count);

changeRevisions = database.ChangesSince(0, null,
(revision, items) => "not updated!".Equals (revision.Properties.Get("status")));
(revision, items) => "not updated!".Equals (revision.Properties.Get("status")), null);
Assert.AreEqual(0, changeRevisions.Count);

// Delete it:
Expand Down Expand Up @@ -189,7 +189,7 @@ public void TestCRUDOperations()
Assert.IsNull(readRev);

// Get Changes feed:
changeRevisions = database.ChangesSince(0, null, null);
changeRevisions = database.ChangesSince(0, null, null, null);
Assert.IsTrue(changeRevisions.Count == 1);

// Get Revision History:
Expand Down
35 changes: 35 additions & 0 deletions src/Couchbase.Lite.Tests.Shared/ReplicationTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2274,6 +2274,41 @@ public void TestReplicationCheckpointUniqueness()

Assert.AreNotEqual(repl1.RemoteCheckpointDocID(), repl2.RemoteCheckpointDocID());
}

[Test]
[Category("issue_398")]
public void TestPusherUsesFilterParams()
{
var docIdTimestamp = Convert.ToString(Runtime.CurrentTimeMillis());
var doc1Id = string.Format("doc1-{0}", docIdTimestamp);
var doc2Id = string.Format("doc2-{0}", docIdTimestamp);

var doc1 = database.GetDocument(doc1Id);
doc1.PutProperties(new Dictionary<string, object> { { "foo", "bar" } });

var doc2 = database.GetDocument(doc2Id);
doc2.PutProperties(new Dictionary<string, object> { { "bar", "foo" } });

var mre = new ManualResetEventSlim();
IDictionary<string, object> gotParams = null;
database.SetFilter("issue-398", (rev, parameters) =>
{
gotParams = parameters;
if(!mre.IsSet) {
mre.Set();
}

return true;
});

var push = database.CreatePushReplication(GetReplicationURL());
push.Filter = "issue-398";
push.FilterParams = new Dictionary<string, object>() { { "issue-398", "finished" } };
push.Start();

mre.Wait();
Assert.AreEqual(push.FilterParams, gotParams);
}

}
}
4 changes: 2 additions & 2 deletions src/Couchbase.Lite.Tests.Shared/RevTreeTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,13 +132,13 @@ public void TestRevTree()

// Get the _changes feed and verify only the winner is in it:
var options = new ChangesOptions();
var changes = database.ChangesSince(0, options, null);
var changes = database.ChangesSince(0, options, null, null);
var expectedChanges = new RevisionList();
expectedChanges.AddItem(conflict);
expectedChanges.AddItem(other);
Assert.AreEqual(changes, expectedChanges);
options.SetIncludeConflicts(true);
changes = database.ChangesSince(0, options, null);
changes = database.ChangesSince(0, options, null, null);
expectedChanges = new RevisionList();
expectedChanges.AddItem(rev);
expectedChanges.AddItem(conflict);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,8 @@ public string IfMatch()

public abstract string GetQueryParam(string key);

public abstract IDictionary<string, object> GetQueryParams();

public abstract bool CacheWithEtag(string etag);

#endregion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
// limitations under the License.
//

using System.Collections.Generic;
using System.Text;
using System.Threading;

Expand Down Expand Up @@ -72,6 +73,12 @@ internal class DBMonitorCouchbaseResponseState : ICouchbaseResponseState
/// </summary>
public FilterDelegate ChangesFilter { get; set; }

/// <summary>
/// The parameters used in the change filter
/// </summary>
/// <value>The filter parameters.</value>
public IDictionary<string, object> FilterParams { get; set; }

//ICouchbaseResponseState
public CouchbaseLiteResponse Response { get; set; }

Expand Down Expand Up @@ -174,7 +181,7 @@ private void DatabaseChanged(object sender, DatabaseChangeEventArgs args)
}
}

if (!_db.RunFilter(ChangesFilter, null, rev)) {
if (!_db.RunFilter(ChangesFilter, FilterParams, rev)) {
continue;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -327,10 +327,12 @@ public static ICouchbaseResponseState GetChanges(ICouchbaseListenerContext conte
if(responseState.ChangesFilter == null) {
return context.CreateResponse(status.Code);
}

responseState.FilterParams = context.GetQueryParams();
}


RevisionList changes = db.ChangesSince(since, options, responseState.ChangesFilter);
RevisionList changes = db.ChangesSince(since, options, responseState.ChangesFilter, responseState.FilterParams);
if((context.ChangesFeedMode >= ChangesFeedMode.Continuous) ||
(context.ChangesFeedMode == ChangesFeedMode.LongPoll && changes.Count == 0)) {
// Response is going to stay open (continuous, or hanging GET):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
using System.IO;

using Couchbase.Lite.Replicator;
using System.Collections.Generic;

namespace Couchbase.Lite.Listener
{
Expand Down Expand Up @@ -139,6 +140,12 @@ public interface ICouchbaseListenerContext
/// <param name="key">The name of the query item to get</param>
string GetQueryParam(string key);

/// <summary>
/// Returns all of the query parameters
/// </summary>
/// <returns>The query parameters of the URL.</returns>
IDictionary<string, object> GetQueryParams();

/// <summary>
/// Inserts the given string into the Etag header of the response, and checks to see if
/// the request has the etag in the If-None-Match header
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@
// limitations under the License.
//
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Net;

namespace Couchbase.Lite.Listener.Tcp
Expand Down Expand Up @@ -92,6 +94,16 @@ public override string GetQueryParam(string key)
return _httpContext.Request.QueryString[key];
}

public override IDictionary<string, object> GetQueryParams()
{
var retVal = new Dictionary<string, object>(_httpContext.Request.QueryString.Count);
foreach (string key in _httpContext.Request.QueryString.AllKeys) {
retVal[key] = _httpContext.Request.QueryString[key];
}

return retVal;
}

public override bool CacheWithEtag(string etag)
{
etag = String.Format("\"{0}\"", etag);
Expand Down

0 comments on commit 874b4de

Please sign in to comment.