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); } }
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)); } }