Beispiel #1
0
        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);
        }
Beispiel #2
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 object Load(Type type, object key, CycleCache cache)
        {
            var newType    = type;
            var assignable = false;
            var keyIndex   = -1;

            if (!this.TableDefinitions.ContainsKey(type))
            {
                // check if type is a base type
                foreach (var t in this.TableDefinitions.Keys.Where(type.IsAssignableFrom))
                {
                    assignable = true;

                    var tableDefinition = this.TableDefinitions[t];

                    lock (tableDefinition)
                    {
                        keyIndex = tableDefinition.Keys.GetIndexForKey(key);
                    }

                    if (keyIndex < 0)
                    {
                        continue;
                    }

                    newType = t;
                    break;
                }
            }
            else
            {
                var tableDefinition = this.TableDefinitions[newType];
                lock (tableDefinition)
                {
                    keyIndex = tableDefinition.Keys.GetIndexForKey(key);
                }
            }

            if (!assignable)
            {
                if (!this.TableDefinitions.ContainsKey(type))
                {
                    throw new SterlingTableNotFoundException(type, this.Name);
                }
            }

            if (keyIndex < 0)
            {
                return(null);
            }

            var obj = GetInstance(newType, key, keyIndex, cache);

            _RaiseOperation(SterlingOperation.Load, newType, key);
            return(obj);
        }
Beispiel #3
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 bool Save(Type actualType, Type tableType, object instance, CycleCache cache, out object key)
        {
            bool retVal;

            if (retVal = SaveInternal(actualType, tableType, instance, cache, out key))
            {
                _RaiseOperation(SterlingOperation.Save, tableType, key, instance);
            }
            return(retVal);
        }
Beispiel #4
0
        /// <summary>
        ///     Gets an instance by key
        /// </summary>
        private object GetInstance(Type type, object key, int keyIndex, CycleCache cache)
        {
            var obj = cache.CheckKey(type, key);

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

            if (keyIndex < 0)
            {
                return(null);
            }

            obj = this.Driver.Load(type, key, keyIndex, cache);

            return(obj);
        }
Beispiel #5
0
 public abstract object Load(Type type, object key, int keyIndex, CycleCache cache);
Beispiel #6
0
 public abstract void Save(Type actualType, Type tableType, object instance, int keyIndex, CycleCache cache);
Beispiel #7
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 object Load(Type type, object key, CycleCache cache)
        {
            var newType    = type;
            var assignable = false;
            var keyIndex   = -1;

            if (!TableDefinitions.ContainsKey(type))
            {
                // check if type is a base type
                foreach (var t in TableDefinitions.Keys.Where(type.IsAssignableFrom))
                {
                    assignable = true;

                    lock (TableDefinitions[t])
                    {
                        keyIndex = TableDefinitions[t].Keys.GetIndexForKey(key);
                    }

                    if (keyIndex < 0)
                    {
                        continue;
                    }

                    newType = t;
                    break;
                }
            }
            else
            {
                lock (TableDefinitions[newType])
                {
                    keyIndex = TableDefinitions[newType].Keys.GetIndexForKey(key);
                }
            }

            if (!assignable)
            {
                if (!TableDefinitions.ContainsKey(type))
                {
                    throw new SterlingTableNotFoundException(type, Name);
                }
            }

            if (keyIndex < 0)
            {
                return(null);
            }

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

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

            BinaryReader br        = null;
            MemoryStream memStream = null;

            try
            {
                br = Driver.Load(newType, keyIndex);

                var serializationHelper = new SerializationHelper(this, Serializer, SterlingFactory.GetLogger(),
                                                                  s => Driver.GetTypeIndex(s),
                                                                  i => Driver.GetTypeAtIndex(i));
                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.Close();
                    br = new BinaryReader(memStream);
                }
                obj = serializationHelper.Load(newType, key, br, cache);
            }
            finally
            {
                if (br != null)
                {
                    br.Close();
                }

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

            _RaiseOperation(SterlingOperation.Load, newType, key);
            return(obj);
        }
Beispiel #8
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 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);
        }