int is long, select column can be function, some fixes..
just to get it work.. needs improvement
This commit is contained in:
119
usql.cpp
119
usql.cpp
@@ -1,12 +1,18 @@
|
||||
#include "usql.h"
|
||||
#include "exception.h"
|
||||
#include "csvreader.h"
|
||||
#include "ml_date.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
|
||||
namespace usql {
|
||||
|
||||
USql::USql(){
|
||||
m_tables.reserve(16); // some initial size, to prevent immediate reallocation
|
||||
}
|
||||
|
||||
|
||||
std::unique_ptr<Table> USql::execute(const std::string &command) {
|
||||
auto node = m_parser.parse(command);
|
||||
|
||||
@@ -30,6 +36,8 @@ std::unique_ptr<Table> USql::execute(Node &node) {
|
||||
return execute_update(static_cast<UpdateTableNode &>(node));
|
||||
case NodeType::load_table:
|
||||
return execute_load(static_cast<LoadIntoTableNode &>(node));
|
||||
case NodeType::save_table:
|
||||
return execute_save(static_cast<SaveTableNode &>(node));
|
||||
default:
|
||||
return create_stmt_result_table(-1, "unknown statement");
|
||||
}
|
||||
@@ -108,15 +116,26 @@ std::unique_ptr<Table> USql::execute_select(SelectFromTableNode &node) {
|
||||
// create result table
|
||||
std::vector<ColDefNode> result_tbl_col_defs{};
|
||||
std::vector<int> source_table_col_index{};
|
||||
int i = 0; // new column order
|
||||
for (auto rc : node.cols_names) {
|
||||
ColDefNode cdef = table->get_column_def(rc.name);
|
||||
source_table_col_index.push_back(cdef.order);
|
||||
|
||||
auto col = ColDefNode(rc.name, cdef.type, i, cdef.length, cdef.null);
|
||||
result_tbl_col_defs.push_back(col);
|
||||
// new column order
|
||||
for (int i = 0; i < node.cols_names->size(); i++) {
|
||||
auto column = node.cols_names.get();
|
||||
std::string new_col_name = column->operator[](i).name;
|
||||
|
||||
i++;
|
||||
if (column->operator[](i).value->node_type == NodeType::column_name) {
|
||||
ColDefNode cdef = table->get_column_def(new_col_name);
|
||||
|
||||
source_table_col_index.push_back(cdef.order);
|
||||
auto col = ColDefNode(new_col_name, cdef.type, i, cdef.length, cdef.null);
|
||||
result_tbl_col_defs.push_back(col);
|
||||
} else {
|
||||
// TODO replace this hardcoded values
|
||||
ColDefNode cdef = ColDefNode{new_col_name, ColumnType::varchar_type, i, 64, true};
|
||||
|
||||
source_table_col_index.push_back(-1);
|
||||
auto col = ColDefNode(new_col_name, cdef.type, i, cdef.length, cdef.null);
|
||||
result_tbl_col_defs.push_back(col);
|
||||
}
|
||||
}
|
||||
auto result = std::make_unique<Table>("result", result_tbl_col_defs);
|
||||
|
||||
@@ -130,14 +149,30 @@ std::unique_ptr<Table> USql::execute_select(SelectFromTableNode &node) {
|
||||
// copy column values
|
||||
for (auto idx = 0; idx < result->columns_count(); idx++) {
|
||||
auto row_col_index = source_table_col_index[idx];
|
||||
ColValue *col_value = row->ithColumn(row_col_index);
|
||||
if (!col_value->isNull()) {
|
||||
if (result_tbl_col_defs[idx].type == ColumnType::integer_type)
|
||||
new_row.setColumnValue(idx, ((ColIntegerValue *) col_value)->integerValue());
|
||||
if (result_tbl_col_defs[idx].type == ColumnType::float_type)
|
||||
new_row.setColumnValue(idx, col_value->floatValue());
|
||||
if (result_tbl_col_defs[idx].type == ColumnType::varchar_type)
|
||||
new_row.setColumnValue(idx, col_value->stringValue());
|
||||
|
||||
if (row_col_index == -1) {
|
||||
// todo its function TODO col_names zmenit na colValues
|
||||
auto evaluated_value = evalValueNode(table, *row, node.cols_names.get()->operator[](idx).value.get());
|
||||
ValueNode *col_value = evaluated_value.get();
|
||||
if (true /* !col_value->isNull() */) { // TODO sjednotit nasledujici
|
||||
if (result_tbl_col_defs[idx].type == ColumnType::integer_type)
|
||||
new_row.setColumnValue(idx, col_value->getIntValue());
|
||||
if (result_tbl_col_defs[idx].type == ColumnType::float_type)
|
||||
new_row.setColumnValue(idx, col_value->getDoubleValue());
|
||||
if (result_tbl_col_defs[idx].type == ColumnType::varchar_type)
|
||||
new_row.setColumnValue(idx, col_value->getStringValue());
|
||||
}
|
||||
|
||||
} else {
|
||||
ColValue *col_value = row->ithColumn(row_col_index);
|
||||
if (!col_value->isNull()) {
|
||||
if (result_tbl_col_defs[idx].type == ColumnType::integer_type)
|
||||
new_row.setColumnValue(idx, col_value->integerValue());
|
||||
if (result_tbl_col_defs[idx].type == ColumnType::float_type)
|
||||
new_row.setColumnValue(idx, col_value->floatValue());
|
||||
if (result_tbl_col_defs[idx].type == ColumnType::varchar_type)
|
||||
new_row.setColumnValue(idx, col_value->stringValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,7 +269,7 @@ std::unique_ptr<Table> USql::execute_load(LoadIntoTableNode &node) {
|
||||
|
||||
// TODO validate value
|
||||
if (col_def.type == ColumnType::integer_type) {
|
||||
new_row.setColumnValue(col_def.order, std::stoi(csv_line[i]));
|
||||
new_row.setColumnValue(col_def.order, std::stol(csv_line[i]));
|
||||
} else if (col_def.type == ColumnType::float_type) {
|
||||
new_row.setColumnValue(col_def.order, std::stof(csv_line[i]));
|
||||
} else {
|
||||
@@ -250,6 +285,41 @@ std::unique_ptr<Table> USql::execute_load(LoadIntoTableNode &node) {
|
||||
}
|
||||
|
||||
|
||||
std::unique_ptr<Table> USql::execute_save(SaveTableNode &node) {
|
||||
// find source table
|
||||
Table *table_def = find_table(node.table_name);
|
||||
|
||||
// header
|
||||
std::string out_string;
|
||||
for(int i = 0; i < table_def->m_col_defs.size(); i++) {
|
||||
if (i > 0) out_string += ",";
|
||||
out_string += table_def->m_col_defs[i].name;
|
||||
}
|
||||
|
||||
// rows
|
||||
for (auto it = table_def->m_rows.begin() + 1; it != table_def->m_rows.end(); ++it) {
|
||||
std::string csv_line = "";
|
||||
for(int i = 0; i < table_def->m_col_defs.size(); i++) {
|
||||
if (i > 0) csv_line += ",";
|
||||
|
||||
auto col = it->ithColumn(i);
|
||||
if (!col->isNull()) {
|
||||
csv_line += col->stringValue(); // TODO handle enclosing commas etc
|
||||
}
|
||||
}
|
||||
out_string += "\n";
|
||||
out_string += csv_line;
|
||||
}
|
||||
|
||||
// save data
|
||||
std::ofstream file(node.filename);
|
||||
file << out_string;
|
||||
file.close();
|
||||
|
||||
return create_stmt_result_table(0, "save succeeded");
|
||||
}
|
||||
|
||||
|
||||
bool USql::evalWhere(Node *where, Table *table, Row &row) const {
|
||||
switch (where->node_type) { // no where clause
|
||||
case NodeType::true_node:
|
||||
@@ -304,7 +374,7 @@ bool USql::evalRelationalOperator(const RelationalOperatorNode &filter, Table *t
|
||||
|
||||
|
||||
std::unique_ptr<ValueNode> USql::evalValueNode(Table *table, Row &row, Node *node) const {
|
||||
if (node->node_type == NodeType::database_value) {
|
||||
if (node->node_type == NodeType::database_value || node->node_type == NodeType::column_name) { // TODO sjednotit
|
||||
return evalDatabaseValueNode(table, row, node);
|
||||
|
||||
} else if (node->node_type == NodeType::int_value || node->node_type == NodeType::float_value || node->node_type == NodeType::string_value) {
|
||||
@@ -374,6 +444,19 @@ std::unique_ptr<ValueNode> USql::evalFunctionValueNode(Table *table, Row &row, N
|
||||
return std::make_unique<StringValueNode>(str);
|
||||
}
|
||||
|
||||
if (fnc->function == "to_date") {
|
||||
std::string date = evaluatedPars[0]->getStringValue();
|
||||
std::string format = evaluatedPars[1]->getStringValue();
|
||||
long epoch_time = string_to_date(date, format);
|
||||
return std::make_unique<IntValueNode>(epoch_time);
|
||||
}
|
||||
if (fnc->function == "to_string") {
|
||||
long date = evaluatedPars[0]->getIntValue();
|
||||
std::string format = evaluatedPars[1]->getStringValue();
|
||||
std::string formated_date = date_to_string(date, format);
|
||||
return std::make_unique<StringValueNode>(formated_date);
|
||||
}
|
||||
|
||||
throw Exception("invalid function");
|
||||
}
|
||||
|
||||
@@ -444,7 +527,7 @@ std::unique_ptr<ValueNode> USql::evalArithmeticOperator(ColumnType outType, Arit
|
||||
}
|
||||
|
||||
|
||||
std::unique_ptr<Table> USql::create_stmt_result_table(int code, std::string text) {
|
||||
std::unique_ptr<Table> USql::create_stmt_result_table(long code, std::string text) {
|
||||
std::vector<ColDefNode> result_tbl_col_defs{};
|
||||
result_tbl_col_defs.push_back(ColDefNode("code", ColumnType::integer_type, 0, 1, false));
|
||||
result_tbl_col_defs.push_back(ColDefNode("desc", ColumnType::varchar_type, 1, 255, false));
|
||||
|
||||
Reference in New Issue
Block a user