Add HISTORY command for CQLSH

patch by Brad Schoening; reviewed by Stefan Miklosovic and Brandon Williams for CASSANDRA-15046
This commit is contained in:
Brad Schoening 2023-05-19 13:52:33 -04:00 committed by Stefan Miklosovic
parent edd35badaf
commit 61333964f4
No known key found for this signature in database
GPG Key ID: 32F35CB2F546D93E
5 changed files with 69 additions and 25 deletions

View File

@ -1,4 +1,5 @@
5.0
* Add HISTORY command for CQLSH (CASSANDRA-15046)
* Fix sstable formats configuration (CASSANDRA-18441)
* Add guardrail to bound timestamps (CASSANDRA-18352)
* Add keyspace_name column to system_views.clients (CASSANDRA-18525)

View File

@ -266,6 +266,20 @@ Gives information about cqlsh commands. To see available topics, enter
`HELP <topic>`. Also see the `--browser` argument for controlling what
browser is used to display help.
=== `HISTORY`
Prints to the screen the last `n` cqlsh commands executed on the server.
The number of lines defaults to 50 if not specified. `n` is set for
the current CQL session so if you set it e.g. to `10`, from that point
there will be at most 10 last commands returned to you.
`Usage`:
[source,none]
----
HISTORY <n>
----
=== `TRACING`
Enables or disables tracing for queries. When tracing is enabled, once a

View File

@ -37,7 +37,8 @@ my_commands_ending_with_newline = (
'exit',
'quit',
'clear',
'cls'
'cls',
'history'
)
cqlsh_syntax_completers = []
@ -73,6 +74,7 @@ cqlsh_special_cmd_command_syntax_rules = r'''
| <exitCommand>
| <pagingCommand>
| <clearCommand>
| <historyCommand>
;
'''
@ -207,6 +209,11 @@ cqlsh_clear_cmd_syntax_rules = r'''
;
'''
cqlsh_history_cmd_syntax_rules = r'''
<historyCommand> ::= "history" (n=<wholenumber>)?
;
'''
cqlsh_question_mark = r'''
<qmark> ::= "?" ;
'''
@ -232,6 +239,7 @@ cqlsh_extra_syntax_rules = cqlsh_cmd_syntax_rules + \
cqlsh_login_cmd_syntax_rules + \
cqlsh_exit_cmd_syntax_rules + \
cqlsh_clear_cmd_syntax_rules + \
cqlsh_history_cmd_syntax_rules + \
cqlsh_question_mark

View File

@ -1836,6 +1836,26 @@ class Shell(cmd.Cmd):
else:
self.printerr("*** No help on %s" % (t,))
def do_history(self, parsed):
"""
HISTORY [cqlsh only]
Displays the most recent commands executed in cqlsh
HISTORY (<n>)
If n is specified, the history display length is set to n for this session
"""
history_length = readline.get_current_history_length()
n = parsed.get_binding('n')
if (n is not None):
self.max_history_length_shown = int(n)
for index in range(max(1, history_length - self.max_history_length_shown), history_length):
print(readline.get_history_item(index))
def do_unicode(self, parsed):
"""
Textual input/output
@ -1913,6 +1933,27 @@ class Shell(cmd.Cmd):
self.cov.save()
self.cov = None
def init_history(self):
if readline is not None:
try:
readline.read_history_file(HISTORY)
except IOError:
pass
delims = readline.get_completer_delims()
delims.replace("'", "")
delims += '.'
readline.set_completer_delims(delims)
# configure length of history shown
self.max_history_length_shown = 50
def save_history(self):
if readline is not None:
try:
readline.write_history_file(HISTORY)
except IOError:
pass
class SwitchCommand(object):
command = None
@ -2193,26 +2234,6 @@ def setup_docspath(path):
CASSANDRA_CQL_HTML = CASSANDRA_CQL_HTML_FALLBACK
def init_history():
if readline is not None:
try:
readline.read_history_file(HISTORY)
except IOError:
pass
delims = readline.get_completer_delims()
delims.replace("'", "")
delims += '.'
readline.set_completer_delims(delims)
def save_history():
if readline is not None:
try:
readline.write_history_file(HISTORY)
except IOError:
pass
def insert_driver_hooks():
class DateOverFlowWarning(RuntimeWarning):
@ -2245,7 +2266,6 @@ def main(cmdline, pkgpath):
setup_docspath(pkgpath)
setup_cqlruleset(options.cqlmodule)
setup_cqldocs(options.cqlmodule)
init_history()
csv.field_size_limit(options.field_size_limit)
if options.file is None:
@ -2343,8 +2363,9 @@ def main(cmdline, pkgpath):
signal.signal(signal.SIGHUP, handle_sighup)
shell.init_history()
shell.cmdloop()
save_history()
shell.save_history()
if shell.batch_mode and shell.statement_error:
sys.exit(2)

View File

@ -164,7 +164,7 @@ class TestCqlshCompletion(CqlshCompletionCase):
'COPY', 'CREATE', 'DEBUG', 'DELETE', 'DESC', 'DESCRIBE',
'DROP', 'GRANT', 'HELP', 'INSERT', 'LIST', 'LOGIN', 'PAGING', 'REVOKE',
'SELECT', 'SHOW', 'SOURCE', 'TRACING', 'EXPAND', 'SERIAL', 'TRUNCATE',
'UPDATE', 'USE', 'exit', 'quit', 'CLEAR', 'CLS'))
'UPDATE', 'USE', 'exit', 'quit', 'CLEAR', 'CLS', 'history'))
def test_complete_command_words(self):
self.trycompletions('alt', '\b\b\bALTER ')
@ -250,7 +250,7 @@ class TestCqlshCompletion(CqlshCompletionCase):
'CREATE', 'DEBUG', 'DELETE', 'DESC', 'DESCRIBE', 'DROP',
'EXPAND', 'GRANT', 'HELP', 'INSERT', 'LIST', 'LOGIN', 'PAGING',
'REVOKE', 'SELECT', 'SHOW', 'SOURCE', 'SERIAL', 'TRACING',
'TRUNCATE', 'UPDATE', 'USE', 'exit', 'quit',
'TRUNCATE', 'UPDATE', 'USE', 'exit', 'history', 'quit',
'CLEAR', 'CLS'])
self.trycompletions(