#ifndef QUERY_DIALECT_HPP #define QUERY_DIALECT_HPP #include "matador/sql/column.hpp" #include "matador/sql/dialect_token.hpp" #include "matador/utils/basic_types.hpp" #include "matador/utils/types.hpp" #include "matador/utils/string.hpp" #include #include #include #include namespace matador::utils { class value; } namespace matador::sql { class connection_impl; class dialect final { public: /** * Holding enums concerning escaping identifiers */ enum class escape_identifier_t : uint8_t { ESCAPE_BOTH_SAME, /**< The escape quotes are the same */ ESCAPE_CLOSING_BRACKET /**< The escape quotes differ; escape the closing one */ }; using token_to_string_map = std::unordered_map; using data_type_to_string_map = std::unordered_map; using sql_func_to_string_map = std::unordered_map; using next_placeholder_func = std::function; using to_escaped_string_func = std::function; public: [[nodiscard]] const std::string& token_at(dialect_token token) const; [[nodiscard]] const std::string& data_type_at(utils::basic_type type) const; /** * Prepare sql dialect identifier for execution * and escape quotes and quote the identifier * string * * @param col The identifier string to be prepared * @return The prepared string */ [[nodiscard]] std::string prepare_identifier(const column &col) const; [[nodiscard]] std::string prepare_identifier_string(const std::string &col) const; [[nodiscard]] std::string prepare_condition(const column &col) const; [[nodiscard]] const std::string& to_string(bool val) const; [[nodiscard]] std::string to_sql_string(const utils::value &val) const ; void bool_strings(const std::string &true_string, const std::string &false_string); /** * Prepare string literal * * @param str String literal to be prepared */ [[nodiscard]] std::string prepare_literal(const std::string &str) const; /** * Wrap identifier quotes around a sql identifier keyword * * @param str Identifier to put quotes around */ void quote_identifier(std::string &str) const; /** * Escape identifier quotes inside identifiers. * * @param str Identifier to be escaped */ void escape_quotes_in_identifier(std::string &str) const; /** * Escape quotes in string literals * * @param str String literal to be escaped */ void escape_quotes_in_literals(std::string &str) const; /** * Returns how the identifier quotes should be * escaped. * * @return How the identifier quotes should be escaped */ [[nodiscard]] escape_identifier_t identifier_escape_type() const; /** * Sets the identifier escape type. Possibilities are * opening and closing escape characters are the same * (ESCAPE_BOTH_SAME) or using a special closing * escape character (ESCAPE_CLOSING_BRACKET) * * @param escape_identifier Identifier escape type */ void identifier_escape_type(escape_identifier_t escape_identifier); /** * Generates a next placeholder string. default is * question mark '?' * * @return Placeholder string */ [[nodiscard]] std::string next_placeholder(const std::vector &bind_vars) const; [[nodiscard]] std::string to_escaped_string(const utils::blob &value, const connection_impl *conn = nullptr) const; /** * Returns the default schema name. * * @return The default schema name. */ [[nodiscard]] std::string default_schema_name() const; private: dialect() = default; private: friend class dialect_builder; next_placeholder_func placeholder_func_ = [](size_t) { return "?"; }; to_escaped_string_func to_escaped_string_func_ = [](const utils::blob &val) { return utils::to_string(val); }; escape_identifier_t identifier_escape_type_ = escape_identifier_t::ESCAPE_BOTH_SAME; std::string default_schema_name_; // std::unique_ptr compiler_; token_to_string_map tokens_ { {dialect_token::Create, "CREATE"}, {dialect_token::Drop, "DROP"}, {dialect_token::Remove, "DELETE"}, {dialect_token::Insert, "INSERT"}, {dialect_token::Table, "TABLE"}, {dialect_token::Into, "INTO"}, {dialect_token::Values, "VALUES"}, {dialect_token::Update, "UPDATE"}, {dialect_token::Select, "SELECT"}, {dialect_token::Columns, "COLUMNS"}, {dialect_token::Column, "COLUMN"}, {dialect_token::From, "FROM"}, {dialect_token::Join, "LEFT JOIN"}, {dialect_token::On, "ON"}, {dialect_token::Where, "WHERE"}, {dialect_token::And, "AND"}, {dialect_token::Or, "OR"}, {dialect_token::Not, "NOT"}, {dialect_token::Like, "LIKE"}, {dialect_token::Between, "BETWEEN"}, {dialect_token::In, "IN"}, {dialect_token::OrderBy, "ORDER BY"}, {dialect_token::GroupBy, "GROUP BY"}, {dialect_token::Asc, "ASC"}, {dialect_token::Desc, "DESC"}, {dialect_token::Offset, "OFFSET"}, {dialect_token::Limit, "LIMIT"}, {dialect_token::As, "AS"}, {dialect_token::Offset, "OFFSET"}, {dialect_token::Distinct, "DISTINCT"}, {dialect_token::Set, "SET"}, {dialect_token::NotNull, "NOT NULL"}, {dialect_token::PrimaryKey, "PRIMARY KEY"}, {dialect_token::Begin, "BEGIN TRANSACTION"}, {dialect_token::Commit, "COMMIT TRANSACTION"}, {dialect_token::Rollback, "ROLLBACK TRANSACTION"}, {dialect_token::StartQuote, "\""}, {dialect_token::EndQuote, "\""}, {dialect_token::StringQuote, "'"}, {dialect_token::BeginBinaryData, "X'"}, {dialect_token::EndBinaryData, "'"}, {dialect_token::BeginStringData, "'"}, {dialect_token::EndStringData, "'"}, {dialect_token::None, ""} }; data_type_to_string_map data_types_ { {utils::basic_type::type_int8, "TINYINT"}, {utils::basic_type::type_int16, "SMALLINT"}, {utils::basic_type::type_int32, "INTEGER"}, {utils::basic_type::type_int64, "BIGINT"}, {utils::basic_type::type_uint8, "TINYINT"}, {utils::basic_type::type_uint16, "INTEGER"}, {utils::basic_type::type_uint32, "BIGINT"}, {utils::basic_type::type_uint64, "BIGINT"}, {utils::basic_type::type_float, "FLOAT"}, {utils::basic_type::type_double, "DOUBLE"}, {utils::basic_type::type_bool, "BOOLEAN"}, {utils::basic_type::type_varchar, "VARCHAR"}, {utils::basic_type::type_text, "TEXT"}, {utils::basic_type::type_date, "DATE"}, {utils::basic_type::type_time, "DATETIME"}, {utils::basic_type::type_blob, "BLOB"}, {utils::basic_type::type_null, "NULL"} }; sql_func_to_string_map sql_func_map_ { {sql_function_t::NONE, "NONE" }, {sql_function_t::COUNT, "COUNT" }, {sql_function_t::AVG, "AVG" }, {sql_function_t::SUM, "SUM" }, {sql_function_t::MIN, "MIN" }, {sql_function_t::MAX, "MAX" }, }; std::array bool_strings_ { "0", "1" }; }; } #endif //QUERY_DIALECT_HPP