Create virtual node table to store category nodes (doesn't exist on the filesystem but need an OHFI).

Enable triggers, disable sync mode and other tweaks so the creation of the database can be faster.
Abort early if a database entry cannot be added.
Fix games and savedatas not being saved with their correct parent id.
Preparing getRootItems to return virtual categories.
Code refactoring.
This commit is contained in:
codestation
2014-02-25 09:18:49 -04:30
parent 99d216d474
commit ae8657325a
2 changed files with 127 additions and 79 deletions

View File

@@ -76,9 +76,15 @@ static const char create_apps[] = "CREATE TABLE IF NOT EXISTS application ("
"title TEXT NOT NULL CHECK (LENGTH(title) > 0),"
"app_type INTEGER)";
static const char create_virtual[] = "CREATE TABLE IF NOT EXISTS virtual_nodes ("
"object_id INTEGER PRIMARY KEY REFERENCES object_node(object_id) ON DELETE CASCADE,"
"title TEXT NOT NULL CHECK (LENGTH(title) > 0),"
"app_type INTEGER)";
static const char create_photos[] = "CREATE TABLE IF NOT EXISTS photos ("
"object_id INTEGER PRIMARY KEY REFERENCES object_node(object_id) ON DELETE CASCADE,"
"date_created TIMESTAMP,"
"month_created TEXT,"
"file_format INTEGER,"
"photo_codec INTEGER,"
"width INTEGER,"
@@ -127,7 +133,7 @@ static const char create_trigger_adjdel[] = "CREATE TRIGGER IF NOT EXISTS trg_ad
static const char *table_list[] = {
create_adjacent, create_obj_node, create_sources,
create_music, create_photos, create_videos, create_savedata, create_apps
create_music, create_photos, create_videos, create_savedata, create_apps, create_virtual
};
static const char *trigger_list[] = {
@@ -182,6 +188,14 @@ bool SQLiteDB::load()
bool success = false;
if(db.open()) {
QSqlQuery query;
query.exec("PRAGMA foreign_keys = ON");
query.exec("PRAGMA synchronous = OFF");
query.exec("PRAGMA user_version = 1");
query.exec("PRAGMA journal_mode = MEMORY");
query.exec("PRAGMA recursive_triggers = true");
query.exec("PRAGMA vacuum_db.synchronous = OFF");
qDebug() << "Database created/registered";
success = !initialize();
} else {
@@ -329,7 +343,12 @@ int SQLiteDB::recursiveScanRootDirectory(const QString &base_path, const QString
// update progress dialog
if(info.isDir()) {
emit directoryAdded(base_path + "/" + rel_name);
total_objects += recursiveScanRootDirectory(base_path, rel_name, ohfi, root_ohfi);
int inserted = recursiveScanRootDirectory(base_path, rel_name, ohfi, root_ohfi);
if(inserted < 0) {
return -1;
}
total_objects += inserted;
qint64 dirsize = getChildenTotalSize(ohfi);
setObjectSize(ohfi, dirsize);
} else if(info.isFile()) {
@@ -366,17 +385,15 @@ int SQLiteDB::insertObjectEntryInternal(const QString &path, const QString &name
if(info.isDir()) {
ohfi = insertDefaultEntry(path, name, info.fileName(), parent_ohfi, Folder);
} else {
ohfi = insertFileEntry(path, name, parent_ohfi, root_ohfi);
switch(parent_ohfi) {
case VITA_OHFI_VITAAPP:
case VITA_OHFI_PSPAPP:
case VITA_OHFI_PSXAPP:
case VITA_OHFI_PSMAPP:
case VITA_OHFI_BACKUP:
insertApplicationEntry(name, ohfi, parent_ohfi);
}
return ohfi;
}
int SQLiteDB::insertFileEntry(const QString &path, const QString &name, int parent_ohfi, int root_ohfi)
{
int ohfi = 0;
} else {
switch(root_ohfi) {
case VITA_OHFI_MUSIC:
ohfi = insertMusicEntry(path, name, parent_ohfi, File | Music);
@@ -395,15 +412,13 @@ int SQLiteDB::insertFileEntry(const QString &path, const QString &name, int pare
case VITA_OHFI_PSXAPP:
case VITA_OHFI_PSMAPP:
case VITA_OHFI_BACKUP:
ohfi = insertApplicationEntry(path, name, parent_ohfi, File | App, root_ohfi);
break;
default:
qFatal("Invalid parent type");
ohfi = insertDefaultEntry(path, name, info.fileName(), parent_ohfi, File | App);
}
}
return ohfi;
}
int SQLiteDB::getPathId(const QString &path)
{
QSqlQuery query(QString("SELECT object_id from sources WHERE path = %1").arg(path));
@@ -472,7 +487,7 @@ int SQLiteDB::insertDefaultEntry(const QString &path, const QString &name, const
return 0;
}
if(parent && !updateAdjacencyList(ohfi, parent)) {
if(parent >= OHFI_BASE_VALUE && !updateAdjacencyList(ohfi, parent)) {
return 0;
}
@@ -734,7 +749,10 @@ uint SQLiteDB::insertPhotoEntry(const QString &path, const QString &name, int pa
return 0;
}
date_created = QFileInfo(path + "/" + name).created().toTime_t();
QDateTime date = QFileInfo(path + "/" + name).created();
date_created = date.toTime_t();
QString month_created = date.toString("yyyy/MM");
width = img.width();
height = img.height();
file_format = photo_list[file_type].file_format;
@@ -748,8 +766,8 @@ uint SQLiteDB::insertPhotoEntry(const QString &path, const QString &name, int pa
QSqlQuery query;
query.prepare("REPLACE INTO photos"
"(object_id, date_created, file_format, photo_codec, width, height)"
"VALUES (:object_id, :date_created, :file_format, :photo_codec, :width, :height)");
"(object_id, date_created, file_format, photo_codec, width, height, month_created)"
"VALUES (:object_id, :date_created, :file_format, :photo_codec, :width, :height, :month_created)");
query.bindValue(0, ohfi);
query.bindValue(1, date_created);
@@ -757,6 +775,7 @@ uint SQLiteDB::insertPhotoEntry(const QString &path, const QString &name, int pa
query.bindValue(3, photo_codec);
query.bindValue(4, width);
query.bindValue(5, height);
query.bindValue(6, month_created);
if(!query.exec()) {
return 0;
@@ -797,7 +816,7 @@ uint SQLiteDB::insertSavedataEntry(const QString &path, const QString &name, int
"(object_id, detail, dir_name, title, date_updated)"
"VALUES (:object_id, :detail, :dir_name, :title, :updated)");
query.bindValue(0, ohfi);
query.bindValue(0, parent);
query.bindValue(1, savedata_detail);
query.bindValue(2, savedata_directory);
query.bindValue(3, title);
@@ -811,25 +830,9 @@ uint SQLiteDB::insertSavedataEntry(const QString &path, const QString &name, int
}
uint SQLiteDB::insertApplicationEntry(const QString &path, const QString &name, int parent, int type, int app_type)
bool SQLiteDB::insertApplicationEntry(const QString &name, int ohfi, int app_type)
{
int ohfi;
QString title_id;
if(name.endsWith(".sfo", Qt::CaseInsensitive)) {
QDir curdir(path + "/" + name);
if(curdir.cdUp() && curdir.cdUp()) {
title_id = QFileInfo(curdir.absolutePath()).fileName();
}
}
if((ohfi = insertDefaultEntry(path, name, QFileInfo(name).fileName(), parent, type)) == 0) {
return 0;
}
if(title_id.isNull()) {
return ohfi;
}
QString title_id = QFileInfo(name).fileName();
QSqlQuery query;
query.prepare("REPLACE INTO application"
@@ -841,10 +844,10 @@ uint SQLiteDB::insertApplicationEntry(const QString &path, const QString &name,
query.bindValue(2, app_type);
if(!query.exec()) {
return 0;
return false;
}
return ohfi;
return true;
}
int SQLiteDB::childObjectCount(int parent_ohfi)
@@ -865,24 +868,9 @@ bool SQLiteDB::deleteEntry(int ohfi, int root_ohfi)
Q_UNUSED(root_ohfi);
qDebug("Deleting node: %i", ohfi);
QSqlQuery source_query("DELETE FROM sources WHERE object_id = :object_id");
source_query.bindValue(0, ohfi);
db.transaction();
if(!source_query.exec()) {
db.rollback();
return false;
}
QSqlQuery object_query("DELETE FROM object_node WHERE object_id = :object_id");
object_query.bindValue(0, ohfi);
if(!object_query.exec()) {
db.rollback();
return false;
}
db.commit();
return true;
QSqlQuery query("DELETE FROM object_node WHERE object_id = :object_id");
query.bindValue(0, ohfi);
return query.exec();
}
void SQLiteDB::fillMetadata(const QSqlQuery &query, metadata_t &metadata)
@@ -896,6 +884,7 @@ void SQLiteDB::fillMetadata(const QSqlQuery &query, metadata_t &metadata)
metadata.size = query.value("size").toULongLong();
metadata.dateTimeCreated = query.value("date_created").toInt();
metadata.next_metadata = NULL;
//TODO: fill the rest of the metadata
}
bool SQLiteDB::getObjectMetadata(int ohfi, metadata_t &metadata)
@@ -931,6 +920,10 @@ int SQLiteDB::getObjectMetadatas(int parent_ohfi, metadata_t **metadata, int ind
return childObjectCount(parent_ohfi);
}
if(parent_ohfi < OHFI_BASE_VALUE) {
return getRootItems(parent_ohfi, metadata);
}
int count = 0;
QString query_str(
"SELECT "
@@ -1175,3 +1168,58 @@ void SQLiteDB::freeMetadata(metadata_t *metadata)
delete current;
}
}
int SQLiteDB::getRootItems(int root_ohfi, metadata_t **metadata)
{
QSqlQuery query;
int count = 0;
switch(root_ohfi) {
case VITA_OHFI_MUSIC:
//query = QSqlQuery("SELECT * FROM music");
break;
case VITA_OHFI_PHOTO:
//query = QSqlQuery("SELECT * FROM photos");
break;
case VITA_OHFI_VIDEO:
//query = QSqlQuery("SELECT * FROM videos");
break;
case VITA_OHFI_PSPSAVE:
//query = QSqlQuery("SELECT * FROM savedata");
break;
case VITA_OHFI_VITAAPP:
case VITA_OHFI_PSPAPP:
case VITA_OHFI_PSXAPP:
case VITA_OHFI_PSMAPP:
case VITA_OHFI_BACKUP:
query = QSqlQuery("SELECT "
"t0.object_id as ohfi,"
":app_type as parent,"
"t3.path as path,"
"t0.title as name,"
"t1.type as type,"
"t1.data_type as data_type,"
"t3.size as size,"
"t3.date_created as date_created "
"FROM application t0 "
"JOIN object_node t1 on t0.object_id = t1.object_id "
"JOIN sources t3 ON t3.object_id = t0.object_id "
"WHERE app_type = :app_type");
query.bindValue(0, root_ohfi);
if(query.exec()) {
metadata_t **last = &*metadata;
while(query.next()) {
metadata_t *meta = new metadata_t();
fillMetadata(query, *meta);
*last = meta;
last = &meta->next_metadata;
count++;
}
}
break;
default:
qFatal("Invalid root ohfi type");
}
return count;
}

View File

@@ -74,7 +74,7 @@ public:
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);
bool insertApplicationEntry(const QString &name, int ohfi, int app_type);
private:
int recursiveScanRootDirectory(const QString &base_path, const QString &rel_path, int parent_ohfi, int root_ohfi);
@@ -83,11 +83,11 @@ private:
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);
int getRootItems(int root_ohfi, metadata_t **metadata);
QTimer *timer;
QThread *thread;