} // end of function // this method is called when query execution is finished public override void ProcessResults(IAsyncResult result) { SqlCommand cmd = null; SqlConnection con = null; SqlDataReader dataReader = null; ushort rowsProcessed = 0; ushort numOfRows = 1; bool columnNamesMatch = true; try { // Retrieve state object var stateObj = (ProbeResultingCallbackStateObject)result.AsyncState; // Extract data from state object cmd = stateObj.SqlCommand; int timeTableId = stateObj.TimeTableId; Target target = stateObj.Target; MetricGroup metricGroup = stateObj.MetricGroup; con = cmd.Connection; dataReader = cmd.EndExecuteReader(result); // prepare ProbeResultingData if (metricGroup.isMultiRow) { numOfRows = DATA_ROWS_INCREMENT; // set initial size } var data = new ProbeResultingData(numOfRows, (ushort)(metricGroup.NumberOfMultiRowKeys + metricGroup.NumberOfMultiRowKeyAttributes + metricGroup.NumberOfMetrics)); data.SetProbeDateTime(DateTime.Now); for (int i = 0; i < metricGroup.NumberOfMultiRowKeys; i++) { data.AddColumnHeader(metricGroup.multiRowKeys[i].name, metricGroup.multiRowKeys[i].type); } for (int i = 0; i < metricGroup.NumberOfMultiRowKeyAttributes; i++) { data.AddColumnHeader(metricGroup.multiRowKeyAttributes[i].name, metricGroup.multiRowKeyAttributes[i].type); } for (int i = 0; i < metricGroup.NumberOfMetrics; i++) { data.AddColumnHeader(metricGroup.metrics[i].name, metricGroup.metrics[i].type); } // read results and save in results object while (dataReader.Read() && columnNamesMatch) { // check that column names match configuration if (rowsProcessed == 0) { for (int i = 0; i < dataReader.FieldCount; i++) { if (i < metricGroup.NumberOfMultiRowKeys) { if (string.Compare(dataReader.GetName(i), metricGroup.multiRowKeys[i].name.Replace(' ', '_'), true) != 0) { _logger.Error("Actual name of key column # " + i.ToString() + " [" + dataReader.GetName(i) + "] doesn't match to configuration [" + metricGroup.multiRowKeys[i].name.Replace(' ', '_') + "]"); columnNamesMatch = false; break; } } else if (i < metricGroup.NumberOfMultiRowKeys + metricGroup.NumberOfMultiRowKeyAttributes) { if (string.Compare(dataReader.GetName(i), metricGroup.multiRowKeyAttributes[i - metricGroup.NumberOfMultiRowKeys].name.Replace(' ', '_'), true) != 0) { _logger.Error("Actual name of key attribute column # " + i.ToString() + " [" + dataReader.GetName(i) + "] doesn't match to configuration [" + metricGroup.multiRowKeyAttributes[i - metricGroup.NumberOfMultiRowKeys].name.Replace(' ', '_') + "]"); columnNamesMatch = false; break; } } else { if (string.Compare(dataReader.GetName(i), metricGroup.metrics[i - metricGroup.NumberOfMultiRowKeys - metricGroup.NumberOfMultiRowKeyAttributes].name.Replace(' ', '_'), true) != 0) { _logger.Error("Actual name of column # " + i.ToString() + " [" + dataReader.GetName(i) + "] doesn't match to configuration [" + metricGroup.metrics[i - metricGroup.NumberOfMultiRowKeys - metricGroup.NumberOfMultiRowKeyAttributes].name.Replace(' ', '_') + "]"); columnNamesMatch = false; break; } } } } if (rowsProcessed == numOfRows) { numOfRows += DATA_ROWS_INCREMENT; data.ChangeNumOfRows(numOfRows); } for (int i = 0; i < dataReader.FieldCount; i++) { // check data type before casting. Data type of a column returned by query may not match the one set up in Configuration switch (data.dataTypes[i]) { case DataType.Ansi: if (!DataTypeMappingSqlServer.DoesBelong(dataReader.GetDataTypeName(i), DataType.Ansi)) { throw new Exception("Data type of column #" + (i + 1).ToString() + " of '" + metricGroup.name + "' metric (target [" + target.name + "]) does not match any allowed data type for internal data type Ansi"); } data.values[rowsProcessed, i] = (object)dataReader.GetString(i); break; case DataType.Unicode: if (!DataTypeMappingSqlServer.DoesBelong(dataReader.GetDataTypeName(i), DataType.Unicode)) { throw new Exception("Data type of column #" + (i + 1).ToString() + " of '" + metricGroup.name + "' metric (target [" + target.name + "]) does not match any allowed data type for internal data type Unicode"); } data.values[rowsProcessed, i] = (object)dataReader.GetString(i); break; case DataType.Double: if (!DataTypeMappingSqlServer.DoesBelong(dataReader.GetDataTypeName(i), DataType.Double)) { throw new Exception("Data type of column #" + (i + 1).ToString() + " of '" + metricGroup.name + "' metric (target [" + target.name + "]) does not match any allowed data type for internal data type Double"); } data.values[rowsProcessed, i] = (object)dataReader.GetDouble(i); break; case DataType.SmallInt: if (!DataTypeMappingSqlServer.DoesBelong(dataReader.GetDataTypeName(i), DataType.SmallInt)) { throw new Exception("Data type of column #" + (i + 1).ToString() + " of '" + metricGroup.name + "' metric (target [" + target.name + "]) does not match any allowed data type for internal data type Int16"); } data.values[rowsProcessed, i] = (object)dataReader.GetInt16(i); break; case DataType.Datetime: if (!DataTypeMappingSqlServer.DoesBelong(dataReader.GetDataTypeName(i), DataType.Datetime)) { throw new Exception("Data type of column #" + (i + 1).ToString() + " of '" + metricGroup.name + "' metric (target [" + target.name + "]) does not match any allowed data type for internal data type Datetime"); } data.values[rowsProcessed, i] = (object)dataReader.GetDateTime(i); break; default: throw new Exception("Unknown data type"); } // end of switch } // end of for rowsProcessed++; } // trim extra pre-allocated rows if (rowsProcessed != numOfRows) { data.ChangeNumOfRows(rowsProcessed); } Configuration.timeTable.SetLastPoll(timeTableId, data.probeDateTime); // pass msg to Analyzer Analyzer.Enqueue(target, metricGroup, data); } // end of try catch (Exception e) { _logger.Error("SqlServerProbe.ProcessResults: " + e.Message); _logger.Error(e.StackTrace); } finally { if (dataReader != null) { dataReader.Close(); dataReader.Dispose(); } if (cmd != null) { cmd.Dispose(); } if (con != null) { con.Close(); con.Dispose(); } } } // end of ProcessResults method
public ProbeResultsDataMessage(Target target, MetricGroup metricGroup, ProbeResultingData data) { this.Target = target; this.MetricGroup = metricGroup; this.Data = data; }