db.cpp 4.1 KB
Newer Older
羽飞's avatar
羽飞 已提交
1 2 3 4 5 6 7 8 9 10 11
/* Copyright (c) 2021 Xie Meiyi(xiemeiyi@hust.edu.cn) and OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
         http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */

//
12
// Created by Meiyi & Longda & Wangyunlai on 2021/5/12.
羽飞's avatar
羽飞 已提交
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
//

#include "storage/common/db.h"

#include <sys/stat.h>
#include <fcntl.h>
#include <vector>

#include "common/log/log.h"
#include "common/os/path.h"
#include "common/lang/string.h"
#include "storage/common/table_meta.h"
#include "storage/common/table.h"
#include "storage/common/meta_util.h"

L
Longda 已提交
28 29
Db::~Db()
{
羽飞's avatar
羽飞 已提交
30 31 32 33 34 35
  for (auto &iter : opened_tables_) {
    delete iter.second;
  }
  LOG_INFO("Db has been closed: %s", name_.c_str());
}

L
Longda 已提交
36 37
RC Db::init(const char *name, const char *dbpath)
{
羽飞's avatar
羽飞 已提交
38

L
Longda 已提交
39 40
  if (common::is_blank(name)) {
    LOG_ERROR("Failed to init DB, name cannot be empty");
羽飞's avatar
羽飞 已提交
41 42 43 44
    return RC::INVALID_ARGUMENT;
  }

  if (!common::is_directory(dbpath)) {
L
Longda 已提交
45
    LOG_ERROR("Failed to init DB, path is not a directory: %s", dbpath);
羽飞's avatar
羽飞 已提交
46 47 48 49 50 51 52 53 54
    return RC::GENERIC_ERROR;
  }

  name_ = name;
  path_ = dbpath;

  return open_all_tables();
}

L
Longda 已提交
55 56
RC Db::create_table(const char *table_name, int attribute_count, const AttrInfo *attributes)
{
羽飞's avatar
羽飞 已提交
57 58 59
  RC rc = RC::SUCCESS;
  // check table_name
  if (opened_tables_.count(table_name) != 0) {
L
Longda 已提交
60
    LOG_WARN("%s has been opened before.", table_name);
羽飞's avatar
羽飞 已提交
61 62 63
    return RC::SCHEMA_TABLE_EXIST;
  }

L
Longda 已提交
64 65
  // 文件路径可以移到Table模块
  std::string table_file_path = table_meta_file(path_.c_str(), table_name);
羽飞's avatar
羽飞 已提交
66 67 68
  Table *table = new Table();
  rc = table->create(table_file_path.c_str(), table_name, path_.c_str(), attribute_count, attributes);
  if (rc != RC::SUCCESS) {
L
Longda 已提交
69
    LOG_ERROR("Failed to create table %s.", table_name);
羽飞's avatar
羽飞 已提交
70 71 72 73 74 75 76 77 78
    delete table;
    return rc;
  }

  opened_tables_[table_name] = table;
  LOG_INFO("Create table success. table name=%s", table_name);
  return RC::SUCCESS;
}

L
Longda 已提交
79 80
Table *Db::find_table(const char *table_name) const
{
羽飞's avatar
羽飞 已提交
81 82 83 84 85 86 87
  std::unordered_map<std::string, Table *>::const_iterator iter = opened_tables_.find(table_name);
  if (iter != opened_tables_.end()) {
    return iter->second;
  }
  return nullptr;
}

L
Longda 已提交
88 89
RC Db::open_all_tables()
{
羽飞's avatar
羽飞 已提交
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
  std::vector<std::string> table_meta_files;
  int ret = common::list_file(path_.c_str(), TABLE_META_FILE_PATTERN, table_meta_files);
  if (ret < 0) {
    LOG_ERROR("Failed to list table meta files under %s.", path_.c_str());
    return RC::IOERR;
  }

  RC rc = RC::SUCCESS;
  for (const std::string &filename : table_meta_files) {
    Table *table = new Table();
    rc = table->open(filename.c_str(), path_.c_str());
    if (rc != RC::SUCCESS) {
      delete table;
      LOG_ERROR("Failed to open table. filename=%s", filename.c_str());
      return rc;
    }

    if (opened_tables_.count(table->name()) != 0) {
      delete table;
L
Longda 已提交
109 110 111
      LOG_ERROR("Duplicate table with difference file name. table=%s, the other filename=%s",
          table->name(),
          filename.c_str());
羽飞's avatar
羽飞 已提交
112 113 114 115 116 117 118 119 120 121 122
      return RC::GENERIC_ERROR;
    }

    opened_tables_[table->name()] = table;
    LOG_INFO("Open table: %s, file: %s", table->name(), filename.c_str());
  }

  LOG_INFO("All table have been opened. num=%d", opened_tables_.size());
  return rc;
}

L
Longda 已提交
123 124
const char *Db::name() const
{
羽飞's avatar
羽飞 已提交
125 126 127
  return name_.c_str();
}

L
Longda 已提交
128 129 130
void Db::all_tables(std::vector<std::string> &table_names) const
{
  for (const auto &table_item : opened_tables_) {
羽飞's avatar
羽飞 已提交
131 132 133 134
    table_names.emplace_back(table_item.first);
  }
}

L
Longda 已提交
135 136
RC Db::sync()
{
羽飞's avatar
羽飞 已提交
137
  RC rc = RC::SUCCESS;
L
Longda 已提交
138
  for (const auto &table_pair : opened_tables_) {
羽飞's avatar
羽飞 已提交
139 140 141 142 143 144
    Table *table = table_pair.second;
    rc = table->sync();
    if (rc != RC::SUCCESS) {
      LOG_ERROR("Failed to flush table. table=%s.%s, rc=%d:%s", name_.c_str(), table->name(), rc, strrc(rc));
      return rc;
    }
L
Longda 已提交
145
    LOG_INFO("Successfully sync table db:%s, table:%s.", name_.c_str(), table->name());
羽飞's avatar
羽飞 已提交
146
  }
L
Longda 已提交
147
  LOG_INFO("Successfully sync db. db=%s", name_.c_str());
羽飞's avatar
羽飞 已提交
148 149
  return rc;
}