mardi 4 août 2015

Qt/QML singleton object howto

I have following situation: I have java app, which communicates with mysql database. This java app has its own configuration file, which database connection parameters reside in. Now, I am working on Qt/QML application that communicates with same mysql database and therefore there is a need for parsing database connection parameters from java's configuration file. Therefore, I've created (in Qt/QML app) following class:

#ifndef UEPOSSETTINGS_H
#define UEPOSSETTINGS_H

#include <QtCore/qglobal.h>
#include <QDirIterator>
#include <QStringList>
#include <QString>
#include <QFile>
#include <QDebug>
#include <QFile>

#include "uedefaults.h"

class UePOSSettings : public QObject
{
    Q_OBJECT

private:
    QString m_strSettingsFilePath;
    QString m_strParsedData;
    QString m_strDbUrl;
    QString m_strUser;
    QString m_strPassword;
    QString m_strHostname;
    QString m_strDbName;
    int m_iDbPort;

    inline void ueSetConfigurationFilePath(const QString& path)
        { this->m_strSettingsFilePath=path; }
    inline QString ueParsedData() const
        { return this->m_strParsedData; }
    inline void ueSetParsedData(const QString& data)
        { this->m_strParsedData=data; }

    inline QString ueDbUrl() const
        { return this->m_strDbUrl; }
    inline void ueSetDbUrl(const QString& dbUrl)
        { this->m_strDbUrl=dbUrl; }
    inline void ueSetDbUser(const QString& dbUser)
        { this->m_strUser=dbUser; }
    inline void ueSetDbPassword(const QString& dbPassword)
        { this->m_strPassword=dbPassword; }
    inline void ueSetDbHostname(const QString& dbHostname)
        { this->m_strHostname=dbHostname; }
    inline void ueSetDbName(const QString& dbName)
        { this->m_strDbName=dbName; }
    inline void ueSetDbPort(const int& dbPort)
        { this->m_iDbPort=dbPort; }

    void ueParseData(const QString& filename);

public:
    explicit UePOSSettings(QObject *parent = 0);

    ~UePOSSettings();

    Q_INVOKABLE static QString ueSearchConfigurationFile();

    inline QString ueConfigurationFilePath() const
        { return this->m_strSettingsFilePath; }

    Q_INVOKABLE inline QString ueDbUser() const
        { return this->m_strUser; }
    Q_INVOKABLE inline QString ueDbPassword() const
        { return this->m_strPassword; }
    Q_INVOKABLE inline QString ueDbHostname() const
        { return this->m_strHostname; }
    Q_INVOKABLE inline QString ueDbName() const
        { return this->m_strDbName; }
    Q_INVOKABLE inline int ueDbPort() const
        { return this->m_iDbPort; }

signals:
    void ueSignalDatabaseParametersFetched();
};

#endif // UEPOSSETTINGS_H

and its implementation:

#include "uepossettings.h"

UePOSSettings::UePOSSettings(QObject *parent)
    : QObject(parent)
{
    this->ueSetConfigurationFilePath(UePOSSettings::ueSearchConfigurationFile());
    this->ueParseData(this->ueConfigurationFilePath());
}   // default constructor

UePOSSettings::~UePOSSettings()
{
}   // destructor

QString UePOSSettings::ueSearchConfigurationFile()
{
    QDirIterator dirIterator("/home",
                             QStringList() << UeDefaults::UeApplication::APPLICATION_SETTINGS_FILE,
                             QDir::Files,
                             QDirIterator::Subdirectories);

    while(dirIterator.hasNext())
    {
        dirIterator.next();

        if(dirIterator.fileName()==UeDefaults::UeApplication::APPLICATION_SETTINGS_FILE)
        {
            return dirIterator.filePath();
        }   // if
    }   // while

    return dirIterator.filePath();
}   // ueSearchConfigurationFile

void UePOSSettings::ueParseData(const QString& filename)
{
    QFile settingsFile(filename);
    QString data;

    settingsFile.open(QIODevice::ReadOnly);
    data=QString::fromLatin1(settingsFile.readAll().constData());
    data.replace("\\:",
                 ":");
    this->ueSetParsedData(data);

    int iDbUrlIndexStart=data.indexOf(UeDefaults::UeDbKeys::KEY_DB_URL);
    int iDbUrlIndexStop=data.indexOf("\n",
                                     iDbUrlIndexStart);
    QString strDbUrl=data.mid(iDbUrlIndexStart,
                             (iDbUrlIndexStop-iDbUrlIndexStart));
    this->ueSetDbUrl(strDbUrl);

    int iDbHostnameIndexStart=this->ueDbUrl().indexOf("//")+2;
    int iDbHostnameIndexStop=this->ueDbUrl().lastIndexOf(":");
    this->ueSetDbHostname(this->ueDbUrl().mid(iDbHostnameIndexStart,
                                             (iDbHostnameIndexStop-iDbHostnameIndexStart)));

    int iDbNameIndexStart=this->ueDbUrl().lastIndexOf("/")+1;
    int iDbNameIndexStop=this->ueDbUrl().size();

    this->ueSetDbName(this->ueDbUrl().mid(iDbNameIndexStart,
                                         (iDbNameIndexStop-iDbNameIndexStart)));

    int iDbPortIndexStart=this->ueDbUrl().lastIndexOf(":")+1;
    int iDbPortIndexStop=this->ueDbUrl().lastIndexOf("/");

    QString strPort=this->ueDbUrl().mid(iDbPortIndexStart,
                                       (iDbPortIndexStop-iDbPortIndexStart));

    this->ueSetDbPort(strPort.toInt());

    int iDbUserIndexStart=data.indexOf(UeDefaults::UeDbKeys::KEY_DB_USER)+UeDefaults::UeDbKeys::KEY_DB_USER.length()+1;
    int iDbUserIndexStop=data.indexOf("\n",
                                      iDbUserIndexStart);
    this->ueSetDbUser(data.mid(iDbUserIndexStart,
                              (iDbUserIndexStop-iDbUserIndexStart)));

    int iDbPasswordIndexStart=data.indexOf(UeDefaults::UeDbKeys::KEY_DB_PASSWORD)+UeDefaults::UeDbKeys::KEY_DB_PASSWORD.length()+1;
    int iDbPasswordIndexStop=data.indexOf("\n",
                                          iDbPasswordIndexStart);
    QString test=data.mid(iDbPasswordIndexStart,
                          iDbPasswordIndexStop);
    this->ueSetDbPassword(data.mid(iDbPasswordIndexStart,
                                  (iDbPasswordIndexStop-iDbPasswordIndexStart)));

    settingsFile.close();

    emit this->ueSignalDatabaseParametersFetched();
}   // ueParseData

Now, as you can see, this object once instantiated from class, it searches for configuration file on disk, which is time consuming and then it parses needed data from text. The problem is, in my Qt/QML app whenever I try to open connection to database, I use this class. Is it wise to modify this class as singleton, so it will search for file just once and all data needed for database connection will also be visible anywhere from application?

Aucun commentaire:

Enregistrer un commentaire