从0开始写数据库-02-条件查询

本篇介绍MyBase数据库中条件过滤的实现。您可以在 https://github.com/zhangqhn/mybase 下载到MyBase项目源码。

  1. 数据的抽象

MyBase支持整数、浮点数、字符串数据类型,在介绍条件查询之前我们需要先对数据进行抽象,目标是能用一个数据类型表示所有类型的数据。在MyBase的实现中,这个数据类型是DBVal (dbval.h) 它的定义如下:

typedef struct _DBVal
{
  int valType_; // value type , null, int, double, string
  int dataLen_; // data length
  union {
    int64_t intVal_;
    double doubleVal_;
    const char* strVal_;
  } val_;
}DBVal;

valType_ :表示当前存储的值类型,null,int,double还是string。

dataLen_ :表示数据的长度,比如:字符串的长度。

val_ : 中存储对应的值。

将数据值通过DBVal存储后,表的每一行数据就可以表示为一个DBVal的数组,在MyBase中我们将每行数据以:std::vector<DBVal> 来表示,条件查询就可以理解为判断一个std::vector<DBVal>对象是否满足给定的条件。

  1. 查询条件的抽象

在MyBase中我们简单的将条件抽象为 字段、运算符、运算数。

例如:age > 20 , name = zhangsan 等等。

也可以没有运算数,例如: score is not null

在表中,字段的位置已经确定,进一步将查询条件简化为:字段下标、运算符、运算数。

根据上面的内容定义出下面的接口:

class ConditionItem
{
public:
  virtual bool GetLogic(const std::vector<DBVal>& vals) = 0;
};

不同的条件只需要定义一个类继承ConditionItem ,执行查询时创建该类的实例并将行数据传递给GetLogic的参数,就可以知道该行数据是否满足指定的条件。

下面以age > 20的示例来说明:

实现在整数类型上执行大于判断的类IntGtCondition

class IntGtCondition : public ConditionItem
{
public:
  IntGtCondition(int fieldPos, int64_t valParam)
  {
    this->fieldPos_ = fieldPos;
    this->valParam_ = valParam;
  }

  virtual ~IntGtCondition() {}

  virtual bool GetLogic(const std::vector<DBVal>& vals)
  {
    if (VALUE_TYPE::VAL_INT == vals[fieldPos_].valType_)
    {
      return vals[fieldPos_].val_.intVal_ > valParam_;
    }

    return false;
  }

private:
  int fieldPos_;
  int64_t valParam_;
};

fieldPos_ 即 字段下标;

valParam_ 即 运算数;

运算符也就是大于;

若表的创建语句如下: CREATE TABLE stuinfo(id int, name string, age int)

那么条件: where age > 20 可以转换为

ConditionItem pCondition = new IntGtCondition(2, 20);

将每行数据分别调用 pCondition的GetLogic 方法即可得到该行数据是否满足 age > 20的条件了。

其他条件的实现类似,具体可以参考源码中:condition.h condition.cpp 文件

猜你喜欢

转载自blog.csdn.net/zhangqhn/article/details/88654134
今日推荐