42 return "SimpleRecord";
47 return std::tie (ID_, Value_);
57 struct AutogenPKeyRecord
62 static QString ClassName ()
64 return "AutogenPKeyRecord";
69 return std::tie (ID_, Value_);
84 static QString ClassName ()
86 return "NoPKeyRecord";
91 return std::tie (ID_, Value_);
101 struct NonInPlaceConstructibleRecord
106 NonInPlaceConstructibleRecord () =
default;
108 NonInPlaceConstructibleRecord (
int id,
const QString& value,
double someExtraArgument)
112 Q_UNUSED (someExtraArgument)
115 static QString ClassName ()
117 return "NonInPlaceConstructibleRecord";
120 auto AsTuple ()
const 122 return std::tie (ID_, Value_);
130 TOSTRING (NonInPlaceConstructibleRecord)
132 struct ComplexConstraintsRecord
139 static QString ClassName ()
141 return "ComplexConstraintsRecord";
144 auto AsTuple ()
const 146 return std::tie (ID_, Value_, Age_, Weight_);
170 auto PrepareRecords (QSqlDatabase db)
172 auto adapted = Util::oral::AdaptPtr<T> (db);
173 for (
int i = 0; i < 3; ++i)
174 adapted->Insert ({ i, QString::number (i) });
179 namespace sph = oral::sph;
181 void OralTest::testSimpleRecordInsertSelect ()
183 auto adapted = PrepareRecords<SimpleRecord> (
MakeDatabase ());
184 const auto& list = adapted->Select ();
188 void OralTest::testSimpleRecordInsertReplaceSelect ()
192 auto adapted = Util::oral::AdaptPtr<SimpleRecord> (db);
193 for (
int i = 0; i < 3; ++i)
194 adapted->Insert ({ 0, QString::number (i) }, lco::InsertAction::Replace);
196 const auto& list = adapted->Select ();
200 void OralTest::testSimpleRecordInsertIgnoreSelect ()
204 auto adapted = Util::oral::AdaptPtr<SimpleRecord> (db);
205 for (
int i = 0; i < 3; ++i)
206 adapted->Insert ({ 0, QString::number (i) }, lco::InsertAction::Ignore);
208 const auto& list = adapted->Select ();
212 void OralTest::testSimpleRecordInsertSelectByPos ()
214 auto adapted = PrepareRecords<SimpleRecord> (
MakeDatabase ());
215 const auto& list = adapted->Select (sph::_0 == 1);
219 void OralTest::testSimpleRecordInsertSelectByPos2 ()
221 auto adapted = PrepareRecords<SimpleRecord> (
MakeDatabase ());
222 const auto& list = adapted->Select (sph::_0 < 2);
226 void OralTest::testSimpleRecordInsertSelectByPos3 ()
228 auto adapted = PrepareRecords<SimpleRecord> (
MakeDatabase ());
229 const auto& list = adapted->Select (sph::_0 < 2 && sph::_1 == QString {
"1" });
233 void OralTest::testSimpleRecordInsertSelectOneByPos ()
235 auto adapted = PrepareRecords<SimpleRecord> (
MakeDatabase ());
236 const auto& single = adapted->SelectOne (sph::_0 == 1);
237 QCOMPARE (single, (boost::optional<SimpleRecord> { { 1,
"1" } }));
240 void OralTest::testSimpleRecordInsertSelectByFields ()
242 auto adapted = PrepareRecords<SimpleRecord> (
MakeDatabase ());
243 const auto& list = adapted->Select (sph::f<&SimpleRecord::ID_> == 1);
247 void OralTest::testSimpleRecordInsertSelectByFields2 ()
249 auto adapted = PrepareRecords<SimpleRecord> (
MakeDatabase ());
250 const auto& list = adapted->Select (sph::f<&SimpleRecord::ID_> < 2);
254 void OralTest::testSimpleRecordInsertSelectByFields3 ()
256 auto adapted = PrepareRecords<SimpleRecord> (
MakeDatabase ());
257 const auto& list = adapted->Select (sph::f<&SimpleRecord::ID_> < 2 && sph::f<&SimpleRecord::Value_> == QString {
"1" });
261 void OralTest::testSimpleRecordInsertSelectOneByFields ()
263 auto adapted = PrepareRecords<SimpleRecord> (
MakeDatabase ());
264 const auto& single = adapted->SelectOne (sph::f<&SimpleRecord::ID_> == 1);
265 QCOMPARE (single, (boost::optional<SimpleRecord> { { 1,
"1" } }));
268 void OralTest::testSimpleRecordInsertSelectSingleFieldByFields ()
270 auto adapted = PrepareRecords<SimpleRecord> (
MakeDatabase ());
271 const auto& list = adapted->Select (sph::fields<&SimpleRecord::Value_>, sph::f<&SimpleRecord::ID_> < 2);
275 void OralTest::testSimpleRecordInsertSelectFieldsByFields ()
277 auto adapted = PrepareRecords<SimpleRecord> (
MakeDatabase ());
278 const auto& list = adapted->Select (sph::fields<&SimpleRecord::ID_, &SimpleRecord::Value_>, sph::f<&SimpleRecord::ID_> < 2);
279 QCOMPARE (list, (
QList<std::tuple<int, QString>> { { 0,
"0" }, { 1,
"1" } }));
282 void OralTest::testSimpleRecordInsertSelectCount ()
284 auto adapted = PrepareRecords<SimpleRecord> (
MakeDatabase ());
289 void OralTest::testSimpleRecordInsertSelectCountByFields ()
291 auto adapted = PrepareRecords<SimpleRecord> (
MakeDatabase ());
292 const auto count = adapted->Select (
sph::count, sph::f<&SimpleRecord::ID_> < 2);
296 void OralTest::testSimpleRecordUpdate ()
298 auto adapted = PrepareRecords<SimpleRecord> (
MakeDatabase ());
299 adapted->Update ({ 0,
"meh" });
300 const auto updated = adapted->Select (sph::f<&SimpleRecord::ID_> == 0);
304 void OralTest::testSimpleRecordUpdateExprTree ()
306 auto adapted = PrepareRecords<SimpleRecord> (
MakeDatabase ());
307 adapted->Update (sph::f<&SimpleRecord::Value_> = QString {
"meh" }, sph::f<&SimpleRecord::ID_> == 0);
308 const auto updated = adapted->Select (sph::f<&SimpleRecord::ID_> == 0);
312 void OralTest::testSimpleRecordUpdateMultiExprTree ()
314 auto adapted = PrepareRecords<SimpleRecord> (
MakeDatabase ());
315 adapted->Update ((sph::f<&SimpleRecord::Value_> = QString {
"meh" }, sph::f<&SimpleRecord::ID_> = 10),
316 sph::f<&SimpleRecord::ID_> == 0);
317 const auto updated = adapted->Select (sph::f<&SimpleRecord::ID_> == 10);
321 void OralTest::testAutoPKeyRecordInsertSelect ()
323 auto adapted = PrepareRecords<AutogenPKeyRecord> (
MakeDatabase ());
324 const auto& list = adapted->Select ();
328 void OralTest::testAutoPKeyRecordInsertRvalueReturnsPKey ()
330 auto adapted = Util::oral::AdaptPtr<AutogenPKeyRecord> (
MakeDatabase ());
333 for (
int i = 0; i < 3; ++i)
334 ids << adapted->Insert ({ 0, QString::number (i) });
339 void OralTest::testAutoPKeyRecordInsertConstLvalueReturnsPKey ()
341 auto adapted = Util::oral::AdaptPtr<AutogenPKeyRecord> (
MakeDatabase ());
344 for (
int i = 0; i < 3; ++i)
345 records.push_back ({ 0, QString::number (i) });
348 for (
const auto& record : records)
349 ids << adapted->Insert (record);
354 void OralTest::testAutoPKeyRecordInsertSetsPKey ()
356 auto adapted = Util::oral::AdaptPtr<AutogenPKeyRecord> (
MakeDatabase ());
359 for (
int i = 0; i < 3; ++i)
360 records.push_back ({ 0, QString::number (i) });
362 for (
auto& record : records)
363 adapted->Insert (record);
368 void OralTest::testNoPKeyRecordInsertSelect ()
370 auto adapted = PrepareRecords<NoPKeyRecord> (
MakeDatabase ());
371 const auto& list = adapted->Select ();
375 void OralTest::testNonInPlaceConstructibleRecordInsertSelect ()
377 auto adapted = Util::oral::AdaptPtr<NonInPlaceConstructibleRecord> (
MakeDatabase ());
378 for (
int i = 0; i < 3; ++i)
379 adapted->Insert ({ i, QString::number (i), 0 });
381 const auto& list = adapted->Select ();
387 template<
typename Ex,
typename F>
388 void ShallThrow (F&&
f)
400 QCOMPARE (failed,
true);
404 void OralTest::testComplexConstraintsRecordInsertSelect ()
406 auto adapted = Util::oral::AdaptPtr<ComplexConstraintsRecord> (
MakeDatabase ());
408 adapted->Insert ({ 0,
"first", 1, 2 });
409 ShallThrow<oral::QueryException> ([&] { adapted->Insert ({ 0,
"second", 1, 2 }); });
410 ShallThrow<oral::QueryException> ([&] { adapted->Insert ({ 0,
"first", 1, 3 }); });
411 adapted->Insert ({ 0,
"second", 1, 3 });
412 ShallThrow<oral::QueryException> ([&] { adapted->Insert ({ 0,
"first", 1, 3 }); });
414 const auto& list = adapted->Select ();
418 void OralTest::benchSimpleRecordAdapt ()
421 Util::oral::Adapt<SimpleRecord> (db);
423 QBENCHMARK { Util::oral::Adapt<SimpleRecord> (db); }
426 void OralTest::benchBaselineInsert ()
429 Util::oral::Adapt<SimpleRecord> (db);
431 QSqlQuery query { db };
432 query.prepare (
"INSERT OR IGNORE INTO SimpleRecord (ID, Value) VALUES (:id, :val);");
436 query.bindValue (
":id", 0);
437 query.bindValue (
":val",
"0");
442 void OralTest::benchSimpleRecordInsert ()
445 const auto& adapted = Util::oral::Adapt<SimpleRecord> (db);
447 QBENCHMARK { adapted.Insert ({ 0,
"0" }, lco::InsertAction::Ignore); }
450 void OralTest::benchBaselineUpdate ()
453 const auto& adapted = Util::oral::Adapt<SimpleRecord> (db);
454 adapted.Insert ({ 0,
"0" });
456 QSqlQuery query { db };
457 query.prepare (
"UPDATE SimpleRecord SET Value = :val WHERE Id = :id;");
461 query.bindValue (
":id", 0);
462 query.bindValue (
":val",
"1");
467 void OralTest::benchSimpleRecordUpdate ()
470 auto adapted = Util::oral::Adapt<SimpleRecord> (db);
471 adapted.Insert ({ 0,
"0" });
473 QBENCHMARK { adapted.Update ({ 0,
"1" }); }
lco::PKey< int, lco::NoAutogen > ID_
constexpr detail::AggregateType< detail::AggregateFunction::Count > count
constexpr detail::ExprTree< detail::ExprType::LeafStaticPlaceholder, detail::MemberPtrs< Ptr > > f
Typelist< Args... > Constraints
static QString ClassName()
QSqlDatabase MakeDatabase(const QString &name=":memory:")
BOOST_FUSION_ADAPT_STRUCT(SimpleRecord, ID_, Value_) struct AutogenPKeyRecord