mirror of
https://github.com/YACReader/yacreader
synced 2025-06-04 01:28:55 -04:00
Add a data migration to ensure that the number types are migrated to text in the db schema
This fixes a problem storing some text number formats in the db when the type is integer.
This commit is contained in:
parent
54fc070a2e
commit
f319b00c70
@ -14,6 +14,7 @@ Version counting is based on semantic versioning (Major.Feature.Patch)
|
|||||||
* Improve content reloading. Navigation and selection state is no longer reseted after content changes (e.g. library updates, tags edits, etc.)
|
* Improve content reloading. Navigation and selection state is no longer reseted after content changes (e.g. library updates, tags edits, etc.)
|
||||||
* The app will try to move comics and folders to the trash bin when deletions are requested, if the file system used doesn't support trash bin the files will be removed permanetly.
|
* The app will try to move comics and folders to the trash bin when deletions are requested, if the file system used doesn't support trash bin the files will be removed permanetly.
|
||||||
* Add menu to choose what columns are displayed in the table comics view (do a right click on the header to show it). The view has new 3 new headers to choose from (Series, Volume and Story arc).
|
* Add menu to choose what columns are displayed in the table comics view (do a right click on the header to show it). The view has new 3 new headers to choose from (Series, Volume and Story arc).
|
||||||
|
* Migrate `number` and `arcNumber` data types to `TEXT`. This only affects databases created before 9.13 and fixes problems with some formats of numbers (e.g. 1.10).
|
||||||
|
|
||||||
### YACReaderLibrary
|
### YACReaderLibrary
|
||||||
* Add `rescan-xml-info` command.
|
* Add `rescan-xml-info` command.
|
||||||
|
@ -160,8 +160,58 @@ bool DataBaseManagement::createTables(QSqlDatabase &database)
|
|||||||
|
|
||||||
{
|
{
|
||||||
// COMIC INFO (representa la información de un cómic, cada cómic tendrá un idéntificador único formado por un hash sha1'de los primeros 512kb' + su tamaño en bytes)
|
// COMIC INFO (representa la información de un cómic, cada cómic tendrá un idéntificador único formado por un hash sha1'de los primeros 512kb' + su tamaño en bytes)
|
||||||
|
success = success && DataBaseManagement::createComicInfoTable(database, "comic_info");
|
||||||
|
|
||||||
|
// FOLDER (representa una carpeta en disco)
|
||||||
|
QSqlQuery queryFolder(database);
|
||||||
|
queryFolder.prepare("CREATE TABLE folder ("
|
||||||
|
"id INTEGER PRIMARY KEY,"
|
||||||
|
"parentId INTEGER NOT NULL,"
|
||||||
|
"name TEXT NOT NULL,"
|
||||||
|
"path TEXT NOT NULL,"
|
||||||
|
// new 7.1 fields
|
||||||
|
"finished BOOLEAN DEFAULT 0," // reading
|
||||||
|
"completed BOOLEAN DEFAULT 1," // collecting
|
||||||
|
// new 9.5 fields
|
||||||
|
"numChildren INTEGER,"
|
||||||
|
"firstChildHash TEXT,"
|
||||||
|
"customImage TEXT,"
|
||||||
|
// new 9.8 fields
|
||||||
|
"manga BOOLEAN DEFAULT 0," // deprecated 9.13
|
||||||
|
// new 9.13 fields
|
||||||
|
"type INTEGER DEFAULT 0," // 0 = comic, 1 = manga, 2 = manga left to right, 3 = webcomic, 4 = 4koma
|
||||||
|
"added INTEGER,"
|
||||||
|
"updated INTEGER," // updated when the folder gets new content
|
||||||
|
"FOREIGN KEY(parentId) REFERENCES folder(id) ON DELETE CASCADE)");
|
||||||
|
success = success && queryFolder.exec();
|
||||||
|
|
||||||
|
// COMIC (representa un cómic en disco, contiene el nombre de fichero)
|
||||||
|
QSqlQuery queryComic(database);
|
||||||
|
queryComic.prepare("CREATE TABLE comic (id INTEGER PRIMARY KEY, parentId INTEGER NOT NULL, comicInfoId INTEGER NOT NULL, fileName TEXT NOT NULL, path TEXT, FOREIGN KEY(parentId) REFERENCES folder(id) ON DELETE CASCADE, FOREIGN KEY(comicInfoId) REFERENCES comic_info(id))");
|
||||||
|
success = success && queryComic.exec();
|
||||||
|
// queryComic.finish();
|
||||||
|
// DB INFO
|
||||||
|
QSqlQuery queryDBInfo(database);
|
||||||
|
queryDBInfo.prepare("CREATE TABLE db_info (version TEXT NOT NULL)");
|
||||||
|
success = success && queryDBInfo.exec();
|
||||||
|
// queryDBInfo.finish();
|
||||||
|
|
||||||
|
QSqlQuery query("INSERT INTO db_info (version) "
|
||||||
|
"VALUES ('" DB_VERSION "')",
|
||||||
|
database);
|
||||||
|
// query.finish();
|
||||||
|
|
||||||
|
// 8.0> tables
|
||||||
|
success = success && DataBaseManagement::createV8Tables(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DataBaseManagement::createComicInfoTable(QSqlDatabase &database, QString tableName)
|
||||||
|
{
|
||||||
QSqlQuery queryComicInfo(database);
|
QSqlQuery queryComicInfo(database);
|
||||||
queryComicInfo.prepare("CREATE TABLE comic_info ("
|
queryComicInfo.prepare("CREATE TABLE " + tableName + " ("
|
||||||
"id INTEGER PRIMARY KEY,"
|
"id INTEGER PRIMARY KEY,"
|
||||||
"title TEXT,"
|
"title TEXT,"
|
||||||
|
|
||||||
@ -235,53 +285,8 @@ bool DataBaseManagement::createTables(QSqlDatabase &database)
|
|||||||
"review TEXT,"
|
"review TEXT,"
|
||||||
"tags TEXT"
|
"tags TEXT"
|
||||||
")");
|
")");
|
||||||
success = success && queryComicInfo.exec();
|
|
||||||
// queryComicInfo.finish();
|
|
||||||
|
|
||||||
// FOLDER (representa una carpeta en disco)
|
return queryComicInfo.exec();
|
||||||
QSqlQuery queryFolder(database);
|
|
||||||
queryFolder.prepare("CREATE TABLE folder ("
|
|
||||||
"id INTEGER PRIMARY KEY,"
|
|
||||||
"parentId INTEGER NOT NULL,"
|
|
||||||
"name TEXT NOT NULL,"
|
|
||||||
"path TEXT NOT NULL,"
|
|
||||||
// new 7.1 fields
|
|
||||||
"finished BOOLEAN DEFAULT 0," // reading
|
|
||||||
"completed BOOLEAN DEFAULT 1," // collecting
|
|
||||||
// new 9.5 fields
|
|
||||||
"numChildren INTEGER,"
|
|
||||||
"firstChildHash TEXT,"
|
|
||||||
"customImage TEXT,"
|
|
||||||
// new 9.8 fields
|
|
||||||
"manga BOOLEAN DEFAULT 0," // deprecated 9.13
|
|
||||||
// new 9.13 fields
|
|
||||||
"type INTEGER DEFAULT 0," // 0 = comic, 1 = manga, 2 = manga left to right, 3 = webcomic, 4 = 4koma
|
|
||||||
"added INTEGER,"
|
|
||||||
"updated INTEGER," // updated when the folder gets new content
|
|
||||||
"FOREIGN KEY(parentId) REFERENCES folder(id) ON DELETE CASCADE)");
|
|
||||||
success = success && queryFolder.exec();
|
|
||||||
|
|
||||||
// COMIC (representa un cómic en disco, contiene el nombre de fichero)
|
|
||||||
QSqlQuery queryComic(database);
|
|
||||||
queryComic.prepare("CREATE TABLE comic (id INTEGER PRIMARY KEY, parentId INTEGER NOT NULL, comicInfoId INTEGER NOT NULL, fileName TEXT NOT NULL, path TEXT, FOREIGN KEY(parentId) REFERENCES folder(id) ON DELETE CASCADE, FOREIGN KEY(comicInfoId) REFERENCES comic_info(id))");
|
|
||||||
success = success && queryComic.exec();
|
|
||||||
// queryComic.finish();
|
|
||||||
// DB INFO
|
|
||||||
QSqlQuery queryDBInfo(database);
|
|
||||||
queryDBInfo.prepare("CREATE TABLE db_info (version TEXT NOT NULL)");
|
|
||||||
success = success && queryDBInfo.exec();
|
|
||||||
// queryDBInfo.finish();
|
|
||||||
|
|
||||||
QSqlQuery query("INSERT INTO db_info (version) "
|
|
||||||
"VALUES ('" DB_VERSION "')",
|
|
||||||
database);
|
|
||||||
// query.finish();
|
|
||||||
|
|
||||||
// 8.0> tables
|
|
||||||
success = success && DataBaseManagement::createV8Tables(database);
|
|
||||||
}
|
|
||||||
|
|
||||||
return success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DataBaseManagement::createV8Tables(QSqlDatabase &database)
|
bool DataBaseManagement::createV8Tables(QSqlDatabase &database)
|
||||||
@ -854,6 +859,7 @@ bool DataBaseManagement::updateToCurrentVersion(const QString &path)
|
|||||||
bool pre9_5 = false;
|
bool pre9_5 = false;
|
||||||
bool pre9_8 = false;
|
bool pre9_8 = false;
|
||||||
bool pre9_13 = false;
|
bool pre9_13 = false;
|
||||||
|
bool pre9_14 = false;
|
||||||
|
|
||||||
QString fullPath = path + "/library.ydb";
|
QString fullPath = path + "/library.ydb";
|
||||||
|
|
||||||
@ -869,22 +875,15 @@ bool DataBaseManagement::updateToCurrentVersion(const QString &path)
|
|||||||
pre9_8 = true;
|
pre9_8 = true;
|
||||||
if (compareVersions(DataBaseManagement::checkValidDB(fullPath), "9.13.0") < 0)
|
if (compareVersions(DataBaseManagement::checkValidDB(fullPath), "9.13.0") < 0)
|
||||||
pre9_13 = true;
|
pre9_13 = true;
|
||||||
|
if (compareVersions(DataBaseManagement::checkValidDB(fullPath), "9.14.0") < 0)
|
||||||
|
pre9_14 = true;
|
||||||
|
|
||||||
QString connectionName = "";
|
QString connectionName = "";
|
||||||
bool returnValue = false;
|
bool returnValue = true;
|
||||||
|
|
||||||
{
|
{
|
||||||
QSqlDatabase db = loadDatabaseFromFile(fullPath);
|
QSqlDatabase db = loadDatabaseFromFile(fullPath);
|
||||||
if (db.isValid() && db.isOpen()) {
|
if (db.isValid() && db.isOpen()) {
|
||||||
QSqlQuery updateVersion(db);
|
|
||||||
updateVersion.prepare("UPDATE db_info SET "
|
|
||||||
"version = :version");
|
|
||||||
updateVersion.bindValue(":version", DB_VERSION);
|
|
||||||
updateVersion.exec();
|
|
||||||
|
|
||||||
if (updateVersion.numRowsAffected() > 0)
|
|
||||||
returnValue = true;
|
|
||||||
|
|
||||||
if (pre7) // TODO: execute only if previous version was < 7.0
|
if (pre7) // TODO: execute only if previous version was < 7.0
|
||||||
{
|
{
|
||||||
// new 7.0 fields
|
// new 7.0 fields
|
||||||
@ -1041,6 +1040,52 @@ bool DataBaseManagement::updateToCurrentVersion(const QString &path)
|
|||||||
returnValue = returnValue && successMigratingManga;
|
returnValue = returnValue && successMigratingManga;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ensure that INTEGER types migrated to TEXT are actually changed in the table definition to avoid internal type castings, this happened in 9.13 but a migration wasn't shipped with that version.
|
||||||
|
if (pre9_14) {
|
||||||
|
{
|
||||||
|
bool pre9_14_successfulMigration = true;
|
||||||
|
|
||||||
|
QSqlQuery pragmaFKOFF(db);
|
||||||
|
pragmaFKOFF.prepare("PRAGMA foreign_keys=OFF");
|
||||||
|
pre9_14_successfulMigration = pre9_14_successfulMigration && pragmaFKOFF.exec();
|
||||||
|
|
||||||
|
db.transaction();
|
||||||
|
|
||||||
|
pre9_14_successfulMigration = pre9_14_successfulMigration && createComicInfoTable(db, "comic_info_migration");
|
||||||
|
|
||||||
|
QSqlQuery copyComicInfoToComicInfoMigration(db);
|
||||||
|
copyComicInfoToComicInfoMigration.prepare("INSERT INTO comic_info_migration SELECT * FROM comic_info");
|
||||||
|
pre9_14_successfulMigration = pre9_14_successfulMigration && copyComicInfoToComicInfoMigration.exec();
|
||||||
|
|
||||||
|
QSqlQuery dropComicInfo(db);
|
||||||
|
dropComicInfo.prepare("DROP TABLE comic_info");
|
||||||
|
pre9_14_successfulMigration = pre9_14_successfulMigration && dropComicInfo.exec();
|
||||||
|
|
||||||
|
QSqlQuery renameComicInfoMigrationToComicInfo(db);
|
||||||
|
renameComicInfoMigrationToComicInfo.prepare("ALTER TABLE comic_info_migration RENAME TO comic_info");
|
||||||
|
pre9_14_successfulMigration = pre9_14_successfulMigration && renameComicInfoMigrationToComicInfo.exec();
|
||||||
|
|
||||||
|
if (pre9_14_successfulMigration)
|
||||||
|
db.commit();
|
||||||
|
else
|
||||||
|
db.rollback();
|
||||||
|
|
||||||
|
QSqlQuery pragmaFKON1("PRAGMA foreign_keys=ON", db);
|
||||||
|
|
||||||
|
returnValue = returnValue && pre9_14_successfulMigration;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (returnValue) {
|
||||||
|
QSqlQuery updateVersion(db);
|
||||||
|
updateVersion.prepare("UPDATE db_info SET "
|
||||||
|
"version = :version");
|
||||||
|
updateVersion.bindValue(":version", DB_VERSION);
|
||||||
|
updateVersion.exec();
|
||||||
|
|
||||||
|
returnValue = updateVersion.numRowsAffected() > 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
connectionName = db.connectionName();
|
connectionName = db.connectionName();
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,7 @@ public:
|
|||||||
static QSqlDatabase loadDatabase(QString path);
|
static QSqlDatabase loadDatabase(QString path);
|
||||||
static QSqlDatabase loadDatabaseFromFile(QString path);
|
static QSqlDatabase loadDatabaseFromFile(QString path);
|
||||||
static bool createTables(QSqlDatabase &database);
|
static bool createTables(QSqlDatabase &database);
|
||||||
|
static bool createComicInfoTable(QSqlDatabase &database, QString tableName);
|
||||||
static bool createV8Tables(QSqlDatabase &database);
|
static bool createV8Tables(QSqlDatabase &database);
|
||||||
|
|
||||||
static void exportComicsInfo(QString source, QString dest);
|
static void exportComicsInfo(QString source, QString dest);
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
// Used to check if the database needs to be updated, the version is stored in the database.
|
// Used to check if the database needs to be updated, the version is stored in the database.
|
||||||
// This value is only incremented when the database structure changes.
|
// This value is only incremented when the database structure changes.
|
||||||
#define DB_VERSION "9.13.1"
|
#define DB_VERSION "9.14.0"
|
||||||
|
|
||||||
#define IMPORT_COMIC_INFO_XML_METADATA "IMPORT_COMIC_INFO_XML_METADATA"
|
#define IMPORT_COMIC_INFO_XML_METADATA "IMPORT_COMIC_INFO_XML_METADATA"
|
||||||
#define COMPARE_MODIFIED_DATE_ON_LIBRARY_UPDATES "COMPARE_MODIFIED_DATE_ON_LIBRARY_UPDATES"
|
#define COMPARE_MODIFIED_DATE_ON_LIBRARY_UPDATES "COMPARE_MODIFIED_DATE_ON_LIBRARY_UPDATES"
|
||||||
|
@ -58,6 +58,8 @@ YACReader::WhatsNewDialog::WhatsNewDialog(QWidget *parent)
|
|||||||
" • Improve content reloading. Navigation and selection state is no longer reseted after content changes (e.g. library updates, tags edits, etc.).<br/>"
|
" • Improve content reloading. Navigation and selection state is no longer reseted after content changes (e.g. library updates, tags edits, etc.).<br/>"
|
||||||
" • The app will try to move comics and folders to the trash bin when deletions are requested, if the file system used doesn't support trash bin the files will be removed permanetly.<br/>"
|
" • The app will try to move comics and folders to the trash bin when deletions are requested, if the file system used doesn't support trash bin the files will be removed permanetly.<br/>"
|
||||||
" • Add menu to choose what columns are displayed in the table comics view (do a right click on the header to show it). The view has new 3 new headers to choose from (Series, Volume and Story arc).<br/>"
|
" • Add menu to choose what columns are displayed in the table comics view (do a right click on the header to show it). The view has new 3 new headers to choose from (Series, Volume and Story arc).<br/>"
|
||||||
|
" • Migrate `number` and `arcNumber` data types to `TEXT`. This only affects databases created before 9.13 and it fixes problems with some formats of numbers (e.g. 1.10).<br/>"
|
||||||
|
"<br/>"
|
||||||
"<span style=\"font-weight:600\">YACReaderLibraryServer</span><br/>"
|
"<span style=\"font-weight:600\">YACReaderLibraryServer</span><br/>"
|
||||||
" • Add `rescan-xml-info` command.<br/>"
|
" • Add `rescan-xml-info` command.<br/>"
|
||||||
"<br/>"
|
"<br/>"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user