/// <summary>
        /// Validate database size - check how many records are stored
        /// in database and how much records need space.
        /// If space or number of records are invalid
        /// database will remove old reports
        /// </summary>
        private bool ValidateDatabaseSize()
        {
            //check how many records are stored in database
            //remove in case when we want to store one more than expected number
            //If record count == 0 then we ignore this condition
            var noMoreSpaceForReport = ReachedMaximumNumberOfRecords();

            //check database size. If database size == 0 then we ignore this condition
            //remove all records till database use enough space
            var noMoreSpace = ReachedDiskSpaceLimit();

            if (noMoreSpaceForReport || noMoreSpace)
            {
                //if your database is entry or every record is locked
                //deletePolicyRetry avoid infinity loop
                int deletePolicyRetry = 5;
                while (ReachedDiskSpaceLimit() || ReachedMaximumNumberOfRecords())
                {
                    var lastRecord = BacktraceDatabaseContext.LastOrDefault();
                    if (lastRecord != null)
                    {
                        BacktraceDatabaseContext.Delete(lastRecord);
                        BacktraceDatabaseFileContext.Delete(lastRecord);
                    }
                    deletePolicyRetry--;
                    if (deletePolicyRetry == 0)
                    {
                        break;
                    }
                }
                return(deletePolicyRetry != 0);
            }
            return(true);
        }
        /// <summary>
        /// Load all records stored in database path
        /// </summary>
        protected virtual void LoadReports()
        {
            if (!Enable)
            {
                return;
            }
            var files = BacktraceDatabaseFileContext.GetRecords();

            foreach (var file in files)
            {
                var record = BacktraceDatabaseRecord.ReadFromFile(file);
                if (record == null)
                {
                    continue;
                }
                if (!BacktraceDatabaseFileContext.IsValidRecord(record))
                {
                    BacktraceDatabaseFileContext.Delete(record);
                    continue;
                }
                BacktraceDatabaseContext.Add(record);
                ValidateDatabaseSize();
                record.Unlock();
            }
        }
 /// <summary>
 /// Delete single record from database
 /// </summary>
 /// <param name="record">Record to delete</param>
 public void Delete(BacktraceDatabaseRecord record)
 {
     if (BacktraceDatabaseContext != null)
     {
         BacktraceDatabaseContext.Delete(record);
     }
     if (BacktraceDatabaseFileContext != null)
     {
         BacktraceDatabaseFileContext.Delete(record);
     }
 }
        private void IncrementBatchRetry()
        {
            var data = BacktraceDatabaseContext.GetRecordsToDelete();

            BacktraceDatabaseContext.IncrementBatchRetry();
            if (data != null && data.Count() != 0)
            {
                foreach (var item in data)
                {
                    BacktraceDatabaseFileContext.Delete(item);
                }
            }
        }
        /// <summary>
        /// Add new report to BacktraceDatabase
        /// </summary>
        public BacktraceDatabaseRecord Add(BacktraceData data, bool @lock = true)
        {
            if (data == null || !Enable)
            {
                return(null);
            }
            //remove old reports (if database is full)
            //and check database health state
            var validationResult = ValidateDatabaseSize();

            if (!validationResult)
            {
                return(null);
            }

            // validate if record already exists in the database object
            var hash = BacktraceDatabaseContext.GetHash(data);

            if (!string.IsNullOrEmpty(hash))
            {
                var existingRecord = BacktraceDatabaseContext.GetRecordByHash(hash);
                if (existingRecord != null)
                {
                    BacktraceDatabaseContext.AddDuplicate(existingRecord);
                    return(existingRecord);
                }
            }

            //add built-in attachments
            var attachments = BacktraceDatabaseFileContext.GenerateRecordAttachments(data);

            for (int attachmentIndex = 0; attachmentIndex < attachments.Count(); attachmentIndex++)
            {
                if (!string.IsNullOrEmpty(attachments.ElementAt(attachmentIndex)))
                {
                    data.Attachments.Add(attachments.ElementAt(attachmentIndex));
                }
            }
            // add to fresh new record breadcrumb attachment
            if (Breadcrumbs != null)
            {
                data.Attachments.Add(Breadcrumbs.GetBreadcrumbLogPath());
                data.Attributes.Attributes["breadcrumbs.lastId"] = Breadcrumbs.BreadcrumbId().ToString("F0", CultureInfo.InvariantCulture);
            }

            // now we now we're adding new unique report to database
            var record = new BacktraceDatabaseRecord(data)
            {
                Hash = hash
            };

            // save record on the hard drive and add it to database context
            var saveResult = BacktraceDatabaseFileContext.Save(record);

            if (!saveResult)
            {
                // file context won't remove json object that wasn't stored in the previous method
                // but will clean up attachments associated with this record.
                BacktraceDatabaseFileContext.Delete(record);
                return(null);
            }

            BacktraceDatabaseContext.Add(record);
            if (!@lock)
            {
                record.Unlock();
            }

            return(record);
        }