newdb: Automatically sanitize ratings tables that contain rating records

This commit is contained in:
Kovid Goyal 2013-08-30 21:21:19 +05:30
parent 6d667dbc8f
commit fb8ab757f5
2 changed files with 18 additions and 3 deletions

View File

@ -32,7 +32,7 @@ from calibre.utils.magick.draw import save_cover_data_to
from calibre.utils.formatter_functions import load_user_template_functions
from calibre.db.tables import (OneToOneTable, ManyToOneTable, ManyToManyTable,
SizeTable, FormatsTable, AuthorsTable, IdentifiersTable, PathTable,
CompositeTable, UUIDTable)
CompositeTable, UUIDTable, RatingTable)
# }}}
'''
@ -702,14 +702,15 @@ class DB(object):
metadata['column'] = col
tables[col] = (PathTable if col == 'path' else UUIDTable if col == 'uuid' else OneToOneTable)(col, metadata)
for col in ('series', 'publisher', 'rating'):
for col in ('series', 'publisher'):
tables[col] = ManyToOneTable(col, self.field_metadata[col].copy())
for col in ('authors', 'tags', 'formats', 'identifiers', 'languages'):
for col in ('authors', 'tags', 'formats', 'identifiers', 'languages', 'rating'):
cls = {
'authors':AuthorsTable,
'formats':FormatsTable,
'identifiers':IdentifiersTable,
'rating':RatingTable,
}.get(col, ManyToManyTable)
tables[col] = cls(col, self.field_metadata[col].copy())

View File

@ -276,6 +276,20 @@ class ManyToOneTable(Table):
self.link_table, lcol, table), (existing_item, item_id, item_id))
return affected_books, new_id
class RatingTable(ManyToOneTable):
def read_id_maps(self, db):
ManyToOneTable.read_id_maps(self, db)
# Ensure there are no records with rating=0 in the table. These should
# be represented as rating:None instead.
bad_ids = {item_id for item_id, rating in self.id_map.iteritems() if rating == 0}
if bad_ids:
self.id_map = {item_id:rating for item_id, rating in self.id_map.iteritems() if rating != 0}
db.conn.executemany('DELETE FROM {0} WHERE {1}=?'.format(self.link_table, self.metadata['link_column']),
tuple((x,) for x in bad_ids))
db.conn.execute('DELETE FROM {0} WHERE {1}=0'.format(
self.metadata['table'], self.metadata['column']))
class ManyToManyTable(ManyToOneTable):
'''