/// <summary> /// Fixes up the text/binary flag on result columns. /// Since we send the Describe command right after the Parse and before the Bind, the resulting RowDescription /// will have text format on all result columns. Fix that up. /// </summary> /// <remarks> /// Note that UnknownResultTypeList only applies to the first query, while AllResultTypesAreUnknown applies /// to all of them. /// </remarks> void FixupRowDescription(RowDescriptionMessage rowDescription, bool isFirst) { for (var i = 0; i < rowDescription.NumFields; i++) { rowDescription[i].FormatCode = (UnknownResultTypeList == null || !isFirst ? AllResultTypesAreUnknown : UnknownResultTypeList[i]) ? FormatCode.Text : FormatCode.Binary; } }
public void SetStateToInitial() { waitingForStartOfMessage = true; messageContents = new MemoryStream(); waitingForMessageLength = false; msgLengthBufferIdx = 0; msgLengthBuffer = new byte[4]; msgLength = -1; waitingToProcessMessage = false; shouldSkipBytesAtBeginningOfNextReadBuffer = false; numberOfBytesToSkipAtBeginning = 0; currentRowDescription = null; }
private void handleRowDescription(byte[] buffer, int offset, int messageLength) { ushort numFields = EndianHelpers.SwapEndianness(BitConverter.ToUInt16(buffer, offset)); offset += 2; currentRowDescription = new RowDescriptionMessage(); currentRowDescription.NumFields = numFields; currentRowDescription.FieldDescriptions = new List <RowDescriptionField>(); for (int i = 0; i < numFields; i++) { RowDescriptionField df = new RowDescriptionField(); int z = offset; while (buffer[z] != 0) { z++; } string fieldName = Encoding.ASCII.GetString(buffer, offset, z - offset); offset = z + 1; //we add 1 because string will end with a null. df.FieldName = fieldName; uint objectId = EndianHelpers.SwapEndianness(BitConverter.ToUInt32(buffer, offset)); offset += 4; df.ObjectId = objectId; ushort attrId = EndianHelpers.SwapEndianness(BitConverter.ToUInt16(buffer, offset)); offset += 2; df.AttrId = attrId; uint dataTypeObjectId = EndianHelpers.SwapEndianness(BitConverter.ToUInt32(buffer, offset)); offset += 4; df.DataTypeObjectId = dataTypeObjectId; ushort dataTypeSize = EndianHelpers.SwapEndianness(BitConverter.ToUInt16(buffer, offset)); offset += 2; df.DataTypeSize = dataTypeSize; uint typeModifier = EndianHelpers.SwapEndianness(BitConverter.ToUInt32(buffer, offset)); offset += 4; df.TypeModifier = typeModifier; ushort formatCode = EndianHelpers.SwapEndianness(BitConverter.ToUInt16(buffer, offset)); offset += 2; df.FormatCode = formatCode; currentRowDescription.FieldDescriptions.Add(df); } var shouldModify = _shouldModifyTable(currentRowDescription.FieldDescriptions.First().ObjectId); currentRowDescription.ShouldModify = shouldModify; }
RowDescriptionMessage(RowDescriptionMessage source) { Count = source.Count; _fields = new FieldDescription?[Count]; for (var i = 0; i < Count; i++) { _fields[i] = source._fields[i] !.Clone(); } _nameIndex = new Dictionary <string, int>(source._nameIndex); if (source._insensitiveIndex?.Count > 0) { _insensitiveIndex = new Dictionary <string, int>(source._insensitiveIndex); } }
/// <summary> /// Fixes up the text/binary flag on result columns. /// Since we send the Describe command right after the Parse and before the Bind, the resulting RowDescription /// will have text format on all result columns. Fix that up. /// </summary> /// <remarks> /// Note that UnknownResultTypeList only applies to the first query, while AllResultTypesAreUnknown applies /// to all of them. /// </remarks> void FixupRowDescription(RowDescriptionMessage rowDescription, bool isFirst) { for (var i = 0; i < rowDescription.NumFields; i++) { var field = rowDescription[i]; field.FormatCode = (UnknownResultTypeList == null || !isFirst ? AllResultTypesAreUnknown : UnknownResultTypeList[i]) ? FormatCode.Text : FormatCode.Binary; if (field.FormatCode == FormatCode.Text) { field.Handler = Connection.Connector.TypeHandlerRegistry.UnrecognizedTypeHandler; } } }
BackendMessage ParseServerMessage(NpgsqlBuffer buf, BackendMessageCode code, int len, DataRowLoadingMode dataRowLoadingMode) { switch (code) { case BackendMessageCode.RowDescription: // TODO: Recycle var rowDescriptionMessage = new RowDescriptionMessage(); return rowDescriptionMessage.Load(buf, TypeHandlerRegistry); case BackendMessageCode.DataRow: Contract.Assert(dataRowLoadingMode == DataRowLoadingMode.NonSequential || dataRowLoadingMode == DataRowLoadingMode.Sequential); return dataRowLoadingMode == DataRowLoadingMode.Sequential ? _dataRowSequentialMessage.Load(buf) : _dataRowNonSequentialMessage.Load(buf); case BackendMessageCode.CompletedResponse: return _commandCompleteMessage.Load(buf, len); case BackendMessageCode.ReadyForQuery: var rfq = _readyForQueryMessage.Load(buf); TransactionStatus = rfq.TransactionStatusIndicator; return rfq; case BackendMessageCode.EmptyQueryResponse: return EmptyQueryMessage.Instance; case BackendMessageCode.ParseComplete: return ParseCompleteMessage.Instance; case BackendMessageCode.ParameterDescription: return _parameterDescriptionMessage.Load(buf); case BackendMessageCode.BindComplete: return BindCompleteMessage.Instance; case BackendMessageCode.NoData: return NoDataMessage.Instance; case BackendMessageCode.CloseComplete: return CloseCompletedMessage.Instance; case BackendMessageCode.ParameterStatus: HandleParameterStatus(buf.ReadNullTerminatedString(), buf.ReadNullTerminatedString()); return null; case BackendMessageCode.NoticeResponse: // TODO: Recycle FireNotice(new NpgsqlError(buf)); return null; case BackendMessageCode.NotificationResponse: FireNotification(new NpgsqlNotificationEventArgs(buf)); return null; case BackendMessageCode.AuthenticationRequest: var authType = (AuthenticationRequestType)buf.ReadInt32(); _log.Trace("Received AuthenticationRequest of type " + authType); switch (authType) { case AuthenticationRequestType.AuthenticationOk: return AuthenticationOkMessage.Instance; case AuthenticationRequestType.AuthenticationCleartextPassword: return AuthenticationCleartextPasswordMessage.Instance; case AuthenticationRequestType.AuthenticationMD5Password: return AuthenticationMD5PasswordMessage.Load(buf); case AuthenticationRequestType.AuthenticationGSS: return AuthenticationGSSMessage.Instance; case AuthenticationRequestType.AuthenticationSSPI: return AuthenticationSSPIMessage.Instance; case AuthenticationRequestType.AuthenticationGSSContinue: return AuthenticationGSSContinueMessage.Load(buf, len); default: throw new NotSupportedException(String.Format(L10N.AuthenticationMethodNotSupported, authType)); } case BackendMessageCode.BackendKeyData: BackendProcessId = buf.ReadInt32(); BackendSecretKey = buf.ReadInt32(); return null; case BackendMessageCode.CopyData: case BackendMessageCode.CopyDone: case BackendMessageCode.CancelRequest: case BackendMessageCode.CopyDataRows: case BackendMessageCode.CopyInResponse: case BackendMessageCode.CopyOutResponse: throw new NotImplementedException(); case BackendMessageCode.PortalSuspended: case BackendMessageCode.IO_ERROR: Debug.Fail("Unimplemented message: " + code); throw new NotImplementedException("Unimplemented message: " + code); case BackendMessageCode.ErrorResponse: return null; case BackendMessageCode.FunctionCallResponse: // We don't use the obsolete function call protocol throw new Exception("Unexpected backend message: " + code); default: throw PGUtil.ThrowIfReached("Unknown backend message code: " + code); } }
internal DbColumnSchemaGenerator(NpgsqlConnection connection, RowDescriptionMessage rowDescription, bool fetchAdditionalInfo) { _connection = connection; _rowDescription = rowDescription; _fetchAdditionalInfo = fetchAdditionalInfo; }
public Enumerator(RowDescriptionMessage rowDescription) => _rowDescription = rowDescription;
internal DbColumnSchemaGenerator(NpgsqlConnection connection, RowDescriptionMessage rowDescription) { _connection = connection; _rowDescription = rowDescription; }