14using LC::operator
""_ct;
21 constexpr static auto ClassName =
"AutogenPKeyRecord"_ct;
40 constexpr static auto ClassName =
"NoPKeyRecord"_ct;
44 return std::tie (ID_, Value_);
54struct NonInPlaceConstructibleRecord
59 NonInPlaceConstructibleRecord () =
default;
61 NonInPlaceConstructibleRecord (
int id,
const QString& value,
double someExtraArgument)
65 Q_UNUSED (someExtraArgument)
68 constexpr static auto ClassName =
"NonInPlaceConstructibleRecord"_ct;
72 return std::tie (ID_, Value_);
80TOSTRING (NonInPlaceConstructibleRecord)
82struct ComplexConstraintsRecord
89 constexpr static auto ClassName =
"ComplexConstraintsRecord"_ct;
93 return std::tie (ID_, Value_, Age_, Weight_);
110template<
typename... Args>
113 return std::apply ([&] (
auto&&... args) {
return ((dbg.nospace () << args <<
' '), ...); },
tup);
122 void OralTest::testAutoPKeyRecordInsertSelect ()
126 const auto& list = adapted->Select ();
127 QCOMPARE (list, (QList<AutogenPKeyRecord> { { 1,
"0" }, { 2,
"1" }, { 3,
"2" } }));
130 void OralTest::testAutoPKeyRecordInsertRvalueReturnsPKey ()
135 for (
int i = 0; i < 3; ++i)
136 ids << adapted->Insert ({ 0, QString::number (i) });
138 QCOMPARE (ids, (QList<int> { 1, 2, 3 }));
141 void OralTest::testAutoPKeyRecordInsertConstLvalueReturnsPKey ()
145 QList<AutogenPKeyRecord> records;
146 for (
int i = 0; i < 3; ++i)
147 records.push_back ({ 0, QString::number (i) });
150 for (
const auto& record : records)
151 ids << adapted->Insert (record);
153 QCOMPARE (ids, (QList<int> { 1, 2, 3 }));
156 void OralTest::testAutoPKeyRecordInsertSetsPKey ()
160 QList<AutogenPKeyRecord> records;
161 for (
int i = 0; i < 3; ++i)
162 records.push_back ({ 0, QString::number (i) });
164 for (
auto& record : records)
165 adapted->Insert (record);
167 QCOMPARE (records, (QList<AutogenPKeyRecord> { { 1,
"0" }, { 2,
"1" }, { 3,
"2" } }));
170 void OralTest::testNoPKeyRecordInsertSelect ()
173 const auto& list = adapted->Select ();
174 QCOMPARE (list, (QList<NoPKeyRecord> { { 0,
"0" }, { 1,
"1" }, { 2,
"2" } }));
177 void OralTest::testNonInPlaceConstructibleRecordInsertSelect ()
180 for (
int i = 0; i < 3; ++i)
181 adapted->Insert ({ i, QString::number (i), 0 });
183 const auto& list = adapted->Select ();
184 QCOMPARE (list, (QList<NonInPlaceConstructibleRecord> { { 0,
"0", 0 }, { 1,
"1", 0 }, { 2,
"2", 0 } }));
189 template<
typename Ex,
typename F>
190 void ShallThrow (F&& f)
202 QCOMPARE (failed,
true);
206 void OralTest::testComplexConstraintsRecordInsertSelectDefault ()
210 adapted->Insert ({ 0,
"first", 1, 2 });
211 ShallThrow<oral::QueryException> ([&] { adapted->Insert ({ 0,
"second", 1, 2 }); });
212 ShallThrow<oral::QueryException> ([&] { adapted->Insert ({ 0,
"first", 1, 3 }); });
213 adapted->Insert ({ 0,
"second", 1, 3 });
214 ShallThrow<oral::QueryException> ([&] { adapted->Insert ({ 0,
"first", 1, 3 }); });
216 const auto& list = adapted->Select ();
217 QCOMPARE (list, (QList<ComplexConstraintsRecord> { { 0,
"first", 1, 2 }, { 0,
"second", 1, 3 } }));
220 void OralTest::testComplexConstraintsRecordInsertSelectIgnore ()
230 const auto& list = adapted->Select ();
231 QCOMPARE (list, (QList<ComplexConstraintsRecord> { { 0,
"first", 1, 2 }, { 0,
"second", 1, 3 } }));
234 void OralTest::testComplexConstraintsRecordInsertSelectReplace ()
239 &ComplexConstraintsRecord::ID_,
240 &ComplexConstraintsRecord::Value_
243 &ComplexConstraintsRecord::Weight_,
244 &ComplexConstraintsRecord::Age_
246 adapted->Insert ({ 0,
"first", 1, 2 }, idValueFields);
247 adapted->Insert ({ 0,
"second", 1, 2 }, weightAgeFields);
248 adapted->Insert ({ 0,
"first", 1, 3 }, idValueFields);
249 adapted->Insert ({ 0,
"third", 1, 3 }, weightAgeFields);
250 adapted->Insert ({ 0,
"first", 1, 3 }, weightAgeFields);
252 const auto& list = adapted->Select ();
253 QCOMPARE (list, (QList<ComplexConstraintsRecord> { {0,
"second", 1, 2 }, { 0,
"first", 1, 3 } }));
constexpr auto FieldNames
constexpr detail::ExprTree< detail::ExprType::LeafStaticPlaceholder, detail::MemberPtrs< Ptr > > f
Typelist< Args... > Constraints
ObjectInfo_ptr< T > AdaptPtr(const QSqlDatabase &db)
auto PrepareRecords(QSqlDatabase db, int count=3)
QSqlDatabase MakeDatabase(const QString &name=":memory:")
#define ORAL_ADAPT_STRUCT(sname,...)
const std::tuple< Args... > & tup
QDataStream & operator<<(QDataStream &out, const LC::Util::RegExp &rx)
static constexpr auto ClassName
static constexpr FieldsType< Ptrs... > Fields
static constexpr struct LC::Util::oral::InsertAction::IgnoreTag Ignore