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); }
/// <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); }
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))); }
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)); }
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); }
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); }
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; }
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; }
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); }
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; }
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; }