【MyDB】6-TabelManager 字段与表管理 之4-SQL语句执行

发布于:2025-03-21 ⋅ 阅读:(33) ⋅ 点赞:(0)

【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中的相关方法,便不再一一赘述。