diff --git a/changes/bug-7441-make-migration-more-robust b/changes/bug-7441-make-migration-more-robust new file mode 100644 index 0000000000..78993d9f73 --- /dev/null +++ b/changes/bug-7441-make-migration-more-robust @@ -0,0 +1,2 @@ +If there are two or more entries in the software table with the same name, version, source, release +and arch but different vendors then the migration used for increasing the vendor width will fail. diff --git a/server/datastore/mysql/migrations/tables/20220818101352_ChangeSoftwareVendorWidth.go b/server/datastore/mysql/migrations/tables/20220818101352_ChangeSoftwareVendorWidth.go index 8fc684ccd7..acba4057aa 100644 --- a/server/datastore/mysql/migrations/tables/20220818101352_ChangeSoftwareVendorWidth.go +++ b/server/datastore/mysql/migrations/tables/20220818101352_ChangeSoftwareVendorWidth.go @@ -16,17 +16,11 @@ func Up_20220818101352(tx *sql.Tx) error { //----------------- // Add temp column. //----------------- - if _, err := tx.Exec( - `ALTER TABLE software ADD COLUMN vendor_wide varchar(114) DEFAULT '' NOT NULL, ALGORITHM=INPLACE, LOCK=NONE`); err != nil { - return errors.Wrapf(err, "creating temp column for vendor") - } - - //--------------------- - // Add uniq constraint - //--------------------- - if _, err := tx.Exec( - "ALTER TABLE software ADD constraint unq_name UNIQUE (name, version, source, `release`, vendor_wide, arch)"); err != nil { - return errors.Wrapf(err, "adding new uniquess constraint") + if !columnExists(tx, "software", "vendor_wide") { + if _, err := tx.Exec( + `ALTER TABLE software ADD COLUMN vendor_wide varchar(114) DEFAULT '' NOT NULL, ALGORITHM=INPLACE, LOCK=NONE`); err != nil { + return errors.Wrapf(err, "creating temp column for vendor") + } } //------------------ @@ -38,6 +32,14 @@ func Up_20220818101352(tx *sql.Tx) error { return errors.Wrapf(err, "updating temp vendor column") } + //--------------------- + // Add uniq constraint + //--------------------- + if _, err := tx.Exec( + "ALTER TABLE software ADD constraint unq_name UNIQUE (name, version, source, `release`, vendor_wide, arch)"); err != nil { + return errors.Wrapf(err, "adding new uniquess constraint") + } + //---------------- // Drop old index //---------------- diff --git a/server/datastore/mysql/migrations/tables/20220818101352_ChangeSoftwareVendorWidth_test.go b/server/datastore/mysql/migrations/tables/20220818101352_ChangeSoftwareVendorWidth_test.go index 26bdbdb7ad..3cef1c9ee2 100644 --- a/server/datastore/mysql/migrations/tables/20220818101352_ChangeSoftwareVendorWidth_test.go +++ b/server/datastore/mysql/migrations/tables/20220818101352_ChangeSoftwareVendorWidth_test.go @@ -12,6 +12,7 @@ func TestUp_20220818101352(t *testing.T) { _, err := db.Exec(`INSERT INTO software (name, version, source, bundle_identifier, vendor, arch) VALUES ('zchunk-libs', '1.2.1', 'rpm_packages', '', 'Fedora Project', 'x86_64'), + ('zchunk-libs', '1.2.1', 'rpm_packages', '', 'Fedora Project II', 'x86_64'), ('word', '1.2.1', 'rpm_packages', '', 'Fake MS', 'x86_64'), ('excel', '1.2.1', 'rpm_packages', '', '', 'x86_64') `) @@ -24,7 +25,7 @@ func TestUp_20220818101352(t *testing.T) { var vendors []string err = db.Select(&vendors, `SELECT vendor FROM software`) require.NoError(t, err) - require.ElementsMatch(t, []string{"Fedora Project", "Fake MS", ""}, vendors) + require.ElementsMatch(t, []string{"Fedora Project", "Fedora Project II", "Fake MS", ""}, vendors) // Check we can store a longer vendors randVendor := `