Permalink
Browse files

NCBC-159: Add debug option to view queries

Change-Id: I3c56431a69861ca9de5b3b660483405becaea290
Reviewed-on: http://review.couchbase.org/22740
Tested-by: John C. Zablocki <john@couchbase.com>
Reviewed-by: John C. Zablocki <john@couchbase.com>
  • Loading branch information...
johnzablocki authored and John C. Zablocki committed Nov 21, 2012
1 parent 9ea473d commit e3de5459bfc0b5efd1eb906a99e903990a3fc2ce
@@ -53,6 +53,7 @@
<Compile Include="ConfigHelperTests.cs" />
<Compile Include="CouchbaseClientExtensionsTests.cs" />
<Compile Include="CouchbaseClientSpatialViewTests.cs" />
+ <Compile Include="CouchbaseClientViewTests.cs" />
<Compile Include="HelperTests\DocHelperTests.cs" />
<Compile Include="HttpClientConfigTests.cs" />
<Compile Include="CouchbaseAuthenticatedViewTests.cs" />
@@ -129,4 +130,4 @@
<Target Name="AfterBuild">
</Target>
-->
-</Project>
+</Project>
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+
+namespace Couchbase.Tests
+{
+ [TestFixture]
+ public class CouchbaseClientViewTests : CouchbaseClientViewTestsBase
+ {
+ [Test]
+ public void When_Querying_View_With_Debug_True_Debug_Info_Dictionary_Is_Returned()
+ {
+ var view = _Client.GetView("cities", "by_name").Limit(1).Debug(true);
+ foreach (var item in view) { }
+
+ Assert.That(view.DebugInfo, Is.InstanceOf(typeof(Dictionary<string, object>)));
+ }
+
+ [Test]
+ public void When_Querying_View_With_Debug_False_Debug_Info_Dictionary_Is_Returned()
+ {
+ var view = _Client.GetView("cities", "by_name").Limit(1).Debug(true);
+ foreach (var item in view) { }
+
+ Assert.That(view.DebugInfo, Is.Null);
+ }
+ }
+}
@@ -35,10 +35,16 @@ internal abstract class CouchbaseViewBase<T> : IView<T> {
protected bool? group;
protected int? groupAt;
+ protected bool? debug;
+
public int TotalRows {
get { return ViewHandler.TotalRows; }
}
+ public IDictionary<string, object> DebugInfo {
+ get { return ViewHandler.DebugInfo; }
+ }
+
internal CouchbaseViewBase(ICouchbaseClient client, IHttpClientLocator clientLocator, string designDocument, string indexName) {
this.ViewHandler = new CouchbaseViewHandler(client, clientLocator, designDocument, indexName);
}
@@ -61,6 +67,8 @@ internal abstract class CouchbaseViewBase<T> : IView<T> {
this.reduce = original.reduce;
this.groupAt = original.groupAt;
+
+ this.debug = original.debug;
}
protected IEnumerator<T> TransformResults<T>(Func<JsonReader, T> rowTransformer) {
@@ -87,6 +95,8 @@ internal abstract class CouchbaseViewBase<T> : IView<T> {
viewParamsBuilder.AddStaleParam(this.stale);
viewParamsBuilder.AddOnErrorParam(this.onError);
+ viewParamsBuilder.AddOptionalParam("debug", this.debug);
+
return this.ViewHandler.TransformResults<T>(rowTransformer, viewParamsBuilder.Build());
}
@@ -168,6 +178,12 @@ internal abstract class CouchbaseViewBase<T> : IView<T> {
return this;
}
+ public IView<T> Debug(bool debug)
+ {
+ this.debug = debug;
+ return this;
+ }
+
public IPagedView<T> GetPagedView(int pageSize, string pagedViewIdProperty = null, string pagedViewKeyProperty = null) {
return new PagedView<T>(this, pageSize, pagedViewIdProperty, pagedViewKeyProperty);
}
@@ -5,6 +5,8 @@
using Newtonsoft.Json;
using System.Diagnostics;
using System.IO;
+using Newtonsoft.Json.Linq;
+using Couchbase.Helpers;
namespace Couchbase
{
@@ -29,26 +31,7 @@ internal CouchbaseViewHandler(ICouchbaseClient client, IHttpClientLocator client
public int TotalRows { get; set; }
- public bool MoveToArray(JsonReader reader, int depth, string name)
- {
- while (reader.Read())
- {
- if (reader.TokenType == Newtonsoft.Json.JsonToken.PropertyName
- && reader.Depth == depth
- && ((string)reader.Value) == name)
- {
- if (!reader.Read()
- || (reader.TokenType != Newtonsoft.Json.JsonToken.StartArray
- && reader.TokenType != Newtonsoft.Json.JsonToken.Null))
- throw new InvalidOperationException("Expecting array named '" + name + "'!");
-
- // we skip the deserialization if the array is null
- return reader.TokenType == Newtonsoft.Json.JsonToken.StartArray;
- }
- }
-
- return false;
- }
+ public IDictionary<string, object> DebugInfo { get; set; }
public IEnumerator<T> TransformResults<T>(Func<JsonReader, T> rowTransformer, IDictionary<string, string> viewParams)
{
@@ -78,13 +61,29 @@ public IEnumerator<T> TransformResults<T>(Func<JsonReader, T> rowTransformer, ID
yield return row;
}
- if (MoveToArray(jsonReader, 1, "errors"))
+ while (jsonReader.Read())
{
- var errors = Json.Parse(jsonReader);
- var formatted = String.Join("\n", FormatErrors(errors as object[]).ToArray());
- if (String.IsNullOrEmpty(formatted)) formatted = "<unknown>";
-
- throw new InvalidOperationException("Cannot read view: " + formatted);
+ if (jsonReader.TokenType == JsonToken.PropertyName
+ && jsonReader.Depth == 1
+ && ((string)jsonReader.Value) == "errors")
+ {
+ // we skip the deserialization if the array is null
+ if (jsonReader.TokenType == Newtonsoft.Json.JsonToken.StartArray)
+ {
+ var errors = Json.Parse(jsonReader);
+ var formatted = String.Join("\n", FormatErrors(errors as object[]).ToArray());
+ if (String.IsNullOrEmpty(formatted)) formatted = "<unknown>";
+
+ throw new InvalidOperationException("Cannot read view: " + formatted);
+ }
+ }
+ else if (jsonReader.TokenType == JsonToken.PropertyName
+ && jsonReader.Depth == 1
+ && ((string)jsonReader.Value) == "debug_info")
+ {
+ var debugInfoJson = (JObject.ReadFrom(jsonReader) as JProperty).Value;
+ DebugInfo = JsonHelper.Deserialize<Dictionary<string, object>>(debugInfoJson.ToString());
+ }
}
}
}
@@ -13,6 +13,11 @@ public interface IView<T> : IEnumerable<T>
/// </summary>
int TotalRows { get; }
+ /// <summary>
+ /// Debug info when Debug param is true
+ /// </summary>
+ IDictionary<string, object> DebugInfo { get; }
+
/// <summary>
/// The view will return only the specified number of items.
/// </summary>
@@ -126,6 +131,13 @@ public interface IView<T> : IEnumerable<T>
/// <param name="pagedViewKeyProperty">When paging over a generic view, this is the property to which the row's key is mapped</param>
/// <returns></returns>
IPagedView<T> GetPagedView(int pageSize, string pagedViewIdProperty = null, string pagedViewKeyProperty = null);
+
+ /// <summary>
+ /// Specifies whether Couchbase should return debug info
+ /// </summary>
+ /// <param name="debug">A value that specifies whether to include debug info.</param>
+ /// <returns>A new <see cref="T:Couchbase.IView"/> that can be used to retrieve the items, including debug info.</returns>
+ IView<T> Debug(bool debug);
}
}

0 comments on commit e3de545

Please sign in to comment.