bool SaveInternal(Type actualType, Type tableType, object instance, CycleCache cache, out object key) { if (!this.TableDefinitions.TryGetValue(tableType, out ITableDefinition tableDefinition)) { throw new SterlingTableNotFoundException(instance.GetType(), this.Name); } if (!tableDefinition.IsDirty(instance)) { key = tableDefinition.FetchKeyFromInstance(instance); return(false); } // call any before save triggers 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()); } key = tableDefinition.FetchKeyFromInstance(instance); int keyIndex; if (cache.Check(instance)) { return(false); } lock (tableDefinition) { if (cache.Check(instance)) { return(false); } cache.Add(tableType, instance, key); keyIndex = tableDefinition.Keys.AddKey(key); } this.Driver.Save(actualType, tableType, instance, keyIndex, cache); // update the indexes foreach (var index in tableDefinition.Indexes.Values) { index.AddIndex(instance, key); } // call post-save triggers foreach (var trigger in _TriggerList(tableType)) { trigger.AfterSave(actualType, instance); } return(true); }
/// <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 object Save(Type actualType, Type tableType, object instance, CycleCache cache) { if (!TableDefinitions.ContainsKey(tableType)) { throw new SterlingTableNotFoundException(instance.GetType(), Name); } if (!TableDefinitions[tableType].IsDirty(instance)) { return(TableDefinitions[tableType].FetchKeyFromInstance(instance)); } // call any before save triggers 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 = TableDefinitions[tableType].FetchKeyFromInstance(instance); int keyIndex; if (cache.Check(instance)) { return(key); } lock (TableDefinitions[tableType]) { if (cache.Check(instance)) { return(key); } cache.Add(tableType, instance, key); keyIndex = TableDefinitions[tableType].Keys.AddKey(key); } 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.GetBuffer(); bytes = _byteInterceptorList.Aggregate(bytes, (current, byteInterceptor) => byteInterceptor.Save(current)); memStream = new MemoryStream(bytes); } memStream.Seek(0, SeekOrigin.Begin); Driver.Save(tableType, keyIndex, memStream.ToArray()); } } finally { memStream.Flush(); memStream.Close(); } // update the indexes foreach (var index in TableDefinitions[tableType].Indexes.Values) { index.AddIndex(instance, key); } // call post-save triggers foreach (var trigger in _TriggerList(tableType)) { trigger.AfterSave(actualType, instance); } _RaiseOperation(SterlingOperation.Save, tableType, key); return(key); }