public QueryResult(DbDataReader reader) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } if (!reader.CanGetColumnSchema()) { throw new CannotGetColumnSchemaException(); } var columnSchema = reader.GetColumnSchema(); Columns = new List <QueryResultColumn>(columnSchema.Count()); for (var columnIndex = 0; columnIndex < columnSchema.Count(); columnIndex++) { var currentColumn = columnSchema.ElementAt(columnIndex); var parsedColumn = new QueryResultColumn(currentColumn.ColumnName, columnIndex, typeDeterminator.FromDataTypeField(currentColumn.DataTypeName)); Columns.Add(parsedColumn); } Rows = new List <QueryResultRow>(); while (reader.Read()) { var values = new string[columnSchema.Count()]; for (var columnIndex = 0; columnIndex < columnSchema.Count(); columnIndex++) { values[columnIndex] = reader[columnIndex].ToString(); } var parsedRow = new QueryResultRow(values); Rows.Add(parsedRow); } }
private static bool[] GetNotCheckNullList(DbDataReader dbDataReader) { var resultList = new bool[dbDataReader.FieldCount]; for (int i = 0; i < resultList.Length; i++) { resultList[i] = true; } if (dbDataReader.CanGetColumnSchema()) { var columnSchema = dbDataReader.GetColumnSchema(); if (columnSchema.Count > 0) { for (int i = 0; i < columnSchema.Count; i++) { var dbColumn = columnSchema[i]; if (dbColumn.ColumnOrdinal.HasValue && dbColumn.AllowDBNull.HasValue) { resultList[dbColumn.ColumnOrdinal.Value] = !dbColumn.AllowDBNull.Value; } } } } return(resultList); }
public static System.Collections.ObjectModel.ReadOnlyCollection <DbColumn> GetColumnSchema(this DbDataReader reader) { if (reader.CanGetColumnSchema()) { return(((IDbColumnSchemaGenerator)reader).GetColumnSchema()); } throw new NotSupportedException(); }
public DbReaderInfo(DbDataReader reader) { if (!reader.CanGetColumnSchema()) { throw new InvalidOperationException("The specified DbDataReader does not provide column schema info"); } _reader = reader; }
private static bool GetHasActionColumn(DbDataReader reader) { if (reader.CanGetColumnSchema()) { return(reader .GetColumnSchema() .Any(c => c.ColumnName != null && c.ColumnName.Equals("action", StringComparison.CurrentCultureIgnoreCase))); } try { var val = reader["action"]; return(true); } catch (IndexOutOfRangeException) { return(false); } }
// Initializes the column names by looping through the data reads columns or using the schema if it is available private void initializeColumnNames() { m_dr_names = new string[m_dr.FieldCount]; if (m_dr.CanGetColumnSchema()) { var columnSchema = m_dr.GetColumnSchema(); for (var i = 0; i < m_dr.FieldCount; i++) { m_dr_names[i] = columnSchema[i].ColumnName; } } else { for (var i = 0; i < m_dr.FieldCount; i++) { m_dr_names[i] = m_dr.GetName(i); } } }
private async Task ExecuteOnce(DbConnection conn, CancellationToken cancellationToken) { // Make sure we haven't cancelled yet cancellationToken.ThrowIfCancellationRequested(); // Create a command that we'll use for executing the query using (DbCommand dbCommand = CreateCommand(conn)) { // Make sure that we cancel the command if the cancellation token is cancelled cancellationToken.Register(() => dbCommand?.Cancel()); // Setup the command for executing the batch dbCommand.CommandText = BatchText; dbCommand.CommandType = CommandType.Text; dbCommand.CommandTimeout = 0; executionStartTime = DateTime.Now; List <DbColumn[]> columnSchemas = null; if (getFullColumnSchema) { // Executing the same query twice with different command behavior causes the second // execution to return no rows if there's a trailing comment with no newline after, // so add a newline to the end of the query. See https://github.com/Microsoft/sqlopsstudio/issues/1424 dbCommand.CommandText += Environment.NewLine; // Fetch schema info separately, since CommandBehavior.KeyInfo will include primary // key columns in the result set, even if they weren't part of the select statement. // Extra key columns get added to the end, so just correlate via Column Ordinal. columnSchemas = new List <DbColumn[]>(); using (DbDataReader reader = await dbCommand.ExecuteReaderAsync(CommandBehavior.KeyInfo | CommandBehavior.SchemaOnly, cancellationToken)) { if (reader != null && reader.CanGetColumnSchema()) { do { columnSchemas.Add(reader.GetColumnSchema().ToArray()); } while (await reader.NextResultAsync(cancellationToken)); } } } // Execute the command to get back a reader using (DbDataReader reader = await dbCommand.ExecuteReaderAsync(cancellationToken)) { do { // Verify that the cancellation token hasn't been canceled cancellationToken.ThrowIfCancellationRequested(); // Skip this result set if there aren't any rows (i.e. UPDATE/DELETE/etc queries) if (!reader.HasRows && reader.FieldCount == 0) { continue; } // This resultset has results (i.e. SELECT/etc queries) ResultSet resultSet = new ResultSet(resultSets.Count, Id, outputFileFactory); resultSet.ResultCompletion += ResultSetCompletion; // Add the result set to the results of the query lock (resultSets) { resultSets.Add(resultSet); } // Read until we hit the end of the result set await resultSet.ReadResultToEnd(reader, cancellationToken); } while (await reader.NextResultAsync(cancellationToken)); // If there were no messages, for whatever reason (NO COUNT set, messages // were emitted, records returned), output a "successful" message if (!messagesSent) { await SendMessage(SR.QueryServiceCompletedSuccessfully, false); } } if (columnSchemas != null) { ExtendResultMetadata(columnSchemas, resultSets); } } }
/// <summary> /// Execute a command against a data source, mapping the data reader GetSchemaTable() result to an enumerable of record dictionaries. /// This method perfoms LAZY LOADING/DEFERRED EXECUTION. /// Note that THE DATA READER WILL NOT BE DISPOSED UPON ENUMERATION OR FOREACH BRANCH OUT. /// </summary> /// <param name="dbDataReader"> The target data reader. </param> /// <param name="recordsAffectedCallback"> Executed when the output count of records affected is available to return (post enumeration). </param> /// <returns> An enumerable of record dictionary instances, containing key/value pairs of schema metadata. </returns> public IEnumerable <IAdoNetStreamingRecord> GetSchemaRecordsFromReader(DbDataReader dbDataReader, Action <int> recordsAffectedCallback) { ReadOnlyCollection <DbColumn> dbColumns; DbColumn dbColumn; PropertyInfo[] propertyInfos; PropertyInfo propertyInfo; AdoNetStreamingRecord record; int recordsAffected; string key; object value; Guid _ = this.__enter(); if ((object)dbDataReader == null) { throw new ArgumentNullException(nameof(dbDataReader)); } if (!dbDataReader.CanGetColumnSchema()) { throw new NotSupportedException(string.Format("The connection command type '{0}' does not support schema access.", dbDataReader.GetType().FullName)); } //using (this.__use(_, dbDataReader)) { dbColumns = dbDataReader.GetColumnSchema(); this.__trace(_, "before yield loop"); if ((object)dbColumns != null) { for (long recordIndex = 0; recordIndex < dbColumns.Count; recordIndex++) { dbColumn = dbColumns[(int)recordIndex]; propertyInfos = dbColumn.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty); record = new AdoNetStreamingRecord(-1, recordIndex); if ((object)propertyInfos != null) { for (int fieldIndex = 0; fieldIndex < propertyInfos.Length; fieldIndex++) { propertyInfo = propertyInfos[fieldIndex]; if (propertyInfo.GetIndexParameters().Any()) { continue; } key = propertyInfo.Name; value = propertyInfo.GetValue(dbColumn); value = value.ChangeType <object>(); record.Add(key, value); } } this.__trace(_, "on yield item"); yield return(record); // LAZY PROCESSING INTENT HERE / DO NOT FORCE EAGER LOAD } } this.__trace(_, "after yield loop"); //this.__disp(_, dbDataReader); } recordsAffected = dbDataReader.RecordsAffected; if ((object)recordsAffectedCallback != null) { recordsAffectedCallback(recordsAffected); } this.__leave(_); }
public IEnumerable <__IRow> ExecuteRecords(bool schemaOnly, Type connectionType, string connectionString, bool transactional, IsolationLevel isolationLevel, CommandType commandType, string commandText, IEnumerable <DbParameter> commandParameters, int?commandTimeout = null, bool commandPrepare = false, Action <long> resultCallback = null) { DbTransaction dbTransaction; const bool OPEN = true; IList <__Row> rows; CommandBehavior commandBehavior; long resultIndex = 0; ReadOnlyCollection <DbColumn> dbColumns; DbColumn dbColumn; PropertyInfo[] propertyInfos; PropertyInfo propertyInfo; if ((object)connectionType == null) { throw new ArgumentNullException(nameof(connectionType)); } if ((object)connectionString == null) { throw new ArgumentNullException(nameof(connectionString)); } using (DbConnection dbConnection = (DbConnection)Activator.CreateInstance(connectionType)) { if (OPEN) { dbConnection.ConnectionString = connectionString; dbConnection.Open(); if (transactional) { dbTransaction = dbConnection.BeginTransaction(isolationLevel); } else { dbTransaction = null; } } using (DbCommand dbCommand = dbConnection.CreateCommand()) { dbCommand.Transaction = dbTransaction; dbCommand.CommandType = commandType; dbCommand.CommandText = commandText; if ((object)commandTimeout != null) { dbCommand.CommandTimeout = (int)commandTimeout; } // add parameters if ((object)commandParameters != null) { foreach (DbParameter commandParameter in commandParameters) { if ((object)commandParameter.Value == null) { commandParameter.Value = DBNull.Value; } dbCommand.Parameters.Add(commandParameter); } } if (commandPrepare) { dbCommand.Prepare(); } rows = new List <__Row>(); commandBehavior = schemaOnly ? CommandBehavior.SchemaOnly : CommandBehavior.Default; using (DbDataReader dbDataReader = (dbCommand.ExecuteReader(commandBehavior))) { __Row row; string key; object value; if (!schemaOnly) { do { if ((object)resultCallback != null) { resultCallback(resultIndex++); } while (dbDataReader.Read()) { row = new __Row(StringComparer.OrdinalIgnoreCase); for (int fieldIndex = 0; fieldIndex < dbDataReader.FieldCount; fieldIndex++) { key = dbDataReader.GetName(fieldIndex); value = dbDataReader.GetValue(fieldIndex); value = this.DataTypeFascade.ChangeType <object>(value); if (row.ContainsKey(key) || (key ?? string.Empty).Length == 0) { key = string.Format("Field_{0:0000}", fieldIndex); } row.Add(key, value); } rows.Add(row); } }while (dbDataReader.NextResult()); } else { if (!dbDataReader.CanGetColumnSchema()) { throw new NotSupportedException(string.Format("The connection command type '{0}' does not support schema access.", dbDataReader.GetType().FullName)); } dbColumns = dbDataReader.GetColumnSchema(); { if ((object)dbColumns != null) { for (long recordIndex = 0; recordIndex < dbColumns.Count; recordIndex++) { dbColumn = dbColumns[(int)recordIndex]; propertyInfos = dbColumn.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance); row = new __Row(StringComparer.OrdinalIgnoreCase); row.Add(string.Empty, dbColumn); if ((object)propertyInfos != null) { for (int fieldIndex = 0; fieldIndex < propertyInfos.Length; fieldIndex++) { propertyInfo = propertyInfos[fieldIndex]; if (propertyInfo.GetIndexParameters().Any()) { continue; } key = propertyInfo.Name; value = propertyInfo.GetValue(dbColumn); value = this.DataTypeFascade.ChangeType <object>(value); row.Add(key, value); } } } } } } } return(rows); } } }
/// <summary> /// Initialises a transform source. /// </summary> /// <param name="inReader">An initialized DbDataReader.</param> /// <param name="sortFields">A list of already sorted fields in the inReader. If the fields are not sorted in the source data and sortfields are set, transforms such as group, row, join will fail or return incorrect results.</param> public ReaderDbDataReader(DbDataReader inReader, List <Sort> sortFields = null) { InReader = inReader; var fieldCount = inReader.FieldCount; CacheTable = new Table("InReader"); #if NET462 try { DataTable schema = inReader.GetSchemaTable(); CacheTable.TableName = schema.Rows[0][SchemaTableColumn.BaseTableName].ToString(); foreach (DataRow row in schema.Rows) { var column = new TableColumn(); column.ColumnName = row[SchemaTableColumn.ColumnName].ToString(); column.DataType = DataType.GetTypeCode((Type)row[SchemaTableColumn.DataType]); column.MaxLength = Convert.ToInt32(row[SchemaTableColumn.ColumnSize]); column.Scale = Convert.ToInt32(row[SchemaTableColumn.NumericScale]); column.Precision = Convert.ToInt32(row[SchemaTableColumn.NumericPrecision]); CacheTable.Columns.Add(column); } } catch (Exception) { for (int i = 0; i < fieldCount; i++) { CacheTable.Columns.Add(new TableColumn(inReader.GetName(i))); } } #else //if we can't get a column schema we will have to settle for column names only if (!inReader.CanGetColumnSchema()) { for (var i = 0; i < fieldCount; i++) { CacheTable.Columns.Add(new TableColumn(inReader.GetName(i))); } } else { var columnSchema = inReader.GetColumnSchema(); CacheTable.Name = columnSchema[0].BaseTableName; foreach (var columnDetail in columnSchema) { var column = new TableColumn { Name = columnDetail.ColumnName, DataType = Dexih.Utils.DataType.DataType.GetTypeCode(columnDetail.DataType), MaxLength = columnDetail.ColumnSize, Scale = columnDetail.NumericScale, Precision = columnDetail.NumericPrecision }; } } #endif _sortFields = sortFields; }