usql/table.cpp

122 lines
3.2 KiB
C++

#include "table.h"
namespace usql {
Table::Table(const std::string name, const std::vector<ColDefNode> columns) {
m_name = name;
m_col_defs = columns;
m_rows.clear();
}
ColDefNode Table::get_column_def(const std::string &col_name) {
auto name_cmp = [col_name](ColDefNode cd) { return cd.name == col_name; };
auto col_def = std::find_if(begin(m_col_defs), end(m_col_defs), name_cmp);
if (col_def != std::end(m_col_defs)) {
return *col_def;
} else {
throw Exception("column not exists (" + col_name + ")");
}
}
Row Table::create_empty_row() {
return Row(columns_count());
}
std::string Table::csv_string() {
// header
std::string out_string;
for(int i = 0; i < m_col_defs.size(); i++) {
if (i > 0) out_string += ",";
out_string += m_col_defs[i].name;
}
// rows
for (auto it = m_rows.begin(); it != m_rows.end(); ++it) {
std::string csv_line{"\n"};
for(int i = 0; i < m_col_defs.size(); i++) {
if (i > 0) csv_line += ",";
auto col = it->ith_column(i);
if (!col->isNull()) {
csv_line += col->getStringValue(); // TODO handle enclosing commas etc
}
}
out_string += csv_line;
}
return out_string;
}
void Table::print() {
std::cout << "** " << m_name << " **" << std::endl;
for (auto row : m_rows) {
row.print();
}
}
Table::Table(const Table &other) {
m_name = other.m_name;
m_col_defs = other.m_col_defs;
for(const Row& orig_row : other.m_rows) {
add_copy_of_row(orig_row);
}
}
void Table::add_row(const Row &row) {
validate_row(row);
m_rows.push_back(row);
}
void Table::add_copy_of_row(const Row &row) {
Row new_row = create_empty_row();
for(int i = 0; i < m_col_defs.size(); i++) {
ColValue *ct = row.ith_column(i);
if (ct->isNull()) {
new_row.setColumnNull(i);
} else {
if (m_col_defs[i].type == ColumnType::integer_type) {
new_row.setColumnValue(i, row.ith_column(i)->getIntValue());
} else if (m_col_defs[i].type == ColumnType::float_type) {
new_row.setColumnValue(i, row.ith_column(i)->getDoubleValue());
} else if (m_col_defs[i].type == ColumnType::varchar_type) {
new_row.setColumnValue(i, row.ith_column(i)->getStringValue());
}
}
}
validate_row(new_row);
m_rows.push_back(new_row);
}
void Table::validate_column(const ColDefNode *col_def, ValueNode *col_val) {
if (col_def->null == false && col_val->isNull()) {
throw Exception("Column " + col_def->name + " cannot be null");
}
if (col_def->type == ColumnType::varchar_type && !col_val->isNull() && col_val->getStringValue().size() > col_def->length) {
throw Exception("Column value of " + col_def->name + " is too long (" + col_val->getStringValue() + ")");
}
}
void Table::validate_column(const ColDefNode *col_def, ColValue *col_val) {
if (col_def->null == false && col_val->isNull()) {
throw Exception("Column " + col_def->name + " cannot be null");
}
if (col_def->type == ColumnType::varchar_type && !col_val->isNull() && col_val->getStringValue().size() > col_def->length) {
throw Exception("Column value of " + col_def->name + " is too long (" + col_val->getStringValue() + ")");
}
}
void Table::validate_row(const Row &row) {
for(int i = 0; i < m_col_defs.size(); i++) {
ColDefNode col_def = m_col_defs[i];
ColValue *col_val = row.ith_column(i);
validate_column(&col_def, col_val);
}
}
} // namespace