Skip to content

Instantly share code, notes, and snippets.

@snow45
Last active August 29, 2015 14:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save snow45/61cea39423b79c61e10f to your computer and use it in GitHub Desktop.
Save snow45/61cea39423b79c61e10f to your computer and use it in GitHub Desktop.
#-------------------------------------------------
# FailinSqliteDb.pro
#-------------------------------------------------
QT += core gui sql
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = FailingSQLiteDb
TEMPLATE = app
SOURCES += main.cpp\
MainWindow.cpp \
MyDatabase.cpp
HEADERS += MainWindow.h \
MyDatabase.h
FORMS += MainWindow.ui
QMAKE_CXXFLAGS += -Werror -Wno-error=unused-local-typedefs -Wno-init-self -fno-exceptions -std=c++11
/*
* main.cpp
*/
#include "MainWindow.h"
#include <QApplication>
#include <QDebug>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
bool runApp2 = false;
for (int i = 1; i < argc; i++)
{
if (strcmp(argv[i], "--help") == 0)
{
qDebug() << "Command line options:";
qDebug() << "--app2 Run in app2 mode";
}
else if (strcmp(argv[i], "--app2") == 0)
runApp2 = true;
}
w.setRunMode(runApp2);
w.show();
return a.exec();
}
/*
* MainWindow.h
*/
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <MyDatabase.h>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
void setRunMode(bool runApp2);
private slots:
void on_saveStuff_BTN_clicked();
private:
Ui::MainWindow *ui;
MyDatabase * mDatabase1 = NULL;
MyDatabase * mDatabase2 = NULL;
bool mRunApp2 = false;
void openDatabase();
};
#endif // MAINWINDOW_H
/*
* MainWindow.cpp
*/
#include "MainWindow.h"
#include "ui_MainWindow.h"
#include <QDir>
#include <QDebug>
#include <QImage>
static const QString FOLDER_1 = "MyApp1_DB";
static const QString FOLDER_2 = "MyApp2_DB";
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QDir().mkpath(FOLDER_1);
QDir().mkpath(FOLDER_2);
openDatabase();
}
MainWindow::~MainWindow()
{
delete ui;
if(!mRunApp2)
delete mDatabase1;
delete mDatabase2;
}
void MainWindow::setRunMode(bool runApp2)
{
mRunApp2 = runApp2;
}
void MainWindow::on_saveStuff_BTN_clicked()
{
MyStuff mystuff;
mystuff.width = rand() % 20;
mystuff.height = rand() % 20;
mystuff.id = mDatabase2->getNextId("myid");
mystuff.image = QImage(mystuff.width, mystuff.height, QImage::Format_RGB32); // Create random image
if(!mRunApp2)
{
mDatabase1->addMyStuff(mystuff);
}
mDatabase2->addMyStuff(mystuff);
}
void MainWindow::openDatabase()
{
mDatabase1 = new MyDatabase();
mDatabase1->open(QDir().absolutePath() + '/' + FOLDER_1);
mDatabase2 = new MyDatabase();
mDatabase2->open(QDir().absolutePath() + '/' + FOLDER_2);
}
/*
* MyDatabase.h
*/
#ifndef MYDATABASE_H
#define MYDATABASE_H
#include <QObject>
#include <QImage>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlTableModel>
struct MyStuff
{
QString id;
QImage image;
int width;
int height;
};
class MyDatabase : public QObject
{
Q_OBJECT
public:
MyDatabase();
~MyDatabase();
void close();
QString getNextId(const QString &id);
MyStuff *getMyStuff(const QString &id);
bool open(const QString &path);
signals:
public slots:
bool addMyStuff(const MyStuff &myStuff);
private:
QString getPathToImage(const QString &imageDir, const QString &id);
MyStuff *myStuffFromRecord(const QSqlRecord &record, const QString &imageDir);
QString mConnectionName = QString::number((ulong)this);
QString mPath;
QSqlDatabase mDb;
QSqlQuery* mQuery = NULL;
};
#endif // MYDATABASE_H
/*
* MyDatabase.cpp
*/
#include "MyDatabase.h"
#include <QApplication>
#include <QDebug>
#include <QSqlDriver>
#include <QSqlError>
#include <QSqlField>
#include <QSqlQuery>
#include <QSqlRecord>
#include <QSqlTableModel>
#include <sys/stat.h>
static const QString DB_NAME = "mystuff.db";
static const QString SELECT_COMMAND = "SELECT * FROM stuffTable";
MyDatabase::MyDatabase() :
mPath("")
{
}
MyDatabase::~MyDatabase()
{
close();
}
void MyDatabase::close()
{
delete mQuery;
mQuery = NULL;
//if the application is closing down, the connection is already gone and a segfault will occur
if (!QApplication::closingDown())
{
QSqlDatabase::removeDatabase(mConnectionName);
}
}
QString MyDatabase::getNextId(const QString& id)
{
int sequenceNumber;
if (!mQuery->exec("SELECT max(substr(id,5,3)) FROM stuffTable"))
{
qCritical() << Q_FUNC_INFO << "mQuery->exec" << mQuery->lastError();
mQuery->finish();
return QString();
}
if (!mQuery->first())
{
qCritical() << Q_FUNC_INFO << "mQuery->first" << mQuery->lastError();
mQuery->finish();
return QString();
}
if (mQuery->value(0).isNull())
sequenceNumber = 1;
else
sequenceNumber = mQuery->value(0).toInt() + 1;
mQuery->finish();
return id + QString::number(sequenceNumber).rightJustified(3, '0');
}
MyStuff* MyDatabase::getMyStuff(const QString& id)
{
if (!mQuery->exec(SELECT_COMMAND + " WHERE id='" + QString(id)) + "'")
{
qCritical() << Q_FUNC_INFO << "mQuery->exec: " << mQuery->lastError();
mQuery->finish();
return NULL;
}
if (!mQuery->first())
{
qCritical() << Q_FUNC_INFO << "mQuery->first:" << mQuery->lastError();
mQuery->finish();
return NULL;
}
MyStuff* mystuff = myStuffFromRecord(mQuery->record(), mPath);
mQuery->finish();
return mystuff;
}
bool MyDatabase::open(const QString& path)
{
mPath = path;
//create connection to database
mDb = QSqlDatabase::addDatabase( "QSQLITE", mConnectionName );
mDb.setDatabaseName( path + '/' + DB_NAME );
// mDb.setConnectOptions("QSQLITE_ENABLE_SHARED_CACHE");
if( !mDb.open() )
{
qCritical() << Q_FUNC_INFO << "mDb->open:" << mDb.lastError();
return false;
}
//for some reason the umask doesn't seem to work with QSqlDatabase
chmod( mDb.databaseName().toLocal8Bit().constData(), 0666 );
mQuery = new QSqlQuery( mDb );
bool result = mQuery->exec( "CREATE TABLE IF NOT EXISTS stuffTable ("
"id TEXT PRIMARY KEY,"
"width INTEGER,"
"height INTEGER"
")" );
if( !result )
{
qCritical() << Q_FUNC_INFO << "mQuery->exec:" << mQuery->lastError();
return false;
}
mQuery->finish();
return true;
}
bool MyDatabase::addMyStuff(const MyStuff& myStuff)
{
QSqlTableModel table(NULL, mDb);
table.setTable("stuffTable");
QSqlRecord record = mDb.record("stuffTable");
record.setValue("id", myStuff.id);
record.setValue("width", myStuff.width);
record.setValue("height", myStuff.height);
if (!table.insertRecord(-1, record))
{
qCritical() << Q_FUNC_INFO << "table.insertRecord:" << table.lastError();
return false;
}
myStuff.image.save(getPathToImage(mPath, myStuff.id), "PNG");
return true;
}
QString MyDatabase::getPathToImage(const QString& imageDir, const QString& id)
{
return imageDir + '/' + id + ".png";
}
MyStuff* MyDatabase::myStuffFromRecord(const QSqlRecord& record, const QString& imageDir)
{
MyStuff* myStuff = new MyStuff;
myStuff->id = record.value("id").toString();
myStuff->width = record.value("width").toInt();
myStuff->height = record.value("height").toInt();
myStuff->image = QImage(getPathToImage(imageDir, myStuff->id));
return myStuff;
}
/*
* MainWindow.ui
*/
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QPushButton" name="saveStuff_BTN">
<property name="geometry">
<rect>
<x>130</x>
<y>130</y>
<width>85</width>
<height>27</height>
</rect>
</property>
<property name="text">
<string>Save Stuff</string>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>27</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment