如何用C++实现一个简易数据库(一)

如何用C++实现一个简易数据库(一)

本文是《如何用C++实现一个简易数据库》的第一个单元

源码位于tutorial01-实现REPL

1. 如何安装我们的单元测试环境?

  • 检查我们是否有安装ruby

    输入命令ruby -v,我们将得到

ruby 2.7.0p0 (2019-12-25 revision 647ee6f091) [x86_64-linux-gnu]

如果没有安装使用sudo apt install ruby或对应操作系统的包管理工具安装即可。

  • 检查我们是否有安装rspec

    输入命令rspec -v,我们将得到

RSpec 3.10
  - rspec-core 3.10.2
  - rspec-expectations 3.10.2
  - rspec-mocks 3.10.3
  - rspec-support 3.10.3

同理如果没有安装则使用sudo gem install rspec安装即可。若提示没有gem则使用sudo apt install gem便可完成安装。

rubyrspec版本基本未对本单元测试造成影响,如果存在问题,可提出。

至此我们的测试环境便已经安装完成了。

2. 如何编写和使用我们的第一个单元测试?

让我们在目录下创建db_test.rb文件。

describe 'database' do
  def run_script(commands)
    raw_output = nil
    IO.popen("./db", "r+") do |pipe|
      commands.each do |command|
        pipe.puts command
      end

      pipe.close_write

      # Read entire output
      raw_output = pipe.gets(nil)
    end
    raw_output.split("\n")
  end

  it 'test exit and unrecognized command' do
    result = run_script([
      "hello world",
      "HELLO WORLD",
      ".exit",
    ])
    expect(result).to match_array([
      "db > Unrecognized command: hello world",
      "db > Unrecognized command: HELLO WORLD",
      "db > Bye!",
    ])
  end
end

让我们来执行它看看,输入rspec spec db_test.rb

LoadError:
  cannot load such file ...

显然是会失败的,因为我们甚至还没有在目录下编译创建我们的db文件。
现在让我们从最简单交互窗口REPL开始。

3. REPL是什么?

“读取-求值-输出”循环 (英語:Read-Eval-Print Loop,简称REPL),也被称做交互式顶层构件 (英語:interactive toplevel),是一个简单的,交互式的编程环境。

4. 怎么实现一个简单REPL?

首先我们直接启动一个无限循环,就像一个shell一样。之后我们print_prompt()意味着打印提示符。接着虽然std::string被大家诟病许久,但是作为我们简易数据库的使用也暂且足矣。我们每次重复创建input_line这个string对象,同时通过std::getline这个函数从std::cin标准输入中获取到所需信息(以换行符做分割,即回车标志着新语句)

.exit意味着退出当前REPL交互,即成功退出,其他情况即输出未知命令。

void DB::print_prompt()
{
    std::cout << "db > ";
}

bool DB::parse_meta_command(std::string command)
{
    if (command == ".exit")
    {
        std::cout << "Bye!" << std::endl;
        exit(EXIT_SUCCESS);
    }
    else
    {
        std::cout << "Unrecognized command: " << command << std::endl;
        return true;
    }
    return false;
}
void DB::start()
{
    while (true)
    {
        print_prompt();
        
        std::string input_line;
        std::getline(std::cin, input_line);

        if (parse_meta_command(input_line))
        {
            continue;
        }
    }
}

让我们来测试一下,首先编译我们的文件g++ db.cpp -o db,再输入rspec spec db_test.rb

.

Finished in 0.00504 seconds (files took 0.07621 seconds to load)
1 example, 0 failures

结果显然,恭喜大家通过了所创建的单元测试。

3. 总结

作为教程第一章,实现REPL是非常基础的。由于我们使用了std::string,故省去了很多c_str内存管理以及长度等一系列繁琐的事情。同时基于我们的测试进行开发,作为教程来说可以让大家更加清楚该朝着哪个方向前进。下一章我们将对输入的命令进行更进一步的分析。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值