1+ """A simple SQLite CLI for the sqlite3 module.
2+
3+ Apart from using 'argparse' for the command-line interface,
4+ this module implements the REPL as a thin wrapper around
5+ the InteractiveConsole class from the 'code' stdlib module.
6+ """
17import sqlite3
28import sys
39
713
814
915def execute (c , sql , suppress_errors = True ):
16+ """Helper that wraps execution of SQL code.
17+
18+ This is used both by the REPL and by direct execution from the CLI.
19+
20+ 'c' may be a cursor or a connection.
21+ 'sql' is the SQL string to execute.
22+ """
23+
1024 try :
1125 for row in c .execute (sql ):
1226 print (row )
@@ -21,13 +35,19 @@ def execute(c, sql, suppress_errors=True):
2135
2236
2337class SqliteInteractiveConsole (InteractiveConsole ):
38+ """A simple SQLite REPL."""
2439
2540 def __init__ (self , connection ):
2641 super ().__init__ ()
2742 self ._con = connection
2843 self ._cur = connection .cursor ()
2944
3045 def runsource (self , source , filename = "<input>" , symbol = "single" ):
46+ """Override runsource, the core of the InteractiveConsole REPL.
47+
48+ Return True if more input is needed; buffering is done automatically.
49+ Return False is input is a complete statement ready for execution.
50+ """
3151 match source :
3252 case ".version" :
3353 print (f"{ sqlite3 .sqlite_version } " )
@@ -73,6 +93,7 @@ def main():
7393 else :
7494 db_name = repr (args .filename )
7595
96+ # Prepare REPL banner and prompts.
7697 banner = dedent (f"""
7798 sqlite3 shell, running on SQLite version { sqlite3 .sqlite_version }
7899 Connected to { db_name }
@@ -86,8 +107,10 @@ def main():
86107 con = sqlite3 .connect (args .filename , isolation_level = None )
87108 try :
88109 if args .sql :
110+ # SQL statement provided on the command-line; execute it directly.
89111 execute (con , args .sql , suppress_errors = False )
90112 else :
113+ # No SQL provided; start the REPL.
91114 console = SqliteInteractiveConsole (con )
92115 console .interact (banner , exitmsg = "" )
93116 finally :
0 commit comments