BusinessMgr 3.0.1.6
This commit is contained in:
@@ -15,6 +15,7 @@ namespace Sarand.Net.Standard.Base.Dbas
|
||||
LeftOuter,
|
||||
RightOuter,
|
||||
FullOuter,
|
||||
OuterApply,
|
||||
Cross,
|
||||
}
|
||||
public enum DbOrderByNullMode
|
||||
@@ -87,6 +88,7 @@ namespace Sarand.Net.Standard.Base.Dbas
|
||||
case DbJoinType.LeftOuter: return (DbGlobalDbms.Type == DbmsType.Sage ? "LEFT JOIN" : "LEFT OUTER JOIN");
|
||||
case DbJoinType.RightOuter: return (DbGlobalDbms.Type == DbmsType.Sage ? "RIGHT JOIN" : "RIGHT OUTER JOIN");
|
||||
case DbJoinType.FullOuter: return (DbGlobalDbms.Type == DbmsType.Sage ? "FULL JOIN" : "FULL OUTER JOIN");
|
||||
case DbJoinType.OuterApply: return ("OUTER APPLY");
|
||||
case DbJoinType.Cross: return "CROSS JOIN";
|
||||
case DbJoinType.Inner:
|
||||
default: return "INNER JOIN";
|
||||
@@ -134,10 +136,11 @@ namespace Sarand.Net.Standard.Base.Dbas
|
||||
foreach (var subJoin in SubJoins)
|
||||
{
|
||||
// Add another bracket in front of the table:
|
||||
joinTable = "(" + joinTable;
|
||||
joinTable = $"({joinTable}";
|
||||
// Add the sub join.
|
||||
subJoinData += subJoin.BuildJoin("") + ")";
|
||||
subJoinData += $"{subJoin.BuildJoin("")})";
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
// Build this join's list of filter conditions.
|
||||
// Take care not to add too many embedded brackets - confuses Access etc.
|
||||
// [Original version: lFilter.Concat (" AND ", "(", ")", true, true)].
|
||||
@@ -149,36 +152,39 @@ namespace Sarand.Net.Standard.Base.Dbas
|
||||
if (filterClause.IsEmpty()) continue;
|
||||
// Embed the clause in brackets if it contains at least one 'OR' operator.
|
||||
if (filterClause.IndexOf(" OR ", StringComparison.OrdinalIgnoreCase) >= 0)
|
||||
filterClause = "(" + filterClause + ")";
|
||||
filterClause = $"({filterClause})";
|
||||
filter += (!filter.IsEmpty() ? " AND " : "") + filterClause;
|
||||
}
|
||||
// Surround the entire filter in brackets (if not already done).
|
||||
if (filter.FindMatchingBrace(0) != filter.Length)
|
||||
filter = "(" + filter + ")";
|
||||
if (!StringUtil.IsBlank(filter) && filter.FindMatchingBrace(0) != filter.Length)
|
||||
filter = $"({filter})";
|
||||
//---------------------------------------------------------------
|
||||
// Build the join.
|
||||
if (enclosedJoin.IsEmpty() && subJoinData.IsEmpty())
|
||||
{
|
||||
//-----------------------------------------------------------
|
||||
// Simple join syntax.
|
||||
// <Join-Type> <Join-Table> ON <Join-Filter>
|
||||
joinData = joinType + " " + joinTable + " ON " + filter;
|
||||
//-----------------------------------------------------------
|
||||
joinData = $"{joinType} {joinTable}";
|
||||
}
|
||||
else
|
||||
{
|
||||
//-----------------------------------------------------------
|
||||
// More complex join syntax - nested joins.
|
||||
// <Join-Type> (<Join-Table> <NestedJoin>) ON <Join-Filter>
|
||||
//-----------------------------------------------------------
|
||||
// Bracket the table, enclosing any enclosed or subordinate joins.
|
||||
joinData = joinType + " (" + joinTable;
|
||||
joinData = $"{joinType} ({joinTable}";
|
||||
if (!subJoinData.IsEmpty())
|
||||
joinData += " " + subJoinData;
|
||||
joinData += $" {subJoinData}";
|
||||
if (!enclosedJoin.IsEmpty())
|
||||
joinData += " " + enclosedJoin;
|
||||
joinData += ") ON " + filter;
|
||||
//-----------------------------------------------------------
|
||||
joinData += $" {enclosedJoin}";
|
||||
joinData += ")";
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
// Add the join filter.
|
||||
if (Type != DbJoinType.OuterApply)
|
||||
joinData += $" ON {filter}";
|
||||
else if (!StringUtil.IsBlank(filter))
|
||||
SaLogger.Warn($"{SysUtil.Fn} Filter found on 'Outer Apply' join: '{filter}'.");
|
||||
//---------------------------------------------------------------
|
||||
return joinData;
|
||||
}
|
||||
|
||||
@@ -187,13 +193,13 @@ namespace Sarand.Net.Standard.Base.Dbas
|
||||
public void Dump()
|
||||
{
|
||||
SaLogger.Debug($"{SysUtil.Fn}");
|
||||
SaLogger.Debug("\tType = " + GetJoinType(Type));
|
||||
SaLogger.Debug("\tTable = " + Table.Concat(" AS "));
|
||||
SaLogger.Debug("\tFilters = " + Filters.Concat("", "\t\t", "\n"));
|
||||
SaLogger.Debug($"\tType = {GetJoinType(Type)}");
|
||||
SaLogger.Debug($"\tTable = {Table.Concat(" AS ")}");
|
||||
SaLogger.Debug($"\tFilters = {Filters.Concat("", "\t\t", "\n")}");
|
||||
if (SubJoins.Count > 0)
|
||||
{
|
||||
}
|
||||
SaLogger.Debug("\tJoin = " + BuildJoin(""));
|
||||
SaLogger.Debug($"\tJoin = {BuildJoin("")}");
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
@@ -229,8 +235,8 @@ namespace Sarand.Net.Standard.Base.Dbas
|
||||
foreach (var join in joins)
|
||||
{
|
||||
// Add the next join in the list.
|
||||
if (++joinCount > 1 && !joinData.IsEmpty()) joinData = "(" + joinData + ")";
|
||||
joinData = joinData + " " + join.BuildJoin("");
|
||||
if (++joinCount > 1 && !joinData.IsEmpty()) joinData = $"({joinData})";
|
||||
joinData = $"{joinData} {join.BuildJoin("")}";
|
||||
joinData.Trim();
|
||||
}
|
||||
}
|
||||
@@ -247,7 +253,7 @@ namespace Sarand.Net.Standard.Base.Dbas
|
||||
joinData = join.BuildJoin(joinData);
|
||||
joinData.Trim();
|
||||
}
|
||||
joinData = primaryTable + " " + joinData;
|
||||
joinData = $"{primaryTable} {joinData}";
|
||||
}
|
||||
}
|
||||
return joinData;
|
||||
@@ -342,14 +348,14 @@ namespace Sarand.Net.Standard.Base.Dbas
|
||||
if (!rawValue.IsEmpty() || !ignoreBlanks)
|
||||
{
|
||||
if (stringData)
|
||||
value = "'" + FormatForCondition(value) + "'";
|
||||
value = $"'{FormatForCondition(value)}'";
|
||||
else value.Trim(); // Non string data can be cleansed.
|
||||
values.Add(value);
|
||||
}
|
||||
}
|
||||
values.RemoveDuplicatesCI();
|
||||
if (values.Count > 0)
|
||||
result = "(" + values.Concat(",") + ")";
|
||||
result = $"({values.Concat(",")})";
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -412,7 +418,7 @@ namespace Sarand.Net.Standard.Base.Dbas
|
||||
{
|
||||
// Surround the expression in brackets if not present.
|
||||
if (expression.Left(1) != "(")
|
||||
expression = "(" + expression + ")";
|
||||
expression = $"({expression})";
|
||||
// Logic to include or exclude null values.
|
||||
if (excludeNulls)
|
||||
{
|
||||
@@ -443,7 +449,7 @@ namespace Sarand.Net.Standard.Base.Dbas
|
||||
{
|
||||
// Surround the expression in brackets if not present.
|
||||
if (expression.Left(1) != "(")
|
||||
expression = "(" + expression + ")";
|
||||
expression = $"({expression})";
|
||||
// Logic to promote null values to start of sequence or demote null values to the end of the sequence.
|
||||
String nullsClause = String.Empty;
|
||||
if (nullMode == DbOrderByNullMode.PromoteNulls || nullMode == DbOrderByNullMode.DatePromoteNulls)
|
||||
@@ -452,15 +458,15 @@ namespace Sarand.Net.Standard.Base.Dbas
|
||||
{
|
||||
// Treat NULLs before other values.
|
||||
List<String> nullsFilters = new List<String>();
|
||||
nullsFilters.Add(expression + " IS NULL");
|
||||
nullsFilters.Add($"{expression} IS NULL");
|
||||
if (treatZeroAsNull)
|
||||
nullsFilters.Add(expression + "=0");
|
||||
nullsFilters.Add($"{expression}=0");
|
||||
if (nullMode == DbOrderByNullMode.DatePromoteNulls)
|
||||
nullsFilters.Add(expression + "<=" + FormatDateForCondition(NullDate));
|
||||
nullsClause = "(CASE WHEN " + nullsFilters.Concat(" OR ", "(", ")") + " THEN 0 ELSE 1 END)";
|
||||
nullsFilters.Add($"{expression}<={FormatDateForCondition(NullDate)}");
|
||||
nullsClause = $"(CASE WHEN {nullsFilters.Concat(" OR ", "(", ")")} THEN 0 ELSE 1 END)";
|
||||
}
|
||||
else
|
||||
nullsClause = expression + " IS NULL";
|
||||
nullsClause = $"{expression} IS NULL";
|
||||
}
|
||||
else if (nullMode == DbOrderByNullMode.DemoteNulls || nullMode == DbOrderByNullMode.DateDemoteNulls)
|
||||
{
|
||||
@@ -472,15 +478,15 @@ namespace Sarand.Net.Standard.Base.Dbas
|
||||
if (treatZeroAsNull)
|
||||
nullsFilters.Add(expression + "=0");
|
||||
if (nullMode == DbOrderByNullMode.DateDemoteNulls)
|
||||
nullsFilters.Add(expression + "<=" + FormatDateForCondition(NullDate));
|
||||
nullsClause = "(CASE WHEN " + nullsFilters.Concat(" OR ", "(", ")") + " THEN 1 ELSE 0 END)";
|
||||
nullsFilters.Add($"{expression}<={FormatDateForCondition(NullDate)}");
|
||||
nullsClause = $"(CASE WHEN {nullsFilters.Concat(" OR ", "(", ")")} THEN 1 ELSE 0 END)";
|
||||
}
|
||||
else
|
||||
nullsClause = expression + " IS NOT NULL";
|
||||
nullsClause = $"{expression} IS NOT NULL";
|
||||
}
|
||||
if (!nullsClause.IsEmpty()) orderBy.Add(nullsClause);
|
||||
// Main clause for this expression.
|
||||
orderBy.Add(expression + " " + (ascending ? "ASC" : "DESC"));
|
||||
orderBy.Add($"{expression} {(ascending ? "ASC" : "DESC")}");
|
||||
}
|
||||
return orderBy;
|
||||
}
|
||||
@@ -617,7 +623,7 @@ namespace Sarand.Net.Standard.Base.Dbas
|
||||
}
|
||||
if (interval.IsEmpty()) return "''";
|
||||
}
|
||||
return "DateDiff(" + interval + "," + column1 + "," + column2 + ")";
|
||||
return $"DateDiff({interval},{column1},{column2})";
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
@@ -643,7 +649,7 @@ namespace Sarand.Net.Standard.Base.Dbas
|
||||
#if DEBUG
|
||||
else
|
||||
{
|
||||
SaLogger.Debug("BuildBitMappedFilter - Invalid bit (" + bit + ").");
|
||||
SaLogger.Debug($"BuildBitMappedFilter - Invalid bit ({bit}).");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -662,7 +668,7 @@ namespace Sarand.Net.Standard.Base.Dbas
|
||||
if (!clause.IsEmpty())
|
||||
{
|
||||
if (DbGlobalDbms.Type == DbmsType.MsSql)
|
||||
clause = "(" + clause + " <> 0)";
|
||||
clause = $"({clause} <> 0)";
|
||||
}
|
||||
return clause;
|
||||
}
|
||||
@@ -708,23 +714,23 @@ namespace Sarand.Net.Standard.Base.Dbas
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Start with the column names.
|
||||
String query = "SELECT ";
|
||||
if (DistinctRows) query += "DISTINCT ";
|
||||
if (RowLimit > 0) query += "TOP " + RowLimit.ToString() + " ";
|
||||
if (Columns.Count < 1) query += "* ";
|
||||
else query += Columns.Concat(" AS ", false).Concat(",");
|
||||
String query = "SELECT";
|
||||
if (DistinctRows) query += " DISTINCT";
|
||||
if (RowLimit > 0) query += $" TOP {RowLimit.ToString()}";
|
||||
if (Columns.Count < 1) query += " *";
|
||||
else query += $" {Columns.Concat(" AS ", false).Concat(",")}";
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Add the tables and joins.
|
||||
String tableAliasOperator = DbGlobalDbms.Type == DbmsType.Sage ? " " : " AS ";
|
||||
if (Tables.Count > 1 || Joins.Count < 1)
|
||||
{
|
||||
query += " FROM " + Tables.Concat(tableAliasOperator, false).Concat(",") + " " + Joins.BuildJoins("");
|
||||
query += $" FROM {Tables.Concat(tableAliasOperator, false).Concat(",")} {Joins.BuildJoins("")}";
|
||||
}
|
||||
else if (Tables.Count == 1)
|
||||
{
|
||||
// Table name is bracketed with multiple joins...
|
||||
query += " FROM " + Joins.BuildJoins(Tables.Concat(tableAliasOperator, false)[0]);
|
||||
// Single Table name is bracketed with multiple joins.
|
||||
query += $" FROM {Joins.BuildJoins(Tables.Concat(tableAliasOperator, false)[0])}";
|
||||
}
|
||||
query.TrimEnd(' ');
|
||||
|
||||
@@ -732,24 +738,24 @@ namespace Sarand.Net.Standard.Base.Dbas
|
||||
// Filters.
|
||||
String filter = Filters.Concat(" AND ", "(", ")", true, true);
|
||||
// Jan2019 Not required: if (Filters.Count > 1) filter = "(" + filter + ")";
|
||||
if (!filter.IsEmpty()) query += " WHERE " + filter;
|
||||
if (!filter.IsEmpty()) query += $" WHERE {filter}";
|
||||
|
||||
// Groupings.
|
||||
String groupByData = GroupBy.Concat(",", "", "", true, true);
|
||||
if (!groupByData.IsEmpty()) query += " GROUP BY " + groupByData;
|
||||
String groupByClause = GroupBy.Concat(",", "", "", true, true);
|
||||
if (!groupByClause.IsEmpty()) query += $" GROUP BY {groupByClause}";
|
||||
|
||||
// Sort sequence.
|
||||
String orderByData = OrderBy.Concat(",", "", "", true, true);
|
||||
if (!orderByData.IsEmpty()) query += " ORDER BY " + orderByData;
|
||||
String orderByClause = OrderBy.Concat(",", "", "", true, true);
|
||||
if (!orderByClause.IsEmpty()) query += $" ORDER BY {orderByClause}";
|
||||
|
||||
// Paging.
|
||||
if (paging != null && paging.Paged)
|
||||
{
|
||||
// Must have an 'Order By' clause to use 'Offset ... Fetch Next ...'
|
||||
if (orderByData.IsEmpty())
|
||||
if (orderByClause.IsEmpty())
|
||||
throw new NotSupportedException("Query paging requires sort order to be specified");
|
||||
if (DbGlobalDbms.Type == DbmsType.MsSql)
|
||||
query += " OFFSET " + ((paging.PageNo - 1) * paging.PageLength) + " ROWS FETCH NEXT " + paging.PageLength + " ROWS ONLY";
|
||||
query += $" OFFSET {((paging.PageNo - 1) * paging.PageLength)} ROWS FETCH NEXT {paging.PageLength} ROWS ONLY";
|
||||
else throw new NotSupportedException($"Query paging not supported for {DbGlobalDbms.Type}");
|
||||
}
|
||||
|
||||
@@ -757,7 +763,7 @@ namespace Sarand.Net.Standard.Base.Dbas
|
||||
#if DEBUG
|
||||
bool bDisplayDebugMsg = false;
|
||||
if (bDisplayDebugMsg)
|
||||
SaLogger.Debug("Query: " + query);
|
||||
SaLogger.Debug($"Query: {query}");
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user