Skip to content

Commit 49b94e9

Browse files
committed
[DataMapper] Add DataMapperOptions in all query functions
1 parent c03e057 commit 49b94e9

File tree

3 files changed

+39
-54
lines changed

3 files changed

+39
-54
lines changed

src/Lightweight/DataMapper/DataMapper.hpp

Lines changed: 11 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ class DataMapper
214214
std::optional<Record> QuerySingle(PrimaryKeyTypes&&... primaryKeys);
215215

216216
/// Queries multiple records from the database, based on the given query.
217-
template <typename Record, typename... InputParameters>
217+
template <typename Record, DataMapperOptions QueryOptions = {}, typename... InputParameters>
218218
std::vector<Record> Query(SqlSelectQueryBuilder::ComposedQuery const& selectQuery, InputParameters&&... inputParameters);
219219

220220
/// Queries multiple records from the database, based on the given query.
@@ -246,7 +246,7 @@ class DataMapper
246246
/// }
247247
/// }
248248
/// @endcode
249-
template <typename Record, typename... InputParameters>
249+
template <typename Record, DataMapperOptions QueryOptions = {}, typename... InputParameters>
250250
std::vector<Record> Query(std::string_view sqlQueryString, InputParameters&&... inputParameters);
251251

252252
/// Queries records from the database, based on the given query and can be used to retrieve only part of the record
@@ -273,7 +273,7 @@ class DataMapper
273273
/// // only info.name and info.city are loaded
274274
/// }
275275
/// @endcode
276-
template <typename ElementMask, typename Record, typename... InputParameters>
276+
template <typename ElementMask, typename Record, DataMapperOptions QueryOptions = {}, typename... InputParameters>
277277
std::vector<Record> Query(SqlSelectQueryBuilder::ComposedQuery const& selectQuery, InputParameters&&... inputParameters);
278278

279279
/// Queries records of different types from the database, based on the given query.
@@ -305,27 +305,6 @@ class DataMapper
305305
requires DataMapperRecord<First> && DataMapperRecord<Second> && DataMapperRecords<Rest...>
306306
std::vector<std::tuple<First, Second, Rest...>> Query(SqlSelectQueryBuilder::ComposedQuery const& selectQuery);
307307

308-
/// Queries records of different types from the database, based on the given query.
309-
template <typename FirstRecord, typename NextRecord, DataMapperOptions QueryOptions = {}>
310-
requires DataMapperRecord<FirstRecord> && DataMapperRecord<NextRecord>
311-
SqlAllFieldsQueryBuilder<std::tuple<FirstRecord, NextRecord>, QueryOptions> Query()
312-
{
313-
std::string fields;
314-
315-
auto const emplaceRecordsFrom = [&fields]<typename Record>() {
316-
Reflection::EnumerateMembers<Record>([&fields]<size_t I, typename Field>() {
317-
if (!fields.empty())
318-
fields += ", ";
319-
fields += std::format(R"("{}"."{}")", RecordTableName<Record>, FieldNameAt<I, Record>);
320-
});
321-
};
322-
323-
emplaceRecordsFrom.template operator()<FirstRecord>();
324-
emplaceRecordsFrom.template operator()<NextRecord>();
325-
326-
return SqlAllFieldsQueryBuilder<std::tuple<FirstRecord, NextRecord>, QueryOptions>(*this, std::move(fields));
327-
}
328-
329308
/// Queries records of given Record type.
330309
///
331310
/// The query builder can be used to further refine the query.
@@ -1567,16 +1546,16 @@ std::optional<Record> DataMapper::QuerySingle(SqlSelectQueryBuilder selectQuery,
15671546
// TODO: Provide Query(QueryBuilder, ...) method variant
15681547

15691548
/// Queries multiple records from the database using a composed query and optional input parameters.
1570-
template <typename Record, typename... InputParameters>
1549+
template <typename Record, DataMapperOptions QueryOptions, typename... InputParameters>
15711550
inline LIGHTWEIGHT_FORCE_INLINE std::vector<Record> DataMapper::Query(
15721551
SqlSelectQueryBuilder::ComposedQuery const& selectQuery, InputParameters&&... inputParameters)
15731552
{
15741553
static_assert(DataMapperRecord<Record> || std::same_as<Record, SqlVariantRow>, "Record must satisfy DataMapperRecord");
15751554

1576-
return Query<Record>(selectQuery.ToSql(), std::forward<InputParameters>(inputParameters)...);
1555+
return Query<Record, QueryOptions>(selectQuery.ToSql(), std::forward<InputParameters>(inputParameters)...);
15771556
}
15781557

1579-
template <typename Record, typename... InputParameters>
1558+
template <typename Record, DataMapperOptions QueryOptions, typename... InputParameters>
15801559
std::vector<Record> DataMapper::Query(std::string_view sqlQueryString, InputParameters&&... inputParameters)
15811560
{
15821561
auto result = std::vector<Record> {};
@@ -1622,7 +1601,8 @@ std::vector<Record> DataMapper::Query(std::string_view sqlQueryString, InputPara
16221601
for (auto& record: result)
16231602
{
16241603
SetModifiedState<ModifiedState::NotModified>(record);
1625-
ConfigureRelationAutoLoading(record);
1604+
if constexpr (QueryOptions.loadRelations)
1605+
ConfigureRelationAutoLoading(record);
16261606
}
16271607
}
16281608

@@ -1709,7 +1689,7 @@ std::vector<std::tuple<First, Second, Rest...>> DataMapper::Query(SqlSelectQuery
17091689
return result;
17101690
}
17111691

1712-
template <typename ElementMask, typename Record, typename... InputParameters>
1692+
template <typename ElementMask, typename Record, DataMapperOptions QueryOptions, typename... InputParameters>
17131693
std::vector<Record> DataMapper::Query(SqlSelectQueryBuilder::ComposedQuery const& selectQuery,
17141694
InputParameters&&... inputParameters)
17151695
{
@@ -1744,7 +1724,8 @@ std::vector<Record> DataMapper::Query(SqlSelectQueryBuilder::ComposedQuery const
17441724
for (auto& record: records)
17451725
{
17461726
SetModifiedState<ModifiedState::NotModified>(record);
1747-
ConfigureRelationAutoLoading(record);
1727+
if constexpr (QueryOptions.loadRelations)
1728+
ConfigureRelationAutoLoading(record);
17481729
}
17491730

17501731
return records;

src/examples/test_chinook/main.cpp

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// SPDX-License-Identifier: Apache-2.0
22

3-
#include <iterator>
43
#include <format>
4+
#include <iterator>
55
#include <optional>
66
#include <print>
77
#include <ranges>
@@ -11,8 +11,8 @@
1111
#ifdef LIGHTWEIGHT_BUILD_MODULES
1212
import Lightweight;
1313
#else
14-
#include <Lightweight/Lightweight.hpp>
15-
#include <Lightweight/SqlLogger.hpp>
14+
#include <Lightweight/Lightweight.hpp>
15+
#include <Lightweight/SqlLogger.hpp>
1616
#endif
1717

1818
using std::basic_string_view;
@@ -78,16 +78,16 @@ void Log(format_string<Args...> fmt, Args&&... args)
7878
template <typename Entity>
7979
void DumpTable(DataMapper& dm, size_t limit = 1)
8080
{
81-
const auto entries = dm.Query<Entity>().First(limit);
82-
for (const auto& entry: entries)
81+
auto const entries = dm.Query<Entity>().First(limit);
82+
for (auto const& entry: entries)
8383
{
8484
Log("{}", DataMapper::Inspect(entry));
8585
}
8686
}
8787

8888
int main()
8989
{
90-
if (const auto odbcConnectionString = GetEnvironmentVariable("ODBC_CONNECTION_STRING"); !odbcConnectionString.empty())
90+
if (auto const odbcConnectionString = GetEnvironmentVariable("ODBC_CONNECTION_STRING"); !odbcConnectionString.empty())
9191
{
9292
SqlConnection::SetDefaultConnectionString(SqlConnectionString { odbcConnectionString });
9393
}
@@ -101,24 +101,24 @@ int main()
101101
DataMapper dm;
102102

103103
// helper function to create std::string from string_view<char16_t>
104-
const auto toString = [](basic_string_view<char16_t> str) {
105-
const auto u8Str = Lightweight::ToUtf8(str);
106-
return string(reinterpret_cast<const char*>(u8Str.data()), u8Str.size());
104+
auto const toString = [](basic_string_view<char16_t> str) {
105+
auto const u8Str = Lightweight::ToUtf8(str);
106+
return string(reinterpret_cast<char const*>(u8Str.data()), u8Str.size());
107107
};
108108

109109
// get all employees
110-
const auto employees = dm.Query<Employee>().All();
111-
for (const auto& employee: employees)
110+
auto const employees = dm.Query<Employee>().All();
111+
for (auto const& employee: employees)
112112
{
113113
Log("EmployeeId: {}, FirstName: {}, LastName: {}",
114114
employee.EmployeeId.Value(),
115115
toString(employee.FirstName.Value().c_str()),
116116
toString(employee.LastName.Value().c_str()));
117117
}
118118

119-
// directly iterate over elements
119+
// directly iterate over elements
120120
int numberOfAlbums = 0;
121-
for (const auto& album: SqlRowIterator<Album>(dm.Connection()))
121+
for (auto const& album: SqlRowIterator<Album>(dm.Connection()))
122122
{
123123
Log("{}", toString(album.Title.Value().c_str()));
124124
++numberOfAlbums;
@@ -155,14 +155,14 @@ int main()
155155

156156
Log("got {} albums", albums.size());
157157

158-
auto albumIds = albums | transform([](const auto& album) { return album.AlbumId.Value(); });
158+
auto albumIds = albums | transform([](auto const& album) { return album.AlbumId.Value(); });
159159
// get all tracks from all albums
160160
auto tracks = dm.Query<Track>().WhereIn(FieldNameOf<&Track::AlbumId>, albumIds).All();
161161

162162
Log("got {} tracks", tracks.size());
163163

164164
// iterate over all tracks and print song names
165-
for (const auto& track: tracks)
165+
for (auto const& track: tracks)
166166
{
167167
Log("TrackId: {}, Name: {}, Bytes: {} , UnitPrice: {}",
168168
track.TrackId.Value(),
@@ -181,17 +181,20 @@ int main()
181181
toString(track.MediaTypeId->Name.ValueOr(u"").ToStringView()),
182182
toString(track.GenreId.Record().transform(Unwrap).value().Name.ValueOr(u"").ToStringView()),
183183
toString(track.AlbumId.Record().transform(Unwrap).value().Title.Value().ToStringView()),
184-
toString(
185-
track.AlbumId.Record().transform(Unwrap).value().ArtistId->Name.ValueOr(u"").ToStringView()));
184+
toString(track.AlbumId.Record().transform(Unwrap).value().ArtistId->Name.ValueOr(u"").ToStringView()));
186185
// NOLINTEND(bugprone-unchecked-optional-access)
187186
}
188187
}
189188

190189
{
191190
// get pair of customer and employee
192-
auto records = dm.Query<Customer, Employee>().InnerJoin<&Employee::EmployeeId, &Customer::SupportRepId>().All();
191+
auto records = dm.Query<Customer, Employee>(dm.FromTable(Lightweight::RecordTableName<Customer>)
192+
.Select()
193+
.Fields<Customer, Employee>()
194+
.InnerJoin<&Employee::EmployeeId, &Customer::SupportRepId>()
195+
.All());
193196

194-
for (const auto& [customer, employee]: records)
197+
for (auto const& [customer, employee]: records)
195198
{
196199
Log("CustomerId: {}, FirstName: {}, LastName: {}",
197200
customer.CustomerId.Value(),
@@ -230,4 +233,3 @@ int main()
230233

231234
Log("Found {} employees.", employees.size());
232235
}
233-

src/tests/DataMapper/ReadTests.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -531,10 +531,12 @@ TEST_CASE_METHOD(SqlTestFixture, "MapForJointStatement", "[DataMapper]")
531531
dm.Create(c);
532532
}
533533

534-
auto const records = dm.Query<JoinA, JoinC>()
535-
.InnerJoin<Member(JoinB::a_id), Member(JoinA::id)>()
536-
.InnerJoin<Member(JoinC::id), Member(JoinB::c_id)>()
537-
.All();
534+
auto const records = dm.Query<JoinA, JoinC>(dm.FromTable(RecordTableName<JoinA>)
535+
.Select()
536+
.Fields<JoinA, JoinC>()
537+
.InnerJoin<Member(JoinB::a_id), Member(JoinA::id)>()
538+
.InnerJoin<Member(JoinC::id), Member(JoinB::c_id)>()
539+
.All());
538540

539541
CHECK(records.size() == 50);
540542
int i = 1;

0 commit comments

Comments
 (0)