Skip to content

Sql fix #314

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 34 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
426dad1
Removed Left over Access support and parametrized nodeID
clackner-gpa Nov 21, 2024
f4ee60c
Parametrized MySQL Query
clackner-gpa Nov 21, 2024
aa261d3
Parametrized query
clackner-gpa Nov 21, 2024
04aab4b
Parametrized queries
clackner-gpa Nov 21, 2024
34b6095
DeviceAlarmStateAdapter
collins-self Dec 17, 2024
a45e402
LocalOutPutAdapter
collins-self Dec 17, 2024
dcef535
CommonPhasorServices
collins-self Dec 17, 2024
43232f5
Device.cs
collins-self Dec 17, 2024
474049a
OutputStream
collins-self Dec 17, 2024
cf90946
CalculatedMeasurements
collins-self Dec 17, 2024
f9a4142
OutputStreamDevice
collins-self Dec 17, 2024
23eeb8c
DatabaseConfigurationLoader
collins-self Dec 17, 2024
f767b50
Adapter and Alarm
collins-self Dec 18, 2024
4465d5d
measurement and historian
collins-self Dec 18, 2024
95b85a4
Node, Vendor, ModelController
collins-self Dec 18, 2024
fd9c380
string.format
collins-self Dec 18, 2024
61bd634
PhasorServices and MetadataExportAdaper
collins-self Dec 23, 2024
c6c50d0
ExecuteScalar
collins-self Dec 23, 2024
39b26b4
ExecuteReader
collins-self Dec 23, 2024
fe0132e
MetaDataImportAdapter, CommonPhasorServices
collins-self Dec 26, 2024
74f7ac0
ErrorLogger
collins-self Dec 26, 2024
e533ec7
TimeSeriesStartupOperations and Adapter
collins-self Dec 26, 2024
41f318e
clean up fixes
collins-self Dec 27, 2024
d0bf21d
OutputAdapter
collins-self Dec 30, 2024
b6758e5
quick fixes to only commented reviews
collins-self Feb 1, 2025
289aa43
refactored and undid changes to strings
collins-self Feb 5, 2025
c22db55
updated query strings
collins-self Feb 5, 2025
8698d1a
fixed many string.format()'s and safe parameter passing
collins-self Feb 6, 2025
fd53abd
whitespace
collins-self Feb 6, 2025
9840022
removed bad changes with sql strings in parameters
collins-self Feb 7, 2025
f81d0c7
DatabaseConfigurationLoader
collins-self Feb 7, 2025
8bb3994
re-implemented changes lost from Commit 95e045f
collins-self Feb 10, 2025
0a9fd1c
fixed Program.cs error
collins-self Feb 12, 2025
74a932d
Cleaned up build errors
collins-self Feb 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 3 additions & 18 deletions Source/Applications/Wave Demo Apps/UpdateWAVMetaData/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,24 +48,9 @@ static int Main(string[] args)
Guid nodeID = systemSettings["NodeID"].ValueAs<Guid>();
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<string, string> 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;
Expand Down Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<string>("Acronym"));

// ReSharper disable once AccessToDisposedClosure
Expand Down
15 changes: 10 additions & 5 deletions Source/Libraries/Adapters/HistorianAdapters/LocalOutputAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -1206,7 +1208,7 @@ private static void AddPIHistorianReaders(AdoDataConnection database, string nod
IEnumerable<DataRow> 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)
Expand Down Expand Up @@ -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('@', ':');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(';'))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,7 @@ private Action<DataSet> 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)
Expand All @@ -462,19 +462,19 @@ private Action<DataSet> 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);
}

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<DataTable>().Sum(dataTable => (long)dataTable.Rows.Count) + 3);
Expand Down
23 changes: 15 additions & 8 deletions Source/Libraries/Adapters/MySqlAdapters/MySqlOutputAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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.ParameterName = "@measurementID";
timeStampParameter.ParameterName = "@timeStamp";
valueParameter.ParameterName = "@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();

}
Expand Down
2 changes: 1 addition & 1 deletion Source/Libraries/Adapters/PIAdapters/PIOutputAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading