/// <summary> /// Tries to compare two JTokens with respect to their types. /// </summary> /// <param name="left">The left JToken.</param> /// <param name="right">The right JToken.</param> /// <param name="comparison">The comparison if comparable.</param> /// <returns>Whether or not the two JTokens were comparable.</returns> public static bool TryCompare(CosmosElement left, CosmosElement right, out int comparison) { if ((left == null) || (right == null)) { comparison = default; return(false); } JsonType leftJsonType = left.Accept(CosmosElementToJsonType.Singleton); JsonType rightJsonType = right.Accept(CosmosElementToJsonType.Singleton); if (leftJsonType != rightJsonType) { comparison = default; return(false); } if (!Utils.IsPrimitive(left)) { comparison = default; return(false); } comparison = left.CompareTo(right); return(true); }
private static UInt128 GetHash(CosmosElement cosmosElement, UInt128 seed) { if (cosmosElement == null) { return(DistinctHash.GetUndefinedHash(seed)); } return(cosmosElement.Accept(CosmosElementHasher.Singleton, seed)); }
private static bool IsPrimitve(CosmosElement cosmosElement) { if (cosmosElement == Undefined) { return(false); } return(cosmosElement.Accept(IsPrimitiveCosmosElementVisitor.Singleton)); }
public static bool IsPrimitive(CosmosElement value) { if (value == null) { return(false); } JsonType type = value.Accept(CosmosElementToJsonType.Singleton); return((type == JsonType.Boolean) || (type == JsonType.Null) || (type == JsonType.Number) || (type == JsonType.String)); }
public void Visit(CosmosArray cosmosArray) { this.stringBuilder.Append("["); for (int i = 0; i < cosmosArray.Count; i++) { if (i > 0) { this.stringBuilder.Append(","); } CosmosElement arrayItem = cosmosArray[i]; arrayItem.Accept(this); } this.stringBuilder.Append("]"); }
public UInt128 Visit(CosmosArray cosmosArray, UInt128 seed) { // Start the array with a distinct hash, so that empty array doesn't hash to another value. UInt128 hash = MurmurHash3.Hash128(CosmosElementHasher.ArrayHashSeed, seed); // Incorporate all the array items into the hash. for (int index = 0; index < cosmosArray.Count; index++) { CosmosElement arrayItem = cosmosArray[index]; // Order of array items matter in equality check, so we add the index just to be safe. // For now we know that murmurhash will correctly give a different hash for // [true, false, true] and [true, true, false] // due to the way the seed works. // But we add the index just incase that property does not hold in the future. UInt128 arrayItemSeed = CosmosElementHasher.ArrayIndexHashSeed + index; hash = MurmurHash3.Hash128(hash, arrayItem.Accept(this, arrayItemSeed)); } return(hash); }
public static TryCatch <T> Deserialize <T>(ReadOnlyMemory <byte> buffer) { TryCatch <CosmosElement> tryCreateFromBuffer = CosmosElement.Monadic.CreateFromBuffer(buffer); if (tryCreateFromBuffer.Failed) { return(TryCatch <T> .FromException(tryCreateFromBuffer.Exception)); } CosmosElement cosmosElement = tryCreateFromBuffer.Result; TryCatch <object> tryAcceptVisitor = cosmosElement.Accept(Visitor.Singleton, typeof(T)); if (tryAcceptVisitor.Failed) { return(TryCatch <T> .FromException(tryAcceptVisitor.Exception)); } if (!(tryAcceptVisitor.Result is T typedResult)) { Type type = typeof(T); if ((tryAcceptVisitor.Result is null) && (!type.IsValueType || (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable <>)))) { return(TryCatch <T> .FromResult(default));
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()); }