Lightweight 0.20250904.0
Loading...
Searching...
No Matches
OracleFormatter.hpp
1// SPDX-License-Identifier: Apache-2.0
2#pragma once
3
4#include "../SqlQueryFormatter.hpp"
5#include "SQLiteFormatter.hpp"
6
7#include <reflection-cpp/reflection.hpp>
8
9#include <cassert>
10#include <format>
11
12namespace Lightweight
13{
14
15class OracleSqlQueryFormatter final: public SQLiteQueryFormatter
16{
17 public:
18 [[nodiscard]] std::string QueryLastInsertId(std::string_view tableName) const override
19 {
20 return std::format("SELECT \"{}_SEQ\".CURRVAL FROM DUAL;", tableName);
21 }
22
23 [[nodiscard]] std::string_view BooleanLiteral(bool literalValue) const noexcept override
24 {
25 return literalValue ? "1" : "0";
26 }
27
28 [[nodiscard]] std::string SelectFirst(bool distinct,
29 // NOLINTNEXTLINE(bugprone-easily-swappable-parameters)
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
37 {
38 std::stringstream sqlQueryString;
39 sqlQueryString << "SELECT";
40 if (distinct)
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;
50 ;
51 return sqlQueryString.str();
52 }
53
54 [[nodiscard]] std::string SelectRange(bool distinct,
55 // NOLINTNEXTLINE(bugprone-easily-swappable-parameters)
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,
63 std::size_t offset,
64 std::size_t limit) const override
65 {
66 assert(!orderBy.empty());
67 std::stringstream sqlQueryString;
68 sqlQueryString << "SELECT " << fields;
69 if (distinct)
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();
80 }
81
82 [[nodiscard]] std::string ColumnType(SqlColumnTypeDefinition const& type) const override
83 {
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);
94 },
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);
104 else
105 return "CLOB";
106 },
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); },
112 },
113 type);
114 }
115
116 [[nodiscard]] std::string BuildColumnDefinition(SqlColumnDeclaration const& column) const override
117 {
118 std::stringstream sqlQueryString;
119 sqlQueryString << '"' << column.name << "\" " << ColumnType(column.type);
120
121 if (column.required && column.primaryKey != SqlPrimaryKeyType::AUTO_INCREMENT)
122 sqlQueryString << " NOT NULL";
123
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";
128
129 if (column.primaryKey != SqlPrimaryKeyType::NONE)
130 sqlQueryString << ",\n PRIMARY KEY (\"" << column.name << "\")";
131
132 return sqlQueryString.str();
133 }
134};
135
136} // namespace Lightweight