Add project files.
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Sarand.Net.Standard.Base.Bus;
|
||||
using Sarand.Net.Standard.Base.Dbas;
|
||||
|
||||
namespace Sarand.Net.Standard.Base.UpdateLog
|
||||
{
|
||||
//=======================================================================
|
||||
// Definitions.
|
||||
|
||||
//=======================================================================
|
||||
public abstract class SaUpdateLogConsole : SaErrorStateItem
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Static initialisation
|
||||
static SaUpdateLogConsole ()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Protected construction - use derived classes.
|
||||
protected SaUpdateLogConsole ()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
public abstract bool DatabaseIsValid { get; }
|
||||
public abstract bool CanUpdateDatabase { get; }
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Utilities - retrieve application data.
|
||||
public abstract Dictionary<SysId, String> GetNameForUserIds (List<SysId> userIds);
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Update Log Form.
|
||||
public class ShowUpdateLogConfig
|
||||
{
|
||||
public ShowUpdateLogConfig(ItemId itemId, String itemCaption, DbUpdateInfo dbUpdateInfo)
|
||||
{
|
||||
ItemId = itemId;
|
||||
ItemCaption = itemCaption;
|
||||
DbUpdateInfo = dbUpdateInfo;
|
||||
}
|
||||
public ItemId ItemId { get; }
|
||||
public String ItemCaption { get; }
|
||||
public DbUpdateInfo DbUpdateInfo { get; }
|
||||
}
|
||||
public abstract bool ShowUpdateLogDialog (ShowUpdateLogConfig config);
|
||||
|
||||
//*******************************************************************
|
||||
// U p d a t e L o g E n t r i e s
|
||||
//*******************************************************************
|
||||
// Log updates.
|
||||
public abstract bool LogUpdates (SaUpdateLogItemMonitor updateLogItemMonitor);
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Retrieve list of updates that match the specified params:
|
||||
public abstract bool ItemHasLogEntries (ItemId itemId);
|
||||
public abstract bool LogEntriesExist (SaUpdateLogEntry.Params prmUpdateLog);
|
||||
public abstract SaUpdateLogEntry GetLogEntry (ItemId itemId, String attrName, DateTime loggedAt);
|
||||
public abstract long GetLogEntryCount (SaUpdateLogEntry.Params prmUpdateLog);
|
||||
public abstract List<SaUpdateLogEntry> GetLogEntries (SaUpdateLogEntry.Params prmUpdateLog);
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Create a new item data.
|
||||
public abstract SaUpdateLogEntry CreateLogEntry (ItemId itemId, String attrName);
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Store item data.
|
||||
public abstract bool StoreLogEntry (SaUpdateLogEntry logEntry, DbUpdateInfo dbUpdateInfo);
|
||||
public abstract bool RemoveLogEntry (SaUpdateLogEntry logEntry, DbUpdateInfo dbUpdateInfo);
|
||||
public abstract bool ClearLogEntriesForItem (ItemId itemId, DbUpdateInfo dbUpdateInfo);
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,320 @@
|
||||
using Sarand.Net.Standard.Base.Core;
|
||||
using Sarand.Net.Standard.Base.Dbas;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Code generated by Sarand Database Utilities Thu 3-Oct-2019 15:11:05
|
||||
//---------------------------------------------------------------------------
|
||||
namespace Sarand.Net.Standard.Base.UpdateLog
|
||||
{
|
||||
public class SaUpdateLogDbDfn
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Table identifiers.
|
||||
public enum TableIdx
|
||||
{
|
||||
Unknown = 0,
|
||||
SaAttrUpdate,
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Column identifiers.
|
||||
public enum ColumnIdx
|
||||
{
|
||||
Unknown = 0,
|
||||
SaAttrUpdate_ItemType,
|
||||
SaAttrUpdate_ItemId,
|
||||
SaAttrUpdate_Logged,
|
||||
SaAttrUpdate_Attribute,
|
||||
SaAttrUpdate_DataBefore,
|
||||
SaAttrUpdate_DataAfter,
|
||||
SaAttrUpdate_Notes,
|
||||
SaAttrUpdate_Flags,
|
||||
SaAttrUpdate_Status,
|
||||
SaAttrUpdate_CreateOn,
|
||||
SaAttrUpdate_CreateBy,
|
||||
SaAttrUpdate_CreateHost,
|
||||
SaAttrUpdate_UpdateOn,
|
||||
SaAttrUpdate_UpdateBy,
|
||||
SaAttrUpdate_UpdateHost,
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
private static readonly int tableCount = 1;
|
||||
private static readonly int columnCount = 15;
|
||||
private static ulong maxTextLen = 0;
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Retrieve Table details (eg. name: 'Company').
|
||||
public static int GetTableCount ()
|
||||
{
|
||||
return tableCount;
|
||||
}
|
||||
public static String GetTableName (TableIdx table, bool delimitReservedWords = true)
|
||||
{
|
||||
int tableIdx = (int)table - 1;
|
||||
if (tableIdx < 0 || tableIdx >= tableCount) return String.Empty;
|
||||
String tableName = tables[(int)tableIdx];
|
||||
if (delimitReservedWords) tableName = DelimitReservedWord(tableName);
|
||||
return tableName;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Identify the table that corresponds with the specified column.
|
||||
public static TableIdx GetTableForColumn (ColumnIdx column)
|
||||
{
|
||||
int columnIdx = (int)column - 1;
|
||||
if (columnIdx < 0 || columnIdx >= columnCount) return TableIdx.Unknown;
|
||||
return columns[columnIdx].TableIdx;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Retrieve the specified Column's name (Qualified include table name: '(<Table>.Column>)').
|
||||
public static String GetColumnName (ColumnIdx column, bool delimitReservedWords = true)
|
||||
{
|
||||
int columnIdx = (int)column - 1;
|
||||
if (columnIdx < 0 || columnIdx >= columnCount) return String.Empty;
|
||||
String columnName = columns[columnIdx].Name;
|
||||
if (delimitReservedWords) columnName = DelimitReservedWord(columnName);
|
||||
return columnName;
|
||||
}
|
||||
public static String GetColumnNameQual (ColumnIdx column, String tableAlias = "", bool braces = false)
|
||||
{
|
||||
String columnName = GetColumnName(column);
|
||||
if (!String.IsNullOrEmpty(columnName))
|
||||
{
|
||||
String tableName = StringUtil.EmptyOnNull(tableAlias);
|
||||
if (tableName.IsEmpty()) tableName = GetTableName(GetTableForColumn(column));
|
||||
columnName = tableName + (tableName.Length > 0 ? "." : "") + columnName;
|
||||
if (braces)
|
||||
columnName = "(" + columnName + ")";
|
||||
}
|
||||
return columnName;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Reserved words.
|
||||
private static DbReservedWordDelim reservedWordDelim = DbReservedWordDelim.SquareBrackets;
|
||||
public static void SetReservedWordDelim (DbReservedWordDelim reservedWordDelim)
|
||||
{
|
||||
SaUpdateLogDbDfn.reservedWordDelim = reservedWordDelim;
|
||||
}
|
||||
public static bool IsReservedWord (String word)
|
||||
{
|
||||
if (String.IsNullOrEmpty(word)) return false;
|
||||
if (reservedWords.Contains(word, StringComparer.OrdinalIgnoreCase)) return true;
|
||||
return false;
|
||||
}
|
||||
public static String DelimitReservedWord (String word)
|
||||
{
|
||||
if (!IsReservedWord(word)) return word;
|
||||
switch (reservedWordDelim)
|
||||
{
|
||||
case DbReservedWordDelim.None:
|
||||
break;
|
||||
case DbReservedWordDelim.DoubleQuotes:
|
||||
word = "\"" + word + "\"";
|
||||
break;
|
||||
case DbReservedWordDelim.SquareBrackets:
|
||||
default:
|
||||
word = "[" + word + "]";
|
||||
break;
|
||||
}
|
||||
return word;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Retrieve information about the specified Column.
|
||||
public static DbColumnDataType GetColDataType (ColumnIdx column)
|
||||
{
|
||||
int columnIdx = (int)column - 1;
|
||||
if (columnIdx < 0 || columnIdx >= columnCount) return DbColumnDataType.Unknown;
|
||||
return columns[columnIdx].DataType;
|
||||
}
|
||||
public static short GetColNativeDataType (ColumnIdx column)
|
||||
{
|
||||
int columnIdx = (int)column - 1;
|
||||
if (columnIdx < 0 || columnIdx >= columnCount) return 0;
|
||||
return columns[columnIdx].NativeDataType;
|
||||
}
|
||||
public static void SetMaxTextLen (ulong maxTextLen)
|
||||
{
|
||||
SaUpdateLogDbDfn.maxTextLen = maxTextLen;
|
||||
}
|
||||
public static bool IsColFmtText (ColumnIdx column)
|
||||
{
|
||||
int columnIdx = (int)column - 1;
|
||||
if (columnIdx < 0 || columnIdx >= columnCount) return false;
|
||||
return (columns[columnIdx].DataType == DbColumnDataType.VarChar);
|
||||
}
|
||||
public static ulong GetColTextLen (ColumnIdx column)
|
||||
{
|
||||
int columnIdx = (int)column - 1;
|
||||
if (columnIdx < 0 || columnIdx >= columnCount) return 0;
|
||||
if (columns[columnIdx].DataType == DbColumnDataType.VarChar)
|
||||
{
|
||||
ulong textLen = columns[columnIdx].DataLen;
|
||||
if (maxTextLen > 0 && textLen > maxTextLen) textLen = maxTextLen;
|
||||
return textLen;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
public static bool IsColFmtBool (ColumnIdx column)
|
||||
{
|
||||
int columnIdx = (int)column - 1;
|
||||
if (columnIdx < 0 || columnIdx >= columnCount) return false;
|
||||
return (columns[columnIdx].DataType == DbColumnDataType.Bit);
|
||||
}
|
||||
public static bool IsColFmtNumeric (ColumnIdx column)
|
||||
{
|
||||
int columnIdx = (int)column - 1;
|
||||
if (columnIdx < 0 || columnIdx >= columnCount) return false;
|
||||
switch (columns[columnIdx].DataType)
|
||||
{
|
||||
case DbColumnDataType.TinyInt:
|
||||
case DbColumnDataType.SmallInt:
|
||||
case DbColumnDataType.Int:
|
||||
case DbColumnDataType.BigInt:
|
||||
case DbColumnDataType.Single:
|
||||
case DbColumnDataType.Double:
|
||||
case DbColumnDataType.Decimal:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Table definitions.
|
||||
private static readonly String[] tables =
|
||||
{
|
||||
"SaAttrUpdate",
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Table column definitions.
|
||||
internal class ColumnDfn
|
||||
{
|
||||
internal TableIdx TableIdx { get; set; }
|
||||
internal String Name { get; set; }
|
||||
internal DbColumnDataType DataType { get; set; }
|
||||
internal short NativeDataType { get; set; }
|
||||
internal bool IsIdentity { get; set; }
|
||||
internal ulong DataLen { get; set; }
|
||||
internal ColumnDfn (int tableIdx, String name, int dataType, short nativeDataType, bool isIdentity, ulong dataLen)
|
||||
{
|
||||
this.TableIdx = (TableIdx)tableIdx;
|
||||
this.Name = name;
|
||||
this.DataType = (DbColumnDataType)dataType;
|
||||
this.NativeDataType = nativeDataType;
|
||||
this.IsIdentity = isIdentity;
|
||||
this.DataLen = dataLen;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
private static readonly ColumnDfn[] columns =
|
||||
{
|
||||
new ColumnDfn(1,"ItemType",3,5,false,5),
|
||||
new ColumnDfn(1,"ItemId",4,4,false,10),
|
||||
new ColumnDfn(1,"Logged",9,93,false,23),
|
||||
new ColumnDfn(1,"Attribute",0,12,false,32),
|
||||
new ColumnDfn(1,"DataBefore",0,-9,false,1024),
|
||||
new ColumnDfn(1,"DataAfter",0,-9,false,1024),
|
||||
new ColumnDfn(1,"Notes",0,-9,false,255),
|
||||
new ColumnDfn(1,"Flags",3,5,false,5),
|
||||
new ColumnDfn(1,"Status",0,12,false,3),
|
||||
new ColumnDfn(1,"CreateOn",9,93,false,23),
|
||||
new ColumnDfn(1,"CreateBy",4,4,false,10),
|
||||
new ColumnDfn(1,"CreateHost",0,12,false,64),
|
||||
new ColumnDfn(1,"UpdateOn",9,93,false,23),
|
||||
new ColumnDfn(1,"UpdateBy",4,4,false,10),
|
||||
new ColumnDfn(1,"UpdateHost",0,12,false,64),
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Reserved words.
|
||||
private static readonly List<String> reservedWords = new List<String>()
|
||||
{
|
||||
"ADD",
|
||||
"ALL",
|
||||
"ALTER",
|
||||
"AND",
|
||||
"ANY",
|
||||
"AS",
|
||||
"ASC",
|
||||
"AVG",
|
||||
"BEGIN",
|
||||
"BETWEEN",
|
||||
"BY",
|
||||
"CASE",
|
||||
"CAST",
|
||||
"COLUMN",
|
||||
"COMMIT",
|
||||
"CONSTRAINT",
|
||||
"CONVERT",
|
||||
"COUNT",
|
||||
"CREATE",
|
||||
"CURRENCY",
|
||||
"DEFAULT",
|
||||
"DELETE",
|
||||
"DESC",
|
||||
"DISTINCT",
|
||||
"DROP",
|
||||
"ELSE",
|
||||
"END",
|
||||
"EXECUTE",
|
||||
"EXISTS",
|
||||
"FALSE",
|
||||
"FROM",
|
||||
"GRANT",
|
||||
"GROUP",
|
||||
"HAVING",
|
||||
"IN",
|
||||
"INDEX",
|
||||
"INNER",
|
||||
"INSERT",
|
||||
"INTO",
|
||||
"IS",
|
||||
"JOIN",
|
||||
"KEY",
|
||||
"LEFT",
|
||||
"LIKE",
|
||||
"MAX",
|
||||
"MIN",
|
||||
"NOT",
|
||||
"NULL",
|
||||
"ON",
|
||||
"OR",
|
||||
"ORDER",
|
||||
"OUTER",
|
||||
"OUTPUT",
|
||||
"PRIMARY",
|
||||
"PROCEDURE",
|
||||
"REVOKE",
|
||||
"ROLLBACK",
|
||||
"ROWCOUNT",
|
||||
"SELECT",
|
||||
"SET",
|
||||
"SQL",
|
||||
"SUM",
|
||||
"TABLE",
|
||||
"THEN",
|
||||
"TRANSACTION",
|
||||
"TRUE",
|
||||
"UNION",
|
||||
"UNIQUE",
|
||||
"UPDATE",
|
||||
"USER",
|
||||
"VALUES",
|
||||
"VIEW",
|
||||
"WHEN",
|
||||
"WHERE",
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,226 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Sarand.Net.Standard.Base.Core;
|
||||
using Sarand.Net.Standard.Base.Bus;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
|
||||
namespace Sarand.Net.Standard.Base.UpdateLog
|
||||
{
|
||||
//=======================================================================
|
||||
public abstract class SaUpdateLogEntry : SacsHierarchyItem
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Columns.
|
||||
public enum Column
|
||||
{
|
||||
Pos = 0,
|
||||
// Log Entry properties.
|
||||
ItemType,
|
||||
ItemType_Desc,
|
||||
ItemId,
|
||||
Attribute,
|
||||
Location,
|
||||
Logged,
|
||||
Logged_Date,
|
||||
Logged_Time,
|
||||
DataBefore,
|
||||
DataAfter,
|
||||
// Common properties.
|
||||
Notes,
|
||||
Status,
|
||||
Status_Desc,
|
||||
Status_Ind,
|
||||
CreateOn_Date,
|
||||
CreateBy,
|
||||
CreateBy_Name,
|
||||
UpdateOn_Date,
|
||||
Hidden,
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>Properties other than common.</summary>
|
||||
public class DataProperties
|
||||
{
|
||||
public ItemId ItemId { get; set; } = null;
|
||||
public String Attribute { get; set; } = String.Empty;
|
||||
public DateTime Logged { get; set; } = DateTime.MinValue;
|
||||
public String DataBefore { get; set; } = String.Empty;
|
||||
public String DataAfter { get; set; } = String.Empty;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data.
|
||||
public new class Data : SacsHierarchyItem.Data
|
||||
{
|
||||
// Data members.
|
||||
private readonly DataProperties data = new DataProperties();
|
||||
// Construction.
|
||||
public Data ()
|
||||
{
|
||||
Status = DefaultStatus;
|
||||
}
|
||||
// Properties.
|
||||
public ItemId ItemId
|
||||
{
|
||||
get { return data.ItemId; }
|
||||
set { CheckChanged(data.ItemId, value); data.ItemId = value; }
|
||||
}
|
||||
public String Attribute
|
||||
{
|
||||
get { return data.Attribute; }
|
||||
set { CheckChanged(data.Attribute, value); data.Attribute = value; }
|
||||
}
|
||||
public DateTime Logged
|
||||
{
|
||||
get { return data.Logged; }
|
||||
set { CheckChanged(data.Logged, value); data.Logged = value; }
|
||||
}
|
||||
public String DataBefore
|
||||
{
|
||||
get { return data.DataBefore; }
|
||||
set { CheckChanged(data.DataBefore, value); data.DataBefore = value; }
|
||||
}
|
||||
public String DataAfter
|
||||
{
|
||||
get { return data.DataAfter; }
|
||||
set { CheckChanged(data.DataAfter, value); data.DataAfter = value; }
|
||||
}
|
||||
// Population.
|
||||
internal void PopulateFrom (Data data)
|
||||
{
|
||||
ItemId = data.ItemId;
|
||||
Attribute = data.Attribute;
|
||||
Logged = data.Logged;
|
||||
DataBefore = data.DataBefore;
|
||||
DataAfter = data.DataAfter;
|
||||
base.PopulateFrom(data);
|
||||
}
|
||||
public Data Clone ()
|
||||
{
|
||||
Data data = new Data();
|
||||
data.PopulateFrom(this);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Error field - identify properties with validation error.
|
||||
public new class ErrField : SacsHierarchyItem.ErrField
|
||||
{
|
||||
// Identifies the field that has invalid data.
|
||||
public ValidValue ItemType { get; set; } = ValidValue.Valid;
|
||||
public ValidValue ItemId { get; set; } = ValidValue.Valid;
|
||||
public ValidValue Attribute { get; set; } = ValidValue.Valid;
|
||||
public ValidValue Logged { get; set; } = ValidValue.Valid;
|
||||
public ValidValue DataBefore { get; set; } = ValidValue.Valid;
|
||||
public ValidValue DataAfter { get; set; } = ValidValue.Valid;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
private readonly Data data = new Data();
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
public SaUpdateLogEntry (ItemId itemId, String attribute, DateTime logged) :
|
||||
base()
|
||||
{
|
||||
base.SetData(data);
|
||||
ItemId = itemId;
|
||||
Attribute = attribute;
|
||||
Logged = logged;
|
||||
Status = DefaultStatus;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Statuses.
|
||||
private static readonly List<SaStatus> validStatuses = new List<SaStatus>()
|
||||
{
|
||||
SaStatus.Logged,
|
||||
SaStatus.Deleted
|
||||
};
|
||||
public static SaStatus DefaultStatus { get { return LoggedStatus; } }
|
||||
public static SaStatus LoggedStatus { get { return SaStatus.Logged; } }
|
||||
public static List<SaStatus> ValidStatuses { get { return new List<SaStatus>(validStatuses); } }
|
||||
public static DataValue.TriStateType GetStatusTriState (SaStatus status)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case SaStatus.Logged:
|
||||
return DataValue.TriStateType.Green;
|
||||
case SaStatus.Deleted:
|
||||
return DataValue.TriStateType.Purple;
|
||||
}
|
||||
return DataValue.TriStateType.Unknown;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
public Data GetData () { return data.Clone(); }
|
||||
public void SetData (Data data)
|
||||
{
|
||||
String fn = GetType().Name + ".SetData";
|
||||
// Properties that cannot be changed if previously specified.
|
||||
if (ItemId.Type >= 0 && ItemId.Type != data.ItemId.Type)
|
||||
throw new NotSupportedException(fn + " Item type cannot be changed");
|
||||
if (SysId.IsValid(ItemId.Id) && SysId.ToInt(ItemId.Id) != SysId.ToInt(data.ItemId.Id))
|
||||
throw new NotSupportedException(fn + " Item Id cannot be changed");
|
||||
if (!StringUtil.IsEmpty(Attribute) && !Attribute.Equals(data.Attribute))
|
||||
throw new NotSupportedException(fn + " Attribute cannot be changed");
|
||||
if (Logged != DateTime.MinValue && !Logged.Equals(data.Logged))
|
||||
throw new NotSupportedException(fn + " Logged date/time cannot be changed");
|
||||
// Populate individual properties to ensure that 'Changed' indicator is kept up to date.
|
||||
this.data.PopulateFrom(data);
|
||||
}
|
||||
public ItemId ItemId
|
||||
{
|
||||
get { return data.ItemId; }
|
||||
protected set { data.ItemId = value; }
|
||||
}
|
||||
public String Attribute
|
||||
{
|
||||
get { return data.Attribute; }
|
||||
protected set { data.Attribute = value; }
|
||||
}
|
||||
public DateTime Logged
|
||||
{
|
||||
get { return data.Logged; }
|
||||
protected set { data.Logged = value; }
|
||||
}
|
||||
public String DataBefore
|
||||
{
|
||||
get { return data.DataBefore; }
|
||||
set { data.DataBefore = value; }
|
||||
}
|
||||
public String DataAfter
|
||||
{
|
||||
get { return data.DataAfter; }
|
||||
set { data.DataAfter = value; }
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// List parameters.
|
||||
/// <summary>
|
||||
/// Item list parameters.
|
||||
/// </summary>
|
||||
public new class Params : SacsHierarchyItem.Params
|
||||
{
|
||||
public List<ItemId> IncludedItemIds { get; } = new List<ItemId>();
|
||||
public List<String> IncludedAttributes { get; } = new List<String>();
|
||||
public DateTime Logged { get; set; } = DateTime.MinValue;
|
||||
public DateTime LoggedFrom { get; set; } = DateTime.MinValue;
|
||||
public DateTime LoggedTo { get; set; } = DateTime.MinValue;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// L i s t
|
||||
//-------------------------------------------------------------------
|
||||
public class List : List<SaUpdateLogEntry>
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Sarand.Net.Standard.Base.Core;
|
||||
using Sarand.Net.Standard.Base.Bus;
|
||||
using Sarand.Net.Standard.Base.Dbas;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
|
||||
namespace Sarand.Net.Standard.Base.UpdateLog
|
||||
{
|
||||
//=======================================================================
|
||||
public class SaUpdateLogItemMonitor : SacsStateItem
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Configuration.
|
||||
public class Config
|
||||
{
|
||||
public Config (SaUpdateLogConsole updateLogConsole, DbUpdateInfo dbUpdateInfo)
|
||||
{
|
||||
UpdateLogConsole = updateLogConsole;
|
||||
DbUpdateInfo = dbUpdateInfo;
|
||||
}
|
||||
public SaUpdateLogConsole UpdateLogConsole { get; }
|
||||
public short ItemType { get; set; }
|
||||
public SysId ItemId { get; set; }
|
||||
public DbUpdateInfo DbUpdateInfo { get; }
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Definitions.
|
||||
public class AttrData
|
||||
{
|
||||
public AttrData (String name)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
public String Name { get; private set; }
|
||||
public DataValue ValueBefore { get; internal set; } = new DataValue();
|
||||
public DataValue ValueAfter { get; internal set; } = new DataValue();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
private Config config = null;
|
||||
private readonly Dictionary<String,AttrData> attrUpdateMap = new Dictionary<String,AttrData>();
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Static initialisation
|
||||
static SaUpdateLogItemMonitor ()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Protected construction - use derived classes.
|
||||
protected SaUpdateLogItemMonitor (Config config)
|
||||
{
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
public short ItemType { get { return config.ItemType; } }
|
||||
public SysId ItemId { get { return config.ItemId; } }
|
||||
public List<AttrData> AttrUpdates
|
||||
{
|
||||
get
|
||||
{
|
||||
// Compile list of attributes whose value has changed.
|
||||
List<AttrData> attrUpdates = new List<AttrData>();
|
||||
foreach (AttrData attrData in attrUpdateMap.Values)
|
||||
{
|
||||
if (!FormatDataValue(attrData.ValueBefore).Equals(FormatDataValue(attrData.ValueAfter)))
|
||||
{
|
||||
// Data values are ppre-formatted as Strings for database storage.
|
||||
attrUpdates.Add(new AttrData(attrData.Name) { ValueBefore=new DataValue(FormatDataValue(attrData.ValueBefore)), ValueAfter= new DataValue(FormatDataValue(attrData.ValueAfter)) });
|
||||
}
|
||||
}
|
||||
return attrUpdates;
|
||||
}
|
||||
}
|
||||
public DbUpdateInfo DbUpdateInfo { get { return config.DbUpdateInfo; } }
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Log updates.
|
||||
public bool LogUpdates ()
|
||||
{
|
||||
ClearErrorState();
|
||||
if (!config.UpdateLogConsole.LogUpdates(this))
|
||||
SetErrorState(config.UpdateLogConsole.ErrorStateMessage);
|
||||
return !HasErrorState();
|
||||
}
|
||||
protected virtual bool IsColumnChangeLogged (String attrName)
|
||||
{
|
||||
if (!config.UpdateLogConsole.CanUpdateDatabase) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Populate attribute values.
|
||||
protected bool RecordAttrValue (String attrName, String value, bool newValue)
|
||||
{
|
||||
return RecordAttrValue(attrName, new DataValue(value), newValue);
|
||||
}
|
||||
protected bool RecordAttrValue (String attrName, int value, bool newValue, bool blankZeroValue = true)
|
||||
{
|
||||
return RecordAttrValue(attrName, new DataValue(value == 0 && blankZeroValue ? "" : value.ToString()), newValue);
|
||||
}
|
||||
protected bool RecordAttrValue (String attrName, decimal value, bool newValue, bool blankZeroValue = true, ushort decimals = 2)
|
||||
{
|
||||
return RecordAttrValue(attrName, new DataValue(value == 0.0m && blankZeroValue ? "" : value.ToString("N" + decimals.ToString())), newValue);
|
||||
}
|
||||
protected bool RecordAttrValue (String attrName, DateTime value, bool newValue, bool includeTime = true)
|
||||
{
|
||||
return RecordAttrValue(attrName, new DataValue(DateUtil.Format(value, (includeTime ? "d-MMM-yyyy HH:mm" : "d-MMM-yyyy"))), newValue);
|
||||
}
|
||||
protected bool RecordAttrValue (String attrName, DataValue value, bool newValue)
|
||||
{
|
||||
ClearErrorState();
|
||||
if (attrName.IsEmpty()) return SetErrorState("Blank attribute name ["+GetType().Name+"]");
|
||||
if (!IsColumnChangeLogged(attrName)) return true;
|
||||
if (newValue)
|
||||
SetAttrValueAfter(attrName, value);
|
||||
else
|
||||
SetAttrValueBefore(attrName, value);
|
||||
return !HasErrorState();
|
||||
}
|
||||
public void SetAttrValueBefore (String attrName, DataValue value)
|
||||
{
|
||||
AttrData attrData = (attrUpdateMap.ContainsKey(attrName) ? attrUpdateMap[attrName] : null);
|
||||
if (attrData == null)
|
||||
{
|
||||
attrData = new AttrData(attrName);
|
||||
attrUpdateMap[attrName] = attrData;
|
||||
}
|
||||
attrData.ValueBefore = new DataValue(value);
|
||||
}
|
||||
public void SetAttrValueAfter (String attrName, DataValue value)
|
||||
{
|
||||
AttrData attrData = (attrUpdateMap.ContainsKey(attrName) ? attrUpdateMap[attrName] : null);
|
||||
if (attrData == null)
|
||||
{
|
||||
attrData = new AttrData(attrName);
|
||||
attrUpdateMap[attrName] = attrData;
|
||||
}
|
||||
attrData.ValueAfter = new DataValue(value);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Format data value for database storage.
|
||||
private static String FormatDataValue (DataValue dataValue)
|
||||
{
|
||||
String value = (dataValue != null ? dataValue.ToString() : "");
|
||||
StringUtil.ReplaceAll(value, "\t", " ");
|
||||
StringUtil.ReplaceAll(value, "\n\r", "\n");
|
||||
StringUtil.ReplaceAll(value, "\r\n", "\n");
|
||||
StringUtil.ReplaceAll(value, "\r", " ");
|
||||
StringUtil.ReplaceAll(value, "\n", " ");
|
||||
return value;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Sarand.Net.Standard.Base.App;
|
||||
using Sarand.Net.Standard.Base.Core;
|
||||
using Sarand.Net.Standard.Base.Bus;
|
||||
using Sarand.Net.Standard.Base.Dbas;
|
||||
using Sarand.Net.Standard.Base.Utils;
|
||||
|
||||
namespace Sarand.Net.Standard.Base.UpdateLog
|
||||
{
|
||||
//=======================================================================
|
||||
public abstract class SaUpdateLogMgr : SacsItemMgr
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Data members.
|
||||
private readonly Dictionary<SysId,String> userNames = new Dictionary<SysId, string>();
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Static initialisation.
|
||||
static SaUpdateLogMgr ()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Construction.
|
||||
protected SaUpdateLogMgr (SaUpdateLogConsole updateLogConsole)
|
||||
{
|
||||
UpdateLogConsole = updateLogConsole;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
protected SaUpdateLogConsole UpdateLogConsole { get; }
|
||||
public abstract bool DatabaseIsValid { get; }
|
||||
public abstract bool CanUpdateDatabase { get; }
|
||||
|
||||
//*******************************************************************
|
||||
// U p d a t e L o g E n t r i e s
|
||||
//*******************************************************************
|
||||
// Retrieve individual update log entries.
|
||||
public abstract bool LogEntryExists (SaUpdateLogEntry logEntry);
|
||||
public abstract bool LogEntryExists (ItemId itemId, String attribute, DateTime logged);
|
||||
public abstract SaUpdateLogEntry GetLogEntry (ItemId itemId, String attribute, DateTime logged);
|
||||
|
||||
// Create Update Log Entry.
|
||||
public abstract SaUpdateLogEntry CreateLogEntry (ItemId itemId, String attribute);
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Validate Update Log Entry.
|
||||
public bool IsValidLogEntry (SaUpdateLogEntry logEntry)
|
||||
{
|
||||
ClearErrorState();
|
||||
if (logEntry == null) return SetErrorState(ErrorMessage.ItemNotSpecified);
|
||||
return IsValidLogEntryData(logEntry.GetData(), new SaUpdateLogEntry.ErrField());
|
||||
}
|
||||
public virtual bool IsValidLogEntryData (SaUpdateLogEntry.Data logEntryData, SaUpdateLogEntry.ErrField errField)
|
||||
{
|
||||
ClearErrorState();
|
||||
if ((int)logEntryData.ItemId.Type < 1)
|
||||
{
|
||||
errField.ItemType = SacsHierarchyItem.ValidValue.Invalid;
|
||||
return SetErrorState("Item type must be supplied");
|
||||
}
|
||||
if (!SysId.IsValid(logEntryData.ItemId.Id))
|
||||
{
|
||||
errField.ItemId = SacsHierarchyItem.ValidValue.Invalid;
|
||||
return SetErrorState("Item Id must be supplied");
|
||||
}
|
||||
if (!IsValidValue(logEntryData.Attribute, "attribute", (long)SaUpdateLogDbDfn.GetColTextLen(SaUpdateLogDbDfn.ColumnIdx.SaAttrUpdate_Attribute), true))
|
||||
{
|
||||
errField.Attribute = SacsHierarchyItem.ValidValue.Invalid;
|
||||
return false;
|
||||
}
|
||||
if (!IsValidValue(logEntryData.DataBefore, "data before", (long)SaUpdateLogDbDfn.GetColTextLen(SaUpdateLogDbDfn.ColumnIdx.SaAttrUpdate_DataBefore)))
|
||||
{
|
||||
errField.DataBefore = SacsHierarchyItem.ValidValue.Invalid;
|
||||
return false;
|
||||
}
|
||||
if (!IsValidValue(logEntryData.DataAfter, "data after", (long)SaUpdateLogDbDfn.GetColTextLen(SaUpdateLogDbDfn.ColumnIdx.SaAttrUpdate_DataAfter)))
|
||||
{
|
||||
errField.DataAfter = SacsHierarchyItem.ValidValue.Invalid;
|
||||
return false;
|
||||
}
|
||||
// Common properties.
|
||||
if (!IsValidValue(logEntryData.Notes, "notes", (long)SaUpdateLogDbDfn.GetColTextLen(SaUpdateLogDbDfn.ColumnIdx.SaAttrUpdate_Notes)))
|
||||
{
|
||||
errField.Notes = SacsHierarchyItem.ValidValue.Invalid;
|
||||
return false;
|
||||
}
|
||||
if (!SaUpdateLogEntry.ValidStatuses.Contains(logEntryData.Status))
|
||||
{
|
||||
errField.Status = SacsHierarchyItem.ValidValue.Invalid;
|
||||
return SetErrorState(ErrorMessage.InvalidStatus);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Update Log Entry database interface.
|
||||
public abstract bool LogUpdates (SaUpdateLogItemMonitor updateLogItemMonitor, DbUpdateInfo dbUpdateInfo);
|
||||
public abstract bool InsertLogEntry (SaUpdateLogEntry logEntry, DbUpdateInfo dbUpdateInfo);
|
||||
public abstract bool UpdateLogEntry (SaUpdateLogEntry logEntry, DbUpdateInfo dbUpdateInfo);
|
||||
public virtual bool LogEntryCanBeDeleted (SaUpdateLogEntry logEntry)
|
||||
{
|
||||
ClearErrorState();
|
||||
return true;
|
||||
}
|
||||
public abstract bool DeleteLogEntry (SaUpdateLogEntry logEntry, DbUpdateInfo dbUpdateInfo);
|
||||
public abstract bool ClearLogEntriesForItem (ItemId itemId, DbUpdateInfo dbUpdateInfo);
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Update Log Entry list.
|
||||
public abstract ColumnDfn GetLogEntryColumnDfn (SaUpdateLogEntry.Column columnId, String caption = "", int width = 0);
|
||||
public abstract List<String> GetLogEntryQueryFilter (SaUpdateLogEntry.Params prm);
|
||||
public abstract long GetLogEntryCount (SaUpdateLogEntry.Params prm);
|
||||
public abstract List<SaUpdateLogEntry> GetLogEntryList (SaUpdateLogEntry.Params prm);
|
||||
public abstract DbResultSet ExecuteLogEntryQuery (List<ColumnDfn> columns, SaUpdateLogEntry.Params prm);
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
/// <summary>
|
||||
/// Extract and format result set data value where specific handling is required.
|
||||
/// <para>Where response is an invalid data value, format value using column.FormatValue(values).</para>
|
||||
/// </summary>
|
||||
public virtual DataValue GetLogEntryDataValue (ColumnDfn column, NamedValue.Map values)
|
||||
{
|
||||
DataValue value = new DataValue();
|
||||
switch ((SaUpdateLogEntry.Column)column.Id)
|
||||
{
|
||||
//-----------------------------------------------------------
|
||||
// Item type.
|
||||
case SaUpdateLogEntry.Column.ItemType_Desc:
|
||||
{
|
||||
short itemType = (short)values.GetValue(column.DataName).AsLong();
|
||||
value = new DataValue(itemType.ToString());
|
||||
}
|
||||
break;
|
||||
|
||||
//-----------------------------------------------------------
|
||||
// Data values.
|
||||
case SaUpdateLogEntry.Column.DataBefore:
|
||||
case SaUpdateLogEntry.Column.DataAfter:
|
||||
{
|
||||
value = new DataValue(values.GetValue(column.DataName).ToString());
|
||||
String attribute = values.GetValue(GetLogEntryColumnDfn(SaUpdateLogEntry.Column.Attribute).DataName).ToString();
|
||||
if (attribute.EqualsCI("Status"))
|
||||
value = new DataValue(SacsSystem.GetStatusDescForCode(value.ToString()));
|
||||
}
|
||||
break;
|
||||
|
||||
//-----------------------------------------------------------
|
||||
// Notes.
|
||||
case SaUpdateLogEntry.Column.Notes:
|
||||
{
|
||||
value = new DataValue(SacsHierarchyItem.FormatForDisplay(values.GetValue(column.DataName).ToString(), 200));
|
||||
}
|
||||
break;
|
||||
|
||||
//-----------------------------------------------------------
|
||||
// Status.
|
||||
case SaUpdateLogEntry.Column.Status_Desc:
|
||||
case SaUpdateLogEntry.Column.Status_Ind:
|
||||
{
|
||||
String statusCode = values.GetValue(column.DataName).ToString();
|
||||
SaStatus status = SacsSystem.GetStatusForCode(statusCode);
|
||||
if (column.Id == (int)SaUpdateLogEntry.Column.Status_Desc)
|
||||
{
|
||||
String statusDesc = SacsSystem.GetStatusDescForCode(statusCode);
|
||||
value = new DataValue(statusDesc);
|
||||
}
|
||||
else if (column.Id == (int)SaUpdateLogEntry.Column.Status_Ind)
|
||||
{
|
||||
DataValue.TriStateType triState = DataValue.TriStateType.Unknown;
|
||||
if (status == SaStatus.Logged)
|
||||
triState = DataValue.TriStateType.Green;
|
||||
value = new DataValue(triState);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
//-----------------------------------------------------------
|
||||
// Notes.
|
||||
case SaUpdateLogEntry.Column.CreateBy_Name:
|
||||
{
|
||||
SysId userId = new SysId(StringUtil.ToInt(values.GetValue(GetLogEntryColumnDfn(SaUpdateLogEntry.Column.CreateBy).DataName).ToString()));
|
||||
String userName = SysId.ToString(userId);
|
||||
if (SysId.IsValid(userId) && !userNames.ContainsKey(userId))
|
||||
{
|
||||
foreach (var userNameKV in UpdateLogConsole.GetNameForUserIds(new List<SysId> { userId }))
|
||||
userNames.Add(userNameKV.Key, userNameKV.Value);
|
||||
}
|
||||
if (userNames.ContainsKey(userId))
|
||||
userName = userNames[userId];
|
||||
value = new DataValue(userName);
|
||||
}
|
||||
break;
|
||||
|
||||
//-----------------------------------------------------------
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
Reference in New Issue
Block a user