Esempio n. 1
0
 /// <summary>
 ///     Load it without knowledge of the key type
 /// </summary>
 /// <param name="type">The type to load</param>
 /// <param name="key">The key</param>
 /// <param name="cache">Cache queue</param>
 /// <returns>The instance</returns>
 public async Task <object> LoadAsync(Type type, object key, CycleCache cache)
 {
     using (await LockAsync().ConfigureAwait(false))
     {
         return(await _Load <object>(type, key, cache).ConfigureAwait(false));
     }
 }
Esempio n. 2
0
        internal async Task <TResult> _Load <TResult>(Type type, object key, CycleCache cache) where TResult : new()
        {
            Interlocked.Increment(ref _taskCount);

            try
            {
                var newType  = type;
                var keyIndex = -1;

                ITableDefinition tableDef = null;

                tableDef = TableDefinitions.SingleOrDefault(pair => pair.Key == type).Value;

                if (tableDef == null)
                {
                    foreach (var subDef in TableDefinitions.Where(pair => this.Database.Engine.PlatformAdapter.IsAssignableFrom(type, pair.Key))
                             .Select(pair => pair.Value))
                    {
                        keyIndex = await subDef.Keys.GetIndexForKeyAsync(key).ConfigureAwait(false);

                        if (keyIndex < 0)
                        {
                            continue;
                        }

                        newType  = subDef.TableType;
                        tableDef = subDef;
                        break;
                    }

                    if (tableDef == null)
                    {
                        throw new SterlingTableNotFoundException(type, Name);
                    }
                }
                else
                {
                    keyIndex = await tableDef.Keys.GetIndexForKeyAsync(key).ConfigureAwait(false);
                }

                if (keyIndex < 0)
                {
                    return(default(TResult));
                }

                var obj = (TResult)cache.CheckKey(newType, key);

                if (obj != null)
                {
                    return(obj);
                }

                BinaryReader br        = null;
                MemoryStream memStream = null;

                try
                {
                    br = await Driver.LoadAsync(newType, keyIndex).ConfigureAwait(false);

                    if (_byteInterceptorList.Count > 0)
                    {
                        var bytes = br.ReadBytes((int)br.BaseStream.Length);

                        bytes = _byteInterceptorList.ToArray().Reverse().Aggregate(bytes,
                                                                                   (current, byteInterceptor) =>
                                                                                   byteInterceptor.Load(current));

                        memStream = new MemoryStream(bytes);

                        br.Dispose();

                        br = new BinaryReader(memStream);
                    }

                    obj = (TResult)Helper.Load(newType, key, br, cache);
                }
                finally
                {
                    if (br != null)
                    {
                        br.Dispose();
                    }

                    if (memStream != null)
                    {
                        memStream.Flush();
                        memStream.Dispose();
                    }
                }

                _RaiseOperation(SterlingOperation.Load, newType, key);

                return(obj);
            }
            finally
            {
                Interlocked.Decrement(ref _taskCount);
            }
        }
Esempio n. 3
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);
        }
Esempio n. 4
0
 /// <summary>
 ///     Save when key is not known
 /// </summary>
 /// <param name="actualType">The type of instance to save</param>
 /// <param name="tableType">The table type to save to</param>
 /// <param name="instance">The instance</param>
 /// <param name="cache">Cycle cache</param>
 /// <returns>The key</returns>
 public async Task <object> SaveAsync(Type actualType, Type tableType, object instance, CycleCache cache)
 {
     using (await LockAsync().ConfigureAwait(false))
     {
         return(await _Save <object>(actualType, tableType, instance, cache).ConfigureAwait(false));
     }
 }