public void TestExtractSpecialTypePartitionKey()
 {
     foreach (Tuple <string, object, Func <object, object> > tuple in new[]
     {
         Tuple.Create <string, object, Func <object, object> >("Guid", Guid.NewGuid(), val => val.ToString()),
         Tuple.Create <string, object, Func <object, object> >("DateTime", DateTime.Now, val =>
         {
             string str = JsonConvert.SerializeObject(val, new JsonSerializerSettings()
             {
                 Converters = new List <JsonConverter> {
                     new IsoDateTimeConverter()
                 }
             });
             return(str.Substring(1, str.Length - 2));
         }),
         Tuple.Create <string, object, Func <object, object> >("Enum", HttpStatusCode.OK, val => (int)val),
         Tuple.Create <string, object, Func <object, object> >("CustomEnum", HttpStatusCode.OK, val => val.ToString()),
         Tuple.Create <string, object, Func <object, object> >("ResourceId", "testid", val => val),
         Tuple.Create <string, object, Func <object, object> >("CustomDateTime", new DateTime(2016, 11, 14), val => EpochDateTimeConverter.DateTimeToEpoch((DateTime)val)),
     })
     {
         SpecialPropertyDocument sd = new SpecialPropertyDocument();
         sd.GetType().GetProperty(tuple.Item1).SetValue(sd, tuple.Item2);
         PartitionKeyDefinition partitionKeyDefinition = new PartitionKeyDefinition {
             Kind = PartitionKind.Hash, Paths = new Collection <string> {
                 "/" + tuple.Item1
             }
         };
         PartitionKeyInternal partitionKeyValue = DocumentAnalyzer.ExtractPartitionKeyValue(Document.FromObject(sd), partitionKeyDefinition);
         Assert.AreEqual(PartitionKeyInternal.FromObjectArray(new object[] { tuple.Item3(tuple.Item2) }, true), partitionKeyValue);
     }
 }
Example #2
0
        public async Task TestQueryWithSpecialPartitionKeysAsync()
        {
            QueryWithSpecialPartitionKeysArgs[] queryWithSpecialPartitionKeyArgsList = new QueryWithSpecialPartitionKeysArgs[]
            {
                new QueryWithSpecialPartitionKeysArgs()
                {
                    Name  = "Guid",
                    Value = Guid.NewGuid(),
                    ValueToPartitionKey = val => val.ToString(),
                },
                //new QueryWithSpecialPartitionKeysArgs()
                //{
                //    Name = "DateTime",
                //    Value = DateTime.Now,
                //    ValueToPartitionKey = val =>
                //    {
                //        string str = JsonConvert.SerializeObject(
                //            val,
                //            new JsonSerializerSettings()
                //            {
                //                Converters = new List<JsonConverter> { new IsoDateTimeConverter() }
                //            });
                //        return str.Substring(1, str.Length - 2);
                //    },
                //},
                new QueryWithSpecialPartitionKeysArgs()
                {
                    Name  = "Enum",
                    Value = HttpStatusCode.OK,
                    ValueToPartitionKey = val => (int)val,
                },
                new QueryWithSpecialPartitionKeysArgs()
                {
                    Name  = "CustomEnum",
                    Value = HttpStatusCode.OK,
                    ValueToPartitionKey = val => val.ToString(),
                },
                new QueryWithSpecialPartitionKeysArgs()
                {
                    Name  = "ResourceId",
                    Value = "testid",
                    ValueToPartitionKey = val => val,
                },
                new QueryWithSpecialPartitionKeysArgs()
                {
                    Name  = "CustomDateTime",
                    Value = new DateTime(2016, 11, 12),
                    ValueToPartitionKey = val => EpochDateTimeConverter.DateTimeToEpoch((DateTime)val),
                },
            };

            foreach (QueryWithSpecialPartitionKeysArgs testArg in queryWithSpecialPartitionKeyArgsList)
            {
                // For this test we need to split direct and gateway runs into separate collections,
                // since the query callback inserts some documents (thus has side effects).
                await this.CreateIngestQueryDeleteAsync <QueryWithSpecialPartitionKeysArgs>(
                    ConnectionModes.Direct,
                    CollectionTypes.SinglePartition,
                    QueryTestsBase.NoDocuments,
                    ImplementationAsync,
                    testArg,
                    "/" + testArg.Name);

                await this.CreateIngestQueryDeleteAsync <QueryWithSpecialPartitionKeysArgs>(
                    ConnectionModes.Direct,
                    CollectionTypes.MultiPartition,
                    QueryTestsBase.NoDocuments,
                    ImplementationAsync,
                    testArg,
                    "/" + testArg.Name);

                await this.CreateIngestQueryDeleteAsync <QueryWithSpecialPartitionKeysArgs>(
                    ConnectionModes.Gateway,
                    CollectionTypes.SinglePartition,
                    QueryTestsBase.NoDocuments,
                    ImplementationAsync,
                    testArg,
                    "/" + testArg.Name);

                await this.CreateIngestQueryDeleteAsync <QueryWithSpecialPartitionKeysArgs>(
                    ConnectionModes.Gateway,
                    CollectionTypes.MultiPartition,
                    QueryTestsBase.NoDocuments,
                    ImplementationAsync,
                    testArg,
                    "/" + testArg.Name);
            }

            async Task ImplementationAsync(
                Container container,
                IReadOnlyList <CosmosObject> documents,
                QueryWithSpecialPartitionKeysArgs testArgs)
            {
                QueryWithSpecialPartitionKeysArgs args = testArgs;

                SpecialPropertyDocument specialPropertyDocument = new SpecialPropertyDocument
                {
                    Id = Guid.NewGuid().ToString()
                };

                specialPropertyDocument.GetType().GetProperty(args.Name).SetValue(specialPropertyDocument, args.Value);
                object getPropertyValueFunction(SpecialPropertyDocument d) => d.GetType().GetProperty(args.Name).GetValue(d);

                ItemResponse <SpecialPropertyDocument> response = await container.CreateItemAsync <SpecialPropertyDocument>(specialPropertyDocument);

                dynamic returnedDoc = response.Resource;

                Assert.AreEqual(args.Value, getPropertyValueFunction((SpecialPropertyDocument)returnedDoc));

                PartitionKey key = new PartitionKey(args.ValueToPartitionKey(args.Value));

                response = await container.ReadItemAsync <SpecialPropertyDocument>(response.Resource.Id, new Cosmos.PartitionKey(key));

                returnedDoc = response.Resource;
                Assert.AreEqual(args.Value, getPropertyValueFunction((SpecialPropertyDocument)returnedDoc));

                returnedDoc = (await this.RunSinglePartitionQuery <SpecialPropertyDocument>(
                                   container,
                                   "SELECT * FROM t")).Single();

                Assert.AreEqual(args.Value, getPropertyValueFunction(returnedDoc));

                string query;

                switch (args.Name)
                {
                case "Guid":
                    query = $"SELECT * FROM T WHERE T.Guid = '{(Guid)args.Value}'";
                    break;

                case "Enum":
                    query = $"SELECT * FROM T WHERE T.Enum = '{(HttpStatusCode)args.Value}'";
                    break;

                case "DateTime":
                    query = $"SELECT * FROM T WHERE T.DateTime = '{(DateTime)args.Value}'";
                    break;

                case "CustomEnum":
                    query = $"SELECT * FROM T WHERE T.CustomEnum = '{(HttpStatusCode)args.Value}'";
                    break;

                case "ResourceId":
                    query = $"SELECT * FROM T WHERE T.ResourceId = '{(string)args.Value}'";
                    break;

                case "CustomDateTime":
                    query = $"SELECT * FROM T WHERE T.CustomDateTime = '{(DateTime)args.Value}'";
                    break;

                default:
                    query = null;
                    break;
                }

                returnedDoc = (await container.GetItemQueryIterator <SpecialPropertyDocument>(
                                   query,
                                   requestOptions: new QueryRequestOptions()
                {
                    MaxItemCount = 1,
                    PartitionKey = new Cosmos.PartitionKey(args.ValueToPartitionKey),
                }).ReadNextAsync()).First();

                Assert.AreEqual(args.Value, getPropertyValueFunction(returnedDoc));
            }
        }