Fix object leaks in database code

Qt's database and query model requires that both the queries and the database
objects are out of scope before a database connection can safely be removed.

Solution: Properly encapsulate databases and queries in "{ }" and use a string
to cache the connection name for out-of-scope removal.
This commit is contained in:
Felix Kauselmann
2020-08-25 14:30:13 +02:00
parent 48a0d64837
commit 4b3042def4
11 changed files with 924 additions and 868 deletions

View File

@ -152,23 +152,25 @@ bool ComicModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int
foreach (ComicItem *item, _data) {
allComicIds << item->data(Id).toULongLong();
}
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
switch (mode) {
case Favorites:
DBHelper::reasignOrderToComicsInFavorites(allComicIds, db);
break;
case Label:
DBHelper::reasignOrderToComicsInLabel(sourceId, allComicIds, db);
break;
case ReadingList:
DBHelper::reasignOrderToComicsInReadingList(sourceId, allComicIds, db);
break;
default:
break;
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
switch (mode) {
case Favorites:
DBHelper::reasignOrderToComicsInFavorites(allComicIds, db);
break;
case Label:
DBHelper::reasignOrderToComicsInLabel(sourceId, allComicIds, db);
break;
case ReadingList:
DBHelper::reasignOrderToComicsInReadingList(sourceId, allComicIds, db);
break;
default:
break;
}
connectionName = db.connectionName();
}
QSqlDatabase::removeDatabase(db.connectionName());
QSqlDatabase::removeDatabase(connectionName);
//endMoveRows();
@ -441,8 +443,9 @@ void ComicModel::setupFolderModelData(unsigned long long int folderId, const QSt
_data.clear();
_databasePath = databasePath;
QSqlDatabase db = DataBaseManagement::loadDatabase(databasePath);
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(databasePath);
QSqlQuery selectQuery(db);
selectQuery.prepare("SELECT ci.number,ci.title,c.fileName,ci.numPages,c.id,c.parentId,c.path,ci.hash,ci.read,ci.isBis,ci.currentPage,ci.rating,ci.hasBeenOpened "
"FROM comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) "
@ -450,13 +453,10 @@ void ComicModel::setupFolderModelData(unsigned long long int folderId, const QSt
selectQuery.bindValue(":parentId", folderId);
selectQuery.exec();
setupModelData(selectQuery);
connectionName = db.connectionName();
}
db.close();
QSqlDatabase::removeDatabase(db.connectionName());
QSqlDatabase::removeDatabase(connectionName);
endResetModel();
/*if(_data.length()==0)
emit isEmpty();*/
}
void ComicModel::setupLabelModelData(unsigned long long parentLabel, const QString &databasePath)
@ -470,8 +470,9 @@ void ComicModel::setupLabelModelData(unsigned long long parentLabel, const QStri
_data.clear();
_databasePath = databasePath;
QSqlDatabase db = DataBaseManagement::loadDatabase(databasePath);
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(databasePath);
QSqlQuery selectQuery(db);
selectQuery.prepare("SELECT ci.number,ci.title,c.fileName,ci.numPages,c.id,c.parentId,c.path,ci.hash,ci.read,ci.isBis,ci.currentPage,ci.rating,ci.hasBeenOpened "
"FROM comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) "
@ -481,13 +482,10 @@ void ComicModel::setupLabelModelData(unsigned long long parentLabel, const QStri
selectQuery.bindValue(":parentLabelId", parentLabel);
selectQuery.exec();
setupModelDataForList(selectQuery);
connectionName = db.connectionName();
}
db.close();
QSqlDatabase::removeDatabase(db.connectionName());
QSqlDatabase::removeDatabase(connectionName);
endResetModel();
/*if(_data.length()==0)
emit isEmpty();*/
}
void ComicModel::setupReadingListModelData(unsigned long long parentReadingList, const QString &databasePath)
@ -500,8 +498,9 @@ void ComicModel::setupReadingListModelData(unsigned long long parentReadingList,
_data.clear();
_databasePath = databasePath;
QSqlDatabase db = DataBaseManagement::loadDatabase(databasePath);
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(databasePath);
QList<qulonglong> ids;
ids << parentReadingList;
@ -535,9 +534,9 @@ void ComicModel::setupReadingListModelData(unsigned long long parentReadingList,
_data = tempData << _data;
}
connectionName = db.connectionName();
}
db.close();
QSqlDatabase::removeDatabase(db.connectionName());
QSqlDatabase::removeDatabase(connectionName);
endResetModel();
}
@ -551,8 +550,9 @@ void ComicModel::setupFavoritesModelData(const QString &databasePath)
_data.clear();
_databasePath = databasePath;
QSqlDatabase db = DataBaseManagement::loadDatabase(databasePath);
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(databasePath);
QSqlQuery selectQuery(db);
selectQuery.prepare("SELECT ci.number,ci.title,c.fileName,ci.numPages,c.id,c.parentId,c.path,ci.hash,ci.read,ci.isBis,ci.currentPage,ci.rating,ci.hasBeenOpened "
"FROM comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) "
@ -562,13 +562,10 @@ void ComicModel::setupFavoritesModelData(const QString &databasePath)
selectQuery.bindValue(":parentDefaultListId", 1);
selectQuery.exec();
setupModelDataForList(selectQuery);
connectionName = db.connectionName();
}
db.close();
QSqlDatabase::removeDatabase(db.connectionName());
QSqlDatabase::removeDatabase(connectionName);
endResetModel();
/*if(_data.length()==0)
emit isEmpty();*/
}
void ComicModel::setupReadingModelData(const QString &databasePath)
@ -581,8 +578,9 @@ void ComicModel::setupReadingModelData(const QString &databasePath)
_data.clear();
_databasePath = databasePath;
QSqlDatabase db = DataBaseManagement::loadDatabase(databasePath);
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(databasePath);
QSqlQuery selectQuery(db);
selectQuery.prepare("SELECT ci.number,ci.title,c.fileName,ci.numPages,c.id,c.parentId,c.path,ci.hash,ci.read,ci.isBis,ci.currentPage,ci.rating,ci.hasBeenOpened "
"FROM comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) "
@ -591,32 +589,22 @@ void ComicModel::setupReadingModelData(const QString &databasePath)
selectQuery.exec();
setupModelDataForList(selectQuery);
connectionName = db.connectionName();
}
db.close();
QSqlDatabase::removeDatabase(db.connectionName());
QSqlDatabase::removeDatabase(connectionName);
endResetModel();
/*if(_data.length()==0)
emit isEmpty();*/
}
void ComicModel::setupModelData(const SearchModifiers modifier, const QString &filter, const QString &databasePath)
{
//QFile f(QCoreApplication::applicationDirPath()+"/performance.txt");
//f.open(QIODevice::Append);
beginResetModel();
//QElapsedTimer timer;
//timer.start();
qDeleteAll(_data);
_data.clear();
//QTextStream txtS(&f);
//txtS << "TABLEMODEL: Tiempo de borrado: " << timer.elapsed() << "ms\r\n";
_databasePath = databasePath;
QSqlDatabase db = DataBaseManagement::loadDatabase(databasePath);
QString connectionName = "";
{
//crear la consulta
//timer.restart();
QSqlDatabase db = DataBaseManagement::loadDatabase(databasePath);
QSqlQuery selectQuery(db);
switch (modifier) {
@ -653,14 +641,10 @@ void ComicModel::setupModelData(const SearchModifiers modifier, const QString &f
QLOG_DEBUG() << selectQuery.lastError() << "--";
//txtS << "TABLEMODEL: Tiempo de consulta: " << timer.elapsed() << "ms\r\n";
//timer.restart();
setupModelData(selectQuery);
//txtS << "TABLEMODEL: Tiempo de creaci�n del modelo: " << timer.elapsed() << "ms\r\n";
//selectQuery.finish();
connectionName = db.connectionName();
}
db.close();
QSqlDatabase::removeDatabase(db.connectionName());
QSqlDatabase::removeDatabase(connectionName);
endResetModel();
emit searchNumResults(_data.length());
@ -715,20 +699,28 @@ void ComicModel::setupModelDataForList(QSqlQuery &sqlquery)
ComicDB ComicModel::getComic(const QModelIndex &mi)
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
ComicDB c = DBHelper::loadComic(_data.at(mi.row())->data(ComicModel::Id).toULongLong(), db);
db.close();
QSqlDatabase::removeDatabase(db.connectionName());
ComicDB c;
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
c = DBHelper::loadComic(_data.at(mi.row())->data(ComicModel::Id).toULongLong(), db);
connectionName = db.connectionName();
}
QSqlDatabase::removeDatabase(connectionName);
return c;
}
ComicDB ComicModel::_getComic(const QModelIndex &mi)
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
ComicDB c = DBHelper::loadComic(_data.at(mi.row())->data(ComicModel::Id).toULongLong(), db);
db.close();
QSqlDatabase::removeDatabase(db.connectionName());
ComicDB c;
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
c = DBHelper::loadComic(_data.at(mi.row())->data(ComicModel::Id).toULongLong(), db);
connectionName = db.connectionName();
}
QSqlDatabase::removeDatabase(connectionName);
return c;
}
@ -757,18 +749,21 @@ QVector<YACReaderComicReadStatus> ComicModel::setAllComicsRead(YACReaderComicRea
QList<ComicDB> ComicModel::getAllComics()
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
db.transaction();
QList<ComicDB> comics;
int numComics = _data.count();
for (int i = 0; i < numComics; i++) {
comics.append(DBHelper::loadComic(_data.value(i)->data(ComicModel::Id).toULongLong(), db));
}
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
db.transaction();
db.commit();
db.close();
QSqlDatabase::removeDatabase(db.connectionName());
int numComics = _data.count();
for (int i = 0; i < numComics; i++) {
comics.append(DBHelper::loadComic(_data.value(i)->data(ComicModel::Id).toULongLong(), db));
}
db.commit();
connectionName = db.connectionName();
}
QSqlDatabase::removeDatabase(connectionName);
return comics;
}
@ -776,44 +771,40 @@ QList<ComicDB> ComicModel::getAllComics()
QList<ComicDB> ComicModel::getComics(QList<QModelIndex> list)
{
QList<ComicDB> comics;
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
db.transaction();
QList<QModelIndex>::const_iterator itr;
for (itr = list.constBegin(); itr != list.constEnd(); itr++) {
for (auto itr = list.constBegin(); itr != list.constEnd(); itr++) {
comics.append(_getComic(*itr));
}
db.commit();
db.close();
QSqlDatabase::removeDatabase(db.connectionName());
return comics;
}
//TODO
QVector<YACReaderComicReadStatus> ComicModel::setComicsRead(QList<QModelIndex> list, YACReaderComicReadStatus read)
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
db.transaction();
foreach (QModelIndex mi, list) {
if (read == YACReader::Read) {
_data.value(mi.row())->setData(ComicModel::ReadColumn, QVariant(true));
ComicDB c = DBHelper::loadComic(_data.value(mi.row())->data(ComicModel::Id).toULongLong(), db);
c.info.read = true;
DBHelper::update(&(c.info), db);
}
if (read == YACReader::Unread) {
_data.value(mi.row())->setData(ComicModel::ReadColumn, QVariant(false));
_data.value(mi.row())->setData(ComicModel::CurrentPage, QVariant(1));
_data.value(mi.row())->setData(ComicModel::HasBeenOpened, QVariant(false));
ComicDB c = DBHelper::loadComic(_data.value(mi.row())->data(ComicModel::Id).toULongLong(), db);
c.info.read = false;
c.info.currentPage = 1;
c.info.hasBeenOpened = false;
DBHelper::update(&(c.info), db);
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
db.transaction();
foreach (QModelIndex mi, list) {
if (read == YACReader::Read) {
_data.value(mi.row())->setData(ComicModel::ReadColumn, QVariant(true));
ComicDB c = DBHelper::loadComic(_data.value(mi.row())->data(ComicModel::Id).toULongLong(), db);
c.info.read = true;
DBHelper::update(&(c.info), db);
}
if (read == YACReader::Unread) {
_data.value(mi.row())->setData(ComicModel::ReadColumn, QVariant(false));
_data.value(mi.row())->setData(ComicModel::CurrentPage, QVariant(1));
_data.value(mi.row())->setData(ComicModel::HasBeenOpened, QVariant(false));
ComicDB c = DBHelper::loadComic(_data.value(mi.row())->data(ComicModel::Id).toULongLong(), db);
c.info.read = false;
c.info.currentPage = 1;
c.info.hasBeenOpened = false;
DBHelper::update(&(c.info), db);
}
}
db.commit();
connectionName = db.connectionName();
}
db.commit();
db.close();
QSqlDatabase::removeDatabase(db.connectionName());
QSqlDatabase::removeDatabase(connectionName);
emit dataChanged(index(list.first().row(), ComicModel::ReadColumn), index(list.last().row(), ComicModel::HasBeenOpened), QVector<int>() << ReadColumnRole << CurrentPageRole << HasBeenOpenedRole);
@ -821,23 +812,25 @@ QVector<YACReaderComicReadStatus> ComicModel::setComicsRead(QList<QModelIndex> l
}
qint64 ComicModel::asignNumbers(QList<QModelIndex> list, int startingNumber)
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
db.transaction();
qint64 idFirst = _data.value(list[0].row())->data(ComicModel::Id).toULongLong();
int i = 0;
foreach (QModelIndex mi, list) {
ComicDB c = DBHelper::loadComic(_data.value(mi.row())->data(ComicModel::Id).toULongLong(), db);
c.info.number = startingNumber + i;
c.info.edited = true;
DBHelper::update(&(c.info), db);
i++;
qint64 idFirst;
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
db.transaction();
idFirst = _data.value(list[0].row())->data(ComicModel::Id).toULongLong();
int i = 0;
foreach (QModelIndex mi, list) {
ComicDB c = DBHelper::loadComic(_data.value(mi.row())->data(ComicModel::Id).toULongLong(), db);
c.info.number = startingNumber + i;
c.info.edited = true;
DBHelper::update(&(c.info), db);
i++;
}
db.commit();
connectionName = db.connectionName();
}
db.commit();
db.close();
QSqlDatabase::removeDatabase(db.connectionName());
//emit dataChanged(index(0,ComicModel::Number),index(_data.count()-1,ComicModel::HasBeenOpened));
QSqlDatabase::removeDatabase(connectionName);
return idFirst;
}
@ -867,19 +860,22 @@ QList<QModelIndex> ComicModel::getIndexesFromIds(const QList<qulonglong> &comicI
void ComicModel::startTransaction()
{
dbTransaction = DataBaseManagement::loadDatabase(_databasePath);
auto dbTransaction = DataBaseManagement::loadDatabase(_databasePath);
_databaseConnection = dbTransaction.connectionName();
dbTransaction.transaction();
}
void ComicModel::finishTransaction()
{
dbTransaction.commit();
dbTransaction.close();
QSqlDatabase::removeDatabase(dbTransaction.connectionName());
{
QSqlDatabase::database(_databaseConnection).commit();
}
QSqlDatabase::removeDatabase(_databaseConnection);
}
void ComicModel::removeInTransaction(int row)
{
auto dbTransaction = QSqlDatabase::database(_databaseConnection);
ComicDB c = DBHelper::loadComic(_data.at(row)->data(ComicModel::Id).toULongLong(), dbTransaction);
DBHelper::removeFromDB(&c, dbTransaction);
@ -890,27 +886,6 @@ void ComicModel::removeInTransaction(int row)
endRemoveRows();
}
/*
void ComicModel::remove(ComicDB * comic, int row)
{
beginRemoveRows(QModelIndex(),row,row);
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
DBHelper::removeFromDB(comic,db);
removeRow(row);
delete _data.at(row);
_data.removeAt(row);
db.close();
QSqlDatabase::removeDatabase(db.connectionName());
endRemoveRows();
}
*/
/*ComicDB TableModel::getComic(int row)
{
return getComic(index(row,0));
}*/
void ComicModel::remove(int row)
{
@ -938,17 +913,18 @@ void ComicModel::reload(const ComicDB &comic)
void ComicModel::resetComicRating(const QModelIndex &mi)
{
ComicDB comic = getComic(mi);
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
comic.info.rating = 0;
_data[mi.row()]->setData(ComicModel::Rating, 0);
DBHelper::update(&(comic.info), db);
comic.info.rating = 0;
_data[mi.row()]->setData(ComicModel::Rating, 0);
DBHelper::update(&(comic.info), db);
emit dataChanged(mi, mi);
db.close();
QSqlDatabase::removeDatabase(db.connectionName());
emit dataChanged(mi, mi);
connectionName = db.connectionName();
}
QSqlDatabase::removeDatabase(connectionName);
}
QUrl ComicModel::getCoverUrlPathForComicHash(const QString &hash) const
@ -964,13 +940,14 @@ void ComicModel::addComicsToFavorites(const QList<qulonglong> &comicIds)
void ComicModel::addComicsToFavorites(const QList<QModelIndex> &comicsList)
{
QList<ComicDB> comics = getComics(comicsList);
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
DBHelper::insertComicsInFavorites(comics, db);
db.close();
QSqlDatabase::removeDatabase(db.connectionName());
DBHelper::insertComicsInFavorites(comics, db);
connectionName = db.connectionName();
}
QSqlDatabase::removeDatabase(connectionName);
}
void ComicModel::addComicsToLabel(const QList<qulonglong> &comicIds, qulonglong labelId)
@ -981,13 +958,14 @@ void ComicModel::addComicsToLabel(const QList<qulonglong> &comicIds, qulonglong
void ComicModel::addComicsToLabel(const QList<QModelIndex> &comicsList, qulonglong labelId)
{
QList<ComicDB> comics = getComics(comicsList);
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
DBHelper::insertComicsInLabel(comics, labelId, db);
db.close();
QSqlDatabase::removeDatabase(db.connectionName());
DBHelper::insertComicsInLabel(comics, labelId, db);
connectionName = db.connectionName();
}
QSqlDatabase::removeDatabase(connectionName);
}
void ComicModel::addComicsToReadingList(const QList<qulonglong> &comicIds, qulonglong readingListId)
@ -998,25 +976,27 @@ void ComicModel::addComicsToReadingList(const QList<qulonglong> &comicIds, qulon
void ComicModel::addComicsToReadingList(const QList<QModelIndex> &comicsList, qulonglong readingListId)
{
QList<ComicDB> comics = getComics(comicsList);
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
DBHelper::insertComicsInReadingList(comics, readingListId, db);
db.close();
QSqlDatabase::removeDatabase(db.connectionName());
DBHelper::insertComicsInReadingList(comics, readingListId, db);
connectionName = db.connectionName();
}
QSqlDatabase::removeDatabase(connectionName);
}
void ComicModel::deleteComicsFromFavorites(const QList<QModelIndex> &comicsList)
{
QList<ComicDB> comics = getComics(comicsList);
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
DBHelper::deleteComicsFromFavorites(comics, db);
db.close();
QSqlDatabase::removeDatabase(db.connectionName());
DBHelper::deleteComicsFromFavorites(comics, db);
connectionName = db.connectionName();
}
QSqlDatabase::removeDatabase(connectionName);
if (mode == Favorites)
deleteComicsFromModel(comicsList);
@ -1025,13 +1005,14 @@ void ComicModel::deleteComicsFromFavorites(const QList<QModelIndex> &comicsList)
void ComicModel::deleteComicsFromLabel(const QList<QModelIndex> &comicsList, qulonglong labelId)
{
QList<ComicDB> comics = getComics(comicsList);
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
DBHelper::deleteComicsFromLabel(comics, labelId, db);
db.close();
QSqlDatabase::removeDatabase(db.connectionName());
DBHelper::deleteComicsFromLabel(comics, labelId, db);
connectionName = db.connectionName();
}
QSqlDatabase::removeDatabase(connectionName);
deleteComicsFromModel(comicsList);
}
@ -1039,13 +1020,14 @@ void ComicModel::deleteComicsFromLabel(const QList<QModelIndex> &comicsList, qul
void ComicModel::deleteComicsFromReadingList(const QList<QModelIndex> &comicsList, qulonglong readingListId)
{
QList<ComicDB> comics = getComics(comicsList);
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
DBHelper::deleteComicsFromReadingList(comics, readingListId, db);
db.close();
QSqlDatabase::removeDatabase(db.connectionName());
DBHelper::deleteComicsFromReadingList(comics, readingListId, db);
connectionName = db.connectionName();
}
QSqlDatabase::removeDatabase(connectionName);
deleteComicsFromModel(comicsList);
}
@ -1068,13 +1050,14 @@ void ComicModel::deleteComicsFromModel(const QList<QModelIndex> &comicsList)
bool ComicModel::isFavorite(const QModelIndex &index)
{
bool isFavorite;
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
isFavorite = DBHelper::isFavoriteComic(_data[index.row()]->data(Id).toLongLong(), db);
db.close();
QSqlDatabase::removeDatabase(db.connectionName());
isFavorite = DBHelper::isFavoriteComic(_data[index.row()]->data(Id).toLongLong(), db);
connectionName = db.connectionName();
}
QSqlDatabase::removeDatabase(connectionName);
return isFavorite;
}
@ -1082,16 +1065,17 @@ bool ComicModel::isFavorite(const QModelIndex &index)
void ComicModel::updateRating(int rating, QModelIndex mi)
{
ComicDB comic = getComic(mi);
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
//TODO optimize update
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
//TODO optimize update
comic.info.rating = rating;
_data[mi.row()]->setData(ComicModel::Rating, rating);
DBHelper::update(&(comic.info), db);
comic.info.rating = rating;
_data[mi.row()]->setData(ComicModel::Rating, rating);
DBHelper::update(&(comic.info), db);
emit dataChanged(mi, mi);
db.close();
QSqlDatabase::removeDatabase(db.connectionName());
emit dataChanged(mi, mi);
connectionName = db.connectionName();
}
QSqlDatabase::removeDatabase(connectionName);
}

View File

@ -150,8 +150,7 @@ private:
QList<ComicItem *> _data;
QString _databasePath;
QSqlDatabase dbTransaction;
QString _databaseConnection;
bool enableResorting;
Mode mode;

View File

@ -97,13 +97,10 @@ QSqlDatabase DataBaseManagement::loadDatabase(QString path)
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", path + threadId);
db.setDatabaseName(path + "/library.ydb");
if (!db.open()) {
//se devuelve una base de datos vacía e inválida
return QSqlDatabase();
}
QSqlQuery pragma("PRAGMA foreign_keys = ON", db);
//pragma.finish();
//devuelve la base de datos
return db;
}
@ -118,11 +115,8 @@ QSqlDatabase DataBaseManagement::loadDatabaseFromFile(QString filePath)
return QSqlDatabase();
}
{
QSqlQuery pragma("PRAGMA foreign_keys = ON", db);
}
//pragma.finish();
//devuelve la base de datos
QSqlQuery pragma("PRAGMA foreign_keys = ON", db);
return db;
}
@ -324,46 +318,34 @@ bool DataBaseManagement::createV8Tables(QSqlDatabase &database)
void DataBaseManagement::exportComicsInfo(QString source, QString dest)
{
//QSqlDatabase sourceDB = loadDatabase(source);
QSqlDatabase destDB = loadDatabaseFromFile(dest);
//sourceDB.open();
QString connectionName = "";
{
QSqlDatabase destDB = loadDatabaseFromFile(dest);
QSqlQuery attach(destDB);
attach.prepare("ATTACH DATABASE '" + QDir().toNativeSeparators(dest) + "' AS dest;");
//attach.bindValue(":dest",QDir().toNativeSeparators(dest));
attach.exec();
//attach.finish();
QSqlQuery attach2(destDB);
attach2.prepare("ATTACH DATABASE '" + QDir().toNativeSeparators(source) + "' AS source;");
attach2.exec();
//attach2.finish();
//sourceDB.close();
QSqlQuery queryDBInfo(destDB);
queryDBInfo.prepare("CREATE TABLE dest.db_info (version TEXT NOT NULL)");
queryDBInfo.exec();
//queryDBInfo.finish();
/*QSqlQuery queryComicsInfo(sourceDB);
queryComicsInfo.prepare("CREATE TABLE dest.comic_info (id INTEGER PRIMARY KEY, hash TEXT NOT NULL, edited BOOLEAN DEFAULT FALSE, title TEXT, read BOOLEAN)");
queryComicsInfo.exec();*/
QSqlQuery query("INSERT INTO dest.db_info (version) "
"VALUES ('" VERSION "')",
destDB);
//query.finish();
QSqlQuery exportData(destDB);
exportData.prepare("create table dest.comic_info as select " + fields +
" from source.comic_info where source.comic_info.edited = 1");
exportData.exec();
//exportData.finish();
connectionName = destDB.connectionName();
}
//sourceDB.close();
destDB.close();
QSqlDatabase::removeDatabase(dest);
QSqlDatabase::removeDatabase(connectionName);
}
bool DataBaseManagement::importComicsInfo(QString source, QString dest)
@ -374,10 +356,13 @@ bool DataBaseManagement::importComicsInfo(QString source, QString dest)
bool b = false;
QSqlDatabase sourceDB = loadDatabaseFromFile(source);
QSqlDatabase destDB = loadDatabaseFromFile(dest);
QString sourceDBconnection = "";
QString destDBconnection = "";
{
QSqlDatabase sourceDB = loadDatabaseFromFile(source);
QSqlDatabase destDB = loadDatabaseFromFile(dest);
QSqlQuery pragma("PRAGMA synchronous=OFF", destDB);
QSqlQuery newInfo(sourceDB);
@ -538,31 +523,30 @@ bool DataBaseManagement::importComicsInfo(QString source, QString dest)
insert.exec();
}
//update.finish();
//insert.finish();
}
destDB.commit();
QString hash;
foreach (hash, hashes) {
QSqlQuery getComic(destDB);
getComic.prepare("SELECT c.path,ci.coverPage FROM comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) where ci.hash = :hash");
getComic.bindValue(":hash", hash);
getComic.exec();
if (getComic.next()) {
QString basePath = QString(dest).remove("/.yacreaderlibrary/library.ydb");
QString path = basePath + getComic.record().value("path").toString();
int coverPage = getComic.record().value("coverPage").toInt();
ThumbnailCreator tc(path, basePath + "/.yacreaderlibrary/covers/" + hash + ".jpg", coverPage);
tc.create();
}
}
sourceDBconnection = sourceDB.connectionName();
destDBconnection = sourceDB.connectionName();
}
destDB.commit();
QString hash;
foreach (hash, hashes) {
QSqlQuery getComic(destDB);
getComic.prepare("SELECT c.path,ci.coverPage FROM comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) where ci.hash = :hash");
getComic.bindValue(":hash", hash);
getComic.exec();
if (getComic.next()) {
QString basePath = QString(dest).remove("/.yacreaderlibrary/library.ydb");
QString path = basePath + getComic.record().value("path").toString();
int coverPage = getComic.record().value("coverPage").toInt();
ThumbnailCreator tc(path, basePath + "/.yacreaderlibrary/covers/" + hash + ".jpg", coverPage);
tc.create();
}
}
QSqlDatabase::removeDatabase(sourceDBconnection);
QSqlDatabase::removeDatabase(destDBconnection);
destDB.close();
sourceDB.close();
QSqlDatabase::removeDatabase(source);
QSqlDatabase::removeDatabase(dest);
return b;
}
//TODO fix these bindings
@ -666,19 +650,23 @@ void DataBaseManagement::bindDouble(const QString &name, const QSqlRecord &recor
QString DataBaseManagement::checkValidDB(const QString &fullPath)
{
QSqlDatabase db = loadDatabaseFromFile(fullPath);
QString versionString = "";
if (db.isValid() && db.isOpen()) {
QSqlQuery version(db);
version.prepare("SELECT * FROM db_info");
version.exec();
QString connectionName = "";
{
QSqlDatabase db = loadDatabaseFromFile(fullPath);
if (version.next())
versionString = version.record().value("version").toString();
if (db.isValid() && db.isOpen()) {
QSqlQuery version(db);
version.prepare("SELECT * FROM db_info");
version.exec();
if (version.next())
versionString = version.record().value("version").toString();
}
connectionName = db.connectionName();
}
db.close();
QSqlDatabase::removeDatabase(db.connectionName());
QSqlDatabase::removeDatabase(connectionName);
return versionString;
}
@ -731,116 +719,120 @@ bool DataBaseManagement::updateToCurrentVersion(const QString &path)
if (compareVersions(DataBaseManagement::checkValidDB(fullPath), "9.5.0") < 0)
pre9_5 = true;
QSqlDatabase db = loadDatabaseFromFile(fullPath);
QString connectionName = "";
bool returnValue = false;
if (db.isValid() && db.isOpen()) {
QSqlQuery updateVersion(db);
updateVersion.prepare("UPDATE db_info SET "
"version = :version");
updateVersion.bindValue(":version", VERSION);
updateVersion.exec();
if (updateVersion.numRowsAffected() > 0)
returnValue = true;
{
QSqlDatabase db = loadDatabaseFromFile(fullPath);
if (db.isValid() && db.isOpen()) {
QSqlQuery updateVersion(db);
updateVersion.prepare("UPDATE db_info SET "
"version = :version");
updateVersion.bindValue(":version", VERSION);
updateVersion.exec();
if (pre7) //TODO: execute only if previous version was < 7.0
{
//new 7.0 fields
QStringList columnDefs;
columnDefs << "hasBeenOpened BOOLEAN DEFAULT 0"
<< "rating INTEGER DEFAULT 0"
<< "currentPage INTEGER DEFAULT 1"
<< "bookmark1 INTEGER DEFAULT -1"
<< "bookmark2 INTEGER DEFAULT -1"
<< "bookmark3 INTEGER DEFAULT -1"
<< "brightness INTEGER DEFAULT -1"
<< "contrast INTEGER DEFAULT -1"
<< "gamma INTEGER DEFAULT -1";
if (updateVersion.numRowsAffected() > 0)
returnValue = true;
bool successAddingColumns = addColumns("comic_info", columnDefs, db);
returnValue = returnValue && successAddingColumns;
}
//TODO update hasBeenOpened value
if (pre7_1) {
if (pre7) //TODO: execute only if previous version was < 7.0
{
//new 7.0 fields
QStringList columnDefs;
columnDefs << "finished BOOLEAN DEFAULT 0"
<< "completed BOOLEAN DEFAULT 1";
bool successAddingColumns = addColumns("folder", columnDefs, db);
returnValue = returnValue && successAddingColumns;
}
columnDefs << "hasBeenOpened BOOLEAN DEFAULT 0"
<< "rating INTEGER DEFAULT 0"
<< "currentPage INTEGER DEFAULT 1"
<< "bookmark1 INTEGER DEFAULT -1"
<< "bookmark2 INTEGER DEFAULT -1"
<< "bookmark3 INTEGER DEFAULT -1"
<< "brightness INTEGER DEFAULT -1"
<< "contrast INTEGER DEFAULT -1"
<< "gamma INTEGER DEFAULT -1";
{ //comic_info
QStringList columnDefs;
columnDefs << "comicVineID TEXT DEFAULT NULL";
bool successAddingColumns = addColumns("comic_info", columnDefs, db);
returnValue = returnValue && successAddingColumns;
}
}
//TODO update hasBeenOpened value
if (pre8) {
bool successCreatingNewTables = createV8Tables(db);
returnValue = returnValue && successCreatingNewTables;
}
if (pre9_5) {
{ //folder
QStringList columnDefs;
//a full library update is needed after updating the table
columnDefs << "numChildren INTEGER";
columnDefs << "firstChildHash TEXT";
columnDefs << "customImage TEXT";
bool successAddingColumns = addColumns("folder", columnDefs, db);
returnValue = returnValue && successAddingColumns;
}
{ //comic_info
QStringList columnDefs;
columnDefs << "lastTimeOpened INTEGER";
columnDefs << "coverSizeRatio REAL";
columnDefs << "originalCoverSize TEXT";
bool successAddingColumns = addColumns("comic_info", columnDefs, db);
returnValue = returnValue && successAddingColumns;
QSqlQuery queryIndexLastTimeOpened(db);
bool successCreatingIndex = queryIndexLastTimeOpened.exec("CREATE INDEX last_time_opened_index ON comic_info (lastTimeOpened)");
returnValue = returnValue && successCreatingIndex;
}
//update folders info
{
DBHelper::updateChildrenInfo(db);
}
{
QSqlQuery selectQuery(db);
selectQuery.prepare("SELECT id, hash FROM comic_info");
selectQuery.exec();
db.transaction();
QSqlQuery updateCoverInfo(db);
updateCoverInfo.prepare("UPDATE comic_info SET coverSizeRatio = :coverSizeRatio WHERE id = :id");
QImageReader thumbnail;
while (selectQuery.next()) {
thumbnail.setFileName(path % "/covers/" % selectQuery.value(1).toString() % ".jpg");
float coverSizeRatio = static_cast<float>(thumbnail.size().width()) / thumbnail.size().height();
updateCoverInfo.bindValue(":coverSizeRatio", coverSizeRatio);
updateCoverInfo.bindValue(":id", selectQuery.value(0));
updateCoverInfo.exec();
if (pre7_1) {
{
QStringList columnDefs;
columnDefs << "finished BOOLEAN DEFAULT 0"
<< "completed BOOLEAN DEFAULT 1";
bool successAddingColumns = addColumns("folder", columnDefs, db);
returnValue = returnValue && successAddingColumns;
}
db.commit();
{ //comic_info
QStringList columnDefs;
columnDefs << "comicVineID TEXT DEFAULT NULL";
bool successAddingColumns = addColumns("comic_info", columnDefs, db);
returnValue = returnValue && successAddingColumns;
}
}
if (pre8) {
bool successCreatingNewTables = createV8Tables(db);
returnValue = returnValue && successCreatingNewTables;
}
if (pre9_5) {
{ //folder
QStringList columnDefs;
//a full library update is needed after updating the table
columnDefs << "numChildren INTEGER";
columnDefs << "firstChildHash TEXT";
columnDefs << "customImage TEXT";
bool successAddingColumns = addColumns("folder", columnDefs, db);
returnValue = returnValue && successAddingColumns;
}
{ //comic_info
QStringList columnDefs;
columnDefs << "lastTimeOpened INTEGER";
columnDefs << "coverSizeRatio REAL";
columnDefs << "originalCoverSize TEXT";
bool successAddingColumns = addColumns("comic_info", columnDefs, db);
returnValue = returnValue && successAddingColumns;
QSqlQuery queryIndexLastTimeOpened(db);
bool successCreatingIndex = queryIndexLastTimeOpened.exec("CREATE INDEX last_time_opened_index ON comic_info (lastTimeOpened)");
returnValue = returnValue && successCreatingIndex;
}
//update folders info
{
DBHelper::updateChildrenInfo(db);
}
{
QSqlQuery selectQuery(db);
selectQuery.prepare("SELECT id, hash FROM comic_info");
selectQuery.exec();
db.transaction();
QSqlQuery updateCoverInfo(db);
updateCoverInfo.prepare("UPDATE comic_info SET coverSizeRatio = :coverSizeRatio WHERE id = :id");
QImageReader thumbnail;
while (selectQuery.next()) {
thumbnail.setFileName(path % "/covers/" % selectQuery.value(1).toString() % ".jpg");
float coverSizeRatio = static_cast<float>(thumbnail.size().width()) / thumbnail.size().height();
updateCoverInfo.bindValue(":coverSizeRatio", coverSizeRatio);
updateCoverInfo.bindValue(":id", selectQuery.value(0));
updateCoverInfo.exec();
}
db.commit();
}
}
}
connectionName = db.connectionName();
}
db.close();
QSqlDatabase::removeDatabase(db.connectionName());
QSqlDatabase::removeDatabase(connectionName);
return returnValue;
}

View File

@ -291,16 +291,17 @@ void FolderModel::setupModelData(QString path)
//cargar la base de datos
_databasePath = path;
QSqlDatabase db = DataBaseManagement::loadDatabase(path);
//crear la consulta
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(path);
QSqlQuery selectQuery("select * from folder where id <> 1 order by parentId,name", db);
setupModelData(selectQuery, rootItem);
connectionName = db.connectionName();
}
//selectQuery.finish();
db.close();
QSqlDatabase::removeDatabase(db.connectionName());
QSqlDatabase::removeDatabase(connectionName);
endResetModel();
}
@ -407,38 +408,44 @@ void FolderModel::resetFilter()
void FolderModel::updateFolderCompletedStatus(const QModelIndexList &list, bool status)
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
db.transaction();
foreach (QModelIndex mi, list) {
auto item = static_cast<FolderItem *>(mi.internalPointer());
item->setData(FolderModel::Completed, status);
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
db.transaction();
foreach (QModelIndex mi, list) {
auto item = static_cast<FolderItem *>(mi.internalPointer());
item->setData(FolderModel::Completed, status);
Folder f = DBHelper::loadFolder(item->id, db);
f.setCompleted(status);
DBHelper::update(f, db);
Folder f = DBHelper::loadFolder(item->id, db);
f.setCompleted(status);
DBHelper::update(f, db);
}
db.commit();
connectionName = db.connectionName();
}
db.commit();
db.close();
QSqlDatabase::removeDatabase(db.connectionName());
QSqlDatabase::removeDatabase(connectionName);
emit dataChanged(index(list.first().row(), FolderModel::Name), index(list.last().row(), FolderModel::Completed));
}
void FolderModel::updateFolderFinishedStatus(const QModelIndexList &list, bool status)
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
db.transaction();
foreach (QModelIndex mi, list) {
auto item = static_cast<FolderItem *>(mi.internalPointer());
item->setData(FolderModel::Finished, status);
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
db.transaction();
foreach (QModelIndex mi, list) {
auto item = static_cast<FolderItem *>(mi.internalPointer());
item->setData(FolderModel::Finished, status);
Folder f = DBHelper::loadFolder(item->id, db);
f.setFinished(status);
DBHelper::update(f, db);
Folder f = DBHelper::loadFolder(item->id, db);
f.setFinished(status);
DBHelper::update(f, db);
}
db.commit();
connectionName = db.connectionName();
}
db.commit();
db.close();
QSqlDatabase::removeDatabase(db.connectionName());
QSqlDatabase::removeDatabase(connectionName);
emit dataChanged(index(list.first().row(), FolderModel::Name), index(list.last().row(), FolderModel::Completed));
}
@ -451,15 +458,17 @@ QStringList FolderModel::getSubfoldersNames(const QModelIndex &mi)
auto item = static_cast<FolderItem *>(mi.internalPointer());
id = item->id;
}
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
db.transaction();
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
db.transaction();
result = DBHelper::loadSubfoldersNames(id, db);
result = DBHelper::loadSubfoldersNames(id, db);
db.commit();
db.close();
QSqlDatabase::removeDatabase(db.connectionName());
db.commit();
connectionName = db.connectionName();
}
QSqlDatabase::removeDatabase(connectionName);
//TODO sort result))
qSort(result.begin(), result.end(), naturalSortLessThanCI);
@ -481,55 +490,57 @@ void FolderModel::fetchMoreFromDB(const QModelIndex &parent)
endRemoveRows();
}
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
QList<FolderItem *> items;
QList<FolderItem *> nextLevelItems;
QList<FolderItem *> items;
QList<FolderItem *> nextLevelItems;
QSqlQuery selectQuery(db);
selectQuery.prepare("select * from folder where id <> 1 and parentId = :parentId order by parentId,name");
QSqlQuery selectQuery(db);
selectQuery.prepare("select * from folder where id <> 1 and parentId = :parentId order by parentId,name");
items << item;
bool firstLevelUpdated = false;
while (items.size() > 0) {
nextLevelItems.clear();
foreach (FolderItem *item, items) {
QLOG_DEBUG() << "ID " << item->id;
selectQuery.bindValue(":parentId", item->id);
items << item;
bool firstLevelUpdated = false;
while (items.size() > 0) {
nextLevelItems.clear();
foreach (FolderItem *item, items) {
QLOG_DEBUG() << "ID " << item->id;
selectQuery.bindValue(":parentId", item->id);
selectQuery.exec();
selectQuery.exec();
if (!firstLevelUpdated) {
//NO size support
int numResults = 0;
while (selectQuery.next())
numResults++;
if (!firstLevelUpdated) {
//NO size support
int numResults = 0;
while (selectQuery.next())
numResults++;
if (!selectQuery.seek(-1))
selectQuery.exec();
//END no size support
if (!selectQuery.seek(-1))
selectQuery.exec();
//END no size support
beginInsertRows(parent, 0, numResults - 1);
beginInsertRows(parent, 0, numResults - 1);
}
updateFolderModelData(selectQuery, item);
if (!firstLevelUpdated) {
endInsertRows();
firstLevelUpdated = true;
}
nextLevelItems << item->children();
}
updateFolderModelData(selectQuery, item);
if (!firstLevelUpdated) {
endInsertRows();
firstLevelUpdated = true;
}
nextLevelItems << item->children();
items.clear();
items = nextLevelItems;
}
items.clear();
items = nextLevelItems;
connectionName = db.connectionName();
}
QLOG_DEBUG() << "item->childCount()-1" << item->childCount() - 1;
db.close();
QSqlDatabase::removeDatabase(db.connectionName());
QSqlDatabase::removeDatabase(connectionName);
}
QModelIndex FolderModel::addFolderAtParent(const QString &folderName, const QModelIndex &parent)
@ -545,11 +556,14 @@ QModelIndex FolderModel::addFolderAtParent(const QString &folderName, const QMod
newFolder.name = folderName;
newFolder.parentId = parentItem->id;
newFolder.path = parentItem->data(1).toString() + "/" + folderName;
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
newFolder.id = DBHelper::insert(&newFolder, db);
DBHelper::updateChildrenInfo(parentItem->id, db);
QSqlDatabase::removeDatabase(db.connectionName());
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
newFolder.id = DBHelper::insert(&newFolder, db);
DBHelper::updateChildrenInfo(parentItem->id, db);
connectionName = db.connectionName();
}
QSqlDatabase::removeDatabase(connectionName);
int destRow = 0;
@ -585,19 +599,27 @@ void FolderModel::deleteFolder(const QModelIndex &mi)
Folder f;
f.setId(item->id);
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
DBHelper::removeFromDB(&f, db);
DBHelper::updateChildrenInfo(item->parent()->id, db);
QSqlDatabase::removeDatabase(db.connectionName());
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
DBHelper::removeFromDB(&f, db);
DBHelper::updateChildrenInfo(item->parent()->id, db);
connectionName = db.connectionName();
}
QSqlDatabase::removeDatabase(connectionName);
endRemoveRows();
}
void FolderModel::updateFolderChildrenInfo(qulonglong folderId)
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
DBHelper::updateChildrenInfo(folderId, db);
QSqlDatabase::removeDatabase(db.connectionName());
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
DBHelper::updateChildrenInfo(folderId, db);
connectionName = db.connectionName();
}
QSqlDatabase::removeDatabase(connectionName);
}
//PROXY
@ -658,10 +680,10 @@ void FolderModelProxy::setupFilteredModelData()
auto model = static_cast<FolderModel *>(sourceModel());
//cargar la base de datos
QSqlDatabase db = DataBaseManagement::loadDatabase(model->_databasePath);
//crear la consulta
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(model->_databasePath);
QSqlQuery selectQuery(db); //TODO check
if (!includeComics) {
selectQuery.prepare("select * from folder where id <> 1 and upper(name) like upper(:filter) order by parentId,name ");
@ -700,10 +722,9 @@ void FolderModelProxy::setupFilteredModelData()
selectQuery.exec();
setupFilteredModelData(selectQuery, rootItem);
connectionName = db.connectionName();
}
//selectQuery.finish();
db.close();
QSqlDatabase::removeDatabase(db.connectionName());
QSqlDatabase::removeDatabase(connectionName);
endResetModel();
}

View File

@ -372,69 +372,68 @@ void ReadingListModel::setupReadingListsData(QString path)
void ReadingListModel::addNewLabel(const QString &name, YACReader::LabelColors color)
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
qulonglong id = DBHelper::insertLabel(name, color, db);
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
qulonglong id = DBHelper::insertLabel(name, color, db);
int newPos = addLabelIntoList(new LabelItem(QList<QVariant>() << name << YACReader::colorToName(color) << id << color));
beginInsertRows(QModelIndex(), specialLists.count() + 1 + newPos + 1, specialLists.count() + 1 + newPos + 1);
int newPos = addLabelIntoList(new LabelItem(QList<QVariant>() << name << YACReader::colorToName(color) << id << color));
beginInsertRows(QModelIndex(), specialLists.count() + 1 + newPos + 1, specialLists.count() + 1 + newPos + 1);
endInsertRows();
QSqlDatabase::removeDatabase(db.connectionName());
endInsertRows();
connectionName = db.connectionName();
}
QSqlDatabase::removeDatabase(connectionName);
}
void ReadingListModel::addReadingList(const QString &name)
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
beginInsertRows(QModelIndex(), 0, 0); //TODO calculate the right coordinates before inserting
beginInsertRows(QModelIndex(), 0, 0); //TODO calculate the right coordinates before inserting
qulonglong id = DBHelper::insertReadingList(name, db);
ReadingListItem *newItem;
rootItem->appendChild(newItem = new ReadingListItem(QList<QVariant>()
<< name
<< id
<< false
<< true
<< 0));
qulonglong id = DBHelper::insertReadingList(name, db);
ReadingListItem *newItem;
rootItem->appendChild(newItem = new ReadingListItem(QList<QVariant>()
<< name
<< id
<< false
<< true
<< 0));
items.insert(id, newItem);
items.insert(id, newItem);
/*int pos = rootItem->children().indexOf(newItem);
pos += specialLists.count()+1+labels.count()+labels.count()>0?1:0;*/
endInsertRows();
QSqlDatabase::removeDatabase(db.connectionName());
endInsertRows();
connectionName = db.connectionName();
}
QSqlDatabase::removeDatabase(connectionName);
}
void ReadingListModel::addReadingListAt(const QString &name, const QModelIndex &mi)
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
beginInsertRows(mi, 0, 0); //TODO calculate the right coordinates before inserting
beginInsertRows(mi, 0, 0); //TODO calculate the right coordinates before inserting
auto readingListParent = static_cast<ReadingListItem *>(mi.internalPointer());
qulonglong id = DBHelper::insertReadingSubList(name, mi.data(IDRole).toULongLong(), readingListParent->childCount(), db);
ReadingListItem *newItem;
auto readingListParent = static_cast<ReadingListItem *>(mi.internalPointer());
qulonglong id = DBHelper::insertReadingSubList(name, mi.data(IDRole).toULongLong(), readingListParent->childCount(), db);
ReadingListItem *newItem;
readingListParent->appendChild(newItem = new ReadingListItem(QList<QVariant>()
<< name
<< id
<< false
<< true
<< readingListParent->childCount()));
readingListParent->appendChild(newItem = new ReadingListItem(QList<QVariant>()
<< name
<< id
<< false
<< true
<< readingListParent->childCount()));
items.insert(id, newItem);
/*int pos = readingListParent->children().indexOf(newItem);
pos += specialLists.count()+1+labels.count()+labels.count()>0?1:0;*/
endInsertRows();
QSqlDatabase::removeDatabase(db.connectionName());
items.insert(id, newItem);
endInsertRows();
connectionName = db.connectionName();
}
QSqlDatabase::removeDatabase(connectionName);
}
bool ReadingListModel::isEditable(const QModelIndex &mi)
@ -477,29 +476,31 @@ void ReadingListModel::rename(const QModelIndex &mi, const QString &name)
{
if (!isEditable(mi))
return;
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
auto item = static_cast<ListItem *>(mi.internalPointer());
auto item = static_cast<ListItem *>(mi.internalPointer());
if (typeid(*item) == typeid(ReadingListItem)) {
auto rli = static_cast<ReadingListItem *>(item);
rli->setName(name);
DBHelper::renameList(item->getId(), name, db);
if (typeid(*item) == typeid(ReadingListItem)) {
auto rli = static_cast<ReadingListItem *>(item);
rli->setName(name);
DBHelper::renameList(item->getId(), name, db);
if (rli->parent->getId() != 0) {
//TODO
//move row depending on the name
} else
if (rli->parent->getId() != 0) {
//TODO
//move row depending on the name
} else
emit dataChanged(index(mi.row(), 0), index(mi.row(), 0));
} else if (typeid(*item) == typeid(LabelItem)) {
auto li = static_cast<LabelItem *>(item);
li->setName(name);
DBHelper::renameLabel(item->getId(), name, db);
emit dataChanged(index(mi.row(), 0), index(mi.row(), 0));
} else if (typeid(*item) == typeid(LabelItem)) {
auto li = static_cast<LabelItem *>(item);
li->setName(name);
DBHelper::renameLabel(item->getId(), name, db);
emit dataChanged(index(mi.row(), 0), index(mi.row(), 0));
}
connectionName = db.connectionName();
}
QSqlDatabase::removeDatabase(db.connectionName());
QSqlDatabase::removeDatabase(connectionName);
}
void ReadingListModel::deleteItem(const QModelIndex &mi)
@ -507,28 +508,30 @@ void ReadingListModel::deleteItem(const QModelIndex &mi)
if (isEditable(mi)) {
QLOG_DEBUG() << "parent row :" << mi.parent().data() << "-" << mi.row();
beginRemoveRows(mi.parent(), mi.row(), mi.row());
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
auto item = static_cast<ListItem *>(mi.internalPointer());
auto item = static_cast<ListItem *>(mi.internalPointer());
if (typeid(*item) == typeid(ReadingListItem)) {
auto rli = static_cast<ReadingListItem *>(item);
QLOG_DEBUG() << "num children : " << rli->parent->childCount();
rli->parent->removeChild(rli);
QLOG_DEBUG() << "num children : " << rli->parent->childCount();
DBHelper::removeListFromDB(item->getId(), db);
if (rli->parent->getId() != 0) {
reorderingChildren(rli->parent->children());
if (typeid(*item) == typeid(ReadingListItem)) {
auto rli = static_cast<ReadingListItem *>(item);
QLOG_DEBUG() << "num children : " << rli->parent->childCount();
rli->parent->removeChild(rli);
QLOG_DEBUG() << "num children : " << rli->parent->childCount();
DBHelper::removeListFromDB(item->getId(), db);
if (rli->parent->getId() != 0) {
reorderingChildren(rli->parent->children());
}
QLOG_DEBUG() << "num children : " << rli->parent->childCount();
} else if (typeid(*item) == typeid(LabelItem)) {
auto li = static_cast<LabelItem *>(item);
labels.removeOne(li);
DBHelper::removeLabelFromDB(item->getId(), db);
}
QLOG_DEBUG() << "num children : " << rli->parent->childCount();
} else if (typeid(*item) == typeid(LabelItem)) {
auto li = static_cast<LabelItem *>(item);
labels.removeOne(li);
DBHelper::removeLabelFromDB(item->getId(), db);
connectionName = db.connectionName();
}
QSqlDatabase::removeDatabase(db.connectionName());
QSqlDatabase::removeDatabase(connectionName);
endRemoveRows();
}
@ -705,10 +708,13 @@ void ReadingListModel::reorderingChildren(QList<ReadingListItem *> children)
item->setOrdering(i++);
childrenIds << item->getId();
}
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
DBHelper::reasignOrderToSublists(childrenIds, db);
QSqlDatabase::removeDatabase(db.connectionName());
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath);
DBHelper::reasignOrderToSublists(childrenIds, db);
connectionName = db.connectionName();
}
QSqlDatabase::removeDatabase(connectionName);
}
bool ReadingListModel::rowIsSpecialList(int row, const QModelIndex &parent) const