/// <summary> /// Execute a SQL statement against the graph database. /// Forward the request to the SQL Client with a JObject type and then convert the resulting graphson documents into our entity using the serialization helper. /// </summary> /// <param name="query">Query to execute</param> /// <param name="pagedResults">true to return only one page of the result set, false(Default) to return all results. </param> /// <param name="continuationToken">token to pass into the query iterator to resume from a specific page. Should be present when using pageResults = true</param> /// <param name="cancellationToken">cancellatinToken used to cancel an operation in progress.</param> /// <returns><see cref="CosmosResponse"/> that encapsulates the result of the query and tracks success status along with various performance parameters.</returns> public async Task <CosmosResponse <IEnumerable <T> > > ExecuteSQL <T>(string query, bool pagedResults = false, string continuationToken = "", CancellationToken cancellationToken = default(CancellationToken)) { EnsureCosmosSqlClient(); if (CosmosEntitySerializer.IsTypeDirectlySerializableToGraph(typeof(T))) { return(await CosmosSqlClient.ExecuteSQL <T>(query, pagedResults, continuationToken, cancellationToken)); } var res = await CosmosSqlClient.ExecuteSQL <JObject>(query, pagedResults, continuationToken, cancellationToken); var cosmosResult = res.Clone <IEnumerable <T> >(); if (typeof(T) == typeof(JObject) || typeof(T) == typeof(object)) { return(cosmosResult); } if (!res.IsSuccessful) { return(cosmosResult); } cosmosResult.Result = res.Result.Select(CosmosSerializer.FromGraphson <T>).ToArray(); return(cosmosResult); }
/// <summary> /// Executes a Gremlin traversal. /// When the type of the result is unknown (using steps like tree() or path(), send T as JObject and manually deserialize /// </summary> /// <typeparam name="T">Type to convert the results to</typeparam> /// <param name="queryString">Gremlin traversal</param> /// <param name="bindings">[Optional] Collection of parameters and their values to be sent to the gremlin server along with the query.</param> /// <example> /// <![CDATA[ /// await cosmosGraphClient.ExecuteGremlin<Movie>("g.V().hasLabel('Movie').has('Language', 'en').has('Budget', gt(1000000))"); /// await cosmosGraphClient.ExecuteGremlin<Movie>("g.V().hasLabel('Movie').has('Language',lang).has('Budget',gt(budget))", new Dictionary<string, object> { { "lang", "en" }, { "budget", 1000000 } }); /// ]]> /// </example> /// <returns>CosmosResponse wrapped Array of results.</returns> public async Task <CosmosResponse <IEnumerable <T> > > ExecuteGremlin <T>(string queryString, Dictionary <string, object> bindings = null) { try { using (var gremlinClient = GetGremlinClient()) { var start = DateTime.Now; var graphResult = await gremlinClient.SubmitAsync <dynamic>(queryString, bindings); var graphResultString = JsonConvert.SerializeObject(graphResult); var res = new CosmosResponse <IEnumerable <T> > { StatusCode = System.Net.HttpStatusCode.OK, RequestCharge = Helpers.GetValueOrDefault <double>(graphResult.StatusAttributes, RESULTSET_ATTRIBUTE_RU), ExecutionTime = DateTime.Now.Subtract(start) }; if (CosmosEntitySerializer.IsTypeDirectlySerializableToGraph(typeof(T))) { res.Result = JsonConvert.DeserializeObject <IEnumerable <T> >(graphResultString).ToArray(); } else { var graphResultJObject = JsonConvert.DeserializeObject <IEnumerable <JObject> >(graphResultString).ToArray(); res.Result = (typeof(T) == typeof(JObject) || typeof(T) == typeof(object)) ? graphResultJObject.Cast <T>() : graphResultJObject.Select(CosmosSerializer.FromGraphson <T>).ToArray(); } return(res); } } catch (ResponseException e) { return(new CosmosResponse <IEnumerable <T> > { Result = null, Error = e, RequestCharge = Helpers.GetValueOrDefault <double>(e.StatusAttributes, RESULTSET_ATTRIBUTE_RU), RetryAfter = TimeSpan.FromMilliseconds(Helpers.GetValueOrDefault <int>(e.StatusAttributes, RESULTSET_ATTRIBUTE_RETRYAFTER)), ActivityId = Helpers.GetValueOrDefault <string>(e.StatusAttributes, RESULTSET_ATTRIBUTE_ACTIVITYID), }); } catch (Exception e) { return(new CosmosResponse <IEnumerable <T> > { Result = null, Error = e, RequestCharge = -1 }); } }
/// <summary> /// Gets all documents of the given type from the collection. /// </summary> /// <param name="filter">Optional filter argument (i.e "budget > 100000 and revenue < 3000000".</param> /// <param name="label">Type of document to retrieve. If empty, attempt to get value from the Attribute name or class name.</param> /// <param name="cancellationToken">cancellatinToken used to cancel an operation in progress.</param> /// <returns>Collection of results.</returns> public Task <CosmosResponse <IEnumerable <T> > > ReadDocuments <T>(string filter = "", string label = "", CancellationToken cancellationToken = default(CancellationToken)) { if (!string.IsNullOrEmpty(filter)) { filter = "and " + filter; } if (string.IsNullOrEmpty(label)) { label = CosmosEntitySerializer.GetLabelForType(typeof(T)); } var query = $"select * from c where c.label = '{label}' {filter}"; return(ExecuteSQL <T>(query, cancellationToken: cancellationToken)); }
public void GenerateCosmosDocumentFromModelWithAttributesCustomSerializer() { var movie = Movie.GetTestModel("The Network"); var movieDoc = new CosmosEntitySerializer("pk").ToCosmosDocument(movie) as IDictionary <string, object>; Assert.IsNotNull(movieDoc, "Failed to convert movie to Document"); //Test that properties are present in the output document var errors = new List <string>(); if (!movieDoc.ContainsKey("id")) { errors.Add("Document missing Id property"); } if (!movieDoc.ContainsKey("label")) { errors.Add("Document missing Label property"); } if (!movieDoc.ContainsKey("pk")) { errors.Add("Document missing PartitionKey property"); } if (!movieDoc.ContainsKey("Budget")) { errors.Add("Document missing Budget property"); } if (!movieDoc.ContainsKey("ReleaseDate")) { errors.Add("Document missing ReleaseDate property"); } if (!movieDoc.ContainsKey("Runtime")) { errors.Add("Document missing Runtime property"); } if (!movieDoc.ContainsKey("Rating")) { errors.Add("Document missing Rating property"); } if (!movieDoc.ContainsKey("Cast")) { errors.Add("Document missing Cast property"); } if (!movieDoc.ContainsKey("MovieId")) { errors.Add("Document missing MovieId property"); } if (!movieDoc.ContainsKey("Title")) { errors.Add("Document missing Title property"); } if (!movieDoc.ContainsKey("Format")) { errors.Add("Document missing Title property"); } Assert.IsFalse(errors.Any(), string.Join(Environment.NewLine, errors.ToArray())); Assert.AreEqual(11, movieDoc.Keys.Count(), "Document has extra properties"); //Test values Assert.AreEqual(movie.MovieId, movieDoc["id"], "id not matching"); Assert.AreEqual(movie.Label, movieDoc["label"], "label not matching"); Assert.AreEqual(movie.Title, movieDoc["pk"], "partitionKey not matching"); Assert.AreEqual(movie.MovieId, movieDoc["MovieId"], "MovieId not matching"); Assert.AreEqual(movie.Title, movieDoc["Title"], "Title not matching"); Assert.AreEqual(movie.Rating, movieDoc["Rating"], "Rating not matching"); Assert.AreEqual(movie.Cast, movieDoc["Cast"], "Cast not matching"); Assert.AreEqual(movie.Budget, movieDoc["Budget"], "Budget not matching"); Assert.AreEqual(movie.ReleaseDate, movieDoc["ReleaseDate"], "ReleaseDate not matching"); Assert.AreEqual(movie.Runtime, movieDoc["Runtime"], "Runtime not matching"); Assert.AreEqual(movie.Format, movieDoc["Format"], "Format not matching"); }