diff --git a/README.md b/README.md index 7fe5d9e..378d2e6 100644 --- a/README.md +++ b/README.md @@ -205,7 +205,9 @@ await rebels.CreateOrUpdateAsync(rebel); await rebels.DeleteAsync(rebel); var rebel = await rebels.FindAsync(id); var rebel = await rebels.FindAsync(id, withConflicts: true); -var rebels = await rebels.FindManyAsync(ids); +var list = await rebels.FindManyAsync(ids); +var list = await rebels.QueryAsync(someMangoJson); +var list = await rebels.QueryAsync(someMangoObject); // Bulk await rebels.CreateOrUpdateRangeAsync(moreRebels); // Utils diff --git a/src/CouchDB.Driver/CouchDatabase.cs b/src/CouchDB.Driver/CouchDatabase.cs index 056928f..fd1908f 100644 --- a/src/CouchDB.Driver/CouchDatabase.cs +++ b/src/CouchDB.Driver/CouchDatabase.cs @@ -10,6 +10,7 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; +using System.Net.Http; using System.Threading.Tasks; namespace CouchDB.Driver @@ -237,6 +238,43 @@ public async Task FindAsync(string docId, bool withConflicts = false) } /// + /// Finds all documents matching the MangoQuery. + /// + /// The JSON representing the Mango query. + /// A task that represents the asynchronous operation. The task result contains a List that contains elements from the database. + public Task> QueryAsync(string mangoQueryJson) + { + return SendQueryAsync(r => r + .WithHeader("Content-Type", "application/json") + .PostStringAsync(mangoQueryJson)); + } + + /// + /// Finds all documents matching the MangoQuery. + /// + /// The object representing the Mango query. + /// A task that represents the asynchronous operation. The task result contains a List that contains elements from the database. + public Task> QueryAsync(object mangoQuery) + { + return SendQueryAsync(r => r + .PostJsonAsync(mangoQuery)); + } + + private async Task> SendQueryAsync(Func> requestFunc) + { + var request = NewRequest() + .AppendPathSegment("_find"); + + var message = requestFunc(request); + + var findResult = await message + .ReceiveJson>() + .SendRequestAsync() + .ConfigureAwait(false); + + return findResult.Docs.ToList(); + } + /// Finds all documents with given IDs. /// /// The collection of documents IDs. diff --git a/tests/CouchDB.Driver.UnitTests/Database_Tests.cs b/tests/CouchDB.Driver.UnitTests/Database_Tests.cs index 9dbcc5e..b75ae03 100644 --- a/tests/CouchDB.Driver.UnitTests/Database_Tests.cs +++ b/tests/CouchDB.Driver.UnitTests/Database_Tests.cs @@ -153,6 +153,43 @@ public async Task CouchList() } } + [Fact] + public async Task QueryJson() + { + using (var httpTest = new HttpTest()) + { + var expected = new List() { new Rebel { Id = Guid.NewGuid().ToString() } }; + httpTest.RespondWithJson(new { Docs = expected }); + + var query = @"{""selector"":{""age"":19}}"; + var result = await _rebels.QueryAsync(query); + httpTest + .ShouldHaveCalled("http://localhost/rebels/_find") + .WithVerb(HttpMethod.Post) + .WithRequestBody(@"{""selector"":{""age"":19}}"); + Assert.Equal(expected.Count, result.Count); + Assert.Equal(expected[0].Id, result[0].Id); + } + } + [Fact] + public async Task QueryObject() + { + using (var httpTest = new HttpTest()) + { + var expected = new List() { new Rebel { Id = Guid.NewGuid().ToString() } }; + httpTest.RespondWithJson(new { Docs = expected }); + + var query = new { selector = new { age = 19 } }; + var result = await _rebels.QueryAsync(query); + httpTest + .ShouldHaveCalled("http://localhost/rebels/_find") + .WithVerb(HttpMethod.Post) + .WithRequestBody(@"{""selector"":{""age"":19}}"); + Assert.Equal(expected.Count, result.Count); + Assert.Equal(expected[0].Id, result[0].Id); + } + } + #endregion #region Bulk