Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions src/database/schemamanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,24 @@ SchemaManager::Result SchemaManager::upgradeToSchemaVersion(
}
FwdSqlQuery query(m_database, statement);
result = query.isPrepared() && query.execPrepared();
if (!result &&
query.hasError() &&
query.lastError().databaseText().startsWith(
QStringLiteral("duplicate column name: "))) {
// New columns may have already been added during a previous
// migration to a different (= preceding) schema version. This
// is a very common situation during development when switching
// between schema versions. Since SQLite does not allow to add
// new columns only if they do not yet exist we need to account
// for and handle those errors here after they occurred. If the
// remaining migration finishes without other errors this is
// probably ok.
kLogger.warning()
<< "Ignoring failed statement"
<< statement
<< "and continuing with schema migration";
result = true;
}
}

if (result) {
Expand Down
27 changes: 24 additions & 3 deletions src/test/schemamanager_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,28 @@ TEST_F(SchemaManagerTest, BackwardsIncompatibleVersion) {
EXPECT_EQ(SchemaManager::Result::NewerVersionIncompatible, result);
}

TEST_F(SchemaManagerTest, FailedUpgrade) {
TEST_F(SchemaManagerTest, IgnoreDuplicateColumn) {
// Establish preconditions for test
{
// Upgrade to version 3 to get the modern library table.
SchemaManager schemaManager(dbConnection());
SchemaManager::Result result = schemaManager.upgradeToSchemaVersion(
MixxxDb::kDefaultSchemaFile, 3);
ASSERT_EQ(SchemaManager::Result::UpgradeSucceeded, result);
}

// Add a column that will be added again in version 24.
QSqlQuery query(dbConnection());
ASSERT_TRUE(query.exec(
"ALTER TABLE library ADD COLUMN coverart_source TEXT"));

SchemaManager schemaManager(dbConnection());
SchemaManager::Result result = schemaManager.upgradeToSchemaVersion(
MixxxDb::kDefaultSchemaFile, MixxxDb::kRequiredSchemaVersion);
EXPECT_EQ(SchemaManager::Result::UpgradeSucceeded, result);
}

TEST_F(SchemaManagerTest, UpgradeFailed) {
// Establish preconditions for test
{
// Upgrade to version 3 to get the modern library table.
Expand All @@ -114,10 +135,10 @@ TEST_F(SchemaManagerTest, FailedUpgrade) {
EXPECT_EQ(SchemaManager::Result::UpgradeSucceeded, result);
}

// Add a column that is added in version 24.
// Drop a table that is expected to exist.
QSqlQuery query(dbConnection());
EXPECT_TRUE(query.exec(
"ALTER TABLE library ADD COLUMN coverart_source TEXT"));
"DROP TABLE PlaylistTracks"));

SchemaManager schemaManager(dbConnection());
SchemaManager::Result result = schemaManager.upgradeToSchemaVersion(
Expand Down
12 changes: 6 additions & 6 deletions src/util/db/fwdsqlquery.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#ifndef MIXXX_FWDSQLQUERY_H
#define MIXXX_FWDSQLQUERY_H
#pragma once


#include <QSqlQuery>
Expand Down Expand Up @@ -45,7 +44,11 @@ class FwdSqlQuery: protected QSqlQuery {
}

bool hasError() const {
return lastError().isValid() && (lastError().type() != QSqlError::NoError);
return lastError().isValid() &&
(lastError().type() != QSqlError::NoError);
}
QSqlError lastError() const {
return QSqlQuery::lastError();
}

static const int BOOLEAN_FALSE = 0;
Expand Down Expand Up @@ -112,6 +115,3 @@ class FwdSqlQuery: protected QSqlQuery {

bool m_prepared;
};


#endif // MIXXX_FWDSQLQUERY_H