Exemplo n.º 1
0
        /// <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);
        }
Exemplo n.º 2
0
        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));
        }
Exemplo n.º 4
0
        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));
        }
Exemplo n.º 5
0
        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("]");
        }
Exemplo n.º 6
0
            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());
        }