Skip to content

Commit fbf6bad

Browse files
Merge pull request #33 from matteobortolazzo/BulkGet
Bulk Get API
2 parents d793e7e + 2ae8ad2 commit fbf6bad

File tree

5 files changed

+79
-4
lines changed

5 files changed

+79
-4
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ await rebels.CreateOrUpdateAsync(rebel);
205205
await rebels.DeleteAsync(rebel);
206206
var rebel = await rebels.FindAsync(id);
207207
var rebel = await rebels.FindAsync(id, withConflicts: true);
208+
var rebels = await rebels.FindManyAsync(ids);
208209
// Bulk
209210
await rebels.CreateOrUpdateRangeAsync(moreRebels);
210211
// Utils

src/CouchDB.Driver/CouchDatabase.cs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,25 @@ public async Task<TSource> FindAsync(string docId, bool withConflicts = false)
236236
}
237237
}
238238

239+
/// <summary>
240+
/// Finds all documents with given IDs.
241+
/// </summary>
242+
/// <param name="docIds">The collection of documents IDs.</param>
243+
/// <returns></returns>
244+
public async Task<List<TSource>> FindManyAsync(IEnumerable<string> docIds)
245+
{
246+
var bulkGetResult = await NewRequest()
247+
.AppendPathSegment("_bulk_get")
248+
.PostJsonAsync(new
249+
{
250+
docs = docIds.Select(id => new { id })
251+
}).ReceiveJson<BulkGetResult<TSource>>()
252+
.SendRequestAsync()
253+
.ConfigureAwait(false);
254+
255+
return bulkGetResult.Results.SelectMany(r => r.Docs).Select(d => d.Item).ToList();
256+
}
257+
239258
#endregion
240259

241260
#region Writing
@@ -345,7 +364,7 @@ public async Task<IEnumerable<TSource>> CreateOrUpdateRangeAsync(IEnumerable<TSo
345364
.SendRequestAsync()
346365
.ConfigureAwait(false);
347366

348-
IEnumerable<(TSource Document, DocumentSaveResponse SaveResponse)> zipped =
367+
IEnumerable<(TSource Document, DocumentSaveResponse SaveResponse)> zipped =
349368
documents.Zip(response, (doc, saveResponse) => (Document: doc, SaveResponse: saveResponse));
350369

351370
foreach ((TSource document, DocumentSaveResponse saveResponse) in zipped)
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using CouchDB.Driver.Types;
2+
using Newtonsoft.Json;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
using System.Text;
7+
using System.Threading.Tasks;
8+
9+
namespace CouchDB.Driver.DTOs
10+
{
11+
#pragma warning disable CA1812 // Avoid uninstantiated internal classes
12+
internal class BulkGetResult<TSource> where TSource : CouchDocument
13+
{
14+
[JsonProperty("results")]
15+
public List<BulkGetResultDoc<TSource>> Results { get; set; }
16+
}
17+
18+
internal class BulkGetResultDoc<TSource> where TSource : CouchDocument
19+
{
20+
[JsonProperty("docs")]
21+
public List<BulkGetResultItem<TSource>> Docs { get; set; }
22+
}
23+
24+
internal class BulkGetResultItem<TSource> where TSource : CouchDocument
25+
{
26+
[JsonProperty("ok")]
27+
public TSource Item { get; set; }
28+
}
29+
#pragma warning restore CA1812 // Avoid uninstantiated internal classes
30+
}

src/CouchDB.Driver/Helpers/MicrosecondEpochConverter.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,17 @@ namespace CouchDB.Driver.Helpers
88
internal class MicrosecondEpochConverter : DateTimeConverterBase
99
#pragma warning restore CA1812 // Avoid uninstantiated internal classes
1010
{
11-
private static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
11+
private static readonly DateTime _epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
1212

1313
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
1414
{
15-
writer.WriteRawValue(((DateTime)value - Epoch).TotalMilliseconds + "000");
15+
writer.WriteRawValue(((DateTime)value - _epoch).TotalMilliseconds + "000");
1616
}
1717

1818
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
1919
{
2020
if (reader.Value == null) { return null; }
21-
return Epoch.AddMilliseconds((long)reader.Value / 1000d);
21+
return _epoch.AddMilliseconds((long)reader.Value / 1000d);
2222
}
2323
}
2424
}

tests/CouchDB.Driver.UnitTests/Database_Tests.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,31 @@ public async Task FindWithConflicts()
4949
}
5050
}
5151
[Fact]
52+
public async Task FindMany()
53+
{
54+
using (var httpTest = new HttpTest())
55+
{
56+
httpTest.RespondWith(@"{""results"":[{""id"":""1"",""docs"":[{""ok"":{""_id"":""1"",""Name"":""Luke""}}]},{""id"":""2"",""docs"":[{""ok"":{""_id"":""2"",""Name"":""Leia""}}]}]}");
57+
var ids = new string[] { "1", "2" };
58+
var result = await _rebels.FindManyAsync(ids);
59+
httpTest
60+
.ShouldHaveCalled("http://localhost/rebels/_bulk_get")
61+
.WithRequestJson(new
62+
{
63+
docs = new[]
64+
{
65+
new { id = "1" },
66+
new { id = "2" },
67+
}
68+
})
69+
.WithVerb(HttpMethod.Post);
70+
71+
Assert.Equal(2, result.Count);
72+
Assert.Equal("Luke", result[0].Name);
73+
Assert.Equal("Leia", result[1].Name);
74+
}
75+
}
76+
[Fact]
5277
public async Task Create()
5378
{
5479
using (var httpTest = new HttpTest())

0 commit comments

Comments
 (0)