示例#1
0
        /// <summary>
        /// +/- blocking
        /// </summary>
        /// <param name="nextAction"></param>
        public void Prepare(Action nextAction = null)
        {
            _execState     = QueryExecState.Prepare;
            _queryUsedMode = QueryUseMode.Prepare;

            if (_cmdParams == null)
            {
                throw new Exception("Sql cmdParams can not null.");
            }
            //-------------------
            //blocking method***
            //wait until execute finish
            //-------------------
            //prepare sql query
            _sqlParserMx.UsePrepareResponseParser();
            _prepareContext = null;
            //-------------------------------------------------------------
            _writer.Reset();
            ComPrepareStatementPacket.Write(
                _writer,
                _sqlStrTemplate.BindValues(_cmdParams, true));
            //-------------------------------------------------------------
            if (nextAction != null)
            {
                //not block here
                SendAndRecv_A(_writer.ToArray(), nextAction);
            }
            else
            {
                //blocking
                _conn.InitWait();
                SendAndRecv_A(_writer.ToArray(), _conn.UnWait);
                _conn.Wait();
            }
        }
        /// <summary>
        /// open connection, +/- blocking
        /// </summary>
        /// <param name="nextAction"></param>
        public void Connect(Action nextAction = null)
        {
            if (State == ConnectionState.Connected)
            {
                throw new NotSupportedException("already connected");
            }
            _mysqlParserMx.UseConnectionParser();
            this._workingState = WorkingState.Rest;
            //--------------
            var endpoint = new IPEndPoint(IPAddress.Parse(config.host), config.port);

            socket.Connect(endpoint);
            this._workingState = WorkingState.Rest;
            //--------------
            //**start listen after connect
            InitWait();
            StartReceive(mysql_result =>
            {
                //when complete1
                //create handshake packet and send back
                var handshakeResult = mysql_result as MySqlHandshakeResult;
                if (handshakeResult == null)
                {
                    //error
                    throw new Exception("err1");
                }
                HandshakePacket handshake_packet = handshakeResult.packet;
                this.threadId = handshake_packet.threadId;

                // https://dev.mysql.com/doc/internals/en/sha256.html

                byte[] token = string.IsNullOrEmpty(config.password) ?
                               /*1*/ new byte[0] : //Empty passwords are not hashed, but sent as empty string.

                               /* or 2*/ MakeToken(config.password, GetScrollbleBuffer(
                                                       handshake_packet.scrambleBuff1,
                                                       handshake_packet.scrambleBuff2));

                _writer.IncrementPacketNumber();
                //----------------------------
                //send authen packet to the server
                var authPacket = new ClientAuthenticationPacket(new PacketHeader());
                authPacket.SetValues(config.user, token, config.database, isProtocol41 = handshake_packet.protocol41);
                authPacket.WritePacket(_writer);
                byte[] sendBuff = _writer.ToArray();
                _writer.Reset();
                //------------------------------------
                //switch to result packet parser
                _mysqlParserMx.SetProtocol41(isProtocol41);
                _mysqlParserMx.UseResultParser();
                //------------------------------------
                StartSend(sendBuff, 0, sendBuff.Length, () =>
                {
                    StartReceive(mysql_result2 =>
                    {
                        var ok = mysql_result2 as MySqlOkResult;
                        if (ok != null)
                        {
                            this._workingState = WorkingState.Rest;
                        }
                        else
                        {
                            //TODO: review here
                            //error
                            _workingState = WorkingState.Error;
                        }
                        //set max allow of the server ***
                        //todo set max allow packet***
                        UnWait();
                        if (nextAction != null)
                        {
                            nextAction();
                        }
                    });
                });
            });
            if (nextAction == null)
            {
                //block ....
                Wait();
            }
            else
            {
                UnWait();
            }
        }