internal void ReadOk(bool read)
        {
            try
            {
                if (read)
                {
                    packet = stream.ReadPacket();
                }
                byte marker = (byte)packet.ReadByte();
                if (marker != 0)
                {
                    throw new MyCatException("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 (MyCatException ex)
            {
                HandleException(ex);
                throw;
            }
        }
Exemple #2
0
 internal void Serialize(MyCatPacket packet, bool binary, MyCatConnectionStringBuilder settings)
 {
     if (!binary && (paramValue == null || paramValue == DBNull.Value))
     {
         packet.WriteStringNoNull("NULL");
     }
     else
     {
         if (ValueObject.MyCatDbType == MyCatDbType.Guid)
         {
             MyCatGuid g = (MyCatGuid)ValueObject;
             g.OldGuids  = settings.OldGuids;
             ValueObject = g;
         }
         if (ValueObject.MyCatDbType == MyCatDbType.Geometry)
         {
             MyCatGeometry v = (MyCatGeometry)ValueObject;
             if (v.IsNull && Value != null)
             {
                 MyCatGeometry.TryParse(Value.ToString(), out v);
             }
             ValueObject = v;
         }
         ValueObject.WriteValue(packet, binary, paramValue, Size);
     }
 }
        //		private void ClearFetchedRow()
        //		{
        //			if (lastCommandResult == 0) return;

        //TODO

        /*			CommandResult result = (CommandResult)commandResults[lastCommandResult];
         *          result.ReadRemainingColumns();
         *
         *          stream.OpenPacket();
         *          if (! stream.IsLastPacket)
         *              throw new MyCatException("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);
        }
Exemple #4
0
        public void SendPacket(MyCatPacket packet)
        {
            byte[] buffer = packet.Buffer;
            int    length = packet.Position - 4;

            if ((ulong)length > maxPacketSize)
            {
                throw new MyCatException(Resources.QueryTooLarge, (int)MyCatErrorCode.PacketTooLarge);
            }

            int offset = 0;

            while (length > 0)
            {
                int lenToSend = length > maxBlockSize ? maxBlockSize : length;
                buffer[offset]     = (byte)(lenToSend & 0xff);
                buffer[offset + 1] = (byte)((lenToSend >> 8) & 0xff);
                buffer[offset + 2] = (byte)((lenToSend >> 16) & 0xff);
                buffer[offset + 3] = sequenceByte++;

                outStream.Write(buffer, offset, lenToSend + 4);
                outStream.Flush();
                length -= lenToSend;
                offset += lenToSend;
            }
        }
Exemple #5
0
        /// <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(MyCatParameterCollection parameters,
                                        MyCatPacket packet, string parmName, int parameterIndex)
        {
            MyCatParameter parameter = null;

            if (!parameters.containsUnnamedParameters)
            {
                parameter = parameters.GetParameterFlexible(parmName, false);
            }
            else
            {
                if (parameterIndex <= parameters.Count)
                {
                    parameter = parameters[parameterIndex];
                }
                else
                {
                    throw new MyCatException(Resources.ParameterIndexNotFound);
                }
            }

            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("@", StringComparison.Ordinal) && ShouldIgnoreMissingParameter(parmName))
                {
                    return(false);
                }
                throw new MyCatException(
                          String.Format(Resources.ParameterMustBeDefined, parmName));
            }
            parameter.Serialize(packet, false, Connection.Settings);
            return(true);
        }
 public void ExecuteStatement(MyCatPacket packetToExecute)
 {
     warnings = 0;
     packetToExecute.SetByte(4, (byte)DBCmd.EXECUTE);
     ExecutePacket(packetToExecute);
     serverStatus |= ServerStatusFlags.AnotherQuery;
 }
Exemple #7
0
        public virtual void ExecuteDirect(string sql)
        {
            MyCatPacket p = new MyCatPacket(Encoding);

            p.WriteString(sql);
            SendQuery(p);
            NextResult(0, false);
        }
Exemple #8
0
        protected virtual void BindParameters()
        {
            MyCatParameterCollection parameters = command.Parameters;
            int index = 0;

            while (true)
            {
                InternalBindParameters(ResolvedCommandText, parameters, null);

                // if we are not batching, then we are done.  This is only really relevant the
                // first time through
                if (command.Batch == null)
                {
                    return;
                }
                while (index < command.Batch.Count)
                {
                    MyCatCommand batchedCmd = command.Batch[index++];
                    MyCatPacket  packet     = (MyCatPacket)buffers[buffers.Count - 1];

                    // now we make a guess if this statement will fit in our current stream
                    long estimatedCmdSize = batchedCmd.EstimatedSize();
                    if (((packet.Length - 4) + estimatedCmdSize) > Connection.driver.MaxPacketSize)
                    {
                        // it won't, so we setup to start a new run from here
                        parameters = batchedCmd.Parameters;
                        break;
                    }

                    // looks like we might have room for it so we remember the current end of the stream
                    buffers.RemoveAt(buffers.Count - 1);
                    //long originalLength = packet.Length - 4;

                    // and attempt to stream the next command
                    string text = ResolvedCommandText;
                    if (text.StartsWith("(", StringComparison.Ordinal))
                    {
                        packet.WriteStringNoNull(", ");
                    }
                    else
                    {
                        packet.WriteStringNoNull("; ");
                    }
                    InternalBindParameters(text, batchedCmd.Parameters, packet);
                    if ((packet.Length - 4) > Connection.driver.MaxPacketSize)
                    {
                        //TODO
                        //stream.InternalBuffer.SetLength(originalLength);
                        parameters = batchedCmd.Parameters;
                        break;
                    }
                }
                if (index == command.Batch.Count)
                {
                    return;
                }
            }
        }
Exemple #9
0
        public virtual void Prepare()
        {
            // strip out names from parameter markers
            string        text;
            List <string> parameter_names = PrepareCommandText(out text);

            // ask our connection to send the prepare command
            MyCatField[] paramList = null;
            statementId = Driver.PrepareStatement(text, ref paramList);

            // now we need to assign our field names since we stripped them out
            // for the prepare
            for (int i = 0; i < parameter_names.Count; i++)
            {
                //paramList[i].ColumnName = (string) parameter_names[i];
                string         parameterName = (string)parameter_names[i];
                MyCatParameter p             = Parameters.GetParameterFlexible(parameterName, false);
                if (p == null)
                {
                    throw new InvalidOperationException(
                              String.Format(Resources.ParameterNotFoundDuringPrepare, parameterName));
                }
                p.Encoding = paramList[i].Encoding;
                parametersToSend.Add(p);
            }

            // now prepare our null map
            int numNullBytes = 0;

            if (paramList != null && paramList.Length > 0)
            {
#if NET451
                nullMap = new BitArray(paramList.Length);
#else
                nullMap = new RtBitArray(paramList.Length);
#endif
                numNullBytes = (nullMap.Count + 7) / 8;
            }

            packet = new MyCatPacket(Driver.Encoding);

            // write out some values that do not change run to run
            packet.WriteByte(0);
            packet.WriteInteger(statementId, 4);
            packet.WriteByte((byte)0);       // flags; always 0 for 4.1
            packet.WriteInteger(1, 4);       // interation count; 1 for 4.1
            nullMapPosition  = packet.Position;
            packet.Position += numNullBytes; // leave room for our null map
            packet.WriteByte(1);             // rebound flag
                                             // write out the parameter types
            foreach (MyCatParameter p in parametersToSend)
            {
                packet.WriteInteger(p.GetPSType(), 2);
            }
            dataPosition = packet.Position;
        }
        public int PrepareStatement(string sql, ref MyCatField[] 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 MyCatException("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);
        }
Exemple #11
0
        private void InternalBindParameters(string sql, MyCatParameterCollection parameters,
                                            MyCatPacket packet)
        {
            bool sqlServerMode = command.Connection.Settings.SqlServerMode;

            if (packet == null)
            {
                packet         = new MyCatPacket(Driver.Encoding);
                packet.Version = Driver.Version;
                packet.WriteByte(0);
            }

            MyCatTokenizer tokenizer = new MyCatTokenizer(sql);

            tokenizer.ReturnComments = true;
            tokenizer.SqlServerMode  = sqlServerMode;

            int    pos            = 0;
            string token          = tokenizer.NextToken();
            int    parameterCount = 0;

            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 (MyCatTokenizer.IsParameter(token))
                {
                    if ((!parameters.containsUnnamedParameters && token.Length == 1 && parameterCount > 0) || parameters.containsUnnamedParameters && token.Length > 1)
                    {
                        throw new MyCatException(Resources.MixedParameterNamingNotAllowed);
                    }

                    parameters.containsUnnamedParameters = token.Length == 1;
                    if (SerializeParameter(parameters, packet, token, parameterCount))
                    {
                        token = null;
                    }
                    parameterCount++;
                }
                if (token != null)
                {
                    if (sqlServerMode && tokenizer.Quoted && token.StartsWith("[", StringComparison.Ordinal))
                    {
                        token = String.Format("`{0}`", token.Substring(1, token.Length - 2));
                    }
                    packet.WriteStringNoNull(token);
                }
                token = tokenizer.NextToken();
            }
            buffers.Add(packet);
        }
Exemple #12
0
        public MyCatStream(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 MyCatPacket(encoding);
        }
        public override void ExecuteStatement(MyCatPacket packetToExecute)
        {
            base.ExecuteStatement(packetToExecute);
            int pos = packetToExecute.Position;

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

            packetToExecute.Position = pos;

            MyCatTrace.TraceEvent(TraceEventType.Information, MyCatTraceEventType.StatementExecuted,
                                  Resources.TraceStatementExecuted, driverId, statementId, ThreadID);
        }
 private void ExecutePacket(MyCatPacket packetToExecute)
 {
     try
     {
         warnings            = 0;
         stream.SequenceByte = 0;
         stream.SendPacket(packetToExecute);
     }
     catch (MyCatException ex)
     {
         HandleException(ex);
         throw;
     }
 }
Exemple #15
0
        public virtual bool ExecuteNext()
        {
            if (buffers.Count == 0)
            {
                return(false);
            }

            MyCatPacket packet = (MyCatPacket)buffers[0];

            //MemoryStream ms = stream.InternalBuffer;
            Driver.SendQuery(packet);
            buffers.RemoveAt(0);
            return(true);
        }
 /// <summary>
 /// Query is the method that is called to send all queries to the server
 /// </summary>
 public void SendQuery(MyCatPacket queryPacket)
 {
     warnings = 0;
     queryPacket.SetByte(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;
 }
        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(MyCatField 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);
            MyCatDbType type = (MyCatDbType)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 == MyCatDbType.Decimal || type == MyCatDbType.NewDecimal)
            {
                field.Precision = (byte)(field.ColumnLength - 2);
                if ((colFlags & ColumnFlags.UNSIGNED) != 0)
                {
                    field.Precision++;
                }
            }

            field.SetTypeAndFlags(type, colFlags);
        }
        public override void SendQuery(MyCatPacket p)
        {
            rowSizeInBytes = 0;
            string cmdText          = Encoding.GetString(p.Buffer, 5, p.Length - 5);
            string normalized_query = null;

            if (cmdText.Length > 300)
            {
                QueryNormalizer normalizer = new QueryNormalizer();
                normalized_query = normalizer.Normalize(cmdText);
                cmdText          = cmdText.Substring(0, 300);
            }

            base.SendQuery(p);

            MyCatTrace.TraceEvent(TraceEventType.Information, MyCatTraceEventType.QueryOpened,
                                  Resources.TraceQueryOpened, driverId, ThreadID, cmdText);
            if (normalized_query != null)
            {
                MyCatTrace.TraceEvent(TraceEventType.Information, MyCatTraceEventType.QueryNormalized,
                                      Resources.TraceQueryNormalized, driverId, ThreadID, normalized_query);
            }
        }
Exemple #20
0
 public virtual void ExecuteStatement(MyCatPacket packetToExecute)
 {
     handler.ExecuteStatement(packetToExecute);
 }
Exemple #21
0
 public virtual void SendQuery(MyCatPacket p)
 {
     handler.SendQuery(p);
     firstResult = true;
 }
 internal void SendPacket(MyCatPacket p)
 {
     stream.SendPacket(p);
 }
 internal MyCatPacket ReadPacket()
 {
     return(packet = stream.ReadPacket());
 }
 private void ReadEOF()
 {
     packet = stream.ReadPacket();
     CheckEOF();
 }
        public void Open()
        {
            // connect to one of our specified hosts
            try
            {
                baseStream = StreamCreator.GetStream(Settings);
#if NET451
                if (Settings.IncludeSecurityAsserts)
                {
                    MyCatSecurityPermission.CreatePermissionSet(false).Assert();
                }
#endif
            }
            catch (System.Security.SecurityException)
            {
                throw;
            }
            catch (Exception ex)
            {
                throw new MyCatException(Resources.UnableToConnectToHost,
                                         (int)MyCatErrorCode.UnableToConnectToHost, ex);
            }
            if (baseStream == null)
            {
                throw new MyCatException(Resources.UnableToConnectToHost,
                                         (int)MyCatErrorCode.UnableToConnectToHost);
            }

            int maxSinglePacket = 255 * 255 * 255;
            stream = new MyCatStream(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 MyCat 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 != MyCatSslMode.None) &&
                    (Settings.SslMode != MyCatSslMode.Preferred))
                {
                    // Client requires SSL connections.
                    string message = String.Format(Resources.NoServerSSLSupport,
                                                   Settings.Server);
                    throw new MyCatException(message);
                }
            }
            else if (Settings.SslMode != MyCatSslMode.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 MyCatStream(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;
        }