Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / whidbey / NetFxQFE / ndp / fx / src / Data / Microsoft / SqlServer / Server / sqlpipe.cs / 1 / sqlpipe.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //[....] //daltodov //----------------------------------------------------------------------------- namespace Microsoft.SqlServer.Server { using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.Data.Sql; using System.Data.Common; using System.Data.SqlClient; using System.Data.SqlTypes; using System.Diagnostics; // SqlPipe // Abstraction of TDS data/message channel exposed to user. #if WINFSInternalOnly internal #else public #endif sealed class SqlPipe { SmiContext _smiContext; SmiRecordBuffer _recordBufferSent; // Last recordBuffer sent to pipe (for push model SendEnd). SqlMetaData[] _metaDataSent; // Metadata of last resultset started (for push model). Overloaded to indicate if push started or not (non-null/null) SmiEventSink_Default _eventSink; // Eventsink to use when calling SmiContext entrypoints bool _isBusy; // Is this pipe currently handling an operation? bool _hadErrorInResultSet; // true if an exception was thrown from within various bodies; used to control cleanup during SendResultsEnd internal SqlPipe( SmiContext smiContext ) { _smiContext = smiContext; _eventSink = new SmiEventSink_Default(); } // // Public methods // public void ExecuteAndSend( SqlCommand command ) { SetPipeBusy( ); try { EnsureNormalSendValid( "ExecuteAndSend" ); if ( null == command ) { throw ADP.ArgumentNull( "command" ); } SqlConnection connection = command.Connection; // if the command doesn't have a connection set up, try to set one up on it's behalf if ( null == connection ) { using ( SqlConnection newConnection = new SqlConnection( "Context Connection=true" ) ) { newConnection.Open( ); // use try-finally to restore command's connection property to it's original state try { command.Connection = newConnection; command.ExecuteToPipe( _smiContext ); } finally { command.Connection = null; } } } else { // validate connection state if ( ConnectionState.Open != connection.State ) { throw ADP.ClosedConnectionError(); } // validate connection is current scope's connection SqlInternalConnectionSmi internalConnection = connection.InnerConnection as SqlInternalConnectionSmi; if ( null == internalConnection ) { throw SQL.SqlPipeCommandHookedUpToNonContextConnection( ); } command.ExecuteToPipe( _smiContext ); } } finally { ClearPipeBusy( ); } } // Equivalent to TSQL PRINT statement -- sends an info-only message. public void Send( string message ) { ADP.CheckArgumentNull(message, "message"); if ( SmiMetaData.MaxUnicodeCharacters < message.Length ) { throw SQL.SqlPipeMessageTooLong( message.Length ); } SetPipeBusy( ); try { EnsureNormalSendValid( "Send" ); _smiContext.SendMessageToPipe( message, _eventSink ); // Handle any errors that are reported. _eventSink.ProcessMessagesAndThrow(); } finally { ClearPipeBusy( ); } } // Send results from SqlDataReader public void Send( SqlDataReader reader ) { ADP.CheckArgumentNull(reader, "reader"); SetPipeBusy( ); try { EnsureNormalSendValid( "Send" ); do { SmiExtendedMetaData[] columnMetaData = reader.GetInternalSmiMetaData(); if (null != columnMetaData && 0 != columnMetaData.Length) { // SQLBUDT #340528 -- don't send empty results. using ( SmiRecordBuffer recordBuffer = _smiContext.CreateRecordBuffer(columnMetaData, _eventSink) ) { _eventSink.ProcessMessagesAndThrow(); // Handle any errors that are reported. _smiContext.SendResultsStartToPipe( recordBuffer, _eventSink ); _eventSink.ProcessMessagesAndThrow(); // Handle any errors that are reported. try { while( reader.Read( ) ) { if (SmiContextFactory.Instance.NegotiatedSmiVersion >= SmiContextFactory.KatmaiVersion) { ValueUtilsSmi.FillCompatibleSettersFromReader(_eventSink, recordBuffer, new List(columnMetaData), reader); } else { ValueUtilsSmi.FillCompatibleITypedSettersFromReader(_eventSink, recordBuffer, columnMetaData, reader); } _smiContext.SendResultsRowToPipe( recordBuffer, _eventSink ); _eventSink.ProcessMessagesAndThrow(); // Handle any errors that are reported. } } finally { _smiContext.SendResultsEndToPipe( recordBuffer, _eventSink ); _eventSink.ProcessMessagesAndThrow(); // Handle any errors that are reported. } } } } while ( reader.NextResult( ) ); } finally { ClearPipeBusy( ); } } public void Send( SqlDataRecord record ) { ADP.CheckArgumentNull(record, "record"); SetPipeBusy( ); try { EnsureNormalSendValid( "Send" ); if (0 != record.FieldCount) { // SQLBUDT #340564 -- don't send empty records. SmiRecordBuffer recordBuffer; if (record.RecordContext == _smiContext) { recordBuffer = record.RecordBuffer; } else { // SendResultsRowToPipe() only takes a RecordBuffer created by an SmiContext SmiExtendedMetaData[] columnMetaData = record.InternalGetSmiMetaData(); recordBuffer = _smiContext.CreateRecordBuffer(columnMetaData, _eventSink); if (SmiContextFactory.Instance.NegotiatedSmiVersion >= SmiContextFactory.KatmaiVersion) { ValueUtilsSmi.FillCompatibleSettersFromRecord(_eventSink, recordBuffer, columnMetaData, record, null /* no default values */); } else { ValueUtilsSmi.FillCompatibleITypedSettersFromRecord(_eventSink, recordBuffer, columnMetaData, record); } } _smiContext.SendResultsStartToPipe( recordBuffer, _eventSink ); _eventSink.ProcessMessagesAndThrow(); // Handle any errors that are reported. // If SendResultsStartToPipe succeeded, then SendResultsEndToPipe must be called. try { _smiContext.SendResultsRowToPipe( recordBuffer, _eventSink ); _eventSink.ProcessMessagesAndThrow(); // Handle any errors that are reported. } finally { _smiContext.SendResultsEndToPipe( recordBuffer, _eventSink ); _eventSink.ProcessMessagesAndThrow(); // Handle any errors that are reported. } } } finally { ClearPipeBusy( ); } } public void SendResultsStart( SqlDataRecord record ) { ADP.CheckArgumentNull(record, "record"); SetPipeBusy( ); try { EnsureNormalSendValid( "SendResultsStart" ); SmiRecordBuffer recordBuffer = record.RecordBuffer; if (record.RecordContext == _smiContext) { recordBuffer = record.RecordBuffer; } else { recordBuffer = _smiContext.CreateRecordBuffer(record.InternalGetSmiMetaData(), _eventSink); // Only MetaData needed for sending start } _smiContext.SendResultsStartToPipe( recordBuffer, _eventSink ); // Handle any errors that are reported. _eventSink.ProcessMessagesAndThrow(); // remember sent buffer info so it can be used in send row/end. _recordBufferSent = recordBuffer; _metaDataSent = record.InternalGetMetaData(); } finally { ClearPipeBusy( ); } } public void SendResultsRow( SqlDataRecord record ) { ADP.CheckArgumentNull(record, "record"); SetPipeBusy( ); try { EnsureResultStarted( "SendResultsRow" ); if ( _hadErrorInResultSet ) { throw SQL.SqlPipeErrorRequiresSendEnd(); } // Assume error state unless cleared below _hadErrorInResultSet = true; SmiRecordBuffer recordBuffer; if (record.RecordContext == _smiContext) { recordBuffer = record.RecordBuffer; } else { SmiExtendedMetaData[] columnMetaData = record.InternalGetSmiMetaData(); recordBuffer = _smiContext.CreateRecordBuffer(columnMetaData, _eventSink); if (SmiContextFactory.Instance.NegotiatedSmiVersion >= SmiContextFactory.KatmaiVersion) { ValueUtilsSmi.FillCompatibleSettersFromRecord(_eventSink, recordBuffer, columnMetaData, record, null /* no default values */); } else { ValueUtilsSmi.FillCompatibleITypedSettersFromRecord(_eventSink, recordBuffer, columnMetaData, record); } } _smiContext.SendResultsRowToPipe( recordBuffer, _eventSink ); // Handle any errors that are reported. _eventSink.ProcessMessagesAndThrow(); // We successfully traversed the send, clear error state _hadErrorInResultSet = false; } finally { ClearPipeBusy( ); } } public void SendResultsEnd( ) { SetPipeBusy( ); try { EnsureResultStarted( "SendResultsEnd" ); _smiContext.SendResultsEndToPipe( _recordBufferSent, _eventSink ); // Once end called down to native code, assume end of resultset _metaDataSent = null; _recordBufferSent = null; _hadErrorInResultSet = false; // Handle any errors that are reported. _eventSink.ProcessMessagesAndThrow(); } finally { ClearPipeBusy( ); } } // This isn't speced, but it may not be a bad idea to implement... public bool IsSendingResults { get { return null != _metaDataSent; } } internal void OnOutOfScope( ) { _metaDataSent = null; _recordBufferSent = null; _hadErrorInResultSet = false; _isBusy = false; } // Pipe busy status. // Ensures user code cannot call any APIs while a send is in progress. // // Public methods must call this method before sending anything to the unmanaged pipe. // Once busy status is set, it must clear before returning from the calling method // ( i.e. clear should be in a finally block). private void SetPipeBusy( ) { if ( _isBusy ) { throw SQL.SqlPipeIsBusy( ); } _isBusy = true; } // Clear the pipe's busy status. private void ClearPipeBusy( ) { _isBusy = false; } // // State validation // One of the Ensure* validation methods should appear at the top of every public method // // Default validation method // Ensures Pipe is not currently transmitting a push-model resultset private void EnsureNormalSendValid( string methodName ) { if ( IsSendingResults ) { throw SQL.SqlPipeAlreadyHasAnOpenResultSet( methodName ); } } private void EnsureResultStarted( string methodName ) { if ( !IsSendingResults ) { throw SQL.SqlPipeDoesNotHaveAnOpenResultSet( methodName ); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //[....] //daltodov //----------------------------------------------------------------------------- namespace Microsoft.SqlServer.Server { using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.Data.Sql; using System.Data.Common; using System.Data.SqlClient; using System.Data.SqlTypes; using System.Diagnostics; // SqlPipe // Abstraction of TDS data/message channel exposed to user. #if WINFSInternalOnly internal #else public #endif sealed class SqlPipe { SmiContext _smiContext; SmiRecordBuffer _recordBufferSent; // Last recordBuffer sent to pipe (for push model SendEnd). SqlMetaData[] _metaDataSent; // Metadata of last resultset started (for push model). Overloaded to indicate if push started or not (non-null/null) SmiEventSink_Default _eventSink; // Eventsink to use when calling SmiContext entrypoints bool _isBusy; // Is this pipe currently handling an operation? bool _hadErrorInResultSet; // true if an exception was thrown from within various bodies; used to control cleanup during SendResultsEnd internal SqlPipe( SmiContext smiContext ) { _smiContext = smiContext; _eventSink = new SmiEventSink_Default(); } // // Public methods // public void ExecuteAndSend( SqlCommand command ) { SetPipeBusy( ); try { EnsureNormalSendValid( "ExecuteAndSend" ); if ( null == command ) { throw ADP.ArgumentNull( "command" ); } SqlConnection connection = command.Connection; // if the command doesn't have a connection set up, try to set one up on it's behalf if ( null == connection ) { using ( SqlConnection newConnection = new SqlConnection( "Context Connection=true" ) ) { newConnection.Open( ); // use try-finally to restore command's connection property to it's original state try { command.Connection = newConnection; command.ExecuteToPipe( _smiContext ); } finally { command.Connection = null; } } } else { // validate connection state if ( ConnectionState.Open != connection.State ) { throw ADP.ClosedConnectionError(); } // validate connection is current scope's connection SqlInternalConnectionSmi internalConnection = connection.InnerConnection as SqlInternalConnectionSmi; if ( null == internalConnection ) { throw SQL.SqlPipeCommandHookedUpToNonContextConnection( ); } command.ExecuteToPipe( _smiContext ); } } finally { ClearPipeBusy( ); } } // Equivalent to TSQL PRINT statement -- sends an info-only message. public void Send( string message ) { ADP.CheckArgumentNull(message, "message"); if ( SmiMetaData.MaxUnicodeCharacters < message.Length ) { throw SQL.SqlPipeMessageTooLong( message.Length ); } SetPipeBusy( ); try { EnsureNormalSendValid( "Send" ); _smiContext.SendMessageToPipe( message, _eventSink ); // Handle any errors that are reported. _eventSink.ProcessMessagesAndThrow(); } finally { ClearPipeBusy( ); } } // Send results from SqlDataReader public void Send( SqlDataReader reader ) { ADP.CheckArgumentNull(reader, "reader"); SetPipeBusy( ); try { EnsureNormalSendValid( "Send" ); do { SmiExtendedMetaData[] columnMetaData = reader.GetInternalSmiMetaData(); if (null != columnMetaData && 0 != columnMetaData.Length) { // SQLBUDT #340528 -- don't send empty results. using ( SmiRecordBuffer recordBuffer = _smiContext.CreateRecordBuffer(columnMetaData, _eventSink) ) { _eventSink.ProcessMessagesAndThrow(); // Handle any errors that are reported. _smiContext.SendResultsStartToPipe( recordBuffer, _eventSink ); _eventSink.ProcessMessagesAndThrow(); // Handle any errors that are reported. try { while( reader.Read( ) ) { if (SmiContextFactory.Instance.NegotiatedSmiVersion >= SmiContextFactory.KatmaiVersion) { ValueUtilsSmi.FillCompatibleSettersFromReader(_eventSink, recordBuffer, new List(columnMetaData), reader); } else { ValueUtilsSmi.FillCompatibleITypedSettersFromReader(_eventSink, recordBuffer, columnMetaData, reader); } _smiContext.SendResultsRowToPipe( recordBuffer, _eventSink ); _eventSink.ProcessMessagesAndThrow(); // Handle any errors that are reported. } } finally { _smiContext.SendResultsEndToPipe( recordBuffer, _eventSink ); _eventSink.ProcessMessagesAndThrow(); // Handle any errors that are reported. } } } } while ( reader.NextResult( ) ); } finally { ClearPipeBusy( ); } } public void Send( SqlDataRecord record ) { ADP.CheckArgumentNull(record, "record"); SetPipeBusy( ); try { EnsureNormalSendValid( "Send" ); if (0 != record.FieldCount) { // SQLBUDT #340564 -- don't send empty records. SmiRecordBuffer recordBuffer; if (record.RecordContext == _smiContext) { recordBuffer = record.RecordBuffer; } else { // SendResultsRowToPipe() only takes a RecordBuffer created by an SmiContext SmiExtendedMetaData[] columnMetaData = record.InternalGetSmiMetaData(); recordBuffer = _smiContext.CreateRecordBuffer(columnMetaData, _eventSink); if (SmiContextFactory.Instance.NegotiatedSmiVersion >= SmiContextFactory.KatmaiVersion) { ValueUtilsSmi.FillCompatibleSettersFromRecord(_eventSink, recordBuffer, columnMetaData, record, null /* no default values */); } else { ValueUtilsSmi.FillCompatibleITypedSettersFromRecord(_eventSink, recordBuffer, columnMetaData, record); } } _smiContext.SendResultsStartToPipe( recordBuffer, _eventSink ); _eventSink.ProcessMessagesAndThrow(); // Handle any errors that are reported. // If SendResultsStartToPipe succeeded, then SendResultsEndToPipe must be called. try { _smiContext.SendResultsRowToPipe( recordBuffer, _eventSink ); _eventSink.ProcessMessagesAndThrow(); // Handle any errors that are reported. } finally { _smiContext.SendResultsEndToPipe( recordBuffer, _eventSink ); _eventSink.ProcessMessagesAndThrow(); // Handle any errors that are reported. } } } finally { ClearPipeBusy( ); } } public void SendResultsStart( SqlDataRecord record ) { ADP.CheckArgumentNull(record, "record"); SetPipeBusy( ); try { EnsureNormalSendValid( "SendResultsStart" ); SmiRecordBuffer recordBuffer = record.RecordBuffer; if (record.RecordContext == _smiContext) { recordBuffer = record.RecordBuffer; } else { recordBuffer = _smiContext.CreateRecordBuffer(record.InternalGetSmiMetaData(), _eventSink); // Only MetaData needed for sending start } _smiContext.SendResultsStartToPipe( recordBuffer, _eventSink ); // Handle any errors that are reported. _eventSink.ProcessMessagesAndThrow(); // remember sent buffer info so it can be used in send row/end. _recordBufferSent = recordBuffer; _metaDataSent = record.InternalGetMetaData(); } finally { ClearPipeBusy( ); } } public void SendResultsRow( SqlDataRecord record ) { ADP.CheckArgumentNull(record, "record"); SetPipeBusy( ); try { EnsureResultStarted( "SendResultsRow" ); if ( _hadErrorInResultSet ) { throw SQL.SqlPipeErrorRequiresSendEnd(); } // Assume error state unless cleared below _hadErrorInResultSet = true; SmiRecordBuffer recordBuffer; if (record.RecordContext == _smiContext) { recordBuffer = record.RecordBuffer; } else { SmiExtendedMetaData[] columnMetaData = record.InternalGetSmiMetaData(); recordBuffer = _smiContext.CreateRecordBuffer(columnMetaData, _eventSink); if (SmiContextFactory.Instance.NegotiatedSmiVersion >= SmiContextFactory.KatmaiVersion) { ValueUtilsSmi.FillCompatibleSettersFromRecord(_eventSink, recordBuffer, columnMetaData, record, null /* no default values */); } else { ValueUtilsSmi.FillCompatibleITypedSettersFromRecord(_eventSink, recordBuffer, columnMetaData, record); } } _smiContext.SendResultsRowToPipe( recordBuffer, _eventSink ); // Handle any errors that are reported. _eventSink.ProcessMessagesAndThrow(); // We successfully traversed the send, clear error state _hadErrorInResultSet = false; } finally { ClearPipeBusy( ); } } public void SendResultsEnd( ) { SetPipeBusy( ); try { EnsureResultStarted( "SendResultsEnd" ); _smiContext.SendResultsEndToPipe( _recordBufferSent, _eventSink ); // Once end called down to native code, assume end of resultset _metaDataSent = null; _recordBufferSent = null; _hadErrorInResultSet = false; // Handle any errors that are reported. _eventSink.ProcessMessagesAndThrow(); } finally { ClearPipeBusy( ); } } // This isn't speced, but it may not be a bad idea to implement... public bool IsSendingResults { get { return null != _metaDataSent; } } internal void OnOutOfScope( ) { _metaDataSent = null; _recordBufferSent = null; _hadErrorInResultSet = false; _isBusy = false; } // Pipe busy status. // Ensures user code cannot call any APIs while a send is in progress. // // Public methods must call this method before sending anything to the unmanaged pipe. // Once busy status is set, it must clear before returning from the calling method // ( i.e. clear should be in a finally block). private void SetPipeBusy( ) { if ( _isBusy ) { throw SQL.SqlPipeIsBusy( ); } _isBusy = true; } // Clear the pipe's busy status. private void ClearPipeBusy( ) { _isBusy = false; } // // State validation // One of the Ensure* validation methods should appear at the top of every public method // // Default validation method // Ensures Pipe is not currently transmitting a push-model resultset private void EnsureNormalSendValid( string methodName ) { if ( IsSendingResults ) { throw SQL.SqlPipeAlreadyHasAnOpenResultSet( methodName ); } } private void EnsureResultStarted( string methodName ) { if ( !IsSendingResults ) { throw SQL.SqlPipeDoesNotHaveAnOpenResultSet( methodName ); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- AffineTransform3D.cs
- Content.cs
- KnownTypesProvider.cs
- TypeBuilderInstantiation.cs
- XmlLoader.cs
- Point3DAnimation.cs
- XmlSerializationGeneratedCode.cs
- _DigestClient.cs
- HandleRef.cs
- MemberBinding.cs
- StringValidatorAttribute.cs
- TaskFactory.cs
- ParseNumbers.cs
- Splitter.cs
- SiteMapDesignerDataSourceView.cs
- TextTreeRootTextBlock.cs
- COM2IPerPropertyBrowsingHandler.cs
- RenderCapability.cs
- FontConverter.cs
- RelatedCurrencyManager.cs
- DSASignatureDeformatter.cs
- TextEditorLists.cs
- DaylightTime.cs
- ConfigurationSection.cs
- BaseUriHelper.cs
- WorkflowCompensationBehavior.cs
- CornerRadiusConverter.cs
- ActivityStatusChangeEventArgs.cs
- HttpStaticObjectsCollectionBase.cs
- ComplexPropertyEntry.cs
- AnonymousIdentificationSection.cs
- SafeNativeMethods.cs
- dsa.cs
- ResolvedKeyFrameEntry.cs
- SaveCardRequest.cs
- ReadOnlyDataSource.cs
- JapaneseCalendar.cs
- MetadataHelper.cs
- IntSecurity.cs
- Ipv6Element.cs
- ConfigurationPermission.cs
- ValidationSettings.cs
- CellLabel.cs
- WebPartTransformerCollection.cs
- WinFormsUtils.cs
- GroupAggregateExpr.cs
- GroupItem.cs
- MultiDataTrigger.cs
- SaveFileDialog.cs
- TableItemStyle.cs
- ScriptManager.cs
- BamlStream.cs
- ChildTable.cs
- UInt64.cs
- PagesSection.cs
- _HeaderInfo.cs
- QilChoice.cs
- EncoderExceptionFallback.cs
- WindowsProgressbar.cs
- WizardPanelChangingEventArgs.cs
- EntityDataSourceWrapperPropertyDescriptor.cs
- SafePointer.cs
- ControlValuePropertyAttribute.cs
- MediaPlayerState.cs
- PassportIdentity.cs
- ProcessManager.cs
- PasswordBoxAutomationPeer.cs
- FieldNameLookup.cs
- TimersDescriptionAttribute.cs
- NCryptSafeHandles.cs
- ErrorLog.cs
- StickyNote.cs
- Action.cs
- XsltOutput.cs
- UserControlAutomationPeer.cs
- ASCIIEncoding.cs
- GridViewColumn.cs
- NetPeerTcpBindingElement.cs
- DrawingVisual.cs
- ByteFacetDescriptionElement.cs
- RealizationDrawingContextWalker.cs
- DataKeyCollection.cs
- Triplet.cs
- QueryStringHandler.cs
- EmptyQuery.cs
- ArrayMergeHelper.cs
- SerialPinChanges.cs
- StickyNoteContentControl.cs
- StrokeNodeOperations.cs
- DeviceSpecificChoiceCollection.cs
- SchemaAttDef.cs
- XPathItem.cs
- InternalResources.cs
- TextBoxLine.cs
- COM2IVsPerPropertyBrowsingHandler.cs
- XpsDocument.cs
- ConditionalWeakTable.cs
- XamlFilter.cs
- Properties.cs
- DataGridDefaultColumnWidthTypeConverter.cs