Saxonite 1.2.11.14

This commit is contained in:
Andy Howard
2024-08-27 19:49:17 +01:00
parent 209dd7ca93
commit 45b3069ce7
9 changed files with 109 additions and 52 deletions
+59 -39
View File
@@ -49,7 +49,7 @@ namespace Sarand.Net.Standard.Base.Dbas
// methods that depend on the value (especially static ones).
public class DbGlobalDbms
{
private DbGlobalDbms () { }
private DbGlobalDbms() { }
private static DbmsType dbms = DbmsType.General;
public static DbmsType Type
{
@@ -66,7 +66,7 @@ namespace Sarand.Net.Standard.Base.Dbas
//-------------------------------------------------------------------
// Construction.
public DbQueryJoin (DbJoinType type = DbJoinType.Inner)
public DbQueryJoin(DbJoinType type = DbJoinType.Inner)
{
this.Type = type;
}
@@ -80,7 +80,7 @@ namespace Sarand.Net.Standard.Base.Dbas
public List<DbQueryJoin> SubJoins { get; } = new List<DbQueryJoin>();
//-------------------------------------------------------------------
public static String GetJoinType (DbJoinType type)
public static String GetJoinType(DbJoinType type)
{
switch (type)
{
@@ -94,7 +94,7 @@ namespace Sarand.Net.Standard.Base.Dbas
}
//-------------------------------------------------------------------
public String BuildJoin (String enclosedJoin)
public String BuildJoin(String enclosedJoin)
{
//---------------------------------------------------------------
// Select syntax.
@@ -129,7 +129,7 @@ namespace Sarand.Net.Standard.Base.Dbas
// Sage doesn't use 'AS' to alias tables.
String tableAliasOperator = (DbGlobalDbms.Type == DbmsType.Sage ? " " : " AS ");
String joinType = GetJoinType(Type);
String joinTable = Table.Concat (tableAliasOperator, false);
String joinTable = Table.Concat(tableAliasOperator, false);
String subJoinData = String.Empty;
foreach (var subJoin in SubJoins)
{
@@ -184,7 +184,7 @@ namespace Sarand.Net.Standard.Base.Dbas
//-------------------------------------------------------------------
// Debugging.
public void Dump ()
public void Dump()
{
SaLogger.Debug($"{SysUtil.Fn}");
SaLogger.Debug("\tType = " + GetJoinType(Type));
@@ -204,7 +204,7 @@ namespace Sarand.Net.Standard.Base.Dbas
{
//-------------------------------------------------------------------
// List extensions.
public static String BuildJoins (this List<DbQueryJoin> joins, String primaryTable)
public static String BuildJoins(this List<DbQueryJoin> joins, String primaryTable)
{
String joinData = primaryTable;
if (joins.Count > 0)
@@ -265,6 +265,11 @@ namespace Sarand.Net.Standard.Base.Dbas
public uint PageNo { get; set; } = 0;
public ushort PageLength { get; set; } = 0;
public virtual bool Paged { get { return PageNo > 0 && PageLength > 0; } }
public void Set(uint pageNo, ushort pageLength)
{
this.PageNo = pageNo;
this.PageLength = pageLength;
}
}
//-------------------------------------------------------------------
@@ -272,7 +277,7 @@ namespace Sarand.Net.Standard.Base.Dbas
//-------------------------------------------------------------------
// Construction.
public DbQuery (DbmsType dbms)
public DbQuery(DbmsType dbms)
{
DbGlobalDbms.Type = dbms;
}
@@ -297,7 +302,7 @@ namespace Sarand.Net.Standard.Base.Dbas
/// Format the value so that it can be used in a conditional clause.
/// <para>- single quotes are duplicated.</para>
/// </summary>
public static String FormatForCondition (String value)
public static String FormatForCondition(String value)
{
return StringUtil.EmptyOnNull(value).Replace("'", "''");
}
@@ -308,7 +313,7 @@ namespace Sarand.Net.Standard.Base.Dbas
/// <para>- percent ('%') is enclosed in square brackets ('[%]') unless wildcards allowed.</para>
/// <para>- asterisk ('*') converted to percent ('%') if wildcards allowed.</para>
/// </summary>
public static String FormatForLike (String value, bool allowWildcards = false)
public static String FormatForLike(String value, bool allowWildcards = false)
{
value = StringUtil.EmptyOnNull(value).Replace("'", "''").Replace("[", "[[]");
if (allowWildcards)
@@ -327,7 +332,7 @@ namespace Sarand.Net.Standard.Base.Dbas
/// <para>- Format as: ('Value1','Value2','Value3') if string data, else (Value1,Value2,Value3) etc.</para>
/// <para>- Returns empty string if list is empty.</para>
/// </summary>
public static String FormatForIn (List<String> rawValues, bool stringData = true, bool ignoreBlanks = true)
public static String FormatForIn(List<String> rawValues, bool stringData = true, bool ignoreBlanks = true)
{
String result = String.Empty;
List<String> values = new List<String>();
@@ -351,14 +356,14 @@ namespace Sarand.Net.Standard.Base.Dbas
//-------------------------------------------------------------------
// D a t e V a l u e F o r m a t t i n g
//-------------------------------------------------------------------
public static String GetDateDelim ()
public static String GetDateDelim()
{
String delim = "#"; // MS Access only?
if (DbGlobalDbms.Type == DbmsType.MsSql)
delim = "'"; // MS SQL Server.
return delim;
}
public static String FormatDateForCondition (DateTime date, bool delimit = true, bool includeMidnight = false)
public static String FormatDateForCondition(DateTime date, bool delimit = true, bool includeMidnight = false)
{
String value = DateUtil.Format(date, "dd-MMM-yyyy");
if (includeMidnight)
@@ -370,9 +375,9 @@ namespace Sarand.Net.Standard.Base.Dbas
}
return value;
}
public static String FormatDateTimeForCondition (DateTime dateTime, bool delimit = true, bool precise = false)
public static String FormatDateTimeForCondition(DateTime dateTime, bool delimit = true, bool precise = false)
{
String value = DateUtil.Format(dateTime, "yyyy-MM-dd HH:mm:ss"+(precise?".fff":""));
String value = DateUtil.Format(dateTime, "yyyy-MM-dd HH:mm:ss" + (precise ? ".fff" : ""));
if (delimit)
{
String delim = GetDateDelim();
@@ -381,7 +386,7 @@ namespace Sarand.Net.Standard.Base.Dbas
return value;
}
public static String FormatTimeForCondition (DateTime time, bool delimit = true, bool zeroSeconds = false)
public static String FormatTimeForCondition(DateTime time, bool delimit = true, bool zeroSeconds = false)
{
String value = String.Empty;
if (zeroSeconds)
@@ -399,7 +404,7 @@ namespace Sarand.Net.Standard.Base.Dbas
//-------------------------------------------------------------------
// F o r m a t F o r F i l t e r
//-------------------------------------------------------------------
public static String FormatNullValueFilter (String expression, bool excludeNulls)
public static String FormatNullValueFilter(String expression, bool excludeNulls)
{
String clause = String.Empty;
expression = StringUtil.EmptyOnNull(expression).Trim();
@@ -430,7 +435,7 @@ namespace Sarand.Net.Standard.Base.Dbas
}
// Construct 'Order By' clauses, allowing direction (ASC/DESC) and whether
// to demote NULL values (push to end of sequence) into account.
public static List<String> FormatForOrderBy (String expression, bool ascending, DbOrderByNullMode nullMode = DbOrderByNullMode.Default, bool treatZeroAsNull = false)
public static List<String> FormatForOrderBy(String expression, bool ascending, DbOrderByNullMode nullMode = DbOrderByNullMode.Default, bool treatZeroAsNull = false)
{
List<String> orderBy = new List<string>();
expression = StringUtil.EmptyOnNull(expression).Trim();
@@ -485,25 +490,25 @@ namespace Sarand.Net.Standard.Base.Dbas
//-------------------------------------------------------------------
// NB Many functions depend on the DBMS in use.
// Default versions are for Access/SQL.
public static String FormatFn_Len (String column)
public static String FormatFn_Len(String column)
{
if (String.IsNullOrEmpty(column)) return "''";
// MS Access.
return "Len(" + column + ")";
}
public static String FormatFn_Left (String column, int length)
public static String FormatFn_Left(String column, int length)
{
if (String.IsNullOrEmpty(column) || length < 1) return "''";
// MS Access.
return "Left(" + column + "," + length.ToString() + ")";
}
public static String FormatFn_Right (String column, int length)
public static String FormatFn_Right(String column, int length)
{
if (String.IsNullOrEmpty(column) || length < 1) return "''";
// MS Access.
return "Right(" + column + "," + length.ToString() + ")";
}
public static String FormatFn_TimeValue (String expression)
public static String FormatFn_TimeValue(String expression)
{
if (DbGlobalDbms.Type == DbmsType.MsSql)
{
@@ -526,13 +531,13 @@ namespace Sarand.Net.Standard.Base.Dbas
//-------------------------------------------------------------------
// N u m e r i c F u n c t i o n s
//-------------------------------------------------------------------
public static String FormatFn_Abs (String sExpr)
public static String FormatFn_Abs(String sExpr)
{
if (sExpr.IsEmpty()) return "''";
return "Abs(" + sExpr + ")";
}
public static String FormatFn_Round (String expression, int decimals = 0)
public static String FormatFn_Round(String expression, int decimals = 0)
{
if (String.IsNullOrEmpty(expression) || decimals < 0) return "''";
if (DbGlobalDbms.Type == DbmsType.Access)
@@ -545,7 +550,7 @@ namespace Sarand.Net.Standard.Base.Dbas
return "Round(" + expression + "," + decimals.ToString() + ")";
}
public static String FormatFn_Truncate (String expression, int decimals = 0)
public static String FormatFn_Truncate(String expression, int decimals = 0)
{
if (String.IsNullOrEmpty(expression) || decimals < 0) return "''";
if (DbGlobalDbms.Type == DbmsType.MsSql)
@@ -554,13 +559,13 @@ namespace Sarand.Net.Standard.Base.Dbas
// MS Access.
if (decimals > 0)
{
String factor = ((long)(10^decimals)).ToString();
String factor = ((long)(10 ^ decimals)).ToString();
return "Int(" + expression + "*" + factor + "," + decimals.ToString() + ")/" + factor;
}
return "Int(" + expression + "," + decimals.ToString() + ")";
}
public static String FormatFn_FormatNumber (String expression, int decimals)
public static String FormatFn_FormatNumber(String expression, int decimals)
{
if (String.IsNullOrEmpty(expression) || decimals < 0) return "''";
// MS Access.
@@ -571,7 +576,7 @@ namespace Sarand.Net.Standard.Base.Dbas
// D a t e D i f f e r e n c e
//-------------------------------------------------------------------
// Date difference: eg. DateDiff('n',Col1,Col2).
public static String FormatFn_DateDiff (DbDateDiffInterval dateInterval, String column1, String column2)
public static String FormatFn_DateDiff(DbDateDiffInterval dateInterval, String column1, String column2)
{
if (column1.IsEmpty() || column2.IsEmpty()) return "''";
String interval = String.Empty;
@@ -618,7 +623,7 @@ namespace Sarand.Net.Standard.Base.Dbas
//-------------------------------------------------------------------
// B i t M a p p e d V a l u e s
//-------------------------------------------------------------------
public static String BuildBitMappedValue (String column, ushort bit, bool match)
public static String BuildBitMappedValue(String column, ushort bit, bool match)
{
// Filter clause to test for specific bit set in field.
String clause = String.Empty;
@@ -627,7 +632,7 @@ namespace Sarand.Net.Standard.Base.Dbas
if (bit > 0 && bit <= 32)
{
// The operation depends on whether the value should be matched or not.
String condition = (match? "<>" : "=");
String condition = (match ? "<>" : "=");
// Test is achieved by shifting the value so as to drop the target bit, shift back one bit
// and identify those value that then do not match the original value shifted by one place less.
// Example match: abcdefgh, Test bit 3: abcde0 <> abcdef
@@ -651,7 +656,7 @@ namespace Sarand.Net.Standard.Base.Dbas
return clause;
}
public static String BuildBitMappedFilter (String column, ushort bit, bool match)
public static String BuildBitMappedFilter(String column, ushort bit, bool match)
{
String clause = BuildBitMappedValue(column, bit, match);
if (!clause.IsEmpty())
@@ -662,10 +667,25 @@ namespace Sarand.Net.Standard.Base.Dbas
return clause;
}
//-------------------------------------------------------------------
// S o r t C o l u m n s
//-------------------------------------------------------------------
public static String GetRandomOrderSortColumn()
{
return GetRandomOrderSortColumn(DbGlobalDbms.Type);
}
public static String GetRandomOrderSortColumn(DbmsType dbms)
{
if (dbms == DbmsType.MsSql)
return "NewId()";
// ToDo: Random sort order by DBMS.
return "Random()";
}
//-------------------------------------------------------------------
// A t t r i b u t e s
//-------------------------------------------------------------------
public void Clear ()
public void Clear()
{
Tables.Clear();
Columns.Clear();
@@ -674,7 +694,7 @@ namespace Sarand.Net.Standard.Base.Dbas
OrderBy.Clear();
Joins.Clear();
}
public bool IsValid ()
public bool IsValid()
{
return (Tables.Count > 0);
}
@@ -682,7 +702,7 @@ namespace Sarand.Net.Standard.Base.Dbas
//-------------------------------------------------------------------
// B u i l d Q u e r y
//-------------------------------------------------------------------
public String BuildQuery (Paging paging = null)
public String BuildQuery(Paging paging = null)
{
if (Tables.Count < 1) return "";
@@ -696,7 +716,7 @@ namespace Sarand.Net.Standard.Base.Dbas
//---------------------------------------------------------------------
// Add the tables and joins.
String tableAliasOperator = DbGlobalDbms.Type == DbmsType.Sage? " " : " AS ";
String tableAliasOperator = DbGlobalDbms.Type == DbmsType.Sage ? " " : " AS ";
if (Tables.Count > 1 || Joins.Count < 1)
{
query += " FROM " + Tables.Concat(tableAliasOperator, false).Concat(",") + " " + Joins.BuildJoins("");
@@ -710,7 +730,7 @@ namespace Sarand.Net.Standard.Base.Dbas
//---------------------------------------------------------------------
// Filters.
String filter = Filters.Concat (" AND ", "(", ")", true, true);
String filter = Filters.Concat(" AND ", "(", ")", true, true);
// Jan2019 Not required: if (Filters.Count > 1) filter = "(" + filter + ")";
if (!filter.IsEmpty()) query += " WHERE " + filter;
@@ -728,9 +748,9 @@ namespace Sarand.Net.Standard.Base.Dbas
// Must have an 'Order By' clause to use 'Offset ... Fetch Next ...'
if (orderByData.IsEmpty())
throw new NotSupportedException("Query paging requires sort order to be specified");
if (DbGlobalDbms.Type != DbmsType.MsSql)
throw new NotSupportedException("Query paging only supported for MS SQL");
query += " OFFSET " + ((paging.PageNo - 1) * paging.PageLength) + " ROWS FETCH NEXT " + paging.PageLength + " ROWS ONLY";
if (DbGlobalDbms.Type == DbmsType.MsSql)
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}");
}
//---------------------------------------------------------------------
@@ -20,6 +20,7 @@ namespace Sarand.Net.Standard.Base.Dbas
FoxPro,
Paradox,
Interbase,
Postgres,
/// <summary>Sage db - No 'AS' in table alias, no 'OUTER' in join type.</summary>
Sage,
QBooks,