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())
51 R
"(SELECT{} COUNT(*) FROM "{}"{}{})", distinct ? " DISTINCT" :
"", fromTable, tableJoins, whereCondition);
53 return std::format(R
"(SELECT{} COUNT(*) FROM "{}" AS "{}"{}{})",
54 distinct ? " DISTINCT" :
"",
61 [[nodiscard]] std::string
SelectAll(
bool distinct,
62 std::string_view fields,
63 std::string_view fromTable,
64 std::string_view fromTableAlias,
65 std::string_view tableJoins,
66 std::string_view whereCondition,
67 std::string_view orderBy,
68 std::string_view groupBy)
const override
70 std::stringstream sqlQueryString;
71 sqlQueryString <<
"SELECT ";
73 sqlQueryString <<
"DISTINCT ";
74 sqlQueryString << fields;
75 sqlQueryString <<
" FROM \"" << fromTable <<
'"';
76 if (!fromTableAlias.empty())
77 sqlQueryString <<
" AS \"" << fromTableAlias <<
'"';
78 sqlQueryString << tableJoins;
79 sqlQueryString << whereCondition;
80 sqlQueryString << groupBy;
81 sqlQueryString << orderBy;
83 return sqlQueryString.str();
86 [[nodiscard]] std::string
SelectFirst(
bool distinct,
87 std::string_view fields,
88 std::string_view fromTable,
89 std::string_view fromTableAlias,
90 std::string_view tableJoins,
91 std::string_view whereCondition,
92 std::string_view orderBy,
93 size_t count)
const override
95 std::stringstream sqlQueryString;
96 sqlQueryString <<
"SELECT " << fields;
98 sqlQueryString <<
" DISTINCT";
99 sqlQueryString <<
" FROM \"" << fromTable <<
"\"";
100 if (!fromTableAlias.empty())
101 sqlQueryString <<
" AS \"" << fromTableAlias <<
"\"";
102 sqlQueryString << tableJoins;
103 sqlQueryString << whereCondition;
104 sqlQueryString << orderBy;
105 sqlQueryString <<
" LIMIT " << count;
106 return sqlQueryString.str();
109 [[nodiscard]] std::string
SelectRange(
bool distinct,
110 std::string_view fields,
111 std::string_view fromTable,
112 std::string_view fromTableAlias,
113 std::string_view tableJoins,
114 std::string_view whereCondition,
115 std::string_view orderBy,
116 std::string_view groupBy,
118 std::size_t limit)
const override
120 std::stringstream sqlQueryString;
121 sqlQueryString <<
"SELECT " << fields;
123 sqlQueryString <<
" DISTINCT";
124 sqlQueryString <<
" FROM \"" << fromTable <<
"\"";
125 if (!fromTableAlias.empty())
126 sqlQueryString <<
" AS \"" << fromTableAlias <<
"\"";
127 sqlQueryString << tableJoins;
128 sqlQueryString << whereCondition;
129 sqlQueryString << groupBy;
130 sqlQueryString << orderBy;
131 sqlQueryString <<
" LIMIT " << limit <<
" OFFSET " << offset;
132 return sqlQueryString.str();
135 [[nodiscard]] std::string
Update(std::string_view table,
136 std::string_view tableAlias,
137 std::string_view setFields,
138 std::string_view whereCondition)
const override
140 if (tableAlias.empty())
141 return std::format(R
"(UPDATE "{}" SET {}{})", table, setFields, whereCondition);
143 return std::format(R
"(UPDATE "{}" AS "{}" SET {}{})", table, tableAlias, setFields, whereCondition);
146 [[nodiscard]] std::string Delete(std::string_view fromTable,
147 std::string_view fromTableAlias,
148 std::string_view tableJoins,
149 std::string_view whereCondition) const override
151 if (fromTableAlias.empty())
152 return std::format(R
"(DELETE FROM "{}"{}{})", fromTable, tableJoins, whereCondition);
154 return std::format(R
"(DELETE FROM "{}" AS "{}"{}{})", fromTable, fromTableAlias, tableJoins, whereCondition);
157 [[nodiscard]] virtual std::string BuildColumnDefinition(
SqlColumnDeclaration const& column)
const
159 std::stringstream sqlQueryString;
161 sqlQueryString <<
'"' << column.
name <<
"\" ";
163 if (column.
primaryKey != SqlPrimaryKeyType::AUTO_INCREMENT)
166 sqlQueryString <<
ColumnType(SqlColumnTypeDefinitions::Integer {});
169 sqlQueryString <<
" NOT NULL";
171 if (column.
primaryKey == SqlPrimaryKeyType::AUTO_INCREMENT)
172 sqlQueryString <<
" PRIMARY KEY AUTOINCREMENT";
174 sqlQueryString <<
" UNIQUE";
176 return sqlQueryString.str();
179 [[nodiscard]]
static std::string BuildForeignKeyConstraint(std::string_view columnName,
182 return std::format(R
"(CONSTRAINT {} FOREIGN KEY ("{}") REFERENCES "{}"("{}"))",
183 std::format("FK_{}", columnName),
189 [[nodiscard]] StringList
CreateTable(std::string_view tableName,
190 std::vector<SqlColumnDeclaration>
const& columns)
const override
192 auto sqlQueries = StringList {};
194 sqlQueries.emplace_back([&]() {
195 std::stringstream sqlQueryString;
196 sqlQueryString <<
"CREATE TABLE \"" << tableName <<
"\" (";
197 size_t currentColumn = 0;
198 std::string primaryKeyColumns;
199 std::string foreignKeyConstraints;
202 if (currentColumn > 0)
203 sqlQueryString <<
",";
205 sqlQueryString <<
"\n ";
206 sqlQueryString << BuildColumnDefinition(column);
207 if (column.
primaryKey == SqlPrimaryKeyType::MANUAL || column.
primaryKey == SqlPrimaryKeyType::GUID)
209 if (!primaryKeyColumns.empty())
210 primaryKeyColumns +=
", ";
211 primaryKeyColumns +=
'"';
212 primaryKeyColumns += column.
name;
213 primaryKeyColumns +=
'"';
217 foreignKeyConstraints +=
",\n ";
218 foreignKeyConstraints += BuildForeignKeyConstraint(column.
name, *column.
foreignKey);
221 if (!primaryKeyColumns.empty())
222 sqlQueryString <<
",\n PRIMARY KEY (" << primaryKeyColumns <<
")";
224 sqlQueryString << foreignKeyConstraints;
226 sqlQueryString <<
"\n);";
227 return sqlQueryString.str();
236 sqlQueries.emplace_back(std::format(R
"(CREATE UNIQUE INDEX "{}_{}_index" ON "{}"("{}");)",
242 sqlQueries.emplace_back(std::format(
243 R
"(CREATE INDEX "{}_{}_index" ON "{}"("{}");)", tableName, column.name, tableName, column.name));
250 [[nodiscard]] StringList
AlterTable(std::string_view tableName,
251 std::vector<SqlAlterTableCommand>
const& commands)
const override
253 std::stringstream sqlQueryString;
255 int currentCommand = 0;
258 if (currentCommand > 0)
259 sqlQueryString <<
'\n';
262 using namespace SqlAlterTableCommands;
263 sqlQueryString << std::visit(
265 [tableName](RenameTable
const& actualCommand) -> std::string {
266 return std::format(R
"(ALTER TABLE "{}" RENAME TO "{}";)", tableName, actualCommand.newTableName);
268 [tableName, this](AddColumn
const& actualCommand) -> std::string {
269 return std::format(R
"(ALTER TABLE "{}" ADD COLUMN "{}" {} {};)",
271 actualCommand.columnName,
272 ColumnType(actualCommand.columnType),
273 actualCommand.nullable == SqlNullable::NotNull ? "NOT NULL" :
"NULL");
275 [tableName,
this](AlterColumn
const& actualCommand) -> std::string {
276 return std::format(R
"(ALTER TABLE "{}" ALTER COLUMN "{}" {} {};)",
278 actualCommand.columnName,
279 ColumnType(actualCommand.columnType),
280 actualCommand.nullable == SqlNullable::NotNull ? "NOT NULL" :
"NULL");
282 [tableName](RenameColumn
const& actualCommand) -> std::string {
283 return std::format(R
"(ALTER TABLE "{}" RENAME COLUMN "{}" TO "{}";)",
285 actualCommand.oldColumnName,
286 actualCommand.newColumnName);
288 [tableName](DropColumn const& actualCommand) -> std::string {
289 return std::format(R
"(ALTER TABLE "{}" DROP COLUMN "{}";)", tableName, actualCommand.columnName);
291 [tableName](AddIndex const& actualCommand) -> std::string {
292 using namespace std::string_view_literals;
293 auto const uniqueStr = actualCommand.unique ?
"UNIQUE "sv :
""sv;
294 return std::format(R
"(CREATE {2}INDEX "{0}_{1}_index" ON "{0}"("{1}");)",
296 actualCommand.columnName,
299 [tableName](DropIndex const& actualCommand) -> std::string {
300 return std::format(R
"(DROP INDEX "{0}_{1}_index";)", tableName, actualCommand.columnName);
302 [tableName](AddForeignKey const& actualCommand) -> std::string {
304 R
"(ALTER TABLE "{}" ADD {};)",
306 BuildForeignKeyConstraint(actualCommand.columnName, actualCommand.referencedColumn));
308 [tableName](DropForeignKey const& actualCommand) -> std::string {
309 return std::format(R
"(ALTER TABLE "{}" DROP CONSTRAINT "{}";)",
311 std::format("FK_{}", actualCommand.columnName));
317 return { sqlQueryString.str() };
320 [[nodiscard]] std::string
ColumnType(SqlColumnTypeDefinition
const& type)
const override
322 using namespace SqlColumnTypeDefinitions;
323 return std::visit(detail::overloaded {
324 [](Bigint
const&) -> std::string {
return "BIGINT"; },
325 [](Binary
const&) -> std::string {
return "BLOB"; },
326 [](Bool
const&) -> std::string {
return "BOOLEAN"; },
327 [](Char
const& type) -> std::string {
return std::format(
"CHAR({})", type.size); },
328 [](Date
const&) -> std::string {
return "DATE"; },
329 [](DateTime
const&) -> std::string {
return "DATETIME"; },
330 [](Decimal
const& type) -> std::string {
331 return std::format(
"DECIMAL({}, {})", type.precision, type.scale);
333 [](Guid
const&) -> std::string {
return "GUID"; },
334 [](Integer
const&) -> std::string {
return "INTEGER"; },
335 [](NChar
const& type) -> std::string {
return std::format(
"NCHAR({})", type.size); },
336 [](NVarchar
const& type) -> std::string {
return std::format(
"NVARCHAR({})", type.size); },
337 [](Real
const&) -> std::string {
return "REAL"; },
338 [](Smallint
const&) -> std::string {
return "SMALLINT"; },
339 [](Text
const&) -> std::string {
return "TEXT"; },
340 [](Time
const&) -> std::string {
return "TIME"; },
341 [](Timestamp
const&) -> std::string {
return "TIMESTAMP"; },
342 [](Tinyint
const&) -> std::string {
return "TINYINT"; },
343 [](VarBinary
const& type) -> std::string {
return std::format(
"VARBINARY({})", type.size); },
344 [](Varchar
const& type) -> std::string {
return std::format(
"VARCHAR({})", type.size); },
349 [[nodiscard]] StringList
DropTable(std::string_view
const& tableName)
const override
351 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.