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;
83 [](Bigint
const&) -> std::string {
return "BIGINT"; },
84 [](Binary
const& type) -> std::string {
return std::format(
"VARBINARY({})", type.size); },
85 [](Bool
const&) -> std::string {
return "BIT"; },
86 [](Char
const& type) -> std::string {
return std::format(
"CHAR({})", type.size); },
87 [](Date
const&) -> std::string {
return "DATE"; },
88 [](DateTime
const&) -> std::string {
return "DATETIME"; },
89 [](Decimal
const& type) -> std::string {
90 return std::format(
"DECIMAL({}, {})", type.precision, type.scale);
92 [](Guid
const&) -> std::string {
return "UNIQUEIDENTIFIER"; },
93 [](Integer
const&) -> std::string {
return "INTEGER"; },
94 [](NChar
const& type) -> std::string {
return std::format(
"NCHAR({})", type.size); },
95 [](NVarchar
const& type) -> std::string {
96 if (type.size == 0 || type.size > SqlOptimalMaxColumnSize)
97 return "NVARCHAR(MAX)";
99 return std::format(
"NVARCHAR({})", type.size);
101 [](Real
const&) -> std::string {
return "REAL"; },
102 [](Smallint
const&) -> std::string {
return "SMALLINT"; },
103 [](Text
const&) -> std::string {
return "VARCHAR(MAX)"; },
104 [](Time
const&) -> std::string {
return "TIME"; },
105 [](Timestamp
const&) -> std::string {
return "TIMESTAMP"; },
106 [](Tinyint
const&) -> std::string {
return "TINYINT"; },
107 [](VarBinary
const& type) -> std::string {
return std::format(
"VARBINARY({})", type.size); },
108 [](Varchar
const& type) -> std::string {
109 if (type.size == 0 || type.size > SqlOptimalMaxColumnSize)
110 return "VARCHAR(MAX)";
112 return std::format(
"VARCHAR({})", type.size);
118 [[nodiscard]] std::string BuildColumnDefinition(
SqlColumnDeclaration const& column)
const override
120 std::stringstream sqlQueryString;
121 sqlQueryString <<
'"' << column.
name <<
"\" " << ColumnType(column.
type);
124 sqlQueryString <<
" NOT NULL";
126 if (column.
primaryKey == SqlPrimaryKeyType::AUTO_INCREMENT)
127 sqlQueryString <<
" IDENTITY(1,1) PRIMARY KEY";
129 sqlQueryString <<
" UNIQUE";
131 return sqlQueryString.str();
134 [[nodiscard]] StringList AlterTable(std::string_view tableName,
135 std::vector<SqlAlterTableCommand>
const& commands)
const override
137 std::stringstream sqlQueryString;
139 int currentCommand = 0;
142 if (currentCommand > 0)
143 sqlQueryString <<
'\n';
146 using namespace SqlAlterTableCommands;
147 sqlQueryString << std::visit(
149 [tableName](RenameTable
const& actualCommand) -> std::string {
151 R
"(ALTER TABLE "{}" RENAME TO "{}";)", tableName, actualCommand.newTableName);
153 [tableName, this](AddColumn
const& actualCommand) -> std::string {
154 return std::format(R
"(ALTER TABLE "{}" ADD "{}" {} {};)",
156 actualCommand.columnName,
157 ColumnType(actualCommand.columnType),
158 actualCommand.nullable == SqlNullable::NotNull ? "NOT NULL" :
"NULL");
160 [tableName,
this](AlterColumn
const& actualCommand) -> std::string {
161 return std::format(R
"(ALTER TABLE "{}" ALTER COLUMN "{}" {} {};)",
163 actualCommand.columnName,
164 ColumnType(actualCommand.columnType),
165 actualCommand.nullable == SqlNullable::NotNull ? "NOT NULL" :
"NULL");
167 [tableName](RenameColumn
const& actualCommand) -> std::string {
168 return std::format(R
"(ALTER TABLE "{}" RENAME COLUMN "{}" TO "{}";)",
170 actualCommand.oldColumnName,
171 actualCommand.newColumnName);
173 [tableName](DropColumn const& actualCommand) -> std::string {
175 R
"(ALTER TABLE "{}" DROP COLUMN "{}";)", tableName, actualCommand.columnName);
177 [tableName](AddIndex const& actualCommand) -> std::string {
178 using namespace std::string_view_literals;
179 auto const uniqueStr = actualCommand.unique ?
"UNIQUE "sv :
""sv;
180 return std::format(R
"(CREATE {2}INDEX "{0}_{1}_index" ON "{0}"("{1}");)",
182 actualCommand.columnName,
185 [tableName](DropIndex const& actualCommand) -> std::string {
186 return std::format(R
"(DROP INDEX "{0}_{1}_index";)", tableName, actualCommand.columnName);
188 [tableName](AddForeignKey const& actualCommand) -> std::string {
190 R
"(ALTER TABLE "{}" ADD {};)",
192 BuildForeignKeyConstraint(actualCommand.columnName, actualCommand.referencedColumn));
194 [tableName](DropForeignKey const& actualCommand) -> std::string {
195 return std::format(R
"(ALTER TABLE "{}" DROP CONSTRAINT "{}";)",
197 std::format("FK_{}", actualCommand.columnName));
203 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.