private void SetupColMetaData(TdsPackageReader reader, TdsPackageWriter writer, int tdsType, byte precision, byte scale, bool isPlp) { Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); var r = reader.CurrentResultSet.ColumnsMetadata = new ColumnsMetadata(1); var w = writer.ColumnsMetadata = new MetadataBulkCopy[1]; var collation = new SqlCollations { Info = 0x00d00409, SortId = 0x34 }; var encoding = Encoding.GetEncoding(collation.GetCodePage()); w[0] = new MetadataBulkCopy(); r[0].TdsType = (byte)tdsType; w[0].TdsType = (byte)tdsType; r[0].Scale = scale; w[0].Scale = scale; r[0].IsPlp = isPlp; w[0].IsPlp = isPlp; r[0].IsPlp = isPlp; w[0].Length = scale;// nullable date testfix r[0].Encoding = encoding; w[0].Encoding = encoding; w[0].Collation = collation; w[0].Precision = precision; w[0].MetaType = TdsMetaType.TdsTypes[tdsType]; r[0].MetaType = TdsMetaType.TdsTypes[tdsType]; r[0].IsTextOrImage = r[0].MetaType.IsTextOrImage; w[0].IsTextOrImage = r[0].MetaType.IsTextOrImage; }
public static void SendRpc(this TdsPackageWriter writer, SqlCollations defaultCollation, FormattableString sql, long sqlConnectionId) { writer.NewPackage(TdsEnums.MT_RPC); writer.WriteMarsHeader(sqlConnectionId); writer.WriteInt16(0xffff); writer.WriteInt16(TdsEnums.RPC_PROCID_EXECUTESQL); // Options writer.WriteInt16(TdsEnums.RPC_PARAM_DEFAULT); // Stream out parameters var parameters = CreateParameters(sql); foreach (var parameter in parameters) { // parameters can be unnamed var param = parameter; var value = parameter.Value; var isNull = value == null; writer.WriteByteLenString(param.Name); // Write parameter status writer.WriteByte(parameter.Status); var p = parameter; var mt = p.MetaData; WriteTdsTypeInfo(writer, mt, p.Size, p.IsNull, defaultCollation, p.Scale); WriteValue(writer, value, mt, isNull); } writer.SendLastMessage(); }
private static void WriteSessionRecoveryFeatureRequest(TdsPackageWriter writer, SessionData reconnectData) { var(_, initialLength, currentLength, writeState) = SessionRecoveryFeatureRequestLengths(reconnectData); writer.WriteByte(TdsEnums.FEATUREEXT_SRECOVERY); if (reconnectData == null) { writer.WriteInt32(0); } else { writer.WriteInt32(8 + initialLength + currentLength); // length of data w/o total length (initial + current + 2 * sizeof(DWORD)) writer.WriteInt32(initialLength); writer.WriteByteLenString(reconnectData.InitialDatabase); writer.WriteCollation(reconnectData.InitialCollation); writer.WriteByteLenString(reconnectData.InitialLanguage); for (var i = 0; i < SessionData.MaxNumberOfSessionStates; i++) { if (reconnectData.InitialState[i] != null) { writer.WriteByte((byte)i); if (reconnectData.InitialState[i].Length < 0xFF) { writer.WriteByte((byte)reconnectData.InitialState[i].Length); } else { writer.WriteByte(0xFF); writer.WriteInt32(reconnectData.InitialState[i].Length); } writer.WriteByteArray(reconnectData.InitialState[i]); } } writer.WriteInt32(currentLength); writer.WriteByteLenString(reconnectData.Database != reconnectData.InitialDatabase ? reconnectData.Database : null); writer.WriteCollation(SqlCollations.AreSame(reconnectData.InitialCollation, reconnectData.Collation) ? null : reconnectData.Collation); writer.WriteByteLenString(reconnectData.Language != reconnectData.InitialLanguage ? reconnectData.Language : null); for (var i = 0; i < SessionData.MaxNumberOfSessionStates; i++) { if (writeState[i]) { writer.WriteByte((byte)i); if (reconnectData.Delta[i].DataLength < 0xFF) { writer.WriteByte((byte)reconnectData.Delta[i].DataLength); } else { writer.WriteByte(0xFF); writer.WriteInt32(reconnectData.Delta[i].DataLength); } writer.WriteByteArray(reconnectData.Delta[i].Data); } } } }
private static (int totalLength, int initialLength, int currentLength, bool[] writeState) SessionRecoveryFeatureRequestLengths(SessionData reconnectData) { var totalLength = 1; var initialLength = 0; // sizeof(DWORD) - length itself var currentLength = 0; // sizeof(DWORD) - length itself var writeState = new bool[SessionData.MaxNumberOfSessionStates]; if (reconnectData == null) { totalLength += 4; } else { Debug.Assert(reconnectData.UnrecoverableStatesCount == 0, "Unrecoverable state count should be 0"); initialLength += 1 + 2 * NullAwareStringLength(reconnectData.InitialDatabase); initialLength += 1 + 2 * NullAwareStringLength(reconnectData.InitialLanguage); initialLength += reconnectData.InitialCollation == null ? 1 : 6; for (var i = 0; i < SessionData.MaxNumberOfSessionStates; i++) { if (reconnectData.InitialState[i] != null) { initialLength += 1 /* StateId*/ + StateValueLength(reconnectData.InitialState[i].Length); } } currentLength += 1 + 2 * (reconnectData.InitialDatabase == reconnectData.Database ? 0 : NullAwareStringLength(reconnectData.Database)); currentLength += 1 + 2 * (reconnectData.InitialLanguage == reconnectData.Language ? 0 : NullAwareStringLength(reconnectData.Language)); currentLength += reconnectData.Collation != null && !SqlCollations.AreSame(reconnectData.Collation, reconnectData.InitialCollation) ? 6 : 1; for (var i = 0; i < SessionData.MaxNumberOfSessionStates; i++) { if (reconnectData.Delta[i] != null) { Debug.Assert(reconnectData.Delta[i].Recoverable, "State should be recoverable"); writeState[i] = true; if (reconnectData.InitialState[i] != null && reconnectData.InitialState[i].Length == reconnectData.Delta[i].DataLength) { writeState[i] = false; for (var j = 0; j < reconnectData.Delta[i].DataLength; j++) { if (reconnectData.InitialState[i][j] != reconnectData.Delta[i].Data[j]) { writeState[i] = true; break; } } } if (writeState[i]) { currentLength += 1 /* StateId*/ + StateValueLength(reconnectData.Delta[i].DataLength); } } } totalLength += initialLength + currentLength + 12 /* length fields (initial, current, total) */; } return(totalLength, initialLength, currentLength, writeState); }
public static async Task SendRpcASync(this TdsPackageWriter writer, SqlCollations defaultCollation, FormattableString sql, long sqlConnectionId) { await Task.Run(() => SendRpc(writer, defaultCollation, sql, sqlConnectionId)); }
public static void WriteTdsTypeInfo(this TdsPackageWriter writer, TdsMetaType.MetaDataWrite metaData, int size, bool isNull, SqlCollations defaultCollation, byte scale) { var mt = metaData; writer.WriteByte(mt.NullableType); writer.WriteTypeInfoLen(mt, size, isNull); //typeinfo varlen if (mt.HasCollation) { writer.WriteCollation2(defaultCollation); } if (mt.HasPrecision) { writer.WriteByte(28); //Max clr precision } if (mt.HasScale) { writer.WriteByte(scale); // } writer.WriteParameterLen(metaData, size, isNull); //len parameter }
public static void WriteCollation2(this TdsPackageWriter writer, SqlCollations collation) { writer.WriteUInt32(collation.Info); writer.WriteByte(collation.SortId); }