Show More
@@ -13,6 +13,7 b'' | |||
|
13 | 13 | from __future__ import print_function |
|
14 | 14 | |
|
15 | 15 | # Stdlib imports |
|
16 | import datetime | |
|
16 | 17 | import os |
|
17 | 18 | import re |
|
18 | 19 | import sqlite3 |
@@ -90,6 +91,7 b' class HistoryManager(Configurable):' | |||
|
90 | 91 | histfname = 'history' |
|
91 | 92 | self.hist_file = os.path.join(shell.ipython_dir, histfname + '.sqlite') |
|
92 | 93 | self.init_db() |
|
94 | self.new_session() | |
|
93 | 95 | |
|
94 | 96 | self._i00, self._i, self._ii, self._iii = '','','','' |
|
95 | 97 | |
@@ -97,8 +99,11 b' class HistoryManager(Configurable):' | |||
|
97 | 99 | '%quit', '%Exit', '%exit']) |
|
98 | 100 | |
|
99 | 101 | def init_db(self): |
|
100 |
"""Connect to the database |
|
|
102 | """Connect to the database, and create tables if necessary.""" | |
|
101 | 103 | self.db = sqlite3.connect(self.hist_file) |
|
104 | self.db.execute("""CREATE TABLE IF NOT EXISTS sessions (session integer | |
|
105 | primary key autoincrement, start timestamp, | |
|
106 | end timestamp, num_cmds integer, remark text)""") | |
|
102 | 107 | self.db.execute("""CREATE TABLE IF NOT EXISTS history |
|
103 | 108 | (session integer, line integer, source text, source_raw text, |
|
104 | 109 | PRIMARY KEY (session, line))""") |
@@ -107,23 +112,47 b' class HistoryManager(Configurable):' | |||
|
107 | 112 | self.db.execute("""CREATE TABLE IF NOT EXISTS output_history |
|
108 | 113 | (session integer, line integer, output text, |
|
109 | 114 | PRIMARY KEY (session, line))""") |
|
110 | cur = self.db.execute("""SELECT name FROM sqlite_master WHERE | |
|
111 | type='table' AND name='singletons'""") | |
|
112 | if not cur.fetchone(): | |
|
113 | self.db.execute("""CREATE TABLE singletons | |
|
114 | (name text PRIMARY KEY, value)""") | |
|
115 | self.db.execute("""INSERT INTO singletons VALUES | |
|
116 | ('session_number', 1)""") | |
|
117 | self.db.commit() | |
|
118 | cur = self.db.execute("""SELECT value FROM singletons WHERE | |
|
119 | name='session_number'""") | |
|
120 | self.session_number = cur.fetchone()[0] | |
|
121 | ||
|
122 | #Increment by one for next session. | |
|
123 | self.db.execute("""UPDATE singletons SET value=? WHERE | |
|
124 | name='session_number'""", (self.session_number+1,)) | |
|
125 | 115 | self.db.commit() |
|
126 | 116 | |
|
117 | def new_session(self): | |
|
118 | """Get a new session number.""" | |
|
119 | with self.db: | |
|
120 | cur = self.db.execute("""INSERT INTO sessions VALUES (NULL, ?, NULL, | |
|
121 | NULL, "") """, (datetime.datetime.now(),)) | |
|
122 | self.session_number = cur.lastrowid | |
|
123 | ||
|
124 | def end_session(self): | |
|
125 | """Close the database session, filling in the end time and line count.""" | |
|
126 | self.writeout_cache() | |
|
127 | with self.db: | |
|
128 | self.db.execute("""UPDATE sessions SET end=?, num_cmds=? WHERE | |
|
129 | session==?""", (datetime.datetime.now(), | |
|
130 | len(self.input_hist_parsed)-1, self.session_number)) | |
|
131 | self.session_number = 0 | |
|
132 | ||
|
133 | def name_session(self, name): | |
|
134 | """Give the current session a name in the history database.""" | |
|
135 | with self.db: | |
|
136 | self.db.execute("UPDATE sessions SET remark=? WHERE session==?", | |
|
137 | (name, self.session_number)) | |
|
138 | ||
|
139 | def reset(self, new_session=True): | |
|
140 | """Clear the session history, releasing all object references, and | |
|
141 | optionally open a new session.""" | |
|
142 | if self.session_number: | |
|
143 | self.end_session() | |
|
144 | self.input_hist_parsed[:] = [""] | |
|
145 | self.input_hist_raw[:] = [""] | |
|
146 | self.output_hist.clear() | |
|
147 | # The directory history can't be completely empty | |
|
148 | self.dir_hist[:] = [os.getcwd()] | |
|
149 | ||
|
150 | if new_session: | |
|
151 | self.new_session() | |
|
152 | ||
|
153 | ## ------------------------------- | |
|
154 | ## Methods for retrieving history: | |
|
155 | ## ------------------------------- | |
|
127 | 156 | def _get_hist_sql(self, sql, params, raw=True, output=False): |
|
128 | 157 | """Prepares and runs an SQL query for the history database. |
|
129 | 158 | |
@@ -245,7 +274,10 b' class HistoryManager(Configurable):' | |||
|
245 | 274 | for sess, s, e in extract_hist_ranges(rangestr): |
|
246 | 275 | for line in self.get_history(sess, s, e, raw=raw, output=output): |
|
247 | 276 | yield line |
|
248 | ||
|
277 | ||
|
278 | ## ---------------------------- | |
|
279 | ## Methods for storing history: | |
|
280 | ## ---------------------------- | |
|
249 | 281 | def store_inputs(self, line_num, source, source_raw=None): |
|
250 | 282 | """Store source and raw input in history and create input cache |
|
251 | 283 | variables _i*. |
@@ -312,27 +344,6 b' class HistoryManager(Configurable):' | |||
|
312 | 344 | self.db_input_cache = [] |
|
313 | 345 | self.db_output_cache = [] |
|
314 | 346 | |
|
315 | def sync_inputs(self): | |
|
316 | """Ensure raw and translated histories have same length.""" | |
|
317 | lr = len(self.input_hist_raw) | |
|
318 | lp = len(self.input_hist_parsed) | |
|
319 | if lp < lr: | |
|
320 | self.input_hist_raw[:lr-lp] = [] | |
|
321 | elif lr < lp: | |
|
322 | self.input_hist_parsed[:lp-lr] = [] | |
|
323 | ||
|
324 | def reset(self, new_session=True): | |
|
325 | """Clear the current session's history, and (optionally) start a new | |
|
326 | session.""" | |
|
327 | self.input_hist_parsed[:] = [""] | |
|
328 | self.input_hist_raw[:] = [""] | |
|
329 | self.output_hist.clear() | |
|
330 | # The directory history can't be completely empty | |
|
331 | self.dir_hist[:] = [os.getcwd()] | |
|
332 | ||
|
333 | if new_session: | |
|
334 | self.writeout_cache() | |
|
335 | self.init_db() # Get new session number | |
|
336 | 347 | |
|
337 | 348 | # To match, e.g. ~5/8-~2/3 |
|
338 | 349 | range_re = re.compile(r""" |
@@ -2526,10 +2526,10 b' class InteractiveShell(Configurable, Magic):' | |||
|
2526 | 2526 | os.unlink(tfile) |
|
2527 | 2527 | except OSError: |
|
2528 | 2528 | pass |
|
2529 |
|
|
|
2530 | # Write anything in the history cache to the database. | |
|
2531 |
self.history_manager. |
|
|
2532 | ||
|
2529 | ||
|
2530 | # Close the history session (this stores the end time and line count) | |
|
2531 | self.history_manager.end_session() | |
|
2532 | ||
|
2533 | 2533 | # Clear all user namespaces to release all references cleanly. |
|
2534 | 2534 | self.reset(new_session=False) |
|
2535 | 2535 |
@@ -30,6 +30,7 b' def test_history():' | |||
|
30 | 30 | ip.history_manager = HistoryManager(shell=ip) |
|
31 | 31 | ip.history_manager.hist_file = histfile |
|
32 | 32 | ip.history_manager.init_db() # Has to be called after changing file |
|
33 | ip.history_manager.reset() | |
|
33 | 34 | print 'test',histfile |
|
34 | 35 | hist = ['a=1', 'def f():\n test = 1\n return test', 'b=2'] |
|
35 | 36 | for i, h in enumerate(hist, start=1): |
@@ -185,10 +185,6 b' class TerminalInteractiveShell(InteractiveShell):' | |||
|
185 | 185 | |
|
186 | 186 | with nested(self.builtin_trap, self.display_trap): |
|
187 | 187 | |
|
188 | # if you run stuff with -c <cmd>, raw hist is not updated | |
|
189 | # ensure that it's in sync | |
|
190 | self.history_manager.sync_inputs() | |
|
191 | ||
|
192 | 188 | while 1: |
|
193 | 189 | try: |
|
194 | 190 | self.interact(display_banner=display_banner) |
General Comments 0
You need to be logged in to leave comments.
Login now