Skip to content

Commit

Permalink
Custom Report - Add option to script report
Browse files Browse the repository at this point in the history
Add option to script report.  Script out the associated stored procedure & metadata to make it easy to share custom reports.
Updated icons on config menu and added descriptions.
#252
  • Loading branch information
DavidWiseman committed Oct 26, 2023
1 parent af47c41 commit 4d82ba9
Show file tree
Hide file tree
Showing 8 changed files with 150 additions and 45 deletions.
12 changes: 8 additions & 4 deletions DBADashGUI/CustomReports/CustomReport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public class CustomReport
/// </summary>
[JsonIgnore]
public IEnumerable<Param> UserParams => Params == null ? new List<Param>() : Params.ParamList.Where(p =>
!(new string[] { "@INSTANCEIDS", "@INSTANCEID", "@DATABASEID", "@FROMDATE", "@TODATE" }).Contains(p.ParamName.ToUpper()));
!(new string[] { "@INSTANCEIDS", "@INSTANCEID", "@DATABASEID", "@FROMDATE", "@TODATE" }).Contains(p.ParamName.ToUpper()));

[JsonIgnore]
public bool IsRootLevel => Params != null && Params.ParamList.Any(p => p.ParamName.ToUpper() == "@INSTANCEIDS");
Expand All @@ -57,15 +57,15 @@ public class CustomReport
/// </summary>
[JsonIgnore]
public bool TimeFilterSupported => Params.ParamList.Any(p =>
p.ParamName.Equals("@FromDate", StringComparison.CurrentCultureIgnoreCase) ||
p.ParamName.Equals("@ToDate", StringComparison.CurrentCultureIgnoreCase));
p.ParamName.Equals("@FromDate", StringComparison.CurrentCultureIgnoreCase) ||
p.ParamName.Equals("@ToDate", StringComparison.CurrentCultureIgnoreCase));

/// <summary>
/// Save customizations
/// </summary>
public void Update()
{
var meta = JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore });
var meta = Serialize();
using var cn = new SqlConnection(Common.ConnectionString);
using var cmd = new SqlCommand("dbo.CustomReport_Upd", cn) { CommandType = CommandType.StoredProcedure };
cmd.Parameters.AddWithValue("ProcedureName", ProcedureName);
Expand All @@ -75,6 +75,10 @@ public void Update()
cmd.ExecuteNonQuery();
}

public string Serialize() => JsonConvert.SerializeObject(this, Formatting.Indented,
new JsonSerializerSettings
{ NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore });

/// <summary>
/// Convert list of parameters for the report to list of CustomSqlParameters
/// </summary>
Expand Down
42 changes: 31 additions & 11 deletions DBADashGUI/CustomReports/CustomReportView.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

65 changes: 63 additions & 2 deletions DBADashGUI/CustomReports/CustomReportView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using DocumentFormat.OpenXml.Office2016.Drawing.Command;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Common;

namespace DBADashGUI.CustomReports
{
Expand Down Expand Up @@ -214,7 +218,7 @@ private void LoadResultsCombo()
{
cboResults.Items.Add(report.CustomReportResults[i].ResultName);
}
renameResultsetToolStripMenuItem.Visible = cboResults.Items.Count > 1;
renameResultSetToolStripMenuItem.Visible = cboResults.Items.Count > 1;
cboResults.Visible = cboResults.Items.Count > 1;
lblSelectResults.Visible = cboResults.Items.Count > 1;
cboResults.SelectedIndex = selectedTableIndex < cboResults.Items.Count ? selectedTableIndex : 0;
Expand Down Expand Up @@ -403,12 +407,16 @@ private void TsCols_Click(object sender, EventArgs e)

private void SaveLayoutToolStripMenuItem_Click(object sender, EventArgs e)
{
if (MessageBox.Show("Save Layout (column visibility, order and size)?", "Save", MessageBoxButtons.YesNo,
MessageBoxIcon.Question) != DialogResult.Yes) return;
report.CustomReportResults[selectedTableIndex].ColumnLayout = dgv.GetColumnLayout();
report.Update();
}

private void ResetLayoutToolStripMenuItem_Click(object sender, EventArgs e)
{
if (MessageBox.Show("Reset Layout (column visibility, order and size)?", "Reset", MessageBoxButtons.YesNo,
MessageBoxIcon.Question) != DialogResult.Yes) return;
report.CustomReportResults[selectedTableIndex].ColumnLayout = new();
report.Update();
dgv.Columns.Clear();
Expand All @@ -423,7 +431,7 @@ private void CboResults_SelectedIndexChanged(object sender, EventArgs e)
ShowTable();
}

private void RenameResultsetToolStripMenuItem_Click(object sender, EventArgs e)
private void RenameResultSetToolStripMenuItem_Click(object sender, EventArgs e)
{
var name = cboResults.SelectedItem.ToString();
if (CommonShared.ShowInputDialog(ref name, "Enter name") == DialogResult.OK)
Expand All @@ -446,5 +454,58 @@ private void SetDescriptionToolStripMenuItem_Click(object sender, EventArgs e)
statusStrip1.Visible = !string.IsNullOrEmpty(report.Description);
lblDescription.Visible = !string.IsNullOrEmpty(report.Description);
}

private void ScriptReportToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
ScriptReport();
}
catch (Exception ex)
{
MessageBox.Show("Error scripting report:" + ex.Message, "Error", MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}

private void ScriptReport()
{
using var cn = new SqlConnection(Common.ConnectionString);
var serverCn = new ServerConnection(cn);
var server = new Server(serverCn);
var db = server.Databases[cn.Database];

var proc = db.StoredProcedures[report.ProcedureName, report.SchemaName];

if (proc != null)
{
var options = new ScriptingOptions() { ScriptForCreateOrAlter = true, ScriptBatchTerminator = true, EnforceScriptingOptions = true }; /* EnforceScriptingOptions = true is required to generate CREATE OR ALTER */

var parts = proc.Script(options);
var sb = new StringBuilder();
sb.AppendFormat("/*\n\t{0}\n\t{1}\n\n\tCustom report for DBA Dash.\n\thttp://dbadash.com\n\tGenerated: {2:yyyy-MM-dd HH:mm:ss} \n*/\n\n",
report.ReportName.Replace("*/", ""), report.Description.Replace("*/", ""), DateTime.Now);
foreach (var part in parts)
{
sb.AppendLine(part);
sb.AppendLine("GO");
}

var meta = report.Serialize();
sb.AppendLine();
sb.AppendLine("/* Report customizations in GUI */");
sb.AppendFormat("DELETE dbo.CustomReport\nWHERE SchemaName = '{0}'\nAND ProcedureName = '{1}'\n\n", report.SchemaName.SqlSingleQuote(), report.ProcedureName.SqlSingleQuote());
sb.AppendLine("INSERT INTO dbo.CustomReport(SchemaName,ProcedureName,MetaData)");
sb.AppendFormat("VALUES('{0}','{1}','{2}')", report.SchemaName.SqlSingleQuote(),
report.ProcedureName.SqlSingleQuote(), meta.SqlSingleQuote());

var frm = new CodeViewer() { SQL = sb.ToString() };
frm.ShowDialog();
}
else
{
MessageBox.Show($"Unable to find procedure {report.QualifiedProcedureName}", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
}
}
1 change: 1 addition & 0 deletions DBADashGUI/DBADashGUI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@
<PackageReference Include="LiveCharts.WinForms" Version="0.9.7.1" />
<PackageReference Include="LiveCharts.Wpf" Version="0.9.7" />
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="Microsoft.SqlServer.SqlManagementObjects" Version="170.18.0" />
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.2088.41" />
<PackageReference Include="SpreadsheetLight" Version="3.5.0" />
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
Expand Down
7 changes: 7 additions & 0 deletions DBADashGUI/ExtensionMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -380,5 +380,12 @@ public static SqlParameter Clone(this SqlParameter original)
SourceVersion = original.SourceVersion
};
}

/// <summary>
/// Replace single ' quote with two single quotes ''. Only to be used where input can't be parameterized
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static string SqlSingleQuote(this string value) => value.Replace("'", "''");
}
}
9 changes: 9 additions & 0 deletions DBADashGUI/Properties/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 4d82ba9

Please sign in to comment.