Warn user when database is corrupted and unreadable. Fixes #3761

This commit is contained in:
Yann Leboulanger 2008-03-17 07:22:43 +00:00
parent 2e7d8f7486
commit 0d427eff3b
4 changed files with 84 additions and 60 deletions

View File

@ -37,6 +37,7 @@ import re
from common import gajim from common import gajim
from common import helpers from common import helpers
from common import exceptions
from message_control import MessageControl from message_control import MessageControl
from conversation_textview import ConversationTextview from conversation_textview import ConversationTextview
from message_textview import MessageTextView from message_textview import MessageTextView
@ -2004,8 +2005,13 @@ class ChatControl(ChatControlBase):
pending_how_many += len(gajim.events.get_events(self.account, pending_how_many += len(gajim.events.get_events(self.account,
self.contact.get_full_jid(), ['chat', 'pm'])) self.contact.get_full_jid(), ['chat', 'pm']))
rows = gajim.logger.get_last_conversation_lines(jid, restore_how_many, try:
pending_how_many, timeout, self.account) rows = gajim.logger.get_last_conversation_lines(jid, restore_how_many,
pending_how_many, timeout, self.account)
except exceptions.DatabaseMalformed:
dialogs.ErrorDialog(_('Database Error'),
_('The database file (%s) cannot be read. Try to repare it or remove it (all history will be lost).') % common.logger.LOG_DB_PATH)
rows = []
local_old_kind = None local_old_kind = None
for row in rows: # row[0] time, row[1] has kind, row[2] the message for row in rows: # row[0] time, row[1] has kind, row[2] the message
if not row[2]: # message is empty, we don't print it if not row[2]: # message is empty, we don't print it

View File

@ -35,6 +35,14 @@ class PysqliteOperationalError(Exception):
def __str__(self): def __str__(self):
return self.text return self.text
class DatabaseMalformed(Exception):
'''The databas can't be read'''
def __init__(self):
Exception.__init__(self)
def __str__(self):
return _('Database cannot be read.')
class ServiceNotAvailable(Exception): class ServiceNotAvailable(Exception):
'''This exception is raised when we cannot use Gajim remotely''' '''This exception is raised when we cannot use Gajim remotely'''
def __init__(self): def __init__(self):

View File

@ -136,8 +136,11 @@ class Logger:
self.get_jids_already_in_db() self.get_jids_already_in_db()
def get_jids_already_in_db(self): def get_jids_already_in_db(self):
self.cur.execute('SELECT jid FROM jids') try:
rows = self.cur.fetchall() # list of tupples: [(u'aaa@bbb',), (u'cc@dd',)] self.cur.execute('SELECT jid FROM jids')
rows = self.cur.fetchall() # list of tupples: [(u'aaa@bbb',), (u'cc@dd',)]
except sqlite.DatabaseError:
raise exceptions.DatabaseMalformed
self.jids_already_in = [] self.jids_already_in = []
for row in rows: for row in rows:
# row[0] is first item of row (the only result here, the jid) # row[0] is first item of row (the only result here, the jid)
@ -443,17 +446,20 @@ class Logger:
timed_out = now - (timeout * 60) # before that they are too old timed_out = now - (timeout * 60) # before that they are too old
# so if we ask last 5 lines and we have 2 pending we get # so if we ask last 5 lines and we have 2 pending we get
# 3 - 8 (we avoid the last 2 lines but we still return 5 asked) # 3 - 8 (we avoid the last 2 lines but we still return 5 asked)
self.cur.execute(''' try:
SELECT time, kind, message FROM logs self.cur.execute('''
WHERE (%s) AND kind IN (%d, %d, %d, %d, %d) AND time > %d SELECT time, kind, message FROM logs
ORDER BY time DESC LIMIT %d OFFSET %d WHERE (%s) AND kind IN (%d, %d, %d, %d, %d) AND time > %d
''' % (where_sql, constants.KIND_SINGLE_MSG_RECV, ORDER BY time DESC LIMIT %d OFFSET %d
constants.KIND_CHAT_MSG_RECV, constants.KIND_SINGLE_MSG_SENT, ''' % (where_sql, constants.KIND_SINGLE_MSG_RECV,
constants.KIND_CHAT_MSG_SENT, constants.KIND_ERROR, constants.KIND_CHAT_MSG_RECV, constants.KIND_SINGLE_MSG_SENT,
timed_out, restore_how_many_rows, pending_how_many) constants.KIND_CHAT_MSG_SENT, constants.KIND_ERROR,
) timed_out, restore_how_many_rows, pending_how_many)
)
results = self.cur.fetchall() results = self.cur.fetchall()
except sqlite.DatabaseError:
raise exceptions.DatabaseMalformed
results.reverse() results.reverse()
return results return results

View File

@ -145,57 +145,56 @@ except Warning, msg:
sys.exit() sys.exit()
warnings.resetwarnings() warnings.resetwarnings()
import message_control pritext = ''
from chat_control import ChatControlBase
from atom_window import AtomWindow
import negotiation
from common import exceptions from common import exceptions
from common.zeroconf import connection_zeroconf
from common import dbus_support
if dbus_support.supported:
import dbus
if os.name == 'posix': # dl module is Unix Only
try: # rename the process name to gajim
import dl
libc = dl.open('/lib/libc.so.6')
libc.call('prctl', 15, 'gajim\0', 0, 0, 0)
except:
pass
pritext = ''
if gtk.pygtk_version < (2, 8, 0):
pritext = _('Gajim needs PyGTK 2.8 or above')
sectext = _('Gajim needs PyGTK 2.8 or above to run. Quiting...')
elif gtk.gtk_version < (2, 8, 0):
pritext = _('Gajim needs GTK 2.8 or above')
sectext = _('Gajim needs GTK 2.8 or above to run. Quiting...')
try: try:
import gtk.glade # check if user has libglade (in pygtk and in gtk) from common import gajim
except ImportError: except exceptions.DatabaseMalformed:
pritext = _('GTK+ runtime is missing libglade support') pritext = _('Database Error')
if os.name == 'nt': sectext = _('The database file (%s) cannot be read. Try to repare it or remove it (all history will be lost).') % common.logger.LOG_DB_PATH
sectext = _('Please remove your current GTK+ runtime and install the latest stable version from %s') % 'http://gladewin32.sourceforge.net' else:
else: from common import dbus_support
sectext = _('Please make sure that GTK+ and PyGTK have libglade support in your system.') if dbus_support.supported:
import dbus
try: if os.name == 'posix': # dl module is Unix Only
from common import check_paths try: # rename the process name to gajim
except exceptions.PysqliteNotAvailable, e: import dl
pritext = _('Gajim needs PySQLite2 to run') libc = dl.open('/lib/libc.so.6')
sectext = str(e) libc.call('prctl', 15, 'gajim\0', 0, 0, 0)
except:
pass
if gtk.pygtk_version < (2, 8, 0):
pritext = _('Gajim needs PyGTK 2.8 or above')
sectext = _('Gajim needs PyGTK 2.8 or above to run. Quiting...')
elif gtk.gtk_version < (2, 8, 0):
pritext = _('Gajim needs GTK 2.8 or above')
sectext = _('Gajim needs GTK 2.8 or above to run. Quiting...')
if os.name == 'nt':
try: try:
import winsound # windows-only built-in module for playing wav import gtk.glade # check if user has libglade (in pygtk and in gtk)
import win32api # do NOT remove. we req this module except ImportError:
except: pritext = _('GTK+ runtime is missing libglade support')
pritext = _('Gajim needs pywin32 to run') if os.name == 'nt':
sectext = _('Please make sure that Pywin32 is installed on your system. You can get it at %s') % 'http://sourceforge.net/project/showfiles.php?group_id=78018' sectext = _('Please remove your current GTK+ runtime and install the latest stable version from %s') % 'http://gladewin32.sourceforge.net'
else:
sectext = _('Please make sure that GTK+ and PyGTK have libglade support in your system.')
try:
from common import check_paths
except exceptions.PysqliteNotAvailable, e:
pritext = _('Gajim needs PySQLite2 to run')
sectext = str(e)
if os.name == 'nt':
try:
import winsound # windows-only built-in module for playing wav
import win32api # do NOT remove. we req this module
except:
pritext = _('Gajim needs pywin32 to run')
sectext = _('Please make sure that Pywin32 is installed on your system. You can get it at %s') % 'http://sourceforge.net/project/showfiles.php?group_id=78018'
if pritext: if pritext:
dlg = gtk.MessageDialog(None, dlg = gtk.MessageDialog(None,
@ -230,14 +229,19 @@ import math
import gtkgui_helpers import gtkgui_helpers
import notify import notify
import message_control
import negotiation
from chat_control import ChatControlBase
from atom_window import AtomWindow
import common.sleepy import common.sleepy
from common.xmpp import idlequeue from common.xmpp import idlequeue
from common.zeroconf import connection_zeroconf
from common import nslookup from common import nslookup
from common import proxy65_manager from common import proxy65_manager
from common import socks5 from common import socks5
from common import gajim
from common import helpers from common import helpers
from common import optparser from common import optparser
from common import dataforms from common import dataforms