| 8 | |
| 9 | |
| 10 | class CompletionRefresher: |
| 11 | |
| 12 | refreshers = OrderedDict() |
| 13 | |
| 14 | def __init__(self): |
| 15 | self._completer_thread = None |
| 16 | self._restart_refresh = threading.Event() |
| 17 | |
| 18 | def refresh(self, mssqcliclient, callbacks, history=None, |
| 19 | settings=None): |
| 20 | """ |
| 21 | Creates a MssqlCompleter object and populates it with the relevant |
| 22 | completion suggestions in a background thread. |
| 23 | |
| 24 | mssqlcliclient - used to extract the credentials to connect |
| 25 | to the database. |
| 26 | settings - dict of settings for completer object |
| 27 | callbacks - A function or a list of functions to call after the thread |
| 28 | has completed the refresh. The newly created completion |
| 29 | object will be passed in as an argument to each callback. |
| 30 | """ |
| 31 | if self.is_refreshing(): |
| 32 | self._restart_refresh.set() |
| 33 | return [(None, None, None, 'Auto-completion refresh restarted.')] |
| 34 | |
| 35 | self._completer_thread = threading.Thread( |
| 36 | target=self._bg_refresh, |
| 37 | args=(mssqcliclient, callbacks, history, settings), |
| 38 | name='completion_refresh') |
| 39 | self._completer_thread.setDaemon(True) |
| 40 | self._completer_thread.start() |
| 41 | return [(None, None, None, |
| 42 | 'Auto-completion refresh started in the background.')] |
| 43 | |
| 44 | def is_refreshing(self): |
| 45 | return self._completer_thread and self._completer_thread.is_alive() |
| 46 | |
| 47 | def _bg_refresh(self, mssqlcliclient, callbacks, history=None, |
| 48 | settings=None): |
| 49 | settings = settings or {} |
| 50 | completer = MssqlCompleter(smart_completion=True, settings=settings) |
| 51 | |
| 52 | executor = mssqlcliclient |
| 53 | owner_uri, error_messages = executor.connect_to_database() |
| 54 | |
| 55 | if not owner_uri: |
| 56 | # If we were unable to connect, do not break the experience for the user. |
| 57 | # Return nothing, smart completion can maintain the keywords and functions completions. |
| 58 | logger.error(u'Completion refresher connection failure.'.join(error_messages)) |
| 59 | return |
| 60 | # If callbacks is a single function then push it into a list. |
| 61 | if callable(callbacks): |
| 62 | callbacks = [callbacks] |
| 63 | |
| 64 | while 1: |
| 65 | for refresh in self.refreshers.values(): |
| 66 | refresh(completer, executor) |
| 67 | if self._restart_refresh.is_set(): |
no outgoing calls