160 namespace sph = oral::sph;
162 void OralTest::testNestedIndirect ()
167 static_assert (std::is_same_v<std::decay_t<
decltype (*prid)>,
int>);
173 static_assert (std::is_same_v<std::decay_t<
decltype (*purid)>,
int>);
176 void OralTest::testAutoPKeyRecordInsertSelect ()
180 const auto& list = adapted->Select ();
184 void OralTest::testAutoPKeyRecordInsertRvalueReturnsPKey ()
189 for (
int i = 0; i < 3; ++i)
190 ids << adapted->Insert ({ 0, QString::number (i) });
195 void OralTest::testAutoPKeyRecordInsertConstLvalueReturnsPKey ()
200 for (
int i = 0; i < 3; ++i)
201 records.push_back ({ 0, QString::number (i) });
204 for (
const auto& record : records)
205 ids << adapted->Insert (record);
210 void OralTest::testAutoPKeyRecordInsertSetsPKey ()
215 for (
int i = 0; i < 3; ++i)
216 records.push_back ({ 0, QString::number (i) });
218 for (
auto& record : records)
219 adapted->Insert (record);
224 void OralTest::testNoPKeyRecordInsertSelect ()
227 const auto& list = adapted->Select ();
231 void OralTest::testNonInPlaceConstructibleRecordInsertSelect ()
234 for (
int i = 0; i < 3; ++i)
235 adapted->Insert ({ i, QString::number (i), 0 });
237 const auto& list = adapted->Select ();
241 void OralTest::testComplexConstraintsRecordInsertSelectDefault ()
245 adapted->Insert ({ 0,
"first",
"c1", 1, 2 });
246 QVERIFY_THROWS_EXCEPTION (oral::QueryException, adapted->Insert ({ 0,
"second",
"c1", 1, 2 }));
247 QVERIFY_THROWS_EXCEPTION (oral::QueryException, adapted->Insert ({ 0,
"first",
"c1", 1, 3 }));
248 adapted->Insert ({ 0,
"second",
"c2", 1, 3 });
249 QVERIFY_THROWS_EXCEPTION (oral::QueryException, adapted->Insert ({ 0,
"first",
"c1", 1, 3 }));
251 const auto& list = adapted->Select ();
252 QCOMPARE (list, (
QList<ComplexConstraintsRecord> { { 0,
"first",
"c1", 1, 2 }, { 0,
"second",
"c2", 1, 3 } }));
255 void OralTest::testComplexConstraintsRecordInsertSelectIgnore ()
265 const auto& list = adapted->Select ();
266 QCOMPARE (list, (
QList<ComplexConstraintsRecord> { { 0,
"first",
"c1", 1, 2 }, { 0,
"second",
"c4", 1, 3 } }));
269 void OralTest::testComplexConstraintsRecordInsertSelectReplace ()
273 adapted->Insert ({ 0,
"alice",
"city1", 1, 2 });
274 adapted->Insert ({ 0,
"bob",
"city2", 1, 2 },
278 adapted->Insert ({ 0,
"alice",
"city3", 2, 3 });
279 QCOMPARE (adapted->Select (), (
QList<ComplexConstraintsRecord> { { 0,
"bob",
"city1", 1, 2 }, { 0,
"alice",
"city3", 2, 3 } }));
282 QVERIFY_THROWS_EXCEPTION (oral::QueryException,
283 adapted->Insert ({ 1,
"bob",
"city4", 2, 3 },
286 adapted->Insert ({ 1,
"bob",
"city4", 2, 3 },
288 QCOMPARE (adapted->Select (), (
QList<ComplexConstraintsRecord> { { 0,
"bob",
"city1", 1, 2 }, { 1,
"bob",
"city4", 2, 3 } }));
291 void OralTest::testConstrainedAutogenPKeyRecordInsertIgnore ()
293 using Rec = ConstrainedAutogenPKeyRecord;
294 auto adapted = Util::oral::AdaptPtr<Rec, OralFactory> (MakeDatabase ());
296 QCOMPARE (adapted->Insert ({ .City_ =
"c1", .Population_ = 100 }), 1);
297 QCOMPARE (adapted->Insert ({ .City_ =
"c2", .Population_ = 200 }), 2);
298 QCOMPARE (adapted->Select (), (
QList<Rec> { { 1,
"c1", 100 }, { 2,
"c2", 200 } }));
302 QCOMPARE (adapted->Select (), (
QList<Rec> { { 1,
"c1", 100 }, { 2,
"c2", 200 } }));
305 void OralTest::testConstrainedAutogenPKeyRecordInsertReplace ()
307 using Rec = ConstrainedAutogenPKeyRecord;
308 auto adapted = Util::oral::AdaptPtr<Rec, OralFactory> (MakeDatabase ());
310 QCOMPARE (adapted->Insert ({ .City_ =
"c1", .Population_ = 100 }), 1);
311 QCOMPARE (adapted->Insert ({ .City_ =
"c2", .Population_ = 200 }), 2);
312 QCOMPARE (adapted->Select (), (
QList<Rec> { { 1,
"c1", 100 }, { 2,
"c2", 200 } }));
314 QVERIFY_THROWS_EXCEPTION (oral::QueryException, adapted->Insert ({ .City_ =
"c1", .Population_ = 300 }));
318 QCOMPARE (adapted->Select (), (
QList<Rec> { { 1,
"c1", 300 }, { 2,
"c2", 400 } }));
321 void OralTest::testOptionalFieldNullRoundTrip ()
323 using Rec = OptionalFieldRecord;
324 auto adapted = Util::oral::AdaptPtr<Rec, OralFactory> (MakeDatabase ());
326 adapted->Insert ({ {},
"alice", std::nullopt, std::nullopt });
327 adapted->Insert ({ {},
"bob", std::nullopt, std::nullopt });
329 const auto& list = adapted->Select ();
330 QCOMPARE (list.size (), 2);
331 QCOMPARE (list [0].NickName_, std::nullopt);
332 QCOMPARE (list [0].Extra_, std::nullopt);
333 QCOMPARE (list [1].NickName_, std::nullopt);
334 QCOMPARE (list [1].Extra_, std::nullopt);
337 void OralTest::testOptionalFieldValueRoundTrip ()
339 using Rec = OptionalFieldRecord;
340 auto adapted = Util::oral::AdaptPtr<Rec, OralFactory> (MakeDatabase ());
342 adapted->Insert ({ {},
"alice",
"Al", QByteArray {
"data1" } });
343 adapted->Insert ({ {},
"bob", std::nullopt, std::nullopt });
345 const auto& list = adapted->Select ();
346 QCOMPARE (list.size (), 2);
347 QCOMPARE (list [0].NickName_, std::optional<QString> {
"Al" });
348 QCOMPARE (list [0].Extra_, std::optional<QByteArray> {
"data1" });
349 QCOMPARE (list [1].NickName_, std::nullopt);
350 QCOMPARE (list [1].Extra_, std::nullopt);
353 void OralTest::testOptionalFieldUpdateNullToValue ()
355 using Rec = OptionalFieldRecord;
356 auto adapted = Util::oral::AdaptPtr<Rec, OralFactory> (MakeDatabase ());
358 adapted->Insert ({ {},
"alice", std::nullopt, std::nullopt });
359 adapted->Update (sph::f<&Rec::NickName_> = QString {
"Al" },
360 sph::f<&Rec::Name_> == QString {
"alice" });
362 const auto& list = adapted->Select ();
363 QCOMPARE (list.size (), 1);
364 QCOMPARE (list [0].NickName_, std::optional<QString> {
"Al" });
365 QCOMPARE (list [0].Extra_, std::nullopt);
368 void OralTest::testOptionalFieldUpdateValueToNull ()
370 using Rec = OptionalFieldRecord;
371 auto adapted = Util::oral::AdaptPtr<Rec, OralFactory> (MakeDatabase ());
373 adapted->Insert ({ {},
"alice",
"Al", QByteArray {
"data" } });
374 adapted->Update (sph::f<&Rec::NickName_> = std::optional<QString> {},
375 sph::f<&Rec::Name_> == QString {
"alice" });
377 const auto& list = adapted->Select ();
378 QCOMPARE (list.size (), 1);
379 QCOMPARE (list [0].NickName_, std::nullopt);
380 QCOMPARE (list [0].Extra_, std::optional<QByteArray> {
"data" });