15#include <boost/preprocessor/stringize.hpp>
16#include <boost/preprocessor/tuple.hpp>
33#ifndef ORAL_ADAPT_STRUCT
35#define ORAL_STRING_FIELD_IMPL(index, sname, field) \
37 constexpr auto MemberNameByIdx<sname, index> = CtString { BOOST_PP_STRINGIZE(field) }; \
39 constexpr auto MemberNameByPtr<&sname::field> = CtString { BOOST_PP_STRINGIZE(field) };
41#define ORAL_STRING_FIELD(_, index, args) \
42 ORAL_STRING_FIELD_IMPL(index, BOOST_PP_TUPLE_ELEM(0, args), BOOST_PP_TUPLE_ELEM(index, BOOST_PP_TUPLE_ELEM(1, args)))
44#define ORAL_ADAPT_STRUCT(sname, ...) \
45namespace LC::Util::oral \
48 constexpr auto BeenAdapted<sname> = true; \
51 constexpr auto SeqSize<sname> = BOOST_PP_TUPLE_SIZE((__VA_ARGS__)); \
53 static_assert (SeqSize<sname> == detail::FullSize<sname>); \
55 BOOST_PP_REPEAT(BOOST_PP_TUPLE_SIZE((__VA_ARGS__)), ORAL_STRING_FIELD, (sname, (__VA_ARGS__))) \
66 using std::runtime_error::runtime_error;
82 template<
typename,
int>
90 template<
size_t Idx,
typename Seq>
91 constexpr decltype (
auto)
Get (
const Seq& seq)
93 const auto& [...fields] = seq;
94 return (fields... [Idx]);
97 template<
size_t Idx,
typename Seq>
98 constexpr decltype (
auto)
Get (Seq& seq)
100 auto& [...fields] = seq;
101 return (fields... [Idx]);
104 template<
typename Seq>
107 const auto& [...fields] = seq;
108 return std::integral_constant<size_t,
sizeof... (fields)> {};
111 template<
typename Seq>
114 template<
typename T, CtString str>
117 if constexpr (
requires { T::template FieldNameMorpher<str> (); })
118 return T::template FieldNameMorpher<str> ();
119 else if constexpr (str.EndsWith (
'_'))
120 return str.template Chop<1> ();
125 template<
typename Seq,
int Idx>
133 constexpr auto SeqIndices = std::make_index_sequence<SeqSize<S>> {};
136 constexpr auto FieldNames = []<
size_t... Ix> (std::index_sequence<Ix...>)
constexpr
142 constexpr auto BoundFieldNames = []<
size_t... Ix> (std::index_sequence<Ix...>)
constexpr
164 requires (!std::same_as<T, QVariant>)
167 template<
typename ImplFactory,
typename T>
170 constexpr auto operator() () const noexcept
178 else if constexpr (std::is_same_v<T, double>)
180 else if constexpr (std::is_same_v<T, QString> || std::is_same_v<T, QDateTime> || std::is_same_v<T, QUrl>)
182 else if constexpr (std::is_same_v<T, QByteArray>)
183 return ImplFactory::TypeLits::Binary;
185 static_assert (std::is_same_v<T, struct Dummy>,
"Unsupported type");
189 template<
typename ImplFactory,
typename T>
195 template<
typename ImplFactory,
typename T>
201 template<
typename ImplFactory,
typename T,
typename...
Tags>
207 template<
typename ImplFactory,
typename...
Tags>
210 constexpr auto operator() () const noexcept {
return ImplFactory::TypeLits::IntAutoincrement; }
213 template<
typename ImplFactory,
typename T>
219 template<
typename ImplFactory, auto Ptr>
222 constexpr auto operator() () const noexcept
234 requires (!std::same_as<T, QVariant>)
237 static QVariant operator() (
const T& t)
noexcept
240 return t.ToVariant ();
241 else if constexpr (std::is_same_v<T, QDateTime>)
242 return t.toString (Qt::ISODateWithMs);
243 else if constexpr (std::is_enum_v<T>)
244 return static_cast<qint64
> (t);
251 static T operator() (
const QVariant& var)
noexcept
254 return T::FromVariant (var);
255 else if constexpr (std::is_same_v<T, QDateTime>)
256 return QDateTime::fromString (var.toString (), Qt::ISODateWithMs);
257 else if constexpr (std::is_enum_v<T>)
258 return static_cast<T
> (var.value<qint64> ());
262 return var.value<T> ();
269 static QVariant operator() (
const std::optional<T>& t)
noexcept
274 static std::optional<T> operator() (
const QVariant& var)
noexcept
276 return var.isNull () ? std::nullopt : std::optional {
Convert<T> (var) };
282 template<
typename Seq,
int Idx>
283 using ValueAtC_t = std::decay_t<decltype (Get<Idx> (std::declval<Seq> ()))>;
288 template<
typename U,
typename...
Tags>
297 template<
size_t Ix,
typename Seq>
298 void BindAtIndex (
const Seq& seq, QSqlQuery& query,
bool bindPrimaryKey)
304 template<
typename Seq>
305 auto DoInsert (
const Seq& seq, QSqlQuery& insertQuery,
bool bindPrimaryKey)
307 [&]<
size_t... Ix> (std::index_sequence<Ix...>)
312 if (!insertQuery.exec ())
314 qCritical () <<
"insert query execution failed";
320 template<
typename Seq>
323 auto run = []<
size_t... Idxes> (std::index_sequence<Idxes...>)
342 template<
typename Seq>
346 static_assert (idx >= 0);
350 template<
typename Seq>
353 template<
typename Seq>
356 template<
typename Seq>
369 template<
typename Seq>
374 return []<
size_t... Idxs> (std::index_sequence<Idxs...>)
376 const auto [...namesPack] = allNames;
377 return std::tuple { namesPack... [Idxs >=
PKeyIndex_v<Seq> ? Idxs + 1 : Idxs]... };
378 } (std::make_index_sequence<SeqSize<Seq> - 1> ());
383 template<
typename Seq,
auto... Ptrs>
389 template<
typename Seq>
392 const QSqlDatabase DB_;
400 template<
typename Action = InsertAction::DefaultTag>
401 auto operator() (Seq& t, Action action = {})
const
403 return Run<SQLite::ImplFactory> (t, action);
406 template<
typename ImplFactory>
407 auto operator() (ImplFactory, Seq& t,
auto action)
const
409 return Run<ImplFactory> (t, action);
412 template<
typename Action = InsertAction::DefaultTag>
413 auto operator() (
const Seq& t, Action action = {})
const
415 return Run<SQLite::ImplFactory> (t, action);
418 template<
typename ImplFactory>
419 auto operator() (ImplFactory,
const Seq& t,
auto action)
const
421 return Run<ImplFactory> (t, action);
424 template<
typename ImplFactory,
typename Action>
425 constexpr static auto MakeInsertSuffix (Action action)
427 if constexpr (HasAutogen_)
430 if constexpr (std::is_same_v<Action, InsertAction::DefaultTag> || std::is_same_v<Action, InsertAction::IgnoreTag>)
434 ExtractReplaceFields<Seq> (action),
435 GetFieldName<Seq, pkIdx> ());
439 if constexpr (std::is_same_v<Action, InsertAction::DefaultTag> || std::is_same_v<Action, InsertAction::IgnoreTag>)
440 return ImplFactory::GetInsertSuffix (action);
442 return ImplFactory::GetInsertSuffix (InsertAction::Replace {},
443 ExtractReplaceFields<Seq> (action));
447 template<
typename ImplFactory>
448 constexpr static auto MakeQueryForAction (
auto action)
450 return ImplFactory::GetInsertPrefix (action) +
451 " INTO " + Seq::ClassName +
452 " (" +
JoinTup (FieldNames<Seq>,
", ") +
") " +
453 "VALUES (" +
JoinTup (BoundFieldNames<Seq>,
", ") +
") " +
454 MakeInsertSuffix<ImplFactory> (action);
457 template<
typename ImplFactory,
typename T,
typename Action>
458 auto Run (T& t, Action action)
const
460 QSqlQuery query { DB_ };
461 constexpr auto queryText = MakeQueryForAction<ImplFactory> (action);
462 query.prepare (ToString<queryText> ());
466 if constexpr (HasAutogen_)
468 constexpr auto pkIndex = PKeyIndex_v<Seq>;
469 constexpr auto mightBeMissing = std::same_as<Action, InsertAction::IgnoreTag>;
474 if constexpr (mightBeMissing)
475 return std::optional<FieldType_t> {};
476 throw QueryException {
"unable to fetch last inserted rowid" };
479 const auto& lastId = Convert<FieldType_t> (query.value (0));
481 if constexpr (!std::is_const_v<T>)
482 Get<pkIndex> (t) = lastId;
484 if constexpr (mightBeMissing)
485 return std::optional { lastId };
492 template<
typename Seq>
503 constexpr auto del =
"DELETE FROM " + Seq::ClassName +
518 template<
typename T,
size_t...
Indices>
552 template<ExprType Type>
574 static_assert (std::is_same_v<struct D1, ExprType>,
"Invalid expression type");
589 template<ExprType Type>
593 return "lower(" + subexpr +
")";
598 template<ExprType Type,
typename Seq,
typename L,
typename R>
605 return requires (LReal l, RReal r) { l == r; };
611 template<ExprType Type,
typename L =
void,
typename R =
void>
617 template<ExprType Type,
typename L,
typename R>
620 template<
typename L,
typename R>
632 template<
typename Seq, CtString S>
633 constexpr static auto ToSql () noexcept
636 return L::GetFieldName () +
" = " + R::template
ToSql<Seq, S +
"r"> ();
641 template<
typename Seq, CtString S>
644 Left_.template
BindValues<Seq, S +
"l"> (query);
645 Right_.template
BindValues<Seq, S +
"r"> (query);
648 template<
typename OL,
typename OR>
655 template<ExprType Type,
typename L,
typename R>
661 constexpr ExprTree (
const L& l,
const R& r) noexcept
667 template<
typename Seq, CtString S>
668 constexpr static auto ToSql () noexcept
671 "Incompatible types passed to a relational operator.");
678 template<
typename Seq, CtString S>
681 Left_.template
BindValues<Seq, S +
"l"> (query);
682 Right_.template
BindValues<Seq, S +
"r"> (query);
711 template<
typename, CtString S>
712 constexpr static auto ToSql () noexcept
714 return ":bound_" + S;
717 template<
typename Seq, CtString S>
727 return std::tuple {};
737 template<
typename... Ts>
740 const std::tuple<Ts...>& Data_;
742 template<
size_t Idx, CtString S>
748 constexpr ExprTree (
const std::tuple<Ts...>& t) noexcept
753 template<
typename, CtString S>
754 constexpr static auto ToSql () noexcept
758 return "(" +
Join (
", "_ct, BoundVarName<Indices, S>...) +
")";
759 } (std::index_sequence_for<Ts...> {});
762 template<
typename Seq, CtString S>
767 (query.bindValue (
ToString<BoundVarName<Indices, S>> (),
ToVariantF (std::get<Indices> (Data_))), ...);
768 } (std::index_sequence_for<Ts...> {});
774 return std::tuple {};
793 template<
auto... Ptr>
804 template<
typename Seq, CtString S>
805 constexpr static auto ToSql () noexcept
810 template<
typename Seq, CtString S>
824 if constexpr (std::is_same_v<Seq, T>)
825 return std::tuple {};
827 return std::tuple { Seq::ClassName };
833 return !std::is_same_v<MemberPtrStruct_t<Ptr>, T>;
836 constexpr auto operator= (
const ExpectedType_t& r)
const noexcept
842 template<
auto... Ptrs>
843 requires (
sizeof... (Ptrs) > 1)
846 using ExpectedType_t = std::tuple<MemberPtrType_t<Ptrs>...>;
851 template<
typename Seq, CtString S>
852 constexpr static auto ToSql () noexcept
857 template<
typename Seq, CtString S>
865 return std::tuple_cat ([]
868 if constexpr (std::is_same_v<Seq, T>)
869 return std::tuple {};
871 return std::tuple { Seq::ClassName };
878 return !(std::is_same_v<MemberPtrStruct_t<Ptrs>, T> || ...);
886 template<
typename, CtString>
887 constexpr static auto ToSql () noexcept
892 template<
typename, CtString>
906 template<ExprType Type,
typename L,
typename R>
914 template<
typename L,
typename R>
917 template<
typename L,
typename R>
924 template<
typename L,
typename R>
925 requires EitherIsExprTree<L, R>
926 auto operator< (
const L& left,
const R& right)
noexcept
931 template<
typename L,
typename R>
932 requires EitherIsExprTree<L, R>
933 auto operator<= (
const L& left,
const R& right)
noexcept
938 template<
typename L,
typename R>
939 requires EitherIsExprTree<L, R>
940 auto operator> (
const L& left,
const R& right)
noexcept
945 template<
typename L,
typename R>
946 requires EitherIsExprTree<L, R>
947 auto operator>= (
const L& left,
const R& right)
noexcept
952 template<
typename L,
typename R>
953 requires EitherIsExprTree<L, R>
954 auto operator!= (
const L& left,
const R& right)
noexcept
959 template<ExprType Op>
971 template<
typename L, ExprType Op>
977 template<
typename L, ExprType Op>
983 template<
typename L, ExprType Op,
typename R>
989 template<
typename L,
typename R>
990 requires EitherIsExprTree<L, R>
991 auto operator&& (
const L& left,
const R& right)
noexcept
996 template<
typename L,
typename R>
997 requires EitherIsExprTree<L, R>
998 auto operator|| (
const L& left,
const R& right)
noexcept
1003 template<CtString BindPrefix,
typename Seq,
typename Tree>
1006 return Tree::template ToSql<Seq, BindPrefix> ();
1009 template<CtString BindPrefix,
typename Seq,
typename Tree>
1012 tree.template BindValues<Seq, BindPrefix> (query);
1022 template<AggregateFunction, auto Ptr>
1025 template<
typename FunRetType, CtString Fun, auto Ptr>
1030 template<
typename... MemberDirectionList>
1033 template<
auto... Ptrs>
1038 template<
typename L,
typename R>
1041 template<
typename T>
1047 template<
typename T>
1053 template<AggregateFunction Fun, auto Ptr>
1056 template<
typename FunRetType, CtString Fun, auto Ptr>
1059 template<
auto... Ptrs>
1062 template<
typename L,
typename R>
1065 template<
typename T>
1068 template<
typename L,
typename R>
1081 template<
auto... Ptrs>
1084 template<
auto... Ptrs>
1089 template<
typename T>
1092 template<
auto... Ptrs>
1095 template<
auto... Ptrs>
1099 template<
auto Ptr = std::true_type {}>
1108 template<
typename FunRetType, CtString Fun, auto Ptr>
1112 template<
typename... Orders>
1115 template<
auto... Ptrs>
1142 template<
auto... Ptrs>
1145 if constexpr (
sizeof... (Ptrs) == 1)
1148 return [&]<
size_t... Ix> (std::index_sequence<Ix...>)
1151 } (std::make_index_sequence<
sizeof... (Ptrs)> {});
1161 template<
size_t RepIdx,
size_t TupIdx,
typename Tuple,
typename NewType>
1164 if constexpr (RepIdx == TupIdx)
1165 return std::forward<NewType> (arg);
1167 return std::get<TupIdx> (tuple);
1170 template<
size_t RepIdx,
typename NewType,
typename Tuple,
size_t... TupIdxs>
1179 template<
size_t RepIdx,
typename NewType,
typename... TupleArgs>
1183 std::forward<NewType> (arg),
1184 std::index_sequence_for<TupleArgs...> {});
1187 template<
typename Seq,
typename T>
1193 template<
typename Seq,
typename... Args>
1199 template<
typename Seq>
1205 template<
typename... LArgs,
typename... RArgs>
1206 auto Combine (std::tuple<LArgs...>&& left, std::tuple<RArgs...>&& right)
noexcept
1208 return std::tuple_cat (std::move (left), std::move (right));
1211 template<
typename... LArgs,
typename R>
1212 auto Combine (std::tuple<LArgs...>&& left,
const R& right)
noexcept
1214 return std::tuple_cat (std::move (left), std::tuple { right });
1217 template<
typename L,
typename... RArgs>
1218 auto Combine (
const L& left, std::tuple<RArgs...>&& right)
noexcept
1220 return std::tuple_cat (std::tuple { left }, std::move (right));
1223 template<
typename L,
typename R>
1224 auto Combine (
const L& left,
const R& right)
noexcept
1226 return std::tuple { left, right };
1235 template<ResultBehaviour ResultBehaviour,
typename ResList>
1239 return std::forward<ResList> (list);
1241 return list.value (0);
1246 const QSqlDatabase DB_;
1254 auto&& binder)
const
1256 QSqlQuery query { DB_ };
1257 query.prepare (queryStr);
1262 qCritical () <<
"select query execution failed";
1271 template<
typename L,
typename O>
1274 if constexpr (std::is_same_v<L, LimitNone>)
1276 static_assert (std::is_same_v<O, OffsetNone>,
"LIMIT-less queries currently cannot have OFFSET");
1280 return " LIMIT :limit "_ct +
1283 if constexpr (std::is_same_v<O, OffsetNone>)
1286 return " OFFSET :offset"_ct;
1290 template<
typename L,
typename O>
1293 if constexpr (!std::is_same_v<std::decay_t<L>,
LimitNone>)
1294 query.bindValue (
":limit", qulonglong { limit.Count });
1295 if constexpr (!std::is_same_v<std::decay_t<O>,
OffsetNone>)
1296 query.bindValue (
":offset", qulonglong { offset.Count });
1299 template<
typename T,
typename Selector>
1305 template<
typename T>
1316 template<
typename T,
typename U>
1322 template<
typename T,
auto... Ptrs>
1333 template<
typename T,
typename FunRetType, CtString Fun, auto Ptr>
1344 template<
typename T>
1347 constexpr static auto Fields =
"count(1)"_ct;
1351 return q.value (startIdx).toLongLong ();
1355 template<
typename T, auto Ptr>
1362 return q.value (startIdx).toLongLong ();
1366 template<CtString Aggregate,
typename T, auto Ptr>
1373 const auto& var = q.value (startIdx);
1374 return var.isNull () ?
1380 template<
typename T, auto Ptr>
1383 template<
typename T, auto Ptr>
1393 template<
typename T,
typename L,
typename R>
1401 constexpr static auto Fields = HL::Fields +
", " + HR::Fields;
1405 constexpr auto shift =
DetectShift<T,
decltype (HL::Initializer (q, 0))>::Value;
1406 return Combine (HL::Initializer (q, startIdx), HR::Initializer (q, startIdx + shift));
1410 template<
typename T, SelectBehaviour SelectBehaviour>
1413 template<
typename ParamsTuple>
1417 ParamsTuple Params_;
1419 template<
typename NewTuple>
1420 constexpr auto RepTuple (NewTuple&& tuple)
noexcept
1422 return Builder<NewTuple> { W_, tuple };
1425 template<
typename U>
1426 constexpr auto Select (U&& selector) &&
noexcept
1431 template<
typename U>
1432 constexpr auto Where (U&& tree) &&
noexcept
1437 template<
typename U>
1438 constexpr auto AndWhere (U&& tree) &&
noexcept
1440 return std::move (*this).Where (std::get<1> (Params_) && std::forward<U> (tree));
1443 template<
typename U>
1444 constexpr auto Order (U&& order) &&
noexcept
1449 template<
typename U>
1450 constexpr auto Group (U&& group) &&
noexcept
1455 constexpr auto Limit (
Limit limit) &&
noexcept
1460 constexpr auto Limit (uint64_t limit) &&
noexcept
1462 return std::move (*this).Limit (
oral::Limit { limit });
1470 constexpr auto Offset (uint64_t offset) &&
noexcept
1472 return std::move (*this).Offset (
oral::Offset { offset });
1475 auto operator() () &&
1477 return std::apply (W_, Params_);
1480 template<
auto... Ptrs>
1481 constexpr auto Group () &&
noexcept
1491 std::tuple defParams
1500 return Builder<
decltype (defParams)> { *
this, defParams };
1503 auto operator() ()
const
1508 template<
typename Single>
1509 auto operator() (Single&& single)
const
1512 return (*
this) (
SelectWhole {}, std::forward<Single> (single));
1519 ExprType Type,
typename L,
typename R,
1525 auto operator() (Selector,
1529 Limit limit = LimitNone {},
1530 Offset offset = OffsetNone {})
const
1532 using TreeType_t = ExprTree<Type, L, R>;
1534 constexpr auto where = ExprTreeToSql<
"", T, TreeType_t> ();
1535 constexpr auto wherePrefix = [where]
1537 if constexpr (where.IsEmpty ())
1540 return " WHERE "_ct;
1542 constexpr auto from = BuildFromClause<TreeType_t> ();
1543 const auto binder = [&] (QSqlQuery& query)
1545 BindExprTree<
"", T> (tree, query);
1546 BindLimitOffset (query, limit, offset);
1548 using HS = HandleSelector<T, Selector>;
1550 constexpr auto query =
"SELECT " + HS::Fields +
1552 wherePrefix + where +
1553 HandleOrder (std::forward<Order> (order)) +
1554 HandleGroup (std::forward<Group> (group)) +
1555 LimitOffsetToString<Limit, Offset> ();
1556 auto selectResult = Select<HS> (ToString<query> (), binder);
1557 return HandleResultBehaviour<HS::ResultBehaviour_v> (std::move (selectResult));
1560 template<
typename HS,
typename Binder>
1561 auto Select (
const QString& queryStr,
1562 Binder&& binder)
const
1564 auto query =
RunQuery (queryStr, binder);
1568 QList<
decltype (HS::Initializer (query, 0))> result;
1569 while (query.next ())
1570 result << HS::Initializer (query, 0);
1575 using RetType_t = std::optional<
decltype (HS::Initializer (query, 0))>;
1576 return query.next () ?
1577 RetType_t { HS::Initializer (query, 0) } :
1582 template<
typename Tree>
1583 consteval static auto BuildFromClause () noexcept
1585 if constexpr (Tree::template HasAdditionalTables<T> ())
1586 return T::ClassName +
", " + JoinTup (Nub<Tree::template AdditionalTables<T>> (),
", ");
1588 return T::ClassName;
1591 constexpr static auto HandleOrder (OrderNone)
noexcept
1596 template<
auto... Ptrs>
1597 constexpr static auto HandleSuborder (sph::asc<Ptrs...>)
noexcept
1599 return std::tuple { (QualifiedFieldNameByPtr<Ptrs> +
" ASC")... };
1602 template<
auto... Ptrs>
1603 constexpr static auto HandleSuborder (sph::desc<Ptrs...>)
noexcept
1605 return std::tuple { (QualifiedFieldNameByPtr<Ptrs> +
" DESC")... };
1608 template<
typename... Suborders>
1609 constexpr static auto HandleOrder (OrderBy<Suborders...>)
noexcept
1611 return " ORDER BY " +
JoinTup (std::tuple_cat (HandleSuborder (Suborders {})...),
", ");
1614 constexpr static auto HandleGroup (GroupNone)
noexcept
1619 template<
auto... Ptrs>
1620 constexpr static auto HandleGroup (GroupBy<Ptrs...>)
noexcept
1622 return " GROUP BY " +
Join (
", ", QualifiedFieldNameByPtr<Ptrs>...);
1626 template<
typename T>
1629 const QSqlDatabase DB_;
1636 template<ExprType Type,
typename L,
typename R>
1641 constexpr auto selectAll =
"DELETE FROM " + T::ClassName +
" WHERE " + where;
1643 QSqlQuery query { DB_ };
1650 template<
typename T>
1653 const QSqlDatabase DB_;
1656 QSqlQuery UpdateByPKey_ { DB_ };
1665 constexpr auto update =
"UPDATE " + T::ClassName +
1666 " SET " +
JoinTup (statements,
", ") +
1667 " WHERE " + std::get<pkeyIdx> (statements);
1674 DoInsert (seq, UpdateByPKey_,
true);
1677 template<
typename SL,
typename SR, ExprType WType,
typename WL,
typename WR>
1681 "joins in update statements are not supported by SQL");
1686 constexpr auto update =
"UPDATE " + T::ClassName +
1687 " SET " + setClause +
1688 " WHERE " + whereClause;
1690 QSqlQuery query { DB_ };
1696 qCritical () <<
"update query execution failed";
1701 return query.numRowsAffected ();
1706 template<
typename...>
typename Tgt = std::tuple,
1707 template<
typename...>
typename Src,
1710 constexpr auto MapTy (Src<Vals...>,
auto f)
1712 return Tgt { f (Vals {})... };
1715 template<
typename Seq,
auto... Ptrs>
1718 constexpr auto query =
"CREATE INDEX IF NOT EXISTS "_ct +
1725 template<
typename Seq>
1728 if constexpr (
requires {
typename Seq::Indices; })
1732 template<
auto... Ptrs>
1738 template<
auto... Ptrs>
1744 template<
typename T>
1747 if constexpr (
requires {
typename T::Constraints; })
1750 return std::tuple {};
1753 template<
typename ImplFactory,
typename T,
size_t...
Indices>
1754 constexpr auto GetTypes (std::index_sequence<Indices...>)
noexcept
1759 template<auto Name,
typename ImplFactory,
typename T>
1765 constexpr auto constraintsStr = [&]
1767 if constexpr (!std::tuple_size_v<
decltype (constraints)>)
1770 return ", " +
JoinTup (constraints,
", ");
1774 return "CREATE TABLE " +
1782 template<
typename ImplFactory,
typename T>
1789 template<
typename T>
1803 template<
typename T,
typename ImplFactory = detail::SQLite::ImplFactory>
1828 template<
typename T>
1831 template<
typename T,
typename ImplFactory = SQLiteImplFactory>
static UTIL_DB_API void DumpError(const QSqlError &error)
Dumps the error to the qWarning() stream.
A somewhat "strong" typedef.
~QueryException() noexcept=default
AdaptInsert(const QSqlDatabase &db) noexcept
AdaptUpdate(const QSqlDatabase &db) noexcept
constexpr AssignList(const L &l, const R &r) noexcept
void BindValues(QSqlQuery &query) const noexcept
static constexpr auto ToSql() noexcept
DeleteByFieldsWrapper(const QSqlDatabase &db) noexcept
static constexpr bool HasAdditionalTables() noexcept
void BindValues(QSqlQuery &) const noexcept
static constexpr auto ToSql() noexcept
static constexpr auto ToSql() noexcept
static constexpr auto AdditionalTables() noexcept
void BindValues(QSqlQuery &query) const noexcept
static constexpr bool HasAdditionalTables() noexcept
constexpr ExprTree(const T &t) noexcept
static constexpr auto AdditionalTables() noexcept
constexpr ExprTree(const std::tuple< Ts... > &t) noexcept
static constexpr bool HasAdditionalTables() noexcept
static constexpr auto ToSql() noexcept
std::tuple< Ts... > ValueType_t
void BindValues(QSqlQuery &query) const noexcept
ExpectedType_t ValueType_t
static constexpr bool HasAdditionalTables() noexcept
static constexpr auto GetFieldName() noexcept
static constexpr auto ToSql() noexcept
void BindValues(QSqlQuery &) const noexcept
static constexpr auto AdditionalTables() noexcept
void BindValues(QSqlQuery &) const noexcept
static constexpr auto AdditionalTables() noexcept
ExpectedType_t ValueType_t
static constexpr auto ToSql() noexcept
static constexpr bool HasAdditionalTables() noexcept
constexpr ExprTree(const L &l, const R &r) noexcept
static constexpr bool HasAdditionalTables() noexcept
void BindValues(QSqlQuery &query) const noexcept
static constexpr auto ToSql() noexcept
static constexpr auto AdditionalTables() noexcept
auto RunQuery(const QString &queryStr, auto &&binder) const
SelectWrapperCommon(const QSqlDatabase &db) noexcept
SelectWrapperCommon(const QSqlDatabase &db) noexcept
auto Build() const noexcept
auto operator==(const T &left, const T &right)
QSqlQuery RunTextQuery(const QSqlDatabase &db, const QString &text)
Runs the given query text on the given db.
void RunQuery(const QSqlDatabase &db, const QString &pluginName, const QString &filename)
Loads the query from the given resource file and runs it.
decltype(GetFieldAt< I >(std::declval< T >())) FieldType_t
constexpr auto GetTypes(std::index_sequence< Indices... >) noexcept
constexpr auto AdaptCreateTableNamed() noexcept
auto MakeIndexedQueryHandler(const QSqlQuery &q, int startIdx=0) noexcept
consteval int PKeyIndex()
constexpr auto ExprTreeToSql() noexcept
constexpr auto MapTy(Src< Vals... >, auto f)
constexpr auto AsLeafData(const T &node) noexcept
constexpr auto LimitOffsetToString() noexcept
T InitializeFromQuery(const QSqlQuery &q, std::index_sequence< Indices... >, int startIdx) noexcept
void BindLimitOffset(QSqlQuery &query, L limit, O offset) noexcept
auto Combine(std::tuple< LArgs... > &&left, std::tuple< RArgs... > &&right) noexcept
constexpr auto GetConstraintsStrings() noexcept
consteval int PKeyIndexUnsafe()
decltype(auto) HandleResultBehaviour(ResList &&list) noexcept
constexpr auto ConstTrueTree_v
constexpr auto ExtractConstraintFields(UniqueSubset< Ptrs... >)
void AdaptCreateIndices(const QSqlDatabase &db)
auto DoInsert(const Seq &seq, QSqlQuery &insertQuery, bool bindPrimaryKey)
constexpr decltype(auto) Get(const Seq &seq)
QVariant ToVariantF(const T &t) noexcept
constexpr bool IsRelational(ExprType type) noexcept
constexpr auto AdaptCreateTable() noexcept
constexpr bool IsExprTree
auto MemberFromVariant(const QVariant &var) noexcept
constexpr auto FieldNames
consteval auto GetFieldName()
constexpr auto TypeToSql() noexcept
constexpr auto CreateIndex(const QSqlDatabase &db, Index< Ptrs... >)
constexpr bool IsForeignKeyRecursive()
std::conditional_t< Indirect< T >, T, WrapDirect< T > >::value_type UnwrapIndirect_t
constexpr decltype(auto) GetReplaceTupleElem(Tuple &&tuple, NewType &&arg) noexcept
constexpr auto FieldNameByPtr
constexpr auto BoundFieldNames
constexpr auto QualifiedFieldNameByPtr
constexpr auto ReplaceTupleElem(std::tuple< TupleArgs... > &&tuple, NewType &&arg) noexcept
constexpr auto WrapSubexpr(auto subexpr)
constexpr auto CombineBehaviour(ResultBehaviour l, ResultBehaviour r) noexcept
auto MakeExprTree(const L &left, const R &right) noexcept
void BindAtIndex(const Seq &seq, QSqlQuery &query, bool bindPrimaryKey)
constexpr auto QualifiedFieldNames
std::decay_t< decltype(Get< Idx >(std::declval< Seq >()))> ValueAtC_t
constexpr auto ReplaceTupleElemImpl(Tuple &&tuple, NewType &&arg, std::index_sequence< TupIdxs... >) noexcept
constexpr bool Typecheck()
constexpr bool IsSelector
void BindExprTree(const Tree &tree, QSqlQuery &query)
constexpr int PKeyIndex_v
constexpr auto GetFullSize(const Seq &seq)
consteval auto MorphFieldName()
constexpr auto SeqIndices
constexpr auto HasAutogenPKey() noexcept
constexpr auto ExtractReplaceFields(InsertAction::Replace::WholeType)
constexpr detail::InfixBinary< detail::ExprType::ILike > ilike
constexpr detail::InfixBinary< detail::ExprType::Like > like
constexpr detail::ExprTree< detail::ExprType::LeafStaticPlaceholder, detail::MemberPtrs< Ptr > > f
constexpr detail::ExprTree< detail::ExprType::LeafStaticPlaceholder, detail::MemberPtrs< Ptrs... > > tuple
constexpr detail::SelectWhole all
constexpr detail::CustomFunctionType< FunRetType, Fun, Ptr > fun
constexpr detail::AggregateType< detail::AggregateFunction::Count, Ptr > count
constexpr detail::AggregateType< detail::AggregateFunction::Min, Ptr > min
detail::SelectDistinct< T > distinct
constexpr detail::MemberPtrs< Ptrs... > fields
constexpr detail::AggregateType< detail::AggregateFunction::Max, Ptr > max
void AdaptPtrs(const QSqlDatabase &db, ObjectInfo_ptr< Ts > &... objects)
ObjectInfo_ptr< T > AdaptPtr(const QSqlDatabase &db)
detail::SQLite::ImplFactory SQLiteImplFactory
constexpr detail::OrderBy< Orders... > OrderBy
Typelist< Args... > Indices
constexpr bool BeenAdapted
constexpr detail::GroupBy< Ptrs... > GroupBy
constexpr auto MemberNameByPtr
constexpr auto MemberNameByIdx
ObjectInfo< T > Adapt(const QSqlDatabase &db)
std::unique_ptr< ObjectInfo< T > > ObjectInfo_ptr
std::shared_ptr< QSqlQuery > QSqlQuery_ptr
typename AsTypelist< T >::Result_t AsTypelist_t
QString ToString() noexcept
std::tuple_element_t< 0, detail::CallTypeGetter_t< F > > RetType_t
constexpr auto ZipWith(Tup1 &&tup1, auto &&sep, Tup2 &&tup2) noexcept
constexpr auto JoinTup(auto &&stringsTuple, auto &&sep) noexcept
constexpr bool HasType(List< Args... >)
constexpr auto ReplaceAll(CtString< N2, Char > replacement) noexcept
constexpr auto IntegralToString()
MemberTypeType_t< decltype(Ptr)> MemberPtrType_t
constexpr auto Join(auto &&) noexcept
MemberTypeStruct_t< decltype(Ptr)> MemberPtrStruct_t
A proper void type, akin to unit (or ()) type in functional languages.
detail::AdaptUpdate< T > Update
detail::SelectWrapper< T, detail::SelectBehaviour::Some > Select
detail::AdaptDelete< T > Delete
detail::AdaptInsert< T > Insert
detail::DeleteByFieldsWrapper< T > DeleteBy
detail::SelectWrapper< T, detail::SelectBehaviour::One > SelectOne
AdaptDelete(const QSqlDatabase &db) noexcept
static constexpr int Value
static constexpr int Value
static constexpr int Value
static constexpr auto ResultBehaviour_v
static constexpr auto ResultBehaviour_v
static auto Initializer(const QSqlQuery &q, int startIdx) noexcept
static constexpr auto Fields
static constexpr auto Fields
static auto Initializer(const QSqlQuery &q, int startIdx)
static auto Initializer(const QSqlQuery &q, int startIdx)
static constexpr auto Fields
static constexpr auto Fields
static auto Initializer(const QSqlQuery &q, int startIdx)
static constexpr auto Fields
static auto Initializer(const QSqlQuery &q, int startIdx) noexcept
static constexpr auto Fields
static auto Initializer(const QSqlQuery &q, int startIdx)
static constexpr auto Fields
static constexpr auto Fields
static constexpr auto ResultBehaviour_v
HandleSelector< T, L > HL
static auto Initializer(const QSqlQuery &q, int startIdx) noexcept
HandleSelector< T, R > HR
SelectDistinct(T) noexcept