Saxonite - various

This commit is contained in:
2021-06-04 14:04:03 +01:00
parent 19be985731
commit 8d3aa5ec03
31 changed files with 390 additions and 170 deletions
@@ -288,7 +288,7 @@ namespace Sarand.Net.Standard.Base.Bus
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Properties. // Properties.
public virtual bool ItemHasId { get { return true; } } public virtual bool ItemHasId { get; } = true;
public SysId Id public SysId Id
{ {
get get
+53 -20
View File
@@ -1,6 +1,10 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.Core; using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Utils; using Sarand.Net.Standard.Base.Utils;
@@ -8,16 +12,17 @@ namespace Sarand.Net.Standard.Base.Bus
{ {
//======================================================================= //=======================================================================
//[Serializable()] //[Serializable()]
[JsonConverter(typeof(SysIdJsonConverter))]
public class SysId public class SysId
{ {
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Data members. // Data members.
private Int64 id = 0; private Int64 id = 0;
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Construction. // Construction.
public SysId () { } public SysId() { }
public SysId (Int64 id) public SysId(Int64 id)
{ {
this.id = id; this.id = id;
} }
@@ -37,30 +42,30 @@ namespace Sarand.Net.Standard.Base.Bus
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Utilities. // Utilities.
public static bool IsValid (SysId sysId) public static bool IsValid(SysId sysId)
{ {
return (sysId != null && sysId.id != 0); return (sysId != null && sysId.id != 0);
} }
public static SysId InvalidOnNull (SysId sysId) public static SysId InvalidOnNull(SysId sysId)
{ {
return (sysId != null ? sysId : new SysId()); return (sysId != null ? sysId : new SysId());
} }
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Comparison. // Comparison.
public override bool Equals (object obj) public override bool Equals(object obj)
{ {
if (obj == null) return false; if (obj == null) return false;
return Equals(obj as SysId); return Equals(obj as SysId);
} }
public bool Equals (SysId sysId) public bool Equals(SysId sysId)
{ {
if (sysId == null) return false; if (sysId == null) return false;
// False if either value invalid. // False if either value invalid.
if (id == 0) return false; if (id == 0) return false;
return ToInt().Equals(InvalidOnNull(sysId).ToInt()); return ToInt().Equals(InvalidOnNull(sysId).ToInt());
} }
public override int GetHashCode () public override int GetHashCode()
{ {
return id.GetHashCode(); return id.GetHashCode();
} }
@@ -75,11 +80,11 @@ namespace Sarand.Net.Standard.Base.Bus
{ {
return ToInt(this); return ToInt(this);
} }
public override String ToString () public override String ToString()
{ {
return ToString(this); return ToString(this);
} }
public String ToString (String invalidValue) public String ToString(String invalidValue)
{ {
return ToString(this, invalidValue); return ToString(this, invalidValue);
} }
@@ -92,15 +97,43 @@ namespace Sarand.Net.Standard.Base.Bus
{ {
return (IsValid(sysId) ? sysId.id : 0); return (IsValid(sysId) ? sysId.id : 0);
} }
public static String ToString (SysId sysId) public static String ToString(SysId sysId)
{ {
return ToString(sysId, String.Empty); return ToString(sysId, String.Empty);
} }
public static String ToString (SysId sysId, String invalidValue) public static String ToString(SysId sysId, String invalidValue)
{ {
return (IsValid(sysId) ? sysId.id.ToString() : invalidValue); return (IsValid(sysId) ? sysId.id.ToString() : invalidValue);
} }
//-------------------------------------------------------------------
/// <summary>
/// JSON Converter to serialise/deserialise SysId to/from simple integer value.
/// </summary>
class SysIdJsonConverter : JsonConverter<SysId>
{
public override void WriteJson(JsonWriter writer, [AllowNull] SysId id, JsonSerializer serializer)
{
if (id == null) return;
// Simply return the integer Id value.
serializer.Serialize(writer, id.Id);
}
public override SysId ReadJson(JsonReader reader, Type objectType, [AllowNull] SysId existingValue, bool hasExistingValue, JsonSerializer serializer)
{
try
{
// Convert the integer value to a SysId.
JValue jValue = new JValue(reader.Value);
return new SysId() { Id = (long)jValue };
}
catch (Exception exc)
{
SaLogger.Debug(GetType().Name + ".ReadJson " + ExceptionUtil.GetErrorStateMessage(exc));
}
return null;
}
}
//------------------------------------------------------------------- //-------------------------------------------------------------------
} }
//======================================================================= //=======================================================================
@@ -108,13 +141,13 @@ namespace Sarand.Net.Standard.Base.Bus
{ {
//------------------------------------------------------------------- //-------------------------------------------------------------------
// List contents. // List contents.
public static int GetIdCount (this List<SysId> values, bool ignoreInvalid = true, bool ignoreDuplicates = true) public static int GetIdCount(this List<SysId> values, bool ignoreInvalid = true, bool ignoreDuplicates = true)
{ {
if (ignoreDuplicates) if (ignoreDuplicates)
{ {
values = values.Select(id => id).Distinct().ToList(); values = values.Select(id => id).Distinct().ToList();
// SysId.Equals treats invalid ids as inequal so 'Distinct' doesn't remove them. // SysId.Equals treats invalid ids as inequal so 'Distinct' doesn't remove them.
if (values.FindIndex(id => !SysId.IsValid(id)) >= 0) if (values.FindIndex(id => !SysId.IsValid(id)) >= 0)
{ {
// Remove all invalid entries and put one back to correct the count. // Remove all invalid entries and put one back to correct the count.
values.RemoveAll(id => !SysId.IsValid(id)); values.RemoveAll(id => !SysId.IsValid(id));
@@ -123,24 +156,24 @@ namespace Sarand.Net.Standard.Base.Bus
} }
return values.Count(id => !ignoreInvalid || SysId.IsValid(id)); return values.Count(id => !ignoreInvalid || SysId.IsValid(id));
} }
public static bool HasValidIds (this List<SysId> values) public static bool HasValidIds(this List<SysId> values)
{ {
return (values.Find(id => SysId.IsValid(id)) != null); return (values.Find(id => SysId.IsValid(id)) != null);
} }
public static bool Equals (this List<SysId> values, List<SysId> values2) public static bool Equals(this List<SysId> values, List<SysId> values2)
{ {
return values.OrderBy(id => id.Id).SequenceEqual(values2.OrderBy(id => id.Id)); return values.OrderBy(id => id.Id).SequenceEqual(values2.OrderBy(id => id.Id));
} }
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Populate list. // Populate list.
public static void AddId (this List<SysId> values, SysId sysId, bool ignoreInvalid = true, bool ignoreDuplicates = true) public static void AddId(this List<SysId> values, SysId sysId, bool ignoreInvalid = true, bool ignoreDuplicates = true)
{ {
if (ignoreInvalid && !SysId.IsValid(sysId)) return; if (ignoreInvalid && !SysId.IsValid(sysId)) return;
if (ignoreDuplicates && values.Contains(sysId)) return; if (ignoreDuplicates && values.Contains(sysId)) return;
values.Add(sysId); values.Add(sysId);
} }
public static void AddIds (this List<SysId> values, List<SysId> sysIds, bool ignoreInvalid = true, bool ignoreDuplicates = true) public static void AddIds(this List<SysId> values, List<SysId> sysIds, bool ignoreInvalid = true, bool ignoreDuplicates = true)
{ {
foreach (SysId id in sysIds) foreach (SysId id in sysIds)
values.AddId(id, ignoreInvalid, ignoreDuplicates); values.AddId(id, ignoreInvalid, ignoreDuplicates);
@@ -150,7 +183,7 @@ namespace Sarand.Net.Standard.Base.Bus
// Extract from list. // Extract from list.
/// <summary>Remove specified number of entries from the list and return them.</summary> /// <summary>Remove specified number of entries from the list and return them.</summary>
/// <returns></returns> /// <returns></returns>
public static List<SysId> ExtractIds (this List<SysId> values, int numberToRemove) public static List<SysId> ExtractIds(this List<SysId> values, int numberToRemove)
{ {
List<SysId> ids = new List<SysId>(); List<SysId> ids = new List<SysId>();
while (values.Count > 0 && ids.Count < numberToRemove) while (values.Count > 0 && ids.Count < numberToRemove)
@@ -170,7 +203,7 @@ namespace Sarand.Net.Standard.Base.Bus
/// <param name="delimiter"></param> /// <param name="delimiter"></param>
/// <param name="ignoreInvalid"></param> /// <param name="ignoreInvalid"></param>
/// <returns></returns> /// <returns></returns>
public static String Concat (this List<SysId> values, String delimiter, bool ignoreInvalid = true) public static String Concat(this List<SysId> values, String delimiter, bool ignoreInvalid = true)
{ {
List<String> ids = new List<string>(); List<String> ids = new List<string>();
foreach (SysId id in values.FindAll(id => !ignoreInvalid || SysId.IsValid(id))) foreach (SysId id in values.FindAll(id => !ignoreInvalid || SysId.IsValid(id)))
+10 -1
View File
@@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Sarand.Net.Standard.Base.Core; using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Utils; using Sarand.Net.Standard.Base.Utils;
@@ -49,12 +50,20 @@ namespace Sarand.Net.Standard.Base.Dbas
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Columns. // Columns.
public int ColumnCount
{
get
{
lock (columns)
return columns.Count();
}
}
public List<DbDfnIndexColumn> Columns public List<DbDfnIndexColumn> Columns
{ {
get get
{ {
lock (columns) lock (columns)
return new List<DbDfnIndexColumn>(columns); return columns.ToList();
} }
set set
{ {
+24 -8
View File
@@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Sarand.Net.Standard.Base.Core; using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Utils; using Sarand.Net.Standard.Base.Utils;
@@ -29,6 +30,7 @@ namespace Sarand.Net.Standard.Base.Dbas
public String Schema { get; set; } = String.Empty; public String Schema { get; set; } = String.Empty;
public String Name { get; set; } = String.Empty; public String Name { get; set; } = String.Empty;
public String QualifiedName { get { return (!StringUtil.IsEmpty(Schema) ? Schema + "." : "") + Name; } } public String QualifiedName { get { return (!StringUtil.IsEmpty(Schema) ? Schema + "." : "") + Name; } }
public String QuotedQualifiedName { get { return (!StringUtil.IsEmpty(Schema) ? "[" + Schema + "]." : "") + "[" + Name + "]"; } }
public String Remarks { get; set; } = String.Empty; public String Remarks { get; set; } = String.Empty;
//------------------------------------------------------------------- //-------------------------------------------------------------------
@@ -47,19 +49,26 @@ namespace Sarand.Net.Standard.Base.Dbas
public bool HasColumnByName(String columnName) public bool HasColumnByName(String columnName)
{ {
lock (columns) lock (columns)
return (columns != null && columns.Exists(col => col.Name.EqualsCI(columnName))); return columns.Exists(col => col.Name.EqualsCI(columnName));
} }
public bool HasColumns() public bool HasColumns()
{ {
lock (columns) return ColumnCount > 0;
return (columns != null && columns.Count > 0); }
public int ColumnCount
{
get
{
lock (columns)
return columns.Count;
}
} }
public List<DbDfnColumn> Columns public List<DbDfnColumn> Columns
{ {
get get
{ {
lock (columns) lock (columns)
return new List<DbDfnColumn>(columns); return columns.ToList();
} }
set set
{ {
@@ -97,19 +106,26 @@ namespace Sarand.Net.Standard.Base.Dbas
public bool HasIndexByName(String indexName) public bool HasIndexByName(String indexName)
{ {
lock (indices) lock (indices)
return (indices != null && indices.Exists(idx => idx.Name.EqualsCI(indexName))); return indices.Exists(idx => idx.Name.EqualsCI(indexName));
} }
public bool HasIndices() public bool HasIndices()
{ {
lock (indices) return IndexCount > 0;
return (indices != null && indices.Count > 0); }
public int IndexCount
{
get
{
lock (indices)
return indices.Count;
}
} }
public List<DbDfnIndex> Indices public List<DbDfnIndex> Indices
{ {
get get
{ {
lock (indices) lock (indices)
return new List<DbDfnIndex>(indices); return indices.ToList();
} }
set set
{ {
+1 -1
View File
@@ -67,7 +67,7 @@ namespace Sarand.Net.Standard.Base.Dbas
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Database schema. // Database schema.
List<String> GetTableNames (); List<String> GetTableNames (bool refresh = false);
List<DbDfnTable> GetTableDfns (bool refresh = false); List<DbDfnTable> GetTableDfns (bool refresh = false);
DbDfnTable GetTableDfn (String name, bool refresh = false); DbDfnTable GetTableDfn (String name, bool refresh = false);
bool TableExists (String tableName); bool TableExists (String tableName);
@@ -16,8 +16,8 @@ namespace Sarand.Net.Standard.Base.Helpers
public static void Fill(byte[] byteArray) public static void Fill(byte[] byteArray)
{ {
// ToDo RandomNumberGenerator.Fill(byteArray); RandomNumberGenerator.Fill(byteArray);
RandomNumberGenerator.GetBytes(byteArray); //RandomNumberGenerator.GetBytes(byteArray);
} }
//------------------------------------------------------------------- //-------------------------------------------------------------------
+2 -2
View File
@@ -40,9 +40,9 @@ namespace Sarand.Net.Standard.Base.Utils
/// <para>[ExceptionType]: [ExceptionMessage]</para> /// <para>[ExceptionType]: [ExceptionMessage]</para>
/// <para>followed by stack entries on separate lines.</para> /// <para>followed by stack entries on separate lines.</para>
/// </summary> /// </summary>
public static String GetLogMessage (this Exception exc, int entries = 8) public static String GetLogMessage (this Exception exc, int entries = 8, String stackEntryDelim = "\n\t")
{ {
return exc.GetType().Name + ": " + GetMessage(exc) + exc.GetStackEntries(entries).Concat("", "\n\t"); return exc.GetType().Name + ": " + GetMessage(exc) + exc.GetStackEntries(entries).Concat("", stackEntryDelim);
} }
//------------------------------------------------------------------- //-------------------------------------------------------------------
@@ -4,7 +4,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Sarand.Net.Standard.Base.Xml namespace Sarand.Net.Standard.Base.Utils
{ {
//======================================================================= //=======================================================================
public enum SoapElementType public enum SoapElementType
@@ -7,7 +7,7 @@ using System.Text;
using System.Xml; using System.Xml;
using System.Xml.Linq; using System.Xml.Linq;
namespace Sarand.Net.Standard.Base.Xml namespace Sarand.Net.Standard.Base.Utils
{ {
//======================================================================= //=======================================================================
public static class SacsXmlUtil public static class SacsXmlUtil
@@ -145,6 +145,7 @@ namespace Sarand.Net.Standard.Base.Xml
} }
//------------------------------------------------------------------- //-------------------------------------------------------------------
// System.Xml.Linq variation.
/// <summary>Get text from first child that matches the node name.</summary> /// <summary>Get text from first child that matches the node name.</summary>
public static String GetChildText (this XElement element, String name) public static String GetChildText (this XElement element, String name)
{ {
@@ -153,9 +154,18 @@ namespace Sarand.Net.Standard.Base.Xml
return child.Value; return child.Value;
return String.Empty; return String.Empty;
} }
// System.Xml varations.
public static String GetChildText(this XmlNode node, String name)
{
foreach (XmlNode child in node.ChildNodes)
if (child.Name.EqualsCI(name))
return child.InnerText;
return String.Empty;
}
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Append element to node. // Append element to node.
// System.Xml.Linq variation.
public static XElement AppendElement (this XContainer container, XElement element) public static XElement AppendElement (this XContainer container, XElement element)
{ {
container.Add(element); container.Add(element);
@@ -173,6 +183,15 @@ namespace Sarand.Net.Standard.Base.Xml
container.Add(child); container.Add(child);
return child; return child;
} }
// System.Xml varations.
public static XmlElement AppendElement(this XmlNode node, String name, String text = "")
{
XmlDocument doc = (node is XmlDocument ? node as XmlDocument : node.OwnerDocument);
XmlElement child = (XmlElement)node.AppendChild(doc.CreateElement(name));
if (!StringUtil.IsEmpty(text))
child.AppendChild(doc.CreateTextNode(text));
return child;
}
//------------------------------------------------------------------- //-------------------------------------------------------------------
} }
-48
View File
@@ -1,48 +0,0 @@
using System;
using System.IO;
using System.Xml;
using System.Xml.Linq;
namespace Sarand.Net.Standard.Base.Utils
{
//=======================================================================
public static class XmlUtil
{
//-------------------------------------------------------------------
// Convert XML document to string.
public static String GetXml (this XDocument xmlDoc)
{
using (var stringWriter = new StringWriter())
using (var xmlTextWriter = XmlWriter.Create(stringWriter))
{
xmlDoc.WriteTo(xmlTextWriter);
xmlTextWriter.Flush();
return stringWriter.GetStringBuilder().ToString();
}
}
//-------------------------------------------------------------------
// Append element to node.
public static XmlElement AppendElement (this XmlNode node, String name, String text = "")
{
XmlDocument doc = (node is XmlDocument ? node as XmlDocument : node.OwnerDocument);
XmlElement child = (XmlElement)node.AppendChild(doc.CreateElement(name));
if (!StringUtil.IsEmpty(text))
child.AppendChild(doc.CreateTextNode(text));
return child;
}
//-------------------------------------------------------------------
// Get child text.
public static String GetChildText (this XmlNode node, String name)
{
foreach (XmlNode child in node.ChildNodes)
if (child.Name.EqualsCI(name))
return child.InnerText;
return String.Empty;
}
//-------------------------------------------------------------------
}
//=======================================================================
}
+1 -1
View File
@@ -226,7 +226,7 @@ namespace Sarand.Net.Standard.Dbas.Base
//------------------------------------------------------------------- //-------------------------------------------------------------------
// D a t a b a s e S c h e m a // D a t a b a s e S c h e m a
//------------------------------------------------------------------- //-------------------------------------------------------------------
public abstract List<String> GetTableNames (); public abstract List<String> GetTableNames (bool refresh = false);
public abstract List<DbDfnTable> GetTableDfns (bool refresh = false); public abstract List<DbDfnTable> GetTableDfns (bool refresh = false);
public abstract DbDfnTable GetTableDfn (String name, bool refresh = false); public abstract DbDfnTable GetTableDfn (String name, bool refresh = false);
public bool TableExists (String tableName) public bool TableExists (String tableName)
@@ -111,7 +111,7 @@ namespace Sarand.Net.Standard.Dbas.CodeTypes
} }
catch (Exception exc) catch (Exception exc)
{ {
SaLogger.Warn(GetType().Name + ".GetCodeType\n\tQuery: " + dbCommand.CommandText + "\n\t" + exc.GetType().Name + ": " + exc.Message); SaLogger.Warn(GetType().Name + ".GetCodeType\n\tQuery: " + dbCommand.CommandText + "\n\t" + ExceptionUtil.GetLogMessage(exc));
} }
} }
return codeType; return codeType;
@@ -469,7 +469,7 @@ namespace Sarand.Net.Standard.Dbas.CodeTypes
} }
catch (Exception exc) catch (Exception exc)
{ {
SaLogger.Warn(GetType().Name + ".GetCodeTypeList\n\tQuery: " + dbCommand.CommandText + "\n\t" + exc.GetType().Name + ": " + exc.Message); SaLogger.Warn(GetType().Name + ".GetCodeTypeList\n\tQuery: " + dbCommand.CommandText + "\n\t" + ExceptionUtil.GetLogMessage(exc));
} }
} }
return codeTypes; return codeTypes;
@@ -493,7 +493,7 @@ namespace Sarand.Net.Standard.Dbas.CodeTypes
} }
catch (Exception exc) catch (Exception exc)
{ {
SaLogger.Warn(GetType().Name + ".GetCodeTypeListAsync\n\tQuery: " + dbCommand.CommandText + "\n\t" + exc.GetType().Name + ": " + exc.Message); SaLogger.Warn(GetType().Name + ".GetCodeTypeListAsync\n\tQuery: " + dbCommand.CommandText + "\n\t" + ExceptionUtil.GetLogMessage(exc));
} }
} }
return codeTypes; return codeTypes;
@@ -624,7 +624,7 @@ namespace Sarand.Net.Standard.Dbas.CodeTypes
} }
catch (Exception exc) catch (Exception exc)
{ {
SaLogger.Warn(GetType().Name + ".GetCode\n\tQuery: " + dbCommand.CommandText + "\n\t" + exc.GetType().Name + ": " + exc.Message); SaLogger.Warn(GetType().Name + ".GetCode\n\tQuery: " + dbCommand.CommandText + "\n\t" + ExceptionUtil.GetLogMessage(exc));
} }
} }
return code; return code;
@@ -1010,7 +1010,7 @@ namespace Sarand.Net.Standard.Dbas.CodeTypes
} }
catch (Exception exc) catch (Exception exc)
{ {
SaLogger.Warn(GetType().Name + ".GetCodeList\n\tQuery: " + dbCommand.CommandText + "\n\t" + exc.GetType().Name + ": " + exc.Message); SaLogger.Warn(GetType().Name + ".GetCodeList\n\tQuery: " + dbCommand.CommandText + "\n\t" + ExceptionUtil.GetLogMessage(exc));
} }
} }
return codes; return codes;
@@ -1035,7 +1035,7 @@ namespace Sarand.Net.Standard.Dbas.CodeTypes
} }
catch (Exception exc) catch (Exception exc)
{ {
SaLogger.Warn(GetType().Name + ".GetCodeListAsync\n\tQuery: " + dbCommand.CommandText + "\n\t" + exc.GetType().Name + ": " + exc.Message); SaLogger.Warn(GetType().Name + ".GetCodeListAsync\n\tQuery: " + dbCommand.CommandText + "\n\t" + ExceptionUtil.GetLogMessage(exc));
} }
} }
return codes; return codes;
@@ -14,10 +14,10 @@ namespace Sarand.Net.Standard.Dbas.Data
{ {
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Data members. // Data members.
private class Data private class DataMembers
{ {
// Construction. // Construction.
public Data (ISacsDatabase database, String query) public DataMembers (ISacsDatabase database, String query)
{ {
Database = database; Database = database;
Query = query; Query = query;
@@ -43,14 +43,14 @@ namespace Sarand.Net.Standard.Dbas.Data
} }
} }
} }
private readonly Data data; private readonly DataMembers data;
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Construction. // Construction.
[Obsolete("Constructor is deprecated. Use ExecuteQuery[Async] instead.")] [Obsolete("Constructor is deprecated. Use ExecuteQuery[Async] instead.")]
public DbResultSet_DataReader (SacsDatabase database, String query) public DbResultSet_DataReader (SacsDatabase database, String query)
{ {
data = new Data(database, query); data = new DataMembers(database, query);
String fn = GetType().Name + ".CTR"; String fn = GetType().Name + ".CTR";
try try
{ {
@@ -64,7 +64,7 @@ namespace Sarand.Net.Standard.Dbas.Data
} }
} }
/// <summary>Private construction - created from ExecuteQuery{Async].</summary> /// <summary>Private construction - created from ExecuteQuery{Async].</summary>
private DbResultSet_DataReader (Data data) private DbResultSet_DataReader (DataMembers data)
{ {
this.data = data; this.data = data;
} }
@@ -77,7 +77,7 @@ namespace Sarand.Net.Standard.Dbas.Data
// Execute query. // Execute query.
public static DbResultSet_DataReader ExecuteQuery (ISacsDatabase database, String query) public static DbResultSet_DataReader ExecuteQuery (ISacsDatabase database, String query)
{ {
Data data = new Data(database, query); DataMembers data = new DataMembers(database, query);
String fn = typeof(DbResultSet_DataReader).Name + ".ExecuteQuery"; String fn = typeof(DbResultSet_DataReader).Name + ".ExecuteQuery";
String errorState = ""; String errorState = "";
try try
@@ -96,7 +96,7 @@ namespace Sarand.Net.Standard.Dbas.Data
} }
public static async Task<DbResultSet_DataReader> ExecuteQueryAsync (SacsDatabase database, String query) public static async Task<DbResultSet_DataReader> ExecuteQueryAsync (SacsDatabase database, String query)
{ {
Data data = new Data(database, query); DataMembers data = new DataMembers(database, query);
String fn = typeof(DbResultSet_DataReader).Name + ".ExecuteQueryAsync"; String fn = typeof(DbResultSet_DataReader).Name + ".ExecuteQueryAsync";
String errorState = ""; String errorState = "";
try try
@@ -134,7 +134,7 @@ namespace Sarand.Net.Standard.Dbas.Data
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Execute query. // Execute query.
private static void ExecuteQuery_Internal (Data data) private static void ExecuteQuery_Internal (DataMembers data)
{ {
data.DbConnection = data.Database.CreateConnection(); data.DbConnection = data.Database.CreateConnection();
data.DbCommand = data.DbConnection.CreateCommand(); data.DbCommand = data.DbConnection.CreateCommand();
@@ -363,10 +363,10 @@ namespace Sarand.Net.Standard.Dbas.Data
//------------------------------------------------------------------- //-------------------------------------------------------------------
// NB Always use ODBC connection for querying schema. // NB Always use ODBC connection for querying schema.
// eg. SQL Connection GetSchema('Indices') doesn't return index columns. // eg. SQL Connection GetSchema('Indices') doesn't return index columns.
public override List<String> GetTableNames () public override List<String> GetTableNames (bool refresh = false)
{ {
// Only populate table names if not previously done. // Only populate table names if not previously done.
if (tables.Count < 1) if (tables.Count < 1 || refresh)
{ {
using (DbConnection dbConnection = CreateConnection(true)) using (DbConnection dbConnection = CreateConnection(true))
{ {
@@ -388,7 +388,7 @@ namespace Sarand.Net.Standard.Dbas.Data
dbConnection.Open(); dbConnection.Open();
if (tables.Count < 1) if (tables.Count < 1)
PopulateTableNames(dbConnection); PopulateTableNames(dbConnection);
foreach (DbDfnTable table in tables) foreach (DbDfnTable table in tables.ToList())
{ {
if (!table.HasColumns()) if (!table.HasColumns())
{ {
@@ -398,7 +398,7 @@ namespace Sarand.Net.Standard.Dbas.Data
} }
} }
} }
return new List<DbDfnTable>(tables); return tables.ToList();
} }
public void ClearTableDfns () public void ClearTableDfns ()
{ {
@@ -488,7 +488,7 @@ namespace Sarand.Net.Standard.Dbas.Data
} }
} }
} }
List<DbDfnTable> tablesUnsorted = new List<DbDfnTable>(tables); List<DbDfnTable> tablesUnsorted = tables.ToList();
tables.Clear(); tables.Clear();
tables.AddRange(tablesUnsorted.OrderBy(item => item.Name).ToList()); tables.AddRange(tablesUnsorted.OrderBy(item => item.Name).ToList());
} }
@@ -71,7 +71,7 @@ namespace Sarand.Net.Standard.Dbas.Interfaces
} }
catch (Exception exc) catch (Exception exc)
{ {
SaLogger.Warn(GetType().Name + ".GetInterfaceDataItem\n\tQuery: " + dbCommand.CommandText + "\n\t" + exc.GetType().Name + ": " + exc.Message); SaLogger.Warn(GetType().Name + ".GetInterfaceDataItem\n\tQuery: " + dbCommand.CommandText + "\n\t" + ExceptionUtil.GetLogMessage(exc));
} }
} }
return interfaceProcessDataItem; return interfaceProcessDataItem;
@@ -531,7 +531,7 @@ namespace Sarand.Net.Standard.Dbas.Interfaces
} }
catch (Exception exc) catch (Exception exc)
{ {
SaLogger.Warn(GetType().Name + ".GetInterfaceDataItemList\n\tQuery: " + dbCommand.CommandText + "\n\t" + exc.GetType().Name + ": " + exc.Message); SaLogger.Warn(GetType().Name + ".GetInterfaceDataItemList\n\tQuery: " + dbCommand.CommandText + "\n\t" + ExceptionUtil.GetLogMessage(exc));
} }
} }
return interfaces; return interfaces;
@@ -72,7 +72,7 @@ namespace Sarand.Net.Standard.Dbas.Interfaces
} }
catch (Exception exc) catch (Exception exc)
{ {
SaLogger.Warn(GetType().Name + ".GetInterfaceProcessMessage\n\tQuery: " + dbCommand.CommandText + "\n\t" + exc.GetType().Name + ": " + exc.Message); SaLogger.Warn(GetType().Name + ".GetInterfaceProcessMessage\n\tQuery: " + dbCommand.CommandText + "\n\t" + ExceptionUtil.GetLogMessage(exc));
} }
} }
return interfaceProcessMessage; return interfaceProcessMessage;
@@ -417,7 +417,7 @@ namespace Sarand.Net.Standard.Dbas.Interfaces
} }
catch (Exception exc) catch (Exception exc)
{ {
SaLogger.Warn(GetType().Name + ".GetInterfaceProcessMessageList\n\tQuery: " + dbCommand.CommandText + "\n\t" + exc.GetType().Name + ": " + exc.Message); SaLogger.Warn(GetType().Name + ".GetInterfaceProcessMessageList\n\tQuery: " + dbCommand.CommandText + "\n\t" + ExceptionUtil.GetLogMessage(exc));
} }
} }
return interfaces; return interfaces;
@@ -93,7 +93,7 @@ namespace Sarand.Net.Standard.Dbas.Interfaces
} }
catch (Exception exc) catch (Exception exc)
{ {
SaLogger.Warn(GetType().Name + ".GetInterfaceProcess\n\tQuery: " + dbCommand.CommandText + "\n\t" + exc.GetType().Name + ": " + exc.Message); SaLogger.Warn(GetType().Name + ".GetInterfaceProcess\n\tQuery: " + dbCommand.CommandText + "\n\t" + ExceptionUtil.GetLogMessage(exc));
} }
} }
return interfaceProcess; return interfaceProcess;
@@ -655,7 +655,7 @@ namespace Sarand.Net.Standard.Dbas.Interfaces
} }
catch (Exception exc) catch (Exception exc)
{ {
SaLogger.Warn(GetType().Name + ".GetInterfaceProcessList\n\tQuery: " + dbCommand.CommandText + "\n\t" + exc.GetType().Name + ": " + exc.Message); SaLogger.Warn(GetType().Name + ".GetInterfaceProcessList\n\tQuery: " + dbCommand.CommandText + "\n\t" + ExceptionUtil.GetLogMessage(exc));
} }
} }
return interfaces; return interfaces;
@@ -104,7 +104,7 @@ namespace Sarand.Net.Standard.Dbas.Interfaces
} }
catch (Exception exc) catch (Exception exc)
{ {
SaLogger.Warn(GetType().Name + ".GetInterface\n\tQuery: " + dbCommand.CommandText + "\n\t" + exc.GetType().Name + ": " + exc.Message); SaLogger.Warn(GetType().Name + ".GetInterface\n\tQuery: " + dbCommand.CommandText + "\n\t" + ExceptionUtil.GetLogMessage(exc));
} }
} }
return interfaceObj; return interfaceObj;
@@ -490,7 +490,7 @@ namespace Sarand.Net.Standard.Dbas.Interfaces
} }
catch (Exception exc) catch (Exception exc)
{ {
SaLogger.Warn(GetType().Name + ".GetInterfaceList\n\tQuery: " + dbCommand.CommandText + "\n\t" + exc.GetType().Name + ": " + exc.Message); SaLogger.Warn(GetType().Name + ".GetInterfaceList\n\tQuery: " + dbCommand.CommandText + "\n\t" + ExceptionUtil.GetLogMessage(exc));
} }
} }
return interfaces; return interfaces;
@@ -158,7 +158,7 @@ namespace Sarand.Net.Standard.Dbas.ItemData
} }
catch (Exception exc) catch (Exception exc)
{ {
SaLogger.Warn(GetType().Name + ".GetItemData\n\tQuery: " + dbCommand.CommandText + "\n\t" + exc.GetType().Name + ": " + exc.Message); SaLogger.Warn(GetType().Name + ".GetItemData\n\tQuery: " + dbCommand.CommandText + "\n\t" + ExceptionUtil.GetLogMessage(exc));
} }
} }
return itemData; return itemData;
@@ -520,7 +520,7 @@ namespace Sarand.Net.Standard.Dbas.ItemData
} }
catch (Exception exc) catch (Exception exc)
{ {
SaLogger.Warn(GetType().Name + ".GetItemDataList\n\tQuery: " + dbCommand.CommandText + "\n\t" + exc.GetType().Name + ": " + exc.Message); SaLogger.Warn(GetType().Name + ".GetItemDataList\n\tQuery: " + dbCommand.CommandText + "\n\t" + ExceptionUtil.GetLogMessage(exc));
} }
} }
return itemDatas; return itemDatas;
@@ -136,7 +136,7 @@ namespace Sarand.Net.Standard.Dbas.ItemDocs
} }
catch (Exception exc) catch (Exception exc)
{ {
SaLogger.Warn(GetType().Name + ".GetItemDoc\n\tQuery: " + dbCommand.CommandText + "\n\t" + exc.GetType().Name + ": " + exc.Message); SaLogger.Warn(GetType().Name + ".GetItemDoc\n\tQuery: " + dbCommand.CommandText + "\n\t" + ExceptionUtil.GetLogMessage(exc));
} }
} }
return itemDoc; return itemDoc;
@@ -556,7 +556,7 @@ namespace Sarand.Net.Standard.Dbas.ItemDocs
} }
catch (Exception exc) catch (Exception exc)
{ {
SaLogger.Warn(GetType().Name + ".GetItemDocList\n\tQuery: " + dbCommand.CommandText + "\n\t" + exc.GetType().Name + ": " + exc.Message); SaLogger.Warn(GetType().Name + ".GetItemDocList\n\tQuery: " + dbCommand.CommandText + "\n\t" + ExceptionUtil.GetLogMessage(exc));
} }
} }
return itemDocs; return itemDocs;
@@ -123,7 +123,7 @@ namespace Sarand.Net.Standard.Dbas.ItemOptions
} }
catch (Exception exc) catch (Exception exc)
{ {
SaLogger.Warn(GetType().Name + ".GetItemOption\n\tQuery: " + dbCommand.CommandText + "\n\t" + exc.GetType().Name + ": " + exc.Message); SaLogger.Warn(GetType().Name + ".GetItemOption\n\tQuery: " + dbCommand.CommandText + "\n\t" + ExceptionUtil.GetLogMessage(exc));
} }
} }
return itemOption; return itemOption;
@@ -509,7 +509,7 @@ namespace Sarand.Net.Standard.Dbas.ItemOptions
} }
catch (Exception exc) catch (Exception exc)
{ {
SaLogger.Warn(GetType().Name + ".GetItemOptionList\n\tQuery: " + dbCommand.CommandText + "\n\t" + exc.GetType().Name + ": " + exc.Message); SaLogger.Warn(GetType().Name + ".GetItemOptionList\n\tQuery: " + dbCommand.CommandText + "\n\t" + ExceptionUtil.GetLogMessage(exc));
} }
} }
return itemOptions; return itemOptions;
@@ -19,13 +19,19 @@ namespace Sarand.Net.Standard.Dbas.Proc
// Configuration. // Configuration.
public new class Config : SacsProcess.Config public new class Config : SacsProcess.Config
{ {
public Config (SacsDatabase sourceDatabase, SacsDatabase targetDatabase) public Config(ISacsDatabase sourceDatabase, ISacsDatabase targetDatabase)
{ {
SourceDatabase = sourceDatabase; SourceDatabase = sourceDatabase;
TargetDatabase = targetDatabase; TargetDatabase = targetDatabase;
} }
public SacsDatabase SourceDatabase { get; } public Config(List<DbDfnTable> sourceTables, ISacsDatabase targetDatabase)
public SacsDatabase TargetDatabase { get; } {
SourceTables = sourceTables;
TargetDatabase = targetDatabase;
}
public ISacsDatabase SourceDatabase { get; }
public List<DbDfnTable> SourceTables { get; }
public ISacsDatabase TargetDatabase { get; }
public bool HideIdenticalObjects { get; set; } public bool HideIdenticalObjects { get; set; }
public bool IgnoreNullable { get; set; } public bool IgnoreNullable { get; set; }
public bool IgnorePosition { get; set; } public bool IgnorePosition { get; set; }
@@ -37,11 +43,11 @@ namespace Sarand.Net.Standard.Dbas.Proc
// Definitions. // Definitions.
public interface IProcessNotifier : ISacsProcessNotifier public interface IProcessNotifier : ISacsProcessNotifier
{ {
void OnSchemaComparisonItemAdded (SaDbProcess_CompareDatabaseSchemas proc); void OnSchemaComparisonItemAdded(SaDbProcess_CompareDatabaseSchemas proc);
} }
public class SchemaComparisonItem public class SchemaComparisonItem
{ {
internal SchemaComparisonItem (String tableName, String columnName, int columnPosition, String indexName, String comment) internal SchemaComparisonItem(String tableName, String columnName, int columnPosition, String indexName, String comment)
{ {
Id = ++SeedId; Id = ++SeedId;
TableName = tableName; TableName = tableName;
@@ -67,11 +73,11 @@ namespace Sarand.Net.Standard.Dbas.Proc
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Construction. // Construction.
public SaDbProcess_CompareDatabaseSchemas (Config config) : base(config) public SaDbProcess_CompareDatabaseSchemas(Config config) : base(config)
{ {
this.config = config; this.config = config;
} }
protected override void Dispose (bool disposing) protected override void Dispose(bool disposing)
{ {
if (disposing) if (disposing)
{ {
@@ -95,7 +101,7 @@ namespace Sarand.Net.Standard.Dbas.Proc
//------------------------------------------------------------------- //-------------------------------------------------------------------
// S c h e m a D i f f e r e n c e s // S c h e m a D i f f e r e n c e s
//------------------------------------------------------------------- //-------------------------------------------------------------------
public List<SchemaComparisonItem> GetSchemaComparisonItems (int minId = 0) public List<SchemaComparisonItem> GetSchemaComparisonItems(int minId = 0)
{ {
return new List<SchemaComparisonItem>(schemaComparisonItems.FindAll(item => item.Id >= minId)); return new List<SchemaComparisonItem>(schemaComparisonItems.FindAll(item => item.Id >= minId));
} }
@@ -103,21 +109,23 @@ namespace Sarand.Net.Standard.Dbas.Proc
//------------------------------------------------------------------- //-------------------------------------------------------------------
// P r o c e s s i n g // P r o c e s s i n g
//------------------------------------------------------------------- //-------------------------------------------------------------------
protected override bool Run () protected override bool Run()
{ {
schemaComparisonItems.Clear(); schemaComparisonItems.Clear();
if (config.SourceDatabase == null) return SetProcessError("Source database must be supplied."); if (config.SourceDatabase == null && config.SourceTables == null) return SetProcessError("Source database must be supplied.");
CompareTables(); CompareTables();
return OK; return OK;
} }
//------------------------------------------------------------------- //-------------------------------------------------------------------
private void CompareTables () private void CompareTables()
{ {
List<String> sourceTables = config.SourceDatabase.GetTableNames().OrderBy(item => item).ToList(); // Database schemas.
List<String> targetTables = config.TargetDatabase.GetTableNames().OrderBy(item => item).ToList(); List<String> sourceTables = (config.SourceDatabase?.GetTableNames(true) ?? config.SourceTables.Select(item => item.Name)).OrderBy(item => item).ToList();
for (int sourceTableIdx = 0, targetTableIdx = 0; sourceTableIdx <= sourceTables.Count && targetTableIdx <= targetTables.Count;) List<String> targetTables = config.TargetDatabase.GetTableNames(true).OrderBy(item => item).ToList();
for (int sourceTableIdx = 0, targetTableIdx = 0; sourceTableIdx < sourceTables.Count || targetTableIdx < targetTables.Count;)
{ {
String sourceTableName = (sourceTableIdx < sourceTables.Count ? sourceTables[sourceTableIdx] : ""); String sourceTableName = (sourceTableIdx < sourceTables.Count ? sourceTables[sourceTableIdx] : "");
String targetTableName = (targetTableIdx < targetTables.Count ? targetTables[targetTableIdx] : ""); String targetTableName = (targetTableIdx < targetTables.Count ? targetTables[targetTableIdx] : "");
@@ -143,8 +151,8 @@ namespace Sarand.Net.Standard.Dbas.Proc
Debugger.Break(); Debugger.Break();
#endif #endif
// Retrieve table definition from each database. // Retrieve table definition from each database.
DbDfnTable sourceTableDfn = config.SourceDatabase.GetTableDfn (sourceTableName); DbDfnTable sourceTableDfn = config.SourceDatabase?.GetTableDfn(sourceTableName, true) ?? config.SourceTables.GetTableByName(sourceTableName);
DbDfnTable targetTableDfn = config.TargetDatabase.GetTableDfn (targetTableName); DbDfnTable targetTableDfn = config.TargetDatabase.GetTableDfn(targetTableName, true);
// Compare the columns and indices. // Compare the columns and indices.
CompareTableColumns(sourceTableDfn, targetTableDfn); CompareTableColumns(sourceTableDfn, targetTableDfn);
CompareTableIndices(sourceTableDfn, targetTableDfn); CompareTableIndices(sourceTableDfn, targetTableDfn);
@@ -155,7 +163,7 @@ namespace Sarand.Net.Standard.Dbas.Proc
} }
//------------------------------------------------------------------- //-------------------------------------------------------------------
private bool CompareTableColumns (DbDfnTable sourceTableDfn, DbDfnTable targetTableDfn) private bool CompareTableColumns(DbDfnTable sourceTableDfn, DbDfnTable targetTableDfn)
{ {
String tableName = sourceTableDfn.Name; String tableName = sourceTableDfn.Name;
#if DEBUG_X #if DEBUG_X
@@ -177,7 +185,7 @@ namespace Sarand.Net.Standard.Dbas.Proc
String sourceColumnName = sourceColumnIdx < sourceColumnNames.Count() ? sourceColumnNames[sourceColumnIdx] : ""; String sourceColumnName = sourceColumnIdx < sourceColumnNames.Count() ? sourceColumnNames[sourceColumnIdx] : "";
String targetColumnName = targetColumnIdx < targetColumnNames.Count() ? targetColumnNames[targetColumnIdx] : ""; String targetColumnName = targetColumnIdx < targetColumnNames.Count() ? targetColumnNames[targetColumnIdx] : "";
// Retrieve Column definition from each database. // Retrieve Column definition from each database.
DbDfnColumn sourceColumn = sourceColumns.GetColumnByName (sourceColumnName); DbDfnColumn sourceColumn = sourceColumns.GetColumnByName(sourceColumnName);
if (sourceColumn != null) iPosition = sourceColumn.Pos; if (sourceColumn != null) iPosition = sourceColumn.Pos;
DbDfnColumn targetColumn = targetColumns.GetColumnByName(targetColumnName); DbDfnColumn targetColumn = targetColumns.GetColumnByName(targetColumnName);
// Compare Columns. // Compare Columns.
@@ -225,7 +233,7 @@ namespace Sarand.Net.Standard.Dbas.Proc
return OK; return OK;
} }
private static long iLargeSizeThreshold = 4000; private static long iLargeSizeThreshold = 4000;
private bool ColumnSizesDiffer (DbDfnColumn sourceColumn, DbDfnColumn targetColumn) private bool ColumnSizesDiffer(DbDfnColumn sourceColumn, DbDfnColumn targetColumn)
{ {
if (sourceColumn.Size == targetColumn.Size) return false; if (sourceColumn.Size == targetColumn.Size) return false;
// If both columns are large, treat then as equal: // If both columns are large, treat then as equal:
@@ -240,33 +248,33 @@ namespace Sarand.Net.Standard.Dbas.Proc
if (config.IgnoreSimilarNumericTypes) if (config.IgnoreSimilarNumericTypes)
{ {
// Floating point types. // Floating point types.
List<String> numericTypes = StringListUtil.Split("Real,Float,Double,Decimal,Numeric",","); List<String> numericTypes = StringListUtil.Split("Real,Float,Double,Decimal,Numeric", ",");
if (numericTypes.ContainsCI(sourceDataType) && numericTypes.ContainsCI(targetDataType)) return false; if (numericTypes.ContainsCI(sourceDataType) && numericTypes.ContainsCI(targetDataType)) return false;
} }
// DateTimes: // DateTimes:
List<String> dateTimeTypes = StringListUtil.Split("DateTime",","); List<String> dateTimeTypes = StringListUtil.Split("DateTime", ",");
if (dateTimeTypes.ContainsCI(sourceDataType) && dateTimeTypes.ContainsCI(targetDataType)) return false; if (dateTimeTypes.ContainsCI(sourceDataType) && dateTimeTypes.ContainsCI(targetDataType)) return false;
return true; return true;
} }
private bool ColumnDecimalsDiffer (DbDfnColumn sourceColumn, DbDfnColumn targetColumn) private bool ColumnDecimalsDiffer(DbDfnColumn sourceColumn, DbDfnColumn targetColumn)
{ {
if (sourceColumn.DecimalDigits == targetColumn.DecimalDigits) return false; if (sourceColumn.DecimalDigits == targetColumn.DecimalDigits) return false;
// Check for specific data types: // Check for specific data types:
String sourceDataType = sourceColumn.DataTypeNameNative; String sourceDataType = sourceColumn.DataTypeNameNative;
String targetDataType = targetColumn.DataTypeNameNative; String targetDataType = targetColumn.DataTypeNameNative;
// Numeric types - float/double columns report decimals as 0. // Numeric types - float/double columns report decimals as 0.
List<String> floatTypes = StringListUtil.Split("Real,Float,Double",","); List<String> floatTypes = StringListUtil.Split("Real,Float,Double", ",");
List<String> decimalTypes = StringListUtil.Split("Decimal,Numeric",","); List<String> decimalTypes = StringListUtil.Split("Decimal,Numeric", ",");
if (sourceColumn.DecimalDigits == 0 && floatTypes.ContainsCI(sourceDataType) && targetColumn.DecimalDigits > 0 && decimalTypes.ContainsCI(targetDataType)) return false; if (sourceColumn.DecimalDigits == 0 && floatTypes.ContainsCI(sourceDataType) && targetColumn.DecimalDigits > 0 && decimalTypes.ContainsCI(targetDataType)) return false;
if (sourceColumn.DecimalDigits > 0 && decimalTypes.ContainsCI(sourceDataType) && targetColumn.DecimalDigits == 0 && floatTypes.ContainsCI(targetDataType)) return false; if (sourceColumn.DecimalDigits > 0 && decimalTypes.ContainsCI(sourceDataType) && targetColumn.DecimalDigits == 0 && floatTypes.ContainsCI(targetDataType)) return false;
// DateTimes: // DateTimes:
List<String> dateTimeTypes = StringListUtil.Split("DateTime",","); List<String> dateTimeTypes = StringListUtil.Split("DateTime", ",");
if (dateTimeTypes.ContainsCI(sourceDataType) && dateTimeTypes.ContainsCI(targetDataType)) return false; if (dateTimeTypes.ContainsCI(sourceDataType) && dateTimeTypes.ContainsCI(targetDataType)) return false;
return true; return true;
} }
private bool ColumnDataTypesDiffer (DbDfnColumn sourceColumn, DbDfnColumn targetColumn) private bool ColumnDataTypesDiffer(DbDfnColumn sourceColumn, DbDfnColumn targetColumn)
{ {
if (sourceColumn.DataType == targetColumn.DataType) return false; if (sourceColumn.DataType == targetColumn.DataType) return false;
@@ -279,13 +287,13 @@ namespace Sarand.Net.Standard.Dbas.Proc
if (config.IgnoreSimilarNumericTypes) if (config.IgnoreSimilarNumericTypes)
{ {
// Similar numeric type. // Similar numeric type.
List<String> numericTypes = StringListUtil.Split("Real,Float,Double,Decimal,Numeric",","); List<String> numericTypes = StringListUtil.Split("Real,Float,Double,Decimal,Numeric", ",");
if (numericTypes.ContainsCI(sourceDataType) && numericTypes.ContainsCI(targetDataType)) return false; if (numericTypes.ContainsCI(sourceDataType) && numericTypes.ContainsCI(targetDataType)) return false;
} }
return true; return true;
} }
private bool ColumnNativeDataTypesDiffer (DbDfnColumn sourceColumn, DbDfnColumn targetColumn) private bool ColumnNativeDataTypesDiffer(DbDfnColumn sourceColumn, DbDfnColumn targetColumn)
{ {
if (sourceColumn.DataTypeNative == targetColumn.DataTypeNative) return false; if (sourceColumn.DataTypeNative == targetColumn.DataTypeNative) return false;
@@ -295,20 +303,20 @@ namespace Sarand.Net.Standard.Dbas.Proc
if (config.IgnoreSimilarCharTypes) if (config.IgnoreSimilarCharTypes)
{ {
// Similar Char types. // Similar Char types.
List<String> varCharTypes = StringListUtil.Split("VarChar,LongVarChar,LongChar,NVarChar,VarWChar",","); List<String> varCharTypes = StringListUtil.Split("VarChar,LongVarChar,LongChar,NVarChar,VarWChar", ",");
if (varCharTypes.ContainsCI(sourceDataType) && varCharTypes.ContainsCI(targetDataType)) return false; if (varCharTypes.ContainsCI(sourceDataType) && varCharTypes.ContainsCI(targetDataType)) return false;
} }
if (config.IgnoreSimilarNumericTypes) if (config.IgnoreSimilarNumericTypes)
{ {
// Similar numeric types. // Similar numeric types.
List<String> numericTypes = StringListUtil.Split("Real,Float,Double,Numeric,Decimal",","); List<String> numericTypes = StringListUtil.Split("Real,Float,Double,Numeric,Decimal", ",");
if (numericTypes.ContainsCI(sourceDataType) && numericTypes.ContainsCI(targetDataType)) return false; if (numericTypes.ContainsCI(sourceDataType) && numericTypes.ContainsCI(targetDataType)) return false;
} }
return true; return true;
} }
//------------------------------------------------------------------- //-------------------------------------------------------------------
private bool CompareTableIndices (DbDfnTable sourceTableDfn, DbDfnTable targetTableDfn) private bool CompareTableIndices(DbDfnTable sourceTableDfn, DbDfnTable targetTableDfn)
{ {
String sTable = sourceTableDfn.Name; String sTable = sourceTableDfn.Name;
@@ -317,7 +325,7 @@ namespace Sarand.Net.Standard.Dbas.Proc
List<DbDfnIndex> targetIndices = targetTableDfn.Indices; List<DbDfnIndex> targetIndices = targetTableDfn.Indices;
List<String> sourceIndexNames = sourceIndices.GetNames().OrderBy(item => item).ToList(); List<String> sourceIndexNames = sourceIndices.GetNames().OrderBy(item => item).ToList();
List<String> targetIndexNames = targetIndices.GetNames().OrderBy(item => item).ToList(); List<String> targetIndexNames = targetIndices.GetNames().OrderBy(item => item).ToList();
for (int sourceIndexIdx = 0, targetIndexIdx = 0; OK && sourceIndexIdx < sourceIndexNames.Count && targetIndexIdx < targetIndexNames.Count; ) for (int sourceIndexIdx = 0, targetIndexIdx = 0; OK && sourceIndexIdx < sourceIndexNames.Count && targetIndexIdx < targetIndexNames.Count;)
{ {
// Retrieve the Index names. // Retrieve the Index names.
String sourceIndexName = sourceIndexIdx < sourceIndexNames.Count ? sourceIndexNames[sourceIndexIdx] : ""; String sourceIndexName = sourceIndexIdx < sourceIndexNames.Count ? sourceIndexNames[sourceIndexIdx] : "";
@@ -382,7 +390,7 @@ namespace Sarand.Net.Standard.Dbas.Proc
} }
//------------------------------------------------------------------- //-------------------------------------------------------------------
private void AddSchemaComparisonItem (String tableName, String columnName, int position, String indexName, String comment) private void AddSchemaComparisonItem(String tableName, String columnName, int position, String indexName, String comment)
{ {
schemaComparisonItems.Add(new SchemaComparisonItem(tableName, columnName, position, indexName, comment)); schemaComparisonItems.Add(new SchemaComparisonItem(tableName, columnName, position, indexName, comment));
if (ProcessNotifier != null) ProcessNotifier.OnSchemaComparisonItemAdded(this); if (ProcessNotifier != null) ProcessNotifier.OnSchemaComparisonItemAdded(this);
@@ -395,7 +403,7 @@ namespace Sarand.Net.Standard.Dbas.Proc
public static class SchemaComparisonItemList public static class SchemaComparisonItemList
{ {
/// <summary>Identify the maximum Id value in the list.</summary> /// <summary>Identify the maximum Id value in the list.</summary>
public static int GetMaxId (this IEnumerable<SaDbProcess_CompareDatabaseSchemas.SchemaComparisonItem> values) public static int GetMaxId(this IEnumerable<SaDbProcess_CompareDatabaseSchemas.SchemaComparisonItem> values)
{ {
int maxId = 0; int maxId = 0;
foreach (SaDbProcess_CompareDatabaseSchemas.SchemaComparisonItem schemaComparisonItem in values) foreach (SaDbProcess_CompareDatabaseSchemas.SchemaComparisonItem schemaComparisonItem in values)
@@ -0,0 +1,183 @@
using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Dbas;
using Sarand.Net.Standard.Base.IO;
using Sarand.Net.Standard.Base.Procs;
using Sarand.Net.Standard.Base.Utils;
using Sarand.Net.Standard.Dbas.Base;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace Sarand.Net.Standard.Dbas.Proc
{
//=======================================================================
public class SaDbProcess_ConvertDbSchema : SacsProcess
{
//-------------------------------------------------------------------
// Configuration.
public new class Config : SacsProcess.Config
{
public Config()
{
}
}
//-------------------------------------------------------------------
// Data members.
private Config config;
//-------------------------------------------------------------------
// Construction.
public SaDbProcess_ConvertDbSchema(Config config) : base(config)
{
this.config = config;
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
}
base.Dispose(disposing);
}
//-------------------------------------------------------------------
// Properties.
public override string ProcessDescription { get; } = "Database Definition Convertor";
public String XmlSchemaRootElementName { get; } = "DbDfnDatabase";
// Processing.
protected override bool Run()
{
throw new NotSupportedException(ProcessDescription + " - 'Run' not supported. Use a specific conversion method.");
}
//-------------------------------------------------------------------
// X M L T o T a b l e s
//-------------------------------------------------------------------
public List<DbDfnTable> ConvertXmlToTables(String xmlSchemaData)
{
ClearProcessError();
String fn = GetType().Name + ".ConvertXmlToTables";
Dictionary<String, DbDfnTable> tables = new Dictionary<String, DbDfnTable>(StringComparer.OrdinalIgnoreCase);
try
{
// Load XML data.
XDocument xmlSchema = XDocument.Parse(xmlSchemaData);
// Root element.
XElement rootElement = xmlSchema.Root;
if (rootElement == null)
throw new NotSupportedException("XML schema missing root node");
String rootElementName = rootElement.GetLocalName();
if (!rootElementName.EqualsCI(XmlSchemaRootElementName))
throw new NotSupportedException("XML schema has invalid root node. Expected: " + XmlSchemaRootElementName + ". Found: " + rootElementName);
// 'Tables' element.
XElement tablesElement = rootElement.GetFirstChildElement("Tables");
if (tablesElement == null)
throw new NotSupportedException("XML schema missing tables node");
// Iterate tables.
foreach (XElement tableElement in tablesElement.GetChildElements("DbDfnTable"))
{
DbDfnTable tableDfn = new DbDfnTable()
{
Schema = tableElement.GetChildText("Schema"),
Name = tableElement.GetChildText("Name"),
Remarks = tableElement.GetChildText("Remarks")
};
if (tableDfn.Name.IsEmpty())
throw new NotSupportedException("XML schema contains blank table name.");
if (tables.ContainsKey(tableDfn.QualifiedName))
throw new NotSupportedException("XML schema contains duplicate table: " + tableDfn.QualifiedName);
tables[tableDfn.QualifiedName] = tableDfn;
// Columns.
XElement columnsElement = tableElement.GetFirstChildElement("Columns");
if (tablesElement == null)
throw new NotSupportedException("XML schema table missing columns node: " + tableDfn.QualifiedName);
// Iterate columns.
foreach (XElement columnElement in columnsElement.GetChildElements("DbDfnColumn"))
{
DbDfnColumn columnDfn = new DbDfnColumn()
{
Schema = tableDfn.Schema,
Table = tableDfn.Name,
Pos = StringUtil.ToShort(columnElement.GetChildText("Pos")),
Name = columnElement.GetChildText("Name"),
DataType = EnumUtil.ParseEnum(columnElement.GetChildText("DataType"), DbColumnDataType.Unknown),
DataTypeName = columnElement.GetChildText("DataTypeName"),
DataTypeNative = StringUtil.ToShort(columnElement.GetChildText("DataTypeNative")),
DataTypeNameNative = columnElement.GetChildText("DataTypeNameNative"),
IsIdentity = StringUtil.ToBool(columnElement.GetChildText("IsIdentity")),
Size = StringUtil.ToLong(columnElement.GetChildText("Size")),
BufferLen = StringUtil.ToLong(columnElement.GetChildText("BufferLen")),
DecimalDigits = StringUtil.ToShort(columnElement.GetChildText("DecimalDigits")),
Nullable = EnumUtil.ParseEnum(columnElement.GetChildText("Nullable"), DbColumnNullable.Unknown),
IsNullable = StringUtil.ToBool(columnElement.GetChildText("IsNullable")),
Remarks = columnElement.GetChildText("Remarks")
};
tableDfn.AddColumn(columnDfn);
}
// Indices.
XElement IndicesElement = tableElement.GetFirstChildElement("Indices");
if (IndicesElement == null)
throw new NotSupportedException("XML schema table missing indices node: " + tableDfn.QualifiedName);
// Iterate indices.
foreach (XElement indexElement in IndicesElement.GetChildElements("DbDfnIndex"))
{
DbDfnIndex indexDfn = new DbDfnIndex()
{
Schema = tableDfn.Schema,
Table = tableDfn.Name,
Name = indexElement.GetChildText("Name"),
IndexType = StringUtil.ToInt(indexElement.GetChildText("IndexType")),
Unique = StringUtil.ToBool(indexElement.GetChildText("Unique")),
Primary = StringUtil.ToBool(indexElement.GetChildText("Primary")),
Clustered = StringUtil.ToBool(indexElement.GetChildText("Clustered")),
Nullable = StringUtil.ToBool(indexElement.GetChildText("Nullable")),
Pages = StringUtil.ToInt(indexElement.GetChildText("Pages")),
UniqueValues = StringUtil.ToInt(indexElement.GetChildText("UniqueValues")),
HasColumns = StringUtil.ToBool(indexElement.GetChildText("HasColumns")),
};
// Index columns.
XElement IndexColumnsElement = indexElement.GetFirstChildElement("Columns");
foreach (XElement indexColumnElement in IndexColumnsElement?.GetChildElements("DbDfnIndexColumn") ?? Enumerable.Empty<XElement>())
{
DbDfnIndexColumn indexColumn = new DbDfnIndexColumn()
{
Seq = StringUtil.ToShort(indexColumnElement.GetChildText("Seq")),
Name = indexColumnElement.GetChildText("Name"),
Ascend = StringUtil.ToBool(indexColumnElement.GetChildText("Ascend")),
};
indexDfn.AddColumn(indexColumn);
}
tableDfn.AddIndex(indexDfn);
}
}
}
catch (Exception exc)
{
SetProcessError(exc.GetErrorStateMessage());
SaLogger.Warn(fn + " " + ExceptionUtil.GetLogMessage(exc));
}
return tables.Values.ToList();
}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -86,7 +86,7 @@ namespace Sarand.Net.Standard.Dbas.ReferenceData
catch (Exception exc) catch (Exception exc)
{ {
SetErrorState("Database query exception"); SetErrorState("Database query exception");
SaLogger.Warn(GetType().Name + ".GetCurrency\n\tQuery: " + dbCommand.CommandText + "\n\t" + exc.GetType().Name + ": " + exc.Message); SaLogger.Warn(GetType().Name + ".GetCurrency\n\tQuery: " + dbCommand.CommandText + "\n\t" + ExceptionUtil.GetLogMessage(exc));
} }
} }
return currency; return currency;
@@ -451,7 +451,7 @@ namespace Sarand.Net.Standard.Dbas.ReferenceData
} }
catch (Exception exc) catch (Exception exc)
{ {
SaLogger.Warn(GetType().Name + ".GetCurrencyList\n\tQuery: " + dbCommand.CommandText + "\n\t" + exc.GetType().Name + ": " + exc.Message); SaLogger.Warn(GetType().Name + ".GetCurrencyList\n\tQuery: " + dbCommand.CommandText + "\n\t" + ExceptionUtil.GetLogMessage(exc));
} }
} }
return currencies; return currencies;
@@ -86,7 +86,7 @@ namespace Sarand.Net.Standard.Dbas.ReferenceData
catch (Exception exc) catch (Exception exc)
{ {
SetErrorState("Database query exception"); SetErrorState("Database query exception");
SaLogger.Warn(GetType().Name + ".GetLanguage\n\tQuery: " + dbCommand.CommandText + "\n\t" + exc.GetType().Name + ": " + exc.Message); SaLogger.Warn(GetType().Name + ".GetLanguage\n\tQuery: " + dbCommand.CommandText + "\n\t" + ExceptionUtil.GetLogMessage(exc));
} }
} }
return language; return language;
@@ -457,7 +457,7 @@ namespace Sarand.Net.Standard.Dbas.ReferenceData
} }
catch (Exception exc) catch (Exception exc)
{ {
SaLogger.Warn(GetType().Name + ".GetLanguageList\n\tQuery: " + dbCommand.CommandText + "\n\t" + exc.GetType().Name + ": " + exc.Message); SaLogger.Warn(GetType().Name + ".GetLanguageList\n\tQuery: " + dbCommand.CommandText + "\n\t" + ExceptionUtil.GetLogMessage(exc));
} }
} }
return languages; return languages;
@@ -86,7 +86,7 @@ namespace Sarand.Net.Standard.Dbas.ReferenceData
catch (Exception exc) catch (Exception exc)
{ {
SetErrorState("Database query exception"); SetErrorState("Database query exception");
SaLogger.Warn(GetType().Name + ".GetRegion\n\tQuery: " + dbCommand.CommandText + "\n\t" + exc.GetType().Name + ": " + exc.Message); SaLogger.Warn(GetType().Name + ".GetRegion\n\tQuery: " + dbCommand.CommandText + "\n\t" + ExceptionUtil.GetLogMessage(exc));
} }
} }
return region; return region;
@@ -239,7 +239,7 @@ namespace Sarand.Net.Standard.Dbas.ReferenceData
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Region column definitions. // Region column definitions.
private static readonly String aliasRegion = "aReg"; private static readonly String aliasRegion = "aRgn";
private void SetRegionColDfn private void SetRegionColDfn
(ColumnDfn col, String caption, int width, SaReferenceDataDbDfn.ColumnIdx dbCol, (ColumnDfn col, String caption, int width, SaReferenceDataDbDfn.ColumnIdx dbCol,
ColumnAlignment align = ColumnAlignment.Default, DataValue.DataType dataType = DataValue.DataType.String, ColumnAlignment align = ColumnAlignment.Default, DataValue.DataType dataType = DataValue.DataType.String,
@@ -436,7 +436,7 @@ namespace Sarand.Net.Standard.Dbas.ReferenceData
} }
catch (Exception exc) catch (Exception exc)
{ {
SaLogger.Warn(GetType().Name + ".GetRegionList\n\tQuery: " + dbCommand.CommandText + "\n\t" + exc.GetType().Name + ": " + exc.Message); SaLogger.Warn(GetType().Name + ".GetRegionList\n\tQuery: " + dbCommand.CommandText + "\n\t" + ExceptionUtil.GetLogMessage(exc));
} }
} }
return regions; return regions;
@@ -86,7 +86,7 @@ namespace Sarand.Net.Standard.Dbas.ReferenceData
catch (Exception exc) catch (Exception exc)
{ {
SetErrorState("Database query exception"); SetErrorState("Database query exception");
SaLogger.Warn(GetType().Name + ".GetTaxCode\n\tQuery: " + dbCommand.CommandText + "\n\t" + exc.GetType().Name + ": " + exc.Message); SaLogger.Warn(GetType().Name + ".GetTaxCode\n\tQuery: " + dbCommand.CommandText + "\n\t" + ExceptionUtil.GetLogMessage(exc));
} }
} }
return taxCode; return taxCode;
@@ -477,7 +477,7 @@ namespace Sarand.Net.Standard.Dbas.ReferenceData
} }
catch (Exception exc) catch (Exception exc)
{ {
SaLogger.Warn(GetType().Name + ".GetTaxCodeList\n\tQuery: " + dbCommand.CommandText + "\n\t" + exc.GetType().Name + ": " + exc.Message); SaLogger.Warn(GetType().Name + ".GetTaxCodeList\n\tQuery: " + dbCommand.CommandText + "\n\t" + ExceptionUtil.GetLogMessage(exc));
} }
} }
return taxCodes; return taxCodes;
@@ -86,7 +86,7 @@ namespace Sarand.Net.Standard.Dbas.ReferenceData
catch (Exception exc) catch (Exception exc)
{ {
SetErrorState("Database query exception"); SetErrorState("Database query exception");
SaLogger.Warn(GetType().Name + ".GetUnitMeasure\n\tQuery: " + dbCommand.CommandText + "\n\t" + exc.GetType().Name + ": " + exc.Message); SaLogger.Warn(GetType().Name + ".GetUnitMeasure\n\tQuery: " + dbCommand.CommandText + "\n\t" + ExceptionUtil.GetLogMessage(exc));
} }
} }
return unitMeasure; return unitMeasure;
@@ -486,7 +486,7 @@ namespace Sarand.Net.Standard.Dbas.ReferenceData
} }
catch (Exception exc) catch (Exception exc)
{ {
SaLogger.Warn(GetType().Name + ".GetUnitMeasureList\n\tQuery: " + dbCommand.CommandText + "\n\t" + exc.GetType().Name + ": " + exc.Message); SaLogger.Warn(GetType().Name + ".GetUnitMeasureList\n\tQuery: " + dbCommand.CommandText + "\n\t" + ExceptionUtil.GetLogMessage(exc));
} }
} }
return unitMeasures; return unitMeasures;
@@ -85,7 +85,7 @@ namespace Sarand.Net.Standard.Dbas.Security
} }
catch (Exception exc) catch (Exception exc)
{ {
SaLogger.Warn(GetType().Name + ".GetSecurityItem\n\tQuery: " + dbCommand.CommandText + "\n\t" + exc.GetType().Name + ": " + exc.Message); SaLogger.Warn(GetType().Name + ".GetSecurityItem\n\tQuery: " + dbCommand.CommandText + "\n\t" + ExceptionUtil.GetLogMessage(exc));
} }
} }
return securityItem; return securityItem;
@@ -520,7 +520,7 @@ namespace Sarand.Net.Standard.Dbas.Security
} }
catch (Exception exc) catch (Exception exc)
{ {
SaLogger.Warn(GetType().Name + ".GetSecurityItemList\n\tQuery: " + dbCommand.CommandText + "\n\t" + exc.GetType().Name + ": " + exc.Message); SaLogger.Warn(GetType().Name + ".GetSecurityItemList\n\tQuery: " + dbCommand.CommandText + "\n\t" + ExceptionUtil.GetLogMessage(exc));
} }
} }
return secItems; return secItems;
@@ -57,7 +57,7 @@ namespace Sarand.Net.Standard.Dbas.Security
} }
catch (Exception exc) catch (Exception exc)
{ {
SaLogger.Warn(GetType().Name + ".GetSecurityLink\n\tQuery: " + dbCommand.CommandText + "\n\t" + exc.GetType().Name + ": " + exc.Message); SaLogger.Warn(GetType().Name + ".GetSecurityLink\n\tQuery: " + dbCommand.CommandText + "\n\t" + ExceptionUtil.GetLogMessage(exc));
} }
} }
return securityLink; return securityLink;
@@ -429,7 +429,7 @@ namespace Sarand.Net.Standard.Dbas.Security
} }
catch (Exception exc) catch (Exception exc)
{ {
SaLogger.Warn(GetType().Name + ".GetSecurityLinkList\n\tQuery: " + dbCommand.CommandText + "\n\t" + exc.GetType().Name + ": " + exc.Message); SaLogger.Warn(GetType().Name + ".GetSecurityLinkList\n\tQuery: " + dbCommand.CommandText + "\n\t" + ExceptionUtil.GetLogMessage(exc));
} }
} }
return secLinks; return secLinks;
@@ -99,7 +99,7 @@ namespace Sarand.Net.Standard.Dbas.UpdateLog
} }
catch (Exception exc) catch (Exception exc)
{ {
SaLogger.Warn(GetType().Name + ".GetUpdateLog\n\tQuery: " + dbCommand.CommandText + "\n\t" + exc.GetType().Name + ": " + exc.Message); SaLogger.Warn(GetType().Name + ".GetUpdateLog\n\tQuery: " + dbCommand.CommandText + "\n\t" + ExceptionUtil.GetLogMessage(exc));
} }
} }
return logEntry; return logEntry;
@@ -589,7 +589,7 @@ namespace Sarand.Net.Standard.Dbas.UpdateLog
} }
catch (Exception exc) catch (Exception exc)
{ {
SaLogger.Warn(GetType().Name + ".GetLogEntryList\n\tQuery: " + dbCommand.CommandText + "\n\t" + exc.GetType().Name + ": " + exc.Message); SaLogger.Warn(GetType().Name + ".GetLogEntryList\n\tQuery: " + dbCommand.CommandText + "\n\t" + ExceptionUtil.GetLogMessage(exc));
} }
} }
return logEntries; return logEntries;