Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 108 additions & 35 deletions App/Server/clsAPIObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,55 +256,128 @@ QVariant clsAPIObject::invoke(bool _isUpdateMethod,
return Result;
}

void clsAPIObject::invokeMethod(const QVariantList& _arguments, QGenericReturnArgument _returnArg) const{
bool InvocationResult= true;
void clsAPIObject::invokeMethod(const QVariantList& _arguments, QGenericReturnArgument _returnArg) const {
bool InvocationResult = true;
QMetaMethod InvokableMethod;
if(_arguments.size() == this->ParamNames.size())

if (_arguments.size() == this->ParamNames.size())
InvokableMethod = this->BaseMethod;
else
InvokableMethod = this->LessArgumentMethods.at(this->ParamNames.size() - _arguments.size() - 1);

QVector<void*> ArgStorage(_arguments.size(), {});

try{
switch(_arguments.size()){
case 0: InvocationResult = InvokableMethod.invoke(this->parent(), this->IsAsync ? Qt::QueuedConnection : Qt::DirectConnection,
_returnArg);break;
case 1: InvocationResult = InvokableMethod.invoke(this->parent(), this->IsAsync ? Qt::QueuedConnection : Qt::DirectConnection,
_returnArg, USE_ARG_AT(0));break;
case 2: InvocationResult = InvokableMethod.invoke(this->parent(), this->IsAsync ? Qt::QueuedConnection : Qt::DirectConnection,
_returnArg, USE_ARG_AT(0), USE_ARG_AT(1));break;
case 3: InvocationResult = InvokableMethod.invoke(this->parent(), this->IsAsync ? Qt::QueuedConnection : Qt::DirectConnection,
_returnArg, USE_ARG_AT(0),USE_ARG_AT(1),USE_ARG_AT(2));break;
case 4: InvocationResult = InvokableMethod.invoke(this->parent(), this->IsAsync ? Qt::QueuedConnection : Qt::DirectConnection,
_returnArg, USE_ARG_AT(0),USE_ARG_AT(1),USE_ARG_AT(2),USE_ARG_AT(3));break;
case 5: InvocationResult = InvokableMethod.invoke(this->parent(), this->IsAsync ? Qt::QueuedConnection : Qt::DirectConnection,
_returnArg, USE_ARG_AT(0),USE_ARG_AT(1),USE_ARG_AT(2),USE_ARG_AT(3),USE_ARG_AT(4));break;
case 6: InvocationResult = InvokableMethod.invoke(this->parent(), this->IsAsync ? Qt::QueuedConnection : Qt::DirectConnection,
_returnArg, USE_ARG_AT(0),USE_ARG_AT(1),USE_ARG_AT(2),USE_ARG_AT(3),USE_ARG_AT(4),
USE_ARG_AT(5));break;
case 7: InvocationResult = InvokableMethod.invoke(this->parent(), this->IsAsync ? Qt::QueuedConnection : Qt::DirectConnection,
_returnArg, USE_ARG_AT(0),USE_ARG_AT(1),USE_ARG_AT(2),USE_ARG_AT(3),USE_ARG_AT(4),
USE_ARG_AT(5),USE_ARG_AT(6));break;
case 8: InvocationResult = InvokableMethod.invoke(this->parent(), this->IsAsync ? Qt::QueuedConnection : Qt::DirectConnection,
_returnArg, USE_ARG_AT(0),USE_ARG_AT(1),USE_ARG_AT(2),USE_ARG_AT(3),USE_ARG_AT(4),
USE_ARG_AT(5),USE_ARG_AT(6),USE_ARG_AT(7));break;
case 9: InvocationResult = InvokableMethod.invoke(this->parent(), this->IsAsync ? Qt::QueuedConnection : Qt::DirectConnection,
_returnArg, USE_ARG_AT(0),USE_ARG_AT(1),USE_ARG_AT(2),USE_ARG_AT(3),USE_ARG_AT(4),
USE_ARG_AT(5),USE_ARG_AT(6),USE_ARG_AT(7),USE_ARG_AT(8));break;
case 10: InvocationResult = InvokableMethod.invoke(this->parent(), this->IsAsync ? Qt::QueuedConnection : Qt::DirectConnection,
_returnArg, USE_ARG_AT(0),USE_ARG_AT(1),USE_ARG_AT(2),USE_ARG_AT(3),USE_ARG_AT(4),
USE_ARG_AT(5),USE_ARG_AT(6),USE_ARG_AT(7),USE_ARG_AT(8),USE_ARG_AT(9));break;
default:
throw exHTTPInternalServerError(QString("At most 10 method params are supported"));
try {
switch(_arguments.size()) {
case 0: InvocationResult = InvokableMethod.invoke(this->parent(),
this->IsAsync ? Qt::QueuedConnection : Qt::DirectConnection,
_returnArg);
break;
case 1: InvocationResult = InvokableMethod.invoke(this->parent(),
this->IsAsync ? Qt::QueuedConnection : Qt::DirectConnection,
_returnArg,
USE_ARG_AT(0));
break;
case 2: InvocationResult = InvokableMethod.invoke(this->parent(),
this->IsAsync ? Qt::QueuedConnection : Qt::DirectConnection,
_returnArg,
USE_ARG_AT(0),
USE_ARG_AT(1));
break;
case 3: InvocationResult = InvokableMethod.invoke(this->parent(),
this->IsAsync ? Qt::QueuedConnection : Qt::DirectConnection,
_returnArg,
USE_ARG_AT(0),
USE_ARG_AT(1),
USE_ARG_AT(2));
break;
case 4: InvocationResult = InvokableMethod.invoke(this->parent(),
this->IsAsync ? Qt::QueuedConnection : Qt::DirectConnection,
_returnArg,
USE_ARG_AT(0),
USE_ARG_AT(1),
USE_ARG_AT(2),
USE_ARG_AT(3));
break;
case 5: InvocationResult = InvokableMethod.invoke(this->parent(),
this->IsAsync ? Qt::QueuedConnection : Qt::DirectConnection,
_returnArg,
USE_ARG_AT(0),
USE_ARG_AT(1),
USE_ARG_AT(2),
USE_ARG_AT(3),
USE_ARG_AT(4));
break;
case 6: InvocationResult = InvokableMethod.invoke(this->parent(),
this->IsAsync ? Qt::QueuedConnection : Qt::DirectConnection,
_returnArg,
USE_ARG_AT(0),
USE_ARG_AT(1),
USE_ARG_AT(2),
USE_ARG_AT(3),
USE_ARG_AT(4),
USE_ARG_AT(5));
break;
case 7: InvocationResult = InvokableMethod.invoke(this->parent(),
this->IsAsync ? Qt::QueuedConnection : Qt::DirectConnection,
_returnArg,
USE_ARG_AT(0),
USE_ARG_AT(1),
USE_ARG_AT(2),
USE_ARG_AT(3),
USE_ARG_AT(4),
USE_ARG_AT(5),
USE_ARG_AT(6));
break;
case 8: InvocationResult = InvokableMethod.invoke(this->parent(),
this->IsAsync ? Qt::QueuedConnection : Qt::DirectConnection,
_returnArg,
USE_ARG_AT(0),
USE_ARG_AT(1),
USE_ARG_AT(2),
USE_ARG_AT(3),
USE_ARG_AT(4),
USE_ARG_AT(5),
USE_ARG_AT(6),
USE_ARG_AT(7));
break;
case 9: InvocationResult = InvokableMethod.invoke(this->parent(),
this->IsAsync ? Qt::QueuedConnection : Qt::DirectConnection,
_returnArg,
USE_ARG_AT(0),
USE_ARG_AT(1),
USE_ARG_AT(2),
USE_ARG_AT(3),
USE_ARG_AT(4),
USE_ARG_AT(5),
USE_ARG_AT(6),
USE_ARG_AT(7),
USE_ARG_AT(8));
break;
case 10: InvocationResult = InvokableMethod.invoke(this->parent(),
this->IsAsync ? Qt::QueuedConnection : Qt::DirectConnection,
_returnArg,
USE_ARG_AT(0),
USE_ARG_AT(1),
USE_ARG_AT(2),
USE_ARG_AT(3),
USE_ARG_AT(4),
USE_ARG_AT(5),
USE_ARG_AT(6),
USE_ARG_AT(7),
USE_ARG_AT(8),
USE_ARG_AT(9));
break;
default:
throw exHTTPInternalServerError(QString("At most 10 method params are supported"));
}

if (InvocationResult == false)
throw exHTTPInternalServerError(QString("Unable to invoke method"));

for(int i=0; i< _arguments.size(); ++i)
CLEAN_ARG_AT(i);
}catch(...){
} catch(...) {
for(int i=0; i< _arguments.size(); ++i)
CLEAN_ARG_AT(i);
throw;
Expand Down
38 changes: 26 additions & 12 deletions Interfaces/Common/tmplAPIArg.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,34 +38,48 @@ class intfCacheConnector;
namespace Common {

template<typename _itmplType, enuVarComplexity _itmplVarType, bool _itmplNullable, bool _isQtType = false>
class tmplAPIArg : public intfAPIArgManipulator {
class tmplAPIArg : public intfAPIArgManipulator
{
public:
virtual ~tmplAPIArg(){}

virtual QGenericArgument makeGenericArgument(const QVariant& _val, const QByteArray& _paramName, void** _argStorage) final{
virtual QGenericArgument makeGenericArgument(const QVariant& _val, const QByteArray& _paramName, void** _argStorage) final
{
*_argStorage = nullptr;
if(this->fromVariantLambda == nullptr && !_val.canConvert<_itmplType>())

///TODO: check if _val is null
/// test case: Account/User/extraInfo with not first param(e.g. education) value, then first param(job) throws

if (this->fromVariantLambda == nullptr && (_val.canConvert<_itmplType>() == false))
if (_val.isValid())
throw exHTTPBadRequest("Invalid value specified for parameter.: " + _paramName);

*_argStorage = new _itmplType;

*(reinterpret_cast<_itmplType*>(*_argStorage)) =
this->fromVariantLambda == nullptr ? _val.value<_itmplType>() : this->fromVariantLambda(_val, _paramName);

return QGenericArgument(this->RealTypeName, *_argStorage);
}

inline QVariant invokeMethod(const intfAPIObject *_apiObject, const QVariantList& _arguments) final {
_itmplType Result;
_apiObject->invokeMethod(_arguments, QReturnArgument<_itmplType >(this->RealTypeName, Result));
return this->toVariantLambda == nullptr ? QVariant::fromValue(Result) : this->toVariantLambda(Result);
inline QVariant invokeMethod(const intfAPIObject *_apiObject, const QVariantList& _arguments) final
{
_itmplType Result;
_apiObject->invokeMethod(_arguments, QReturnArgument<_itmplType>(this->RealTypeName, Result));
return this->toVariantLambda == nullptr ? QVariant::fromValue(Result) : this->toVariantLambda(Result);
}

inline void validate(const QVariant& _val, const QByteArray& _paramName) const final {
if(this->fromVariantLambda == nullptr && !_val.canConvert<_itmplType>())
throw exHTTPBadRequest("Invalid value specified for parameter.:: " + _paramName);
if(this->fromVariantLambda)
inline void validate(const QVariant& _val, const QByteArray& _paramName) const final
{
if (this->fromVariantLambda == nullptr && !_val.canConvert<_itmplType>())
throw exHTTPBadRequest("Invalid value specified for parameter.:: " + _paramName);

if (this->fromVariantLambda)
this->fromVariantLambda(_val, _paramName);
}

inline QVariant defaultVariant() const {
inline QVariant defaultVariant() const
{
_itmplType Default;
return this->toVariantLambda == nullptr ? QVariant::fromValue(Default) : this->toVariantLambda(Default);
}
Expand Down
26 changes: 24 additions & 2 deletions Modules/Account/functionalTest/testAccount.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -469,19 +469,41 @@ private slots:
.toBool());
}

void UpdateUserExtraInfo() {
void UpdateUserExtraInfo_json() {
QVERIFY(callAPI(RESTClientHelper::PATCH,
"Account/User/extraInfo",
{},
{
// { "job", "1234" },
{ "education", "456" },
})
.toBool());
}

void UpdateUserExtraInfo_birthdate() {
QVERIFY(callAPI(RESTClientHelper::PATCH,
"Account/User/extraInfo",
{},
{
{ "birthDate", "1973/09/11" },
})
.toBool());
}

void UpdateUserExtraInfo_all() {
QVERIFY(callAPI(RESTClientHelper::PATCH,
"Account/User/extraInfo",
{},
{
{ "birthDate", "1973/09/11" },
{ "job", "1234" },
{ "education", "" },
})
.toBool());
}

//private:
private slots:
//private:
/***************************************************************************************/
/* cleanup *****************************************************************************/
/***************************************************************************************/
Expand Down
Loading