Advertisement
Guest User

Untitled

a guest
Apr 23rd, 2017
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.02 KB | None | 0 0
  1.  
  2. #include "SQLExec.h"
  3.  
  4. Tables* SQLExec::tables = nullptr;
  5. Indices* SQLExec::indices = nullptr;
  6. using namespace std;
  7.  
  8. std::ostream &operator<<(std::ostream &out, const QueryResult &qres) {
  9. if (qres.column_names != nullptr) {
  10. for (auto const &column_name: *qres.column_names)
  11. out << column_name << " ";
  12. out << std::endl << "+";
  13. for (int i = 0; i < qres.column_names->size(); i++)
  14. out << "----------+";
  15. out << std::endl;
  16. for (auto const &row: *qres.rows) {
  17. for (auto const &column_name: *qres.column_names) {
  18. Value value = row->at(column_name);
  19. switch (value.data_type) {
  20. case ColumnAttribute::INT:
  21. out << value.n;
  22. break;
  23. case ColumnAttribute::TEXT:
  24. out << "\"" << value.s << "\"";
  25. break;
  26. case ColumnAttribute::BOOLEAN:
  27. out << (value.n == 0 ? "false" : "true");
  28. break;
  29. default:
  30. out << "???";
  31. }
  32. out << " ";
  33. }
  34. out << std::endl;
  35. }
  36. }
  37. out << qres.message;
  38. return out;
  39. }
  40.  
  41. QueryResult::~QueryResult() {
  42. if (column_names != nullptr)
  43. delete column_names;
  44. if (column_attributes != nullptr)
  45. delete column_attributes;
  46. if (rows != nullptr) {
  47. for (auto row: *rows)
  48. delete row;
  49. delete rows;
  50. }
  51. }
  52.  
  53.  
  54. QueryResult *SQLExec::execute(const hsql::SQLStatement *statement) throw(SQLExecError) {
  55. // initialize _tables table, if not yet present
  56. if (SQLExec::tables == nullptr)
  57. SQLExec::tables = new Tables();
  58.  
  59. // initialize _indices table, if not yet present
  60. if (SQLExec::indices == nullptr)
  61. SQLExec::indices = new Indices();
  62.  
  63. try {
  64. switch (statement->type()) {
  65. case hsql::kStmtCreate:
  66. return create((const hsql::CreateStatement *) statement);
  67. case hsql::kStmtDrop:
  68. return drop((const hsql::DropStatement *) statement);
  69. case hsql::kStmtShow:
  70. return show((const hsql::ShowStatement *) statement);
  71. default:
  72. return new QueryResult("not implemented");
  73. }
  74. } catch (DbRelationError& e) {
  75. throw SQLExecError(std::string("DbRelationError: ") + e.what());
  76. }
  77. }
  78.  
  79. void SQLExec::column_definition(const hsql::ColumnDefinition *col, Identifier& column_name,
  80. ColumnAttribute& column_attribute) {
  81. column_name = col->name;
  82. switch (col->type) {
  83. case hsql::ColumnDefinition::INT:
  84. column_attribute.set_data_type(ColumnAttribute::INT);
  85. break;
  86. case hsql::ColumnDefinition::TEXT:
  87. column_attribute.set_data_type(ColumnAttribute::TEXT);
  88. break;
  89. case hsql::ColumnDefinition::DOUBLE:
  90. default:
  91. throw SQLExecError("unrecognized data type");
  92. }
  93. }
  94.  
  95. QueryResult *SQLExec::create(const hsql::CreateStatement *statement) {
  96. switch(statement->type) {
  97. case hsql::CreateStatement::kTable:
  98. return create_table(statement);
  99. case hsql::CreateStatement::kIndex:
  100. return create_index(statement);
  101. default:
  102. return new QueryResult("Only CREATE TABLE and CREATE INDEX are implemented");
  103. }
  104. }
  105.  
  106. QueryResult *SQLExec::create_table(const hsql::CreateStatement *statement) {
  107. Identifier table_name = statement->tableName;
  108. ColumnNames column_names;
  109. ColumnAttributes column_attributes;
  110. Identifier column_name;
  111. ColumnAttribute column_attribute;
  112. for (hsql::ColumnDefinition *col : *statement->columns) {
  113. column_definition(col, column_name, column_attribute);
  114. column_names.push_back(column_name);
  115. column_attributes.push_back(column_attribute);
  116. }
  117.  
  118. // Add to schema: _tables and _columns
  119. ValueDict row;
  120. row["table_name"] = table_name;
  121. Handle t_handle = SQLExec::tables->insert(&row); // Insert into _tables
  122. try {
  123. Handles c_handles;
  124. DbRelation& columns = SQLExec::tables->get_table(Columns::TABLE_NAME);
  125. try {
  126. for (uint i = 0; i < column_names.size(); i++) {
  127. row["column_name"] = column_names[i];
  128. row["data_type"] = Value(column_attributes[i].get_data_type() == ColumnAttribute::INT ? "INT" : "TEXT");
  129. c_handles.push_back(columns.insert(&row)); // Insert into _columns
  130. }
  131.  
  132. // Finally, actually create the relation
  133. DbRelation& table = SQLExec::tables->get_table(table_name);
  134. if (statement->ifNotExists)
  135. table.create_if_not_exists();
  136. else
  137. table.create();
  138.  
  139. } catch (std::exception& e) {
  140. // attempt to remove from _columns
  141. try {
  142. for (auto const &handle: c_handles)
  143. columns.del(handle);
  144. } catch (...) {}
  145. throw;
  146. }
  147.  
  148. } catch (std::exception& e) {
  149. try {
  150. // attempt to remove from _tables
  151. SQLExec::tables->del(t_handle);
  152. } catch (...) {}
  153. throw;
  154. }
  155. return new QueryResult("created " + table_name);
  156. }
  157.  
  158. QueryResult *SQLExec::create_index(const hsql::CreateStatement *statement) {
  159. Identifier table_name = statement->tableName;
  160. Identifier index_name = statement->indexName;
  161. ColumnNames column_names;
  162. // ColumnAttributes column_attributes;
  163. Identifier column_name;
  164. // ColumnAttribute column_attribute;
  165. for (char *col : *statement->indexColumns) {
  166. column_names.push_back(col);
  167. }
  168.  
  169. ValueDict row;
  170. row["table_name"] = table_name;
  171. row["index_name"] = index_name;
  172. row["index_type"] = Value(statement->indexType);
  173. Identifier myIndexType = statement->indexType;
  174. if(myIndexType == "BTREE")
  175. {
  176. row["is_unique"] = Value(true);
  177. }
  178. else if(myIndexType == "HASH")
  179. {
  180. row["is_unique"] = Value(false);
  181. } else
  182. {
  183. throw SQLExecError("Dan doesnt work");
  184. }
  185.  
  186. int i = 1;
  187. for(Identifier myName: column_names)
  188. {
  189. row["column_name"] = myName;
  190. row["seq_in_index"] = i;
  191. i++;
  192. SQLExec::indices->insert(&row);
  193. }
  194.  
  195. DbIndex& indexTable = SQLExec::indices->get_index(table_name, index_name);
  196. indexTable.create();
  197.  
  198. return new QueryResult("created index " + index_name); // FIXME
  199. }
  200.  
  201. // DROP ...
  202. QueryResult *SQLExec::drop(const hsql::DropStatement *statement) {
  203. switch(statement->type) {
  204. case hsql::DropStatement::kTable:
  205. return drop_table(statement);
  206. case hsql::DropStatement::kIndex:
  207. return drop_index(statement);
  208. default:
  209. return new QueryResult("Only DROP TABLE and CREATE INDEX are implemented");
  210. }
  211. }
  212.  
  213. QueryResult *SQLExec::drop_table(const hsql::DropStatement *statement)
  214. {
  215. Identifier table_name = statement->name;
  216. if (table_name == Tables::TABLE_NAME || table_name == Columns::TABLE_NAME)
  217. throw SQLExecError("cannot drop a schema table");
  218. ValueDict where;
  219. where["table_name"] = Value(table_name);
  220. DbRelation& table = SQLExec::tables->get_table(table_name);
  221. IndexNames names = indices->get_index_names(table_name);
  222. for(Identifier index : names){
  223. ValueDict who;
  224. who["table_name"] = Value(table_name);
  225. who["index_name"] = Value(index);
  226. DbIndex& ind = SQLExec::indices->get_index(table_name, index);
  227. ind.drop();
  228. Handles* handles = indices->select(&who);
  229. for (auto const& handle: *handles)
  230. indices->del(handle);
  231. delete handles;
  232. }
  233. DbRelation& columns = SQLExec::tables->get_table(Columns::TABLE_NAME);
  234. Handles* handles = columns.select(&where);
  235. for (auto const& handle: *handles)
  236. columns.del(handle);
  237. delete handles;
  238. table.drop();
  239. SQLExec::tables->del(*SQLExec::tables->select(&where)->begin()); // expect only one row from select
  240. return new QueryResult(std::string("dropped ") + table_name);
  241.  
  242. }
  243.  
  244. QueryResult *SQLExec::drop_index(const hsql::DropStatement *statement)
  245. {
  246. Identifier table_name = statement->name;
  247. Identifier index_name = statement->indexName;
  248. ValueDict chicken;
  249. chicken["table_name"] = Value(table_name);
  250. chicken["index_name"] = Value(index_name);
  251. DbIndex& chickenbutt = SQLExec::indices->get_index(table_name, index_name);
  252. chickenbutt.drop();
  253. Handles* handles = indices->select(&chicken);
  254. for (auto const& handle: *handles)
  255. indices->del(handle);
  256. delete handles;
  257. return new QueryResult("dropped index " + index_name);
  258. }
  259.  
  260.  
  261.  
  262. QueryResult *SQLExec::show(const hsql::ShowStatement *statement) {
  263. switch (statement->type) {
  264. case hsql::ShowStatement::kTables:
  265. return show_tables();
  266. case hsql::ShowStatement::kColumns:
  267. return show_columns(statement);
  268. case hsql::ShowStatement::kIndex:
  269. return show_index(statement);
  270. default:
  271. throw SQLExecError("unrecognized SHOW type");
  272. }
  273. }
  274.  
  275. QueryResult *SQLExec::show_index(const hsql::ShowStatement *statement) {
  276. ColumnNames* column_names = new ColumnNames;
  277. ColumnAttributes* column_attributes = new ColumnAttributes;
  278.  
  279. // column_names returns table_name, column_name, data_type
  280. tables->get_columns(Indices::TABLE_NAME, *column_names, *column_attributes);
  281.  
  282. ValueDict where;
  283. where["table_name"] = Value(statement->tableName);
  284. Handles* handles = indices->select(&where);
  285. u_long n = handles->size();
  286.  
  287. ValueDicts* rows = new ValueDicts;
  288. for (auto const& handle: *handles) {
  289. ValueDict* row = indices->project(handle, column_names);
  290. rows->push_back(row);
  291. }
  292. delete handles;
  293. return new QueryResult(column_names, column_attributes, rows,
  294. "successfully returned " + std::to_string(n) + " rows");
  295. }
  296.  
  297. QueryResult *SQLExec::show_tables() {
  298. ColumnNames* column_names = new ColumnNames;
  299. column_names->push_back("table_name");
  300.  
  301. ColumnAttributes* column_attributes = new ColumnAttributes;
  302. column_attributes->push_back(ColumnAttribute(ColumnAttribute::TEXT));
  303.  
  304. Handles* handles = SQLExec::tables->select();
  305. u_long n = handles->size() - 3;
  306.  
  307. ValueDicts* rows = new ValueDicts;
  308. for (auto const& handle: *handles) {
  309. ValueDict* row = SQLExec::tables->project(handle, column_names);
  310. Identifier table_name = row->at("table_name").s;
  311. if (table_name != Tables::TABLE_NAME && table_name != Columns::TABLE_NAME && table_name != Indices::TABLE_NAME)
  312. rows->push_back(row);
  313. }
  314. delete handles;
  315. return new QueryResult(column_names, column_attributes, rows,
  316. "successfully returned " + std::to_string(n) + " rows");
  317. }
  318.  
  319. QueryResult *SQLExec::show_columns(const hsql::ShowStatement *statement) {
  320. DbRelation& columns = SQLExec::tables->get_table(Columns::TABLE_NAME);
  321.  
  322. ColumnNames* column_names = new ColumnNames;
  323. column_names->push_back("table_name");
  324. column_names->push_back("column_name");
  325. column_names->push_back("data_type");
  326.  
  327. ColumnAttributes* column_attributes = new ColumnAttributes;
  328. column_attributes->push_back(ColumnAttribute(ColumnAttribute::TEXT));
  329.  
  330. ValueDict where;
  331. where["table_name"] = Value(statement->tableName);
  332. Handles* handles = columns.select(&where);
  333. u_long n = handles->size();
  334.  
  335. ValueDicts* rows = new ValueDicts;
  336. for (auto const& handle: *handles) {
  337. ValueDict* row = columns.project(handle, column_names);
  338. rows->push_back(row);
  339. }
  340. delete handles;
  341. return new QueryResult(column_names, column_attributes, rows,
  342. "successfully returned " + std::to_string(n) + " rows");
  343. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement