230 lines
7.3 KiB
C++
230 lines
7.3 KiB
C++
#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 <functional>
|
|
#include <string>
|
|
#include <unordered_map>
|
|
#include <vector>
|
|
|
|
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<dialect_token, std::string>;
|
|
using data_type_to_string_map = std::unordered_map<utils::basic_type, std::string>;
|
|
using sql_func_to_string_map = std::unordered_map<sql_function_t, std::string>;
|
|
|
|
using next_placeholder_func = std::function<std::string(size_t)>;
|
|
using to_escaped_string_func = std::function<std::string(const utils::blob &)>;
|
|
|
|
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<std::string> &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<query_compiler> compiler_;
|
|
|
|
token_to_string_map tokens_ {
|
|
{dialect_token::Create, "CREATE"},
|
|
{dialect_token::Drop, "DROP"},
|
|
{dialect_token::Remove, "DELETE"},
|
|
{dialect_token::Insert, "INSERT"},
|
|
{dialect_token::Alter, "ALTER"},
|
|
{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::ForeignKey, "FOREIGN KEY"},
|
|
{dialect_token::References, "REFERENCES"},
|
|
{dialect_token::AddConstraint, "ADD CONSTRAINT"},
|
|
{dialect_token::DropConstraint, "DROP CONSTRAINT"},
|
|
{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<std::string, 2> bool_strings_ {
|
|
"0", "1"
|
|
};
|
|
};
|
|
|
|
}
|
|
|
|
#endif //QUERY_DIALECT_HPP
|