##// END OF EJS Templates
only avoid clobbering corrupt dbs that have some content...
Min RK -
Show More
@@ -71,11 +71,18 b' else:'
71 class OperationalError(Exception):
71 class OperationalError(Exception):
72 "Dummy exception when sqlite could not be imported. Should never occur."
72 "Dummy exception when sqlite could not be imported. Should never occur."
73
73
74 # use 16kB as threshold for whether a corrupt history db should be saved
75 # that should be at least 100 entries or so
76 _SAVE_DB_SIZE = 16384
77
74 @decorator
78 @decorator
75 def catch_corrupt_db(f, self, *a, **kw):
79 def catch_corrupt_db(f, self, *a, **kw):
76 """A decorator which wraps HistoryAccessor method calls to catch errors from
80 """A decorator which wraps HistoryAccessor method calls to catch errors from
77 a corrupt SQLite database, move the old database out of the way, and create
81 a corrupt SQLite database, move the old database out of the way, and create
78 a new one.
82 a new one.
83
84 We avoid clobbering larger databases because this may be triggered due to filesystem issues,
85 not just a corrupt file.
79 """
86 """
80 try:
87 try:
81 return f(self, *a, **kw)
88 return f(self, *a, **kw)
@@ -87,16 +94,23 b' def catch_corrupt_db(f, self, *a, **kw):'
87 self.hist_file = ':memory:'
94 self.hist_file = ':memory:'
88 self.log.error("Failed to load history too many times, history will not be saved.")
95 self.log.error("Failed to load history too many times, history will not be saved.")
89 elif os.path.isfile(self.hist_file):
96 elif os.path.isfile(self.hist_file):
90 # Try to move the file out of the way
97 # move the file out of the way
91 base,ext = os.path.splitext(self.hist_file)
98 base, ext = os.path.splitext(self.hist_file)
92 now = datetime.datetime.now().isoformat().replace(':', '.')
99 size = os.stat(self.hist_file).st_size
93 newpath = base + '-corrupt-' + now + ext
100 if size >= _SAVE_DB_SIZE:
94 # don't clobber previous corrupt backups
101 # if there's significant content, avoid clobbering
95 for i in range(100):
102 now = datetime.datetime.now().isoformat().replace(':', '.')
96 if not os.path.isfile(newpath):
103 newpath = base + '-corrupt-' + now + ext
97 break
104 # don't clobber previous corrupt backups
98 else:
105 for i in range(100):
99 newpath = base + '-corrupt-' + now + (u'-%i' % i) + ext
106 if not os.path.isfile(newpath):
107 break
108 else:
109 newpath = base + '-corrupt-' + now + (u'-%i' % i) + ext
110 else:
111 # not much content, possibly empty; don't worry about clobbering
112 # maybe we should just delete it?
113 newpath = base + '-corrupt' + ext
100 os.rename(self.hist_file, newpath)
114 os.rename(self.hist_file, newpath)
101 self.log.error("History file was moved to %s and a new file created.", newpath)
115 self.log.error("History file was moved to %s and a new file created.", newpath)
102 self.init_db()
116 self.init_db()
General Comments 0
You need to be logged in to leave comments. Login now