自己动手写数据库:解析 select 语句并生成查询树

首先我们需要给原来代码打个补丁,在SelectScan 结构体初始化时需要传入 UpdateScan 接口对象,但很多时候我们需要传入的是 Scan 对象,因此我们需要做一个转换,也就是当初始化 SelectScan 时,如果传入的是 Scan 对象,那么我们就将其封装成 UpdateScan 接口对象,因此在 query 目录下增加一个名为 updatescan_wrapper.go 的文件,在其中输入内容如下:

package query

import (
    "record_manager"
)

type UpdateScanWrapper struct {
    scan Scan
}

func NewUpdateScanWrapper(s Scan) *UpdateScanWrapper {
    return &UpdateScanWrapper{
        scan: s,
    }
}

func (u *UpdateScanWrapper) GetScan() Scan {
    return u.scan
}

func (u *UpdateScanWrapper) SetInt(fldName string, val int) {
    //DO NOTHING
}

func (u *UpdateScanWrapper) SetString(fldName string, val string) {
    //DO NOTHING
}

func (u *UpdateScanWrapper) SetVal(fldName string, val *Constant) {
    //DO NOTHING
}

func (u *UpdateScanWrapper) Insert() {
    //DO NOTHING
}

func (u *UpdateScanWrapper) Delete() {
    //DO NOTHING
}

func (u *UpdateScanWrapper) GetRid() *record_manager.RID {
    return nil
}

func (u *UpdateScanWrapper) MoveToRid(rid *record_manager.RID) {
    // DO NOTHING
}

上面代码逻辑简单,如果调用 Scan 对象接口时,他直接调用其 Scan 内部对象的接口,如果调用到 UpdateScan 的接口,那么它什么都不做。完成上面代码后,我们在select_plan.go 中进行一些修改:

func (s *SelectPlan) Open() interface{} {
    scan := s.p.Open()
    updateScan, ok := scan.(query.UpdateScan)
    if !ok {
        updateScanWrapper := query.NewUpdateScanWrapper(scan.(query.Scan))
        return query.NewSelectionScan(updateScanWrapper, s.pred)
    }
    return query.NewSelectionScan(updateScan, s.pred)
}

上面代码在创建 SelectScan 对象时,先判断传进来的对象是否能类型转换为 UpdateScan,如果不能,那意味着s.p.Open 获取的是 Scan 对象,因此我们使用前面的代码封装一下再用来创建 SelectScan 对象。完

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值