summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbjornasm <bjornasm@gmail.com>2023-05-04 13:05:10 +0200
committerbjornasm <bjornasm@gmail.com>2023-05-04 13:05:10 +0200
commitd48571b7696970a39f676682922cd6f9084d95c4 (patch)
tree492e5dc39248d025b69d5d078dff34811d9c3432
parentc27c2f25ef617fecc46d4fe65fc798f7bc877622 (diff)
Minimal implementation of startup commands
-rw-r--r--litecli/liteclirc8
-rw-r--r--litecli/main.py39
-rw-r--r--litecli/sqlexecute.py17
3 files changed, 53 insertions, 11 deletions
diff --git a/litecli/liteclirc b/litecli/liteclirc
index 4db6f3a..924b585 100644
--- a/litecli/liteclirc
+++ b/litecli/liteclirc
@@ -117,6 +117,12 @@ output.header = "#00ff5f bold"
output.odd-row = ""
output.even-row = ""
-
# Favorite queries.
[favorite_queries]
+
+# Startup commands
+# litecli commands or sqlite commands to be executed on startup.
+# some of them will require you to have a database attached.
+# they will be executed in the same order as they appear in the list.
+[startup_commands]
+#commands = ".tables", "pragma foreign_keys = ON;" \ No newline at end of file
diff --git a/litecli/main.py b/litecli/main.py
index 34db568..25c15ea 100644
--- a/litecli/main.py
+++ b/litecli/main.py
@@ -110,7 +110,12 @@ class LiteCli(object):
fg="red",
)
self.logfile = False
-
+ # Load startup commands.
+ try:
+ self.startup_commands = c["startup_commands"]
+ except KeyError: # Redundant given the load_config() function that merges in the standard config, but put here to avoid fail if user do not have updated config file.
+ self.startup_commands = None
+
self.completion_refresher = CompletionRefresher()
self.logger = logging.getLogger(__name__)
@@ -442,6 +447,7 @@ class LiteCli(object):
start = time()
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)
@@ -456,8 +462,6 @@ class LiteCli(object):
if not confirm("Do you want to continue?"):
self.echo("Aborted!", err=True, fg="red")
break
- else:
- successful = True
if self.auto_vertical_output:
max_width = self.prompt_app.output.get_size().columns
@@ -476,8 +480,6 @@ class LiteCli(object):
self.output(formatted, status)
except KeyboardInterrupt:
pass
- else:
- successful = True
self.echo("Time: %0.03fs" % t)
except KeyboardInterrupt:
pass
@@ -592,6 +594,33 @@ class LiteCli(object):
editing_mode=editing_mode,
search_ignore_case=True,
)
+ def startup_commands():
+ #TODO: Wait for attach db
+ if self.startup_commands:
+ if "commands" in self.startup_commands:
+ for command in self.startup_commands['commands']:
+ try:
+ res = sqlexecute.run(command)
+ except Exception as e:
+ click.echo(command)
+ self.echo(str(e), err=True, fg="red")
+ else:
+ click.echo(command)
+ for title, cur, headers, status in res:
+ if title == 'dot command not implemented':
+ self.echo("The SQLite dot command '" + command.split(' ', 1)[0]+"' is not yet implemented.", fg="yellow")
+ else:
+ output = self.format_output(title, cur, headers)
+ for line in output:
+ self.echo(line)
+
+ else:
+ self.echo("Could not read commands. The startup commands needs to be formatted as: \n commands = 'command1', 'command2', ...", fg="yellow")
+
+ try:
+ startup_commands()
+ except Exception as e:
+ self.echo("Could not execute all startup commands: \n"+str(e), fg="yellow")
try:
while True:
diff --git a/litecli/sqlexecute.py b/litecli/sqlexecute.py
index 3f78d49..b721654 100644
--- a/litecli/sqlexecute.py
+++ b/litecli/sqlexecute.py
@@ -8,7 +8,6 @@ import sqlparse
import os.path
from .packages import special
-
_logger = logging.getLogger(__name__)
# FIELD_TYPES = decoders.copy()
@@ -16,6 +15,9 @@ _logger = logging.getLogger(__name__)
# FIELD_TYPE.NULL: type(None)
# })
+sqlite3dotcommands = ['.archive','.auth','.backup','.bail','.binary','.cd','.changes','.check','.clone','.connection','.databases','.dbconfig','.dbinfo','.dump','.echo','.eqp','.excel','.exit','.expert','.explain','.filectrl','.fullschema','.headers','.help','.import','.imposter','.indexes','.limit','.lint','.load','.log','.mode','.nonce','.nullvalue','.once','.open','.output','.parameter','.print','.progress','.prompt','.quit','.read','.recover','.restore','.save','.scanstats','.schema','.selftest','.separator','.session','.sha3sum','.shell','.show','.stats','.system','.tables','.testcase','.testctrl','.timeout','.timer','.trace','.vfsinfo','.vfslist','.vfsname','.width']
+
+
class SQLExecute(object):
@@ -79,6 +81,7 @@ class SQLExecute(object):
# retrieve connection id
self.reset_connection_id()
+
def run(self, statement):
"""Execute the sql in the database and return the results. The results
are a list of tuples. Each tuple has 4 values
@@ -129,10 +132,14 @@ class SQLExecute(object):
for result in special.execute(cur, sql):
yield result
except special.CommandNotFound: # Regular SQL
- _logger.debug("Regular sql statement. sql: %r", sql)
- cur.execute(sql)
- yield self.get_result(cur)
-
+ basecommand = sql.split(' ', 1)[0]
+ if basecommand.lower() in sqlite3dotcommands:
+ yield ('dot command not implemented', None, None, None)
+ else:
+ _logger.debug("Regular sql statement. sql: %r", sql)
+ cur.execute(sql)
+ yield self.get_result(cur)
+
def get_result(self, cursor):
"""Get the current result's data from the cursor."""
title = headers = None