1
0
Fork 0

Merging upstream version 1.14.2.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-09 17:57:00 +01:00
parent a842e453d1
commit 3b8f21e56b
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
18 changed files with 766 additions and 97 deletions

View file

@ -1,52 +1,50 @@
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import print_function, unicode_literals
import os
import sys
import traceback
import itertools
import logging
import os
import re
import shutil
import sys
import threading
from time import time
import traceback
from collections import namedtuple
from datetime import datetime
from io import open
from collections import namedtuple
from sqlite3 import OperationalError, sqlite_version
import shutil
from time import time
from cli_helpers.tabular_output import TabularOutputFormatter
from cli_helpers.tabular_output import preprocessors
import click
import sqlparse
from cli_helpers.tabular_output import TabularOutputFormatter, preprocessors
from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
from prompt_toolkit.completion import DynamicCompleter
from prompt_toolkit.enums import DEFAULT_BUFFER, EditingMode
from prompt_toolkit.shortcuts import PromptSession, CompleteStyle
from prompt_toolkit.document import Document
from prompt_toolkit.enums import DEFAULT_BUFFER, EditingMode
from prompt_toolkit.filters import HasFocus, IsDone
from prompt_toolkit.formatted_text import ANSI
from prompt_toolkit.history import FileHistory
from prompt_toolkit.layout.processors import (
HighlightMatchingBracketProcessor,
ConditionalProcessor,
HighlightMatchingBracketProcessor,
)
from prompt_toolkit.lexers import PygmentsLexer
from prompt_toolkit.history import FileHistory
from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
from prompt_toolkit.shortcuts import CompleteStyle, PromptSession
from .packages.special.main import NO_QUERY
from .packages.prompt_utils import confirm, confirm_destructive_query
from .packages import special
from .sqlcompleter import SQLCompleter
from .clitoolbar import create_toolbar_tokens_func
from .clistyle import style_factory, style_factory_output
from .sqlexecute import SQLExecute
from .__init__ import __version__
from .clibuffer import cli_is_multiline
from .clistyle import style_factory, style_factory_output
from .clitoolbar import create_toolbar_tokens_func
from .completion_refresher import CompletionRefresher
from .config import config_location, ensure_dir_exists, get_config
from .key_bindings import cli_bindings
from .lexer import LiteCliLexer
from .__init__ import __version__
from .packages import special
from .packages.filepaths import dir_path_exists
import itertools
from .packages.prompt_utils import confirm, confirm_destructive_query
from .packages.special.main import NO_QUERY
from .sqlcompleter import SQLCompleter
from .sqlexecute import SQLExecute
click.disable_unicode_literals_warning = True
@ -385,6 +383,47 @@ class LiteCli(object):
def show_suggestion_tip():
return iterations < 2
def output_res(res, start):
result_count = 0
mutating = False
for title, cur, headers, status in res:
logger.debug("headers: %r", headers)
logger.debug("rows: %r", cur)
logger.debug("status: %r", status)
threshold = 1000
if is_select(status) and cur and cur.rowcount > threshold:
self.echo(
"The result set has more than {} rows.".format(threshold),
fg="red",
)
if not confirm("Do you want to continue?"):
self.echo("Aborted!", err=True, fg="red")
break
if self.auto_vertical_output:
max_width = self.prompt_app.output.get_size().columns
else:
max_width = None
formatted = self.format_output(title, cur, headers, special.is_expanded_output(), max_width)
t = time() - start
try:
if result_count > 0:
self.echo("")
try:
self.output(formatted, status)
except KeyboardInterrupt:
pass
self.echo("Time: %0.03fs" % t)
except KeyboardInterrupt:
pass
start = time()
result_count += 1
mutating = mutating or is_mutating(status)
return mutating
def one_iteration(text=None):
if text is None:
try:
@ -402,6 +441,24 @@ class LiteCli(object):
self.echo(str(e), err=True, fg="red")
return
if special.is_llm_command(text):
try:
start = time()
cur = self.sqlexecute.conn.cursor()
context, sql = special.handle_llm(text, cur)
if context:
click.echo(context)
text = self.prompt_app.prompt(default=sql)
except KeyboardInterrupt:
return
except special.FinishIteration as e:
return output_res(e.results, start) if e.results else None
except RuntimeError as e:
logger.error("sql: %r, error: %r", text, e)
logger.error("traceback: %r", traceback.format_exc())
self.echo(str(e), err=True, fg="red")
return
if not text.strip():
return
@ -415,9 +472,6 @@ class LiteCli(object):
self.echo("Wise choice!")
return
# Keep track of whether or not the query is mutating. In case
# of a multi-statement query, the overall query is considered
# mutating if any one of the component statements is mutating
mutating = False
try:
@ -434,44 +488,11 @@ class LiteCli(object):
res = sqlexecute.run(text)
self.formatter.query = text
successful = True
result_count = 0
for title, cur, headers, status in res:
logger.debug("headers: %r", headers)
logger.debug("rows: %r", cur)
logger.debug("status: %r", status)
threshold = 1000
if is_select(status) and cur and cur.rowcount > threshold:
self.echo(
"The result set has more than {} rows.".format(threshold),
fg="red",
)
if not confirm("Do you want to continue?"):
self.echo("Aborted!", err=True, fg="red")
break
if self.auto_vertical_output:
max_width = self.prompt_app.output.get_size().columns
else:
max_width = None
formatted = self.format_output(title, cur, headers, special.is_expanded_output(), max_width)
t = time() - start
try:
if result_count > 0:
self.echo("")
try:
self.output(formatted, status)
except KeyboardInterrupt:
pass
self.echo("Time: %0.03fs" % t)
except KeyboardInterrupt:
pass
start = time()
result_count += 1
mutating = mutating or is_mutating(status)
special.unset_once_if_written()
# Keep track of whether or not the query is mutating. In case
# of a multi-statement query, the overall query is considered
# mutating if any one of the component statements is mutating
mutating = output_res(res, start)
special.unset_pipe_once_if_written()
except EOFError as e:
raise e
@ -735,20 +756,32 @@ class LiteCli(object):
return self.completer.get_completions(Document(text=text, cursor_position=cursor_positition), None)
def get_prompt(self, string):
self.logger.debug("Getting prompt")
self.logger.debug("Getting prompt %r", string)
sqlexecute = self.sqlexecute
now = datetime.now()
string = string.replace("\\d", sqlexecute.dbname or "(none)")
string = string.replace("\\f", os.path.basename(sqlexecute.dbname or "(none)"))
string = string.replace("\\n", "\n")
string = string.replace("\\D", now.strftime("%a %b %d %H:%M:%S %Y"))
string = string.replace("\\m", now.strftime("%M"))
string = string.replace("\\P", now.strftime("%p"))
string = string.replace("\\R", now.strftime("%H"))
string = string.replace("\\r", now.strftime("%I"))
string = string.replace("\\s", now.strftime("%S"))
string = string.replace("\\_", " ")
return string
# Prepare the replacements dictionary
replacements = {
r"\d": sqlexecute.dbname or "(none)",
r"\f": os.path.basename(sqlexecute.dbname or "(none)"),
r"\n": "\n",
r"\D": now.strftime("%a %b %d %H:%M:%S %Y"),
r"\m": now.strftime("%M"),
r"\P": now.strftime("%p"),
r"\R": now.strftime("%H"),
r"\r": now.strftime("%I"),
r"\s": now.strftime("%S"),
r"\_": " ",
}
# Compile a regex pattern that matches any of the keys in replacements
pattern = re.compile("|".join(re.escape(key) for key in replacements.keys()))
# Define the replacement function
def replacer(match):
return replacements[match.group(0)]
# Perform the substitution
return pattern.sub(replacer, string)
def run_query(self, query, new_line=True):
"""Runs *query*."""