Skip to content
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

Sql fix #314

Open
wants to merge 24 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
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
19 changes: 2 additions & 17 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({7}, {0}, {1}, {2}, {3}, {4}, {5}, {6})",
"acronym", "name", "protocolID", "framesPerSecond", "measurementReportingInterval",
"connectionString", "enabled");
Comment on lines +97 to 99
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to also include a name for parameter 7. Probably, you should add 7 at the end and insert the name before acronym like so...

Suggested change
"MeasurementReportingInterval, ConnectionString, Enabled) VALUES({7}, {0}, {1}, {2}, {3}, {4}, {5}, {6})",
"acronym", "name", "protocolID", "framesPerSecond", "measurementReportingInterval",
"connectionString", "enabled");
"MeasurementReportingInterval, ConnectionString, Enabled) VALUES({0}, {1}, {2}, {3}, {4}, {5}, {6}, {7})",
"nodeID", "acronym", "name", "protocolID", "framesPerSecond", "measurementReportingInterval",
"connectionString", "enabled");


// 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), nodeID);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This old API for parameterized queries isn't as clever about matching arguments to your format string. Even if you use {7} as the first parameter in the query string, nodeID has to be the first argument to ExecuteNonQuery(). Also, you need database.Guid() or else it won't work for SQLite, PostgreSQL, or Oracle.

Suggested change
connection.ExecuteNonQuery(parameterizedQuery, acronym, name, protocolID, sourceWave.SampleRate, 1000000, $"wavFileName={FilePath.GetAbsolutePath(sourceFileName)}; connectOnDemand=true; outputSourceIDs={acronym}; memoryCache={useMemoryCache}", database.Bool(true), nodeID);
connection.ExecuteNonQuery(parameterizedQuery, database.Guid(nodeID), acronym, name, protocolID, sourceWave.SampleRate, 1000000, $"wavFileName={FilePath.GetAbsolutePath(sourceFileName)}; connectOnDemand=true; outputSourceIDs={acronym}; memoryCache={useMemoryCache}", database.Bool(true));

int deviceID = Convert.ToInt32(connection.ExecuteScalar(database.ParameterizedQueryString("SELECT ID FROM Device WHERE Acronym = {0}", "acronym"), acronym));
string pointTag;
int lastPhasorIndex = 0;
Expand Down
13 changes: 4 additions & 9 deletions Source/Libraries/Adapters/MySqlAdapters/MySqlOutputAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -176,17 +176,12 @@ 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();
command.Parameters.Add(measurement.ID);
command.Parameters.Add((long)measurement.Timestamp);
command.Parameters.Add(measurement.AdjustedValue);
Comment on lines +180 to +182
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a feeling this won't work. IDbCommand.Parameters returns a collection of type IDataParameterCollection which implements the non-generic IList interface. It's entirely possible that the MySQL implementation of the Add() method can convert any old value to an instance of IDbDataParameter, but I feel it's pretty unlikely. You'll need to use command.CreateParameter() and then set the ParameterName and Value fields for each parameter.


commandString.Append(measurement.ID);
commandString.Append("','");
commandString.Append((long)measurement.Timestamp);
commandString.Append("',");
commandString.Append(measurement.AdjustedValue);
commandString.Append(')');

command.CommandText = commandString.ToString();
command.CommandText = "INSERT INTO Measurement VALUES ({0}, {1}, {2})";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I missed this. Format strings only work with AdoDataConnection. Otherwise, you need to use the SQL syntax for parameters. In MySQL, that'd be @parameterName.

command.ExecuteNonQuery();

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit, whitespace

Suggested change
database.Connection.ExecuteNonQuery("DELETE FROM TrackedChange WHERE ID <= {0}",latestVersion);
database.Connection.ExecuteNonQuery("DELETE FROM TrackedChange WHERE ID <= {0}", latestVersion);

}
catch (Exception ex)
{
Expand Down
10 changes: 5 additions & 5 deletions Source/Libraries/GSF.TimeSeries/Transport/DataSubscriber.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3456,23 +3456,23 @@ 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;

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)
Expand Down