From c571604aa5b843b8ea7a2a155d422af9dae7d913 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicen=C3=A7=20Masanas?= Date: Sat, 28 Sep 2013 09:45:26 +0200 Subject: [PATCH 1/2] DNN-3706 Better management for sql errors Previously only errors for scripts were displayed. Added handling of messages for standard 'selects' --- DNN Platform/Library/Data/DataProvider.cs | Bin 368172 -> 368470 bytes DNN Platform/Library/Data/SqlDataProvider.cs | 17 ++++++++++++++--- Website/DesktopModules/Admin/SQL/SQL.ascx.cs | 9 +++++++-- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/DNN Platform/Library/Data/DataProvider.cs b/DNN Platform/Library/Data/DataProvider.cs index 9989547519ef1983d10bf4f0a70cb85e13dd0373..d5c1c5fc19fa0385f22ffab212cd13090844782d 100644 GIT binary patch delta 97 zcmZ3pN9@`@u?-D+(>GjW5tzI|M`7|G-5O3E1_g$EhEj%-=?{gNgeM<}5u1EKS7vfU xflc!Tz4i-wj6lq^{em8Inf^2xpgxd-ka)T23fmdw+Ee0~ftY1`N*wD6djLsGBya!# delta 44 xcmcb%Pi)N|u?-D+ljU>*nz!k(); @@ -194,11 +195,15 @@ protected void OnExecuteClick(object sender, EventArgs e) else { UI.Skins.Skin.AddModuleMessage(this, Localization.GetString("QueryError", LocalResourceFile), ModuleMessage.ModuleMessageType.RedError); + errorRow.Visible = true; + txtError.Text = errorMessage; } } catch (SqlException sqlException) { - UI.Skins.Skin.AddModuleMessage(this, sqlException.Message, ModuleMessage.ModuleMessageType.RedError); + UI.Skins.Skin.AddModuleMessage(this, Localization.GetString("QueryError", LocalResourceFile), ModuleMessage.ModuleMessageType.RedError); + errorRow.Visible = true; + txtError.Text = sqlException.Message; return; } } From ddd6c3f431b54389c9d6ba54967673b78327eb3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicen=C3=A7=20Masanas?= Date: Tue, 1 Oct 2013 11:55:36 +0200 Subject: [PATCH 2/2] DNN-3191 Enhancements to the SQL Module DNN-3706 Better management for sql errors DNN-26286 SQL Results --- DNN Platform/Library/Data/DataProvider.cs | Bin 368470 -> 368402 bytes DNN Platform/Library/Data/SqlDataProvider.cs | 2 +- .../Library/DotNetNuke.Library.csproj | 2 + .../Modules/SQL/Components/SqlQuery.cs | 54 ++++ .../SQL/Components/SqlQueryController.cs | 100 ++++++ .../SQL/App_LocalResources/SQL.ascx.resx | 65 +++- Website/DesktopModules/Admin/SQL/SQL.ascx.cs | 296 ++++++++++++------ Website/DesktopModules/Admin/SQL/module.css | 5 +- .../SQL/plugins/clipboard/ZeroClipboard.swf | Bin 0 -> 1071 bytes .../SQL/plugins/clipboard/jquery.zclip.min.js | 12 + Website/DesktopModules/Admin/SQL/sql.ascx | 102 ++++-- Website/Licenses/ZeroClipboard (MIT).txt | 8 + Website/Licenses/zClip (MIT).txt | 10 + Website/Portals/_default/default.css | 4 +- .../SqlDataProvider/07.02.00.SqlDataProvider | 24 ++ 15 files changed, 544 insertions(+), 140 deletions(-) create mode 100644 DNN Platform/Library/Modules/SQL/Components/SqlQuery.cs create mode 100644 DNN Platform/Library/Modules/SQL/Components/SqlQueryController.cs create mode 100644 Website/DesktopModules/Admin/SQL/plugins/clipboard/ZeroClipboard.swf create mode 100644 Website/DesktopModules/Admin/SQL/plugins/clipboard/jquery.zclip.min.js create mode 100644 Website/Licenses/ZeroClipboard (MIT).txt create mode 100644 Website/Licenses/zClip (MIT).txt diff --git a/DNN Platform/Library/Data/DataProvider.cs b/DNN Platform/Library/Data/DataProvider.cs index d5c1c5fc19fa0385f22ffab212cd13090844782d..6d65812f1a0a068b2bc8d994bc46392a1bc60141 100644 GIT binary patch delta 29 jcmcb%Pi)dYv4$4L7N#xCI`QoV@ytNXvb`Xl^_e{Yv3CnW delta 46 zcmbQVPwd)0v4$4L7N#xCI`NYY#Q7$>=}Syj5|f)gA%ID)-7B6Mh*`FK#j~EU2LO5u B4> + + diff --git a/DNN Platform/Library/Modules/SQL/Components/SqlQuery.cs b/DNN Platform/Library/Modules/SQL/Components/SqlQuery.cs new file mode 100644 index 00000000000..94906399406 --- /dev/null +++ b/DNN Platform/Library/Modules/SQL/Components/SqlQuery.cs @@ -0,0 +1,54 @@ +#region Copyright +// +// DotNetNuke® - http://www.dotnetnuke.com +// Copyright (c) 2002-2013 +// by DotNetNuke Corporation +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +// documentation files (the "Software"), to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and +// to permit persons to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions +// of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +#endregion +#region Usings + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Text; +using System.Xml; + +using DotNetNuke.Common; +using DotNetNuke.Entities.Modules; +using DotNetNuke.Entities.Portals; +using DotNetNuke.Entities.Tabs; +using DotNetNuke.Services.Exceptions; +using DotNetNuke.ComponentModel.DataAnnotations; +using DotNetNuke.Entities; + +#endregion + +namespace DotNetNuke.Modules.SQL.Components +{ + [TableName("SQLQueries")] + [PrimaryKey("QueryId")] + public partial class SqlQuery + { + public int QueryId { get; set; } + public string Name { get; set; } + public string Query { get; set; } + public string ConnectionStringName { get; set; } + public int CreatedByUserId { get; set; } + public DateTime CreatedOnDate { get; set; } + public int LastModifiedByUserId { get; set; } + public DateTime LastModifiedOnDate { get; set; } + } +} \ No newline at end of file diff --git a/DNN Platform/Library/Modules/SQL/Components/SqlQueryController.cs b/DNN Platform/Library/Modules/SQL/Components/SqlQueryController.cs new file mode 100644 index 00000000000..10e1b78fa0c --- /dev/null +++ b/DNN Platform/Library/Modules/SQL/Components/SqlQueryController.cs @@ -0,0 +1,100 @@ +#region Copyright +// +// DotNetNuke® - http://www.dotnetnuke.com +// Copyright (c) 2002-2013 +// by DotNetNuke Corporation +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +// documentation files (the "Software"), to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and +// to permit persons to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions +// of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +#endregion + +#region Usings + +using System.Collections.Generic; +using DotNetNuke.Data; +using System.Linq; + +#endregion + +namespace DotNetNuke.Modules.SQL.Components +{ + public class SqlQueryController + { + public void AddQuery(SqlQuery query) + { + using (IDataContext ctx = DataContext.Instance()) + { + var rep = ctx.GetRepository(); + rep.Insert(query); + } + } + + public void DeleteQuery(SqlQuery query) + { + using (IDataContext ctx = DataContext.Instance()) + { + var rep = ctx.GetRepository(); + rep.Delete(query); + } + } + + public IEnumerable GetQueries() + { + IEnumerable queries; + + using (IDataContext ctx = DataContext.Instance()) + { + var rep = ctx.GetRepository(); + queries = rep.Get(); + } + return queries; + } + + public SqlQuery GetQuery(int id) + { + SqlQuery query; + + using (IDataContext ctx = DataContext.Instance()) + { + var rep = ctx.GetRepository(); + query = rep.GetById(id); + } + return query; + } + + public SqlQuery GetQuery(string name) + { + List queries; + SqlQuery query = null; + + using (IDataContext ctx = DataContext.Instance()) + { + var rep = ctx.GetRepository(); + queries = rep.Find("where name = @0", name).ToList(); + if (queries != null && queries.Count > 0) + query = queries.ElementAt(0); + } + return query; + } + + public void UpdateQuery(SqlQuery query) + { + using (IDataContext ctx = DataContext.Instance()) + { + var rep = ctx.GetRepository(); + rep.Update(query); + } + } + } +} \ No newline at end of file diff --git a/Website/DesktopModules/Admin/SQL/App_LocalResources/SQL.ascx.resx b/Website/DesktopModules/Admin/SQL/App_LocalResources/SQL.ascx.resx index 0a76748c458..bf59b502372 100644 --- a/Website/DesktopModules/Admin/SQL/App_LocalResources/SQL.ascx.resx +++ b/Website/DesktopModules/Admin/SQL/App_LocalResources/SQL.ascx.resx @@ -121,7 +121,7 @@ Run Script - can include {directives} and /*comments*/ + Can include {directives} and /*comments*/ There is an error in your query! @@ -157,21 +157,66 @@ The query did not return any data - Script: + Script - Enter the SQL you wish to execute. - - - Run as Script: - - - Select if the SQL statement does not return a value and only acts on the database to make changes + Enter the SQL you wish to execute. You can use more than one SELECT statement to return multiple result sets. This is the error returned by SQL server after executing your SQL script. - Error Details: + Error Details + + + The query has been loaded but the associated Connection ("{0}") was not found. Default "SiteSqlServer" Connection has been selected instead. + + + The query has been successfully deleted. + + + Select a presaved query. You can run it as is or modify before executing it + + + Saved Query: + + + Delete Query + + + Load Query + + + Save Query + + + < New Query > + + + Please write or load the script you want to run. + + + Save Query As... + + + Provide a name to identify the saved query. + + + Name: + + + Save + + + You have to provide a name for the query + + + The query has been successfully saved. + + + Copy to Clipboard + + + Your query returned no data. \ No newline at end of file diff --git a/Website/DesktopModules/Admin/SQL/SQL.ascx.cs b/Website/DesktopModules/Admin/SQL/SQL.ascx.cs index a89500ea045..58d8e4943e2 100644 --- a/Website/DesktopModules/Admin/SQL/SQL.ascx.cs +++ b/Website/DesktopModules/Admin/SQL/SQL.ascx.cs @@ -38,6 +38,9 @@ using System.Globalization; using System.Collections.Generic; using System.Data.SqlClient; +using DotNetNuke.Modules.SQL.Components; +using System.Text.RegularExpressions; +using System.Web.UI.HtmlControls; #endregion @@ -61,69 +64,100 @@ public partial class SQL : PortalModuleBase #region Event Handlers - /// ----------------------------------------------------------------------------- - /// - /// Page_Load runs when the control is loaded. - /// - /// - /// - /// - /// [cnurse] 9/28/2004 Updated to reflect design changes for Help, 508 support - /// and localisation - /// [VMasanas] 9/28/2004 Changed redirect to Access Denied - /// - /// ----------------------------------------------------------------------------- protected override void OnLoad(EventArgs e) { base.OnLoad(e); CheckSecurity(); + LoadPlugins(); cmdExecute.Click += OnExecuteClick; cmdUpload.Click += OnUploadClick; - ResultsRepeater.ItemDataBound += ResultsRepeater_ItemDataBound; - errorRow.Visible = false; + lnkDelete.Click += lnkDelete_Click; + lnkSave.Click += lnkSave_Click; + rptResults.ItemDataBound += rptResults_ItemDataBound; + ddlSavedQuery.SelectedIndexChanged += ddlSavedQuery_SelectedIndexChanged; try { - if (!UserInfo.IsSuperUser) - { - Response.Redirect(Globals.NavigateURL("Access Denied"), true); - } if (!Page.IsPostBack) { - ConnectionStringSettingsCollection connections = ConfigurationManager.ConnectionStrings; - foreach (ConnectionStringSettings connection in connections) - { - if (connection.Name.ToLower() != "localmysqlserver" && connection.Name.ToLower() != "localsqlserver") - { - cboConnection.AddItem(connection.Name, connection.Name); - } - } - cboConnection.SelectedIndex = 0; + LoadConnectionStrings(); + LoadSavedQueries(); + cmdExecute.ToolTip = Localization.GetString("cmdExecute.ToolTip", LocalResourceFile); - chkRunAsScript.ToolTip = Localization.GetString("chkRunAsScript.ToolTip", LocalResourceFile); + DotNetNuke.UI.Utilities.ClientAPI.AddButtonConfirm(lnkDelete, LocalizeString("DeleteItem")); } } - catch (Exception exc) //Module failed to load + catch (Exception exc) { Exceptions.ProcessModuleLoadException(this, exc); } } - private void ResultsRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e) + protected void OnExecuteClick(object sender, EventArgs e) { try { - if (e.Item.ItemType != ListItemType.AlternatingItem && e.Item.ItemType != ListItemType.Item) + if (!Page.IsValid) { return; } - var gvResults = (DnnGrid)e.Item.FindControl("gvResults"); - gvResults.PreRender += this.gvResults_PreRender; - gvResults.DataSource = e.Item.DataItem; - gvResults.DataBind(); + var connectionstring = Config.GetConnectionString(ddlConnection.SelectedValue); + + if (RunAsScript()) + { + var strError = DataProvider.Instance().ExecuteScript(connectionstring, txtQuery.Text); + if (strError == Null.NullString) + { + UI.Skins.Skin.AddModuleMessage(this, Localization.GetString("QuerySuccess", LocalResourceFile), ModuleMessage.ModuleMessageType.GreenSuccess); + } + else + { + UI.Skins.Skin.AddModuleMessage(this, Localization.GetString("QueryError", LocalResourceFile), ModuleMessage.ModuleMessageType.RedError); + errorRow.Visible = true; + txtError.Text = strError; + } + } + else + { + try + { + string errorMessage; + var dr = DataProvider.Instance().ExecuteSQLTemp(connectionstring, txtQuery.Text, out errorMessage); + if (dr != null) + { + var tables = new List(); + do + { + var table = new DataTable { Locale = CultureInfo.CurrentCulture }; + table.Load(dr); + tables.Add(table); + } + while (!dr.IsClosed); // table.Load automatically moves to the next result and closes the reader once there are no more + + rptResults.DataSource = tables; + rptResults.DataBind(); + + UI.Skins.Skin.AddModuleMessage(this, Localization.GetString("QuerySuccess", LocalResourceFile), ModuleMessage.ModuleMessageType.GreenSuccess); + } + else + { + UI.Skins.Skin.AddModuleMessage(this, Localization.GetString("QueryError", LocalResourceFile), ModuleMessage.ModuleMessageType.RedError); + errorRow.Visible = true; + txtError.Text = errorMessage; + } + } + catch (SqlException sqlException) + { + UI.Skins.Skin.AddModuleMessage(this, Localization.GetString("QueryError", LocalResourceFile), ModuleMessage.ModuleMessageType.RedError); + errorRow.Visible = true; + txtError.Text = sqlException.Message; + return; + } + } + RecordAuditEventLog(txtQuery.Text); } catch (Exception exc) { @@ -131,89 +165,107 @@ private void ResultsRepeater_ItemDataBound(object sender, RepeaterItemEventArgs } } - - void gvResults_PreRender(object sender, EventArgs e) + private void rptResults_ItemDataBound(object sender, RepeaterItemEventArgs e) { - ((DnnGrid)sender).ClientSettings.Scrolling.AllowScroll = false; + try + { + if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item) + { + var gvResults = (GridView)e.Item.FindControl("grdResults"); + gvResults.DataSource = e.Item.DataItem; + gvResults.DataBind(); + } + } + catch (Exception exc) + { + Exceptions.ProcessModuleLoadException(this, exc); + } } - /// ----------------------------------------------------------------------------- - /// - /// cmdExecute_Click runs when the Execute button is clicked - /// - /// - /// - /// - /// [cnurse] 9/28/2004 Updated to reflect design changes for Help, 508 support - /// and localisation - /// - /// ----------------------------------------------------------------------------- - protected void OnExecuteClick(object sender, EventArgs e) + private void ddlSavedQuery_SelectedIndexChanged(object sender, EventArgs e) { - try + if (ddlSavedQuery.SelectedValue == "") { - - if (!String.IsNullOrEmpty(txtQuery.Text)) + txtQuery.Text = ""; + lnkDelete.Visible = false; + ddlConnection.SelectedValue = "SiteSqlServer"; + } + else + { + SqlQueryController ctl = new SqlQueryController(); + SqlQuery query = ctl.GetQuery(int.Parse(ddlSavedQuery.SelectedValue)); + if (query != null) { - var connectionstring = Config.GetConnectionString(cboConnection.SelectedValue); - if (chkRunAsScript.Checked) + txtQuery.Text = query.Query; + lnkDelete.Visible = true; + if (ddlConnection.Items.FindByValue(query.ConnectionStringName) != null) { - var strError = DataProvider.Instance().ExecuteScript(connectionstring, txtQuery.Text); - if (strError == Null.NullString) - { - UI.Skins.Skin.AddModuleMessage(this, Localization.GetString("QuerySuccess", LocalResourceFile), ModuleMessage.ModuleMessageType.GreenSuccess); - } - else - { - UI.Skins.Skin.AddModuleMessage(this, Localization.GetString("QueryError", LocalResourceFile), ModuleMessage.ModuleMessageType.RedError); - errorRow.Visible = true; - txtError.Text = strError; - } + ddlConnection.SelectedValue = query.ConnectionStringName; } else { - try - { - string errorMessage; - var dr = DataProvider.Instance().ExecuteSQLTemp(connectionstring, txtQuery.Text, out errorMessage); - if (dr != null) - { - var tables = new List(); - do - { - var table = new DataTable { Locale = CultureInfo.CurrentCulture }; - table.Load(dr); - tables.Add(table); - } - while (!dr.IsClosed); // table.Load automatically moves to the next result and closes the reader once there are no more - - ResultsRepeater.DataSource = tables; - ResultsRepeater.DataBind(); - - UI.Skins.Skin.AddModuleMessage(this, Localization.GetString("QuerySuccess", LocalResourceFile), ModuleMessage.ModuleMessageType.GreenSuccess); - } - else - { - UI.Skins.Skin.AddModuleMessage(this, Localization.GetString("QueryError", LocalResourceFile), ModuleMessage.ModuleMessageType.RedError); - errorRow.Visible = true; - txtError.Text = errorMessage; - } - } - catch (SqlException sqlException) - { - UI.Skins.Skin.AddModuleMessage(this, Localization.GetString("QueryError", LocalResourceFile), ModuleMessage.ModuleMessageType.RedError); - errorRow.Visible = true; - txtError.Text = sqlException.Message; - return; - } + DotNetNuke.UI.Skins.Skin.AddModuleMessage(this, string.Format(LocalizeString("CnnStringNotFound"), query.ConnectionStringName), ModuleMessage.ModuleMessageType.YellowWarning); } - RecordAuditEventLog(txtQuery.Text); } } - catch (Exception exc) //Module failed to load + } + + private void lnkSave_Click(object sender, EventArgs e) + { + try + { + SqlQueryController ctl = new SqlQueryController(); + SqlQuery query = ctl.GetQuery(txtName.Text); + if (query == null) + { + query = new SqlQuery(); + query.CreatedByUserId = UserId; + query.CreatedOnDate = DateTime.Now; + } + query.Name = txtName.Text; + query.Query = txtQuery.Text; + query.ConnectionStringName = ddlConnection.SelectedValue; + query.LastModifiedByUserId = UserId; + query.LastModifiedOnDate = DateTime.Now; + + if (query.QueryId == 0) + { + ctl.AddQuery(query); + } + else + { + ctl.UpdateQuery(query); + } + LoadSavedQueries(); + ddlSavedQuery.SelectedValue = query.QueryId.ToString(); + lnkDelete.Visible = true; + + DotNetNuke.UI.Skins.Skin.AddModuleMessage(this, LocalizeString("Saved"), ModuleMessage.ModuleMessageType.GreenSuccess); + } + catch (Exception exc) + { + Exceptions.ProcessModuleLoadException(this, exc); + } + } + + private void lnkDelete_Click(object sender, EventArgs e) + { + try + { + SqlQueryController ctl = new SqlQueryController(); + SqlQuery query = ctl.GetQuery(int.Parse(ddlSavedQuery.SelectedValue)); + if (query != null) + { + ctl.DeleteQuery(query); + LoadSavedQueries(); + DotNetNuke.UI.Skins.Skin.AddModuleMessage(this, LocalizeString("Deleted"), ModuleMessage.ModuleMessageType.GreenSuccess); + } + } + catch (Exception exc) { Exceptions.ProcessModuleLoadException(this, exc); } + } protected void OnUploadClick(object sender, EventArgs e) @@ -248,6 +300,46 @@ private void CheckSecurity() } } + private void LoadConnectionStrings() + { + ConnectionStringSettingsCollection connections = ConfigurationManager.ConnectionStrings; + foreach (ConnectionStringSettings connection in connections) + { + if (connection.Name.ToLower() != "localmysqlserver" && connection.Name.ToLower() != "localsqlserver") + { + ddlConnection.Items.Add(new ListItem(connection.Name, connection.Name)); + } + } + ddlConnection.SelectedIndex = 0; + } + + private void LoadSavedQueries() + { + SqlQueryController ctl = new SqlQueryController(); + ddlSavedQuery.DataSource = ctl.GetQueries(); + ddlSavedQuery.DataBind(); + + ddlSavedQuery.Items.Insert(0, new ListItem(LocalizeString("NewQuery"), "")); + lnkDelete.Visible = false; + + } + + private bool RunAsScript() + { + string _scriptDelimiterRegex = "(?<=(?:[^\\w]+|^))GO(?=(?: |\\t)*?(?:\\r?\\n|$))"; + Regex objRegex = new Regex(_scriptDelimiterRegex, RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Multiline); + return objRegex.IsMatch(txtQuery.Text); + } + + private void LoadPlugins() + { + Page.ClientScript.RegisterClientScriptInclude("clipboard", this.TemplateSourceDirectory + "/plugins/clipboard/jquery.zclip.min.js"); + } + + protected string GetClipboardPath() + { + return this.TemplateSourceDirectory + "/plugins/clipboard/zeroclipboard.swf"; + } #endregion } diff --git a/Website/DesktopModules/Admin/SQL/module.css b/Website/DesktopModules/Admin/SQL/module.css index 0bbc28e7a62..0bddf95b372 100644 --- a/Website/DesktopModules/Admin/SQL/module.css +++ b/Website/DesktopModules/Admin/SQL/module.css @@ -1,5 +1,6 @@ /* =========== SQL Module Styling =========== */ .dnnSQLModule{width:100%;margin:2em auto;} -.dnnFormItem.dnnResults{overflow:auto;height: 600px;} -.dnnFormItem.dnnResults .RadGrid{margin-bottom:3em;} +.dnnFormItem.dnnResults{overflow:auto;margin-bottom:20px;} +#dialog-save .dnnFormItem {margin-top: 70px;} +#dialog-save .dnnFormItem span.dnnFormMessage.dnnFormError{bottom: 65%;} /* =========== End SQL Module Styling =========== */ \ No newline at end of file diff --git a/Website/DesktopModules/Admin/SQL/plugins/clipboard/ZeroClipboard.swf b/Website/DesktopModules/Admin/SQL/plugins/clipboard/ZeroClipboard.swf new file mode 100644 index 0000000000000000000000000000000000000000..13bf8e396202964e0048333d878f4b949a2f5e6a GIT binary patch literal 1071 zcmV+~1kn3KS5pay1^@tfoPAa6Qrkup-d$aeB-A-xFjKf1te)pFM-&Q&_dOT zp~-XxqP4X~YJ}vGWC;KAD1C=MKwiO_PG6^Vbs@z~r#qgr-}!Xr?4IxJ9P1kT4dpSa zmlT9hja*+}e;Cbih*6`(JT|+I(1(#NIVSiTL~Dq=|Lb=d5tOYL`L;_#dyQQ%FAAmI zcth~a_gzLk@xphk!Y?fFYp&C2`ZTZ#X}INt9hY9ojZWZ1Om23g$oC2%i(XLAs&#|V z5ArS7X}yhomj%SJGT~|rnZj|zM|I&j59e1QKqGxQN5!(ijWrx1S)ZN!RwWBwC`$uYc z!)028S7F4?l?H2dd39HKImh$+mv#S~I-YjmQ;P-rUfUM~-;Xr+ldpAXK+hS!b|@Ro zUs)@fv!kf9RjpFXZ?d(Pe_q{bY*sgP{Ykaib==7Da_N!X$Z^AwK5e&BZ5R56j>T=;_5DD$nR8}GiWShym;5A&x*eM;)Us-}<67Eb+@9n>sdlhm z`(coON!$a6H-ML=9U8}t-8aV1yD!xY9v@|7-FWq*lEUMka&b=Hq$X{>72}4eNl_P+ zccPJWGtXb!r#GbVPIO$}sN%oME%Yf<`b@|2f6G5y#$}-l zAR|D=L6`ti0Wt|N4P*v{Ss-&j?gE(yvY_TMkQE@SK-Pd%f#~WwXExMLZXW@84CD#m zFMxar!IU~i}ZGSTvX;GX_!`A@yKkIbSu*e=l_b9m*BF@hOB8SS;p?XkU4 z+#Y{FagI+_hF#pQ*y^c#B7H9*TQ=n-IvJZOQ*KYMV&e{u!2((~XOiIAy*Zr0yBr$x zqA6D~T{u}ZWn+;Cn@jC`refSD34E}PZ{YGaxq%P2g&VlCEyl30qM2Z<#-M2CQxMno zG_4J8H7mc8(VenQzJ;=@j=BiTh*RubMeS$61ORcM^S6!u6l;=?s|@ py1A~K8@jovn~!u;;=k8uI$3rc`gC{*rT-s&a~N%N=5J58nk1s|4c7nw literal 0 HcmV?d00001 diff --git a/Website/DesktopModules/Admin/SQL/plugins/clipboard/jquery.zclip.min.js b/Website/DesktopModules/Admin/SQL/plugins/clipboard/jquery.zclip.min.js new file mode 100644 index 00000000000..51471a10954 --- /dev/null +++ b/Website/DesktopModules/Admin/SQL/plugins/clipboard/jquery.zclip.min.js @@ -0,0 +1,12 @@ +/* + * zClip :: jQuery ZeroClipboard v1.1.1 + * http://steamdev.com/zclip + * + * Copyright 2011, SteamDev + * Released under the MIT license. + * http://www.opensource.org/licenses/mit-license.php + * + * Date: Wed Jun 01, 2011 + */ + +(function(a){a.fn.zclip=function(c){if(typeof c=="object"&&!c.length){var b=a.extend({path:"ZeroClipboard.swf",copy:null,beforeCopy:null,afterCopy:null,clickAfter:true,setHandCursor:true,setCSSEffects:true},c);return this.each(function(){var e=a(this);if(e.is(":visible")&&(typeof b.copy=="string"||a.isFunction(b.copy))){ZeroClipboard.setMoviePath(b.path);var d=new ZeroClipboard.Client();if(a.isFunction(b.copy)){e.bind("zClip_copy",b.copy)}if(a.isFunction(b.beforeCopy)){e.bind("zClip_beforeCopy",b.beforeCopy)}if(a.isFunction(b.afterCopy)){e.bind("zClip_afterCopy",b.afterCopy)}d.setHandCursor(b.setHandCursor);d.setCSSEffects(b.setCSSEffects);d.addEventListener("mouseOver",function(f){e.trigger("mouseenter")});d.addEventListener("mouseOut",function(f){e.trigger("mouseleave")});d.addEventListener("mouseDown",function(f){e.trigger("mousedown");if(!a.isFunction(b.copy)){d.setText(b.copy)}else{d.setText(e.triggerHandler("zClip_copy"))}if(a.isFunction(b.beforeCopy)){e.trigger("zClip_beforeCopy")}});d.addEventListener("complete",function(f,g){if(a.isFunction(b.afterCopy)){e.trigger("zClip_afterCopy")}else{if(g.length>500){g=g.substr(0,500)+"...\n\n("+(g.length-500)+" characters not shown)"}e.removeClass("hover");alert("Copied text to clipboard:\n\n "+g)}if(b.clickAfter){e.trigger("click")}});d.glue(e[0],e.parent()[0]);a(window).bind("load resize",function(){d.reposition()})}})}else{if(typeof c=="string"){return this.each(function(){var f=a(this);c=c.toLowerCase();var e=f.data("zclipId");var d=a("#"+e+".zclip");if(c=="remove"){d.remove();f.removeClass("active hover")}else{if(c=="hide"){d.hide();f.removeClass("active hover")}else{if(c=="show"){d.show()}}}})}}}})(jQuery);var ZeroClipboard={version:"1.0.7",clients:{},moviePath:"ZeroClipboard.swf",nextId:1,$:function(a){if(typeof(a)=="string"){a=document.getElementById(a)}if(!a.addClass){a.hide=function(){this.style.display="none"};a.show=function(){this.style.display=""};a.addClass=function(b){this.removeClass(b);this.className+=" "+b};a.removeClass=function(d){var e=this.className.split(/\s+/);var b=-1;for(var c=0;c-1){e.splice(b,1);this.className=e.join(" ")}return this};a.hasClass=function(b){return !!this.className.match(new RegExp("\\s*"+b+"\\s*"))}}return a},setMoviePath:function(a){this.moviePath=a},dispatch:function(d,b,c){var a=this.clients[d];if(a){a.receiveEvent(b,c)}},register:function(b,a){this.clients[b]=a},getDOMObjectPosition:function(c,a){var b={left:0,top:0,width:c.width?c.width:c.offsetWidth,height:c.height?c.height:c.offsetHeight};if(c&&(c!=a)){b.left+=c.offsetLeft;b.top+=c.offsetTop}return b},Client:function(a){this.handlers={};this.id=ZeroClipboard.nextId++;this.movieId="ZeroClipboardMovie_"+this.id;ZeroClipboard.register(this.id,this);if(a){this.glue(a)}}};ZeroClipboard.Client.prototype={id:0,ready:false,movie:null,clipText:"",handCursorEnabled:true,cssEffects:true,handlers:null,glue:function(d,b,e){this.domElement=ZeroClipboard.$(d);var f=99;if(this.domElement.style.zIndex){f=parseInt(this.domElement.style.zIndex,10)+1}if(typeof(b)=="string"){b=ZeroClipboard.$(b)}else{if(typeof(b)=="undefined"){b=document.getElementsByTagName("body")[0]}}var c=ZeroClipboard.getDOMObjectPosition(this.domElement,b);this.div=document.createElement("div");this.div.className="zclip";this.div.id="zclip-"+this.movieId;$(this.domElement).data("zclipId","zclip-"+this.movieId);var a=this.div.style;a.position="absolute";a.left=""+c.left+"px";a.top=""+c.top+"px";a.width=""+c.width+"px";a.height=""+c.height+"px";a.zIndex=f;if(typeof(e)=="object"){for(addedStyle in e){a[addedStyle]=e[addedStyle]}}b.appendChild(this.div);this.div.innerHTML=this.getHTML(c.width,c.height)},getHTML:function(d,a){var c="";var b="id="+this.id+"&width="+d+"&height="+a;if(navigator.userAgent.match(/MSIE/)){var e=location.href.match(/^https/i)?"https://":"http://";c+=''}else{c+=''}return c},hide:function(){if(this.div){this.div.style.left="-2000px"}},show:function(){this.reposition()},destroy:function(){if(this.domElement&&this.div){this.hide();this.div.innerHTML="";var a=document.getElementsByTagName("body")[0];try{a.removeChild(this.div)}catch(b){}this.domElement=null;this.div=null}},reposition:function(c){if(c){this.domElement=ZeroClipboard.$(c);if(!this.domElement){this.hide()}}if(this.domElement&&this.div){var b=ZeroClipboard.getDOMObjectPosition(this.domElement);var a=this.div.style;a.left=""+b.left+"px";a.top=""+b.top+"px"}},setText:function(a){this.clipText=a;if(this.ready){this.movie.setText(a)}},addEventListener:function(a,b){a=a.toString().toLowerCase().replace(/^on/,"");if(!this.handlers[a]){this.handlers[a]=[]}this.handlers[a].push(b)},setHandCursor:function(a){this.handCursorEnabled=a;if(this.ready){this.movie.setHandCursor(a)}},setCSSEffects:function(a){this.cssEffects=!!a},receiveEvent:function(d,f){d=d.toString().toLowerCase().replace(/^on/,"");switch(d){case"load":this.movie=document.getElementById(this.movieId);if(!this.movie){var c=this;setTimeout(function(){c.receiveEvent("load",null)},1);return}if(!this.ready&&navigator.userAgent.match(/Firefox/)&&navigator.userAgent.match(/Windows/)){var c=this;setTimeout(function(){c.receiveEvent("load",null)},100);this.ready=true;return}this.ready=true;try{this.movie.setText(this.clipText)}catch(h){}try{this.movie.setHandCursor(this.handCursorEnabled)}catch(h){}break;case"mouseover":if(this.domElement&&this.cssEffects){this.domElement.addClass("hover");if(this.recoverActive){this.domElement.addClass("active")}}break;case"mouseout":if(this.domElement&&this.cssEffects){this.recoverActive=false;if(this.domElement.hasClass("active")){this.domElement.removeClass("active");this.recoverActive=true}this.domElement.removeClass("hover")}break;case"mousedown":if(this.domElement&&this.cssEffects){this.domElement.addClass("active")}break;case"mouseup":if(this.domElement&&this.cssEffects){this.domElement.removeClass("active");this.recoverActive=false}break}if(this.handlers[d]){for(var b=0,a=this.handlers[d].length;b
- - - + + +
+
+
- - + +
- - + + +
- - + + +
-
- - +
+
+ +
+
+ +
    -
  • +
  • +
  • +
  • +
-
- - - - - + + +
+ <%#LocalizeString("CopyToClipboard") %> + + + + + + + + +
+
+
+
- \ No newline at end of file + $('#<%=lnkSaveQuery.ClientID%>').bind("click", function () { + var active = $('#<%=ddlSavedQuery.ClientID%> option:selected').text(); + if ($('#<%=ddlSavedQuery.ClientID%>').val() == "") + active = ""; + $('#<%=txtName.ClientID%>').val(active); + $("#dialog-save").dialog('open'); + return false; + }); + $('#btcancel').bind("click", function () { + $("#dialog-save").dialog('close'); + return false; + }); + + $("#dialog-save").dialog({ + modal: true, + autoOpen: false, + resizable: false, + dialogClass: 'dnnFormPopup dnnClear', + width: 400, + height: 250, + title: '<%=LocalizeString("SaveDialogTitle")%>' + }).parent().appendTo(jQuery('form:first'));; + + $('img.imgCopy').zclip({ + path: '<%=GetClipboardPath()%>', + copy: function () { return $(this).siblings('div').html(); } + }); + + }); + diff --git a/Website/Licenses/ZeroClipboard (MIT).txt b/Website/Licenses/ZeroClipboard (MIT).txt new file mode 100644 index 00000000000..e01f08747e5 --- /dev/null +++ b/Website/Licenses/ZeroClipboard (MIT).txt @@ -0,0 +1,8 @@ +The MIT License (MIT) +Copyright (c) 2013 Jon Rohan, James M. Greene + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Website/Licenses/zClip (MIT).txt b/Website/Licenses/zClip (MIT).txt new file mode 100644 index 00000000000..e216802ab40 --- /dev/null +++ b/Website/Licenses/zClip (MIT).txt @@ -0,0 +1,10 @@ +/* + * zClip :: jQuery ZeroClipboard v1.1.1 + * http://steamdev.com/zclip + * + * Copyright 2011, SteamDev + * Released under the MIT license. + * http://www.opensource.org/licenses/mit-license.php + * + * Date: Wed Jun 01, 2011 + */ \ No newline at end of file diff --git a/Website/Portals/_default/default.css b/Website/Portals/_default/default.css index f61798fb3eb..370bf76a6ca 100644 --- a/Website/Portals/_default/default.css +++ b/Website/Portals/_default/default.css @@ -2593,8 +2593,8 @@ table.dnnASPGrid { padding: 4px; } -.dnnGridHeader td, thead.dnnGridHeader th { - padding: 6px 0 6px 12px; +.dnnGridHeader td, thead.dnnGridHeader th, tr.dnnGridHeader th{ + padding: 6px 12px 6px 12px; border-bottom: 1px solid #c9c9c9; border-right: 1px solid #c9c9c9; background: #f0f2f1; diff --git a/Website/Providers/DataProviders/SqlDataProvider/07.02.00.SqlDataProvider b/Website/Providers/DataProviders/SqlDataProvider/07.02.00.SqlDataProvider index 1af9355832f..a3872152e88 100644 --- a/Website/Providers/DataProviders/SqlDataProvider/07.02.00.SqlDataProvider +++ b/Website/Providers/DataProviders/SqlDataProvider/07.02.00.SqlDataProvider @@ -1143,6 +1143,30 @@ INSERT INTO {databaseOwner}[{objectQualifier}EventLogConfig] ([LogTypeKey], [Log GO +/** DNN-3191 Enhancements to the SQL Module **/ +/*********************************************/ +IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'{databaseOwner}{objectQualifier}SQLQueries') AND OBJECTPROPERTY(id, N'IsTable') = 1) +BEGIN + CREATE TABLE {databaseOwner}{objectQualifier}SQLQueries( + [QueryId] [int] IDENTITY(1,1) NOT NULL, + [Name] [nvarchar](200) NOT NULL, + [Query] [nvarchar](max) NOT NULL, + [ConnectionStringName] [nvarchar](50) NOT NULL, + [CreatedByUserId] [int] NOT NULL, + [CreatedOnDate] [datetime] NOT NULL, + [LastModifiedByUserId] [int] NOT NULL, + [LastModifiedOnDate] [datetime] NOT NULL, + CONSTRAINT [PK_dnn_SavedQueries] PRIMARY KEY CLUSTERED + ( + [QueryId] ASC + ) + ) +END + +GO + + + /************************************************************/ /***** SqlDataProvider *****/ /************************************************************/ \ No newline at end of file