/// <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)); } }
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 => 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);
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("BaseDatabaseInstance_Save_Save_suppressed_by_trigger", trigger.GetType()); } var key = (TKey)tableDef.FetchKeyFromInstance(instance); int keyIndex; 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); }
/// <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)); } }