Fixed workitem:29297 - overloaded mssql db reads caused by creating styles on a stylesheet for use in the richtexteditor styles drop down (tinymce).
Patch supplied by @tentonipete (unable to create fork/PR)
This commit is contained in:
@@ -1,12 +1,11 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Data;
|
||||
using System.Xml;
|
||||
using umbraco.DataLayer;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Xml;
|
||||
using umbraco.cms.businesslogic.cache;
|
||||
using umbraco.DataLayer;
|
||||
using umbraco.IO;
|
||||
|
||||
namespace umbraco.cms.businesslogic.web
|
||||
@@ -33,9 +32,8 @@ namespace umbraco.cms.businesslogic.web
|
||||
|
||||
//move old file
|
||||
_filename = value;
|
||||
SqlHelper.ExecuteNonQuery("update cmsStylesheet set filename = '" + _filename + "' where nodeId = " + base.Id.ToString());
|
||||
SqlHelper.ExecuteNonQuery(string.Format("update cmsStylesheet set filename = '{0}' where nodeId = {1}", _filename, Id));
|
||||
InvalidateCache();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +58,9 @@ namespace umbraco.cms.businesslogic.web
|
||||
|
||||
StylesheetProperty[] retVal = new StylesheetProperty[tmp.Length];
|
||||
for (int i = 0; i < tmp.Length; i++)
|
||||
{
|
||||
retVal[i] = StylesheetProperty.GetStyleSheetProperty(this.ChildrenOfAllObjectTypes[i].Id);
|
||||
}
|
||||
m_properties = retVal;
|
||||
}
|
||||
return m_properties;
|
||||
@@ -101,49 +101,49 @@ namespace umbraco.cms.businesslogic.web
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void setupStyleSheet(bool loadFileData, bool updateStyleProperties)
|
||||
{
|
||||
// Get stylesheet data
|
||||
IRecordsReader dr = SqlHelper.ExecuteReader("select filename, content from cmsStylesheet where nodeid = " + base.Id.ToString());
|
||||
if (dr.Read())
|
||||
using (IRecordsReader dr = SqlHelper.ExecuteReader("select filename, content from cmsStylesheet where nodeid = " + Id))
|
||||
{
|
||||
if (!dr.IsNull("filename"))
|
||||
_filename = dr.GetString("filename");
|
||||
// Get Content from db or file
|
||||
if (!loadFileData)
|
||||
if (dr.Read())
|
||||
{
|
||||
if (!dr.IsNull("content"))
|
||||
_content = dr.GetString("content");
|
||||
}
|
||||
else
|
||||
if (File.Exists(IOHelper.MapPath(SystemDirectories.Css + "/" + this.Text + ".css")))
|
||||
if (!dr.IsNull("filename"))
|
||||
_filename = dr.GetString("filename");
|
||||
// Get Content from db or file
|
||||
if (!loadFileData)
|
||||
{
|
||||
if (!dr.IsNull("content"))
|
||||
_content = dr.GetString("content");
|
||||
}
|
||||
else if (File.Exists(IOHelper.MapPath(String.Format("{0}/{1}.css", SystemDirectories.Css, this.Text))))
|
||||
{
|
||||
|
||||
StreamReader re = File.OpenText(IOHelper.MapPath(SystemDirectories.Css + "/" + this.Text + ".css"));
|
||||
string input = null;
|
||||
bool read = true;
|
||||
_content = string.Empty;
|
||||
// NH: Updates the reader to support properties
|
||||
bool readingProperties = false;
|
||||
string propertiesContent = String.Empty;
|
||||
while ((input = re.ReadLine()) != null && read)
|
||||
{
|
||||
if (input.Contains("EDITOR PROPERTIES"))
|
||||
{
|
||||
readingProperties = true;
|
||||
}
|
||||
else if (readingProperties)
|
||||
{
|
||||
propertiesContent += input.Replace("\n", "") + "\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
_content += input.Replace("\n", "") + "\n";
|
||||
|
||||
using (StreamReader re = File.OpenText(IOHelper.MapPath(String.Format("{0}/{1}.css", SystemDirectories.Css, this.Text))))
|
||||
{
|
||||
string input = null;
|
||||
_content = string.Empty;
|
||||
// NH: Updates the reader to support properties
|
||||
bool readingProperties = false;
|
||||
|
||||
while ((input = re.ReadLine()) != null && true)
|
||||
{
|
||||
if (input.Contains("EDITOR PROPERTIES"))
|
||||
{
|
||||
readingProperties = true;
|
||||
}
|
||||
else
|
||||
if (readingProperties)
|
||||
{
|
||||
propertiesContent += input.Replace("\n", "") + "\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
_content += input.Replace("\n", "") + "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
re.Close();
|
||||
|
||||
// update properties
|
||||
if (updateStyleProperties)
|
||||
@@ -154,16 +154,13 @@ namespace umbraco.cms.businesslogic.web
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
dr.Close();
|
||||
|
||||
}
|
||||
|
||||
private void parseProperties(string propertiesContent)
|
||||
{
|
||||
MatchCollection m =
|
||||
Regex.Matches(propertiesContent, "([^{]*){([^}]*)}", RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
|
||||
MatchCollection m = Regex.Matches(propertiesContent, "([^{]*){([^}]*)}", RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
|
||||
|
||||
foreach (Match match in m)
|
||||
{
|
||||
@@ -171,7 +168,7 @@ namespace umbraco.cms.businesslogic.web
|
||||
string cssClass = groups[1].Value.Replace("\n", "").Replace("\r", "").Trim().Trim(Environment.NewLine.ToCharArray());
|
||||
string cssCode = groups[2].Value.Trim(Environment.NewLine.ToCharArray());
|
||||
foreach (StylesheetProperty sp in this.Properties)
|
||||
if (sp.Alias == cssClass)
|
||||
if (sp.Alias == cssClass && sp.value != cssCode) // check before setting to avoid invalidating cache unecessarily
|
||||
sp.value = cssCode;
|
||||
}
|
||||
}
|
||||
@@ -183,7 +180,7 @@ namespace umbraco.cms.businesslogic.web
|
||||
CMSNode newNode = CMSNode.MakeNew(-1, ModuleObjectType, user.Id, 1, Text, Guid.NewGuid());
|
||||
|
||||
// Create the stylesheet data
|
||||
SqlHelper.ExecuteNonQuery("insert into cmsStylesheet (nodeId, filename, content) values ('" + newNode.Id.ToString() + "','" + FileName + "',@content)", SqlHelper.CreateParameter("@content", Content));
|
||||
SqlHelper.ExecuteNonQuery(string.Format("insert into cmsStylesheet (nodeId, filename, content) values ('{0}','{1}',@content)", newNode.Id, FileName), SqlHelper.CreateParameter("@content", Content));
|
||||
|
||||
// save to file to avoid file coherency issues
|
||||
StyleSheet newCss = new StyleSheet(newNode.Id, false, false);
|
||||
@@ -229,7 +226,7 @@ namespace umbraco.cms.businesslogic.web
|
||||
|
||||
string content = string.Empty;
|
||||
|
||||
using (StreamReader re = File.OpenText(IOHelper.MapPath(SystemDirectories.Css + "/" + fileStylesheets[i].ToString() + ".css")))
|
||||
using (StreamReader re = File.OpenText(IOHelper.MapPath(string.Format("{0}/{1}.css", SystemDirectories.Css, fileStylesheets[i]))))
|
||||
{
|
||||
content = re.ReadToEnd();
|
||||
}
|
||||
@@ -257,7 +254,7 @@ namespace umbraco.cms.businesslogic.web
|
||||
|
||||
if (!e.Cancel)
|
||||
{
|
||||
File.Delete(IOHelper.MapPath(SystemDirectories.Css + "/" + this.Text + ".css"));
|
||||
File.Delete(IOHelper.MapPath(String.Format("{0}/{1}.css", SystemDirectories.Css, this.Text)));
|
||||
foreach (StylesheetProperty p in this.Properties)
|
||||
p.delete();
|
||||
SqlHelper.ExecuteNonQuery("delete from cmsStylesheet where nodeId = @nodeId", SqlHelper.CreateParameter("@nodeId", this.Id));
|
||||
@@ -270,18 +267,16 @@ namespace umbraco.cms.businesslogic.web
|
||||
|
||||
public void saveCssToFile()
|
||||
{
|
||||
StreamWriter SW;
|
||||
SW = File.CreateText(IOHelper.MapPath(SystemDirectories.Css + "/" + this.Text + ".css"));
|
||||
string tmpCss;
|
||||
//tmpCss = "/* GENERAL STYLES */\n";
|
||||
tmpCss = this.Content + "\n\n";
|
||||
tmpCss += "/* EDITOR PROPERTIES - PLEASE DON'T DELETE THIS LINE TO AVOID DUPLICATE PROPERTIES */\n";
|
||||
foreach (StylesheetProperty p in this.Properties)
|
||||
using (StreamWriter SW = File.CreateText(IOHelper.MapPath(string.Format("{0}/{1}.css", SystemDirectories.Css, this.Text))))
|
||||
{
|
||||
tmpCss += p.ToString() + "\n";
|
||||
string tmpCss = this.Content + "\n\n";
|
||||
tmpCss += "/* EDITOR PROPERTIES - PLEASE DON'T DELETE THIS LINE TO AVOID DUPLICATE PROPERTIES */\n";
|
||||
foreach (StylesheetProperty p in this.Properties)
|
||||
{
|
||||
tmpCss += p + "\n";
|
||||
}
|
||||
SW.Write(tmpCss);
|
||||
}
|
||||
SW.Write(tmpCss);
|
||||
SW.Close();
|
||||
}
|
||||
|
||||
public XmlNode ToXml(XmlDocument xd)
|
||||
@@ -308,26 +303,22 @@ namespace umbraco.cms.businesslogic.web
|
||||
return doc;
|
||||
}
|
||||
|
||||
|
||||
public static StyleSheet GetStyleSheet(int id, bool setupStyleProperties, bool loadContentFromFile)
|
||||
{
|
||||
return Cache.GetCacheItem<StyleSheet>(GetCacheKey(id), stylesheetCacheSyncLock,
|
||||
TimeSpan.FromMinutes(30),
|
||||
delegate
|
||||
{
|
||||
try
|
||||
{
|
||||
return new StyleSheet(id, setupStyleProperties, loadContentFromFile);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
return Cache.GetCacheItem<StyleSheet>(GetCacheKey(id), stylesheetCacheSyncLock, TimeSpan.FromMinutes(30), () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
return new StyleSheet(id, setupStyleProperties, loadContentFromFile);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void InvalidateCache()
|
||||
public void InvalidateCache()
|
||||
{
|
||||
Cache.ClearCacheItem(GetCacheKey(this.Id));
|
||||
}
|
||||
@@ -337,7 +328,6 @@ namespace umbraco.cms.businesslogic.web
|
||||
return UmbracoStylesheetCacheKey + id;
|
||||
}
|
||||
|
||||
|
||||
//EVENTS
|
||||
/// <summary>
|
||||
/// The save event handler
|
||||
|
||||
@@ -1,49 +1,49 @@
|
||||
using System;
|
||||
using System.Data;
|
||||
using umbraco.DataLayer;
|
||||
|
||||
using umbraco.cms.businesslogic.cache;
|
||||
using umbraco.DataLayer;
|
||||
|
||||
namespace umbraco.cms.businesslogic.web
|
||||
{
|
||||
public class StylesheetProperty : CMSNode
|
||||
{
|
||||
private string _alias;
|
||||
public class StylesheetProperty : CMSNode
|
||||
{
|
||||
private string _alias;
|
||||
private string _value;
|
||||
|
||||
private static object stylesheetPropertyCacheSyncLock = new object();
|
||||
private static readonly string UmbracoStylesheetPropertyCacheKey = "UmbracoStylesheetProperty";
|
||||
|
||||
private static Guid moduleObjectType = new Guid("5555da4f-a123-42b2-4488-dcdfb25e4111");
|
||||
// internal static moduleId =
|
||||
private static Guid moduleObjectType = new Guid("5555da4f-a123-42b2-4488-dcdfb25e4111");
|
||||
// internal static moduleId =
|
||||
|
||||
public StylesheetProperty(int id) : base(id)
|
||||
{
|
||||
initProperty();
|
||||
}
|
||||
// Used to check whether the parent stylesheet cache has already been cleared
|
||||
private bool isParentStyleSheetCacheCleared;
|
||||
|
||||
public StylesheetProperty(Guid id) : base(id)
|
||||
{
|
||||
initProperty();
|
||||
}
|
||||
private void initProperty() {
|
||||
public StylesheetProperty(int id) : base(id)
|
||||
{
|
||||
initProperty();
|
||||
}
|
||||
|
||||
IRecordsReader dr = SqlHelper.ExecuteReader("Select stylesheetPropertyAlias,stylesheetPropertyValue from cmsStylesheetProperty where nodeId = " + this.Id.ToString());
|
||||
if (dr.Read())
|
||||
{
|
||||
_alias = dr.GetString("stylesheetPropertyAlias");
|
||||
_value = dr.GetString("stylesheetPropertyValue");
|
||||
}
|
||||
else
|
||||
throw new ArgumentException("NO DATA EXSISTS");
|
||||
dr.Close();
|
||||
public StylesheetProperty(Guid id) : base(id)
|
||||
{
|
||||
initProperty();
|
||||
}
|
||||
|
||||
}
|
||||
private void initProperty() {
|
||||
|
||||
IRecordsReader dr = SqlHelper.ExecuteReader("Select stylesheetPropertyAlias,stylesheetPropertyValue from cmsStylesheetProperty where nodeId = " + this.Id);
|
||||
if (dr.Read())
|
||||
{
|
||||
_alias = dr.GetString("stylesheetPropertyAlias");
|
||||
_value = dr.GetString("stylesheetPropertyValue");
|
||||
}
|
||||
else
|
||||
throw new ArgumentException("NO DATA EXSISTS");
|
||||
dr.Close();
|
||||
}
|
||||
|
||||
public StyleSheet StyleSheet() {
|
||||
return new StyleSheet(this.Parent.Id, true, false);
|
||||
}
|
||||
public StyleSheet StyleSheet() {
|
||||
return new StyleSheet(this.Parent.Id, true, false);
|
||||
}
|
||||
|
||||
public void RefreshFromFile() {
|
||||
// ping the stylesheet
|
||||
@@ -51,47 +51,51 @@ namespace umbraco.cms.businesslogic.web
|
||||
initProperty();
|
||||
}
|
||||
|
||||
public string Alias {
|
||||
get{return _alias;}
|
||||
set {
|
||||
SqlHelper.ExecuteNonQuery(String.Format("update cmsStylesheetProperty set stylesheetPropertyAlias = '{0}' where nodeId = {1}", value.Replace("'", "''"), this.Id));
|
||||
_alias=value;
|
||||
|
||||
public string Alias {
|
||||
get{return _alias;}
|
||||
set {
|
||||
SqlHelper.ExecuteNonQuery("update cmsStylesheetProperty set stylesheetPropertyAlias = '"+ value.Replace("'","''")+"' where nodeId = " + this.Id);
|
||||
_alias=value;
|
||||
InvalidateCache();
|
||||
InvalidateParentStyleSheetCache();
|
||||
}
|
||||
}
|
||||
|
||||
public string value {
|
||||
get {return _value;}
|
||||
set {
|
||||
SqlHelper.ExecuteNonQuery("update cmsStylesheetProperty set stylesheetPropertyValue = '"+ value.Replace("'","''")+"' where nodeId = " + this.Id);
|
||||
_value=value;
|
||||
InvalidateCache();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static StylesheetProperty MakeNew(string Text, StyleSheet sheet, BusinessLogic.User user) {
|
||||
CMSNode newNode = CMSNode.MakeNew(sheet.Id, moduleObjectType, user.Id, 2, Text, Guid.NewGuid());
|
||||
SqlHelper.ExecuteNonQuery("Insert into cmsStylesheetProperty (nodeId,stylesheetPropertyAlias,stylesheetPropertyValue) values ('"+ newNode.Id +"','" + Text+ "','')");
|
||||
StylesheetProperty ssp = new StylesheetProperty(newNode.Id);
|
||||
public string value {
|
||||
get {return _value;}
|
||||
set {
|
||||
SqlHelper.ExecuteNonQuery(String.Format("update cmsStylesheetProperty set stylesheetPropertyValue = '{0}' where nodeId = {1}", value.Replace("'", "''"), this.Id));
|
||||
_value=value;
|
||||
|
||||
InvalidateCache();
|
||||
InvalidateParentStyleSheetCache();
|
||||
}
|
||||
}
|
||||
|
||||
public static StylesheetProperty MakeNew(string Text, StyleSheet sheet, BusinessLogic.User user) {
|
||||
CMSNode newNode = CMSNode.MakeNew(sheet.Id, moduleObjectType, user.Id, 2, Text, Guid.NewGuid());
|
||||
SqlHelper.ExecuteNonQuery(String.Format("Insert into cmsStylesheetProperty (nodeId,stylesheetPropertyAlias,stylesheetPropertyValue) values ('{0}','{1}','')", newNode.Id, Text));
|
||||
StylesheetProperty ssp = new StylesheetProperty(newNode.Id);
|
||||
NewEventArgs e = new NewEventArgs();
|
||||
ssp.OnNew(e);
|
||||
return ssp;
|
||||
}
|
||||
}
|
||||
|
||||
public override void delete()
|
||||
{
|
||||
public override void delete()
|
||||
{
|
||||
DeleteEventArgs e = new DeleteEventArgs();
|
||||
FireBeforeDelete(e);
|
||||
|
||||
if (!e.Cancel) {
|
||||
InvalidateCache();
|
||||
InvalidateParentStyleSheetCache();
|
||||
SqlHelper.ExecuteNonQuery("delete from cmsStylesheetProperty where nodeId = @nodeId", SqlHelper.CreateParameter("@nodeId", this.Id));
|
||||
base.delete();
|
||||
|
||||
FireAfterDelete(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Save() {
|
||||
SaveEventArgs e = new SaveEventArgs();
|
||||
@@ -104,28 +108,25 @@ namespace umbraco.cms.businesslogic.web
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return this.Alias +" {\n"+ this.value+"\n}\n";
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("{0} {{\n{1}\n}}\n", this.Alias, this.value);
|
||||
}
|
||||
|
||||
|
||||
public static StylesheetProperty GetStyleSheetProperty(int id)
|
||||
{
|
||||
return Cache.GetCacheItem<StylesheetProperty>(GetCacheKey(id), stylesheetPropertyCacheSyncLock,
|
||||
TimeSpan.FromMinutes(30),
|
||||
delegate
|
||||
{
|
||||
try
|
||||
{
|
||||
return new StylesheetProperty(id);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
return Cache.GetCacheItem<StylesheetProperty>(GetCacheKey(id), stylesheetPropertyCacheSyncLock, TimeSpan.FromMinutes(30), () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
return new StylesheetProperty(id);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void InvalidateCache()
|
||||
@@ -133,14 +134,25 @@ namespace umbraco.cms.businesslogic.web
|
||||
Cache.ClearCacheItem(GetCacheKey(this.Id));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invalidates the parent style sheet cache.
|
||||
/// </summary>
|
||||
private void InvalidateParentStyleSheetCache()
|
||||
{
|
||||
// not sure whether should be doing this check, but if not then the stylesheet is invalidated, then reloaded from db in order to invalidate again.
|
||||
if (!isParentStyleSheetCacheCleared)
|
||||
{
|
||||
umbraco.cms.businesslogic.web.StyleSheet.GetStyleSheet(this.Parent.Id, false, false).InvalidateCache();
|
||||
isParentStyleSheetCacheCleared = true;
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetCacheKey(int id)
|
||||
{
|
||||
return UmbracoStylesheetPropertyCacheKey + id;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//EVENTS
|
||||
// EVENTS
|
||||
/// <summary>
|
||||
/// The save event handler
|
||||
/// </summary>
|
||||
@@ -219,5 +231,5 @@ namespace umbraco.cms.businesslogic.web
|
||||
if (AfterDelete != null)
|
||||
AfterDelete(this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,7 +150,8 @@ namespace umbraco.editorControls.tinyMCE3
|
||||
if (styleSheetId.Trim() != "")
|
||||
try
|
||||
{
|
||||
var s = new StyleSheet(int.Parse(styleSheetId));
|
||||
var s = StyleSheet.GetStyleSheet(int.Parse(styleSheetId), false, false);
|
||||
|
||||
if (s.nodeObjectType == StyleSheet.ModuleObjectType)
|
||||
{
|
||||
cssFiles += IOHelper.ResolveUrl(SystemDirectories.Css + "/" + s.Text + ".css");
|
||||
|
||||
Reference in New Issue
Block a user