added alter table command to fluent query builder
This commit is contained in:
parent
c87a4c29b4
commit
4b51ad21da
|
|
@ -79,10 +79,11 @@ int main() {
|
|||
object::repository repo("Administration");
|
||||
|
||||
auto result = repo.attach<admin::CollectionCenter>("collection_centers");
|
||||
repo.create(pool);
|
||||
repo.drop(pool);
|
||||
// repo.create(pool);
|
||||
// repo.drop(pool);
|
||||
|
||||
orm::session ses(pool);
|
||||
utils::message_bus bus;
|
||||
orm::session ses({bus, pool});
|
||||
|
||||
result = ses.attach<admin::CollectionCenter>("collection_centers")
|
||||
.and_then([&ses] { return ses.attach<admin::UserDirectory>("user_directories"); })
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ public:
|
|||
[[nodiscard]] utils::result<sql::statement, utils::error> prepare(sql::executor &exec) const;
|
||||
|
||||
[[nodiscard]] std::string str(const sql::executor &exec) const;
|
||||
[[nodiscard]] sql::query_context compile(const sql::dialect &d, query_mode mode) const;
|
||||
[[nodiscard]] sql::query_context compile(const sql::dialect &d) const;
|
||||
|
||||
private:
|
||||
[[nodiscard]] utils::result<std::unique_ptr<sql::query_result_impl>, utils::error> fetch(const sql::executor &exec) const;
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@
|
|||
|
||||
namespace matador::query {
|
||||
|
||||
class query_create_intermediate : public query_intermediate
|
||||
{
|
||||
class query_create_intermediate : public query_intermediate {
|
||||
public:
|
||||
query_create_intermediate();
|
||||
|
||||
|
|
@ -20,6 +19,7 @@ public:
|
|||
executable_query table(const sql::table &table, const object::repository &schema) {
|
||||
return this->table(table, object::attribute_definition_generator::generate<Type>(schema));
|
||||
}
|
||||
executable_query schema(const std::string &schema_name);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,12 +5,12 @@
|
|||
|
||||
namespace matador::query {
|
||||
|
||||
class query_drop_intermediate : query_intermediate
|
||||
{
|
||||
class query_drop_intermediate : query_intermediate {
|
||||
public:
|
||||
query_drop_intermediate();
|
||||
|
||||
executable_query table(const sql::table &table);
|
||||
executable_query schema(const std::string &schema_name);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "matador/sql/column.hpp"
|
||||
|
||||
#include "matador/utils/placeholder.hpp"
|
||||
#include "matador/utils/types.hpp"
|
||||
|
||||
namespace matador::query::internal {
|
||||
|
|
@ -12,13 +13,14 @@ public:
|
|||
key_value_pair(const sql::column &col, utils::database_type value);
|
||||
key_value_pair(std::string name, utils::database_type value);
|
||||
key_value_pair(const char *name, utils::database_type value);
|
||||
key_value_pair(const char *name, utils::placeholder p);
|
||||
|
||||
[[nodiscard]] const std::string& name() const;
|
||||
[[nodiscard]] const utils::database_type& value() const;
|
||||
[[nodiscard]] const std::variant<utils::placeholder, utils::database_type>& value() const;
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
utils::database_type value_;
|
||||
std::variant<utils::placeholder, utils::database_type> value_;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ private:
|
|||
|
||||
class query_drop_foreign_key_constraint_part final : public query_part {
|
||||
public:
|
||||
explicit query_drop_foreign_key_constraint_part( const std::vector<sql::column>& columns);
|
||||
query_drop_foreign_key_constraint_part();
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
};
|
||||
|
||||
|
|
@ -377,6 +377,19 @@ private:
|
|||
std::vector<object::attribute_definition> columns_;
|
||||
};
|
||||
|
||||
class query_create_schema_part final : public query_part {
|
||||
public:
|
||||
explicit query_create_schema_part(std::string schema);
|
||||
|
||||
[[nodiscard]] const std::string& schema() const;
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
|
||||
private:
|
||||
std::string schema_;
|
||||
};
|
||||
|
||||
class query_drop_part final : public query_part
|
||||
{
|
||||
public:
|
||||
|
|
@ -400,5 +413,18 @@ private:
|
|||
sql::table table_;
|
||||
};
|
||||
|
||||
class query_drop_schema_part final : public query_part {
|
||||
public:
|
||||
explicit query_drop_schema_part(std::string schema_);
|
||||
|
||||
[[nodiscard]] const std::string& schema() const;
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
|
||||
private:
|
||||
std::string schema_;
|
||||
};
|
||||
|
||||
}
|
||||
#endif //QUERY_QUERY_PARTS_HPP
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ class query
|
|||
public:
|
||||
[[nodiscard]] static query_create_intermediate create();
|
||||
[[nodiscard]] static query_drop_intermediate drop();
|
||||
[[nodiscard]] static query_select_intermediate select();
|
||||
[[nodiscard]] static query_select_intermediate select(std::initializer_list<sql::column> columns);
|
||||
[[nodiscard]] static query_select_intermediate select(const std::vector<sql::column>& columns);
|
||||
[[nodiscard]] static query_select_intermediate select(const std::vector<std::string> &column_names);
|
||||
|
|
|
|||
|
|
@ -22,8 +22,7 @@ struct basic_type_to_string_visitor;
|
|||
struct query_data;
|
||||
struct value_visitor;
|
||||
|
||||
class query_compiler final : public query_part_visitor
|
||||
{
|
||||
class query_compiler final : public query_part_visitor {
|
||||
public:
|
||||
sql::query_context compile(const query_data &data,
|
||||
const sql::dialect &d,
|
||||
|
|
@ -33,42 +32,45 @@ protected:
|
|||
void visit(internal::query_alter_part& part) override;
|
||||
void visit(internal::query_alter_table_part& part) override;
|
||||
void visit(internal::query_add_key_constraint_part& part) override;
|
||||
void visit( internal::query_add_foreign_key_constraint_part& part ) override;
|
||||
void visit( internal::query_add_primary_key_constraint_part& part ) override;
|
||||
void visit( internal::query_add_foreign_key_reference_part& part ) override;
|
||||
void visit(internal::query_add_foreign_key_constraint_part& part) override;
|
||||
void visit(internal::query_add_primary_key_constraint_part& part) override;
|
||||
void visit(internal::query_add_foreign_key_reference_part& part) override;
|
||||
void visit(internal::query_drop_key_constraint_part& part) override;
|
||||
void visit(internal::query_drop_foreign_key_constraint_part& part) override;
|
||||
|
||||
void visit(internal::query_select_part &select_part) override;
|
||||
void visit(internal::query_from_part &from_part) override;
|
||||
void visit(internal::query_join_part &join_part) override;
|
||||
void visit(internal::query_on_part &on_part) override;
|
||||
void visit(internal::query_where_part &where_part) override;
|
||||
void visit(internal::query_group_by_part &group_by_part) override;
|
||||
void visit(internal::query_order_by_part &order_by_part) override;
|
||||
void visit(internal::query_order_by_asc_part &order_by_asc_part) override;
|
||||
void visit(internal::query_order_by_desc_part &order_by_desc_part) override;
|
||||
void visit(internal::query_offset_part &offset_part) override;
|
||||
void visit(internal::query_limit_part &limit_part) override;
|
||||
void visit(internal::query_insert_part &insert_part) override;
|
||||
void visit(internal::query_into_part &into_part) override;
|
||||
void visit(internal::query_values_part &values_part) override;
|
||||
protected:
|
||||
void visit(internal::query_select_part &part) override;
|
||||
void visit(internal::query_from_part &part) override;
|
||||
void visit(internal::query_join_part &part) override;
|
||||
void visit(internal::query_on_part &part) override;
|
||||
void visit(internal::query_where_part &part) override;
|
||||
void visit(internal::query_group_by_part &part) override;
|
||||
void visit(internal::query_order_by_part &part) override;
|
||||
void visit(internal::query_order_by_asc_part &part) override;
|
||||
void visit(internal::query_order_by_desc_part &part) override;
|
||||
void visit(internal::query_offset_part &part) override;
|
||||
void visit(internal::query_limit_part &part) override;
|
||||
void visit(internal::query_insert_part &part) override;
|
||||
void visit(internal::query_into_part &part) override;
|
||||
void visit(internal::query_values_part &part) override;
|
||||
|
||||
void visit(internal::query_update_part &update_part) override;
|
||||
void visit(internal::query_set_part &set_part) override;
|
||||
void visit(internal::query_update_part &part) override;
|
||||
void visit(internal::query_set_part &part) override;
|
||||
|
||||
void visit(internal::query_delete_part &delete_part) override;
|
||||
void visit(internal::query_delete_from_part &delete_from_part) override;
|
||||
void visit(internal::query_delete_part &part) override;
|
||||
void visit(internal::query_delete_from_part &part) override;
|
||||
|
||||
void visit(internal::query_create_part &create_part) override;
|
||||
void visit(internal::query_create_table_part &create_table_part) override;
|
||||
void visit(internal::query_create_part &part) override;
|
||||
void visit(internal::query_create_table_part &part) override;
|
||||
void visit(internal::query_create_schema_part& part) override;
|
||||
|
||||
void visit(internal::query_drop_part &drop_part) override;
|
||||
void visit(internal::query_drop_table_part &drop_table_part) override;
|
||||
void visit(internal::query_drop_part &part) override;
|
||||
void visit(internal::query_drop_table_part &part) override;
|
||||
void visit(internal::query_drop_schema_part& part) override;
|
||||
|
||||
static std::string build_table_name(sql::dialect_token token, const sql::dialect &d, const sql::table& t);
|
||||
|
||||
std::string determine_value(value_visitor &visitor, const std::variant<utils::placeholder, utils::database_type> &val);
|
||||
std::string determine_set_value(internal::basic_type_to_string_visitor &visitor, const utils::database_type &val);
|
||||
static std::string determine_value(value_visitor &visitor, const std::variant<utils::placeholder, utils::database_type> &val);
|
||||
|
||||
protected:
|
||||
const query_data *data_{};
|
||||
|
|
|
|||
|
|
@ -12,16 +12,10 @@
|
|||
|
||||
namespace matador::query {
|
||||
|
||||
enum struct query_mode {
|
||||
Direct = 0,
|
||||
Prepared = 1
|
||||
};
|
||||
|
||||
struct query_data {
|
||||
std::vector<std::unique_ptr<query_part>> parts{};
|
||||
std::vector<object::attribute_definition> columns{};
|
||||
std::unordered_map<std::string, sql::table> tables{};
|
||||
query_mode mode = query_mode::Direct;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ class query_alter_part;
|
|||
class query_alter_table_part;
|
||||
class query_add_key_constraint_part;
|
||||
class query_drop_key_constraint_part;
|
||||
class query_drop_foreign_key_constraint_part;
|
||||
class query_add_foreign_key_constraint_part;
|
||||
class query_add_foreign_key_reference_part;
|
||||
class query_add_primary_key_constraint_part;
|
||||
|
|
@ -31,8 +32,10 @@ class query_delete_part;
|
|||
class query_delete_from_part;
|
||||
class query_create_part;
|
||||
class query_create_table_part;
|
||||
class query_create_schema_part;
|
||||
class query_drop_part;
|
||||
class query_drop_table_part;
|
||||
class query_drop_schema_part;
|
||||
}
|
||||
|
||||
class query_part_visitor {
|
||||
|
|
@ -46,34 +49,37 @@ public:
|
|||
virtual void visit(internal::query_add_primary_key_constraint_part &part) = 0;
|
||||
virtual void visit(internal::query_add_foreign_key_reference_part &part) = 0;
|
||||
virtual void visit(internal::query_drop_key_constraint_part &part) = 0;
|
||||
virtual void visit(internal::query_drop_foreign_key_constraint_part &part) = 0;
|
||||
|
||||
virtual void visit(internal::query_select_part &select_part) = 0;
|
||||
virtual void visit(internal::query_from_part &from_part) = 0;
|
||||
virtual void visit(internal::query_join_part &join_part) = 0;
|
||||
virtual void visit(internal::query_on_part &on_part) = 0;
|
||||
virtual void visit(internal::query_where_part &where_part) = 0;
|
||||
virtual void visit(internal::query_group_by_part &group_by_part) = 0;
|
||||
virtual void visit(internal::query_order_by_part &order_by_part) = 0;
|
||||
virtual void visit(internal::query_order_by_asc_part &order_by_asc_part) = 0;
|
||||
virtual void visit(internal::query_order_by_desc_part &order_by_desc_part) = 0;
|
||||
virtual void visit(internal::query_offset_part &offset_part) = 0;
|
||||
virtual void visit(internal::query_limit_part &limit_part) = 0;
|
||||
virtual void visit(internal::query_select_part &part) = 0;
|
||||
virtual void visit(internal::query_from_part &part) = 0;
|
||||
virtual void visit(internal::query_join_part &part) = 0;
|
||||
virtual void visit(internal::query_on_part &part) = 0;
|
||||
virtual void visit(internal::query_where_part &part) = 0;
|
||||
virtual void visit(internal::query_group_by_part &part) = 0;
|
||||
virtual void visit(internal::query_order_by_part &part) = 0;
|
||||
virtual void visit(internal::query_order_by_asc_part &part) = 0;
|
||||
virtual void visit(internal::query_order_by_desc_part &part) = 0;
|
||||
virtual void visit(internal::query_offset_part &part) = 0;
|
||||
virtual void visit(internal::query_limit_part &part) = 0;
|
||||
|
||||
virtual void visit(internal::query_insert_part &insert_part) = 0;
|
||||
virtual void visit(internal::query_into_part &into_part) = 0;
|
||||
virtual void visit(internal::query_values_part &values_part) = 0;
|
||||
virtual void visit(internal::query_insert_part &part) = 0;
|
||||
virtual void visit(internal::query_into_part &part) = 0;
|
||||
virtual void visit(internal::query_values_part &part) = 0;
|
||||
|
||||
virtual void visit(internal::query_update_part &update_part) = 0;
|
||||
virtual void visit(internal::query_set_part &set_part) = 0;
|
||||
virtual void visit(internal::query_update_part &part) = 0;
|
||||
virtual void visit(internal::query_set_part &part) = 0;
|
||||
|
||||
virtual void visit(internal::query_delete_part &delete_part) = 0;
|
||||
virtual void visit(internal::query_delete_from_part &delete_from_part) = 0;
|
||||
virtual void visit(internal::query_delete_part &part) = 0;
|
||||
virtual void visit(internal::query_delete_from_part &part) = 0;
|
||||
|
||||
virtual void visit(internal::query_create_part &create_part) = 0;
|
||||
virtual void visit(internal::query_create_table_part &create_table_part) = 0;
|
||||
virtual void visit(internal::query_create_part &part) = 0;
|
||||
virtual void visit(internal::query_create_table_part &part) = 0;
|
||||
virtual void visit(internal::query_create_schema_part &part) = 0;
|
||||
|
||||
virtual void visit(internal::query_drop_part &drop_part) = 0;
|
||||
virtual void visit(internal::query_drop_table_part &drop_table_part) = 0;
|
||||
virtual void visit(internal::query_drop_part &part) = 0;
|
||||
virtual void visit(internal::query_drop_table_part &part) = 0;
|
||||
virtual void visit(internal::query_drop_schema_part &part) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -136,58 +136,57 @@ private:
|
|||
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::Alter, "ALTER"},
|
||||
{dialect_token::And, "AND"},
|
||||
{dialect_token::As, "AS"},
|
||||
{dialect_token::Asc, "ASC"},
|
||||
{dialect_token::Asterisk, "*"},
|
||||
{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::Between, "BETWEEN"},
|
||||
{dialect_token::Column, "COLUMN"},
|
||||
{dialect_token::Columns, "COLUMNS"},
|
||||
{dialect_token::Commit, "COMMIT TRANSACTION"},
|
||||
{dialect_token::Create, "CREATE"},
|
||||
{dialect_token::Desc, "DESC"},
|
||||
{dialect_token::Distinct, "DISTINCT"},
|
||||
{dialect_token::Drop, "DROP"},
|
||||
{dialect_token::DropConstraint, "DROP CONSTRAINT"},
|
||||
{dialect_token::EndBinaryData, "'"},
|
||||
{dialect_token::EndQuote, "\""},
|
||||
{dialect_token::EndStringData, "'"},
|
||||
{dialect_token::None, ""}
|
||||
{dialect_token::ForeignKey, "FOREIGN KEY"},
|
||||
{dialect_token::From, "FROM"},
|
||||
{dialect_token::GroupBy, "GROUP BY"},
|
||||
{dialect_token::In, "IN"},
|
||||
{dialect_token::Insert, "INSERT"},
|
||||
{dialect_token::Into, "INTO"},
|
||||
{dialect_token::Join, "LEFT JOIN"},
|
||||
{dialect_token::Like, "LIKE"},
|
||||
{dialect_token::Limit, "LIMIT"},
|
||||
{dialect_token::None, ""},
|
||||
{dialect_token::Not, "NOT"},
|
||||
{dialect_token::NotNull, "NOT NULL"},
|
||||
{dialect_token::Offset, "OFFSET"},
|
||||
{dialect_token::On, "ON"},
|
||||
{dialect_token::Or, "OR"},
|
||||
{dialect_token::OrderBy, "ORDER BY"},
|
||||
{dialect_token::PrimaryKey, "PRIMARY KEY"},
|
||||
{dialect_token::References, "REFERENCES"},
|
||||
{dialect_token::Remove, "DELETE"},
|
||||
{dialect_token::Rollback, "ROLLBACK TRANSACTION"},
|
||||
{dialect_token::Select, "SELECT"},
|
||||
{dialect_token::Set, "SET"},
|
||||
{dialect_token::StartQuote, "\""},
|
||||
{dialect_token::StringQuote, "'"},
|
||||
{dialect_token::Table, "TABLE"},
|
||||
{dialect_token::Update, "UPDATE"},
|
||||
{dialect_token::Values, "VALUES"},
|
||||
{dialect_token::Where, "WHERE"}
|
||||
};
|
||||
|
||||
data_type_to_string_map data_types_ {
|
||||
|
|
|
|||
|
|
@ -6,59 +6,57 @@
|
|||
namespace matador::sql {
|
||||
|
||||
enum class dialect_token : uint8_t {
|
||||
Create = 0,
|
||||
Drop,
|
||||
Remove,
|
||||
Insert,
|
||||
Update,
|
||||
Select,
|
||||
AddConstraint = 0,
|
||||
Alter,
|
||||
ForeignKey,
|
||||
PrimaryKey,
|
||||
AddConstraint,
|
||||
DropConstraint,
|
||||
References,
|
||||
Schema,
|
||||
Database,
|
||||
Table,
|
||||
Values,
|
||||
InsertValues,
|
||||
Columns,
|
||||
Column,
|
||||
From,
|
||||
Join,
|
||||
On,
|
||||
Into,
|
||||
Where,
|
||||
WhereClause,
|
||||
And,
|
||||
Or,
|
||||
Not,
|
||||
Like,
|
||||
Between,
|
||||
In,
|
||||
OrderBy,
|
||||
GroupBy,
|
||||
Asc,
|
||||
Desc,
|
||||
Limit,
|
||||
As,
|
||||
Offset,
|
||||
Distinct,
|
||||
Set,
|
||||
UpdateValues,
|
||||
NotNull,
|
||||
Asc,
|
||||
Asterisk,
|
||||
Begin,
|
||||
Commit,
|
||||
Rollback,
|
||||
StartQuote,
|
||||
EndQuote,
|
||||
StringQuote,
|
||||
BeginBinaryData,
|
||||
EndBinaryData,
|
||||
BeginStringData,
|
||||
Between,
|
||||
Column,
|
||||
Columns,
|
||||
Commit,
|
||||
Create,
|
||||
Database,
|
||||
Desc,
|
||||
Distinct,
|
||||
Drop,
|
||||
DropConstraint,
|
||||
EndBinaryData,
|
||||
EndQuote,
|
||||
EndStringData,
|
||||
None
|
||||
ForeignKey,
|
||||
From,
|
||||
GroupBy,
|
||||
In,
|
||||
Insert,
|
||||
Into,
|
||||
Join,
|
||||
Like,
|
||||
Limit,
|
||||
None,
|
||||
Not,
|
||||
NotNull,
|
||||
Offset,
|
||||
On,
|
||||
Or,
|
||||
OrderBy,
|
||||
PrimaryKey,
|
||||
References,
|
||||
Remove,
|
||||
Rollback,
|
||||
Schema,
|
||||
Select,
|
||||
Set,
|
||||
StartQuote,
|
||||
StringQuote,
|
||||
Table,
|
||||
Update,
|
||||
Values,
|
||||
Where
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ namespace matador::sql {
|
|||
|
||||
enum class sql_command {
|
||||
SQL_UNKNOWN,
|
||||
SQL_CREATE,
|
||||
SQL_CREATE_TABLE,
|
||||
SQL_CREATE_SCHEMA,
|
||||
SQL_CREATE_DATABASE,
|
||||
|
|
@ -17,6 +18,7 @@ enum class sql_command {
|
|||
SQL_INSERT,
|
||||
SQL_DELETE,
|
||||
SQL_SELECT,
|
||||
SQL_DROP,
|
||||
SQL_DROP_TABLE,
|
||||
SQL_DROP_SCHEMA,
|
||||
SQL_DROP_DATABASE,
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ namespace matador::sql {
|
|||
|
||||
struct column;
|
||||
|
||||
class record
|
||||
{
|
||||
class record final {
|
||||
private:
|
||||
using field_ref = std::reference_wrapper<field>;
|
||||
using field_by_index = std::vector<field_ref>;
|
||||
|
|
@ -45,13 +44,11 @@ public:
|
|||
[[nodiscard]] const field& at(const column &col) const;
|
||||
[[nodiscard]] const field& at(size_t index) const;
|
||||
template<class Type>
|
||||
std::optional<Type> at(const column &col) const
|
||||
{
|
||||
std::optional<Type> at(const column &col) const {
|
||||
return at(col).as<Type>();
|
||||
}
|
||||
template<class Type>
|
||||
std::optional<Type> at(size_t index) const
|
||||
{
|
||||
std::optional<Type> at(const size_t index) const {
|
||||
return at(index).as<Type>();
|
||||
}
|
||||
|
||||
|
|
@ -70,8 +67,6 @@ public:
|
|||
[[nodiscard]] bool empty() const;
|
||||
void clear();
|
||||
|
||||
// [[nodiscard]] bool unknown() const;
|
||||
|
||||
private:
|
||||
void init();
|
||||
void add_to_map(field &col, size_t index);
|
||||
|
|
@ -79,8 +74,6 @@ private:
|
|||
private:
|
||||
field_by_index fields_;
|
||||
field_by_name_map fields_by_name_;
|
||||
|
||||
// int pk_index_{-1};
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ public:
|
|||
return bus_.subscribe<EventType>(handler);
|
||||
}
|
||||
|
||||
connection_pool& pool() const;
|
||||
[[nodiscard]] connection_pool& pool() const;
|
||||
|
||||
private:
|
||||
size_t max_size_{};
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ add_library(matador-orm STATIC
|
|||
../../include/matador/query/intermediates/executable_query.hpp
|
||||
../../include/matador/query/intermediates/fetchable_query.hpp
|
||||
../../include/matador/query/intermediates/query_alter_intermediate.hpp
|
||||
../../include/matador/query/intermediates/query_alter_table_intermediate.hpp
|
||||
../../include/matador/query/intermediates/query_create_intermediate.hpp
|
||||
../../include/matador/query/intermediates/query_delete_from_intermediate.hpp
|
||||
../../include/matador/query/intermediates/query_delete_intermediate.hpp
|
||||
|
|
@ -97,6 +98,7 @@ add_library(matador-orm STATIC
|
|||
query/intermediates/executable_query.cpp
|
||||
query/intermediates/fetchable_query.cpp
|
||||
query/intermediates/query_alter_intermediate.cpp
|
||||
query/intermediates/query_alter_table_intermediate.cpp
|
||||
query/intermediates/query_create_intermediate.cpp
|
||||
query/intermediates/query_delete_from_intermediate.cpp
|
||||
query/intermediates/query_delete_intermediate.cpp
|
||||
|
|
@ -118,6 +120,7 @@ add_library(matador-orm STATIC
|
|||
query/intermediates/query_order_direction_intermediate.cpp
|
||||
query/intermediates/query_select_intermediate.cpp
|
||||
query/intermediates/query_set_intermediate.cpp
|
||||
query/intermediates/query_update_intermediate.cpp
|
||||
query/intermediates/query_where_intermediate.cpp
|
||||
query/internal/basic_type_to_string_visitor.cpp
|
||||
query/internal/key_value_pair.cpp
|
||||
|
|
@ -127,7 +130,6 @@ add_library(matador-orm STATIC
|
|||
query/query.cpp
|
||||
query/query_compiler.cpp
|
||||
query/query_part.cpp
|
||||
query/query_update_intermediate.cpp
|
||||
query/value_extractor.cpp
|
||||
sql/backend_provider.cpp
|
||||
sql/column.cpp
|
||||
|
|
@ -152,8 +154,6 @@ add_library(matador-orm STATIC
|
|||
sql/statement.cpp
|
||||
sql/statement_cache.cpp
|
||||
sql/table.cpp
|
||||
../../include/matador/query/intermediates/query_alter_table_intermediate.hpp
|
||||
query/intermediates/query_alter_table_intermediate.cpp
|
||||
)
|
||||
|
||||
target_include_directories(matador-orm
|
||||
|
|
|
|||
|
|
@ -8,25 +8,21 @@ namespace matador::query {
|
|||
|
||||
utils::result<size_t, utils::error> executable_query::execute(const sql::executor &exec) const {
|
||||
query_compiler compiler;
|
||||
context_->mode = query_mode::Direct;
|
||||
return exec.execute(compiler.compile(*context_, exec.dialect(), std::nullopt));
|
||||
}
|
||||
|
||||
utils::result<sql::statement, utils::error> executable_query::prepare(sql::executor &exec) const {
|
||||
query_compiler compiler;
|
||||
context_->mode = query_mode::Prepared;
|
||||
return exec.prepare(compiler.compile(*context_, exec.dialect(), std::nullopt));
|
||||
}
|
||||
|
||||
sql::query_context executable_query::compile( const sql::executor& exec ) const {
|
||||
query_compiler compiler;
|
||||
context_->mode = query_mode::Prepared;
|
||||
return compiler.compile(*context_, exec.dialect(), std::nullopt);
|
||||
}
|
||||
|
||||
std::string executable_query::str(const sql::executor &exec) const {
|
||||
query_compiler compiler;
|
||||
context_->mode = query_mode::Direct;
|
||||
return exec.str(compiler.compile(*context_, exec.dialect(), std::nullopt));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ sql::record *create_prototype(const std::vector<object::attribute_definition> &p
|
|||
}
|
||||
utils::result<sql::query_result<sql::record>, utils::error> fetchable_query::fetch_all(const sql::executor &exec) const {
|
||||
query_compiler compiler;
|
||||
context_->mode = query_mode::Direct;
|
||||
const auto ctx = compiler.compile(*context_, exec.dialect(), std::nullopt);
|
||||
return exec.fetch(ctx)
|
||||
.and_then([](auto &&res) {
|
||||
|
|
@ -47,7 +46,6 @@ utils::result<sql::query_result<sql::record>, utils::error> fetchable_query::fet
|
|||
|
||||
utils::result<std::optional<sql::record>, utils::error> fetchable_query::fetch_one(const sql::executor &exec) const {
|
||||
query_compiler compiler;
|
||||
context_->mode = query_mode::Direct;
|
||||
auto result = exec.fetch(compiler.compile(*context_, exec.dialect(), std::nullopt));
|
||||
if (!result.is_ok()) {
|
||||
return utils::failure(result.err());
|
||||
|
|
@ -66,21 +64,20 @@ utils::result<std::optional<sql::record>, utils::error> fetchable_query::fetch_o
|
|||
}
|
||||
|
||||
std::string fetchable_query::str(const sql::executor &exec) const {
|
||||
return exec.str(compile(exec.dialect(), query_mode::Direct));
|
||||
return exec.str(compile(exec.dialect()));
|
||||
}
|
||||
|
||||
sql::query_context fetchable_query::compile(const sql::dialect &d, const query_mode mode) const {
|
||||
sql::query_context fetchable_query::compile(const sql::dialect &d) const {
|
||||
query_compiler compiler;
|
||||
context_->mode = mode;
|
||||
return compiler.compile(*context_, d, std::nullopt);
|
||||
}
|
||||
|
||||
utils::result<std::unique_ptr<sql::query_result_impl>, utils::error> fetchable_query::fetch(const sql::executor &exec) const {
|
||||
return exec.fetch(compile(exec.dialect(), query_mode::Direct));
|
||||
return exec.fetch(compile(exec.dialect()));
|
||||
}
|
||||
|
||||
utils::result<sql::statement, utils::error> fetchable_query::prepare(sql::executor &exec) const {
|
||||
return exec.prepare(compile(exec.dialect(), query_mode::Prepared));
|
||||
return exec.prepare(compile(exec.dialect()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -4,20 +4,21 @@
|
|||
|
||||
namespace matador::query {
|
||||
|
||||
query_create_intermediate::query_create_intermediate()
|
||||
{
|
||||
query_create_intermediate::query_create_intermediate() {
|
||||
context_->parts.push_back(std::make_unique<internal::query_create_part>());
|
||||
}
|
||||
|
||||
executable_query query_create_intermediate::table(const sql::table &table, const std::initializer_list<object::attribute_definition> columns)
|
||||
{
|
||||
executable_query query_create_intermediate::table(const sql::table &table, const std::initializer_list<object::attribute_definition> columns) {
|
||||
return this->table(table, std::vector<object::attribute_definition>{columns});
|
||||
}
|
||||
|
||||
executable_query query_create_intermediate::table(const sql::table &table, const std::vector<object::attribute_definition> &columns)
|
||||
{
|
||||
executable_query query_create_intermediate::table(const sql::table &table, const std::vector<object::attribute_definition> &columns) {
|
||||
context_->parts.push_back(std::make_unique<internal::query_create_table_part>(table, columns));
|
||||
return {context_};
|
||||
}
|
||||
|
||||
executable_query query_create_intermediate::schema( const std::string& schema_name ) {
|
||||
context_->parts.push_back(std::make_unique<internal::query_create_schema_part>(schema_name));
|
||||
return {context_};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,13 +4,11 @@
|
|||
|
||||
namespace matador::query {
|
||||
|
||||
query_drop_intermediate::query_drop_intermediate()
|
||||
{
|
||||
query_drop_intermediate::query_drop_intermediate() {
|
||||
context_->parts.push_back(std::make_unique<internal::query_drop_part>());
|
||||
}
|
||||
|
||||
executable_query query_drop_intermediate::table(const sql::table &table)
|
||||
{
|
||||
executable_query query_drop_intermediate::table(const sql::table &table) {
|
||||
context_->parts.push_back(std::make_unique<internal::query_drop_table_part>(table));
|
||||
return {context_};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,15 +15,19 @@ key_value_pair::key_value_pair(const sql::column &col, utils::database_type valu
|
|||
}
|
||||
|
||||
key_value_pair::key_value_pair(const char *name, utils::database_type value)
|
||||
: name_(name)
|
||||
, value_(std::move(value)) {
|
||||
: name_(name)
|
||||
, value_(std::move(value)) {
|
||||
}
|
||||
|
||||
key_value_pair::key_value_pair( const char* name, utils::placeholder p )
|
||||
: name_(name)
|
||||
, value_(p) {}
|
||||
|
||||
const std::string &key_value_pair::name() const {
|
||||
return name_;
|
||||
}
|
||||
|
||||
const utils::database_type& key_value_pair::value() const {
|
||||
const std::variant<utils::placeholder, utils::database_type>& key_value_pair::value() const {
|
||||
return value_;
|
||||
}
|
||||
}
|
||||
|
|
@ -46,6 +46,13 @@ const std::string& query_drop_key_constraint_part::name() const {
|
|||
return name_;
|
||||
}
|
||||
|
||||
query_drop_foreign_key_constraint_part::query_drop_foreign_key_constraint_part()
|
||||
: query_part( sql::dialect_token::DropConstraint ) {}
|
||||
|
||||
void query_drop_foreign_key_constraint_part::accept( query_part_visitor& visitor ) {
|
||||
visitor.visit(*this);
|
||||
}
|
||||
|
||||
query_add_foreign_key_constraint_part::query_add_foreign_key_constraint_part(const std::vector<sql::column>& columns)
|
||||
: query_part(sql::dialect_token::ForeignKey)
|
||||
, columns_(columns) {}
|
||||
|
|
@ -357,6 +364,18 @@ void query_create_table_part::accept(query_part_visitor &visitor)
|
|||
visitor.visit(*this);
|
||||
}
|
||||
|
||||
query_create_schema_part::query_create_schema_part(std::string schema)
|
||||
: query_part( sql::dialect_token::Schema )
|
||||
, schema_( std::move( schema ) ){}
|
||||
|
||||
const std::string& query_create_schema_part::schema() const {
|
||||
return schema_;
|
||||
}
|
||||
|
||||
void query_create_schema_part::accept( query_part_visitor& visitor ) {
|
||||
visitor.visit(*this);
|
||||
}
|
||||
|
||||
query_drop_part::query_drop_part()
|
||||
: query_part(sql::dialect_token::Drop) {}
|
||||
|
||||
|
|
@ -379,4 +398,15 @@ void query_drop_table_part::accept(query_part_visitor &visitor)
|
|||
visitor.visit(*this);
|
||||
}
|
||||
|
||||
query_drop_schema_part::query_drop_schema_part(std::string schema_)
|
||||
: query_part( sql::dialect_token::Schema )
|
||||
, schema_( std::move( schema_ ) ) {}
|
||||
|
||||
const std::string& query_drop_schema_part::schema() const {
|
||||
return schema_;
|
||||
}
|
||||
|
||||
void query_drop_schema_part::accept( query_part_visitor& visitor ) {
|
||||
visitor.visit(*this);
|
||||
}
|
||||
}
|
||||
|
|
@ -32,6 +32,10 @@ query_drop_intermediate query::drop() {
|
|||
return {};
|
||||
}
|
||||
|
||||
query_select_intermediate query::select() {
|
||||
return query_select_intermediate{{}};
|
||||
}
|
||||
|
||||
query_select_intermediate query::select( const std::initializer_list<sql::column> columns) {
|
||||
return select(std::vector<sql::column>{columns});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ void query_compiler::visit(internal::query_add_key_constraint_part& part) {
|
|||
query_.sql += " " + dialect_->token_at(sql::dialect_token::AddConstraint) + " " + part.name();
|
||||
}
|
||||
|
||||
void query_compiler::visit( internal::query_add_foreign_key_constraint_part& part ) {
|
||||
void query_compiler::visit(internal::query_add_foreign_key_constraint_part& part) {
|
||||
query_.sql += " " + dialect_->token_at(part.token()) + " (";
|
||||
|
||||
if (part.columns().size() < 2) {
|
||||
|
|
@ -82,9 +82,9 @@ void query_compiler::visit( internal::query_add_foreign_key_constraint_part& par
|
|||
query_.sql += ")";
|
||||
}
|
||||
|
||||
void query_compiler::visit( internal::query_add_primary_key_constraint_part& part ) {}
|
||||
void query_compiler::visit(internal::query_add_primary_key_constraint_part& part) {}
|
||||
|
||||
void query_compiler::visit( internal::query_add_foreign_key_reference_part& part ) {
|
||||
void query_compiler::visit(internal::query_add_foreign_key_reference_part& part) {
|
||||
query_.sql += " " + dialect_->token_at(part.token()) + " " +
|
||||
part.table().name + " (";
|
||||
|
||||
|
|
@ -106,7 +106,10 @@ void query_compiler::visit(internal::query_drop_key_constraint_part& part) {
|
|||
query_.sql += " " + dialect_->token_at(part.token()) + " " + part.name();
|
||||
}
|
||||
|
||||
void query_compiler::visit(internal::query_select_part &select_part)
|
||||
void query_compiler::visit(internal::query_drop_foreign_key_constraint_part& part) {
|
||||
}
|
||||
|
||||
void query_compiler::visit(internal::query_select_part &part)
|
||||
{
|
||||
query_.command = sql::sql_command::SQL_SELECT;
|
||||
query_.sql = dialect_->token_at(sql::dialect_token::Select) + " ";
|
||||
|
|
@ -114,7 +117,9 @@ void query_compiler::visit(internal::query_select_part &select_part)
|
|||
query_.prototype.clear();
|
||||
|
||||
std::string result;
|
||||
if (const auto &columns = select_part.columns(); columns.size() < 2) {
|
||||
if (part.columns().empty()) {
|
||||
result = dialect_->token_at(sql::dialect_token::Asterisk);
|
||||
} else if (const auto &columns = part.columns(); columns.size() < 2) {
|
||||
for (const auto &col: columns) {
|
||||
result.append(handle_column(query_, dialect_, *data_, col ));
|
||||
}
|
||||
|
|
@ -130,38 +135,38 @@ void query_compiler::visit(internal::query_select_part &select_part)
|
|||
query_.sql += result;
|
||||
}
|
||||
|
||||
void query_compiler::visit(internal::query_from_part &from_part)
|
||||
void query_compiler::visit(internal::query_from_part &part)
|
||||
{
|
||||
query_.table = from_part.table();
|
||||
query_.sql += " " + build_table_name(from_part.token(), *dialect_, query_.table);
|
||||
query_.table = part.table();
|
||||
query_.sql += " " + build_table_name(part.token(), *dialect_, query_.table);
|
||||
query_.table_aliases.insert({query_.table.name, query_.table.alias});
|
||||
}
|
||||
|
||||
void query_compiler::visit(internal::query_join_part &join_part)
|
||||
void query_compiler::visit(internal::query_join_part &part)
|
||||
{
|
||||
query_.sql += " " + query_compiler::build_table_name(join_part.token(), *dialect_, join_part.table());
|
||||
query_.sql += " " + query_compiler::build_table_name(part.token(), *dialect_, part.table());
|
||||
}
|
||||
|
||||
void query_compiler::visit(internal::query_on_part &on_part) {
|
||||
void query_compiler::visit(internal::query_on_part &part) {
|
||||
criteria_evaluator evaluator(*dialect_, query_);
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::On) +
|
||||
" " + evaluator.evaluate(on_part.condition());
|
||||
" " + evaluator.evaluate(part.condition());
|
||||
}
|
||||
|
||||
void query_compiler::visit(internal::query_where_part &where_part) {
|
||||
void query_compiler::visit(internal::query_where_part &part) {
|
||||
criteria_evaluator evaluator(*dialect_, query_);
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::Where) +
|
||||
" " + evaluator.evaluate(where_part.condition());
|
||||
" " + evaluator.evaluate(part.condition());
|
||||
}
|
||||
|
||||
void query_compiler::visit(internal::query_group_by_part &group_by_part) {
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::GroupBy) + " " + dialect_->prepare_identifier(group_by_part.column());
|
||||
void query_compiler::visit(internal::query_group_by_part &part) {
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::GroupBy) + " " + dialect_->prepare_identifier(part.column());
|
||||
}
|
||||
|
||||
void query_compiler::visit(internal::query_order_by_part &order_by_part)
|
||||
void query_compiler::visit(internal::query_order_by_part &part)
|
||||
{
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::OrderBy) +
|
||||
" " + dialect_->prepare_condition(order_by_part.column());
|
||||
" " + dialect_->prepare_condition(part.column());
|
||||
}
|
||||
|
||||
void query_compiler::visit(internal::query_order_by_asc_part &/*order_by_asc_part*/)
|
||||
|
|
@ -174,14 +179,14 @@ void query_compiler::visit(internal::query_order_by_desc_part &/*order_by_desc_p
|
|||
query_.sql += " " + dialect_->token_at(sql::dialect_token::Desc);
|
||||
}
|
||||
|
||||
void query_compiler::visit(internal::query_offset_part &offset_part)
|
||||
void query_compiler::visit(internal::query_offset_part &part)
|
||||
{
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::Offset) + " " + std::to_string(offset_part.offset());
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::Offset) + " " + std::to_string(part.offset());
|
||||
}
|
||||
|
||||
void query_compiler::visit(internal::query_limit_part &limit_part)
|
||||
void query_compiler::visit(internal::query_limit_part &part)
|
||||
{
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::Limit) + " " + std::to_string(limit_part.limit());
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::Limit) + " " + std::to_string(part.limit());
|
||||
}
|
||||
|
||||
void query_compiler::visit(internal::query_insert_part &/*insert_part*/)
|
||||
|
|
@ -190,21 +195,21 @@ void query_compiler::visit(internal::query_insert_part &/*insert_part*/)
|
|||
query_.sql = dialect_->token_at(sql::dialect_token::Insert);
|
||||
}
|
||||
|
||||
void query_compiler::visit(internal::query_into_part &into_part)
|
||||
void query_compiler::visit(internal::query_into_part &part)
|
||||
{
|
||||
query_.table = into_part.table();
|
||||
query_.table = part.table();
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::Into) +
|
||||
" " + dialect_->prepare_identifier_string(into_part.table().name);
|
||||
" " + dialect_->prepare_identifier_string(part.table().name);
|
||||
|
||||
std::string result{"("};
|
||||
if (into_part.columns().size() < 2) {
|
||||
for (const auto &col: into_part.columns()) {
|
||||
if (part.columns().size() < 2) {
|
||||
for (const auto &col: part.columns()) {
|
||||
result.append(dialect_->prepare_identifier_string(col.name));
|
||||
}
|
||||
} else {
|
||||
auto it = into_part.columns().begin();
|
||||
auto it = part.columns().begin();
|
||||
result.append(dialect_->prepare_identifier_string((it++)->name));
|
||||
for (; it != into_part.columns().end(); ++it) {
|
||||
for (; it != part.columns().end(); ++it) {
|
||||
result.append(", ");
|
||||
result.append(dialect_->prepare_identifier_string(it->name));
|
||||
}
|
||||
|
|
@ -222,7 +227,7 @@ struct value_visitor {
|
|||
|
||||
}
|
||||
void operator()(const utils::placeholder &/*val*/) {
|
||||
value_to_string_visitor.query.bind_vars.emplace_back("unknown");
|
||||
value_to_string_visitor.query.bind_vars.emplace_back(std::string("value_") + std::to_string(value_to_string_visitor.query.bind_vars.size() + 1));
|
||||
value_to_string_visitor.result = value_to_string_visitor.writer->dialect().next_placeholder(value_to_string_visitor.query.bind_vars);
|
||||
}
|
||||
|
||||
|
|
@ -230,31 +235,26 @@ struct value_visitor {
|
|||
};
|
||||
|
||||
std::string query_compiler::determine_value(value_visitor &visitor, const std::variant<utils::placeholder, utils::database_type> &val) {
|
||||
if (data_->mode == query_mode::Direct) {
|
||||
std::visit(visitor, val);
|
||||
return visitor.value_to_string_visitor.result;
|
||||
}
|
||||
|
||||
query_.bind_vars.emplace_back(std::string("value_") + std::to_string(query_.bind_vars.size() + 1));
|
||||
return dialect_->next_placeholder(query_.bind_vars);
|
||||
}
|
||||
|
||||
void query_compiler::visit(internal::query_values_part &values_part) {
|
||||
void query_compiler::visit(internal::query_values_part &part) {
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::Values);
|
||||
|
||||
attribute_string_writer writer(*dialect_, connection_);
|
||||
|
||||
value_visitor visitor(writer, query_);
|
||||
std::string result{"("};
|
||||
if (values_part.values().size() < 2) {
|
||||
for (const auto& val: values_part.values()) {
|
||||
if (part.values().size() < 2) {
|
||||
for (const auto& val: part.values()) {
|
||||
result.append(determine_value(visitor, val));
|
||||
}
|
||||
} else {
|
||||
auto it = values_part.values().begin();
|
||||
auto it = part.values().begin();
|
||||
auto val = *it++;
|
||||
result.append(determine_value(visitor, val));
|
||||
for (; it != values_part.values().end(); ++it) {
|
||||
for (; it != part.values().end(); ++it) {
|
||||
result.append(", ");
|
||||
val = *it;
|
||||
result.append(determine_value(visitor, val));
|
||||
|
|
@ -265,11 +265,11 @@ void query_compiler::visit(internal::query_values_part &values_part) {
|
|||
query_.sql += " " + result;
|
||||
}
|
||||
|
||||
void query_compiler::visit(internal::query_update_part &update_part)
|
||||
void query_compiler::visit(internal::query_update_part &part)
|
||||
{
|
||||
query_.command = sql::sql_command::SQL_UPDATE;
|
||||
query_.table = update_part.table();
|
||||
query_.sql += query_compiler::build_table_name(update_part.token(), *dialect_, query_.table);
|
||||
query_.table = part.table();
|
||||
query_.sql += query_compiler::build_table_name(part.token(), *dialect_, query_.table);
|
||||
}
|
||||
|
||||
void query_compiler::visit(internal::query_delete_part &/*delete_part*/)
|
||||
|
|
@ -278,10 +278,10 @@ void query_compiler::visit(internal::query_delete_part &/*delete_part*/)
|
|||
query_.sql = dialect_->token_at(sql::dialect_token::Remove);
|
||||
}
|
||||
|
||||
void query_compiler::visit(internal::query_delete_from_part &delete_from_part)
|
||||
void query_compiler::visit(internal::query_delete_from_part &part)
|
||||
{
|
||||
query_.table = delete_from_part.table();
|
||||
query_.sql += " " + build_table_name(delete_from_part.token(), *dialect_, query_.table);
|
||||
query_.table = part.table();
|
||||
query_.sql += " " + build_table_name(part.token(), *dialect_, query_.table);
|
||||
}
|
||||
|
||||
void query_compiler::visit(internal::query_create_part &/*create_part*/)
|
||||
|
|
@ -303,30 +303,30 @@ struct column_context
|
|||
|
||||
std::string build_create_column(const object::attribute_definition &col, const sql::dialect &d, column_context &context);
|
||||
|
||||
void query_compiler::visit(internal::query_create_table_part &create_table_part)
|
||||
void query_compiler::visit(internal::query_create_table_part &part)
|
||||
{
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::Table) + " " + dialect_->prepare_identifier_string(create_table_part.table().name) + " ";
|
||||
query_.table = create_table_part.table();
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::Table) + " " + dialect_->prepare_identifier_string(part.table().name) + " ";
|
||||
query_.table = part.table();
|
||||
|
||||
std::string result = "(";
|
||||
|
||||
column_context context;
|
||||
|
||||
if (create_table_part.columns().size() < 2) {
|
||||
for (const auto &col: create_table_part.columns()) {
|
||||
if (part.columns().size() < 2) {
|
||||
for (const auto &col: part.columns()) {
|
||||
result.append(build_create_column(col, *dialect_, context));
|
||||
}
|
||||
} else {
|
||||
auto it = create_table_part.columns().begin();
|
||||
auto it = part.columns().begin();
|
||||
result.append(build_create_column(*it++, *dialect_, context));
|
||||
for (; it != create_table_part.columns().end(); ++it) {
|
||||
for (; it != part.columns().end(); ++it) {
|
||||
result.append(", ");
|
||||
result.append(build_create_column(*it, *dialect_, context));
|
||||
}
|
||||
}
|
||||
|
||||
if (!context.primary_keys.empty()) {
|
||||
result.append(", CONSTRAINT PK_" + create_table_part.table().name + " PRIMARY KEY (" + utils::join(context.primary_keys, ", ") + ")");
|
||||
result.append(", CONSTRAINT PK_" + part.table().name + " PRIMARY KEY (" + utils::join(context.primary_keys, ", ") + ")");
|
||||
}
|
||||
for (const auto &[column, reference_column]: context.foreign_contexts) {
|
||||
// ALTER TABLE Orders ADD CONSTRAINT FK_PersonOrder FOREIGN KEY (PersonID) REFERENCES Persons(PersonID);
|
||||
|
|
@ -342,52 +342,50 @@ void query_compiler::visit(internal::query_create_table_part &create_table_part)
|
|||
query_.sql += result;
|
||||
}
|
||||
|
||||
void query_compiler::visit(internal::query_drop_part &/*drop_part*/)
|
||||
{
|
||||
void query_compiler::visit( internal::query_create_schema_part& part ) {
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::Create) + " " +
|
||||
dialect_->token_at(sql::dialect_token::Schema) + " " + dialect_->prepare_identifier_string(part.schema());
|
||||
}
|
||||
|
||||
void query_compiler::visit(internal::query_drop_part &part) {
|
||||
query_.command = sql::sql_command::SQL_DROP_TABLE;
|
||||
query_.sql = dialect_->token_at(sql::dialect_token::Drop);
|
||||
query_.sql = dialect_->token_at(part.token());
|
||||
}
|
||||
|
||||
std::string query_compiler::determine_set_value(internal::basic_type_to_string_visitor &visitor, const utils::database_type &val) {
|
||||
if (data_->mode == query_mode::Direct) {
|
||||
std::visit(visitor, val);
|
||||
return visitor.result;
|
||||
}
|
||||
|
||||
query_.bind_vars.emplace_back(std::string("value_") + std::to_string(query_.bind_vars.size() + 1));
|
||||
return dialect_->next_placeholder(query_.bind_vars);
|
||||
void query_compiler::visit( internal::query_drop_schema_part& part ) {
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::Drop) + " " +
|
||||
dialect_->token_at(sql::dialect_token::Schema) + " " + dialect_->prepare_identifier_string(part.schema());
|
||||
}
|
||||
|
||||
void query_compiler::visit(internal::query_set_part &set_part)
|
||||
{
|
||||
void query_compiler::visit(internal::query_set_part &part) {
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::Set) + " ";
|
||||
|
||||
attribute_string_writer writer(*dialect_, connection_);
|
||||
internal::basic_type_to_string_visitor visitor(writer, query_);
|
||||
std::string result;
|
||||
if (set_part.key_values().size() < 2) {
|
||||
for (const auto &col: set_part.key_values()) {
|
||||
|
||||
value_visitor visitor(writer, query_); if (part.key_values().size() < 2) {
|
||||
for (const auto &col: part.key_values()) {
|
||||
result.append(dialect_->prepare_identifier_string(col.name()) + "=");
|
||||
result.append(determine_set_value(visitor, col.value()));
|
||||
result.append(determine_value(visitor, col.value()));
|
||||
}
|
||||
} else {
|
||||
auto it = set_part.key_values().begin();
|
||||
auto it = part.key_values().begin();
|
||||
result.append(dialect_->prepare_identifier_string(it->name()) + "=");
|
||||
result.append(determine_set_value(visitor, (it++)->value()));
|
||||
for (; it != set_part.key_values().end(); ++it) {
|
||||
result.append(determine_value(visitor, (it++)->value()));
|
||||
for (; it != part.key_values().end(); ++it) {
|
||||
result.append(", ");
|
||||
result.append(dialect_->prepare_identifier_string(it->name()) + "=");
|
||||
result.append(determine_set_value(visitor, it->value()));
|
||||
result.append(determine_value(visitor, it->value()));
|
||||
}
|
||||
}
|
||||
|
||||
query_.sql += result;
|
||||
}
|
||||
|
||||
void query_compiler::visit(internal::query_drop_table_part &drop_table_part)
|
||||
void query_compiler::visit(internal::query_drop_table_part &part)
|
||||
{
|
||||
query_.table = drop_table_part.table();
|
||||
query_.sql += " " + query_compiler::build_table_name(drop_table_part.token(), *dialect_, query_.table);
|
||||
query_.table = part.table();
|
||||
query_.sql += " " + query_compiler::build_table_name(part.token(), *dialect_, query_.table);
|
||||
}
|
||||
|
||||
std::string build_create_column(const object::attribute_definition &col, const sql::dialect &d, column_context &context)
|
||||
|
|
|
|||
|
|
@ -66,6 +66,14 @@ TEST_CASE_METHOD(QueryFixture, "Test drop table sql statement string", "[query]"
|
|||
REQUIRE(result == R"(DROP TABLE "person")");
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(QueryFixture, "Test select all columns with asterisk", "[query][select][asterisk]") {
|
||||
const auto result = query::select()
|
||||
.from("person")
|
||||
.str(*db);
|
||||
|
||||
REQUIRE(result == R"(SELECT * FROM "person")");
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(QueryFixture, "Test select sql statement string", "[query]") {
|
||||
const auto result = query::select({"id", "name", "age"})
|
||||
.from("person")
|
||||
|
|
|
|||
|
|
@ -172,11 +172,11 @@ TEST_CASE("Test LRU cache evicts oldest entries", "[statement][cache][evict]") {
|
|||
result = cache.acquire({"SELECT title FROM book"});
|
||||
REQUIRE(result);
|
||||
auto stmt2 = result.value();
|
||||
result = cache.acquire({"SELECT name FROM author"}); // Should evict first statement
|
||||
result = cache.acquire({"SELECT name FROM author"}); // Should evict the first statement
|
||||
REQUIRE(result);
|
||||
auto stmt3 = result.value();
|
||||
|
||||
// Trigger re-prepare of evicted statement
|
||||
// Trigger re-prepares of an evicted statement
|
||||
result = cache.acquire({"SELECT 1"});
|
||||
REQUIRE(result);
|
||||
auto stmt4 = result.value();
|
||||
|
|
@ -317,6 +317,7 @@ TEST_CASE("Race condition simulation with mixed access", "[statement_cache][race
|
|||
};
|
||||
|
||||
std::vector<std::thread> jobs;
|
||||
jobs.reserve(threads);
|
||||
for (int i = 0; i < threads; ++i) {
|
||||
jobs.emplace_back(task, i);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue