##// END OF EJS Templates
allow trimming to an empty database (--keep=0)
Paul Ivanov -
Show More
@@ -1,124 +1,126 b''
1 1 # encoding: utf-8
2 2 """
3 3 An application for managing IPython history.
4 4
5 5 To be invoked as the `ipython history` subcommand.
6 6 """
7 7 from __future__ import print_function
8 8
9 9 import os
10 10 import sqlite3
11 11
12 12 from IPython.config.application import Application
13 13 from IPython.core.application import BaseIPythonApplication
14 14 from IPython.utils.traitlets import Bool, Int, Dict
15 15
16 16 trim_hist_help = """Trim the IPython history database to the last 1000 entries.
17 17
18 18 This actually copies the last 1000 entries to a new database, and then replaces
19 19 the old file with the new. Use the `--keep=` argument to specify a number
20 20 other than 1000.
21 21 """
22 22
23 23 class HistoryTrim(BaseIPythonApplication):
24 24 description = trim_hist_help
25 25
26 26 backup = Bool(False, config=True,
27 27 help="Keep the old history file as history.sqlite.<N>")
28 28
29 29 keep = Int(1000, config=True,
30 30 help="Number of recent lines to keep in the database.")
31 31
32 32 flags = Dict(dict(
33 33 backup = ({'HistoryTrim' : {'backup' : True}},
34 34 backup.get_metadata('help')
35 35 )
36 36 ))
37 37
38 38 aliases=Dict(dict(
39 39 keep = 'HistoryTrim.keep'
40 40 ))
41 41
42 42 def start(self):
43 43 profile_dir = self.profile_dir.location
44 44 hist_file = os.path.join(profile_dir, 'history.sqlite')
45 45 con = sqlite3.connect(hist_file)
46 46
47 47 # Grab the recent history from the current database.
48 48 inputs = list(con.execute('SELECT session, line, source, source_raw FROM '
49 49 'history ORDER BY session DESC, line DESC LIMIT ?', (self.keep+1,)))
50 50 if len(inputs) <= self.keep:
51 51 print("There are already at most %d entries in the history database." % self.keep)
52 52 print("Not doing anything. Use --keep= argument to keep fewer entries")
53 53 return
54 54
55 55 print("Trimming history to the most recent %d entries." % self.keep)
56 56
57 57 inputs.pop() # Remove the extra element we got to check the length.
58 58 inputs.reverse()
59 first_session = inputs[0][0]
60 outputs = list(con.execute('SELECT session, line, output FROM '
61 'output_history WHERE session >= ?', (first_session,)))
62 sessions = list(con.execute('SELECT session, start, end, num_cmds, remark FROM '
63 'sessions WHERE session >= ?', (first_session,)))
59 if inputs:
60 first_session = inputs[0][0]
61 outputs = list(con.execute('SELECT session, line, output FROM '
62 'output_history WHERE session >= ?', (first_session,)))
63 sessions = list(con.execute('SELECT session, start, end, num_cmds, remark FROM '
64 'sessions WHERE session >= ?', (first_session,)))
64 65 con.close()
65 66
66 67 # Create the new history database.
67 68 new_hist_file = os.path.join(profile_dir, 'history.sqlite.new')
68 69 i = 0
69 70 while os.path.exists(new_hist_file):
70 71 # Make sure we don't interfere with an existing file.
71 72 i += 1
72 73 new_hist_file = os.path.join(profile_dir, 'history.sqlite.new'+str(i))
73 74 new_db = sqlite3.connect(new_hist_file)
74 75 new_db.execute("""CREATE TABLE IF NOT EXISTS sessions (session integer
75 76 primary key autoincrement, start timestamp,
76 77 end timestamp, num_cmds integer, remark text)""")
77 78 new_db.execute("""CREATE TABLE IF NOT EXISTS history
78 79 (session integer, line integer, source text, source_raw text,
79 80 PRIMARY KEY (session, line))""")
80 81 new_db.execute("""CREATE TABLE IF NOT EXISTS output_history
81 82 (session integer, line integer, output text,
82 83 PRIMARY KEY (session, line))""")
83 84 new_db.commit()
84 85
85 86
86 with new_db:
87 # Add the recent history into the new database.
88 new_db.executemany('insert into sessions values (?,?,?,?,?)', sessions)
89 new_db.executemany('insert into history values (?,?,?,?)', inputs)
90 new_db.executemany('insert into output_history values (?,?,?)', outputs)
87 if inputs:
88 with new_db:
89 # Add the recent history into the new database.
90 new_db.executemany('insert into sessions values (?,?,?,?,?)', sessions)
91 new_db.executemany('insert into history values (?,?,?,?)', inputs)
92 new_db.executemany('insert into output_history values (?,?,?)', outputs)
91 93 new_db.close()
92 94
93 95 if self.backup:
94 96 i = 1
95 97 backup_hist_file = os.path.join(profile_dir, 'history.sqlite.old.%d' % i)
96 98 while os.path.exists(backup_hist_file):
97 99 i += 1
98 100 backup_hist_file = os.path.join(profile_dir, 'history.sqlite.old.%d' % i)
99 101 os.rename(hist_file, backup_hist_file)
100 102 print("Backed up longer history file to", backup_hist_file)
101 103 else:
102 104 os.remove(hist_file)
103 105
104 106 os.rename(new_hist_file, hist_file)
105 107
106 108
107 109 class HistoryApp(Application):
108 110 name = u'ipython-history'
109 111 description = "Manage the IPython history database."
110 112
111 113 subcommands = Dict(dict(
112 114 trim = (HistoryTrim, HistoryTrim.description.splitlines()[0]),
113 115 ))
114 116
115 117 def start(self):
116 118 if self.subapp is None:
117 119 print("No subcommand specified. Must specify one of: %s" % \
118 120 (self.subcommands.keys()))
119 121 print()
120 122 self.print_description()
121 123 self.print_subcommands()
122 124 self.exit(1)
123 125 else:
124 126 return self.subapp.start()
General Comments 0
You need to be logged in to leave comments. Login now