##// END OF EJS Templates
Fix `history_manager.search(?, unique=True)` returning old entries
Nikita Kniazev -
Show More
@@ -265,7 +265,7 b' class HistoryAccessor(HistoryAccessorBase):'
265 265 ## -------------------------------
266 266 ## Methods for retrieving history:
267 267 ## -------------------------------
268 def _run_sql(self, sql, params, raw=True, output=False):
268 def _run_sql(self, sql, params, raw=True, output=False, latest=False):
269 269 """Prepares and runs an SQL query for the history database.
270 270
271 271 Parameters
@@ -276,6 +276,8 b' class HistoryAccessor(HistoryAccessorBase):'
276 276 Parameters passed to the SQL query (to replace "?")
277 277 raw, output : bool
278 278 See :meth:`get_range`
279 latest : bool
280 Select rows with max (session, line)
279 281
280 282 Returns
281 283 -------
@@ -286,8 +288,12 b' class HistoryAccessor(HistoryAccessorBase):'
286 288 if output:
287 289 sqlfrom = "history LEFT JOIN output_history USING (session, line)"
288 290 toget = "history.%s, output_history.output" % toget
291 if latest:
292 toget += ", MAX(session * 128 * 1024 + line)"
289 293 cur = self.db.execute("SELECT session, line, %s FROM %s " %\
290 294 (toget, sqlfrom) + sql, params)
295 if latest:
296 cur = (row[:-1] for row in cur)
291 297 if output: # Regroup into 3-tuples, and parse JSON
292 298 return ((ses, lin, (inp, out)) for ses, lin, inp, out in cur)
293 299 return cur
@@ -395,7 +401,7 b' class HistoryAccessor(HistoryAccessorBase):'
395 401 params += (n,)
396 402 elif unique:
397 403 sqlform += " ORDER BY session, line"
398 cur = self._run_sql(sqlform, params, raw=raw, output=output)
404 cur = self._run_sql(sqlform, params, raw=raw, output=output, latest=unique)
399 405 if n is not None:
400 406 return reversed(list(cur))
401 407 return cur
@@ -817,7 +823,7 b' class HistorySavingThread(threading.Thread):'
817 823 try:
818 824 self.db = sqlite3.connect(
819 825 str(self.history_manager.hist_file),
820 **self.history_manager.connection_options
826 **self.history_manager.connection_options,
821 827 )
822 828 while True:
823 829 self.history_manager.save_flag.wait()
@@ -17,12 +17,10 b' import sqlite3'
17 17 from traitlets.config.loader import Config
18 18 from IPython.utils.tempdir import TemporaryDirectory
19 19 from IPython.core.history import HistoryManager, extract_hist_ranges
20 from IPython.testing.decorators import skipif
21 20
22 21 def test_proper_default_encoding():
23 22 assert sys.getdefaultencoding() == "utf-8"
24 23
25 @skipif(sqlite3.sqlite_version_info > (3,24,0))
26 24 def test_history():
27 25 ip = get_ipython()
28 26 with TemporaryDirectory() as tmpdir:
@@ -133,6 +131,17 b' def test_history():'
133 131 ip.history_manager.store_inputs(1, "rogue")
134 132 ip.history_manager.writeout_cache()
135 133 assert ip.history_manager.session_number == 3
134
135 # Check that session and line values are not just max values
136 sessid, lineno, entry = newhist[-1]
137 assert lineno > 1
138 ip.history_manager.reset()
139 lineno = 1
140 ip.history_manager.store_inputs(lineno, entry)
141 gothist = ip.history_manager.search("*=*", unique=True)
142 hist = list(gothist)[-1]
143 assert sessid < hist[0]
144 assert hist[1:] == (lineno, entry)
136 145 finally:
137 146 # Ensure saving thread is shut down before we try to clean up the files
138 147 ip.history_manager.save_thread.stop()
General Comments 0
You need to be logged in to leave comments. Login now