예제 #1
0
        internal void ReadOk(bool read)
        {
            try
            {
                if (read)
                {
                    packet = stream.ReadPacket();
                }
                byte marker = (byte)packet.ReadByte();
                if (marker != 0)
                {
                    throw new MySqlException("Out of sync with server", true, null);
                }

                packet.ReadFieldLength(); /* affected rows */
                packet.ReadFieldLength(); /* last insert id */
                if (packet.HasMoreData)
                {
                    serverStatus = (ServerStatusFlags)packet.ReadInteger(2);
                    packet.ReadInteger(2);  /* warning count */
                    if (packet.HasMoreData)
                    {
                        packet.ReadLenString();  /* message */
                    }
                }
            }
            catch (MySqlException ex)
            {
                HandleException(ex);
                throw;
            }
        }
        public int PrepareStatement(string sql, ref MySqlField[] parameters)
        {
            //TODO: check this
            //ClearFetchedRow();

            packet.Length = sql.Length * 4 + 5;
            byte[] buffer = packet.Buffer;
            int    len    = Encoding.GetBytes(sql, 0, sql.Length, packet.Buffer, 5);

            packet.Position = len + 5;
            buffer[4]       = (byte)DBCmd.PREPARE;
            ExecutePacket(packet);

            packet = stream.ReadPacket();

            int marker = packet.ReadByte();

            if (marker != 0)
            {
                throw new MySqlException("Expected prepared statement marker");
            }

            int statementId = packet.ReadInteger(4);
            int numCols     = packet.ReadInteger(2);
            int numParams   = packet.ReadInteger(2);

            //TODO: find out what this is needed for
            packet.ReadInteger(3);
            if (numParams > 0)
            {
                parameters = owner.GetColumns(numParams);
                // we set the encoding for each parameter back to our connection encoding
                // since we can't trust what is coming back from the server
                for (int i = 0; i < parameters.Length; i++)
                {
                    parameters[i].Encoding = Encoding;
                }
            }

            if (numCols > 0)
            {
                while (numCols-- > 0)
                {
                    packet = stream.ReadPacket();
                    //TODO: handle streaming packets
                }

                ReadEOF();
            }

            return(statementId);
        }
예제 #3
0
        /// <summary>
        /// ReadPacket is called by NativeDriver to start reading the next
        /// packet on the stream.
        /// </summary>
        public MySqlPacket ReadPacket()
        {
            //Debug.Assert(packet.Position == packet.Length);

            // make sure we have read all the data from the previous packet
            //Debug.Assert(HasMoreData == false, "HasMoreData is true in OpenPacket");

            LoadPacket();

            // now we check if this packet is a server error
            if (packet.Buffer[0] == 0xff)
            {
                packet.ReadByte();  // read off the 0xff

                int    code = packet.ReadInteger(2);
                string msg  = String.Empty;

                if (packet.Version.isAtLeast(5, 5, 0))
                {
                    msg = packet.ReadString(Encoding.UTF8);
                }
                else
                {
                    msg = packet.ReadString();
                }

                if (msg.StartsWith("#", StringComparison.Ordinal))
                {
                    msg.Substring(1, 5);  /* state code */
                    msg = msg.Substring(6);
                }
                throw new MySqlException(msg, code);
            }
            return(packet);
        }
        public long GetResult(ref long affectedRow, ref long insertedId)
        {
            try
            {
                packet = stream.ReadPacket();
            }
            catch (TimeoutException)
            {
                // Do not reset serverStatus, allow to reenter, e.g when
                // ResultSet is closed.
                throw;
            }
            catch (Exception)
            {
                serverStatus = 0;

                throw;
            }

            var fieldCount = (long)packet.ReadFieldLength();

            if (-1 == fieldCount)
            {
                string filename = packet.ReadString();
                SendFileToServer(filename);

                return(GetResult(ref affectedRow, ref insertedId));
            }
            else if (fieldCount == 0)
            {
                // the code to read last packet will set these server status vars
                // again if necessary.
                serverStatus &= ~(ServerStatusFlags.AnotherQuery |
                                  ServerStatusFlags.MoreResults);
                affectedRow = (int)packet.ReadFieldLength();
                insertedId  = (long)packet.ReadFieldLength();

                serverStatus = (ServerStatusFlags)packet.ReadInteger(2);
                warnings    += packet.ReadInteger(2);
                if (packet.HasMoreData)
                {
                    packet.ReadLenString(); //TODO: server message
                }
            }
            return(fieldCount);
        }
        private void GetColumnData(MySqlField field)
        {
            stream.Encoding          = Encoding;
            packet                   = stream.ReadPacket();
            field.Encoding           = Encoding;
            field.CatalogName        = packet.ReadLenString();
            field.DatabaseName       = packet.ReadLenString();
            field.TableName          = packet.ReadLenString();
            field.RealTableName      = packet.ReadLenString();
            field.ColumnName         = packet.ReadLenString();
            field.OriginalColumnName = packet.ReadLenString();
            packet.ReadByte();
            field.CharacterSetIndex = packet.ReadInteger(2);
            field.ColumnLength      = packet.ReadInteger(4);
            MySqlDbType type = (MySqlDbType)packet.ReadByte();
            ColumnFlags colFlags;

            if ((connectionFlags & ClientFlags.LONG_FLAG) != 0)
            {
                colFlags = (ColumnFlags)packet.ReadInteger(2);
            }
            else
            {
                colFlags = (ColumnFlags)packet.ReadByte();
            }
            field.Scale = (byte)packet.ReadByte();

            if (packet.HasMoreData)
            {
                packet.ReadInteger(2); // reserved
            }

            if (type == MySqlDbType.Decimal || type == MySqlDbType.NewDecimal)
            {
                field.Precision = (byte)(field.ColumnLength - 2);
                if ((colFlags & ColumnFlags.UNSIGNED) != 0)
                {
                    field.Precision++;
                }
            }

            field.SetTypeAndFlags(type, colFlags);
        }
예제 #6
0
    IMySqlValue IMySqlValue.ReadValue(MySqlPacket packet, long length, bool nullVal)
    {
      if (nullVal)
        return new MySqlUInt16(true);

      if (length == -1)
        return new MySqlUInt16((ushort)packet.ReadInteger(2));
      else
        return new MySqlUInt16(UInt16.Parse(packet.ReadString(length)));
    }
예제 #7
0
    IMySqlValue IMySqlValue.ReadValue(MySqlPacket packet, long length, bool nullVal)
    {
      if (nullVal)
        return new MySqlUInt32((this as IMySqlValue).MySqlDbType, true);

      if (length == -1)
        return new MySqlUInt32((this as IMySqlValue).MySqlDbType,
                     (uint)packet.ReadInteger(4));
      else
        return new MySqlUInt32((this as IMySqlValue).MySqlDbType,
                     UInt32.Parse(packet.ReadString(length), NumberStyles.Any, CultureInfo.InvariantCulture));
    }
예제 #8
0
        public override void ExecuteStatement(MySqlPacket packetToExecute)
        {
            base.ExecuteStatement(packetToExecute);
            int pos = packetToExecute.Position;

            packetToExecute.Position = 1;
            int statementId = packetToExecute.ReadInteger(4);

            packetToExecute.Position = pos;

            MySqlTrace.TraceEvent(TraceEventType.Information, MySqlTraceEventType.StatementExecuted,
                                  Resources.TraceStatementExecuted, driverId, statementId, ThreadID);
        }
예제 #9
0
    IMySqlValue IMySqlValue.ReadValue(MySqlPacket packet, long length, bool nullVal)
    {

      if (nullVal) return new MySqlDateTime(type, true);

      if (length >= 0)
      {
        string value = packet.ReadString(length);
        return ParseMySql(value);
      }

      long bufLength = packet.ReadByte();
      int year = 0, month = 0, day = 0;
      int hour = 0, minute = 0, second = 0, microsecond = 0;
      if (bufLength >= 4)
      {
        year = packet.ReadInteger(2);
        month = packet.ReadByte();
        day = packet.ReadByte();
      }

      if (bufLength > 4)
      {
        hour = packet.ReadByte();
        minute = packet.ReadByte();
        second = packet.ReadByte();
      }

      if (bufLength > 7)
      {
        microsecond = packet.Read3ByteInt();
        packet.ReadByte();
      }

      return new MySqlDateTime(type, year, month, day, hour, minute, second, microsecond);
    }
예제 #10
0
    IMySqlValue IMySqlValue.ReadValue(MySqlPacket packet, long length, bool nullVal)
    {
      if (nullVal) return new MySqlTimeSpan(true);

      if (length >= 0)
      {
        string value = packet.ReadString(length);
        ParseMySql(value);
        return this;
      }

      long bufLength = packet.ReadByte();
      int negate = 0;
      if (bufLength > 0)
        negate = packet.ReadByte();

      isNull = false;
      if (bufLength == 0)
        isNull = true;
      else if (bufLength == 5)
        mValue = new TimeSpan(packet.ReadInteger(4), 0, 0, 0);
      else if (bufLength == 8)
        mValue = new TimeSpan(packet.ReadInteger(4),
             packet.ReadByte(), packet.ReadByte(), packet.ReadByte());
      else
        mValue = new TimeSpan(packet.ReadInteger(4),
             packet.ReadByte(), packet.ReadByte(), packet.ReadByte(),
             packet.ReadInteger(4) / 1000000);

      if (negate == 1)
        mValue = mValue.Negate();
      return this;
    }
        public void Open()
        {
            // connect to one of our specified hosts
            try
            {
                baseStream = StreamCreator.GetStream(Settings);
#if NET451
                if (Settings.IncludeSecurityAsserts)
                {
                    MySqlSecurityPermission.CreatePermissionSet(false).Assert();
                }
#endif
            }
            catch (System.Security.SecurityException)
            {
                throw;
            }
            catch (Exception ex)
            {
                throw new MySqlException(Resources.UnableToConnectToHost,
                                         (int)MySqlErrorCode.UnableToConnectToHost, ex);
            }
            if (baseStream == null)
            {
                throw new MySqlException(Resources.UnableToConnectToHost,
                                         (int)MySqlErrorCode.UnableToConnectToHost);
            }

            int maxSinglePacket = 255 * 255 * 255;
            stream = new MySqlStream(baseStream, Encoding, false);

            stream.ResetTimeout((int)Settings.ConnectionTimeout * 1000);

            // read off the welcome packet and parse out it's values
            packet = stream.ReadPacket();
            int    protocol      = packet.ReadByte();
            string versionString = packet.ReadString();
            owner.isFabric = versionString.EndsWith("fabric", StringComparison.OrdinalIgnoreCase);
            version        = DBVersion.Parse(versionString);
            if (!owner.isFabric && !version.isAtLeast(5, 0, 0))
            {
                throw new NotSupportedException(Resources.ServerTooOld);
            }
            threadId       = packet.ReadInteger(4);
            encryptionSeed = packet.ReadString();

            maxSinglePacket = (256 * 256 * 256) - 1;

            // read in Server capabilities if they are provided
            ClientFlags serverCaps = 0;
            if (packet.HasMoreData)
            {
                serverCaps = (ClientFlags)packet.ReadInteger(2);
            }

            /* New protocol with 16 bytes to describe server characteristics */
            owner.ConnectionCharSetIndex = (int)packet.ReadByte();

            serverStatus = (ServerStatusFlags)packet.ReadInteger(2);

            // Since 5.5, high bits of server caps are stored after status.
            // Previously, it was part of reserved always 0x00 13-byte filler.
            uint serverCapsHigh = (uint)packet.ReadInteger(2);
            serverCaps |= (ClientFlags)(serverCapsHigh << 16);

            packet.Position += 11;
            string seedPart2 = packet.ReadString();
            encryptionSeed += seedPart2;

            string authenticationMethod = "";
            if ((serverCaps & ClientFlags.PLUGIN_AUTH) != 0)
            {
                authenticationMethod = packet.ReadString();
            }
            else
            {
                // Some MySql versions like 5.1, don't give name of plugin, default to native password.
                authenticationMethod = "mysql_native_password";
            }

            // based on our settings, set our connection flags
            SetConnectionFlags(serverCaps);

            packet.Clear();
            packet.WriteInteger((int)connectionFlags, 4);

            if ((serverCaps & ClientFlags.SSL) == 0)
            {
                if ((Settings.SslMode != MySqlSslMode.None) &&
                    (Settings.SslMode != MySqlSslMode.Preferred))
                {
                    // Client requires SSL connections.
                    string message = String.Format(Resources.NoServerSSLSupport,
                                                   Settings.Server);
                    throw new MySqlException(message);
                }
            }
            else if (Settings.SslMode != MySqlSslMode.None)
            {
                stream.SendPacket(packet);
                StartSSL();
                packet.Clear();
                packet.WriteInteger((int)connectionFlags, 4);
            }

            packet.WriteInteger(maxSinglePacket, 4);
            packet.WriteByte(8);
            packet.Write(new byte[23]);

            Authenticate(authenticationMethod, false);

            // if we are using compression, then we use our CompressedStream class
            // to hide the ugliness of managing the compression
            if ((connectionFlags & ClientFlags.COMPRESS) != 0)
            {
                stream = new MySqlStream(baseStream, Encoding, true);
            }

            // give our stream the server version we are connected to.
            // We may have some fields that are read differently based
            // on the version of the server we are connected to.
            packet.Version      = version;
            stream.MaxBlockSize = maxSinglePacket;
        }
예제 #12
0
        public int PrepareStatement(string sql, ref MySqlField[] parameters)
        {
            //TODO: check this
            //ClearFetchedRow();

            packet.Length = sql.Length * 4 + 5;
            byte[] buffer = packet.Buffer;
            int len = Encoding.GetBytes(sql, 0, sql.Length, packet.Buffer, 5);
            packet.Position = len + 5;
            buffer[4] = (byte)DBCmd.PREPARE;
            ExecutePacket(packet);

            packet = stream.ReadPacket();

            int marker = packet.ReadByte();
            if (marker != 0)
                throw new MySqlException("Expected prepared statement marker");

            int statementId = packet.ReadInteger(4);
            int numCols = packet.ReadInteger(2);
            int numParams = packet.ReadInteger(2);
            //TODO: find out what this is needed for
            packet.ReadInteger(3);
            if (numParams > 0)
            {
                parameters = owner.GetColumns(numParams);
                // we set the encoding for each parameter back to our connection encoding
                // since we can't trust what is coming back from the server
                for (int i = 0; i < parameters.Length; i++)
                    parameters[i].Encoding = Encoding;
            }

            if (numCols > 0)
            {
                while (numCols-- > 0)
                {
                    packet = stream.ReadPacket();
                    //TODO: handle streaming packets
                }

                ReadEOF();
            }

            return statementId;
        }
예제 #13
0
        private void GetColumnData(MySqlField field)
        {
            stream.Encoding = Encoding;
            packet = stream.ReadPacket();
            field.Encoding = Encoding;
            field.CatalogName = packet.ReadLenString();
            field.DatabaseName = packet.ReadLenString();
            field.TableName = packet.ReadLenString();
            field.RealTableName = packet.ReadLenString();
            field.ColumnName = packet.ReadLenString();
            field.OriginalColumnName = packet.ReadLenString();
            packet.ReadByte();
            field.CharacterSetIndex = packet.ReadInteger(2);
            field.ColumnLength = packet.ReadInteger(4);
            MySqlDbType type = (MySqlDbType)packet.ReadByte();
            ColumnFlags colFlags;
            if ((connectionFlags & ClientFlags.LONG_FLAG) != 0)
                colFlags = (ColumnFlags)packet.ReadInteger(2);
            else
                colFlags = (ColumnFlags)packet.ReadByte();
            field.Scale = (byte)packet.ReadByte();

            if (packet.HasMoreData)
            {
                packet.ReadInteger(2); // reserved
            }

            if (type == MySqlDbType.Decimal || type == MySqlDbType.NewDecimal)
            {
                field.Precision = (byte)(field.ColumnLength - 2);
                if ((colFlags & ColumnFlags.UNSIGNED) != 0)
                    field.Precision++;
            }

            field.SetTypeAndFlags(type, colFlags);
        }
예제 #14
0
        public long GetResult(ref long affectedRow, ref long insertedId)
        {
            try
            {
                packet = stream.ReadPacket();
            }
            catch (TimeoutException)
            {
                // Do not reset serverStatus, allow to reenter, e.g when
                // ResultSet is closed.
                throw;
            }
            catch (Exception)
            {
                serverStatus = 0;

                throw;
            }

            var fieldCount = (long)packet.ReadFieldLength();
            if (-1 == fieldCount)
            {
                string filename = packet.ReadString();
                SendFileToServer(filename);

                return GetResult(ref affectedRow, ref insertedId);
            }
            else if (fieldCount == 0)
            {
                // the code to read last packet will set these server status vars 
                // again if necessary.
                serverStatus &= ~(ServerStatusFlags.AnotherQuery |
                                  ServerStatusFlags.MoreResults);
                affectedRow = (int)packet.ReadFieldLength();
                insertedId = (long)packet.ReadFieldLength();

                serverStatus = (ServerStatusFlags)packet.ReadInteger(2);
                warnings += packet.ReadInteger(2);
                if (packet.HasMoreData)
                {
                    packet.ReadLenString(); //TODO: server message
                }
            }
            return fieldCount;
        }
예제 #15
0
        public void Open()
        {
            // connect to one of our specified hosts
            try
            {
                baseStream = StreamCreator.GetStream(Settings);
#if NET451
         if (Settings.IncludeSecurityAsserts)
            MySqlSecurityPermission.CreatePermissionSet(false).Assert();
#endif
            }
            catch (System.Security.SecurityException)
            {
                throw;
            }
            catch (Exception ex)
            {
                throw new MySqlException(Resources.UnableToConnectToHost,
                    (int)MySqlErrorCode.UnableToConnectToHost, ex);
            }
            if (baseStream == null)
                throw new MySqlException(Resources.UnableToConnectToHost,
                    (int)MySqlErrorCode.UnableToConnectToHost);

            int maxSinglePacket = 255 * 255 * 255;
            stream = new MySqlStream(baseStream, Encoding, false);

            stream.ResetTimeout((int)Settings.ConnectionTimeout * 1000);

            // read off the welcome packet and parse out it's values
            packet = stream.ReadPacket();
            int protocol = packet.ReadByte();
            string versionString = packet.ReadString();
            owner.isFabric = versionString.EndsWith("fabric", StringComparison.OrdinalIgnoreCase);
            version = DBVersion.Parse(versionString);
            if (!owner.isFabric && !version.isAtLeast(5, 0, 0))
                throw new NotSupportedException(Resources.ServerTooOld);
            threadId = packet.ReadInteger(4);
            encryptionSeed = packet.ReadString();

            maxSinglePacket = (256 * 256 * 256) - 1;

            // read in Server capabilities if they are provided
            ClientFlags serverCaps = 0;
            if (packet.HasMoreData)
                serverCaps = (ClientFlags)packet.ReadInteger(2);

            /* New protocol with 16 bytes to describe server characteristics */
            owner.ConnectionCharSetIndex = (int)packet.ReadByte();

            serverStatus = (ServerStatusFlags)packet.ReadInteger(2);

            // Since 5.5, high bits of server caps are stored after status.
            // Previously, it was part of reserved always 0x00 13-byte filler.
            uint serverCapsHigh = (uint)packet.ReadInteger(2);
            serverCaps |= (ClientFlags)(serverCapsHigh << 16);

            packet.Position += 11;
            string seedPart2 = packet.ReadString();
            encryptionSeed += seedPart2;

            string authenticationMethod = "";
            if ((serverCaps & ClientFlags.PLUGIN_AUTH) != 0)
            {
                authenticationMethod = packet.ReadString();
            }
            else
            {
                // Some MySql versions like 5.1, don't give name of plugin, default to native password.
                authenticationMethod = "mysql_native_password";
            }

            // based on our settings, set our connection flags
            SetConnectionFlags(serverCaps);

            packet.Clear();
            packet.WriteInteger((int)connectionFlags, 4);
            
            if ((serverCaps & ClientFlags.SSL) == 0)
            {
                if ((Settings.SslMode != MySqlSslMode.None)
                && (Settings.SslMode != MySqlSslMode.Preferred))
                {
                    // Client requires SSL connections.
                    string message = String.Format(Resources.NoServerSSLSupport,
                        Settings.Server);
                    throw new MySqlException(message);
                }
            }
            else if (Settings.SslMode != MySqlSslMode.None)
            {
                stream.SendPacket(packet);
                StartSSL();
                packet.Clear();
                packet.WriteInteger((int)connectionFlags, 4);
            }
            
            packet.WriteInteger(maxSinglePacket, 4);
            packet.WriteByte(8);
            packet.Write(new byte[23]);

            Authenticate(authenticationMethod, false);

            // if we are using compression, then we use our CompressedStream class
            // to hide the ugliness of managing the compression
            if ((connectionFlags & ClientFlags.COMPRESS) != 0)
                stream = new MySqlStream(baseStream, Encoding, true);

            // give our stream the server version we are connected to.  
            // We may have some fields that are read differently based 
            // on the version of the server we are connected to.
            packet.Version = version;
            stream.MaxBlockSize = maxSinglePacket;
        }
예제 #16
0
    public override void ExecuteStatement(MySqlPacket packetToExecute)
    {
      base.ExecuteStatement(packetToExecute);
      int pos = packetToExecute.Position;
      packetToExecute.Position = 1;
      int statementId = packetToExecute.ReadInteger(4);
      packetToExecute.Position = pos;

      MySqlTrace.TraceEvent(TraceEventType.Information, MySqlTraceEventType.StatementExecuted,
          Resources.TraceStatementExecuted, driverId, statementId, ThreadID);
    }