Show More
@@ -62,6 +62,37 b' def needs_sqlite(f, self, *a, **kw):' | |||||
62 | return f(self, *a, **kw) |
|
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 | class HistoryAccessor(Configurable): |
|
96 | class HistoryAccessor(Configurable): | |
66 | """Access the history database without adding to it. |
|
97 | """Access the history database without adding to it. | |
67 |
|
98 | |||
@@ -143,25 +174,7 b' class HistoryAccessor(Configurable):' | |||||
143 | warn("IPython History requires SQLite, your history will not be saved\n") |
|
174 | warn("IPython History requires SQLite, your history will not be saved\n") | |
144 | self.enabled = False |
|
175 | self.enabled = False | |
145 |
|
176 | |||
146 | if sqlite3 is not None: |
|
177 | self.init_db() | |
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 |
|
|||
165 |
|
178 | |||
166 | def _get_hist_file_name(self, profile='default'): |
|
179 | def _get_hist_file_name(self, profile='default'): | |
167 | """Find the history file for the given profile name. |
|
180 | """Find the history file for the given profile name. | |
@@ -176,6 +189,7 b' class HistoryAccessor(Configurable):' | |||||
176 | """ |
|
189 | """ | |
177 | return os.path.join(locate_profile(profile), 'history.sqlite') |
|
190 | return os.path.join(locate_profile(profile), 'history.sqlite') | |
178 |
|
191 | |||
|
192 | @catch_corrupt_db | |||
179 | def init_db(self): |
|
193 | def init_db(self): | |
180 | """Connect to the database, and create tables if necessary.""" |
|
194 | """Connect to the database, and create tables if necessary.""" | |
181 | if not self.enabled: |
|
195 | if not self.enabled: | |
@@ -207,6 +221,7 b' class HistoryAccessor(Configurable):' | |||||
207 | ## ------------------------------- |
|
221 | ## ------------------------------- | |
208 | ## Methods for retrieving history: |
|
222 | ## Methods for retrieving history: | |
209 | ## ------------------------------- |
|
223 | ## ------------------------------- | |
|
224 | @catch_corrupt_db | |||
210 | def _run_sql(self, sql, params, raw=True, output=False): |
|
225 | def _run_sql(self, sql, params, raw=True, output=False): | |
211 | """Prepares and runs an SQL query for the history database. |
|
226 | """Prepares and runs an SQL query for the history database. | |
212 |
|
227 | |||
@@ -235,6 +250,7 b' class HistoryAccessor(Configurable):' | |||||
235 | return cur |
|
250 | return cur | |
236 |
|
251 | |||
237 | @needs_sqlite |
|
252 | @needs_sqlite | |
|
253 | @catch_corrupt_db | |||
238 | def get_session_info(self, session=0): |
|
254 | def get_session_info(self, session=0): | |
239 | """get info about a session |
|
255 | """get info about a session | |
240 |
|
256 |
General Comments 0
You need to be logged in to leave comments.
Login now