More SQL optimizations.

Fixes: 26866

[TFS Changeset #65734]
This commit is contained in:
Shandem
2010-04-24 06:14:20 +00:00
parent f57b24e270
commit f2e4350c0a
13 changed files with 238 additions and 125 deletions

View File

@@ -9,6 +9,7 @@ using umbraco.cms.businesslogic.propertytype;
using umbraco.DataLayer;
using System.Runtime.CompilerServices;
using umbraco.cms.helpers;
using umbraco.BusinessLogic;
namespace umbraco.cms.businesslogic
{
@@ -202,24 +203,24 @@ namespace umbraco.cms.businesslogic
{
get
{
//EnsureProperties();
//return m_LoadedProperties.ToArray();
EnsureProperties();
return m_LoadedProperties.ToArray();
if (this.ContentType == null)
return new Property[0];
//if (this.ContentType == null)
// return new Property[0];
List<Property> result = new List<Property>();
foreach (PropertyType prop in this.ContentType.PropertyTypes)
{
if (prop == null)
continue;
Property p = getProperty(prop);
if (p == null)
continue;
result.Add(p);
}
//List<Property> result = new List<Property>();
//foreach (PropertyType prop in this.ContentType.PropertyTypes)
//{
// if (prop == null)
// continue;
// Property p = getProperty(prop);
// if (p == null)
// continue;
// result.Add(p);
//}
return result.ToArray();
//return result.ToArray();
}
}
@@ -253,11 +254,13 @@ namespace umbraco.cms.businesslogic
#region Public Methods
/// <summary>
/// Used to persist object changes to the database. In Version3.0 it's just a stub for future compatibility
/// Used to persist object changes to the database. This ensures that the properties are re-loaded from the database.
/// </summary>
public override void Save()
{
{
base.Save();
ClearLoadedProperties();
}
/// <summary>
@@ -284,32 +287,31 @@ namespace umbraco.cms.businesslogic
public Property getProperty(PropertyType pt)
{
object o = SqlHelper.ExecuteScalar<object>(
"select id from cmsPropertyData where versionId=@version and propertyTypeId=@propertyTypeId",
SqlHelper.CreateParameter("@version", this.Version),
SqlHelper.CreateParameter("@propertyTypeId", pt.Id));
if (o == null)
return null;
int propertyId;
if (!int.TryParse(o.ToString(), out propertyId))
return null;
try
{
return new Property(propertyId, pt);
}
catch
{
return null;
}
//object o = SqlHelper.ExecuteScalar<object>(
// "select id from cmsPropertyData where versionId=@version and propertyTypeId=@propertyTypeId",
// SqlHelper.CreateParameter("@version", this.Version),
// SqlHelper.CreateParameter("@propertyTypeId", pt.Id));
//if (o == null)
// return null;
//int propertyId;
//if (!int.TryParse(o.ToString(), out propertyId))
// return null;
//try
//{
// return new Property(propertyId, pt);
//}
//catch (Exception ex)
//{
// Log.Add(LogTypes.Error, this.Id, "An error occurred retreiving property. EXCEPTION: " + ex.Message);
// return null;
//}
EnsureProperties();
//EnsureProperties();
//var prop = m_LoadedProperties
// .Where(x => x.PropertyType.Id == pt.Id)
// .SingleOrDefault();
//return prop;
var prop = m_LoadedProperties
.Where(x => x.PropertyType.Id == pt.Id)
.SingleOrDefault();
return prop;
}
@@ -321,7 +323,10 @@ namespace umbraco.cms.businesslogic
/// <returns>The new Property</returns>
public Property addProperty(PropertyType pt, Guid versionId)
{
ClearLoadedProperties();
return property.Property.MakeNew(pt, this, versionId);
}
/// <summary>
@@ -440,6 +445,30 @@ namespace umbraco.cms.businesslogic
x.AppendChild(c.ToXml(xd, true));
}
}
/// <summary>
/// Deletes the current Content object, must be overridden in the child class.
/// </summary>
public override void delete()
{
ClearLoadedProperties();
// Delete all data associated with this content
this.deleteAllProperties();
// Delete version history
SqlHelper.ExecuteNonQuery("Delete from cmsContentVersion where ContentId = " + this.Id);
// Delete Contentspecific data ()
SqlHelper.ExecuteNonQuery("Delete from cmsContent where NodeId = " + this.Id);
// Delete xml
SqlHelper.ExecuteNonQuery("delete from cmsContentXml where nodeID = @nodeId", SqlHelper.CreateParameter("@nodeId", this.Id));
// Delete Nodeinformation!!
base.delete();
}
#endregion
#region Protected Methods
@@ -453,6 +482,8 @@ namespace umbraco.cms.businesslogic
/// <param name="InitContentTypeIcon"></param>
protected void InitializeContent(int InitContentType, Guid InitVersion, DateTime InitVersionDate, string InitContentTypeIcon)
{
ClearLoadedProperties();
if (_contentType == null)
_contentType = ContentType.GetContentType(InitContentType);
_version = InitVersion;
@@ -477,6 +508,8 @@ namespace umbraco.cms.businesslogic
/// <returns>The new version Id</returns>
protected Guid createNewVersion()
{
ClearLoadedProperties();
Guid newVersion = Guid.NewGuid();
bool tempHasVersion = hasVersion();
foreach (propertytype.PropertyType pt in this.ContentType.PropertyTypes)
@@ -498,28 +531,6 @@ namespace umbraco.cms.businesslogic
return newVersion;
}
/// <summary>
/// Deletes the current Content object, must be overridden in the child class.
/// </summary>
protected new void delete()
{
// Delete all data associated with this content
this.deleteAllProperties();
// Delete version history
SqlHelper.ExecuteNonQuery("Delete from cmsContentVersion where ContentId = " + this.Id);
// Delete Contentspecific data ()
SqlHelper.ExecuteNonQuery("Delete from cmsContent where NodeId = " + this.Id);
// Delete xml
SqlHelper.ExecuteNonQuery("delete from cmsContentXml where nodeID = @nodeId", SqlHelper.CreateParameter("@nodeId", this.Id));
// Delete Nodeinformation!!
base.delete();
}
protected virtual XmlNode generateXmlWithoutSaving(XmlDocument xd)
{
string nodeName = UmbracoSettings.UseLegacyXmlSchema ? "node" : Casing.SafeAlias(ContentType.Alias);
@@ -552,6 +563,14 @@ namespace umbraco.cms.businesslogic
#region Private Methods
/// <summary>
/// Clears the locally loaded properties which forces them to be reloaded next time they requested
/// </summary>
private void ClearLoadedProperties()
{
m_LoadedProperties = null;
}
/// <summary>
/// Makes sure that the properties are initialized. If they are already initialized, this does nothing.
/// </summary>

View File

@@ -55,39 +55,63 @@ namespace umbraco.cms.businesslogic.datatype
// get it by lookup the value associated to the datatypedefinition id.
public string DataFieldName
{
get {
if (_datafield == "")
{
get
{
if (_datafield == "")
{
string dbtypestr = SqlHelper.ExecuteScalar<string>("select dbType from cmsDataType where nodeId = @datadefinitionid", SqlHelper.CreateParameter("@datadefinitionid", _datatypedefinitionid));
DBTypes DataTypeSQLType = (DBTypes) Enum.Parse(typeof(DBTypes),dbtypestr,true);
_DBType = DataTypeSQLType;
switch (DataTypeSQLType)
{
case DBTypes.Date :
_datafield = "dataDate";
break;
case DBTypes.Integer :
_datafield = "DataInt";
break;
case DBTypes.Ntext :
_datafield = "dataNtext";
break;
case DBTypes.Nvarchar :
_datafield = "dataNvarchar";
break;
}
return _datafield;
}
return _datafield;
}
DBTypes DataTypeSQLType = GetDBType(dbtypestr);
_DBType = DataTypeSQLType;
_datafield = GetDataFieldName(_DBType);
}
return _datafield;
}
}
#endregion
}
public enum DBTypes
{
Integer,
Date,
Nvarchar,
Ntext
/// <summary>
/// This is used internally for performance reasons since we are querying for all of the data properties at once in the
/// DefaultData object, therefore, the DefaultDataObject will set these properties manually instead of incurring a bunch
/// of additional SQL calls.
/// </summary>
/// <param name="dataField"></param>
/// <param name="dataType"></param>
internal void SetDataTypeProperties(string dataField, DBTypes dataType)
{
_datafield = dataField;
_DBType = dataType;
}
/// <summary>
/// Returns the DBType based on the row value in the dbType column of the cmsDataType
/// </summary>
/// <param name="dbtypestr"></param>
/// <returns></returns>
internal static DBTypes GetDBType(string dbtypestr)
{
return (DBTypes)Enum.Parse(typeof(DBTypes), dbtypestr, true);
}
/// <summary>
/// Returns the data column for the data base where the value resides based on the dbType
/// </summary>
/// <param name="dbType"></param>
/// <returns></returns>
internal static string GetDataFieldName(DBTypes dbType)
{
switch (dbType)
{
case DBTypes.Date:
return "dataDate";
case DBTypes.Integer:
return "dataInt";
case DBTypes.Ntext:
return "dataNtext";
case DBTypes.Nvarchar:
return "dataNvarchar";
default:
return "dataNvarchar";
}
}
}
}

View File

@@ -0,0 +1,15 @@
using System;
using System.Data;
using umbraco.DataLayer;
using umbraco.BusinessLogic;
namespace umbraco.cms.businesslogic.datatype
{
public enum DBTypes
{
Integer,
Date,
Nvarchar,
Ntext
}
}

View File

@@ -17,6 +17,7 @@ namespace umbraco.cms.businesslogic.datatype
private object m_Value;
protected BaseDataType _dataType;
private bool m_PreviewMode;
private bool m_ValueLoaded = false;
protected static ISqlHelper SqlHelper
{
@@ -48,7 +49,34 @@ namespace umbraco.cms.businesslogic.datatype
/// </summary>
protected virtual void LoadValueFromDatabase()
{
m_Value = SqlHelper.ExecuteScalar<object>("SELECT " + _dataType.DataFieldName + " FROM cmsPropertyData WHERE id = " + m_PropertyId);
//this is an optimized version of this query. In one call it will return the data type
//and the values, this will then set the underlying db type and value of the BaseDataType object
//instead of having it query the database itself.
var sql = @"
SELECT dataInt, dataDate, dataNvarchar, dataNtext, dbType FROM cmsPropertyData
INNER JOIN cmsPropertyType ON cmsPropertyType.id = cmsPropertyData.propertytypeid
INNER JOIN cmsDataType ON cmsDataType.nodeId = cmsPropertyType.dataTypeId
WHERE cmsPropertyData.id = " + m_PropertyId;
using (var r = SqlHelper.ExecuteReader(sql))
{
if (r.Read())
{
//the type stored in the cmsDataType table
var strDbType = r.GetString("dbType");
//get the enum of the data type
var dbType = BaseDataType.GetDBType(strDbType);
//get the column name in the cmsPropertyData table that stores the correct information for the data type
var fieldName = BaseDataType.GetDataFieldName(dbType);
//get the value for the data type, if null, set it to an empty string
m_Value = r.GetObject(fieldName) ?? string.Empty;
//now that we've set our value, we can update our BaseDataType object with the correct values from the db
//instead of making it query for itself. This is a peformance optimization enhancement.
_dataType.SetDataTypeProperties(fieldName, dbType);
}
}
}
public DBTypes DatabaseType
@@ -82,6 +110,12 @@ namespace umbraco.cms.businesslogic.datatype
{
get
{
//Lazy load the value when it is required.
if (!m_ValueLoaded)
{
LoadValueFromDatabase();
m_ValueLoaded = true;
}
return m_Value;
}
set
@@ -140,7 +174,7 @@ namespace umbraco.cms.businesslogic.datatype
set
{
m_PropertyId = value;
LoadValueFromDatabase();
//LoadValueFromDatabase();
}
}

View File

@@ -79,7 +79,7 @@ namespace umbraco.cms.businesslogic.web
{
using (IRecordsReader dr =
SqlHelper.ExecuteReader(string.Format(m_SQLOptimizedSingle, "umbracoNode.id = @id", "cmsContentVersion.id desc"),
SqlHelper.ExecuteReader(string.Format(m_SQLOptimizedSingle.Trim(), "umbracoNode.id = @id", "cmsContentVersion.id desc"),
SqlHelper.CreateParameter("@id", id)))
{
if (dr.Read())

View File

@@ -172,6 +172,7 @@
<Compile Include="Actions\IActionHandler.cs" />
<Compile Include="businesslogic\CMSPreviewNode.cs" />
<Compile Include="businesslogic\datatype\ClientDependencyAttribute.cs" />
<Compile Include="businesslogic\datatype\DBTypes.cs" />
<Compile Include="businesslogic\ISaveHandlerContents.cs" />
<Compile Include="businesslogic\Packager\FileResources\PackageFiles.Designer.cs">
<AutoGen>True</AutoGen>

View File

@@ -194,7 +194,7 @@ namespace umbraco.DataLayer
P[] parametersConverted = ConvertParameters(parameters);
try
{
return ConvertScalar<T>(ExecuteScalar(commandConverted, parametersConverted));
return ConvertScalar<T>(ExecuteScalar(commandConverted.TrimToOneLine(), parametersConverted));
}
catch (Exception e)
{
@@ -217,7 +217,7 @@ namespace umbraco.DataLayer
P[] parametersConverted = ConvertParameters(parameters);
try
{
return ExecuteNonQuery(commandConverted, parametersConverted);
return ExecuteNonQuery(commandConverted.TrimToOneLine(), parametersConverted);
}
catch (Exception e)
{
@@ -239,8 +239,8 @@ namespace umbraco.DataLayer
string commandConverted = ConvertCommand(commandText);
P[] parametersConverted = ConvertParameters(parameters);
try
{
return ExecuteReader(commandConverted, parametersConverted);
{
return ExecuteReader(commandConverted.TrimToOneLine(), parametersConverted);
}
catch (Exception e)
{
@@ -263,7 +263,7 @@ namespace umbraco.DataLayer
P[] parametersConverted = ConvertParameters(parameters);
try
{
return ExecuteXmlReader(commandConverted, parametersConverted);
return ExecuteXmlReader(commandConverted.TrimToOneLine(), parametersConverted);
}
catch (Exception e)
{

View File

@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace umbraco.DataLayer
{
public static class StringExtensions
{
/// <summary>
/// This trims all white spaces from beginning and end of the string and removes any line breaks (repacing with a space)
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static string TrimToOneLine(this string str)
{
return str.Replace(Environment.NewLine, " ").Trim();
}
}
}

View File

@@ -94,6 +94,7 @@
</Compile>
<Compile Include="SqlHelpers\SqlServer\SqlServerInstaller.cs" />
<Compile Include="SqlHelpers\SqlServer\SqlServerUtility.cs" />
<Compile Include="StringExtensions.cs" />
<Compile Include="UmbracoException.cs" />
<Compile Include="Utility\BaseUtility.cs" />
<Compile Include="Utility\Installer\DatabaseVersion.cs" />

View File

@@ -32,8 +32,7 @@ namespace umbraco.controls
public event EventHandler Save;
private publishModes CanPublish = publishModes.NoPublish;
public TabPage tpProp;
public bool DoesPublish = false;
private Hashtable inTab = new Hashtable();
public bool DoesPublish = false;
public TextBox NameTxt = new TextBox();
public PlaceHolder NameTxtHolder = new PlaceHolder();
public RequiredFieldValidator NameTxtValidator = new RequiredFieldValidator();
@@ -100,6 +99,8 @@ namespace umbraco.controls
Save += new EventHandler(standardSaveAndPublishHandler);
prntpage = (UmbracoEnsuredPage)Page;
int i = 0;
var inTab = new Hashtable();
foreach (ContentType.TabI t in _content.ContentType.getVirtualTabs.ToList())
{
var tp = this.Panels[i] as TabPage;
@@ -124,13 +125,21 @@ namespace umbraco.controls
i++;
}
// Add property pane
tpProp = NewTabPage(ui.Text("general", "properties", null));
addSaveAndPublishButtons(ref tpProp);
tpProp.Controls.Add(
new LiteralControl("<div id=\"errorPane_" + tpProp.ClientID +
"\" style=\"display: none; text-align: left; color: red;width: 100%; border: 1px solid red; background-color: #FCDEDE\"><div><b>There were errors - data has not been saved!</b><br/></div></div>"));
//if the property is not in a tab, add it to the general tab
var props = _content.GenericProperties;
foreach (Property p in props)
{
if (inTab[p.PropertyType.Id.ToString()] == null)
addControlNew(p, tpProp, ui.Text("general", "properties", null));
}
}
/// <summary>
@@ -185,13 +194,7 @@ namespace umbraco.controls
}
protected override void OnLoad(EventArgs e)
{
var props = _content.getProperties;
foreach (Property p in props)
{
if (inTab[p.PropertyType.Id.ToString()] == null)
addControlNew(p, tpProp, ui.Text("general", "properties", null));
}
{
base.OnLoad(e);
ContentControlLoadEventArgs contentcontrolEvent = new ContentControlLoadEventArgs();

View File

@@ -7,6 +7,7 @@ namespace dashboardUtilities
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using umbraco.IO;
using umbraco.cms.businesslogic.web;
/// <summary>
/// Summary description for LatestEdits.
@@ -35,17 +36,10 @@ namespace dashboardUtilities
printedIds.Add(NodeId);
try
{
umbraco.cms.businesslogic.web.Document d = new umbraco.cms.businesslogic.web.Document(int.Parse(NodeId.ToString()));
string parent = "";
try
{
if (d.Parent != null)
parent = " (" + d.Parent.Text + ")";
}
catch {}
Document d = new Document(int.Parse(NodeId.ToString()));
count++;
return
"<a href=\"editContent.aspx?id=" + NodeId.ToString() + "\" style=\"text-decoration: none\"><img src=\"" + IOHelper.ResolveUrl(SystemDirectories.Umbraco) + "/images/forward.png\" align=\"absmiddle\" border=\"0\"/> " + d.Text + parent + "</a>. " + umbraco.ui.Text("general", "edited", bp.getUser()) + " " + umbraco.library.ShortDateWithTimeAndGlobal(DateTime.Parse(Date.ToString()).ToString(), umbraco.ui.Culture(bp.getUser())) + "<br/>";
"<a href=\"editContent.aspx?id=" + NodeId.ToString() + "\" style=\"text-decoration: none\"><img src=\"" + IOHelper.ResolveUrl(SystemDirectories.Umbraco) + "/images/forward.png\" align=\"absmiddle\" border=\"0\"/> " + d.Text + "</a>. " + umbraco.ui.Text("general", "edited", bp.getUser()) + " " + umbraco.library.ShortDateWithTimeAndGlobal(DateTime.Parse(Date.ToString()).ToString(), umbraco.ui.Culture(bp.getUser())) + "<br/>";
}
catch {
return "";

View File

@@ -12,7 +12,7 @@
</xsl:template>
<!-- Add trace output -->
<xsl:template match="/configuration">
<!--<xsl:template match="/configuration">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates/>
@@ -24,7 +24,7 @@
</trace>
</system.diagnostics>
</xsl:copy>
</xsl:template>
</xsl:template>-->
<!-- Default templates to match anything else -->
<xsl:template match="@*">

View File

@@ -20,7 +20,7 @@
</xsl:template>
<!-- Add trace output -->
<xsl:template match="/configuration">
<!--<xsl:template match="/configuration">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates/>
@@ -32,7 +32,7 @@
</trace>
</system.diagnostics>
</xsl:copy>
</xsl:template>
</xsl:template>-->
<!-- Default templates to match anything else -->
<xsl:template match="@*">