Ejemplo n.º 1
0
        public QueryQueryStep(QueryRunner queryRunner, StringSegment alias, Query query, QueryMetadata queryMetadata, Sparrow.Json.BlittableJsonReaderObject queryParameters, DocumentsOperationContext documentsContext, long?existingResultEtag,
                              GraphQueryPlan gqp, OperationCancelToken token)
        {
            _graphQueryPlan = gqp;
            Query           = query;
            _alias          = alias;
            _aliases        = new HashSet <string> {
                _alias.Value
            };
            _queryRunner     = queryRunner;
            _queryMetadata   = queryMetadata;
            _queryParameters = queryParameters;
            _context         = documentsContext;
            _resultEtag      = existingResultEtag;
            _token           = token;

            if (!string.IsNullOrEmpty(queryMetadata.CollectionName)) //not a '_' collection
            {
                try
                {
                    var _ = _queryRunner.Database.DocumentsStorage.GetCollection(queryMetadata.CollectionName, throwIfDoesNotExist: true);
                }
                catch (Exception e)
                {
                    throw new InvalidQueryException("Query on collection " + queryMetadata.CollectionName + " failed, because there is no such collection. If you meant to use " + queryMetadata.CollectionName + " as an alias, use: (_ as " + queryMetadata.CollectionName + ")", e);
                }
            }
        }
        public bool TryRead(BlittableJsonReaderObject docReader, StringSegment path, out object result)
        {
            var    indexOfFirstSeparator = path.IndexOfAny(_separators, 0);
            object reader;

            //if not found -> indexOfFirstSeparator == -1 -> take whole includePath as segment
            if (docReader.TryGetMember(path.SubSegment(0, indexOfFirstSeparator), out reader) == false)
            {
                result = null;
                return(false);
            }

            if (indexOfFirstSeparator == -1)
            {
                result = reader;
                return(true);
            }

            var pathSegment = path.SubSegment(indexOfFirstSeparator + 1);

            switch (path[indexOfFirstSeparator])
            {
            case PropertySeparator:
                var subObject = reader as BlittableJsonReaderObject;
                if (subObject != null)
                {
                    return(TryRead(subObject, pathSegment, out result));
                }

                if (pathSegment == "Length")
                {
                    var lazyStringValue = reader as LazyStringValue;
                    if (lazyStringValue == null)
                    {
                        var lazyCompressedStringValue = reader as LazyCompressedStringValue;
                        if (lazyCompressedStringValue != null)
                        {
                            lazyStringValue = lazyCompressedStringValue.ToLazyStringValue();
                        }
                    }

                    if (lazyStringValue != null)
                    {
                        var value = lazyStringValue.ToString();
                        result = value.Length;
                        return(true);
                    }
                }

                throw new InvalidOperationException($"Invalid path. After the property separator ('{PropertySeparator}') {reader?.GetType()?.FullName ?? "null"} object has been ancountered instead of {nameof(BlittableJsonReaderObject)}.");

            case CollectionSeparator:
                var subArray = reader as BlittableJsonReaderArray;
                if (subArray != null)
                {
                    result = ReadArray(subArray, pathSegment);
                    return(true);
                }

                throw new InvalidOperationException($"Invalid path. After the collection separator ('{CollectionSeparator}') {reader?.GetType()?.FullName ?? "null"}  object has been ancountered instead of {nameof(BlittableJsonReaderArray)}.");

            default:
                throw new NotSupportedException($"Unhandled separator character: {path[indexOfFirstSeparator]}");
            }
        }
        private int PropertiesValidation(BlittableJsonToken rootTokenTypen, int mainPropOffsetSize, int mainPropIdSize,
                                         int objStartOffset, int numberOfPropsNames)
        {
            byte offset;
            var  numberOfProperties = ReadVariableSizeInt(_mem + objStartOffset, 0, out offset);
            var  current            = objStartOffset + offset;

            if (numberOfProperties < 0)
            {
                ThrowInvalidNumbeOfProperties();
            }

            for (var i = 1; i <= numberOfProperties; i++)
            {
                var propOffset = ReadNumber(_mem + current, mainPropOffsetSize);
                if ((propOffset > objStartOffset) || (propOffset < 0))
                {
                    ThrowInvalidPropertiesOffest();
                }
                current += mainPropOffsetSize;

                if (rootTokenTypen == BlittableJsonToken.StartObject)
                {
                    var id = ReadNumber(_mem + current, mainPropIdSize);
                    if ((id > numberOfPropsNames) || (id < 0))
                    {
                        ThrowInvalidPropertiesId();
                    }
                    current += mainPropIdSize;
                }

                int propOffsetSize;
                int propIdSize;
                var tokenType = TokenValidation(*(_mem + current), out propOffsetSize, out propIdSize);
                current++;

                var propValueOffset = objStartOffset - propOffset;

                switch (tokenType)
                {
                case BlittableJsonToken.StartObject:
                    PropertiesValidation(tokenType, propOffsetSize, propIdSize, propValueOffset, numberOfPropsNames);
                    break;

                case BlittableJsonToken.StartArray:
                    PropertiesValidation(tokenType, propOffsetSize, propIdSize, propValueOffset, numberOfPropsNames);
                    break;

                case BlittableJsonToken.Integer:
                    ReadVariableSizeLong(propValueOffset);
                    break;

                case BlittableJsonToken.LazyNumber:
                    var numberLength = ReadVariableSizeInt(propValueOffset, out byte lengthOffset);
                    var escCount     = ReadVariableSizeInt(propValueOffset + lengthOffset + numberLength, out byte escOffset);

                    // if number has any non-ascii symbols, we rull it out immediately
                    if (escCount > 0)
                    {
                        ThrowInvalidNumber(propValueOffset);
                    }

                    var numberCharsStart = _mem + objStartOffset - propOffset + lengthOffset;

                    // try and validate number using double's validation
                    if (_context.TryParseDouble(numberCharsStart, numberLength, out _) == false)
                    {
                        ThrowInvalidNumber(propValueOffset);
                    }
                    break;

                case BlittableJsonToken.String:
                    StringValidation(propValueOffset);
                    break;

                case BlittableJsonToken.CompressedString:
                    var stringLength           = ReadVariableSizeInt(propValueOffset, out offset);
                    var compressedStringLength = ReadVariableSizeInt(propValueOffset + offset, out offset);
                    if ((compressedStringLength > stringLength) ||
                        (compressedStringLength < 0) ||
                        (stringLength < 0))
                    {
                        ThrowInvalidCompressedString();
                    }
                    break;

                case BlittableJsonToken.Boolean:
                    var boolProp = ReadNumber(_mem + propValueOffset, 1);
                    if ((boolProp != 0) && (boolProp != 1))
                    {
                        ThrowInvalidBool();
                    }
                    break;

                case BlittableJsonToken.Null:
                    if (ReadNumber(_mem + propValueOffset, 1) != 0)
                    {
                        ThrowInvalidNull();
                    }
                    break;

                case BlittableJsonToken.EmbeddedBlittable:
                    byte offsetLen;
                    stringLength = ReadVariableSizeInt(propValueOffset, out offsetLen);
                    var blittableJsonReaderObject = new BlittableJsonReaderObject(_mem + propValueOffset + offsetLen, stringLength, _context);
                    blittableJsonReaderObject.BlittableValidation();
                    break;

                default:
                    ThrowInvalidTokenType();
                    break;
                }
            }
            return(current);
        }
Ejemplo n.º 4
0
 private static void ThrowInvalidPrimitiveCastException(string prop, string type, BlittableJsonReaderObject json)
 {
     throw new InvalidCastException($"Failed to fetch property name = {prop} of type {type} from json with value : [{json}]");
 }
Ejemplo n.º 5
0
        private static Dictionary <string, Dictionary <string, string[]> > ToDictionaryOfDictionaryOfStringArray(BlittableJsonReaderObject json, string name)
        {
            var dic = new Dictionary <string, Dictionary <string, string[]> >(StringComparer.OrdinalIgnoreCase);

            BlittableJsonReaderObject obj;

            //should a "null" exist in json? -> not sure that "null" can exist there
            if (json.TryGet(name, out obj) == false || obj == null)
            {
                return(dic);
            }

            foreach (var propertyName in obj.GetPropertyNames())
            {
                BlittableJsonReaderObject result;
                if (obj.TryGet(propertyName, out result))
                {
                    var prop = new Dictionary <string, string[]>();
                    dic[propertyName] = prop;
                    foreach (var innerPropName in result.GetPropertyNames())
                    {
                        BlittableJsonReaderArray val;
                        if (result.TryGet(innerPropName, out val))
                        {
                            var array = new string[val.Length];
                            for (int i = 0; i < val.Length; i++)
                            {
                                array[i] = val[i]?.ToString();
                            }
                            prop[innerPropName] = array;
                        }
                    }
                }
            }
            return(dic);
        }
Ejemplo n.º 6
0
        private static Dictionary <TK, TV> ToDictionary <TK, TV>(BlittableJsonReaderObject json, string name, Func <BlittableJsonReaderObject, TV> converter)
        {
            var isStringKey = typeof(TK) == typeof(string);
            var dictionary  = new Dictionary <TK, TV>((IEqualityComparer <TK>)StringComparer.Ordinal); // we need to deserialize it as we got it, keys could be case sensitive - RavenDB-8713

            BlittableJsonReaderObject obj;

            if (json.TryGet(name, out obj) == false || obj == null)
            {
                return(dictionary);
            }

            foreach (var propertyName in obj.GetPropertyNames())
            {
                object val;
                if (obj.TryGetMember(propertyName, out val) == false)
                {
                    continue;
                }

                dynamic key;
                if (isStringKey)
                {
                    key = propertyName;
                }
                else
                {
                    key = (TK)Convert.ChangeType(propertyName, typeof(TK));
                }

                var typeOfValue = typeof(TV);
                if (typeOfValue.IsConstructedGenericType && typeOfValue.GetGenericTypeDefinition() == typeof(Dictionary <,>))
                {
                    var keyType      = typeOfValue.GenericTypeArguments[0];
                    var valueType    = typeOfValue.GenericTypeArguments[1];
                    var newConverter = GetConverterFromCache(valueType);
                    var methodInfo   = typeof(JsonDeserializationBase)
                                       .GetMethod("ToDictionary", BindingFlags.NonPublic | BindingFlags.Static);
                    var method = methodInfo.MakeGenericMethod(keyType, valueType);
                    var result = method.Invoke(null, new[] { obj, key, newConverter });
                    dictionary[key] = (TV)Convert.ChangeType(result, typeOfValue);
                }
                else
                {
                    if (typeOfValue != typeof(object) &&
                        val is BlittableJsonReaderObject blittableJsonReaderObject)
                    {
                        dictionary[key] = converter(blittableJsonReaderObject);
                    }
                    else
                    {
                        if (val is BlittableJsonReaderArray)
                        {
                            ThrowNotSupportedBlittableArray(propertyName);
                        }

                        obj.TryGet(propertyName, out TV value);
                        dictionary[key] = value;
                    }
                }
            }
            return(dictionary);
        }