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);
        }
Exemplo n.º 5
0
        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);
        }
Exemplo n.º 6
0
        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;
            }
        }
Exemplo n.º 7
0
 public ParameterSqlParser(StatementPreparer preparer, ByteBufferWriter writer)
     : base(preparer)
 {
     m_writer = writer;
 }
Exemplo n.º 8
0
 public PreparedCommandSqlParser(StatementPreparer preparer, List <ParsedStatement> statements, List <int> statementStartEndIndexes, ByteBufferWriter writer)
     : base(preparer)
 {
     m_statements = statements;
     m_statementStartEndIndexes = statementStartEndIndexes;
     m_writer = writer;
 }
Exemplo n.º 9
0
        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;
            }
        }
Exemplo n.º 10
0
        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);
                    }
                }
        }
Exemplo n.º 11
0
 public virtual void WriteData(ByteBufferWriter bbw)
 {
 }
Exemplo n.º 12
0
 public DualWriter(byte[] dualBuffer)
 {
     this.dualBuffer = dualBuffer;
     this.dualSize   = 0;
     this.writer     = new();
 }
Exemplo n.º 13
0
        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);
                }
            }
        }
Exemplo n.º 14
0
        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];
Exemplo n.º 15
0
 /// <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());
        }
Exemplo n.º 18
0
        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);
        }
Exemplo n.º 19
0
        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);
                }
            }
        }
Exemplo n.º 20
0
        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);
        }
Exemplo n.º 21
0
        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);
        }
Exemplo n.º 22
0
        private void WriteCommand(IMySqlCommand command, ByteBufferWriter writer)
        {
            var preparer = new StatementPreparer(command.CommandText, command.Parameters, command.CreateStatementPreparerOptions());

            preparer.ParseAndBindParameters(writer);
        }
Exemplo n.º 23
0
        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);
        }