QSQL, Create a factory for connections
-
I tried to create a singleton class that will act as a connection factory. In theory it should create a new connection when your method "connection" is called.
The code I was able to write this:
@/*
- dataaccess.hpp
- This file is part of TecTracker
- Copyright (C) 2014 - Matheus
- TecTracker is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
- TecTracker is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with TecTracker. If not, see http://www.gnu.org/licenses/.
*/
/Classe singleton/
#ifndef DATAACCESS_HPP
#define DATAACCESS_HPP
#include<QtSql/QSqlDatabase>
#include<QObject>class DataAccess
{
public:
static DataAccess* instance(); /* <= Devolve um objeto do tipo DataAccess*/
QSqlDatabase* conection(QSqlDatabase cnx, QObject evoker = 0); /<= Método para obter uma conexão/private:
explicit DataAccess();
DataAccess(const DataAccess&);
DataAccess& operator=(const DataAccess&);
static DataAccess dataaccess; / <= Objeto DataAccess*/};
#endif // DATAACCESS_HPP
@@/*
- dataaccess.cpp
- This file is part of TecTracker
- Copyright (C) 2014 - Matheus
- TecTracker is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
- TecTracker is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with TecTracker. If not, see http://www.gnu.org/licenses/.
*/
#include <QMutex>
#include "dataaccess.hpp"DataAccess *DataAccess::dataaccess; /DataAccess object null/
DataAccess* DataAccess::instance()
{
static QMutex mutex;if(!dataaccess)
{
mutex.lock();if(!dataaccess) dataaccess = new DataAccess; mutex.unlock();
}
return dataaccess;
}QSqlDatabase* DataAccess::conection(QSqlDatabase *cnx, QObject *evoker )
{
if(evoker)
*cnx = QSqlDatabase::addDatabase("QPSQL", evoker->objectName().append("cnx")); /Namede conection/
else
*cnx = QSqlDatabase::addDatabase("QPSQL"); /Default conection/cnx->setDatabaseName("tectracker");
cnx->setUserName("");
cnx->setPassword("");
cnx->setPort(***);
cnx->setHostName("*****");return cnx;
}DataAccess::DataAccess() /Private Constructor/
{
}
@However, I am getting signal 11 and fatal error during unit testing.
When I trigger the debug, I get Signal name: SIGSEGV and Signal meaning: Segmentation faultThe debug indicates the line:
@*cnx = QSqlDatabase::addDatabase("QPSQL", evoker->objectName().append("cnx")); /Namede conection/@
I believe I'm using pointers incorrectly, but not sure.
-
I believe that the error was in how I called the method:
@ QSqlDatabase *objdata;
QFETCH(QObject*, parente);
QFETCH(bool, banco);
QCOMPARE(DataAccess::instance()->conection(&objdata, parente)->open(), banco);@I switched to
@QSqlDatabase objdata;
QFETCH(QObject*, parente);
QFETCH(bool, banco);
QCOMPARE(DataAccess::instance()->conection(&objdata, parente)->open(), banco);@Thus there is no more the error.
What was wrong in the previous form?
-
Ok, I think I understood. Thanks to: http://en.wikipedia.org/wiki/Segmentation_fault
In the first case I was stored the returned object of QSqlDatabase::addDatabase on a non-existent address
Since @QSqlDatabase * objdata;@ does not define an address