forked from Quick-Box/quickevent
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Fanda Vacek
committed
Feb 29, 2024
1 parent
7db6d9f
commit b35183d
Showing
8 changed files
with
312 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
183 changes: 183 additions & 0 deletions
183
quickevent/app/quickevent/plugins/Event/src/services/shvapi/rpcsqlresult.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
#include "rpcsqlresult.h" | ||
|
||
#include <qf/core/log.h> | ||
|
||
#include <shv/chainpack/rpcmessage.h> | ||
#include <shv/coreqt/rpc.h> | ||
|
||
#include <QDateTime> | ||
#include <QSqlQuery> | ||
#include <QSqlRecord> | ||
#include <QSqlField> | ||
|
||
using namespace shv::chainpack; | ||
|
||
namespace Event::services::shvapi { | ||
|
||
RpcValue RpcSqlField::toRpcValue() const | ||
{ | ||
RpcValue::Map ret; | ||
ret["name"] = name.toStdString(); | ||
ret["type"] = type; | ||
ret["typeName"] = QMetaType(type).name(); | ||
return RpcValue(std::move(ret)); | ||
} | ||
|
||
QVariant RpcSqlField::toVariant() const | ||
{ | ||
QVariantMap ret; | ||
ret["name"] = name; | ||
ret["type"] = type; | ||
ret["typeName"] = QMetaType(type).name(); | ||
return ret; | ||
} | ||
|
||
RpcSqlField RpcSqlField::fromRpcValue(const shv::chainpack::RpcValue &rv) | ||
{ | ||
RpcSqlField ret; | ||
const RpcValue::Map &map = rv.asMap(); | ||
ret.name = QString::fromStdString(map.value("name").asString()); | ||
ret.type = map.value("type").toInt(); | ||
return ret; | ||
} | ||
|
||
RpcSqlField RpcSqlField::fromVariant(const QVariant &v) | ||
{ | ||
RpcSqlField ret; | ||
const QVariantMap map = v.toMap(); | ||
ret.name = map.value("name").toString(); | ||
ret.type = map.value("type").toInt(); | ||
return ret; | ||
} | ||
|
||
RpcSqlResult::RpcSqlResult(const shv::chainpack::RpcResponse &resp) | ||
{ | ||
if(resp.isSuccess()) { | ||
const RpcValue::Map result = resp.result().asMap(); | ||
for(const RpcValue &rv : result.valref("fields").asList()) { | ||
RpcSqlField fld; | ||
fld.name = QString::fromStdString(rv.asMap().value("name").toString()); | ||
fld.type = rv.asMap().value("type").toInt(); | ||
fields.append(fld); | ||
} | ||
for(const RpcValue &rowv : result.valref("rows").asList()) { | ||
Row row; | ||
for(const RpcValue &rv : rowv.asList()) { | ||
bool ok; | ||
QVariant v = shv::coreqt::rpc::rpcValueToQVariant(rv, &ok); | ||
if (!ok) { | ||
qfError() << "Cannot convert:" << rv.toCpon() << "to QVariant"; | ||
} | ||
row.append(v); | ||
} | ||
rows.insert(rows.count(), row); | ||
} | ||
numRowsAffected = result.value("numRowsAffected").toInt(); | ||
lastInsertId = result.value("lastInserId").toInt(); | ||
} | ||
else { | ||
lastError = QString::fromStdString(resp.errorString()); | ||
} | ||
} | ||
|
||
QVariant RpcSqlResult::value(int col, int row) const | ||
{ | ||
return rows.value(row).toList().value(col); | ||
} | ||
|
||
RpcValue RpcSqlResult::toRpcValue() const | ||
{ | ||
return shv::coreqt::rpc::qVariantToRpcValue(toVariant()); | ||
} | ||
|
||
QVariant RpcSqlResult::toVariant() const | ||
{ | ||
QVariantMap ret; | ||
if(isSelect()) { | ||
QVariantList flds; | ||
for(const auto &fld : this->fields) | ||
flds.push_back(fld.toVariant()); | ||
ret["fields"] = flds; | ||
ret["rows"] = rows; | ||
} | ||
else { | ||
ret["numRowsAffected"] = numRowsAffected; | ||
ret["lastInsertId"] = lastInsertId; | ||
} | ||
return ret; | ||
} | ||
|
||
/* | ||
RpcSqlResult RpcSqlResult::fromRpcValue(const shv::chainpack::RpcValue &rv) | ||
{ | ||
RpcSqlResult ret; | ||
const RpcValue::Map &map = rv.asMap(); | ||
const RpcValue::List &flds = map.value("fields").asList(); | ||
if(flds.empty()) { | ||
ret.numRowsAffected = map.value("numRowsAffected").toInt(); | ||
ret.lastInsertId = map.value("lastInsertId").toInt(); | ||
} | ||
else { | ||
} | ||
return ret; | ||
} | ||
*/ | ||
|
||
RpcSqlResult RpcSqlResult::fromVariant(const QVariant &v) | ||
{ | ||
RpcSqlResult ret; | ||
const QVariantMap map = v.toMap(); | ||
const QVariantList flds = map.value("fields").toList(); | ||
if(flds.isEmpty()) { | ||
ret.numRowsAffected = map.value("numRowsAffected").toInt(); | ||
ret.lastInsertId = map.value("lastInsertId").toInt(); | ||
} | ||
else { | ||
for(const QVariant &fv : flds) | ||
ret.fields.append(RpcSqlField::fromVariant(fv)); | ||
ret.rows = map.value("rows").toList(); | ||
} | ||
return ret; | ||
} | ||
|
||
RpcSqlResult RpcSqlResult::fromRpcValue(const shv::chainpack::RpcValue &rv) | ||
{ | ||
auto v = shv::coreqt::rpc::rpcValueToQVariant(rv); | ||
return fromVariant(v); | ||
} | ||
|
||
RpcSqlResult RpcSqlResult::fromQuery(QSqlQuery &q) | ||
{ | ||
RpcSqlResult ret; | ||
if(q.isSelect()) { | ||
QSqlRecord rec = q.record(); | ||
for (int i = 0; i < rec.count(); ++i) { | ||
QSqlField fld = rec.field(i); | ||
RpcSqlField rfld; | ||
rfld.name = fld.name(); | ||
rfld.type = fld.metaType().id(); | ||
ret.fields.append(rfld); | ||
} | ||
while(q.next()) { | ||
RpcSqlResult::Row row; | ||
for (int i = 0; i < rec.count(); ++i) { | ||
const QVariant v = q.value(i); | ||
if (v.isNull()) | ||
row.append(QVariant()); | ||
else | ||
row.append(v); | ||
//shvError() << v << v.isNull() << jsv.toVariant() << jsv.toVariant().isNull(); | ||
} | ||
ret.rows.insert(ret.rows.count(), row); | ||
} | ||
} | ||
else { | ||
ret.numRowsAffected = q.numRowsAffected(); | ||
ret.lastInsertId = q.lastInsertId().toInt(); | ||
} | ||
return ret; | ||
} | ||
|
||
} |
50 changes: 50 additions & 0 deletions
50
quickevent/app/quickevent/plugins/Event/src/services/shvapi/rpcsqlresult.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
#pragma once | ||
|
||
#include <QVector> | ||
#include <QVariantList> | ||
|
||
namespace shv::chainpack { class RpcResponse; class RpcValue; } | ||
|
||
class QSqlQuery; | ||
|
||
namespace Event::services::shvapi { | ||
|
||
class RpcSqlField | ||
{ | ||
public: | ||
QString name; | ||
int type = 0; | ||
public: | ||
//explicit RpcSqlField(const QJsonObject &jo = QJsonObject()) : Super(jo) {} | ||
shv::chainpack::RpcValue toRpcValue() const; | ||
QVariant toVariant() const; | ||
static RpcSqlField fromRpcValue(const shv::chainpack::RpcValue &rv); | ||
static RpcSqlField fromVariant(const QVariant &v); | ||
}; | ||
|
||
class RpcSqlResult | ||
{ | ||
public: | ||
int numRowsAffected = 0; | ||
int lastInsertId = 0; | ||
QString lastError; | ||
QVector<RpcSqlField> fields; | ||
using Row = QVariantList; | ||
QVariantList rows; | ||
public: | ||
explicit RpcSqlResult() = default; | ||
explicit RpcSqlResult(const shv::chainpack::RpcResponse &resp); | ||
|
||
QVariant value(int col, int row) const; | ||
|
||
bool isSelect() const {return !fields.isEmpty();} | ||
shv::chainpack::RpcValue toRpcValue() const; | ||
QVariant toVariant() const; | ||
//static RpcSqlResult fromRpcValue(const shv::chainpack::RpcValue &rv); | ||
static RpcSqlResult fromVariant(const QVariant &v); | ||
static RpcSqlResult fromRpcValue(const shv::chainpack::RpcValue &rv); | ||
static RpcSqlResult fromQuery(QSqlQuery &q); | ||
|
||
}; | ||
|
||
} |
49 changes: 49 additions & 0 deletions
49
quickevent/app/quickevent/plugins/Event/src/services/shvapi/sqlnode.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
#include "sqlnode.h" | ||
#include "rpcsqlresult.h" | ||
|
||
#include <qf/core/exception.h> | ||
#include <qf/core/sql/query.h> | ||
#include <qf/core/log.h> | ||
|
||
#include <shv/chainpack/rpc.h> | ||
#include <shv/coreqt/rpc.h> | ||
|
||
using namespace shv::chainpack; | ||
|
||
namespace Event::services::shvapi { | ||
|
||
SqlNode::SqlNode(shv::iotqt::node::ShvNode *parent) | ||
: Super("sql", parent) | ||
{ | ||
|
||
} | ||
|
||
static auto METH_EXEC_SQL = "execSql"; | ||
|
||
const std::vector<MetaMethod> &SqlNode::metaMethods() | ||
{ | ||
static std::vector<MetaMethod> meta_methods { | ||
{Rpc::METH_DIR, MetaMethod::Signature::RetParam, MetaMethod::Flag::None, Rpc::ROLE_BROWSE}, | ||
{Rpc::METH_LS, MetaMethod::Signature::RetParam, MetaMethod::Flag::None, Rpc::ROLE_BROWSE}, | ||
{METH_EXEC_SQL, MetaMethod::Signature::RetVoid, MetaMethod::Flag::None, Rpc::ROLE_WRITE}, | ||
}; | ||
return meta_methods; | ||
} | ||
|
||
RpcValue SqlNode::callMethod(const StringViewList &shv_path, const std::string &method, const shv::chainpack::RpcValue ¶ms, const shv::chainpack::RpcValue &user_id) | ||
{ | ||
qfLogFuncFrame() << shv_path.join('/') << method; | ||
//eyascore::utils::UserId user_id = eyascore::utils::UserId::makeUserName(QString::fromStdString(rq.userId().toMap().value("userName").toString())); | ||
if(shv_path.empty()) { | ||
if(method == METH_EXEC_SQL) { | ||
qf::core::sql::Query q; | ||
QString qs = params.to<QString>(); | ||
q.exec(qs, qf::core::Exception::Throw); | ||
auto res = RpcSqlResult::fromQuery(q); | ||
return res.toRpcValue(); | ||
} | ||
} | ||
return Super::callMethod(shv_path, method, params, user_id); | ||
} | ||
|
||
} |
20 changes: 20 additions & 0 deletions
20
quickevent/app/quickevent/plugins/Event/src/services/shvapi/sqlnode.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#pragma once | ||
|
||
#include "shvnode.h" | ||
|
||
namespace Event::services::shvapi { | ||
|
||
class SqlNode : public ShvNode | ||
{ | ||
Q_OBJECT | ||
|
||
using Super = ShvNode; | ||
public: | ||
explicit SqlNode(shv::iotqt::node::ShvNode *parent); | ||
|
||
protected: | ||
const std::vector<shv::chainpack::MetaMethod> &metaMethods() override; | ||
shv::chainpack::RpcValue callMethod(const StringViewList &shv_path, const std::string &method, const shv::chainpack::RpcValue ¶ms, const shv::chainpack::RpcValue &user_id) override; | ||
}; | ||
|
||
} |