예제 #1
0
            public UInt128 Visit(CosmosGuid cosmosGuid, UInt128 seed)
            {
                UInt128 hash = MurmurHash3.Hash128(CosmosElementHasher.GuidHashSeed, seed);

                hash = MurmurHash3.Hash128(cosmosGuid.Value.ToByteArray(), seed);
                return(hash);
            }
예제 #2
0
        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));
            }
        }
예제 #3
0
            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);
            }
예제 #4
0
        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));
            }
예제 #7
0
        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"))
            });
예제 #8
0
 public bool Visit(CosmosGuid cosmosGuid) => false;
예제 #9
0
        /// <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);
        }
예제 #10
0
 public JsonType Visit(CosmosGuid cosmosGuid) => throw new NotSupportedException("Guid is not a json type.");
예제 #11
0
 public CosmosElement Visit(CosmosGuid cosmosGuid, CosmosElement indexer) => Undefined;
예제 #12
0
 public int Visit(CosmosGuid cosmosGuid, CosmosElement input)
 {
     return(cosmosGuid.CompareTo((CosmosGuid)input));
 }
 public int Visit(CosmosGuid cosmosGuid, CosmosElement input) => cosmosGuid.CompareTo((CosmosGuid)input);
예제 #14
0
 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);
        }
예제 #19
0
 public void Visit(CosmosGuid cosmosGuid)
 {
     this.stringBuilder.AppendFormat("C_Guid(\"{0}\")", cosmosGuid.Value);
 }