parsed_query parser(const std::string& csql_query) { std::string sql_query(csql_query); parsed_query p; p.agg_type = db::aggregate_type::NONE; p.is_join = false; p.logic_op = db::logic_type::NONE; std::stringstream ss(sql_query); std::string token; int number = 0; bool starred = false; while(ss >> token) { if(number == 0) { // select to_lower(token); if(token != "select") { throw "UnimplementedError: Operation " + token + " Unsupported."; } p.query_type = token; } else if(number == 1) { // fields if(token == "*") { starred = true; } else { starred = false; std::stringstream tokenizer(token); std::string field; while(std::getline(tokenizer,field,',')) { sanitize_field(field, p); p.fields.push_back(field); } } } else if(number == 2) { // from to_lower(token); if(token != "from") { throw "QueryError: Malformed Query."; } } else if(number == 3) { // tables std::stringstream tokenizer(token); std::string table; while(std::getline(tokenizer,table,',')) { p.tables.push_back(table); } if(starred == true) { for(auto& table : p.tables) { std::vector<std::string> b = get_table(table).fields(); std::vector<std::string> c; for(auto& var : b) { c.push_back(table + "." + var); } p.fields.reserve(p.fields.size() + b.size()); p.fields.insert(p.fields.end(), c.begin(), c.end()); c.clear(); b.clear(); } } else { for(auto& field : p.fields) { complete_field(field,p); } } if(!p.dis_column.empty()) { complete_field(p.dis_column,p); } if(!p.agg_column.empty()) { complete_field(p.agg_column,p); } if(p.tables.size() > 1) { // if greater than one table, join. p.is_join = true; } } else if(number == 4) { // where to_lower(token); if(token != "where") { throw "QueryError: Malformed Query."; } } else { // condition try { if(std::regex_match(token,std::regex("([a-zA-Z0-9.]+)[=<>]([-+]?[0-9]+)"))) { // not join condition for(auto &c : {"=",">","<"}) { if(token.find_last_of(c) != std::string::npos) { int index = token.find_last_of(c); int value = std::stoi(token.substr(index+1)); std::string field = token.substr(0,index); complete_field(field,p); p.conditionals.push_back(std::make_tuple(field, c, value)); } } } else if (std::regex_match(token,std::regex("([a-zA-Z0-9.]+)[=<>]([a-zA-Z0-9.]+)"))) { // join condition for(auto &c : {"=",">","<"}) { if(token.find_last_of(c) != std::string::npos) { int index = token.find_last_of(c); std::string field2 = token.substr(index+1); std::string field1 = token.substr(0,index); complete_field(field1,p); complete_field(field2,p); p.string_conditionals.push_back(std::make_tuple(field1, c, field2)); } } } else { // logical op to_lower(token); if(token == "or" or token == "||") { p.logic_op = db::logic_type::OR; } else if (token == "and" or token == "&&") { p.logic_op = db::logic_type::AND; } else { throw "QueryError: Malformed Query."; } } } catch(std::regex_error& e) { throw std::string("QueryError: ") + std::string(e.what()); } } number += 1; } return p; }
/** * TODO * * */ GSList * csv_parse_line ( gchar **contents, gchar *separator ) { gchar *tmp; gchar *begin; gint is_unquoted = FALSE; gint len; GSList *list = NULL; len = strlen ( separator ); tmp = (*contents); begin = tmp; if ( *tmp == '\n' ) { *contents = tmp + 1; return GINT_TO_POINTER ( -1 ); } if ( *tmp == '!' || *tmp == '#' || *tmp == ';' ) { *contents = strchr ( tmp, '\n' ) + 1; return GINT_TO_POINTER(-1); } while ( *tmp ) { switch ( *tmp ) { case '\n': list = g_slist_append ( list, sanitize_field ( begin, tmp ) ); *contents = tmp+1; return list; case '"': if ( ! is_unquoted ) { tmp++; while ( *tmp ) { /* This is lame escaping but we need to * support it. */ if ( *tmp == '\\' && *(tmp+1) == '"' ) { tmp += 2; } /* End of quoted string. */ if ( *tmp == '"' && *(tmp+1) != '"' ) { break; } tmp++; } } default: is_unquoted = TRUE; if ( !strncmp ( tmp, separator, len ) ) { list = g_slist_append ( list, sanitize_field ( begin, tmp ) ); begin = tmp + len; is_unquoted = FALSE; } break; } tmp++; } return NULL; }