Qt5 访问influxdb的httpApi接口

//注意在 .pro工程文件中添加 对网络访问的支持模块 QT+= network

#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QtCore>
#include <iostream>

using namespace std ;

//用于插入和查询输出的数据结构与measurement结构对应
class InfluxPoint
{
public:
    QString attr_oid;
    QString attr_time;
    qreal   attr_value;
};
class TestInfluxdb : public QObject
{
   public:
       
       //构造函数1  入参形如"127.0.0.1:8086"
    TestInfluxdb(const QString&host)
    {
        m_manager = new QNetworkAccessManager();
        m_host = host;
    }

  //构造函数2,提供host和数据库名称db
    TestInfluxdb(const QString&host, const QString& db)
    {
        m_manager = new QNetworkAccessManager();
        m_db = db;
        m_host = host;
    }

  //构造函数3,提供host 数据库名称db,用户,密码
    TestInfluxdb(const QString&host, const QString& db, const QString& usr, const QString& pwd)
    {
        m_manager = new QNetworkAccessManager();
        m_db = db;
        m_usr = usr;
        m_pwd = pwd;
        m_host = host;
    }

  //析构函数
    ~TestInfluxdb()
    {
        delete m_manager;
    }

  //执行非查询语句
    QString execNonSelect(const QString & url)
    {
        QByteArray ba;
        QNetworkRequest req(url);
        req.setHeader(QNetworkRequest::ContentTypeHeader,"application/x-www-form-urlencoded");
        QNetworkReply *reply = m_manager->post(req,ba);
        QByteArray responseData;
        QEventLoop eventLoop;
        connect(m_manager, SIGNAL(finished(QNetworkReply*)), &eventLoop, SLOT(quit()));
        eventLoop.exec();       //block until finish
        responseData = reply->readAll();

        return responseData;
    }

  //执行查询语句
    QString execSelect(const QString & url)
    {
        QNetworkRequest req(url);
        req.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
        QNetworkReply *reply = m_manager->get(req);
        QByteArray responseData;
        QEventLoop eventLoop;
        connect(m_manager, SIGNAL(finished(QNetworkReply*)), &eventLoop, SLOT(quit()));
        eventLoop.exec();       //block until finish
        responseData = reply->readAll();

        return responseData;
    }

  //带post参数的非查询语句
    QString execNonSelect(const QString & url, const QByteArray &ba)
    {
        QNetworkRequest req(url);
        req.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
        QNetworkReply *reply = m_manager->post(req, ba);
        QByteArray responseData;
        QEventLoop eventLoop;
        connect(m_manager, SIGNAL(finished(QNetworkReply*)), &eventLoop, SLOT(quit()));
        eventLoop.exec();//block until finish
        responseData = reply->readAll();
        return responseData;
    }
    
    //建库
    QString createDB(const QString& db)
    {
        QString urlCreate;
        urlCreate = QString("http://%1/query?q=CREATE DATABASE %2").arg(m_host).arg(db);
        return execNonSelect(urlCreate);
    }
 
  //删库
    QString dropDB(const QString& db)
    {
        QString urlCreate;
        urlCreate = QString("http://%1/query?q=DROP DATABASE %2").arg(m_host).arg(db);
        return execNonSelect(urlCreate);
    }

  //显示包含库的名称
    QString showDB()
    {
        QString urlCreate;
        urlCreate = QString("http://%1/query?q=SHOW DATABASES").arg(m_host);
        return execNonSelect(urlCreate);
    }

  //插入数据
    QString insertData(const QString& db,const QString& table,QList<InfluxPoint>& datPoints)
    {
        if (datPoints.count() == 1)
        {
            const InfluxPoint& pt = datPoints[0];
            QString urlCreate;
            urlCreate = QString("http://%1/write?db=%2").arg(m_host).arg(db);
            QString dat;
            dat.append(table);
            dat.append(QString(",%1=%2").arg("attr_oid").arg(pt.attr_oid));    //tag 
            dat.append(QString(",%1=%2 ").arg("attr_time").arg(pt.attr_time));   //value1
            dat.append(QString("%1=%2 ").arg("attr_value").arg(pt.attr_value)); //value2            
            return execNonSelect(urlCreate,dat.toLocal8Bit());
        }else if(datPoints.count() > 1)
        {    
            QString urlCreate;
            urlCreate = QString("http://%1/write?db=%2").arg(m_host).arg(db);    
            QString dat;

           //注意拼装数据格式满足influxdb的接口

          // ”,“用来分隔tag和field ,空格分隔value, 换行分隔 point。
            for (auto& pt : datPoints)
            {
                //const InfluxPoint& pt = datPoints[0];        
                if (!dat.isEmpty())dat.append("\n");
                dat.append(table);
                //注意前后空格只能一个
                dat.append(QString(",%1=%2").arg("attr_oid").arg(pt.attr_oid));    //tag 
                dat.append(QString(",%1=%2 ").arg("attr_time").arg(pt.attr_time)); //value1
                dat.append(QString("%1=%2").arg("attr_value").arg(pt.attr_value)); //value2
            }
            return execNonSelect(urlCreate, dat.toLocal8Bit());
        }
    
    }

  //数据查询
    QString queryData(const QString& db, const QString& sql, QList<InfluxPoint>& datPoints)
    {
        QString urlCreate;
        urlCreate = QString("http://%1/query?pretty=true&db=%2&q=%3").arg(m_host).arg(db).arg(sql);            
        return execSelect(urlCreate);
    }

  //数据查询带条件
    QString queryData(const QString& db, 
                      const QString& attr_oid,
                      QDateTime &begin,
                      QDateTime &end,
                      QList<InfluxPoint>& datPoints)
    {
        QString urlCreate;
        QString sql;

        begin = begin.addSecs(-8 * 3600);
        end = end.addSecs(-8 * 3600);
        sql.append(" select time,attr_oid,attr_value from Analog ");
        sql.append(" where time>= '");
        sql.append(begin.toString("yyyy-MM-ddTHH:mm:ssZ"));
        sql.append("' and  time<='");
        sql.append(end.toString("yyyy-MM-ddTHH:mm:ssZ"));
        sql.append("' tz('Asia/Shanghai')");
        //sql.append("group by xxx ");
        //sql.append("order by yyy ");
    

        urlCreate = QString("http://%1/query?pretty=true&db=%2&q=%3").arg(m_host).arg(db).arg(sql);
        return execSelect(urlCreate);
    }

  //json转字符串
    static QString JsonToString(const QJsonObject& json,bool readable=false)
    {
        return QString(QJsonDocument(json).toJson(readable?QJsonDocument::Indented:QJsonDocument::Compact));
    }

  //字符串转json
    static QJsonObject StringToJson(const QString& str)
    {
        QJsonObject l_ret;
        QJsonParseError l_err;
        QJsonDocument l_doc = QJsonDocument::fromJson(str.toUtf8(), &l_err);
        if (l_err.error == QJsonParseError::NoError)
        {
            if (l_doc.isObject())
            {
                l_ret = l_doc.object();
            }
        }
        return l_ret;
    }

  //json返回解析
    static QString parseJsonRet(const QString& str)
    {
        //根对象的成员
        QJsonObject root = TestInfluxdb::StringToJson(str);
        if (root.isEmpty())
        {
            return "root is invalid";
        }
        

        //只有一个成员数组
        QJsonArray  results = root["results"].toArray();
        if (results.count()==0)
        {
            return "results is invalid";
        }

        for (auto o : results)
        {
            if (o.isObject())
            {
                //qDebug() << TestInfluxdb::JsonToString(o.toObject(), true);
            }
        }

        //数组的第一个对象
        QJsonObject retObject = results[0].toObject();

        //返回错误码
        int  statement_id = retObject["statement_id"].toInt();
        if (statement_id != 0)
        {
            return "statement_id fail";
        }

        QJsonArray  series = retObject["series"].toArray();
        if (series.count() == 0)
        {
            return "series=0";
        }
        
        QJsonObject series1 = series[0].toObject();
        QJsonArray  columns = series1["columns"].toArray();//对应列数
        QJsonArray  values  = series1["values"].toArray(); //对应行数

        cout << JsonToString(root, true).toStdString() << endl;
        return "success";
    }

    //静态方法,get方式访问 influxdb
    static QString getHtml(QString url)
    {
        QNetworkAccessManager *manager = new QNetworkAccessManager();
        QNetworkReply *reply = manager->get(QNetworkRequest(QUrl(url)));
        QByteArray responseData;
        QEventLoop eventLoop;
        connect(manager, SIGNAL(finished(QNetworkReply*)), &eventLoop, SLOT(quit()));
        eventLoop.exec();       //block until finish
        responseData = reply->readAll();
        return QString(responseData);
    }

   //静态方法,post方式访问 influxdb
    static QString postUrl(const QString& url,const QByteArray& ba)
    {
        QNetworkAccessManager *manager = new QNetworkAccessManager();
        QByteArray  baNew = ba;
        baNew.append("q = CREATE DATABASE mydb;");
        QUrl qurl(url+"?q=CREATE DATABASE mydb");
        
        QNetworkReply *reply = manager->post(QNetworkRequest(qurl),baNew);
        QByteArray responseData;
        QEventLoop eventLoop;
        connect(manager, SIGNAL(finished(QNetworkReply*)), &eventLoop, SLOT(quit()));
        eventLoop.exec();       //block until finish
        responseData = reply->readAll();
        return QString(responseData);
    }
private:
    QString m_host; //influxdb 服务地址
    QString m_db;   //数据库名称
    QString m_usr;  //用户名
    QString m_pwd;  //密码 
    QNetworkAccessManager *m_manager; //网络管理
};
 
int main(int argc, char *argv[])
{
    TestInfluxdb influxdb("127.0.0.1:8086");
  QCoreApplication a(argc, argv);
   //QString data = TestInfluxdb::getHtml(QString("http://www.baidu.com") );
  QList<InfluxPoint> lstDat;
    QString data;
    
    //测试建库
    data = influxdb.createDB("epacsdb1");
    
    //测试删库
    data = influxdb.dropDB("epacsdb2");    
        
    //测试查表
    data = influxdb.showDB();

  //测试批量插入
#if 0
    InfluxPoint pt1;
    qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));    
    for (int i = 0; i < 200; i++)
    {
        pt1.attr_oid = QString("85001%1").arg(i);
        pt1.attr_time ="152208";
        pt1.attr_value = qrand();
        lstDat.append(pt1);
    }
    data = influxdb.insertData("epacsdb1","Analog",lstDat);
#endif

    //测试查询注意区分大小写
    data = influxdb.queryData("epacsdb1", "select * from Analog limit 10;",lstDat);
    

  //测试按时间条件查询
    QDateTime dtBegin(QDate(2021,8,28),QTime(21,28,0));
    QDateTime dtEnd(QDate(2021, 8, 28), QTime(22,0,0));
    QString  oidString;
    data = influxdb.queryData("epacsdb1",oidString,dtBegin,dtEnd,lstDat);

    TestInfluxdb::parseJsonRet(data);
    cout<<data.toStdString()<<endl;
    
  return a.exec();
}

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值