Fixes paging for MySQL (actually makes it a better query anyways), fixes null ref for member indexer, Fixes MNTP after upgrade from v6, fixes typo on migration downgrade.

This commit is contained in:
Shannon
2014-10-02 12:23:43 +10:00
parent 2ec8d124fd
commit 08ea69caae
6 changed files with 90 additions and 72 deletions

View File

@@ -635,7 +635,7 @@ namespace Umbraco.Core.Persistence.Repositories
return GetPagedResultsByQuery<DocumentDto, Content>(query, pageIndex, pageSize, out totalRecords,
"SELECT cmsDocument.nodeId",
new Tuple<string, string>("cmsDocument", "nodeId"),
ProcessQuery, orderBy, orderDirection,
filterCallback);

View File

@@ -388,7 +388,7 @@ namespace Umbraco.Core.Persistence.Repositories
}
return GetPagedResultsByQuery<ContentVersionDto, Models.Media>(query, pageIndex, pageSize, out totalRecords,
"SELECT cmsContentVersion.contentId",
new Tuple<string, string>("cmsContentVersion", "contentId"),
ProcessQuery, orderBy, orderDirection,
filterCallback);

View File

@@ -584,7 +584,7 @@ namespace Umbraco.Core.Persistence.Repositories
}
return GetPagedResultsByQuery<MemberDto, Member>(query, pageIndex, pageSize, out totalRecords,
"SELECT cmsMember.nodeId",
new Tuple<string, string>("cmsMember", "nodeId"),
ProcessQuery, orderBy, orderDirection,
filterCallback);
}

View File

@@ -225,6 +225,40 @@ namespace Umbraco.Core.Persistence.Repositories
}
}
private Sql GetFilteredSqlForPagedResults(Sql sql, Func<Tuple<string, object[]>> defaultFilter = null)
{
//copy to var so that the original isn't changed
var filteredSql = new Sql(sql.SQL, sql.Arguments);
// Apply filter
if (defaultFilter != null)
{
var filterResult = defaultFilter();
filteredSql.Append(filterResult.Item1, filterResult.Item2);
}
return filteredSql;
}
private Sql GetSortedSqlForPagedResults(Sql sql, Direction orderDirection, string orderBy)
{
//copy to var so that the original isn't changed
var sortedSql = new Sql(sql.SQL, sql.Arguments);
// Apply order according to parameters
if (string.IsNullOrEmpty(orderBy) == false)
{
var orderByParams = new[] { GetDatabaseFieldNameForOrderBy(orderBy) };
if (orderDirection == Direction.Ascending)
{
sortedSql.OrderBy(orderByParams);
}
else
{
sortedSql.OrderByDescending(orderByParams);
}
return sortedSql;
}
return sortedSql;
}
/// <summary>
/// A helper method for inheritors to get the paged results by query in a way that minimizes queries
/// </summary>
@@ -234,7 +268,7 @@ namespace Umbraco.Core.Persistence.Repositories
/// <param name="pageIndex">Index of the page.</param>
/// <param name="pageSize">Size of the page.</param>
/// <param name="totalRecords">The total records.</param>
/// <param name="nodeIdSelect">The SQL select statement fragment to return the node id from the query</param>
/// <param name="nodeIdSelect">The tablename + column name for the SELECT statement fragment to return the node id from the query</param>
/// <param name="defaultFilter">A callback to create the default filter to be applied if there is one</param>
/// <param name="processQuery">A callback to process the query result</param>
/// <param name="orderBy">The order by column</param>
@@ -242,7 +276,7 @@ namespace Umbraco.Core.Persistence.Repositories
/// <returns></returns>
/// <exception cref="System.ArgumentNullException">orderBy</exception>
protected IEnumerable<TEntity> GetPagedResultsByQuery<TDto,TContentBase>(IQuery<TEntity> query, int pageIndex, int pageSize, out int totalRecords,
string nodeIdSelect,
Tuple<string, string> nodeIdSelect,
Func<Sql, IEnumerable<TEntity>> processQuery,
string orderBy,
Direction orderDirection,
@@ -257,51 +291,18 @@ namespace Umbraco.Core.Persistence.Repositories
if (query == null) query = new Query<TEntity>();
var translator = new SqlTranslator<TEntity>(sqlBase, query);
var sqlQuery = translator.Translate();
Func<Sql, string, object[], Sql> getFilteredSql = (sql, additionalFilter, additionalFilterArgs) =>
{
//copy to var so that the original isn't changed
var filteredSql = new Sql(sql.SQL, sql.Arguments);
// Apply filter
if (defaultFilter != null)
{
var filterResult = defaultFilter();
filteredSql.Append(filterResult.Item1, filterResult.Item2);
}
if (string.IsNullOrEmpty(additionalFilter) == false)
{
filteredSql.Append("AND (" + additionalFilter + ")", additionalFilterArgs);
}
return filteredSql;
};
Func<Sql, Sql> getSortedSql = sql =>
{
//copy to var so that the original isn't changed
var sortedSql = new Sql(sql.SQL, sql.Arguments);
// Apply order according to parameters
if (string.IsNullOrEmpty(orderBy) == false)
{
var orderByParams = new[] { GetDatabaseFieldNameForOrderBy(orderBy) };
if (orderDirection == Direction.Ascending)
{
sortedSql.OrderBy(orderByParams);
}
else
{
sortedSql.OrderByDescending(orderByParams);
}
return sortedSql;
}
return sortedSql;
};
// Note we can't do multi-page for several DTOs like we can multi-fetch and are doing in PerformGetByQuery,
// but actually given we are doing a Get on each one (again as in PerformGetByQuery), we only need the node Id.
// So we'll modify the SQL.
var sqlNodeIds = new Sql(sqlQuery.SQL.Replace("SELECT *", nodeIdSelect), sqlQuery.Arguments);
var sqlNodeIdsWithSort = getSortedSql(getFilteredSql(sqlNodeIds, null, new object[0]));
var sqlNodeIds = new Sql(
sqlQuery.SQL.Replace("SELECT *", string.Format("SELECT {0}.{1}",nodeIdSelect.Item1, nodeIdSelect.Item2)),
sqlQuery.Arguments);
//get sorted and filtered sql
var sqlNodeIdsWithSort = GetSortedSqlForPagedResults(
GetFilteredSqlForPagedResults(sqlNodeIds, defaultFilter),
orderDirection, orderBy);
// Get page of results and total count
IEnumerable<TEntity> result;
@@ -314,19 +315,29 @@ namespace Umbraco.Core.Persistence.Repositories
string sqlStringCount, sqlStringPage;
Database.BuildPageQueries<TDto>(pageIndex * pageSize, pageSize, sqlNodeIdsWithSort.SQL, ref args, out sqlStringCount, out sqlStringPage);
//we now need to finalize/parse this query so that the args are built in to it, we know the args will only be two for this operation
//sqlPage = sqlPage.Replace("@0", args[0].ToString()).Replace("@1", args[1].ToString());
//if this is for sql server, the sqlPage will start with a SELECT * but we don't want that, we only want to return the nodeId
sqlStringPage = sqlStringPage
.Replace("SELECT *",
//This ensures we only take the field name of the node id select and not the table name - since the resulting select
// will ony work with the field name.
"SELECT " + nodeIdSelect.Item2);
//if this is for sql server, the sqlPage will start with a SELECT * but we don't want that, we only want to return the nodeId
var nodeIdSelectParts = nodeIdSelect.Split(new[] {'.'}, StringSplitOptions.RemoveEmptyEntries);
sqlStringPage = sqlStringPage.Replace("SELECT *",
//This ensures we only take the field name of the node id select and not the table name - since the resulting select
// will ony work with the field name.
"SELECT " + nodeIdSelectParts[nodeIdSelectParts.Length - 1]);
var fullQuery = getSortedSql(
getFilteredSql(sqlQuery, string.Format("umbracoNode.id IN ({0})", sqlStringPage), args));
//We need to make this an inner join on the paged query
var splitQuery = sqlQuery.SQL.Split(new[] {"WHERE "}, StringSplitOptions.None);
var withInnerJoinSql = new Sql(splitQuery[0])
.Append("INNER JOIN (")
//join the paged query with the paged query arguments
.Append(sqlStringPage, args)
.Append(") temp ")
.Append(string.Format("ON {0}.{1} = temp.{1}", nodeIdSelect.Item1, nodeIdSelect.Item2))
//add the original where clause back with the original arguments
.Where(splitQuery[1], sqlQuery.Arguments);
//get sorted and filtered sql
var fullQuery = GetSortedSqlForPagedResults(
GetFilteredSqlForPagedResults(withInnerJoinSql, defaultFilter),
orderDirection, orderBy);
var content = processQuery(fullQuery)
.Cast<TContentBase>()
.AsQueryable();

View File

@@ -67,18 +67,22 @@ namespace Umbraco.Web.PropertyEditors
}
//set the multiPicker val correctly depending on the maxNumber
var asNumber = result["maxNumber"].TryConvertTo<int>();
if (asNumber.Success)
if (result.ContainsKey("maxNumber"))
{
if (asNumber.Result <= 1)
var asNumber = result["maxNumber"].TryConvertTo<int>();
if (asNumber.Success)
{
result["multiPicker"] = "0";
}
else
{
result["multiPicker"] = "1";
}
if (asNumber.Result <= 1)
{
result["multiPicker"] = "0";
}
else
{
result["multiPicker"] = "1";
}
}
}
return result;
}

View File

@@ -29,11 +29,14 @@ namespace UmbracoExamine
private readonly IMemberService _memberService;
private readonly IDataTypeService _dataTypeService;
/// <summary>
/// Default constructor
/// </summary>
public UmbracoMemberIndexer()
: base() { }
/// <summary>
/// Default constructor
/// </summary>
public UmbracoMemberIndexer() : base()
{
_dataTypeService = ApplicationContext.Current.Services.DataTypeService;
_memberService = ApplicationContext.Current.Services.MemberService;
}
/// <summary>
/// Constructor to allow for creating an indexer at runtime