4#include "../SqlQueryFormatter.hpp"
5#include "SQLiteFormatter.hpp"
7#include <reflection-cpp/reflection.hpp>
12class SqlServerQueryFormatter final:
public SQLiteQueryFormatter
15 [[nodiscard]] std::string QueryLastInsertId(std::string_view )
const override
18 return std::format(
"SELECT @@IDENTITY");
21 [[nodiscard]] std::string_view BooleanLiteral(
bool literalValue)
const noexcept override
23 return literalValue ?
"1" :
"0";
26 [[nodiscard]] std::string SelectFirst(
bool distinct,
27 std::string_view fields,
28 std::string_view fromTable,
29 std::string_view fromTableAlias,
30 std::string_view tableJoins,
31 std::string_view whereCondition,
32 std::string_view orderBy,
33 size_t count)
const override
35 std::stringstream sqlQueryString;
36 sqlQueryString <<
"SELECT";
38 sqlQueryString <<
" DISTINCT";
39 sqlQueryString <<
" TOP " << count;
40 sqlQueryString <<
' ' << fields;
41 sqlQueryString <<
" FROM \"" << fromTable <<
'"';
42 if (!fromTableAlias.empty())
43 sqlQueryString <<
" AS \"" << fromTableAlias <<
'"';
44 sqlQueryString << tableJoins;
45 sqlQueryString << whereCondition;
46 sqlQueryString << orderBy;
48 return sqlQueryString.str();
51 [[nodiscard]] std::string SelectRange(
bool distinct,
52 std::string_view fields,
53 std::string_view fromTable,
54 std::string_view fromTableAlias,
55 std::string_view tableJoins,
56 std::string_view whereCondition,
57 std::string_view orderBy,
58 std::string_view groupBy,
60 std::size_t limit)
const override
62 assert(!orderBy.empty());
63 std::stringstream sqlQueryString;
64 sqlQueryString <<
"SELECT " << fields;
66 sqlQueryString <<
" DISTINCT";
67 sqlQueryString <<
" FROM \"" << fromTable <<
"\"";
68 if (!fromTableAlias.empty())
69 sqlQueryString <<
" AS \"" << fromTableAlias <<
"\"";
70 sqlQueryString << tableJoins;
71 sqlQueryString << whereCondition;
72 sqlQueryString << groupBy;
73 sqlQueryString << orderBy;
74 sqlQueryString <<
" OFFSET " << offset <<
" ROWS FETCH NEXT " << limit <<
" ROWS ONLY";
75 return sqlQueryString.str();
78 [[nodiscard]] std::string ColumnType(SqlColumnTypeDefinition
const& type)
const override
80 using namespace SqlColumnTypeDefinitions;
81 return std::visit(detail::overloaded {
82 [](Bigint
const&) -> std::string {
return "BIGINT"; },
83 [](Binary
const& type) -> std::string {
return std::format(
"VARBINARY({})", type.size); },
84 [](Bool
const&) -> std::string {
return "BIT"; },
85 [](Char
const& type) -> std::string {
return std::format(
"CHAR({})", type.size); },
86 [](Date
const&) -> std::string {
return "DATE"; },
87 [](DateTime
const&) -> std::string {
return "DATETIME"; },
88 [](Decimal
const& type) -> std::string {
89 return std::format(
"DECIMAL({}, {})", type.precision, type.scale);
91 [](Guid
const&) -> std::string {
return "UNIQUEIDENTIFIER"; },
92 [](Integer
const&) -> std::string {
return "INTEGER"; },
93 [](NChar
const& type) -> std::string {
return std::format(
"NCHAR({})", type.size); },
94 [](NVarchar
const& type) -> std::string {
95 if (type.size == 0 || type.size > SqlOptimalMaxColumnSize)
96 return "NVARCHAR(MAX)";
98 return std::format(
"NVARCHAR({})", type.size);
100 [](Real
const&) -> std::string {
return "REAL"; },
101 [](Smallint
const&) -> std::string {
return "SMALLINT"; },
102 [](Text
const&) -> std::string {
return "VARCHAR(MAX)"; },
103 [](Time
const&) -> std::string {
return "TIME"; },
104 [](Timestamp
const&) -> std::string {
return "TIMESTAMP"; },
105 [](Tinyint
const&) -> std::string {
return "TINYINT"; },
106 [](VarBinary
const& type) -> std::string {
return std::format(
"VARBINARY({})", type.size); },
107 [](Varchar
const& type) -> std::string {
108 if (type.size == 0 || type.size > SqlOptimalMaxColumnSize)
109 return "VARCHAR(MAX)";
111 return std::format(
"VARCHAR({})", type.size);
117 [[nodiscard]] std::string BuildColumnDefinition(
SqlColumnDeclaration const& column)
const override
119 std::stringstream sqlQueryString;
120 sqlQueryString <<
'"' << column.
name <<
"\" " << ColumnType(column.
type);
123 sqlQueryString <<
" NOT NULL";
125 if (column.
primaryKey == SqlPrimaryKeyType::AUTO_INCREMENT)
126 sqlQueryString <<
" IDENTITY(1,1) PRIMARY KEY";
128 sqlQueryString <<
" UNIQUE";
130 return sqlQueryString.str();
133 [[nodiscard]] StringList AlterTable(std::string_view tableName,
134 std::vector<SqlAlterTableCommand>
const& commands)
const override
136 std::stringstream sqlQueryString;
138 int currentCommand = 0;
141 if (currentCommand > 0)
142 sqlQueryString <<
'\n';
145 using namespace SqlAlterTableCommands;
146 sqlQueryString << std::visit(
148 [tableName](RenameTable
const& actualCommand) -> std::string {
149 return std::format(R
"(ALTER TABLE "{}" RENAME TO "{}";)", tableName, actualCommand.newTableName);
151 [tableName, this](AddColumn
const& actualCommand) -> std::string {
152 return std::format(R
"(ALTER TABLE "{}" ADD "{}" {} {};)",
154 actualCommand.columnName,
155 ColumnType(actualCommand.columnType),
156 actualCommand.nullable == SqlNullable::NotNull ? "NOT NULL" :
"NULL");
158 [tableName,
this](AlterColumn
const& actualCommand) -> std::string {
159 return std::format(R
"(ALTER TABLE "{}" ALTER COLUMN "{}" {} {};)",
161 actualCommand.columnName,
162 ColumnType(actualCommand.columnType),
163 actualCommand.nullable == SqlNullable::NotNull ? "NOT NULL" :
"NULL");
165 [tableName](RenameColumn
const& actualCommand) -> std::string {
166 return std::format(R
"(ALTER TABLE "{}" RENAME COLUMN "{}" TO "{}";)",
168 actualCommand.oldColumnName,
169 actualCommand.newColumnName);
171 [tableName](DropColumn const& actualCommand) -> std::string {
172 return std::format(R
"(ALTER TABLE "{}" DROP COLUMN "{}";)", tableName, actualCommand.columnName);
174 [tableName](AddIndex const& actualCommand) -> std::string {
175 using namespace std::string_view_literals;
176 auto const uniqueStr = actualCommand.unique ?
"UNIQUE "sv :
""sv;
177 return std::format(R
"(CREATE {2}INDEX "{0}_{1}_index" ON "{0}"("{1}");)",
179 actualCommand.columnName,
182 [tableName](DropIndex const& actualCommand) -> std::string {
183 return std::format(R
"(DROP INDEX "{0}_{1}_index";)", tableName, actualCommand.columnName);
185 [tableName](AddForeignKey const& actualCommand) -> std::string {
187 R
"(ALTER TABLE "{}" ADD {};)",
189 BuildForeignKeyConstraint(actualCommand.columnName, actualCommand.referencedColumn));
191 [tableName](DropForeignKey const& actualCommand) -> std::string {
192 return std::format(R
"(ALTER TABLE "{}" DROP CONSTRAINT "{}";)",
194 std::format("FK_{}", actualCommand.columnName));
200 return { sqlQueryString.str() };
std::variant< SqlAlterTableCommands::RenameTable, SqlAlterTableCommands::AddColumn, SqlAlterTableCommands::AlterColumn, SqlAlterTableCommands::AddIndex, SqlAlterTableCommands::RenameColumn, SqlAlterTableCommands::DropColumn, SqlAlterTableCommands::DropIndex, SqlAlterTableCommands::AddForeignKey, SqlAlterTableCommands::DropForeignKey > SqlAlterTableCommand
Represents a single SQL ALTER TABLE command.
Represents a SQL column declaration.
bool index
Indicates if the column is indexed.
SqlColumnTypeDefinition type
The type of the column.
bool required
Indicates if the column is required (non-nullable).
SqlPrimaryKeyType primaryKey
The primary key type of the column.
bool unique
Indicates if the column is unique.
std::string name
The name of the column.