4#include "../SqlQueryFormatter.hpp"
5#include "SQLiteFormatter.hpp"
7#include <reflection-cpp/reflection.hpp>
14class PostgreSqlFormatter final:
public SQLiteQueryFormatter
17 [[nodiscard]] std::string QueryLastInsertId(std::string_view )
const override
22 return std::format(
"SELECT lastval();");
25 [[nodiscard]] std::string BuildColumnDefinition(SqlColumnDeclaration
const& column)
const override
27 std::stringstream sqlQueryString;
29 sqlQueryString <<
'"' << column.name <<
"\" ";
31 if (column.primaryKey == SqlPrimaryKeyType::AUTO_INCREMENT)
32 sqlQueryString <<
"SERIAL";
34 sqlQueryString << ColumnType(column.type);
37 sqlQueryString <<
" NOT NULL";
39 if (column.primaryKey == SqlPrimaryKeyType::AUTO_INCREMENT)
40 sqlQueryString <<
" PRIMARY KEY";
41 else if (column.primaryKey == SqlPrimaryKeyType::NONE && !column.index && column.unique)
42 sqlQueryString <<
" UNIQUE";
44 return sqlQueryString.str();
47 [[nodiscard]] std::string ColumnType(SqlColumnTypeDefinition
const& type)
const override
49 using namespace SqlColumnTypeDefinitions;
52 return std::visit(detail::overloaded {
53 [](Bigint
const&) -> std::string {
return "BIGINT"; },
54 [](Binary
const& type) -> std::string {
return std::format(
"BYTEA", type.size); },
55 [](Bool
const&) -> std::string {
return "BOOLEAN"; },
56 [](Char
const& type) -> std::string {
return std::format(
"CHAR({})", type.size); },
57 [](Date
const&) -> std::string {
return "DATE"; },
58 [](DateTime
const&) -> std::string {
return "TIMESTAMP"; },
59 [](Decimal
const& type) -> std::string {
60 return std::format(
"DECIMAL({}, {})", type.precision, type.scale);
62 [](Guid
const&) -> std::string {
return "UUID"; },
63 [](Integer
const&) -> std::string {
return "INTEGER"; },
64 [](NChar
const& type) -> std::string {
return std::format(
"CHAR({})", type.size); },
65 [](NVarchar
const& type) -> std::string {
return std::format(
"VARCHAR({})", type.size); },
66 [](Real
const&) -> std::string {
return "REAL"; },
67 [](Smallint
const&) -> std::string {
return "SMALLINT"; },
68 [](Text
const&) -> std::string {
return "TEXT"; },
69 [](Time
const&) -> std::string {
return "TIME"; },
70 [](Timestamp
const&) -> std::string {
return "TIMESTAMP"; },
72 [](Tinyint
const&) -> std::string {
return "SMALLINT"; },
73 [](VarBinary
const& ) -> std::string {
return std::format(
"BYTEA"); },
74 [](Varchar
const& type) -> std::string {
return std::format(
"VARCHAR({})", type.size); },
79 [[nodiscard]] StringList AlterTable(std::string_view tableName,
80 std::vector<SqlAlterTableCommand>
const& commands)
const override
82 std::stringstream sqlQueryString;
84 int currentCommand = 0;
85 for (SqlAlterTableCommand
const& command: commands)
87 if (currentCommand > 0)
88 sqlQueryString <<
'\n';
91 using namespace SqlAlterTableCommands;
92 sqlQueryString << std::visit(
94 [tableName](RenameTable
const& actualCommand) -> std::string {
95 return std::format(R
"(ALTER TABLE "{}" RENAME TO "{}";)", tableName, actualCommand.newTableName);
97 [tableName, this](AddColumn
const& actualCommand) -> std::string {
98 return std::format(R
"(ALTER TABLE "{}" ADD COLUMN "{}" {} {};)",
100 actualCommand.columnName,
101 ColumnType(actualCommand.columnType),
102 actualCommand.nullable == SqlNullable::NotNull ? "NOT NULL" :
"NULL");
104 [tableName,
this](AlterColumn
const& actualCommand) -> std::string {
106 R
"(ALTER TABLE "{0}" ALTER COLUMN "{1}" TYPE {2}, ALTER COLUMN "{1}" {3} NOT NULL;)",
108 actualCommand.columnName,
109 ColumnType(actualCommand.columnType),
110 actualCommand.nullable == SqlNullable::NotNull ? "SET" :
"DROP");
112 [tableName](RenameColumn
const& actualCommand) -> std::string {
113 return std::format(R
"(ALTER TABLE "{}" RENAME COLUMN "{}" TO "{}";)",
115 actualCommand.oldColumnName,
116 actualCommand.newColumnName);
118 [tableName](DropColumn const& actualCommand) -> std::string {
119 return std::format(R
"(ALTER TABLE "{}" DROP COLUMN "{}";)", tableName, actualCommand.columnName);
121 [tableName](AddIndex const& actualCommand) -> std::string {
122 using namespace std::string_view_literals;
123 auto const uniqueStr = actualCommand.unique ?
"UNIQUE "sv :
""sv;
124 return std::format(R
"(CREATE {2}INDEX "{0}_{1}_index" ON "{0}"("{1}");)",
126 actualCommand.columnName,
129 [tableName](DropIndex const& actualCommand) -> std::string {
130 return std::format(R
"(DROP INDEX "{0}_{1}_index";)", tableName, actualCommand.columnName);
132 [tableName](AddForeignKey const& actualCommand) -> std::string {
134 R
"(ALTER TABLE "{}" ADD {};)",
136 BuildForeignKeyConstraint(actualCommand.columnName, actualCommand.referencedColumn));
138 [tableName](DropForeignKey const& actualCommand) -> std::string {
139 return std::format(R
"(ALTER TABLE "{}" DROP CONSTRAINT "{}";)",
141 std::format("FK_{}", actualCommand.columnName));
147 return { sqlQueryString.str() };