/* * Copyright 2008-2108 amoeba.meidusa.com * * This program is free software; you can redistribute it and/or modify it under the terms of * the GNU AFFERO GENERAL PUBLIC LICENSE as published by the Free Software Foundation; either version 3 of the License, * or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU AFFERO GENERAL PUBLIC LICENSE for more details. * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE along with this program; * if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package com.meidusa.amoeba.mysql.handler; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import com.meidusa.amoeba.mysql.handler.session.CommandStatus; import com.meidusa.amoeba.mysql.handler.session.ConnectionStatuts; import com.meidusa.amoeba.mysql.net.CommandInfo; import com.meidusa.amoeba.mysql.net.MysqlClientConnection; import com.meidusa.amoeba.mysql.net.MysqlServerConnection; import com.meidusa.amoeba.mysql.net.packet.EOFPacket; import com.meidusa.amoeba.mysql.net.packet.ErrorPacket; import com.meidusa.amoeba.mysql.net.packet.MysqlPacketBuffer; import com.meidusa.amoeba.mysql.net.packet.OkPacket; import com.meidusa.amoeba.mysql.net.packet.QueryCommandPacket; import com.meidusa.amoeba.net.Connection; import com.meidusa.amoeba.net.packet.Packet; import com.meidusa.amoeba.parser.statement.InsertStatement; import com.meidusa.amoeba.parser.statement.Statement; import com.meidusa.amoeba.util.StringUtil; class CommandQueue{ protected List<CommandInfo> sessionInitQueryQueue; //���еĴӿͻ��˷��͹����� command ���� protected CommandInfo currentCommand;//��ǰ��query protected Map<MysqlServerConnection,ConnectionStatuts> connStatusMap = new HashMap<MysqlServerConnection,ConnectionStatuts>(); boolean mainCommandExecuted; private MysqlClientConnection source; protected Statement statment; public CommandQueue(MysqlClientConnection source,Statement statment){ this.source = source; this.statment = statment; } public boolean isMultiple(){ return connStatusMap.size()>1; } public void clearAllBuffer(){ Collection<ConnectionStatuts> collection = connStatusMap.values(); for(ConnectionStatuts status : collection){ status.clearBuffer(); } } /** * ������һ������������false����ʾ������û�������ˡ� * * @return */ boolean tryNextCommandTuple(){ if(sessionInitQueryQueue == null){ return false; }else{ if(sessionInitQueryQueue.size()>0){ currentCommand = sessionInitQueryQueue.get(0); if(CommandMessageHandler.logger.isDebugEnabled()){ QueryCommandPacket command = new QueryCommandPacket(); command.init(currentCommand.getBuffer(),source); CommandMessageHandler.logger.debug(command); } return true; } return false; } } /** * �жϷ��ص������Ƿ��ǵ�ǰ����Ľ������� * ��ǰȫ�����Ӷ�ȫ�������Ժ����ʾ��ǰ������ȫ������ * @param conn * @param buffer * @return */ protected CommandStatus checkResponseCompleted(Connection conn,byte[] buffer){ boolean isCompleted = false; ConnectionStatuts connStatus = connStatusMap.get(conn); if(connStatus == null){ CommandMessageHandler.logger.error("connection Status not Found, byffer="+StringUtil.dumpAsHex(buffer, buffer.length)); } try{ connStatus.buffers.add(buffer); isCompleted = connStatus.isCompleted(buffer); /** * ����Ƕ�����ӵģ���Ҫ�����ݻ����������ȴ�����ȫ������Ժ󣬽����ݽ�����װ��Ȼ���͵��ͻ��� * {@link #CommandMessageHandler.mergeMessageToClient} */ if(isCompleted){ //set last insert id to client connection; if(conn != source){ if(connStatus.packetIndex == 0 && MysqlPacketBuffer.isOkPacket(buffer)){ if(statment instanceof InsertStatement && currentCommand.isMain()){ OkPacket packet = new OkPacket(); packet.init(buffer,conn); if(packet.insertId>0){ source.setLastInsertId(packet.insertId); } } } } boolean isAllCompleted = currentCommand.getCompletedCount().incrementAndGet() == connStatusMap.size(); if(isAllCompleted){ connStatus.isMerged = true; } if(isAllCompleted){ if(CommandMessageHandler.logger.isDebugEnabled()){ Packet packet = null; if(MysqlPacketBuffer.isErrorPacket(buffer)){ packet = new ErrorPacket(); }else if(MysqlPacketBuffer.isEofPacket(buffer)){ packet = new EOFPacket(); }else if(MysqlPacketBuffer.isOkPacket(buffer)){ packet = new OkPacket(); } packet.init(buffer,conn); CommandMessageHandler.logger.debug("returned Packet:"+packet); } return CommandStatus.AllCompleted; }else{ return CommandStatus.ConnectionCompleted; } }else{ return CommandStatus.ConnectionNotComplete; } }finally{ connStatus.packetIndex ++; } } /** * �Ƿ�append �ɹ�������ɹ����ʾ��ǰ�����ѻ�������Ҫ��������֤���������ѭ�� * ���������û�жѻ�������򷵻�false. * ���򷵻�true�� ���ʾ��ֱ�ӷ������� * @param commandInfo * @param force ǿ��append �������Ϊtrue * @return */ public synchronized boolean appendCommand(CommandInfo commandInfo,boolean force){ if(force){ if(sessionInitQueryQueue == null){ sessionInitQueryQueue = Collections.synchronizedList(new ArrayList<CommandInfo>()); } if(!sessionInitQueryQueue.contains(commandInfo)){ sessionInitQueryQueue.add(commandInfo); } return true; }else{ if(sessionInitQueryQueue == null){ return false; }else{ if(sessionInitQueryQueue.size() ==0){ return false; } if(!sessionInitQueryQueue.contains(commandInfo)){ sessionInitQueryQueue.add(commandInfo); } return true; } } } }