public UInt128 Visit(CosmosGuid cosmosGuid, UInt128 seed) { UInt128 hash = MurmurHash3.Hash128(CosmosElementHasher.GuidHashSeed, seed); hash = MurmurHash3.Hash128(cosmosGuid.Value.ToByteArray(), seed); return(hash); }
private object CosmosElementToPartitionKeyObject(CosmosElement cosmosElement) { // TODO: Leverage original serialization and avoid re-serialization (bug) switch (cosmosElement.Type) { case CosmosElementType.String: CosmosString cosmosString = cosmosElement as CosmosString; return(cosmosString.Value); case CosmosElementType.Number: CosmosNumber cosmosNumber = cosmosElement as CosmosNumber; return(cosmosNumber.AsFloatingPoint()); case CosmosElementType.Boolean: CosmosBoolean cosmosBool = cosmosElement as CosmosBoolean; return(cosmosBool.Value); case CosmosElementType.Guid: CosmosGuid cosmosGuid = cosmosElement as CosmosGuid; return(cosmosGuid.Value); default: throw new ArgumentException( string.Format(CultureInfo.InvariantCulture, RMResources.UnsupportedPartitionKeyComponentValue, cosmosElement)); } }
public UInt128 Visit(CosmosGuid cosmosGuid, UInt128 seed) { UInt128 hash = seed == RootHashSeed ? RootCache.Guid : MurmurHash3.Hash128(HashSeeds.Guid, seed); hash = MurmurHash3.Hash128(cosmosGuid.Value.ToByteArray(), hash); return(hash); }
public void TestGuid() { Guid value = Guid.NewGuid(); ReadOnlyMemory <byte> result = JsonSerializer.Serialize(value); CosmosGuid cosmosGuid = (CosmosGuid)CosmosElement.CreateFromBuffer(result); Assert.AreEqual(expected: value, actual: cosmosGuid.Value); }
public TryCatch <object> Visit(CosmosGuid cosmosGuid, Type type) { if (type != typeof(Guid)) { return(TryCatch <object> .FromException(Visitor.Exceptions.ExpectedGuid)); } return(TryCatch <object> .FromResult((object)cosmosGuid.Value)); }
public TryCatch <object> Visit(CosmosArray cosmosArray, Type type) { bool isReadOnlyList = type.IsGenericType && (type.GetGenericTypeDefinition() == typeof(IReadOnlyList <>)); if (!isReadOnlyList) { return(TryCatch <object> .FromException(Visitor.Exceptions.ExpectedArray)); } Type genericArgumentType = type.GenericTypeArguments.First(); Type listType = typeof(List <>).MakeGenericType(genericArgumentType); IList list = (IList)Activator.CreateInstance(listType); foreach (CosmosElement arrayItem in cosmosArray) { TryCatch <object> tryGetMaterializedArrayItem; if (genericArgumentType == typeof(object)) { Type dotNetType = arrayItem switch { CosmosArray _ => typeof(IReadOnlyList <object>), CosmosBoolean _ => typeof(bool), CosmosNull _ => typeof(object), CosmosNumber _ => typeof(Number64), CosmosObject _ => typeof(object), CosmosString _ => typeof(string), CosmosGuid _ => typeof(Guid), CosmosBinary _ => typeof(ReadOnlyMemory <byte>), _ => throw new ArgumentOutOfRangeException($"Unknown cosmos element type."), }; tryGetMaterializedArrayItem = arrayItem.Accept(this, dotNetType); } else { tryGetMaterializedArrayItem = arrayItem.Accept(this, genericArgumentType); } if (tryGetMaterializedArrayItem.Failed) { return(tryGetMaterializedArrayItem); } list.Add(tryGetMaterializedArrayItem.Result); } return(TryCatch <object> .FromResult(list)); }
private static IReadOnlyList <(string serializedToken, CosmosElement element)> TokenTestData() { Guid guid = Guid.Parse("69D5AB17-C94A-4173-A278-B59D0D9C7C37"); byte[] randomBytes = guid.ToByteArray(); string hexString = PartitionKeyInternal.HexConvert.ToHex(randomBytes, 0, randomBytes.Length); return(new List <(string, CosmosElement)> { ("[42, 37]", CosmosArray.Parse("[42, 37]")), ($@"{{C_Binary(""0x{hexString}"")}}", CosmosBinary.Create(new ReadOnlyMemory <byte>(randomBytes))), ("false", CosmosBoolean.Create(false)), ($@"{{C_Guid(""{guid}"")}}", CosmosGuid.Create(guid)), ("null", CosmosNull.Create()), ("1", CosmosInt64.Create(1)), ("{\"foo\": false}", CosmosObject.Parse("{\"foo\": false}")), ("asdf", CosmosString.Create("asdf")) });
public bool Visit(CosmosGuid cosmosGuid) => false;
/// <summary> /// Compares to objects and returns their partial sort relationship. /// </summary> /// <param name="element1">The first element to compare.</param> /// <param name="element2">The second element to compare.</param> /// <returns> /// Less than zero if obj1 comes before obj2 in the sort order. /// Zero if obj1 and obj2 are interchangeable in the sort order. /// Greater than zero if obj2 comes before obj1 in the sort order. /// </returns> public int Compare(CosmosElement element1, CosmosElement element2) { if (object.ReferenceEquals(element1, element2)) { return(0); } if (object.ReferenceEquals(element1, MinValueItem.Singleton)) { return(-1); } if (object.ReferenceEquals(element2, MinValueItem.Singleton)) { return(1); } if (object.ReferenceEquals(element1, MaxValueItem.Singleton)) { return(1); } if (object.ReferenceEquals(element2, MaxValueItem.Singleton)) { return(-1); } if (element1 == Undefined) { return(-1); } if (element2 == Undefined) { return(1); } CosmosElementType type1 = element1.Type; int cmp = CompareTypes(element1, element2); if (cmp == 0) { // If they are the same type then you need to break the tie. switch (type1) { case CosmosElementType.Boolean: cmp = Comparer <bool> .Default.Compare( (element1 as CosmosBoolean).Value, (element2 as CosmosBoolean).Value); break; case CosmosElementType.Null: // All nulls are the same. cmp = 0; break; case CosmosElementType.Number: CosmosNumber number1 = element1 as CosmosNumber; CosmosNumber number2 = element2 as CosmosNumber; if (number1.NumberType == CosmosNumberType.Number64) { double double1; if (number1.IsFloatingPoint) { double1 = number1.AsFloatingPoint().Value; } else { double1 = number1.AsInteger().Value; } double double2; if (number2.IsFloatingPoint) { double2 = number2.AsFloatingPoint().Value; } else { double2 = number2.AsInteger().Value; } cmp = Comparer <double> .Default.Compare( double1, double2); } else if (number1.IsFloatingPoint) { double double1 = number1.AsFloatingPoint().Value; double double2 = number2.AsFloatingPoint().Value; cmp = Comparer <double> .Default.Compare(double1, double2); } else { long integer1 = number1.AsInteger().Value; long integer2 = number2.AsInteger().Value; cmp = Comparer <long> .Default.Compare(integer1, integer2); } break; case CosmosElementType.String: CosmosString string1 = element1 as CosmosString; CosmosString string2 = element2 as CosmosString; cmp = string.CompareOrdinal( string1.Value, string2.Value); break; case CosmosElementType.Guid: CosmosGuid guid1 = element1 as CosmosGuid; CosmosGuid guid2 = element2 as CosmosGuid; cmp = guid1.Value.CompareTo(guid2.Value); break; case CosmosElementType.Binary: CosmosBinary binary1 = element1 as CosmosBinary; CosmosBinary binary2 = element2 as CosmosBinary; cmp = ItemComparer.CompareTo(binary1, binary2); break; default: throw new ArgumentException($"Unknown: {nameof(CosmosElementType)}: {type1}"); } } return(cmp); }
public JsonType Visit(CosmosGuid cosmosGuid) => throw new NotSupportedException("Guid is not a json type.");
public CosmosElement Visit(CosmosGuid cosmosGuid, CosmosElement indexer) => Undefined;
public int Visit(CosmosGuid cosmosGuid, CosmosElement input) { return(cosmosGuid.CompareTo((CosmosGuid)input)); }
public int Visit(CosmosGuid cosmosGuid, CosmosElement input) => cosmosGuid.CompareTo((CosmosGuid)input);
public int Visit(CosmosGuid cosmosGuid) { return(6); }
public int Visit(CosmosGuid cosmosGuid) => 6;
public bool Visit(CosmosGuid cosmosGuid) { return(true); }
public void TestOrderByQueryLiterals() { StringBuilder sb = new StringBuilder(); CosmosElement element = CosmosObject.Create( new Dictionary <string, CosmosElement>() { { "item", CosmosString.Create("asdf") } }); element.Accept(new CosmosElementToQueryLiteral(sb)); Assert.AreEqual( @"{""item"":""asdf""}", sb.ToString()); element = CosmosObject.Create( new Dictionary <string, CosmosElement>() { { "item", CosmosBoolean.Create(true) } }); sb.Clear(); element.Accept(new CosmosElementToQueryLiteral(sb)); Assert.AreEqual( @"{""item"":true}", sb.ToString()); element = CosmosObject.Create( new Dictionary <string, CosmosElement>() { { "item", CosmosBoolean.Create(false) } }); sb.Clear(); element.Accept(new CosmosElementToQueryLiteral(sb)); Assert.AreEqual( @"{""item"":false}", sb.ToString()); element = CosmosObject.Create( new Dictionary <string, CosmosElement>() { { "item", CosmosNull.Create() } }); sb.Clear(); element.Accept(new CosmosElementToQueryLiteral(sb)); Assert.AreEqual( @"{""item"":null}", sb.ToString()); element = CosmosObject.Create( new Dictionary <string, CosmosElement>() { { "item", CosmosNumber64.Create(1.0) } }); sb.Clear(); element.Accept(new CosmosElementToQueryLiteral(sb)); Assert.AreEqual( @"{""item"":1}", sb.ToString()); element = CosmosObject.Create( new Dictionary <string, CosmosElement>() { { "item", CosmosNumber64.Create(1L) } }); sb.Clear(); element.Accept(new CosmosElementToQueryLiteral(sb)); Assert.AreEqual( @"{""item"":1}", sb.ToString()); element = CosmosObject.Create( new Dictionary <string, CosmosElement>() { { "item", CosmosInt8.Create(3) }, { "item2", CosmosInt16.Create(4) }, { "item3", CosmosInt32.Create(5) }, { "item5", CosmosUInt32.Create(7) }, { "item6", CosmosInt64.Create(8) }, { "item7", CosmosFloat32.Create(9.1f) }, { "item8", CosmosFloat64.Create(10.2) }, }); sb.Clear(); element.Accept(new CosmosElementToQueryLiteral(sb)); Assert.AreEqual( @"{""item"":C_Int8(3),""item2"":C_Int16(4),""item3"":C_Int32(5),""item5"":C_UInt32(7),""item6"":C_Int64(8)," + @"""item7"":C_Float32(9.1),""item8"":C_Float64(10.2)}", sb.ToString()); Guid guid = Guid.NewGuid(); byte[] randomBytes = Guid.NewGuid().ToByteArray(); string hexString = PartitionKeyInternal.HexConvert.ToHex(randomBytes, 0, randomBytes.Length); element = CosmosObject.Create( new Dictionary <string, CosmosElement>() { { "item", CosmosGuid.Create(guid) }, { "item2", CosmosBinary.Create(new ReadOnlyMemory <byte>(randomBytes)) }, }); sb.Clear(); element.Accept(new CosmosElementToQueryLiteral(sb)); Assert.AreEqual( $@"{{""item"":C_Guid(""{guid.ToString()}""),""item2"":C_Binary(""0x{hexString}"")}}", sb.ToString()); // deeply nested arrays and objects element = CosmosObject.Create( new Dictionary <string, CosmosElement>() { { "item", CosmosGuid.Create(guid) }, // empty array { "item2", CosmosArray.Create(new CosmosElement[] { }) }, // empty object { "item3", CosmosObject.Create(new Dictionary <string, CosmosElement>()) }, // array of objects with numbers { "item4", CosmosArray.Create(new CosmosElement[] { CosmosObject.Create(new Dictionary <string, CosmosElement>() { { "a", CosmosInt8.Create(3) }, { "b", CosmosString.Create("adf") }, }), CosmosInt16.Create(25) }) }, }); sb.Clear(); element.Accept(new CosmosElementToQueryLiteral(sb)); Assert.AreEqual( $@"{{""item"":C_Guid(""{guid.ToString()}""),""item2"":[],""item3"":{{}},""item4"":[{{""a"":C_Int8(3),""b"":""adf""}},C_Int16(25)]}}", sb.ToString()); }
/// <summary> /// Compares to objects and returns their partial sort relationship. /// </summary> /// <param name="element1">The first element to compare.</param> /// <param name="element2">The second element to compare.</param> /// <returns> /// Less than zero if obj1 comes before obj2 in the sort order. /// Zero if obj1 and obj2 are interchangeable in the sort order. /// Greater than zero if obj2 comes before obj1 in the sort order. /// </returns> public int Compare(CosmosElement element1, CosmosElement element2) { if (object.ReferenceEquals(element1, element2)) { return(0); } if (object.ReferenceEquals(element1, MinValueItem.Singleton)) { return(-1); } if (object.ReferenceEquals(element2, MinValueItem.Singleton)) { return(1); } if (object.ReferenceEquals(element1, MaxValueItem.Singleton)) { return(1); } if (object.ReferenceEquals(element2, MaxValueItem.Singleton)) { return(-1); } if (element1 == Undefined) { return(-1); } if (element2 == Undefined) { return(1); } CosmosElementType type1 = element1.Type; int cmp = CompareTypes(element1, element2); if (cmp == 0) { // If they are the same type then you need to break the tie. switch (type1) { case CosmosElementType.Boolean: cmp = Comparer <bool> .Default.Compare( (element1 as CosmosBoolean).Value, (element2 as CosmosBoolean).Value); break; case CosmosElementType.Null: // All nulls are the same. cmp = 0; break; case CosmosElementType.Number: CosmosNumber number1 = element1 as CosmosNumber; CosmosNumber number2 = element2 as CosmosNumber; if (number1.NumberType == CosmosNumberType.Number64) { // Both are Number64, so compare as Number64 cmp = number1.Value.CompareTo(number2.Value); } else { // We have a number with precision if (number2.Value.IsInteger) { // compare as longs, since all types have an implicit conversion with full fidelity. long integer1 = Number64.ToLong(number1.Value); long integer2 = Number64.ToLong(number2.Value); cmp = Comparer <long> .Default.Compare(integer1, integer2); } else { // compare as doubles, since all types have an implicit conversion with full fidelity. double double1 = Number64.ToDouble(number1.Value); double double2 = Number64.ToDouble(number2.Value); cmp = Comparer <double> .Default.Compare(double1, double2); } } break; case CosmosElementType.String: CosmosString string1 = element1 as CosmosString; CosmosString string2 = element2 as CosmosString; cmp = string.CompareOrdinal( string1.Value, string2.Value); break; case CosmosElementType.Guid: CosmosGuid guid1 = element1 as CosmosGuid; CosmosGuid guid2 = element2 as CosmosGuid; cmp = guid1.Value.CompareTo(guid2.Value); break; case CosmosElementType.Binary: CosmosBinary binary1 = element1 as CosmosBinary; CosmosBinary binary2 = element2 as CosmosBinary; cmp = ItemComparer.CompareTo(binary1, binary2); break; case CosmosElementType.Array: case CosmosElementType.Object: { UInt128 hash1 = DistinctHash.GetHash(element1); UInt128 hash2 = DistinctHash.GetHash(element2); return(hash1.CompareTo(hash2)); } default: throw new ArgumentException($"Unknown: {nameof(CosmosElementType)}: {type1}"); } } return(cmp); }
public void Visit(CosmosGuid cosmosGuid) { this.stringBuilder.AppendFormat("C_Guid(\"{0}\")", cosmosGuid.Value); }