Skip to content

Commit 1d15649

Browse files
authored
Merge pull request #158 from oblivioncth/dev
Merge to master for v0.7
2 parents ea74299 + 8623e6a commit 1d15649

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+4882
-109
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ cmake_minimum_required(VERSION 3.23.0...3.31.0)
88
# avoided and only used for hotfixes. DON'T USE TRAILING
99
# ZEROS IN VERSIONS
1010
project(Qx
11-
VERSION 0.6.3
11+
VERSION 0.7
1212
LANGUAGES CXX
1313
DESCRIPTION "Qt Extensions Library"
1414
)

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Detailed documentation of this library, facilitated by Doxygen, is available at:
1515

1616
- [Bindable Properties](https://oblivioncth.github.io/Qx/properties.html)
1717
- [Declarative JSON](https://oblivioncth.github.io/Qx/declarativejson.html)
18+
- [Declarative SQL](https://oblivioncth.github.io/Qx/declarativesql.html)
1819
- [Qx::ApplicationLogger](https://oblivioncth.github.io/Qx/classQx_1_1ApplicationLogger.html)
1920
- [Qx::AsyncDownloadManager](https://oblivioncth.github.io/Qx/classQx_1_1AsyncDownloadManager.html)/[Qx::SyncDownloadManager](https://oblivioncth.github.io/Qx/classQx_1_1SyncDownloadManager.html)
2021
- [Qx::Base85](https://oblivioncth.github.io/Qx/classQx_1_1Base85.html)

doc/CMakeLists.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,14 @@ set(DOXYGEN_PREDEFINED
1717

1818
set(DOXYGEN_EXCLUDE_SYMBOLS
1919
"_QxPrivate"
20+
"__QX*"
2021
)
2122

23+
include(cmake/SqlMacros.cmake)
24+
2225
# Setup documentation
2326
ob_standard_documentation(${DOC_TARGET_NAME}
24-
DOXY_VER 1.9.4
27+
DOXY_VER 1.12.0
2528
PROJ_NAME "${PROJECT_NAME}"
2629
QT_MODULES
2730
qtconcurrent

doc/cmake/SqlMacros.cmake

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Forwhaetver reason, putting these in DOXYGEN_EXPAND_AS_DEFINED does not work, possibly because
2+
# there are nested macros, so we have to define all of the macros used to create symobls that need
3+
# documentation in the SQL module here in a way that allows Doxygen to recognize said symbols.
4+
# The function definition isn't needed, just the declaration.
5+
#
6+
# NOTE: @ seems not to work here, so we need to use \\ for doxygen commands instead (\ itself escaped)
7+
8+
list(APPEND DOXYGEN_PREDEFINED
9+
# Queries
10+
"__QX_SQL_QUERY_ADD_KEYWORD_ZERO_ARG_X(keyword, method)=\
11+
/*! Adds a `keyword` clause to the query and returns a reference to the query. */ \
12+
auto& method();"
13+
"__QX_SQL_QUERY_ADD_KEYWORD_ZERO_ARG(keyword)=\
14+
/*! Adds a `keyword` clause to the query and returns a reference to the query. */ \
15+
auto& keyword();"
16+
"__QX_SQL_QUERY_ADD_KEYWORD_SINGLE_ARG_X(keyword, method)=\
17+
/*! Adds a `keyword` clause to the query using \\a fs and returns a reference to the query. */ \
18+
template<sql_stringable First> auto& method(First&& fs);"
19+
"__QX_SQL_QUERY_ADD_KEYWORD_SINGLE_ARG_PAREN_X(keyword, method)=\
20+
/*! Adds a `keyword` clause to the query using \\a fs and returns a reference to the query. */ \
21+
template<sql_stringable First> auto& method(First&& fs);"
22+
"__QX_SQL_QUERY_ADD_KEYWORD_SINGLE_ARG(keyword)=\
23+
/*! Adds a `keyword` clause to the query using \\a fs and returns a reference to the query. */ \
24+
template<sql_stringable First> auto& keyword(First&& fs);"
25+
"__QX_SQL_QUERY_ADD_KEYWORD_SINGLE_ARG_PAREN(keyword)=\
26+
/*! Adds a `keyword` clause to the query using \\a fs and returns a reference to the query. */ \
27+
template<sql_stringable First> auto& keyword(First&& fs);"
28+
"__QX_SQL_QUERY_ADD_KEYWORD_MULTI_ARG_X(keyword, method)=\
29+
/*! Adds a `keyword` clause to the query using \\a fs through \\a s and returns a reference \
30+
to the query. */ \
31+
template<sql_stringable First, sql_stringable ...Rest> auto& method(First&& fs, Rest&&... s);"
32+
"__QX_SQL_QUERY_ADD_KEYWORD_MULTI_ARG_PAREN_X(keyword, method)=\
33+
/*! Adds a `keyword` clause to the query using \\a fs through \\a s and returns a reference \
34+
to the query. */ \
35+
template<sql_stringable First, sql_stringable ...Rest> auto& method(First&& fs, Rest&&... s);"
36+
"__QX_SQL_QUERY_ADD_KEYWORD_MULTI_ARG(keyword)=\
37+
/*! Adds a `keyword` clause to the query using \\a fs through \\a s and returns a reference \
38+
to the query. */ \
39+
template<sql_stringable First, sql_stringable ...Rest> auto& keyword(First&& fs, Rest&&... s);"
40+
"__QX_SQL_QUERY_ADD_KEYWORD_MULTI_ARG_PAREN(keyword)=\
41+
/*! Adds a `keyword` clause to the query using \\a fs through \\a s and returns a reference \
42+
to the query. */ \
43+
template<sql_stringable First, sql_stringable ...Rest> auto& keyword(First&& fs, Rest&&... s);"
44+
"__QX_SQL_QUERY_ADD_KEYWORD_SUB_QUERY_X(keyword, method)=\
45+
/*! Adds a `keyword` clause to the query using \\a q as a sub-query and returns a reference \
46+
to the query. */ \
47+
auto& method(const SqlQuery& q);"
48+
"__QX_SQL_QUERY_ADD_KEYWORD_SUB_QUERY(keyword)=\
49+
/*! Adds a `keyword` clause to the query using \\a q as a sub-query and returns a reference \
50+
to the query. */ \
51+
auto& keyword(const SqlQuery& q);"
52+
)

doc/general/majorfeatures.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
Major Features {#majorfeatures}
22
===============================
33

4-
This page catalogues the most significant features of Qx, which generally form a complete/comprehensive system that can be evaluated independently from the rest of the library.
4+
This page catalogues the most significant features of Qx, which generally form a complete/comprehensive system that can be evaluated independently from the rest of the library.
55

66
- @subpage properties "Bindable Properties System"
77
- @subpage declarativejson "Declarative JSON"
8+
- @subpage declarativesql "Declarative SQL module"

lib/core/include/qx/core/__private/qx-internalerror.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#include "qx/core/qx-abstracterror.h"
66

77
/*! @cond */
8-
namespace QxPrivate
8+
namespace _QxPrivate
99
{
1010

1111
// Basically a copy of GenericError for internal use only

lib/core/include/qx/core/qx-abstracterror.h

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,17 @@ class QX_CORE_EXPORT IError
3333
static inline const QString T_NAME_DUPE = u"Error type name %1 is already claimed!"_s;
3434
static inline const QString T_CODE_RESERVED = u"Error type code %1 is reserved!"_s;
3535
static inline constinit QHash<quint16, const QString*> codeRegistry;
36-
static constexpr std::array<QStringView, 8> RESERVED_NAMES{
36+
static constexpr std::array<QStringView, 10> RESERVED_NAMES{
3737
u"Qx::InternalError",
3838
u"Qx::GenericError",
3939
u"Qx::IoOpReport",
4040
u"Qx::SystemError",
4141
u"Qx::DownloadManagerReport",
4242
u"Qx::DownloadOpReport",
4343
u"Qx::JsonError",
44-
u"QJsonParseError"
44+
u"QJsonParseError",
45+
u"Qx::SqlError",
46+
u"Qx::SqlSchemaReport",
4547
};
4648
// TODO: If this becomes sufficiently large, move to a constexpr set (hopefully available in std by that time)
4749

@@ -81,14 +83,14 @@ class QX_CORE_EXPORT IError
8183
bool operator!=(const IError& other) const = default;
8284
};
8385

84-
template<StringLiteral EName, quint16 ECode>
86+
template<CStringLiteral EName, quint16 ECode>
8587
class AbstractError : protected IError
8688
{
8789
friend class Error;
8890
//-Class Variables----------------------------------------------------------------------------------------------------------
8991
public:
9092
static constexpr quint16 TYPE_CODE = ECode;
91-
static constexpr QLatin1StringView TYPE_NAME{EName.value};
93+
static constexpr QLatin1StringView TYPE_NAME{EName};
9294

9395
private:
9496
static const bool REGISTER;
@@ -116,39 +118,23 @@ friend class Error;
116118

117119
//-Namespace Concepts-------------------------------------------------------------------------------------------------------
118120

119-
/* TODO: Clang 12 doesn't support the C++20 feature "Lambdas in unevaluated contexts",
120-
* so this helper function needs to be used instead. Once moving on to at least Clang 13
121-
* as the minimum supported version instead the lambda commented out below can be used
122-
* instead.
123-
*/
124-
//template<class E>
125-
//concept error_type = requires(E type) {
126-
// // IIFE that ensures E is a specialization of AbstractError
127-
// []<StringLiteral Y, quint16 Z>(AbstractError<Y, Z>&){}(type);
128-
//};
121+
template<class E>
122+
concept error_type = requires(E type) {
123+
// IIFE that ensures E is a specialization of AbstractError
124+
[]<CStringLiteral Y, quint16 Z>(AbstractError<Y, Z>&){}(type);
125+
};
129126

130127
/* Define error type registrar variable. This must be done out of line to ensure that only
131128
* one instance of the variable exists per-error-type across an entire program. If the variable
132-
* is defined inline, multiple versiosn of it can exist in parallel when linking via shared-libraries,
129+
* is defined inline, multiple versions of it can exist in parallel when linking via shared-libraries,
133130
* if those libraries are used by multiple targets in the same project. This would cause an error type
134131
* to call registerType() multiple times.
135132
*/
136-
template<StringLiteral EName, quint16 ECode>
137-
const bool AbstractError<EName, ECode>::REGISTER = registerType(TYPE_CODE, TYPE_NAME);
138-
139133
/*! @cond */
140-
namespace AbstractErrorPrivate
141-
{
142-
template<Qx::StringLiteral Y, quint16 Z>
143-
void aeDerived(Qx::AbstractError<Y, Z>&);
144-
}
134+
template<CStringLiteral EName, quint16 ECode>
135+
const bool AbstractError<EName, ECode>::REGISTER = registerType(TYPE_CODE, TYPE_NAME);
145136
/*! @endcond */
146137

147-
template<class E>
148-
concept error_type = requires(E type) {
149-
AbstractErrorPrivate::aeDerived(type);
150-
};
151-
152138
template<class A>
153139
concept error_adapter =
154140
error_type<A> &&

lib/core/include/qx/core/qx-error.h

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,39 @@ namespace QxErrorPrivate
2828
* half the purpose of the adapters.
2929
*/
3030
namespace Qx { class Error; }
31-
3231
QX_CORE_EXPORT QTextStream& operator<<(QTextStream& ts, const Qx::Error& e);
3332

3433
namespace Qx
3534
{
3635

36+
class Error;
37+
38+
// Need to define here, needed later
39+
template<class E>
40+
concept adapted_error = error_adaptation<E, typename QxErrorPrivate::adapter_registry<E>::adapter>;
41+
42+
}
43+
44+
/*! @cond */
45+
namespace QxErrorPrivate
46+
{
47+
48+
template <typename T>
49+
inline constexpr bool variant_has_error_types = false;
50+
51+
template <typename... Types>
52+
inline constexpr bool variant_has_error_types<std::variant<Types...>> =
53+
((Qx::error_type<Types> || Qx::adapted_error<Types>) && ...);
54+
55+
}
56+
/*! @endcond */
57+
58+
namespace Qx
59+
{
60+
61+
template <typename V>
62+
concept error_variant = QxErrorPrivate::variant_has_error_types<V>;
63+
3764
class QX_CORE_EXPORT Error
3865
{
3966
//-Class Variables----------------------------------------------------------------------------------------------------------
@@ -42,7 +69,7 @@ class QX_CORE_EXPORT Error
4269

4370
// Adapter Registry Alias
4471
template <class K>
45-
using AdapterRegistry = QxErrorPrivate::adapter_registry<K>;
72+
using AdapterType = typename QxErrorPrivate::adapter_registry<K>::adapter;
4673

4774
public:
4875
static constexpr quint16 TYPE_CODE = 0;
@@ -82,9 +109,14 @@ class QX_CORE_EXPORT Error
82109
}
83110
}
84111

85-
template<class EAble, class EAter = typename AdapterRegistry<EAble>::adapter>
86-
requires error_adaptation<EAble, EAter>
87-
Error(const EAble& adapted) : Error(EAter(adapted))
112+
template<class EAble>
113+
requires adapted_error<EAble>
114+
Error(const EAble& adapted) : Error(AdapterType<EAble>(adapted))
115+
{}
116+
117+
template<typename Errors>
118+
requires error_variant<Errors>
119+
Error(const Errors& e) : Error(std::visit([](auto&& arg){ return arg; }, e))
88120
{}
89121

90122
//-Instance Functions------------------------------------------------------------------------------------------------------

lib/core/include/qx/core/qx-json.h

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,11 @@ class QX_CORE_EXPORT File
9898

9999
class QX_CORE_EXPORT Data
100100
{
101+
private:
102+
QString mDataError;
103+
101104
public:
102-
Data();
105+
Data(const QString& dataError = {});
103106

104107
QString string() const;
105108
};
@@ -227,7 +230,7 @@ namespace QxJson
227230
template<typename T>
228231
struct Converter;
229232

230-
template<class Struct, Qx::StringLiteral member>
233+
template<class Struct, Qx::CStringLiteral member>
231234
struct MemberOverrideCoverter;
232235

233236
template<typename SelfType, typename DelayedSelfType>
@@ -258,7 +261,7 @@ concept json_convertible = requires(T& tValue) {
258261
{ Converter<T>::toJson(tValue) } -> qjson_type;
259262
};
260263

261-
template<class K, typename T, Qx::StringLiteral N>
264+
template<class K, typename T, Qx::CStringLiteral N>
262265
concept json_override_convertible = requires(T& tValue) {
263266
{ MemberOverrideCoverter<K, N>::fromJson(tValue, QJsonValue()) } -> std::same_as<Qx::JsonError>;
264267
{ MemberOverrideCoverter<K, N>::toJson(tValue) } -> qjson_type;
@@ -303,16 +306,16 @@ static inline const QString ERR_READ_DATA = u"JSON Error: Could not read JSON da
303306
static inline const QString ERR_WRITE_FILE = u"JSON Error: Could not write JSON file."_s;
304307

305308
//-Structs---------------------------------------------------------------
306-
template<Qx::StringLiteral MemberN, typename MemberT, class Struct>
309+
template<Qx::CStringLiteral MemberN, typename MemberT, class Struct>
307310
struct MemberMetadata
308311
{
309-
constexpr static Qx::StringLiteral M_NAME = MemberN;
312+
constexpr static Qx::CStringLiteral M_NAME = MemberN;
310313
typedef MemberT M_TYPE;
311314
MemberT Struct::* mPtr;
312315
};
313316

314317
//-Functions-------------------------------------------------------------
315-
template <Qx::StringLiteral N, typename T, class S>
318+
template <Qx::CStringLiteral N, typename T, class S>
316319
constexpr MemberMetadata<N, T, S> makeMemberMetadata(T S::*memberPtr)
317320
{
318321
return {memberPtr};
@@ -374,14 +377,14 @@ constexpr auto getMemberMeta()
374377
return QxJson::QxJsonMetaStructOutside<K, K>::memberMetadata();
375378
}
376379

377-
template<class K, typename T, Qx::StringLiteral N>
380+
template<class K, typename T, Qx::CStringLiteral N>
378381
requires QxJson::json_override_convertible<K, T, N>
379382
Qx::JsonError overrideParse(T& value, const QJsonValue& jv)
380383
{
381384
return QxJson::MemberOverrideCoverter<K, N>::fromJson(value, jv);
382385
}
383386

384-
template<class K, typename T, Qx::StringLiteral N>
387+
template<class K, typename T, Qx::CStringLiteral N>
385388
requires QxJson::json_override_convertible<K, T, N>
386389
auto overrideSerialize(const T& value)
387390
{
@@ -462,7 +465,7 @@ struct Converter<T>
462465
([&]{
463466
// Meta
464467
static constexpr auto mName = std::remove_reference<decltype(memberMeta)>::type::M_NAME;
465-
constexpr QLatin1StringView mKey(mName.value);
468+
constexpr QLatin1StringView mKey(mName);
466469
using mType = typename std::remove_reference<decltype(memberMeta)>::type::M_TYPE;
467470
auto& mRef = value.*(memberMeta.mPtr);
468471

@@ -511,7 +514,7 @@ struct Converter<T>
511514
([&]{
512515
// Meta
513516
static constexpr auto mName = std::remove_reference<decltype(memberMeta)>::type::M_NAME;
514-
constexpr QLatin1StringView mKey(mName.value);
517+
constexpr QLatin1StringView mKey(mName);
515518
using mType = typename std::remove_reference<decltype(memberMeta)>::type::M_TYPE;
516519
auto& mRef = value.*(memberMeta.mPtr);
517520

@@ -812,7 +815,7 @@ JsonError parseJson(T& parsed, const QByteArray& data)
812815
QJsonDocument jd = QJsonDocument::fromJson(data, &jpe);
813816

814817
if(jpe.error != jpe.NoError)
815-
return JsonError(QxJsonPrivate::ERR_READ_DATA, JsonError::InvalidData).withContext(QxJson::Data());
818+
return JsonError(QxJsonPrivate::ERR_READ_DATA, JsonError::InvalidData).withContext(QxJson::Data(jpe.errorString()));
816819

817820
// True parse
818821
return parseJson(parsed, jd).withContext(QxJson::Data());

lib/core/src/__private/qx-internalerror.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#include "qx/core/__private/qx-internalerror.h"
33

44
/*! @cond */
5-
namespace QxPrivate
5+
namespace _QxPrivate
66
{
77

88
//===============================================================================================================

0 commit comments

Comments
 (0)