提交 cf3afe45 编写于 作者: Y Yiming Liu

bug fix, support show table status, support schema_inforamtion.

上级 8a4b56d4
......@@ -37,6 +37,11 @@
<version>3.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
......@@ -19,11 +19,13 @@ 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.InformationSchemaDatabase;
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.dianping.bee.server.SimpleUseHandler;
import com.site.lookup.configuration.AbstractResourceConfigurator;
import com.site.lookup.configuration.Component;
......@@ -34,6 +36,7 @@ public class ComponentsConfigurator extends AbstractResourceConfigurator {
all.add(C(SimpleServer.class));
all.add(C(DatabaseProvider.class, "information_schema", InformationSchemaDatabase.class));
all.add(C(DatabaseProvider.class, "cat", CatDatabase.class));
all.add(C(DatabaseProvider.class, "dog", DogDatabase.class));
......@@ -52,13 +55,15 @@ public class ComponentsConfigurator extends AbstractResourceConfigurator {
all.add(C(MultiTableStatementVisitor.class).is(PER_LOOKUP) //
.req(TableHelper.class, MultiTableStatement.class, RowFilter.class));
all.add(C(SimpleShowHandler.class));
all.add(C(SimpleShowHandler.class)//
.req(TableProviderManager.class));
all.add(C(SimpleUseHandler.class));
all.add(C(SimpleDescHandler.class)//
.req(TableProviderManager.class));
all.add(C(SimpleSelectHandler.class) //
.req(StatementManager.class));
all.add(C(SimpleServerQueryHandler.class).is(PER_LOOKUP) //
.req(SimpleSelectHandler.class, SimpleShowHandler.class, SimpleDescHandler.class));
.req(SimpleSelectHandler.class, SimpleShowHandler.class, SimpleDescHandler.class, SimpleUseHandler.class));
return all;
}
......
......@@ -5,5 +5,4 @@ public interface DatabaseProvider {
public TableProvider[] getTables();
public TableProvider getTable(String tableName);
}
\ No newline at end of file
......@@ -65,7 +65,9 @@ public class DefaultSingleTableStatement implements SingleTableStatement {
// Query By Index
RowSet providerRowSet = m_table.queryByIndex(m_index, m_selectColumns);
// Filter
providerRowSet.filter(m_rowFilter);
if (providerRowSet != null) {
providerRowSet.filter(m_rowFilter);
}
// Build select columns
RowSet returnRowSet = buildReturnRowSet(providerRowSet);
return returnRowSet;
......
......@@ -12,10 +12,25 @@ import com.alibaba.cobar.parser.util.Pair;
import com.alibaba.cobar.parser.visitor.EmptySQLASTVisitor;
import com.dianping.bee.engine.spi.RowFilter;
import com.dianping.bee.engine.spi.SingleTableStatement;
import com.dianping.bee.engine.spi.TableProvider;
import com.dianping.bee.engine.spi.meta.ColumnMeta;
import com.site.lookup.annotation.Inject;
public class SingleTableStatementVisitor extends EmptySQLASTVisitor {
static enum Clause {
SELECT,
TABLE,
WHERE,
GROUP,
HAVING,
ORDER;
}
@Inject
private TableHelper m_helper;
......@@ -35,6 +50,22 @@ public class SingleTableStatementVisitor extends EmptySQLASTVisitor {
private List<ColumnMeta> m_whereColumns = new ArrayList<ColumnMeta>();
private boolean checkSelectAll(List<ColumnMeta> columns, String columnName) {
if ("*".equals(columnName)) {
TableProvider table = m_helper.findTable(m_tableName);
if (table != null) {
ColumnMeta[] columnMetas = table.getColumns();
if (columnMetas != null) {
for (ColumnMeta meta : columnMetas) {
columns.add(meta);
}
}
}
return true;
}
return false;
}
private ColumnMeta findOrCreateColumnFrom(List<ColumnMeta> columns, String columnName) {
for (ColumnMeta column : columns) {
if (column.getName().equals(columnName)) {
......@@ -107,7 +138,9 @@ public class SingleTableStatementVisitor extends EmptySQLASTVisitor {
case SELECT:
String selectColumnName = node.getIdTextUpUnescape();
findOrCreateColumnFrom(m_selectColumns, selectColumnName);
if (!checkSelectAll(m_selectColumns, selectColumnName)) {
findOrCreateColumnFrom(m_selectColumns, selectColumnName);
}
break;
case WHERE:
String whereColumnName = node.getIdTextUpUnescape();
......@@ -132,18 +165,4 @@ public class SingleTableStatementVisitor extends EmptySQLASTVisitor {
m_alias = node.getAlias();
m_tableName = node.getTable().getIdTextUpUnescape();
}
static enum Clause {
SELECT,
TABLE,
WHERE,
GROUP,
HAVING,
ORDER;
}
}
/**
* Project: bee-engine
*
* File Created at 2012-8-24
*
* 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.internal;
import java.util.List;
import com.dianping.bee.engine.spi.TableProvider;
import com.dianping.bee.engine.spi.meta.ColumnMeta;
import com.dianping.bee.engine.spi.meta.Index;
/**
* @author <a href="mailto:yiming.liu@dianping.com">Yiming Liu</a>
*/
public class StaticTableHelper {
public static ColumnMeta findColumn(TableProvider table, String columnName) {
ColumnMeta[] columns = table.getColumns();
if (columns != null) {
for (ColumnMeta column : columns) {
if (column.getName().equalsIgnoreCase(columnName)) {
return column;
}
}
}
throw new BadSQLSyntaxException("Column(%s) of table(%s) is not found!", columnName, table.getName());
}
public Index findIndex(TableProvider table, List<ColumnMeta> columns) {
Index[] indexes = table.getIndexes();
if (indexes != null && indexes.length > 0) {
for (Index index : indexes) {
// if first column of index is in columns, then pick it up
ColumnMeta first = index.getColumn(0);
String columnName = first.getName();
for (ColumnMeta column : columns) {
if (column.getName().equalsIgnoreCase(columnName)) {
return index;
}
}
}
}
return null;
}
}
......@@ -16,12 +16,13 @@ public class TableHelper {
TableProvider table = findTable(tableName);
ColumnMeta[] columns = table.getColumns();
for (ColumnMeta column : columns) {
if (column.getName().equalsIgnoreCase(columnName)) {
return column;
if (columns != null) {
for (ColumnMeta column : columns) {
if (column.getName().equalsIgnoreCase(columnName)) {
return column;
}
}
}
throw new BadSQLSyntaxException("Column(%s) of table(%s) is not found!", columnName, tableName);
}
......
/**
* Project: bee-engine
*
* File Created at 2012-8-24
*
* 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.dianping.bee.engine.spi.DatabaseProvider;
import com.dianping.bee.engine.spi.TableProvider;
import com.dianping.bee.engine.spi.internal.StaticTableHelper;
import com.dianping.bee.engine.spi.meta.Cell;
import com.dianping.bee.engine.spi.meta.ColumnMeta;
import com.dianping.bee.engine.spi.meta.Index;
import com.dianping.bee.engine.spi.meta.Row;
import com.dianping.bee.engine.spi.meta.RowSet;
import com.dianping.bee.engine.spi.meta.internal.DefaultCell;
import com.dianping.bee.engine.spi.meta.internal.DefaultRow;
import com.dianping.bee.engine.spi.meta.internal.DefaultRowSet;
/**
* @author <a href="mailto:yiming.liu@dianping.com">Yiming Liu</a>
*/
public class InformationSchemaDatabase implements DatabaseProvider {
public static enum InformationSchemaTable implements TableProvider {
CHARACTER_SETS("CHARACTER_SETS"),
COLLATIONS("COLLATIONS"),
COLUMNS("COLUMNS"),
ENGINES("ENGINES"),
TABLES("TABLES"),
SCHEMATA("SCHEMATA") {
@Override
public SchemataColumn[] getColumns() {
return SchemataColumn.values();
}
};
private String m_name;
private InformationSchemaTable(String name) {
m_name = name;
}
@Override
public ColumnMeta[] getColumns() {
return SchemataColumn.values();
}
@Override
public Index[] getIndexes() {
return null;
}
@Override
public String getName() {
return m_name;
}
@Override
public RowSet queryByIndex(Index index, ColumnMeta[] selectColumns) {
ColumnMeta[] columns = selectColumns;
DefaultRowSet rowSet = new DefaultRowSet(columns);
Cell[] cells = new Cell[columns.length];
for (int colIndex = 0; colIndex < cells.length; colIndex++) {
ColumnMeta columnMeta = StaticTableHelper.findColumn(this, columns[colIndex].getName());
cells[colIndex] = new DefaultCell(columnMeta, null);
}
Row row = new DefaultRow(cells);
rowSet.addRow(row);
return rowSet;
}
}
public static enum SchemataColumn implements ColumnMeta {
CATALOG_NAME(String.class),
SCHEMA_NAME(String.class),
DEFAULT_CHARACTER_SET_NAME(String.class),
DEFAULT_COLLATION_NAME(String.class),
SQL_PATH(String.class);
private String m_name;
private Class<?> m_type;
private SchemataColumn(Class<?> type) {
m_type = type;
m_name = name().toLowerCase();
}
@Override
public String getName() {
return m_name;
}
@Override
public Class<?> getType() {
return m_type;
}
}
@Override
public String getName() {
return "information_schema";
}
@Override
public TableProvider[] getTables() {
return InformationSchemaTable.values();
}
}
......@@ -61,7 +61,6 @@ public class SimpleDescHandler {
}
TableProvider table = m_manager.getTableProvider(tableName);
if (table == null) {
c.writeErrMessage(ErrorCode.ER_BAD_TABLE_ERROR, "Unknown table '" + tableName + "'");
return;
......@@ -106,14 +105,26 @@ public class SimpleDescHandler {
// write rows
packetId = eof.packetId;
for (ColumnMeta column : columns) {
if (columns != null) {
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(null);
row.add(null);
row.add(null);
row.add(null);
row.packetId = ++packetId;
buffer = row.write(buffer, c);
}
} else {
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.add(null);
row.add(null);
row.add(null);
row.add(null);
row.add(null);
row.add(null);
row.packetId = ++packetId;
buffer = row.write(buffer, c);
}
......
......@@ -5,6 +5,9 @@ import java.io.IOException;
import org.codehaus.plexus.logging.LogEnabled;
import org.codehaus.plexus.logging.Logger;
import com.alibaba.cobar.CobarServer;
import com.alibaba.cobar.config.model.SystemConfig;
import com.alibaba.cobar.net.FrontendConnection;
import com.alibaba.cobar.net.NIOAcceptor;
import com.alibaba.cobar.net.NIOConnector;
import com.alibaba.cobar.net.NIOProcessor;
......@@ -19,6 +22,8 @@ public class SimpleServer implements LogEnabled {
private Logger m_logger;
public static final String VERSION = "bee-0.0.1-cobar-1.3.0";
@Override
public void enableLogging(Logger logger) {
m_logger = logger;
......@@ -29,11 +34,13 @@ public class SimpleServer implements LogEnabled {
}
public void startup() throws IOException {
SystemConfig system = CobarServer.getInstance().getConfig().getSystem();
FrontendConnection.setServerVersion(VERSION);
// start processors
NIOProcessor[] processors = new NIOProcessor[4];
NIOProcessor[] processors = new NIOProcessor[system.getProcessors()];
for (int i = 0; i < processors.length; i++) {
processors[i] = new NIOProcessor("Processor" + i, 4, 4);
processors[i] = new NIOProcessor("Processor" + i, system.getProcessorHandler(), system.getProcessorExecutor());
processors[i].startup();
}
......@@ -46,7 +53,7 @@ public class SimpleServer implements LogEnabled {
// startup server
SimpleServerConnectionFactory sf = new SimpleServerConnectionFactory();
sf.setIdleTimeout(3600 * 1000L); // one hour
sf.setIdleTimeout(system.getIdleTimeout()); // one hour
sf.setContainer(ContainerLoader.getDefaultContainer());
NIOAcceptor server = new NIOAcceptor("BeeServer", m_port, sf);
......
......@@ -29,7 +29,6 @@ public class SimpleServerConnectionFactory extends FrontendConnectionFactory {
c.setTxIsolation(Isolations.REPEATED_READ);
c.setSession(new BlockingSession(c));
c.setSession2(new NonBlockingSession(c));
return c;
}
......
......@@ -26,6 +26,12 @@ public class SimpleServerParseShow {
public static final int TABLES = 2;
public static final int STATUS = 3;
public static final int VARIABLES = 4;
public static final int TABLESTATUS = 5;
public static int parse(String stmt, int offset) {
int i = offset;
for (; i < stmt.length(); i++) {
......@@ -38,10 +44,16 @@ public class SimpleServerParseShow {
continue;
case 'T':
case 't':
return showTablesCheck(stmt, i);
return showTableCheck(stmt, i);
case 'D':
case 'd':
return showDatabasesCheck(stmt, i);
case 'S':
case 's':
return showStatusCheck(stmt, i);
case 'V':
case 'v':
return showVariablesCheck(stmt, i);
default:
return OTHER;
}
......@@ -49,6 +61,44 @@ public class SimpleServerParseShow {
return OTHER;
}
// SHOW VARIABLES
private static int showVariablesCheck(String stmt, int offset) {
if (stmt.length() > offset + "ariables".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 == 'R' || c2 == 'r') && (c3 == 'I' || c3 == 'i')
&& (c4 == 'A' || c4 == 'a') && (c5 == 'B' || c5 == 'b') && (c6 == 'L' || c6 == 'l')
&& (c7 == 'E' || c7 == 'e') && (c8 == 'S' || c8 == 's')
&& (stmt.length() == ++offset || ParseUtil.isEOF(stmt.charAt(offset)))) {
return VARIABLES;
}
}
return OTHER;
}
// SHOW STATUS
static int showStatusCheck(String stmt, int offset) {
if (stmt.length() > offset + "tatus".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 == 'T' || c1 == 't') && (c2 == 'A' || c2 == 'a') && (c3 == 'T' || c3 == 't')
&& (c4 == 'U' || c4 == 'u') && (c5 == 'S' || c5 == 's')
&& (stmt.length() == ++offset || ParseUtil.isEOF(stmt.charAt(offset)))) {
return STATUS;
}
}
return OTHER;
}
// SHOW DATABASES
static int showDatabasesCheck(String stmt, int offset) {
if (stmt.length() > offset + "atabases".length()) {
......@@ -70,8 +120,8 @@ public class SimpleServerParseShow {
return OTHER;
}
// SHOW TABLES
static int showTablesCheck(String stmt, int offset) {
// SHOW TABLES OR SHOW TABLE STATUS FROM [TABLE]
static int showTableCheck(String stmt, int offset) {
if (stmt.length() > offset + "ables".length()) {
char c1 = stmt.charAt(++offset);
char c2 = stmt.charAt(++offset);
......@@ -82,6 +132,37 @@ public class SimpleServerParseShow {
&& (c4 == 'E' || c4 == 'e') && (c5 == 'S' || c5 == 's')
&& (stmt.length() == ++offset || ParseUtil.isEOF(stmt.charAt(offset)))) {
return TABLES;
} else if (c5 == ' ') {
return showTableStatusCheck(stmt, offset);
}
}
return OTHER;
}
/**
* @param stmt
* @param offset
* @return
*/
static int showTableStatusCheck(String stmt, int offset) {
if (stmt.length() > offset + "status from ".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);
char c9 = stmt.charAt(++offset);
char c10 = stmt.charAt(++offset);
char c11 = stmt.charAt(++offset);
char c12 = stmt.charAt(++offset);
if ((c1 == 'S' || c1 == 's') && (c2 == 'T' || c2 == 't') && (c3 == 'A' || c3 == 'a')
&& (c4 == 'T' || c4 == 't') && (c5 == 'U' || c5 == 'u') && (c6 == 'S' || c6 == 's') && (c7 == ' ')
&& (c8 == 'F' || c8 == 'f') && (c9 == 'R' || c9 == 'r') && (c10 == 'o' || c10 == 'o')
&& (c11 == 'M' || c11 == 'm') && (c12 == ' ')) {
return TABLESTATUS;
}
}
return OTHER;
......
......@@ -25,7 +25,6 @@ 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.StartHandler;
import com.alibaba.cobar.server.handler.UseHandler;
import com.site.lookup.annotation.Inject;
/**
......@@ -41,6 +40,9 @@ public class SimpleServerQueryHandler implements FrontendQueryHandler {
@Inject
private SimpleDescHandler m_descHandler;
@Inject
private SimpleUseHandler m_useHandler;
private static final Logger LOGGER = Logger.getLogger(SimpleServerQueryHandler.class);
private ServerConnection m_conn;
......@@ -62,16 +64,9 @@ public class SimpleServerQueryHandler implements FrontendQueryHandler {
SetHandler.handle(sql, c, rs >>> 8);
break;
case SimpleServerParse.DESC:
//FIXME: why not inject
if(m_descHandler==null){
m_descHandler = new SimpleDescHandler();
}
m_descHandler.handle(sql, c, rs >>> 8);
break;
case SimpleServerParse.SHOW:
// FIXME: why not inject
if (m_showHandler == null) {
m_showHandler = new SimpleShowHandler();
}
m_showHandler.handle(sql, c, rs >>> 8);
break;
case SimpleServerParse.SELECT:
......@@ -93,7 +88,7 @@ public class SimpleServerQueryHandler implements FrontendQueryHandler {
c.writeErrMessage(ErrorCode.ER_UNKNOWN_COM_ERROR, "Unsupported command");
break;
case SimpleServerParse.USE:
UseHandler.handle(sql, c, rs >>> 8);
m_useHandler.handle(sql, c, rs >>> 8);
break;
case SimpleServerParse.COMMIT:
c.commit();
......
......@@ -15,6 +15,8 @@
package com.dianping.bee.server;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
......@@ -28,17 +30,20 @@ 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.dianping.bee.engine.spi.TableProviderManager;
import com.site.lookup.ContainerLoader;
import com.site.lookup.annotation.Inject;
/**
* @author <a href="mailto:yiming.liu@dianping.com">Yiming Liu</a>
*/
public class SimpleShowHandler {
@Inject
private TableProviderManager m_manager;
/**
* @param stmt
......@@ -51,14 +56,195 @@ public class SimpleShowHandler {
ShowDatabases.response(c);
break;
case SimpleServerParseShow.TABLES:
showTable(c, stmt, ServerParse.SHOW);
showTables(c, stmt);
break;
case SimpleServerParseShow.TABLESTATUS:
showTableStatus(c, stmt);
break;
case SimpleServerParseShow.STATUS:
showStatus(c, stmt);
break;
case SimpleServerParseShow.VARIABLES:
showVariables(c, stmt);
break;
default:
c.writeErrMessage(ErrorCode.ER_UNKNOWN_COM_ERROR, "Unsupported show command");
}
}
private void showTable(ServerConnection c, String sql, int type) {
/**
* @param c
* @param stmt
*/
private void showTableStatus(ServerConnection c, String stmt) {
String dbName = stmt.substring("show table status from ".length()).trim();
DatabaseProvider provider = null;
try {
provider = ContainerLoader.getDefaultContainer().lookup(DatabaseProvider.class, dbName);
} catch (ComponentLookupException e) {
c.writeErrMessage(ErrorCode.ER_BAD_DB_ERROR, "Can not load database '" + dbName + "'");
return;
}
int FIELD_COUNT = 18;
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("Name", Fields.FIELD_TYPE_VAR_STRING);
fields[i++].packetId = ++packetId;
fields[i] = PacketUtil.getField("Engine", Fields.FIELD_TYPE_VAR_STRING);
fields[i++].packetId = ++packetId;
fields[i] = PacketUtil.getField("Version", Fields.FIELD_TYPE_VAR_STRING);
fields[i++].packetId = ++packetId;
fields[i] = PacketUtil.getField("Row_format", Fields.FIELD_TYPE_VAR_STRING);
fields[i++].packetId = ++packetId;
fields[i] = PacketUtil.getField("Rows", Fields.FIELD_TYPE_VAR_STRING);
fields[i++].packetId = ++packetId;
fields[i] = PacketUtil.getField("Avg_row_length", Fields.FIELD_TYPE_VAR_STRING);
fields[i++].packetId = ++packetId;
fields[i] = PacketUtil.getField("Data_length", Fields.FIELD_TYPE_VAR_STRING);
fields[i++].packetId = ++packetId;
fields[i] = PacketUtil.getField("Max_data_length", Fields.FIELD_TYPE_VAR_STRING);
fields[i++].packetId = ++packetId;
fields[i] = PacketUtil.getField("Index_length", Fields.FIELD_TYPE_VAR_STRING);
fields[i++].packetId = ++packetId;
fields[i] = PacketUtil.getField("Data_free", Fields.FIELD_TYPE_VAR_STRING);
fields[i++].packetId = ++packetId;
fields[i] = PacketUtil.getField("Auto_increment", Fields.FIELD_TYPE_VAR_STRING);
fields[i++].packetId = ++packetId;
fields[i] = PacketUtil.getField("Create_time", Fields.FIELD_TYPE_VAR_STRING);
fields[i++].packetId = ++packetId;
fields[i] = PacketUtil.getField("Update_time", Fields.FIELD_TYPE_VAR_STRING);
fields[i++].packetId = ++packetId;
fields[i] = PacketUtil.getField("Check_time", Fields.FIELD_TYPE_VAR_STRING);
fields[i++].packetId = ++packetId;
fields[i] = PacketUtil.getField("Collation", Fields.FIELD_TYPE_VAR_STRING);
fields[i++].packetId = ++packetId;
fields[i] = PacketUtil.getField("Checksum", Fields.FIELD_TYPE_VAR_STRING);
fields[i++].packetId = ++packetId;
fields[i] = PacketUtil.getField("Create_options", Fields.FIELD_TYPE_VAR_STRING);
fields[i++].packetId = ++packetId;
fields[i] = PacketUtil.getField("Comment", 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;
// TODO: sample result currently
TableProvider[] tables = provider.getTables();
if (tables != null) {
for (TableProvider table : tables) {
RowDataPacket row = new RowDataPacket(FIELD_COUNT);
row.add(StringUtil.encode(table.getName(), c.getCharset()));
row.add(StringUtil.encode("Bee", c.getCharset()));
row.add(null);
row.add(null);
row.add(null);
row.add(null);
row.add(null);
row.add(null);
row.add(null);
row.add(null);
row.add(null);
row.add(null);
row.add(null);
row.add(null);
row.add(null);
row.add(null);
row.add(null);
row.add(null);
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);
}
/**
* @param c
* @param stmt
*/
private void showStatus(ServerConnection c, String stmt) {
int FIELD_COUNT = 2;
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("Variable_name", Fields.FIELD_TYPE_VAR_STRING);
fields[i++].packetId = ++packetId;
fields[i] = PacketUtil.getField("Value", 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;
// TODO: sample result currently
Map<String, String> sampleStatus = new HashMap<String, String>();
sampleStatus.put("bee_status", "good");
for (Map.Entry<String, String> variable : sampleStatus.entrySet()) {
RowDataPacket row = new RowDataPacket(FIELD_COUNT);
row.add(StringUtil.encode(variable.getKey(), c.getCharset()));
row.add(StringUtil.encode(variable.getValue(), 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);
}
/**
*
* @param c
* @param stmt
*/
private void showTables(ServerConnection c, String stmt) {
// 检查当前使用的DB
String db = c.getSchema();
if (db == null) {
......@@ -112,9 +298,70 @@ public class SimpleShowHandler {
// write rows
packetId = eof.packetId;
for (TableProvider table : tables) {
if (tables != null) {
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);
}
} else {
RowDataPacket row = new RowDataPacket(FIELD_COUNT);
row.add(null);
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);
}
/**
* @param c
* @param stmt
*/
private void showVariables(ServerConnection c, String stmt) {
int FIELD_COUNT = 2;
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("Variable_name", Fields.FIELD_TYPE_VAR_STRING);
fields[i++].packetId = ++packetId;
fields[i] = PacketUtil.getField("Value", 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;
// TODO: sample result currently
Map<String, String> sampleVariables = new HashMap<String, String>();
sampleVariables.put("bee_status", "good");
for (Map.Entry<String, String> variable : sampleVariables.entrySet()) {
RowDataPacket row = new RowDataPacket(FIELD_COUNT);
row.add(StringUtil.encode(table.getName(), c.getCharset()));
row.add(StringUtil.encode(variable.getKey(), c.getCharset()));
row.add(StringUtil.encode(variable.getValue(), c.getCharset()));
row.packetId = ++packetId;
buffer = row.write(buffer, c);
}
......
/**
* Project: bee-engine
*
* File Created at 2012-8-24
*
* 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 java.util.Set;
import com.alibaba.cobar.ErrorCode;
import com.alibaba.cobar.net.handler.FrontendPrivileges;
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 SimpleUseHandler {
public void handle(String sql, ServerConnection c, int offset) {
String schema = sql.substring(offset).trim();
int length = schema.length();
if (length > 0) {
if (schema.charAt(0) == '`' && schema.charAt(length - 1) == '`') {
schema = schema.substring(1, length - 1);
}
}
// 表示当前连接已经指定了schema
// if (c.getSchema() != null) {
// if (c.getSchema().equals(schema)) {
// ByteBuffer buffer = c.allocate();
// c.write(c.writeToBuffer(OkPacket.OK, buffer));
// } else {
// c.writeErrMessage(ErrorCode.ER_DBACCESS_DENIED_ERROR,
// "Not allowed to change the database!");
// }
// return;
// }
// 检查schema的有效性
FrontendPrivileges privileges = c.getPrivileges();
if (schema == null || !privileges.schemaExists(schema)) {
c.writeErrMessage(ErrorCode.ER_BAD_DB_ERROR, "Unknown database '" + schema + "'");
return;
}
String user = c.getUser();
if (!privileges.userExists(user, c.getHost())) {
c.writeErrMessage(ErrorCode.ER_ACCESS_DENIED_ERROR, "Access denied for user '" + c.getUser() + "'");
return;
}
Set<String> schemas = privileges.getUserSchemas(user);
if (schemas == null || schemas.size() == 0 || schemas.contains(schema)) {
c.setSchema(schema);
ByteBuffer buffer = c.allocate();
c.write(c.writeToBuffer(OkPacket.OK, buffer));
} else {
String msg = "Access denied for user '" + c.getUser() + "' to database '" + schema + "'";
c.writeErrMessage(ErrorCode.ER_DBACCESS_DENIED_ERROR, msg);
}
}
}
......@@ -4,6 +4,11 @@
<role>com.dianping.bee.server.SimpleServer</role>
<implementation>com.dianping.bee.server.SimpleServer</implementation>
</component>
<component>
<role>com.dianping.bee.engine.spi.DatabaseProvider</role>
<role-hint>information_schema</role-hint>
<implementation>com.dianping.bee.server.InformationSchemaDatabase</implementation>
</component>
<component>
<role>com.dianping.bee.engine.spi.DatabaseProvider</role>
<role-hint>cat</role-hint>
......@@ -86,6 +91,15 @@
<component>
<role>com.dianping.bee.server.SimpleShowHandler</role>
<implementation>com.dianping.bee.server.SimpleShowHandler</implementation>
<requirements>
<requirement>
<role>com.dianping.bee.engine.spi.TableProviderManager</role>
</requirement>
</requirements>
</component>
<component>
<role>com.dianping.bee.server.SimpleUseHandler</role>
<implementation>com.dianping.bee.server.SimpleUseHandler</implementation>
</component>
<component>
<role>com.dianping.bee.server.SimpleDescHandler</role>
......@@ -119,6 +133,9 @@
<requirement>
<role>com.dianping.bee.server.SimpleDescHandler</role>
</requirement>
<requirement>
<role>com.dianping.bee.server.SimpleUseHandler</role>
</requirement>
</requirements>
</component>
</components>
......
......@@ -24,4 +24,7 @@
<schema name="dog">
</schema>
<schema name="information_schema">
</schema>
</cobar:schema>
......@@ -36,7 +36,7 @@
<!-- 用户访问定义,用户名、密码、schema等信息。 -->
<user name="test">
<property name="password">test</property>
<property name="schemas">cat,dog</property>
<property name="schemas">cat,dog,information_schema</property>
</user>
<!--
<user name="root">
......
......@@ -4,6 +4,7 @@ import org.apache.commons.lang3.RandomStringUtils;
import com.dianping.bee.engine.spi.DatabaseProvider;
import com.dianping.bee.engine.spi.TableProvider;
import com.dianping.bee.engine.spi.internal.StaticTableHelper;
import com.dianping.bee.engine.spi.meta.Cell;
import com.dianping.bee.engine.spi.meta.ColumnMeta;
import com.dianping.bee.engine.spi.meta.Index;
......@@ -14,6 +15,7 @@ import com.dianping.bee.engine.spi.meta.internal.DefaultRow;
import com.dianping.bee.engine.spi.meta.internal.DefaultRowSet;
public class CatDatabase implements DatabaseProvider {
public static enum CatTable implements TableProvider {
Transaction("transaction") {
@Override
......@@ -29,13 +31,13 @@ public class CatDatabase implements DatabaseProvider {
Event("event") {
@Override
public TransactionColumn[] getColumns() {
return TransactionColumn.values();
public EventColumn[] getColumns() {
return EventColumn.values();
}
@Override
public TransactionIndex[] getIndexes() {
return TransactionIndex.values();
public EventIndex[] getIndexes() {
return EventIndex.values();
}
},
......@@ -68,10 +70,11 @@ public class CatDatabase implements DatabaseProvider {
public RowSet queryByIndex(Index index, ColumnMeta[] selectColumns) {
ColumnMeta[] columns = selectColumns;
DefaultRowSet rowSet = new DefaultRowSet(columns);
for (int i = 0; i < 10; i++) {
for (int rowIndex = 0; rowIndex < 10; rowIndex++) {
Cell[] cells = new Cell[columns.length];
for (int j = 0; j < cells.length; j++) {
ColumnMeta columnMeta = TransactionColumn.findByName(columns[j].getName());
for (int colIndex = 0; colIndex < cells.length; colIndex++) {
ColumnMeta columnMeta = StaticTableHelper.findColumn(this, columns[colIndex].getName());
String randomValue = null;
if (columnMeta.getType().getSimpleName().equals("String")) {
randomValue = RandomStringUtils.randomAlphabetic(5);
......@@ -81,7 +84,7 @@ public class CatDatabase implements DatabaseProvider {
} else {
randomValue = RandomStringUtils.randomAlphanumeric(5);
}
cells[j] = new DefaultCell(columnMeta, randomValue);
cells[colIndex] = new DefaultCell(columnMeta, randomValue);
}
Row row = new DefaultRow(cells);
......@@ -219,17 +222,6 @@ 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;
......@@ -303,18 +295,6 @@ public class CatDatabase implements DatabaseProvider {
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();
......
......@@ -4,6 +4,7 @@ import org.apache.commons.lang3.RandomStringUtils;
import com.dianping.bee.engine.spi.DatabaseProvider;
import com.dianping.bee.engine.spi.TableProvider;
import com.dianping.bee.engine.spi.internal.StaticTableHelper;
import com.dianping.bee.engine.spi.meta.Cell;
import com.dianping.bee.engine.spi.meta.ColumnMeta;
import com.dianping.bee.engine.spi.meta.Index;
......@@ -14,6 +15,7 @@ import com.dianping.bee.engine.spi.meta.internal.DefaultRow;
import com.dianping.bee.engine.spi.meta.internal.DefaultRowSet;
public class DogDatabase implements DatabaseProvider {
public static enum DogTable implements TableProvider {
Transaction("transaction") {
@Override
......@@ -58,10 +60,12 @@ public class DogDatabase implements DatabaseProvider {
public RowSet queryByIndex(Index index, ColumnMeta[] selectColumns) {
ColumnMeta[] columns = selectColumns;
DefaultRowSet rowSet = new DefaultRowSet(columns);
for (int i = 0; i < 10; i++) {
for (int rowIndex = 0; rowIndex < 10; rowIndex++) {
Cell[] cells = new Cell[columns.length];
for (int j = 0; j < cells.length; j++) {
ColumnMeta columnMeta = TransactionColumn.findByName(columns[j].getName());
for (int colIndex = 0; colIndex < cells.length; colIndex++) {
ColumnMeta columnMeta = StaticTableHelper.findColumn(this, columns[colIndex].getName());
String randomValue = null;
if (columnMeta.getType().getSimpleName().equals("String")) {
randomValue = RandomStringUtils.randomAlphabetic(5);
......@@ -71,7 +75,7 @@ public class DogDatabase implements DatabaseProvider {
} else {
randomValue = RandomStringUtils.randomAlphanumeric(5);
}
cells[j] = new DefaultCell(columnMeta, randomValue);
cells[colIndex] = new DefaultCell(columnMeta, randomValue);
}
Row row = new DefaultRow(cells);
......@@ -108,17 +112,6 @@ public class DogDatabase 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;
......@@ -192,18 +185,6 @@ public class DogDatabase implements DatabaseProvider {
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();
......
/**
* Project: bee-engine
*
* File Created at 2012-8-24
*
* 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.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import com.dianping.bee.server.SimpleServer;
import com.site.lookup.ComponentTestCase;
/**
* @author <a href="mailto:yiming.liu@dianping.com">Yiming Liu</a>
*/
@RunWith(JUnit4.class)
public class JDBCTest extends ComponentTestCase {
private SimpleServer server;
@Before
public void runServer() throws Exception {
server = lookup(SimpleServer.class);
server.startup();
}
@Test
public void testConnection() {
Connection conn = null;
String url = "jdbc:mysql://localhost:2330/";
String dbName = "cat";
String driver = "com.mysql.jdbc.Driver";
String userName = "test";
String password = "test";
try {
Class.forName(driver).newInstance();
conn = DriverManager.getConnection(url + dbName, userName, password);
System.out.println("Connected to the database");
conn.close();
System.out.println("Disconnected from database");
} catch (Exception e) {
e.printStackTrace();
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册