private object GetNestedObjectValue(object result) { if (result != DBNull.Value) { RecordState newSource = result as RecordState; if (newSource != null) { if (newSource.IsNull) { result = (object)DBNull.Value; } else { BridgeDataRecord bridgeDataRecord = new BridgeDataRecord(this._shaper, this.Depth + 1); bridgeDataRecord.SetRecordSource(newSource, true); result = (object)bridgeDataRecord; this._currentNestedRecord = bridgeDataRecord; this._currentNestedReader = (BridgeDataReader)null; } } else { Coordinator <RecordState> coordinator = result as Coordinator <RecordState>; if (coordinator != null) { BridgeDataReader bridgeDataReader = new BridgeDataReader(this._shaper, coordinator.TypedCoordinatorFactory, this.Depth + 1, (IEnumerator <KeyValuePair <Shaper <RecordState>, CoordinatorFactory <RecordState> > >)null); result = (object)bridgeDataReader; this._currentNestedRecord = (BridgeDataRecord)null; this._currentNestedReader = bridgeDataReader; } } } return(result); }
internal BridgeDataReader( Shaper <RecordState> shaper, CoordinatorFactory <RecordState> coordinatorFactory, int depth, IEnumerator <KeyValuePair <Shaper <RecordState>, CoordinatorFactory <RecordState> > > nextResultShaperInfos) { BridgeDataReader bridgeDataReader = this; this._nextResultShaperInfoEnumerator = nextResultShaperInfos; this._initialize = (Action)(() => bridgeDataReader.SetShaper(shaper, coordinatorFactory, depth)); this._initializeAsync = (Func <CancellationToken, Task>)(ct => bridgeDataReader.SetShaperAsync(shaper, coordinatorFactory, depth, ct)); }
/// <summary> /// The primary factory method to produce the BridgeDataReader; given a store data /// reader and a column map, create the BridgeDataReader, hooking up the IteratorSources /// and ResultColumn Hierarchy. All construction of top level data readers go through /// this method. /// </summary> /// <param name="storeDataReader"></param> /// <param name="columnMap">column map of the first result set</param> /// <param name="nextResultColumnMaps">enumerable of the column maps for NextResult() calls.</param> /// <returns></returns> public virtual DbDataReader Create( DbDataReader storeDataReader, ColumnMap columnMap, MetadataWorkspace workspace, IEnumerable<ColumnMap> nextResultColumnMaps) { Contract.Requires(storeDataReader != null); Contract.Requires(columnMap != null); Contract.Requires(workspace != null); Contract.Requires(nextResultColumnMaps != null); var shaperInfo = CreateShaperInfo(storeDataReader, columnMap, workspace); DbDataReader result = new BridgeDataReader( shaperInfo.Key, shaperInfo.Value, /*depth:*/ 0, GetNextResultShaperInfo(storeDataReader, workspace, nextResultColumnMaps).GetEnumerator()); return result; }
/// <summary> /// The primary factory method to produce the BridgeDataReader; given a store data /// reader and a column map, create the BridgeDataReader, hooking up the IteratorSources /// and ResultColumn Hierarchy. All construction of top level data readers go through /// this method. /// </summary> /// <param name="storeDataReader"> </param> /// <param name="columnMap"> column map of the first result set </param> /// <param name="nextResultColumnMaps"> enumerable of the column maps for NextResult() calls. </param> /// <returns> </returns> public virtual DbDataReader Create( DbDataReader storeDataReader, ColumnMap columnMap, MetadataWorkspace workspace, IEnumerable<ColumnMap> nextResultColumnMaps) { DebugCheck.NotNull(storeDataReader); DebugCheck.NotNull(columnMap); DebugCheck.NotNull(workspace); DebugCheck.NotNull(nextResultColumnMaps); var shaperInfo = CreateShaperInfo(storeDataReader, columnMap, workspace); DbDataReader result = new BridgeDataReader( shaperInfo.Key, shaperInfo.Value, /*depth:*/ 0, GetNextResultShaperInfo(storeDataReader, workspace, nextResultColumnMaps).GetEnumerator()); return result; }
public virtual DbDataReader Create( DbDataReader storeDataReader, ColumnMap columnMap, MetadataWorkspace workspace, IEnumerable <ColumnMap> nextResultColumnMaps) { DebugCheck.NotNull(storeDataReader); DebugCheck.NotNull(columnMap); DebugCheck.NotNull(workspace); DebugCheck.NotNull(nextResultColumnMaps); var shaperInfo = CreateShaperInfo(storeDataReader, columnMap, workspace); DbDataReader result = new BridgeDataReader( shaperInfo.Key, shaperInfo.Value, /*depth:*/ 0, GetNextResultShaperInfo(storeDataReader, workspace, nextResultColumnMaps).GetEnumerator()); return(result); }
private async Task CloseNestedObjectImplicitlyAsync(CancellationToken cancellationToken) { BridgeDataRecord currentNestedRecord = this._currentNestedRecord; if (currentNestedRecord != null) { this._currentNestedRecord = (BridgeDataRecord)null; await currentNestedRecord.CloseImplicitlyAsync(cancellationToken).WithCurrentCulture(); } BridgeDataReader currentNestedReader = this._currentNestedReader; if (currentNestedReader == null) { return; } this._currentNestedReader = (BridgeDataReader)null; await currentNestedReader.CloseImplicitlyAsync(cancellationToken).WithCurrentCulture(); }
private object CloseNestedObjectImplicitly() { BridgeDataRecord currentNestedRecord = this._currentNestedRecord; if (currentNestedRecord != null) { this._currentNestedRecord = (BridgeDataRecord)null; currentNestedRecord.CloseImplicitly(); } BridgeDataReader currentNestedReader = this._currentNestedReader; if (currentNestedReader != null) { this._currentNestedReader = (BridgeDataReader)null; currentNestedReader.CloseImplicitly(); } return((object)null); }
/// <summary> /// An asynchronous version of <see cref="CloseNestedObjectImplicitly" />, which /// Ensure that whatever column we're currently processing is implicitly closed; /// </summary> private async Task CloseNestedObjectImplicitlyAsync(CancellationToken cancellationToken) { // it would be nice to use Interlocked.Exchange to avoid multi-thread `race condition risk // when the the bridge is being misused by the user accessing it with multiple threads. // but this is called frequently enough to have a performance impact var currentNestedRecord = _currentNestedRecord; if (null != currentNestedRecord) { _currentNestedRecord = null; await currentNestedRecord.CloseImplicitlyAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } var currentNestedReader = _currentNestedReader; if (null != currentNestedReader) { _currentNestedReader = null; await currentNestedReader.CloseImplicitlyAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } }
/// <summary> /// For nested objects (records/readers) we have a bit more work to do; this /// method extracts it all out from the main GetValue method so it doesn't /// have to be so big. /// </summary> /// <param name="result"> </param> /// <returns> </returns> private object GetNestedObjectValue(object result) { if (result != DBNull.Value) { var recordState = result as RecordState; if (null != recordState) { if (recordState.IsNull) { result = DBNull.Value; } else { var nestedRecord = new BridgeDataRecord(_shaper, Depth + 1); nestedRecord.SetRecordSource(recordState, true); result = nestedRecord; _currentNestedRecord = nestedRecord; _currentNestedReader = null; } } else { var coordinator = result as Coordinator <RecordState>; if (null != coordinator) { var nestedReader = new BridgeDataReader( _shaper, coordinator.TypedCoordinatorFactory, Depth + 1, nextResultShaperInfos: null); result = nestedReader; _currentNestedRecord = null; _currentNestedReader = nestedReader; } else { Debug.Fail("unexpected type of nested object result: " + result.GetType()); } } } return(result); }
public void Read_and_GetFieldValue_return_data_from_underlying_reader() { var sourceEnumerable = new[] { new object[] { 1 }, new object[] { null }, new object[] { 2 }, new object[] { 2 } }; var underlyingEnumerator = ((IEnumerable<object[]>)sourceEnumerable).GetEnumerator(); var dbDataReaderMock = new Mock<DbDataReader>(); dbDataReaderMock.Setup(m => m.Read()).Returns(underlyingEnumerator.MoveNext); dbDataReaderMock.Setup(m => m.GetValue(It.IsAny<int>())).Returns((int ordinal) => underlyingEnumerator.Current[ordinal]); dbDataReaderMock.Setup(m => m.IsDBNull(It.IsAny<int>())).Returns((int ordinal) => underlyingEnumerator.Current[ordinal] == null); var rootCoordinatorFactory = Objects.MockHelper.CreateCoordinatorFactory<int, RecordState>( depth: 0, stateSlot: 0, ordinal: 0, nestedCoordinators: new CoordinatorFactory[0], producedValues: null); var shaperMock = new Mock<Shaper<RecordState>>(dbDataReaderMock.Object, /*context*/ null, /*workspace*/ null, MergeOption.AppendOnly, /*stateCount*/ 2, rootCoordinatorFactory, /*checkPermissions*/ null, /*readerOwned*/ false) { CallBase = true }; var bridgeDataReader = new BridgeDataReader(shaperMock.Object, rootCoordinatorFactory, 0, null); var actualValues = new List<int>(); while (bridgeDataReader.Read()) { actualValues.Add(bridgeDataReader.GetFieldValue<int>(0)); } Assert.Equal(new [] { 1, 2 }.ToList(), actualValues); }
/// <summary> /// Ensure that whatever column we're currently processing is implicitly closed; /// </summary> private object CloseNestedObjectImplicitly() { // it would be nice to use Interlocked.Exchange to avoid multi-thread `race condition risk // when the the bridge is being misused by the user accessing it with multiple threads. // but this is called frequently enough to have a performance impact var currentNestedRecord = _currentNestedRecord; if (null != currentNestedRecord) { _currentNestedRecord = null; currentNestedRecord.CloseImplicitly(); } var currentNestedReader = _currentNestedReader; if (null != currentNestedReader) { _currentNestedReader = null; currentNestedReader.CloseImplicitly(); } return(null); }
public void Constructors_dont_advance_the_underlying_shaper() { var sourceEnumerable = new[] { new object[] { 1 } }; var rootCoordinatorFactory = MockHelper.CreateCoordinatorFactory <int, RecordState>( depth: 0, stateSlot: 0, ordinal: 0, nestedCoordinators: new CoordinatorFactory[0], producedValues: null); var shaperMock = new Mock <Shaper <RecordState> >( Common.Internal.Materialization.MockHelper.CreateDbDataReader(sourceEnumerable), /*context*/ null, /*workspace*/ null, MergeOption.AppendOnly, /*stateCount*/ 2, rootCoordinatorFactory, /*readerOwned*/ false, /*useSpatialReader*/ false, /*shouldReleaseConnection*/ true) { CallBase = true }; shaperMock.Setup(m => m.GetEnumerator()).Returns( () => { Assert.True(false); return(null); }); // Verify these methods don't cause initialization var bridgeDataReader = new BridgeDataReader(shaperMock.Object, rootCoordinatorFactory, 0, null); bridgeDataReader.GetEnumerator(); }
public override Type GetFieldType(int ordinal) { this.EnsureInitialized(); this.AssertReaderIsOpen(nameof(GetFieldType)); return(!this._dataRecord.HasData ? BridgeDataReader.GetClrTypeFromTypeMetadata(this._defaultRecordState.GetTypeUsage(ordinal)) : this._dataRecord.GetFieldType(ordinal)); }
/// <summary> /// implementation of DbDataRecord.GetFieldType() method /// </summary> /// <param name="ordinal"> </param> /// <returns> </returns> public override Type GetFieldType(int ordinal) { AssertReaderIsOpenWithData(); return(BridgeDataReader.GetClrTypeFromTypeMetadata(GetTypeUsage(ordinal))); }