Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "SQLExec.h"
- Tables* SQLExec::tables = nullptr;
- Indices* SQLExec::indices = nullptr;
- using namespace std;
- std::ostream &operator<<(std::ostream &out, const QueryResult &qres) {
- if (qres.column_names != nullptr) {
- for (auto const &column_name: *qres.column_names)
- out << column_name << " ";
- out << std::endl << "+";
- for (int i = 0; i < qres.column_names->size(); i++)
- out << "----------+";
- out << std::endl;
- for (auto const &row: *qres.rows) {
- for (auto const &column_name: *qres.column_names) {
- Value value = row->at(column_name);
- switch (value.data_type) {
- case ColumnAttribute::INT:
- out << value.n;
- break;
- case ColumnAttribute::TEXT:
- out << "\"" << value.s << "\"";
- break;
- case ColumnAttribute::BOOLEAN:
- out << (value.n == 0 ? "false" : "true");
- break;
- default:
- out << "???";
- }
- out << " ";
- }
- out << std::endl;
- }
- }
- out << qres.message;
- return out;
- }
- QueryResult::~QueryResult() {
- if (column_names != nullptr)
- delete column_names;
- if (column_attributes != nullptr)
- delete column_attributes;
- if (rows != nullptr) {
- for (auto row: *rows)
- delete row;
- delete rows;
- }
- }
- QueryResult *SQLExec::execute(const hsql::SQLStatement *statement) throw(SQLExecError) {
- // initialize _tables table, if not yet present
- if (SQLExec::tables == nullptr)
- SQLExec::tables = new Tables();
- // initialize _indices table, if not yet present
- if (SQLExec::indices == nullptr)
- SQLExec::indices = new Indices();
- try {
- switch (statement->type()) {
- case hsql::kStmtCreate:
- return create((const hsql::CreateStatement *) statement);
- case hsql::kStmtDrop:
- return drop((const hsql::DropStatement *) statement);
- case hsql::kStmtShow:
- return show((const hsql::ShowStatement *) statement);
- default:
- return new QueryResult("not implemented");
- }
- } catch (DbRelationError& e) {
- throw SQLExecError(std::string("DbRelationError: ") + e.what());
- }
- }
- void SQLExec::column_definition(const hsql::ColumnDefinition *col, Identifier& column_name,
- ColumnAttribute& column_attribute) {
- column_name = col->name;
- switch (col->type) {
- case hsql::ColumnDefinition::INT:
- column_attribute.set_data_type(ColumnAttribute::INT);
- break;
- case hsql::ColumnDefinition::TEXT:
- column_attribute.set_data_type(ColumnAttribute::TEXT);
- break;
- case hsql::ColumnDefinition::DOUBLE:
- default:
- throw SQLExecError("unrecognized data type");
- }
- }
- QueryResult *SQLExec::create(const hsql::CreateStatement *statement) {
- switch(statement->type) {
- case hsql::CreateStatement::kTable:
- return create_table(statement);
- case hsql::CreateStatement::kIndex:
- return create_index(statement);
- default:
- return new QueryResult("Only CREATE TABLE and CREATE INDEX are implemented");
- }
- }
- QueryResult *SQLExec::create_table(const hsql::CreateStatement *statement) {
- Identifier table_name = statement->tableName;
- ColumnNames column_names;
- ColumnAttributes column_attributes;
- Identifier column_name;
- ColumnAttribute column_attribute;
- for (hsql::ColumnDefinition *col : *statement->columns) {
- column_definition(col, column_name, column_attribute);
- column_names.push_back(column_name);
- column_attributes.push_back(column_attribute);
- }
- // Add to schema: _tables and _columns
- ValueDict row;
- row["table_name"] = table_name;
- Handle t_handle = SQLExec::tables->insert(&row); // Insert into _tables
- try {
- Handles c_handles;
- DbRelation& columns = SQLExec::tables->get_table(Columns::TABLE_NAME);
- try {
- for (uint i = 0; i < column_names.size(); i++) {
- row["column_name"] = column_names[i];
- row["data_type"] = Value(column_attributes[i].get_data_type() == ColumnAttribute::INT ? "INT" : "TEXT");
- c_handles.push_back(columns.insert(&row)); // Insert into _columns
- }
- // Finally, actually create the relation
- DbRelation& table = SQLExec::tables->get_table(table_name);
- if (statement->ifNotExists)
- table.create_if_not_exists();
- else
- table.create();
- } catch (std::exception& e) {
- // attempt to remove from _columns
- try {
- for (auto const &handle: c_handles)
- columns.del(handle);
- } catch (...) {}
- throw;
- }
- } catch (std::exception& e) {
- try {
- // attempt to remove from _tables
- SQLExec::tables->del(t_handle);
- } catch (...) {}
- throw;
- }
- return new QueryResult("created " + table_name);
- }
- QueryResult *SQLExec::create_index(const hsql::CreateStatement *statement) {
- Identifier table_name = statement->tableName;
- Identifier index_name = statement->indexName;
- ColumnNames column_names;
- // ColumnAttributes column_attributes;
- Identifier column_name;
- // ColumnAttribute column_attribute;
- for (char *col : *statement->indexColumns) {
- column_names.push_back(col);
- }
- ValueDict row;
- row["table_name"] = table_name;
- row["index_name"] = index_name;
- row["index_type"] = Value(statement->indexType);
- Identifier myIndexType = statement->indexType;
- if(myIndexType == "BTREE")
- {
- row["is_unique"] = Value(true);
- }
- else if(myIndexType == "HASH")
- {
- row["is_unique"] = Value(false);
- } else
- {
- throw SQLExecError("Dan doesnt work");
- }
- int i = 1;
- for(Identifier myName: column_names)
- {
- row["column_name"] = myName;
- row["seq_in_index"] = i;
- i++;
- SQLExec::indices->insert(&row);
- }
- DbIndex& indexTable = SQLExec::indices->get_index(table_name, index_name);
- indexTable.create();
- return new QueryResult("created index " + index_name); // FIXME
- }
- // DROP ...
- QueryResult *SQLExec::drop(const hsql::DropStatement *statement) {
- switch(statement->type) {
- case hsql::DropStatement::kTable:
- return drop_table(statement);
- case hsql::DropStatement::kIndex:
- return drop_index(statement);
- default:
- return new QueryResult("Only DROP TABLE and CREATE INDEX are implemented");
- }
- }
- QueryResult *SQLExec::drop_table(const hsql::DropStatement *statement)
- {
- Identifier table_name = statement->name;
- if (table_name == Tables::TABLE_NAME || table_name == Columns::TABLE_NAME)
- throw SQLExecError("cannot drop a schema table");
- ValueDict where;
- where["table_name"] = Value(table_name);
- DbRelation& table = SQLExec::tables->get_table(table_name);
- IndexNames names = indices->get_index_names(table_name);
- for(Identifier index : names){
- ValueDict who;
- who["table_name"] = Value(table_name);
- who["index_name"] = Value(index);
- DbIndex& ind = SQLExec::indices->get_index(table_name, index);
- ind.drop();
- Handles* handles = indices->select(&who);
- for (auto const& handle: *handles)
- indices->del(handle);
- delete handles;
- }
- DbRelation& columns = SQLExec::tables->get_table(Columns::TABLE_NAME);
- Handles* handles = columns.select(&where);
- for (auto const& handle: *handles)
- columns.del(handle);
- delete handles;
- table.drop();
- SQLExec::tables->del(*SQLExec::tables->select(&where)->begin()); // expect only one row from select
- return new QueryResult(std::string("dropped ") + table_name);
- }
- QueryResult *SQLExec::drop_index(const hsql::DropStatement *statement)
- {
- Identifier table_name = statement->name;
- Identifier index_name = statement->indexName;
- ValueDict chicken;
- chicken["table_name"] = Value(table_name);
- chicken["index_name"] = Value(index_name);
- DbIndex& chickenbutt = SQLExec::indices->get_index(table_name, index_name);
- chickenbutt.drop();
- Handles* handles = indices->select(&chicken);
- for (auto const& handle: *handles)
- indices->del(handle);
- delete handles;
- return new QueryResult("dropped index " + index_name);
- }
- QueryResult *SQLExec::show(const hsql::ShowStatement *statement) {
- switch (statement->type) {
- case hsql::ShowStatement::kTables:
- return show_tables();
- case hsql::ShowStatement::kColumns:
- return show_columns(statement);
- case hsql::ShowStatement::kIndex:
- return show_index(statement);
- default:
- throw SQLExecError("unrecognized SHOW type");
- }
- }
- QueryResult *SQLExec::show_index(const hsql::ShowStatement *statement) {
- ColumnNames* column_names = new ColumnNames;
- ColumnAttributes* column_attributes = new ColumnAttributes;
- // column_names returns table_name, column_name, data_type
- tables->get_columns(Indices::TABLE_NAME, *column_names, *column_attributes);
- ValueDict where;
- where["table_name"] = Value(statement->tableName);
- Handles* handles = indices->select(&where);
- u_long n = handles->size();
- ValueDicts* rows = new ValueDicts;
- for (auto const& handle: *handles) {
- ValueDict* row = indices->project(handle, column_names);
- rows->push_back(row);
- }
- delete handles;
- return new QueryResult(column_names, column_attributes, rows,
- "successfully returned " + std::to_string(n) + " rows");
- }
- QueryResult *SQLExec::show_tables() {
- ColumnNames* column_names = new ColumnNames;
- column_names->push_back("table_name");
- ColumnAttributes* column_attributes = new ColumnAttributes;
- column_attributes->push_back(ColumnAttribute(ColumnAttribute::TEXT));
- Handles* handles = SQLExec::tables->select();
- u_long n = handles->size() - 3;
- ValueDicts* rows = new ValueDicts;
- for (auto const& handle: *handles) {
- ValueDict* row = SQLExec::tables->project(handle, column_names);
- Identifier table_name = row->at("table_name").s;
- if (table_name != Tables::TABLE_NAME && table_name != Columns::TABLE_NAME && table_name != Indices::TABLE_NAME)
- rows->push_back(row);
- }
- delete handles;
- return new QueryResult(column_names, column_attributes, rows,
- "successfully returned " + std::to_string(n) + " rows");
- }
- QueryResult *SQLExec::show_columns(const hsql::ShowStatement *statement) {
- DbRelation& columns = SQLExec::tables->get_table(Columns::TABLE_NAME);
- ColumnNames* column_names = new ColumnNames;
- column_names->push_back("table_name");
- column_names->push_back("column_name");
- column_names->push_back("data_type");
- ColumnAttributes* column_attributes = new ColumnAttributes;
- column_attributes->push_back(ColumnAttribute(ColumnAttribute::TEXT));
- ValueDict where;
- where["table_name"] = Value(statement->tableName);
- Handles* handles = columns.select(&where);
- u_long n = handles->size();
- ValueDicts* rows = new ValueDicts;
- for (auto const& handle: *handles) {
- ValueDict* row = columns.project(handle, column_names);
- rows->push_back(row);
- }
- delete handles;
- return new QueryResult(column_names, column_attributes, rows,
- "successfully returned " + std::to_string(n) + " rows");
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement