Lightweight 0.1.0
Loading...
Searching...
No Matches
Insert.hpp
1// SPDX-License-Identifier: Apache-2.0
2
3#pragma once
4
5#include "Core.hpp"
6
7#include <cassert>
8#include <string>
9#include <string_view>
10#include <vector>
11
12/// @brief Query builder for building INSERT INTO ... queries.
13///
14/// @see SqlQueryBuilder
15/// @ingroup QueryBuilder
16class [[nodiscard]] SqlInsertQueryBuilder final
17{
18 public:
19 explicit SqlInsertQueryBuilder(SqlQueryFormatter const& formatter,
20 std::string tableName,
21 std::vector<SqlVariant>* inputBindings) noexcept;
22
23 // Adds a single column to the INSERT query.
24 template <typename ColumnValue>
25 SqlInsertQueryBuilder& Set(std::string_view columnName, ColumnValue const& value);
26
27 // Adds a single column to the INSERT query with the value being a string literal.
28 template <std::size_t N>
29 inline SqlInsertQueryBuilder& Set(std::string_view columnName, char const (&value)[N]);
30
31 // Adds a single column to the INSERT query with the value being a MFC like CString.
32 inline SqlInsertQueryBuilder& Set(std::string_view columnName, MFCStringLike auto const* value);
33
34 // Finalizes building the query as INSERT INTO ... query.
35 [[nodiscard]] LIGHTWEIGHT_API std::string ToSql() const;
36
37 private:
38 SqlQueryFormatter const& m_formatter;
39 std::string m_tableName;
40 std::string m_fields;
41 std::string m_values;
42 std::vector<SqlVariant>* m_inputBindings;
43};
44
45inline LIGHTWEIGHT_FORCE_INLINE SqlInsertQueryBuilder::SqlInsertQueryBuilder(
46 SqlQueryFormatter const& formatter, std::string tableName, std::vector<SqlVariant>* inputBindings) noexcept:
47 m_formatter { formatter },
48 m_tableName { std::move(tableName) },
49 m_inputBindings { inputBindings }
50{
51}
52
53template <typename ColumnValue>
54SqlInsertQueryBuilder& SqlInsertQueryBuilder::Set(std::string_view columnName, ColumnValue const& value)
55{
56 using namespace std::string_view_literals;
57
58 if (!m_fields.empty())
59 m_fields += ", "sv;
60
61 m_fields += '"';
62 m_fields += columnName;
63 m_fields += '"';
64
65 if (!m_values.empty())
66 m_values += ", "sv;
67
68 if constexpr (std::is_same_v<ColumnValue, SqlNullType>)
69 m_values += "NULL"sv;
70 else if constexpr (std::is_same_v<ColumnValue, SqlWildcardType>)
71 m_values += '?';
72 else if (m_inputBindings)
73 {
74 m_values += '?';
75 m_inputBindings->emplace_back(value);
76 }
77 else if constexpr (std::is_same_v<ColumnValue, char>)
78 m_values += m_formatter.StringLiteral(value);
79 else if constexpr (std::is_arithmetic_v<ColumnValue>)
80 m_values += std::format("{}", value);
81 else if constexpr (std::is_convertible_v<ColumnValue, std::string>
82 || std::is_convertible_v<ColumnValue, std::string_view>
83 || std::is_convertible_v<ColumnValue, char const*>)
84 {
85 m_values += m_formatter.StringLiteral(value);
86 }
87 else
88 {
89 m_values += m_formatter.StringLiteral(std::format("{}", value));
90 }
91
92 return *this;
93}
94
95template <std::size_t N>
96inline SqlInsertQueryBuilder& SqlInsertQueryBuilder::Set(std::string_view columnName, char const (&value)[N])
97{
98 return Set(columnName, std::string_view { value, N - 1 });
99}
100
101inline SqlInsertQueryBuilder& SqlInsertQueryBuilder::Set(std::string_view columnName, MFCStringLike auto const* value)
102{
103 return Set(columnName, std::string_view { value->GetString(), value->GetLength() });
104}
105
106inline std::string SqlInsertQueryBuilder::ToSql() const
107{
108 return m_formatter.Insert(m_tableName, m_fields, m_values);
109}
Query builder for building INSERT INTO ... queries.
Definition Insert.hpp:17
API to format SQL queries for different SQL dialects.
virtual std::string StringLiteral(std::string_view value) const noexcept=0
Converts a string value to a string literal.
virtual std::string Insert(std::string_view intoTable, std::string_view fields, std::string_view values) const =0
LIGHTWEIGHT_API std::vector< std::string > ToSql(SqlQueryFormatter const &formatter, SqlMigrationPlanElement const &element)