date and boolean data types added
This commit is contained in:
73
table.cpp
73
table.cpp
@@ -6,10 +6,10 @@
|
||||
|
||||
namespace usql {
|
||||
|
||||
Table::Table(const std::string name, const std::vector<ColDefNode> columns) {
|
||||
Table::Table(const std::string& name, const std::vector<ColDefNode>& columns) {
|
||||
m_name = name;
|
||||
m_col_defs = columns;
|
||||
m_rows.reserve(16);
|
||||
m_rows.reserve(256);
|
||||
}
|
||||
|
||||
Table::Table(const Table &other) {
|
||||
@@ -22,7 +22,7 @@ Table::Table(const Table &other) {
|
||||
}
|
||||
|
||||
ColDefNode Table::get_column_def(const std::string &col_name) {
|
||||
auto name_cmp = [col_name](ColDefNode cd) { return cd.name == col_name; };
|
||||
auto name_cmp = [col_name](const 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;
|
||||
@@ -39,8 +39,8 @@ ColDefNode Table::get_column_def(int col_index) {
|
||||
}
|
||||
}
|
||||
|
||||
Row Table::create_empty_row() {
|
||||
return Row(columns_count());
|
||||
Row Table::create_empty_row() const {
|
||||
return {columns_count()};
|
||||
}
|
||||
|
||||
std::string Table::csv_string() {
|
||||
@@ -52,12 +52,12 @@ std::string Table::csv_string() {
|
||||
}
|
||||
|
||||
// rows
|
||||
for (auto it = m_rows.begin(); it != m_rows.end(); ++it) {
|
||||
for (auto & m_row : m_rows) {
|
||||
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);
|
||||
auto col = m_row.ith_column(i);
|
||||
if (!col->isNull()) {
|
||||
csv_line += col->getStringValue(); // TODO handle enclosing commas etc
|
||||
}
|
||||
@@ -86,14 +86,20 @@ int Table::load_csv_string(const std::string &content) {
|
||||
for (size_t i = 0; i < columns_count(); i++) {
|
||||
ColDefNode col_def = get_column_def(colDefs[i].name);
|
||||
|
||||
// TODO validate value
|
||||
if (col_def.type == ColumnType::integer_type) {
|
||||
new_row.setColumnValue(col_def.order, std::stol(csv_line[i]));
|
||||
if (csv_line[i].empty()) {
|
||||
new_row.setColumnNull(col_def.order);
|
||||
} else if (col_def.type == ColumnType::integer_type) {
|
||||
new_row.setIntColumnValue(col_def.order, string_to_long(csv_line[i]));
|
||||
} else if (col_def.type == ColumnType::float_type) {
|
||||
new_row.setColumnValue(col_def.order, std::stof(csv_line[i]));
|
||||
} else {
|
||||
new_row.setColumnValue(col_def.order, csv_line[i]);
|
||||
}
|
||||
new_row.setFloatColumnValue(col_def.order, string_to_double(csv_line[i]));
|
||||
} else if (col_def.type == ColumnType::varchar_type) {
|
||||
new_row.setStringColumnValue(col_def.order, csv_line[i]);
|
||||
} else if (col_def.type == ColumnType::date_type) {
|
||||
new_row.setDateColumnValue(col_def.order, csv_line[i]);
|
||||
} else if (col_def.type == ColumnType::bool_type) {
|
||||
new_row.setBoolColumnValue(col_def.order, csv_line[i]);
|
||||
} else
|
||||
throw Exception("unsupported column type");
|
||||
}
|
||||
|
||||
// append new_row
|
||||
@@ -105,12 +111,28 @@ int Table::load_csv_string(const std::string &content) {
|
||||
return row_cnt;
|
||||
}
|
||||
|
||||
double Table::string_to_double(const std::string &s) {
|
||||
try {
|
||||
return std::stod(s);
|
||||
} catch (std::invalid_argument &e) {
|
||||
throw Exception("error parsing as double: " + s);
|
||||
}
|
||||
}
|
||||
|
||||
long Table::string_to_long(const std::string &s) {
|
||||
try {
|
||||
return std::stol(s);
|
||||
} catch (std::invalid_argument &e) {
|
||||
throw Exception("error parsing as integer: " + s);
|
||||
}
|
||||
}
|
||||
|
||||
void Table::print() {
|
||||
std::string out{"| "};
|
||||
std::string out2{"+-"};
|
||||
std::vector<int> col_char_sizes{};
|
||||
|
||||
for(auto col_def : m_col_defs) {
|
||||
for(const auto& col_def : m_col_defs) {
|
||||
int col_size = col_def.type == ColumnType::varchar_type ? col_def.length : 10;
|
||||
col_char_sizes.push_back(col_size);
|
||||
|
||||
@@ -129,6 +151,10 @@ void Table::print() {
|
||||
}
|
||||
|
||||
void Table::add_row(const Row &row) {
|
||||
// PERF, here it is performance botleneck, because
|
||||
// m_rows.push_back(row) calls Row::Row(const Row &other) constructor
|
||||
// it would be much more performant to add row directly to m_rows in create_new_row
|
||||
// and here in case of failed validation only remove it
|
||||
validate_row(row);
|
||||
m_rows.push_back(row);
|
||||
}
|
||||
@@ -143,12 +169,17 @@ void Table::add_copy_of_row(const Row &row) {
|
||||
new_row.setColumnNull(i);
|
||||
} else {
|
||||
if (m_col_defs[i].type == ColumnType::integer_type) {
|
||||
new_row.setColumnValue(i, row.ith_column(i)->getIntValue());
|
||||
new_row.setIntColumnValue(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());
|
||||
new_row.setFloatColumnValue(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());
|
||||
}
|
||||
new_row.setStringColumnValue(i, row.ith_column(i)->getStringValue());
|
||||
} else if (m_col_defs[i].type == ColumnType::date_type) {
|
||||
new_row.setDateColumnValue(i, row.ith_column(i)->getDateValue());
|
||||
} else if (m_col_defs[i].type == ColumnType::bool_type) {
|
||||
new_row.setBoolColumnValue(i, row.ith_column(i)->getBoolValue());
|
||||
} else
|
||||
throw Exception("unsupported column type");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,7 +188,7 @@ void Table::add_copy_of_row(const Row &row) {
|
||||
}
|
||||
|
||||
void Table::validate_column(const ColDefNode *col_def, ValueNode *col_val) {
|
||||
if (col_def->null == false && col_val->isNull()) {
|
||||
if (!col_def->null && 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) {
|
||||
@@ -166,7 +197,7 @@ void Table::validate_column(const ColDefNode *col_def, ValueNode *col_val) {
|
||||
}
|
||||
|
||||
void Table::validate_column(const ColDefNode *col_def, ColValue *col_val) {
|
||||
if (col_def->null == false && col_val->isNull()) {
|
||||
if (!col_def->null && 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) {
|
||||
|
||||
Reference in New Issue
Block a user