diff --git a/TBF/Rig/Output/DataStorage/UniDataStorageWriter/Diagnostic/WriterDiagnosticResult.cs b/TBF/Rig/Output/DataStorage/UniDataStorageWriter/Diagnostic/WriterDiagnosticResult.cs new file mode 100644 index 000000000..88be87585 --- /dev/null +++ b/TBF/Rig/Output/DataStorage/UniDataStorageWriter/Diagnostic/WriterDiagnosticResult.cs @@ -0,0 +1,53 @@ +using System.Text; + +namespace TBF.Rig.Output.DataStorage.UniDataStorageWriter +{ + /// + /// Diagnostic result for writer source testing and write execution. + /// + public class WriterDiagnosticResult + { + public bool Success { get; set; } + + public string Message { get; set; } + + /// + /// Final resolved template/query/body actually executed by writer. + /// + public string ExecutedTemplate { get; set; } + + public static WriterDiagnosticResult Ok(string message = null) + { + return new WriterDiagnosticResult + { + Success = true, + Message = message + }; + } + + public static WriterDiagnosticResult Fail(string message) + { + return new WriterDiagnosticResult + { + Success = false, + Message = message + }; + } + + public string ToDisplayDiag() + { + StringBuilder sb = new StringBuilder(); + + sb.AppendLine("Success: " + Success); + sb.AppendLine("Message: " + (string.IsNullOrWhiteSpace(Message) ? "" : Message)); + + if (!string.IsNullOrWhiteSpace(ExecutedTemplate)) + { + sb.AppendLine("Executed template:"); + sb.AppendLine(ExecutedTemplate); + } + + return sb.ToString(); + } + } +} \ No newline at end of file diff --git a/TBF/Rig/Output/DataStorage/UniDataStorageWriter/Enums.cs b/TBF/Rig/Output/DataStorage/UniDataStorageWriter/Enums.cs new file mode 100644 index 000000000..d06ca28d9 --- /dev/null +++ b/TBF/Rig/Output/DataStorage/UniDataStorageWriter/Enums.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace TBF.Rig.Output.DataStorage.UniDataStorageWriter +{ + /// + /// Helper class to assign descriptions to enum values + /// + public class Description : Attribute + { + public string Text; + public Description(string t) + { + Text = t; + } + } + + public static class GetDescription + { + /// Extension method for enum-s + public static string ToDescription(this Enum en) + { + Type type = en.GetType(); + MemberInfo[] memInfo = type.GetMember(en.ToString()); + + if (memInfo != null && memInfo.Length > 0) + { + object[] attrs = memInfo[0].GetCustomAttributes(typeof(Description), false); + if (attrs != null && attrs.Length > 0) + return ((Description)attrs[0]).Text; + } + + return en.ToString(); /// Return ToString() value in case there is no description + } + } + + /// + /// Identifies the type of data storage + /// + public enum DataStorageType + { + RestApi, + Database, + Json, + Csv + } +} diff --git a/TBF/Rig/Output/DataStorage/UniDataStorageWriter/Factory.cs b/TBF/Rig/Output/DataStorage/UniDataStorageWriter/Factory.cs new file mode 100644 index 000000000..271dfdf59 --- /dev/null +++ b/TBF/Rig/Output/DataStorage/UniDataStorageWriter/Factory.cs @@ -0,0 +1,38 @@ +/// +/// Copyright (c) 2018 Sensus Slovensko a.s. +/// + +using System; +using System.Collections.Generic; +using TBF.Rig.Generic; + +namespace TBF.Rig.Output.DataStorage.UniDataStorageWriter +{ + /// + /// Factory component 'UniDataStorageWriter' implements more storing modules + /// Modules: + /// + public class Factory : IComponentFactory + { + public string ClassName { get { return GetType().Namespace.Substring(8); } } /// For backward compatibility + public override string ToString() { return ClassName; } + + public IComponent DummyComponent() { return new Writer(new WriterCfg("UniDataStorageWriter", this)); } + + public IComponent GetComponent(IComponentCfg cfg, IList components) + { + WriterCfg WriterCfg = cfg as WriterCfg; + if (WriterCfg == null) + throw new ArgumentException("Invalid config for UniDataStorageWriter"); + + return new Writer(WriterCfg); + } + + public IComponentCfg DefaultConfig() { return new WriterCfg("UniDataStorageWriter", this); } + + public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component) + { + return ComponentCfgBase.CreateFromDbEntity(WriterCfg.Serializer, component, this); + } + } +} diff --git a/TBF/Rig/Output/DataStorage/UniDataStorageWriter/Interfaces/DataWriteRequest.cs b/TBF/Rig/Output/DataStorage/UniDataStorageWriter/Interfaces/DataWriteRequest.cs new file mode 100644 index 000000000..86ab4ca98 --- /dev/null +++ b/TBF/Rig/Output/DataStorage/UniDataStorageWriter/Interfaces/DataWriteRequest.cs @@ -0,0 +1,59 @@ +using System.Collections.Generic; + +namespace TBF.Rig.Output.DataStorage.UniDataStorageWriter.Interfaces +{ + /// + /// Request for write operation. + /// Contains batch of write items. + /// + public class DataWriteRequest + { + public DataWriteRequest() + { + InsertItems = new List(); + UpdateItems = new List(); + Mode = WriteMode.Insert; + } + + public string TargetName { get; set; } + + public WriteMode Mode { get; set; } + + public List InsertItems { get; private set; } + + public List UpdateItems { get; private set; } + } + + public enum WriteMode + { + Insert, + Update, + Upsert, + Append + } + + public class InsertWriteItem + { + public string ColumnName { get; set; } + public string Value { get; set; } + + public override string ToString() + { + return $"{ColumnName} = {Value}"; + } + } + + public class UpdateWriteItem + { + public string WhereParameterName { get; set; } + public string WhereValue { get; set; } + + public string SetParameterName { get; set; } + public string SetValue { get; set; } + + public override string ToString() + { + return $"WHERE {WhereParameterName} = {WhereValue} -> SET {SetParameterName} = {SetValue}"; + } + } +} \ No newline at end of file diff --git a/TBF/Rig/Output/DataStorage/UniDataStorageWriter/Interfaces/IDataStorageWriter.cs b/TBF/Rig/Output/DataStorage/UniDataStorageWriter/Interfaces/IDataStorageWriter.cs new file mode 100644 index 000000000..94cb41759 --- /dev/null +++ b/TBF/Rig/Output/DataStorage/UniDataStorageWriter/Interfaces/IDataStorageWriter.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using TBF.Rig.Output.DataStorage.UniDataStorageWriter.Interfaces; + +namespace TBF.Rig.Output.DataStorage.UniDataStorageWriter +{ + public interface IDataStorageWriter + { + WriterDiagnosticResult TestSource(bool validateOnly); + WriterDiagnosticResult WriteData(DataWriteRequest request); + } +} diff --git a/TBF/Rig/Output/DataStorage/UniDataStorageWriter/Searching/SearchOrderDefinition.cs b/TBF/Rig/Output/DataStorage/UniDataStorageWriter/Searching/SearchOrderDefinition.cs new file mode 100644 index 000000000..e25ba9491 --- /dev/null +++ b/TBF/Rig/Output/DataStorage/UniDataStorageWriter/Searching/SearchOrderDefinition.cs @@ -0,0 +1,65 @@ +using System; + +namespace TBF.Rig.Input.DataStorage.UniDataStorageWriter.Searching +{ + /// + /// Parsed representation of QueryTemplate expression. + /// Example: + /// SELECT [Password] WHERE [PcbId] = QUERYPARAM + /// + public class SearchOrderDefinition + { + /// + /// Column to be returned. + /// + public ColumnReference SelectColumn { get; set; } + + /// + /// Column used for lookup. + /// + public ColumnReference WhereColumn { get; set; } + } + + /// + /// Represents a column reference either by name or by zero-based index. + /// + public class ColumnReference + { + /// + /// Column name if referenced by [ColumnName]. + /// + public string Name { get; set; } + + /// + /// Zero-based column index if referenced by COLUMN(n). + /// + public int? Index { get; set; } + + /// + /// Returns true if reference is by column name. + /// + public bool HasName + { + get { return !string.IsNullOrWhiteSpace(Name); } + } + + /// + /// Returns true if reference is by column index. + /// + public bool HasIndex + { + get { return Index.HasValue; } + } + + public override string ToString() + { + if (HasName) + return "[" + Name + "]"; + + if (HasIndex) + return "COLUMN(" + Index.Value + ")"; + + return ""; + } + } +} \ No newline at end of file diff --git a/TBF/Rig/Output/DataStorage/UniDataStorageWriter/Searching/SearchOrderParser.cs b/TBF/Rig/Output/DataStorage/UniDataStorageWriter/Searching/SearchOrderParser.cs new file mode 100644 index 000000000..8ba62f7d0 --- /dev/null +++ b/TBF/Rig/Output/DataStorage/UniDataStorageWriter/Searching/SearchOrderParser.cs @@ -0,0 +1,87 @@ +using System; +using System.Text.RegularExpressions; +using TBF.Rig.Input.DataStorage.UniDataStorageWriter.Searching; + +namespace TBF.Rig.Input.DataStorage.UniDataStorageWriter +{ + /// + /// Parses SQL-like QueryTemplate expressions. + /// Supported syntax: + /// SELECT [ReturnColumn] WHERE [MatchColumn] = QUERYPARAM + /// SELECT COLUMN(1) WHERE COLUMN(0) = QUERYPARAM + /// Mixed forms are also supported. + /// + public static class SearchOrderParser + { + private static readonly Regex FullPattern = new Regex( + @"^\s*SELECT\s+(?