diff --git a/Source/Applications/Wave Demo Apps/UpdateWAVMetaData/Program.cs b/Source/Applications/Wave Demo Apps/UpdateWAVMetaData/Program.cs index d2b86fb8485..ea37e24200b 100755 --- a/Source/Applications/Wave Demo Apps/UpdateWAVMetaData/Program.cs +++ b/Source/Applications/Wave Demo Apps/UpdateWAVMetaData/Program.cs @@ -48,24 +48,9 @@ static int Main(string[] args) Guid nodeID = systemSettings["NodeID"].ValueAs(); bool useMemoryCache = systemSettings["UseMemoryCache"].ValueAsBoolean(false); string connectionString = systemSettings["ConnectionString"].Value; - string nodeIDQueryString = null; string parameterizedQuery; int protocolID, signalTypePMID, signalTypePAID; - // Define guid with query string delimiters according to database needs - Dictionary settings = connectionString.ParseKeyValuePairs(); - string setting; - - if (settings.TryGetValue("Provider", out setting)) - { - // Check if provider is for Access since it uses braces as Guid delimiters - if (setting.StartsWith("Microsoft.Jet.OLEDB", StringComparison.OrdinalIgnoreCase)) - nodeIDQueryString = "{" + nodeID + "}"; - } - - if (string.IsNullOrWhiteSpace(nodeIDQueryString)) - nodeIDQueryString = "'" + nodeID + "'"; - using (AdoDataConnection database = new AdoDataConnection("systemSettings")) { IDbConnection connection = database.Connection; @@ -109,12 +94,12 @@ static int Main(string[] args) if (Convert.ToInt32(connection.ExecuteScalar(database.ParameterizedQueryString("SELECT COUNT(*) FROM Device WHERE Acronym = {0}", "acronym"), acronym)) == 0) { parameterizedQuery = database.ParameterizedQueryString("INSERT INTO Device(NodeID, Acronym, Name, ProtocolID, FramesPerSecond, " + - "MeasurementReportingInterval, ConnectionString, Enabled) VALUES(" + nodeIDQueryString + ", {0}, {1}, {2}, {3}, {4}, {5}, {6})", + "MeasurementReportingInterval, ConnectionString, Enabled) VALUES({0}, {1}, {2}, {3}, {4}, {5}, {6}, {7})", "acronym", "name", "protocolID", "framesPerSecond", "measurementReportingInterval", - "connectionString", "enabled"); + "connectionString", "enabled", "nodeID"); // Insert new device record - connection.ExecuteNonQuery(parameterizedQuery, acronym, name, protocolID, sourceWave.SampleRate, 1000000, $"wavFileName={FilePath.GetAbsolutePath(sourceFileName)}; connectOnDemand=true; outputSourceIDs={acronym}; memoryCache={useMemoryCache}", database.Bool(true)); + connection.ExecuteNonQuery(parameterizedQuery, acronym, name, protocolID, sourceWave.SampleRate, 1000000, $"wavFileName={FilePath.GetAbsolutePath(sourceFileName)}; connectOnDemand=true; outputSourceIDs={acronym}; memoryCache={useMemoryCache}", database.Bool(true), database.Guid(nodeID)); int deviceID = Convert.ToInt32(connection.ExecuteScalar(database.ParameterizedQueryString("SELECT ID FROM Device WHERE Acronym = {0}", "acronym"), acronym)); string pointTag; int lastPhasorIndex = 0; diff --git a/Source/Libraries/Adapters/GrafanaAdapters/DeviceAlarmStateAdapter.cs b/Source/Libraries/Adapters/GrafanaAdapters/DeviceAlarmStateAdapter.cs index d8e269d7ff9..51b082ecb02 100644 --- a/Source/Libraries/Adapters/GrafanaAdapters/DeviceAlarmStateAdapter.cs +++ b/Source/Libraries/Adapters/GrafanaAdapters/DeviceAlarmStateAdapter.cs @@ -451,9 +451,10 @@ private void LoadAlarmStates(bool reload = false) { // Querying from MeasurementDetail because we also want to include disabled device measurements string measurementSQL = TargetParentDevices ? - "SELECT MeasurementDetail.SignalID AS SignalID, MeasurementDetail.ID AS ID FROM MeasurementDetail INNER JOIN DeviceDetail ON MeasurementDetail.DeviceID = DeviceDetail.ID WHERE (DeviceDetail.Acronym = {0} OR DeviceDetail.ParentAcronym = {0}) AND MeasurementDetail.SignalAcronym = 'FREQ'" : + "SELECT MeasurementDetail.SignalID AS SignalID, MeasurementDetail.ID AS ID " + + "FROM MeasurementDetail INNER JOIN DeviceDetail ON MeasurementDetail.DeviceID = DeviceDetail.ID " + + "WHERE (DeviceDetail.Acronym = {0} OR DeviceDetail.ParentAcronym = {0}) AND MeasurementDetail.SignalAcronym = 'FREQ'" : "SELECT SignalID, ID FROM MeasurementDetail WHERE DeviceAcronym = {0} AND SignalAcronym = 'FREQ'"; - DataTable table = connection.RetrieveData(measurementSQL, metadata.ConvertField("Acronym")); // ReSharper disable once AccessToDisposedClosure diff --git a/Source/Libraries/Adapters/HistorianAdapters/LocalOutputAdapter.cs b/Source/Libraries/Adapters/HistorianAdapters/LocalOutputAdapter.cs index 57c67cdad7f..948d661fdd9 100755 --- a/Source/Libraries/Adapters/HistorianAdapters/LocalOutputAdapter.cs +++ b/Source/Libraries/Adapters/HistorianAdapters/LocalOutputAdapter.cs @@ -1119,12 +1119,14 @@ private static void OptimizeLocalHistorianSettings(AdoDataConnection database, s string archiveLocation = FilePath.GetDirectoryName(settings["FileName"].Value); string adapterName = $"{instanceName}READER"; string connectionString = string.Format("archiveLocation={0}; instanceName={1}; sourceIDs={1}; publicationInterval=333333; connectOnDemand=true", archiveLocation, instanceName); - string query = "INSERT INTO CustomInputAdapter(NodeID, AdapterName, AssemblyName, TypeName, ConnectionString, LoadOrder, Enabled) " + $"VALUES({nodeIDQueryString}, @adapterName, 'HistorianAdapters.dll', 'HistorianAdapters.LocalInputAdapter', @connectionString, 0, 1)"; - + string query = database.ParameterizedQueryString("INSERT INTO " + + "CustomInputAdapter(NodeID, AdapterName, AssemblyName, TypeName, ConnectionString, LoadOrder, Enabled) " + + "VALUES({0}, @{1}, 'HistorianAdapters.dll', 'HistorianAdapters.LocalInputAdapter', @{2}, 0, 1)", + "nodeIDQueryString", "adapterName", "connectionString"); if (database.IsOracle) query = query.Replace('@', ':'); - database.Connection.ExecuteNonQuery(query, adapterName, connectionString); + database.Connection.ExecuteNonQuery(query, nodeIDQueryString, adapterName, connectionString); } catch (Exception ex) { @@ -1206,7 +1208,7 @@ private static void AddPIHistorianReaders(AdoDataConnection database, string nod IEnumerable readers = database.Connection.RetrieveData(database.AdapterType, $"SELECT * FROM CustomInputAdapter WHERE NodeID = {nodeIDQueryString} AND TypeName = 'PIAdapters.PIPBInputAdapter'").AsEnumerable(); // Also check for PI adapters loaded into CustomOutputAdapters - historians = historians.Concat(database.Connection.RetrieveData(database.AdapterType, $"SELECT AdapterName, ConnectionString FROM RuntimeCustomOutputAdapter WHERE NodeID = {nodeIDQueryString} AND TypeName = 'PIAdapters.PIOutputAdapter'").AsEnumerable()); + historians = historians.Concat(database.Connection.RetrieveData(database.AdapterType, "SELECT AdapterName, ConnectionString FROM RuntimeCustomOutputAdapter WHERE NodeID = {0} AND TypeName = 'PIAdapters.PIOutputAdapter'", nodeIDQueryString).AsEnumerable()); // Make sure a temporal reader is defined for each OSI-PI historian foreach (DataRow row in historians) @@ -1252,7 +1254,10 @@ private static void AddPIHistorianReaders(AdoDataConnection database, string nod string connectionString = string.IsNullOrEmpty(userName) ? $"ServerName={serverName}; ConnectTimeout={connectTimeout}; sourceIDs={instanceName}; connectOnDemand=true" : $"ServerName={serverName}; UserName={userName}; Password={password.ToNonNullString()}; ConnectTimeout={connectTimeout}; sourceIDs={instanceName}; connectOnDemand=true"; - string query = "INSERT INTO CustomInputAdapter(NodeID, AdapterName, AssemblyName, TypeName, ConnectionString, LoadOrder, Enabled) " + $"VALUES({nodeIDQueryString}, @adapterName, 'PIAdapters.dll', 'PIAdapters.PIPBInputAdapter', @connectionString, 0, 1)"; + string query = database.ParameterizedQueryString("INSERT INTO " + + "CustomInputAdapter(NodeID, AdapterName, AssemblyName, TypeName, ConnectionString, LoadOrder, Enabled) " + + "VALUES({0}, @{1}, 'PIAdapters.dll', 'PIAdapters.PIPBInputAdapter', @{2}, 0, 1)", + "nodeIDQueryString", "adapterName", "connectionString"); if (database.IsOracle) query = query.Replace('@', ':'); diff --git a/Source/Libraries/Adapters/MetadataAdapters/MetadataExportAdapter.cs b/Source/Libraries/Adapters/MetadataAdapters/MetadataExportAdapter.cs index c0dd33398d8..1f094cd1e38 100644 --- a/Source/Libraries/Adapters/MetadataAdapters/MetadataExportAdapter.cs +++ b/Source/Libraries/Adapters/MetadataAdapters/MetadataExportAdapter.cs @@ -303,7 +303,7 @@ private DataSet AcquireMetadata() DataSet metadata = new DataSet(); // Initialize active node ID - Guid nodeID = Guid.Parse(dbConnection.ExecuteScalar($"SELECT NodeID FROM IaonActionAdapter WHERE ID = {ID}").ToString()); + Guid nodeID = Guid.Parse(dbConnection.ExecuteScalar("SELECT NodeID FROM IaonActionAdapter WHERE ID = {0}", ID).ToString()); // Copy key metadata tables foreach (string tableExpression in MetadataTables.Split(';')) diff --git a/Source/Libraries/Adapters/MetadataAdapters/MetadataImportAdapter.cs b/Source/Libraries/Adapters/MetadataAdapters/MetadataImportAdapter.cs index 43ee9044b9a..e85ded81471 100644 --- a/Source/Libraries/Adapters/MetadataAdapters/MetadataImportAdapter.cs +++ b/Source/Libraries/Adapters/MetadataAdapters/MetadataImportAdapter.cs @@ -443,7 +443,7 @@ private Action GetSynchronizeMetadataAction() // Determine the active node ID - we cache this since this value won't change for the lifetime of this class if (nodeID == Guid.Empty) - nodeID = Guid.Parse(command.ExecuteScalar($"SELECT NodeID FROM IaonActionAdapter WHERE ID = {(int)ID}", MetadataSynchronizationTimeout).ToString()); + nodeID = Guid.Parse(command.ExecuteScalar("SELECT NodeID FROM IaonActionAdapter WHERE ID = {0}", (int)ID, MetadataSynchronizationTimeout).ToString()); // Determine the protocol record auto-inc ID value for the gateway transport protocol (GEP) - this value is also cached since it shouldn't change for the lifetime of this class if (virtualProtocolID == 0) @@ -462,7 +462,7 @@ private Action GetSynchronizeMetadataAction() if (sourceID == null || sourceID == DBNull.Value) { // Get a historian ID, but exclude the STAT historian - object randomHistorianID = command.ExecuteScalar($"SELECT ID FROM Historian WHERE Acronym <> 'STAT'", MetadataSynchronizationTimeout); + object randomHistorianID = command.ExecuteScalar("SELECT ID FROM Historian WHERE Acronym <> 'STAT'", MetadataSynchronizationTimeout); command.ExecuteNonQuery(insertParentDeviceSql, MetadataSynchronizationTimeout, database.Guid(nodeID), randomHistorianID, ParentDeviceAcronym, ParentDeviceAcronym, virtualProtocolID); sourceID = command.ExecuteScalar(parentDeviceIDSql, MetadataSynchronizationTimeout, ParentDeviceAcronym); } @@ -470,11 +470,11 @@ private Action GetSynchronizeMetadataAction() int parentID = Convert.ToInt32(sourceID); // Validate that the subscriber device is marked as a concentrator (we are about to associate children devices with it) - if (!command.ExecuteScalar($"SELECT IsConcentrator FROM Device WHERE ID = {parentID}", MetadataSynchronizationTimeout).ToString().ParseBoolean()) - command.ExecuteNonQuery($"UPDATE Device SET IsConcentrator = 1 WHERE ID = {parentID}", MetadataSynchronizationTimeout); + if (!command.ExecuteScalar("SELECT IsConcentrator FROM Device WHERE ID = {0}", parentID, MetadataSynchronizationTimeout).ToString().ParseBoolean()) + command.ExecuteNonQuery("UPDATE Device SET IsConcentrator = 1 WHERE ID = {0}", parentID, MetadataSynchronizationTimeout); // Get any historian associated with the subscriber device - object historianID = command.ExecuteScalar($"SELECT HistorianID FROM Device WHERE ID = {parentID}", MetadataSynchronizationTimeout); + object historianID = command.ExecuteScalar("SELECT HistorianID FROM Device WHERE ID = {0}", parentID, MetadataSynchronizationTimeout); // Ascertain total number of actions required for all metadata synchronization so some level feed back can be provided on progress initSyncProgress(metadata.Tables.Cast().Sum(dataTable => (long)dataTable.Rows.Count) + 3); diff --git a/Source/Libraries/Adapters/MySqlAdapters/MySqlOutputAdapter.cs b/Source/Libraries/Adapters/MySqlAdapters/MySqlOutputAdapter.cs index 8aa9b784f33..edae5ee0313 100755 --- a/Source/Libraries/Adapters/MySqlAdapters/MySqlOutputAdapter.cs +++ b/Source/Libraries/Adapters/MySqlAdapters/MySqlOutputAdapter.cs @@ -176,17 +176,24 @@ protected override void ProcessMeasurements(IMeasurement[] measurements) foreach (IMeasurement measurement in measurements) { // Create the command string to insert the measurement as a record in the table. - StringBuilder commandString = new StringBuilder("INSERT INTO Measurement VALUES ('"); IDbCommand command = m_connection.CreateCommand(); + IDataParameter measurementIDParameter = command.CreateParameter(); + IDataParameter timeStampParameter = command.CreateParameter(); + IDataParameter valueParameter = command.CreateParameter(); - commandString.Append(measurement.ID); - commandString.Append("','"); - commandString.Append((long)measurement.Timestamp); - commandString.Append("',"); - commandString.Append(measurement.AdjustedValue); - commandString.Append(')'); + measurementIDParameter.Name = "@measurementID"; + timeStampParameter.Name = "@timeStamp"; + valueParameter.Name = "@adjustedValue"; - command.CommandText = commandString.ToString(); + measurementIDParameter.Value = measurement.ID; + timeStampParameter.Value = (long)measurement.Timestamp; + valueParameter.Value = measurement.AdjustedValue; + + command.Parameters.Add(measurementIDParameter); + command.Parameters.Add(timeStampParameter); + command.Parameters.Add(valueParameter); + + command.CommandText = "INSERT INTO Measurement VALUES (@measurementID, @timeStamp, @adjustedValue)"; command.ExecuteNonQuery(); } diff --git a/Source/Libraries/Adapters/PIAdapters/PIOutputAdapter.cs b/Source/Libraries/Adapters/PIAdapters/PIOutputAdapter.cs index 7be4ed87386..1d1fff1a927 100755 --- a/Source/Libraries/Adapters/PIAdapters/PIOutputAdapter.cs +++ b/Source/Libraries/Adapters/PIAdapters/PIOutputAdapter.cs @@ -2475,7 +2475,7 @@ protected override void ExecuteMetadataRefresh() { // Attempt to look up last update time for record database ??= new AdoDataConnection("systemSettings"); - updateTime = Convert.ToDateTime(database.Connection.ExecuteScalar($"SELECT UpdatedOn FROM Measurement WHERE SignalID = '{signalID}'")); + updateTime = Convert.ToDateTime(database.Connection.ExecuteScalar("SELECT UpdatedOn FROM Measurement WHERE SignalID = '{0}'", signalID)); } } catch diff --git a/Source/Libraries/Adapters/PhasorProtocolAdapters/CommonPhasorServices.cs b/Source/Libraries/Adapters/PhasorProtocolAdapters/CommonPhasorServices.cs index e4a9e1237c5..93aaa6c4b77 100755 --- a/Source/Libraries/Adapters/PhasorProtocolAdapters/CommonPhasorServices.cs +++ b/Source/Libraries/Adapters/PhasorProtocolAdapters/CommonPhasorServices.cs @@ -1112,7 +1112,7 @@ private static void MeasurementDeviceAssociation(AdoDataConnection connection, s } // Make sure device acronym exists - if (connection.ExecuteScalar($"SELECT COUNT(*) FROM Device WHERE NodeID={nodeIDQueryString} AND Acronym={{0}}", deviceAcronym) == 0) + if (connection.ExecuteScalar("SELECT COUNT(*) FROM Device WHERE NodeID={0} AND Acronym={1}", nodeIDQueryString, deviceAcronym) == 0) { // Lookup virtual device protocol if (connection.ExecuteScalar("SELECT COUNT(*) FROM Protocol WHERE Acronym='VirtualInput'") == 0) @@ -1126,16 +1126,16 @@ private static void MeasurementDeviceAssociation(AdoDataConnection connection, s int virtualProtocolID = connection.ExecuteScalar("SELECT ID FROM Protocol WHERE Acronym='VirtualInput'"); // Create new virtual device record - connection.ExecuteNonQuery($"INSERT INTO Device(NodeID, Acronym, Name, ProtocolID, Enabled) VALUES({nodeIDQueryString}, {{0}}, {{1}}, {{2}}, 1)", deviceAcronym, deviceAcronym, virtualProtocolID); + connection.ExecuteNonQuery("INSERT INTO Device(NodeID, Acronym, Name, ProtocolID, Enabled) VALUES({0}, {1}, {2}, {3}, 1)", nodeIDQueryString, deviceAcronym, deviceAcronym, virtualProtocolID); } statusMessage($"Validating \"{deviceAcronym}\" virtual device measurement associations..."); // Get device ID - int deviceID = connection.ExecuteScalar($"SELECT ID FROM Device WHERE NodeID={nodeIDQueryString} AND Acronym={{0}}", deviceAcronym); + int deviceID = connection.ExecuteScalar("SELECT ID FROM Device WHERE NodeID={0} AND Acronym={1}", nodeIDQueryString, deviceAcronym); // Get measurements that should be associated with device ID but are not currently - IEnumerable measurements = connection.RetrieveData($"SELECT PointID FROM Measurement WHERE ({lookupExpression}) AND (DeviceID IS NULL OR DeviceID <> {{0}})", deviceID).AsEnumerable(); + IEnumerable measurements = connection.RetrieveData("SELECT PointID FROM Measurement WHERE ({0}) AND (DeviceID IS NULL OR DeviceID <> {{1}})", lookupExpression, deviceID).AsEnumerable(); int associatedMeasurements = 0; @@ -1296,8 +1296,8 @@ private static void PhasorDataSourceValidation(AdoDataConnection database, strin statusMessage("Verifying statistics archive exists..."); // Validate that the statistics historian exists - if (Convert.ToInt32(database.Connection.ExecuteScalar($"SELECT COUNT(*) FROM Historian WHERE Acronym='STAT' AND NodeID={nodeIDQueryString}")) == 0) - database.Connection.ExecuteNonQuery($"INSERT INTO Historian(NodeID, Acronym, Name, AssemblyName, TypeName, ConnectionString, IsLocal, Description, LoadOrder, Enabled) VALUES({nodeIDQueryString}, 'STAT', 'Statistics Archive', 'HistorianAdapters.dll', 'HistorianAdapters.LocalOutputAdapter', '', 1, 'Local historian used to archive system statistics', 9999, 1)"); + if (Convert.ToInt32(database.Connection.ExecuteScalar("SELECT COUNT(*) FROM Historian WHERE Acronym='STAT' AND NodeID={0}", nodeIDQueryString)) == 0) + database.Connection.ExecuteNonQuery("INSERT INTO Historian(NodeID, Acronym, Name, AssemblyName, TypeName, ConnectionString, IsLocal, Description, LoadOrder, Enabled) VALUES({0}, 'STAT', 'Statistics Archive', 'HistorianAdapters.dll', 'HistorianAdapters.LocalOutputAdapter', '', 1, 'Local historian used to archive system statistics', 9999, 1)", nodeIDQueryString); // Make sure statistics path exists to hold historian files string statisticsPath = FilePath.GetAbsolutePath(FilePath.AddPathSuffix("Statistics")); @@ -1351,7 +1351,7 @@ private static void PhasorDataSourceValidation(AdoDataConnection database, strin configFile.Save(); // Get the needed statistic related IDs - int statHistorianID = Convert.ToInt32(database.Connection.ExecuteScalar($"SELECT ID FROM Historian WHERE Acronym='STAT' AND NodeID={nodeIDQueryString}")); + int statHistorianID = Convert.ToInt32(database.Connection.ExecuteScalar("SELECT ID FROM Historian WHERE Acronym='STAT' AND NodeID={0}, nodeIDQueryString")); // Load the defined system statistics IEnumerable statistics = database.Connection.RetrieveData(database.AdapterType, "SELECT * FROM Statistic ORDER BY Source, SignalIndex").AsEnumerable(); @@ -1457,7 +1457,7 @@ private static void PhasorDataSourceValidation(AdoDataConnection database, strin // Determine how many changes were made to devices and measurements - // if no changes were made, we can skip the next few steps if (trackedTables.Contains("Device") && trackedTables.Contains("Measurement")) - changes = Convert.ToUInt64(database.Connection.ExecuteScalar($"SELECT COUNT(*) FROM TrackedChange WHERE (TableName = 'Device' OR TableName = 'Measurement') AND ID > {trackingVersion}")); + changes = Convert.ToUInt64(database.Connection.ExecuteScalar("SELECT COUNT(*) FROM TrackedChange WHERE (TableName = 'Device' OR TableName = 'Measurement') AND ID > {0}", nodeIDQueryString)); else changes = ulong.MaxValue; } @@ -1487,7 +1487,8 @@ private static void PhasorDataSourceValidation(AdoDataConnection database, strin int qualityFlagsSignalTypeID = Convert.ToInt32(database.Connection.ExecuteScalar("SELECT ID FROM SignalType WHERE Acronym='QUAL'")); // Make sure one device quality flags measurement exists for each "connection" for devices that support time quality flags - foreach (DataRow device in database.Connection.RetrieveData(database.AdapterType, $"SELECT * FROM Device WHERE ((IsConcentrator = 0 AND ParentID IS NULL) OR IsConcentrator = 1) AND NodeID = {nodeIDQueryString} AND ProtocolID IN ({timeQualityProtocolIDs})").Rows) + foreach (DataRow device in database.Connection.RetrieveData(database.AdapterType, "SELECT * FROM Device WHERE ((IsConcentrator = 0 AND ParentID IS NULL) " + + "OR IsConcentrator = 1) AND NodeID = {0} AND ProtocolID IN ({1})", nodeIDQueryString, timeQualityProtocolIDs).Rows) { Dictionary connectionSettings = device.Field("ConnectionString")?.ParseKeyValuePairs(); @@ -1500,11 +1501,11 @@ private static void PhasorDataSourceValidation(AdoDataConnection database, strin signalReference = SignalReference.ToString(acronym, SignalKind.Quality); // See if quality flags measurement exists for device - if (Convert.ToInt32(database.Connection.ExecuteScalar($"SELECT COUNT(*) FROM Measurement WHERE SignalReference = '{signalReference}' AND DeviceID = {deviceID}")) == 0) + if (Convert.ToInt32(database.Connection.ExecuteScalar("SELECT COUNT(*) FROM Measurement WHERE SignalReference = '{0}' AND DeviceID = {1}", signalReference, deviceID)) == 0) { historianID = device.ConvertNullableField("HistorianID"); - company = (string)database.Connection.ExecuteScalar($"SELECT MapAcronym FROM Company WHERE ID = {device.ConvertNullableField("CompanyID") ?? 0}"); + company = (string)database.Connection.ExecuteScalar("SELECT MapAcronym FROM Company WHERE ID = {0}", device.ConvertNullableField("CompanyID") ?? 0); if (string.IsNullOrEmpty(company)) company = configFile.Settings["systemSettings"]["CompanyAcronym"].Value.TruncateRight(3); @@ -1521,7 +1522,7 @@ private static void PhasorDataSourceValidation(AdoDataConnection database, strin } // Make sure needed device statistic measurements exist, currently statistics are only associated with phasor devices so we filter based on protocol - foreach (DataRow device in database.Connection.RetrieveData(database.AdapterType, $"SELECT * FROM Device WHERE IsConcentrator = 0 AND NodeID = {nodeIDQueryString} AND ProtocolID IN ({protocolIDs})").Rows) + foreach (DataRow device in database.Connection.RetrieveData(database.AdapterType, "SELECT * FROM Device WHERE IsConcentrator = 0 AND NodeID = {0} AND ProtocolID IN ({1})", nodeIDQueryString, protocolIDs).Rows) { foreach (DataRow statistic in deviceStatistics) { @@ -1530,10 +1531,10 @@ private static void PhasorDataSourceValidation(AdoDataConnection database, strin acronym = oldAcronym + "!PMU"; string oldSignalReference = SignalReference.ToString(oldAcronym, SignalKind.Statistic, signalIndex); signalReference = SignalReference.ToString(acronym, SignalKind.Statistic, signalIndex); - // If the original format for device statistics is found in the database, update to new format - if (Convert.ToInt32(database.Connection.ExecuteScalar($"SELECT COUNT(*) FROM Measurement WHERE SignalReference='{oldSignalReference}' AND HistorianID={statHistorianID}")) > 0) - database.Connection.ExecuteNonQuery($"UPDATE Measurement SET SignalReference='{signalReference}' WHERE SignalReference='{oldSignalReference}' AND HistorianID={statHistorianID}"); + if (Convert.ToInt32(database.Connection.ExecuteScalar("SELECT COUNT(*) FROM Measurement WHERE SignalReference='{0}' AND HistorianID={1}", oldSignalReference, statHistorianID)) > 0) + database.Connection.ExecuteNonQuery("UPDATE Measurement SET SignalReference='{0}' " + + "WHERE SignalReference='{1}' AND HistorianID={2}", signalReference, oldSignalReference, statHistorianID); else if (!skipOptimization) break; } @@ -1543,7 +1544,7 @@ private static void PhasorDataSourceValidation(AdoDataConnection database, strin // Make sure devices associated with a concentrator do not have any extraneous input stream statistic measurements - this can happen // when a device was once a direct connect device but now is part of a concentrator... - foreach (DataRow inputStream in database.Connection.RetrieveData(database.AdapterType, $"SELECT * FROM Device WHERE (IsConcentrator = 0 AND ParentID IS NOT NULL) AND NodeID = {nodeIDQueryString} AND ProtocolID IN ({protocolIDs})").Rows) + foreach (DataRow inputStream in database.Connection.RetrieveData(database.AdapterType, "SELECT * FROM Device WHERE (IsConcentrator = 0 AND ParentID IS NOT NULL) AND NodeID = {0} AND ProtocolID IN ({1})", nodeIDQueryString, protocolIDs).Rows) { firstStatisticExisted = false; @@ -1556,7 +1557,7 @@ private static void PhasorDataSourceValidation(AdoDataConnection database, strin // To reduce time required to execute these steps, only first statistic is verified to exist if (!skipOptimization && !firstStatisticExisted) { - firstStatisticExisted = Convert.ToInt32(database.Connection.ExecuteScalar($"SELECT COUNT(*) FROM Measurement WHERE SignalReference='{signalReference}'")) > 0; + firstStatisticExisted = Convert.ToInt32(database.Connection.ExecuteScalar("SELECT COUNT(*) FROM Measurement WHERE SignalReference='{0}'", signalReference)) > 0; // If the first extraneous input statistic doesn't exist, we assume no others do as well if (!firstStatisticExisted) @@ -1564,7 +1565,7 @@ private static void PhasorDataSourceValidation(AdoDataConnection database, strin } // Remove extraneous input statistics - database.Connection.ExecuteNonQuery($"DELETE FROM Measurement WHERE SignalReference = '{signalReference}'"); + database.Connection.ExecuteNonQuery("DELETE FROM Measurement WHERE SignalReference = '{0}'", signalReference); } } } @@ -1574,7 +1575,7 @@ private static void PhasorDataSourceValidation(AdoDataConnection database, strin // Determine how many changes were made to output streams, devices, and measurements - // if no changes were made, we can skip the next few steps if (trackedTables.Contains("OutputStream") && trackedTables.Contains("OutputStreamDevice") && trackedTables.Contains("OutputStreamMeasurement") && trackedTables.Contains("Measurement")) - changes = Convert.ToUInt64(database.Connection.ExecuteScalar($"SELECT COUNT(*) FROM TrackedChange WHERE (TableName = 'OutputStream' OR TableName = 'OutputStreamDevice' OR TableName = 'OutputStreamMeasurement' OR TableName = 'Measurement') AND ID > {trackingVersion}")); + changes = Convert.ToUInt64(database.Connection.ExecuteScalar("SELECT COUNT(*) FROM TrackedChange WHERE (TableName = 'OutputStream' OR TableName = 'OutputStreamDevice' OR TableName = 'OutputStreamMeasurement' OR TableName = 'Measurement') AND ID > {0}", trackingVersion)); else changes = ulong.MaxValue; } @@ -1588,14 +1589,14 @@ private static void PhasorDataSourceValidation(AdoDataConnection database, strin statusMessage("Validating output stream measurements..."); // Make sure needed output stream statistic measurements exist - foreach (DataRow outputStream in database.Connection.RetrieveData(database.AdapterType, $"SELECT * FROM OutputStream WHERE NodeID = {nodeIDQueryString}").Rows) + foreach (DataRow outputStream in database.Connection.RetrieveData(database.AdapterType, "SELECT * FROM OutputStream WHERE NodeID = {0}", nodeIDQueryString).Rows) { adapterID = outputStream.ConvertField("ID"); // Load devices acronyms associated with this output stream List deviceAcronyms = database.Connection.RetrieveData(database.AdapterType, - $"SELECT Acronym FROM OutputStreamDevice WHERE AdapterID = {adapterID} AND NodeID = {nodeIDQueryString}") + "SELECT Acronym FROM OutputStreamDevice WHERE AdapterID = {0} AND NodeID = {1}", adapterID, nodeIDQueryString) .AsEnumerable() .Select(row => row.Field("Acronym")) .ToList(); @@ -1607,7 +1608,7 @@ private static void PhasorDataSourceValidation(AdoDataConnection database, strin deviceAcronyms.Sort(StringComparer.OrdinalIgnoreCase); // Validate measurements associated with this output stream - foreach (DataRow outputStreamMeasurement in database.Connection.RetrieveData(database.AdapterType, $"SELECT * FROM OutputStreamMeasurement WHERE AdapterID = {adapterID} AND NodeID = {nodeIDQueryString}").Rows) + foreach (DataRow outputStreamMeasurement in database.Connection.RetrieveData(database.AdapterType, "SELECT * FROM OutputStreamMeasurement WHERE AdapterID = {0} AND NodeID = {1}", adapterID, nodeIDQueryString).Rows) { // Parse output stream measurement signal reference deviceSignalReference = new SignalReference(outputStreamMeasurement.Field("SignalReference")); @@ -1635,7 +1636,7 @@ private static void PhasorDataSourceValidation(AdoDataConnection database, strin foreach (int measurementID in measurementIDsToDelete) { - database.Connection.ExecuteNonQuery($"DELETE FROM OutputStreamMeasurement WHERE ID = {measurementID} AND NodeID = {nodeIDQueryString}"); + database.Connection.ExecuteNonQuery("DELETE FROM OutputStreamMeasurement WHERE ID = {0} AND NodeID = {1}", measurementID, nodeIDQueryString); } } @@ -1656,7 +1657,7 @@ private static void PhasorDataSourceValidation(AdoDataConnection database, strin continue; int? vendorDeviceID = measurement.ConvertNullableField("VendorDeviceID"); - string vendor = vendorDeviceID.HasValue ? (string)database.Connection.ExecuteScalar("SELECT Acronym FROM Vendor WHERE ID = " + vendorDeviceID.Value) : null; + string vendor = vendorDeviceID.HasValue ? (string)database.Connection.ExecuteScalar("SELECT Acronym FROM Vendor WHERE ID = {0}", vendorDeviceID.Value) : null; string signalAcronym = measurement.ConvertField("SignalAcronym"); try @@ -1679,7 +1680,8 @@ private static void PhasorDataSourceValidation(AdoDataConnection database, strin if (string.IsNullOrWhiteSpace(label)) label = measurement.ConvertField("AlternateTag"); - database.Connection.ExecuteNonQuery($"UPDATE Measurement SET PointTag = '{CreatePointTag(company, device, vendor, signalAcronym, label, signalIndex, phase ?? '_', baseKV)}' WHERE SignalID = '{database.Guid(measurement, "SignalID")}'"); + database.Connection.ExecuteNonQuery("UPDATE Measurement SET PointTag = '{0}' WHERE SignalID = '{1}'", + CreatePointTag(company, device, vendor, signalAcronym, label, signalIndex, phase ?? '_', baseKV), database.Guid(measurement, "SignalID")); } } @@ -1709,7 +1711,7 @@ private static void CreateDefaultNode(AdoDataConnection database, string nodeIDQ { statusMessage("Creating default record for Node..."); database.Connection.ExecuteNonQuery("INSERT INTO Node(Name, CompanyID, Description, Settings, MenuType, MenuData, Master, LoadOrder, Enabled) VALUES('Default', NULL, 'Default node', 'RemoteStatusServerConnectionString={server=localhost:8500;integratedSecurity=true};datapublisherport=6165;AlarmServiceUrl=http://localhost:5018/alarmservices', 'File', 'Menu.xml', 1, 0, 1)"); - database.Connection.ExecuteNonQuery("UPDATE Node SET ID=" + nodeIDQueryString); + database.Connection.ExecuteNonQuery("UPDATE Node SET ID={0}", nodeIDQueryString); } } diff --git a/Source/Libraries/Adapters/PowerCalculations/PowerMultiCalculator/PowerCalculationConfigurationValidation.cs b/Source/Libraries/Adapters/PowerCalculations/PowerMultiCalculator/PowerCalculationConfigurationValidation.cs index 3da88cd47d6..6629994509b 100644 --- a/Source/Libraries/Adapters/PowerCalculations/PowerMultiCalculator/PowerCalculationConfigurationValidation.cs +++ b/Source/Libraries/Adapters/PowerCalculations/PowerMultiCalculator/PowerCalculationConfigurationValidation.cs @@ -56,14 +56,15 @@ public static void ValidateDatabaseDefinitions() /// Database connection to use for checking the data operation /// True or false indicating whether the operation exists private static bool DataOperationExists(AdoDataConnection database) => - Convert.ToInt32(database.ExecuteScalar($"SELECT COUNT(*) FROM DataOperation WHERE TypeName='{typeof(PowerCalculationConfigurationValidation).FullName}' AND MethodName='ValidatePowerCalculationConfigurations'")) > 0; + Convert.ToInt32(database.ExecuteScalar("SELECT COUNT(*) FROM DataOperation WHERE TypeName = {0} AND MethodName='ValidatePowerCalculationConfigurations'", typeof(PowerCalculationConfigurationValidation).FullName)) > 0; /// /// Creates a data operation to run the validations in this class. /// /// Database connection to use for creating the data operation private static void CreateDataOperation(AdoDataConnection database) => - database.ExecuteNonQuery($"INSERT INTO DataOperation(Description, AssemblyName, TypeName, MethodName, Enabled) VALUES ('Power Calculation Validations', 'PowerCalculations.dll', '{typeof(PowerCalculationConfigurationValidation).FullName}', 'ValidatePowerCalculationConfigurations', 1)"); + database.ExecuteNonQuery("INSERT INTO DataOperation(Description, AssemblyName, TypeName, MethodName, Enabled) " + + "VALUES ('Power Calculation Validations', 'PowerCalculations.dll', {0}, 'ValidatePowerCalculationConfigurations', 1)", typeof(PowerCalculationConfigurationValidation).FullName); /// /// Returns true if a data operation exists to run this class. Returns false otherwise. @@ -71,14 +72,16 @@ private static void CreateDataOperation(AdoDataConnection database) => /// Database connection to use for checking the data operation /// True or false indicating whether the operation exists private static bool AdapterInstanceExists(AdoDataConnection database) => - Convert.ToInt32(database.ExecuteScalar($"SELECT COUNT(*) FROM CustomActionAdapter WHERE TypeName='{typeof(PowerMultiCalculatorAdapter).FullName}'")) > 0; + Convert.ToInt32(database.ExecuteScalar("SELECT COUNT(*) FROM CustomActionAdapter WHERE TypeName = {0}", typeof(PowerMultiCalculatorAdapter).FullName)) > 0; /// /// Creates a data operation to run the validations in this class. /// /// Database connection to use for creating the data operation private static void CreateAdapterInstance(AdoDataConnection database) => - database.ExecuteNonQuery($"INSERT INTO CustomActionAdapter(NodeID, AdapterName, AssemblyName, TypeName, ConnectionString, Enabled) VALUES ('{ConfigurationFile.Current.Settings["systemSettings"]["NodeID"].ValueAs()}', 'PHASOR!POWERCALC', 'PowerCalculations.dll', '{typeof(PowerMultiCalculatorAdapter).FullName}', 'FramesPerSecond=30; LagTime=5.0; LeadTime=3.0', 1)"); + database.ExecuteNonQuery("INSERT INTO CustomActionAdapter(NodeID, AdapterName, AssemblyName, TypeName, ConnectionString, Enabled) " + + "VALUES ({0}, 'PHASOR!POWERCALC', 'PowerCalculations.dll', {1}, 'FramesPerSecond=30; LagTime=5.0; LeadTime=3.0', 1)", + ConfigurationFile.Current.Settings["systemSettings"]["NodeID"].ValueAs(), typeof(PowerMultiCalculatorAdapter).FullName); /// /// Data operation to validate power calculation configuration. This method checks that input measurements and non-null output measurements exist, are enabled, and have the correct signal type. diff --git a/Source/Libraries/Adapters/PowerCalculations/PowerMultiCalculator/PowerMultiCalculatorAdapter.cs b/Source/Libraries/Adapters/PowerCalculations/PowerMultiCalculator/PowerMultiCalculatorAdapter.cs index 0c7b9d7552c..8e76a717bed 100644 --- a/Source/Libraries/Adapters/PowerCalculations/PowerMultiCalculator/PowerMultiCalculatorAdapter.cs +++ b/Source/Libraries/Adapters/PowerCalculations/PowerMultiCalculator/PowerMultiCalculatorAdapter.cs @@ -268,13 +268,11 @@ public override void Initialize() if (Settings.TryGetValue(nameof(TableName), out string tableName)) TableName = tableName; - - // 0 1 2 3 4 5 + // 0 1 2 3 4 5 string query = "SELECT ID, CircuitDescription, VoltageAngleSignalID, VoltageMagSignalID, CurrentAngleSignalID, CurrentMagSignalID, " + // 6 7 8 "ActivePowerOutputSignalID, ReactivePowerOutputSignalID, ApparentPowerOutputSignalID " + $"FROM {TableName} WHERE NodeId = {{0}} AND Enabled <> 0"; - using (AdoDataConnection database = new("systemSettings")) using (IDataReader reader = database.ExecuteReader(query, ConfigurationFile.Current.Settings["systemSettings"]["NodeID"].ValueAs())) { diff --git a/Source/Libraries/Adapters/eDNAAdapters/OutputAdapter.cs b/Source/Libraries/Adapters/eDNAAdapters/OutputAdapter.cs index 674072056de..222a81cad3a 100644 --- a/Source/Libraries/Adapters/eDNAAdapters/OutputAdapter.cs +++ b/Source/Libraries/Adapters/eDNAAdapters/OutputAdapter.cs @@ -848,7 +848,7 @@ protected override void ExecuteMetadataRefresh() if ((object)database == null) database = new AdoDataConnection("systemSettings"); - updateTime = Convert.ToDateTime(database.Connection.ExecuteScalar($"SELECT UpdatedOn FROM Measurement WHERE SignalID = '{signalID}'")); + updateTime = Convert.ToDateTime(database.Connection.ExecuteScalar("SELECT UpdatedOn FROM Measurement WHERE SignalID = {0}", signalID)); } } catch (Exception) diff --git a/Source/Libraries/GSF.Core/Data/DataDeleter.cs b/Source/Libraries/GSF.Core/Data/DataDeleter.cs index 5cd76211560..1a2eb8aec40 100644 --- a/Source/Libraries/GSF.Core/Data/DataDeleter.cs +++ b/Source/Libraries/GSF.Core/Data/DataDeleter.cs @@ -232,7 +232,9 @@ private void ExecuteDeletes(Table fromTable, Table toTable) OnOverallProgress((int)m_overallProgress, (int)m_overallTotal); // Execute source query - using (IDataReader fromReader = fromTable.Connection.ExecuteReader("SELECT " + fieldCollection.GetList(sqlEscapeFunction: fromTable.Parent.Parent.SQLEscapeName) + " FROM " + fromTable.SQLEscapedName, CommandBehavior.SequentialAccess, Timeout)) + using (IDataReader fromReader = fromTable.Connection.ExecuteReader( + "SELECT " + fieldCollection.GetList(sqlEscapeFunction: fromTable.Parent.Parent.SQLEscapeName) + + " FROM " + fromTable.SQLEscapedName, CommandBehavior.SequentialAccess, Timeout)) { // Create Sql delete stub deleteSQLStub = "DELETE FROM " + toTable.SQLEscapedName; diff --git a/Source/Libraries/GSF.Core/Data/DataInserter.cs b/Source/Libraries/GSF.Core/Data/DataInserter.cs index 2b41a2f80c2..ff671270c90 100644 --- a/Source/Libraries/GSF.Core/Data/DataInserter.cs +++ b/Source/Libraries/GSF.Core/Data/DataInserter.cs @@ -413,15 +413,12 @@ private bool ClearTable(Table table) useTruncateTable = m_forceTruncateTable || (table.Parent.Parent.DataSourceType == DatabaseType.SQLServer && !table.ReferencedByForeignKeys); } - if (useTruncateTable) - deleteSql = "TRUNCATE TABLE " + table.SQLEscapedName; - else - deleteSql = "DELETE FROM " + table.SQLEscapedName; - try { - table.Connection.ExecuteNonQuery(deleteSql, Timeout); - + if (useTruncateTable) + table.Connection.ExecuteNonQuery("TRUNCATE TABLE " + table.SQLEscapedName, Timeout); + else + table.Connection.ExecuteNonQuery("DELETE FROM " + table.SQLEscapedName, Timeout); if ((object)TableCleared != null) TableCleared(this, new EventArgs(table.Name)); //-V3083 @@ -437,7 +434,8 @@ private bool ClearTable(Table table) return ClearTable(table); } - OnSQLFailure(deleteSql, ex); + if (useTruncateTable) OnSQLFailure("TRUNCATE TABLE " + table.SQLEscapedName, ex); + else OnSQLFailure("DELETE FROM " + table.SQLEscapedName, ex); } return false; @@ -616,7 +614,7 @@ private void ExecuteInserts(Table fromTable, Table toTable) case DatabaseType.SQLServer: try { - toTable.Connection.ExecuteNonQuery("SET IDENTITY_INSERT " + toTable.SQLEscapedName + " ON", Timeout); + toTable.Connection.ExecuteNonQuery($"SET IDENTITY_INSERT {toTable.SQLEscapedName} ON", Timeout); usingIdentityInsert = true; } catch @@ -677,7 +675,7 @@ private void ExecuteInserts(Table fromTable, Table toTable) try { // Turn off identity inserts - toTable.Connection.ExecuteNonQuery(setIndentityInsertSQL, Timeout); + toTable.Connection.ExecuteNonQuery($"SET IDENTITY_INSERT {toTable.SQLEscapedName} OFF", Timeout); } catch (Exception ex) { @@ -822,7 +820,7 @@ private void InsertDestinationRecord(Table toTable, Fields fieldCollection, stri // Added check to preserve ID number for auto-inc fields if (!usingIdentityInsert && !skipKeyValuePreservation && m_preserveAutoIncValues && (object)autoIncField != null) { - int toTableRowCount = int.Parse(Common.ToNonNullString(toTable.Connection.ExecuteScalar("SELECT MAX(" + autoIncField.SQLEscapedName + ") FROM " + toTable.SQLEscapedName, Timeout), "0")) + 1; + int toTableRowCount = int.Parse(Common.ToNonNullString(toTable.Connection.ExecuteScalar($"SELECT MAX({autoIncField.SQLEscapedName}) FROM {toTable.SQLEscapedName}", Timeout), "0")) + 1; int sourceTablePrimaryFieldValue = int.Parse(Common.ToNonNullString(autoIncField.Value, "0")); int synchronizations = 0; @@ -833,7 +831,7 @@ private void InsertDestinationRecord(Table toTable, Fields fieldCollection, stri int currentIdentityValue = int.Parse(Common.ToNonNullString(toTable.Connection.ExecuteScalar(toTable.IdentitySQL, Timeout), "0")); // Delete record which was just inserted - toTable.Connection.ExecuteNonQuery("DELETE FROM " + toTable.SQLEscapedName + " WHERE " + autoIncField.SQLEscapedName + " = " + currentIdentityValue, Timeout); + toTable.Connection.ExecuteNonQuery($"DELETE FROM {toTable.SQLEscapedName} WHERE {autoIncField.SQLEscapedName} = {{0}}", currentIdentityValue, Timeout); // For very long spans of auto-inc identity gaps we at least provide some level of feedback if (synchronizations++ % 50 == 0) diff --git a/Source/Libraries/GSF.Core/Data/DataUpdater.cs b/Source/Libraries/GSF.Core/Data/DataUpdater.cs index e4e38df6119..37c76e143a2 100644 --- a/Source/Libraries/GSF.Core/Data/DataUpdater.cs +++ b/Source/Libraries/GSF.Core/Data/DataUpdater.cs @@ -233,7 +233,9 @@ private void ExecuteUpdates(Table fromTable, Table toTable) OnOverallProgress((int)m_overallProgress, (int)m_overallTotal); // Execute source query - using (IDataReader fromReader = fromTable.Connection.ExecuteReader("SELECT " + fieldsCollection.GetList(sqlEscapeFunction: fromTable.Parent.Parent.SQLEscapeName) + " FROM " + fromTable.SQLEscapedName, CommandBehavior.SequentialAccess, Timeout)) + using (IDataReader fromReader = fromTable.Connection.ExecuteReader("SELECT " + + $"{fieldsCollection.GetList(sqlEscapeFunction: fromTable.Parent.Parent.SQLEscapeName)} " + + $"FROM {fromTable.SQLEscapedName}", CommandBehavior.SequentialAccess, Timeout)) { // Create Sql update stub updateSQLStub = "UPDATE " + toTable.SQLEscapedName + " SET "; diff --git a/Source/Libraries/GSF.Core/ErrorManagement/ErrorLogger.cs b/Source/Libraries/GSF.Core/ErrorManagement/ErrorLogger.cs index 157c435e4ec..2282f4d4399 100644 --- a/Source/Libraries/GSF.Core/ErrorManagement/ErrorLogger.cs +++ b/Source/Libraries/GSF.Core/ErrorManagement/ErrorLogger.cs @@ -1544,8 +1544,8 @@ private void m_tableSizeCurtailmentTimer_Elapsed(object sender, System.Timers.El command.Transaction = transaction; // Get min and max IDs from error log - int minID = Convert.ToInt32(command.ExecuteScalar(string.Format("SELECT MIN(ID) FROM ErrorLog"))); - int maxID = Convert.ToInt32(command.ExecuteScalar(string.Format("SELECT MAX(ID) FROM ErrorLog"))); + int minID = Convert.ToInt32(command.ExecuteScalar("SELECT MIN(ID) FROM ErrorLog")); + int maxID = Convert.ToInt32(command.ExecuteScalar("SELECT MAX(ID) FROM ErrorLog")); int errorLogSize = maxID - minID; // Roughly, assuming no manual deletions // When exception log is larger than desired size - delete roughly 25% of the records, diff --git a/Source/Libraries/GSF.PhasorProtocols/UI/DataModels/CalculatedMeasurement.cs b/Source/Libraries/GSF.PhasorProtocols/UI/DataModels/CalculatedMeasurement.cs index 401ec96a778..b062ce226ca 100755 --- a/Source/Libraries/GSF.PhasorProtocols/UI/DataModels/CalculatedMeasurement.cs +++ b/Source/Libraries/GSF.PhasorProtocols/UI/DataModels/CalculatedMeasurement.cs @@ -490,7 +490,7 @@ public static IList LoadKeys(AdoDataConnection database, string sortMember if (!string.IsNullOrEmpty(sortMember)) sortClause = $"ORDER BY {sortMember} {sortDirection}"; - DataTable calculatedMeasurementTable = database.Connection.RetrieveData(database.AdapterType, $"SELECT ID From CalculatedMeasurementDetail {sortClause}"); + DataTable calculatedMeasurementTable = database.Connection.RetrieveData(database.AdapterType, "SELECT ID From CalculatedMeasurementDetail " + sortClause); foreach (DataRow row in calculatedMeasurementTable.Rows) { @@ -531,12 +531,11 @@ public static ObservableCollection Load(AdoDataConnection { commaSeparatedKeys = keys.Select(key => key.ToString()).Aggregate((str1, str2) => $"{str1},{str2}"); - query = string.Format("SELECT NodeID, ID, Acronym, Name, AssemblyName, " + + query = database.ParameterizedQueryString("SELECT NodeID, ID, Acronym, Name, AssemblyName, " + "TypeName, ConnectionString, ConfigSection, InputMeasurements, OutputMeasurements, MinimumMeasurementsToUse, FramesPerSecond, LagTime, " + "LeadTime, UseLocalClockAsRealTime, AllowSortsByArrival, LoadOrder, Enabled, IgnoreBadTimeStamps, TimeResolution, AllowPreemptivePublishing, " + - "DownSamplingMethod, NodeName, PerformTimeReasonabilityCheck From CalculatedMeasurementDetail WHERE ID IN ({0}) AND NodeID = '{1}'", commaSeparatedKeys, database.CurrentNodeID()); - - calculatedMeasurementTable = database.Connection.RetrieveData(database.AdapterType, query); + "DownSamplingMethod, NodeName, PerformTimeReasonabilityCheck From CalculatedMeasurementDetail WHERE ID IN ({0}) AND NodeID = {1}", "commaSeparatedKeys", "database.CurrentNodeID()"); + calculatedMeasurementTable = database.Connection.RetrieveData(database.AdapterType, query, commaSeparatedKeys, database.CurrentNodeID()); calculatedMeasurementList = new CalculatedMeasurement[calculatedMeasurementTable.Rows.Count]; foreach (DataRow row in calculatedMeasurementTable.Rows) diff --git a/Source/Libraries/GSF.PhasorProtocols/UI/DataModels/Device.cs b/Source/Libraries/GSF.PhasorProtocols/UI/DataModels/Device.cs index bb42125cb69..7d6f384b599 100755 --- a/Source/Libraries/GSF.PhasorProtocols/UI/DataModels/Device.cs +++ b/Source/Libraries/GSF.PhasorProtocols/UI/DataModels/Device.cs @@ -1452,7 +1452,7 @@ public static Device GetDevice(AdoDataConnection database, string whereClause) try { createdConnection = CreateConnection(ref database); - DataTable deviceTable = database.Connection.RetrieveData(database.AdapterType, $"SELECT * FROM DeviceDetail {whereClause}"); + DataTable deviceTable = database.Connection.RetrieveData(database.AdapterType, "SELECT * FROM DeviceDetail " + whereClause); if (deviceTable.Rows.Count == 0) return null; @@ -1537,7 +1537,7 @@ public static ObservableCollection GetDevices(AdoDataConnection database try { createdConnection = CreateConnection(ref database); - DataTable deviceTable = database.Connection.RetrieveData(database.AdapterType, $"SELECT * FROM DeviceDetail {whereClause}"); + DataTable deviceTable = database.Connection.RetrieveData(database.AdapterType, "SELECT * FROM DeviceDetail " + whereClause); ObservableCollection deviceList = new(); if (deviceTable.Rows.Count == 0) @@ -1696,7 +1696,8 @@ public static ObservableCollection GetNewDevicesForOutputStream(AdoDataC // Note that OleDB does not support parameterized sub-query. if (database.DatabaseType == DatabaseType.Access) { - query = database.ParameterizedQueryString($"SELECT * FROM DeviceDetail WHERE NodeID = {{0}} AND IsConcentrator = {{1}} AND Acronym NOT IN (SELECT Acronym FROM OutputStreamDevice WHERE AdapterID = {outputStreamID}) ORDER BY Acronym", "nodeID", "isConcentrator"); + query = database.ParameterizedQueryString($"SELECT * FROM DeviceDetail WHERE NodeID = {{0}} AND IsConcentrator = {{1}} " + + $"AND Acronym NOT IN (SELECT Acronym FROM OutputStreamDevice WHERE AdapterID = {outputStreamID}) ORDER BY Acronym", "nodeID", "isConcentrator"); deviceTable = database.Connection.RetrieveData(database.AdapterType, query, DefaultTimeout, database.CurrentNodeID(), database.Bool(false)); } diff --git a/Source/Libraries/GSF.PhasorProtocols/UI/DataModels/OutputStream.cs b/Source/Libraries/GSF.PhasorProtocols/UI/DataModels/OutputStream.cs index f3ecadf6e7c..5d914c998ca 100644 --- a/Source/Libraries/GSF.PhasorProtocols/UI/DataModels/OutputStream.cs +++ b/Source/Libraries/GSF.PhasorProtocols/UI/DataModels/OutputStream.cs @@ -1057,7 +1057,7 @@ public static string Save(AdoDataConnection database, OutputStream outputStream, if (qualityType is not null) { - IList keys = database.Connection.RetrieveData(database.AdapterType, $"SELECT ID FROM OutputStreamMeasurement WHERE AdapterID = {outputStream.ID}") + IList keys = database.Connection.RetrieveData(database.AdapterType, "SELECT ID FROM OutputStreamMeasurement WHERE AdapterID = {0}", outputStream.ID) .Select().Select(row => row.ConvertField("ID")).ToList(); foreach (OutputStreamMeasurement measurement in OutputStreamMeasurement.Load(database, keys)) diff --git a/Source/Libraries/GSF.PhasorProtocols/UI/DataModels/OutputStreamDevice.cs b/Source/Libraries/GSF.PhasorProtocols/UI/DataModels/OutputStreamDevice.cs index 17afc563b53..f6e5c95d93c 100755 --- a/Source/Libraries/GSF.PhasorProtocols/UI/DataModels/OutputStreamDevice.cs +++ b/Source/Libraries/GSF.PhasorProtocols/UI/DataModels/OutputStreamDevice.cs @@ -359,10 +359,12 @@ public static ObservableCollection Load(AdoDataConnection da { string commaSeparatedKeys = keys.Select(key => key.ToString()).Aggregate((str1, str2) => $"{str1},{str2}"); - string query = $"SELECT NodeID, AdapterID, ID, IDCode, Acronym, BpaAcronym, Name, PhasorDataFormat, FrequencyDataFormat, AnalogDataFormat, CoordinateFormat, LoadOrder, Enabled, Virtual FROM OutputStreamDeviceDetail WHERE ID IN ({commaSeparatedKeys})"; + string query = "SELECT NodeID, AdapterID, ID, IDCode, Acronym, BpaAcronym, Name, PhasorDataFormat, FrequencyDataFormat, AnalogDataFormat, " + + $"CoordinateFormat, LoadOrder, Enabled, Virtual FROM OutputStreamDeviceDetail WHERE ID IN ({commaSeparatedKeys})"; if (database.IsMySQL) - query = $"SELECT NodeID, AdapterID, ID, IDCode, Acronym, BpaAcronym, Name, PhasorDataFormat, FrequencyDataFormat, AnalogDataFormat, CoordinateFormat, LoadOrder, Enabled, `Virtual` FROM OutputStreamDeviceDetail WHERE ID IN ({commaSeparatedKeys})"; + query = $"SELECT NodeID, AdapterID, ID, IDCode, Acronym, BpaAcronym, Name, PhasorDataFormat, FrequencyDataFormat, AnalogDataFormat, " + + $"CoordinateFormat, LoadOrder, Enabled, `Virtual` FROM OutputStreamDeviceDetail WHERE ID IN ({commaSeparatedKeys})"; DataTable outputStreamDeviceTable = database.Connection.RetrieveData(database.AdapterType, query, DefaultTimeout); outputStreamDeviceList = new OutputStreamDevice[outputStreamDeviceTable.Rows.Count]; diff --git a/Source/Libraries/GSF.PhasorProtocols/UI/DataModels/OutputStreamDeviceDigital.cs b/Source/Libraries/GSF.PhasorProtocols/UI/DataModels/OutputStreamDeviceDigital.cs index 632a1798d76..87e794c8385 100755 --- a/Source/Libraries/GSF.PhasorProtocols/UI/DataModels/OutputStreamDeviceDigital.cs +++ b/Source/Libraries/GSF.PhasorProtocols/UI/DataModels/OutputStreamDeviceDigital.cs @@ -272,9 +272,10 @@ public static ObservableCollection Load(AdoDataConnec if (keys is not null && keys.Count > 0) { commaSeparatedKeys = keys.Select(key => $"{key}").Aggregate((str1, str2) => $"{str1},{str2}"); - query = database.ParameterizedQueryString($"SELECT NodeID, OutputStreamDeviceID, ID, Label, MaskValue, LoadOrder FROM OutputStreamDeviceDigital WHERE ID IN ({commaSeparatedKeys})"); - outputStreamDeviceDigitalTable = database.Connection.RetrieveData(database.AdapterType, query, DefaultTimeout); + outputStreamDeviceDigitalTable = database.Connection.RetrieveData(database.AdapterType, + "SELECT NodeID, OutputStreamDeviceID, ID, Label, MaskValue, LoadOrder FROM OutputStreamDeviceDigital " + + $"WHERE ID IN ({commaSeparatedKeys})", DefaultTimeout); outputStreamDeviceDigitalList = new OutputStreamDeviceDigital[outputStreamDeviceDigitalTable.Rows.Count]; foreach (DataRow row in outputStreamDeviceDigitalTable.Rows) diff --git a/Source/Libraries/GSF.PhasorProtocols/UI/DataModels/OutputStreamDevicePhasor.cs b/Source/Libraries/GSF.PhasorProtocols/UI/DataModels/OutputStreamDevicePhasor.cs index 517759bf983..aeae0d828c1 100755 --- a/Source/Libraries/GSF.PhasorProtocols/UI/DataModels/OutputStreamDevicePhasor.cs +++ b/Source/Libraries/GSF.PhasorProtocols/UI/DataModels/OutputStreamDevicePhasor.cs @@ -243,7 +243,8 @@ public static IList LoadKeys(AdoDataConnection database, int outputStreamDe if (!string.IsNullOrEmpty(sortMember)) sortClause = $"ORDER BY {sortMember} {sortDirection}"; - DataTable OutputStreamDevicePhasorTable = database.Connection.RetrieveData(database.AdapterType, $"SELECT ID FROM OutputStreamDevicePhasor WHERE OutputStreamDeviceID = {outputStreamDeviceID} {sortClause}"); + DataTable OutputStreamDevicePhasorTable = database.Connection.RetrieveData(database.AdapterType, + $"SELECT ID FROM OutputStreamDevicePhasor WHERE OutputStreamDeviceID = {{0}} {sortClause}", outputStreamDeviceID); foreach (DataRow row in OutputStreamDevicePhasorTable.Rows) outputStreamDevicePhasorList.Add((row.ConvertField("ID"))); @@ -276,9 +277,8 @@ public static ObservableCollection Load(AdoDataConnect if (keys is not null && keys.Count > 0) { string commaSeparatedKeys = keys.Select(key => $"{key}").Aggregate((str1, str2) => $"{str1},{str2}"); - string query = database.ParameterizedQueryString($"SELECT NodeID, OutputStreamDeviceID, ID, Label, Type, Phase, ScalingValue, LoadOrder FROM OutputStreamDevicePhasor WHERE ID IN ({commaSeparatedKeys})"); - DataTable outputStreamDevicePhasorTable = database.Connection.RetrieveData(database.AdapterType, query); + DataTable outputStreamDevicePhasorTable = database.Connection.RetrieveData(database.AdapterType, "SELECT NodeID, OutputStreamDeviceID, ID, Label, Type, Phase, ScalingValue, LoadOrder FROM OutputStreamDevicePhasor WHERE ID IN ({0})", commaSeparatedKeys); outputStreamDevicePhasorList = new OutputStreamDevicePhasor[outputStreamDevicePhasorTable.Rows.Count]; foreach (DataRow row in outputStreamDevicePhasorTable.Rows) @@ -524,8 +524,8 @@ private static void GetDeleteMeasurementDetails(AdoDataConnection database, int { const string outputPhasorFormat = "SELECT Label, OutputStreamDeviceID FROM OutputStreamDevicePhasor WHERE ID = {0}"; const string outputDeviceFormat = "SELECT Acronym, AdapterID FROM OutputStreamDevice WHERE ID = {0}"; - const string measurementDetailFormat = "SELECT PointTag FROM MeasurementDetail WHERE DeviceAcronym = '{0}' AND PhasorLabel = '{1}' AND SignalTypeSuffix = '{2}'"; - const string outputMeasurementDetailFormat = "SELECT SignalReference FROM OutputStreamMeasurementDetail WHERE SourcePointTag = '{0}'"; + const string measurementDetailFormat = "SELECT PointTag FROM MeasurementDetail WHERE DeviceAcronym = {0} AND PhasorLabel = {1} AND SignalTypeSuffix = {2}"; + const string outputMeasurementDetailFormat = "SELECT SignalReference FROM OutputStreamMeasurementDetail WHERE SourcePointTag = {0}"; bool createdConnection = false; @@ -541,11 +541,11 @@ private static void GetDeleteMeasurementDetails(AdoDataConnection database, int string deviceName = outputDeviceRecord.Field("Acronym"); adapterID = outputDeviceRecord.ConvertField("AdapterID"); - string anglePointTag = database.Connection.ExecuteScalar(string.Format(measurementDetailFormat, deviceName, labelName, "PA")).ToNonNullString(); - angleSignalReference = database.Connection.ExecuteScalar(string.Format(outputMeasurementDetailFormat, anglePointTag)).ToNonNullString(); + string anglePointTag = database.Connection.ExecuteScalar(measurementDetailFormat, deviceName, labelName, "PA").ToNonNullString(); + angleSignalReference = database.Connection.ExecuteScalar(outputMeasurementDetailFormat, anglePointTag).ToNonNullString(); - string magnitudePointTag = database.Connection.ExecuteScalar(string.Format(measurementDetailFormat, deviceName, labelName, "PM")).ToNonNullString(); - magnitudeSignalReference = database.Connection.ExecuteScalar(string.Format(outputMeasurementDetailFormat, magnitudePointTag)).ToNonNullString(); + string magnitudePointTag = database.Connection.ExecuteScalar(measurementDetailFormat, deviceName, labelName, "PM").ToNonNullString(); + magnitudeSignalReference = database.Connection.ExecuteScalar(outputMeasurementDetailFormat, magnitudePointTag).ToNonNullString(); } catch (Exception ex) { diff --git a/Source/Libraries/GSF.PhasorProtocols/UI/DataModels/OutputStreamMeasurement.cs b/Source/Libraries/GSF.PhasorProtocols/UI/DataModels/OutputStreamMeasurement.cs index c2620bd3e4f..ef1b31c1801 100755 --- a/Source/Libraries/GSF.PhasorProtocols/UI/DataModels/OutputStreamMeasurement.cs +++ b/Source/Libraries/GSF.PhasorProtocols/UI/DataModels/OutputStreamMeasurement.cs @@ -261,9 +261,10 @@ public static ObservableCollection Load(AdoDataConnecti if (keys is not null && keys.Count > 0) { commaSeparatedKeys = keys.Select(key => $"{key}").Aggregate((str1, str2) => $"{str1},{str2}"); - query = $"SELECT NodeID, AdapterID, ID, HistorianID, PointID, SignalReference, SourcePointTag, HistorianAcronym FROM OutputStreamMeasurementDetail WHERE ID IN ({commaSeparatedKeys})"; - outputStreamMeasurementTable = database.Connection.RetrieveData(database.AdapterType, query, DefaultTimeout); + outputStreamMeasurementTable = database.Connection.RetrieveData(database.AdapterType, + "SELECT NodeID, AdapterID, ID, HistorianID, PointID, SignalReference, SourcePointTag, HistorianAcronym " + + $"FROM OutputStreamMeasurementDetail WHERE ID IN ({commaSeparatedKeys})", DefaultTimeout); outputStreamMeasurementList = new OutputStreamMeasurement[outputStreamMeasurementTable.Rows.Count]; foreach (DataRow row in outputStreamMeasurementTable.Rows) diff --git a/Source/Libraries/GSF.TimeSeries/Configuration/DatabaseConfigurationLoader.cs b/Source/Libraries/GSF.TimeSeries/Configuration/DatabaseConfigurationLoader.cs index 7dcca5e97d5..c93669f9ef6 100755 --- a/Source/Libraries/GSF.TimeSeries/Configuration/DatabaseConfigurationLoader.cs +++ b/Source/Libraries/GSF.TimeSeries/Configuration/DatabaseConfigurationLoader.cs @@ -330,7 +330,7 @@ public override void Augment(DataSet configuration) try { - database.Connection.ExecuteNonQuery($"DELETE FROM TrackedChange WHERE ID <= {latestVersion}"); + database.Connection.ExecuteNonQuery("DELETE FROM TrackedChange WHERE ID <= {0}", latestVersion); } catch (Exception ex) { @@ -365,7 +365,8 @@ private void ExecuteDataOperations(ulong trackingVersion = ulong.MinValue) { string assemblyName = "", typeName = "", methodName = ""; - foreach (DataRow row in database.Connection.RetrieveData(database.AdapterType, $"SELECT * FROM DataOperation WHERE (NodeID IS NULL OR NodeID={NodeIDQueryString}) AND Enabled <> 0 ORDER BY LoadOrder").Rows) + foreach (DataRow row in database.Connection.RetrieveData(database.AdapterType, + "SELECT * FROM DataOperation WHERE (NodeID IS NULL OR NodeID={0}) AND Enabled <> 0 ORDER BY LoadOrder", NodeIDQueryString).Rows) { try { @@ -410,7 +411,7 @@ private DataTable LoadTable(DataRow entityRow) { // Load configuration entity data filtered by node ID Ticks operationStartTime = DateTime.UtcNow.Ticks; - DataTable source = database.Connection.RetrieveData(database.AdapterType, $"SELECT * FROM {entityRow["SourceName"]} WHERE NodeID={NodeIDQueryString}"); + DataTable source = database.Connection.RetrieveData(database.AdapterType, $"SELECT * FROM {entityRow["SourceName"]} WHERE NodeID={{1}}", NodeIDQueryString); Time operationElapsedTime = (DateTime.UtcNow.Ticks - operationStartTime).ToSeconds(); // Update table name as defined in configuration entity @@ -491,8 +492,7 @@ private ulong GetLatestVersion(ulong currentVersion) { try { - string query = $"SELECT CASE WHEN COUNT(ID) = 0 THEN {currentVersion} ELSE MAX(ID) END FROM TrackedChange"; - version = Convert.ToUInt64(database.Connection.ExecuteScalar(query)); + version = Convert.ToUInt64(database.Connection.ExecuteScalar($"SELECT CASE WHEN COUNT(ID) = 0 THEN {currentVersion} ELSE MAX(ID) END FROM TrackedChange")); } catch { @@ -511,8 +511,7 @@ private bool TrackedChangesAreValid(ulong currentVersion) { try { - string query = $"SELECT COUNT(ID) FROM TrackedChange WHERE ID < {currentVersion}"; - changesAreValid = Convert.ToInt32(database.Connection.ExecuteScalar(query)) == 0; + changesAreValid = Convert.ToInt32(database.Connection.ExecuteScalar($"SELECT COUNT(ID) FROM TrackedChange WHERE ID < {currentVersion}")) == 0; } catch { @@ -536,8 +535,8 @@ private DataTable GetChangedRecords(string tableName, string primaryKeyColumn, u Execute(database => { - string query = $"SELECT * FROM {tableName} WHERE {primaryKeyColumn} IN (SELECT PrimaryKeyValue FROM TrackedChange WHERE TableName = '{tableName}' AND ID > {currentVersion}) AND NodeID = {NodeIDQueryString}"; - changes = database.Connection.RetrieveData(database.AdapterType, query); + changes = database.Connection.RetrieveData(database.AdapterType, $"SELECT * FROM {tableName} WHERE {primaryKeyColumn} IN " + + $"(SELECT PrimaryKeyValue FROM TrackedChange WHERE TableName = {tableName} AND ID > {currentVersion}) AND NodeID = {NodeIDQueryString}",); }); return changes; diff --git a/Source/Libraries/GSF.TimeSeries/Statistics/StatisticsEngine.cs b/Source/Libraries/GSF.TimeSeries/Statistics/StatisticsEngine.cs index 722bc0ae884..66e511c698e 100755 --- a/Source/Libraries/GSF.TimeSeries/Statistics/StatisticsEngine.cs +++ b/Source/Libraries/GSF.TimeSeries/Statistics/StatisticsEngine.cs @@ -665,7 +665,8 @@ private void UpdateStatisticMeasurements() // Get the statistic measurements from the database which have already been defined for this source string args = string.Join(",", signalReferences.Select((_, index) => $"{{{index}}}")); - List statisticMeasurements = helper.RetrieveData(string.Format(StatisticMeasurementSelectFormat, args), signalReferences.ToArray()).Select().ToList(); + string sql = database.ParameterizedQueryString(StatisticMeasurementSelectFormat, "args"); + List statisticMeasurements = helper.RetrieveData(sql, args, signalReferences.ToArray()).Select().ToList(); // If the number of statistics for the source category matches // the number of statistic measurements for the source, assume @@ -995,7 +996,7 @@ private string GetSystemName() using AdoDataConnection database = new("systemSettings"); - return database.Connection.ExecuteScalar($"SELECT Name FROM Node WHERE ID = '{database.Guid(GetNodeID())}'").ToNonNullString().ToUpper(); + return database.Connection.ExecuteScalar("SELECT Name FROM Node WHERE ID = '{0}'", database.Guid(GetNodeID())).ToNonNullString().ToUpper(); } private void RestartReloadStatisticsTimer() diff --git a/Source/Libraries/GSF.TimeSeries/TimeSeriesStartupOperations.cs b/Source/Libraries/GSF.TimeSeries/TimeSeriesStartupOperations.cs index abc3685448b..6899f38c87b 100755 --- a/Source/Libraries/GSF.TimeSeries/TimeSeriesStartupOperations.cs +++ b/Source/Libraries/GSF.TimeSeries/TimeSeriesStartupOperations.cs @@ -84,7 +84,7 @@ private static void ValidateDefaultNode(AdoDataConnection database, string nodeI return; database.Connection.ExecuteNonQuery(NodeInsertFormat); - database.Connection.ExecuteNonQuery(string.Format(NodeUpdateFormat, nodeIDQueryString)); + database.Connection.ExecuteNonQuery(NodeUpdateFormat, nodeIDQueryString); } /// @@ -184,7 +184,7 @@ private static void ValidateAccountsAndGroups(AdoDataConnection database, string // Update user accounts foreach (KeyValuePair pair in updateMap) - database.Connection.ExecuteNonQuery(string.Format(UpdateUserAccountFormat, pair.Value, pair.Key)); + database.Connection.ExecuteNonQuery(UpdateUserAccountFormat, pair.Value, pair.Key); updateMap.Clear(); @@ -208,7 +208,7 @@ private static void ValidateAccountsAndGroups(AdoDataConnection database, string // Update security groups foreach (KeyValuePair pair in updateMap) - database.Connection.ExecuteNonQuery(string.Format(UpdateSecurityGroupFormat, pair.Value, pair.Key)); + database.Connection.ExecuteNonQuery(UpdateSecurityGroupFormat, pair.Value, pair.Key); } /// @@ -218,8 +218,11 @@ private static void ValidateAccountsAndGroups(AdoDataConnection database, string private static void ValidateDataPublishers(AdoDataConnection database, string nodeIDQueryString, string arguments) { const string DataPublisherCountFormat = "SELECT COUNT(*) FROM CustomActionAdapter WHERE AdapterName='{0}!DATAPUBLISHER' AND NodeID = {1}"; - const string GEPDataPublisherInsertFormat = "INSERT INTO CustomActionAdapter(NodeID, AdapterName, AssemblyName, TypeName, ConnectionString, Enabled) VALUES({0}, '{1}!DATAPUBLISHER', 'GSF.TimeSeries.dll', 'GSF.TimeSeries.Transport.DataPublisher', 'securityMode={2}; allowSynchronizedSubscription=false; useBaseTimeOffsets=true; {3}', {4})"; - const string STTPDataPublisherInsertFormat = "INSERT INTO CustomActionAdapter(NodeID, AdapterName, AssemblyName, TypeName, ConnectionString, Enabled) VALUES({0}, '{1}!DATAPUBLISHER', 'sttp.gsf.dll', 'sttp.DataPublisher', 'securityMode={2}; {3}', {4})"; + const string GEPDataPublisherInsertFormat = "INSERT INTO CustomActionAdapter(NodeID, AdapterName, AssemblyName, TypeName, ConnectionString, Enabled) " + + "VALUES({0}, '{1}!DATAPUBLISHER', 'GSF.TimeSeries.dll', 'GSF.TimeSeries.Transport.DataPublisher', 'securityMode={2}; " + + "allowSynchronizedSubscription=false; useBaseTimeOffsets=true; {3}', {4})"; + const string STTPDataPublisherInsertFormat = "INSERT INTO CustomActionAdapter(NodeID, AdapterName, AssemblyName, TypeName, ConnectionString, Enabled) " + + "VALUES({0}, '{1}!DATAPUBLISHER', 'sttp.gsf.dll', 'sttp.DataPublisher', 'securityMode={2}; {3}', {4})"; bool internalDataPublisherEnabled = true; bool externalDataPublisherEnabled = true; diff --git a/Source/Libraries/GSF.TimeSeries/Transport/DataPublisher.cs b/Source/Libraries/GSF.TimeSeries/Transport/DataPublisher.cs index ec9d96534c9..17fc626d8d9 100755 --- a/Source/Libraries/GSF.TimeSeries/Transport/DataPublisher.cs +++ b/Source/Libraries/GSF.TimeSeries/Transport/DataPublisher.cs @@ -3069,7 +3069,7 @@ protected virtual DataSet AquireMetadata(ClientConnection connection, Dictionary DataSet metadata = new(); // Initialize active node ID - Guid nodeID = Guid.Parse(dbConnection.ExecuteScalar($"SELECT NodeID FROM IaonActionAdapter WHERE ID = {ID}").ToString()); + Guid nodeID = Guid.Parse(dbConnection.ExecuteScalar("SELECT NodeID FROM IaonActionAdapter WHERE ID = {0}", ID).ToString()); // Determine whether we're sending internal and external meta-data bool sendExternalMetadata = connection.OperationalModes.HasFlag(OperationalModes.ReceiveExternalMetadata); diff --git a/Source/Libraries/GSF.TimeSeries/Transport/DataSubscriber.cs b/Source/Libraries/GSF.TimeSeries/Transport/DataSubscriber.cs index 54182c0c7b6..63466866c8b 100755 --- a/Source/Libraries/GSF.TimeSeries/Transport/DataSubscriber.cs +++ b/Source/Libraries/GSF.TimeSeries/Transport/DataSubscriber.cs @@ -3456,7 +3456,7 @@ protected virtual void SynchronizeMetadata() command.Transaction = transaction; // Query the actual record ID based on the known run-time ID for this subscriber device - object sourceID = command.ExecuteScalar($"SELECT SourceID FROM Runtime WHERE ID = {ID} AND SourceTable='Device'", MetadataSynchronizationTimeout); + object sourceID = command.ExecuteScalar("SELECT SourceID FROM Runtime WHERE ID = {0} AND SourceTable='Device'", MetadataSynchronizationTimeout, ID); if (sourceID is null || sourceID == DBNull.Value) return; @@ -3464,15 +3464,15 @@ protected virtual void SynchronizeMetadata() int parentID = Convert.ToInt32(sourceID); // Validate that the subscriber device is marked as a concentrator (we are about to associate children devices with it) - if (!command.ExecuteScalar($"SELECT IsConcentrator FROM Device WHERE ID = {parentID}", MetadataSynchronizationTimeout).ToString().ParseBoolean()) - command.ExecuteNonQuery($"UPDATE Device SET IsConcentrator = 1 WHERE ID = {parentID}", MetadataSynchronizationTimeout); + if (!command.ExecuteScalar("SELECT IsConcentrator FROM Device WHERE ID = {0}", MetadataSynchronizationTimeout, parentID).ToString().ParseBoolean()) + command.ExecuteNonQuery("UPDATE Device SET IsConcentrator = 1 WHERE ID = {0}", MetadataSynchronizationTimeout, parentID); // Get any historian associated with the subscriber device - object historianID = command.ExecuteScalar($"SELECT HistorianID FROM Device WHERE ID = {parentID}", MetadataSynchronizationTimeout); + object historianID = command.ExecuteScalar("SELECT HistorianID FROM Device WHERE ID = {0}", MetadataSynchronizationTimeout, parentID); // Determine the active node ID - we cache this since this value won't change for the lifetime of this class if (m_nodeID == Guid.Empty) - m_nodeID = Guid.Parse(command.ExecuteScalar($"SELECT NodeID FROM IaonInputAdapter WHERE ID = {(int)ID}", MetadataSynchronizationTimeout).ToString()); + m_nodeID = Guid.Parse(command.ExecuteScalar("SELECT NodeID FROM IaonInputAdapter WHERE ID = {0}", MetadataSynchronizationTimeout, ID).ToString()); // Determine the protocol record auto-inc ID value for the gateway transport protocol (GEP) - this value is also cached since it shouldn't change for the lifetime of this class if (m_gatewayProtocolID == 0) diff --git a/Source/Libraries/GSF.TimeSeries/Transport/UI/WPF/ViewModels/Subscribers.cs b/Source/Libraries/GSF.TimeSeries/Transport/UI/WPF/ViewModels/Subscribers.cs index 0ee1a8143dc..fc22f1829f3 100755 --- a/Source/Libraries/GSF.TimeSeries/Transport/UI/WPF/ViewModels/Subscribers.cs +++ b/Source/Libraries/GSF.TimeSeries/Transport/UI/WPF/ViewModels/Subscribers.cs @@ -714,8 +714,6 @@ private void LoadPermissionsDataSet() }; DataTable dataTable; - string queryFormat; - string parameterizedQuery; m_subscriberPermissionsDataSet = new DataSet(); @@ -723,9 +721,7 @@ private void LoadPermissionsDataSet() { foreach (KeyValuePair definition in dataTableDefinitions) { - queryFormat = string.Format("SELECT * FROM {0} WHERE NodeID = {{0}}", definition.Key); - parameterizedQuery = database.ParameterizedQueryString(queryFormat, "nodeID"); - dataTable = database.Connection.RetrieveData(database.AdapterType, parameterizedQuery, DataExtensions.DefaultTimeoutDuration, database.CurrentNodeID()); + dataTable = database.Connection.RetrieveData(database.AdapterType, $"SELECT * FROM {definition.Key} WHERE NodeID = {{0}}", DataExtensions.DefaultTimeoutDuration, database.CurrentNodeID()); dataTable.TableName = definition.Value; dataTable.DataSet.Tables.Remove(dataTable); m_subscriberPermissionsDataSet.Tables.Add(dataTable); diff --git a/Source/Libraries/GSF.TimeSeries/UI/AuthorizedMeasurementsQuery.cs b/Source/Libraries/GSF.TimeSeries/UI/AuthorizedMeasurementsQuery.cs index b813ba42b50..c5e32f12103 100755 --- a/Source/Libraries/GSF.TimeSeries/UI/AuthorizedMeasurementsQuery.cs +++ b/Source/Libraries/GSF.TimeSeries/UI/AuthorizedMeasurementsQuery.cs @@ -217,6 +217,8 @@ private void ExecuteAuthorizationQuery() string query = string.Format("SELECT DISTINCT DeviceID FROM ActiveMeasurement WHERE ProtocolType = 'Measurement' AND SignalID IN ({0})", sourceMeasurements.Select(signalID => guidPrefix + signalID.ToString() + guidSuffix).ToDelimitedString(", ")); DataTable measurementDevices = database.Connection.RetrieveData(database.AdapterType, query); + sourceMeasurements.Select(signalID => guidPrefix + signalID.ToString() + guidSuffix).ToDelimitedString(", ")); + foreach (DataRow row in measurementDevices.Rows) { int? deviceID = row.ConvertNullableField("DeviceID"); diff --git a/Source/Libraries/GSF.TimeSeries/UI/DataModels/Adapter.cs b/Source/Libraries/GSF.TimeSeries/UI/DataModels/Adapter.cs index 930a09e9187..09c3d3c9855 100755 --- a/Source/Libraries/GSF.TimeSeries/UI/DataModels/Adapter.cs +++ b/Source/Libraries/GSF.TimeSeries/UI/DataModels/Adapter.cs @@ -379,14 +379,12 @@ public static IList LoadIDs(AdoDataConnection database, AdapterType adapter IList adapterList = new List(); string sortClause = string.Empty; DataTable adapterTable; - string query; if (!string.IsNullOrEmpty(sortMember)) - sortClause = string.Format("ORDER BY {0} {1}", sortMember, sortDirection); - - query = database.ParameterizedQueryString(string.Format("SELECT ID FROM {0} WHERE NodeID = {{0}} {1}", viewName, sortClause), "nodeID"); - - adapterTable = database.Connection.RetrieveData(database.AdapterType, query, DefaultTimeout, database.CurrentNodeID()); + adapterTable = database.Connection.RetrieveData(database.AdapterType, + $"SELECT ID FROM {viewName} WHERE NodeID = {{0}} ORDER BY {sortMember} {sortDirection}", DefaultTimeout, database.CurrentNodeID()); + else adapterTable = database.Connection.RetrieveData(database.AdapterType, + $"SELECT ID FROM {viewName} WHERE NodeID = {{0}}", DefaultTimeout, database.CurrentNodeID()); foreach (DataRow row in adapterTable.Rows) { @@ -428,7 +426,6 @@ public static ObservableCollection Load(AdoDataConnection database, Ada else viewName = "CustomOutputAdapterDetail"; - string query; string commaSeparatedKeys; Adapter[] adapterList = null; @@ -438,10 +435,10 @@ public static ObservableCollection Load(AdoDataConnection database, Ada if ((object)keys != null && keys.Count > 0) { commaSeparatedKeys = keys.Select(key => "" + key.ToString() + "").Aggregate((str1, str2) => str1 + "," + str2); - query = database.ParameterizedQueryString(string.Format("SELECT NodeID, ID, AdapterName, AssemblyName, TypeName, ConnectionString, " + - "LoadOrder, Enabled, NodeName FROM {0} WHERE NodeID = {{0}} AND ID IN ({1})", viewName, commaSeparatedKeys), "nodeID"); - adapterTable = database.Connection.RetrieveData(database.AdapterType, query, DefaultTimeout, database.CurrentNodeID()); + adapterTable = database.Connection.RetrieveData(database.AdapterType, + "SELECT NodeID, ID, AdapterName, AssemblyName, TypeName, ConnectionString, " + + $"LoadOrder, Enabled, NodeName FROM {viewName} WHERE NodeID = {database.CurrentNodeID()} AND ID IN ({commaSeparatedKeys})", DefaultTimeout); adapterList = new Adapter[adapterTable.Rows.Count]; foreach (DataRow row in adapterTable.Rows) @@ -503,8 +500,8 @@ public static Dictionary GetLookupList(AdoDataConnection database, else tableName = "CustomOutputAdapter"; - string query = database.ParameterizedQueryString("SELECT ID, Name FROM " + tableName + " WHERE Enabled = {0} ORDER BY LoadOrder", "enabled"); - DataTable adapterTable = database.Connection.RetrieveData(database.AdapterType, query, DefaultTimeout, database.Bool(true)); + DataTable adapterTable = database.Connection.RetrieveData(database.AdapterType, + $"SELECT ID, Name FROM {tableName} WHERE Enabled = {{0}} ORDER BY LoadOrder", "enabled", DefaultTimeout, database.Bool(true)); foreach (DataRow row in adapterTable.Rows) adapterList[row.ConvertField("ID")] = row.Field("Name"); diff --git a/Source/Libraries/GSF.TimeSeries/UI/DataModels/Alarm.cs b/Source/Libraries/GSF.TimeSeries/UI/DataModels/Alarm.cs index 4bd03d8836b..dcbe43a8c46 100755 --- a/Source/Libraries/GSF.TimeSeries/UI/DataModels/Alarm.cs +++ b/Source/Libraries/GSF.TimeSeries/UI/DataModels/Alarm.cs @@ -24,6 +24,7 @@ //****************************************************************************************************** using System; +using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; @@ -524,7 +525,7 @@ public static IList LoadKeys(AdoDataConnection database, string sortMember string sortClause = string.Empty; DataTable adapterTable; string query; - + if (!string.IsNullOrEmpty(sortMember)) sortClause = string.Format("ORDER BY {0} {1}", sortMember, sortDirection); @@ -571,8 +572,9 @@ public static ObservableCollection Load(AdoDataConnection database, IList if ((object)keys != null && keys.Count > 0) { commaSeparatedKeys = keys.Select(key => "" + key.ToString() + "").Aggregate((str1, str2) => str1 + "," + str2); - query = database.ParameterizedQueryString(string.Format("SELECT NodeID, TagName, ID, SignalID, AssociatedMeasurementID, Description, Severity, Operation, " + - "SetPoint, Tolerance, Delay, Hysteresis, LoadOrder, Enabled FROM Alarm WHERE NodeID = {{0}} AND ID IN ({0})", commaSeparatedKeys), "nodeID"); + query = database.ParameterizedQueryString(string.Format("SELECT NodeID, TagName, ID, SignalID, AssociatedMeasurementID, " + + "Description, Severity, Operation, SetPoint, Tolerance, Delay, Hysteresis, LoadOrder, Enabled " + + "FROM Alarm WHERE NodeID = {{0}} AND ID IN ({0})", commaSeparatedKeys), "nodeID"); alarmTable = database.Connection.RetrieveData(database.AdapterType, query, DefaultTimeout, database.CurrentNodeID()); alarmList = new Alarm[alarmTable.Rows.Count]; @@ -625,7 +627,7 @@ public static Alarm GetAlarm(AdoDataConnection database, string whereClause) try { createdConnection = CreateConnection(ref database); - DataTable alarmTable = database.Connection.RetrieveData(database.AdapterType, "SELECT * FROM Alarm " + whereClause); + DataTable alarmTable = database.Connection.RetrieveData(database.AdapterType, $"SELECT * FROM Alarm {whereClause}"); if (alarmTable.Rows.Count == 0) return null; diff --git a/Source/Libraries/GSF.TimeSeries/UI/DataModels/Historian.cs b/Source/Libraries/GSF.TimeSeries/UI/DataModels/Historian.cs index 1c7a7cfa15a..5c1704ad401 100755 --- a/Source/Libraries/GSF.TimeSeries/UI/DataModels/Historian.cs +++ b/Source/Libraries/GSF.TimeSeries/UI/DataModels/Historian.cs @@ -34,6 +34,7 @@ //****************************************************************************************************** using System; +using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; diff --git a/Source/Libraries/GSF.TimeSeries/UI/DataModels/Node.cs b/Source/Libraries/GSF.TimeSeries/UI/DataModels/Node.cs index 1871232f6f6..f75bffc7c11 100755 --- a/Source/Libraries/GSF.TimeSeries/UI/DataModels/Node.cs +++ b/Source/Libraries/GSF.TimeSeries/UI/DataModels/Node.cs @@ -509,7 +509,8 @@ public static ObservableCollection Load(AdoDataConnection database, IList< if ((object)keys != null && keys.Count > 0) { commaSeparatedKeys = keys.Select(key => "'" + key.ToString() + "'").Aggregate((str1, str2) => str1 + "," + str2); - query = "Select ID, Name, CompanyID, Longitude, Latitude, Description, ImagePath, Settings, MenuData, " + $"MenuType, Master, LoadOrder, Enabled, CompanyName From NodeDetail WHERE ID IN ({commaSeparatedKeys})"; + query = "Select ID, Name, CompanyID, Longitude, Latitude, Description, ImagePath, Settings, MenuData, " + + $"MenuType, Master, LoadOrder, Enabled, CompanyName From NodeDetail WHERE ID IN ({commaSeparatedKeys})"; nodeTable = database.Connection.RetrieveData(database.AdapterType, query); nodeList = new Node[nodeTable.Rows.Count]; diff --git a/Source/Libraries/GSF.TimeSeries/UI/DataModels/UserAccount.cs b/Source/Libraries/GSF.TimeSeries/UI/DataModels/UserAccount.cs index 0cdc0b0272d..6decc90c7fe 100755 --- a/Source/Libraries/GSF.TimeSeries/UI/DataModels/UserAccount.cs +++ b/Source/Libraries/GSF.TimeSeries/UI/DataModels/UserAccount.cs @@ -342,7 +342,8 @@ public static ObservableCollection Load(AdoDataConnection database) createdConnection = CreateConnection(ref database); ObservableCollection userAccountList = new ObservableCollection(); - DataTable userAccountTable = database.Connection.RetrieveData(database.AdapterType, "SELECT * From UserAccount WHERE DefaultNodeID = '" + database.CurrentNodeID() + "' ORDER BY Name"); + DataTable userAccountTable = database.Connection.RetrieveData(database.AdapterType, "SELECT * From UserAccount WHERE DefaultNodeID = '" + + database.CurrentNodeID() + "' ORDER BY Name"); foreach (DataRow row in userAccountTable.Rows) { diff --git a/Source/Libraries/GSF.TimeSeries/UI/DataModels/Vendor.cs b/Source/Libraries/GSF.TimeSeries/UI/DataModels/Vendor.cs index 172453ba04b..fa3c7fa3b47 100755 --- a/Source/Libraries/GSF.TimeSeries/UI/DataModels/Vendor.cs +++ b/Source/Libraries/GSF.TimeSeries/UI/DataModels/Vendor.cs @@ -261,7 +261,6 @@ public static IList LoadKeys(AdoDataConnection database, string sortMember, if (!string.IsNullOrEmpty(sortMember)) sortClause = string.Format("ORDER BY {0} {1}", sortMember, sortDirection); - // check the query once again , Does it have to be details or somethng else vendorTable = database.Connection.RetrieveData(database.AdapterType, string.Format("SELECT ID From VendorDetail {0}", sortClause)); diff --git a/Source/Libraries/GSF.TimeSeries/UI/DataModels/VendorDevice.cs b/Source/Libraries/GSF.TimeSeries/UI/DataModels/VendorDevice.cs index 38a21cd52d7..7ff11606df2 100755 --- a/Source/Libraries/GSF.TimeSeries/UI/DataModels/VendorDevice.cs +++ b/Source/Libraries/GSF.TimeSeries/UI/DataModels/VendorDevice.cs @@ -248,7 +248,6 @@ public static IList LoadKeys(AdoDataConnection database, string sortMember, if (!string.IsNullOrEmpty(sortMember)) sortClause = string.Format("ORDER BY {0} {1}", sortMember, sortDirection); - // check the query once again , Does it have to be details or somethng else vendorDeviceTable = database.Connection.RetrieveData(database.AdapterType, string.Format("SELECT ID From VendorDeviceDetail {0}", sortClause)); diff --git a/Source/Libraries/GSF.Web/Model/ModelController.cs b/Source/Libraries/GSF.Web/Model/ModelController.cs index 12413c20422..1fb43dd3d40 100644 --- a/Source/Libraries/GSF.Web/Model/ModelController.cs +++ b/Source/Libraries/GSF.Web/Model/ModelController.cs @@ -791,7 +791,7 @@ protected virtual DataTable GetSearchResults(PostData postData, int? page = null if (SearchSettings.Condition != String.Empty) joinCondition = $"{joinCondition} AND "; joinCondition = joinCondition + $"SRC.{PrimaryKeyField} = AF.{SearchSettings.PrimaryKeyField}"; - + string sqlPivotColumns = $@" SELECT '[AFV_' + [Key] + ']' FROM (Select DISTINCT {SearchSettings.FieldKeyField} AS [Key] FROM {SearchSettings.AdditionalFieldTable} AS AF WHERE {collumnCondition} ) AS [Fields]";