public static void Render(LogStatsDal dal, LiveViewOptions options, LayoutStyle layoutStyle)
        {
            Initialize();

            List <DbccLogInfoItem> vlfs;

            try
            {
                vlfs = dal.ReadDbccLogInfo(null, true, options.ForceDbccLoginfo);
            }
            catch (Exception ex)
            {
                try
                {
                    RenderException(options, ex);
                }
                catch
                {
                    // Intentionally swallow any exceptions.
                }
                return;
            }

            using (Bitmap bitmap = CreateImage(vlfs, options, layoutStyle))
            {
                if (options.DisplaySurface.InvokeRequired)
                {
                    options.DisplaySurface.Invoke(new Action <LiveViewOptions, Bitmap>(SetImage), options, bitmap);
                }
                else
                {
                    SetImage(options, bitmap);
                }
            }

            long   totalLogSize = vlfs.Sum(v => v.FileSize);
            string displaySize  = Utilities.FriendlySize(totalLogSize);

            DatabaseInfo dbInfo = dal.GetCurrentDatabaseInfo();

            string statusMessage = $"Instance: {dal.InstanceName}; Database: {dal.DatabaseName}; Recovery model: {dbInfo.RecoveryModelDescription}; Log size: {displaySize}; VLFs: {vlfs.Count}; Wait: {dbInfo.LogReuseWaitDescription}; Last refresh: {DateTime.Now:HH:mm:ss}";

            ToolStrip toolStrip = options.StatusLabel.GetCurrentParent();

            if (toolStrip != null)
            {
                if (toolStrip.InvokeRequired)
                {
                    toolStrip.Invoke(new Action <LiveViewOptions, string>(SetStatus), options, statusMessage);
                }
                else
                {
                    SetStatus(options, statusMessage);
                }
            }
        }
        public LiveViewVisualizer(LiveViewOptions options, LayoutStyle layoutStyle)
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            _options     = options;
            _layoutStyle = layoutStyle;
            _isCancelled = false;
            _dal         = new LogStatsDal(options.Connection);
        }
        public LiveViewOptionsForm(ApplicationSqlConnection connection)
        {
            InitializeComponent();

            _options = VisualizerSettings.Instance.LiveViewOptions;
            if (_options == null)
            {
                _options = new LiveViewOptions();
            }

            if (connection != null)
            {
                _options.Connection = connection;
            }
        }
        private static Bitmap CreateImage(List <DbccLogInfoItem> vlfs, LiveViewOptions options, LayoutStyle layoutStyle)
        {
            int width  = Math.Max(options.DisplaySurface.Width, 1);
            int height = Math.Max(options.DisplaySurface.Height, 1);

            Bitmap bitmap = new Bitmap(width, height);

            if (layoutStyle == LayoutStyle.Logical)
            {
                // If logical style is requested, make a copy of the VLF list and sort by the VLF number.
                vlfs = new List <DbccLogInfoItem>(vlfs);
                vlfs.Sort(new VlfComparer());
            }

            using (Graphics graphics = Graphics.FromImage(bitmap))
            {
                double scale = GenerateBlocks(vlfs, options, graphics, 1.0, true);
                GenerateBlocks(vlfs, options, graphics, scale, false);
            }

            return(bitmap);
        }
        public static void RenderException(LiveViewOptions options, Exception ex)
        {
            using (Bitmap bitmap = new Bitmap(options.DisplaySurface.Width, options.DisplaySurface.Height))
            {
                using (Graphics graphics = Graphics.FromImage(bitmap))
                {
                    graphics.FillRectangle(Brushes.White, 0, 0, options.DisplaySurface.Width, options.DisplaySurface.Height);
                    string fullMessage = ex.Message;
                    Font   font        = new Font("Times New Roman", 10);

                    List <MessageInfo> messages = SplitMessageToFitWindow(fullMessage, font, graphics, options.DisplaySurface.Width);
                    float totalHeight           = messages.Sum(m => m.Height);
                    float top = (options.DisplaySurface.Height - totalHeight) / 2;

                    foreach (MessageInfo messageInfo in messages)
                    {
                        SizeF      size      = graphics.MeasureString(messageInfo.Message, font);
                        RectangleF rectangle = new RectangleF(
                            (options.DisplaySurface.Width - size.Width) / 2,
                            top,
                            size.Width,
                            size.Height);
                        graphics.DrawString(messageInfo.Message, font, Brushes.Black, rectangle);

                        top += messageInfo.Height;
                    }
                }

                if (options.DisplaySurface.InvokeRequired)
                {
                    options.DisplaySurface.Invoke(new Action <LiveViewOptions, Bitmap>(SetImage), options, bitmap);
                }
                else
                {
                    SetImage(options, bitmap);
                }
            }
        }
        private static double GenerateBlocks(List <DbccLogInfoItem> vlfs, LiveViewOptions options, Graphics graphics, double verticalScale, bool simulateOnly)
        {
            // Current VLF is the active VLF (status = 2) with the largest VLF Number
            DbccLogInfoItem currentVlf = vlfs.Where(v => v.Status == 2).OrderByDescending(v => v.VirtualLogFileNumber).FirstOrDefault();

            // Get total VLF size;
            long totalVlfSize = vlfs.Sum(v => v.FileSize);

            int width  = options.DisplaySurface.Width - _leftMargin - _rightMargin;
            int height = options.DisplaySurface.Height - _topMargin - _bottomMargin;

            int horizontalBlocks = (int)Math.Ceiling(Math.Sqrt(vlfs.Count));
            int verticalBlocks   = horizontalBlocks;

            int averageBlockWidth = (width - (horizontalBlocks - 1) * _horizontalSpacing) / horizontalBlocks;
            int blockHeight       = (int)((height - (verticalBlocks - 1) * _verticalSpacing) / verticalBlocks * verticalScale);

            int blockLeft   = _leftMargin;
            int blockTop    = _topMargin;
            int blockBottom = 0;

            Font font = null;

            if (simulateOnly == false)
            {
                font = new Font(VisualizerSettings.Instance.VlfFontName, VisualizerSettings.Instance.VlfFontSize.Value);
            }

            for (int vlfIndex = 0; vlfIndex < vlfs.Count; vlfIndex++)
            {
                DbccLogInfoItem vlf        = vlfs[vlfIndex];
                int             blockWidth = (int)(averageBlockWidth * (vlf.FileSize * 1.0 / totalVlfSize * vlfs.Count));

                int blockRight = blockLeft + blockWidth;
                blockBottom = blockTop + blockHeight;
                if (blockRight > options.DisplaySurface.Width - _rightMargin)
                {
                    blockLeft = _leftMargin;
                    blockTop += blockHeight + _verticalSpacing;

                    blockRight  = blockLeft + blockWidth;
                    blockBottom = blockTop + blockHeight;
                }

                if (simulateOnly == false)
                {
                    Brush blockBrush = vlf.Status == 2 ? ((vlf == currentVlf) ? _currentVlfBrush : _activeVlfBrush) : _inactiveVlfBrush;
                    graphics.FillRectangle(blockBrush, blockLeft, blockTop, blockWidth, blockHeight);

                    if (options.ShowVlfNumbers &&
                        vlf.VirtualLogFileNumber > 0)
                    {
                        string vlfNumber = vlf.VirtualLogFileNumber.ToString();
                        SizeF  textSize  = graphics.MeasureString(vlfNumber, font);
                        if (textSize.Width < blockWidth &&
                            textSize.Height < blockHeight)
                        {
                            RectangleF textRectangle = new RectangleF(
                                blockLeft + blockWidth * 0.5f - textSize.Width * 0.5f,
                                blockTop + blockHeight * 0.5f - textSize.Height * 0.5f,
                                textSize.Width,
                                textSize.Height);
                            graphics.DrawString(vlfNumber, font, _vlfFontBrush, textRectangle);
                        }
                    }
                }

                blockLeft += blockWidth + _horizontalSpacing;
            }

            double scale = height * 1.0 / (blockBottom - _topMargin);

            return(scale);
        }
 private static void SetStatus(LiveViewOptions options, string message)
 {
     options.StatusLabel.Text = message;
 }
 private static void SetImage(LiveViewOptions options, Bitmap bitmap)
 {
     options.DisplaySurface.Image = bitmap.Clone() as Bitmap;
 }