From 86dfefc10e9216f08af8103f1785c4ab8c9c5d67 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Thu, 28 May 2020 10:36:33 +0200 Subject: [PATCH] Add proof-of-concept REPL --- Lib/sqlite3/__main__.py | 82 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 Lib/sqlite3/__main__.py diff --git a/Lib/sqlite3/__main__.py b/Lib/sqlite3/__main__.py new file mode 100644 index 0000000000..f82ca22f6f --- /dev/null +++ b/Lib/sqlite3/__main__.py @@ -0,0 +1,82 @@ +from argparse import ArgumentParser +from code import InteractiveConsole + +import sqlite3 +import sys + + +class SqliteInteractiveConsole(InteractiveConsole): + + def __init__(self, database): + super().__init__() + self.con = sqlite3.connect(database) + self.cur = self.con.cursor() + + def runsql(self, sql): + try: + self.cur.execute(sql) + res = self.cur.fetchall() + if res: + print(res) + except sqlite3.Error as e: + print(str(e)) + + def runpy(self, source, filename='', symbol='single'): + code = self.compile(source, filename, symbol) + self.runcode(code) + + def printhelp(self, ignored): + print( + 'Enter SQL code and press enter. The REPL will run each command\n' + 'using execute() and then fetchall() on the database cursor. If\n' + 'the query produces any results, they are printed using\n' + 'print(str(result)).\n' + '\n' + f'Type "help", "copyright", "credits" or "license" for more ' + f'information.\n' + ) + + def runsource(self, source, filename='', symbol='single'): + keywords = { + 'version': lambda x: print(f'{sqlite3.sqlite_version}'), + 'help': self.printhelp, + 'copyright': self.runpy, + 'credits': self.runpy, + 'license': self.runpy, + 'license()': self.runpy, + 'quit()': self.runpy, + 'quit': self.runpy, + } + keywords.get(source, self.runsql)(source) + + +if __name__ == '__main__': + parser = ArgumentParser( + description='Python sqlite3 REPL', + prog='python -m sqlite3' + ) + parser.add_argument( + '-f', '--filename', + type=str, dest='database', action='store', default=':memory:', + help='Database to open (default in-memory database)' + ) + args = parser.parse_args() + database = args.database + + if database == ':memory:': + db_name = 'a transient in-memory database' + else: + db_name = f"'{database}'" + banner = ( + f'Python {sys.version} on {sys.platform}\n' + f'sqlite-{sqlite3.sqlite_version} (based on pysqlite ' + f'{sqlite3.version} REPL\n' + f'Connected to {db_name}\n' + f'Each command will be run using execute() on the cursor.\n' + f'Type "help", "copyright", "credits" or "license" for more ' + f'information.\n' + ) + sys.ps1 = 'sqlite> ' + + console = SqliteInteractiveConsole(database) + console.interact(banner, exitmsg='') -- 2.27.0.rc2