/// <summary> /// Fast SUCCESS_ATOM conversion without the DLR dynamic /// </summary> protected virtual async Task <T> RunQueryAtomAsync <T>(Query query, CancellationToken cancelToken) { var res = await SendQuery(query, cancelToken, awaitResponse : true).ConfigureAwait(false); if (res.IsAtom) { try { if (typeof(T).IsJToken()) { if (res.Data[0].Type == JTokenType.Null) { return((T)(object)null); } var fmt = FormatOptions.FromOptArgs(query.GlobalOptions); Converter.ConvertPseudoTypes(res.Data[0], fmt); return((T)(object)res.Data[0]); //ugh ugly. find a better way to do this. //return res.Data[0].ToObject<T>(); } return(res.Data[0].ToObject <T>(Converter.Serializer)); } catch (IndexOutOfRangeException ex) { throw new ReqlDriverError("Atom response was empty!", ex); } } if (res.IsError) { throw res.MakeError(query); } throw new ReqlDriverError( $"The query response cannot be converted to an object of T or List<T>. This run helper works with SUCCESS_ATOM results. The server response was {res.Type}. If the server response can be handled by this run method try converting to T or List<T>. Otherwise, if the server response cannot be handled by this run helper use another run helper like `.RunCursor` or `.RunResult<T>`."); }
internal Cursor(Connection conn, Query query, Response firstResponse) { this.conn = conn; this.IsFeed = firstResponse.IsFeed; this.Token = query.Token; this.fmt = FormatOptions.FromOptArgs(query.GlobalOptions); this.conn.AddToCache(this.Token, this); //is the first response all there is? this.sequenceFinished = firstResponse.Type == ResponseType.SUCCESS_SEQUENCE; MaybeSendContinue(); ExtendBuffer(firstResponse); }
/// <summary> /// Run the query but it's return type is standard dynamic. /// </summary> protected async Task <dynamic> RunQueryAsync <T>(Query query, CancellationToken cancelToken) { //If you need to continue after an await, **while inside the driver**, //as a library writer, you must use ConfigureAwait(false) on *your* //await to tell the compiler NOT to resume //on synchronization context (if one is present). // //The top most await (your user) will capture the correct synchronization context //(if any) when they await on a query's run. // // https://channel9.msdn.com/Series/Three-Essential-Tips-for-Async/Async-library-methods-should-consider-using-Task-ConfigureAwait-false- // http://blogs.msdn.com/b/lucian/archive/2013/11/23/talk-mvp-summit-async-best-practices.aspx // var res = await SendQuery(query, cancelToken, awaitResponse : true).ConfigureAwait(false); if (res.IsAtom) { try { if (typeof(T).IsJToken()) { if (res.Data[0].Type == JTokenType.Null) { return(null); } var fmt = FormatOptions.FromOptArgs(query.GlobalOptions); Converter.ConvertPseudoTypes(res.Data[0], fmt); return(res.Data[0]); } return(res.Data[0].ToObject(typeof(T), Converter.Serializer)); } catch (IndexOutOfRangeException ex) { throw new ReqlDriverError("Atom response was empty!", ex); } } else if (res.IsPartial || res.IsSequence) { return(new Cursor <T>(this, query, res)); } else if (res.IsWaitComplete) { return(null); } else { throw res.MakeError(query); } }
/// <summary> /// Fast SUCCESS_ATOM or SUCCESS_SEQUENCE conversion without the DLR dynamic /// </summary> private async Task <T> RunQueryResultAsync <T>(Query query, CancellationToken cancelToken) { var res = await SendQuery(query, cancelToken, awaitResponse : true).ConfigureAwait(false); if (res.IsAtom) { try { if (typeof(T).IsJToken()) { if (res.Data[0].Type == JTokenType.Null) { return((T)(object)null); } var fmt = FormatOptions.FromOptArgs(query.GlobalOptions); Converter.ConvertPseudoTypes(res.Data[0], fmt); return((T)(object)res.Data[0]); //ugh ugly. find a better way to do this. } return(res.Data[0].ToObject <T>(Converter.Serializer)); } catch (IndexOutOfRangeException ex) { throw new ReqlDriverError("Atom response was empty!", ex); } } if (res.IsSequence) { if (typeof(T).IsJToken()) { var fmt = FormatOptions.FromOptArgs(query.GlobalOptions); Converter.ConvertPseudoTypes(res.Data, fmt); return((T)(object)res.Data); //ugh ugly. find a better way to do this. } return(res.Data.ToObject <T>(Converter.Serializer)); } if (res.IsError) { throw res.MakeError(query); } throw new ReqlDriverError( $"The query response cannot be converted to an object of T or List<T> " + $"because the server response was {res.Type}. The `.RunResult<T>` helper " + $"only works with SUCCESS_ATOM or SUCCESS_SEQUENCE responses. When the query " + $"response grows larger (over 100K), the response type from the server " + $"can change from SUCCESS_SEQUENCE to SUCCESS_PARTIAL; in which case, you'll " + $"need to use `.RunCursor` that handles both SUCCESS_SEQUENCE and SUCCESS_PARTIAL " + $"response types. The `.RunResult` run helper is only meant to be a " + $"convenience method for relatively quick and smaller responses."); }