Пример #1
0
        internal async Task <TKey> _Save <TKey>(Type actualType, Type tableType, object instance, CycleCache cache)
        {
            ITableDefinition tableDef = null;

            if (!TableDefinitions.ContainsKey(tableType))
            {
                throw new SterlingTableNotFoundException(instance.GetType(), Name);
            }

            tableDef = TableDefinitions[tableType];

            if (!tableDef.IsDirty(instance))
            {
                return((TKey)tableDef.FetchKeyFromInstance(instance));
            }

            foreach (var trigger in _TriggerList(tableType).Where(trigger => !trigger.BeforeSave(actualType, instance)))
            {
                throw new SterlingTriggerException(Exceptions.Exceptions.BaseDatabaseInstance_Save_Save_suppressed_by_trigger, trigger.GetType());
            }

            var key = (TKey)tableDef.FetchKeyFromInstance(instance);

            int keyIndex;

            if (cache.Check(instance))
            {
                return(key);
            }

            if (cache.Check(instance))
            {
                return(key);
            }

            cache.Add(tableType, instance, key);

            keyIndex = await tableDef.Keys.AddKeyAsync(key).ConfigureAwait(false);

            var memStream = new MemoryStream();

            try
            {
                using (var bw = new BinaryWriter(memStream))
                {
                    Helper.Save(actualType, instance, bw, cache, true);

                    bw.Flush();

                    if (_byteInterceptorList.Count > 0)
                    {
                        var bytes = memStream.ToArray();

                        bytes = _byteInterceptorList.Aggregate(bytes,
                                                               (current, byteInterceptor) =>
                                                               byteInterceptor.Save(current));

                        memStream = new MemoryStream(bytes);
                    }

                    memStream.Seek(0, SeekOrigin.Begin);

                    await Driver.SaveAsync(tableType, keyIndex, memStream.ToArray()).ConfigureAwait(false);
                }
            }
            finally
            {
                memStream.Flush();
                memStream.Dispose();
            }

            // update the indexes
            foreach (var index in tableDef.Indexes.Values)
            {
                await index.AddIndexAsync(instance, key).ConfigureAwait(false);
            }

            // call post-save triggers
            foreach (var trigger in _TriggerList(tableType))
            {
                trigger.AfterSave(actualType, instance);
            }

            _RaiseOperation(SterlingOperation.Save, tableType, key);

            return(key);
        }