Adding upstream version 1.9.0.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
8e68f130dd
commit
1b5fc2913b
11 changed files with 96 additions and 25 deletions
15
CHANGELOG.md
15
CHANGELOG.md
|
@ -1,3 +1,18 @@
|
||||||
|
## 1.9.0 - 2022-06-06
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Add support for ANSI escape sequences for coloring the prompt.
|
||||||
|
* Add support for `.indexes` command.
|
||||||
|
* Add an option to turn off the auto-completion menu. Completion menu can be
|
||||||
|
triggered by pressed the `<tab>` key when this option is set to False. Fixes
|
||||||
|
[#105](https://github.com/dbcli/litecli/issues/105).
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Fix [#120](https://github.com/dbcli/litecli/issues/120). Make the `.read` command actually read and execute the commands from a file.
|
||||||
|
* Fix [#96](https://github.com/dbcli/litecli/issues/96) the crash in VI mode when pressing `r`.
|
||||||
|
|
||||||
## 1.8.0 - 2022-03-29
|
## 1.8.0 - 2022-03-29
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
__version__ = "1.8.0"
|
__version__ = "1.9.0"
|
||||||
|
|
|
@ -48,4 +48,5 @@ def _get_vi_mode():
|
||||||
InputMode.NAVIGATION: "N",
|
InputMode.NAVIGATION: "N",
|
||||||
InputMode.REPLACE: "R",
|
InputMode.REPLACE: "R",
|
||||||
InputMode.INSERT_MULTIPLE: "M",
|
InputMode.INSERT_MULTIPLE: "M",
|
||||||
|
InputMode.REPLACE_SINGLE: "R",
|
||||||
}[get_app().vi_state.input_mode]
|
}[get_app().vi_state.input_mode]
|
||||||
|
|
|
@ -52,6 +52,10 @@ key_bindings = emacs
|
||||||
# Enabling this option will show the suggestions in a wider menu. Thus more items are suggested.
|
# Enabling this option will show the suggestions in a wider menu. Thus more items are suggested.
|
||||||
wider_completion_menu = False
|
wider_completion_menu = False
|
||||||
|
|
||||||
|
# Autocompletion is on by default. This can be truned off by setting this
|
||||||
|
# option to False. Pressing tab will still trigger completion.
|
||||||
|
autocompletion = True
|
||||||
|
|
||||||
# litecli prompt
|
# litecli prompt
|
||||||
# \D - The full current date
|
# \D - The full current date
|
||||||
# \d - Database name
|
# \d - Database name
|
||||||
|
@ -62,6 +66,7 @@ wider_completion_menu = False
|
||||||
# \R - The current time, in 24-hour military time (0-23)
|
# \R - The current time, in 24-hour military time (0-23)
|
||||||
# \r - The current time, standard 12-hour time (1-12)
|
# \r - The current time, standard 12-hour time (1-12)
|
||||||
# \s - Seconds of the current time
|
# \s - Seconds of the current time
|
||||||
|
# \x1b[...m - insert ANSI escape sequence
|
||||||
prompt = '\d> '
|
prompt = '\d> '
|
||||||
prompt_continuation = '-> '
|
prompt_continuation = '-> '
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ from prompt_toolkit.shortcuts import PromptSession, CompleteStyle
|
||||||
from prompt_toolkit.styles.pygments import style_from_pygments_cls
|
from prompt_toolkit.styles.pygments import style_from_pygments_cls
|
||||||
from prompt_toolkit.document import Document
|
from prompt_toolkit.document import Document
|
||||||
from prompt_toolkit.filters import HasFocus, IsDone
|
from prompt_toolkit.filters import HasFocus, IsDone
|
||||||
|
from prompt_toolkit.formatted_text import ANSI
|
||||||
from prompt_toolkit.layout.processors import (
|
from prompt_toolkit.layout.processors import (
|
||||||
HighlightMatchingBracketProcessor,
|
HighlightMatchingBracketProcessor,
|
||||||
ConditionalProcessor,
|
ConditionalProcessor,
|
||||||
|
@ -88,6 +89,7 @@ class LiteCli(object):
|
||||||
self.cli_style = c["colors"]
|
self.cli_style = c["colors"]
|
||||||
self.output_style = style_factory_output(self.syntax_style, self.cli_style)
|
self.output_style = style_factory_output(self.syntax_style, self.cli_style)
|
||||||
self.wider_completion_menu = c["main"].as_bool("wider_completion_menu")
|
self.wider_completion_menu = c["main"].as_bool("wider_completion_menu")
|
||||||
|
self.autocompletion = c["main"].as_bool("autocompletion")
|
||||||
c_dest_warning = c["main"].as_bool("destructive_warning")
|
c_dest_warning = c["main"].as_bool("destructive_warning")
|
||||||
self.destructive_warning = c_dest_warning if warn is None else warn
|
self.destructive_warning = c_dest_warning if warn is None else warn
|
||||||
self.login_path_as_host = c["main"].as_bool("login_path_as_host")
|
self.login_path_as_host = c["main"].as_bool("login_path_as_host")
|
||||||
|
@ -161,10 +163,11 @@ class LiteCli(object):
|
||||||
)
|
)
|
||||||
special.register_special_command(
|
special.register_special_command(
|
||||||
self.execute_from_file,
|
self.execute_from_file,
|
||||||
"source",
|
".read",
|
||||||
"\\. filename",
|
"\\. filename",
|
||||||
"Execute commands from file.",
|
"Execute commands from file.",
|
||||||
aliases=("\\.",),
|
case_sensitive=True,
|
||||||
|
aliases=("\\.", "source"),
|
||||||
)
|
)
|
||||||
special.register_special_command(
|
special.register_special_command(
|
||||||
self.change_prompt_format,
|
self.change_prompt_format,
|
||||||
|
@ -381,7 +384,8 @@ class LiteCli(object):
|
||||||
and len(prompt) > self.max_len_prompt
|
and len(prompt) > self.max_len_prompt
|
||||||
):
|
):
|
||||||
prompt = self.get_prompt("\\d> ")
|
prompt = self.get_prompt("\\d> ")
|
||||||
return [("class:prompt", prompt)]
|
prompt = prompt.replace("\\x1b", "\x1b")
|
||||||
|
return ANSI(prompt)
|
||||||
|
|
||||||
def get_continuation(width, line_number, is_soft_wrap):
|
def get_continuation(width, line_number, is_soft_wrap):
|
||||||
continuation = " " * (width - 1) + " "
|
continuation = " " * (width - 1) + " "
|
||||||
|
@ -547,6 +551,9 @@ class LiteCli(object):
|
||||||
else:
|
else:
|
||||||
complete_style = CompleteStyle.COLUMN
|
complete_style = CompleteStyle.COLUMN
|
||||||
|
|
||||||
|
if not self.autocompletion:
|
||||||
|
complete_style = CompleteStyle.READLINE_LIKE
|
||||||
|
|
||||||
with self._completer_lock:
|
with self._completer_lock:
|
||||||
|
|
||||||
if self.key_bindings == "vi":
|
if self.key_bindings == "vi":
|
||||||
|
|
|
@ -105,14 +105,14 @@ def suggest_special(text):
|
||||||
if cmd in ["\\f", "\\fs", "\\fd"]:
|
if cmd in ["\\f", "\\fs", "\\fd"]:
|
||||||
return [{"type": "favoritequery"}]
|
return [{"type": "favoritequery"}]
|
||||||
|
|
||||||
if cmd in ["\\d", "\\dt", "\\dt+", ".schema"]:
|
if cmd in ["\\d", "\\dt", "\\dt+", ".schema", ".indexes"]:
|
||||||
return [
|
return [
|
||||||
{"type": "table", "schema": []},
|
{"type": "table", "schema": []},
|
||||||
{"type": "view", "schema": []},
|
{"type": "view", "schema": []},
|
||||||
{"type": "schema"},
|
{"type": "schema"},
|
||||||
]
|
]
|
||||||
|
|
||||||
if cmd in ["\\.", "source", ".open"]:
|
if cmd in ["\\.", "source", ".open", ".read"]:
|
||||||
return [{"type": "file_name"}]
|
return [{"type": "file_name"}]
|
||||||
|
|
||||||
if cmd in [".import"]:
|
if cmd in [".import"]:
|
||||||
|
|
|
@ -110,6 +110,41 @@ def list_databases(cur, **_):
|
||||||
return [(None, None, None, "")]
|
return [(None, None, None, "")]
|
||||||
|
|
||||||
|
|
||||||
|
@special_command(
|
||||||
|
".indexes",
|
||||||
|
".indexes [tablename]",
|
||||||
|
"List indexes.",
|
||||||
|
arg_type=PARSED_QUERY,
|
||||||
|
case_sensitive=True,
|
||||||
|
aliases=("\\di",),
|
||||||
|
)
|
||||||
|
def list_indexes(cur, arg=None, arg_type=PARSED_QUERY, verbose=False):
|
||||||
|
if arg:
|
||||||
|
args = ("{0}%".format(arg),)
|
||||||
|
query = """
|
||||||
|
SELECT name FROM sqlite_master
|
||||||
|
WHERE type = 'index' AND tbl_name LIKE ? AND name NOT LIKE 'sqlite_%'
|
||||||
|
ORDER BY 1
|
||||||
|
"""
|
||||||
|
else:
|
||||||
|
args = tuple()
|
||||||
|
query = """
|
||||||
|
SELECT name FROM sqlite_master
|
||||||
|
WHERE type = 'index' AND name NOT LIKE 'sqlite_%'
|
||||||
|
ORDER BY 1
|
||||||
|
"""
|
||||||
|
|
||||||
|
log.debug(query)
|
||||||
|
cur.execute(query, args)
|
||||||
|
indexes = cur.fetchall()
|
||||||
|
status = ""
|
||||||
|
if cur.description:
|
||||||
|
headers = [x[0] for x in cur.description]
|
||||||
|
else:
|
||||||
|
return [(None, None, None, "")]
|
||||||
|
return [(None, indexes, headers, status)]
|
||||||
|
|
||||||
|
|
||||||
@special_command(
|
@special_command(
|
||||||
".status",
|
".status",
|
||||||
"\\s",
|
"\\s",
|
||||||
|
@ -202,24 +237,6 @@ def describe(cur, arg, **_):
|
||||||
return [(None, tables, headers, status)]
|
return [(None, tables, headers, status)]
|
||||||
|
|
||||||
|
|
||||||
@special_command(
|
|
||||||
".read",
|
|
||||||
".read path",
|
|
||||||
"Read input from path",
|
|
||||||
arg_type=PARSED_QUERY,
|
|
||||||
case_sensitive=True,
|
|
||||||
)
|
|
||||||
def read_script(cur, arg, **_):
|
|
||||||
args = shlex.split(arg)
|
|
||||||
if len(args) != 1:
|
|
||||||
raise TypeError(".read accepts exactly one path")
|
|
||||||
path = args[0]
|
|
||||||
with open(path, "r") as f:
|
|
||||||
script = f.read()
|
|
||||||
cur.executescript(script)
|
|
||||||
return [(None, None, None, "")]
|
|
||||||
|
|
||||||
|
|
||||||
@special_command(
|
@special_command(
|
||||||
".import",
|
".import",
|
||||||
".import filename table",
|
".import filename table",
|
||||||
|
|
|
@ -38,6 +38,13 @@ class SQLExecute(object):
|
||||||
ORDER BY tableName, columnName
|
ORDER BY tableName, columnName
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
indexes_query = """
|
||||||
|
SELECT name
|
||||||
|
FROM sqlite_master
|
||||||
|
WHERE type = 'index' AND name NOT LIKE 'sqlite_%'
|
||||||
|
ORDER BY 1
|
||||||
|
"""
|
||||||
|
|
||||||
functions_query = '''SELECT ROUTINE_NAME FROM INFORMATION_SCHEMA.ROUTINES
|
functions_query = '''SELECT ROUTINE_NAME FROM INFORMATION_SCHEMA.ROUTINES
|
||||||
WHERE ROUTINE_TYPE="FUNCTION" AND ROUTINE_SCHEMA = "%s"'''
|
WHERE ROUTINE_TYPE="FUNCTION" AND ROUTINE_SCHEMA = "%s"'''
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ def upload_distribution_files():
|
||||||
|
|
||||||
|
|
||||||
def push_to_github():
|
def push_to_github():
|
||||||
run_step("git", "push", "origin", "master")
|
run_step("git", "push", "origin", "main")
|
||||||
|
|
||||||
|
|
||||||
def push_tags_to_github():
|
def push_tags_to_github():
|
||||||
|
|
|
@ -51,6 +51,10 @@ key_bindings = emacs
|
||||||
# Enabling this option will show the suggestions in a wider menu. Thus more items are suggested.
|
# Enabling this option will show the suggestions in a wider menu. Thus more items are suggested.
|
||||||
wider_completion_menu = False
|
wider_completion_menu = False
|
||||||
|
|
||||||
|
# Autocompletion is on by default. This can be truned off by setting this
|
||||||
|
# option to False. Pressing tab will still trigger completion.
|
||||||
|
autocompletion = True
|
||||||
|
|
||||||
# litecli prompt
|
# litecli prompt
|
||||||
# \D - The full current date
|
# \D - The full current date
|
||||||
# \d - Database name
|
# \d - Database name
|
||||||
|
@ -61,9 +65,13 @@ wider_completion_menu = False
|
||||||
# \R - The current time, in 24-hour military time (0-23)
|
# \R - The current time, in 24-hour military time (0-23)
|
||||||
# \r - The current time, standard 12-hour time (1-12)
|
# \r - The current time, standard 12-hour time (1-12)
|
||||||
# \s - Seconds of the current time
|
# \s - Seconds of the current time
|
||||||
|
# \x1b[...m - insert ANSI escape sequence
|
||||||
prompt = "\t :\d> "
|
prompt = "\t :\d> "
|
||||||
prompt_continuation = "-> "
|
prompt_continuation = "-> "
|
||||||
|
|
||||||
|
# Show/hide the informational toolbar with function keymap at the footer.
|
||||||
|
show_bottom_toolbar = True
|
||||||
|
|
||||||
# Skip intro info on startup and outro info on exit
|
# Skip intro info on startup and outro info on exit
|
||||||
less_chatty = False
|
less_chatty = False
|
||||||
|
|
||||||
|
|
|
@ -63,3 +63,14 @@ def test_format_uptime():
|
||||||
|
|
||||||
seconds = 522600
|
seconds = 522600
|
||||||
assert "6 days 1 hour 10 min 0 sec" == format_uptime(seconds)
|
assert "6 days 1 hour 10 min 0 sec" == format_uptime(seconds)
|
||||||
|
|
||||||
|
|
||||||
|
def test_indexes():
|
||||||
|
suggestions = suggest_type(".indexes", ".indexes ")
|
||||||
|
assert sorted_dicts(suggestions) == sorted_dicts(
|
||||||
|
[
|
||||||
|
{"type": "table", "schema": []},
|
||||||
|
{"type": "view", "schema": []},
|
||||||
|
{"type": "schema"},
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
Loading…
Add table
Reference in a new issue