Enable SQLiteDB backend.

Multiple fixed and finished the implementation of the SQLite backend.
Try to load the database before trying to attempt a rescan.
Delete the metadala list for backends that allocate them on demand.
Moved some generic functions to the databse class.
Renamed utils header to avoid rare QtCreator bug.
This commit is contained in:
codestation
2014-02-05 23:30:12 -04:30
parent f722c4579b
commit 99d216d474
18 changed files with 747 additions and 399 deletions

View File

@@ -20,7 +20,7 @@ SOURCES += src/main.cpp \
src/capability.cpp \
src/cmaobject.cpp \
src/cmarootobject.cpp \
src/utils.cpp \
src/cmautils.cpp \
src/mainwidget.cpp \
src/singleapplication.cpp \
src/sforeader.cpp \
@@ -34,20 +34,20 @@ SOURCES += src/main.cpp \
src/sqlitedb.cpp \
src/httpdownloader.cpp \
src/qlistdb.cpp \
src/database.cpp \
# forms
src/forms/backupitem.cpp \
src/forms/backupmanagerform.cpp \
src/forms/configwidget.cpp \
src/forms/confirmdialog.cpp \
src/forms/pinform.cpp \
src/forms/progressform.cpp \
src/database.cpp
src/forms/progressform.cpp
HEADERS += \
src/capability.h \
src/cmaobject.h \
src/cmarootobject.h \
src/utils.h \
src/cmautils.h \
src/mainwidget.h \
src/singleapplication.h \
src/sforeader.h \
@@ -61,14 +61,14 @@ HEADERS += \
src/sqlitedb.h \
src/httpdownloader.h \
src/qlistdb.h \
src/database.h \
# forms
src/forms/backupitem.h \
src/forms/backupmanagerform.h \
src/forms/configwidget.h \
src/forms/confirmdialog.h \
src/forms/pinform.h \
src/forms/progressform.h \
src/database.h
src/forms/progressform.h
FORMS += \
src/forms/configwidget.ui \

View File

@@ -17,7 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "utils.h"
#include "cmautils.h"
#include "avdecoder.h"
#include "database.h"

View File

@@ -19,7 +19,7 @@
#include "clientmanager.h"
#include "cmaclient.h"
#include "utils.h"
#include "cmautils.h"
#include "forms/progressform.h"
#include <QSettings>
@@ -122,13 +122,12 @@ void ClientManager::start()
void ClientManager::refreshDatabase()
{
bool prepared;
if(!m_db->reload(prepared)) {
if(prepared) {
emit messageSent(tr("Cannot refresh the database while is in use"));
} else {
emit messageSent(tr("No PS Vita system has been registered"));
if(m_db->load()) {
return;
}
if(!m_db->rescan()) {
emit messageSent(tr("No PS Vita system has been registered"));
} else {
progress.showDelayed(1000);
}

View File

@@ -21,7 +21,7 @@
#include "capability.h"
#include "avdecoder.h"
#include "cmaevent.h"
#include "utils.h"
#include "cmautils.h"
#include <QApplication>
#include <QDateTime>

View File

@@ -18,7 +18,7 @@
*/
#include "cmaevent.h"
#include "utils.h"
#include "cmautils.h"
#include <QDateTime>
#include <QDebug>
@@ -179,7 +179,8 @@ quint16 CmaEvent::processAllObjects(metadata_t &parent_metadata, quint32 handle)
m_db->deleteEntry(ohfi);
}
QDir dir(m_db->getAbsolutePath(parent_metadata.ohfi));
QString fullpath = m_db->getAbsolutePath(parent_metadata.ohfi);
QDir dir(fullpath);
if(dataType & Folder) {
if(!dir.mkpath(name)) {
@@ -205,12 +206,10 @@ quint16 CmaEvent::processAllObjects(metadata_t &parent_metadata, quint32 handle)
}
}
QFileInfo info(dir, name);
int new_ohfi = m_db->insertObjectEntry(info.absoluteFilePath(), parent_metadata.ohfi);
int new_ohfi = m_db->insertObjectEntry(fullpath, name, parent_metadata.ohfi);
qDebug("Added object %s with OHFI %i to database", name, new_ohfi);
free(name);
qDebug() << QString("Added object %1 with OHFI %2 to database").arg(info.absoluteFilePath(), QString::number(new_ohfi));
if(dataType & Folder) {
metadata_t folder_metadata;
m_db->getObjectMetadata(new_ohfi, folder_metadata);
@@ -389,6 +388,7 @@ void CmaEvent::vitaEventSendObjectMetadata(vita_event_t *event, int eventId)
} else {
VitaMTP_ReportResult(device, eventId, PTP_RC_OK);
}
m_db->freeMetadata(meta);
}
void CmaEvent::vitaEventSendObject(vita_event_t *event, int eventId)
@@ -470,6 +470,8 @@ void CmaEvent::vitaEventSendObject(vita_event_t *event, int eventId)
} while(metadata && metadata->ohfiParent >= OHFI_BASE_VALUE); // get everything under this "folder"
m_db->freeMetadata(start);
VitaMTP_ReportResultWithParam(device, eventId, PTP_RC_OK, handle);
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Invalid_Data); // TODO: Send thumbnail
@@ -562,13 +564,14 @@ void CmaEvent::vitaEventSendObjectStatus(vita_event_t *event, int eventId)
QMutexLocker locker(&m_db->mutex);
qDebug("Checking for path %s under ohfi %i", objectstatus.title, objectstatus.ohfiRoot);
int ohfi = m_db->getPathId(objectstatus.title, objectstatus.ohfiRoot);
if(ohfi == 0) { // not in database, don't return metadata
qDebug("Object %s not in database (OHFI: %i). Sending OK response for non-existence", objectstatus.title, objectstatus.ohfiRoot);
VitaMTP_ReportResult(device, eventId, PTP_RC_OK);
} else {
metadata_t metadata;
metadata_t metadata = metadata_t();
m_db->getObjectMetadata(ohfi, metadata);
metadata.next_metadata = NULL;
qDebug("Sending metadata for OHFI %d", ohfi);
@@ -780,7 +783,7 @@ void CmaEvent::vitaEventOperateObject(vita_event_t *event, int eventId)
qWarning("Unable to create temporary folder: %s", operateobject.title);
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Failed_Operate_Object);
} else {
int new_ohfi = m_db->insertObjectEntry(QDir(dir).absoluteFilePath(operateobject.title), operateobject.ohfi);
int new_ohfi = m_db->insertObjectEntry(fullpath, operateobject.title, operateobject.ohfi);
qDebug("Created folder %s with OHFI %d", operateobject.title, new_ohfi);
VitaMTP_ReportResultWithParam(device, eventId, PTP_RC_OK, new_ohfi);
}
@@ -794,7 +797,7 @@ void CmaEvent::vitaEventOperateObject(vita_event_t *event, int eventId)
qWarning("Unable to create temporary file: %s", operateobject.title);
VitaMTP_ReportResult(device, eventId, PTP_RC_VITA_Failed_Operate_Object);
} else {
int new_ohfi = m_db->insertObjectEntry(file.fileName(), operateobject.ohfi);
int new_ohfi = m_db->insertObjectEntry(fullpath, operateobject.title, operateobject.ohfi);
//qDebug("Created file %s with OHFI %d under parent %s", newobj->metadata.path, new_ohfi, root->metadata.path);
VitaMTP_ReportResultWithParam(device, eventId, PTP_RC_OK, new_ohfi);
}

View File

@@ -21,7 +21,7 @@
#include "sforeader.h"
#include "avdecoder.h"
#include "database.h"
#include "utils.h"
#include "cmautils.h"
#include <QDir>
#include <QDateTime>

View File

@@ -17,7 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "utils.h"
#include "cmautils.h"
#include "avdecoder.h"
#include <QBuffer>
@@ -162,7 +162,7 @@ QByteArray getThumbnail(const QString &path, DataType type, metadata_t *metadata
return data;
}
QString readable_size(quint64 size, bool use_gib)
QString readable_size(qint64 size, bool use_gib)
{
QStringList list;
list << "KiB" << "MiB";

View File

@@ -46,7 +46,7 @@ public:
#endif
bool removeRecursively(const QString &path);
QString readable_size(quint64 size, bool use_gib = false);
QString readable_size(qint64 size, bool use_gib = false);
bool getDiskSpace(const QString &dir, quint64 *free, quint64 *total);
QByteArray getThumbnail(const QString &path, DataType type, metadata_t *metadata);

View File

@@ -2,6 +2,7 @@
#include "avdecoder.h"
#include <QSettings>
#include <QThread>
const file_type audio_list[] = {
{"mp3", FILE_FORMAT_MP3, CODEC_TYPE_MP3},
@@ -28,6 +29,33 @@ Database::Database(QObject *parent) :
mutex(QMutex::Recursive)
{
}
#include <QDebug>
void Database::process()
{
qDebug("Starting database_thread: 0x%016" PRIxPTR, (uintptr_t)QThread::currentThreadId());
clear();
cancel_operation = false;
int count = create();
cancel_operation = false;
qDebug("Added %i entries to the database", count);
if(count < 0) {
clear();
}
emit updated(count);
mutex.unlock();
}
void Database::cancelOperation()
{
QMutexLocker locker(&cancel);
cancel_operation = true;
}
bool Database::continueOperation()
{
QMutexLocker locker(&cancel);
return !cancel_operation;
}
int Database::checkFileType(const QString path, int ohfi_root)
{

View File

@@ -43,6 +43,11 @@ class Database : public QObject
Q_OBJECT
public:
explicit Database(QObject *parent = 0);
virtual bool load() = 0;
virtual bool rescan() = 0;
virtual void setUUID(const QString &uuid) = 0;
virtual int childObjectCount(int parent_ohfi) = 0;
virtual bool deleteEntry(int ohfi, int root_ohfi = 0) = 0;
virtual QString getAbsolutePath(int ohfi) = 0;
@@ -51,14 +56,12 @@ public:
virtual int getObjectMetadatas(int parent_ohfi, metadata_t **metadata, int index = 0, int max_number = 0) = 0;
virtual qint64 getObjectSize(int ohfi) = 0;
virtual int getPathId(const char *name, int ohfi) = 0;
virtual int insertObjectEntry(const QString &path, int parent_ohfi) = 0;
virtual int insertObjectEntry(const QString &path, const QString &name, int parent_ohfi) = 0;
virtual bool renameObject(int ohfi, const QString &name) = 0;
virtual void setObjectSize(int ohfi, qint64 size) = 0;
virtual int getParentId(int ohfi) = 0;
virtual int getRootId(int ohfi) = 0;
virtual bool reload(bool &prepared) = 0;
virtual void setUUID(const QString uuid) = 0;
virtual void freeMetadata(metadata_t *metadata) = 0;
static int checkFileType(const QString path, int ohfi_root);
static void loadMusicMetadata(const QString &path, metadata_t &metadata);
@@ -66,6 +69,29 @@ public:
static void loadVideoMetadata(const QString &path, metadata_t &metadata);
QMutex mutex;
protected:
bool continueOperation();
private:
virtual void clear() = 0;
virtual int create() = 0;
// control variables
QMutex cancel;
bool cancel_operation;
signals:
void fileAdded(QString);
void directoryAdded(QString);
void updated(int);
protected slots:
void process();
public slots:
void cancelOperation();
};
#endif // DATABASE_H

View File

@@ -19,7 +19,7 @@
#include "backupitem.h"
#include "ui_backupitem.h"
#include "utils.h"
#include "cmautils.h"
#include "dds.h"
#include <QDesktopServices>

View File

@@ -22,7 +22,7 @@
#include "cmaobject.h"
#include "sforeader.h"
#include "confirmdialog.h"
#include "utils.h"
#include "cmautils.h"
#include "filterlineedit.h"
#include <QDebug>
@@ -83,7 +83,7 @@ void BackupManagerForm::removeEntry(BackupItem *item)
}
}
void BackupManagerForm::setBackupUsage(quint64 size)
void BackupManagerForm::setBackupUsage(qint64 size)
{
ui->usageLabel->setText(tr("Backup disk usage: %1").arg(readable_size(size, true)));
}
@@ -163,10 +163,12 @@ void BackupManagerForm::loadBackupListing(int index)
#else
horiz_header->setResizeMode(QHeaderView::Stretch);
#endif
setBackupUsage(m_db->getObjectSize(ohfi));
qint64 backup_size = m_db->getObjectSize(ohfi);
setBackupUsage(backup_size);
QString path = m_db->getAbsolutePath(ohfi);
QList<BackupItem *> item_list;
metadata_t *first = meta;
while(meta) {
QString base_path = path + QDir::separator() + meta->name;
QString parent_path = sys_dir ? base_path + QDir::separator() + "sce_sys" : base_path;
@@ -215,6 +217,8 @@ void BackupManagerForm::loadBackupListing(int index)
meta = meta->next_metadata;
}
m_db->freeMetadata(first);
qSort(item_list.begin(), item_list.end(), BackupItem::lessThan);
int row;

View File

@@ -41,7 +41,7 @@ public:
private:
void setupForm();
void setBackupUsage(quint64 size);
void setBackupUsage(qint64 size);
Ui::BackupManagerForm *ui;

View File

@@ -19,7 +19,7 @@
#include "mainwidget.h"
#include "cmaclient.h"
#include "utils.h"
#include "cmautils.h"
#include "qlistdb.h"
#include "sqlitedb.h"
@@ -123,7 +123,7 @@ void MainWidget::prepareApplication()
if(QSettings().value("useMemoryStorage", true).toBool()) {
db = new QListDB();
} else {
db = NULL; // new SQLiteDB();
db = new SQLiteDB();
}
configForm = new ConfigWidget(this);
@@ -267,4 +267,5 @@ MainWidget::~MainWidget()
#ifndef ENABLE_KDE_NOTIFIER
trayIcon->hide();
#endif
delete db;
}

View File

@@ -17,7 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "utils.h"
#include "cmautils.h"
#include "qlistdb.h"
#include "cmaobject.h"
@@ -34,8 +34,8 @@ QListDB::QListDB(QObject *parent) :
QString uuid = QSettings().value("lastAccountId", "ffffffffffffffff").toString();
CMARootObject::uuid = uuid;
thread = new QThread();
timer = new QTimer();
moveToThread(thread);
timer = new QTimer();
thread->start();
timer->setInterval(0);
@@ -45,7 +45,7 @@ QListDB::QListDB(QObject *parent) :
QListDB::~QListDB()
{
destroy();
clear();
timer->stop();
delete timer;
thread->quit();
@@ -53,53 +53,41 @@ QListDB::~QListDB()
delete thread;
}
void QListDB::setUUID(const QString uuid)
void QListDB::setUUID(const QString &uuid)
{
CMARootObject::uuid = uuid;
QSettings().setValue("lastAccountId", uuid);
}
bool QListDB::reload(bool &prepared)
bool QListDB::load()
{
if(mutex.tryLock()) {
// not implemented
return false;
}
bool QListDB::rescan()
{
if(mutex.tryLock(1000)) {
if(CMARootObject::uuid != "ffffffffffffffff") {
timer->start();
prepared = true;
} else {
mutex.unlock();
prepared = false;
return false;
}
return true;
} else {
mutex.unlock();
return false;
}
}
void QListDB::process()
{
destroy();
cancel_operation = false;
int count = create();
cancel_operation = false;
qDebug("Added %i entries to the database", count);
if(count < 0) {
destroy();
}
emit updated(count);
mutex.unlock();
return false;
}
void QListDB::cancelOperation()
void QListDB::clear()
{
QMutexLocker locker(&cancel);
cancel_operation = true;
}
for(map_list::iterator root = object_list.begin(); root != object_list.end(); ++root) {
CMARootObject *first = static_cast<CMARootObject *>((*root).takeFirst());
delete first;
qDeleteAll(*root);
}
bool QListDB::continueOperation()
{
QMutexLocker locker(&cancel);
return !cancel_operation;
object_list.clear();
}
int QListDB::create()
@@ -147,6 +135,8 @@ int QListDB::create()
return -1;
}
qDebug("Added %i objects for OHFI %#02X", dir_count, ohfi_array[i]);
total_objects += dir_count;
object_list[ohfi_array[i]] = list;
}
@@ -236,19 +226,6 @@ int QListDB::recursiveScanRootDirectory(root_list &list, CMAObject *parent, int
return total_objects;
}
void QListDB::destroy()
{
//QMutexLocker locker(&mutex);
for(map_list::iterator root = object_list.begin(); root != object_list.end(); ++root) {
CMARootObject *first = static_cast<CMARootObject *>((*root).takeFirst());
delete first;
qDeleteAll(*root);
}
object_list.clear();
}
bool QListDB::removeInternal(root_list &list, int ohfi)
{
bool found = false;
@@ -487,7 +464,7 @@ int QListDB::getPathId(const char *name, int ohfi)
return 0;
}
int QListDB::insertObjectEntry(const QString &path, int parent_ohfi)
int QListDB::insertObjectEntry(const QString &path, const QString &name, int parent_ohfi)
{
QMutexLocker locker(&mutex);
@@ -505,7 +482,8 @@ int QListDB::insertObjectEntry(const QString &path, int parent_ohfi)
parent_obj = parent_obj->parent;
}
newobj->initObject(path, parent_obj->metadata.dataType);
QFileInfo info(path, name);
newobj->initObject(info, parent_obj->metadata.dataType);
cat_list->append(newobj);
return newobj->metadata.ohfi;
}

View File

@@ -38,8 +38,13 @@ public:
explicit QListDB(QObject *parent = 0);
~QListDB();
bool load();
bool rescan();
void close();
void clear();
bool reload(bool &prepared);
void setUUID(const QString uuid);
void setUUID(const QString &uuid);
int childObjectCount(int parent_ohfi);
bool deleteEntry(int ohfi, int root_ohfi = 0);
@@ -51,9 +56,12 @@ public:
int getPathId(const char *name, int ohfi);
QString getRelativePath(int ohfi);
int getRootId(int ohfi);
int insertObjectEntry(const QString &path, int parent_ohfi);
int insertObjectEntry(const QString &path, const QString &name, int parent_ohfi);
bool renameObject(int ohfi, const QString &name);
void setObjectSize(int ohfi, qint64 size);
void freeMetadata(metadata_t *metadata) {
Q_UNUSED(metadata);
}
private:
typedef struct {
@@ -65,7 +73,6 @@ private:
typedef QMap<int, root_list> map_list;
int create();
void destroy();
int scanRootDirectory(root_list &list,int ohfi_type);
int recursiveScanRootDirectory(root_list &list, CMAObject *parent, int ohfi_type);
bool hasFilter(const CMARootObject *object,int ohfi);
@@ -78,26 +85,10 @@ private:
bool find(int ohfi, find_data &data);
int acceptFilteredObject(const CMAObject *parent, const CMAObject *current, int type);
CMAObject *ohfiToObject(int ohfi);
bool continueOperation();
// control variables
QMutex cancel;
bool cancel_operation;
QTimer *timer;
QThread *thread;
map_list object_list;
signals:
void fileAdded(QString);
void directoryAdded(QString);
void updated(int);
protected slots:
void process();
public slots:
void cancelOperation();
};
#endif // QLISTDB_H

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +1,22 @@
/*
* QCMA: Cross-platform content manager assistant for the PS Vita
*
* Copyright (C) 2014 Codestation
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SQLITEDB_H
#define SQLITEDB_H
@@ -5,27 +24,11 @@
#include <vitamtp.h>
#include <QFileInfo>
#include <QObject>
#include <QSqlDatabase>
#include <QSqlError>
#define OBJECT_FILE 0x10000000
#define OBJECT_FOLDER 0x20000000
#define OBJECT_SPECIAL 0x40000000
#define OBJECT_MUSIC 0x00000100
#define OBJECT_PHOTO 0x00000200
#define OBJECT_VIDEO 0x00000400
#define OBJECT_ALBUM 0x00000002
#define OBJECT_ARTIST 0x00000005
#define OBJECT_ALBUM_ARTIST 0x00000008
#define OBJECT_GENRE 0x0000000B
#define OBJECT_SAVEDATA 0x00040000
#define OBJECT_SAVEDATA_FILE 0x00000002
#define OBJECT_APPLICATION 0x00080000
#include <QTimer>
class SQLiteDB : public Database
{
@@ -34,9 +37,16 @@ public:
explicit SQLiteDB(QObject *parent = 0);
~SQLiteDB();
bool load();
bool rescan();
void close();
bool reload(bool &prepared);
void setUUID(const QString &uuid);
bool open();
int create();
void remove();
void clear();
bool initialize();
QSqlError getLastError();
@@ -50,35 +60,40 @@ public:
int getPathId(const char *name, int ohfi);
QString getRelativePath(int ohfi);
int getRootId(int ohfi);
int insertObjectEntry(const QString &path, int parent_ohfi);
int insertObjectEntry(const QString &path, const QString &name, int parent_ohfi);
bool renameObject(int ohfi, const QString &name);
void setObjectSize(int ohfi, qint64 size);
void freeMetadata(metadata_t *metadata);
int getPathId(const QString &path);
QString getPathFromId(int ohfi);
bool updateSize(int ohfi, quint64 size);
bool deleteEntry(int ohfi);
bool deleteEntry(const QString &path);
uint insertObjectEntry(const char *title, int type);
bool insertSourceEntry(uint object_id, const QString &path);
uint insertMusicEntry(const QString &path, int type, int parent);
uint insertVideoEntry(const QString &path, int type, int parent);
uint insertPhotoEntry(const QString &path, int type, int parent);
uint insertSavedataEntry(const QString &path, int type, int parent);
uint insertApplicationEntry(const QString &path, int type, int parent, int app_type);
bool insertSourceEntry(uint object_id, const QString &path, const QString &name);
uint insertMusicEntry(const QString &path, const QString &name, int parent, int type);
uint insertVideoEntry(const QString &path, const QString &name, int parent, int type);
uint insertPhotoEntry(const QString &path, const QString &name, int parent, int type);
uint insertSavedataEntry(const QString &path, const QString &name, int parent, int type);
uint insertApplicationEntry(const QString &path, const QString &name, int parent, int type, int app_type);
private:
int recursiveScanRootDirectory(const QString &base_path, int parent, int type);
uint insertDirectoryEntry(const QString &path, int type, int parent);
int recursiveScanRootDirectory(const QString &base_path, const QString &rel_path, int parent_ohfi, int root_ohfi);
int insertObjectEntryInternal(const QString &path, const QString &name, int parent_ohfi, int type);
int insertDefaultEntry(const QString &path, const QString &name, const QString &title, int parent, int type);
int insertNodeEntry(const QString &title, int type, int data_type);
bool updateAdjacencyList(int ohfi, int parent);
QString getBasePath(int root_ohfi);
int insertFileEntry(const QString &path, const QString &name, int parent, int parent_type);
int getObjectType(int ohfi);
void fillMetadata(const QSqlQuery &query, metadata_t &metadata);
qint64 getChildenTotalSize(int ohfi);
bool updateObjectPath(int ohfi, const QString &name);
QTimer *timer;
QThread *thread;
QString uuid;
QSqlDatabase db;
signals:
public slots:
};
#endif // SQLITEDB_H