Пример #1
0
        void StoreObject(object o)
        {
            var type = o.GetType();

            if (!type.IsClass)
            {
                throw new BTDBException("You can store only classes, not " + type.ToSimpleName());
            }
            var tableInfo = _owner.TablesInfo.FindByType(type);

            IfNeededPersistTableInfo(tableInfo);
            DBObjectMetadata metadata = null;

            if (_objSmallMetadata != null)
            {
                _objSmallMetadata.TryGetValue(o, out metadata);
            }
            else if (_objBigMetadata != null)
            {
                _objBigMetadata.TryGetValue(o, out metadata);
            }
            if (metadata == null)
            {
                throw new BTDBException("Metadata for object not found");
            }
            if (metadata.State == DBObjectState.Deleted)
            {
                return;
            }
            var writer = new ByteBufferWriter();

            writer.WriteVUInt32(tableInfo.Id);
            writer.WriteVUInt32(tableInfo.ClientTypeVersion);
            tableInfo.Saver(this, metadata, writer, o);
            if (tableInfo.IsSingletonOid(metadata.Id))
            {
                tableInfo.CacheSingletonContent(_transactionNumber + 1, null);
            }
            _keyValueTrProtector.Start();
            _keyValueTr.SetKeyPrefix(ObjectDB.AllObjectsPrefix);
            _keyValueTr.CreateOrUpdateKeyValue(BuildKeyFromOid(metadata.Id), writer.Data.ToByteArray());
        }
Пример #2
0
        public int RemoveByKeyPrefixWithoutIterate(ByteBuffer keyBytesPrefix)
        {
            if (_hasSecondaryIndexes)
            {
                //keyBytePrefix contains [Index Relation, Primary key prefix] we need
                //                       [Index Relation, Secondary Key Index, Primary key prefix]
                int idBytesLength = ObjectDB.AllRelationsPKPrefix.Length + PackUnpack.LengthVUInt(_relationInfo.Id);
                var writer        = new ByteBufferWriter();
                foreach (var secKey in _relationInfo.ClientRelationVersionInfo.SecondaryKeys)
                {
                    writer.WriteBlock(ObjectDB.AllRelationsSKPrefix);
                    writer.WriteVUInt32(_relationInfo.Id);
                    writer.WriteVUInt32(secKey.Key);
                    writer.WriteBlock(keyBytesPrefix.Buffer, idBytesLength, keyBytesPrefix.Length - idBytesLength);
                    _transaction.KeyValueDBTransaction.SetKeyPrefix(writer.Data);
                    _transaction.KeyValueDBTransaction.EraseAll();
                    writer.Reset();
                }
            }

            return(RemovePrimaryKeysByPrefix(keyBytesPrefix));
        }
Пример #3
0
        void CalculateSecondaryKey(IInternalObjectDBTransaction tr, IList <KeyValuePair <uint, SecondaryKeyInfo> > indexes)
        {
            var keyWriter = new ByteBufferWriter();

            var enumeratorType = typeof(RelationEnumerator <>).MakeGenericType(_clientType);

            keyWriter.WriteByteArrayRaw(ObjectDB.AllRelationsPKPrefix);
            keyWriter.WriteVUInt32(Id);
            var enumerator = (IEnumerator)Activator.CreateInstance(enumeratorType, tr, this, keyWriter.GetDataAndRewind().ToAsyncSafe(), new SimpleModificationCounter());

            var keySavers = new Action <IInternalObjectDBTransaction, AbstractBufferedWriter, object> [indexes.Count];

            for (int i = 0; i < indexes.Count; i++)
            {
                keySavers[i] = CreateSaver(ClientRelationVersionInfo.GetSecondaryKeyFields(indexes[i].Key),
                                           $"Relation_{Name}_Upgrade_SK_{indexes[i].Value.Name}_KeySaver");
            }

            while (enumerator.MoveNext())
            {
                var obj = enumerator.Current;

                tr.TransactionProtector.Start();
                tr.KeyValueDBTransaction.SetKeyPrefix(ObjectDB.AllRelationsSKPrefix);

                for (int i = 0; i < indexes.Count; i++)
                {
                    keyWriter.WriteVUInt32(Id);
                    keyWriter.WriteVUInt32(indexes[i].Key);
                    keySavers[i](tr, keyWriter, obj);
                    var keyBytes = keyWriter.GetDataAndRewind();

                    if (!tr.KeyValueDBTransaction.CreateOrUpdateKeyValue(keyBytes, ByteBuffer.NewEmpty()))
                    {
                        throw new BTDBException("Internal error, secondary key bytes must be always unique.");
                    }
                }
            }
        }
Пример #4
0
        public RelationInfo(uint id, string name, IRelationInfoResolver relationInfoResolver, Type interfaceType,
                            Type clientType, IInternalObjectDBTransaction tr)
        {
            _id   = id;
            _name = name;
            _relationInfoResolver     = relationInfoResolver;
            _interfaceType            = interfaceType;
            _clientType               = clientType;
            ClientRelationVersionInfo = CreateVersionInfoByReflection();
            LoadVersionInfos(tr.KeyValueDBTransaction);
            ApartFields = FindApartFields(interfaceType, ClientRelationVersionInfo);
            if (LastPersistedVersion > 0 && RelationVersionInfo.Equal(_relationVersions[LastPersistedVersion], ClientRelationVersionInfo))
            {
                _relationVersions[LastPersistedVersion] = ClientRelationVersionInfo;
                ClientTypeVersion = LastPersistedVersion;
            }
            else
            {
                ClientTypeVersion = LastPersistedVersion + 1;
                _relationVersions.Add(ClientTypeVersion, ClientRelationVersionInfo);
                var writerk = new ByteBufferWriter();
                writerk.WriteByteArrayRaw(ObjectDB.RelationVersionsPrefix);
                writerk.WriteVUInt32(_id);
                writerk.WriteVUInt32(ClientTypeVersion);
                var writerv = new ByteBufferWriter();
                ClientRelationVersionInfo.Save(writerv);
                tr.KeyValueDBTransaction.SetKeyPrefix(ByteBuffer.NewEmpty());
                tr.KeyValueDBTransaction.CreateOrUpdateKeyValue(writerk.Data, writerv.Data);

                if (LastPersistedVersion > 0)
                {
                    CheckThatPrimaryKeyHasNotChanged(name, ClientRelationVersionInfo, _relationVersions[LastPersistedVersion]);
                    UpdateSecondaryKeys(tr, ClientRelationVersionInfo, _relationVersions[LastPersistedVersion]);
                }
            }
            _typeConvertorGenerator = tr.Owner.TypeConvertorGenerator;
        }
Пример #5
0
            public byte[] ToConfiguration()
            {
                var writer = new ByteBufferWriter();

                writer.WriteVUInt32((_signed ? 1u : 0) + (Flags ? 2u : 0) + 4u * (uint)Names.Length);
                foreach (var name in Names)
                {
                    writer.WriteString(name);
                }
                foreach (var value in Values)
                {
                    if (_signed)
                    {
                        writer.WriteVInt64((long)value);
                    }
                    else
                    {
                        writer.WriteVUInt64(value);
                    }
                }
                return(writer.Data.ToByteArray());
            }
Пример #6
0
        internal RelationInfo CreateByName(IInternalObjectDBTransaction tr, string name, Type interfaceType,
                                           RelationBuilder builder)
        {
            name = string.Intern(name);
            if (!_name2Id.TryGetValue(name, out var id))
            {
                id             = _freeId++;
                _name2Id[name] = id;
                tr.KeyValueDBTransaction.SetKeyPrefixUnsafe(ObjectDB.RelationNamesPrefix);
                var nameWriter = new ByteBufferWriter();
                nameWriter.WriteString(name);
                var idWriter = new ByteBufferWriter();
                idWriter.WriteVUInt32(id);
                tr.KeyValueDBTransaction.CreateOrUpdateKeyValue(nameWriter.Data, idWriter.Data);
            }

            if (_id2Relation.TryGetValue(id, out var relation))
            {
                throw new BTDBException($"Relation with name '{name}' was already initialized");
            }
            relation         = new RelationInfo(id, name, builder, tr);
            _id2Relation[id] = relation;
            return(relation);
        }
Пример #7
0
        void SerializeIntoBuffer(object metadata, IReadOnlyList <object> events, out int startOffset,
                                 out IDescriptorSerializerContext serializerContext, out BlockType blockType,
                                 out int lenWithoutEndPadding, out ByteBuffer block)
        {
            startOffset = (int)EndBufferLen + HeaderSize;
            var writer = new ByteBufferWriter();

            writer.WriteBlock(_zeroes.AsSpan(0, startOffset));
            serializerContext = Mapping;
            if (metadata != null)
            {
                serializerContext = serializerContext.StoreNewDescriptors(writer, metadata);
            }
            if (events != null)
            {
                foreach (var o in events)
                {
                    serializerContext = serializerContext.StoreNewDescriptors(writer, o);
                }
                if (events.Count == 0)
                {
                    events = null;
                }
            }
            serializerContext.FinishNewDescriptors(writer);
            blockType = BlockType.FirstBlock;
            if (serializerContext.SomeTypeStored)
            {
                blockType |= BlockType.HasTypeDeclaration;
            }
            if (metadata != null)
            {
                serializerContext.StoreObject(writer, metadata);
                blockType |= BlockType.HasMetadata;
            }
            if (events != null)
            {
                if (events.Count == 1)
                {
                    serializerContext.StoreObject(writer, events[0]);
                    blockType |= BlockType.HasOneEvent;
                }
                else
                {
                    writer.WriteVUInt32((uint)events.Count);
                    foreach (var o in events)
                    {
                        serializerContext.StoreObject(writer, o);
                    }
                    blockType |= BlockType.HasMoreEvents;
                }
            }
            lenWithoutEndPadding = (int)writer.GetCurrentPosition();
            writer.WriteBlock(_zeroes.AsSpan(0, (int)(SectorSize - 1)));
            block = writer.Data;
            if (CompressionStrategy.ShouldTryToCompress(lenWithoutEndPadding - startOffset))
            {
                var compressedBlock = ByteBuffer.NewSync(block.Buffer, startOffset, lenWithoutEndPadding - startOffset);
                if (CompressionStrategy.Compress(ref compressedBlock))
                {
                    blockType |= BlockType.Compressed;
                    Array.Copy(compressedBlock.Buffer, compressedBlock.Offset, block.Buffer, startOffset, compressedBlock.Length);
                    lenWithoutEndPadding = startOffset + compressedBlock.Length;
                    Array.Copy(_zeroes, 0, block.Buffer, lenWithoutEndPadding, (int)SectorSize - 1);
                }
            }
        }