Saxonite v1.2.3
This commit is contained in:
@@ -20,8 +20,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution files", "Solution
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SacsStandardAccounts", "SacsStandardAccounts\SacsStandardAccounts.csproj", "{C62999E2-1947-4EB7-82D2-A0EDB67D2F10}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SaBusMgrCoreProcs", "..\..\BusinessMgr\Workspace\SaBusMgrCoreProcs\SaBusMgrCoreProcs.csproj", "{452FC874-81D6-4858-A6F4-0337AA656D23}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -52,10 +50,6 @@ Global
|
||||
{C62999E2-1947-4EB7-82D2-A0EDB67D2F10}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C62999E2-1947-4EB7-82D2-A0EDB67D2F10}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C62999E2-1947-4EB7-82D2-A0EDB67D2F10}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{452FC874-81D6-4858-A6F4-0337AA656D23}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{452FC874-81D6-4858-A6F4-0337AA656D23}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{452FC874-81D6-4858-A6F4-0337AA656D23}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{452FC874-81D6-4858-A6F4-0337AA656D23}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Sarand.Net.Standard.Base.Helpers;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
|
||||
namespace Sacs.UnitTests.Net.Standard.Base.Helpers
|
||||
{
|
||||
//=======================================================================
|
||||
[TestClass]
|
||||
public class SacsRandomHelper_Tester
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Random Helper.
|
||||
//-------------------------------------------------------------------
|
||||
// Fill byte array.
|
||||
[TestMethod]
|
||||
public void Fill_ByteArray()
|
||||
{
|
||||
int dataLength = 10;
|
||||
byte[] data = new byte[dataLength];
|
||||
Assert.IsNotNull(data);
|
||||
|
||||
// Initial values should be zero.
|
||||
for (int i = 0; i < dataLength; i++)
|
||||
Assert.AreEqual(0, data[i]);
|
||||
|
||||
SacsRandomHelper.Fill(data);
|
||||
|
||||
// Sum of data values should no longer be zero.
|
||||
int total = 0;
|
||||
for (int i = 0; i < dataLength; i++)
|
||||
total += data[i];
|
||||
Assert.AreNotEqual(0, total);
|
||||
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
[TestMethod]
|
||||
public void GetInt32_ToExclusive()
|
||||
{
|
||||
for (int i = 1; i < 1000; i++)
|
||||
{
|
||||
int value = SacsRandomHelper.GetInt32(i);
|
||||
Assert.IsTrue(value >= 0);
|
||||
Assert.IsTrue(value < i);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
[TestMethod]
|
||||
public void GetInt32_FromInclusive_ToExclusive()
|
||||
{
|
||||
for (int i = -100; i < 101; i++)
|
||||
{
|
||||
for (int j = i + 1; j < i + 100; j++)
|
||||
{
|
||||
int value = SacsRandomHelper.GetInt32(i, j);
|
||||
//Debug.WriteLine("Value: "+value);
|
||||
Assert.IsTrue(value >= i);
|
||||
Assert.IsTrue(value < j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
[TestMethod]
|
||||
public void GetInt32_getRandomLengthNumber()
|
||||
{
|
||||
for (ushort i = 1; i < 13; i++)
|
||||
{
|
||||
for (int j = 0; j < 10; j++)
|
||||
{
|
||||
String value = SacsRandomHelper.getRandomLengthNumber(i);
|
||||
//Debug.WriteLine("Value: " + value);
|
||||
Assert.IsTrue(value.Length > 0);
|
||||
Assert.IsTrue(value.Length < i + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -210,20 +210,21 @@ namespace Sarand.Net.Standard.Base.Bus
|
||||
if (Changed) return;
|
||||
Changed = !oldValue.Equals(newValue);
|
||||
}
|
||||
protected void CheckChanged (List<String> oldValues, List<String> newValues)
|
||||
protected void CheckChanged(IEnumerable<String> oldValues, IEnumerable<String> newValues)
|
||||
{
|
||||
if (Changed) return;
|
||||
Changed = !oldValues.ContentEquals(newValues);
|
||||
}
|
||||
protected void CheckChanged<T> (List<T> oldValues, List<T> newValues)
|
||||
protected void CheckChanged<T>(IEnumerable<T> oldValues, IEnumerable<T> newValues)
|
||||
{
|
||||
if (Changed) return;
|
||||
if (oldValues.Count() != newValues.Count()) Changed = true;
|
||||
else
|
||||
{
|
||||
for (int idx = 0; idx < oldValues.Count(); idx++)
|
||||
var combinedValues = oldValues.Zip(newValues, Tuple.Create);
|
||||
foreach (var combinedValue in combinedValues)
|
||||
{
|
||||
if (!oldValues[idx].Equals(newValues[idx]))
|
||||
if (!combinedValue.Item1.Equals(combinedValue.Item2))
|
||||
{
|
||||
Changed = true;
|
||||
return;
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace Sarand.Net.Standard.Base.Core
|
||||
{
|
||||
//=======================================================================
|
||||
public sealed class DisposableCollection<T> : Collection<T>, IDisposable
|
||||
where T : IDisposable
|
||||
where T : class, IDisposable
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
@@ -47,10 +47,31 @@ namespace Sarand.Net.Standard.Base.Core
|
||||
/// </summary>
|
||||
public new void Add(T item)
|
||||
{
|
||||
if (item != null)
|
||||
if (item != null && !Contains(item))
|
||||
base.Add(item);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add list of items to the collection.
|
||||
/// <para>Null items are ignored.</para>
|
||||
/// <para>Items that can't be cast to the required object type cause a debug break.</para>
|
||||
/// </summary>
|
||||
public void AddRange<O>(List<O> items) where O : class, IDisposable
|
||||
{
|
||||
if (items != null && !items.IsEmpty())
|
||||
{
|
||||
foreach (O item in items)
|
||||
{
|
||||
if (item == null) continue;
|
||||
T obj = item as T;
|
||||
if (obj != null)
|
||||
Add(obj);
|
||||
else if (SacsSystem.DebugMode)
|
||||
Debugger.Break();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
using Sarand.Net.Standard.Base.App;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Sarand.Net.Standard.Base.Core
|
||||
{
|
||||
//=======================================================================
|
||||
/// <summary>
|
||||
/// Dictionary with items queued as if in FIFO list.
|
||||
/// </summary>
|
||||
/// <typeparam name="K">Type of key</typeparam>
|
||||
/// <typeparam name="V">Type of value</typeparam>
|
||||
public class SacsQueueDictionary<K, V>
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Data memners.
|
||||
private readonly Queue<K> queue = new Queue<K>();
|
||||
private readonly Dictionary<K, V> dictionary = new Dictionary<K, V>();
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
public int Count { get { lock (dictionary) return queue.Count; } }
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>
|
||||
/// Is the KLey defined in the queue dictionary.
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns>True if found, else false.</returns>
|
||||
public bool HasValue(K key)
|
||||
{
|
||||
lock (dictionary)
|
||||
{
|
||||
return dictionary.ContainsKey(key);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>
|
||||
/// Retrieve the value determined by the key.
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns>Corresponding value if present, else default value.</returns>
|
||||
public V GetValue(K key)
|
||||
{
|
||||
V value = default(V);
|
||||
lock (dictionary)
|
||||
{
|
||||
dictionary.TryGetValue(key, out value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
public bool SetEntry(K key, V value)
|
||||
{
|
||||
if (key == null || value == null) return false;
|
||||
lock (dictionary)
|
||||
{
|
||||
if (dictionary.ContainsKey(key))
|
||||
{
|
||||
// Existsing key.
|
||||
// Replace value in dictionary.
|
||||
dictionary[key] = value;
|
||||
return true;
|
||||
}
|
||||
// New Key.
|
||||
// Add to queue and set value in dictionary.
|
||||
queue.Enqueue(key);
|
||||
dictionary[key] = value;
|
||||
return true;
|
||||
}
|
||||
if (SacsSystem.DebugMode) Validate();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>
|
||||
/// Remove the top n entries from the queue dictionary.
|
||||
/// </summary>
|
||||
/// <param name="maxEntries"></param>
|
||||
/// <returns></returns>
|
||||
public List<KeyValuePair<K, V>> RemoveTopEntries(int maxEntries)
|
||||
{
|
||||
List<KeyValuePair<K, V>> entries = new List<KeyValuePair<K, V>>();
|
||||
lock (dictionary)
|
||||
{
|
||||
while (queue.Count > 0 && entries.Count < maxEntries)
|
||||
{
|
||||
K key = queue.Dequeue();
|
||||
V value = dictionary[key];
|
||||
entries.Add(new KeyValuePair<K, V>(key, value));
|
||||
dictionary.Remove(key);
|
||||
}
|
||||
}
|
||||
if (SacsSystem.DebugMode) Validate();
|
||||
return entries;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Internal utilities.
|
||||
//-------------------------------------------------------------------
|
||||
private void Validate()
|
||||
{
|
||||
lock (dictionary)
|
||||
{
|
||||
if (queue.Count != dictionary.Count)
|
||||
throw new NotSupportedException("SacsQueueDictionary.Validate Inconsistent entry counts. Quete: " + queue.Count + ". Dictionary: " + dictionary.Count);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -39,7 +39,7 @@ namespace Sarand.Net.Standard.Base.Dbas
|
||||
/// <returns>the name of an ODBC driver for Microsoft SQL Server, if one is present; null, otherwise.</returns>
|
||||
public static string GetOdbcSqlDriverName ()
|
||||
{
|
||||
List<string> driverPrecedence = new List<string>() { "SQL Server Native Client 14.0", "SQL Server Native Client 13.0", "SQL Server Native Client 12.0", "SQL Server Native Client 11.0", "SQL Server Native Client 10.0", "SQL Server Native Client 9.0", "SQL Server" };
|
||||
List<string> driverPrecedence = new List<string>() { "ODBC Driver 17 for SQL Server", "ODBC Driver 13 for SQL Server", "ODBC Driver 11 for SQL Server", "SQL Server Native Client 11.0", "SQL Server Native Client 10.0", "SQL Server Native Client 9.0", "SQL Server" };
|
||||
string[] availableOdbcDrivers = GetOdbcDriverNames();
|
||||
string driverName = null;
|
||||
if (availableOdbcDrivers != null)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
@@ -49,6 +50,20 @@ namespace Sarand.Net.Standard.Base.Helpers
|
||||
//return Random.Next(fromInclusive, toExclusive);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
public static String getRandomLengthNumber(ushort maxLength=4)
|
||||
{
|
||||
String value = "";
|
||||
int len = GetInt32(1, maxLength + 1);
|
||||
for (int i = 0; i < len; i++)
|
||||
value += GetInt32(0,10);
|
||||
if (StringUtil.IsEmpty(value))
|
||||
throw new NotSupportedException("getRandomLengthNumber Generated blank value");
|
||||
if (value.Length > maxLength)
|
||||
throw new NotSupportedException("getRandomLengthNumber Generated excess length value");
|
||||
return value;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
|
||||
namespace Sarand.Net.Standard.Base.Utils
|
||||
@@ -75,6 +77,31 @@ namespace Sarand.Net.Standard.Base.Utils
|
||||
dictToAdd.ForEach(x => dict.Add(x.Key, x.Value));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Orderd Dictionary
|
||||
//-------------------------------------------------------------------
|
||||
public static DictionaryEntry GetElementAt(this OrderedDictionary dictionary, int index)
|
||||
{
|
||||
return dictionary.Cast<DictionaryEntry>().ElementAt(index);
|
||||
}
|
||||
public static K GetKeyAt<K>(this OrderedDictionary dictionary, int index)
|
||||
{
|
||||
return (K)dictionary.GetElementAt(index).Key;
|
||||
}
|
||||
public static V GetValue<K, V>(this OrderedDictionary dictionary, K key)
|
||||
{
|
||||
if (dictionary == null || key == null)
|
||||
return default(V);
|
||||
try
|
||||
{
|
||||
return (V)dictionary.Cast<DictionaryEntry>().AsQueryable().Single(kvp => ((K)kvp.Key).Equals(key)).Value;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return default(V);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
|
||||
@@ -42,7 +42,16 @@ namespace Sarand.Net.Standard.Base.Utils
|
||||
/// </summary>
|
||||
public static String GetLogMessage(this Exception exc, int entries = 8, String stackEntryDelim = "\n\t")
|
||||
{
|
||||
return exc.GetType().Name + ": " + GetMessage(exc) + exc.GetStackEntries(entries).Concat("", stackEntryDelim);
|
||||
return exc.GetLogMessage("", entries, stackEntryDelim);
|
||||
}
|
||||
/// <summary>
|
||||
/// Generate standard exception log message.
|
||||
/// <para>[ExceptionType] [message]: [ExceptionMessage]</para>
|
||||
/// <para>followed by stack entries on separate lines.</para>
|
||||
/// </summary>
|
||||
public static String GetLogMessage(this Exception exc, String message, int entries = 8, String stackEntryDelim = "\n\t")
|
||||
{
|
||||
return (exc.GetType().Name + " " + message + ": " + GetMessage(exc) + exc.GetStackEntries(entries).Concat("", stackEntryDelim)).TrimAll();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
@@ -42,18 +42,18 @@ namespace Sarand.Net.Standard.Base.Utils
|
||||
// C o m p a r i s o n
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>Compare lists to verify that they contain the same value in the corresponding position.</summary>
|
||||
public static bool ContentEquals (this List<String> values, List<String> target)
|
||||
public static bool ContentEquals (this IEnumerable<String> values, IEnumerable<String> target)
|
||||
{
|
||||
if (values.Count != target.Count) return false;
|
||||
if (values.Count() != target.Count()) return false;
|
||||
var combinedValues = values.Zip(target, Tuple.Create);
|
||||
foreach (var combinedValue in combinedValues)
|
||||
if (!combinedValue.Item1.Equals(combinedValue.Item2)) return false;
|
||||
return true;
|
||||
}
|
||||
/// <summary>Compare lists to verify that they contain the same case-insensitive value in the corresponding position.</summary>
|
||||
public static bool ContentEqualsCI (this List<String> values, List<String> target)
|
||||
public static bool ContentEqualsCI (this IEnumerable<String> values, IEnumerable<String> target)
|
||||
{
|
||||
if (values.Count != target.Count) return false;
|
||||
if (values.Count() != target.Count()) return false;
|
||||
var combinedValues = values.Zip(target, Tuple.Create);
|
||||
foreach (var combinedValue in combinedValues)
|
||||
if (!combinedValue.Item1.EqualsCI(combinedValue.Item2)) return false;
|
||||
|
||||
@@ -365,6 +365,8 @@ namespace Sarand.Net.Standard.Dbas.Data
|
||||
// NB Always use ODBC connection for querying schema.
|
||||
// eg. SQL Connection GetSchema('Indices') doesn't return index columns.
|
||||
public override List<String> GetTableNames(bool refresh = false)
|
||||
{
|
||||
lock (tables)
|
||||
{
|
||||
// Only populate table names if not previously done.
|
||||
if (tables.Count < 1 || refresh)
|
||||
@@ -378,7 +380,10 @@ namespace Sarand.Net.Standard.Dbas.Data
|
||||
}
|
||||
return tables.GetNames();
|
||||
}
|
||||
}
|
||||
public override List<DbDfnTable> GetTableDfns(bool refresh = false)
|
||||
{
|
||||
lock (tables)
|
||||
{
|
||||
if (refresh) ClearTableDfns();
|
||||
// Only populate table names and/or table schemas where not previously done.
|
||||
@@ -402,11 +407,15 @@ namespace Sarand.Net.Standard.Dbas.Data
|
||||
}
|
||||
return tables.ToList();
|
||||
}
|
||||
}
|
||||
public void ClearTableDfns()
|
||||
{
|
||||
lock (tables)
|
||||
tables.Clear();
|
||||
}
|
||||
public override DbDfnTable GetTableDfn(String tableName, bool refresh = false)
|
||||
{
|
||||
lock (tables)
|
||||
{
|
||||
if (!tables.GetNames().Contains(tableName) || refresh)
|
||||
{
|
||||
@@ -431,9 +440,12 @@ namespace Sarand.Net.Standard.Dbas.Data
|
||||
}
|
||||
return tables.GetTableByName(tableName);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
private void PopulateTableNames(DbConnection dbConnection, String tableNameRestriction = null)
|
||||
{
|
||||
lock (tables)
|
||||
{
|
||||
if (StringUtil.IsEmpty(tableNameRestriction) && tables.Count > 0) return;
|
||||
if (!StringUtil.IsEmpty(tableNameRestriction) && tables.Exists(item => item.Name.Equals(tableNameRestriction))) return;
|
||||
@@ -496,6 +508,7 @@ namespace Sarand.Net.Standard.Dbas.Data
|
||||
tables.Clear();
|
||||
tables.AddRange(tablesUnsorted.OrderBy(item => item.Name).ToList());
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
private void PopulateTableColumns(DbConnection dbConnection, DbDfnTable table)
|
||||
|
||||
Reference in New Issue
Block a user