using System.Collections.Generic;
using System.IO;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using RethinkDb.Driver.Ast;
using RethinkDb.Driver.Model;
using RethinkDb.Driver.Proto;
namespace RethinkDb.Driver.Net
{
///
/// Response from the server.
///
public class Response
{
private const string TypeKey = "t";
private const string NotesKey = "n";
private const string ErrorKey = "e";
private const string ProfileKey = "p";
private const string BacktraceKey = "b";
private const string DataKey = "r";
///
/// The token ID associated with the query.
///
public long Token { get; }
///
/// The response type .
///
public ResponseType Type { get; }
///
/// Notes about the response
///
public List Notes { get; private set; }
///
/// The data payload.
///
public JArray Data { get; private set; }
///
/// Profile information about the query
///
public Profile Profile { get; private set; }
///
/// Backtrace information about a failed query.
///
public Backtrace Backtrace { get; private set; }
///
/// The error type, if any.
///
public ErrorType? ErrorType { get; private set; }
private Response(long token, ResponseType responseType)
{
this.Token = token;
this.Type = responseType;
}
///
/// Parses a Response from a raw JSON string
///
public static Response ParseFrom(long token, string buf)
{
//we check here because it's possibly very expensive to ship this buf around in the call stack
if( Log.IsTraceEnabled ) Log.Trace($"JSON Recv: Token: {token}, JSON: {buf}");
var jsonResp = ParseJson(buf);
var responseType = jsonResp[TypeKey].ToObject();
var responseNotes = jsonResp[NotesKey]?.ToObject>() ?? new List();
ErrorType? et = jsonResp[ErrorKey]?.ToObject();
var profile = Profile.FromJsonArray((JArray)jsonResp[ProfileKey]);
var backtrace = Backtrace.FromJsonArray((JArray)jsonResp[BacktraceKey]);
var res = new Response(token, responseType)
{
ErrorType = et,
Profile = profile,
Backtrace = backtrace,
Data = (JArray)jsonResp[DataKey] ?? new JArray(),
Notes = responseNotes
};
return res;
}
private static JObject ParseJson(string buf)
{
using( var reader = new JsonTextReader(new StringReader(buf)) )
{
return Converter.Serializer.Deserialize(reader);
}
}
public virtual bool IsWaitComplete => this.Type == ResponseType.WAIT_COMPLETE;
/* Whether the response is any kind of feed */
public virtual bool IsFeed => this.Notes.Any(rn => rn.IsFeed());
/* Whether the response is any kind of error */
public virtual bool IsError => this.Type.IsError();
/* What type of success the response contains */
public virtual bool IsAtom => this.Type == ResponseType.SUCCESS_ATOM;
public virtual bool IsSequence => this.Type == ResponseType.SUCCESS_SEQUENCE;
public virtual bool IsPartial => this.Type == ResponseType.SUCCESS_PARTIAL;
public virtual ReqlError MakeError(Query query)
{
string msg = this.Data.Count > 0 ? (string)Data[0] : "Unknown error message";
return new ErrorBuilder(msg, this.Type)
.SetBacktrace(this.Backtrace)
.SetErrorType(this.ErrorType.GetValueOrDefault())
.SetTerm(query)
.Build();
}
///
/// Pretty printing a response for diagnostics.
///
public override string ToString()
{
return JsonConvert.SerializeObject(this, Formatting.Indented);
}
}
}