runtime: move runtime types into a directory

This commit is contained in:
Danny Robson 2022-06-23 07:07:49 +10:00
parent 689bc6b60d
commit 18484dd57b
19 changed files with 222 additions and 185 deletions

View File

@ -9,20 +9,19 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR})
###############################################################################
add_library(cruft-db
fwd.hpp
column.cpp
column.hpp
constraint.cpp
constraint.hpp
index.cpp
index.hpp
ostream.cpp
ostream.hpp
schema.cpp
schema.hpp
table.cpp
table.hpp
runtime/fwd.hpp
runtime/column.cpp
runtime/column.hpp
runtime/constraint.cpp
runtime/constraint.hpp
runtime/index.cpp
runtime/index.hpp
runtime/ostream.cpp
runtime/ostream.hpp
runtime/schema.cpp
runtime/schema.hpp
runtime/table.cpp
runtime/table.hpp
introspection/information_schema.hpp
introspection/information_schema.cpp

View File

@ -8,9 +8,9 @@
#include "./information_schema.hpp"
#include "../column.hpp"
#include "../schema.hpp"
#include "../table.hpp"
#include "../runtime/column.hpp"
#include "../runtime/schema.hpp"
#include "../runtime/table.hpp"
#include <cruft/pq/connection.hpp>
#include <cruft/pq/result.hpp>
@ -24,26 +24,26 @@
///////////////////////////////////////////////////////////////////////////////
static std::map<
std::string,
cruft::db::type,
cruft::db::runtime::type,
std::less<>
>
const STRING_TO_TYPE {
{ "real", cruft::db::type::REAL },
{ "double precision", cruft::db::type::REAL },
{ "boolean", cruft::db::type::BOOLEAN },
{ "smallint", cruft::db::type::INTEGER },
{ "bigint", cruft::db::type::INTEGER },
{ "integer", cruft::db::type::INTEGER },
{ "text", cruft::db::type::STRING },
{ "character varying", cruft::db::type::STRING },
{ "USER-DEFINED", cruft::db::type::UDT },
{ "jsonb", cruft::db::type::JSON },
{ "timestamp without time zone", cruft::db::type::TIMESTAMP },
{ "real", cruft::db::runtime::type::REAL },
{ "double precision", cruft::db::runtime::type::REAL },
{ "boolean", cruft::db::runtime::type::BOOLEAN },
{ "smallint", cruft::db::runtime::type::INTEGER },
{ "bigint", cruft::db::runtime::type::INTEGER },
{ "integer", cruft::db::runtime::type::INTEGER },
{ "text", cruft::db::runtime::type::STRING },
{ "character varying", cruft::db::runtime::type::STRING },
{ "USER-DEFINED", cruft::db::runtime::type::UDT },
{ "jsonb", cruft::db::runtime::type::JSON },
{ "timestamp without time zone", cruft::db::runtime::type::TIMESTAMP },
};
//-----------------------------------------------------------------------------
static cruft::db::type
static cruft::db::runtime::type
string_to_type [[maybe_unused]] (std::string_view name)
{
auto const pos = STRING_TO_TYPE.find (name);
@ -71,25 +71,25 @@ enum column_fields { COLUMN_FIELDS(LIST_LIST), };
///////////////////////////////////////////////////////////////////////////////
static cruft::db::real_t::subtype_t
static cruft::db::runtime::real_t::subtype_t
data_type_to_real_subtype (std::string_view str)
{
if (str == "real")
return cruft::db::real_t::REAL;
return cruft::db::runtime::real_t::REAL;
if (str == "double precision")
return cruft::db::real_t::DOUBLE;
return cruft::db::runtime::real_t::DOUBLE;
if (str == "float")
return cruft::db::real_t::FLOAT;
return cruft::db::runtime::real_t::FLOAT;
throw std::out_of_range (fmt::format ("Unhandled real subtype {}", str));
}
//-----------------------------------------------------------------------------
static cruft::db::detail_t
static cruft::db::runtime::detail_t
extract_column_real (cruft::pq::result const &rows, int const idx)
{
return cruft::db::real_t {
return cruft::db::runtime::real_t {
.subtype = data_type_to_real_subtype (
*rows.get<std::string_view> (idx, data_type)
),
@ -99,25 +99,25 @@ extract_column_real (cruft::pq::result const &rows, int const idx)
///////////////////////////////////////////////////////////////////////////////
static cruft::db::integer_t::subtype_t
static cruft::db::runtime::integer_t::subtype_t
data_type_to_integer_subtype (std::string_view str)
{
if (str == "smallint")
return cruft::db::integer_t::SMALLINT;
return cruft::db::runtime::integer_t::SMALLINT;
if (str == "integer")
return cruft::db::integer_t::INTEGER;
return cruft::db::runtime::integer_t::INTEGER;
if (str == "bigint")
return cruft::db::integer_t::BIGINT;
return cruft::db::runtime::integer_t::BIGINT;
throw std::out_of_range (fmt::format ("Unhandled integer subtype {}", str));
}
//-----------------------------------------------------------------------------
static cruft::db::detail_t
static cruft::db::runtime::detail_t
extract_column_integer (cruft::pq::result const &rows, int const idx)
{
return cruft::db::integer_t {
return cruft::db::runtime::integer_t {
.subtype = data_type_to_integer_subtype (
*rows.get<std::string_view> (idx, data_type)
)
@ -126,10 +126,10 @@ extract_column_integer (cruft::pq::result const &rows, int const idx)
///////////////////////////////////////////////////////////////////////////////
static cruft::db::detail_t
static cruft::db::runtime::detail_t
extract_column_udt (cruft::pq::result const &rows, int const idx)
{
return cruft::db::udt_t {
return cruft::db::runtime::udt_t {
.schema = *rows.get<std::string> (idx, udt_schema),
.name = *rows.get<std::string> (idx, udt_name ),
};
@ -137,24 +137,24 @@ extract_column_udt (cruft::pq::result const &rows, int const idx)
///////////////////////////////////////////////////////////////////////////////
cruft::db::json_t::subtype_t
cruft::db::runtime::json_t::subtype_t
string_to_json_subtype (std::string_view str)
{
if (str == "json")
return cruft::db::json_t::TEXT;
return cruft::db::runtime::json_t::TEXT;
if (str == "jsonb")
return cruft::db::json_t::BINARY;
return cruft::db::runtime::json_t::BINARY;
throw std::out_of_range (fmt::format ("Unhandled JSON type {}", str));
}
//-----------------------------------------------------------------------------
static cruft::db::detail_t
static cruft::db::runtime::detail_t
extract_column_json (cruft::pq::result const &rows, int const idx)
{
return cruft::db::json_t {
return cruft::db::runtime::json_t {
.subtype = string_to_json_subtype (
*rows.get<std::string_view> (idx, data_type)
),
@ -163,7 +163,7 @@ extract_column_json (cruft::pq::result const &rows, int const idx)
///////////////////////////////////////////////////////////////////////////////
static cruft::db::detail_t
static cruft::db::runtime::detail_t
extract_column_timestamp (cruft::pq::result const &rows, int const idx)
{
auto const _data_type = *rows.get<std::string_view> (idx, data_type);
@ -172,7 +172,7 @@ extract_column_timestamp (cruft::pq::result const &rows, int const idx)
_data_type == "timestamp without time zone" ? false :
(throw std::out_of_range ("Unknown timezone status"), false);
return cruft::db::timestamp_t {
return cruft::db::runtime::timestamp_t {
.precision = *rows.get<int> (idx, datetime_precision),
.timezone = has_timezone,
};
@ -180,23 +180,23 @@ extract_column_timestamp (cruft::pq::result const &rows, int const idx)
///////////////////////////////////////////////////////////////////////////////
cruft::db::string_t::subtype_t
cruft::db::runtime::string_t::subtype_t
data_type_to_string_subtype (std::string_view str)
{
if (str == "text")
return cruft::db::string_t::TEXT;
return cruft::db::runtime::string_t::TEXT;
if (str == "character varying")
return cruft::db::string_t::VARCHAR;
return cruft::db::runtime::string_t::VARCHAR;
throw std::out_of_range (fmt::format ("Unhandled string subtype {}", str));
}
//-----------------------------------------------------------------------------
static cruft::db::detail_t
static cruft::db::runtime::detail_t
extract_column_string (cruft::pq::result const &rows, int const idx)
{
return cruft::db::string_t {
return cruft::db::runtime::string_t {
.subtype = data_type_to_string_subtype (
*rows.get<std::string_view> (idx, data_type)
),
@ -207,17 +207,17 @@ extract_column_string (cruft::pq::result const &rows, int const idx)
///////////////////////////////////////////////////////////////////////////////
static cruft::db::detail_t
static cruft::db::runtime::detail_t
extract_column_boolean (cruft::pq::result const &, int const idx)
{
(void)idx;
return cruft::db::boolean_t { };
return cruft::db::runtime::boolean_t { };
}
///////////////////////////////////////////////////////////////////////////////
using detail_loader_t = cruft::db::detail_t (*) (cruft::pq::result const&, int);
using detail_loader_t = cruft::db::runtime::detail_t (*) (cruft::pq::result const&, int);
//-----------------------------------------------------------------------------
@ -246,7 +246,7 @@ yes_no_to_bool (std::string_view str)
///////////////////////////////////////////////////////////////////////////////
cruft::db::table
cruft::db::runtime::table
cruft::db::introspection::information_schema::extract_table (
cruft::pq::connection &conn,
std::string_view table_name
@ -261,7 +261,7 @@ cruft::db::introspection::information_schema::extract_table (
);
rows.try_status (PGRES_TUPLES_OK);
table res {
cruft::db::runtime::table res {
.name = std::string (table_name),
.columns = {},
};
@ -291,7 +291,7 @@ cruft::db::introspection::information_schema::extract_table (
///////////////////////////////////////////////////////////////////////////////
cruft::db::schema
cruft::db::runtime::schema
cruft::db::introspection::information_schema::extract_schema (
cruft::pq::connection &conn,
std::string_view schema_name
@ -302,7 +302,7 @@ cruft::db::introspection::information_schema::extract_schema (
);
rows.try_status (PGRES_TUPLES_OK);
schema res;
cruft::db::runtime::schema res;
for (int i = 0, last = rows.size (); i != last; ++i) {
res.tables.push_back (
extract_table (

View File

@ -8,19 +8,19 @@
#pragma once
#include "../fwd.hpp"
#include "../runtime/fwd.hpp"
#include <cruft/pq/fwd.hpp>
#include <string_view>
namespace cruft::db::introspection::information_schema {
table extract_table (
runtime::table extract_table (
cruft::pq::connection &,
std::string_view name
);
schema extract_schema (
runtime::schema extract_schema (
cruft::pq::connection &,
std::string_view name
);

View File

@ -1,17 +1,19 @@
#include "./postgresql.hpp"
#include "../column.hpp"
#include "../table.hpp"
#include "../schema.hpp"
#include "../index.hpp"
#include "../runtime/column.hpp"
#include "../runtime/table.hpp"
#include "../runtime/schema.hpp"
#include "../runtime/index.hpp"
#include <cruft/pq/connection.hpp>
#include <cruft/pq/array.hpp>
#include <catalog/pg_class_d.h>
#include <catalog/pg_constraint_d.h>
// Reference:
// https://www.postgresql.org/docs/current/catalogs.html
///////////////////////////////////////////////////////////////////////////////
static
@ -32,7 +34,7 @@ array_to_strings (std::span<std::byte const> data)
///////////////////////////////////////////////////////////////////////////////
static
std::vector<cruft::db::enumeration>
std::vector<cruft::db::runtime::enumeration>
extract_enums (cruft::pq::connection &conn)
{
enum columns_t {
@ -54,7 +56,7 @@ extract_enums (cruft::pq::connection &conn)
auto const rows = conn.exec (SQL);
rows.try_status (PGRES_TUPLES_OK);
std::vector<cruft::db::enumeration> res;
std::vector<cruft::db::runtime::enumeration> res;
for (int i = 0, last = rows.size (); i != last; ++i) {
cruft::pq::array values_arr (rows.get_bytes (i, VALUES));
@ -63,7 +65,7 @@ extract_enums (cruft::pq::connection &conn)
for (auto const &raw: values_arr)
values.emplace_back (reinterpret_cast<char const*> (raw.data ()), raw.size ());
res.push_back (cruft::db::enumeration {
res.push_back (cruft::db::runtime::enumeration {
.oid = *rows.get<Oid> (i, OID),
.name = std::string (*rows.get<std::string_view> (i, TYPNAME)),
.values = std::move (values),
@ -76,7 +78,7 @@ extract_enums (cruft::pq::connection &conn)
///////////////////////////////////////////////////////////////////////////////
static
std::vector<cruft::db::index>
std::vector<cruft::db::runtime::index>
extract_indices (cruft::pq::connection &conn)
{
enum {
@ -113,10 +115,10 @@ extract_indices (cruft::pq::connection &conn)
auto const rows = conn.exec (SQL);
rows.try_status (PGRES_TUPLES_OK);
std::vector<cruft::db::index> res;
std::vector<cruft::db::runtime::index> res;
std::vector<std::string> columns;
std::vector<cruft::db::expression> expressions;
std::vector<cruft::db::runtime::expression> expressions;
for (int i = 0, last = rows.size (); i != last; ++i) {
if (auto const bytes = rows.get_bytes (i, INDKEY); !bytes.empty ()) {
@ -131,7 +133,7 @@ extract_indices (cruft::pq::connection &conn)
expressions.resize (arr.size ());
}
res.push_back (cruft::db::index {
res.push_back (cruft::db::runtime::index {
.name = std::string (*rows.get<std::string_view> (i, INDEX_RELNAME)),
.table = std::string (*rows.get<std::string_view> (i, TABLE_RELNAME)),
.columns = std::move (columns),
@ -166,18 +168,18 @@ enum {
//-----------------------------------------------------------------------------
static
cruft::db::constraint::referential_t
cruft::db::runtime::constraint::referential_t
char_to_referential [[gnu::pure]] (char const c)
{
// Use the fact we define these constants in terms of the values PostgreSQL
// returns for convenience.
switch (c) {
case cruft::db::constraint::NOACTION:
case cruft::db::constraint::CASCADE:
case cruft::db::constraint::RESTRICT:
case cruft::db::constraint::SETNULL:
case cruft::db::constraint::SETDEFAULT:
return cruft::db::constraint::referential_t (c);
case cruft::db::runtime::constraint::NOACTION:
case cruft::db::runtime::constraint::CASCADE:
case cruft::db::runtime::constraint::RESTRICT:
case cruft::db::runtime::constraint::SETNULL:
case cruft::db::runtime::constraint::SETDEFAULT:
return cruft::db::runtime::constraint::referential_t (c);
default:
throw std::runtime_error (
@ -189,10 +191,10 @@ char_to_referential [[gnu::pure]] (char const c)
//-----------------------------------------------------------------------------
static
cruft::db::constraint::base
cruft::db::runtime::constraint::base
extract_constraint_base (cruft::pq::result const &rows, int const idx)
{
return cruft::db::constraint::base {
return cruft::db::runtime::constraint::base {
.name = std::string (*rows.get<std::string_view> (idx, CONSTRAINT_CONNAME)),
.table = std::string (*rows.get<std::string_view> (idx, CONSTRAINT_CONRELID)),
.deferrable = *rows.get<bool> (idx, CONSTRAINT_CONDEFERRABLE),
@ -203,11 +205,11 @@ extract_constraint_base (cruft::pq::result const &rows, int const idx)
//-----------------------------------------------------------------------------
static
cruft::db::constraint::check
cruft::db::runtime::constraint::check
extract_constraint_check (cruft::pq::result const &rows, int const idx)
{
// HACK: Mostly unimplemented for convenience right now
return cruft::db::constraint::check {
return cruft::db::runtime::constraint::check {
extract_constraint_base (rows, idx),
};
}
@ -215,10 +217,10 @@ extract_constraint_check (cruft::pq::result const &rows, int const idx)
//-----------------------------------------------------------------------------
static
cruft::db::constraint::foreign
cruft::db::runtime::constraint::foreign
extract_constraint_foreign (cruft::pq::result const &rows, int const idx)
{
return cruft::db::constraint::foreign {
return cruft::db::runtime::constraint::foreign {
extract_constraint_base (rows, idx),
array_to_strings (rows.get_bytes (idx, CONSTRAINT_LKEY)),
std::string (*rows.get<std::string_view> (idx, CONSTRAINT_CONFRELID)),
@ -231,10 +233,10 @@ extract_constraint_foreign (cruft::pq::result const &rows, int const idx)
//-----------------------------------------------------------------------------
static
cruft::db::constraint::unique
cruft::db::runtime::constraint::unique
extract_constraint_unique (cruft::pq::result const &rows, int const idx)
{
return cruft::db::constraint::unique {
return cruft::db::runtime::constraint::unique {
extract_constraint_base (rows, idx),
array_to_strings (rows.get_bytes (idx, CONSTRAINT_LKEY)),
};
@ -243,10 +245,10 @@ extract_constraint_unique (cruft::pq::result const &rows, int const idx)
//-----------------------------------------------------------------------------
static
cruft::db::constraint::primary
cruft::db::runtime::constraint::primary
extract_constraint_primary (cruft::pq::result const &rows, int const idx)
{
return cruft::db::constraint::primary {
return cruft::db::runtime::constraint::primary {
extract_constraint_base (rows, idx),
array_to_strings (rows.get_bytes (idx, CONSTRAINT_LKEY)),
};
@ -255,7 +257,7 @@ extract_constraint_primary (cruft::pq::result const &rows, int const idx)
//-----------------------------------------------------------------------------
static
std::vector<cruft::db::constraint::any>
std::vector<cruft::db::runtime::constraint::any>
extract_constraints (cruft::pq::connection &conn)
{
static constexpr char const SQL[] =
@ -291,7 +293,7 @@ extract_constraints (cruft::pq::connection &conn)
auto const rows = conn.exec (SQL);
rows.try_status (PGRES_TUPLES_OK);
std::vector<cruft::db::constraint::any> res;
std::vector<cruft::db::runtime::constraint::any> res;
for (int i = 0, last = rows.size (); i != last; ++i) {
switch (auto const contype = *rows.get<char> (i, CONSTRAINT_CONTYPE); contype) {
@ -338,10 +340,10 @@ enum tablecolumns {
//-----------------------------------------------------------------------------
static
cruft::db::detail_t
cruft::db::runtime::detail_t
extract_column_enum (cruft::pq::result const &rows, int idx)
{
return cruft::db::enumeration_t {
return cruft::db::runtime::enumeration_t {
.oid = *rows.get<Oid> (idx, atttypid),
};
}
@ -349,27 +351,27 @@ extract_column_enum (cruft::pq::result const &rows, int idx)
//-----------------------------------------------------------------------------
static
cruft::db::detail_t
cruft::db::runtime::detail_t
extract_column_numeric (cruft::pq::result const &rows, int idx)
{
auto const typeoid = *rows.get<Oid> (idx, atttypid);
switch (typeoid) {
case INT2OID:
return cruft::db::integer_t { .subtype = cruft::db::integer_t::SMALLINT };
return cruft::db::runtime::integer_t { .subtype = cruft::db::runtime::integer_t::SMALLINT };
case INT4OID:
return cruft::db::integer_t { .subtype = cruft::db::integer_t::INTEGER };
return cruft::db::runtime::integer_t { .subtype = cruft::db::runtime::integer_t::INTEGER };
case INT8OID:
return cruft::db::integer_t { .subtype = cruft::db::integer_t::BIGINT };
return cruft::db::runtime::integer_t { .subtype = cruft::db::runtime::integer_t::BIGINT };
case FLOAT4OID:
return cruft::db::real_t {
.subtype = cruft::db::real_t::subtype_t::REAL,
return cruft::db::runtime::real_t {
.subtype = cruft::db::runtime::real_t::subtype_t::REAL,
.precision = 0,
};
case FLOAT8OID:
return cruft::db::real_t {
.subtype = cruft::db::real_t::subtype_t::DOUBLE,
return cruft::db::runtime::real_t {
.subtype = cruft::db::runtime::real_t::subtype_t::DOUBLE,
.precision = 0,
};
}
@ -380,20 +382,20 @@ extract_column_numeric (cruft::pq::result const &rows, int idx)
//-----------------------------------------------------------------------------
static
cruft::db::detail_t
cruft::db::runtime::detail_t
extract_column_string (cruft::pq::result const &rows, int idx)
{
auto const typeoid = *rows.get<Oid> (idx, atttypid);
auto const subtype =
typeoid == VARCHAROID ? cruft::db::string_t::subtype_t::VARCHAR :
typeoid == TEXTOID ? cruft::db::string_t::subtype_t::TEXT :
typeoid == VARCHAROID ? cruft::db::runtime::string_t::subtype_t::VARCHAR :
typeoid == TEXTOID ? cruft::db::runtime::string_t::subtype_t::TEXT :
(
throw std::runtime_error (fmt::format ("Unhandled string OID {}", typeoid)),
cruft::db::string_t::subtype_t::VARCHAR
cruft::db::runtime::string_t::subtype_t::VARCHAR
);
return cruft::db::string_t {
return cruft::db::runtime::string_t {
.subtype = subtype,
.length = {},
.octets = -1,
@ -402,18 +404,18 @@ extract_column_string (cruft::pq::result const &rows, int idx)
//-----------------------------------------------------------------------------
static cruft::db::detail_t
static cruft::db::runtime::detail_t
extract_column_boolean (cruft::pq::result const &rows, int idx)
{
(void)rows;
(void)idx;
return cruft::db::boolean_t { };
return cruft::db::runtime::boolean_t { };
}
//-----------------------------------------------------------------------------
static cruft::db::detail_t
static cruft::db::runtime::detail_t
extract_column_datetime (cruft::pq::result const &rows, int idx)
{
bool tz = false;
@ -430,7 +432,7 @@ extract_column_datetime (cruft::pq::result const &rows, int idx)
throw std::runtime_error (fmt::format ("Unhandled datetime OID {}", typeoid));
}
return cruft::db::timestamp_t {
return cruft::db::runtime::timestamp_t {
.precision = 0,
.timezone = tz,
};
@ -438,14 +440,14 @@ extract_column_datetime (cruft::pq::result const &rows, int idx)
//-----------------------------------------------------------------------------
static cruft::db::detail_t
static cruft::db::runtime::detail_t
extract_column_user (cruft::pq::result const &rows, int idx)
{
switch (auto const typeoid = *rows.get<Oid> (idx, atttypid); typeoid) {
case JSONOID:
return cruft::db::json_t { .subtype = cruft::db::json_t::subtype_t::TEXT, };
return cruft::db::runtime::json_t { .subtype = cruft::db::runtime::json_t::subtype_t::TEXT, };
case JSONBOID:
return cruft::db::json_t { .subtype = cruft::db::json_t::subtype_t::BINARY, };
return cruft::db::runtime::json_t { .subtype = cruft::db::runtime::json_t::subtype_t::BINARY, };
default:
throw std::runtime_error (fmt::format ("Unhandled user OID {}", typeoid));
@ -454,7 +456,7 @@ extract_column_user (cruft::pq::result const &rows, int idx)
///////////////////////////////////////////////////////////////////////////////
cruft::db::table
cruft::db::runtime::table
cruft::db::introspection::postgresql::extract_table (
cruft::pq::connection &conn,
std::string_view name
@ -487,12 +489,12 @@ cruft::db::introspection::postgresql::extract_table (
auto const rows = conn.exec (sql, name);
rows.try_status (PGRES_TUPLES_OK);
std::vector<column> columns;
std::vector<runtime::column> columns;
for (int i = 0, last = rows.size (); i != last; ++i) {
auto const cat = *rows.get<char> (i, typcategory);
using loader_t = detail_t (*) (cruft::pq::result const&, int);
using loader_t = runtime::detail_t (*) (cruft::pq::result const&, int);
loader_t loader =
cat == TYPCATEGORY_ENUM ? extract_column_enum :
@ -503,17 +505,17 @@ cruft::db::introspection::postgresql::extract_table (
cat == TYPCATEGORY_USER ? extract_column_user :
(throw std::runtime_error (fmt::format ("Unhandled type category {}", cat)), nullptr);
auto &obj = columns.emplace_back (column {
auto &obj = columns.emplace_back (runtime::column {
.name = std::string (*rows.get<std::string_view> (i, attname)),
.nullable = not *rows.get<bool> (i, attnotnull),
.type_ = type::UDT,
.type_ = runtime::type::UDT,
.detail = (*loader) (rows, i),
});
obj.type_ = std::visit ([] (auto const &val) { return val.base; }, obj.detail);
}
return table {
return runtime::table {
.name = std::string (name),
.columns = std::move (columns),
};
@ -521,7 +523,7 @@ cruft::db::introspection::postgresql::extract_table (
///////////////////////////////////////////////////////////////////////////////
cruft::db::schema
cruft::db::runtime::schema
cruft::db::introspection::postgresql::extract_schema (
cruft::pq::connection &conn,
std::string_view name
@ -545,7 +547,7 @@ cruft::db::introspection::postgresql::extract_schema (
auto const rows = conn.exec (sql, name);
rows.try_status (PGRES_TUPLES_OK);
schema res {
runtime::schema res {
.enumerations = extract_enums (conn),
.tables = {},
.indices = extract_indices (conn),

View File

@ -8,7 +8,7 @@
#pragma once
#include "./fwd.hpp"
#include "../runtime/fwd.hpp"
#include <cruft/pq/fwd.hpp>
@ -16,6 +16,6 @@
namespace cruft::db::introspection::postgresql {
table extract_table (cruft::pq::connection &, std::string_view name);
schema extract_schema (cruft::pq::connection &, std::string_view name);
runtime::table extract_table (cruft::pq::connection &, std::string_view name);
runtime::schema extract_schema (cruft::pq::connection &, std::string_view name);
}

View File

@ -16,7 +16,7 @@
#include <vector>
namespace cruft::db {
namespace cruft::db::runtime {
struct real_t {
static constexpr type base = type::REAL;
enum subtype_t { FLOAT, REAL, DOUBLE } subtype;

View File

@ -13,7 +13,7 @@
#include <vector>
namespace cruft::db::constraint {
namespace cruft::db::runtime::constraint {
// The values of these constants are the same as pg_constraint.confupdype
// and friends from PostgreSQL. This should be considered an
// implementation convenience and not a deliberate design choice.

View File

@ -8,7 +8,7 @@
#pragma once
namespace cruft::db {
namespace cruft::db::runtime {
enum class type {
REAL,
BOOLEAN,

View File

@ -11,11 +11,11 @@
#include <string>
#include <vector>
namespace cruft::db {
namespace cruft::db::runtime {
struct expression {};
}
namespace cruft::db {
namespace cruft::db::runtime {
struct index {
std::string name;

View File

@ -24,7 +24,7 @@
///////////////////////////////////////////////////////////////////////////////
std::ostream&
cruft::db::operator<< (std::ostream &os, type const val)
cruft::db::runtime::operator<< (std::ostream &os, type const val)
{
fmt::print (os, "{}", std::quoted (cruft::introspection::to_string (val)));
return os;
@ -33,7 +33,7 @@ cruft::db::operator<< (std::ostream &os, type const val)
//-----------------------------------------------------------------------------
std::ostream&
cruft::db::operator<< (std::ostream &os, column const &val)
cruft::db::runtime::operator<< (std::ostream &os, column const &val)
{
fmt::print (os,
R"({{ "name": {}, "type": {} }})",
@ -46,7 +46,7 @@ cruft::db::operator<< (std::ostream &os, column const &val)
//-----------------------------------------------------------------------------
std::ostream&
cruft::db::operator<< (std::ostream &os, table const &val)
cruft::db::runtime::operator<< (std::ostream &os, table const &val)
{
fmt::print (
os,
@ -61,7 +61,7 @@ cruft::db::operator<< (std::ostream &os, table const &val)
//-----------------------------------------------------------------------------
std::ostream&
cruft::db::operator<< (std::ostream &os, schema const &val)
cruft::db::runtime::operator<< (std::ostream &os, schema const &val)
{
fmt::print (
os,

View File

@ -13,7 +13,7 @@
#include <iosfwd>
namespace cruft::db {
namespace cruft::db::runtime {
std::ostream& operator<< (std::ostream &os, type const val);
std::ostream& operator<< (std::ostream &os, column const &val);
std::ostream& operator<< (std::ostream &os, table const &val);

View File

@ -15,7 +15,7 @@
#include <vector>
namespace cruft::db {
namespace cruft::db::runtime {
struct enumeration {
unsigned oid;
std::string name;

View File

@ -13,7 +13,7 @@
#include <string>
#include <vector>
namespace cruft::db {
namespace cruft::db::runtime {
struct table {
std::string name;
std::vector<column> columns;

View File

@ -6,12 +6,12 @@
* Copyright 2022, Danny Robson <danny@nerdcruft.net>
*/
#include <cruft/db/column.hpp>
#include <cruft/db/schema.hpp>
#include <cruft/db/table.hpp>
#include <cruft/db/runtime/column.hpp>
#include <cruft/db/runtime/schema.hpp>
#include <cruft/db/runtime/table.hpp>
#include <cruft/db/runtime/ostream.hpp>
#include <cruft/db/introspection/information_schema.hpp>
#include <cruft/db/introspection/postgresql.hpp>
#include <cruft/db/ostream.hpp>
#include <cruft/pq/connection.hpp>
@ -28,8 +28,11 @@
///////////////////////////////////////////////////////////////////////////////
static std::ostream&
print_sql (std::ostream &os, cruft::db::schema const &, cruft::db::real_t const &val)
{
print_sql (
std::ostream &os,
cruft::db::runtime::schema const &,
cruft::db::runtime::real_t const &val
) {
static constexpr char const* NAMES[] = {
"FLOAT",
"REAL",
@ -43,8 +46,11 @@ print_sql (std::ostream &os, cruft::db::schema const &, cruft::db::real_t const
//-----------------------------------------------------------------------------
static std::ostream&
print_sql (std::ostream &os, cruft::db::schema const &, cruft::db::integer_t const &val)
{
print_sql (
std::ostream &os,
cruft::db::runtime::schema const &,
cruft::db::runtime::integer_t const &val
) {
static constexpr char const* NAMES[] = {
"SMALLINT",
"INTEGER",
@ -57,8 +63,11 @@ print_sql (std::ostream &os, cruft::db::schema const &, cruft::db::integer_t con
//-----------------------------------------------------------------------------
static std::ostream&
print_sql (std::ostream &os, cruft::db::schema const &, cruft::db::udt_t const &val)
{
print_sql (
std::ostream &os,
cruft::db::runtime::schema const &,
cruft::db::runtime::udt_t const &val
) {
fmt::print (os, "{}.{}", val.schema, val.name);
return os;
}
@ -66,8 +75,11 @@ print_sql (std::ostream &os, cruft::db::schema const &, cruft::db::udt_t const &
//-----------------------------------------------------------------------------
static std::ostream&
print_sql (std::ostream &os, cruft::db::schema const &, cruft::db::timestamp_t const &val)
{
print_sql (
std::ostream &os,
cruft::db::runtime::schema const &,
cruft::db::runtime::timestamp_t const &val
) {
os << "TIMESTAMP";
if (val.timezone)
os << "WITH TIME ZONE";
@ -77,11 +89,14 @@ print_sql (std::ostream &os, cruft::db::schema const &, cruft::db::timestamp_t c
//-----------------------------------------------------------------------------
static std::ostream&
print_sql (std::ostream &os, cruft::db::schema const &, cruft::db::json_t const &val)
{
print_sql (
std::ostream &os,
cruft::db::runtime::schema const &,
cruft::db::runtime::json_t const &val
) {
switch (val.subtype) {
case cruft::db::json_t::TEXT: return os << "JSON";
case cruft::db::json_t::BINARY: return os << "JSONB";
case cruft::db::runtime::json_t::TEXT: return os << "JSON";
case cruft::db::runtime::json_t::BINARY: return os << "JSONB";
}
unhandled (val.subtype);
@ -90,12 +105,15 @@ print_sql (std::ostream &os, cruft::db::schema const &, cruft::db::json_t const
//-----------------------------------------------------------------------------
static std::ostream&
print_sql (std::ostream &os, cruft::db::schema const &, cruft::db::string_t const &val)
{
print_sql (
std::ostream &os,
cruft::db::runtime::schema const &,
cruft::db::runtime::string_t const &val
) {
switch (val.subtype) {
case cruft::db::string_t::TEXT:
case cruft::db::runtime::string_t::TEXT:
return os << "TEXT";
case cruft::db::string_t::VARCHAR:
case cruft::db::runtime::string_t::VARCHAR:
os << "CHARACTER VARYING";
if (val.length)
os << '(' << *val.length << ')';
@ -108,16 +126,22 @@ print_sql (std::ostream &os, cruft::db::schema const &, cruft::db::string_t cons
//-----------------------------------------------------------------------------
static std::ostream&
print_sql (std::ostream &os, cruft::db::schema const &, cruft::db::boolean_t const &)
{
print_sql (
std::ostream &os,
cruft::db::runtime::schema const &,
cruft::db::runtime::boolean_t const &
) {
return os << "BOOLEAN";
}
//-----------------------------------------------------------------------------
static std::ostream&
print_sql (std::ostream &os, cruft::db::schema const &ctx, cruft::db::enumeration_t const &col)
{
print_sql (
std::ostream &os,
cruft::db::runtime::schema const &ctx,
cruft::db::runtime::enumeration_t const &col
) {
for (auto const &i: ctx.enumerations)
if (i.oid == col.oid)
return os << i.name;
@ -128,8 +152,11 @@ print_sql (std::ostream &os, cruft::db::schema const &ctx, cruft::db::enumeratio
//-----------------------------------------------------------------------------
static std::ostream&
print_sql (std::ostream &os, cruft::db::schema const &ctx, cruft::db::column const &obj)
{
print_sql (
std::ostream &os,
cruft::db::runtime::schema const &ctx,
cruft::db::runtime::column const &obj
) {
os << obj.name << ' ';
std::visit ([&] (auto const &detail) { print_sql (os, ctx, detail); }, obj.detail);
return os;
@ -138,8 +165,11 @@ print_sql (std::ostream &os, cruft::db::schema const &ctx, cruft::db::column con
//-----------------------------------------------------------------------------
static std::ostream&
print_sql (std::ostream &os, cruft::db::schema const &ctx, cruft::db::table const &obj)
{
print_sql (
std::ostream &os,
cruft::db::runtime::schema const &ctx,
cruft::db::runtime::table const &obj
) {
fmt::print (os, "CREATE TABLE {} (", obj.name);
for (auto const &col: obj.columns) {
print_sql (os, ctx, col);
@ -153,8 +183,11 @@ print_sql (std::ostream &os, cruft::db::schema const &ctx, cruft::db::table cons
//-----------------------------------------------------------------------------
static std::ostream&
print_sql (std::ostream &os, cruft::db::schema const &, cruft::db::enumeration const &obj)
{
print_sql (
std::ostream &os,
cruft::db::runtime::schema const &,
cruft::db::runtime::enumeration const &obj
) {
fmt::print (os,
"CREATE TYPE {} AS ENUM ({});",
obj.name,
@ -172,8 +205,11 @@ print_sql (std::ostream &os, cruft::db::schema const &, cruft::db::enumeration c
//-----------------------------------------------------------------------------
static std::ostream&
print_sql (std::ostream &os, cruft::db::schema const&, cruft::db::index const &obj)
{
print_sql (
std::ostream &os,
cruft::db::runtime::schema const&,
cruft::db::runtime::index const &obj
) {
fmt::print (os,
"CREATE {} INDEX {} ON {} ({});",
obj.unique and not obj.primary ? "UNIQUE" : "",
@ -189,8 +225,8 @@ print_sql (std::ostream &os, cruft::db::schema const&, cruft::db::index const &o
static std::ostream&
print_sql (
std::ostream &os,
cruft::db::schema const &,
cruft::db::constraint::foreign const &obj
cruft::db::runtime::schema const &,
cruft::db::runtime::constraint::foreign const &obj
) {
fmt::print (os,
"ALTER TABLE {} ADD CONSTRAINT FOREIGN KEY ({}) REFERENCES {} ({});",
@ -208,8 +244,8 @@ print_sql (
static std::ostream&
print_sql (
std::ostream &os,
cruft::db::schema const &,
cruft::db::constraint::unique const &obj
cruft::db::runtime::schema const &,
cruft::db::runtime::constraint::unique const &obj
) {
fmt::print (os,
"ALTER TABLE {} ADD CONSTRAINT UNIQUE ({});",
@ -225,8 +261,8 @@ print_sql (
static std::ostream&
print_sql (
std::ostream &os,
cruft::db::schema const &,
cruft::db::constraint::primary const &obj
cruft::db::runtime::schema const &,
cruft::db::runtime::constraint::primary const &obj
) {
fmt::print (os,
"ALTER TABLE {} ADD CONSTRAINT PRIMARY ({});",
@ -242,8 +278,8 @@ print_sql (
static std::ostream&
print_sql (
std::ostream &,
cruft::db::schema const &,
cruft::db::constraint::check const &
cruft::db::runtime::schema const &,
cruft::db::runtime::constraint::check const &
) {
unimplemented ();
}
@ -253,8 +289,8 @@ print_sql (
static std::ostream&
print_sql (
std::ostream &os,
cruft::db::schema const &ctx,
cruft::db::constraint::any const &obj
cruft::db::runtime::schema const &ctx,
cruft::db::runtime::constraint::any const &obj
) {
return std::visit (
[&] (auto const &derived) -> std::ostream& {
@ -267,7 +303,7 @@ print_sql (
//-----------------------------------------------------------------------------
static std::ostream&
print_sql (std::ostream &os, cruft::db::schema const &obj)
print_sql (std::ostream &os, cruft::db::runtime::schema const &obj)
{
for (auto const &i: obj.enumerations) {
print_sql (os, obj, i);