/// <summary>
        /// Reload the content of a table into the cache
        /// </summary>
        /// <param name="database"></param>
        /// <param name="customerId"></param>
        /// <param name="table"></param>
        public void Reload(DatabaseContext database, int customerId, string table)
        {
            if (!_enable)
            {
                return;
            }

            // Check if the reload data is possible

            if (!_tick.ContainsKey(customerId) || !_tables.ContainsKey(table) || !_records.ContainsKey(customerId))
            {
                return;
            }

            // Clean up cache of the table

            Dictionary <string, Dictionary <int, Tuple <DSRecord, InformationRecord> > > currentCache = _records[customerId];

            if (!currentCache.ContainsKey(table))
            {
                return;
            }

            Debug($"Reloading table '{table}' into the cache for the customer '{customerId}' ...");

            Dictionary <int, Tuple <DSRecord, InformationRecord> > currentCacheTable = currentCache[table];

            currentCacheTable.Clear();

            // Update the content of the cache

            DSTable currentTable = _tables[table];

            foreach (Tuple <DSRecord, InformationRecord> record in currentTable.ReadRecords(database, customerId))
            {
                currentCacheTable[record.Item1.Id] = record;
            }

            Info($"[{customerId}] {currentCacheTable.Count} records read into the table '{table}'");

            GC.Collect();
        }
Example #2
0
        /// <summary>
        /// Build the schema by introspection (tables, columns and properties)
        /// </summary>
        /// <param name="schema">Type of DbContext</param>
        /// <param name="request"></param>
        public DSDatabase(Type schema, IDSRequest request)
        {
            Schema   = schema;
            Tables   = new Dictionary <string, DSTable>();
            _request = request;

            if (schema.IsSubclassOf(typeof(DbContext)))
            {
                // Each table is described by a DbSet<> object

                foreach (PropertyInfo property in schema.GetProperties())
                {
                    // Only DbSet<X> contains a table

                    if (!property.PropertyType.IsGenericType || property.PropertyType.GetGenericTypeDefinition() != typeof(DbSet <>))
                    {
                        continue;
                    }

                    // Ignore private, protected tables or properties started with "_"

                    if (property.Name.StartsWith("_") || property.PropertyType.IsNotPublic)
                    {
                        continue;
                    }

                    // Ignore record not inheritence of DSRecord

                    if (!property.PropertyType.GetGenericArguments().First().IsSubclassOf(typeof(DSRecord)))
                    {
                        continue;
                    }

                    DSTable table = new DSTable(this, property, property.PropertyType.GetGenericArguments().First());
                    Tables[table.Name] = table;
                }
            }
        }
        /// <summary>
        /// Check if the last tick loaded is different, and only load differences ...
        /// </summary>
        /// <param name="database"></param>
        /// <param name="customerId"></param>
        /// <param name="getDatabase"></param>
        public void UpdateCache(DatabaseContext database, int customerId, FunctionGetDatabase getDatabase)
        {
            if (!_enable)
            {
                return;
            }

            // Check if the customer is currently loaded

            if (!_tick.ContainsKey(customerId))
            {
                Initialize(database, customerId, getDatabase);
            }

            // the current customer is available

            Lock(customerId); // lock critical section

            // If the tick into the cache is not the same as the current one ... update the cache manager

            int currentTick  = GetTick(database, customerId);
            int previousTick = _tick[customerId];

            if (currentTick <= previousTick)
            {
                Unlock(customerId); // unlock critical section
                return;
            }

            Debug($"[{customerId}] Updating cache between {previousTick} and {currentTick} ...");
            int nbUpdates = 0;

            try
            {
                // Load all records between the last tick and the new one (only for request successfully executed)

                DSTable currentTable = null;
                Dictionary <int, Tuple <DSRecord, InformationRecord> > currentContent = null;
                foreach (RequestTableRecord request in database._RequestTable.Where(r => r.CustomerId == customerId &&
                                                                                    r.Id != null &&
                                                                                    previousTick < r.Tick && r.Tick <= currentTick).ToList().OrderBy(r => r.Table).ThenBy(r => r.Id))
                {
                    // new table ?

                    if (currentTable == null || !currentTable.Name.Equals(request.Table))
                    {
                        currentTable   = null;
                        currentContent = null;
                        if (!_tables.ContainsKey(request.Table))
                        {
                            if (IsVerbose())
                            {
                                Verbose($"[{customerId}] The table '{request.Table}' doesn't exist into the cache. May be, the table doesn't exist into the schemas");
                            }
                            continue;
                        }
                        currentTable   = _tables[request.Table];
                        currentContent = _records[customerId][request.Table];
                    }

                    // read the current record

                    Tuple <DSRecord, InformationRecord> currentRecord = currentTable.GetRecord(database, request.Id.Value, customerId);
                    if (currentRecord == null)
                    {
                        continue;
                    }

                    // Update the cache

                    currentContent[request.Id.Value] = currentRecord;
                    nbUpdates++;
                }

                _tick[customerId] = currentTick;
            }
            catch (System.Exception ex)
            {
                Exception($"[{customerId}] Unable to update the cache", ex);
            }

            Info($"[{customerId}] {nbUpdates} records loaded between {previousTick} and {currentTick}");

            Unlock(customerId); // Unlock the critical section
        }