【MyDB】6-TabelManager 字段与表管理 之4-SQL语句执行
前言
TableManager.java 和 TabelManagerImpl.java 是最顶层,tbm中的对外层提供的接口。服务端通过调用TabelManagerImpl中的insert,update,select,show,begin等方法,对数据库进行操作。
TableManager.java是一个接口类,包括初始化。定义了待实现的接口事务控制,表结构管理,数据操作等。
TabelManagerImpl.java 则是 TableManager.java 的实现类。
loadTables() 加载数据库中所有的表。(链表结构:表通过 nextUid 形成链表,booter 存储头节点 UID。
插入时使用头插法)
事务管理方法:begin/commit/abort
表元数据操作:create(long xid, Create create),show(long xid),
数据操作方法:insert,select,update 等,都是调用Tabel中的相关方法实现。
TBM对外提供服务的是TableManager接口,如下
public interface TableManager {
BeginRes begin(Begin begin);
byte[] commit(long xid) throws Exception;
byte[] abort(long xid);
byte[] show(long xid);
byte[] create(long xid, Create create) throws Exception;
byte[] insert(long xid, Insert insert) throws Exception;
byte[] read(long xid, Select select) throws Exception;
byte[] update(long xid, Update update) throws Exception;
byte[] delete(long xid, Delete delete) throws Exception;
}
由于 TableManager 已经是直接被最外层 Server 调用(MYDB 是 C/S 结构),这些方法直接返回执行的结果,例如错误信息或者结果信息的字节数组(可读)。
各个方法的具体实现很简单,不再赘述,无非是调用 VM 的相关方法。唯一值得注意的一个小点是,在创建新表时,采用的时头插法,所以每次创建表都需要更新 Booter 文件。
TableManagerImpl
loadTables 加载所有表
加载所有表,表之间通过链式存储,有新表时,插入到表头
/**
* 加载所有表,表之间通过链式存储,有新表时,插入到表头
*/
private void loadTables() {
long uid = firstTableUid(); // 读取第一个表的uid
while(uid != 0) {
Table tb = Table.loadTable(this, uid);
uid = tb.nextUid;
tableCache.put(tb.name, tb);
}
}
create 创建表
/**
* 创建表
* @param xid
* @param create
* @return
* @throws Exception
*/
@Override
public byte[] create(long xid, Create create) throws Exception {
lock.lock();
try {
// 表名不能重复
if(tableCache.containsKey(create.tableName)) {
throw Error.DuplicatedTableException;
}
// 1.创建表并将表插入到表头中
Table table = Table.createTable(this, firstTableUid(), xid, create);
updateFirstTableUid(table.uid);
tableCache.put(create.tableName, table);
if(!xidTableCache.containsKey(xid)) {
xidTableCache.put(xid, new ArrayList<>());
}
xidTableCache.get(xid).add(table);
return ("create " + create.tableName).getBytes();
} finally {
lock.unlock();
}
}
insert 向表中插入数据
// 插入数据,调用table的insert方法
@Override
public byte[] insert(long xid, Insert insert) throws Exception {
lock.lock();
Table table = tableCache.get(insert.tableName);
lock.unlock();
if(table == null) {
throw Error.TableNotFoundException;
}
table.insert(xid, insert);
return "insert".getBytes();
}
接下来的read,update,delete都是调用table中的相关方法,便不再一一赘述。