Skip to content

Support for direct queries without using the LINQ api #32

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Apr 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
38 changes: 38 additions & 0 deletions src/CouchDB.Driver/CouchDatabase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -237,6 +238,43 @@ public async Task<TSource> FindAsync(string docId, bool withConflicts = false)
}

/// <summary>
/// Finds all documents matching the MangoQuery.
/// </summary>
/// <param name="mangoQueryJson">The JSON representing the Mango query.</param>
/// <retuns>A task that represents the asynchronous operation. The task result contains a List<T> that contains elements from the database.</retuns>
public Task<List<TSource>> QueryAsync(string mangoQueryJson)
{
return SendQueryAsync(r => r
.WithHeader("Content-Type", "application/json")
.PostStringAsync(mangoQueryJson));
}

/// <summary>
/// Finds all documents matching the MangoQuery.
/// </summary>
/// <param name="mangoQuery">The object representing the Mango query.</param>
/// <retuns>A task that represents the asynchronous operation. The task result contains a List<T> that contains elements from the database.</retuns>
public Task<List<TSource>> QueryAsync(object mangoQuery)
{
return SendQueryAsync(r => r
.PostJsonAsync(mangoQuery));
}

private async Task<List<TSource>> SendQueryAsync(Func<IFlurlRequest, Task<HttpResponseMessage>> requestFunc)
{
var request = NewRequest()
.AppendPathSegment("_find");

var message = requestFunc(request);

var findResult = await message
.ReceiveJson<FindResult<TSource>>()
.SendRequestAsync()
.ConfigureAwait(false);

return findResult.Docs.ToList();
}

/// Finds all documents with given IDs.
/// </summary>
/// <param name="docIds">The collection of documents IDs.</param>
Expand Down
37 changes: 37 additions & 0 deletions tests/CouchDB.Driver.UnitTests/Database_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,43 @@ public async Task CouchList()
}
}

[Fact]
public async Task QueryJson()
{
using (var httpTest = new HttpTest())
{
var expected = new List<Rebel>() { 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<Rebel>() { 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
Expand Down