4#include "../SqlQueryFormatter.hpp"
6#include <reflection-cpp/reflection.hpp>
13 [[nodiscard]] std::string
Insert(std::string_view intoTable,
14 std::string_view fields,
15 std::string_view values)
const override
17 return std::format(R
"(INSERT INTO "{}" ({}) VALUES ({}))", intoTable, fields, values);
23 return "SELECT LAST_INSERT_ROWID()";
26 [[nodiscard]] std::string_view
BooleanLiteral(
bool literalValue)
const noexcept override
28 return literalValue ?
"TRUE" :
"FALSE";
31 [[nodiscard]] std::string
StringLiteral(std::string_view value)
const noexcept override
34 return std::format(
"'{}'", value);
37 [[nodiscard]] std::string
StringLiteral(
char value)
const noexcept override
40 return std::format(
"'{}'", value);
43 [[nodiscard]] std::string
SelectCount(
bool distinct,
44 std::string_view fromTable,
45 std::string_view fromTableAlias,
46 std::string_view tableJoins,
47 std::string_view whereCondition)
const override
49 if (fromTableAlias.empty())
50 return std::format(R
"(SELECT{} COUNT(*) FROM "{}"{}{})",
51 distinct ? " DISTINCT" :
"",
56 return std::format(R
"(SELECT{} COUNT(*) FROM "{}" AS "{}"{}{})",
57 distinct ? " DISTINCT" :
"",
64 [[nodiscard]] std::string
SelectAll(
bool distinct,
65 std::string_view fields,
66 std::string_view fromTable,
67 std::string_view fromTableAlias,
68 std::string_view tableJoins,
69 std::string_view whereCondition,
70 std::string_view orderBy,
71 std::string_view groupBy)
const override
73 std::stringstream sqlQueryString;
74 sqlQueryString <<
"SELECT ";
76 sqlQueryString <<
"DISTINCT ";
77 sqlQueryString << fields;
78 sqlQueryString <<
" FROM \"" << fromTable <<
'"';
79 if (!fromTableAlias.empty())
80 sqlQueryString <<
" AS \"" << fromTableAlias <<
'"';
81 sqlQueryString << tableJoins;
82 sqlQueryString << whereCondition;
83 sqlQueryString << groupBy;
84 sqlQueryString << orderBy;
86 return sqlQueryString.str();
89 [[nodiscard]] std::string
SelectFirst(
bool distinct,
90 std::string_view fields,
91 std::string_view fromTable,
92 std::string_view fromTableAlias,
93 std::string_view tableJoins,
94 std::string_view whereCondition,
95 std::string_view orderBy,
96 size_t count)
const override
98 std::stringstream sqlQueryString;
99 sqlQueryString <<
"SELECT " << fields;
101 sqlQueryString <<
" DISTINCT";
102 sqlQueryString <<
" FROM \"" << fromTable <<
"\"";
103 if (!fromTableAlias.empty())
104 sqlQueryString <<
" AS \"" << fromTableAlias <<
"\"";
105 sqlQueryString << tableJoins;
106 sqlQueryString << whereCondition;
107 sqlQueryString << orderBy;
108 sqlQueryString <<
" LIMIT " << count;
109 return sqlQueryString.str();
112 [[nodiscard]] std::string
SelectRange(
bool distinct,
113 std::string_view fields,
114 std::string_view fromTable,
115 std::string_view fromTableAlias,
116 std::string_view tableJoins,
117 std::string_view whereCondition,
118 std::string_view orderBy,
119 std::string_view groupBy,
121 std::size_t limit)
const override
123 std::stringstream sqlQueryString;
124 sqlQueryString <<
"SELECT " << fields;
126 sqlQueryString <<
" DISTINCT";
127 sqlQueryString <<
" FROM \"" << fromTable <<
"\"";
128 if (!fromTableAlias.empty())
129 sqlQueryString <<
" AS \"" << fromTableAlias <<
"\"";
130 sqlQueryString << tableJoins;
131 sqlQueryString << whereCondition;
132 sqlQueryString << groupBy;
133 sqlQueryString << orderBy;
134 sqlQueryString <<
" LIMIT " << limit <<
" OFFSET " << offset;
135 return sqlQueryString.str();
138 [[nodiscard]] std::string
Update(std::string_view table,
139 std::string_view tableAlias,
140 std::string_view setFields,
141 std::string_view whereCondition)
const override
143 if (tableAlias.empty())
144 return std::format(R
"(UPDATE "{}" SET {}{})", table, setFields, whereCondition);
146 return std::format(R
"(UPDATE "{}" AS "{}" SET {}{})", table, tableAlias, setFields, whereCondition);
149 [[nodiscard]] std::string Delete(std::string_view fromTable,
150 std::string_view fromTableAlias,
151 std::string_view tableJoins,
152 std::string_view whereCondition) const override
154 if (fromTableAlias.empty())
155 return std::format(R
"(DELETE FROM "{}"{}{})", fromTable, tableJoins, whereCondition);
158 R
"(DELETE FROM "{}" AS "{}"{}{})", fromTable, fromTableAlias, tableJoins, whereCondition);
161 [[nodiscard]] virtual std::string BuildColumnDefinition(
SqlColumnDeclaration const& column)
const
163 std::stringstream sqlQueryString;
165 sqlQueryString <<
'"' << column.
name <<
"\" ";
167 if (column.
primaryKey != SqlPrimaryKeyType::AUTO_INCREMENT)
170 sqlQueryString <<
ColumnType(SqlColumnTypeDefinitions::Integer {});
173 sqlQueryString <<
" NOT NULL";
175 if (column.
primaryKey == SqlPrimaryKeyType::AUTO_INCREMENT)
176 sqlQueryString <<
" PRIMARY KEY AUTOINCREMENT";
178 sqlQueryString <<
" UNIQUE";
180 return sqlQueryString.str();
183 [[nodiscard]]
static std::string BuildForeignKeyConstraint(std::string_view columnName,
186 return std::format(R
"(CONSTRAINT {} FOREIGN KEY ("{}") REFERENCES "{}"("{}"))",
187 std::format("FK_{}", columnName),
193 [[nodiscard]] StringList
CreateTable(std::string_view tableName,
194 std::vector<SqlColumnDeclaration>
const& columns)
const override
196 auto sqlQueries = StringList {};
198 sqlQueries.emplace_back([&]() {
199 std::stringstream sqlQueryString;
200 sqlQueryString <<
"CREATE TABLE \"" << tableName <<
"\" (";
201 size_t currentColumn = 0;
202 std::string primaryKeyColumns;
203 std::string foreignKeyConstraints;
206 if (currentColumn > 0)
207 sqlQueryString <<
",";
209 sqlQueryString <<
"\n ";
210 sqlQueryString << BuildColumnDefinition(column);
211 if (column.
primaryKey == SqlPrimaryKeyType::MANUAL || column.
primaryKey == SqlPrimaryKeyType::GUID)
213 if (!primaryKeyColumns.empty())
214 primaryKeyColumns +=
", ";
215 primaryKeyColumns +=
'"';
216 primaryKeyColumns += column.
name;
217 primaryKeyColumns +=
'"';
221 foreignKeyConstraints +=
",\n ";
222 foreignKeyConstraints += BuildForeignKeyConstraint(column.
name, *column.
foreignKey);
225 if (!primaryKeyColumns.empty())
226 sqlQueryString <<
",\n PRIMARY KEY (" << primaryKeyColumns <<
")";
228 sqlQueryString << foreignKeyConstraints;
230 sqlQueryString <<
"\n);";
231 return sqlQueryString.str();
240 sqlQueries.emplace_back(std::format(R
"(CREATE UNIQUE INDEX "{}_{}_index" ON "{}"("{}");)",
246 sqlQueries.emplace_back(std::format(R
"(CREATE INDEX "{}_{}_index" ON "{}"("{}");)",
257 [[nodiscard]] StringList
AlterTable(std::string_view tableName,
258 std::vector<SqlAlterTableCommand>
const& commands)
const override
260 std::stringstream sqlQueryString;
262 int currentCommand = 0;
265 if (currentCommand > 0)
266 sqlQueryString <<
'\n';
269 using namespace SqlAlterTableCommands;
270 sqlQueryString << std::visit(
272 [tableName](RenameTable
const& actualCommand) -> std::string {
274 R
"(ALTER TABLE "{}" RENAME TO "{}";)", tableName, actualCommand.newTableName);
276 [tableName, this](AddColumn
const& actualCommand) -> std::string {
277 return std::format(R
"(ALTER TABLE "{}" ADD COLUMN "{}" {} {};)",
279 actualCommand.columnName,
280 ColumnType(actualCommand.columnType),
281 actualCommand.nullable == SqlNullable::NotNull ? "NOT NULL" :
"NULL");
283 [tableName,
this](AlterColumn
const& actualCommand) -> std::string {
284 return std::format(R
"(ALTER TABLE "{}" ALTER COLUMN "{}" {} {};)",
286 actualCommand.columnName,
287 ColumnType(actualCommand.columnType),
288 actualCommand.nullable == SqlNullable::NotNull ? "NOT NULL" :
"NULL");
290 [tableName](RenameColumn
const& actualCommand) -> std::string {
291 return std::format(R
"(ALTER TABLE "{}" RENAME COLUMN "{}" TO "{}";)",
293 actualCommand.oldColumnName,
294 actualCommand.newColumnName);
296 [tableName](DropColumn const& actualCommand) -> std::string {
298 R
"(ALTER TABLE "{}" DROP COLUMN "{}";)", tableName, actualCommand.columnName);
300 [tableName](AddIndex const& actualCommand) -> std::string {
301 using namespace std::string_view_literals;
302 auto const uniqueStr = actualCommand.unique ?
"UNIQUE "sv :
""sv;
303 return std::format(R
"(CREATE {2}INDEX "{0}_{1}_index" ON "{0}"("{1}");)",
305 actualCommand.columnName,
308 [tableName](DropIndex const& actualCommand) -> std::string {
309 return std::format(R
"(DROP INDEX "{0}_{1}_index";)", tableName, actualCommand.columnName);
311 [tableName](AddForeignKey const& actualCommand) -> std::string {
313 R
"(ALTER TABLE "{}" ADD {};)",
315 BuildForeignKeyConstraint(actualCommand.columnName, actualCommand.referencedColumn));
317 [tableName](DropForeignKey const& actualCommand) -> std::string {
318 return std::format(R
"(ALTER TABLE "{}" DROP CONSTRAINT "{}";)",
320 std::format("FK_{}", actualCommand.columnName));
326 return { sqlQueryString.str() };
329 [[nodiscard]] std::string
ColumnType(SqlColumnTypeDefinition
const& type)
const override
331 using namespace SqlColumnTypeDefinitions;
334 [](Bigint
const&) -> std::string {
return "BIGINT"; },
335 [](Binary
const&) -> std::string {
return "BLOB"; },
336 [](Bool
const&) -> std::string {
return "BOOLEAN"; },
337 [](Char
const& type) -> std::string {
return std::format(
"CHAR({})", type.size); },
338 [](Date
const&) -> std::string {
return "DATE"; },
339 [](DateTime
const&) -> std::string {
return "DATETIME"; },
340 [](Decimal
const& type) -> std::string {
341 return std::format(
"DECIMAL({}, {})", type.precision, type.scale);
343 [](Guid
const&) -> std::string {
return "GUID"; },
344 [](Integer
const&) -> std::string {
return "INTEGER"; },
345 [](NChar
const& type) -> std::string {
return std::format(
"NCHAR({})", type.size); },
346 [](NVarchar
const& type) -> std::string {
return std::format(
"NVARCHAR({})", type.size); },
347 [](Real
const&) -> std::string {
return "REAL"; },
348 [](Smallint
const&) -> std::string {
return "SMALLINT"; },
349 [](Text
const&) -> std::string {
return "TEXT"; },
350 [](Time
const&) -> std::string {
return "TIME"; },
351 [](Timestamp
const&) -> std::string {
return "TIMESTAMP"; },
352 [](Tinyint
const&) -> std::string {
return "TINYINT"; },
353 [](VarBinary
const& type) -> std::string {
return std::format(
"VARBINARY({})", type.size); },
354 [](Varchar
const& type) -> std::string {
return std::format(
"VARCHAR({})", type.size); },
359 [[nodiscard]] StringList
DropTable(std::string_view
const& tableName)
const override
361 return { std::format(R
"(DROP TABLE "{}";)", tableName) };
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).
std::optional< SqlForeignKeyReferenceDefinition > foreignKey
The foreign key reference definition of the column.
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.
Represents a foreign key reference definition.
std::string columnName
The column name that the foreign key references.
std::string tableName
The table name that the foreign key references.