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); }
public MySqlStream(Encoding encoding) { // we have no idea what the real value is so we start off with the max value // The real value will be set in NativeDriver.Configure() maxPacketSize = ulong.MaxValue; // we default maxBlockSize to MaxValue since we will get the 'real' value in // the authentication handshake and we know that value will not exceed // true maxBlockSize prior to that. maxBlockSize = Int32.MaxValue; packet = new MySqlPacket(encoding); bufferStream = new MemoryStream(); }
void IMySqlValue.WriteValue(MySqlPacket packet, bool binary, object value, int length) { MySqlDateTime dtValue; string valueAsString = value as string; if (value is DateTime) dtValue = new MySqlDateTime(type, (DateTime)value); else if (valueAsString != null) dtValue = new MySqlDateTime(type, DateTime.Parse(valueAsString, CultureInfo.CurrentCulture)); else if (value is MySqlDateTime) dtValue = (MySqlDateTime)value; else throw new MySqlException("Unable to serialize date/time value."); if (!binary) { SerializeText(packet, dtValue); return; } if (type == MySqlDbType.Timestamp) packet.WriteByte(11); else packet.WriteByte(7); packet.WriteInteger(dtValue.Year, 2); packet.WriteByte((byte)dtValue.Month); packet.WriteByte((byte)dtValue.Day); if (type == MySqlDbType.Date) { packet.WriteByte(0); packet.WriteByte(0); packet.WriteByte(0); } else { packet.WriteByte((byte)dtValue.Hour); packet.WriteByte((byte)dtValue.Minute); packet.WriteByte((byte)dtValue.Second); } if (type == MySqlDbType.Timestamp) packet.WriteInteger(dtValue.Millisecond, 4); }
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; 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) packet.ReadInteger(4); return new MySqlDateTime(type, year, month, day, hour, minute, second); }
void IMySqlValue.SkipValue(MySqlPacket packet) { packet.ReadByte(); }
/// <summary> /// Serializes the given parameter to the given memory stream /// </summary> /// <remarks> /// <para>This method is called by PrepareSqlBuffers to convert the given /// parameter to bytes and write those bytes to the given memory stream. /// </para> /// </remarks> /// <returns>True if the parameter was successfully serialized, false otherwise.</returns> private bool SerializeParameter(MySqlParameterCollection parameters, MySqlPacket packet, string parmName) { MySqlParameter parameter = parameters.GetParameterFlexible(parmName, false); if (parameter == null) { // if we are allowing user variables and the parameter name starts with @ // then we can't throw an exception if (parmName.StartsWith("@") && ShouldIgnoreMissingParameter(parmName)) return false; throw new MySqlException( String.Format(Resources.ParameterMustBeDefined, parmName)); } parameter.Serialize(packet, false, Connection.Settings); return true; }
IMySqlValue IMySqlValue.ReadValue(MySqlPacket packet, long length, bool nullVal) { if (nullVal) return new MySqlInt64(true); if (length == -1) return new MySqlInt64((long)packet.ReadULong(8)); else return new MySqlInt64(Int64.Parse(packet.ReadString(length))); }
void IMySqlValue.SkipValue(MySqlPacket packet) { packet.Position += 8; }
private void ReadEOF() { packet = stream.ReadPacket(); CheckEOF(); }
public void ExecuteStatement(MySqlPacket packetToExecute) { warnings = 0; packetToExecute.Buffer[4] = (byte)DBCmd.EXECUTE; ExecutePacket(packetToExecute); serverStatus |= ServerStatusFlags.AnotherQuery; }
public IMySqlValue ReadValue(MySqlPacket packet, long length, bool isNull) { this.isNull = isNull; if (isNull) return this; if (length == -1) length = packet.ReadFieldLength(); if (ReadAsString) mValue = UInt64.Parse(packet.ReadString(length)); else mValue = (UInt64)packet.ReadBitValue((int)length); return this; }
public void WriteValue(MySqlPacket packet, bool binary, object value, int length) { ulong v = (value is UInt64) ? (UInt64)value : Convert.ToUInt64(value); if (binary) packet.WriteInteger((long)v, 8); else packet.WriteStringNoNull(v.ToString()); }
public void SkipValue(MySqlPacket packet) { int len = (int)packet.ReadFieldLength(); packet.Position += len; }
private void WriteOldGuid(MySqlPacket packet, Guid guid, bool binary) { byte[] bytes = guid.ToByteArray(); if (binary) { packet.WriteLength(bytes.Length); packet.Write(bytes); } else { packet.WriteStringNoNull("_binary "); packet.WriteByte((byte)'\''); EscapeByteArray(bytes, bytes.Length, packet); packet.WriteByte((byte)'\''); } }
public virtual void ExecuteStatement(MySqlPacket packetToExecute) { handler.ExecuteStatement(packetToExecute); }
// private void ClearFetchedRow() // { // if (lastCommandResult == 0) return; //TODO /* CommandResult result = (CommandResult)commandResults[lastCommandResult]; result.ReadRemainingColumns(); stream.OpenPacket(); if (! stream.IsLastPacket) throw new MySqlException("Cursor reading out of sync"); ReadEOF(false); lastCommandResult = 0;*/ // } /// <summary> /// FetchDataRow is the method that the data reader calls to see if there is another /// row to fetch. In the non-prepared mode, it will simply read the next data packet. /// In the prepared mode (statementId > 0), it will /// </summary> public bool FetchDataRow(int statementId, int columns) { /* ClearFetchedRow(); if (!commandResults.ContainsKey(statementId)) return false; if ( (serverStatus & ServerStatusFlags.LastRowSent) != 0) return false; stream.StartPacket(9, true); stream.WriteByte((byte)DBCmd.FETCH); stream.WriteInteger(statementId, 4); stream.WriteInteger(1, 4); stream.Flush(); lastCommandResult = statementId; */ packet = stream.ReadPacket(); if (packet.IsLastPacket) { CheckEOF(); return false; } nullMap = null; if (statementId > 0) ReadNullMap(columns); return true; }
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 int GetResult(ref int affectedRow, ref int 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; } int fieldCount = (int)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 = (int)packet.ReadFieldLength(); serverStatus = (ServerStatusFlags)packet.ReadInteger(2); warnings += packet.ReadInteger(2); if (packet.HasMoreData) { packet.ReadLenString(); //TODO: server message } } return fieldCount; }
private 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 void Open() { // connect to one of our specified hosts try { if (Settings.ConnectionProtocol == MySqlConnectionProtocol.SharedMemory) { SharedMemoryStream str = new SharedMemoryStream(Settings.SharedMemoryName); str.Open(Settings.ConnectionTimeout); baseStream = str; } else { string pipeName = Settings.PipeName; if (Settings.ConnectionProtocol != MySqlConnectionProtocol.NamedPipe) pipeName = null; #if !DNX StreamCreator sc = new StreamCreator(Settings.Server, Settings.Port, pipeName,Settings.Keepalive); #else StreamCreator sc = new StreamCreator(Settings.Server, Settings.Port, Settings.Keepalive); #endif baseStream = sc.GetStream(Settings.ConnectionTimeout); } } 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(); version = DBVersion.Parse(versionString); if (!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(); } // based on our settings, set our connection flags SetConnectionFlags(serverCaps); packet.Clear(); packet.WriteInteger((int)connectionFlags, 4); #if !CF 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); } #endif packet.WriteInteger(maxSinglePacket, 4); packet.WriteByte(8); packet.Write(new byte[23]); Authenticate(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; }
void IMySqlValue.WriteValue(MySqlPacket packet, bool binary, object val, int length) { long v = (val is Int64) ? (Int64)val : Convert.ToInt64(val); if (binary) packet.WriteInteger(v, 8); else packet.WriteStringNoNull(v.ToString()); }
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 InternalBindParameters(string sql, MySqlParameterCollection parameters, MySqlPacket packet) { bool sqlServerMode = command.Connection.Settings.SqlServerMode; if (packet == null) { packet = new MySqlPacket(Driver.Encoding); packet.Version = Driver.Version; packet.WriteByte(0); } MySqlTokenizer tokenizer = new MySqlTokenizer(sql); tokenizer.ReturnComments = true; tokenizer.SqlServerMode = sqlServerMode; int pos = 0; string token = tokenizer.NextToken(); while (token != null) { // serialize everything that came before the token (i.e. whitespace) packet.WriteStringNoNull(sql.Substring(pos, tokenizer.StartIndex - pos)); pos = tokenizer.StopIndex; if (MySqlTokenizer.IsParameter(token)) { if (SerializeParameter(parameters, packet, token)) token = null; } if (token != null) { if (sqlServerMode && tokenizer.Quoted && token.StartsWith("[")) token = String.Format("`{0}`", token.Substring(1, token.Length - 2)); packet.WriteStringNoNull(token); } token = tokenizer.NextToken(); } buffers.Add(packet); }
/// <summary> /// Query is the method that is called to send all queries to the server /// </summary> public void SendQuery(MySqlPacket queryPacket) { warnings = 0; queryPacket.Buffer[4] = (byte)DBCmd.QUERY; ExecutePacket(queryPacket); // the server will respond in one of several ways with the first byte indicating // the type of response. // 0 == ok packet. This indicates non-select queries // 0xff == error packet. This is handled in stream.OpenPacket // > 0 = number of columns in select query // We don't actually read the result here since a single query can generate // multiple resultsets and we don't want to duplicate code. See ReadResult // Instead we set our internal server status flag to indicate that we have a query waiting. // This flag will be maintained by ReadResult serverStatus |= ServerStatusFlags.AnotherQuery; }
IMySqlValue IMySqlValue.ReadValue(MySqlPacket packet, long length, bool nullVal) { if (nullVal) return new MySqlByte(true); if (length == -1) return new MySqlByte((sbyte)packet.ReadByte()); else { string s = packet.ReadString(length); MySqlByte b = new MySqlByte(SByte.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture)); b.TreatAsBoolean = TreatAsBoolean; return b; } }
/// <summary> /// Perform an authentication against a 4.1.1 server /// <param name="reset"> /// True, if this function is called as part of CHANGE_USER request /// (connection reset) /// False, for first-time logon /// </param> /// </summary> private void AuthenticateNew(bool reset) { if ((connectionFlags & ClientFlags.SECURE_CONNECTION) == 0) AuthenticateOld(); packet.Write(Crypt.Get411Password(Settings.Password, encryptionSeed)); if ((connectionFlags & ClientFlags.CONNECT_WITH_DB) != 0 && Settings.Database != null) packet.WriteString(Settings.Database); else packet.WriteString(""); // Add a null termination to the string. if (Settings.IntegratedSecurity) { // Append authentication method after the database name in the // handshake authentication packet.If we're sending CHANGE_USER // also write charset number after database name prior to plugin name if (reset) { packet.WriteInteger(8, 2); // Charset number } packet.WriteString(AuthenticationWindowsPlugin); stream.SendPacket(packet); AuthenticateSSPI(); return; } else { stream.SendPacket(packet); } // this result means the server wants us to send the password using // old encryption packet = stream.ReadPacket(); if (packet.IsLastPacket) { packet.Clear(); packet.WriteString(Crypt.EncryptPassword( Settings.Password, encryptionSeed.Substring(0, 8), true)); stream.SendPacket(packet); ReadOk(true); } ReadOk(false); }
void IMySqlValue.WriteValue(MySqlPacket packet, bool binary, object val, int length) { sbyte v = (val is sbyte) ? (sbyte)val : Convert.ToSByte(val); if (binary) packet.WriteByte((byte)v); else packet.WriteStringNoNull(v.ToString()); }
private void AuthenticateSSPI() { string targetName = ""; // target name (required by Kerberos) // First packet sent by server should include target name (for // Kerberos) as UTF8 string. It might however be prepended by junk // at the start of the string (0xfe"authentication_win_client"\0, // see Bug#57442), this junk will be ignored. Target name can also // be an empty string if server is not running in a domain environment, // in this case authentication will fallback to NTLM. // Note that 0xfe byte at the start could also indicate that windows // authentication is not supported by sérver, we throw an exception // if this happens. packet = stream.ReadPacket(); byte b = packet.ReadByte(); if (b == 0xfe) { string authMethod = packet.ReadString(); if (authMethod.Equals(AuthenticationWindowsPlugin)) { targetName = packet.ReadString(Encoding.UTF8); } else { // User has requested Windows authentication, bail out. throw new MySqlException("unexpected authentication method " + authMethod); } } else { targetName = Encoding.UTF8.GetString(packet.Buffer, 0, packet.Buffer.Length); } // Do SSPI authentication handshake SSPI sspi = new SSPI(targetName, stream.BaseStream, stream.SequenceByte); sspi.AuthenticateClient(); // read ok packet. packet = stream.ReadPacket(); ReadOk(false); }
void IMySqlValue.SkipValue(MySqlPacket packet) { int len = packet.ReadByte(); packet.Position += len; }
private void ExecutePacket(MySqlPacket packetToExecute) { try { warnings = 0; stream.SequenceByte = 0; stream.SendPacket(packetToExecute); } catch (MySqlException ex) { HandleException(ex); throw; } }
private void SerializeText(MySqlPacket packet, MySqlDateTime value) { string val = String.Empty; val = String.Format("{0:0000}-{1:00}-{2:00}", value.Year, value.Month, value.Day); if (type != MySqlDbType.Date) val = String.Format("{0} {1:00}:{2:00}:{3:00}", val, value.Hour, value.Minute, value.Second); packet.WriteStringNoNull("'" + val + "'"); }
public virtual void SendQuery(MySqlPacket p) { handler.SendQuery(p); firstResult = true; }