/// <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
                });
            }
        }
Example #3
0
        /// <summary>
        /// Gets all documents of the given type from the collection.
        /// </summary>
        /// <param name="filter">Optional filter argument (i.e "budget &gt; 100000 and revenue &lt; 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");
        }