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:
leekelleher
2012-06-29 10:32:20 -01:00
parent f513fb52c0
commit eed13fcfda
3 changed files with 153 additions and 150 deletions

View File

@@ -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

View File

@@ -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);
}
}
}
}

View File

@@ -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");