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()); }
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)); }
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."); } } } }
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; }
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()); }
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); }
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); } } }