From a2b2e117a7fb5031431ba81fe7435911b04d22d6 Mon Sep 17 00:00:00 2001 From: Matheus Teixeira Date: Sat, 13 May 2017 17:37:20 -0300 Subject: [PATCH 1/3] Fixes #19 using option --- README.md | 1 - SQLTools.py | 25 ++++++++++++--------- SQLTools.sublime-settings | 1 + SQLToolsAPI/Command.py | 47 ++++++++++++++++++++++++++------------- SQLToolsAPI/Connection.py | 6 ++--- 5 files changed, 50 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 28bfff8..933d43f 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,6 @@ SQLTools will save you (for sure) a lot of time and help you to increase your pr PayPal donate button - ## Contributors diff --git a/SQLTools.py b/SQLTools.py index 58a0e32..d133689 100644 --- a/SQLTools.py +++ b/SQLTools.py @@ -115,15 +115,20 @@ def loadDefaultConnection(): return default -def output(content, panel=None, syntax=None, prependText=None): +def createOutput(panel=None, syntax=None, prependText=None): # hide previously set command running message (if any) Window().status_message('') if not panel: panel = getOutputPlace(syntax) if prependText: panel.run_command('append', {'characters': str(prependText)}) - panel.run_command('append', {'characters': content}) - panel.set_read_only(True) + + def append(outputContent): + panel.set_read_only(False) + panel.run_command('append', {'characters': outputContent}) + panel.set_read_only(True) + + return append def toNewTab(content, name="", suffix="SQLTools Saved Query"): @@ -401,7 +406,7 @@ def cb(index): prependText = 'Table "{tableName}"\n'.format(tableName=tableName) return ST.conn.getTableRecords( tableName, - partial(output, prependText=prependText)) + createOutput(prependText=prependText)) ST.selectTable(cb) @@ -419,7 +424,7 @@ def cb(index): if index < 0: return None Window().status_message(MESSAGE_RUNNING_CMD) - return ST.conn.getTableDescription(ST.tables[index], partial(output, syntax=currentSyntax)) + return ST.conn.getTableDescription(ST.tables[index], createOutput(syntax=currentSyntax)) ST.selectTable(cb) @@ -438,7 +443,7 @@ def cb(index): return None Window().status_message(MESSAGE_RUNNING_CMD) functionName = ST.functions[index].split('(', 1)[0] - return ST.conn.getFunctionDescription(functionName, partial(output, syntax=currentSyntax)) + return ST.conn.getFunctionDescription(functionName, createOutput(syntax=currentSyntax)) # get everything until first occurence of "(", e.g. get "function_name" # from "function_name(int)" @@ -453,7 +458,7 @@ def run(): return Window().status_message(MESSAGE_RUNNING_CMD) - ST.conn.explainPlan(getSelection(), output) + ST.conn.explainPlan(getSelection(), createOutput()) class StExecute(WindowCommand): @@ -464,7 +469,7 @@ def run(): return Window().status_message(MESSAGE_RUNNING_CMD) - ST.conn.execute(getSelection(), output) + ST.conn.execute(getSelection(), createOutput(), stream=settings.get('use_streams', False)) class StFormat(TextCommand): @@ -498,7 +503,7 @@ def run(): def cb(index): if index < 0: return None - return ST.conn.execute(history.get(index), output) + return ST.conn.execute(history.get(index), createOutput()) Window().show_quick_panel(history.all(), cb) @@ -534,7 +539,7 @@ def cb(index): if index < 0: return None - param2 = output if mode == "run" else options[index][0] + param2 = createOutput() if mode == "run" else options[index][0] func = ST.conn.execute if mode == "run" else toNewTab return func(options[index][1], param2) diff --git a/SQLTools.sublime-settings b/SQLTools.sublime-settings index 590b7c0..4e51af6 100644 --- a/SQLTools.sublime-settings +++ b/SQLTools.sublime-settings @@ -10,6 +10,7 @@ "safe_limit" : false, "show_query" : false, "expand_to_paragraph" : false, + "use_streams" : false, // use streams for results /** * The list of syntax selectors for which the plugin autocompletion will be active. * An empty list means autocompletion always active. diff --git a/SQLToolsAPI/Command.py b/SQLToolsAPI/Command.py index e477c8f..9da27e4 100644 --- a/SQLToolsAPI/Command.py +++ b/SQLToolsAPI/Command.py @@ -7,14 +7,15 @@ from .Log import Log -class Command: +class Command(object): timeout = 15 def __init__(self, args, callback, query=None, encoding='utf-8', - options=None, timeout=15, silenceErrors=False): + options=None, timeout=15, silenceErrors=False, stream=False): if options is None: options = {} + self.stream = stream self.args = args self.callback = callback self.query = query @@ -43,6 +44,23 @@ def run(self): env=os.environ.copy(), startupinfo=si) + if self.stream: + self.process.stdin.write(self.query.encode()) + self.process.stdin.close() + for line in self.process.stdout: + self.callback(line.decode(self.encoding, + 'replace').replace('\r', '')) + + queryTimerEnd = time.time() + if 'show_query' in self.options and self.options['show_query']: + resultInfo = "/*\n-- Executed querie(s) at {0} took {1:.3f}ms --".format( + str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(queryTimerStart))), + (queryTimerEnd - queryTimerStart)) + resultLine = "-" * (len(resultInfo) - 3) + resultString = "{0}\n{1}\n{2}\n{3}\n*/".format( + resultInfo, resultLine, self.query, resultLine) + return self.callback(resultString) + results, errors = self.process.communicate(input=self.query.encode()) queryTimerEnd = time.time() @@ -58,9 +76,9 @@ def run(self): 'replace').replace('\r', '') if 'show_query' in self.options and self.options['show_query']: - resultInfo = "/*\n-- Executed querie(s) at {0} took {1}ms --".format( + resultInfo = "/*\n-- Executed querie(s) at {0} took {1:.3f}ms --".format( str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(queryTimerStart))), - str(queryTimerEnd - queryTimerStart)) + (queryTimerEnd - queryTimerStart)) resultLine = "-" * (len(resultInfo) - 3) resultString = "{0}\n{1}\n{2}\n{3}\n*/\n{4}".format( resultInfo, resultLine, self.query, resultLine, resultString) @@ -68,7 +86,7 @@ def run(self): self.callback(resultString) @staticmethod - def createAndRun(args, query, callback, options=None, timeout=15, silenceErrors=False): + def createAndRun(args, query, callback, options=None, timeout=15, silenceErrors=False, stream=False): if options is None: options = {} command = Command(args, callback, query, options=options, @@ -78,18 +96,14 @@ def createAndRun(args, query, callback, options=None, timeout=15, silenceErrors= class ThreadCommand(Command, Thread): def __init__(self, args, callback, query=None, encoding='utf-8', - options=None, timeout=Command.timeout, silenceErrors=False): + options=None, timeout=Command.timeout, silenceErrors=False, stream=False): if options is None: options = {} - self.args = args - self.callback = callback - self.query = query - self.encoding = encoding - self.options = options - self.timeout = timeout - self.silenceErrors = silenceErrors - self.process = None + Command.__init__(self, args, callback, query=query, + encoding=encoding, options=options, + timeout=timeout, silenceErrors=silenceErrors, + stream=stream) Thread.__init__(self) def stop(self): @@ -108,13 +122,14 @@ def stop(self): pass @staticmethod - def createAndRun(args, query, callback, options=None, timeout=Command.timeout, silenceErrors=False): + def createAndRun(args, query, callback, options=None, + timeout=Command.timeout, silenceErrors=False, stream=False): # Don't allow empty dicts or lists as defaults in method signature, # cfr http://nedbatchelder.com/blog/200806/pylint.html if options is None: options = {} command = ThreadCommand(args, callback, query, options=options, - timeout=timeout, silenceErrors=silenceErrors) + timeout=timeout, silenceErrors=silenceErrors, stream=stream) command.start() killTimeout = Timer(command.timeout, command.stop) killTimeout.start() diff --git a/SQLToolsAPI/Connection.py b/SQLToolsAPI/Connection.py index e188499..2a87ece 100644 --- a/SQLToolsAPI/Connection.py +++ b/SQLToolsAPI/Connection.py @@ -7,7 +7,7 @@ from . import Command as C -class Connection: +class Connection(object): DB_CLI_NOT_FOUND_MESSAGE = """'{0}' could not be found. Please set the path to '{0}' binary in your SQLTools settings before continuing. Example of "cli" section in SQLTools.sublime-settings: @@ -134,7 +134,7 @@ def explainPlan(self, queries, callback): queryToRun = '\n'.join(self.getOptionsForSgdbCli()['before'] + stripped_queries) self.Command.createAndRun(self.builArgs('explain plan'), queryToRun, callback, timeout=self.timeout) - def execute(self, queries, callback): + def execute(self, queries, callback, stream=False): queryToRun = '' for query in self.getOptionsForSgdbCli()['before']: @@ -165,7 +165,7 @@ def execute(self, queries, callback): if Connection.history: Connection.history.add(queryToRun) - self.Command.createAndRun(self.builArgs(), queryToRun, callback, options={'show_query': self.show_query}, timeout=self.timeout) + self.Command.createAndRun(self.builArgs(), queryToRun, callback, options={'show_query': self.show_query}, timeout=self.timeout, stream=stream) def builArgs(self, queryName=None): cliOptions = self.getOptionsForSgdbCli() From eab045e68b74618000edd496e08f3a6a7f153e0e Mon Sep 17 00:00:00 2001 From: Matheus Teixeira Date: Sat, 13 May 2017 17:44:35 -0300 Subject: [PATCH 2/3] Removed trailing spaces --- SQLToolsAPI/Command.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SQLToolsAPI/Command.py b/SQLToolsAPI/Command.py index 9da27e4..d740858 100644 --- a/SQLToolsAPI/Command.py +++ b/SQLToolsAPI/Command.py @@ -60,7 +60,7 @@ def run(self): resultString = "{0}\n{1}\n{2}\n{3}\n*/".format( resultInfo, resultLine, self.query, resultLine) return self.callback(resultString) - + results, errors = self.process.communicate(input=self.query.encode()) queryTimerEnd = time.time() From 495b0e4db9cd80750cdcec536d5bca570f12e265 Mon Sep 17 00:00:00 2001 From: Matheus Teixeira Date: Sat, 13 May 2017 17:45:04 -0300 Subject: [PATCH 3/3] Removed unsed import --- SQLTools.py | 1 - 1 file changed, 1 deletion(-) diff --git a/SQLTools.py b/SQLTools.py index d133689..3852f52 100644 --- a/SQLTools.py +++ b/SQLTools.py @@ -3,7 +3,6 @@ import sys import os import re -from functools import partial import sublime from sublime_plugin import WindowCommand, EventListener, TextCommand