mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Added publication and subscription support in Schema Diff. Fixes #6153
This commit is contained in:
parent
c1e80ac38a
commit
44cc7a308a
@ -13,6 +13,7 @@ New features
|
||||
| `Issue #5912 <https://redmine.postgresql.org/issues/5912>`_ - Added support for Logical Replication.
|
||||
| `Issue #5967 <https://redmine.postgresql.org/issues/5967>`_ - Implemented runtime using NWjs to open pgAdmin4 in a standalone window instead of the system tray and web browser.
|
||||
| `Issue #6148 <https://redmine.postgresql.org/issues/6148>`_ - Added Quick Search functionality for menu items and help articles.
|
||||
| `Issue #6153 <https://redmine.postgresql.org/issues/6153>`_ - Added publication and subscription support in Schema Diff.
|
||||
| `Issue #6170 <https://redmine.postgresql.org/issues/6170>`_ - Ensure logs are not stored in the container, and only sent to the console.
|
||||
|
||||
Housekeeping
|
||||
|
@ -21,6 +21,8 @@ from pgadmin.utils.ajax import make_json_response, internal_server_error, \
|
||||
from pgadmin.utils.driver import get_driver
|
||||
from config import PG_DEFAULT_DRIVER
|
||||
from pgadmin.tools.schema_diff.compare import SchemaDiffObjectCompare
|
||||
from pgadmin.tools.schema_diff.node_registry import SchemaDiffRegistry
|
||||
from urllib.parse import unquote
|
||||
|
||||
|
||||
class PublicationModule(CollectionNodeModule):
|
||||
@ -153,17 +155,10 @@ class PublicationView(PGChildNodeView, SchemaDiffObjectCompare):
|
||||
- This function returns the handler and inline functions for the
|
||||
selected publication node
|
||||
|
||||
* get_templates(gid, sid, did)
|
||||
- This function returns publication templates.
|
||||
|
||||
* sql(gid, sid, did, pbid):
|
||||
- This function will generate sql to show it in sql pane for the
|
||||
selected publication node.
|
||||
|
||||
* dependents(gid, sid, did, pbid):
|
||||
- This function get the dependents and return ajax response for the
|
||||
publication node.
|
||||
|
||||
* dependencies(self, gid, sid, did, pbid):
|
||||
- This function get the dependencies and return ajax response for the
|
||||
publication node.
|
||||
@ -194,7 +189,6 @@ class PublicationView(PGChildNodeView, SchemaDiffObjectCompare):
|
||||
'dependency': [{'get': 'dependencies'}],
|
||||
'dependent': [{'get': 'dependents'}],
|
||||
'get_tables': [{}, {'get': 'get_tables'}],
|
||||
'get_templates': [{}, {'get': 'get_templates'}],
|
||||
'delete': [{'delete': 'delete'}, {'delete': 'delete'}]
|
||||
})
|
||||
|
||||
@ -281,7 +275,8 @@ class PublicationView(PGChildNodeView, SchemaDiffObjectCompare):
|
||||
)
|
||||
status, pname = self.conn.execute_scalar(get_name_sql)
|
||||
table_sql = render_template(
|
||||
"/".join([self.template_path, 'get_tables.sql']),
|
||||
"/".join([self.template_path,
|
||||
self._GET_TABLE_FOR_PUBLICATION]),
|
||||
pname=pname
|
||||
)
|
||||
|
||||
@ -412,7 +407,8 @@ class PublicationView(PGChildNodeView, SchemaDiffObjectCompare):
|
||||
)
|
||||
status, pname = self.conn.execute_scalar(get_name_sql)
|
||||
table_sql = render_template(
|
||||
"/".join([self.template_path, 'get_tables.sql']),
|
||||
"/".join([self.template_path,
|
||||
self._GET_TABLE_FOR_PUBLICATION]),
|
||||
pname=pname
|
||||
)
|
||||
|
||||
@ -444,6 +440,9 @@ class PublicationView(PGChildNodeView, SchemaDiffObjectCompare):
|
||||
try:
|
||||
data = self._parser_data_input_from_client(data)
|
||||
|
||||
# unquote the table data
|
||||
data = self.unquote_the_table(data)
|
||||
|
||||
sql, name = self.get_sql(data, pbid)
|
||||
|
||||
# Most probably this is due to error
|
||||
@ -465,6 +464,22 @@ class PublicationView(PGChildNodeView, SchemaDiffObjectCompare):
|
||||
except Exception as e:
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
def unquote_the_table(self, data):
|
||||
"""
|
||||
This function unquote the table value
|
||||
:param data:
|
||||
:return: data
|
||||
"""
|
||||
pubtable = []
|
||||
|
||||
# Unquote the values
|
||||
if 'pubtable' in data:
|
||||
for table in data['pubtable']:
|
||||
pubtable.append(unquote(table))
|
||||
data['pubtable'] = pubtable
|
||||
|
||||
return data
|
||||
|
||||
@check_precondition
|
||||
def create(self, gid, sid, did):
|
||||
"""
|
||||
@ -495,6 +510,9 @@ class PublicationView(PGChildNodeView, SchemaDiffObjectCompare):
|
||||
try:
|
||||
data = self._parser_data_input_from_client(data)
|
||||
|
||||
# unquote the table data
|
||||
data = self.unquote_the_table(data)
|
||||
|
||||
sql = render_template("/".join([self.template_path,
|
||||
self._CREATE_SQL]),
|
||||
data=data, conn=self.conn)
|
||||
@ -525,7 +543,7 @@ class PublicationView(PGChildNodeView, SchemaDiffObjectCompare):
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
@check_precondition
|
||||
def delete(self, gid, sid, did, pbid=None):
|
||||
def delete(self, gid, sid, did, pbid=None, only_sql=False):
|
||||
"""
|
||||
This function will drop the publication object
|
||||
|
||||
@ -551,6 +569,7 @@ class PublicationView(PGChildNodeView, SchemaDiffObjectCompare):
|
||||
"/".join([self.template_path, self._DELETE_SQL]),
|
||||
pbid=pbid, conn=self.conn
|
||||
)
|
||||
|
||||
status, pname = self.conn.execute_scalar(sql)
|
||||
|
||||
if not status:
|
||||
@ -562,6 +581,10 @@ class PublicationView(PGChildNodeView, SchemaDiffObjectCompare):
|
||||
pname=pname, cascade=cascade, conn=self.conn
|
||||
)
|
||||
|
||||
# Used for schema diff tool
|
||||
if only_sql:
|
||||
return sql
|
||||
|
||||
status, res = self.conn.execute_scalar(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
@ -598,6 +621,9 @@ class PublicationView(PGChildNodeView, SchemaDiffObjectCompare):
|
||||
except ValueError:
|
||||
data[k] = v
|
||||
try:
|
||||
# unquote the table data
|
||||
data = self.unquote_the_table(data)
|
||||
|
||||
sql, name = self.get_sql(data, pbid)
|
||||
# Most probably this is due to error
|
||||
if not isinstance(sql, str):
|
||||
@ -637,6 +663,31 @@ class PublicationView(PGChildNodeView, SchemaDiffObjectCompare):
|
||||
|
||||
return data
|
||||
|
||||
def _get_table_details_to_add_and_delete(self, old_data, data):
|
||||
"""
|
||||
This function returns the tables which need to add and delete
|
||||
:param old_data:
|
||||
:param data:
|
||||
:return:
|
||||
"""
|
||||
drop_table_data = []
|
||||
add_table_data = []
|
||||
drop_table = False
|
||||
add_table = False
|
||||
|
||||
for table in old_data['pubtable']:
|
||||
if 'pubtable' in data and table not in data['pubtable']:
|
||||
drop_table_data.append(table)
|
||||
drop_table = True
|
||||
|
||||
if 'pubtable' in data:
|
||||
for table in data['pubtable']:
|
||||
if table not in old_data['pubtable']:
|
||||
add_table_data.append(table)
|
||||
add_table = True
|
||||
|
||||
return drop_table, add_table, drop_table_data, add_table_data
|
||||
|
||||
def get_sql(self, data, pbid=None):
|
||||
"""
|
||||
This function will generate sql from model data.
|
||||
@ -648,9 +699,6 @@ class PublicationView(PGChildNodeView, SchemaDiffObjectCompare):
|
||||
required_args = [
|
||||
'name'
|
||||
]
|
||||
drop_table = False
|
||||
add_table = False
|
||||
|
||||
if pbid is not None:
|
||||
sql = render_template(
|
||||
"/".join([self.template_path, self._PROPERTIES_SQL]), pbid=pbid
|
||||
@ -664,20 +712,8 @@ class PublicationView(PGChildNodeView, SchemaDiffObjectCompare):
|
||||
|
||||
old_data = self._get_old_table_data(res['rows'][0]['name'], res)
|
||||
|
||||
drop_table_data = []
|
||||
|
||||
add_table_data = []
|
||||
|
||||
for table in old_data['pubtable']:
|
||||
if 'pubtable' in data and table not in data['pubtable']:
|
||||
drop_table_data.append(table)
|
||||
drop_table = True
|
||||
|
||||
if 'pubtable' in data:
|
||||
for table in data['pubtable']:
|
||||
if table not in old_data['pubtable']:
|
||||
add_table_data.append(table)
|
||||
add_table = True
|
||||
drop_table, add_table, drop_table_data, add_table_data = \
|
||||
self._get_table_details_to_add_and_delete(old_data, data)
|
||||
|
||||
for arg in required_args:
|
||||
if arg not in data:
|
||||
@ -743,7 +779,7 @@ class PublicationView(PGChildNodeView, SchemaDiffObjectCompare):
|
||||
"""
|
||||
|
||||
table_sql = render_template(
|
||||
"/".join([self.template_path, 'get_tables.sql']),
|
||||
"/".join([self.template_path, self._GET_TABLE_FOR_PUBLICATION]),
|
||||
pname=pname
|
||||
)
|
||||
|
||||
@ -854,5 +890,102 @@ class PublicationView(PGChildNodeView, SchemaDiffObjectCompare):
|
||||
status=200
|
||||
)
|
||||
|
||||
def get_dependencies(self, conn, object_id, where=None,
|
||||
show_system_objects=None, is_schema_diff=False):
|
||||
"""
|
||||
This function gets the dependencies and returns an ajax response
|
||||
for the publication node.
|
||||
:param conn:
|
||||
:param object_id:
|
||||
:param where:
|
||||
:param show_system_objects:
|
||||
:param is_schema_diff:
|
||||
:return: dependencies result
|
||||
"""
|
||||
|
||||
get_name_sql = render_template(
|
||||
"/".join([self.template_path, self._DELETE_SQL]),
|
||||
pbid=object_id, conn=self.conn
|
||||
)
|
||||
status, pname = self.conn.execute_scalar(get_name_sql)
|
||||
table_sql = render_template(
|
||||
"/".join([self.template_path, 'dependencies.sql']),
|
||||
pname=pname
|
||||
)
|
||||
status, res = self.conn.execute_dict(table_sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
dependencies_result = []
|
||||
|
||||
for pub_table in res['rows']:
|
||||
dependencies_result.append(
|
||||
{'type': 'table',
|
||||
'name': pub_table['pubtable'],
|
||||
'field': 'normal',
|
||||
'oid': pub_table['oid']})
|
||||
|
||||
return dependencies_result
|
||||
|
||||
@check_precondition
|
||||
def fetch_objects_to_compare(self, sid, did):
|
||||
"""
|
||||
This function will fetch the list of all the event triggers for
|
||||
specified database id.
|
||||
|
||||
:param sid: Server Id
|
||||
:param did: Database Id
|
||||
:return:
|
||||
"""
|
||||
res = dict()
|
||||
|
||||
if self.manager.version < 100000:
|
||||
return res
|
||||
|
||||
last_system_oid = 0
|
||||
if self.manager.db_info is not None and did in self.manager.db_info:
|
||||
last_system_oid = (self.manager.db_info[did])['datlastsysoid']
|
||||
|
||||
sql = render_template(
|
||||
"/".join([self.template_path, 'nodes.sql']),
|
||||
datlastsysoid=last_system_oid,
|
||||
showsysobj=self.blueprint.show_system_objects
|
||||
)
|
||||
status, rset = self.conn.execute_2darray(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=rset)
|
||||
|
||||
for row in rset['rows']:
|
||||
status, data = self._fetch_properties(did, row['oid'])
|
||||
if status:
|
||||
res[row['name']] = data
|
||||
|
||||
return res
|
||||
|
||||
def get_sql_from_diff(self, **kwargs):
|
||||
"""
|
||||
This function is used to get the DDL/DML statements.
|
||||
:param kwargs:
|
||||
:return:
|
||||
"""
|
||||
gid = kwargs.get('gid')
|
||||
sid = kwargs.get('sid')
|
||||
did = kwargs.get('did')
|
||||
oid = kwargs.get('oid')
|
||||
data = kwargs.get('data', None)
|
||||
drop_sql = kwargs.get('drop_sql', False)
|
||||
|
||||
if data:
|
||||
sql, name = self.get_sql(data=data, pbid=oid)
|
||||
else:
|
||||
if drop_sql:
|
||||
sql = self.delete(gid=gid, sid=sid, did=did,
|
||||
pbid=oid, only_sql=True)
|
||||
else:
|
||||
sql = self.sql(gid=gid, sid=sid, did=did, pbid=oid,
|
||||
json_resp=False)
|
||||
return sql
|
||||
|
||||
|
||||
SchemaDiffRegistry(blueprint.node_type, PublicationView, 'Database')
|
||||
PublicationView.register_node_view(blueprint)
|
||||
|
@ -1,6 +1,6 @@
|
||||
{# ============= Get the publication name using oid ============= #}
|
||||
{% if pbid %}
|
||||
SELECT pubname FROM pg_publication WHERE oid = {{pbid}}::oid;
|
||||
SELECT pubname FROM pg_publication WHERE oid = {{pbid}}::oid;
|
||||
{% endif %}
|
||||
{# ============= Drop the publication ============= #}
|
||||
{% if pname %}
|
||||
|
@ -0,0 +1,5 @@
|
||||
SELECT cl.oid AS oid,
|
||||
quote_ident(pgb_table.schemaname)||'.'||quote_ident(pgb_table.tablename) AS pubtable
|
||||
FROM pg_publication_tables pgb_table
|
||||
LEFT JOIN pg_class cl ON pgb_table.tablename = cl.relname
|
||||
WHERE pubname = '{{ pname }}' AND pgb_table.schemaname NOT LIKE 'pgagent';
|
@ -1,6 +1,6 @@
|
||||
SELECT quote_ident(c.table_schema)||'.'||quote_ident(c.table_name) AS table
|
||||
FROM information_schema.tables c
|
||||
where c.table_type = 'BASE TABLE'
|
||||
WHERE c.table_type = 'BASE TABLE'
|
||||
AND c.table_schema NOT LIKE 'pg\_%'
|
||||
AND c.table_schema NOT LIKE 'pgagent'
|
||||
AND c.table_schema NOT IN ('information_schema') ORDER BY 1;
|
||||
|
@ -1 +1 @@
|
||||
SELECT oid, pubname AS name FROM pg_publication where pubname = '{{ pubname }}';
|
||||
SELECT oid, pubname AS name FROM pg_publication WHERE pubname = '{{ pubname }}';
|
||||
|
@ -1 +1,3 @@
|
||||
SELECT quote_ident(pgb_table.schemaname)||'.'||quote_ident(pgb_table.tablename) AS pubtable FROM pg_publication_tables pgb_table where pubname = '{{ pname }}' and pgb_table.schemaname NOT LIKE 'pgagent';
|
||||
SELECT quote_ident(pgb_table.schemaname)||'.'||quote_ident(pgb_table.tablename)
|
||||
AS pubtable FROM pg_publication_tables pgb_table WHERE pubname = '{{ pname }}'
|
||||
AND pgb_table.schemaname NOT LIKE 'pgagent';
|
||||
|
@ -169,7 +169,7 @@ class SubscriptionView(PGChildNodeView, SchemaDiffObjectCompare):
|
||||
- This function get the dependents and return ajax response for the
|
||||
subscription node.
|
||||
|
||||
* dependencies(self, gid, sid, did, subid):
|
||||
* dependencies(gid, sid, did, subid):
|
||||
- This function get the dependencies and return ajax response for the
|
||||
subscription node.
|
||||
"""
|
||||
@ -379,28 +379,10 @@ class SubscriptionView(PGChildNodeView, SchemaDiffObjectCompare):
|
||||
|
||||
return True, res['rows'][0]
|
||||
|
||||
@check_precondition
|
||||
def dependents(self, gid, sid, did, subid):
|
||||
"""
|
||||
This function gets the dependents and returns an ajax response
|
||||
for the view node.
|
||||
|
||||
Args:
|
||||
gid: Server Group ID
|
||||
sid: Server ID
|
||||
did: Database ID
|
||||
subid: View ID
|
||||
"""
|
||||
dependents_result = self.get_dependents(self.conn, subid)
|
||||
return ajax_response(
|
||||
response=dependents_result,
|
||||
status=200
|
||||
)
|
||||
|
||||
@check_precondition
|
||||
def statistics(self, gid, sid, did, subid):
|
||||
"""
|
||||
This function gets the dependents and returns an ajax response
|
||||
This function gets the statistics and returns an ajax response
|
||||
for the view node.
|
||||
|
||||
Args:
|
||||
@ -418,24 +400,6 @@ class SubscriptionView(PGChildNodeView, SchemaDiffObjectCompare):
|
||||
status=200
|
||||
)
|
||||
|
||||
@check_precondition
|
||||
def dependencies(self, gid, sid, did, subid):
|
||||
"""
|
||||
This function gets the dependencies and returns an ajax response
|
||||
for the view node.
|
||||
|
||||
Args:
|
||||
gid: Server Group ID
|
||||
sid: Server ID
|
||||
did: Database ID
|
||||
subid: View ID
|
||||
"""
|
||||
dependencies_result = self.get_dependencies(self.conn, subid)
|
||||
return ajax_response(
|
||||
response=dependencies_result,
|
||||
status=200
|
||||
)
|
||||
|
||||
@check_precondition
|
||||
def update(self, gid, sid, did, subid):
|
||||
"""
|
||||
@ -537,7 +501,7 @@ class SubscriptionView(PGChildNodeView, SchemaDiffObjectCompare):
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
@check_precondition
|
||||
def delete(self, gid, sid, did, subid=None):
|
||||
def delete(self, gid, sid, did, subid=None, only_sql=False):
|
||||
"""
|
||||
This function will drop the subscription object
|
||||
|
||||
@ -575,6 +539,10 @@ class SubscriptionView(PGChildNodeView, SchemaDiffObjectCompare):
|
||||
subname=subname, cascade=cascade, conn=self.conn
|
||||
)
|
||||
|
||||
# Used for schema diff tool
|
||||
if only_sql:
|
||||
return sql
|
||||
|
||||
status, res = self.conn.execute_scalar(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
@ -625,26 +593,32 @@ class SubscriptionView(PGChildNodeView, SchemaDiffObjectCompare):
|
||||
except Exception as e:
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
def get_details(self, data, old_data):
|
||||
def get_required_details(self, data, old_data):
|
||||
"""
|
||||
This function returns the required data to create subscription
|
||||
:param data:
|
||||
:return:
|
||||
:return:data , old_data
|
||||
|
||||
"""
|
||||
required_args = ['name']
|
||||
|
||||
required_connection_args = ['host', 'port', 'username', 'db',
|
||||
'connect_timeout', 'passfile']
|
||||
|
||||
# Set connection time out to zero if initial set
|
||||
# value is replaced to ''
|
||||
if 'connect_timeout' in data and data['connect_timeout'] == '':
|
||||
data['connect_timeout'] = 0
|
||||
|
||||
for arg in required_args:
|
||||
if arg not in data and arg in old_data:
|
||||
if arg not in data:
|
||||
data[arg] = old_data[arg]
|
||||
|
||||
for arg in required_connection_args:
|
||||
if arg not in data and arg in old_data:
|
||||
data[arg] = old_data[arg]
|
||||
if arg in data:
|
||||
old_data[arg] = data[arg]
|
||||
|
||||
return data
|
||||
return data, old_data
|
||||
|
||||
def get_sql(self, data, subid=None, operation=None):
|
||||
"""
|
||||
@ -655,10 +629,6 @@ class SubscriptionView(PGChildNodeView, SchemaDiffObjectCompare):
|
||||
subid: Subscription ID
|
||||
"""
|
||||
|
||||
required_args = ['name']
|
||||
|
||||
required_connection_args = ['host', 'port', 'username', 'db',
|
||||
'connect_timeout', 'passfile']
|
||||
if operation == 'msql':
|
||||
dummy = True
|
||||
else:
|
||||
@ -677,13 +647,7 @@ class SubscriptionView(PGChildNodeView, SchemaDiffObjectCompare):
|
||||
return gone(self._NOT_FOUND_PUB_INFORMATION)
|
||||
|
||||
old_data = res['rows'][0]
|
||||
for arg in required_args:
|
||||
if arg not in data:
|
||||
data[arg] = old_data[arg]
|
||||
|
||||
for arg in required_connection_args:
|
||||
if arg in data:
|
||||
old_data[arg] = data[arg]
|
||||
data, old_data = self.get_required_details(data, old_data)
|
||||
|
||||
if 'slot_name' in data and data['slot_name'] == '':
|
||||
data['slot_name'] = 'None'
|
||||
@ -702,6 +666,11 @@ class SubscriptionView(PGChildNodeView, SchemaDiffObjectCompare):
|
||||
return sql.strip('\n'), data['name']
|
||||
|
||||
def get_connection(self, connection_details):
|
||||
"""
|
||||
This function is used to connect to DB and returns the publications
|
||||
:param connection_details:
|
||||
:return: publication list
|
||||
"""
|
||||
|
||||
passfile = connection_details['passfile'] if \
|
||||
'passfile' in connection_details and \
|
||||
@ -772,13 +741,13 @@ class SubscriptionView(PGChildNodeView, SchemaDiffObjectCompare):
|
||||
def sql(self, gid, sid, did, subid, json_resp=True):
|
||||
"""
|
||||
This function will generate sql to show in the sql pane for the
|
||||
selected publication node.
|
||||
selected subscription node.
|
||||
|
||||
Args:
|
||||
gid: Server Group ID
|
||||
sid: Server ID
|
||||
did: Database ID
|
||||
subid: Publication ID
|
||||
subid: Subscription ID
|
||||
json_resp:
|
||||
"""
|
||||
sql = render_template(
|
||||
@ -794,8 +763,11 @@ class SubscriptionView(PGChildNodeView, SchemaDiffObjectCompare):
|
||||
|
||||
# Making copy of output for future use
|
||||
old_data = dict(res['rows'][0])
|
||||
if old_data['slot_name'] is None and 'create_slot' not in old_data:
|
||||
old_data['create_slot'] = False
|
||||
old_data['create_slot'] = False
|
||||
if old_data['enabled']:
|
||||
old_data['connect'] = True
|
||||
else:
|
||||
old_data['connect'] = False
|
||||
|
||||
sql = render_template("/".join([self.template_path,
|
||||
self._CREATE_SQL]),
|
||||
@ -856,5 +828,104 @@ class SubscriptionView(PGChildNodeView, SchemaDiffObjectCompare):
|
||||
status=200
|
||||
)
|
||||
|
||||
def get_dependencies(self, conn, object_id, where=None,
|
||||
show_system_objects=None, is_schema_diff=False):
|
||||
"""
|
||||
This function gets the dependencies and returns an ajax response
|
||||
for the subscription node.
|
||||
:param conn:
|
||||
:param object_id:
|
||||
:param where:
|
||||
:param show_system_objects:
|
||||
:param is_schema_diff:
|
||||
:return: dependencies result
|
||||
"""
|
||||
|
||||
get_name_sql = render_template(
|
||||
"/".join([self.template_path, self._DELETE_SQL]),
|
||||
subid=object_id, conn=self.conn
|
||||
)
|
||||
status, subname = self.conn.execute_scalar(get_name_sql)
|
||||
table_sql = render_template(
|
||||
"/".join([self.template_path, 'dependencies.sql']),
|
||||
subname=subname
|
||||
)
|
||||
status, res = self.conn.execute_dict(table_sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
dependencies_result = []
|
||||
|
||||
for publication in res['rows'][0]['pub']:
|
||||
dependencies_result.append(
|
||||
{'type': 'publication',
|
||||
'name': publication,
|
||||
'field': 'normal'})
|
||||
|
||||
return dependencies_result
|
||||
|
||||
@check_precondition
|
||||
def fetch_objects_to_compare(self, sid, did):
|
||||
"""
|
||||
This function will fetch the list of all the event triggers for
|
||||
specified database id.
|
||||
|
||||
:param sid: Server Id
|
||||
:param did: Database Id
|
||||
:return:
|
||||
"""
|
||||
res = dict()
|
||||
if self.manager.version < 100000:
|
||||
return res
|
||||
|
||||
last_system_oid = 0
|
||||
if self.manager.db_info is not None and did in self.manager.db_info:
|
||||
last_system_oid = (self.manager.db_info[did])['datlastsysoid']
|
||||
|
||||
sql = render_template(
|
||||
"/".join([self.template_path, 'nodes.sql']),
|
||||
datlastsysoid=last_system_oid,
|
||||
showsysobj=self.blueprint.show_system_objects,
|
||||
did=did
|
||||
)
|
||||
status, rset = self.conn.execute_2darray(sql)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=rset)
|
||||
|
||||
for row in rset['rows']:
|
||||
status, data = self._fetch_properties(did, row['oid'])
|
||||
if status:
|
||||
res[row['name']] = data
|
||||
|
||||
return res
|
||||
|
||||
def get_sql_from_diff(self, **kwargs):
|
||||
"""
|
||||
This function is used to get the DDL/DML statements.
|
||||
:param kwargs:
|
||||
:return:
|
||||
"""
|
||||
gid = kwargs.get('gid')
|
||||
sid = kwargs.get('sid')
|
||||
did = kwargs.get('did')
|
||||
oid = kwargs.get('oid')
|
||||
data = kwargs.get('data', None)
|
||||
drop_sql = kwargs.get('drop_sql', False)
|
||||
|
||||
if data:
|
||||
if 'pub' in data and type(data['pub']) == str:
|
||||
# Convert publication details to list
|
||||
data['pub'] = data['pub'].split(',,')
|
||||
sql, name = self.get_sql(data=data, subid=oid)
|
||||
else:
|
||||
if drop_sql:
|
||||
sql = self.delete(gid=gid, sid=sid, did=did,
|
||||
subid=oid, only_sql=True)
|
||||
else:
|
||||
sql = self.sql(gid=gid, sid=sid, did=did, subid=oid,
|
||||
json_resp=False)
|
||||
return sql
|
||||
|
||||
|
||||
SchemaDiffRegistry(blueprint.node_type, SubscriptionView, 'Database')
|
||||
SubscriptionView.register_node_view(blueprint)
|
||||
|
@ -77,6 +77,7 @@ define('pgadmin.node.subscription', [
|
||||
name: undefined,
|
||||
subowner: undefined,
|
||||
pubtable: undefined,
|
||||
connect_timeout: undefined,
|
||||
pub:[],
|
||||
enabled:true,
|
||||
create_slot: true,
|
||||
|
@ -5,4 +5,4 @@
|
||||
CREATE SUBSCRIPTION test_alter_subscription
|
||||
CONNECTION 'host=localhost port=5432 user=postgres dbname=edb'
|
||||
PUBLICATION sample__1
|
||||
WITH (enabled = false, create_slot = false, slot_name = None, synchronous_commit = 'remote_apply');
|
||||
WITH (connect = false, enabled = false, create_slot = false, slot_name = None, synchronous_commit = 'remote_apply');
|
||||
|
@ -5,4 +5,4 @@
|
||||
CREATE SUBSCRIPTION test_alter_subscription
|
||||
CONNECTION 'host=localhost port=5432 user=postgres dbname=postgres'
|
||||
PUBLICATION sample__1
|
||||
WITH (enabled = false, create_slot = false, slot_name = None, synchronous_commit = 'off');
|
||||
WITH (connect = false, enabled = false, create_slot = false, slot_name = None, synchronous_commit = 'off');
|
||||
|
@ -5,4 +5,4 @@
|
||||
CREATE SUBSCRIPTION test_alter_subscription
|
||||
CONNECTION 'host=localhost port=5432 user=postgres dbname=postgres'
|
||||
PUBLICATION sample__1
|
||||
WITH (enabled = false, create_slot = false, slot_name = None, synchronous_commit = 'remote_apply');
|
||||
WITH (connect = false, enabled = false, create_slot = false, slot_name = None, synchronous_commit = 'remote_apply');
|
||||
|
@ -5,4 +5,4 @@
|
||||
CREATE SUBSCRIPTION test_create_subscription
|
||||
CONNECTION 'host=localhost port=5432 user=postgres dbname=postgres'
|
||||
PUBLICATION sample__1
|
||||
WITH (enabled = false, create_slot = false, slot_name = None, synchronous_commit = 'off');
|
||||
WITH (connect = false, enabled = false, create_slot = false, slot_name = None, synchronous_commit = 'off');
|
||||
|
@ -14,12 +14,12 @@
|
||||
"subowner": "postgres",
|
||||
"enabled": false,
|
||||
"host": "localhost",
|
||||
"slot_name": "NONE",
|
||||
"slot_name": "None",
|
||||
"service": "",
|
||||
"port": 5432,
|
||||
"password": "",
|
||||
"sync": "off",
|
||||
"pub": "PLACE_HOLDER"
|
||||
"pub": "[\"sample__1\"]"
|
||||
},
|
||||
"mocking_required": false,
|
||||
"mock_data": {},
|
||||
@ -42,12 +42,12 @@
|
||||
"subowner": "postgres",
|
||||
"enabled": false,
|
||||
"host": "localhost",
|
||||
"slot_name": "NONE",
|
||||
"slot_name": "None",
|
||||
"service": "",
|
||||
"port": 5432,
|
||||
"password": "",
|
||||
"sync": "off",
|
||||
"pub": "PLACE_HOLDER"
|
||||
"pub": "[\"sample__1\"]"
|
||||
},
|
||||
"mocking_required": false,
|
||||
"mock_data": {},
|
||||
@ -70,12 +70,12 @@
|
||||
"subowner": "postgres",
|
||||
"enabled": false,
|
||||
"host": "localhost",
|
||||
"slot_name": "NONE",
|
||||
"slot_name": "None",
|
||||
"service": "",
|
||||
"port": 5432,
|
||||
"password": "",
|
||||
"sync": "off",
|
||||
"pub": "PLACE_HOLDER"
|
||||
"pub": "[\"sample__1\"]"
|
||||
},
|
||||
"mocking_required": false,
|
||||
"mock_data": {},
|
||||
@ -98,12 +98,12 @@
|
||||
"subowner": "postgres",
|
||||
"enabled": false,
|
||||
"host": "localhost",
|
||||
"slot_name": "NONE",
|
||||
"slot_name": "None",
|
||||
"service": "",
|
||||
"port": 5432,
|
||||
"password": "",
|
||||
"sync": "off",
|
||||
"pub": "PLACE_HOLDER"
|
||||
"pub": "[\"sample__1\"]"
|
||||
},
|
||||
"mocking_required": true,
|
||||
"mock_data": {
|
||||
@ -128,12 +128,12 @@
|
||||
"subowner": "postgres",
|
||||
"enabled": false,
|
||||
"host": "localhost",
|
||||
"slot_name": "NONE",
|
||||
"slot_name": "None",
|
||||
"service": "",
|
||||
"port": 5432,
|
||||
"password": "",
|
||||
"sync": "off",
|
||||
"pub": "PLACE_HOLDER"
|
||||
"pub": "[\"sample__1\"]"
|
||||
},
|
||||
"mocking_required": true,
|
||||
"mock_data": {
|
||||
|
@ -59,8 +59,7 @@ class SubscriptionAddTestCase(BaseTestGenerator):
|
||||
"""This function will subscription."""
|
||||
self.test_data['name'] = \
|
||||
"test_subscription_add_%s" % (str(uuid.uuid4())[1:8])
|
||||
|
||||
self.test_data['pub'] = """["sample__1"]"""
|
||||
self.test_data['slot_name'] = None
|
||||
|
||||
data = self.test_data
|
||||
if self.is_positive_test:
|
||||
|
@ -19,14 +19,13 @@ SELECT DISTINCT dep.deptype, dep.classid, cl.relkind, ad.adbin, ad.adsrc,
|
||||
WHEN ftst.oid IS NOT NULL THEN 'Ft'::text
|
||||
WHEN ext.oid IS NOT NULL THEN 'Ex'::text
|
||||
WHEN pl.oid IS NOT NULL THEN 'Rs'::text
|
||||
WHEN pub_rel.oid IS NOT NULL THEN 'r'::text
|
||||
ELSE ''
|
||||
END AS type,
|
||||
COALESCE(coc.relname, clrw.relname) AS ownertable,
|
||||
CASE WHEN cl.relname IS NOT NULL AND att.attname IS NOT NULL THEN cl.relname || COALESCE('.' || att.attname, '')
|
||||
ELSE COALESCE(cl.relname, co.conname, pr.proname, tg.tgname, ty.typname, la.lanname, rw.rulename, ns.nspname,
|
||||
fs.srvname, fdw.fdwname, evt.evtname, col.collname, ftsc.cfgname, ftsd.dictname, ftsp.prsname,
|
||||
ftst.tmplname, ext.extname, pl.polname, quote_ident(pubns.nspname)||'.'||quote_ident(pubcl.relname))
|
||||
ftst.tmplname, ext.extname, pl.polname)
|
||||
END AS refname,
|
||||
COALESCE(nsc.nspname, nso.nspname, nsp.nspname, nst.nspname, nsrw.nspname, colns.nspname, ftscns.nspname,
|
||||
ftsdns.nspname, ftspns.nspname, ftstns.nspname) AS nspname,
|
||||
@ -68,12 +67,9 @@ LEFT JOIN pg_ts_template ftst ON ftst.oid=dep.objid
|
||||
LEFT JOIN pg_namespace ftstns ON ftst.tmplnamespace=ftstns.oid
|
||||
LEFT JOIN pg_extension ext ON ext.oid=dep.objid
|
||||
LEFT JOIN pg_policy pl ON pl.oid=dep.objid
|
||||
LEFT JOIN pg_publication_rel pub_rel ON pub_rel.oid = dep.objid
|
||||
LEFT JOIN pg_class pubcl ON pubcl.oid = pub_rel.prrelid
|
||||
LEFT JOIN pg_namespace pubns ON pubns.oid=pubcl.relnamespace
|
||||
{{where_clause}} AND
|
||||
classid IN ( SELECT oid FROM pg_class WHERE relname IN
|
||||
('pg_class', 'pg_constraint', 'pg_conversion', 'pg_language', 'pg_proc', 'pg_rewrite', 'pg_namespace',
|
||||
'pg_trigger', 'pg_type', 'pg_attrdef', 'pg_event_trigger', 'pg_foreign_server', 'pg_foreign_data_wrapper',
|
||||
'pg_collation', 'pg_ts_config', 'pg_ts_dict', 'pg_ts_parser', 'pg_ts_template', 'pg_extension', 'pg_policy', 'pg_subscription', 'pg_publication_rel'))
|
||||
'pg_collation', 'pg_ts_config', 'pg_ts_dict', 'pg_ts_parser', 'pg_ts_template', 'pg_extension', 'pg_policy'))
|
||||
ORDER BY classid, cl.relkind
|
||||
|
@ -19,14 +19,13 @@ SELECT DISTINCT dep.deptype, dep.classid, cl.relkind, ad.adbin, pg_get_expr(ad.a
|
||||
WHEN ftst.oid IS NOT NULL THEN 'Ft'::text
|
||||
WHEN ext.oid IS NOT NULL THEN 'Ex'::text
|
||||
WHEN pl.oid IS NOT NULL THEN 'Rs'::text
|
||||
WHEN pub_rel.oid IS NOT NULL THEN 'r'::text
|
||||
ELSE ''
|
||||
END AS type,
|
||||
COALESCE(coc.relname, clrw.relname) AS ownertable,
|
||||
CASE WHEN cl.relname IS NOT NULL AND att.attname IS NOT NULL THEN cl.relname || COALESCE('.' || att.attname, '')
|
||||
ELSE COALESCE(cl.relname, co.conname, pr.proname, tg.tgname, ty.typname, la.lanname, rw.rulename, ns.nspname,
|
||||
fs.srvname, fdw.fdwname, evt.evtname, col.collname, ftsc.cfgname, ftsd.dictname, ftsp.prsname,
|
||||
ftst.tmplname, ext.extname, pl.polname, quote_ident(pubns.nspname)||'.'||quote_ident(pubcl.relname))
|
||||
ftst.tmplname, ext.extname, pl.polname)
|
||||
END AS refname,
|
||||
COALESCE(nsc.nspname, nso.nspname, nsp.nspname, nst.nspname, nsrw.nspname, colns.nspname, ftscns.nspname,
|
||||
ftsdns.nspname, ftspns.nspname, ftstns.nspname) AS nspname,
|
||||
@ -68,12 +67,9 @@ LEFT JOIN pg_ts_template ftst ON ftst.oid=dep.objid
|
||||
LEFT JOIN pg_namespace ftstns ON ftst.tmplnamespace=ftstns.oid
|
||||
LEFT JOIN pg_extension ext ON ext.oid=dep.objid
|
||||
LEFT JOIN pg_policy pl ON pl.oid=dep.objid
|
||||
LEFT JOIN pg_publication_rel pub_rel ON pub_rel.oid = dep.objid
|
||||
LEFT JOIN pg_class pubcl ON pubcl.oid = pub_rel.prrelid
|
||||
LEFT JOIN pg_namespace pubns ON pubns.oid=pubcl.relnamespace
|
||||
{{where_clause}} AND
|
||||
classid IN ( SELECT oid FROM pg_class WHERE relname IN
|
||||
('pg_class', 'pg_constraint', 'pg_conversion', 'pg_language', 'pg_proc', 'pg_rewrite', 'pg_namespace',
|
||||
'pg_trigger', 'pg_type', 'pg_attrdef', 'pg_event_trigger', 'pg_foreign_server', 'pg_foreign_data_wrapper',
|
||||
'pg_collation', 'pg_ts_config', 'pg_ts_dict', 'pg_ts_parser', 'pg_ts_template', 'pg_extension', 'pg_policy', 'pg_subscription', 'pg_publication_rel'))
|
||||
'pg_collation', 'pg_ts_config', 'pg_ts_dict', 'pg_ts_parser', 'pg_ts_template', 'pg_extension', 'pg_policy'))
|
||||
ORDER BY classid, cl.relkind
|
||||
|
@ -20,14 +20,13 @@ SELECT DISTINCT dep.deptype, dep.classid, cl.relkind, ad.adbin, ad.adsrc,
|
||||
WHEN ext.oid IS NOT NULL THEN 'Ex'::text
|
||||
WHEN syn.oid IS NOT NULL THEN 'Sy'::text
|
||||
WHEN pl.oid IS NOT NULL THEN 'Rs'::text
|
||||
WHEN pub_rel.oid IS NOT NULL THEN 'r'::text
|
||||
ELSE ''
|
||||
END AS type,
|
||||
COALESCE(coc.relname, clrw.relname) AS ownertable,
|
||||
CASE WHEN cl.relname IS NOT NULL AND att.attname IS NOT NULL THEN cl.relname || COALESCE('.' || att.attname, '')
|
||||
ELSE COALESCE(cl.relname, co.conname, pr.proname, tg.tgname, ty.typname, la.lanname, rw.rulename, ns.nspname,
|
||||
fs.srvname, fdw.fdwname, evt.evtname, col.collname, ftsc.cfgname, ftsd.dictname, ftsp.prsname,
|
||||
ftst.tmplname, ext.extname, syn.synname, pl.polname, quote_ident(pubns.nspname)||'.'||quote_ident(pubcl.relname))
|
||||
ftst.tmplname, ext.extname, syn.synname, pl.polname)
|
||||
END AS refname,
|
||||
COALESCE(nsc.nspname, nso.nspname, nsp.nspname, nst.nspname, nsrw.nspname, colns.nspname, ftscns.nspname,
|
||||
ftsdns.nspname, ftspns.nspname, ftstns.nspname, synns.nspname) AS nspname,
|
||||
@ -71,12 +70,10 @@ LEFT JOIN pg_extension ext ON ext.oid=dep.objid
|
||||
LEFT JOIN pg_synonym syn ON syn.oid=dep.objid
|
||||
LEFT JOIN pg_namespace synns ON syn.synnamespace=synns.oid
|
||||
LEFT JOIN pg_policy pl ON pl.oid=dep.objid
|
||||
LEFT JOIN pg_publication_rel pub_rel ON pub_rel.oid = dep.objid
|
||||
LEFT JOIN pg_class pubcl ON pubcl.oid = pub_rel.prrelid
|
||||
LEFT JOIN pg_namespace pubns ON pubns.oid=pubcl.relnamespace
|
||||
{{where_clause}} AND
|
||||
classid IN ( SELECT oid FROM pg_class WHERE relname IN
|
||||
('pg_class', 'pg_constraint', 'pg_conversion', 'pg_language', 'pg_proc', 'pg_rewrite', 'pg_namespace',
|
||||
'pg_trigger', 'pg_type', 'pg_attrdef', 'pg_event_trigger', 'pg_foreign_server', 'pg_foreign_data_wrapper',
|
||||
'pg_collation', 'pg_ts_config', 'pg_ts_dict', 'pg_ts_parser', 'pg_ts_template', 'pg_extension', 'pg_policy', 'pg_subscription', 'pg_publication_rel'))
|
||||
'pg_collation', 'pg_ts_config', 'pg_ts_dict', 'pg_ts_parser', 'pg_ts_template', 'pg_extension',
|
||||
'pg_synonym', 'pg_policy'))
|
||||
ORDER BY classid, cl.relkind
|
||||
|
@ -20,14 +20,13 @@ SELECT DISTINCT dep.deptype, dep.classid, cl.relkind, ad.adbin, pg_get_expr(ad.a
|
||||
WHEN ext.oid IS NOT NULL THEN 'Ex'::text
|
||||
WHEN syn.oid IS NOT NULL THEN 'Sy'::text
|
||||
WHEN pl.oid IS NOT NULL THEN 'Rs'::text
|
||||
WHEN pub_rel.oid IS NOT NULL THEN 'r'::text
|
||||
ELSE ''
|
||||
END AS type,
|
||||
COALESCE(coc.relname, clrw.relname) AS ownertable,
|
||||
CASE WHEN cl.relname IS NOT NULL AND att.attname IS NOT NULL THEN cl.relname || COALESCE('.' || att.attname, '')
|
||||
ELSE COALESCE(cl.relname, co.conname, pr.proname, tg.tgname, ty.typname, la.lanname, rw.rulename, ns.nspname,
|
||||
fs.srvname, fdw.fdwname, evt.evtname, col.collname, ftsc.cfgname, ftsd.dictname, ftsp.prsname,
|
||||
ftst.tmplname, ext.extname, syn.synname, pl.polname, quote_ident(pubns.nspname)||'.'||quote_ident(pubcl.relname))
|
||||
ftst.tmplname, ext.extname, syn.synname, pl.polname)
|
||||
END AS refname,
|
||||
COALESCE(nsc.nspname, nso.nspname, nsp.nspname, nst.nspname, nsrw.nspname, colns.nspname, ftscns.nspname,
|
||||
ftsdns.nspname, ftspns.nspname, ftstns.nspname, synns.nspname) AS nspname,
|
||||
@ -71,13 +70,10 @@ LEFT JOIN pg_extension ext ON ext.oid=dep.objid
|
||||
LEFT JOIN pg_synonym syn ON syn.oid=dep.objid
|
||||
LEFT JOIN pg_namespace synns ON syn.synnamespace=synns.oid
|
||||
LEFT JOIN pg_policy pl ON pl.oid=dep.objid
|
||||
LEFT JOIN pg_publication_rel pub_rel ON pub_rel.oid = dep.objid
|
||||
LEFT JOIN pg_class pubcl ON pubcl.oid = pub_rel.prrelid
|
||||
LEFT JOIN pg_namespace pubns ON pubns.oid=pubcl.relnamespace
|
||||
{{where_clause}} AND
|
||||
classid IN ( SELECT oid FROM pg_class WHERE relname IN
|
||||
('pg_class', 'pg_constraint', 'pg_conversion', 'pg_language', 'pg_proc', 'pg_rewrite', 'pg_namespace',
|
||||
'pg_trigger', 'pg_type', 'pg_attrdef', 'pg_event_trigger', 'pg_foreign_server', 'pg_foreign_data_wrapper',
|
||||
'pg_collation', 'pg_ts_config', 'pg_ts_dict', 'pg_ts_parser', 'pg_ts_template', 'pg_extension',
|
||||
'pg_synonym', 'pg_policy', 'pg_subscription', 'pg_publication_rel'))
|
||||
'pg_synonym', 'pg_policy'))
|
||||
ORDER BY classid, cl.relkind
|
||||
|
@ -393,6 +393,7 @@ class PGChildNodeView(NodeView):
|
||||
_GET_COLUMNS_FOR_TABLE_SQL = 'get_columns_for_table.sql'
|
||||
_GET_SUBTYPES_SQL = 'get_subtypes.sql'
|
||||
_GET_EXTERNAL_FUNCTIONS_SQL = 'get_external_functions.sql'
|
||||
_GET_TABLE_FOR_PUBLICATION = 'get_tables.sql'
|
||||
|
||||
def get_children_nodes(self, manager, **kwargs):
|
||||
"""
|
||||
@ -638,9 +639,7 @@ class PGChildNodeView(NodeView):
|
||||
# if type is present in the types dictionary, but it's
|
||||
# value is None then it requires special handling.
|
||||
if type_str[0] == 'r':
|
||||
if len(type_str) == 1:
|
||||
type_name = 'table'
|
||||
elif (type_str[1].isdigit() and int(type_str[1]) > 0) or \
|
||||
if (type_str[1].isdigit() and int(type_str[1]) > 0) or \
|
||||
(len(type_str) > 2 and type_str[2].isdigit() and
|
||||
int(type_str[2]) > 0):
|
||||
type_name = 'column'
|
||||
|
@ -39,12 +39,16 @@ export class ModelValidation {
|
||||
this.checkForEmpty('db', gettext('Maintenance database must be specified.'));
|
||||
this.checkForEmpty('username', gettext('Username must be specified.'));
|
||||
this.checkForEmpty('port', gettext('Port must be specified.'));
|
||||
if(!_.isUndefined(pub) && pub.length == 0){
|
||||
if(!_.isUndefined(pub)){
|
||||
if (this.model.isNew())
|
||||
this.checkForEmpty('password', gettext('Password must be specified.'));
|
||||
this.checkForEmpty('pub', gettext('Publication must be specified.'));
|
||||
}
|
||||
} else {
|
||||
this.checkForEmpty('db', gettext('Maintenance database must be specified.'));
|
||||
if(!_.isUndefined(pub) && pub.length == 0){
|
||||
if(!_.isUndefined(pub)){
|
||||
if (this.model.isNew())
|
||||
this.checkForEmpty('password', gettext('Password must be specified.'));
|
||||
this.checkForEmpty('pub', gettext('Publication must be specified.'));
|
||||
}
|
||||
this.clearHostAddressAndDbErrors();
|
||||
@ -90,7 +94,7 @@ export class ModelValidation {
|
||||
|
||||
let pub = this.model.get('pub'),
|
||||
errmsg;
|
||||
if(!_.isUndefined(pub) && pub.length == 0){
|
||||
if(!_.isUndefined(pub)){
|
||||
errmsg = gettext('Host name, Address must ' +
|
||||
'be specified.');
|
||||
}else{
|
||||
|
@ -207,7 +207,7 @@ export default class BodyWidget extends React.Component {
|
||||
}, ()=>this.registerKeyboardShortcuts());
|
||||
});
|
||||
|
||||
this.props.panel.on(window.wcDocker.EVENT.CLOSING, () => {
|
||||
this.props.panel?.on(window.wcDocker?.EVENT.CLOSING, () => {
|
||||
if(this.state.dirty) {
|
||||
this.closeOnSave = false;
|
||||
this.confirmBeforeClose();
|
||||
|
@ -1117,3 +1117,44 @@ CREATE USER MAPPING FOR public SERVER test_fs_for_user_mapping;
|
||||
|
||||
CREATE USER MAPPING FOR postgres SERVER test_fs_for_user_mapping
|
||||
OPTIONS (password 'admin123');
|
||||
|
||||
-- Publication Script
|
||||
CREATE TABLE test_schema_diff.table_for_publication (
|
||||
col1 integer NOT NULL,
|
||||
col2 text
|
||||
);
|
||||
|
||||
CREATE PUBLICATION for_all_table
|
||||
FOR ALL TABLES
|
||||
WITH (publish = 'insert, delete');
|
||||
|
||||
CREATE PUBLICATION with_one_table
|
||||
FOR TABLE test_schema_diff.table_for_publication
|
||||
WITH (publish = 'insert, delete');
|
||||
|
||||
ALTER PUBLICATION with_one_table
|
||||
RENAME TO with_one_table_alter;
|
||||
|
||||
ALTER PUBLICATION with_one_table_alter SET
|
||||
(publish = 'insert, update');
|
||||
|
||||
-- Subscription script
|
||||
|
||||
CREATE SUBSCRIPTION "subscription_test1"
|
||||
CONNECTION 'host=localhost port=5432 user=postgres dbname=edb password=samplepassword'
|
||||
PUBLICATION sample_publication
|
||||
WITH (connect = false, enabled = false, create_slot = false, slot_name = None, synchronous_commit = 'off');
|
||||
|
||||
ALTER SUBSCRIPTION subscription_test1
|
||||
CONNECTION 'host=localhost port=5432 user=postgres dbname=postgres';
|
||||
|
||||
ALTER SUBSCRIPTION subscription_test1
|
||||
SET (synchronous_commit = 'remote_apply');
|
||||
|
||||
ALTER SUBSCRIPTION subscription_test1
|
||||
SET PUBLICATION edb WITH (refresh = false);
|
||||
|
||||
ALTER SUBSCRIPTION subscription_test1
|
||||
RENAME TO subscription_test;
|
||||
|
||||
DROP SUBSCRIPTION subscription_test;
|
||||
|
@ -1062,3 +1062,50 @@ CREATE USER MAPPING FOR public SERVER test_fs_for_user_mapping
|
||||
OPTIONS (password 'admin123');
|
||||
|
||||
CREATE USER MAPPING FOR postgres SERVER test_fs_for_user_mapping;
|
||||
|
||||
-- Publication script
|
||||
|
||||
CREATE TABLE test_schema_diff.table_for_publication (
|
||||
col1 integer NOT NULL,
|
||||
col2 text
|
||||
);
|
||||
|
||||
CREATE TABLE test_schema_diff.table_for_publication_in_target (
|
||||
col1 integer NOT NULL,
|
||||
col2 text
|
||||
);
|
||||
|
||||
CREATE PUBLICATION for_all_table
|
||||
FOR ALL TABLES
|
||||
WITH (publish = 'insert, delete');
|
||||
|
||||
CREATE PUBLICATION with_one_table_in_target
|
||||
FOR TABLE test_schema_diff.table_for_publication_in_target
|
||||
WITH (publish = 'insert, delete');
|
||||
|
||||
ALTER PUBLICATION with_one_table_in_target
|
||||
RENAME TO with_one_table_in_target_alter;
|
||||
|
||||
ALTER PUBLICATION with_one_table_in_target_alter SET
|
||||
(publish = 'insert, update');
|
||||
|
||||
-- Subscription script
|
||||
|
||||
CREATE SUBSCRIPTION "subscription_test1_in_target"
|
||||
CONNECTION 'host=localhost port=5432 user=postgres dbname=edb password=samplepassword'
|
||||
PUBLICATION sample_publication
|
||||
WITH (connect = false, enabled = false, create_slot = false, slot_name = None, synchronous_commit = 'off');
|
||||
|
||||
ALTER SUBSCRIPTION subscription_test1_in_target
|
||||
CONNECTION 'host=localhost port=5432 user=postgres dbname=postgres';
|
||||
|
||||
ALTER SUBSCRIPTION subscription_test1_in_target
|
||||
SET (synchronous_commit = 'remote_apply');
|
||||
|
||||
ALTER SUBSCRIPTION subscription_test1_in_target
|
||||
SET PUBLICATION edb WITH (refresh = false);
|
||||
|
||||
ALTER SUBSCRIPTION subscription_test1_in_target
|
||||
RENAME TO subscription_test_in_target;
|
||||
|
||||
DROP SUBSCRIPTION subscription_test_in_target;
|
||||
|
@ -1116,3 +1116,46 @@ CREATE USER MAPPING FOR public SERVER test_fs_for_user_mapping;
|
||||
|
||||
CREATE USER MAPPING FOR postgres SERVER test_fs_for_user_mapping
|
||||
OPTIONS (password 'admin123');
|
||||
|
||||
-- Publication Script
|
||||
|
||||
CREATE TABLE test_schema_diff.table_for_publication (
|
||||
col1 integer NOT NULL,
|
||||
col2 text
|
||||
);
|
||||
|
||||
CREATE PUBLICATION for_all_table
|
||||
FOR ALL TABLES
|
||||
WITH (publish = 'insert, delete');
|
||||
|
||||
CREATE PUBLICATION with_one_table
|
||||
FOR TABLE test_schema_diff.table_for_publication
|
||||
WITH (publish = 'insert, delete');
|
||||
|
||||
ALTER PUBLICATION with_one_table
|
||||
RENAME TO with_one_table_alter;
|
||||
|
||||
ALTER PUBLICATION with_one_table_alter SET
|
||||
(publish = 'insert, update, truncate');
|
||||
|
||||
-- Subscription script
|
||||
|
||||
CREATE SUBSCRIPTION "subscription_test1"
|
||||
CONNECTION 'host=localhost port=5432 user=postgres dbname=edb password=samplepassword'
|
||||
PUBLICATION sample_publication
|
||||
WITH (connect = false, enabled = false, create_slot = false, slot_name = None, synchronous_commit = 'off');
|
||||
|
||||
ALTER SUBSCRIPTION subscription_test1
|
||||
CONNECTION 'host=localhost port=5432 user=postgres dbname=postgres';
|
||||
|
||||
ALTER SUBSCRIPTION subscription_test1
|
||||
SET (synchronous_commit = 'remote_apply');
|
||||
|
||||
ALTER SUBSCRIPTION subscription_test1
|
||||
SET PUBLICATION edb WITH (refresh = false);
|
||||
|
||||
ALTER SUBSCRIPTION subscription_test1
|
||||
RENAME TO subscription_test;
|
||||
|
||||
DROP SUBSCRIPTION subscription_test;
|
||||
|
||||
|
@ -1061,3 +1061,51 @@ CREATE USER MAPPING FOR public SERVER test_fs_for_user_mapping
|
||||
OPTIONS (password 'admin123');
|
||||
|
||||
CREATE USER MAPPING FOR postgres SERVER test_fs_for_user_mapping;
|
||||
|
||||
-- Publication scripts
|
||||
|
||||
CREATE TABLE test_schema_diff.table_for_publication (
|
||||
col1 integer NOT NULL,
|
||||
col2 text
|
||||
);
|
||||
|
||||
CREATE TABLE test_schema_diff.table_for_publication_in_target (
|
||||
col1 integer NOT NULL,
|
||||
col2 text
|
||||
);
|
||||
|
||||
CREATE PUBLICATION for_all_table
|
||||
FOR ALL TABLES
|
||||
WITH (publish = 'insert, delete');
|
||||
|
||||
CREATE PUBLICATION with_one_table_in_target
|
||||
FOR TABLE test_schema_diff.table_for_publication_in_target
|
||||
WITH (publish = 'insert, delete');
|
||||
|
||||
ALTER PUBLICATION with_one_table_in_target
|
||||
RENAME TO with_one_table_in_target_alter;
|
||||
|
||||
ALTER PUBLICATION with_one_table_in_target_alter SET
|
||||
(publish = 'insert, update, truncate');
|
||||
|
||||
-- Subscription script
|
||||
|
||||
CREATE SUBSCRIPTION "subscription_test1_in_target"
|
||||
CONNECTION 'host=localhost port=5432 user=postgres dbname=edb password=samplepassword'
|
||||
PUBLICATION sample_publication
|
||||
WITH (connect = false, enabled = false, create_slot = false, slot_name = None, synchronous_commit = 'off');
|
||||
|
||||
ALTER SUBSCRIPTION subscription_test1_in_target
|
||||
CONNECTION 'host=localhost port=5432 user=postgres dbname=postgres';
|
||||
|
||||
ALTER SUBSCRIPTION subscription_test1_in_target
|
||||
SET (synchronous_commit = 'remote_apply');
|
||||
|
||||
ALTER SUBSCRIPTION subscription_test1_in_target
|
||||
SET PUBLICATION edb WITH (refresh = false);
|
||||
|
||||
ALTER SUBSCRIPTION subscription_test1_in_target
|
||||
RENAME TO subscription_test_in_target;
|
||||
|
||||
DROP SUBSCRIPTION subscription_test_in_target;
|
||||
|
||||
|
@ -1117,3 +1117,53 @@ CREATE USER MAPPING FOR public SERVER test_fs_for_user_mapping;
|
||||
|
||||
CREATE USER MAPPING FOR postgres SERVER test_fs_for_user_mapping
|
||||
OPTIONS (password 'admin123');
|
||||
|
||||
-- Publication scripts
|
||||
|
||||
CREATE TABLE test_schema_diff.table_for_publication (
|
||||
col1 integer NOT NULL,
|
||||
col2 text
|
||||
);
|
||||
|
||||
CREATE TABLE test_schema_diff.table_for_publication_in_target (
|
||||
col1 integer NOT NULL,
|
||||
col2 text
|
||||
);
|
||||
|
||||
CREATE PUBLICATION for_all_table
|
||||
FOR ALL TABLES
|
||||
WITH (publish = 'insert, delete');
|
||||
|
||||
CREATE PUBLICATION with_one_table_in_target
|
||||
FOR TABLE test_schema_diff.table_for_publication_in_target
|
||||
WITH (publish = 'insert, delete');
|
||||
|
||||
ALTER PUBLICATION with_one_table_in_target
|
||||
OWNER TO managers;
|
||||
|
||||
ALTER PUBLICATION with_one_table_in_target
|
||||
RENAME TO with_one_table_in_target_alter;
|
||||
|
||||
ALTER PUBLICATION with_one_table_in_target_alter SET
|
||||
(publish = 'insert, update, truncate');
|
||||
|
||||
-- Subscription script
|
||||
|
||||
CREATE SUBSCRIPTION "subscription_test1"
|
||||
CONNECTION 'host=localhost port=5432 user=postgres dbname=edb password=samplepassword'
|
||||
PUBLICATION sample_publication
|
||||
WITH (connect = false, enabled = false, create_slot = false, slot_name = None, synchronous_commit = 'off');
|
||||
|
||||
ALTER SUBSCRIPTION subscription_test1
|
||||
CONNECTION 'host=localhost port=5432 user=postgres dbname=postgres';
|
||||
|
||||
ALTER SUBSCRIPTION subscription_test1
|
||||
SET (synchronous_commit = 'remote_apply');
|
||||
|
||||
ALTER SUBSCRIPTION subscription_test1
|
||||
SET PUBLICATION edb WITH (refresh = false);
|
||||
|
||||
ALTER SUBSCRIPTION subscription_test1
|
||||
RENAME TO subscription_test;
|
||||
|
||||
DROP SUBSCRIPTION subscription_test;
|
||||
|
@ -1050,3 +1050,51 @@ CREATE USER MAPPING FOR public SERVER test_fs_for_user_mapping
|
||||
OPTIONS (password 'admin123');
|
||||
|
||||
CREATE USER MAPPING FOR postgres SERVER test_fs_for_user_mapping;
|
||||
|
||||
CREATE TABLE test_schema_diff.table_for_publication (
|
||||
col1 integer NOT NULL,
|
||||
col2 text
|
||||
);
|
||||
|
||||
CREATE TABLE test_schema_diff.table_for_publication_in_target (
|
||||
col1 integer NOT NULL,
|
||||
col2 text
|
||||
);
|
||||
|
||||
CREATE PUBLICATION for_all_table
|
||||
FOR ALL TABLES
|
||||
WITH (publish = 'insert, delete');
|
||||
|
||||
CREATE PUBLICATION with_one_table_in_target
|
||||
FOR TABLE test_schema_diff.table_for_publication_in_target
|
||||
WITH (publish = 'insert, delete');
|
||||
|
||||
ALTER PUBLICATION with_one_table_in_target
|
||||
OWNER TO managers;
|
||||
|
||||
ALTER PUBLICATION with_one_table_in_target
|
||||
RENAME TO with_one_table_in_target_alter;
|
||||
|
||||
ALTER PUBLICATION with_one_table_in_target_alter SET
|
||||
(publish = 'insert, update, truncate');
|
||||
|
||||
-- Subscription script
|
||||
|
||||
CREATE SUBSCRIPTION "subscription_test1_in_target"
|
||||
CONNECTION 'host=localhost port=5432 user=postgres dbname=edb password=samplepassword'
|
||||
PUBLICATION sample_publication
|
||||
WITH (connect = false, enabled = false, create_slot = false, slot_name = None, synchronous_commit = 'off');
|
||||
|
||||
ALTER SUBSCRIPTION subscription_test1_in_target
|
||||
CONNECTION 'host=localhost port=5432 user=postgres dbname=postgres';
|
||||
|
||||
ALTER SUBSCRIPTION subscription_test1_in_target
|
||||
SET (synchronous_commit = 'remote_apply');
|
||||
|
||||
ALTER SUBSCRIPTION subscription_test1_in_target
|
||||
SET PUBLICATION edb WITH (refresh = false);
|
||||
|
||||
ALTER SUBSCRIPTION subscription_test1_in_target
|
||||
RENAME TO subscription_test_in_target;
|
||||
|
||||
DROP SUBSCRIPTION subscription_test_in_target;
|
||||
|
@ -1275,3 +1275,46 @@ CREATE USER MAPPING FOR public SERVER test_fs_for_user_mapping;
|
||||
|
||||
CREATE USER MAPPING FOR enterprisedb SERVER test_fs_for_user_mapping
|
||||
OPTIONS (password 'admin123');
|
||||
|
||||
-- Publication Script
|
||||
|
||||
CREATE TABLE test_schema_diff.table_for_publication (
|
||||
col1 integer NOT NULL,
|
||||
col2 text
|
||||
);
|
||||
|
||||
|
||||
CREATE PUBLICATION for_all_table
|
||||
FOR ALL TABLES
|
||||
WITH (publish = 'insert, delete');
|
||||
|
||||
CREATE PUBLICATION with_one_table
|
||||
FOR TABLE test_schema_diff.table_for_publication
|
||||
WITH (publish = 'insert, delete');
|
||||
|
||||
ALTER PUBLICATION with_one_table
|
||||
RENAME TO with_one_table_alter;
|
||||
|
||||
ALTER PUBLICATION with_one_table_alter SET
|
||||
(publish = 'insert, update');
|
||||
|
||||
-- Subscription script
|
||||
|
||||
CREATE SUBSCRIPTION "subscription_test1"
|
||||
CONNECTION 'host=localhost port=5432 user=postgres dbname=edb password=samplepassword'
|
||||
PUBLICATION sample_publication
|
||||
WITH (connect = false, enabled = false, create_slot = false, slot_name = None, synchronous_commit = 'off');
|
||||
|
||||
ALTER SUBSCRIPTION subscription_test1
|
||||
CONNECTION 'host=localhost port=5432 user=postgres dbname=postgres';
|
||||
|
||||
ALTER SUBSCRIPTION subscription_test1
|
||||
SET (synchronous_commit = 'remote_apply');
|
||||
|
||||
ALTER SUBSCRIPTION subscription_test1
|
||||
SET PUBLICATION edb WITH (refresh = false);
|
||||
|
||||
ALTER SUBSCRIPTION subscription_test1
|
||||
RENAME TO subscription_test;
|
||||
|
||||
DROP SUBSCRIPTION subscription_test;
|
||||
|
@ -1212,3 +1212,50 @@ CREATE USER MAPPING FOR public SERVER test_fs_for_user_mapping
|
||||
OPTIONS (password 'admin123');
|
||||
|
||||
CREATE USER MAPPING FOR enterprisedb SERVER test_fs_for_user_mapping;
|
||||
|
||||
-- Publication script
|
||||
|
||||
CREATE TABLE test_schema_diff.table_for_publication (
|
||||
col1 integer NOT NULL,
|
||||
col2 text
|
||||
);
|
||||
|
||||
CREATE TABLE test_schema_diff.table_for_publication_in_target (
|
||||
col1 integer NOT NULL,
|
||||
col2 text
|
||||
);
|
||||
|
||||
CREATE PUBLICATION for_all_table
|
||||
FOR ALL TABLES
|
||||
WITH (publish = 'insert, delete');
|
||||
|
||||
CREATE PUBLICATION with_one_table_in_target
|
||||
FOR TABLE test_schema_diff.table_for_publication_in_target
|
||||
WITH (publish = 'insert, delete');
|
||||
|
||||
ALTER PUBLICATION with_one_table_in_target
|
||||
RENAME TO with_one_table_in_target_alter;
|
||||
|
||||
ALTER PUBLICATION with_one_table_in_target_alter SET
|
||||
(publish = 'insert, update');
|
||||
|
||||
-- Subscription script
|
||||
|
||||
CREATE SUBSCRIPTION "subscription_test1_in_target"
|
||||
CONNECTION 'host=localhost port=5432 user=postgres dbname=edb password=samplepassword'
|
||||
PUBLICATION sample_publication
|
||||
WITH (connect = false, enabled = false, create_slot = false, slot_name = None, synchronous_commit = 'off');
|
||||
|
||||
ALTER SUBSCRIPTION subscription_test1_in_target
|
||||
CONNECTION 'host=localhost port=5432 user=postgres dbname=postgres';
|
||||
|
||||
ALTER SUBSCRIPTION subscription_test1_in_target
|
||||
SET (synchronous_commit = 'remote_apply');
|
||||
|
||||
ALTER SUBSCRIPTION subscription_test1_in_target
|
||||
SET PUBLICATION edb WITH (refresh = false);
|
||||
|
||||
ALTER SUBSCRIPTION subscription_test1_in_target
|
||||
RENAME TO subscription_test_in_target;
|
||||
|
||||
DROP SUBSCRIPTION subscription_test_in_target;
|
||||
|
1319
web/pgadmin/tools/schema_diff/tests/ppas/11_plus/source.sql
Normal file
1319
web/pgadmin/tools/schema_diff/tests/ppas/11_plus/source.sql
Normal file
File diff suppressed because it is too large
Load Diff
1261
web/pgadmin/tools/schema_diff/tests/ppas/11_plus/target.sql
Normal file
1261
web/pgadmin/tools/schema_diff/tests/ppas/11_plus/target.sql
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user