public void ModifyMetadata(BlittableJsonReaderObject metadata, ref DynamicJsonValue modifications)
        {
            if (metadata == null)
            {
                return;
            }

            if (_operateOnTypes.HasFlag(DatabaseItemType.Counters) == false && metadata.TryGet(Constants.Documents.Metadata.Counters, out BlittableJsonReaderArray _))
            {
                modifications.Remove(Constants.Documents.Metadata.Counters);
            }

            if (_operateOnTypes.HasFlag(DatabaseItemType.Attachments) == false && metadata.TryGet(Constants.Documents.Metadata.Attachments, out BlittableJsonReaderArray _))
            {
                modifications.Remove(Constants.Documents.Metadata.Attachments);
            }
        }
Example #2
0
        private static bool FilterIdentity(string indentityName, DatabaseItemType operateOnTypes)
        {
            if ("Raven/Etag".Equals(indentityName, StringComparison.InvariantCultureIgnoreCase))
            {
                return(false);
            }

            if ("IndexId".Equals(indentityName, StringComparison.InvariantCultureIgnoreCase))
            {
                return(false);
            }

            if (Constants.RavenSubscriptionsPrefix.Equals(indentityName, StringComparison.OrdinalIgnoreCase))
            {
                return(false);
            }

            if (operateOnTypes.HasFlag(DatabaseItemType.Documents))
            {
                return(true);
            }

            return(false);
        }
        private unsafe bool AboutToReadPropertyNameInMetadataUnlikely(IJsonParser reader, JsonParserState state, out bool aboutToReadPropertyName)
        {
            aboutToReadPropertyName = true;

            switch (state.StringSize)
            {
                default: // accept this property
                    {
                        return true;
                    }
                case -2: // IgnoreArrayProperty
                    {
                        if (state.CurrentTokenType != JsonParserToken.StartArray)
                            ThrowInvalidArrayType(state, reader);

                        while (state.CurrentTokenType != JsonParserToken.EndArray)
                        {
                            if (reader.Read() == false)
                            {
                                _state = State.IgnoreArray;
                                aboutToReadPropertyName = false;
                                return true;
                            }
                        }
                        break;
                    }
                case -1: // IgnoreProperty
                    {
                        if (reader.Read() == false)
                        {
                            _state = State.IgnoreProperty;
                            aboutToReadPropertyName = false;
                            return true;
                        }
                        if (state.CurrentTokenType == JsonParserToken.StartArray ||
                            state.CurrentTokenType == JsonParserToken.StartObject)
                            ThrowInvalidMetadataProperty(state, reader);
                        break;
                    }

                case 3: // @id
                    if (state.StringBuffer[0] != (byte)'@' ||
                        *(short*)(state.StringBuffer + 1) != 25705)
                    {
                        aboutToReadPropertyName = true;
                        return true;
                    }

                    if (reader.Read() == false)
                    {
                        _state = State.ReadingId;
                        aboutToReadPropertyName = false;
                        return true;
                    }
                    if (state.CurrentTokenType != JsonParserToken.String)
                        ThrowExpectedFieldTypeOfString(Constants.Documents.Metadata.Id, state, reader);
                    Id = CreateLazyStringValueFromParserState(state);
                    break;
                case 5: // @etag
                    if (state.StringBuffer[0] != (byte)'@' ||
                        *(int*)(state.StringBuffer + 1) != 1734440037)
                    {
                        aboutToReadPropertyName = true;
                        return true;
                    }

                    if (ReadFirstEtagOfLegacyRevision &&
                        (NonPersistentFlags & NonPersistentDocumentFlags.LegacyRevision) == NonPersistentDocumentFlags.LegacyRevision)
                    {
                        if (FirstEtagOfLegacyRevision == null)
                        {
                            if (reader.Read() == false)
                            {
                                _state = State.ReadingFirstEtagOfLegacyRevision;
                                aboutToReadPropertyName = false;
                                return true;
                            }
                            if (state.CurrentTokenType != JsonParserToken.String)
                                ThrowExpectedFieldTypeOfString("@etag", state, reader);
                            FirstEtagOfLegacyRevision = LegacyEtag = CreateLazyStringValueFromParserState(state);
                            ChangeVector = ChangeVectorUtils.NewChangeVector("RV", ++LegacyRevisionsCount, new Guid(FirstEtagOfLegacyRevision).ToBase64Unpadded());
                            break;
                        }

                        ChangeVector = ChangeVectorUtils.NewChangeVector("RV", ++LegacyRevisionsCount, new Guid(FirstEtagOfLegacyRevision).ToBase64Unpadded());
                    }

                    if (ReadLegacyEtag)
                    {
                        if (reader.Read() == false)
                        {
                            _state = State.ReadingEtag;
                            aboutToReadPropertyName = false;
                            return true;
                        }

                        if (state.CurrentTokenType != JsonParserToken.String)
                            ThrowExpectedFieldTypeOfString("@etag", state, reader);
                        LegacyEtag = CreateLazyStringValueFromParserState(state);
                        break;
                    }

                    goto case -1;
                case 6: // @flags
                    if (state.StringBuffer[0] != (byte)'@' ||
                        *(int*)(state.StringBuffer + 1) != 1734437990 ||
                        state.StringBuffer[1 + sizeof(int)] != (byte)'s')
                    {
                        aboutToReadPropertyName = true;
                        return true;
                    }

                    if (reader.Read() == false)
                    {
                        _state = State.ReadingFlags;
                        aboutToReadPropertyName = false;
                        return true;
                    }
                    if (state.CurrentTokenType != JsonParserToken.String)
                        ThrowExpectedFieldTypeOfString(Constants.Documents.Metadata.Flags, state, reader);
                    Flags = ReadFlags(state);
                    break;

                case 9: // @counters
                    // always remove the @counters metadata
                    // not doing so might cause us to have counter on the document but not in the storage.
                    // the counters will be updated when we import the counters themselves
                    if (state.StringBuffer[0] != (byte)'@' ||
                        *(long*)(state.StringBuffer + 1) != 8318823012450529123)
                    {
                        aboutToReadPropertyName = true;
                        return true;
                    }

                    SeenCounters = true;
                    if (reader.Read() == false)
                    {
                        _verifyStartArray = true;
                        _state = State.IgnoreArray;
                        aboutToReadPropertyName = false;
                        return true;
                    }
                    goto case -2;

                case 12: // @index-score OR @attachments

                    if (state.StringBuffer[0] == (byte)'@')
                    {   // @index-score
                        if (*(long*)(state.StringBuffer + 1) == 7166121427196997225 &&
                            *(short*)(state.StringBuffer + 1 + sizeof(long)) == 29295 &&
                            state.StringBuffer[1 + sizeof(long) + sizeof(short)] == (byte)'e')
                        {
                            goto case -1;
                        }

                        // @attachments
                        SeenAttachments = true;
                        if (OperateOnTypes.HasFlag(DatabaseItemType.Attachments) == false &&
                            *(long*)(state.StringBuffer + 1) == 7308612546338255969 &&
                            *(short*)(state.StringBuffer + 1 + sizeof(long)) == 29806 &&
                            state.StringBuffer[1 + sizeof(long) + sizeof(short)] == (byte)'s')
                        {
                            if (reader.Read() == false)
                            {
                                _verifyStartArray = true;
                                _state = State.IgnoreArray;
                                aboutToReadPropertyName = false;
                                return true;
                            }
                            goto case -2;
                        }
                    }

                    aboutToReadPropertyName = true;
                    return true;
                case 13: //Last-Modified
                    if (*(long*)state.StringBuffer != 7237087983830262092 ||
                        *(int*)(state.StringBuffer + sizeof(long)) != 1701406313 ||
                        state.StringBuffer[12] != (byte)'d')
                    {
                        aboutToReadPropertyName = true;
                        return true;
                    }

                    goto case -1;

                case 14:
                    if (state.StringBuffer[0] == (byte)'@')
                    {
                        // @change-vector
                        if (*(long*)(state.StringBuffer + 1) == 8515573965335390307 &&
                            *(int*)(state.StringBuffer + 1 + sizeof(long)) == 1869898597 &&
                            state.StringBuffer[1 + sizeof(long) + sizeof(int)] == (byte)'r')
                        {
                            if (reader.Read() == false)
                            {
                                _state = State.ReadingChangeVector;
                                aboutToReadPropertyName = false;
                                return true;
                            }
                            if (state.CurrentTokenType != JsonParserToken.String)
                                ThrowExpectedFieldTypeOfString(Constants.Documents.Metadata.ChangeVector, state, reader);
                            ChangeVector = CreateLazyStringValueFromParserState(state);
                            break;
                        }

                        // @last-modified
                        if (*(long*)(state.StringBuffer + 1) == 7237123168202350956 &&
                            *(int*)(state.StringBuffer + 1 + sizeof(long)) == 1701406313 &&
                            state.StringBuffer[1 + sizeof(long) + sizeof(int)] == (byte)'d')
                        {
                            if (reader.Read() == false)
                            {
                                _state = State.ReadingLastModified;
                                aboutToReadPropertyName = false;
                                return true;
                            }
                            if (state.CurrentTokenType != JsonParserToken.String)
                                ThrowExpectedFieldTypeOfString(Constants.Documents.Metadata.LastModified, state, reader);
                            LastModified = ReadDateTime(state, reader, State.ReadingLastModified);
                            break;
                        }
                    }

                    aboutToReadPropertyName = true;
                    return true;
                case 15: //Raven-Read-Only
                    if (*(long*)state.StringBuffer != 7300947898092904786 ||
                        *(int*)(state.StringBuffer + sizeof(long)) != 1328374881 ||
                        *(short*)(state.StringBuffer + sizeof(long) + sizeof(int)) != 27758 ||
                        state.StringBuffer[14] != (byte)'y')
                    {
                        aboutToReadPropertyName = true;
                        return true;
                    }

                    goto case -1;

                case 17: //Raven-Entity-Name --> @collection
                    if (*(long*)state.StringBuffer != 7945807069737017682 ||
                        *(long*)(state.StringBuffer + sizeof(long)) != 7881666780093245812 ||
                        state.StringBuffer[16] != (byte)'e')
                    {
                        aboutToReadPropertyName = true;
                        return true;
                    }

                    var collection = _metadataCollections;
                    state.StringBuffer = collection.AllocatedMemoryData.Address;
                    state.StringSize = collection.Size;
                    aboutToReadPropertyName = true;
                    return true;
                case 19: //Raven-Last-Modified or Raven-Delete-Marker
                    if (*(int*)state.StringBuffer != 1702256978 ||
                        *(short*)(state.StringBuffer + sizeof(int)) != 11630)
                    {
                        aboutToReadPropertyName = true;
                        return true;
                    }

                    var longValue = *(long*)(state.StringBuffer + sizeof(int) + sizeof(short));
                    var intValue = *(int*)(state.StringBuffer + sizeof(int) + sizeof(short) + sizeof(long));
                    if ((longValue != 7237087983830262092 || intValue != 1701406313) && // long: Last-Mod, int: ifie
                        (longValue != 5561212665464644932 || intValue != 1701540449))   // long: Delete-M, int: arke
                    {
                        aboutToReadPropertyName = true;
                        return true;
                    }

                    var lb = state.StringBuffer[18];
                    if (lb != (byte)'d' && lb != (byte)'r')
                    {
                        aboutToReadPropertyName = true;
                        return true;
                    }

                    var isLegacyLastModified = lb == (byte)'d';
                    if (reader.Read() == false)
                    {
                        _state = isLegacyLastModified ? State.ReadingLegacyLastModified : State.ReadingLegacyDeleteMarker;
                        aboutToReadPropertyName = false;
                        return true;
                    }

                    if (isLegacyLastModified)
                    {
                        if (state.CurrentTokenType != JsonParserToken.String)
                            ThrowExpectedFieldTypeOfString(LegacyLastModified, state, reader);

                        LastModified = ReadDateTime(state, reader, State.ReadingLegacyLastModified);
                    }
                    else
                    {
                        if (state.CurrentTokenType == JsonParserToken.True)
                            NonPersistentFlags |= NonPersistentDocumentFlags.LegacyDeleteMarker;
                    }

                    break;
                case 21: //Raven-Expiration-Date
                    if (*(long*)state.StringBuffer != 8666383010116297042 ||
                        *(long*)(state.StringBuffer + sizeof(long)) != 7957695015158966640 ||
                        *(short*)(state.StringBuffer + sizeof(long) + sizeof(long)) != 17453 ||
                        state.StringBuffer[20] != (byte)'e')
                    {
                        aboutToReadPropertyName = true;
                        return true;
                    }

                    var expires = _metadataExpires;
                    state.StringBuffer = expires.AllocatedMemoryData.Address;
                    state.StringSize = expires.Size;
                    aboutToReadPropertyName = true;
                    return true;
                case 23: //Raven-Document-Revision
                    if (*(long*)state.StringBuffer != 8017583188798234962 ||
                        *(long*)(state.StringBuffer + sizeof(long)) != 5921517102558967139 ||
                        *(int*)(state.StringBuffer + sizeof(long) + sizeof(long)) != 1936291429 ||
                        *(short*)(state.StringBuffer + sizeof(long) + sizeof(long) + sizeof(int)) != 28521 ||
                        state.StringBuffer[22] != (byte)'n')
                    {
                        aboutToReadPropertyName = true;
                        return true;
                    }

                    goto case -1;
                case 24: //Raven-Replication-Source
                    if (*(long*)state.StringBuffer != 7300947898092904786 ||
                        *(long*)(state.StringBuffer + sizeof(long)) != 8028075772393122928 ||
                        *(long*)(state.StringBuffer + sizeof(long) + sizeof(long)) != 7305808869229538670)
                    {
                        aboutToReadPropertyName = true;
                        return true;
                    }

                    goto case -1;
                case 25: //Raven-Replication-Version OR Raven-Replication-History
                    if (*(long*)state.StringBuffer != 7300947898092904786 ||
                        *(long*)(state.StringBuffer + sizeof(long)) != 8028075772393122928)
                    {
                        aboutToReadPropertyName = true;
                        return true;
                    }

                    var value = *(long*)(state.StringBuffer + sizeof(long) + sizeof(long));
                    var lastByte = state.StringBuffer[24];
                    if ((value != 8028074745928232302 || lastByte != (byte)'n') &&
                        (value != 8245937481775066478 || lastByte != (byte)'y'))
                    {
                        aboutToReadPropertyName = true;
                        return true;
                    }

                    var isReplicationHistory = lastByte == (byte)'y';
                    if (reader.Read() == false)
                    {
                        _verifyStartArray = isReplicationHistory;
                        _state = isReplicationHistory ? State.IgnoreArray : State.IgnoreProperty;
                        aboutToReadPropertyName = false;
                        return true;
                    }

                    // Raven-Replication-History is an array
                    if (isReplicationHistory)
                    {
                        goto case -2;
                    }
                    else if (state.CurrentTokenType == JsonParserToken.StartArray ||
                             state.CurrentTokenType == JsonParserToken.StartObject)
                        ThrowInvalidMetadataProperty(state, reader);
                    break;
                case 29: //Non-Authoritative-Information
                    if (*(long*)state.StringBuffer != 7526769800038477646 ||
                        *(long*)(state.StringBuffer + sizeof(long)) != 8532478930943832687 ||
                        *(long*)(state.StringBuffer + sizeof(long) + sizeof(long)) != 7886488383206796645 ||
                        *(int*)(state.StringBuffer + sizeof(long) + sizeof(long) + sizeof(long)) != 1869182049 ||
                        state.StringBuffer[28] != (byte)'n')
                    {
                        aboutToReadPropertyName = true;
                        return true;
                    }

                    goto case -1;

                case 30: //Raven-Document-Parent-Revision OR Raven-Document-Revision-Status
                    if (*(long*)state.StringBuffer != 8017583188798234962)
                    {
                        aboutToReadPropertyName = true;
                        return true;
                    }

                    if ((*(long*)(state.StringBuffer + sizeof(long)) != 5777401914483111267 ||
                         *(long*)(state.StringBuffer + sizeof(long) + sizeof(long)) != 7300947924012593761 ||
                         *(int*)(state.StringBuffer + sizeof(long) + sizeof(long) + sizeof(long)) != 1769171318 ||
                         *(short*)(state.StringBuffer + sizeof(long) + sizeof(long) + sizeof(long) + sizeof(int)) != 28271) &&
                        (*(long*)(state.StringBuffer + sizeof(long)) != 5921517102558967139 ||
                         *(long*)(state.StringBuffer + sizeof(long) + sizeof(long)) != 3273676477843469925 ||
                         *(int*)(state.StringBuffer + sizeof(long) + sizeof(long) + sizeof(long)) != 1952543827 ||
                         *(short*)(state.StringBuffer + sizeof(long) + sizeof(long) + sizeof(long) + sizeof(int)) != 29557))
                    {
                        aboutToReadPropertyName = true;
                        return true;
                    }

                    var isRevisionStatusProperty = state.StringBuffer[29] == 's';
                    if (reader.Read() == false)
                    {
                        _state = isRevisionStatusProperty ? State.IgnoreRevisionStatusProperty : State.IgnoreProperty;
                        aboutToReadPropertyName = false;
                        return true;
                    }

                    if (state.CurrentTokenType == JsonParserToken.StartArray ||
                        state.CurrentTokenType == JsonParserToken.StartObject)
                        ThrowInvalidMetadataProperty(state, reader);

                    if (isRevisionStatusProperty)
                    {
                        switch (CreateLazyStringValueFromParserState(state))
                        {
                            case LegacyHasRevisionsDocumentState:
                                NonPersistentFlags |= NonPersistentDocumentFlags.LegacyHasRevisions;
                                break;
                            case LegacyRevisionState:
                                NonPersistentFlags |= NonPersistentDocumentFlags.LegacyRevision;
                                break;
                        }
                    }

                    break;
                case 32: //Raven-Replication-Merged-History
                    if (*(long*)state.StringBuffer != 7300947898092904786 ||
                        *(long*)(state.StringBuffer + sizeof(long)) != 8028075772393122928 ||
                        *(long*)(state.StringBuffer + sizeof(long) + sizeof(long)) != 7234302117464059246 ||
                        *(long*)(state.StringBuffer + sizeof(long) + sizeof(long) + sizeof(long)) != 8751179571877464109)
                    {
                        aboutToReadPropertyName = true;
                        return true;
                    }

                    goto case -1;
            }
            return false;
        }