public void can_write_to_our_context() { var buffer = new byte[] {1, 2, 3, 4, 5, 6, 7}; var mgr = new BufferManager(100, 10); var context = new WriterContext(mgr); var sut = new ByteBufferWriter(buffer, 0, buffer.Length); sut.Write(context); context.GetPackets()[0].Buffer.Should().BeSubsetOf(buffer); }
public void can_do_partial_write() { var buffer = new byte[] { 1, 2, 3, 4, 5, 6, 7 }; var mgr = new BufferManager(100, 10); var context = new WriterContext(mgr); context.BytesLeftToEnqueue = 4; var sut = new ByteBufferWriter(buffer, 0, buffer.Length); var actual = sut.Write(context); actual.Should().BeFalse(); }
public void partial_bytes_are_copied() { var buffer = new byte[] { 1, 2, 3, 4, 5, 6, 7 }; var mgr = new BufferManager(100, 10); var context = new WriterContext(mgr); context.BytesLeftToEnqueue = 4; var sut = new ByteBufferWriter(buffer, 0, buffer.Length); sut.Write(context); context.GetPackets()[0].Buffer[3].Should().Be(4); }
public void can_continue_on_a_partial_write() { var buffer = new byte[] { 1, 2, 3, 4, 5, 6, 7 }; var mgr = new BufferManager(100, 10); var context = new WriterContext(mgr); context.BytesLeftToEnqueue = 4; var sut = new ByteBufferWriter(buffer, 0, buffer.Length); context.BytesLeftToEnqueue = 4; sut.Write(context); context.BytesLeftToEnqueue = 10; var actual = sut.Write(context); actual.Should().BeTrue(); var packet = context.GetPackets()[1]; packet.Buffer[packet.Offset + 2].Should().Be(7); }
public bool WriteQueryCommand(ref CommandListPosition commandListPosition, IDictionary <string, CachedProcedure?> cachedProcedures, ByteBufferWriter writer) { if (commandListPosition.CommandIndex == commandListPosition.Commands.Count) { return(false); } var command = commandListPosition.Commands[commandListPosition.CommandIndex]; var preparedStatements = command.TryGetPreparedStatements(); if (preparedStatements is null) { if (Log.IsDebugEnabled()) { Log.Debug("Session{0} Preparing command payload; CommandText: {1}", command.Connection !.Session.Id, command.CommandText); } writer.Write((byte)CommandKind.Query); WriteQueryPayload(command, cachedProcedures, writer); commandListPosition.CommandIndex++; } else { writer.Write((byte)CommandKind.StatementExecute); WritePreparedStatement(command, preparedStatements.Statements[commandListPosition.PreparedStatementIndex], writer); // advance to next prepared statement or next command if (++commandListPosition.PreparedStatementIndex == preparedStatements.Statements.Count) { commandListPosition.CommandIndex++; commandListPosition.PreparedStatementIndex = 0; } } return(true); }
internal async Task <bool> NextResultAsync(IOBehavior ioBehavior, CancellationToken cancellationToken) { VerifyNotDisposed(); try { while (true) { await m_resultSet !.ReadEntireAsync(ioBehavior, cancellationToken).ConfigureAwait(false); await ScanResultSetAsync(ioBehavior, m_resultSet, cancellationToken).ConfigureAwait(false); if (m_hasMoreResults && m_resultSet.ContainsCommandParameters) { await ReadOutParametersAsync(Command !, m_resultSet, ioBehavior, cancellationToken).ConfigureAwait(false); } else { break; } } if (!m_hasMoreResults) { if (m_commandListPosition.CommandIndex < m_commandListPosition.Commands.Count) { Command = m_commandListPosition.Commands[m_commandListPosition.CommandIndex]; using (Command.CancellableCommand.RegisterCancel(cancellationToken)) { var writer = new ByteBufferWriter(); if (!Command.Connection !.Session.IsCancelingQuery && m_payloadCreator.WriteQueryCommand(ref m_commandListPosition, m_cachedProcedures !, writer)) { using var payload = writer.ToPayloadData(); await Command.Connection.Session.SendAsync(payload, ioBehavior, cancellationToken).ConfigureAwait(false); await m_resultSet.ReadResultSetHeaderAsync(ioBehavior).ConfigureAwait(false); ActivateResultSet(); m_hasMoreResults = true; } } } } else { ActivateResultSet(); } if (!m_hasMoreResults) { m_resultSet.Reset(); } #if !NETSTANDARD1_3 m_schemaTable = null; #endif return(m_hasMoreResults); } catch (MySqlException) { m_resultSet !.Reset(); m_hasMoreResults = false; #if !NETSTANDARD1_3 m_schemaTable = null; #endif throw; } }
public ParameterSqlParser(StatementPreparer preparer, ByteBufferWriter writer) : base(preparer) { m_writer = writer; }
public PreparedCommandSqlParser(StatementPreparer preparer, List <ParsedStatement> statements, List <int> statementStartEndIndexes, ByteBufferWriter writer) : base(preparer) { m_statements = statements; m_statementStartEndIndexes = statementStartEndIndexes; m_writer = writer; }
private void writeDataByteBuffer(ByteBufferWriter writer, int index, object data) { Assert.IsNotNull(writer); Assert.IsNotNull(data); writer.WriteVarint32((uint)index); switch (index) { case 0: writer.WriteBool((bool)data); break; case 1: writer.WriteByte((byte)data); break; case 2: writer.WriteUint16((ushort)data); break; case 3: writer.WriteUint32((uint)data); break; case 4: writer.WriteUint64((ulong)data); break; case 5: writer.WriteInt16((short)data); break; case 6: writer.WriteInt32((int)data); break; case 7: writer.WriteInt64((long)data); break; case 8: writer.WriteVarint32((uint)data); break; case 9: writer.WriteVarint64((ulong)data); break; case 10: writer.WriteSVarint32((int)data); break; case 11: writer.WriteSVarint64((long)data); break; case 12: writer.WriteFloat((float)data); break; case 13: writer.WriteDouble((double)data); break; case 14: writer.WriteString((string)data); break; case 15: { var buffer = (byte[])data; writer.WriteVarint32((uint)buffer.Length); writer.WriteBuffer(buffer, 0, buffer.Length); } break; case 16: { writer.WriteVarint32((uint)(int)data); writer.Skip((int)data); } break; default: Assert.Fail(); break; } }
public static async Task <DbDataReader> ExecuteReaderAsync(IReadOnlyList <IMySqlCommand> commands, ICommandPayloadCreator payloadCreator, CommandBehavior behavior, IOBehavior ioBehavior, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var commandListPosition = new CommandListPosition(commands); var command = commands[0]; // pre-requisite: Connection is non-null must be checked before calling this method var connection = command.Connection !; if (Log.IsDebugEnabled()) { Log.Debug("Session{0} ExecuteReader {1} CommandCount: {2}", connection.Session.Id, ioBehavior, commands.Count); } Dictionary <string, CachedProcedure?>?cachedProcedures = null; foreach (var command2 in commands) { if (command2.CommandType == CommandType.StoredProcedure) { if (cachedProcedures is null) { cachedProcedures = new Dictionary <string, CachedProcedure?>(); } var commandText = command2.CommandText !; if (!cachedProcedures.ContainsKey(commandText)) { cachedProcedures.Add(commandText, await connection.GetCachedProcedure(ioBehavior, commandText, cancellationToken).ConfigureAwait(false)); } } } var writer = new ByteBufferWriter(); // cachedProcedures will be non-null if there is a stored procedure, which is also the only time it will be read if (!payloadCreator.WriteQueryCommand(ref commandListPosition, cachedProcedures !, writer)) { throw new InvalidOperationException("ICommandPayloadCreator failed to write query payload"); } cancellationToken.ThrowIfCancellationRequested(); using (var payload = writer.ToPayloadData()) using (command.CancellableCommand.RegisterCancel(cancellationToken)) { connection.Session.StartQuerying(command.CancellableCommand); command.SetLastInsertedId(-1); try { await connection.Session.SendAsync(payload, ioBehavior, CancellationToken.None).ConfigureAwait(false); return(await MySqlDataReader.CreateAsync(commandListPosition, payloadCreator, cachedProcedures, command, behavior, ioBehavior, cancellationToken).ConfigureAwait(false)); } catch (MySqlException ex) when(ex.Number == (int)MySqlErrorCode.QueryInterrupted && cancellationToken.IsCancellationRequested) { Log.Warn("Session{0} query was interrupted", connection.Session.Id); throw new OperationCanceledException(cancellationToken); } catch (Exception ex) when(payload.Span.Length > 4_194_304 && (ex is SocketException || ex is IOException || ex is MySqlProtocolException)) { // the default MySQL Server value for max_allowed_packet (in MySQL 5.7) is 4MiB: https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_max_allowed_packet // use "decimal megabytes" (to round up) when creating the exception message int megabytes = payload.Span.Length / 1_000_000; throw new MySqlException("Error submitting {0}MB packet; ensure 'max_allowed_packet' is greater than {0}MB.".FormatInvariant(megabytes), ex); } } }
public virtual void WriteData(ByteBufferWriter bbw) { }
public DualWriter(byte[] dualBuffer) { this.dualBuffer = dualBuffer; this.dualSize = 0; this.writer = new(); }
void SerializeIntoBuffer(object metadata, IReadOnlyList <object> events, out int startOffset, out IDescriptorSerializerContext serializerContext, out BlockType blockType, out int lenWithoutEndPadding, out ByteBuffer block) { startOffset = (int)EndBufferLen + HeaderSize; var writer = new ByteBufferWriter(); writer.WriteBlock(_zeroes.AsSpan(0, startOffset)); serializerContext = Mapping; if (metadata != null) { serializerContext = serializerContext.StoreNewDescriptors(writer, metadata); } if (events != null) { foreach (var o in events) { serializerContext = serializerContext.StoreNewDescriptors(writer, o); } if (events.Count == 0) { events = null; } } serializerContext.FinishNewDescriptors(writer); blockType = BlockType.FirstBlock; if (serializerContext.SomeTypeStored) { blockType |= BlockType.HasTypeDeclaration; } if (metadata != null) { serializerContext.StoreObject(writer, metadata); blockType |= BlockType.HasMetadata; } if (events != null) { if (events.Count == 1) { serializerContext.StoreObject(writer, events[0]); blockType |= BlockType.HasOneEvent; } else { writer.WriteVUInt32((uint)events.Count); foreach (var o in events) { serializerContext.StoreObject(writer, o); } blockType |= BlockType.HasMoreEvents; } } lenWithoutEndPadding = (int)writer.GetCurrentPosition(); writer.WriteBlock(_zeroes.AsSpan(0, (int)(SectorSize - 1))); block = writer.Data; if (CompressionStrategy.ShouldTryToCompress(lenWithoutEndPadding - startOffset)) { var compressedBlock = ByteBuffer.NewSync(block.Buffer, startOffset, lenWithoutEndPadding - startOffset); if (CompressionStrategy.Compress(ref compressedBlock)) { blockType |= BlockType.Compressed; Array.Copy(compressedBlock.Buffer, compressedBlock.Offset, block.Buffer, startOffset, compressedBlock.Length); lenWithoutEndPadding = startOffset + compressedBlock.Length; Array.Copy(_zeroes, 0, block.Buffer, lenWithoutEndPadding, (int)SectorSize - 1); } } }
private static void WritePreparedStatement(IMySqlCommand command, PreparedStatement preparedStatement, ByteBufferWriter writer) { var parameterCollection = command.RawParameters; if (Log.IsDebugEnabled()) { Log.Debug("Session{0} Preparing command payload; CommandId: {1}; CommandText: {2}", command.Connection !.Session.Id, preparedStatement.StatementId, command.CommandText); } writer.Write(preparedStatement.StatementId); writer.Write((byte)0); writer.Write(1); if (preparedStatement.Parameters?.Length > 0) { // TODO: How to handle incorrect number of parameters? // build subset of parameters for this statement var parameters = new MySqlParameter[preparedStatement.Statement.ParameterNames.Count]; for (var i = 0; i < preparedStatement.Statement.ParameterNames.Count; i++) { var parameterName = preparedStatement.Statement.ParameterNames[i]; var parameterIndex = parameterName is object?(parameterCollection?.NormalizedIndexOf(parameterName) ?? -1) : preparedStatement.Statement.ParameterIndexes[i]; if (parameterIndex == -1 && parameterName is object) { throw new MySqlException("Parameter '{0}' must be defined.".FormatInvariant(parameterName)); } else if (parameterIndex < 0 || parameterIndex >= (parameterCollection?.Count ?? 0)) { throw new MySqlException("Parameter index {0} is invalid when only {1} parameter{2} defined.".FormatInvariant(parameterIndex, parameterCollection?.Count ?? 0, parameterCollection?.Count == 1 ? " is" : "s are")); } parameters[i] = parameterCollection ![parameterIndex];
/// <summary> /// Writes the text of <paramref name="command"/> to <paramref name="writer"/>, encoded in UTF-8. /// </summary> /// <param name="command">The command.</param> /// <param name="cachedProcedures">The cached procedures.</param> /// <param name="writer">The output writer.</param> /// <returns><c>true</c> if a complete command was written; otherwise, <c>false</c>.</returns> public static bool WriteQueryPayload(IMySqlCommand command, IDictionary <string, CachedProcedure?> cachedProcedures, ByteBufferWriter writer) => (command.CommandType == CommandType.StoredProcedure) ? WriteStoredProcedure(command, cachedProcedures, writer) : WriteCommand(command, writer);
public bool WriteQueryCommand(ref CommandListPosition commandListPosition, IDictionary <string, CachedProcedure?> cachedProcedures, ByteBufferWriter writer) { if (commandListPosition.CommandIndex == commandListPosition.Commands.Count) { return(false); } writer.Write((byte)CommandKind.Query); bool isComplete; do { var command = commandListPosition.Commands[commandListPosition.CommandIndex]; if (Log.IsTraceEnabled()) { Log.Trace("Session{0} Preparing command payload; CommandText: {1}", command.Connection !.Session.Id, command.CommandText); } isComplete = SingleCommandPayloadCreator.WriteQueryPayload(command, cachedProcedures, writer); commandListPosition.CommandIndex++; }while (commandListPosition.CommandIndex < commandListPosition.Commands.Count && isComplete); return(true); }
private PayloadData CreateQueryPayload(PreparedStatement preparedStatement, MySqlParameterCollection parameterCollection, MySqlGuidFormat guidFormat) { var writer = new ByteBufferWriter(); writer.Write((byte)CommandKind.StatementExecute); writer.Write(preparedStatement.StatementId); writer.Write((byte)0); writer.Write(1); if (preparedStatement.Parameters?.Length > 0) { // TODO: How to handle incorrect number of parameters? // build subset of parameters for this statement var parameters = new MySqlParameter[preparedStatement.Statement.ParameterNames.Count]; for (var i = 0; i < preparedStatement.Statement.ParameterNames.Count; i++) { var parameterName = preparedStatement.Statement.ParameterNames[i]; var parameterIndex = parameterName != null ? (parameterCollection?.NormalizedIndexOf(parameterName) ?? -1) : preparedStatement.Statement.ParameterIndexes[i]; if (parameterIndex == -1 && parameterName != null) { throw new MySqlException("Parameter '{0}' must be defined.".FormatInvariant(parameterName)); } else if (parameterIndex < 0 || parameterIndex >= (parameterCollection?.Count ?? 0)) { throw new MySqlException("Parameter index {0} is invalid when only {1} parameter{2} defined.".FormatInvariant(parameterIndex, parameterCollection?.Count ?? 0, parameterCollection?.Count == 1 ? " is" : "s are")); } parameters[i] = parameterCollection[parameterIndex]; } // write null bitmap byte nullBitmap = 0; for (var i = 0; i < parameters.Length; i++) { var parameter = parameters[i]; if (parameter.Value == null || parameter.Value == DBNull.Value) { nullBitmap |= (byte)(1 << (i % 8)); } if (i % 8 == 7) { writer.Write(nullBitmap); nullBitmap = 0; } } if (parameters.Length % 8 != 0) { writer.Write(nullBitmap); } // write "new parameters bound" flag writer.Write((byte)1); foreach (var parameter in parameters) { writer.Write(TypeMapper.ConvertToColumnTypeAndFlags(parameter.MySqlDbType, guidFormat)); } var options = m_command.CreateStatementPreparerOptions(); foreach (var parameter in parameters) { parameter.AppendBinary(writer, options); } } return(writer.ToPayloadData()); }
public void ReadToEnd(IEventStoreObserver observer) { var overflowWriter = default(ByteBufferWriter); var bufferBlock = GetReadBuffer(); var bufferStartPosition = NextReadPosition & SectorMask; var bufferFullLength = 0; var bufferReadOffset = (int)(NextReadPosition - bufferStartPosition); var currentReadAhead = FirstReadAhead; var buf = ByteBuffer.NewSync(bufferBlock, bufferFullLength, currentReadAhead); var bufReadLength = (int)File.Read(buf, bufferStartPosition); bufferFullLength += bufReadLength; while (true) { if (bufferStartPosition + (ulong)bufferReadOffset + HeaderSize > File.MaxFileSize) { KnownAsFinished = true; return; } if (bufferReadOffset == bufferFullLength) { break; } if (bufferReadOffset + HeaderSize > bufferFullLength) { for (var i = bufferReadOffset; i < bufferFullLength; i++) { if (bufferBlock[i] != 0) { SetCorrupted(); return; } } break; } var blockCheckSum = PackUnpack.UnpackUInt32LE(bufferBlock, bufferReadOffset); bufferReadOffset += 4; var blockLen = PackUnpack.UnpackUInt32LE(bufferBlock, bufferReadOffset); if (blockCheckSum == 0 && blockLen == 0) { bufferReadOffset -= 4; break; } var blockType = (BlockType)(blockLen & 0xff); blockLen >>= 8; if (blockType == BlockType.LastBlock && blockLen == 0) { if (Checksum.CalcFletcher32(bufferBlock, (uint)bufferReadOffset, 4) != blockCheckSum) { SetCorrupted(); return; } KnownAsFinished = true; return; } if (blockLen == 0 && blockType != (BlockType.FirstBlock | BlockType.LastBlock)) { SetCorrupted(); return; } if (blockLen + HeaderSize > MaxBlockSize) { SetCorrupted(); return; } bufferReadOffset += 4; var bufferLenToFill = (uint)(bufferReadOffset + (int)blockLen + FirstReadAhead) & SectorMaskUInt; if (bufferLenToFill > bufferBlock.Length) { bufferLenToFill = (uint)bufferBlock.Length; } buf = ByteBuffer.NewSync(bufferBlock, bufferFullLength, (int)(bufferLenToFill - bufferFullLength)); if (buf.Length > 0) { bufferLenToFill = (uint)(bufferReadOffset + (int)blockLen + currentReadAhead) & SectorMaskUInt; if (bufferLenToFill > bufferBlock.Length) { bufferLenToFill = (uint)bufferBlock.Length; } if (bufferStartPosition + bufferLenToFill > File.MaxFileSize) { bufferLenToFill = (uint)(File.MaxFileSize - bufferStartPosition); } buf = ByteBuffer.NewSync(bufferBlock, bufferFullLength, (int)(bufferLenToFill - bufferFullLength)); if (buf.Length > 0) { if (currentReadAhead * 4 < MaxBlockSize) { currentReadAhead = currentReadAhead * 2; } bufReadLength = (int)File.Read(buf, bufferStartPosition + (ulong)bufferFullLength); bufferFullLength += bufReadLength; } } if (bufferReadOffset + (int)blockLen > bufferFullLength) { SetCorrupted(); return; } if (Checksum.CalcFletcher32(bufferBlock, (uint)bufferReadOffset - 4, blockLen + 4) != blockCheckSum) { SetCorrupted(); return; } var blockTypeBlock = blockType & (BlockType.FirstBlock | BlockType.MiddleBlock | BlockType.LastBlock); var stopReadingRequested = false; if (blockTypeBlock == (BlockType.FirstBlock | BlockType.LastBlock)) { stopReadingRequested = Process(blockType, ByteBuffer.NewSync(bufferBlock, bufferReadOffset, (int)blockLen), observer); } else { if (blockTypeBlock == BlockType.FirstBlock) { overflowWriter = new ByteBufferWriter(); } else if (blockTypeBlock == BlockType.MiddleBlock || blockTypeBlock == BlockType.LastBlock) { if (overflowWriter == null) { SetCorrupted(); return; } } else { SetCorrupted(); return; } overflowWriter.WriteBlock(ByteBuffer.NewSync(bufferBlock, bufferReadOffset, (int)blockLen)); if (blockTypeBlock == BlockType.LastBlock) { stopReadingRequested = Process(blockType, overflowWriter.Data, observer); overflowWriter = null; } } bufferReadOffset += (int)blockLen; if (overflowWriter == null) { NextReadPosition = bufferStartPosition + (ulong)bufferReadOffset; } if (stopReadingRequested) { return; } var nextBufferStartPosition = (bufferStartPosition + (ulong)bufferReadOffset) & SectorMask; var bufferMoveDistance = (int)(nextBufferStartPosition - bufferStartPosition); if (bufferMoveDistance <= 0) { continue; } Array.Copy(bufferBlock, bufferMoveDistance, bufferBlock, 0, bufferFullLength - bufferMoveDistance); bufferStartPosition = nextBufferStartPosition; bufferFullLength -= bufferMoveDistance; bufferReadOffset -= bufferMoveDistance; } if (overflowWriter != null) { // It is not corrupted here just unfinished, but definitely not appendable EndBufferPosition = ulong.MaxValue; return; } EndBufferLen = (uint)(bufferReadOffset - (bufferReadOffset & SectorMaskUInt)); EndBufferPosition = bufferStartPosition + (ulong)bufferReadOffset - EndBufferLen; Array.Copy(bufferBlock, bufferReadOffset - EndBufferLen, EndBuffer, 0, EndBufferLen); }
private void WritePreparedStatement(IMySqlCommand command, PreparedStatement preparedStatement, ByteBufferWriter writer) { var parameterCollection = command.Parameters; if (Log.IsDebugEnabled()) { Log.Debug("Session{0} Preparing command payload; CommandId: {1}; CommandText: {2}", command.Connection.Session.Id, preparedStatement.StatementId, command.CommandText); } writer.Write((byte)CommandKind.StatementExecute); writer.Write(preparedStatement.StatementId); writer.Write((byte)0); writer.Write(1); if (preparedStatement.Parameters?.Length > 0) { // TODO: How to handle incorrect number of parameters? // build subset of parameters for this statement var parameters = new MySqlParameter[preparedStatement.Statement.ParameterNames.Count]; for (var i = 0; i < preparedStatement.Statement.ParameterNames.Count; i++) { var parameterName = preparedStatement.Statement.ParameterNames[i]; var parameterIndex = parameterName != null ? (parameterCollection?.NormalizedIndexOf(parameterName) ?? -1) : preparedStatement.Statement.ParameterIndexes[i]; if (parameterIndex == -1 && parameterName != null) { throw new MySqlException("Parameter '{0}' must be defined.".FormatInvariant(parameterName)); } else if (parameterIndex < 0 || parameterIndex >= (parameterCollection?.Count ?? 0)) { throw new MySqlException("Parameter index {0} is invalid when only {1} parameter{2} defined.".FormatInvariant(parameterIndex, parameterCollection?.Count ?? 0, parameterCollection?.Count == 1 ? " is" : "s are")); } parameters[i] = parameterCollection[parameterIndex]; } // write null bitmap byte nullBitmap = 0; for (var i = 0; i < parameters.Length; i++) { var parameter = parameters[i]; if (parameter.Value is null || parameter.Value == DBNull.Value) { nullBitmap |= (byte)(1 << (i % 8)); } if (i % 8 == 7) { writer.Write(nullBitmap); nullBitmap = 0; } } if (parameters.Length % 8 != 0) { writer.Write(nullBitmap); } // write "new parameters bound" flag writer.Write((byte)1); foreach (var parameter in parameters) { writer.Write(TypeMapper.ConvertToColumnTypeAndFlags(parameter.MySqlDbType, command.Connection.GuidFormat)); } var options = command.CreateStatementPreparerOptions(); foreach (var parameter in parameters) { parameter.AppendBinary(writer, options); } } }
private void WriteStoredProcedure(IMySqlCommand command, IDictionary <string, CachedProcedure> cachedProcedures, ByteBufferWriter writer) { var parameterCollection = command.Parameters; var cachedProcedure = cachedProcedures[command.CommandText]; if (cachedProcedure is object) { parameterCollection = cachedProcedure.AlignParamsWithDb(parameterCollection); } MySqlParameter returnParameter = null; var outParameters = new MySqlParameterCollection(); var outParameterNames = new List <string>(); var inParameters = new MySqlParameterCollection(); var argParameterNames = new List <string>(); var inOutSetParameters = ""; for (var i = 0; i < (parameterCollection?.Count ?? 0); i++) { var param = parameterCollection[i]; var inName = "@inParam" + i; var outName = "@outParam" + i; switch (param.Direction) { case ParameterDirection.Input: case ParameterDirection.InputOutput: var inParam = param.WithParameterName(inName); inParameters.Add(inParam); if (param.Direction == ParameterDirection.InputOutput) { inOutSetParameters += $"SET {outName}={inName}; "; goto case ParameterDirection.Output; } argParameterNames.Add(inName); break; case ParameterDirection.Output: outParameters.Add(param); outParameterNames.Add(outName); argParameterNames.Add(outName); break; case ParameterDirection.ReturnValue: returnParameter = param; break; } } // if a return param is set, assume it is a function; otherwise, assume stored procedure var commandText = command.CommandText + "(" + string.Join(", ", argParameterNames) + ");"; if (returnParameter is null) { commandText = inOutSetParameters + "CALL " + commandText; if (outParameters.Count > 0) { commandText += "SELECT '" + OutParameterSentinelColumnName + "' AS '" + OutParameterSentinelColumnName + "', " + string.Join(", ", outParameterNames); } } else { commandText = "SELECT " + commandText; } command.OutParameters = outParameters; command.ReturnParameter = returnParameter; var preparer = new StatementPreparer(commandText, inParameters, command.CreateStatementPreparerOptions()); preparer.ParseAndBindParameters(writer); }
public bool WriteQueryCommand(ref CommandListPosition commandListPosition, IDictionary <string, CachedProcedure?> cachedProcedures, ByteBufferWriter writer) { writer.Write((byte)CommandKind.Multi); bool?firstResult = default; bool wroteCommand; do { // save room for command length var position = writer.Position; writer.Write(Padding); wroteCommand = SingleCommandPayloadCreator.Instance.WriteQueryCommand(ref commandListPosition, cachedProcedures, writer); if (firstResult is null) { firstResult = wroteCommand; } // write command length var commandLength = writer.Position - position - Padding.Length; var span = writer.ArraySegment.AsSpan().Slice(position); span[0] = 0xFE; BinaryPrimitives.WriteUInt64LittleEndian(span.Slice(1), (ulong)commandLength); } while (wroteCommand); // remove the padding that was saved for the final command (which wasn't written) writer.TrimEnd(Padding.Length); return(firstResult.Value); }
private void WriteCommand(IMySqlCommand command, ByteBufferWriter writer) { var preparer = new StatementPreparer(command.CommandText, command.Parameters, command.CreateStatementPreparerOptions()); preparer.ParseAndBindParameters(writer); }
public void TestSocketServerClientThread() { var server = SocketBase.Create <SocketServer>(); bool rc = server.Bind("127.0.0.1:" + port); Assert.IsTrue(rc); List <SocketBase> clientSet = new List <SocketBase>(); for (int i = 0; i < clientCount; i++) { var client = SocketBase.Create(SocketType.Client); rc = client.Connect("127.0.0.1:" + port); Assert.IsTrue(rc); clientSet.Add(client); } port++; var checkData = generateCheckData(); rc = Thread.Wait(() => server.ConnectionCount == clientCount, 1000); Assert.IsTrue(rc); string hello = "Hello"; var writer = new ByteBufferWriter(16); writer.WriteString(hello); var helloMessage = new Message(writer); for (int i = 0; i < clientCount; i++) { rc = clientSet[i].TrySend(ref helloMessage, 1000); Assert.IsTrue(rc); } List <uint> clientIdSet = new List <uint>(clientCount); for (int i = 0; i < clientCount; i++) { Message msg; rc = server.TryRecv(out msg, 1000); Assert.IsTrue(rc); Assert.Less(0, msg.RouteId); Assert.IsFalse(clientIdSet.Contains(msg.RouteId)); clientIdSet.Add(msg.RouteId); var reader = msg.GetBufferReader(); var value = reader.ReadString(); Assert.AreEqual(value, hello); } var threadPool = new ThreadPool(clientCount); threadPool.Send(() => { for (int c = 0; c < clientCount; c++) { for (int i = 0; i < checkCount; i++) { var msg = generateMessage(checkData); rc = server.Send(clientIdSet[c], ref msg); Assert.IsTrue(rc, "client id: " + clientIdSet[c] + ", message id: " + i); } } }); int result = 0; for (int c = 0; c < clientCount; c++) { var client = clientSet[c]; var clientId = clientIdSet[c]; threadPool.Post(() => { for (int i = 0; i < checkCount; i++) { Message msg; rc = client.Recv(out msg); Assert.IsTrue(rc, "client id: " + clientId + ", message id: " + i); checkMessage(ref msg, checkData); Atomic.Inc(ref result); } }); } rc = Thread.Wait(() => result == clientCount * checkCount, -1); Assert.IsTrue(rc); threadPool.Dispose(); Assert.AreEqual(result, clientCount * checkCount); for (int i = 0; i < clientSet.Count; i++) { clientSet[i].Close(); rc = clientSet[i].WaitClose(1000); Assert.IsTrue(rc); } server.Close(); rc = server.WaitClose(1000); Assert.IsTrue(rc); }