Example #1
0
Info API::DropIndex(SqlCommandDropIndex* command){
  CatalogManager catalog_manager;
  IndexManager index_manager;
  std::string index_name = command->index_name();

  if (!catalog_manager.HasIndex(index_name)){
    std::string error_info;
    error_info = "Index \"" + index_name + "\" not exists.";
    return Info(error_info);
  }
  else{
    IndexInfo index = catalog_manager.GetIndexInfo(index_name);
    std::string table_name = index.table_name();
    std::string attribute_name = index.attribute_name();
    index_manager.EmptyIndex(index);
    if (catalog_manager.DropIndex(index_name)){
      //update table info
      TableInfo table = catalog_manager.GetTableInfo(table_name);
      table.remove_index(attribute_name,index_name);
      catalog_manager.WriteTableInfo(table);
      return Info();
    }
    else{
      return Info("Drop index Failed");
    }
  }

}
Example #2
0
Info API::DropTable(SqlCommandDropTable* command){
  CatalogManager catalog_manager;
  std::string table_name = command->table_name();

  if (!catalog_manager.HasTable(table_name)){
    std::string error_info;
    error_info = "Table \"" + table_name + "\" not exists.";
    return Info(error_info);
  }
  else{
    TableInfo table = catalog_manager.GetTableInfo(table_name);
    
    for (auto it : table.index_names()){
      SqlCommandDropIndex* cmd = new SqlCommandDropIndex(it);
        if(!DropIndex(cmd).is_succeed()){
          return Info("Drop table success but index \"" + it +"\" failed to be dropped");
        }
    }

    if (catalog_manager.DropTable(table_name)){
        //drop index
      return Info();
    }
    else{
      return Info("Drop table Failed");
    }
  }
}
Example #3
0
std::string lua_details::tableAsString(const TableInfo& table, size_t limit)
{
	std::ostringstream ost;

	ost << "{ ";

	const size_t count= table.size();

	for (size_t i= 0; i < count; ++i)
	{
		const LuaField& f= table[i];

		if (i > 0)
			ost << ", ";

		ost << f.getKey().getValue() << " = " << f.getValue().getValue();

		if (i + 1 == limit)
		{
			ost << ", ... ";
			break;
		}
	}

	if (count > 0)
		ost << ' ';

	ost << "}";

	return ost.str();
}
Example #4
0
void SQLCreateIndex(CreateIndexData &cID)
{
	IndexInfo *newIndex;
	TableInfo *indexTable;

	cout<<"\"Create Index\" operation is triggered."<<endl;
	cout<<cID;

	indexTable = catalogInfo.FindTable(cID.tableName);
	if(indexTable == NULL)
	{
		cout<<"The specified table doesn't exist."<<endl;
		return;
	}

	newIndex = indexTable->CreateIndex(cID);
}
Example #5
0
Info API::CreateIndex(SqlCommandCreateIndex* command){
  IndexManager index_manager;
  CatalogManager catalog_manager;
  RecordManager record_manager;
  std::string index_name = command->index_name();
  std::string attribute_name = command->column_name();
  std::string table_name = command->table_name();

  if (catalog_manager.HasIndex(index_name)){
    std::string error_info;
    error_info = "Index \"" + index_name + "\" already exists.";
    return Info(error_info);
  }
  if (!catalog_manager.HasTable(table_name)){
    std::string error_info;
    error_info = "table \"" + table_name + "\" not exists.";
    return Info(error_info);
  }
  TableInfo table = catalog_manager.GetTableInfo(table_name);

  if(!table.HasAttribute(attribute_name)){
    std::string error_info;
    error_info = "attribute \"" + attribute_name + "\" not exists.";
    return Info(error_info);
  }
  if (!table.attribute(attribute_name).is_unique() && !table.attribute(attribute_name).is_primary_key()){
    std::string error_info;
    error_info = "attribute \"" + attribute_name + "\" is not an unique attribute.";
    return Info(error_info);
  }
  else{
    IndexInfo index_info(index_name, table_name, attribute_name);
    //create index in index manager
    if(index_manager.CreateIndex(table.attribute(attribute_name).type(),table.attribute(attribute_name).length(), index_info)){
      auto all_records = record_manager.SelectAllRecords(table);

      for (auto record : all_records){
          if(!index_manager.AddRecord(table,index_info,record.first.at(table.attribute_index(index_info.attribute_name())),record.second)){
          return Info("Update index failed.");
        }
      }
      if (!catalog_manager.RegisterIndex(index_info))
      {
        return Info("Register Index failed.");
      }
      //update table info in catalog manager
      table.add_index(attribute_name, index_name);
      catalog_manager.WriteTableInfo(table);
      return Info();
    }
    else{
      return Info("Create index failed.");
    }
  }
}
Example #6
0
 void reset() {
     tableName="";
     attrName="";
     indexName="";
     tableInfo.reset();
     condNum=0;
     attrNum=0;
     fileName="";
 }
Example #7
0
bool CheckUnqiueAndPrimaryKey(const TableInfo& table, const std::vector<std::string>& values){
  IndexManager index_manager;
  RecordManager record_manager;
  std::vector<std::string> attributes_to_be_checked;
  attributes_to_be_checked = table.unique();
  attributes_to_be_checked.push_back(table.primary_key());

  for (auto it : attributes_to_be_checked){
    int attribute_index = table.attribute_index(it);

    if (!table.attribute(it).index_names().empty()){//has index
      std::string index_name = table.attribute(it).index_names().at(0);
      IndexInfo index_info(index_name, table.table_name(), it);
      if (index_manager.FindValue(table,index_info,values.at(attribute_index))){ // has value
        return false;
      }
    }
    else{
      WhereClause where;
      where.kColumnName = it;
      where.kOperator ="=";
      where.kCondition = values.at(attribute_index);
      if (!record_manager.FindRecordsWithNoIndex(table,where).empty()){
        return false;
      }
    }
  }
  return true;
}
Example #8
0
bool lua_details::listTable(lua_State* L, int idx, TableInfo& out, int recursive)
{
	out.clear();

	if (lua_type(L, idx) != LUA_TTABLE)
		return false;

	UInt32 size= getNumFields(L, idx);

	out.reserve(size);

	// table to traverse
	lua_pushvalue(L, idx);

	// push a key
	lua_pushnil(L);

	popStackElements pop(L, 2);	// remove key & table off the stack at the end of this fn
//	popStackElements pop(L, 1);	// remove table off the stack at the end of this fn

	int table= lua_gettop(L) - 1;

	// traverse a table
	while (lua_next(L, table))
	{
		popStackElements pop(L, 1);

        Value Key(L, -2);
        Value Val(L, -1, recursive);
		LuaField field(Key,Val);

		out.push_back(field);
	}

	pop.dec();	// final lua_next call removed key

	return true;
}
Example #9
0
bool lua_details::list_table(lua_State* L, int idx, TableInfo& out, int recursive)
{
	out.clear();

	if (lua_type(L, idx) != LUA_TTABLE)
		return false;

	int size= lua_objlen(L, idx);

	out.reserve(size);

	// table to traverse
	lua_pushvalue(L, idx);

	// push a key
	lua_pushnil(L);

	pop_stack_elements pop(L, 2);	// remove key & table off the stack at the end of this fn
//	pop_stack_elements pop(L, 1);	// remove table off the stack at the end of this fn

	int table= lua_gettop(L) - 1;

	// traverse a table
	while (lua_next(L, table))
	{
		pop_stack_elements pop(L, 1);

		LuaField field;
		capture_value(L, field.key, -2);
		capture_value(L, field.val, -1, recursive);

		out.push_back(field);
	}

	pop.dec();	// final lua_next call removed key

	return true;
}
Example #10
0
Info API::SelectFrom(SqlCommandSelectFrom* command){
  CatalogManager catalog_manager;
  RecordManager record_manager;
  IndexManager index_manager;

  bool select_all_columns = command->select_all_columns();
  bool select_all_records = command->select_all_records();
  std::vector<std::string> column_names = command->column_names();
  std::string table_name = command->table_name();
  std::vector<WhereClause> where_clause = command->where_clause();
  if (!catalog_manager.HasTable(table_name)){
    std::string error_info;
    error_info = "Table \"" + table_name + "\" not exists.";
    return Info(error_info);
  }

  TableInfo table = catalog_manager.GetTableInfo(table_name);

  if (column_names.empty()){
    column_names = table.attribute_names_ordered();
  }
  else{
    for (auto it : column_names){
      if(!table.HasAttribute(it)){
        std::string error_info;
        error_info = "attribute \"" + it + "\" not exists.";
        return Info(error_info);
      }
    }
  }

  for (auto it: where_clause){
    if(!table.HasAttribute(it.kColumnName)){
      std::string error_info;
      error_info = "attribute \"" + it.kColumnName + "\"in where clause \""+it.kColumnName + it.kOperator + it.kCondition +"\" not exists.";
      return Info(error_info);
    }
  }

  std::vector<std::pair<int,int> > results;
  std::vector<std::vector<std::string> > records;
  if (select_all_records){
    auto records_offset_pairs = record_manager.SelectAllRecords(table);
    for (auto i : records_offset_pairs){
      records.push_back(i.first);
    }
  }
  else{
    std::vector<WhereClause> where_clause_with_index;
    std::vector<WhereClause> where_clause_without_index;

    for (auto it : where_clause){
      if (!table.attribute(it.kColumnName).index_names().empty() && it.kOperator != "!="){
        where_clause_with_index.push_back(it);
      }
      else{
        where_clause_without_index.push_back(it);
      }
    }


    if (!where_clause_with_index.empty()) //条件里有属性有 index
    {
      for (auto it : where_clause_with_index){
        std::string index_name = table.attribute(it.kColumnName).index_names().at(0);
        IndexInfo index = catalog_manager.GetIndexInfo(index_name);
        std::vector<int> offsets_of_a_clause = index_manager.FindRecords(table,index, it);
        std::sort(offsets_of_a_clause.begin(), offsets_of_a_clause.end());
        offsets_of_a_clause.erase(std::unique(offsets_of_a_clause.begin(), offsets_of_a_clause.end()), offsets_of_a_clause.end());
        std::vector<std::pair<int,int>> results_of_a_clause = record_manager.FindRecordsWithIndex(offsets_of_a_clause, table, it);

        if (results.empty()){
          results = results_of_a_clause;
        }
        else{
          std::vector<std::pair<int,int> > results_temp;
          std::set_intersection(results.begin(),results.end(),
                                results_of_a_clause.begin(),results_of_a_clause.end(),
                                std::back_inserter(results_temp));
          results = results_temp;
        }
      }

      for(auto it : where_clause_without_index){
        results = record_manager.RecordsFilter(results, table, it);
      }
    }
    else{ //条件里属性都没有 index
      for (auto it: where_clause_without_index){
        if (results.empty()){
          results = record_manager.FindRecordsWithNoIndex(table, it);
        }
        else{
          results = record_manager.RecordsFilter(results,table, it);
        }
      }
    }
    records = record_manager.SelectRecords(results, table);
  }

  //print table
  for (auto it : column_names){
    std::cout<<"+" << "--------------";
  }

  std::cout<<"+"<<std::endl;
  //表头
  for (auto it : column_names){
    std::cout<<"| " << std::setw(12) << it <<" ";
  }

  std::cout<<"|"<<std::endl;

  for (auto it : column_names){
    std::cout<<"+" << "--------------";
  }
  std::cout<<"+"<<std::endl;

  std::vector<int> index;
  for (auto it: column_names){
    auto attribute_names_ordered = table.attribute_names_ordered();
    auto i = std::find(attribute_names_ordered.begin(), attribute_names_ordered.end(),it);
    int position= std::distance(attribute_names_ordered.begin(),i);
    index.push_back(position);
  }
  //print records
  for (auto it : records){
    for (auto i : index){
      std::cout<<"| "<<std::setw(12) << it.at(i)<<" ";
    }
    std::cout<<"|"<<std::endl;
  }

  for (auto it : column_names){
    std::cout<<"+" << "--------------";
  }

  std::cout<<"+"<<std::endl;
  return Info();
}
Example #11
0
Info API::CreateTable(SqlCommandCreateTable* command){
  IndexManager index_manager;
  CatalogManager catalog_manager;
  TableInfo table;
  std::string table_name = command->table_name();
  std::string primary_key = command->primary_key();
  std::vector<std::string> unique_keys = command->unique();
  int attribute_count = 0;

  //判断表是否存在
  if(catalog_manager.HasTable(table_name)){
    std::string error_info;
    error_info = "Table \"" + table_name + "\" already exists.";
    return Info(error_info);
  }
  else{
    table.set_table_name(table_name);

    //Check primary key.
    if (primary_key.empty()){
      return Info("Must assign a primary key.");   
    }

    std::map<std::string, std::pair<std::string,int>> attributes = command->attribute();
    for (auto it = attributes.begin(); it != attributes.end(); ++it){
      AttributeInfo single_attribute_info;
      single_attribute_info.set_name(it->first);

      attribute_count++;

      //判断类型是否有效
      if (it->second.first != "char" && it->second.first != "int" && it->second.first != "float"){
        std::string error_info;
        error_info = "The type \"" + it->second.first + "\" of attribute \"" + it->first + "\" is invalid.";
        return Info(error_info);
      }
      else{
        single_attribute_info.set_type(it->second.first);

        //判断char(n) n是否在1~255的范围内
        if (0<it->second.second && it->second.second<256){
          single_attribute_info.set_length(it->second.second);
        }
        else{
          std::string error_info;
          error_info = "The length of char of attribute \"" + it->first + "\" must in range of [1,256].";
          return Info(error_info);
        }
      }

      //判断是否是 primary_key
      if(it->first == primary_key){
        single_attribute_info.set_is_primary_key(true);
        single_attribute_info.add_index("#pri_" + table_name +"_"+it->first);
        index_manager.CreateIndex(it->second.first,it->second.second,IndexInfo("#pri_" + table_name +"_"+it->first,table_name,it->first));
        catalog_manager.RegisterIndex(IndexInfo("#pri_" + table_name +"_"+it->first,table_name,it->first));
      }
      else{
        single_attribute_info.set_is_primary_key(false);
      }

      //判断是否 unique
      if (std::find(unique_keys.begin(), unique_keys.end(), it->first) != unique_keys.end()){
        single_attribute_info.set_is_unique(true);
      }
      else{
        single_attribute_info.set_is_unique(false);
      }

      table.add_attribute(single_attribute_info);
    }
    
    if(!table.HasAttribute(primary_key)){
      std::string error_info;
      error_info = "assigned primary key \"" + primary_key + "\" is not an attribute of the table.";
      return Info(error_info);
    }

    table.set_attribute_number(attribute_count);


    table.set_attribute_names_ordered(command->attribute_names_ordered());
    if(catalog_manager.RegisterTable(table)){
      return Info();
    }
    else{
      return Info("Register table failed.");
    }
  }
}
Example #12
0
Info API::InsertInto(SqlCommandInsertInto* command){
  CatalogManager catalog_manager;
  RecordManager record_manager;
  IndexManager index_manager;
  int offset;
  std::string table_name = command->table_name();
  auto values = command->values();
  if (!catalog_manager.HasTable(table_name)){
    std::string error_info;
    error_info = "Table \"" + table_name + "\" not exists.";
    return Info(error_info);
  }
  TableInfo table = catalog_manager.GetTableInfo(table_name);
  if (table.attribute_names_ordered().size()!=values.size()){
    return Info("Number of values not equals to the number of attributes");
  }

  auto ano = table.attribute_names_ordered();

  //Check string length and overflow
  for (int i = 0; i<values.size(); ++i){
    int type = table.attribute(ano.at(i)).type();
    int length = table.attribute(ano.at(i)).length();
    if (type == 0){
      if (!is_int_overflow_notchecked(values.at(i))){
        std::string error_info;
        error_info = "Value \"" + values.at(i)  + "\" is not a int number.";
        return Info(error_info);
      }

      try{
        int v = std::stoi(values.at(i));
      }
      catch(const std::out_of_range& e){
        std::string error_info;
        error_info = "Value \"" + values.at(i)  + "\" is out of range of int.";
        return Info(error_info);
      }
    }
    if (type == 1){
      if (!is_float_overflow_notchecked(values.at(i))&&!is_int_overflow_notchecked(values.at(i))){
        std::string error_info;
        error_info = "Value \"" + values.at(i)  + "\" is not a float number.";
        return Info(error_info);
      }

      try{
        float v = std::stof(values.at(i));
      }
      catch(const std::out_of_range& e){
        std::string error_info;
        error_info = "Value \"" + values.at(i)  + "\" is out of range of float.";
        return Info(error_info);
      }
    }
    if (type == 2){
      if (values.at(i).length() > length){
        std::string error_info;
        error_info = "Value \"" + values.at(i)  + "\" is out of range of char("+ std::to_string(length) +").";
        return Info(error_info);
      }
    }

  }

  if (!CheckUnqiueAndPrimaryKey(table,values)){
    return Info("Violation of uniqueness");
  }


  offset = record_manager.InsertRecord(table,values);
  if (offset == -1){
    return Info("Insert failed");
  }

  //update index
  std::vector<std::string> index_names = table.index_names();

  for (auto it : index_names){
    IndexInfo index_info = catalog_manager.GetIndexInfo(it);
    if(!index_manager.AddRecord(table,index_info,values.at(table.attribute_index(index_info.attribute_name())),offset)){
      return Info("Update index failed.");
    }
  }

  return Info();
}