MCPcopy Create free account
hub / github.com/ipython/ipython / catch_corrupt_db

Function catch_corrupt_db

IPython/core/history.py:78–119  ·  view source on GitHub ↗

A decorator which wraps HistoryAccessor method calls to catch errors from a corrupt SQLite database, move the old database out of the way, and create a new one. We avoid clobbering larger databases because this may be triggered due to filesystem issues, not just a corrupt file.

(f, self, *a, **kw)

Source from the content-addressed store, hash-verified

76
77@decorator
78def catch_corrupt_db(f, self, *a, **kw):
79 """A decorator which wraps HistoryAccessor method calls to catch errors from
80 a corrupt SQLite database, move the old database out of the way, and create
81 a new one.
82
83 We avoid clobbering larger databases because this may be triggered due to filesystem issues,
84 not just a corrupt file.
85 """
86 try:
87 return f(self, *a, **kw)
88 except (DatabaseError, OperationalError) as e:
89 self._corrupt_db_counter += 1
90 self.log.error("Failed to open SQLite history %s (%s).", self.hist_file, e)
91 if self.hist_file != ':memory:':
92 if self._corrupt_db_counter > self._corrupt_db_limit:
93 self.hist_file = ':memory:'
94 self.log.error("Failed to load history too many times, history will not be saved.")
95 elif os.path.isfile(self.hist_file):
96 # move the file out of the way
97 base, ext = os.path.splitext(self.hist_file)
98 size = os.stat(self.hist_file).st_size
99 if size >= _SAVE_DB_SIZE:
100 # if there's significant content, avoid clobbering
101 now = datetime.datetime.now().isoformat().replace(':', '.')
102 newpath = base + '-corrupt-' + now + ext
103 # don't clobber previous corrupt backups
104 for i in range(100):
105 if not os.path.isfile(newpath):
106 break
107 else:
108 newpath = base + '-corrupt-' + now + (u'-%i' % i) + ext
109 else:
110 # not much content, possibly empty; don't worry about clobbering
111 # maybe we should just delete it?
112 newpath = base + '-corrupt' + ext
113 os.rename(self.hist_file, newpath)
114 self.log.error("History file was moved to %s and a new file created.", newpath)
115 self.init_db()
116 return []
117 else:
118 # Failed with :memory:, something serious is wrong
119 raise
120
121class HistoryAccessorBase(LoggingConfigurable):
122 """An abstract class for History Accessors """

Callers

nothing calls this directly

Calls 3

errorMethod · 0.80
init_dbMethod · 0.80
fFunction · 0.50

Tested by

no test coverage detected