Modified schema diff tool to compare two databases instead of two schemas. Fixes #5126

This commit is contained in:
Akshay Joshi
2020-08-10 15:13:34 +05:30
parent 3672013ddc
commit 4f74609ecf
72 changed files with 1622 additions and 741 deletions

View File

@@ -21,6 +21,8 @@ from pgadmin.utils.ajax import make_json_response, \
make_response as ajax_response, internal_server_error, gone
from pgadmin.utils.driver import get_driver
from config import PG_DEFAULT_DRIVER
from pgadmin.tools.schema_diff.node_registry import SchemaDiffRegistry
from pgadmin.tools.schema_diff.compare import SchemaDiffObjectCompare
class ExtensionModule(CollectionNodeModule):
@@ -75,7 +77,7 @@ class ExtensionModule(CollectionNodeModule):
blueprint = ExtensionModule(__name__)
class ExtensionView(PGChildNodeView):
class ExtensionView(PGChildNodeView, SchemaDiffObjectCompare):
"""
This is a class for extension nodes which inherits the
properties and methods from NodeView class and define
@@ -173,7 +175,7 @@ class ExtensionView(PGChildNodeView):
for row in rset['rows']:
res.append(
self.blueprint.generate_browser_node(
row['eid'],
row['oid'],
did,
row['name'],
'icon-extension'
@@ -199,7 +201,7 @@ class ExtensionView(PGChildNodeView):
for row in rset['rows']:
return make_json_response(
data=self.blueprint.generate_browser_node(
row['eid'],
row['oid'],
did,
row['name'],
'icon-extension'
@@ -214,23 +216,37 @@ class ExtensionView(PGChildNodeView):
"""
Fetch the properties of a single extension and render in properties tab
"""
status, res = self._fetch_properties(did, eid)
if not status:
return res
return ajax_response(
response=res,
status=200
)
def _fetch_properties(self, did, eid):
"""
This function fetch the properties of the extension.
:param did:
:param eid:
:return:
"""
SQL = render_template("/".join(
[self.template_path, self._PROPERTIES_SQL]), eid=eid)
status, res = self.conn.execute_dict(SQL)
if not status:
return internal_server_error(errormsg=res)
return False, internal_server_error(errormsg=res)
if len(res['rows']) == 0:
return gone(
return False, gone(
gettext("Could not find the extension information.")
)
res['rows'][0]['is_sys_obj'] = (
res['rows'][0]['eid'] <= self.datlastsysoid)
return ajax_response(
response=res['rows'][0],
status=200
)
res['rows'][0]['oid'] <= self.datlastsysoid)
return True, res['rows'][0]
@check_precondition
def create(self, gid, sid, did):
@@ -278,7 +294,7 @@ class ExtensionView(PGChildNodeView):
for row in rset['rows']:
return jsonify(
node=self.blueprint.generate_browser_node(
row['eid'],
row['oid'],
did,
row['name'],
'icon-extension'
@@ -316,7 +332,7 @@ class ExtensionView(PGChildNodeView):
return internal_server_error(errormsg=str(e))
@check_precondition
def delete(self, gid, sid, did, eid=None):
def delete(self, gid, sid, did, eid=None, only_sql=False):
"""
This function will drop/drop cascade a extension object
"""
@@ -355,6 +371,11 @@ class ExtensionView(PGChildNodeView):
SQL = render_template("/".join(
[self.template_path, self._DELETE_SQL]
), name=name, cascade=cascade)
# 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)
@@ -452,7 +473,7 @@ class ExtensionView(PGChildNodeView):
)
@check_precondition
def sql(self, gid, sid, did, eid):
def sql(self, gid, sid, did, eid, json_resp=True):
"""
This function will generate sql for the sql panel
"""
@@ -477,6 +498,9 @@ class ExtensionView(PGChildNodeView):
display_comments=True
)
if not json_resp:
return SQL
return ajax_response(response=SQL)
@check_precondition
@@ -515,6 +539,57 @@ class ExtensionView(PGChildNodeView):
status=200
)
@check_precondition
def fetch_objects_to_compare(self, sid, did):
"""
This function will fetch the list of all the extensions for
specified database id.
:param sid: Server Id
:param did: Database Id
:return:
"""
res = dict()
sql = render_template("/".join([self.template_path,
'properties.sql']))
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.getSQL(gid=gid, sid=sid, did=did, data=data,
eid=oid)
else:
if drop_sql:
sql = self.delete(gid=gid, sid=sid, did=did,
eid=oid, only_sql=True)
else:
sql = self.sql(gid=gid, sid=sid, did=did, eid=oid,
json_resp=False)
return sql
SchemaDiffRegistry(blueprint.node_type, ExtensionView, 'Database')
# Register and add ExtensionView as blueprint
ExtensionView.register_node_view(blueprint)

View File

@@ -4,5 +4,5 @@ SELECT x.extname from pg_extension x
WHERE x.oid = {{ eid }}::oid
{% endif %}
{% if name %}
DROP EXTENSION {{ conn|qtIdent(name) }} {% if cascade %} CASCADE {% endif %}
DROP EXTENSION {{ conn|qtIdent(name) }}{% if cascade %} CASCADE{% endif %};
{% endif %}

View File

@@ -1,6 +1,6 @@
{#===================Fetch properties of each extension by name or oid===================#}
SELECT
x.oid AS eid, pg_get_userbyid(extowner) AS owner,
x.oid, pg_get_userbyid(extowner) AS owner,
x.extname AS name, n.nspname AS schema,
x.extrelocatable AS relocatable, x.extversion AS version,
e.comment