diff --git a/web/pgadmin/tools/datagrid/__init__.py b/web/pgadmin/tools/datagrid/__init__.py index 95c83dd..08b01ab 100644 --- a/web/pgadmin/tools/datagrid/__init__.py +++ b/web/pgadmin/tools/datagrid/__init__.py @@ -117,7 +117,8 @@ def initialize_datagrid(cmd_type, obj_type, sid, did, obj_id): conn_id = str(random.randint(1, 9999999)) try: manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid) - conn = manager.connection(did=did, conn_id=conn_id) + conn = manager.connection(did=did, conn_id=conn_id, + use_binary_placeholder=True) except Exception as e: return internal_server_error(errormsg=str(e)) diff --git a/web/pgadmin/tools/sqleditor/templates/sqleditor/js/sqleditor.js b/web/pgadmin/tools/sqleditor/templates/sqleditor/js/sqleditor.js index 72904a9..ce65f6f 100644 --- a/web/pgadmin/tools/sqleditor/templates/sqleditor/js/sqleditor.js +++ b/web/pgadmin/tools/sqleditor/templates/sqleditor/js/sqleditor.js @@ -578,6 +578,7 @@ define([ name: c.label, display_name: c.display_name, column_type: c.column_type, + column_type_internal: c.column_type_internal, not_null: c.not_null, has_default_val: c.has_default_val }; @@ -744,6 +745,11 @@ define([ // Listener function which will be called before user updates existing cell // This will be used to collect primary key for that row grid.onBeforeEditCell.subscribe(function (e, args) { + if (args.column.column_type_internal == 'bytea' || + args.column.column_type_internal == 'bytea[]') { + return false; + } + var before_data = args.item; // If newly added row is saved but grid is not refreshed, @@ -2000,9 +2006,9 @@ define([ pg_types[pg_types.length - 1][0] : 'unknown'; if (!is_primary_key) - col_type += ' ' + type; + col_type += type; else - col_type += ' [PK] ' + type; + col_type += '[PK] ' + type; if (c.precision && c.precision >= 0 && c.precision != 65535) { col_type += ' (' + c.precision; @@ -2051,6 +2057,7 @@ define([ 'name': c.name, 'display_name': c.display_name, 'column_type': col_type, + 'column_type_internal': type, 'pos': c.pos, 'label': column_label, 'cell': col_cell, diff --git a/web/pgadmin/utils/driver/psycopg2/__init__.py b/web/pgadmin/utils/driver/psycopg2/__init__.py index 8a20521..cf6cfbd 100644 --- a/web/pgadmin/utils/driver/psycopg2/__init__.py +++ b/web/pgadmin/utils/driver/psycopg2/__init__.py @@ -120,6 +120,31 @@ def register_string_typecasters(connection): psycopg2.extensions.register_type(unicode_array_type) +def register_binary_typecasters(connection): + psycopg2.extensions.register_type( + psycopg2.extensions.new_type( + ( + # To cast bytea type + 17, + ), + 'BYTEA_PLACEHOLDER', + # Only show placeholder if data actually exists. + lambda value, cursor: '' if value is not None else None), + connection + ) + + psycopg2.extensions.register_type( + psycopg2.extensions.new_type( + ( + # To cast bytea[] type + 1001, + ), + 'BYTEA_ARRAY_PLACEHOLDER', + # Only show placeholder if data actually exists. + lambda value, cursor: '' if value is not None else None), + connection + ) + class Connection(BaseConnection): """ class Connection(object) @@ -201,7 +226,8 @@ class Connection(BaseConnection): """ - def __init__(self, manager, conn_id, db, auto_reconnect=True, async=0): + def __init__(self, manager, conn_id, db, auto_reconnect=True, async=0, + use_binary_placeholder=False): assert (manager is not None) assert (conn_id is not None) @@ -222,6 +248,7 @@ class Connection(BaseConnection): self.wasConnected = False # This flag indicates the connection reconnecting status. self.reconnecting = False + self.use_binary_placeholder = use_binary_placeholder super(Connection, self).__init__() @@ -239,6 +266,7 @@ class Connection(BaseConnection): res['database'] = self.db res['async'] = self.async res['wasConnected'] = self.wasConnected + res['use_binary_placeholder'] = self.use_binary_placeholder return res @@ -397,6 +425,10 @@ Failed to connect to the database server(#{server_id}) for connection ({conn_id} self.conn.autocommit = True register_string_typecasters(self.conn) + + if self.use_binary_placeholder: + register_binary_typecasters(self.conn) + status = _execute(cur, """ SET DateStyle=ISO; SET client_min_messages=notice; @@ -1639,7 +1671,7 @@ class ServerManager(object): def connection( self, database=None, conn_id=None, auto_reconnect=True, did=None, - async=None + async=None, use_binary_placeholder=False ): if database is not None: if hasattr(str, 'decode') and \ @@ -1693,7 +1725,7 @@ WHERE db.oid = {0}""".format(did)) else: async = 1 if async is True else 0 self.connections[my_id] = Connection( - self, my_id, database, auto_reconnect, async + self, my_id, database, auto_reconnect, async, use_binary_placeholder=use_binary_placeholder ) return self.connections[my_id] @@ -1722,7 +1754,8 @@ WHERE db.oid = {0}""".format(did)) conn_info = connections[conn_id] conn = self.connections[conn_info['conn_id']] = Connection( self, conn_info['conn_id'], conn_info['database'], - True, conn_info['async'] + True, conn_info['async'], + use_binary_placeholder=conn_info['use_binary_placeholder'] ) # only try to reconnect if connection was connected previously. if conn_info['wasConnected']: