applist: Backup db before applying sort and log if errors occur

This commit is contained in:
Joel16 2021-04-08 11:58:17 -04:00
parent 8446b9d795
commit 2abb13e579
12 changed files with 204 additions and 29 deletions

View File

@ -42,7 +42,9 @@ add_executable(${PROJECT_NAME}
libs/imgui/imgui_widgets.cpp
libs/libsqlite/libsqlite/sqlite.c
source/applist.cpp
source/fs.cpp
source/gui.cpp
source/log.cpp
source/main.cpp
source/utils.cpp
)

View File

@ -29,6 +29,7 @@ namespace AppList {
bool SortAlphabeticalAsc(const AppInfoIcon &entryA, const AppInfoIcon &entryB);
bool SortAlphabeticalDesc(const AppInfoIcon &entryA, const AppInfoIcon &entryB);
void Sort(std::vector<AppInfoIcon> &entries, std::vector<AppInfoPage> &pages, std::vector<AppInfoFolder> &folders);
int Backup(void);
}
#endif

15
include/fs.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef _VITA_HB_SORTER_FS_H_
#define _VITA_HB_SORTER_FS_H_
#include <psp2/types.h>
#include <string>
namespace FS {
bool FileExists(const std::string &path);
bool DirExists(const std::string &path);
int CreateFile(const std::string &path);
int ReadFile(const std::string &path, unsigned char **buffer, SceOff *size);
int WriteFile(const std::string &path, const void *data, SceSize size);
}
#endif

View File

@ -1,8 +1,6 @@
#ifndef _VITA_HB_SORTER_GUI_H_
#define _VITA_HB_SORTER_GUI_H_
#include "textures.h"
namespace GUI {
int RenderLoop(void);
}

10
include/log.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef _VITA_HB_SORTER_LOG_H_
#define _VITA_HB_SORTER_LOG_H_
namespace Log {
int Init(void);
int Exit(void);
int Error(const char *format, ...);
}
#endif

View File

@ -1,17 +0,0 @@
#ifndef _VITA_HB_SORTER_TEXTURES_H_
#define _VITA_HB_SORTER_TEXTURES_H_
#include <vitaGL.h>
typedef struct {
GLuint id = 0;
int width = 0;
int height = 0;
} Tex;
namespace Textures {
void Init(void);
void Exit(void);
}
#endif

View File

@ -3,7 +3,10 @@
#include <string>
#include "applist.h"
#include "fs.h"
#include "log.h"
#include "sqlite3.h"
#include "utils.h"
namespace AppList {
constexpr char path[] = "ur0:/shell/db/app.db";
@ -101,7 +104,7 @@ namespace AppList {
ret = sqlite3_exec(db, query.c_str(), nullptr, nullptr, &error);
if (ret != SQLITE_OK) {
printf("sqlite3_exec error: %s\n", error);
Log::Error("sqlite3_exec error: %s\n", error);
sqlite3_free(error);
sqlite3_close(db);
return ret;
@ -122,7 +125,7 @@ namespace AppList {
ret = sqlite3_exec(db, query.c_str(), nullptr, nullptr, &error);
if (ret != SQLITE_OK) {
printf("sqlite3_exec error: %s\n", error);
Log::Error("sqlite3_exec error: %s\n", error);
sqlite3_free(error);
sqlite3_close(db);
return ret;
@ -184,4 +187,18 @@ namespace AppList {
}
}
}
int Backup(void) {
unsigned char *data = nullptr;
SceOff size = 0;
int ret = 0;
if (R_FAILED(ret = FS::ReadFile(path, &data, &size)))
return ret;
if (R_FAILED(ret = FS::WriteFile("ux0:/data/VITAHomebrewSorter/app.db", data, size)))
return ret;
return 0;
}
}

96
source/fs.cpp Normal file
View File

@ -0,0 +1,96 @@
#include <psp2/io/dirent.h>
#include <psp2/io/fcntl.h>
#include <psp2/io/stat.h>
#include <string>
#include "log.h"
#include "utils.h"
namespace FS {
bool FileExists(const std::string &path) {
SceUID file = 0;
if (R_SUCCEEDED(file = sceIoOpen(path.c_str(), SCE_O_RDONLY, 0777))) {
sceIoClose(file);
return true;
}
return false;
}
bool DirExists(const std::string &path) {
SceUID dir = 0;
if (R_SUCCEEDED(dir = sceIoDopen(path.c_str()))) {
sceIoDclose(dir);
return true;
}
return false;
}
int CreateFile(const std::string &path) {
int ret = 0;
SceUID file = 0;
if (R_FAILED(ret = file = sceIoOpen(path.c_str(), SCE_O_WRONLY | SCE_O_CREAT | SCE_O_TRUNC, 0777))) {
Log::Error("sceIoOpen(%s) failed: 0x%lx\n", path.c_str(), ret);
return ret;
}
if (R_FAILED(ret = sceIoClose(file))) {
Log::Error("sceIoClose(%s) failed: 0x%lx\n", path.c_str(), ret);
return ret;
}
return 0;
}
int ReadFile(const std::string &path, unsigned char **buffer, SceOff *size) {
int ret = 0;
SceUID file = 0;
if (R_FAILED(ret = file = sceIoOpen(path.c_str(), SCE_O_RDONLY, 0))) {
Log::Error("sceIoOpen(%s) failed: 0x%lx\n", path.c_str(), ret);
return ret;
}
*size = sceIoLseek(file, 0, SEEK_END);
*buffer = new unsigned char[*size];
if (R_FAILED(ret = sceIoPread(file, *buffer, *size, SCE_SEEK_SET))) {
Log::Error("sceIoPread(%s) failed: 0x%lx\n", path.c_str(), ret);
return ret;
}
if (R_FAILED(ret = sceIoClose(file))) {
Log::Error("sceIoClose(%s) failed: 0x%lx\n", path.c_str(), ret);
return ret;
}
return 0;
}
int WriteFile(const std::string &path, const void *data, SceSize size) {
int ret = 0, bytes_written = 0;
SceUID file = 0;
if (R_FAILED(ret = file = sceIoOpen(path.c_str(), SCE_O_WRONLY | SCE_O_CREAT | SCE_O_TRUNC, 0777))) {
Log::Error("sceIoOpen(%s) failed: 0x%lx\n", path.c_str(), ret);
return ret;
}
if (R_FAILED(ret = bytes_written = sceIoWrite(file, data, size))) {
Log::Error("sceIoWrite(%s) failed: 0x%lx\n", path.c_str(), ret);
sceIoClose(file);
return ret;
}
if (R_FAILED(ret = sceIoClose(file))) {
Log::Error("sceIoClose(%s) failed: 0x%lx\n", path.c_str(), ret);
return ret;
}
return bytes_written;
}
}

View File

@ -75,8 +75,10 @@ namespace GUI {
ImGui::SameLine();
if (ImGui::Button("Apply Sort"))
if (ImGui::Button("Apply Sort")) {
AppList::Backup();
AppList::Save(entries);
}
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing

46
source/log.cpp Normal file
View File

@ -0,0 +1,46 @@
#include <psp2/io/fcntl.h>
#include <psp2/io/stat.h>
#include <cstdarg>
#include <cstdio>
#include "fs.h"
#include "utils.h"
namespace Log {
static SceUID log_file = 0;
void Init(void) {
if (!FS::DirExists("ux0:data"))
sceIoMkdir("ux0:data", 0777);
if (!FS::DirExists("ux0:data/VITAHomebrewSorter"))
sceIoMkdir("ux0:data/VITAHomebrewSorter", 0777);
if (!FS::FileExists("ux0:data/VITAHomebrewSorter/debug.log"))
FS::CreateFile("ux0:data/VITAHomebrewSorter/debug.log");
if (R_FAILED(log_file = sceIoOpen("ux0:data/VITAHomebrewSorter/debug.log", SCE_O_WRONLY | SCE_O_APPEND, 0)))
return;
}
void Exit(void) {
if (R_FAILED(sceIoClose(log_file)))
return;
}
void Error(const char *data, ...) {
char buf[512];
va_list args;
va_start(args, data);
std::vsnprintf(buf, sizeof(buf), data, args);
va_end(args);
std::string error_string = "[ERROR] ";
error_string.append(buf);
std::printf("%s", error_string.c_str());
printf("%s", error_string.c_str());
if (R_FAILED(sceIoWrite(log_file, error_string.data(), error_string.length())))
return;
}
}

View File

@ -3,6 +3,7 @@
#include <vitaGL.h>
#include "gui.h"
#include "log.h"
#include "utils.h"
extern "C" {
@ -88,10 +89,13 @@ namespace Services {
sceSysmoduleLoadModule(SCE_SYSMODULE_SQLITE);
sqlite3_rw_init();
Log::Init();
}
void Exit(void) {
// Clean up
Log::Exit();
sqlite3_rw_exit();
sceSysmoduleUnloadModule(SCE_SYSMODULE_SQLITE);
Utils::EndAppUtil();

View File

@ -4,6 +4,7 @@
#include <psp2/system_param.h>
#include <cstdio>
#include "log.h"
#include "utils.h"
int SCE_CTRL_ENTER, SCE_CTRL_CANCEL;
@ -20,7 +21,7 @@ namespace Utils {
int ret = 0;
if (R_FAILED(ret = sceAppUtilInit(&init, &boot))) {
printf("sceAppUtilInit failed: 0x%lx\n", ret);
Log::Error("sceAppUtilInit failed: 0x%lx\n", ret);
return ret;
}
@ -28,17 +29,17 @@ namespace Utils {
sceCommonDialogConfigParamInit(&param);
if (R_FAILED(ret = sceAppUtilSystemParamGetInt(SCE_SYSTEM_PARAM_ID_LANG, reinterpret_cast<int *>(&param.language)))) {
printf("sceAppUtilSystemParamGetInt(SCE_SYSTEM_PARAM_ID_LANG) failed: 0x%lx\n", ret);
Log::Error("sceAppUtilSystemParamGetInt(SCE_SYSTEM_PARAM_ID_LANG) failed: 0x%lx\n", ret);
return ret;
}
if (R_FAILED(ret = sceAppUtilSystemParamGetInt(SCE_SYSTEM_PARAM_ID_ENTER_BUTTON, reinterpret_cast<int *>(&param.enterButtonAssign)))) {
printf("sceAppUtilSystemParamGetInt(SCE_SYSTEM_PARAM_ID_ENTER_BUTTON) failed: 0x%lx\n", ret);
Log::Error("sceAppUtilSystemParamGetInt(SCE_SYSTEM_PARAM_ID_ENTER_BUTTON) failed: 0x%lx\n", ret);
return ret;
}
if (R_FAILED(ret = sceCommonDialogSetConfigParam(&param))) {
printf("sceCommonDialogSetConfigParam failed: 0x%lx\n", ret);
Log::Error("sceCommonDialogSetConfigParam failed: 0x%lx\n", ret);
return ret;
}
@ -49,7 +50,7 @@ namespace Utils {
int ret = 0;
if (R_FAILED(ret = sceAppUtilShutdown())) {
printf("sceAppUtilShutdown failed: 0x%lx\n", ret);
Log::Error("sceAppUtilShutdown failed: 0x%lx\n", ret);
return ret;
}
@ -59,7 +60,7 @@ namespace Utils {
int GetEnterButton(void) {
int button = 0, ret = 0;
if (R_FAILED(ret = sceAppUtilSystemParamGetInt(SCE_SYSTEM_PARAM_ID_ENTER_BUTTON, &button))) {
printf("sceAppUtilSystemParamGetInt(SCE_SYSTEM_PARAM_ID_ENTER_BUTTON) failed: 0x%lx\n", ret);
Log::Error("sceAppUtilSystemParamGetInt(SCE_SYSTEM_PARAM_ID_ENTER_BUTTON) failed: 0x%lx\n", ret);
return ret;
}
@ -74,7 +75,7 @@ namespace Utils {
int GetCancelButton(void) {
int button = 0, ret = 0;
if (R_FAILED(ret = sceAppUtilSystemParamGetInt(SCE_SYSTEM_PARAM_ID_ENTER_BUTTON, &button))) {
printf("sceAppUtilSystemParamGetInt(SCE_SYSTEM_PARAM_ID_ENTER_BUTTON) failed: 0x%lx\n", ret);
Log::Error("sceAppUtilSystemParamGetInt(SCE_SYSTEM_PARAM_ID_ENTER_BUTTON) failed: 0x%lx\n", ret);
return ret;
}