public ByteBuffer Serialize(out bool hasMetaData, object obj) { if (obj == null) { hasMetaData = false; _writer.WriteUInt8(0); // null return(_writer.GetDataAndRewind()); } try { _newTypeFound = false; StoreObject(obj); _visited.Clear(); if (!_newTypeFound) { // No unknown metadata found - to be optimistic pays off hasMetaData = false; return(_writer.GetDataAndRewind()); } StoreNewDescriptors(obj); if (_typeOrDescriptor2InfoNew.Count > 0) { _writer.Rewind(); if (MergeTypesByShapeAndStoreNew()) { _typeOrDescriptor2InfoNew.Clear(); _visited.Clear(); hasMetaData = true; return(_writer.GetDataAndRewind()); } _typeOrDescriptor2InfoNew.Clear(); } _visited.Clear(); _newTypeFound = false; StoreObject(obj); if (_newTypeFound) { throw new BTDBException("Forgot descriptor or type"); } _visited.Clear(); hasMetaData = false; return(_writer.GetDataAndRewind()); } catch { _visited.Clear(); _typeOrDescriptor2InfoNew.Clear(); _writer.Rewind(); throw; } }
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."); } } } }