Show More
@@ -62,6 +62,37 b' def needs_sqlite(f, self, *a, **kw):' | |||
|
62 | 62 | return f(self, *a, **kw) |
|
63 | 63 | |
|
64 | 64 | |
|
65 | if sqlite3 is not None: | |
|
66 | DatabaseError = sqlite3.DatabaseError | |
|
67 | else: | |
|
68 | class DatabaseError(Exception): | |
|
69 | "Dummy exception when sqlite could not be imported. Should never occur." | |
|
70 | ||
|
71 | @decorator | |
|
72 | def catch_corrupt_db(f, self, *a, **kw): | |
|
73 | """A decorator which wraps HistoryAccessor method calls to catch errors from | |
|
74 | a corrupt SQLite database, move the old database out of the way, create a | |
|
75 | new one, and optionally retry the function. | |
|
76 | """ | |
|
77 | try: | |
|
78 | return f(self, *a, **kw) | |
|
79 | except DatabaseError: | |
|
80 | if os.path.isfile(self.hist_file): | |
|
81 | # Try to move the file out of the way | |
|
82 | base,ext = os.path.splitext(self.hist_file) | |
|
83 | newpath = base + '-corrupt' + ext | |
|
84 | os.rename(self.hist_file, newpath) | |
|
85 | self.init_db() | |
|
86 | print("ERROR! History file wasn't a valid SQLite database.", | |
|
87 | "It was moved to %s" % newpath, "and a new file created.") | |
|
88 | return [] | |
|
89 | ||
|
90 | else: | |
|
91 | # The hist_file is probably :memory: or something else. | |
|
92 | raise | |
|
93 | ||
|
94 | ||
|
95 | ||
|
65 | 96 | class HistoryAccessor(Configurable): |
|
66 | 97 | """Access the history database without adding to it. |
|
67 | 98 | |
@@ -143,25 +174,7 b' class HistoryAccessor(Configurable):' | |||
|
143 | 174 | warn("IPython History requires SQLite, your history will not be saved\n") |
|
144 | 175 | self.enabled = False |
|
145 | 176 | |
|
146 | if sqlite3 is not None: | |
|
147 | DatabaseError = sqlite3.DatabaseError | |
|
148 | else: | |
|
149 | DatabaseError = Exception | |
|
150 | ||
|
151 | try: | |
|
152 | self.init_db() | |
|
153 | except DatabaseError: | |
|
154 | if os.path.isfile(self.hist_file): | |
|
155 | # Try to move the file out of the way | |
|
156 | base,ext = os.path.splitext(self.hist_file) | |
|
157 | newpath = base + '-corrupt' + ext | |
|
158 | os.rename(self.hist_file, newpath) | |
|
159 | print("ERROR! History file wasn't a valid SQLite database.", | |
|
160 | "It was moved to %s" % newpath, "and a new file created.") | |
|
161 | self.init_db() | |
|
162 | else: | |
|
163 | # The hist_file is probably :memory: or something else. | |
|
164 | raise | |
|
177 | self.init_db() | |
|
165 | 178 | |
|
166 | 179 | def _get_hist_file_name(self, profile='default'): |
|
167 | 180 | """Find the history file for the given profile name. |
@@ -176,6 +189,7 b' class HistoryAccessor(Configurable):' | |||
|
176 | 189 | """ |
|
177 | 190 | return os.path.join(locate_profile(profile), 'history.sqlite') |
|
178 | 191 | |
|
192 | @catch_corrupt_db | |
|
179 | 193 | def init_db(self): |
|
180 | 194 | """Connect to the database, and create tables if necessary.""" |
|
181 | 195 | if not self.enabled: |
@@ -207,6 +221,7 b' class HistoryAccessor(Configurable):' | |||
|
207 | 221 | ## ------------------------------- |
|
208 | 222 | ## Methods for retrieving history: |
|
209 | 223 | ## ------------------------------- |
|
224 | @catch_corrupt_db | |
|
210 | 225 | def _run_sql(self, sql, params, raw=True, output=False): |
|
211 | 226 | """Prepares and runs an SQL query for the history database. |
|
212 | 227 | |
@@ -235,6 +250,7 b' class HistoryAccessor(Configurable):' | |||
|
235 | 250 | return cur |
|
236 | 251 | |
|
237 | 252 | @needs_sqlite |
|
253 | @catch_corrupt_db | |
|
238 | 254 | def get_session_info(self, session=0): |
|
239 | 255 | """get info about a session |
|
240 | 256 |
General Comments 0
You need to be logged in to leave comments.
Login now