コード例 #1
0
    def __init__(self, my_app: "sqlApp") -> None:

        self.my_app = my_app
        self.search_field = SearchToolbar()
        history_file = config_location() + 'history'
        ensure_dir_exists(history_file)
        hist = ThreadedHistory(FileHistory(expanduser(history_file)))
        self.input_buffer = Buffer(
            name="defaultbuffer",
            tempfile_suffix=".py",
            multiline=MultilineFilter(self.my_app),
            history=hist,
            completer=DynamicCompleter(
                lambda: ThreadedCompleter(self.my_app.completer)),
            #                    lambda: self.my_app.completer),
            auto_suggest=ThreadedAutoSuggest(AutoSuggestFromHistory()),
            complete_while_typing=Condition(
                lambda: self.my_app.active_conn is not None))
        main_win_control = BufferControl(
            buffer=self.input_buffer,
            lexer=PygmentsLexer(SqlLexer),
            search_buffer_control=self.search_field.control,
            include_default_input_processors=False,
            input_processors=[AppendAutoSuggestion()],
            preview_search=True)

        self.main_win = Window(
            main_win_control,
            height=(
                lambda:
                (None if get_app().is_done else
                 (Dimension(min=self.my_app.min_num_menu_lines)
                  if not self.my_app.show_preview else Dimension(
                      min=self.my_app.min_num_menu_lines, preferred=180)))),
            get_line_prefix=partial(sql_line_prefix, my_app=self.my_app),
            scroll_offsets=ScrollOffsets(bottom=1, left=4, right=4))

        self.lprompt = login_prompt(self.my_app)
        self.preview = preview_element(self.my_app)
        self.disconnect_dialog = disconnect_dialog(self.my_app)
        container = HSplit([
            VSplit([
                FloatContainer(
                    content=HSplit([
                        self.main_win,
                        self.search_field,
                    ]),
                    floats=[
                        Float(
                            bottom=1,
                            left=1,
                            right=0,
                            content=sql_sidebar_help(self.my_app),
                        ),
                        Float(content=self.lprompt),
                        Float(content=self.preview, ),
                        Float(content=self.disconnect_dialog, ),
                        Float(left=2,
                              bottom=1,
                              content=exit_confirmation(self.my_app)),
                        Float(xcursor=True,
                              ycursor=True,
                              transparent=True,
                              content=CompletionsMenu(scroll_offset=1,
                                                      max_height=16,
                                                      extra_filter=has_focus(
                                                          self.input_buffer)))
                    ]),
                ConditionalContainer(
                    content=sql_sidebar(self.my_app),
                    filter=ShowSidebar(self.my_app) & ~is_done,
                )
            ]),
            VSplit([
                status_bar(self.my_app),
                show_sidebar_button_info(self.my_app)
            ])
        ])

        def accept(buff):
            app = get_app()
            app.exit(result=["non-preview", buff.text])
            app.pre_run_callables.append(buff.reset)
            return True

        self.input_buffer.accept_handler = accept
        self.layout = Layout(container, focused_element=self.main_win)
コード例 #2
0
ファイル: base.py プロジェクト: Gabriel-Fig-2020/Web-Estudos
    def __init__(
        self,
        text: str = "",
        multiline: FilterOrBool = True,
        password: FilterOrBool = False,
        lexer: Optional[Lexer] = None,
        auto_suggest: Optional[AutoSuggest] = None,
        completer: Optional[Completer] = None,
        complete_while_typing: FilterOrBool = True,
        validator: Optional[Validator] = None,
        accept_handler: Optional[BufferAcceptHandler] = None,
        history: Optional[History] = None,
        focusable: FilterOrBool = True,
        focus_on_click: FilterOrBool = False,
        wrap_lines: FilterOrBool = True,
        read_only: FilterOrBool = False,
        width: AnyDimension = None,
        height: AnyDimension = None,
        dont_extend_height: FilterOrBool = False,
        dont_extend_width: FilterOrBool = False,
        line_numbers: bool = False,
        get_line_prefix: Optional[GetLinePrefixCallable] = None,
        scrollbar: bool = False,
        style: str = "",
        search_field: Optional[SearchToolbar] = None,
        preview_search: FilterOrBool = True,
        prompt: AnyFormattedText = "",
        input_processors: Optional[List[Processor]] = None,
    ) -> None:

        if search_field is None:
            search_control = None
        elif isinstance(search_field, SearchToolbar):
            search_control = search_field.control

        if input_processors is None:
            input_processors = []

        # Writeable attributes.
        self.completer = completer
        self.complete_while_typing = complete_while_typing
        self.lexer = lexer
        self.auto_suggest = auto_suggest
        self.read_only = read_only
        self.wrap_lines = wrap_lines
        self.validator = validator

        self.buffer = Buffer(
            document=Document(text, 0),
            multiline=multiline,
            read_only=Condition(lambda: is_true(self.read_only)),
            completer=DynamicCompleter(lambda: self.completer),
            complete_while_typing=Condition(
                lambda: is_true(self.complete_while_typing)),
            validator=DynamicValidator(lambda: self.validator),
            auto_suggest=DynamicAutoSuggest(lambda: self.auto_suggest),
            accept_handler=accept_handler,
            history=history,
        )

        self.control = BufferControl(
            buffer=self.buffer,
            lexer=DynamicLexer(lambda: self.lexer),
            input_processors=[
                ConditionalProcessor(AppendAutoSuggestion(),
                                     has_focus(self.buffer) & ~is_done),
                ConditionalProcessor(processor=PasswordProcessor(),
                                     filter=to_filter(password)),
                BeforeInput(prompt, style="class:text-area.prompt"),
            ] + input_processors,
            search_buffer_control=search_control,
            preview_search=preview_search,
            focusable=focusable,
            focus_on_click=focus_on_click,
        )

        if multiline:
            if scrollbar:
                right_margins = [ScrollbarMargin(display_arrows=True)]
            else:
                right_margins = []
            if line_numbers:
                left_margins = [NumberedMargin()]
            else:
                left_margins = []
        else:
            height = D.exact(1)
            left_margins = []
            right_margins = []

        style = "class:text-area " + style

        self.window = Window(
            height=height,
            width=width,
            dont_extend_height=dont_extend_height,
            dont_extend_width=dont_extend_width,
            content=self.control,
            style=style,
            wrap_lines=Condition(lambda: is_true(self.wrap_lines)),
            left_margins=left_margins,
            right_margins=right_margins,
            get_line_prefix=get_line_prefix,
        )
コード例 #3
0
	def run_cli(self):
		iterations = 0
		sqlexecute = self.sqlexecute
		logger = self.logger
		self.configure_pager()
		self.refresh_completions()

		history_file = config_location() + "history"
		if dir_path_exists(history_file):
			history = FileHistory(history_file)
		else:
			history = None
			self.echo(
				'Error: Unable to open the history file "{}". '
				"Your query history will not be saved.".format(history_file),
				err=True,
				fg="red",
			)

		key_bindings = cli_bindings(self)

		if 0 and not self.less_chatty:
			print("Version:", __version__)
			print("Mail: https://groups.google.com/forum/#!forum/litecli-users")
			print("Github: https://github.com/dbcli/litecli")
			# print("Home: https://litecli.com")

		def get_message():
			prompt = self.get_prompt(self.prompt_format)
			if (
				self.prompt_format == self.default_prompt
				and len(prompt) > self.max_len_prompt
			):
				prompt = self.get_prompt("\\d> ")
			#print(prompt)
			return [("class:prompt", 'Snow> ')]

		def get_continuation(width, line_number, is_soft_wrap):
			continuation = " " * (width - 1) + " "
			return [("class:continuation", continuation)]

		def show_suggestion_tip():
			return iterations < 2

		def one_iteration(text=None):
			
			if text is None:
				try:
					text = self.prompt_app.prompt()
					
				except KeyboardInterrupt:
					return

				special.set_expanded_output(False)

				try:
					text = self.handle_editor_command(text)
				except RuntimeError as e:
					logger.error("sql: %r, error: %r", text, e)
					logger.error("traceback: %r", traceback.format_exc())
					self.echo(str(e), err=True, fg="red")
					return

			if not text.strip():
				return

			if self.destructive_warning:
				destroy = confirm_destructive_query(text)
				if destroy is None:
					pass  # Query was not destructive. Nothing to do here.
				elif destroy is True:
					self.echo("Your call!")
				else:
					self.echo("Wise choice!")
					return

			# Keep track of whether or not the query is mutating. In case
			# of a multi-statement query, the overall query is considered
			# mutating if any one of the component statements is mutating
			mutating = False

			try:
				logger.debug("sql: %r", text)

				special.write_tee(self.get_prompt(self.prompt_format) + text)
				if self.logfile:
					self.logfile.write("\n# %s\n" % datetime.now())
					self.logfile.write(text)
					self.logfile.write("\n")

				successful = False
				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)
					logger.debug("rows: %r", cur)
					logger.debug("status: %r", status)
					threshold = 1000
					if is_select(status) and cur and cur.rowcount > threshold:
						self.echo(
							"The result set has more than {} rows.".format(threshold),
							fg="red",
						)
						if not confirm("Do you want to continue?"):
							self.echo("Aborted!", err=True, fg="red")
							break

					if self.auto_vertical_output:
						max_width = self.prompt_app.output.get_size().columns
					else:
						max_width = None

					formatted = self.format_output(
						title, cur, headers, special.is_expanded_output(), max_width
					)

					t = time() - start
					try:
						if result_count > 0:
							self.echo("")
						try:
							self.output(formatted, status)
						except KeyboardInterrupt:
							pass
						self.echo("Time: %0.03fs" % t)
					except KeyboardInterrupt:
						pass

					start = time()
					result_count += 1
					mutating = mutating or is_mutating(status)
				special.unset_once_if_written()
			except EOFError as e:
				raise e
			except KeyboardInterrupt:
				# get last connection id
				connection_id_to_kill = sqlexecute.connection_id
				logger.debug("connection id to kill: %r", connection_id_to_kill)
				# Restart connection to the database
				sqlexecute.connect()
				try:
					for title, cur, headers, status in sqlexecute.run(
						"kill %s" % connection_id_to_kill
					):
						status_str = str(status).lower()
						if status_str.find("ok") > -1:
							logger.debug(
								"canceled query, connection id: %r, sql: %r",
								connection_id_to_kill,
								text,
							)
							self.echo("canceled query", err=True, fg="red")
				except Exception as e:
					self.echo(
						"Encountered error while canceling query: {}".format(e),
						err=True,
						fg="red",
					)
			except NotImplementedError:
				self.echo("Not Yet Implemented.", fg="yellow")
			except OperationalError as e:
				logger.debug("Exception: %r", e)
				if e.args[0] in (2003, 2006, 2013):
					logger.debug("Attempting to reconnect.")
					self.echo("Reconnecting...", fg="yellow")
					try:
						sqlexecute.connect()
						logger.debug("Reconnected successfully.")
						one_iteration(text)
						return  # OK to just return, cuz the recursion call runs to the end.
					except OperationalError as e:
						logger.debug("Reconnect failed. e: %r", e)
						self.echo(str(e), err=True, fg="red")
						# If reconnection failed, don't proceed further.
						return
				else:
					logger.error("sql: %r, error: %r", text, e)
					logger.error("traceback: %r", traceback.format_exc())
					self.echo(str(e), err=True, fg="red")
			except Exception as e:
				logger.error("sql: %r, error: %r", text, e)
				logger.error("traceback: %r", traceback.format_exc())
				self.echo(str(e), err=True, fg="red")
			else:
				if is_dropping_database(text, self.sqlexecute.dbname):
					self.sqlexecute.dbname = None
					self.sqlexecute.connect()

				# Refresh the table names and column names if necessary.
				if need_completion_refresh(text):
					self.refresh_completions(reset=need_completion_reset(text))
			finally:
				if self.logfile is False:
					self.echo("Warning: This query was not logged.", err=True, fg="red")
			query = Query(text, successful, mutating)
			self.query_history.append(query)

		get_toolbar_tokens = create_toolbar_tokens_func(self, show_suggestion_tip)

		if self.wider_completion_menu:
			complete_style = CompleteStyle.MULTI_COLUMN
		else:
			complete_style = CompleteStyle.COLUMN

		with self._completer_lock:

			if self.key_bindings == "vi":
				editing_mode = EditingMode.VI
			else:
				editing_mode = EditingMode.EMACS

			self.prompt_app = PromptSession(
				lexer=PygmentsLexer(LiteCliLexer),
				reserve_space_for_menu=self.get_reserved_space(),
				message=get_message,
				prompt_continuation=get_continuation,
				bottom_toolbar=get_toolbar_tokens,
				complete_style=complete_style,
				input_processors=[
					ConditionalProcessor(
						processor=HighlightMatchingBracketProcessor(chars="[](){}"),
						filter=HasFocus(DEFAULT_BUFFER) & ~IsDone(),
					)
				],
				tempfile_suffix=".sql",
				completer=DynamicCompleter(lambda: self.completer),
				history=history,
				auto_suggest=AutoSuggestFromHistory(),
				complete_while_typing=True,
				multiline=cli_is_multiline(self),
				style=style_factory(self.syntax_style, self.cli_style),
				include_default_pygments_style=False,
				key_bindings=key_bindings,
				enable_open_in_editor=True,
				enable_system_prompt=True,
				enable_suspend=True,
				editing_mode=editing_mode,
				search_ignore_case=True,
			)

		try:
			while True:
				one_iteration()
				iterations += 1
		except EOFError:
			special.close_tee()
			if not self.less_chatty:
				self.echo("Goodbye!")
コード例 #4
0
    def __init__(self, text='', multiline=True, password=False,
                 lexer=None, auto_suggest=None, completer=None,
                 complete_while_typing=True, accept_handler=None, history=None,
                 focusable=True, focus_on_click=False, wrap_lines=True,
                 read_only=False, width=None, height=None,
                 dont_extend_height=False, dont_extend_width=False,
                 line_numbers=False, get_line_prefix=None, scrollbar=False,
                 style='', search_field=None, preview_search=True, prompt='',
                 input_processors=None):
        assert isinstance(text, six.text_type)
        assert search_field is None or isinstance(search_field, SearchToolbar)

        if search_field is None:
            search_control = None
        elif isinstance(search_field, SearchToolbar):
            search_control = search_field.control

        if input_processors is None:
            input_processors = []

        # Writeable attributes.
        self.completer = completer
        self.complete_while_typing = complete_while_typing
        self.lexer = lexer
        self.auto_suggest = auto_suggest
        self.read_only = read_only
        self.wrap_lines = wrap_lines

        self.buffer = Buffer(
            document=Document(text, 0),
            multiline=multiline,
            read_only=Condition(lambda: is_true(self.read_only)),
            completer=DynamicCompleter(lambda: self.completer),
            complete_while_typing=Condition(
                lambda: is_true(self.complete_while_typing)),
            auto_suggest=DynamicAutoSuggest(lambda: self.auto_suggest),
            accept_handler=accept_handler,
            history=history)

        self.control = BufferControl(
            buffer=self.buffer,
            lexer=DynamicLexer(lambda: self.lexer),
            input_processors=[
                ConditionalProcessor(
                    AppendAutoSuggestion(),
                    has_focus(self.buffer) & ~is_done),
                ConditionalProcessor(
                    processor=PasswordProcessor(),
                    filter=to_filter(password)
                ),
                BeforeInput(prompt, style='class:text-area.prompt'),
            ] + input_processors,
            search_buffer_control=search_control,
            preview_search=preview_search,
            focusable=focusable,
            focus_on_click=focus_on_click)

        if multiline:
            if scrollbar:
                right_margins = [ScrollbarMargin(display_arrows=True)]
            else:
                right_margins = []
            if line_numbers:
                left_margins = [NumberedMargin()]
            else:
                left_margins = []
        else:
            height = D.exact(1)
            left_margins = []
            right_margins = []

        style = 'class:text-area ' + style

        self.window = Window(
            height=height,
            width=width,
            dont_extend_height=dont_extend_height,
            dont_extend_width=dont_extend_width,
            content=self.control,
            style=style,
            wrap_lines=Condition(lambda: is_true(self.wrap_lines)),
            left_margins=left_margins,
            right_margins=right_margins,
            get_line_prefix=get_line_prefix)
コード例 #5
0
ファイル: python_input.py プロジェクト: Secozzi/ptpython
    def __init__(
        self,
        get_globals: Optional[_GetNamespace] = None,
        get_locals: Optional[_GetNamespace] = None,
        history_filename: Optional[str] = None,
        vi_mode: bool = False,
        color_depth: Optional[ColorDepth] = None,
        # Input/output.
        input: Optional[Input] = None,
        output: Optional[Output] = None,
        # For internal use.
        extra_key_bindings: Optional[KeyBindings] = None,
        _completer: Optional[Completer] = None,
        _validator: Optional[Validator] = None,
        _lexer: Optional[Lexer] = None,
        _extra_buffer_processors=None,
        _extra_layout_body=None,
        _extra_toolbars=None,
        _input_buffer_height=None,
    ) -> None:

        self.get_globals: _GetNamespace = get_globals or (lambda: {})
        self.get_locals: _GetNamespace = get_locals or self.get_globals

        self.completer = _completer or PythonCompleter(
            self.get_globals,
            self.get_locals,
            lambda: self.enable_dictionary_completion,
        )

        self._completer = HidePrivateCompleter(
            # If fuzzy is enabled, first do fuzzy completion, but always add
            # the non-fuzzy completions, if somehow the fuzzy completer didn't
            # find them. (Due to the way the cursor position is moved in the
            # fuzzy completer, some completions will not always be found by the
            # fuzzy completer, but will be found with the normal completer.)
            merge_completers(
                [
                    ConditionalCompleter(
                        FuzzyCompleter(
                            DynamicCompleter(lambda: self.completer)),
                        Condition(lambda: self.enable_fuzzy_completion),
                    ),
                    DynamicCompleter(lambda: self.completer),
                ],
                deduplicate=True,
            ),
            lambda: self.complete_private_attributes,
        )
        self._validator = _validator or PythonValidator(
            self.get_compiler_flags)
        self._lexer = PtpythonLexer(_lexer)

        self.history: History
        if history_filename:
            self.history = ThreadedHistory(FileHistory(history_filename))
        else:
            self.history = InMemoryHistory()

        self._input_buffer_height = _input_buffer_height
        self._extra_layout_body = _extra_layout_body or []
        self._extra_toolbars = _extra_toolbars or []
        self._extra_buffer_processors = _extra_buffer_processors or []

        self.extra_key_bindings = extra_key_bindings or KeyBindings()

        # Settings.
        self.title: AnyFormattedText = ""
        self.show_signature: bool = False
        self.show_docstring: bool = False
        self.show_meta_enter_message: bool = True
        self.completion_visualisation: CompletionVisualisation = (
            CompletionVisualisation.MULTI_COLUMN)
        self.completion_menu_scroll_offset: int = 1

        self.show_line_numbers: bool = False
        self.show_status_bar: bool = True
        self.wrap_lines: bool = True
        self.complete_while_typing: bool = True
        self.paste_mode: bool = (
            False  # When True, don't insert whitespace after newline.
        )
        self.confirm_exit: bool = (
            True  # Ask for confirmation when Control-D is pressed.
        )
        self.accept_input_on_enter: int = 2  # Accept when pressing Enter 'n' times.
        # 'None' means that meta-enter is always required.
        self.enable_open_in_editor: bool = True
        self.enable_system_bindings: bool = True
        self.enable_input_validation: bool = True
        self.enable_auto_suggest: bool = False
        self.enable_mouse_support: bool = False
        self.enable_history_search: bool = False  # When True, like readline, going
        # back in history will filter the
        # history on the records starting
        # with the current input.

        self.enable_syntax_highlighting: bool = True
        self.enable_fuzzy_completion: bool = False
        self.enable_dictionary_completion: bool = False  # Also eval-based completion.
        self.complete_private_attributes: CompletePrivateAttributes = (
            CompletePrivateAttributes.ALWAYS)
        self.swap_light_and_dark: bool = False
        self.highlight_matching_parenthesis: bool = False
        self.show_sidebar: bool = False  # Currently show the sidebar.

        # Pager.
        self.enable_output_formatting: bool = False
        self.enable_pager: bool = False
        self.show_locals: bool = True

        # When the sidebar is visible, also show the help text.
        self.show_sidebar_help: bool = True

        # Currently show 'Do you really want to exit?'
        self.show_exit_confirmation: bool = False

        # The title to be displayed in the terminal. (None or string.)
        self.terminal_title: Optional[str] = None

        self.exit_message: str = "Do you really want to exit?"
        self.insert_blank_line_after_output: bool = True  # (For the REPL.)
        self.insert_blank_line_after_input: bool = False  # (For the REPL.)

        # The buffers.
        self.default_buffer = self._create_buffer()
        self.search_buffer: Buffer = Buffer()
        self.docstring_buffer: Buffer = Buffer(read_only=True)

        # Tokens to be shown at the prompt.
        self.prompt_style: str = "classic"  # The currently active style.

        # Styles selectable from the menu.
        self.all_prompt_styles: Dict[str, PromptStyle] = {
            "ipython": IPythonPrompt(self),
            "classic": ClassicPrompt(),
        }

        self.get_input_prompt = lambda: self.all_prompt_styles[
            self.prompt_style].in_prompt()

        self.get_output_prompt = lambda: self.all_prompt_styles[
            self.prompt_style].out_prompt()

        #: Load styles.
        self.code_styles: Dict[str, BaseStyle] = get_all_code_styles()
        self.ui_styles = get_all_ui_styles()
        self._current_code_style_name: str = "default"
        self._current_ui_style_name: str = "default"

        if is_windows():
            self._current_code_style_name = "win32"

        self._current_style = self._generate_style()
        self.color_depth: ColorDepth = color_depth or ColorDepth.default()

        self.max_brightness: float = 1.0
        self.min_brightness: float = 0.0

        # Options to be configurable from the sidebar.
        self.options = self._create_options()
        self.selected_option_index: int = 0

        #: Incremeting integer counting the current statement.
        self.current_statement_index: int = 1

        # Code signatures. (This is set asynchronously after a timeout.)
        self.signatures: List[Signature] = []

        # Boolean indicating whether we have a signatures thread running.
        # (Never run more than one at the same time.)
        self._get_signatures_thread_running: bool = False

        # Get into Vi navigation mode at startup
        self.vi_start_in_navigation_mode: bool = False

        # Preserve last used Vi input mode between main loop iterations
        self.vi_keep_last_used_mode: bool = False

        self.style_transformation = merge_style_transformations([
            ConditionalStyleTransformation(
                SwapLightAndDarkStyleTransformation(),
                filter=Condition(lambda: self.swap_light_and_dark),
            ),
            AdjustBrightnessStyleTransformation(lambda: self.min_brightness,
                                                lambda: self.max_brightness),
        ])
        self.ptpython_layout = PtPythonLayout(
            self,
            lexer=DynamicLexer(lambda: self._lexer if self.
                               enable_syntax_highlighting else SimpleLexer()),
            input_buffer_height=self._input_buffer_height,
            extra_buffer_processors=self._extra_buffer_processors,
            extra_body=self._extra_layout_body,
            extra_toolbars=self._extra_toolbars,
        )

        self.app = self._create_application(input, output)

        if vi_mode:
            self.app.editing_mode = EditingMode.VI
コード例 #6
0
    def run_cli(self):
        iterations = 0
        sqlexecute = self.sqlexecute
        logger = self.logger
        self.configure_pager()

        if self.smart_completion:
            self.refresh_completions()

        author_file = os.path.join(PACKAGE_ROOT, 'AUTHORS')
        sponsor_file = os.path.join(PACKAGE_ROOT, 'SPONSORS')

        history_file = os.path.expanduser(
            os.environ.get('MYCLI_HISTFILE', '~/.mycli-history'))
        if dir_path_exists(history_file):
            history = FileHistory(history_file)
        else:
            history = None
            self.echo(
                'Error: Unable to open the history file "{}". '
                'Your query history will not be saved.'.format(history_file),
                err=True, fg='red')

        key_bindings = mycli_bindings(self)

        if not self.less_chatty:
            print(' '.join(sqlexecute.server_type()))
            print('mycli', __version__)
            print('Chat: https://gitter.im/dbcli/mycli')
            print('Mail: https://groups.google.com/forum/#!forum/mycli-users')
            print('Home: http://mycli.net')
            print('Thanks to the contributor -', thanks_picker([author_file, sponsor_file]))

        def get_message():
            prompt = self.get_prompt(self.prompt_format)
            if self.prompt_format == self.default_prompt and len(prompt) > self.max_len_prompt:
                prompt = self.get_prompt('\\d> ')
            return [('class:prompt', prompt)]

        def get_continuation(width, line_number, is_soft_wrap):
            continuation = ' ' * (width - 1) + ' '
            return [('class:continuation', continuation)]

        def show_suggestion_tip():
            return iterations < 2

        def one_iteration(text=None):
            if text is None:
                try:
                    text = self.prompt_app.prompt(
                        vi_mode=self.key_bindings == 'vi'
                    )
                except KeyboardInterrupt:
                    return

                special.set_expanded_output(False)

                try:
                    text = self.handle_editor_command(text)
                except RuntimeError as e:
                    logger.error("sql: %r, error: %r", text, e)
                    logger.error("traceback: %r", traceback.format_exc())
                    self.echo(str(e), err=True, fg='red')
                    return

            if not text.strip():
                return

            if self.destructive_warning:
                destroy = confirm_destructive_query(text)
                if destroy is None:
                    pass  # Query was not destructive. Nothing to do here.
                elif destroy is True:
                    self.echo('Your call!')
                else:
                    self.echo('Wise choice!')
                    return

            # Keep track of whether or not the query is mutating. In case
            # of a multi-statement query, the overall query is considered
            # mutating if any one of the component statements is mutating
            mutating = False

            try:
                logger.debug('sql: %r', text)

                special.write_tee(self.get_prompt(self.prompt_format) + text)
                if self.logfile:
                    self.logfile.write('\n# %s\n' % datetime.now())
                    self.logfile.write(text)
                    self.logfile.write('\n')

                successful = False
                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)
                    logger.debug("rows: %r", cur)
                    logger.debug("status: %r", status)
                    threshold = 1000
                    if (is_select(status) and
                            cur and cur.rowcount > threshold):
                        self.echo('The result set has more than {} rows.'.format(
                            threshold), fg='red')
                        if not confirm('Do you want to continue?'):
                            self.echo("Aborted!", err=True, fg='red')
                            break

                    if self.auto_vertical_output:
                        max_width = self.prompt_app.output.get_size().columns
                    else:
                        max_width = None

                    formatted = self.format_output(
                        title, cur, headers, special.is_expanded_output(),
                        max_width)

                    t = time() - start
                    try:
                        if result_count > 0:
                            self.echo('')
                        try:
                            self.output(formatted, status)
                        except KeyboardInterrupt:
                            pass
                        if special.is_timing_enabled():
                            self.echo('Time: %0.03fs' % t)
                    except KeyboardInterrupt:
                        pass

                    start = time()
                    result_count += 1
                    mutating = mutating or is_mutating(status)
                special.unset_once_if_written()
            except EOFError as e:
                raise e
            except KeyboardInterrupt:
                # get last connection id
                connection_id_to_kill = sqlexecute.connection_id
                logger.debug("connection id to kill: %r", connection_id_to_kill)
                # Restart connection to the database
                sqlexecute.connect()
                try:
                    for title, cur, headers, status in sqlexecute.run('kill %s' % connection_id_to_kill):
                        status_str = str(status).lower()
                        if status_str.find('ok') > -1:
                            logger.debug("cancelled query, connection id: %r, sql: %r",
                                         connection_id_to_kill, text)
                            self.echo("cancelled query", err=True, fg='red')
                except Exception as e:
                    self.echo('Encountered error while cancelling query: {}'.format(e),
                              err=True, fg='red')
            except NotImplementedError:
                self.echo('Not Yet Implemented.', fg="yellow")
            except OperationalError as e:
                logger.debug("Exception: %r", e)
                if (e.args[0] in (2003, 2006, 2013)):
                    logger.debug('Attempting to reconnect.')
                    self.echo('Reconnecting...', fg='yellow')
                    try:
                        sqlexecute.connect()
                        logger.debug('Reconnected successfully.')
                        one_iteration(text)
                        return  # OK to just return, cuz the recursion call runs to the end.
                    except OperationalError as e:
                        logger.debug('Reconnect failed. e: %r', e)
                        self.echo(str(e), err=True, fg='red')
                        # If reconnection failed, don't proceed further.
                        return
                else:
                    logger.error("sql: %r, error: %r", text, e)
                    logger.error("traceback: %r", traceback.format_exc())
                    self.echo(str(e), err=True, fg='red')
            except Exception as e:
                logger.error("sql: %r, error: %r", text, e)
                logger.error("traceback: %r", traceback.format_exc())
                self.echo(str(e), err=True, fg='red')
            else:
                if is_dropping_database(text, self.sqlexecute.dbname):
                    self.sqlexecute.dbname = None
                    self.sqlexecute.connect()

                # Refresh the table names and column names if necessary.
                if need_completion_refresh(text):
                    self.refresh_completions(
                        reset=need_completion_reset(text))
            finally:
                if self.logfile is False:
                    self.echo("Warning: This query was not logged.",
                              err=True, fg='red')
            query = Query(text, successful, mutating)
            self.query_history.append(query)

        get_toolbar_tokens = create_toolbar_tokens_func(
            self, show_suggestion_tip)
        if self.wider_completion_menu:
            complete_style = CompleteStyle.MULTI_COLUMN
        else:
            complete_style = CompleteStyle.COLUMN

        with self._completer_lock:

            if self.key_bindings == 'vi':
                editing_mode = EditingMode.VI
            else:
                editing_mode = EditingMode.EMACS

            self.prompt_app = PromptSession(
                lexer=PygmentsLexer(MyCliLexer),
                reserve_space_for_menu=self.get_reserved_space(),
                message=get_message,
                prompt_continuation=get_continuation,
                bottom_toolbar=get_toolbar_tokens,
                complete_style=complete_style,
                input_processors=[ConditionalProcessor(
                    processor=HighlightMatchingBracketProcessor(
                        chars='[](){}'),
                    filter=HasFocus(DEFAULT_BUFFER) & ~IsDone()
                )],
                tempfile_suffix='.sql',
                completer=DynamicCompleter(lambda: self.completer),
                history=history,
                auto_suggest=AutoSuggestFromHistory(),
                complete_while_typing=True,
                multiline=cli_is_multiline(self),
                style=style_factory(self.syntax_style, self.cli_style),
                include_default_pygments_style=False,
                key_bindings=key_bindings,
                enable_open_in_editor=True,
                enable_system_prompt=True,
                editing_mode=editing_mode,
                search_ignore_case=True
            )

        try:
            while True:
                one_iteration()
                iterations += 1
        except EOFError:
            special.close_tee()
            if not self.less_chatty:
                self.echo('Goodbye!')
コード例 #7
0
ファイル: main.py プロジェクト: timgates42/pgcli
    def _build_cli(self, history):
        key_bindings = pgcli_bindings(self)

        def get_message():
            if self.dsn_alias and self.prompt_dsn_format is not None:
                prompt_format = self.prompt_dsn_format
            else:
                prompt_format = self.prompt_format

            prompt = self.get_prompt(prompt_format)

            if (
                prompt_format == self.default_prompt
                and len(prompt) > self.max_len_prompt
            ):
                prompt = self.get_prompt("\\d> ")

            return [("class:prompt", prompt)]

        def get_continuation(width, line_number, is_soft_wrap):
            continuation = self.multiline_continuation_char * (width - 1) + " "
            return [("class:continuation", continuation)]

        get_toolbar_tokens = create_toolbar_tokens_func(self)

        if self.wider_completion_menu:
            complete_style = CompleteStyle.MULTI_COLUMN
        else:
            complete_style = CompleteStyle.COLUMN

        with self._completer_lock:
            prompt_app = PromptSession(
                lexer=PygmentsLexer(PostgresLexer),
                reserve_space_for_menu=self.min_num_menu_lines,
                message=get_message,
                prompt_continuation=get_continuation,
                bottom_toolbar=get_toolbar_tokens,
                complete_style=complete_style,
                input_processors=[
                    # Highlight matching brackets while editing.
                    ConditionalProcessor(
                        processor=HighlightMatchingBracketProcessor(chars="[](){}"),
                        filter=HasFocus(DEFAULT_BUFFER) & ~IsDone(),
                    ),
                    # Render \t as 4 spaces instead of "^I"
                    TabsProcessor(char1=" ", char2=" "),
                ],
                auto_suggest=AutoSuggestFromHistory(),
                tempfile_suffix=".sql",
                # N.b. pgcli's multi-line mode controls submit-on-Enter (which
                # overrides the default behaviour of prompt_toolkit) and is
                # distinct from prompt_toolkit's multiline mode here, which
                # controls layout/display of the prompt/buffer
                multiline=True,
                history=history,
                completer=ThreadedCompleter(DynamicCompleter(lambda: self.completer)),
                complete_while_typing=True,
                style=style_factory(self.syntax_style, self.cli_style),
                include_default_pygments_style=False,
                key_bindings=key_bindings,
                enable_open_in_editor=True,
                enable_system_prompt=True,
                enable_suspend=True,
                editing_mode=EditingMode.VI if self.vi_mode else EditingMode.EMACS,
                search_ignore_case=True,
            )

            return prompt_app
コード例 #8
0
    def doexec(self):
        """Entrance of the client terminal program"""
        def exec():
            try:
                text = self.xprompt.prompt()
            except KeyboardInterrupt:
                return
          
            if len(text) < 7 and ''.join(text.lower().split()) in ['quit;', 'exit;']:
                click.secho('See you again!', fg='green')
                sys.exit(0)

        def continuation(width, *_):
            if self.multi_continuation == '':
                pmp = ''
            elif self.multi_continuation:
                left = width - len(self.multi_continuation)
                pmp = " " * max((left - 1), 0) + self.multi_continuation + " "  
            else:
                pmp = ""

            return [('class:continuation', pmp)]

        print("")
        print("Welcome to use xugu database products.")
        print("Successfully connect to %s:%s %s as %s" %(self.options['host'], 
               self.options['port'], self.options['database'], self.options['user']))
        print("%s: %s" %(self.options['name'], self.version))
        print('Home: http://www.xugucn.com/')
        print("")

        bar = xbottom_toolbar(self)
        binding = xbottom_binding(self)

        def xstyle():
            elem = [ 
                    ('completion-menu.completion.current', 'bg:#ffffff #000000'),
                    ('completion-menu.completion', 'bg:#008888 #ffffff'),
                    ('completion-menu.meta.completion.current', 'bg:#44aaaa #000000'),
                    ('completion-menu.meta.completion', 'bg:#448888 #ffffff'),
                    ('completion-menu.multi-column-meta', 'bg:#aaffff #000000'),
                    ('scrollbar.arrow', 'bg:#003333'),
                    ('scrollbar', 'bg:#00aaaa'),
                    ('selected', '#ffffff bg:#6666aa'),
                    ('search', '#ffffff bg:#4444aa'),
                    ('output.header', '#00ff5f bold'),
                    ('output.odd-row', ''),
                    ('output.even-row', ''),
                    ('output.null', '#808080'),
                    ('search.current', '#ffffff bg:#44aa44'),
                    ('bottom-toolbar', 'bg:#222222 #aaaaaa'),
                    ('bottom-toolbar.off', 'bg:#222222 #888888'),
                    ('bottom-toolbar.on', 'bg:#222222 #ffffff'),
                    ('bottom-toolbar.transaction.valid', 'bg:#222222 #00ff5f bold'),
                    ('bottom-toolbar.transaction.failed', 'bg:#222222 #ff005f bold'),
                    ('search-toolbar', 'noinherit bold'),
                    ('search-toolbar.text', 'nobold'),
                    ('system-toolbar', 'noinherit bold'),
                    ('arg-toolbar', 'noinherit bold')]

            style = pygments.styles.get_style_by_name('default')
            override_style = Style([('bottom-toolbar', 'noreverse')])
            
            return merge_styles([style_from_pygments_cls(style),
                              override_style,
                              Style(elem)])

        self.xprompt = PromptSession(
                            message = self.xlogin(),
                            lexer = PygmentsLexer(XgCliLexer),
                            completer = DynamicCompleter(lambda: self.completer),
                            bottom_toolbar = bar,
                            style = xstyle(),
                            prompt_continuation = continuation,
                            key_bindings = binding,
                            multiline = cli_multiline(self),
                            complete_while_typing=True,
                            include_default_pygments_style=False, 
        )
        
        try:
            while True:
                exec()
        except EOFError:
            click.secho('See you again!', fg='green')
コード例 #9
0
    def _create_application(self, editing_mode, erase_when_done):
        def dyncond(attr_name):
            """
            Dynamically take this setting from this 'Prompt' class.
            `attr_name` represents an attribute name of this class. Its value
            can either be a boolean or a `Filter`.

            This returns something that can be used as either a `Filter`
            or `Filter`.
            """
            @Condition
            def dynamic():
                value = getattr(self, attr_name)
                return to_filter(value)()

            return dynamic

        # Create functions that will dynamically split the prompt. (If we have
        # a multiline prompt.)
        has_before_fragments, get_prompt_text_1, get_prompt_text_2 = \
            _split_multiline_prompt(self._get_prompt)

        # Create buffers list.
        def accept(buff):
            """ Accept the content of the default buffer. This is called when
            the validation succeeds. """
            self.app.set_result(buff.document.text)

            # Reset content before running again.
            self.app.pre_run_callables.append(buff.reset)

        default_buffer = Buffer(
            name=DEFAULT_BUFFER,
            # Make sure that complete_while_typing is disabled when
            # enable_history_search is enabled. (First convert to Filter,
            # to avoid doing bitwise operations on bool objects.)
            complete_while_typing=Condition(
                lambda: _true(self.complete_while_typing) and not _true(
                    self.enable_history_search) and not self.complete_style ==
                CompleteStyle.READLINE_LIKE),
            validate_while_typing=dyncond('validate_while_typing'),
            enable_history_search=dyncond('enable_history_search'),
            validator=DynamicValidator(lambda: self.validator),
            completer=ThreadedCompleter(
                completer=DynamicCompleter(lambda: self.completer),
                in_thread=dyncond('complete_in_thread'),
            ),
            history=DynamicHistory(lambda: self.history),
            auto_suggest=DynamicAutoSuggest(lambda: self.auto_suggest),
            accept_handler=accept,
            get_tempfile_suffix=lambda: self.tempfile_suffix)

        search_buffer = Buffer(name=SEARCH_BUFFER)

        # Create processors list.
        input_processor = merge_processors([
            ConditionalProcessor(
                # By default, only highlight search when the search
                # input has the focus. (Note that this doesn't mean
                # there is no search: the Vi 'n' binding for instance
                # still allows to jump to the next match in
                # navigation mode.)
                HighlightSearchProcessor(preview_search=True),
                has_focus(search_buffer)),
            HighlightSelectionProcessor(),
            ConditionalProcessor(AppendAutoSuggestion(),
                                 has_focus(default_buffer) & ~is_done),
            ConditionalProcessor(PasswordProcessor(), dyncond('is_password')),
            DisplayMultipleCursors(),

            # Users can insert processors here.
            DynamicProcessor(lambda: self.extra_input_processor),

            # For single line mode, show the prompt before the input.
            ConditionalProcessor(
                merge_processors([
                    BeforeInput(get_prompt_text_2),
                    ShowArg(),
                ]), ~dyncond('multiline'))
        ])

        # Create bottom toolbars.
        bottom_toolbar = ConditionalContainer(
            Window(FormattedTextControl(lambda: self.bottom_toolbar,
                                        style='class:bottom-toolbar.text'),
                   style='class:bottom-toolbar',
                   dont_extend_height=True,
                   height=Dimension(min=1)),
            filter=~is_done & renderer_height_is_known
            & Condition(lambda: self.bottom_toolbar is not None))

        search_toolbar = SearchToolbar(
            search_buffer,
            get_search_state=lambda: default_buffer_control.get_search_state())
        search_buffer_control = BufferControl(buffer=search_buffer,
                                              input_processor=merge_processors(
                                                  [
                                                      ReverseSearchProcessor(),
                                                      ShowArg(),
                                                  ]))

        system_toolbar = SystemToolbar()

        def get_search_buffer_control():
            " Return the UIControl to be focused when searching start. "
            if _true(self.multiline):
                return search_toolbar.control
            else:
                return search_buffer_control

        default_buffer_control = BufferControl(
            buffer=default_buffer,
            get_search_buffer_control=get_search_buffer_control,
            input_processor=input_processor,
            lexer=DynamicLexer(lambda: self.lexer),
            preview_search=True)

        default_buffer_window = Window(
            default_buffer_control,
            height=self._get_default_buffer_control_height,
            left_margins=[
                # In multiline mode, use the window margin to display
                # the prompt and continuation fragments.
                ConditionalMargin(
                    PromptMargin(get_prompt_text_2, self._get_continuation),
                    filter=dyncond('multiline'),
                )
            ],
            wrap_lines=dyncond('wrap_lines'))

        @Condition
        def multi_column_complete_style():
            return self.complete_style == CompleteStyle.MULTI_COLUMN

        # Build the layout.
        layout = HSplit([
            # The main input, with completion menus floating on top of it.
            FloatContainer(
                HSplit([
                    ConditionalContainer(
                        Window(FormattedTextControl(get_prompt_text_1),
                               dont_extend_height=True),
                        Condition(has_before_fragments)),
                    ConditionalContainer(
                        default_buffer_window,
                        Condition(lambda: get_app().layout.current_control !=
                                  search_buffer_control),
                    ),
                    ConditionalContainer(
                        Window(search_buffer_control),
                        Condition(lambda: get_app().layout.current_control ==
                                  search_buffer_control),
                    ),
                ]),
                [
                    # Completion menus.
                    Float(xcursor=True,
                          ycursor=True,
                          content=CompletionsMenu(
                              max_height=16,
                              scroll_offset=1,
                              extra_filter=has_focus(default_buffer)
                              & ~multi_column_complete_style)),
                    Float(xcursor=True,
                          ycursor=True,
                          content=MultiColumnCompletionsMenu(
                              show_meta=True,
                              extra_filter=has_focus(default_buffer)
                              & multi_column_complete_style)),
                    # The right prompt.
                    Float(right=0,
                          top=0,
                          hide_when_covering_content=True,
                          content=_RPrompt(lambda: self.rprompt)),
                ]),
            ConditionalContainer(ValidationToolbar(), filter=~is_done),
            ConditionalContainer(system_toolbar,
                                 dyncond('enable_system_prompt') & ~is_done),

            # In multiline mode, we use two toolbars for 'arg' and 'search'.
            ConditionalContainer(
                Window(FormattedTextControl(self._get_arg_text), height=1),
                dyncond('multiline') & has_arg),
            ConditionalContainer(search_toolbar,
                                 dyncond('multiline') & ~is_done),
            bottom_toolbar,
        ])

        # Default key bindings.
        auto_suggest_bindings = load_auto_suggest_bindings()
        open_in_editor_bindings = load_open_in_editor_bindings()
        prompt_bindings = self._create_prompt_bindings()

        # Create application
        application = Application(
            layout=Layout(layout, default_buffer_window),
            style=DynamicStyle(lambda: self.style),
            include_default_pygments_style=dyncond(
                'include_default_pygments_style'),
            clipboard=DynamicClipboard(lambda: self.clipboard),
            key_bindings=merge_key_bindings([
                merge_key_bindings([
                    auto_suggest_bindings,
                    ConditionalKeyBindings(
                        open_in_editor_bindings,
                        dyncond('enable_open_in_editor')
                        & has_focus(DEFAULT_BUFFER)), prompt_bindings
                ]),
                ConditionalKeyBindings(
                    system_toolbar.get_global_key_bindings(),
                    dyncond('enable_system_prompt')),
                DynamicKeyBindings(lambda: self.extra_key_bindings),
            ]),
            mouse_support=dyncond('mouse_support'),
            editing_mode=editing_mode,
            erase_when_done=erase_when_done,
            reverse_vi_search_direction=True,

            # I/O.
            input=self.input,
            output=self.output)

        # During render time, make sure that we focus the right search control
        # (if we are searching). - This could be useful if people make the
        # 'multiline' property dynamic.
        '''
        def on_render(app):
            multiline = _true(self.multiline)
            current_control = app.layout.current_control

            if multiline:
                if current_control == search_buffer_control:
                    app.layout.current_control = search_toolbar.control
                    app.invalidate()
            else:
                if current_control == search_toolbar.control:
                    app.layout.current_control = search_buffer_control
                    app.invalidate()

        app.on_render += on_render
        '''

        return application, default_buffer, default_buffer_control
コード例 #10
0
    def _build_cli(self, history):
        """
            Builds prompt session.
            NOTE: PROMPT-SESSION USES THIS AS DEPENDENCY.
        """

        def get_message():
            prompt = self.get_prompt(self.prompt_format)
            return [(u'class:prompt', prompt)]

        def get_continuation(width, line_number, is_soft_wrap):
            """
                NOTE: updating parameters will cause prompt session to crash.
            """
            # pylint: disable=unused-argument
            continuation = self.multiline_continuation_char * (width - 1) + ' '
            return [(u'class:continuation', continuation)]

        get_toolbar_tokens = create_toolbar_tokens_func(self)

        if self.wider_completion_menu:
            complete_style = CompleteStyle.MULTI_COLUMN
        else:
            complete_style = CompleteStyle.COLUMN

        with self._completer_lock:
            self.prompt_session = PromptSession(
                message=get_message,
                style=style_factory(self.syntax_style, self.cli_style),

                # Layout options.
                lexer=PygmentsLexer(PostgresLexer),
                prompt_continuation=get_continuation,
                bottom_toolbar=get_toolbar_tokens,
                complete_style=complete_style,
                input_processors=[
                    ConditionalProcessor(
                        processor=HighlightMatchingBracketProcessor(
                            chars='[](){}'),
                        #pylint: disable=invalid-unary-operand-type
                        filter=HasFocus(DEFAULT_BUFFER) & ~IsDone()),
                    # Render \t as 4 spaces instead of "^I"
                    TabsProcessor(char1=u' ', char2=u' ')],
                reserve_space_for_menu=self.min_num_menu_lines,

                # Buffer options.
                multiline=mssql_is_multiline(self),
                completer=ThreadedCompleter(
                    DynamicCompleter(lambda: self.completer)),
                history=history, auto_suggest=AutoSuggestFromHistory(),
                complete_while_typing=True,

                # Key bindings.
                enable_system_prompt=True,
                enable_open_in_editor=True,

                # Other options.
                key_bindings=mssqlcli_bindings(self),
                editing_mode=EditingMode.VI if self.vi_mode else EditingMode.EMACS,
                search_ignore_case=True)

            return self.prompt_session