#include "db_helper.h" #include #include #include #include #include #include #include #include #include #include #include #include "library_item.h" #include "comic_db.h" #include "data_base_management.h" #include "folder.h" #include "qnaturalsorting.h" //server //TODO optimizar, evitar que se tenga que leer en cada petición el archivo //conservar un QDateTime stático que compruebe si libraries.yacr ha sido modificado //libraries debe ser una variable estática static QDateTime lastModified; static QMap libraries; QMap DBHelper::getLibraries() { QFileInfo fi(QCoreApplication::applicationDirPath()+"/libraries.yacr"); if(fi.lastModified() == lastModified) return libraries; lastModified = fi.lastModified(); libraries.clear(); QFile f(QCoreApplication::applicationDirPath()+"/libraries.yacr"); f.open(QIODevice::ReadOnly); QTextStream txtS(&f); QString content = txtS.readAll(); QStringList lines = content.split('\n'); QString line,name; int i=0; foreach(line,lines) { if((i%2)==0) { name = line; } else { //sólo se agregan las bibliotecas realmente disponibles QSqlDatabase db = DataBaseManagement::loadDatabase(line.trimmed()+"/.yacreaderlibrary"); if(db.isValid()) libraries.insert(name.trimmed(),line.trimmed()); db.close(); } i++; } f.close(); return libraries; } QList DBHelper::getFolderContentFromLibrary(const QString & libraryName, qulonglong folderId) { QString libraryPath = DBHelper::getLibraries().value(libraryName); QSqlDatabase db = DataBaseManagement::loadDatabase(libraryPath+"/.yacreaderlibrary"); QList list = DBHelper::getFoldersFromParent(folderId,db,false); db.close(); QSqlDatabase::removeDatabase(libraryPath); return list; } QList DBHelper::getFolderComicsFromLibrary(const QString & libraryName, qulonglong folderId) { QString libraryPath = DBHelper::getLibraries().value(libraryName); QSqlDatabase db = DataBaseManagement::loadDatabase(libraryPath+"/.yacreaderlibrary"); QList list = DBHelper::getComicsFromParent(folderId,db,false); db.close(); QSqlDatabase::removeDatabase(libraryPath); return list; } qulonglong DBHelper::getParentFromComicFolderId(const QString & libraryName, qulonglong id) { QString libraryPath = DBHelper::getLibraries().value(libraryName); QSqlDatabase db = DataBaseManagement::loadDatabase(libraryPath+"/.yacreaderlibrary"); Folder f = DBHelper::loadFolder(id,db); db.close(); QSqlDatabase::removeDatabase(libraryPath); return f.parentId; } ComicDB DBHelper::getComicInfo(const QString & libraryName, qulonglong id) { QString libraryPath = DBHelper::getLibraries().value(libraryName); QSqlDatabase db = DataBaseManagement::loadDatabase(libraryPath+"/.yacreaderlibrary"); ComicDB comic = DBHelper::loadComic(id,db); db.close(); QSqlDatabase::removeDatabase(libraryPath); return comic; } QList DBHelper::getSiblings(const QString & libraryName, qulonglong parentId) { QString libraryPath = DBHelper::getLibraries().value(libraryName); QSqlDatabase db = DataBaseManagement::loadDatabase(libraryPath+"/.yacreaderlibrary"); QList comics = DBHelper::getSortedComicsFromParent(parentId,db); db.close(); QSqlDatabase::removeDatabase(libraryPath); return comics; } QString DBHelper::getFolderName(const QString & libraryName, qulonglong id) { QString libraryPath = DBHelper::getLibraries().value(libraryName); QSqlDatabase db = DataBaseManagement::loadDatabase(libraryPath+"/.yacreaderlibrary"); QString name=""; { QSqlQuery selectQuery(db); //TODO check selectQuery.prepare("SELECT name FROM folder WHERE id = :id"); selectQuery.bindValue(":id", id); selectQuery.exec(); if(selectQuery.next()) { QSqlRecord record = selectQuery.record(); name = record.value(0).toString(); } } db.close(); QSqlDatabase::removeDatabase(libraryPath); return name; } QList DBHelper::getLibrariesNames() { QStringList names = getLibraries().keys(); qSort(names.begin(),names.end(),naturalSortLessThanCI); return names; } QString DBHelper::getLibraryName(int id) { QStringList names = getLibrariesNames(); if(names.isEmpty()) return ""; if(id>=0 && idisDir()) DBHelper::removeFromDB(dynamic_cast(item),db); else DBHelper::removeFromDB(dynamic_cast(item),db); } void DBHelper::removeFromDB(Folder * folder, QSqlDatabase & db) { QSqlQuery query(db); query.prepare("DELETE FROM folder WHERE id = :id"); query.bindValue(":id", folder->id); query.exec(); } void DBHelper::removeFromDB(ComicDB * comic, QSqlDatabase & db) { QSqlQuery query(db); query.prepare("DELETE FROM comic WHERE id = :id"); query.bindValue(":id", comic->id); query.exec(); } //updates void DBHelper::update(ComicDB * comic, QSqlDatabase & db) { //do nothing } void DBHelper::update(const QString & libraryName, ComicInfo & comicInfo) { QString libraryPath = DBHelper::getLibraries().value(libraryName); QSqlDatabase db = DataBaseManagement::loadDatabase(libraryPath+"/.yacreaderlibrary"); DBHelper::update(&comicInfo,db); db.close(); QSqlDatabase::removeDatabase(libraryPath); } #include void DBHelper::update(ComicInfo * comicInfo, QSqlDatabase & db) { QSqlQuery updateComicInfo(db); updateComicInfo.prepare("UPDATE comic_info SET " "title = :title," "coverPage = :coverPage," "numPages = :numPages," "number = :number," "isBis = :isBis," "count = :count," "volume = :volume," "storyArc = :storyArc," "arcNumber = :arcNumber," "arcCount = :arcCount," "genere = :genere," "writer = :writer," "penciller = :penciller," "inker = :inker," "colorist = :colorist," "letterer = :letterer," "coverArtist = :coverArtist," "date = :date," "publisher = :publisher," "format = :format," "color = :color," "ageRating = :ageRating," "synopsis = :synopsis," "characters = :characters," "notes = :notes," "read = :read," "edited = :edited," //new 7.0 fields "hasBeenOpened = :hasBeenOpened," "currentPage = :currentPage," "bookmark1 = :bookmark1," "bookmark2 = :bookmark2," "bookmark3 = :bookmark3," "brightness = :brightness," "contrast = :contrast, " "gamma = :gamma," "rating = :rating" //-- " WHERE id = :id "); bindField(":title",comicInfo->title,updateComicInfo); bindField(":coverPage",comicInfo->coverPage,updateComicInfo); bindField(":numPages",comicInfo->numPages,updateComicInfo); bindField(":number",comicInfo->number,updateComicInfo); bindField(":isBis",comicInfo->isBis,updateComicInfo); bindField(":count",comicInfo->count,updateComicInfo); bindField(":volume",comicInfo->volume,updateComicInfo); bindField(":storyArc",comicInfo->storyArc,updateComicInfo); bindField(":arcNumber",comicInfo->arcNumber,updateComicInfo); bindField(":arcCount",comicInfo->arcCount,updateComicInfo); bindField(":genere",comicInfo->genere,updateComicInfo); bindField(":writer",comicInfo->writer,updateComicInfo); bindField(":penciller",comicInfo->penciller,updateComicInfo); bindField(":inker",comicInfo->inker,updateComicInfo); bindField(":colorist",comicInfo->colorist,updateComicInfo); bindField(":letterer",comicInfo->letterer,updateComicInfo); bindField(":coverArtist",comicInfo->coverArtist,updateComicInfo); bindField(":date",comicInfo->date,updateComicInfo); bindField(":publisher",comicInfo->publisher,updateComicInfo); bindField(":format",comicInfo->format,updateComicInfo); bindField(":color",comicInfo->color,updateComicInfo); bindField(":ageRating",comicInfo->ageRating,updateComicInfo); bindField(":synopsis",comicInfo->synopsis,updateComicInfo); bindField(":characters",comicInfo->characters,updateComicInfo); bindField(":notes",comicInfo->notes,updateComicInfo); updateComicInfo.bindValue(":read", comicInfo->read?1:0); updateComicInfo.bindValue(":id", comicInfo->id); updateComicInfo.bindValue(":edited", comicInfo->edited?1:0); updateComicInfo.bindValue(":hasBeenOpened", comicInfo->hasBeenOpened?1:0); updateComicInfo.bindValue(":currentPage", comicInfo->currentPage); updateComicInfo.bindValue(":bookmark1", comicInfo->bookmark1); updateComicInfo.bindValue(":bookmark2", comicInfo->bookmark2); updateComicInfo.bindValue(":bookmark3", comicInfo->bookmark3); updateComicInfo.bindValue(":brightness", comicInfo->brightness); updateComicInfo.bindValue(":contrast", comicInfo->contrast); updateComicInfo.bindValue(":gamma", comicInfo->gamma); updateComicInfo.bindValue(":rating", comicInfo->rating); if(!updateComicInfo.exec()) QMessageBox::critical(0,"",updateComicInfo.lastError().text()); } void DBHelper::updateRead(ComicInfo * comicInfo, QSqlDatabase & db) { QSqlQuery findComicInfo(db); findComicInfo.prepare("UPDATE comic_info SET " "read = :read" " WHERE id = :id "); findComicInfo.bindValue(":read", comicInfo->read?1:0); findComicInfo.bindValue(":id", comicInfo->id); findComicInfo.exec(); } //inserts qulonglong DBHelper::insert(Folder * folder, QSqlDatabase & db) { QSqlQuery query(db); query.prepare("INSERT INTO folder (parentId, name, path) " "VALUES (:parentId, :name, :path)"); query.bindValue(":parentId", folder->parentId); query.bindValue(":name", folder->name); query.bindValue(":path", folder->path); query.exec(); return query.lastInsertId().toULongLong(); } qulonglong DBHelper::insert(ComicDB * comic, QSqlDatabase & db) { if(!comic->info.existOnDb) { QSqlQuery comicInfoInsert(db); comicInfoInsert.prepare("INSERT INTO comic_info (hash,numPages) " "VALUES (:hash,:numPages)"); comicInfoInsert.bindValue(":hash", comic->info.hash); comicInfoInsert.bindValue(":numPages", *(comic->info.numPages)); comicInfoInsert.exec(); comic->info.id =comicInfoInsert.lastInsertId().toULongLong(); comic->_hasCover = false; } else comic->_hasCover = true; QSqlQuery query(db); query.prepare("INSERT INTO comic (parentId, comicInfoId, fileName, path) " "VALUES (:parentId,:comicInfoId,:name, :path)"); query.bindValue(":parentId", comic->parentId); query.bindValue(":comicInfoId", comic->info.id); query.bindValue(":name", comic->name); query.bindValue(":path", comic->path); query.exec(); return query.lastInsertId().toULongLong(); } //queries QList DBHelper::getFoldersFromParent(qulonglong parentId, QSqlDatabase & db, bool sort) { QList list; QSqlQuery selectQuery(db); //TODO check selectQuery.prepare("SELECT * FROM folder WHERE parentId = :parentId and id <> 1"); selectQuery.bindValue(":parentId", parentId); selectQuery.exec(); Folder * currentItem; while (selectQuery.next()) { QList data; QSqlRecord record = selectQuery.record(); for(int i=0;i(list.back()); QString nameLast = last->name; QString nameCurrent = currentItem->name; QList::iterator i; i = list.end(); i--; while ((0 > (lessThan = nameCurrent.localeAwareCompare(nameLast))) && i != list.begin()) { i--; nameLast = (*i)->name; } if(lessThan>0) //si se ha encontrado un elemento menor que current, se inserta justo después list.insert(++i,currentItem); else list.insert(i,currentItem); } } return list; } QList DBHelper::getSortedComicsFromParent(qulonglong parentId, QSqlDatabase & db) { QList list; QSqlQuery selectQuery(db); selectQuery.prepare("select c.id,c.parentId,c.fileName,c.path,ci.hash from comic c inner join comic_info ci on (c.comicInfoId = ci.id) where c.parentId = :parentId"); selectQuery.bindValue(":parentId", parentId); selectQuery.exec(); ComicDB currentItem; while (selectQuery.next()) { QList data; QSqlRecord record = selectQuery.record(); for(int i=0;i(list.back()); QString nameLast = last.name; QString nameCurrent = currentItem.name; QList::iterator i; i = list.end(); i--; while ((0 > (lessThan = nameCurrent.localeAwareCompare(nameLast))) && i != list.begin()) //se usa la misma ordenación que en QDir { i--; nameLast = (*i).name; } if(lessThan>0) //si se ha encontrado un elemento menor que current, se inserta justo después list.insert(++i,currentItem); else list.insert(i,currentItem); } } //selectQuery.finish(); return list; } QList DBHelper::getComicsFromParent(qulonglong parentId, QSqlDatabase & db, bool sort) { QList list; QSqlQuery selectQuery(db); selectQuery.prepare("select c.id,c.parentId,c.fileName,c.path,ci.hash from comic c inner join comic_info ci on (c.comicInfoId = ci.id) where c.parentId = :parentId"); selectQuery.bindValue(":parentId", parentId); selectQuery.exec(); ComicDB * currentItem; while (selectQuery.next()) { QList data; QSqlRecord record = selectQuery.record(); for(int i=0;iid = record.value("id").toULongLong(); currentItem->parentId = record.value(1).toULongLong(); currentItem->name = record.value(2).toString(); currentItem->path = record.value(3).toString(); currentItem->info = DBHelper::loadComicInfo(record.value(4).toString(),db); int lessThan = 0; if(list.isEmpty() || !sort) list.append(currentItem); else { ComicDB * last = static_cast(list.back()); QString nameLast = last->name; QString nameCurrent = currentItem->name; QList::iterator i; i = list.end(); i--; while ((0 > (lessThan = nameCurrent.localeAwareCompare(nameLast))) && i != list.begin()) //se usa la misma ordenación que en QDir { i--; nameLast = (*i)->name; } if(lessThan>0) //si se ha encontrado un elemento menor que current, se inserta justo después list.insert(++i,currentItem); else list.insert(i,currentItem); } } //selectQuery.finish(); return list; } //loads Folder DBHelper::loadFolder(qulonglong id, QSqlDatabase & db) { Folder folder; QSqlQuery query(db); query.prepare("SELECT * FROM folder WHERE id = :id"); query.bindValue(":id",id); query.exec(); folder.id = id; folder.parentId = 0; if(query.next()) { QSqlRecord record = query.record(); folder.parentId = record.value("parentId").toULongLong(); folder.name = record.value("name").toString(); folder.path = record.value("path").toString(); } return folder; } ComicDB DBHelper::loadComic(qulonglong id, QSqlDatabase & db) { ComicDB comic; QSqlQuery selectQuery(db); selectQuery.prepare("select c.id,c.parentId,c.fileName,c.path,ci.hash from comic c inner join comic_info ci on (c.comicInfoId = ci.id) where c.id = :id"); selectQuery.bindValue(":id", id); selectQuery.exec(); comic.id = id; if(selectQuery.next()) { QSqlRecord record = selectQuery.record(); //id = record.value("id").toULongLong(); comic.parentId = record.value("parentId").toULongLong(); comic.name = record.value("name").toString(); comic.path = record.value("path").toString(); comic.info = DBHelper::loadComicInfo(record.value("hash").toString(),db); } return comic; } ComicDB DBHelper::loadComic(qulonglong cparentId, QString cname, QString cpath, QString chash, QSqlDatabase & database) { ComicDB comic; comic.parentId = cparentId; comic.name = cname; comic.path = cpath; comic.info = DBHelper::loadComicInfo(chash,database); if(!comic.info.existOnDb) { comic.info.hash = chash; comic.info.coverPage = new int(1); comic._hasCover = false; } else comic._hasCover = true; return comic; } ComicInfo DBHelper::loadComicInfo(QString hash, QSqlDatabase & db) { ComicInfo comicInfo; QSqlQuery findComicInfo(db); findComicInfo.prepare("SELECT * FROM comic_info WHERE hash = :hash"); findComicInfo.bindValue(":hash", hash); findComicInfo.exec(); if(findComicInfo.next()) { comicInfo.hash = hash; QSqlRecord record = findComicInfo.record(); comicInfo.hash = hash; comicInfo.id = record.value("id").toULongLong(); comicInfo.read = record.value("read").toBool(); comicInfo.edited = record.value("edited").toBool(); //new 7.0 fields comicInfo.hasBeenOpened = record.value("hasBeenOpened").toBool(); comicInfo.currentPage = record.value("currentPage").toInt(); comicInfo.bookmark1 = record.value("bookmark1").toInt(); comicInfo.bookmark2 = record.value("bookmark2").toInt(); comicInfo.bookmark3 = record.value("bookmark3").toInt(); comicInfo.brightness = record.value("brightness").toInt(); comicInfo.contrast = record.value("contrast").toInt(); comicInfo.gamma = record.value("gamma").toInt(); //-- setField("title",comicInfo.title,record); setField("numPages",comicInfo.numPages,record); setField("coverPage",comicInfo.coverPage,record); setField("number",comicInfo.number,record); setField("isBis",comicInfo.isBis,record); setField("count",comicInfo.count,record); setField("volume",comicInfo.volume,record); setField("storyArc",comicInfo.storyArc,record); setField("arcNumber",comicInfo.arcNumber,record); setField("arcCount",comicInfo.arcCount,record); setField("genere",comicInfo.genere,record); setField("writer",comicInfo.writer,record); setField("penciller",comicInfo.penciller,record); setField("inker",comicInfo.inker,record); setField("colorist",comicInfo.colorist,record); setField("letterer",comicInfo.letterer,record); setField("coverArtist",comicInfo.coverArtist,record); setField("date",comicInfo.date,record); setField("publisher",comicInfo.publisher,record); setField("format",comicInfo.format,record); setField("color",comicInfo.color,record); setField("ageRating",comicInfo.ageRating,record); setField("synopsis",comicInfo.synopsis,record); setField("characters",comicInfo.characters,record); setField("notes",comicInfo.notes,record); comicInfo.existOnDb = true; } else comicInfo.existOnDb = false; return comicInfo; } void DBHelper::setField(const QString & name, QString * & field, QSqlRecord & record) { if(!record.value(name).isNull()) { field = new QString(); *field = record.value(name).toString(); } } void DBHelper::setField(const QString & name, int * & field, QSqlRecord & record) { if(!record.value(name).isNull()) { field = new int; *field = record.value(name).toInt(); } } void DBHelper::setField(const QString & name, bool * & field, QSqlRecord & record) { if(!record.value(name).isNull()) { field = new bool; *field = record.value(name).toBool(); } } void DBHelper::bindField(const QString & name, QString * field, QSqlQuery & query) { if(field != NULL) { query.bindValue(name,*field); } } void DBHelper::bindField(const QString & name, int * field, QSqlQuery & query) { if(field != NULL) { query.bindValue(name,*field); } } void DBHelper::bindField(const QString & name, bool * field, QSqlQuery & query) { if(field != NULL) { query.bindValue(name,*field); } }