Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fix empty podcast list on DB migration (bug 1198)
Thanks to all who reported this bug. This fix works for
both unmigrated 2.7 databases and 2.9 databases for which
migration has failed (but due to the way the data is saved,
this only works when you have not added any podcasts since
the migration took place.
  • Loading branch information
thp committed Jan 11, 2011
1 parent 7491373 commit 5c2b190
Showing 1 changed file with 41 additions and 12 deletions.
53 changes: 41 additions & 12 deletions src/gpodder/dbsqlite.py
Expand Up @@ -607,9 +607,12 @@ def force_last_new(self, channel):
cur.close()
self.lock.release()

def _upgrade_name(self, table_name):
return table_name + '_save'

def recreate_table(self, cur, table_name, fields, index_list):
log('Rename table %s', table_name, sender=self)
new_table_name = table_name + "_save"
new_table_name = self._upgrade_name(table_name)
cur.execute("ALTER TABLE %s RENAME TO %s" % (table_name, new_table_name))
#log("ALTER TABLE %s RENAME TO %s" % (table_name, new_table_name))

Expand Down Expand Up @@ -650,27 +653,53 @@ def upgrade_table(self, table_name, fields, index_list):
cur.execute("PRAGMA table_info(%s)" % table_name)
available = cur.fetchall()

# Check if an old migration to 2.9 failed and recover (bug 1198)
new_table_name = self._upgrade_name(table_name)
cur.execute("PRAGMA table_info(%s)" % new_table_name)
available_migration = cur.fetchall()
if available and available_migration:
# Both tables exist - check if our podcasts table is empty
# and if so, assume the last migration failed and recover
def count_rows(table_name):
cur.execute('SELECT COUNT(*) FROM %s' % table_name)
return cur.fetchone()[0]

real_count = count_rows(table_name)
migr_count = count_rows(new_table_name)

if real_count == 0 and migr_count > 0:
log('Recovering from previous failed migration', sender=self)
cur.execute('DROP TABLE %s' % table_name)
cur.execute('ALTER TABLE %s RENAME TO %s' % (new_table_name, table_name))

# Cleanup any remaining migration table contents after we
# have tried to recover from bug 1198, so contents do not
# get re-imported when all podcasts are deleted by the user
cur.execute('DROP TABLE IF EXISTS %s' % new_table_name)

if not available:
self.create_table(cur, table_name, fields)

else:
# Table info columns, as returned by SQLite
ID, NAME, TYPE, NOTNULL, DEFAULT = range(5)

# Check first if we have any "not null" columns
exists_notnull_column = any(bool(column[NOTNULL]) for column in available)

# Must add missing columns before recreate_table()
# otherwise http://gpodder.org/bug/1198 occurs!
existing = set(column[NAME] for column in available)
for field_name, field_type, field_required, field_default in fields:
if field_name not in existing:
log('Adding column: %s.%s (%s)', table_name, field_name, field_type, sender=self)
sql = "ALTER TABLE %s ADD COLUMN %s %s" % (table_name, field_name, field_type)
if field_required:
sql += " NOT NULL DEFAULT %s" % (field_default)
cur.execute(sql)

if not exists_notnull_column:
self.recreate_table(cur, table_name, fields, index_list)

else:
existing = set(column[NAME] for column in available)
for field_name, field_type, field_required, field_default in fields:
if field_name not in existing:
log('Adding column: %s.%s (%s)', table_name, field_name, field_type, sender=self)
sql = "ALTER TABLE %s ADD COLUMN %s %s" % (table_name, field_name, field_type)
if field_required:
sql += " NOT NULL DEFAULT %s" % (field_default)
cur.execute(sql)

for column, typ in index_list:
cur.execute('CREATE %s IF NOT EXISTS idx_%s ON %s (%s)' % (typ, column, table_name, column))

Expand Down

0 comments on commit 5c2b190

Please sign in to comment.