Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Native Development

Reply
Developer
unbreakable
Posts: 74
Registered: ‎12-17-2009
My Device: Z30

Re: Sql Error

Thanks! :smileyhappy:

 

I am still running into problems. I have looked at the Quotes sample app but it seems too complicated and there are no explanation such that I am not sure which are the necessary bits and which are not.

 

#ifndef DBHELPER_H_
#define DBHELPER_H_

#include <QObject>
#include <QMetaType>
#include <bb/data/DataSource>
#include <bb/data/SqlConnection>

using namespace bb::data;

namespace bb
{
    namespace data
    {
        class SqlConnection;
    }
}

class dbHelper: public QObject
{
	Q_OBJECT

public:
	dbHelper();
	virtual ~dbHelper();

	Q_INVOKABLE void favourite(const QString &rule_id);

private:
	void initDatabase();

	bool checkConnection();

	SqlConnection *mSqlConnector;
	DataSource *mDataSource;
};

 But it is turning up ''SqlConnection' does not name a type' for SqlConnection *mSqlConnector;

 

#include "dbHelper.h"
#include <bb/data/SqlDataAccess>
#include <bb/data/DataAccessError>
#include <bb/system/SystemDialog>

#include <QtSql/QtSql>
#include <QDebug>

using namespace bb::data;
using namespace bb::system;

dbHelper::dbHelper() {
	initDatabase();
}

void dbHelper::initDatabase(){
	QFile dbFile (QDir::homePath() + "/Rules.db");

	if (!dbFile.exists()){
		QString appRoot (QDir::homePath());
		appRoot.chop(4);
		//copy original File
		QFile::copy(appRoot + "app/native/assets/Rules.db", QDir::homePath() + "/Rules.db");
	}

	mSourceInDataFolder = dbFile;

}

bool dbHelper::checkConnection()
{
	if (mSqlConnector)
	{
		return true;
	}
	else
	{
		QFile newFile(mSourceInDataFolder);

		if (newFile.exist()){
			disconnect(mSqlConnector, SIGNAL(reply(const bb::data&colon;:DataAccessReply&)), this,
			                        SLOT(onLoadAsyncResultData(const bb::data&colon;:DataAccessReply&)));
			delete mSqlConnector;
			}

		mSqlConnector = new SqlConnection(mSourceInDataFolder, "connect");

		connect(mSqlConnector, SIGNAL(reply(const bb::data&colon;:DataAccessReply&)), this,
		                    SLOT(onLoadAsyncResultData(const bb::data&colon;:DataAccessReply&)));

			return true;
		}
	return false;
}


void dbHelper::favourite(const QString &rule_id)
{
//	bool success = false;

	QVariantMap rule;
	rule["id"] = rule_id;

	if (checkConnection()){
		mSqlConnector->beginTransaction();
		mSqlConnector->execute("INSERT INTO user (ruleid, favourite) VALUES (:id, 1)", rule);
	}

//	if (!sqlda->hasError())
//			{success = true;}
//			return success;
}

dbHelper::~dbHelper() {
  delete mSqlConnector;
}

 

I have tried to follow mostly the samples, but tbh, I am nto sure what to do with the Signal/Slots. Not exactly sure what I am missing here!

Developer
BBSJdev
Posts: 6,118
Registered: ‎07-05-2012
My Device: Playbook, Dev Alpha C, Z10 LE, Z30

Re: Sql Error

Can I recommend reading around the subject a little bit, signals and slots are explained nicely here...

http://developer.blackberry.com/native/documentation/cascades/dev/signals_slots/

If you've been helped click on Like Button, if you've been saved buy the app. :smileyhappy:

Developer of stokLocker, Sympatico and Super Sentences.
Developer
unbreakable
Posts: 74
Registered: ‎12-17-2009
My Device: Z30

Re: Sql Error

I have read them. I am just not sure what they mean in this context. Do I really need to use them?

In the quotes tutorial there seems to be so many steps to just get a connection to the database but in the CRUD sample it has so little steps, I am not sure which one to follow.
Developer
greenmr
Posts: 919
Registered: ‎03-20-2013
My Device: Red LE Developer Z10

Re: Sql Error

You should not need this bit...

 

namespace bb
{
    namespace data
    {
        class SqlConnection;
    }
}

 

 


unbreakable wrote:

Thanks! :smileyhappy:

 

I am still running into problems. I have looked at the Quotes sample app but it seems too complicated and there are no explanation such that I am not sure which are the necessary bits and which are not.

 

#ifndef DBHELPER_H_
#define DBHELPER_H_

#include <QObject>
#include <QMetaType>
#include <bb/data/DataSource>
#include <bb/data/SqlConnection>

using namespace bb::data;

namespace bb
{
    namespace data
    {
        class SqlConnection;
    }
}

class dbHelper: public QObject
{
	Q_OBJECT

public:
	dbHelper();
	virtual ~dbHelper();

	Q_INVOKABLE void favourite(const QString &rule_id);

private:
	void initDatabase();

	bool checkConnection();

	SqlConnection *mSqlConnector;
	DataSource *mDataSource;
};

 But it is turning up ''SqlConnection' does not name a type' for SqlConnection *mSqlConnector;

 

#include "dbHelper.h"
#include <bb/data/SqlDataAccess>
#include <bb/data/DataAccessError>
#include <bb/system/SystemDialog>

#include <QtSql/QtSql>
#include <QDebug>

using namespace bb::data;
using namespace bb::system;

dbHelper::dbHelper() {
	initDatabase();
}

void dbHelper::initDatabase(){
	QFile dbFile (QDir::homePath() + "/Rules.db");

	if (!dbFile.exists()){
		QString appRoot (QDir::homePath());
		appRoot.chop(4);
		//copy original File
		QFile::copy(appRoot + "app/native/assets/Rules.db", QDir::homePath() + "/Rules.db");
	}

	mSourceInDataFolder = dbFile;

}

bool dbHelper::checkConnection()
{
	if (mSqlConnector)
	{
		return true;
	}
	else
	{
		QFile newFile(mSourceInDataFolder);

		if (newFile.exist()){
			disconnect(mSqlConnector, SIGNAL(reply(const bb::data&colon;:DataAccessReply&)), this,
			                        SLOT(onLoadAsyncResultData(const bb::data&colon;:DataAccessReply&)));
			delete mSqlConnector;
			}

		mSqlConnector = new SqlConnection(mSourceInDataFolder, "connect");

		connect(mSqlConnector, SIGNAL(reply(const bb::data&colon;:DataAccessReply&)), this,
		                    SLOT(onLoadAsyncResultData(const bb::data&colon;:DataAccessReply&)));

			return true;
		}
	return false;
}


void dbHelper::favourite(const QString &rule_id)
{
//	bool success = false;

	QVariantMap rule;
	rule["id"] = rule_id;

	if (checkConnection()){
		mSqlConnector->beginTransaction();
		mSqlConnector->execute("INSERT INTO user (ruleid, favourite) VALUES (:id, 1)", rule);
	}

//	if (!sqlda->hasError())
//			{success = true;}
//			return success;
}

dbHelper::~dbHelper() {
  delete mSqlConnector;
}

 

I have tried to follow mostly the samples, but tbh, I am nto sure what to do with the Signal/Slots. Not exactly sure what I am missing here!






Developer of Built for BlackBerry certified multiFEED RSS/Atom feed reader and aggregator.
Developer
greenmr
Posts: 919
Registered: ‎03-20-2013
My Device: Red LE Developer Z10

Re: Sql Error

I'm trying to follow your code but I don't see where you declare mSourceInDataFolder:

 

mSourceInDataFolder = dbFile;

I assume it is supposed to be a private member variable, but I don't see it declared anywhere.



Developer of Built for BlackBerry certified multiFEED RSS/Atom feed reader and aggregator.
Developer
greenmr
Posts: 919
Registered: ‎03-20-2013
My Device: Red LE Developer Z10

Re: Sql Error

I do all my database stuff using only SqlDataAccess. I don't use DataSource or SqlConnection at all. I think you are overcomplicating things.

 


unbreakable wrote:

Thanks! :smileyhappy:

 

I am still running into problems. I have looked at the Quotes sample app but it seems too complicated and there are no explanation such that I am not sure which are the necessary bits and which are not.

 

#ifndef DBHELPER_H_
#define DBHELPER_H_

#include <QObject>
#include <QMetaType>
#include <bb/data/DataSource>
#include <bb/data/SqlConnection>

using namespace bb::data;

namespace bb
{
    namespace data
    {
        class SqlConnection;
    }
}

class dbHelper: public QObject
{
	Q_OBJECT

public:
	dbHelper();
	virtual ~dbHelper();

	Q_INVOKABLE void favourite(const QString &rule_id);

private:
	void initDatabase();

	bool checkConnection();

	SqlConnection *mSqlConnector;
	DataSource *mDataSource;
};

 But it is turning up ''SqlConnection' does not name a type' for SqlConnection *mSqlConnector;

 

#include "dbHelper.h"
#include <bb/data/SqlDataAccess>
#include <bb/data/DataAccessError>
#include <bb/system/SystemDialog>

#include <QtSql/QtSql>
#include <QDebug>

using namespace bb::data;
using namespace bb::system;

dbHelper::dbHelper() {
	initDatabase();
}

void dbHelper::initDatabase(){
	QFile dbFile (QDir::homePath() + "/Rules.db");

	if (!dbFile.exists()){
		QString appRoot (QDir::homePath());
		appRoot.chop(4);
		//copy original File
		QFile::copy(appRoot + "app/native/assets/Rules.db", QDir::homePath() + "/Rules.db");
	}

	mSourceInDataFolder = dbFile;

}

bool dbHelper::checkConnection()
{
	if (mSqlConnector)
	{
		return true;
	}
	else
	{
		QFile newFile(mSourceInDataFolder);

		if (newFile.exist()){
			disconnect(mSqlConnector, SIGNAL(reply(const bb::data&colon;:DataAccessReply&)), this,
			                        SLOT(onLoadAsyncResultData(const bb::data&colon;:DataAccessReply&)));
			delete mSqlConnector;
			}

		mSqlConnector = new SqlConnection(mSourceInDataFolder, "connect");

		connect(mSqlConnector, SIGNAL(reply(const bb::data&colon;:DataAccessReply&)), this,
		                    SLOT(onLoadAsyncResultData(const bb::data&colon;:DataAccessReply&)));

			return true;
		}
	return false;
}


void dbHelper::favourite(const QString &rule_id)
{
//	bool success = false;

	QVariantMap rule;
	rule["id"] = rule_id;

	if (checkConnection()){
		mSqlConnector->beginTransaction();
		mSqlConnector->execute("INSERT INTO user (ruleid, favourite) VALUES (:id, 1)", rule);
	}

//	if (!sqlda->hasError())
//			{success = true;}
//			return success;
}

dbHelper::~dbHelper() {
  delete mSqlConnector;
}

 

I have tried to follow mostly the samples, but tbh, I am nto sure what to do with the Signal/Slots. Not exactly sure what I am missing here!






Developer of Built for BlackBerry certified multiFEED RSS/Atom feed reader and aggregator.
Developer
greenmr
Posts: 919
Registered: ‎03-20-2013
My Device: Red LE Developer Z10

Re: Sql Error

I haven't tested this, but try it this way instead:

 

#ifndef DBHELPER_H_
#define DBHELPER_H_

#include <QObject>
#include <bb/data/SqlDataAccess>

using namespace bb::data;

class dbHelper: public QObject
{
	Q_OBJECT
	Q_DISABLE_COPY()

	SqlDataAccess* db;
	void initDatabase();

public:
	dbHelper();

	Q_INVOKABLE void favourite(const QString& rule_id);
};

#endif /* DBHELPER_H_ */
dbHelper::dbHelper() {
	this->initDatabase();
}

void dbHelper::initDatabase(){
	QFile dbFile (QDir::homePath() + "/Rules.db");

	if (!dbFile.exists()){
		QString appRoot (QDir::homePath());
		appRoot.chop(4);
		//copy original File
		QFile::copy(appRoot + "app/native/assets/Rules.db", QDir::homePath() + "/Rules.db");
	}

    this->db = SqlDataAccess(dbFile.toString(), this);
}

void dbHelper::favourite(const QString& rule_id)
{
	QVariantMap rule;
	rule["id"] = rule_id;

	this->db->execute("INSERT INTO user (ruleid, favourite) VALUES (:id, 1)", rule);
	if (this->db->hasError()) {
		// ---Do error handling
	}
}

You don't really need transaction processing when you only have single update to do, but if you want it you can add this:

 

void dbHelper::favourite(const QString& rule_id)
{
	QVariantMap rule;
	rule["id"] = rule_id;

	this->db->connection().transaction();
	this->db->execute("INSERT INTO user (ruleid, favourite) VALUES (:id, 1)", rule);
	if (this->db->hasError()) {
		this->db->connection().rollback();
	else
		this->db->connection().commit();
	}
}

As I said I haven't tested this, but it should at least point you in the right direction.



Developer of Built for BlackBerry certified multiFEED RSS/Atom feed reader and aggregator.
Developer
unbreakable
Posts: 74
Registered: ‎12-17-2009
My Device: Z30

Re: Sql Error

Thank you!

I think I was trying to combine too many elements of the different tutorials together. :s

Thanks for the basic guideline. WIll try to build it from there!
Developer
unbreakable
Posts: 74
Registered: ‎12-17-2009
My Device: Z30

Re: Sql Error

[ Edited ]

Hi,

 

I have been doing more reading up/exploration and I just found out that there is actually a difference between SqlDataAccess/QSqlDatabase etc.( Somehow sometimes the sample apps seems to be able to do things magically which doesnt seem to work for me)

 

I have decided to go with the QSql route... (thanks for the previous examples! they did give me a guideline!

 

Finally I've managed to get to the error message: QSqlQuery::exec: database not open. I hope that implies at least that I have at the very least managed to create the database in the data folder etc.?

 

I am not sure what is wrong as I've more or less followed the tutorial. I have tried to open the database with .open() . Everything necessary had been declared in the header.

 

void dbHelper::initDatabase(){
	//Copy database to Data folder
	QString newFileName = QDir::homePath() + "/Rules.db";
	QFile dbFile (newFileName);

	if (!dbFile.exists()){
		QString appRoot (QDir::homePath());
		appRoot.chop(4);
		QFile originalFile (appRoot + "app/native/assets/Rules.db");
		originalFile.copy(newFileName);
	}

	//Set up connection with QSqlDataBase
	mdbFilewithPath = "data/" + newFileName;
	mDb = QSqlDatabase::addDatabase ("QSQLITE", "database_helper_connection");
	mDb.setDatabaseName(mdbFilewithPath);

	bool success = mDb.open();
	if (!success) {
		qWarning() << "Could not open database.";
	}
}

void dbHelper::executeQuery (const QString query){
	if (!mDb.open()){
		mDb.open();
	}
	QSqlQuery sqlQuery (query, mDb);
}

void dbHelper::favourite(const QString &rule_id)
{

	QVariantMap rule;
	rule["id"] = rule_id;
	QString query ="INSERT INTO user (rule_id, isFavourite) VALUES (" + rule_id + ", 1)";
	executeQuery(query);
}

 

I guess my main question is, is it correct to do my executeQuery() function this way? How/where should I open my database? Will it stay open this way?

 

Or should I use .prepare() first, and then .exec()? 

 

Thanks in advance for all the help!!

 

Developer
greenmr
Posts: 919
Registered: ‎03-20-2013
My Device: Red LE Developer Z10

Re: Sql Error

Are you planning to have more than one database open in your app? If not, I'm curious why you would go with the more complicated QSqlDatabase addDatabase route? What is it that is different between the two approaches that you need but aren't getting with SqlDataAccess?

 


unbreakable wrote:

Hi,

 

I have been doing more reading up/exploration and I just found out that there is actually a difference between SqlDataAccess/QSqlDatabase etc.( Somehow sometimes the sample apps seems to be able to do things magically which doesnt seem to work for me)

 

I have decided to go with the QSql route... (thanks for the previous examples! they did give me a guideline!

 

Finally I've managed to get to the error message: QSqlQuery::exec: database not open. I hope that implies at least that I have at the very least managed to create the database in the data folder etc.?

 

I am not sure what is wrong as I've more or less followed the tutorial. I have tried to open the database with .open() . Everything necessary had been declared in the header.

 

void dbHelper::initDatabase(){
	//Copy database to Data folder
	QString newFileName = QDir::homePath() + "/Rules.db";
	QFile dbFile (newFileName);

	if (!dbFile.exists()){
		QString appRoot (QDir::homePath());
		appRoot.chop(4);
		QFile originalFile (appRoot + "app/native/assets/Rules.db");
		originalFile.copy(newFileName);
	}

	//Set up connection with QSqlDataBase
	mdbFilewithPath = "data/" + newFileName;
	mDb = QSqlDatabase::addDatabase ("QSQLITE", "database_helper_connection");
	mDb.setDatabaseName(mdbFilewithPath);

	bool success = mDb.open();
	if (!success) {
		qWarning() << "Could not open database.";
	}
}

void dbHelper::executeQuery (const QString query){
	if (!mDb.open()){
		mDb.open();
	}
	QSqlQuery sqlQuery (query, mDb);
}

void dbHelper::favourite(const QString &rule_id)
{

	QVariantMap rule;
	rule["id"] = rule_id;
	QString query ="INSERT INTO user (rule_id, isFavourite) VALUES (" + rule_id + ", 1)";
	executeQuery(query);
}

 

I guess my main question is, is it correct to do my executeQuery() function this way? How/where should I open my database? Will it stay open this way?

 

Thanks in advance for all the help!!

 






Developer of Built for BlackBerry certified multiFEED RSS/Atom feed reader and aggregator.