Пример #1
0
        public static void AddChanges(this ICollection <DocumentsChanges> docChanges, KeyValuePair <string, RavenJToken> kvp, RavenJToken token, string fieldName)
        {
            var changes = new DocumentsChanges
            {
                FieldNewType  = kvp.Value.Type.ToString(),
                FieldOldType  = token.Type.ToString(),
                FieldNewValue = kvp.Value.ToString(),
                FieldOldValue = token.ToString(),
                Change        = DocumentsChanges.ChangeType.FieldChanged,
                FieldName     = fieldName
            };

            docChanges.Add(changes);
        }
Пример #2
0
 internal virtual void AddForCloning(string key, RavenJToken token)
 {
     // kept virtual (as opposed to abstract) to waive the new for implementing this in RavenJValue
 }
Пример #3
0
        internal static U Convert <U>(this RavenJToken token, bool cast)
        {
            if (cast)
            {
                // HACK
                return((U)(object)token);
            }
            if (token == null || token.Type == JTokenType.Null)
            {
                return(default(U));
            }

            var value = token as RavenJValue;

            if (value == null)
            {
                throw new InvalidCastException("Cannot cast {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, token.GetType(), typeof(U)));
            }

            if (value.Value is U)
            {
                return((U)value.Value);
            }

            Type targetType = typeof(U);

            if (targetType.IsGenericType() && targetType.GetGenericTypeDefinition() == typeof(Nullable <>))
            {
                if (value.Value == null)
                {
                    return(default(U));
                }

                targetType = Nullable.GetUnderlyingType(targetType);
            }
            if (targetType == typeof(Guid))
            {
                if (value.Value == null)
                {
                    return(default(U));
                }
                return((U)(object)new Guid(value.Value.ToString()));
            }
            if (targetType == typeof(string))
            {
                if (value.Value == null)
                {
                    return(default(U));
                }
                return((U)(object)value.Value.ToString());
            }
            if (targetType == typeof(DateTime))
            {
                var s = value.Value as string;
                if (s != null)
                {
                    DateTime dateTime;
                    if (DateTime.TryParseExact(s, Default.DateTimeFormatsToRead, CultureInfo.InvariantCulture,
                                               DateTimeStyles.RoundtripKind, out dateTime))
                    {
                        return((U)(object)dateTime);
                    }

                    dateTime = RavenJsonTextReader.ParseDateMicrosoft(s);
                    return((U)(object)dateTime);
                }
                if (value.Value is DateTimeOffset)
                {
                    return((U)(object)((DateTimeOffset)value.Value).UtcDateTime);
                }
            }
            if (targetType == typeof(DateTimeOffset))
            {
                var s = value.Value as string;
                if (s != null)
                {
                    DateTimeOffset dateTimeOffset;
                    if (DateTimeOffset.TryParseExact(s, Default.DateTimeFormatsToRead, CultureInfo.InvariantCulture,
                                                     DateTimeStyles.RoundtripKind, out dateTimeOffset))
                    {
                        return((U)(object)dateTimeOffset);
                    }

                    return(default(U));
                }
                if (value.Value is DateTime)
                {
                    return((U)(object)(new DateTimeOffset((DateTime)value.Value)));
                }
            }
            if (targetType == typeof(byte[]) && value.Value is string)
            {
                return((U)(object)System.Convert.FromBase64String((string)value.Value));
            }

            if (value.Value == null && typeof(U).IsValueType)
            {
                throw new InvalidOperationException("value.Value == null and conversion target type is not nullable");
            }

            try
            {
                return((U)System.Convert.ChangeType(value.Value, targetType, CultureInfo.InvariantCulture));
            }
            catch (Exception e)
            {
                if (value.Value != null)
                {
                    throw new InvalidOperationException(string.Format("Unable to find suitable conversion for {0} since it is not predefined and does not implement IConvertible. ", value.Value.GetType()), e);
                }

                throw new InvalidOperationException(string.Format("Unable to find suitable conversion for {0} since it is not predefined ", value), e);
            }
        }
Пример #4
0
 public static int GetDeepHashCode(RavenJToken t)
 {
     return(t == null ? 0 : t.GetDeepHashCode());
 }
Пример #5
0
        internal virtual bool DeepEquals(RavenJToken other)
        {
            if (other == null)
            {
                return(false);
            }

            if (Type != other.Type)
            {
                return(false);
            }

            var otherStack = new Stack <RavenJToken>();
            var thisStack  = new Stack <RavenJToken>();

            thisStack.Push(this);
            otherStack.Push(other);

            while (otherStack.Count > 0)
            {
                var curOtherReader = otherStack.Pop();
                var curThisReader  = thisStack.Pop();

                if (curOtherReader == null && curThisReader == null)
                {
                    continue;                     // shouldn't happen, but we got an error report from a user about this
                }
                if (curOtherReader == null || curThisReader == null)
                {
                    return(false);
                }

                if (curThisReader.Type == curOtherReader.Type)
                {
                    switch (curOtherReader.Type)
                    {
                    case JTokenType.Array:
                        var selfArray  = (RavenJArray)curThisReader;
                        var otherArray = (RavenJArray)curOtherReader;
                        if (selfArray.Length != otherArray.Length)
                        {
                            return(false);
                        }

                        for (int i = 0; i < selfArray.Length; i++)
                        {
                            thisStack.Push(selfArray[i]);
                            otherStack.Push(otherArray[i]);
                        }
                        break;

                    case JTokenType.Object:
                        var selfObj  = (RavenJObject)curThisReader;
                        var otherObj = (RavenJObject)curOtherReader;
                        if (selfObj.Count != otherObj.Count)
                        {
                            return(false);
                        }

                        foreach (var kvp in selfObj.Properties)
                        {
                            RavenJToken token;
                            if (otherObj.TryGetValue(kvp.Key, out token) == false)
                            {
                                return(false);
                            }
                            if (kvp.Value == null)
                            {
                                if (token != null && token.Type != JTokenType.Null)
                                {
                                    return(false);
                                }
                                continue;
                            }
                            switch (kvp.Value.Type)
                            {
                            case JTokenType.Array:
                            case JTokenType.Object:
                                otherStack.Push(token);
                                thisStack.Push(kvp.Value);
                                break;

                            case JTokenType.Bytes:
                                var    bytes      = kvp.Value.Value <byte[]>();
                                byte[] tokenBytes = token.Type == JTokenType.String
                                                                                                                                ? Convert.FromBase64String(token.Value <string>())
                                                                                                                                : token.Value <byte[]>();
                                if (tokenBytes == null)
                                {
                                    return(false);
                                }
                                if (bytes.Length != tokenBytes.Length)
                                {
                                    return(false);
                                }

                                if (tokenBytes.Where((t, i) => t != bytes[i]).Any())
                                {
                                    return(false);
                                }

                                break;

                            default:
                                if (!kvp.Value.DeepEquals(token))
                                {
                                    return(false);
                                }
                                break;
                            }
                        }
                        break;

                    default:
                        if (!curOtherReader.DeepEquals(curThisReader))
                        {
                            return(false);
                        }
                        break;
                    }
                }
                else
                {
                    switch (curThisReader.Type)
                    {
                    case JTokenType.Guid:
                        if (curOtherReader.Type != JTokenType.String)
                        {
                            return(false);
                        }

                        if (curThisReader.Value <string>() != curOtherReader.Value <string>())
                        {
                            return(false);
                        }

                        break;

                    default:
                        return(false);
                    }
                }
            }

            return(true);
        }
Пример #6
0
 internal abstract bool DeepEquals(RavenJToken node);
Пример #7
0
 /// <summary>
 /// Compares the values of two tokens, including the values of all descendant tokens.
 /// </summary>
 /// <param name="t1">The first <see cref="RavenJToken"/> to compare.</param>
 /// <param name="t2">The second <see cref="RavenJToken"/> to compare.</param>
 /// <returns>true if the tokens are equal; otherwise false.</returns>
 public static bool DeepEquals(RavenJToken t1, RavenJToken t2)
 {
     return(t1 == t2 || (t1 != null && t2 != null && t1.DeepEquals(t2)));
 }
Пример #8
0
 internal virtual bool DeepEquals(RavenJToken other)
 {
     return(DeepEquals(other, (List <DocumentsChanges>)null));
 }
Пример #9
0
        internal virtual bool DeepEquals(RavenJToken other, List <DocumentsChanges> docChanges)
        {
            if (other == null)
            {
                return(false);
            }

            if (Type != other.Type)
            {
                return(false);
            }

            var curType        = JTokenType.None;
            var fieldName      = string.Empty;
            var otherStack     = new Stack <RavenJToken>();
            var thisStack      = new Stack <RavenJToken>();
            var fieldNameStack = new Stack <string>();
            var isEqual        = true;

            thisStack.Push(this);
            otherStack.Push(other);

            while (otherStack.Count > 0)
            {
                var    curOtherReader = otherStack.Pop();
                var    curThisReader  = thisStack.Pop();
                string fieldArrName   = string.Empty;
                if (fieldNameStack.Count > 0)
                {
                    fieldArrName = fieldNameStack.Pop();
                    fieldName    = fieldArrName;
                }


                if (curOtherReader == null && curThisReader == null)
                {
                    continue; // shouldn't happen, but we got an error report from a user about this
                }
                if (curOtherReader == null || curThisReader == null)
                {
                    return(false);
                }

                if (curThisReader.Type == curOtherReader.Type)
                {
                    switch (curOtherReader.Type)
                    {
                    case JTokenType.Array:
                        var selfArray  = (RavenJArray)curThisReader;
                        var otherArray = (RavenJArray)curOtherReader;
                        curType = JTokenType.Array;
                        if (selfArray.Length != otherArray.Length)
                        {
                            if (docChanges == null)
                            {
                                return(false);
                            }

                            isEqual = docChanges.CompareRavenJArrayData(selfArray, otherArray, fieldArrName);
                        }
                        else
                        {
                            for (var i = 0; i < selfArray.Length; i++)
                            {
                                thisStack.Push(selfArray[i]);
                                otherStack.Push(otherArray[i]);
                                fieldNameStack.Push(fieldName);
                            }
                        }
                        break;

                    case JTokenType.Object:
                        var selfObj  = (RavenJObject)curThisReader;
                        var otherObj = (RavenJObject)curOtherReader;
                        if (selfObj.Count != otherObj.Count)
                        {
                            curType = JTokenType.Object;

                            if (docChanges == null)
                            {
                                return(false);
                            }
                            isEqual = docChanges.CompareDifferentLengthRavenJObjectData(otherObj, selfObj, fieldName);
                        }
                        else
                        {
                            var prevType = curType;
                            curType = JTokenType.Object;
                            var origFieldName = fieldName;
                            foreach (var kvp in selfObj.Properties)
                            {
                                if (prevType == JTokenType.Object)
                                {
                                    fieldName = origFieldName + "." + kvp.Key;
                                }
                                else
                                {
                                    fieldName = kvp.Key;
                                }

                                RavenJToken token;
                                if (otherObj.TryGetValue(kvp.Key, out token) == false)
                                {
                                    if (docChanges == null)
                                    {
                                        return(false);
                                    }

                                    docChanges.AddChanges(DocumentsChanges.ChangeType.RemovedField);
                                    isEqual = false;
                                }

                                if (kvp.Value == null)
                                {
                                    if (token != null && token.Type != JTokenType.Null)
                                    {
                                        if (docChanges == null)
                                        {
                                            return(false);
                                        }

                                        docChanges.AddChanges(DocumentsChanges.ChangeType.NewField);
                                        isEqual = false;
                                    }

                                    continue;
                                }
                                switch (kvp.Value.Type)
                                {
                                case JTokenType.Array:
                                case JTokenType.Object:
                                    otherStack.Push(token);
                                    thisStack.Push(kvp.Value);
                                    fieldNameStack.Push(fieldName);
                                    break;

                                case JTokenType.Bytes:
                                    var bytes      = kvp.Value.Value <byte[]>();
                                    var tokenBytes = token.Type == JTokenType.String
                                                ? Convert.FromBase64String(token.Value <string>())
                                                : token.Value <byte[]>();
                                    if (tokenBytes == null)
                                    {
                                        return(false);
                                    }
                                    if (bytes.Length != tokenBytes.Length)
                                    {
                                        return(false);
                                    }

                                    if (tokenBytes.Where((t, i) => t != bytes[i]).Any())
                                    {
                                        return(false);
                                    }

                                    break;

                                default:
                                    if (!kvp.Value.DeepEquals(token))
                                    {
                                        if (docChanges == null)
                                        {
                                            return(false);
                                        }
                                        docChanges.AddChanges(kvp, token, fieldName);
                                        isEqual = false;
                                    }

                                    break;
                                }
                            }
                        }
                        break;

                    default:
                        curType = curThisReader.Type;
                        if (!curOtherReader.DeepEquals(curThisReader))
                        {
                            if (docChanges == null)
                            {
                                return(false);
                            }
                            docChanges.AddChanges(curThisReader, curOtherReader, fieldName);
                            isEqual = false;
                        }

                        break;
                    }
                }
                else
                {
                    curType = curThisReader.Type;
                    switch (curThisReader.Type)
                    {
                    case JTokenType.Guid:
                        if (curOtherReader.Type != JTokenType.String)
                        {
                            return(false);
                        }

                        if (curThisReader.Value <string>() != curOtherReader.Value <string>())
                        {
                            return(false);
                        }

                        break;

                    default:
                        return(false);
                    }
                }
            }

            return(isEqual);
        }
Пример #10
0
 /// <summary>
 /// Initializes a new instance of the <see cref="RavenJTokenReader"/> class.
 /// </summary>
 /// <param name="token">The token to read from.</param>
 public RavenJTokenReader(RavenJToken token)
 {
     _root = token;
 }
Пример #11
0
 /// <summary>
 ///     Compares the values of two tokens, including the values of all descendant tokens.
 /// </summary>
 /// <param name="t1">The first <see cref="RavenJToken" /> to compare.</param>
 /// <param name="t2">The second <see cref="RavenJToken" /> to compare.</param>
 /// <param name="difference"> changes description</param>
 /// <returns>true if the tokens are equal; otherwise false.</returns>
 public static bool DeepEquals(RavenJToken t1, RavenJToken t2, List <DocumentsChanges> difference)
 {
     return(t1 == t2 || (t1 != null && t2 != null && t1.DeepEquals(t2, difference)));
 }
Пример #12
0
 public static U Value <U>(this RavenJToken value)
 {
     return(value.Convert <U>());
 }
Пример #13
0
        internal static U Convert <U>(this RavenJToken token, bool cast)
        {
            if (cast)
            {
                // HACK
                return((U)(object)token);
            }
            if (token == null)
            {
                return(default(U));
            }

            var value = token as RavenJValue;

            if (value == null)
            {
                throw new InvalidCastException("Cannot cast {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, token.GetType(), typeof(U)));
            }

            if (value.Value is U)
            {
                return((U)value.Value);
            }

            Type targetType = typeof(U);

            if (targetType.IsGenericType && targetType.GetGenericTypeDefinition() == typeof(Nullable <>))
            {
                if (value.Value == null)
                {
                    return(default(U));
                }

                targetType = Nullable.GetUnderlyingType(targetType);
            }
            if (targetType == typeof(Guid))
            {
                if (value.Value == null)
                {
                    return(default(U));
                }
                return((U)(object)new Guid(value.Value.ToString()));
            }
            if (targetType == typeof(string))
            {
                if (value.Value == null)
                {
                    return(default(U));
                }
                return((U)(object)value.Value.ToString());
            }
            if (targetType == typeof(DateTime) && value.Value is string)
            {
                DateTime dateTime;
                if (DateTime.TryParseExact((string)value.Value, Default.DateTimeFormatsToRead, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out dateTime))
                {
                    return((U)(object)dateTime);
                }

                dateTime = RavenJsonTextReader.ParseDateMicrosoft((string)value.Value);
                return((U)(object)dateTime);
            }
            return((U)System.Convert.ChangeType(value.Value, targetType, CultureInfo.InvariantCulture));
        }
Пример #14
0
        internal virtual bool DeepEquals(RavenJToken other)
        {
            if (other == null)
            {
                return(false);
            }

            if (Type != other.Type)
            {
                return(false);
            }

            var otherStack = new Stack <RavenJToken>();
            var thisStack  = new Stack <RavenJToken>();

            thisStack.Push(this);
            otherStack.Push(other);

            while (otherStack.Count > 0)
            {
                var curOtherReader = otherStack.Pop();
                var curThisReader  = thisStack.Pop();

                if (curThisReader.Type != curOtherReader.Type)
                {
                    return(false);
                }

                if (curOtherReader.Type == JTokenType.Array)
                {
                    var selfArray  = (RavenJArray)curThisReader;
                    var otherArray = (RavenJArray)curOtherReader;
                    if (selfArray.Length != otherArray.Length)
                    {
                        return(false);
                    }

                    for (int i = 0; i < selfArray.Length; i++)
                    {
                        thisStack.Push(selfArray[i]);
                        otherStack.Push(otherArray[i]);
                    }
                }
                else if (curOtherReader.Type == JTokenType.Object)
                {
                    var selfObj  = (RavenJObject)curThisReader;
                    var otherObj = (RavenJObject)curOtherReader;
                    if (selfObj.Count != otherObj.Count)
                    {
                        return(false);
                    }

                    foreach (var kvp in selfObj.Properties)
                    {
                        RavenJToken token;
                        if (otherObj.TryGetValue(kvp.Key, out token) == false)
                        {
                            return(false);
                        }
                        otherStack.Push(token);
                        thisStack.Push(kvp.Value);
                    }
                }
                else                 // value
                {
                    if (!curOtherReader.DeepEquals(curThisReader))
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
Пример #15
0
        public static void AddChanges(this ICollection <DocumentsChanges> docChanges, RavenJToken curThisReader, RavenJToken curOtherReader, string fieldName)
        {
            var changes = new DocumentsChanges
            {
                FieldNewType  = curThisReader.Type.ToString(),
                FieldOldType  = curOtherReader.Type.ToString(),
                FieldNewValue = curThisReader.ToString(),
                FieldOldValue = curOtherReader.ToString(),
                Change        = DocumentsChanges.ChangeType.FieldChanged,
                FieldName     = fieldName
            };

            docChanges.Add(changes);
        }
Пример #16
0
        internal override bool DeepEquals(RavenJToken node)
        {
            var other = node as RavenJValue;

            return(other != null && ValuesEquals(this, other));
        }
Пример #17
0
        internal RavenJToken Evaluate(RavenJToken root, bool errorWhenNoMatch)
        {
            var current = root;

            foreach (object part in Parts)
            {
                var propertyName = part as string;
                if (propertyName != null)
                {
                    var o = current as RavenJObject;
                    if (o != null)
                    {
                        current = o[propertyName];

                        if (current == null && errorWhenNoMatch)
                        {
                            throw new Exception("Property '{0}' does not exist on RavenJObject.".FormatWith(CultureInfo.InvariantCulture, propertyName));
                        }
                    }
                    else
                    {
                        var array = current as RavenJArray;
                        if (array != null)
                        {
                            switch (propertyName)
                            {
                            case "Count":
                            case "count":
                            case "Length":
                            case "length":
                                current = array.Length;
                                break;

                            default:
                                if (errorWhenNoMatch)
                                {
                                    throw new Exception("Property '{0}' not valid on {1}.".FormatWith(CultureInfo.InvariantCulture, propertyName, current.GetType().Name));
                                }
                                break;
                            }
                            continue;
                        }
                        if (errorWhenNoMatch)
                        {
                            throw new Exception("Property '{0}' not valid on {1}.".FormatWith(CultureInfo.InvariantCulture, propertyName, current.GetType().Name));
                        }

                        return(null);
                    }
                }
                else
                {
                    var index = (int)part;

                    var a = current as RavenJArray;

                    if (a != null)
                    {
                        if (a.Length <= index)
                        {
                            if (errorWhenNoMatch)
                            {
                                throw new IndexOutOfRangeException("Index {0} outside the bounds of RavenJArray.".FormatWith(CultureInfo.InvariantCulture, index));
                            }

                            return(null);
                        }

                        current = a[index];
                    }
                    else
                    {
                        if (errorWhenNoMatch)
                        {
                            throw new Exception("Index {0} not valid on {1}.".FormatWith(CultureInfo.InvariantCulture, index, current.GetType().Name));
                        }

                        return(null);
                    }
                }
            }

            return(current);
        }
Пример #18
0
        internal RavenJToken Evaluate(RavenJToken root, bool errorWhenNoMatch, bool createSnapshots = false)
        {
            var current = root;

            foreach (object part in Parts)
            {
                var propertyName = part as string;
                if (propertyName != null)
                {
                    var o = current as RavenJObject;
                    if (o != null)
                    {
                        if (createSnapshots)
                        {
                            switch (propertyName)
                            {
                            case "$Values":
                                current = new RavenJArray(o.Values());
                                break;

                            case "$Keys":
                                current = new RavenJArray(o.Keys);
                                break;

                            default:
                                var newProp = o[propertyName];
                                if (newProp != null)
                                {
                                    newProp.EnsureCannotBeChangeAndEnableSnapshotting();
                                    newProp = newProp.CreateSnapshot();
                                    current = o[propertyName] = newProp;
                                }
                                else
                                {
                                    current = null;
                                }
                                break;
                            }
                        }
                        else
                        {
                            switch (propertyName)
                            {
                            case "$Values":
                                current = new RavenJArray(o.Values());
                                break;

                            case "$Keys":
                                current = new RavenJArray(o.Keys);
                                break;

                            default:
                                current = o[propertyName];
                                break;
                            }
                        }

                        if (current == null && errorWhenNoMatch)
                        {
                            throw new Exception("Property '{0}' does not exist on RavenJObject.".FormatWith(CultureInfo.InvariantCulture, propertyName));
                        }
                    }
                    else
                    {
                        var array = current as RavenJArray;
                        if (array != null)
                        {
                            switch (propertyName)
                            {
                            case "Count":
                            case "count":
                            case "Length":
                            case "length":
                                current = array.Length;
                                break;

                            default:
                                if (errorWhenNoMatch)
                                {
                                    throw new Exception("Property '{0}' not valid on {1}.".FormatWith(CultureInfo.InvariantCulture, propertyName, current.GetType().Name));
                                }
                                break;
                            }
                            continue;
                        }
                        if (errorWhenNoMatch)
                        {
                            throw new Exception("Property '{0}' not valid on {1}.".FormatWith(CultureInfo.InvariantCulture, propertyName, current.GetType().Name));
                        }

                        return(null);
                    }
                }
                else
                {
                    var index = (int)part;

                    var a = current as RavenJArray;

                    if (a != null)
                    {
                        if (a.Length <= index)
                        {
                            if (errorWhenNoMatch)
                            {
                                throw new IndexOutOfRangeException("Index {0} outside the bounds of RavenJArray.".FormatWith(CultureInfo.InvariantCulture, index));
                            }

                            return(null);
                        }

                        current = a[index];
                    }
                    else
                    {
                        if (errorWhenNoMatch)
                        {
                            throw new Exception("Index {0} not valid on {1}.".FormatWith(CultureInfo.InvariantCulture, index, current.GetType().Name));
                        }

                        return(null);
                    }
                }
            }

            return(current);
        }