From 53416750cdccfd6fb39c28ed0d5067a5a252f388 Mon Sep 17 00:00:00 2001 From: 2mik Date: Tue, 4 Jun 2019 15:31:52 +0300 Subject: [PATCH 1/4] KpDbImport: support commands --- .../DbImport/Configuration/Config.cs | 27 +++- .../DbImport/Configuration/ExportCmd.cs | 90 +++++++++++++ .../KpDbImport/DbImport/Data/DataSource.cs | 40 +++++- .../DbImport/Data/MySqlDataSource.cs | 18 ++- .../DbImport/Data/OleDbDataSource.cs | 19 ++- .../KpDbImport/DbImport/Data/OraDataSource.cs | 16 +++ .../DbImport/Data/PgSqlDataSource.cs | 18 ++- .../KpDbImport/DbImport/Data/SqlDataSource.cs | 18 ++- .../OpenKPs/KpDbImport/KpDbImport.csproj | 1 + .../OpenKPs/KpDbImport/KpDbImportLogic.cs | 125 +++++++++++++++--- .../OpenKPs/KpDbImport/KpDbImportView.cs | 2 +- .../communicator-drivers-history.html | 5 +- .../communicator-drivers-history.html | 5 +- 13 files changed, 352 insertions(+), 32 deletions(-) create mode 100644 ScadaComm/OpenKPs/KpDbImport/DbImport/Configuration/ExportCmd.cs diff --git a/ScadaComm/OpenKPs/KpDbImport/DbImport/Configuration/Config.cs b/ScadaComm/OpenKPs/KpDbImport/DbImport/Configuration/Config.cs index d2b7d9e87..7fa742402 100644 --- a/ScadaComm/OpenKPs/KpDbImport/DbImport/Configuration/Config.cs +++ b/ScadaComm/OpenKPs/KpDbImport/DbImport/Configuration/Config.cs @@ -1,5 +1,5 @@ /* - * Copyright 2018 Mikhail Shiryaev + * Copyright 2019 Mikhail Shiryaev * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,10 +20,11 @@ * * Author : Mikhail Shiryaev * Created : 2018 - * Modified : 2018 + * Modified : 2019 */ using System; +using System.Collections.Generic; using System.IO; using System.Xml; @@ -69,6 +70,11 @@ public Config() /// public int TagCount { get; set; } + /// + /// Gets the export commands. + /// + public SortedList ExportCmds { get; private set; } + /// /// Sets the default values. @@ -80,6 +86,7 @@ private void SetToDefault() SelectQuery = ""; AutoTagCount = true; TagCount = 0; + ExportCmds = new SortedList(); } @@ -105,6 +112,16 @@ public bool Load(string fileName, out string errMsg) AutoTagCount = rootElem.GetChildAsBool("AutoTagCount"); TagCount = rootElem.GetChildAsInt("TagCount"); + if (rootElem.SelectSingleNode("ExportCmds") is XmlNode exportCmdsNode) + { + foreach (XmlNode exportCmdNode in exportCmdsNode.SelectNodes("ExportCmd")) + { + ExportCmd exportCmd = new ExportCmd(); + exportCmd.LoadFromXml(exportCmdNode); + ExportCmds[exportCmd.CmdNum] = exportCmd; + } + } + errMsg = ""; return true; } @@ -135,6 +152,12 @@ public bool Save(string fileName, out string errMsg) rootElem.AppendElem("AutoTagCount", AutoTagCount); rootElem.AppendElem("TagCount", TagCount); + XmlElement exportCmdsElem = rootElem.AppendElem("ExportCmds"); + foreach (ExportCmd exportCmd in ExportCmds.Values) + { + exportCmd.SaveToXml(exportCmdsElem.AppendElem("ExportCmd")); + } + xmlDoc.Save(fileName); errMsg = ""; return true; diff --git a/ScadaComm/OpenKPs/KpDbImport/DbImport/Configuration/ExportCmd.cs b/ScadaComm/OpenKPs/KpDbImport/DbImport/Configuration/ExportCmd.cs new file mode 100644 index 000000000..6fd8acfaa --- /dev/null +++ b/ScadaComm/OpenKPs/KpDbImport/DbImport/Configuration/ExportCmd.cs @@ -0,0 +1,90 @@ +/* + * Copyright 2019 Mikhail Shiryaev + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * + * Product : Rapid SCADA + * Module : KpDBImport + * Summary : Configuration of a data export command + * + * Author : Mikhail Shiryaev + * Created : 2019 + * Modified : 2019 + */ + +using System; +using System.Xml; + +namespace Scada.Comm.Devices.DbImport.Configuration +{ + /// + /// Configuration of a data export command. + /// Конфигурация команды экспорта данных. + /// + internal class ExportCmd + { + /// + /// Initializes a new instance of the class. + /// + public ExportCmd() + { + CmdNum = 1; + Name = ""; + Query = ""; + } + + + /// + /// Gets or sets the command number. + /// + public int CmdNum { get; set; } + + /// + /// Gets or sets the command name. + /// + public string Name { get; set; } + + /// + /// Gets or sets the SQL-query of the command. + /// + public string Query { get; set; } + + + /// + /// Loads the command from the XML node. + /// + public void LoadFromXml(XmlNode xmlNode) + { + if (xmlNode == null) + throw new ArgumentNullException("xmlNode"); + + CmdNum = xmlNode.GetChildAsInt("CmdNum"); + Name = xmlNode.GetChildAsString("Name"); + Query = xmlNode.GetChildAsString("Query"); + } + + /// + /// Saves the command into the XML node. + /// + public void SaveToXml(XmlElement xmlElem) + { + if (xmlElem == null) + throw new ArgumentNullException("xmlElem"); + + xmlElem.AppendElem("CmdNum", CmdNum); + xmlElem.AppendElem("Name", Name); + xmlElem.AppendElem("Query", Query); + } + } +} diff --git a/ScadaComm/OpenKPs/KpDbImport/DbImport/Data/DataSource.cs b/ScadaComm/OpenKPs/KpDbImport/DbImport/Data/DataSource.cs index 12dd38967..330a64d3a 100644 --- a/ScadaComm/OpenKPs/KpDbImport/DbImport/Data/DataSource.cs +++ b/ScadaComm/OpenKPs/KpDbImport/DbImport/Data/DataSource.cs @@ -25,6 +25,7 @@ using Scada.Comm.Devices.DbImport.Configuration; using System; +using System.Collections.Generic; using System.Data.Common; namespace Scada.Comm.Devices.DbImport.Data @@ -55,6 +56,11 @@ protected DataSource() /// public DbCommand SelectCommand { get; protected set; } + /// + /// Gets the export commands. + /// + public SortedList ExportCommands { get; protected set; } + /// /// Creates a database connection. @@ -66,6 +72,11 @@ protected DataSource() /// protected abstract DbCommand CreateCommand(); + /// + /// Adds the command parameter containing the value. + /// + protected abstract void AddCmdParamWithValue(DbCommand cmd, string paramName, object value); + /// /// Clears the connection pool. /// @@ -128,14 +139,39 @@ public void Disconnect() /// /// Initializes the data source. /// - public void Init(string connectionString, string selectQuery) + public void Init(string connectionString, Config config) { + if (config == null) + throw new ArgumentNullException("config"); + Connection = CreateConnection(); Connection.ConnectionString = connectionString; SelectCommand = CreateCommand(); - SelectCommand.CommandText = selectQuery; + SelectCommand.CommandText = config.SelectQuery; SelectCommand.Connection = Connection; + + foreach (ExportCmd exportCmd in config.ExportCmds.Values) + { + DbCommand exportCommand = CreateCommand(); + exportCommand.CommandText = exportCmd.Query; + exportCommand.Connection = Connection; + ExportCommands.Add(exportCmd.CmdNum, exportCommand); + } + } + + /// + /// Sets the command parameter. + /// + public void SetCmdParam(DbCommand cmd, string paramName, object value) + { + if (cmd == null) + throw new ArgumentNullException("cmd"); + + if (cmd.Parameters.Contains(paramName)) + cmd.Parameters[paramName].Value = value; + else + AddCmdParamWithValue(cmd, paramName, value); } } } diff --git a/ScadaComm/OpenKPs/KpDbImport/DbImport/Data/MySqlDataSource.cs b/ScadaComm/OpenKPs/KpDbImport/DbImport/Data/MySqlDataSource.cs index 83f26abc1..75e72d6ac 100644 --- a/ScadaComm/OpenKPs/KpDbImport/DbImport/Data/MySqlDataSource.cs +++ b/ScadaComm/OpenKPs/KpDbImport/DbImport/Data/MySqlDataSource.cs @@ -1,5 +1,5 @@ /* - * Copyright 2018 Mikhail Shiryaev + * Copyright 2019 Mikhail Shiryaev * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ * * Author : Mikhail Shiryaev * Created : 2018 - * Modified : 2018 + * Modified : 2019 */ using MySql.Data.MySqlClient; @@ -58,6 +58,20 @@ protected override DbCommand CreateCommand() return new MySqlCommand(); } + /// + /// Adds the command parameter containing the value. + /// + protected override void AddCmdParamWithValue(DbCommand cmd, string paramName, object value) + { + if (cmd == null) + throw new ArgumentNullException("cmd"); + if (!(cmd is MySqlCommand)) + throw new ArgumentException("MySqlCommand is required.", "cmd"); + + MySqlCommand mySqlCmd = (MySqlCommand)cmd; + mySqlCmd.Parameters.AddWithValue(paramName, value); + } + /// /// Clears the connection pool. /// diff --git a/ScadaComm/OpenKPs/KpDbImport/DbImport/Data/OleDbDataSource.cs b/ScadaComm/OpenKPs/KpDbImport/DbImport/Data/OleDbDataSource.cs index aeb43e73b..6aa38d061 100644 --- a/ScadaComm/OpenKPs/KpDbImport/DbImport/Data/OleDbDataSource.cs +++ b/ScadaComm/OpenKPs/KpDbImport/DbImport/Data/OleDbDataSource.cs @@ -1,5 +1,5 @@ /* - * Copyright 2018 Mikhail Shiryaev + * Copyright 2019 Mikhail Shiryaev * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,10 +20,11 @@ * * Author : Mikhail Shiryaev * Created : 2018 - * Modified : 2018 + * Modified : 2019 */ using Scada.Comm.Devices.DbImport.Configuration; +using System; using System.Data.Common; using System.Data.OleDb; @@ -51,6 +52,20 @@ protected override DbCommand CreateCommand() return new OleDbCommand(); } + /// + /// Adds the command parameter containing the value. + /// + protected override void AddCmdParamWithValue(DbCommand cmd, string paramName, object value) + { + if (cmd == null) + throw new ArgumentNullException("cmd"); + if (!(cmd is OleDbCommand)) + throw new ArgumentException("OleDbCommand is required.", "cmd"); + + OleDbCommand oleDbCmd = (OleDbCommand)cmd; + oleDbCmd.Parameters.AddWithValue(paramName, value); + } + /// /// Clears the connection pool. /// diff --git a/ScadaComm/OpenKPs/KpDbImport/DbImport/Data/OraDataSource.cs b/ScadaComm/OpenKPs/KpDbImport/DbImport/Data/OraDataSource.cs index 56797657f..660085383 100644 --- a/ScadaComm/OpenKPs/KpDbImport/DbImport/Data/OraDataSource.cs +++ b/ScadaComm/OpenKPs/KpDbImport/DbImport/Data/OraDataSource.cs @@ -28,6 +28,8 @@ using System.Data.Common; using System.Data.OracleClient; +#pragma warning disable 618 // disable the warning about obsolete Oracle classes + namespace Scada.Comm.Devices.DbImport.Data { /// @@ -52,6 +54,20 @@ protected override DbCommand CreateCommand() return new OracleCommand(); } + /// + /// Adds the command parameter containing the value. + /// + protected override void AddCmdParamWithValue(DbCommand cmd, string paramName, object value) + { + if (cmd == null) + throw new ArgumentNullException("cmd"); + if (!(cmd is OracleCommand)) + throw new ArgumentException("OracleCommand is required.", "cmd"); + + OracleCommand oraCmd = (OracleCommand)cmd; + oraCmd.Parameters.AddWithValue(paramName, value); + } + /// /// Clears the connection pool. /// diff --git a/ScadaComm/OpenKPs/KpDbImport/DbImport/Data/PgSqlDataSource.cs b/ScadaComm/OpenKPs/KpDbImport/DbImport/Data/PgSqlDataSource.cs index 48a689a8c..2d263c57f 100644 --- a/ScadaComm/OpenKPs/KpDbImport/DbImport/Data/PgSqlDataSource.cs +++ b/ScadaComm/OpenKPs/KpDbImport/DbImport/Data/PgSqlDataSource.cs @@ -1,5 +1,5 @@ /* - * Copyright 2018 Mikhail Shiryaev + * Copyright 2019 Mikhail Shiryaev * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ * * Author : Mikhail Shiryaev * Created : 2018 - * Modified : 2018 + * Modified : 2019 */ using Npgsql; @@ -58,6 +58,20 @@ protected override DbCommand CreateCommand() return new NpgsqlCommand(); } + /// + /// Adds the command parameter containing the value. + /// + protected override void AddCmdParamWithValue(DbCommand cmd, string paramName, object value) + { + if (cmd == null) + throw new ArgumentNullException("cmd"); + if (!(cmd is NpgsqlCommand)) + throw new ArgumentException("NpgsqlCommand is required.", "cmd"); + + NpgsqlCommand pgSqlCmd = (NpgsqlCommand)cmd; + pgSqlCmd.Parameters.AddWithValue(paramName, value); + } + /// /// Clears the connection pool. /// diff --git a/ScadaComm/OpenKPs/KpDbImport/DbImport/Data/SqlDataSource.cs b/ScadaComm/OpenKPs/KpDbImport/DbImport/Data/SqlDataSource.cs index 1b1f7130f..3c4b2b084 100644 --- a/ScadaComm/OpenKPs/KpDbImport/DbImport/Data/SqlDataSource.cs +++ b/ScadaComm/OpenKPs/KpDbImport/DbImport/Data/SqlDataSource.cs @@ -1,5 +1,5 @@ /* - * Copyright 2018 Mikhail Shiryaev + * Copyright 2019 Mikhail Shiryaev * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ * * Author : Mikhail Shiryaev * Created : 2018 - * Modified : 2018 + * Modified : 2019 */ using Scada.Comm.Devices.DbImport.Configuration; @@ -52,6 +52,20 @@ protected override DbCommand CreateCommand() return new SqlCommand(); } + /// + /// Adds the command parameter containing the value. + /// + protected override void AddCmdParamWithValue(DbCommand cmd, string paramName, object value) + { + if (cmd == null) + throw new ArgumentNullException("cmd"); + if (!(cmd is SqlCommand)) + throw new ArgumentException("SqlCommand is required.", "cmd"); + + SqlCommand sqlCmd = (SqlCommand)cmd; + sqlCmd.Parameters.AddWithValue(paramName, value); + } + /// /// Clears the connection pool. /// diff --git a/ScadaComm/OpenKPs/KpDbImport/KpDbImport.csproj b/ScadaComm/OpenKPs/KpDbImport/KpDbImport.csproj index e76f35e6a..482438c66 100644 --- a/ScadaComm/OpenKPs/KpDbImport/KpDbImport.csproj +++ b/ScadaComm/OpenKPs/KpDbImport/KpDbImport.csproj @@ -57,6 +57,7 @@ + diff --git a/ScadaComm/OpenKPs/KpDbImport/KpDbImportLogic.cs b/ScadaComm/OpenKPs/KpDbImport/KpDbImportLogic.cs index 4c71b145f..f57485ccb 100644 --- a/ScadaComm/OpenKPs/KpDbImport/KpDbImportLogic.cs +++ b/ScadaComm/OpenKPs/KpDbImport/KpDbImportLogic.cs @@ -26,6 +26,7 @@ using Scada.Comm.Devices.DbImport.Configuration; using Scada.Comm.Devices.DbImport.Data; using Scada.Data.Configuration; +using Scada.Data.Models; using Scada.Data.Tables; using System; using System.Collections.Generic; @@ -109,7 +110,7 @@ private void InitDataSource(Config config) } else { - dataSource.Init(connStr, config.SelectQuery); + dataSource.Init(connStr, config); } } } @@ -168,6 +169,42 @@ private SrezTableLight.CnlData DecodeTag(object val, out TagType tagType) } } + /// + /// Validates the data source. + /// + private bool ValidateDataSource() + { + if (dataSource == null) + { + WriteToLog(Localization.UseRussian ? + "Нормальное взаимодействие с КП невозможно, т.к. источник данных не определён" : + "Normal device communication is impossible because data source is undefined"); + return false; + } + else + { + return true; + } + } + + /// + /// Validates the database command. + /// + private bool ValidateCommand(DbCommand dbCommand) + { + if (dbCommand == null) + { + WriteToLog(Localization.UseRussian ? + "Нормальное взаимодействие с КП невозможно, т.к. SQL-команда не определена" : + "Normal device communication is impossible because SQL command is undefined"); + return false; + } + else + { + return true; + } + } + /// /// Connects to the database. /// @@ -248,7 +285,29 @@ private bool Request() { WriteToLog(string.Format(Localization.UseRussian ? "Ошибка при выполнении запроса: {0}" : - "Error executing the query: {0}", ex.Message)); + "Error executing query: {0}", ex.Message)); + return false; + } + } + + /// + /// Sends the command to the database. + /// + private bool SendDbCommand(DbCommand dbCommand) + { + try + { + WriteToLog(Localization.UseRussian ? + "Запрос на изменение данных" : + "Data modification request"); + dbCommand.ExecuteNonQuery(); + return true; + } + catch (Exception ex) + { + WriteToLog(string.Format(Localization.UseRussian ? + "Ошибка при отправке команды БД: {0}" : + "Error sending command to the database: {0}", ex.Message)); return false; } } @@ -281,21 +340,7 @@ public override void Session() base.Session(); lastCommSucc = false; - if (dataSource == null) - { - WriteToLog(Localization.UseRussian ? - "Нормальное взаимодействие с КП невозможно, т.к. источник данных не определён" : - "Normal device communication is impossible because data source is undefined"); - Thread.Sleep(ReqParams.Delay); - } - else if (dataSource.SelectCommand == null) - { - WriteToLog(Localization.UseRussian ? - "Нормальное взаимодействие с КП невозможно, т.к. SQL-команда не определена" : - "Normal device communication is impossible because SQL command is undefined"); - Thread.Sleep(ReqParams.Delay); - } - else + if (ValidateDataSource() && ValidateCommand(dataSource.SelectCommand)) { // request data int tryNum = 0; @@ -313,11 +358,56 @@ public override void Session() if (!lastCommSucc && !Terminated) InvalidateCurData(); } + else + { + Thread.Sleep(ReqParams.Delay); + } // calculate session stats CalcSessStats(); } + /// + /// Sends the telecontrol command. + /// + public override void SendCmd(Command cmd) + { + base.SendCmd(cmd); + + if (CanSendCmd) + { + lastCommSucc = false; + + if ((cmd.CmdTypeID == BaseValues.CmdTypes.Standard || cmd.CmdTypeID == BaseValues.CmdTypes.Binary) && + dataSource.ExportCommands.TryGetValue(cmd.CmdNum, out DbCommand dbCommand)) + { + + if (ValidateDataSource() && ValidateCommand(dbCommand)) + { + dataSource.SetCmdParam(dbCommand, "val", + cmd.CmdTypeID == BaseValues.CmdTypes.Standard ? (object)cmd.CmdVal : cmd.GetCmdDataStr()); + int tryNum = 0; + + while (RequestNeeded(ref tryNum)) + { + if (Connect() && SendDbCommand(dbCommand)) + lastCommSucc = true; + + Disconnect(); + FinishRequest(); + tryNum++; + } + } + } + else + { + WriteToLog(CommPhrases.IllegalCommand); + } + } + + CalcCmdStats(); + } + /// /// Performs actions after adding the device to a communication line. /// @@ -330,6 +420,7 @@ public override void OnAddedToCommLine() { InitDataSource(config); InitDeviceTags(config); + CanSendCmd = config.ExportCmds.Count > 0; } else { diff --git a/ScadaComm/OpenKPs/KpDbImport/KpDbImportView.cs b/ScadaComm/OpenKPs/KpDbImport/KpDbImportView.cs index 6158ce6d4..29af36c22 100644 --- a/ScadaComm/OpenKPs/KpDbImport/KpDbImportView.cs +++ b/ScadaComm/OpenKPs/KpDbImport/KpDbImportView.cs @@ -39,7 +39,7 @@ public class KpDbImportView : KPView /// /// The driver version. /// - internal const string KpVersion = "5.0.0.0"; + internal const string KpVersion = "5.0.1.0"; /// diff --git a/ScadaDoc/ScadaDoc/content/latest/en/version-history/communicator-drivers-history.html b/ScadaDoc/ScadaDoc/content/latest/en/version-history/communicator-drivers-history.html index 08d3332a5..f5e51e761 100644 --- a/ScadaDoc/ScadaDoc/content/latest/en/version-history/communicator-drivers-history.html +++ b/ScadaDoc/ScadaDoc/content/latest/en/version-history/communicator-drivers-history.html @@ -12,7 +12,10 @@

History of Communicator Drivers

DB Import

-
KpDbImport 5.0.0.0 (December 26, 2018)
+    
KpDbImport 5.0.1.0 (In development)
+- Support commands for changing data in the database
+
+KpDbImport 5.0.0.0 (December 26, 2018)
 - Initial development of the driver
 
diff --git a/ScadaDoc/ScadaDoc/content/latest/ru/version-history/communicator-drivers-history.html b/ScadaDoc/ScadaDoc/content/latest/ru/version-history/communicator-drivers-history.html index 7728d7a96..cea41f897 100644 --- a/ScadaDoc/ScadaDoc/content/latest/ru/version-history/communicator-drivers-history.html +++ b/ScadaDoc/ScadaDoc/content/latest/ru/version-history/communicator-drivers-history.html @@ -12,7 +12,10 @@

История драйверов Коммуникатора

Импорт из БД

-
KpDbImport 5.0.0.0 (26.12.2018)
+    
KpDbImport 5.0.1.0 (В разработке)
+- Поддержка команд на изменение данных в БД
+
+KpDbImport 5.0.0.0 (26.12.2018)
 - Первоначальная разработка драйвера
 
From 8a423083ca16f60a940697b63b4535eac3e69538 Mon Sep 17 00:00:00 2001 From: 2mik Date: Wed, 5 Jun 2019 18:47:45 +0300 Subject: [PATCH 2/4] KpDbImport: update UI --- .../DbImport/Configuration/Config.cs | 10 +- .../DbImport/Configuration/ExportCmd.cs | 20 +- .../KpDbImport/DbImport/Data/DataSource.cs | 4 +- .../DbImport/UI/FrmConfig.Designer.cs | 222 +++++++++++++++--- .../KpDbImport/DbImport/UI/FrmConfig.cs | 204 +++++++++++++++- .../OpenKPs/KpDbImport/KpDbImportLogic.cs | 7 +- .../KpDbImport/Lang/KpDbImport.en-GB.xml | 14 +- .../KpDbImport/Lang/KpDbImport.ru-RU.xml | 14 +- 8 files changed, 440 insertions(+), 55 deletions(-) diff --git a/ScadaComm/OpenKPs/KpDbImport/DbImport/Configuration/Config.cs b/ScadaComm/OpenKPs/KpDbImport/DbImport/Configuration/Config.cs index 7fa742402..521afb4d5 100644 --- a/ScadaComm/OpenKPs/KpDbImport/DbImport/Configuration/Config.cs +++ b/ScadaComm/OpenKPs/KpDbImport/DbImport/Configuration/Config.cs @@ -73,7 +73,7 @@ public Config() /// /// Gets the export commands. /// - public SortedList ExportCmds { get; private set; } + public List ExportCmds { get; private set; } /// @@ -86,7 +86,7 @@ private void SetToDefault() SelectQuery = ""; AutoTagCount = true; TagCount = 0; - ExportCmds = new SortedList(); + ExportCmds = new List(); } @@ -118,8 +118,10 @@ public bool Load(string fileName, out string errMsg) { ExportCmd exportCmd = new ExportCmd(); exportCmd.LoadFromXml(exportCmdNode); - ExportCmds[exportCmd.CmdNum] = exportCmd; + ExportCmds.Add(exportCmd); } + + ExportCmds.Sort(); } errMsg = ""; @@ -153,7 +155,7 @@ public bool Save(string fileName, out string errMsg) rootElem.AppendElem("TagCount", TagCount); XmlElement exportCmdsElem = rootElem.AppendElem("ExportCmds"); - foreach (ExportCmd exportCmd in ExportCmds.Values) + foreach (ExportCmd exportCmd in ExportCmds) { exportCmd.SaveToXml(exportCmdsElem.AppendElem("ExportCmd")); } diff --git a/ScadaComm/OpenKPs/KpDbImport/DbImport/Configuration/ExportCmd.cs b/ScadaComm/OpenKPs/KpDbImport/DbImport/Configuration/ExportCmd.cs index 6fd8acfaa..fcceb9444 100644 --- a/ScadaComm/OpenKPs/KpDbImport/DbImport/Configuration/ExportCmd.cs +++ b/ScadaComm/OpenKPs/KpDbImport/DbImport/Configuration/ExportCmd.cs @@ -32,7 +32,7 @@ namespace Scada.Comm.Devices.DbImport.Configuration /// Configuration of a data export command. /// Конфигурация команды экспорта данных. /// - internal class ExportCmd + internal class ExportCmd : IComparable { /// /// Initializes a new instance of the class. @@ -60,7 +60,7 @@ public ExportCmd() /// public string Query { get; set; } - + /// /// Loads the command from the XML node. /// @@ -86,5 +86,21 @@ public void SaveToXml(XmlElement xmlElem) xmlElem.AppendElem("Name", Name); xmlElem.AppendElem("Query", Query); } + + /// + /// Compares the current instance with another object of the same type. + /// + public int CompareTo(ExportCmd other) + { + return CmdNum.CompareTo(other.CmdNum); + } + + /// + /// Returns a string that represents the current object. + /// + public override string ToString() + { + return string.Format("[{0}] {1}", CmdNum, Name); + } } } diff --git a/ScadaComm/OpenKPs/KpDbImport/DbImport/Data/DataSource.cs b/ScadaComm/OpenKPs/KpDbImport/DbImport/Data/DataSource.cs index 330a64d3a..a9b39e60c 100644 --- a/ScadaComm/OpenKPs/KpDbImport/DbImport/Data/DataSource.cs +++ b/ScadaComm/OpenKPs/KpDbImport/DbImport/Data/DataSource.cs @@ -151,12 +151,12 @@ public void Init(string connectionString, Config config) SelectCommand.CommandText = config.SelectQuery; SelectCommand.Connection = Connection; - foreach (ExportCmd exportCmd in config.ExportCmds.Values) + foreach (ExportCmd exportCmd in config.ExportCmds) { DbCommand exportCommand = CreateCommand(); exportCommand.CommandText = exportCmd.Query; exportCommand.Connection = Connection; - ExportCommands.Add(exportCmd.CmdNum, exportCommand); + ExportCommands[exportCmd.CmdNum] = exportCommand; } } diff --git a/ScadaComm/OpenKPs/KpDbImport/DbImport/UI/FrmConfig.Designer.cs b/ScadaComm/OpenKPs/KpDbImport/DbImport/UI/FrmConfig.Designer.cs index 24fc5f81c..afdb55957 100644 --- a/ScadaComm/OpenKPs/KpDbImport/DbImport/UI/FrmConfig.Designer.cs +++ b/ScadaComm/OpenKPs/KpDbImport/DbImport/UI/FrmConfig.Designer.cs @@ -49,15 +49,31 @@ private void InitializeComponent() this.lblTagCount = new System.Windows.Forms.Label(); this.txtSelectQuery = new System.Windows.Forms.TextBox(); this.lblSelectQuery = new System.Windows.Forms.Label(); + this.pageCommands = new System.Windows.Forms.TabPage(); + this.gbCommandParams = new System.Windows.Forms.GroupBox(); + this.txtCmdQuery = new System.Windows.Forms.TextBox(); + this.lblCmdQuery = new System.Windows.Forms.Label(); + this.txtName = new System.Windows.Forms.TextBox(); + this.lblName = new System.Windows.Forms.Label(); + this.numCmdNum = new System.Windows.Forms.NumericUpDown(); + this.lblCmdNum = new System.Windows.Forms.Label(); + this.gbCommand = new System.Windows.Forms.GroupBox(); + this.cbCommand = new System.Windows.Forms.ComboBox(); + this.btnDeleteCommand = new System.Windows.Forms.Button(); + this.btnCreateCommand = new System.Windows.Forms.Button(); this.pnlBottom = new System.Windows.Forms.Panel(); - this.btnCancel = new System.Windows.Forms.Button(); - this.btnOK = new System.Windows.Forms.Button(); + this.btnClose = new System.Windows.Forms.Button(); + this.btnSave = new System.Windows.Forms.Button(); this.gbConnection.SuspendLayout(); this.tabControl.SuspendLayout(); this.pageDatabase.SuspendLayout(); this.gbDataSourceType.SuspendLayout(); this.pageQuery.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.numTagCount)).BeginInit(); + this.pageCommands.SuspendLayout(); + this.gbCommandParams.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.numCmdNum)).BeginInit(); + this.gbCommand.SuspendLayout(); this.pnlBottom.SuspendLayout(); this.SuspendLayout(); // @@ -189,6 +205,7 @@ private void InitializeComponent() // this.tabControl.Controls.Add(this.pageDatabase); this.tabControl.Controls.Add(this.pageQuery); + this.tabControl.Controls.Add(this.pageCommands); this.tabControl.Dock = System.Windows.Forms.DockStyle.Fill; this.tabControl.Location = new System.Drawing.Point(0, 0); this.tabControl.Name = "tabControl"; @@ -231,7 +248,7 @@ private void InitializeComponent() this.pageQuery.Padding = new System.Windows.Forms.Padding(3); this.pageQuery.Size = new System.Drawing.Size(426, 283); this.pageQuery.TabIndex = 1; - this.pageQuery.Text = "Query"; + this.pageQuery.Text = "Data Retrieval"; this.pageQuery.UseVisualStyleBackColor = true; // // chkAutoTagCount @@ -251,6 +268,7 @@ private void InitializeComponent() this.numTagCount.Name = "numTagCount"; this.numTagCount.Size = new System.Drawing.Size(100, 20); this.numTagCount.TabIndex = 3; + this.numTagCount.ValueChanged += new System.EventHandler(this.control_Changed); // // lblTagCount // @@ -272,6 +290,7 @@ private void InitializeComponent() this.txtSelectQuery.Size = new System.Drawing.Size(414, 219); this.txtSelectQuery.TabIndex = 1; this.txtSelectQuery.WordWrap = false; + this.txtSelectQuery.TextChanged += new System.EventHandler(this.control_Changed); // // lblSelectQuery // @@ -282,44 +301,175 @@ private void InitializeComponent() this.lblSelectQuery.TabIndex = 0; this.lblSelectQuery.Text = "SQL"; // + // pageCommands + // + this.pageCommands.Controls.Add(this.gbCommandParams); + this.pageCommands.Controls.Add(this.gbCommand); + this.pageCommands.Location = new System.Drawing.Point(4, 22); + this.pageCommands.Name = "pageCommands"; + this.pageCommands.Padding = new System.Windows.Forms.Padding(3); + this.pageCommands.Size = new System.Drawing.Size(426, 283); + this.pageCommands.TabIndex = 2; + this.pageCommands.Text = "Commands"; + this.pageCommands.UseVisualStyleBackColor = true; + // + // gbCommandParams + // + this.gbCommandParams.Controls.Add(this.txtCmdQuery); + this.gbCommandParams.Controls.Add(this.lblCmdQuery); + this.gbCommandParams.Controls.Add(this.txtName); + this.gbCommandParams.Controls.Add(this.lblName); + this.gbCommandParams.Controls.Add(this.numCmdNum); + this.gbCommandParams.Controls.Add(this.lblCmdNum); + this.gbCommandParams.Location = new System.Drawing.Point(6, 67); + this.gbCommandParams.Name = "gbCommandParams"; + this.gbCommandParams.Padding = new System.Windows.Forms.Padding(10, 3, 10, 10); + this.gbCommandParams.Size = new System.Drawing.Size(414, 210); + this.gbCommandParams.TabIndex = 1; + this.gbCommandParams.TabStop = false; + this.gbCommandParams.Text = "Command Parameters"; + // + // txtCmdQuery + // + this.txtCmdQuery.AcceptsReturn = true; + this.txtCmdQuery.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); + this.txtCmdQuery.Location = new System.Drawing.Point(13, 71); + this.txtCmdQuery.Multiline = true; + this.txtCmdQuery.Name = "txtCmdQuery"; + this.txtCmdQuery.ScrollBars = System.Windows.Forms.ScrollBars.Both; + this.txtCmdQuery.Size = new System.Drawing.Size(388, 126); + this.txtCmdQuery.TabIndex = 5; + this.txtCmdQuery.WordWrap = false; + this.txtCmdQuery.TextChanged += new System.EventHandler(this.txtCmdQuery_TextChanged); + // + // lblCmdQuery + // + this.lblCmdQuery.AutoSize = true; + this.lblCmdQuery.Location = new System.Drawing.Point(10, 55); + this.lblCmdQuery.Name = "lblCmdQuery"; + this.lblCmdQuery.Size = new System.Drawing.Size(28, 13); + this.lblCmdQuery.TabIndex = 4; + this.lblCmdQuery.Text = "SQL"; + // + // txtName + // + this.txtName.Location = new System.Drawing.Point(119, 32); + this.txtName.Name = "txtName"; + this.txtName.Size = new System.Drawing.Size(282, 20); + this.txtName.TabIndex = 3; + this.txtName.TextChanged += new System.EventHandler(this.txtName_TextChanged); + // + // lblName + // + this.lblName.AutoSize = true; + this.lblName.Location = new System.Drawing.Point(116, 16); + this.lblName.Name = "lblName"; + this.lblName.Size = new System.Drawing.Size(35, 13); + this.lblName.TabIndex = 2; + this.lblName.Text = "Name"; + // + // numCmdNum + // + this.numCmdNum.Location = new System.Drawing.Point(13, 32); + this.numCmdNum.Maximum = new decimal(new int[] { + 65535, + 0, + 0, + 0}); + this.numCmdNum.Name = "numCmdNum"; + this.numCmdNum.Size = new System.Drawing.Size(100, 20); + this.numCmdNum.TabIndex = 1; + this.numCmdNum.ValueChanged += new System.EventHandler(this.numCmdNum_ValueChanged); + // + // lblCmdNum + // + this.lblCmdNum.AutoSize = true; + this.lblCmdNum.Location = new System.Drawing.Point(10, 16); + this.lblCmdNum.Name = "lblCmdNum"; + this.lblCmdNum.Size = new System.Drawing.Size(92, 13); + this.lblCmdNum.TabIndex = 0; + this.lblCmdNum.Text = "Command number"; + // + // gbCommand + // + this.gbCommand.Controls.Add(this.cbCommand); + this.gbCommand.Controls.Add(this.btnDeleteCommand); + this.gbCommand.Controls.Add(this.btnCreateCommand); + this.gbCommand.Location = new System.Drawing.Point(6, 6); + this.gbCommand.Name = "gbCommand"; + this.gbCommand.Padding = new System.Windows.Forms.Padding(10, 3, 10, 10); + this.gbCommand.Size = new System.Drawing.Size(414, 55); + this.gbCommand.TabIndex = 0; + this.gbCommand.TabStop = false; + this.gbCommand.Text = "Command"; + // + // cbCommand + // + this.cbCommand.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cbCommand.FormattingEnabled = true; + this.cbCommand.Location = new System.Drawing.Point(13, 20); + this.cbCommand.Name = "cbCommand"; + this.cbCommand.Size = new System.Drawing.Size(226, 21); + this.cbCommand.TabIndex = 0; + this.cbCommand.SelectedIndexChanged += new System.EventHandler(this.cbCommand_SelectedIndexChanged); + // + // btnDeleteCommand + // + this.btnDeleteCommand.Location = new System.Drawing.Point(326, 19); + this.btnDeleteCommand.Name = "btnDeleteCommand"; + this.btnDeleteCommand.Size = new System.Drawing.Size(75, 23); + this.btnDeleteCommand.TabIndex = 2; + this.btnDeleteCommand.Text = "Delete"; + this.btnDeleteCommand.UseVisualStyleBackColor = true; + this.btnDeleteCommand.Click += new System.EventHandler(this.btnDeleteCommand_Click); + // + // btnCreateCommand + // + this.btnCreateCommand.Location = new System.Drawing.Point(245, 19); + this.btnCreateCommand.Name = "btnCreateCommand"; + this.btnCreateCommand.Size = new System.Drawing.Size(75, 23); + this.btnCreateCommand.TabIndex = 1; + this.btnCreateCommand.Text = "Create"; + this.btnCreateCommand.UseVisualStyleBackColor = true; + this.btnCreateCommand.Click += new System.EventHandler(this.btnCreateCommand_Click); + // // pnlBottom // - this.pnlBottom.Controls.Add(this.btnCancel); - this.pnlBottom.Controls.Add(this.btnOK); + this.pnlBottom.Controls.Add(this.btnClose); + this.pnlBottom.Controls.Add(this.btnSave); this.pnlBottom.Dock = System.Windows.Forms.DockStyle.Bottom; this.pnlBottom.Location = new System.Drawing.Point(0, 309); this.pnlBottom.Name = "pnlBottom"; this.pnlBottom.Size = new System.Drawing.Size(434, 41); this.pnlBottom.TabIndex = 1; // - // btnCancel + // btnClose // - this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.btnCancel.Location = new System.Drawing.Point(347, 6); - this.btnCancel.Name = "btnCancel"; - this.btnCancel.Size = new System.Drawing.Size(75, 23); - this.btnCancel.TabIndex = 1; - this.btnCancel.Text = "Cancel"; - this.btnCancel.UseVisualStyleBackColor = true; + this.btnClose.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnClose.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnClose.Location = new System.Drawing.Point(347, 6); + this.btnClose.Name = "btnClose"; + this.btnClose.Size = new System.Drawing.Size(75, 23); + this.btnClose.TabIndex = 1; + this.btnClose.Text = "Close"; + this.btnClose.UseVisualStyleBackColor = true; // - // btnOK + // btnSave // - this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.btnOK.Location = new System.Drawing.Point(266, 6); - this.btnOK.Name = "btnOK"; - this.btnOK.Size = new System.Drawing.Size(75, 23); - this.btnOK.TabIndex = 0; - this.btnOK.Text = "OK"; - this.btnOK.UseVisualStyleBackColor = true; - this.btnOK.Click += new System.EventHandler(this.btnOK_Click); + this.btnSave.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnSave.Location = new System.Drawing.Point(266, 6); + this.btnSave.Name = "btnSave"; + this.btnSave.Size = new System.Drawing.Size(75, 23); + this.btnSave.TabIndex = 0; + this.btnSave.Text = "Save"; + this.btnSave.UseVisualStyleBackColor = true; + this.btnSave.Click += new System.EventHandler(this.btnSave_Click); // // FrmConfig // - this.AcceptButton = this.btnOK; this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.CancelButton = this.btnCancel; + this.CancelButton = this.btnClose; this.ClientSize = new System.Drawing.Size(434, 350); this.Controls.Add(this.tabControl); this.Controls.Add(this.pnlBottom); @@ -330,6 +480,7 @@ private void InitializeComponent() this.ShowInTaskbar = false; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "DB Import - Device {0} Properties"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FrmConfig_FormClosing); this.Load += new System.EventHandler(this.FrmConfig_Load); this.gbConnection.ResumeLayout(false); this.gbConnection.PerformLayout(); @@ -339,6 +490,11 @@ private void InitializeComponent() this.pageQuery.ResumeLayout(false); this.pageQuery.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this.numTagCount)).EndInit(); + this.pageCommands.ResumeLayout(false); + this.gbCommandParams.ResumeLayout(false); + this.gbCommandParams.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.numCmdNum)).EndInit(); + this.gbCommand.ResumeLayout(false); this.pnlBottom.ResumeLayout(false); this.ResumeLayout(false); @@ -361,13 +517,25 @@ private void InitializeComponent() private System.Windows.Forms.TabPage pageDatabase; private System.Windows.Forms.TabPage pageQuery; private System.Windows.Forms.Panel pnlBottom; - private System.Windows.Forms.Button btnCancel; - private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.Button btnClose; + private System.Windows.Forms.Button btnSave; private System.Windows.Forms.GroupBox gbDataSourceType; private System.Windows.Forms.TextBox txtSelectQuery; private System.Windows.Forms.Label lblSelectQuery; private System.Windows.Forms.NumericUpDown numTagCount; private System.Windows.Forms.Label lblTagCount; private System.Windows.Forms.CheckBox chkAutoTagCount; + private System.Windows.Forms.TabPage pageCommands; + private System.Windows.Forms.ComboBox cbCommand; + private System.Windows.Forms.GroupBox gbCommand; + private System.Windows.Forms.Button btnDeleteCommand; + private System.Windows.Forms.Button btnCreateCommand; + private System.Windows.Forms.GroupBox gbCommandParams; + private System.Windows.Forms.TextBox txtCmdQuery; + private System.Windows.Forms.Label lblCmdQuery; + private System.Windows.Forms.TextBox txtName; + private System.Windows.Forms.Label lblName; + private System.Windows.Forms.NumericUpDown numCmdNum; + private System.Windows.Forms.Label lblCmdNum; } } \ No newline at end of file diff --git a/ScadaComm/OpenKPs/KpDbImport/DbImport/UI/FrmConfig.cs b/ScadaComm/OpenKPs/KpDbImport/DbImport/UI/FrmConfig.cs index f40704966..56172c5db 100644 --- a/ScadaComm/OpenKPs/KpDbImport/DbImport/UI/FrmConfig.cs +++ b/ScadaComm/OpenKPs/KpDbImport/DbImport/UI/FrmConfig.cs @@ -1,5 +1,5 @@ /* - * Copyright 2018 Mikhail Shiryaev + * Copyright 2019 Mikhail Shiryaev * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,20 +20,15 @@ * * Author : Mikhail Shiryaev * Created : 2018 - * Modified : 2018 + * Modified : 2019 */ using Scada.Comm.Devices.DbImport.Configuration; using Scada.Comm.Devices.DbImport.Data; using Scada.UI; using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; using System.Drawing; using System.IO; -using System.Linq; -using System.Text; using System.Windows.Forms; namespace Scada.Comm.Devices.DbImport.UI @@ -46,8 +41,9 @@ public partial class FrmConfig : Form { private AppDirs appDirs; // the application directories private int kpNum; // the device number - private string configFileName; // the configuration file name private Config config; // the device configuration + private string configFileName; // the configuration file name + private bool modified; // the configuration was modified private bool connChanging; // connection settings are changing @@ -68,11 +64,29 @@ public FrmConfig(AppDirs appDirs, int kpNum) { this.appDirs = appDirs ?? throw new ArgumentNullException("appDirs"); this.kpNum = kpNum; - configFileName = ""; config = new Config(); + configFileName = ""; + modified = false; connChanging = false; } + + /// + /// Gets or sets a value indicating whether the configuration was modified. + /// + private bool Modified + { + get + { + return modified; + } + set + { + modified = value; + btnSave.Enabled = modified; + } + } + /// /// Sets the controls according to the configuration. @@ -125,6 +139,14 @@ private void ConfigToControls() } } + // fill the command list + cbCommand.Items.AddRange(config.ExportCmds.ToArray()); + + if (cbCommand.Items.Count > 0) + cbCommand.SelectedIndex = 0; + else + ShowCommandParams(null); + connChanging = false; } @@ -206,6 +228,57 @@ private void EnableConnString() txtConnectionString.BackColor = Color.FromKnownColor(KnownColor.Window); } + /// + /// Shows the command parameters. + /// + private void ShowCommandParams(ExportCmd exportCmd) + { + if (exportCmd == null) + { + gbCommandParams.Enabled = false; + numCmdNum.Value = numCmdNum.Minimum; + txtName.Text = ""; + txtCmdQuery.Text = ""; + } + else + { + gbCommandParams.Enabled = true; + numCmdNum.SetValue(exportCmd.CmdNum); + txtName.Text = exportCmd.Name; + txtCmdQuery.Text = exportCmd.Query; + } + } + + /// + /// Sort and update the command list. + /// + private void UpdateCommands() + { + try + { + cbCommand.BeginUpdate(); + config.ExportCmds.Sort(); + ExportCmd selectedCmd = cbCommand.SelectedItem as ExportCmd; + + cbCommand.Items.Clear(); + cbCommand.Items.AddRange(config.ExportCmds.ToArray()); + cbCommand.SelectedIndex = config.ExportCmds.IndexOf(selectedCmd); + } + finally + { + cbCommand.EndUpdate(); + } + } + + /// + /// Update text of the selected item. + /// + private void UpdateCommandItem() + { + if (cbCommand.SelectedIndex >= 0) + cbCommand.Items[cbCommand.SelectedIndex] = cbCommand.SelectedItem; + } + private void FrmConfig_Load(object sender, EventArgs e) { @@ -225,6 +298,39 @@ private void FrmConfig_Load(object sender, EventArgs e) // display the configuration ConfigToControls(); + Modified = false; + } + + private void FrmConfig_FormClosing(object sender, FormClosingEventArgs e) + { + if (Modified) + { + DialogResult result = MessageBox.Show(CommPhrases.SaveKpSettingsConfirm, + CommonPhrases.QuestionCaption, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); + + switch (result) + { + case DialogResult.Yes: + string errMsg; + if (!config.Save(configFileName, out errMsg)) + { + ScadaUiUtils.ShowError(errMsg); + e.Cancel = true; + } + break; + case DialogResult.No: + break; + default: + e.Cancel = true; + break; + } + } + } + + + private void control_Changed(object sender, EventArgs e) + { + Modified = true; } private void cbDataSourceType_SelectedIndexChanged(object sender, EventArgs e) @@ -250,6 +356,7 @@ private void cbDataSourceType_SelectedIndexChanged(object sender, EventArgs e) EnableConnProps(); } + Modified = true; connChanging = false; } } @@ -267,6 +374,8 @@ private void txtConnProp_TextChanged(object sender, EventArgs e) EnableConnProps(); connChanging = false; } + + Modified = true; } } @@ -275,22 +384,95 @@ private void txtConnectionString_TextChanged(object sender, EventArgs e) if (!connChanging) { EnableConnString(); + Modified = true; } } private void chkAutoTagCount_CheckedChanged(object sender, EventArgs e) { numTagCount.Enabled = !chkAutoTagCount.Checked; + Modified = true; + } + + private void cbCommand_SelectedIndexChanged(object sender, EventArgs e) + { + ShowCommandParams(cbCommand.SelectedItem as ExportCmd); + } + + private void btnCreateCommand_Click(object sender, EventArgs e) + { + // add a new command + ExportCmd exportCmd = new ExportCmd(); + + if (config.ExportCmds.Count > 0) + exportCmd.CmdNum = config.ExportCmds[config.ExportCmds.Count - 1].CmdNum + 1; + + config.ExportCmds.Add(exportCmd); + cbCommand.SelectedIndex = cbCommand.Items.Add(exportCmd); + Modified = true; + } + + private void btnDeleteCommand_Click(object sender, EventArgs e) + { + // delete the selected command + int selectedIndex = cbCommand.SelectedIndex; + + if (selectedIndex >= 0) + { + config.ExportCmds.RemoveAt(selectedIndex); + cbCommand.Items.RemoveAt(selectedIndex); + + if (cbCommand.Items.Count > 0) + { + cbCommand.SelectedIndex = selectedIndex >= cbCommand.Items.Count ? + cbCommand.Items.Count - 1 : selectedIndex; + } + else + { + ShowCommandParams(null); + } + + Modified = true; + } + } + + private void numCmdNum_ValueChanged(object sender, EventArgs e) + { + if (cbCommand.SelectedItem is ExportCmd exportCmd) + { + exportCmd.CmdNum = Convert.ToInt32(numCmdNum.Value); + UpdateCommands(); + Modified = true; + } + } + + private void txtName_TextChanged(object sender, EventArgs e) + { + if (cbCommand.SelectedItem is ExportCmd exportCmd) + { + exportCmd.Name = txtName.Text; + UpdateCommandItem(); + Modified = true; + } + } + + private void txtCmdQuery_TextChanged(object sender, EventArgs e) + { + if (cbCommand.SelectedItem is ExportCmd exportCmd) + { + exportCmd.Query = txtCmdQuery.Text; + Modified = true; + } } - private void btnOK_Click(object sender, EventArgs e) + private void btnSave_Click(object sender, EventArgs e) { // retrieve the configuration ControlsToConfig(); // save the configuration if (config.Save(configFileName, out string errMsg)) - DialogResult = DialogResult.OK; + Modified = false; else ScadaUiUtils.ShowError(errMsg); } diff --git a/ScadaComm/OpenKPs/KpDbImport/KpDbImportLogic.cs b/ScadaComm/OpenKPs/KpDbImport/KpDbImportLogic.cs index f57485ccb..f6c2e84e4 100644 --- a/ScadaComm/OpenKPs/KpDbImport/KpDbImportLogic.cs +++ b/ScadaComm/OpenKPs/KpDbImport/KpDbImportLogic.cs @@ -379,13 +379,14 @@ public override void SendCmd(Command cmd) lastCommSucc = false; if ((cmd.CmdTypeID == BaseValues.CmdTypes.Standard || cmd.CmdTypeID == BaseValues.CmdTypes.Binary) && - dataSource.ExportCommands.TryGetValue(cmd.CmdNum, out DbCommand dbCommand)) + (dataSource.ExportCommands.TryGetValue(cmd.CmdNum, out DbCommand dbCommand) || + dataSource.ExportCommands.TryGetValue(0, out dbCommand))) { - if (ValidateDataSource() && ValidateCommand(dbCommand)) { - dataSource.SetCmdParam(dbCommand, "val", + dataSource.SetCmdParam(dbCommand, "cmdVal", cmd.CmdTypeID == BaseValues.CmdTypes.Standard ? (object)cmd.CmdVal : cmd.GetCmdDataStr()); + dataSource.SetCmdParam(dbCommand, "cmdNum", cmd.CmdNum); int tryNum = 0; while (RequestNeeded(ref tryNum)) diff --git a/ScadaComm/OpenKPs/KpDbImport/Lang/KpDbImport.en-GB.xml b/ScadaComm/OpenKPs/KpDbImport/Lang/KpDbImport.en-GB.xml index 82f948e12..88671a5ed 100644 --- a/ScadaComm/OpenKPs/KpDbImport/Lang/KpDbImport.en-GB.xml +++ b/ScadaComm/OpenKPs/KpDbImport/Lang/KpDbImport.en-GB.xml @@ -10,11 +10,19 @@ User Password Connection string - Query + Data Retrieval SQL Tag count Auto - OK - Cancel + Commands + Command + Create + Delete + Command Parameters + Command number + Name + SQL + Save + Close diff --git a/ScadaComm/OpenKPs/KpDbImport/Lang/KpDbImport.ru-RU.xml b/ScadaComm/OpenKPs/KpDbImport/Lang/KpDbImport.ru-RU.xml index 70c0c75da..97b095322 100644 --- a/ScadaComm/OpenKPs/KpDbImport/Lang/KpDbImport.ru-RU.xml +++ b/ScadaComm/OpenKPs/KpDbImport/Lang/KpDbImport.ru-RU.xml @@ -10,11 +10,19 @@ Пользователь Пароль Строка соединения - Запрос + Извлечение данных SQL Количество тегов Авто - OK - Отмена + Команды + Команда + Создать + Удалить + Параметры команды + Номер команды + Наименование + SQL + Сохранить + Закрыть From 33b0597f37c741dcc4e7e0687305fab788805c99 Mon Sep 17 00:00:00 2001 From: 2mik Date: Wed, 5 Jun 2019 21:08:49 +0300 Subject: [PATCH 3/4] KpDbImport: fixes --- .../KpDbImport/DbImport/Data/DataSource.cs | 1 + .../KpDbImport/DbImport/UI/FrmConfig.cs | 21 +++++++++++++------ .../OpenKPs/KpDbImport/KpDbImportView.cs | 11 ++++++++-- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/ScadaComm/OpenKPs/KpDbImport/DbImport/Data/DataSource.cs b/ScadaComm/OpenKPs/KpDbImport/DbImport/Data/DataSource.cs index a9b39e60c..17b6e0713 100644 --- a/ScadaComm/OpenKPs/KpDbImport/DbImport/Data/DataSource.cs +++ b/ScadaComm/OpenKPs/KpDbImport/DbImport/Data/DataSource.cs @@ -43,6 +43,7 @@ protected DataSource() { Connection = null; SelectCommand = null; + ExportCommands = new SortedList(); } diff --git a/ScadaComm/OpenKPs/KpDbImport/DbImport/UI/FrmConfig.cs b/ScadaComm/OpenKPs/KpDbImport/DbImport/UI/FrmConfig.cs index 56172c5db..3517ac05f 100644 --- a/ScadaComm/OpenKPs/KpDbImport/DbImport/UI/FrmConfig.cs +++ b/ScadaComm/OpenKPs/KpDbImport/DbImport/UI/FrmConfig.cs @@ -45,6 +45,7 @@ public partial class FrmConfig : Form private string configFileName; // the configuration file name private bool modified; // the configuration was modified private bool connChanging; // connection settings are changing + private bool cmdSelecting; // a command is selecting @@ -68,6 +69,7 @@ public FrmConfig(AppDirs appDirs, int kpNum) configFileName = ""; modified = false; connChanging = false; + cmdSelecting = false; } @@ -94,6 +96,7 @@ private bool Modified private void ConfigToControls() { connChanging = true; + cmdSelecting = true; // set the control values cbDataSourceType.SelectedIndex = (int)config.DataSourceType; @@ -144,10 +147,11 @@ private void ConfigToControls() if (cbCommand.Items.Count > 0) cbCommand.SelectedIndex = 0; - else - ShowCommandParams(null); + + ShowCommandParams(cbCommand.SelectedItem as ExportCmd); connChanging = false; + cmdSelecting = false; } /// @@ -396,7 +400,12 @@ private void chkAutoTagCount_CheckedChanged(object sender, EventArgs e) private void cbCommand_SelectedIndexChanged(object sender, EventArgs e) { - ShowCommandParams(cbCommand.SelectedItem as ExportCmd); + if (!cmdSelecting) + { + cmdSelecting = true; + ShowCommandParams(cbCommand.SelectedItem as ExportCmd); + cmdSelecting = false; + } } private void btnCreateCommand_Click(object sender, EventArgs e) @@ -438,7 +447,7 @@ private void btnDeleteCommand_Click(object sender, EventArgs e) private void numCmdNum_ValueChanged(object sender, EventArgs e) { - if (cbCommand.SelectedItem is ExportCmd exportCmd) + if (!cmdSelecting && cbCommand.SelectedItem is ExportCmd exportCmd) { exportCmd.CmdNum = Convert.ToInt32(numCmdNum.Value); UpdateCommands(); @@ -448,7 +457,7 @@ private void numCmdNum_ValueChanged(object sender, EventArgs e) private void txtName_TextChanged(object sender, EventArgs e) { - if (cbCommand.SelectedItem is ExportCmd exportCmd) + if (!cmdSelecting && cbCommand.SelectedItem is ExportCmd exportCmd) { exportCmd.Name = txtName.Text; UpdateCommandItem(); @@ -458,7 +467,7 @@ private void txtName_TextChanged(object sender, EventArgs e) private void txtCmdQuery_TextChanged(object sender, EventArgs e) { - if (cbCommand.SelectedItem is ExportCmd exportCmd) + if (!cmdSelecting && cbCommand.SelectedItem is ExportCmd exportCmd) { exportCmd.Query = txtCmdQuery.Text; Modified = true; diff --git a/ScadaComm/OpenKPs/KpDbImport/KpDbImportView.cs b/ScadaComm/OpenKPs/KpDbImport/KpDbImportView.cs index 29af36c22..3ea1965c4 100644 --- a/ScadaComm/OpenKPs/KpDbImport/KpDbImportView.cs +++ b/ScadaComm/OpenKPs/KpDbImport/KpDbImportView.cs @@ -68,8 +68,15 @@ public override string KPDescr get { return Localization.UseRussian ? - "Импорт из сторонней базы данных." : - "Import from a third-party database."; + "Импорт из сторонней базы данных.\n\n" + + "Команды определяются в конфигурации КП.\n" + + "Пример команды:\n" + + "UPDATE table SET column1 = @cmdVal WHERE column2 = @cmdNum" : + + "Import from a third-party database.\n\n" + + "Commands are defined in the device configuration.\n" + + "Command example:\n" + + "UPDATE table SET column1 = @cmdVal WHERE column2 = @cmdNum"; } } From e28c071ecc339bb4ac567bac02efde83995a6302 Mon Sep 17 00:00:00 2001 From: 2mik Date: Thu, 6 Jun 2019 09:44:43 +0300 Subject: [PATCH 4/4] ScadaAdmin: fix uploading --- ScadaAdmin/ScadaAdmin5/ScadaAdminCommon/ImportExport.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ScadaAdmin/ScadaAdmin5/ScadaAdminCommon/ImportExport.cs b/ScadaAdmin/ScadaAdmin5/ScadaAdminCommon/ImportExport.cs index d0e223fe8..c4d4de34d 100644 --- a/ScadaAdmin/ScadaAdmin5/ScadaAdminCommon/ImportExport.cs +++ b/ScadaAdmin/ScadaAdmin5/ScadaAdminCommon/ImportExport.cs @@ -368,14 +368,14 @@ public void ExportToArchive(string destFileName, ScadaProject project, Instance } // add the Communicator settings to the archive - if (uploadSettings.IncludeServer && instance.ServerApp.Enabled) + if (uploadSettings.IncludeComm && instance.CommApp.Enabled) { PackDirectory(zipArchive, instance.CommApp.AppDir, DirectoryBuilder.GetDirectory(ConfigParts.Comm, '/'), ignoreRegKeys); } // add the Webstation settings to the archive - if (uploadSettings.IncludeServer && instance.ServerApp.Enabled) + if (uploadSettings.IncludeWeb && instance.WebApp.Enabled) { PackDirectory(zipArchive, Path.Combine(instance.WebApp.AppDir, "config"), DirectoryBuilder.GetDirectory(ConfigParts.Web, AppFolder.Config, '/'), ignoreRegKeys);