4#include "../SqlQueryFormatter.hpp"
5#include "SQLiteFormatter.hpp"
7#include <reflection-cpp/reflection.hpp>
15class OracleSqlQueryFormatter final:
public SQLiteQueryFormatter
18 [[nodiscard]] std::string QueryLastInsertId(std::string_view tableName)
const override
20 return std::format(
"SELECT \"{}_SEQ\".CURRVAL FROM DUAL;", tableName);
23 [[nodiscard]] std::string_view BooleanLiteral(
bool literalValue)
const noexcept override
25 return literalValue ?
"1" :
"0";
28 [[nodiscard]] std::string SelectFirst(
bool distinct,
30 std::string_view fields,
31 std::string_view fromTable,
32 std::string_view fromTableAlias,
33 std::string_view tableJoins,
34 std::string_view whereCondition,
35 std::string_view orderBy,
36 size_t count)
const override
38 std::stringstream sqlQueryString;
39 sqlQueryString <<
"SELECT";
41 sqlQueryString <<
" DISTINCT";
42 sqlQueryString <<
" TOP " << count;
43 sqlQueryString <<
' ' << fields;
44 sqlQueryString <<
" FROM \"" << fromTable <<
'"';
45 if (!fromTableAlias.empty())
46 sqlQueryString <<
" AS \"" << fromTableAlias <<
'"';
47 sqlQueryString << tableJoins;
48 sqlQueryString << whereCondition;
49 sqlQueryString << orderBy;
51 return sqlQueryString.str();
54 [[nodiscard]] std::string SelectRange(
bool distinct,
56 std::string_view fields,
57 std::string_view fromTable,
58 std::string_view fromTableAlias,
59 std::string_view tableJoins,
60 std::string_view whereCondition,
61 std::string_view orderBy,
62 std::string_view groupBy,
64 std::size_t limit)
const override
66 assert(!orderBy.empty());
67 std::stringstream sqlQueryString;
68 sqlQueryString <<
"SELECT " << fields;
70 sqlQueryString <<
" DISTINCT";
71 sqlQueryString <<
" FROM \"" << fromTable <<
"\"";
72 if (!fromTableAlias.empty())
73 sqlQueryString <<
" AS \"" << fromTableAlias <<
"\"";
74 sqlQueryString << tableJoins;
75 sqlQueryString << whereCondition;
76 sqlQueryString << groupBy;
77 sqlQueryString << orderBy;
78 sqlQueryString <<
" OFFSET " << offset <<
" ROWS FETCH NEXT " << limit <<
" ROWS ONLY";
79 return sqlQueryString.str();
82 [[nodiscard]] std::string ColumnType(SqlColumnTypeDefinition
const& type)
const override
84 using namespace SqlColumnTypeDefinitions;
85 return std::visit(detail::overloaded {
86 [](Bigint
const&) -> std::string {
return "NUMBER(21, 0)"; },
87 [](Binary
const&) -> std::string {
return "BLOB"; },
88 [](Bool
const&) -> std::string {
return "BIT"; },
89 [](Char
const& type) -> std::string {
return std::format(
"CHAR({})", type.size); },
90 [](Date
const&) -> std::string {
return "DATE"; },
91 [](DateTime
const&) -> std::string {
return "TIMESTAMP"; },
92 [](Decimal
const& type) -> std::string {
93 return std::format(
"DECIMAL({}, {})", type.precision, type.scale);
95 [](Guid
const&) -> std::string {
return "RAW(16)"; },
96 [](Integer
const&) -> std::string {
return "INTEGER"; },
97 [](NChar
const& type) -> std::string {
return std::format(
"NCHAR({})", type.size); },
98 [](NVarchar
const& type) -> std::string {
return std::format(
"NVARCHAR2({})", type.size); },
99 [](Real
const&) -> std::string {
return "REAL"; },
100 [](Smallint
const&) -> std::string {
return "SMALLINT"; },
101 [](Text
const& type) -> std::string {
102 if (type.size <= SqlOptimalMaxColumnSize)
103 return std::format(
"VARCHAR2({})", type.size);
107 [](Time
const&) -> std::string {
return "TIMESTAMP"; },
108 [](Timestamp
const&) -> std::string {
return "TIMESTAMP"; },
109 [](Tinyint
const&) -> std::string {
return "TINYINT"; },
110 [](VarBinary
const& type) -> std::string {
return std::format(
"VARBINARY({})", type.size); },
111 [](Varchar
const& type) -> std::string {
return std::format(
"VARCHAR({})", type.size); },
116 [[nodiscard]] std::string BuildColumnDefinition(SqlColumnDeclaration
const& column)
const override
118 std::stringstream sqlQueryString;
119 sqlQueryString <<
'"' << column.name <<
"\" " << ColumnType(column.type);
121 if (column.required && column.primaryKey != SqlPrimaryKeyType::AUTO_INCREMENT)
122 sqlQueryString <<
" NOT NULL";
124 if (column.primaryKey == SqlPrimaryKeyType::AUTO_INCREMENT)
125 sqlQueryString <<
" GENERATED ALWAYS AS IDENTITY";
126 else if (column.primaryKey == SqlPrimaryKeyType::NONE && !column.index && column.unique)
127 sqlQueryString <<
" UNIQUE";
129 if (column.primaryKey != SqlPrimaryKeyType::NONE)
130 sqlQueryString <<
",\n PRIMARY KEY (\"" << column.name <<
"\")";
132 return sqlQueryString.str();