identity generator progress
This commit is contained in:
parent
881e93e0f6
commit
4c63322024
|
|
@ -4,8 +4,7 @@
|
|||
|
||||
#include "matador/utils/basic_types.hpp"
|
||||
|
||||
[[maybe_unused]] const matador::sql::dialect *get_dialect()
|
||||
{
|
||||
[[maybe_unused]] const matador::sql::dialect *get_dialect() {
|
||||
using namespace matador::sql;
|
||||
const static dialect d = dialect_builder::builder()
|
||||
.create()
|
||||
|
|
@ -13,16 +12,17 @@
|
|||
return "$" + std::to_string(index);
|
||||
})
|
||||
.with_token_replace_map({
|
||||
{dialect_token::BeginBinaryData, "'\\x"}
|
||||
})
|
||||
{dialect_token::BeginBinaryData, "'\\x"},
|
||||
{dialect_token::Identity, "GENERATED BY DEFAULT AS IDENTITY"}
|
||||
})
|
||||
.with_data_type_replace_map({
|
||||
{matador::utils::basic_type::Int8, "SMALLINT"},
|
||||
{matador::utils::basic_type::UInt8, "SMALLINT"},
|
||||
{matador::utils::basic_type::Float, "REAL"},
|
||||
{matador::utils::basic_type::Double, "DOUBLE PRECISION"},
|
||||
{matador::utils::basic_type::Time, "TIME(6)"},
|
||||
{matador::utils::basic_type::DateTime, "TIMESTAMPTZ(6)"},
|
||||
{matador::utils::basic_type::Blob, "BYTEA"}
|
||||
{matador::utils::basic_type::Int8, "SMALLINT"},
|
||||
{matador::utils::basic_type::UInt8, "SMALLINT"},
|
||||
{matador::utils::basic_type::Float, "REAL"},
|
||||
{matador::utils::basic_type::Double, "DOUBLE PRECISION"},
|
||||
{matador::utils::basic_type::Time, "TIME(6)"},
|
||||
{matador::utils::basic_type::DateTime, "TIMESTAMPTZ(6)"},
|
||||
{matador::utils::basic_type::Blob, "BYTEA"}
|
||||
})
|
||||
.with_bool_strings("TRUE", "FALSE")
|
||||
.with_default_schema_name("public")
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ public:
|
|||
column_builder& not_null();
|
||||
column_builder& primary_key();
|
||||
column_builder& unique();
|
||||
column_builder& identity();
|
||||
|
||||
private:
|
||||
std::string column_name_;
|
||||
|
|
|
|||
|
|
@ -36,11 +36,17 @@ public:
|
|||
query_create_table_columns_intermediate columns(const std::vector<table_column> &columns);
|
||||
};
|
||||
|
||||
class query_create_sequence_intermediate : public executable_query {
|
||||
public:
|
||||
using executable_query::executable_query;
|
||||
};
|
||||
|
||||
class query_create_intermediate : public query_intermediate {
|
||||
public:
|
||||
query_create_intermediate();
|
||||
|
||||
query_create_table_intermediate table(const table &tab);
|
||||
query_create_sequence_intermediate sequence(const std::string &sequence_name);
|
||||
executable_query schema(const std::string &schema_name);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -52,8 +52,6 @@ private:
|
|||
std::vector<table_column> columns_;
|
||||
};
|
||||
|
||||
table operator ""_tab(const char *name, size_t len);
|
||||
|
||||
template<typename Type = table>
|
||||
class typed_table : public table {
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -148,6 +148,7 @@ public:
|
|||
[[nodiscard]] const std::string& foreign_key() const;
|
||||
[[nodiscard]] const std::string& from() const;
|
||||
[[nodiscard]] const std::string& group_by() const;
|
||||
[[nodiscard]] const std::string& identity() const;
|
||||
[[nodiscard]] const std::string& in() const;
|
||||
[[nodiscard]] const std::string& insert() const;
|
||||
[[nodiscard]] const std::string& into() const;
|
||||
|
|
@ -213,9 +214,10 @@ private:
|
|||
{dialect_token::EndBinaryData, "'"},
|
||||
{dialect_token::EndQuote, "\""},
|
||||
{dialect_token::EndStringData, "'"},
|
||||
{dialect_token::ForeignKey, "FOREIGN KEY"},
|
||||
{dialect_token::ForeignKey, "FOREIGN KEY"},
|
||||
{dialect_token::From, "FROM"},
|
||||
{dialect_token::GroupBy, "GROUP BY"},
|
||||
{dialect_token::Identity, "AUTO INCREMENT"},
|
||||
{dialect_token::In, "IN"},
|
||||
{dialect_token::Insert, "INSERT"},
|
||||
{dialect_token::Into, "INTO"},
|
||||
|
|
@ -238,7 +240,7 @@ private:
|
|||
{dialect_token::Schema, "SCHEMA"},
|
||||
{dialect_token::Select, "SELECT"},
|
||||
{dialect_token::Set, "SET"},
|
||||
{dialect_token::StartQuote, "\""},
|
||||
{dialect_token::StartQuote, "\""},
|
||||
{dialect_token::StringQuote, "'"},
|
||||
{dialect_token::Table, "TABLE"},
|
||||
{dialect_token::Unique, "UNIQUE"},
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ enum class dialect_token : uint8_t {
|
|||
ForeignKey,
|
||||
From,
|
||||
GroupBy,
|
||||
Identity,
|
||||
In,
|
||||
Insert,
|
||||
Into,
|
||||
|
|
|
|||
|
|
@ -7,10 +7,11 @@ enum class constraints : unsigned char {
|
|||
None = 0,
|
||||
Index = 1 << 0,
|
||||
Unique = 1 << 1,
|
||||
PrimaryKey = 1 << 2,
|
||||
ForeignKey = 1 << 3,
|
||||
Default = 1 << 4,
|
||||
NotNull = 1 << 5
|
||||
PrimaryKey = 1 << 2,
|
||||
ForeignKey = 1 << 3,
|
||||
Identity = 1 << 4,
|
||||
Default = 1 << 5,
|
||||
NotNull = 1 << 6
|
||||
};
|
||||
|
||||
inline constraints operator|(constraints a, constraints b) { return static_cast<constraints>(static_cast<unsigned int>(a) | static_cast<unsigned int>(b)); }
|
||||
|
|
|
|||
|
|
@ -26,6 +26,11 @@ column_builder & column_builder::unique() {
|
|||
return *this;
|
||||
}
|
||||
|
||||
column_builder& column_builder::identity() {
|
||||
constraints_ |= utils::constraints::Identity;
|
||||
return *this;
|
||||
}
|
||||
|
||||
table_builder::table_builder(std::string name)
|
||||
: table_name( std::move(name) ) {}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,9 @@ query_create_table_intermediate query_create_intermediate::table(const class tab
|
|||
context_->parts.push_back(std::make_unique<internal::query_create_table_part>(tab));
|
||||
return {context_};
|
||||
}
|
||||
query_create_sequence_intermediate query_create_intermediate::sequence(const std::string& sequence_name) {
|
||||
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));
|
||||
|
|
|
|||
|
|
@ -378,6 +378,9 @@ void build_create_column(std::string &out, const table_column &col, const sql::d
|
|||
if (is_constraint_set(col.attributes().options(), utils::constraints::Unique)) {
|
||||
out.append(" ").append(d.unique());
|
||||
}
|
||||
if (is_constraint_set(col.attributes().options(), utils::constraints::Identity)) {
|
||||
out.append(" ").append(d.identity());
|
||||
}
|
||||
if (is_constraint_set(col.attributes().options(), utils::constraints::PrimaryKey)) {
|
||||
out.append(" ").append(d.primary_key());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,35 +13,6 @@
|
|||
namespace matador::query {
|
||||
|
||||
utils::result<void, utils::error> schema::create(const sql::connection &conn) const {
|
||||
// Step 1: Build dependency graph
|
||||
// std::unordered_map<std::string, std::vector<std::string> > dependency_graph;
|
||||
// std::unordered_map<std::string, std::pair<int,object::repository::node_ptr>> in_degree;
|
||||
//
|
||||
// for (const auto &node: repo_) {
|
||||
// for (auto it = node->info().endpoint_begin(); it != node->info().endpoint_end(); ++it) {
|
||||
// dependency_graph[node->name()].push_back(it->second->node().name());
|
||||
//
|
||||
// if (const auto dit = in_degree.find(it->second->node().name()); dit == in_degree.end()) {
|
||||
// in_degree[it->second->node().name()] = std::make_pair(1, it->second->node_ptr());
|
||||
// } else {
|
||||
// in_degree[it->second->node().name()].first++;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Ensure the current node exists in the graph representation
|
||||
// if (in_degree.find(node->name()) == in_degree.end()) {
|
||||
// in_degree[node->name()] = std::make_pair(0, node);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// for (const auto &it : dependency_graph) {
|
||||
// std::cout << "Dependency graph " << it.first << std::endl;
|
||||
// for (const auto &neighbor: it.second) {
|
||||
// std::cout << " " << neighbor << std::endl;
|
||||
// }
|
||||
// std::cout << std::endl;
|
||||
// }
|
||||
|
||||
std::vector<std::string> fk_sql_commands;
|
||||
|
||||
const auto q = query::create().schema(repo_.name()).compile(conn);
|
||||
|
|
@ -52,7 +23,6 @@ utils::result<void, utils::error> schema::create(const sql::connection &conn) co
|
|||
auto ctx = query::query::create()
|
||||
.table(node.name())
|
||||
.columns(node.info().attributes())
|
||||
// .constraints(node->info().constraints())
|
||||
.compile(conn);
|
||||
|
||||
std::cout << ctx.sql << std::endl;
|
||||
|
|
|
|||
|
|
@ -103,10 +103,4 @@ const table_column& table::create_column(class table &tab, const std::string &na
|
|||
tab.columns_.back().table(&tab);
|
||||
return tab.columns_.back();
|
||||
}
|
||||
|
||||
|
||||
table operator ""_tab(const char *name, size_t len) {
|
||||
return {{name, len}};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -175,6 +175,10 @@ const std::string &dialect::from() const {
|
|||
return token_at(dialect_token::From);
|
||||
}
|
||||
|
||||
const std::string &dialect::identity() const {
|
||||
return token_at(dialect_token::Identity);
|
||||
}
|
||||
|
||||
const std::string &dialect::in() const {
|
||||
return token_at(dialect_token::In);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,10 +17,8 @@ TEST_CASE_METHOD(SchemaFixture, "Test schema one-two-many", "[schema][one-to-man
|
|||
using namespace matador::test;
|
||||
query::schema repo;
|
||||
|
||||
// auto result = repo.attach<department>("departments")
|
||||
// .and_then([&repo] { return repo.attach<employee>("employees"); });
|
||||
auto result = repo.attach<employee>("employees")
|
||||
.and_then([&repo] { return repo.attach<department>("departments"); });
|
||||
auto result = repo.attach<department>("departments")
|
||||
.and_then([&repo] { return repo.attach<employee>("employees"); });
|
||||
REQUIRE(result);
|
||||
|
||||
auto conn = pool.acquire();
|
||||
|
|
|
|||
|
|
@ -44,8 +44,8 @@ utils::result<utils::version, utils::error> test_connection::server_version() co
|
|||
return utils::ok(utils::version{3, 2, 1});
|
||||
}
|
||||
|
||||
utils::result<size_t, utils::error> test_connection::execute(const std::string &/*stmt*/) {
|
||||
return utils::ok(static_cast<size_t>(4));
|
||||
utils::result<sql::execute_result, utils::error> test_connection::execute(const sql::query_context &/*context*/) {
|
||||
return utils::ok(sql::execute_result{4});
|
||||
}
|
||||
|
||||
utils::result<std::unique_ptr<sql::query_result_impl>, utils::error> test_connection::fetch(const sql::query_context &context) {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#define QUERY_NOOP_CONNECTION_HPP
|
||||
|
||||
#include "matador/sql/interface/connection_impl.hpp"
|
||||
#include "matador/sql/execute_result.hpp"
|
||||
|
||||
namespace matador::test::orm {
|
||||
|
||||
|
|
@ -16,7 +17,7 @@ public:
|
|||
[[nodiscard]] utils::result<bool, utils::error> is_valid() const override;
|
||||
[[nodiscard]] utils::result<utils::version, utils::error> client_version() const override;
|
||||
[[nodiscard]] utils::result<utils::version, utils::error> server_version() const override;
|
||||
utils::result<size_t, utils::error> execute(const std::string &stmt) override;
|
||||
utils::result<sql::execute_result, utils::error> execute(const sql::query_context &context) override;
|
||||
utils::result<std::unique_ptr<sql::query_result_impl>, utils::error> fetch(const sql::query_context &context) override;
|
||||
utils::result<std::unique_ptr<sql::statement_impl>, utils::error> prepare(const sql::query_context &context) override;
|
||||
utils::result<std::vector<object::attribute>, utils::error> describe(const std::string &table) override;
|
||||
|
|
|
|||
|
|
@ -10,12 +10,12 @@ namespace matador::test::orm {
|
|||
test_statement::test_statement(const sql::query_context &query)
|
||||
: statement_impl(query, 0) {}
|
||||
|
||||
utils::result<size_t, utils::error> test_statement::execute(const sql::parameter_binder &/*bindings*/) {
|
||||
utils::result<sql::execute_result, utils::error> test_statement::execute(const sql::parameter_binder &/*bindings*/) {
|
||||
using namespace std::chrono_literals;
|
||||
std::mt19937 rng(query_.sql.size());
|
||||
std::uniform_int_distribution dist(10, 50);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(dist(rng)));
|
||||
return utils::ok(static_cast<size_t>(8));
|
||||
return utils::ok(sql::execute_result{8});
|
||||
}
|
||||
|
||||
utils::result<std::unique_ptr<sql::query_result_impl>, utils::error> test_statement::fetch(const sql::parameter_binder &/*bindings*/) {
|
||||
|
|
|
|||
|
|
@ -2,13 +2,14 @@
|
|||
#define TEST_STATEMENT_HPP
|
||||
|
||||
#include "matador/sql/interface/statement_impl.hpp"
|
||||
#include "matador/sql/execute_result.hpp"
|
||||
|
||||
namespace matador::test::orm {
|
||||
|
||||
class test_statement final : public sql::statement_impl {
|
||||
public:
|
||||
explicit test_statement(const sql::query_context &query);
|
||||
utils::result<size_t, utils::error> execute(const sql::parameter_binder &bindings) override;
|
||||
utils::result<sql::execute_result, utils::error> execute(const sql::parameter_binder &bindings) override;
|
||||
utils::result<std::unique_ptr<sql::query_result_impl>, utils::error> fetch(const sql::parameter_binder &bindings) override;
|
||||
void reset() override;
|
||||
|
||||
|
|
|
|||
|
|
@ -50,6 +50,17 @@ TEST_CASE_METHOD(QueryFixture, "Test create table sql statement string", "[query
|
|||
|
||||
REQUIRE(result == R"##(CREATE TABLE "person" ("id" BIGINT NOT NULL, "name" VARCHAR(255) NOT NULL, "age" INTEGER NOT NULL, CONSTRAINT PK_person PRIMARY KEY (id)))##");
|
||||
|
||||
result = query::create()
|
||||
.table({"person"})
|
||||
.columns({
|
||||
column("id", basic_type::UInt32).primary_key().identity(),
|
||||
column("name", basic_type::Varchar, 255),
|
||||
column("age", basic_type::UInt16)
|
||||
})
|
||||
.str(*db);
|
||||
|
||||
REQUIRE(result == R"##(CREATE TABLE "person" ("id" BIGINT NOT NULL AUTO INCREMENT PRIMARY KEY, "name" VARCHAR(255) NOT NULL, "age" INTEGER NOT NULL))##");
|
||||
|
||||
auto ctx = query::create()
|
||||
.table("person")
|
||||
.columns({
|
||||
|
|
|
|||
|
|
@ -58,15 +58,15 @@ int record_printer::width(const sql::field &f) {
|
|||
// If it's a varchar/string and has a defined size, use it if it's reasonable,
|
||||
// otherwise fall back to type defaults.
|
||||
if ((f.is_varchar() || f.is_string()) && f.size() > 0 && f.size() < 100) {
|
||||
return std::max(f.name().length(), f.size());
|
||||
return static_cast<int>(std::max(f.name().length(), f.size()));
|
||||
}
|
||||
|
||||
// Find the default width for type
|
||||
// Note: field class doesn't expose basic_type directly but we can use value().type()
|
||||
// if we had access. For now we use name length as minimum.
|
||||
// Note: field class doesn't expose basic_type directly, but we can use value().type()
|
||||
// if we had access. For now we use name length as a minimum.
|
||||
constexpr size_t w = 15;
|
||||
// In a real implementation we would probe the field's underlying type.
|
||||
|
||||
return std::max(f.name().length(), w);
|
||||
return static_cast<int>(std::max(f.name().length(), w));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue