def refresh(self, callbacks, history=None, settings=None) -> str: """ Creates a PGCompleter object and populates it with the relevant completion suggestions in a background thread. settings - dict of settings for completer object callbacks - A function or a list of functions to call after the thread has completed the refresh. The newly created completion object will be passed in as an argument to each callback. """ if self.server is None: # Delay server creation until on background thread self.server = Server(self.connection) if self.is_refreshing(): self._restart_refresh.set() return 'Auto-completion refresh restarted.' else: self._completer_thread = threading.Thread( target=self._bg_refresh, args=(callbacks, history, settings), name='completion_refresh') self._completer_thread.daemon = True self._completer_thread.start() return 'Auto-completion refresh started in the background.' # TODO localize
def setUp(self): mock_server = Server(utils.MockPGServerConnection()) db = Database(mock_server, mock_server.maintenance_db_name) mock_server._child_objects[ Database.__name__] = self._as_node_collection([db]) mock_server._search_path = self._as_node_collection([MYSCHEMA]) self.schema1 = Schema(mock_server, db, MYSCHEMA) self.schema2 = Schema(mock_server, db, MYSCHEMA2) db._schemas = self._as_node_collection([self.schema1, self.schema2]) self.mock_server = mock_server self.executor: MetadataExecutor = MetadataExecutor(mock_server)
def get(self, connection: 'psycopg2.extensions.connection', schema_name: str, object_name: str, object_type: str) -> EditTableMetadata: server = Server(connection) result_object: Table = None object_metadata = ObjectMetadata(server.urn_base, None, object_type, object_name, schema_name) if object_type.lower() == 'table': result_object = object_finder.find_table(server, object_metadata) elif object_type.lower() == 'view': result_object = object_finder.find_view(server, object_metadata) else: raise ValueError('Not supported object type') edit_columns_metadata: List[EditColumnMetadata] = [] for column in result_object.columns: db_column = self.create_db_column(column) edit_columns_metadata.append( EditColumnMetadata(db_column, column.default_value)) return EditTableMetadata(schema_name, object_name, edit_columns_metadata)
def _initialize_session(self, request_context: RequestContext, session: ObjectExplorerSession): conn_service = self._service_provider[utils.constants.CONNECTION_SERVICE_NAME] connection = None try: # Step 1: Connect with the provided connection details connect_request = ConnectRequestParams( session.connection_details, session.id, ConnectionType.OBJECT_EXLPORER ) connect_result = conn_service.connect(connect_request) if connect_result is None: raise RuntimeError('Connection was cancelled during connect') # TODO Localize if connect_result.error_message is not None: raise RuntimeError(connect_result.error_message) # Step 2: Get the connection to use for object explorer connection = conn_service.get_connection(session.id, ConnectionType.OBJECT_EXLPORER) # Step 3: Create the PGSMO Server object for the session and create the root node for the server session.server = Server(connection, functools.partial(self._create_connection, session)) metadata = ObjectMetadata(session.server.urn_base, None, 'Database', session.server.maintenance_db_name) node = NodeInfo() node.label = session.connection_details.options['dbname'] node.is_leaf = False node.node_path = session.id node.node_type = 'Database' node.metadata = metadata # Step 4: Send the completion notification to the server response = SessionCreatedParameters() response.success = True response.session_id = session.id response.root_node = node response.error_message = None request_context.send_notification(SESSION_CREATED_METHOD, response) # Mark the session as complete session.is_ready = True except Exception as e: # Return a notification that an error occurred message = f'Failed to initialize object explorer session: {str(e)}' # TODO Localize self._session_created_error(request_context, session, message) # Attempt to clean up the connection if connection is not None: conn_service.disconnect(session.id, ConnectionType.OBJECT_EXLPORER)
def setUp(self): self._smo_metadata_factory = SmoEditTableMetadataFactory() self._connection = MockPGServerConnection(cur=None, port="8080", host="test", name="test", user="******") self._server = Server(self._connection) self._schema_name = 'public' self._table_name = 'Employee' self._view_name = 'Vendor' self._table_object_type = 'TABLE' self._view_object_type = 'VIEW' self._columns = [ Column(self._server, "testTable", 'testName', 'testDatatype') ]
def setUp(self): self._smo_metadata_factory = SmoEditTableMetadataFactory() self._connection = MockConnection({ "port": "8080", "host": "test", "dbname": "test", "user": "******" }) self._server = Server(self._connection) self._schema_name = 'public' self._table_name = 'Employee' self._view_name = 'Vendor' self._table_object_type = 'TABLE' self._view_object_type = 'VIEW' self._columns = [ Column(self._server, "testTable", 'testName', 'testDatatype') ]
def test_tables(self): # Given 2 tables in the database expected_table_tuples = [] for x in range(0, 3): s1_table_name = 's1_t%s' % x s2_table_name = 's2_t%s' % x expected_table_tuples.append( tuple([self.schema1.name, s1_table_name])) expected_table_tuples.append( tuple([self.schema2.name, s2_table_name])) cursor = MockCursor(expected_table_tuples) mock_server = Server(utils.MockPGServerConnection(cursor)) executor: MetadataExecutor = MetadataExecutor(mock_server) # When I query tables actual_table_tuples = executor.tables() # I expect to get 2 tables from the executor self.assertEqual(len(expected_table_tuples), len(actual_table_tuples)) for expected in expected_table_tuples: self.assertTrue(expected in actual_table_tuples)
def __init__(self, conn): # get server from psycopg2 connection self.server: Server = Server(conn)
class CompletionRefresher: """ Handles creating a PGCompleter object and populates it with the relevant completion suggestions in a background thread. """ refreshers = OrderedDict() def __init__(self, connection: 'psycopg2.extensions.connection', logger: Logger = None): self.connection = connection self.logger: Logger = logger self.server: Server = None self._completer_thread: threading.Thread = None self._restart_refresh: threading.Event = threading.Event() def refresh(self, callbacks, history=None, settings=None) -> str: """ Creates a PGCompleter object and populates it with the relevant completion suggestions in a background thread. settings - dict of settings for completer object callbacks - A function or a list of functions to call after the thread has completed the refresh. The newly created completion object will be passed in as an argument to each callback. """ if self.server is None: # Delay server creation until on background thread self.server = Server(self.connection) if self.is_refreshing(): self._restart_refresh.set() return 'Auto-completion refresh restarted.' else: self._completer_thread = threading.Thread( target=self._bg_refresh, args=(callbacks, history, settings), name='completion_refresh') self._completer_thread.daemon = True self._completer_thread.start() return 'Auto-completion refresh started in the background.' # TODO localize def is_refreshing(self): return self._completer_thread and self._completer_thread.is_alive() def _bg_refresh(self, callbacks, history=None, settings=None): settings = settings or {} completer = PGCompleter(smart_completion=True, settings=settings) self.server.refresh() metadata_executor = MetadataExecutor(self.server) # If callbacks is a single function then push it into a list. if callable(callbacks): callbacks = [callbacks] try: while True: for do_refresh in self.refreshers.values(): do_refresh(completer, metadata_executor) if self._restart_refresh.is_set(): self._restart_refresh.clear() break else: # Break out of while loop if the for loop finishes natually # without hitting the break statement. break # Start over the refresh from the beginning if the for loop hit the # break statement. continue # Load history into pgcompleter so it can learn user preferences n_recent = 100 if history: for recent in history[-n_recent:]: completer.extend_query_history(recent, is_init=True) except Exception as e: if self.logger: self.logger.exception('Error during metadata refresh: {0}', e) for callback in callbacks: callback(completer) if self._restart_refresh.is_set(): self._restart_refresh.clear()