| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| Expand Up | @@ -41,41 +41,206 @@ def execute(c, sql, suppress_errors=True, theme=theme_no_color): | |||||
|
|
||||||
| class SqliteInteractiveConsole(InteractiveConsole): | ||||||
| """A simple SQLite REPL.""" | ||||||
| PS1 = "sqlite> " | ||||||
| PS2 = " ... " | ||||||
| ruler = "=" | ||||||
| doc_header = "Documented commands (type .help <command>):" | ||||||
| undoc_header = "Undocumented commands:" | ||||||
|
|
||||||
| def __init__(self, connection, use_color=False): | ||||||
| super().__init__() | ||||||
| self._con = connection | ||||||
| self._cur = connection.cursor() | ||||||
| self._use_color = use_color | ||||||
| self._theme = get_theme(force_no_color=not use_color) | ||||||
|
|
||||||
| s = self._theme.syntax | ||||||
| sys.ps1 = f"{s.prompt}{self.PS1}{s.reset}" | ||||||
| sys.ps2 = f"{s.prompt}{self.PS2}{s.reset}" | ||||||
|
|
||||||
| def do_version(self, _): | ||||||
| """.version | ||||||
|
|
||||||
| Show version of the runtime SQLite library. | ||||||
|
Comment thread
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality
Suggested change
This is the more common way of describing this. And also this does not need a new function.
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityJust as explained at #133935 (comment), we do need a function here.
Sorry, something went wrong.
All reactions
|
||||||
| """ | ||||||
| print(sqlite3.sqlite_version) | ||||||
|
|
||||||
| def do_help(self, arg): | ||||||
|
Comment thread
picnixz marked this conversation as resolved.
|
||||||
| """.help [-all] [command] | ||||||
|
|
||||||
| Without argument, print the list of available commands. | ||||||
| With a command name as argument, print help about that command. | ||||||
| With more command names as arguments, only the first one is used. | ||||||
| """ | ||||||
| if not arg: | ||||||
| cmds = sorted(name[3:] for name in dir(self.__class__) | ||||||
| if name.startswith("do_")) | ||||||
| cmds_doc = [] | ||||||
| cmds_undoc = [] | ||||||
| for cmd in cmds: | ||||||
| if getattr(self, f"do_{cmd}").__doc__: | ||||||
| cmds_doc.append(cmd) | ||||||
| else: | ||||||
| cmds_undoc.append(cmd) | ||||||
| self._print_commands(self.doc_header, cmds_doc, 80) | ||||||
| self._print_commands(self.undoc_header, cmds_undoc, 80) | ||||||
| else: | ||||||
| arg = arg.split()[0] | ||||||
| if arg in ("-all", "--all"): | ||||||
|
Comment thread
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityWe should not have both. Please only keep the -- option, we could have -a too but it is unnecessary IMO
Sorry, something went wrong.
All reactions
|
||||||
| names = sorted(name for name in dir(self.__class__) | ||||||
| if name.startswith("do_")) | ||||||
| print(self._help_message_from_method_names(names)) | ||||||
| else: | ||||||
| if (method := getattr(self, "do_" + arg, None)) is not None: | ||||||
| print(self._help_message_from_doc(method.__doc__)) | ||||||
| else: | ||||||
| self._error(f"No help for '{arg}'") | ||||||
|
Comment thread
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityJust use print and add the theme normally IMO
Sorry, something went wrong.
All reactions
|
||||||
|
|
||||||
| def do_quit(self, _): | ||||||
| """.q(uit) | ||||||
|
|
||||||
| Exit this program. | ||||||
| """ | ||||||
| sys.exit(0) | ||||||
|
Comment thread
Comment on lines
+99
to
+104
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityNot needed?
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityAlthough it's just a one-liner we still need to put it in a function with a do_ prefix to mark it as a dot command. That way the quit command is accessible by .help.
Sorry, something went wrong.
All reactions
|
||||||
|
|
||||||
| do_q = do_quit | ||||||
|
|
||||||
| def _help_message_from_doc(self, doc): | ||||||
| # copied from Lib/pdb.py#L2544 | ||||||
|
Comment thread
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityThis will change, we don't need it anyway for inter-stdlib copies
Sorry, something went wrong.
All reactions
|
||||||
| lines = [line.strip() for line in doc.rstrip().splitlines()] | ||||||
| if not lines: | ||||||
| return "No help message found." | ||||||
| if "" in lines: | ||||||
| usage_end = lines.index("") | ||||||
| else: | ||||||
| usage_end = 1 | ||||||
| formatted = [] | ||||||
| indent = " " * len(self.PS1) | ||||||
| for i, line in enumerate(lines): | ||||||
| if i == 0: | ||||||
| prefix = "Usage: " | ||||||
| elif i < usage_end: | ||||||
| prefix = " " | ||||||
| else: | ||||||
| prefix = "" | ||||||
| formatted.append(indent + prefix + line) | ||||||
| return "\n".join(formatted) | ||||||
|
|
||||||
| def _help_message_from_method_names(self, names): | ||||||
| formatted = [] | ||||||
| indent = " " * len(self.PS1) | ||||||
| for name in names: | ||||||
| if not (doc := getattr(self, name).__doc__): | ||||||
| formatted.append(f".{name[3:]}") | ||||||
| continue | ||||||
| lines = [line.strip() for line in doc.rstrip().splitlines()] | ||||||
| if "" in lines: | ||||||
| usage_end = lines.index("") | ||||||
| else: | ||||||
| usage_end = 1 | ||||||
| for i, line in enumerate(lines): | ||||||
| # skip method aliases, e.g. do_q for do_quit | ||||||
| if i == 0 and line in formatted: | ||||||
| break | ||||||
| elif i < usage_end: | ||||||
| formatted.append(line) | ||||||
| elif not line and i == usage_end: | ||||||
| continue | ||||||
| else: | ||||||
| formatted.append(indent + line) | ||||||
| return "\n".join(formatted) | ||||||
|
|
||||||
| def _error(self, msg): | ||||||
| t = self._theme.traceback | ||||||
| self.write(f"{t.message}{msg}{t.reset}\n") | ||||||
|
|
||||||
| def _print_commands(self, header, cmds, maxcol): | ||||||
| # copied and modified from Lib/cmd.py#L351 | ||||||
|
Comment thread
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Qualityditto
Sorry, something went wrong.
All reactions
|
||||||
| if cmds: | ||||||
| print(header) | ||||||
| if self.ruler: | ||||||
| print(self.ruler * len(header)) | ||||||
| self._columnize(cmds, maxcol-1) | ||||||
| print() | ||||||
|
|
||||||
| def _columnize(self, strings, displaywidth=80): | ||||||
| """Display a list of strings as a compact set of columns. | ||||||
|
|
||||||
| Each column is only as wide as necessary. | ||||||
| Columns are separated by two spaces (one was not legible enough). | ||||||
| """ | ||||||
| # copied and modified from Lib/cmd.py#L359 | ||||||
|
Comment thread
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Qualityditto
Sorry, something went wrong.
All reactions
|
||||||
| if not strings: | ||||||
| print("<empty>") | ||||||
| return | ||||||
|
|
||||||
| size = len(strings) | ||||||
| if size == 1: | ||||||
| print(strings[0]) | ||||||
| return | ||||||
| # Try every row count from 1 upwards | ||||||
| for nrows in range(1, size): | ||||||
| ncols = (size+nrows-1) // nrows | ||||||
| colwidths = [] | ||||||
| totwidth = -2 | ||||||
| for col in range(ncols): | ||||||
| colwidth = 0 | ||||||
| for row in range(nrows): | ||||||
| i = row + nrows*col | ||||||
| if i >= size: | ||||||
| break | ||||||
| x = strings[i] | ||||||
| colwidth = max(colwidth, len(x)) | ||||||
| colwidths.append(colwidth) | ||||||
| totwidth += colwidth + 2 | ||||||
| if totwidth > displaywidth: | ||||||
| break | ||||||
| if totwidth <= displaywidth: | ||||||
| break | ||||||
| else: | ||||||
| nrows = size | ||||||
| ncols = 1 | ||||||
| colwidths = [0] | ||||||
| for row in range(nrows): | ||||||
| texts = [] | ||||||
| for col in range(ncols): | ||||||
| i = row + nrows*col | ||||||
| if i >= size: | ||||||
| x = "" | ||||||
| else: | ||||||
| x = strings[i] | ||||||
| texts.append(x) | ||||||
| while texts and not texts[-1]: | ||||||
| del texts[-1] | ||||||
| for col in range(len(texts)): | ||||||
| texts[col] = texts[col].ljust(colwidths[col]) | ||||||
| print(" ".join(texts)) | ||||||
|
|
||||||
| def runsource(self, source, filename="<input>", symbol="single"): | ||||||
| """Override runsource, the core of the InteractiveConsole REPL. | ||||||
|
|
||||||
| Return True if more input is needed; buffering is done automatically. | ||||||
| Return False if input is a complete statement ready for execution. | ||||||
| """ | ||||||
| theme = get_theme(force_no_color=not self._use_color) | ||||||
|
|
||||||
| if not source or source.isspace(): | ||||||
| return False | ||||||
| if source[0] == ".": | ||||||
| match source[1:].strip(): | ||||||
| case "version": | ||||||
| print(f"{sqlite3.sqlite_version}") | ||||||
| case "help": | ||||||
| print("Enter SQL code and press enter.") | ||||||
| case "quit": | ||||||
| sys.exit(0) | ||||||
| case "": | ||||||
| pass | ||||||
| case _ as unknown: | ||||||
| t = theme.traceback | ||||||
| if line := source[1:].strip(): | ||||||
| try: | ||||||
| cmd, arg = line.split(maxsplit=1) | ||||||
| except ValueError: | ||||||
| cmd, arg = line, None | ||||||
| if (func := getattr(self, "do_" + cmd, None)) is not None: | ||||||
| func(arg) | ||||||
| else: | ||||||
| t = self._theme.traceback | ||||||
| self.write(f'{t.type}Error{t.reset}:{t.message} unknown' | ||||||
| f'command or invalid arguments: "{unknown}".\n{t.reset}') | ||||||
| f' command or invalid arguments: "{line}".' | ||||||
| f' Enter ".help" for help{t.reset}\n') | ||||||
| else: | ||||||
| if not sqlite3.complete_statement(source): | ||||||
| return True | ||||||
| execute(self._cur, source, theme=theme) | ||||||
| execute(self._cur, source, theme=self._theme) | ||||||
| return False | ||||||
|
|
||||||
|
|
||||||
| Expand Down Expand Up | @@ -124,10 +289,6 @@ def main(*args): | |||||
| """).strip() | ||||||
|
|
||||||
| theme = get_theme() | ||||||
| s = theme.syntax | ||||||
|
|
||||||
| sys.ps1 = f"{s.prompt}sqlite> {s.reset}" | ||||||
| sys.ps2 = f"{s.prompt} ... {s.reset}" | ||||||
|
|
||||||
| con = sqlite3.connect(args.filename, isolation_level=None) | ||||||
| try: | ||||||
| Expand Down | ||||||
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,2 @@ | ||||||||||
| Make ``.help`` in the :mod:`sqlite3` command-line interface print list of | ||||||||||
| available commands and ``.help <command>`` prints help for that command. | ||||||||||
|
Comment thread
Comment on lines
+1
to
+2
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality
Suggested change
Sorry, something went wrong.
All reactions
|
||||||||||
| Back | FazBrowse Home | New Git URL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityRemove these and use sys.ps1 like before, this would break current behavior.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityThe self.PS1 is needed by this line to get the length of plain prompt string. The length can't be obtained through sys.ps1 because sys.ps1 has surrounding control sequences for coloring.
I tested it and it doesn't break current behavior.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.