提交 7614b225 编写于 作者: Y Yiming Liu

add desc support, replace original ServerParse & Server ParseShow

上级 26407bf6
......@@ -19,9 +19,11 @@ import com.dianping.bee.engine.spi.internal.DefaultTableProviderManager;
import com.dianping.bee.engine.spi.internal.MultiTableStatementVisitor;
import com.dianping.bee.engine.spi.internal.SingleTableStatementVisitor;
import com.dianping.bee.engine.spi.internal.TableHelper;
import com.dianping.bee.server.SelectHandler;
import com.dianping.bee.server.SimpleDescHandler;
import com.dianping.bee.server.SimpleSelectHandler;
import com.dianping.bee.server.SimpleServer;
import com.dianping.bee.server.SimpleServerQueryHandler;
import com.dianping.bee.server.SimpleShowHandler;
import com.site.lookup.configuration.AbstractResourceConfigurator;
import com.site.lookup.configuration.Component;
......@@ -50,10 +52,12 @@ public class ComponentsConfigurator extends AbstractResourceConfigurator {
all.add(C(MultiTableStatementVisitor.class).is(PER_LOOKUP) //
.req(TableHelper.class, MultiTableStatement.class, RowFilter.class));
all.add(C(SelectHandler.class) //
all.add(C(SimpleShowHandler.class));
all.add(C(SimpleDescHandler.class));
all.add(C(SimpleSelectHandler.class) //
.req(StatementManager.class));
all.add(C(SimpleServerQueryHandler.class).is(PER_LOOKUP) //
.req(SelectHandler.class));
.req(SimpleSelectHandler.class, SimpleShowHandler.class));
return all;
}
......
......@@ -5,4 +5,6 @@ public interface DatabaseProvider {
public String getName();
public TableProvider[] getTables();
public TableProvider getTable(String tableName);
}
\ No newline at end of file
/**
* Project: bee-engine
*
* File Created at 2012-8-23
*
* Copyright 2012 dianping.com.
* All rights reserved.
*
* This software is the confidential and proprietary information of
* Dianping Company. ("Confidential Information"). You shall not
* disclose such Confidential Information and shall use it only in
* accordance with the terms of the license agreement you entered into
* with dianping.com.
*/
package com.dianping.bee.engine.spi.meta.internal;
import com.alibaba.cobar.Fields;
/**
* @author <a href="mailto:yiming.liu@dianping.com">Yiming Liu</a>
*/
public class TypeUtils {
public static int convertJavaTypeToFieldType(Class<?> clazz) {
String simpleClassName = clazz.getSimpleName();
if ("String".equals(simpleClassName)) {
return Fields.FIELD_TYPE_STRING;
} else if ("int".equals(simpleClassName) || "Integer".equals(simpleClassName)) {
return Fields.FIELD_TYPE_INT24;
} else if ("long".equals(simpleClassName) || "Long".equals(simpleClassName)) {
return Fields.FIELD_TYPE_LONG;
} else if ("float".equals(simpleClassName) || "Float".equals(simpleClassName)) {
return Fields.FIELD_TYPE_FLOAT;
} else if ("double".equals(simpleClassName) || "Double".equals(simpleClassName)) {
return Fields.FIELD_TYPE_DOUBLE;
} else if ("Date".equals(simpleClassName)) {
return Fields.FIELD_TYPE_DATE;
} else if ("Timestamp".equals(simpleClassName)) {
return Fields.FIELD_TYPE_TIMESTAMP;
} else {
return Fields.FIELD_TYPE_STRING;
}
}
}
/**
* Project: bee-engine
*
* File Created at 2012-8-23
*
* Copyright 2012 dianping.com.
* All rights reserved.
*
* This software is the confidential and proprietary information of
* Dianping Company. ("Confidential Information"). You shall not
* disclose such Confidential Information and shall use it only in
* accordance with the terms of the license agreement you entered into
* with dianping.com.
*/
package com.dianping.bee.server;
import java.nio.ByteBuffer;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import com.alibaba.cobar.CobarServer;
import com.alibaba.cobar.ErrorCode;
import com.alibaba.cobar.Fields;
import com.alibaba.cobar.config.model.SchemaConfig;
import com.alibaba.cobar.net.util.PacketUtil;
import com.alibaba.cobar.protocol.mysql.EOFPacket;
import com.alibaba.cobar.protocol.mysql.FieldPacket;
import com.alibaba.cobar.protocol.mysql.ResultSetHeaderPacket;
import com.alibaba.cobar.protocol.mysql.RowDataPacket;
import com.alibaba.cobar.server.ServerConnection;
import com.alibaba.cobar.util.StringUtil;
import com.dianping.bee.engine.spi.DatabaseProvider;
import com.dianping.bee.engine.spi.TableProvider;
import com.dianping.bee.engine.spi.meta.ColumnMeta;
import com.site.lookup.ContainerLoader;
/**
* @author <a href="mailto:yiming.liu@dianping.com">Yiming Liu</a>
*/
public class SimpleDescHandler {
/**
* @param stmt
* @param c
* @param offset
*/
public void handle(String stmt, ServerConnection c, int offset) {
String tableName = stmt.substring(offset).trim();
// 检查当前使用的DB
String db = c.getSchema();
if (db == null) {
c.writeErrMessage(ErrorCode.ER_NO_DB_ERROR, "No database selected");
return;
}
SchemaConfig schema = CobarServer.getInstance().getConfig().getSchemas().get(db);
if (schema == null) {
c.writeErrMessage(ErrorCode.ER_BAD_DB_ERROR, "Unknown database '" + db + "'");
return;
}
DatabaseProvider provider = null;
try {
provider = ContainerLoader.getDefaultContainer().lookup(DatabaseProvider.class, db);
} catch (ComponentLookupException e) {
c.writeErrMessage(ErrorCode.ER_BAD_DB_ERROR, "Can not load database '" + db + "'");
return;
}
if (provider == null) {
c.writeErrMessage(ErrorCode.ER_BAD_DB_ERROR, "Can not load database '" + db + "'");
return;
}
//FIXME: why abstractmethod exception
TableProvider table = provider.getTable(tableName);
if (table == null) {
c.writeErrMessage(ErrorCode.ER_BAD_TABLE_ERROR, "Can not load table '" + tableName + "'");
return;
}
ColumnMeta[] columns = table.getColumns();
int FIELD_COUNT = 6;
ResultSetHeaderPacket header = PacketUtil.getHeader(FIELD_COUNT);
FieldPacket[] fields = new FieldPacket[FIELD_COUNT];
EOFPacket eof = new EOFPacket();
int i = 0;
byte packetId = 0;
header.packetId = ++packetId;
fields[i] = PacketUtil.getField("Field", Fields.FIELD_TYPE_VAR_STRING);
fields[i++].packetId = ++packetId;
fields[i] = PacketUtil.getField("Type", Fields.FIELD_TYPE_VAR_STRING);
fields[i++].packetId = ++packetId;
fields[i] = PacketUtil.getField("Null", Fields.FIELD_TYPE_VAR_STRING);
fields[i++].packetId = ++packetId;
fields[i] = PacketUtil.getField("Key", Fields.FIELD_TYPE_VAR_STRING);
fields[i++].packetId = ++packetId;
fields[i] = PacketUtil.getField("Default", Fields.FIELD_TYPE_VAR_STRING);
fields[i++].packetId = ++packetId;
fields[i] = PacketUtil.getField("Extra", Fields.FIELD_TYPE_VAR_STRING);
fields[i++].packetId = ++packetId;
eof.packetId = ++packetId;
ByteBuffer buffer = c.allocate();
// write header
buffer = header.write(buffer, c);
// write fields
for (FieldPacket field : fields) {
buffer = field.write(buffer, c);
}
// write eof
buffer = eof.write(buffer, c);
// write rows
packetId = eof.packetId;
for (ColumnMeta column : columns) {
RowDataPacket row = new RowDataPacket(FIELD_COUNT);
row.add(StringUtil.encode(column.getName(), c.getCharset()));
row.add(StringUtil.encode(column.getType().getSimpleName(), c.getCharset()));
row.add(StringUtil.encode(null, c.getCharset()));
row.add(StringUtil.encode(null, c.getCharset()));
row.add(StringUtil.encode(null, c.getCharset()));
row.add(StringUtil.encode(null, c.getCharset()));
row.packetId = ++packetId;
buffer = row.write(buffer, c);
}
// write last eof
EOFPacket lastEof = new EOFPacket();
lastEof.packetId = ++packetId;
buffer = lastEof.write(buffer, c);
// post write
c.write(buffer);
}
}
......@@ -41,32 +41,13 @@ import com.dianping.bee.engine.spi.meta.Cell;
import com.dianping.bee.engine.spi.meta.ColumnMeta;
import com.dianping.bee.engine.spi.meta.Row;
import com.dianping.bee.engine.spi.meta.RowSet;
import com.dianping.bee.engine.spi.meta.internal.TypeUtils;
import com.site.lookup.annotation.Inject;
/**
* @author <a href="mailto:yiming.liu@dianping.com">Yiming Liu</a>
*/
public class SelectHandler {
private static int convertJavaTypeToFieldType(Class<?> clazz) {
String simpleClassName = clazz.getSimpleName();
if ("String".equals(simpleClassName)) {
return Fields.FIELD_TYPE_STRING;
} else if ("int".equals(simpleClassName) || "Integer".equals(simpleClassName)) {
return Fields.FIELD_TYPE_INT24;
} else if ("long".equals(simpleClassName) || "Long".equals(simpleClassName)) {
return Fields.FIELD_TYPE_LONG;
} else if ("float".equals(simpleClassName) || "Float".equals(simpleClassName)) {
return Fields.FIELD_TYPE_FLOAT;
} else if ("double".equals(simpleClassName) || "Double".equals(simpleClassName)) {
return Fields.FIELD_TYPE_DOUBLE;
} else if ("Date".equals(simpleClassName)) {
return Fields.FIELD_TYPE_DATE;
} else if ("Timestamp".equals(simpleClassName)) {
return Fields.FIELD_TYPE_TIMESTAMP;
} else {
return Fields.FIELD_TYPE_STRING;
}
}
public class SimpleSelectHandler {
@Inject
private StatementManager m_manager;
......@@ -80,7 +61,7 @@ public class SelectHandler {
ColumnMeta column = rowset.getColumn(i);
Cell cell = row.getCell(i);
String value = cell.getValue().toString();
switch (convertJavaTypeToFieldType(column.getType())) {
switch (TypeUtils.convertJavaTypeToFieldType(column.getType())) {
case Fields.FIELD_TYPE_STRING:
packet.add(StringUtil.encode(value, charset));
break;
......@@ -208,8 +189,8 @@ public class SelectHandler {
int columnIndex = 0;
FieldPacket[] fields = new FieldPacket[fieldCount];
for (int i = 0; i < fieldCount; i++) {
fields[columnIndex] = PacketUtil.getField(rowset.getColumn(i).getName(), convertJavaTypeToFieldType(rowset
.getColumn(i).getType()));
fields[columnIndex] = PacketUtil.getField(rowset.getColumn(i).getName(),
TypeUtils.convertJavaTypeToFieldType(rowset.getColumn(i).getType()));
fields[columnIndex++].packetId = ++packetId;
}
eof.packetId = ++packetId;
......
/**
* Project: bee-engine
*
* File Created at 2012-8-23
*
* Copyright 2012 dianping.com.
* All rights reserved.
*
* This software is the confidential and proprietary information of
* Dianping Company. ("Confidential Information"). You shall not
* disclose such Confidential Information and shall use it only in
* accordance with the terms of the license agreement you entered into
* with dianping.com.
*/
package com.dianping.bee.server;
import java.nio.channels.SocketChannel;
import java.util.Set;
import com.alibaba.cobar.ErrorCode;
import com.alibaba.cobar.net.util.MySQLMessage;
import com.alibaba.cobar.protocol.mysql.OkPacket;
import com.alibaba.cobar.server.ServerConnection;
/**
* @author <a href="mailto:yiming.liu@dianping.com">Yiming Liu</a>
*/
public class SimpleServerConnection extends ServerConnection {
/**
* @param channel
*/
public SimpleServerConnection(SocketChannel channel) {
super(channel);
}
// commands --------------------------------------------------------------
/**
* Override parent method in FrontendConnection
*/
public void initDB(byte[] data) {
MySQLMessage mm = new MySQLMessage(data);
mm.position(5);
String db = mm.readString();
// 检查schema是否已经设置
// if (schema != null) {
// if (schema.equals(db)) {
// write(writeToBuffer(OkPacket.OK, allocate()));
// } else {
// writeErrMessage(ErrorCode.ER_DBACCESS_DENIED_ERROR, "Not allowed to change the database!");
// }
// return;
// }
// 检查schema的有效性
// if (db == null || !privileges.schemaExists(db)) {
// writeErrMessage(ErrorCode.ER_BAD_DB_ERROR, "Unknown database '" + db + "'");
// return;
// }
if (!privileges.userExists(user, host)) {
writeErrMessage(ErrorCode.ER_ACCESS_DENIED_ERROR, "Access denied for user '" + user + "'");
return;
}
Set<String> schemas = privileges.getUserSchemas(user);
if (schemas == null || schemas.size() == 0 || schemas.contains(db)) {
this.schema = db;
write(writeToBuffer(OkPacket.OK, allocate()));
} else {
String s = "Access denied for user '" + user + "' to database '" + db + "'";
writeErrMessage(ErrorCode.ER_DBACCESS_DENIED_ERROR, s);
}
}
}
......@@ -21,7 +21,7 @@ public class SimpleServerConnectionFactory extends FrontendConnectionFactory {
@Override
protected FrontendConnection getConnection(SocketChannel channel) {
ServerConnection c = new ServerConnection(channel);
ServerConnection c = new SimpleServerConnection(channel);
SimpleServerQueryHandler queryHandler = getQueryHandler(c);
c.setQueryHandler(queryHandler);
......@@ -41,7 +41,8 @@ public class SimpleServerConnectionFactory extends FrontendConnectionFactory {
return queryHandler;
} catch (ComponentLookupException e) {
throw new RuntimeException(
"Unable to get SimpleServerQueryHandler instance, please check if the environment is setup correctly!", e);
"Unable to get SimpleServerQueryHandler instance, please check if the environment is setup correctly!",
e);
}
}
......
/**
* Project: bee-engine
*
* File Created at 2012-8-23
*
* Copyright 2012 dianping.com.
* All rights reserved.
*
* This software is the confidential and proprietary information of
* Dianping Company. ("Confidential Information"). You shall not
* disclose such Confidential Information and shall use it only in
* accordance with the terms of the license agreement you entered into
* with dianping.com.
*/
package com.dianping.bee.server;
import com.alibaba.cobar.parser.util.ParseUtil;
/**
* @author <a href="mailto:yiming.liu@dianping.com">Yiming Liu</a>
*/
public class SimpleServerParse {
public static final int OTHER = -1;
public static final int BEGIN = 1;
public static final int COMMIT = 2;
public static final int DELETE = 3;
public static final int INSERT = 4;
public static final int REPLACE = 5;
public static final int ROLLBACK = 6;
public static final int SELECT = 7;
public static final int SET = 8;
public static final int SHOW = 9;
public static final int START = 10;
public static final int UPDATE = 11;
public static final int KILL = 12;
public static final int SAVEPOINT = 13;
public static final int USE = 14;
public static final int EXPLAIN = 15;
public static final int KILL_QUERY = 16;
public static final int DESC = 17;
public static int parse(String stmt) {
for (int i = 0; i < stmt.length(); ++i) {
switch (stmt.charAt(i)) {
case ' ':
case '\t':
case '\r':
case '\n':
continue;
case '/':
case '#':
i = ParseUtil.comment(stmt, i);
continue;
case 'B':
case 'b':
return beginCheck(stmt, i);
case 'C':
case 'c':
return commitCheck(stmt, i);
case 'D':
case 'd':
return descCheck(stmt, i);
// return deleteCheck(stmt, i);
case 'E':
case 'e':
return explainCheck(stmt, i);
case 'I':
case 'i':
return insertCheck(stmt, i);
case 'R':
case 'r':
return rCheck(stmt, i);
case 'S':
case 's':
return sCheck(stmt, i);
case 'U':
case 'u':
return uCheck(stmt, i);
case 'K':
case 'k':
return killCheck(stmt, i);
default:
return OTHER;
}
}
return OTHER;
}
// DESC' '
static int descCheck(String stmt, int offset) {
if (stmt.length() > offset + "ESC ".length()) {
char c1 = stmt.charAt(++offset);
char c2 = stmt.charAt(++offset);
char c3 = stmt.charAt(++offset);
char c4 = stmt.charAt(++offset);
if ((c1 == 'E' || c1 == 'e') && (c2 == 'S' || c2 == 's') && (c3 == 'C' || c3 == 'c')
&& (c4 == ' ' || c4 == '\t' || c4 == '\r' || c4 == '\n')) {
return (offset << 8) | DESC;
}
}
return OTHER;
}
// EXPLAIN' '
static int explainCheck(String stmt, int offset) {
if (stmt.length() > offset + "XPLAIN ".length()) {
char c1 = stmt.charAt(++offset);
char c2 = stmt.charAt(++offset);
char c3 = stmt.charAt(++offset);
char c4 = stmt.charAt(++offset);
char c5 = stmt.charAt(++offset);
char c6 = stmt.charAt(++offset);
char c7 = stmt.charAt(++offset);
if ((c1 == 'X' || c1 == 'x') && (c2 == 'P' || c2 == 'p') && (c3 == 'L' || c3 == 'l')
&& (c4 == 'A' || c4 == 'a') && (c5 == 'I' || c5 == 'i') && (c6 == 'N' || c6 == 'n')
&& (c7 == ' ' || c7 == '\t' || c7 == '\r' || c7 == '\n')) {
return (offset << 8) | EXPLAIN;
}
}
return OTHER;
}
// KILL' '
static int killCheck(String stmt, int offset) {
if (stmt.length() > offset + "ILL ".length()) {
char c1 = stmt.charAt(++offset);
char c2 = stmt.charAt(++offset);
char c3 = stmt.charAt(++offset);
char c4 = stmt.charAt(++offset);
if ((c1 == 'I' || c1 == 'i') && (c2 == 'L' || c2 == 'l') && (c3 == 'L' || c3 == 'l')
&& (c4 == ' ' || c4 == '\t' || c4 == '\r' || c4 == '\n')) {
while (stmt.length() > ++offset) {
switch (stmt.charAt(offset)) {
case ' ':
case '\t':
case '\r':
case '\n':
continue;
case 'Q':
case 'q':
return killQueryCheck(stmt, offset);
default:
return (offset << 8) | KILL;
}
}
return OTHER;
}
}
return OTHER;
}
// KILL QUERY' '
static int killQueryCheck(String stmt, int offset) {
if (stmt.length() > offset + "UERY ".length()) {
char c1 = stmt.charAt(++offset);
char c2 = stmt.charAt(++offset);
char c3 = stmt.charAt(++offset);
char c4 = stmt.charAt(++offset);
char c5 = stmt.charAt(++offset);
if ((c1 == 'U' || c1 == 'u') && (c2 == 'E' || c2 == 'e') && (c3 == 'R' || c3 == 'r')
&& (c4 == 'Y' || c4 == 'y') && (c5 == ' ' || c5 == '\t' || c5 == '\r' || c5 == '\n')) {
while (stmt.length() > ++offset) {
switch (stmt.charAt(offset)) {
case ' ':
case '\t':
case '\r':
case '\n':
continue;
default:
return (offset << 8) | KILL_QUERY;
}
}
return OTHER;
}
}
return OTHER;
}
// BEGIN
static int beginCheck(String stmt, int offset) {
if (stmt.length() > offset + 4) {
char c1 = stmt.charAt(++offset);
char c2 = stmt.charAt(++offset);
char c3 = stmt.charAt(++offset);
char c4 = stmt.charAt(++offset);
if ((c1 == 'E' || c1 == 'e') && (c2 == 'G' || c2 == 'g') && (c3 == 'I' || c3 == 'i')
&& (c4 == 'N' || c4 == 'n') && (stmt.length() == ++offset || ParseUtil.isEOF(stmt.charAt(offset)))) {
return BEGIN;
}
}
return OTHER;
}
// COMMIT
static int commitCheck(String stmt, int offset) {
if (stmt.length() > offset + 5) {
char c1 = stmt.charAt(++offset);
char c2 = stmt.charAt(++offset);
char c3 = stmt.charAt(++offset);
char c4 = stmt.charAt(++offset);
char c5 = stmt.charAt(++offset);
if ((c1 == 'O' || c1 == 'o') && (c2 == 'M' || c2 == 'm') && (c3 == 'M' || c3 == 'm')
&& (c4 == 'I' || c4 == 'i') && (c5 == 'T' || c5 == 't')
&& (stmt.length() == ++offset || ParseUtil.isEOF(stmt.charAt(offset)))) {
return COMMIT;
}
}
return OTHER;
}
// DELETE' '
static int deleteCheck(String stmt, int offset) {
if (stmt.length() > offset + 6) {
char c1 = stmt.charAt(++offset);
char c2 = stmt.charAt(++offset);
char c3 = stmt.charAt(++offset);
char c4 = stmt.charAt(++offset);
char c5 = stmt.charAt(++offset);
char c6 = stmt.charAt(++offset);
if ((c1 == 'E' || c1 == 'e') && (c2 == 'L' || c2 == 'l') && (c3 == 'E' || c3 == 'e')
&& (c4 == 'T' || c4 == 't') && (c5 == 'E' || c5 == 'e')
&& (c6 == ' ' || c6 == '\t' || c6 == '\r' || c6 == '\n')) {
return DELETE;
}
}
return OTHER;
}
// INSERT' '
static int insertCheck(String stmt, int offset) {
if (stmt.length() > offset + 6) {
char c1 = stmt.charAt(++offset);
char c2 = stmt.charAt(++offset);
char c3 = stmt.charAt(++offset);
char c4 = stmt.charAt(++offset);
char c5 = stmt.charAt(++offset);
char c6 = stmt.charAt(++offset);
if ((c1 == 'N' || c1 == 'n') && (c2 == 'S' || c2 == 's') && (c3 == 'E' || c3 == 'e')
&& (c4 == 'R' || c4 == 'r') && (c5 == 'T' || c5 == 't')
&& (c6 == ' ' || c6 == '\t' || c6 == '\r' || c6 == '\n')) {
return INSERT;
}
}
return OTHER;
}
static int rCheck(String stmt, int offset) {
if (stmt.length() > ++offset) {
switch (stmt.charAt(offset)) {
case 'E':
case 'e':
return replaceCheck(stmt, offset);
case 'O':
case 'o':
return rollabckCheck(stmt, offset);
default:
return OTHER;
}
}
return OTHER;
}
// REPLACE' '
static int replaceCheck(String stmt, int offset) {
if (stmt.length() > offset + 6) {
char c1 = stmt.charAt(++offset);
char c2 = stmt.charAt(++offset);
char c3 = stmt.charAt(++offset);
char c4 = stmt.charAt(++offset);
char c5 = stmt.charAt(++offset);
char c6 = stmt.charAt(++offset);
if ((c1 == 'P' || c1 == 'p') && (c2 == 'L' || c2 == 'l') && (c3 == 'A' || c3 == 'a')
&& (c4 == 'C' || c4 == 'c') && (c5 == 'E' || c5 == 'e')
&& (c6 == ' ' || c6 == '\t' || c6 == '\r' || c6 == '\n')) {
return REPLACE;
}
}
return OTHER;
}
// ROLLBACK
static int rollabckCheck(String stmt, int offset) {
if (stmt.length() > offset + 6) {
char c1 = stmt.charAt(++offset);
char c2 = stmt.charAt(++offset);
char c3 = stmt.charAt(++offset);
char c4 = stmt.charAt(++offset);
char c5 = stmt.charAt(++offset);
char c6 = stmt.charAt(++offset);
if ((c1 == 'L' || c1 == 'l') && (c2 == 'L' || c2 == 'l') && (c3 == 'B' || c3 == 'b')
&& (c4 == 'A' || c4 == 'a') && (c5 == 'C' || c5 == 'c') && (c6 == 'K' || c6 == 'k')
&& (stmt.length() == ++offset || ParseUtil.isEOF(stmt.charAt(offset)))) {
return ROLLBACK;
}
}
return OTHER;
}
static int sCheck(String stmt, int offset) {
if (stmt.length() > ++offset) {
switch (stmt.charAt(offset)) {
case 'A':
case 'a':
return savepointCheck(stmt, offset);
case 'E':
case 'e':
return seCheck(stmt, offset);
case 'H':
case 'h':
return showCheck(stmt, offset);
case 'T':
case 't':
return startCheck(stmt, offset);
default:
return OTHER;
}
}
return OTHER;
}
// SAVEPOINT
static int savepointCheck(String stmt, int offset) {
if (stmt.length() > offset + 8) {
char c1 = stmt.charAt(++offset);
char c2 = stmt.charAt(++offset);
char c3 = stmt.charAt(++offset);
char c4 = stmt.charAt(++offset);
char c5 = stmt.charAt(++offset);
char c6 = stmt.charAt(++offset);
char c7 = stmt.charAt(++offset);
char c8 = stmt.charAt(++offset);
if ((c1 == 'V' || c1 == 'v') && (c2 == 'E' || c2 == 'e') && (c3 == 'P' || c3 == 'p')
&& (c4 == 'O' || c4 == 'o') && (c5 == 'I' || c5 == 'i') && (c6 == 'N' || c6 == 'n')
&& (c7 == 'T' || c7 == 't') && (c8 == ' ' || c8 == '\t' || c8 == '\r' || c8 == '\n')) {
return SAVEPOINT;
}
}
return OTHER;
}
static int seCheck(String stmt, int offset) {
if (stmt.length() > ++offset) {
switch (stmt.charAt(offset)) {
case 'L':
case 'l':
return selectCheck(stmt, offset);
case 'T':
case 't':
if (stmt.length() > ++offset) {
char c = stmt.charAt(offset);
if (c == ' ' || c == '\r' || c == '\n' || c == '\t' || c == '/' || c == '#') {
return (offset << 8) | SET;
}
}
return OTHER;
default:
return OTHER;
}
}
return OTHER;
}
// SELECT' '
static int selectCheck(String stmt, int offset) {
if (stmt.length() > offset + 4) {
char c1 = stmt.charAt(++offset);
char c2 = stmt.charAt(++offset);
char c3 = stmt.charAt(++offset);
char c4 = stmt.charAt(++offset);
if ((c1 == 'E' || c1 == 'e') && (c2 == 'C' || c2 == 'c') && (c3 == 'T' || c3 == 't')
&& (c4 == ' ' || c4 == '\t' || c4 == '\r' || c4 == '\n' || c4 == '/' || c4 == '#')) {
return (offset << 8) | SELECT;
}
}
return OTHER;
}
// SHOW' '
static int showCheck(String stmt, int offset) {
if (stmt.length() > offset + 3) {
char c1 = stmt.charAt(++offset);
char c2 = stmt.charAt(++offset);
char c3 = stmt.charAt(++offset);
if ((c1 == 'O' || c1 == 'o') && (c2 == 'W' || c2 == 'w')
&& (c3 == ' ' || c3 == '\t' || c3 == '\r' || c3 == '\n')) {
return (offset << 8) | SHOW;
}
}
return OTHER;
}
// START' '
static int startCheck(String stmt, int offset) {
if (stmt.length() > offset + 4) {
char c1 = stmt.charAt(++offset);
char c2 = stmt.charAt(++offset);
char c3 = stmt.charAt(++offset);
char c4 = stmt.charAt(++offset);
if ((c1 == 'A' || c1 == 'a') && (c2 == 'R' || c2 == 'r') && (c3 == 'T' || c3 == 't')
&& (c4 == ' ' || c4 == '\t' || c4 == '\r' || c4 == '\n')) {
return (offset << 8) | START;
}
}
return OTHER;
}
// UPDATE' ' | USE' '
static int uCheck(String stmt, int offset) {
if (stmt.length() > ++offset) {
switch (stmt.charAt(offset)) {
case 'P':
case 'p':
if (stmt.length() > offset + 5) {
char c1 = stmt.charAt(++offset);
char c2 = stmt.charAt(++offset);
char c3 = stmt.charAt(++offset);
char c4 = stmt.charAt(++offset);
char c5 = stmt.charAt(++offset);
if ((c1 == 'D' || c1 == 'd') && (c2 == 'A' || c2 == 'a') && (c3 == 'T' || c3 == 't')
&& (c4 == 'E' || c4 == 'e') && (c5 == ' ' || c5 == '\t' || c5 == '\r' || c5 == '\n')) {
return UPDATE;
}
}
break;
case 'S':
case 's':
if (stmt.length() > offset + 2) {
char c1 = stmt.charAt(++offset);
char c2 = stmt.charAt(++offset);
if ((c1 == 'E' || c1 == 'e') && (c2 == ' ' || c2 == '\t' || c2 == '\r' || c2 == '\n')) {
return (offset << 8) | USE;
}
}
break;
default:
return OTHER;
}
}
return OTHER;
}
}
/**
* Project: bee-engine
*
* File Created at 2012-8-23
*
* Copyright 2012 dianping.com.
* All rights reserved.
*
* This software is the confidential and proprietary information of
* Dianping Company. ("Confidential Information"). You shall not
* disclose such Confidential Information and shall use it only in
* accordance with the terms of the license agreement you entered into
* with dianping.com.
*/
package com.dianping.bee.server;
import com.alibaba.cobar.parser.util.ParseUtil;
/**
* @author <a href="mailto:yiming.liu@dianping.com">Yiming Liu</a>
*/
public class SimpleServerParseShow {
public static final int OTHER = -1;
public static final int DATABASES = 1;
public static final int TABLES = 2;
public static int parse(String stmt, int offset) {
int i = offset;
for (; i < stmt.length(); i++) {
switch (stmt.charAt(i)) {
case ' ':
continue;
case '/':
case '#':
i = ParseUtil.comment(stmt, i);
continue;
case 'T':
case 't':
return showTablesCheck(stmt, i);
case 'D':
case 'd':
return showDatabasesCheck(stmt, i);
default:
return OTHER;
}
}
return OTHER;
}
// SHOW DATABASES
static int showDatabasesCheck(String stmt, int offset) {
if (stmt.length() > offset + "atabases".length()) {
char c1 = stmt.charAt(++offset);
char c2 = stmt.charAt(++offset);
char c3 = stmt.charAt(++offset);
char c4 = stmt.charAt(++offset);
char c5 = stmt.charAt(++offset);
char c6 = stmt.charAt(++offset);
char c7 = stmt.charAt(++offset);
char c8 = stmt.charAt(++offset);
if ((c1 == 'A' || c1 == 'a') && (c2 == 'T' || c2 == 't') && (c3 == 'A' || c3 == 'a')
&& (c4 == 'B' || c4 == 'b') && (c5 == 'A' || c5 == 'a') && (c6 == 'S' || c6 == 's')
&& (c7 == 'E' || c7 == 'e') && (c8 == 'S' || c8 == 's')
&& (stmt.length() == ++offset || ParseUtil.isEOF(stmt.charAt(offset)))) {
return DATABASES;
}
}
return OTHER;
}
// SHOW TABLES
static int showTablesCheck(String stmt, int offset) {
if (stmt.length() > offset + "ables".length()) {
char c1 = stmt.charAt(++offset);
char c2 = stmt.charAt(++offset);
char c3 = stmt.charAt(++offset);
char c4 = stmt.charAt(++offset);
char c5 = stmt.charAt(++offset);
if ((c1 == 'A' || c1 == 'a') && (c2 == 'B' || c2 == 'b') && (c3 == 'L' || c3 == 'l')
&& (c4 == 'E' || c4 == 'e') && (c5 == 'S' || c5 == 's')
&& (stmt.length() == ++offset || ParseUtil.isEOF(stmt.charAt(offset)))) {
return TABLES;
}
}
return OTHER;
}
}
......@@ -24,10 +24,8 @@ import com.alibaba.cobar.server.handler.ExplainHandler;
import com.alibaba.cobar.server.handler.KillHandler;
import com.alibaba.cobar.server.handler.SavepointHandler;
import com.alibaba.cobar.server.handler.SetHandler;
import com.alibaba.cobar.server.handler.ShowHandler;
import com.alibaba.cobar.server.handler.StartHandler;
import com.alibaba.cobar.server.handler.UseHandler;
import com.alibaba.cobar.server.parser.ServerParse;
import com.site.lookup.annotation.Inject;
/**
......@@ -35,7 +33,13 @@ import com.site.lookup.annotation.Inject;
*/
public class SimpleServerQueryHandler implements FrontendQueryHandler {
@Inject
private SelectHandler m_selectHandler;
private SimpleSelectHandler m_selectHandler;
@Inject
private SimpleShowHandler m_showHandler;
@Inject
private SimpleDescHandler m_descHandler;
private static final Logger LOGGER = Logger.getLogger(SimpleServerQueryHandler.class);
......@@ -49,42 +53,52 @@ public class SimpleServerQueryHandler implements FrontendQueryHandler {
LOGGER.debug(new StringBuilder().append(c).append(sql).toString());
}
int rs = ServerParse.parse(sql);
int rs = SimpleServerParse.parse(sql);
switch (rs & 0xff) {
case ServerParse.EXPLAIN:
case SimpleServerParse.EXPLAIN:
ExplainHandler.handle(sql, c, rs >>> 8);
break;
case ServerParse.SET:
case SimpleServerParse.SET:
SetHandler.handle(sql, c, rs >>> 8);
break;
case ServerParse.SHOW:
ShowHandler.handle(sql, c, rs >>> 8);
case SimpleServerParse.DESC:
//FIXME: why not inject
if(m_descHandler==null){
m_descHandler = new SimpleDescHandler();
}
m_descHandler.handle(sql, c, rs >>> 8);
case SimpleServerParse.SHOW:
// FIXME: why not inject
if (m_showHandler == null) {
m_showHandler = new SimpleShowHandler();
}
m_showHandler.handle(sql, c, rs >>> 8);
break;
case ServerParse.SELECT:
case SimpleServerParse.SELECT:
m_selectHandler.handle(sql, c, rs >>> 8);
break;
case ServerParse.START:
case SimpleServerParse.START:
StartHandler.handle(sql, c, rs >>> 8);
break;
case ServerParse.BEGIN:
case SimpleServerParse.BEGIN:
BeginHandler.handle(sql, c);
break;
case ServerParse.SAVEPOINT:
case SimpleServerParse.SAVEPOINT:
SavepointHandler.handle(sql, c);
break;
case ServerParse.KILL:
case SimpleServerParse.KILL:
KillHandler.handle(sql, rs >>> 8, c);
break;
case ServerParse.KILL_QUERY:
case SimpleServerParse.KILL_QUERY:
c.writeErrMessage(ErrorCode.ER_UNKNOWN_COM_ERROR, "Unsupported command");
break;
case ServerParse.USE:
case SimpleServerParse.USE:
UseHandler.handle(sql, c, rs >>> 8);
break;
case ServerParse.COMMIT:
case SimpleServerParse.COMMIT:
c.commit();
break;
case ServerParse.ROLLBACK:
case SimpleServerParse.ROLLBACK:
c.rollback();
break;
default:
......
/**
* Project: bee-engine
*
* File Created at 2012-8-23
*
* Copyright 2012 dianping.com.
* All rights reserved.
*
* This software is the confidential and proprietary information of
* Dianping Company. ("Confidential Information"). You shall not
* disclose such Confidential Information and shall use it only in
* accordance with the terms of the license agreement you entered into
* with dianping.com.
*/
package com.dianping.bee.server;
import java.nio.ByteBuffer;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import com.alibaba.cobar.CobarServer;
import com.alibaba.cobar.ErrorCode;
import com.alibaba.cobar.Fields;
import com.alibaba.cobar.config.model.SchemaConfig;
import com.alibaba.cobar.net.util.PacketUtil;
import com.alibaba.cobar.protocol.mysql.EOFPacket;
import com.alibaba.cobar.protocol.mysql.FieldPacket;
import com.alibaba.cobar.protocol.mysql.ResultSetHeaderPacket;
import com.alibaba.cobar.protocol.mysql.RowDataPacket;
import com.alibaba.cobar.server.ServerConnection;
import com.alibaba.cobar.server.parser.ServerParse;
import com.alibaba.cobar.server.response.ShowDatabases;
import com.alibaba.cobar.util.StringUtil;
import com.dianping.bee.engine.spi.DatabaseProvider;
import com.dianping.bee.engine.spi.TableProvider;
import com.site.lookup.ContainerLoader;
/**
* @author <a href="mailto:yiming.liu@dianping.com">Yiming Liu</a>
*/
public class SimpleShowHandler {
/**
* @param stmt
* @param c
* @param offset
*/
public void handle(String stmt, ServerConnection c, int offset) {
switch (SimpleServerParseShow.parse(stmt, offset)) {
case SimpleServerParseShow.DATABASES:
ShowDatabases.response(c);
break;
case SimpleServerParseShow.TABLES:
showTable(c, stmt, ServerParse.SHOW);
break;
default:
c.writeErrMessage(ErrorCode.ER_UNKNOWN_COM_ERROR, "Unsupported show command");
}
}
private void showTable(ServerConnection c, String sql, int type) {
// 检查当前使用的DB
String db = c.getSchema();
if (db == null) {
c.writeErrMessage(ErrorCode.ER_NO_DB_ERROR, "No database selected");
return;
}
SchemaConfig schema = CobarServer.getInstance().getConfig().getSchemas().get(db);
if (schema == null) {
c.writeErrMessage(ErrorCode.ER_BAD_DB_ERROR, "Unknown database '" + db + "'");
return;
}
DatabaseProvider provider = null;
try {
provider = ContainerLoader.getDefaultContainer().lookup(DatabaseProvider.class, db);
} catch (ComponentLookupException e) {
c.writeErrMessage(ErrorCode.ER_BAD_DB_ERROR, "Can not load database '" + db + "'");
return;
}
if (provider == null) {
c.writeErrMessage(ErrorCode.ER_BAD_DB_ERROR, "Can not load database '" + db + "'");
return;
}
TableProvider[] tables = provider.getTables();
int FIELD_COUNT = 1;
ResultSetHeaderPacket header = PacketUtil.getHeader(FIELD_COUNT);
FieldPacket[] fields = new FieldPacket[FIELD_COUNT];
EOFPacket eof = new EOFPacket();
int i = 0;
byte packetId = 0;
header.packetId = ++packetId;
fields[i] = PacketUtil.getField("TABLE", Fields.FIELD_TYPE_VAR_STRING);
fields[i++].packetId = ++packetId;
eof.packetId = ++packetId;
ByteBuffer buffer = c.allocate();
// write header
buffer = header.write(buffer, c);
// write fields
for (FieldPacket field : fields) {
buffer = field.write(buffer, c);
}
// write eof
buffer = eof.write(buffer, c);
// write rows
packetId = eof.packetId;
for (TableProvider table : tables) {
RowDataPacket row = new RowDataPacket(FIELD_COUNT);
row.add(StringUtil.encode(table.getName(), c.getCharset()));
row.packetId = ++packetId;
buffer = row.write(buffer, c);
}
// write last eof
EOFPacket lastEof = new EOFPacket();
lastEof.packetId = ++packetId;
buffer = lastEof.write(buffer, c);
// post write
c.write(buffer);
}
}
......@@ -6,8 +6,14 @@
</component>
<component>
<role>com.dianping.bee.engine.spi.DatabaseProvider</role>
<role-hint>cat</role-hint>
<implementation>com.dianping.bee.db.CatDatabase</implementation>
</component>
<component>
<role>com.dianping.bee.engine.spi.DatabaseProvider</role>
<role-hint>dog</role-hint>
<implementation>com.dianping.bee.db.DogDatabase</implementation>
</component>
<component>
<role>com.dianping.bee.engine.spi.TableProviderManager</role>
<implementation>com.dianping.bee.engine.spi.internal.DefaultTableProviderManager</implementation>
......@@ -78,8 +84,12 @@
</requirements>
</component>
<component>
<role>com.dianping.bee.server.SelectHandler</role>
<implementation>com.dianping.bee.server.SelectHandler</implementation>
<role>com.dianping.bee.server.SimpleShowHandler</role>
<implementation>com.dianping.bee.server.SimpleShowHandler</implementation>
</component>
<component>
<role>com.dianping.bee.server.SimpleSelectHandler</role>
<implementation>com.dianping.bee.server.SimpleSelectHandler</implementation>
<requirements>
<requirement>
<role>com.dianping.bee.engine.spi.StatementManager</role>
......@@ -92,7 +102,10 @@
<instantiation-strategy>per-lookup</instantiation-strategy>
<requirements>
<requirement>
<role>com.dianping.bee.server.SelectHandler</role>
<role>com.dianping.bee.server.SimpleSelectHandler</role>
</requirement>
<requirement>
<role>com.dianping.bee.server.SimpleShowHandler</role>
</requirement>
</requirements>
</component>
......
......@@ -14,16 +14,6 @@ import com.dianping.bee.engine.spi.meta.internal.DefaultRow;
import com.dianping.bee.engine.spi.meta.internal.DefaultRowSet;
public class CatDatabase implements DatabaseProvider {
@Override
public String getName() {
return "cat";
}
@Override
public CatTable[] getTables() {
return CatTable.values();
}
public static enum CatTable implements TableProvider {
Transaction("transaction") {
@Override
......@@ -101,7 +91,7 @@ public class CatDatabase implements DatabaseProvider {
}
}
public static enum TransactionColumn implements ColumnMeta {
public static enum EventColumn implements ColumnMeta {
StartTime(String.class), // 20120822(for daily), 2012082213(for hour)
Domain(String.class), // MobileApi
......@@ -126,25 +116,25 @@ public class CatDatabase implements DatabaseProvider {
Line95(Integer.class); // 123
public static EventColumn findByName(String name) {
for (EventColumn column : values()) {
if (column.getName().equalsIgnoreCase(name)) {
return column;
}
}
throw new RuntimeException(String.format("Column(%s) is not found in %s", name, EventColumn.class.getName()));
}
private String m_name;
private Class<?> m_type;
private TransactionColumn(Class<?> type) {
private EventColumn(Class<?> type) {
m_type = type;
m_name = name().toLowerCase();
}
public static TransactionColumn findByName(String name) {
for (TransactionColumn column : values()) {
if (column.getName().equalsIgnoreCase(name)) {
return column;
}
}
throw new RuntimeException(String.format("Column(%s) is not found in %s", name, TransactionColumn.class.getName()));
}
@Override
public String getName() {
return m_name;
......@@ -156,18 +146,19 @@ public class CatDatabase implements DatabaseProvider {
}
}
public static enum TransactionIndex implements Index {
IDX_STARTTIME_DOMAIN(TransactionColumn.StartTime, false, TransactionColumn.Domain, true);
public static enum EventIndex implements Index {
IDX_STARTTIME_DOMAIN(EventColumn.StartTime, false, EventColumn.Domain, true);
private ColumnMeta[] m_columns;
private boolean[] m_orders;
private TransactionIndex(Object... args) {
private EventIndex(Object... args) {
int length = args.length;
if (length % 2 != 0) {
throw new IllegalArgumentException(String.format("Parameters should be paired for %s(%s)!", getClass(), name()));
throw new IllegalArgumentException(String.format("Parameters should be paired for %s(%s)!", getClass(),
name()));
}
m_columns = new ColumnMeta[length / 2];
......@@ -203,7 +194,7 @@ public class CatDatabase implements DatabaseProvider {
}
}
public static enum EventColumn implements ColumnMeta {
public static enum TransactionColumn implements ColumnMeta {
StartTime(String.class), // 20120822(for daily), 2012082213(for hour)
Domain(String.class), // MobileApi
......@@ -228,25 +219,26 @@ public class CatDatabase implements DatabaseProvider {
Line95(Integer.class); // 123
public static TransactionColumn findByName(String name) {
for (TransactionColumn column : values()) {
if (column.getName().equalsIgnoreCase(name)) {
return column;
}
}
throw new RuntimeException(String.format("Column(%s) is not found in %s", name,
TransactionColumn.class.getName()));
}
private String m_name;
private Class<?> m_type;
private EventColumn(Class<?> type) {
private TransactionColumn(Class<?> type) {
m_type = type;
m_name = name().toLowerCase();
}
public static EventColumn findByName(String name) {
for (EventColumn column : values()) {
if (column.getName().equalsIgnoreCase(name)) {
return column;
}
}
throw new RuntimeException(String.format("Column(%s) is not found in %s", name, EventColumn.class.getName()));
}
@Override
public String getName() {
return m_name;
......@@ -258,18 +250,19 @@ public class CatDatabase implements DatabaseProvider {
}
}
public static enum EventIndex implements Index {
IDX_STARTTIME_DOMAIN(EventColumn.StartTime, false, EventColumn.Domain, true);
public static enum TransactionIndex implements Index {
IDX_STARTTIME_DOMAIN(TransactionColumn.StartTime, false, TransactionColumn.Domain, true);
private ColumnMeta[] m_columns;
private boolean[] m_orders;
private EventIndex(Object... args) {
private TransactionIndex(Object... args) {
int length = args.length;
if (length % 2 != 0) {
throw new IllegalArgumentException(String.format("Parameters should be paired for %s(%s)!", getClass(), name()));
throw new IllegalArgumentException(String.format("Parameters should be paired for %s(%s)!", getClass(),
name()));
}
m_columns = new ColumnMeta[length / 2];
......@@ -304,4 +297,26 @@ public class CatDatabase implements DatabaseProvider {
}
}
}
@Override
public String getName() {
return "cat";
}
@Override
public TableProvider getTable(String tableName) {
for (TableProvider table : CatTable.values()) {
if (table.getName().equalsIgnoreCase(tableName)) {
return table;
}
}
throw new RuntimeException(
String.format("Table(%s) is not found in %s", tableName, TableProvider.class.getName()));
}
@Override
public CatTable[] getTables() {
return CatTable.values();
}
}
......@@ -14,16 +14,6 @@ import com.dianping.bee.engine.spi.meta.internal.DefaultRow;
import com.dianping.bee.engine.spi.meta.internal.DefaultRowSet;
public class DogDatabase implements DatabaseProvider {
@Override
public String getName() {
return "dog";
}
@Override
public DogTable[] getTables() {
return DogTable.values();
}
public static enum DogTable implements TableProvider {
Transaction("transaction") {
@Override
......@@ -118,15 +108,6 @@ public class DogDatabase implements DatabaseProvider {
Line95(Integer.class); // 123
private String m_name;
private Class<?> m_type;
private TransactionColumn(Class<?> type) {
m_type = type;
m_name = name().toLowerCase();
}
public static TransactionColumn findByName(String name) {
for (TransactionColumn column : values()) {
if (column.getName().equalsIgnoreCase(name)) {
......@@ -138,6 +119,15 @@ public class DogDatabase implements DatabaseProvider {
TransactionColumn.class.getName()));
}
private String m_name;
private Class<?> m_type;
private TransactionColumn(Class<?> type) {
m_type = type;
m_name = name().toLowerCase();
}
@Override
public String getName() {
return m_name;
......@@ -196,4 +186,26 @@ public class DogDatabase implements DatabaseProvider {
}
}
}
@Override
public String getName() {
return "dog";
}
@Override
public TableProvider getTable(String tableName) {
for (TableProvider table : DogTable.values()) {
if (table.getName().equalsIgnoreCase(tableName)) {
return table;
}
}
throw new RuntimeException(
String.format("Table(%s) is not found in %s", tableName, TableProvider.class.getName()));
}
@Override
public DogTable[] getTables() {
return DogTable.values();
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册