mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2026-08-05 02:43:27 -05:00
Modified schema diff tool to compare two databases instead of two schemas. Fixes #5126
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
import simplejson as json
|
||||
import pickle
|
||||
import random
|
||||
import copy
|
||||
|
||||
from flask import Response, session, url_for, request
|
||||
from flask import render_template, current_app as app
|
||||
@@ -61,7 +62,6 @@ class SchemaDiffModule(PgAdminModule):
|
||||
'schema_diff.panel',
|
||||
'schema_diff.servers',
|
||||
'schema_diff.databases',
|
||||
'schema_diff.schemas',
|
||||
'schema_diff.compare',
|
||||
'schema_diff.poll',
|
||||
'schema_diff.ddl_compare',
|
||||
@@ -397,46 +397,14 @@ def databases(sid):
|
||||
return make_json_response(data=res)
|
||||
|
||||
|
||||
@blueprint.route(
|
||||
'/schemas/<int:sid>/<int:did>',
|
||||
methods=["GET"],
|
||||
endpoint="schemas"
|
||||
)
|
||||
@login_required
|
||||
def schemas(sid, did):
|
||||
"""
|
||||
This function will return the list of schemas for the specified
|
||||
server id and database id.
|
||||
"""
|
||||
res = []
|
||||
try:
|
||||
view = SchemaDiffRegistry.get_node_view('schema')
|
||||
server = Server.query.filter_by(id=sid).first()
|
||||
response = view.nodes(gid=server.servergroup_id, sid=sid, did=did)
|
||||
if response.status_code == 200:
|
||||
schemas = json.loads(response.data)['data']
|
||||
for sch in schemas:
|
||||
res.append({
|
||||
"value": sch['_id'],
|
||||
"label": sch['label'],
|
||||
"_id": sch['_id'],
|
||||
"image": sch['icon'],
|
||||
})
|
||||
except Exception as e:
|
||||
app.logger.exception(e)
|
||||
|
||||
return make_json_response(data=res)
|
||||
|
||||
|
||||
@blueprint.route(
|
||||
'/compare/<int:trans_id>/<int:source_sid>/<int:source_did>/'
|
||||
'<int:source_scid>/<int:target_sid>/<int:target_did>/<int:target_scid>',
|
||||
'<int:target_sid>/<int:target_did>',
|
||||
methods=["GET"],
|
||||
endpoint="compare"
|
||||
)
|
||||
@login_required
|
||||
def compare(trans_id, source_sid, source_did, source_scid,
|
||||
target_sid, target_did, target_scid):
|
||||
def compare(trans_id, source_sid, source_did, target_sid, target_did):
|
||||
"""
|
||||
This function will compare the two schemas.
|
||||
"""
|
||||
@@ -463,33 +431,88 @@ def compare(trans_id, source_sid, source_did, source_scid,
|
||||
pref = Preferences.module('schema_diff')
|
||||
ignore_whitespaces = pref.preference('ignore_whitespaces').get()
|
||||
|
||||
all_registered_nodes = SchemaDiffRegistry.get_registered_nodes()
|
||||
node_percent = round(100 / len(all_registered_nodes))
|
||||
# Fetch all the schemas of source and target database
|
||||
# Compare them and get the status.
|
||||
schema_result = fetch_compare_schemas(source_sid, source_did,
|
||||
target_sid, target_did)
|
||||
|
||||
total_schema = len(schema_result['source_only']) + len(
|
||||
schema_result['target_only']) + len(
|
||||
schema_result['in_both_database'])
|
||||
|
||||
node_percent = round(100 / (total_schema * len(
|
||||
SchemaDiffRegistry.get_registered_nodes())))
|
||||
total_percent = 0
|
||||
|
||||
for node_name, node_view in all_registered_nodes.items():
|
||||
view = SchemaDiffRegistry.get_node_view(node_name)
|
||||
if hasattr(view, 'compare'):
|
||||
msg = gettext('Comparing {0}').\
|
||||
format(gettext(view.blueprint.collection_label))
|
||||
diff_model_obj.set_comparison_info(msg, total_percent)
|
||||
# Update the message and total percentage in session object
|
||||
update_session_diff_transaction(trans_id, session_obj,
|
||||
diff_model_obj)
|
||||
# Compare Database objects
|
||||
comparison_schema_result, total_percent = \
|
||||
compare_database_objects(
|
||||
trans_id=trans_id, session_obj=session_obj,
|
||||
source_sid=source_sid, source_did=source_did,
|
||||
target_sid=target_sid, target_did=target_did,
|
||||
diff_model_obj=diff_model_obj, total_percent=total_percent,
|
||||
node_percent=node_percent,
|
||||
ignore_whitespaces=ignore_whitespaces)
|
||||
comparison_result = \
|
||||
comparison_result + comparison_schema_result
|
||||
|
||||
res = view.compare(source_sid=source_sid,
|
||||
source_did=source_did,
|
||||
source_scid=source_scid,
|
||||
target_sid=target_sid,
|
||||
target_did=target_did,
|
||||
target_scid=target_scid,
|
||||
ignore_whitespaces=ignore_whitespaces)
|
||||
# Compare Schema objects
|
||||
if 'source_only' in schema_result and \
|
||||
len(schema_result['source_only']) > 0:
|
||||
for item in schema_result['source_only']:
|
||||
comparison_schema_result, total_percent = \
|
||||
compare_schema_objects(
|
||||
trans_id=trans_id, session_obj=session_obj,
|
||||
source_sid=source_sid, source_did=source_did,
|
||||
source_scid=item['scid'], target_sid=target_sid,
|
||||
target_did=target_did, target_scid=None,
|
||||
schema_name=item['schema_name'],
|
||||
diff_model_obj=diff_model_obj,
|
||||
total_percent=total_percent,
|
||||
node_percent=node_percent,
|
||||
ignore_whitespaces=ignore_whitespaces)
|
||||
|
||||
if res is not None:
|
||||
comparison_result = comparison_result + res
|
||||
total_percent = total_percent + node_percent
|
||||
comparison_result = \
|
||||
comparison_result + comparison_schema_result
|
||||
|
||||
msg = gettext("Successfully compare the specified schemas.")
|
||||
if 'target_only' in schema_result and \
|
||||
len(schema_result['target_only']) > 0:
|
||||
for item in schema_result['target_only']:
|
||||
comparison_schema_result, total_percent = \
|
||||
compare_schema_objects(
|
||||
trans_id=trans_id, session_obj=session_obj,
|
||||
source_sid=source_sid, source_did=source_did,
|
||||
source_scid=None, target_sid=target_sid,
|
||||
target_did=target_did, target_scid=item['scid'],
|
||||
schema_name=item['schema_name'],
|
||||
diff_model_obj=diff_model_obj,
|
||||
total_percent=total_percent,
|
||||
node_percent=node_percent,
|
||||
ignore_whitespaces=ignore_whitespaces)
|
||||
|
||||
comparison_result = \
|
||||
comparison_result + comparison_schema_result
|
||||
|
||||
# Compare the two schema present in both the databases
|
||||
if 'in_both_database' in schema_result and \
|
||||
len(schema_result['in_both_database']) > 0:
|
||||
for item in schema_result['in_both_database']:
|
||||
comparison_schema_result, total_percent = \
|
||||
compare_schema_objects(
|
||||
trans_id=trans_id, session_obj=session_obj,
|
||||
source_sid=source_sid, source_did=source_did,
|
||||
source_scid=item['src_scid'], target_sid=target_sid,
|
||||
target_did=target_did, target_scid=item['tar_scid'],
|
||||
schema_name=item['schema_name'],
|
||||
diff_model_obj=diff_model_obj,
|
||||
total_percent=total_percent,
|
||||
node_percent=node_percent,
|
||||
ignore_whitespaces=ignore_whitespaces)
|
||||
|
||||
comparison_result = \
|
||||
comparison_result + comparison_schema_result
|
||||
|
||||
msg = gettext("Successfully compare the specified databases.")
|
||||
total_percent = 100
|
||||
diff_model_obj.set_comparison_info(msg, total_percent)
|
||||
# Update the message and total percentage done in session object
|
||||
@@ -609,3 +632,169 @@ def check_version_compatibility(sid, tid):
|
||||
|
||||
return False, gettext('Source and Target database server must be of '
|
||||
'the same major version.')
|
||||
|
||||
|
||||
def get_schemas(sid, did):
|
||||
"""
|
||||
This function will return the list of schemas for the specified
|
||||
server id and database id.
|
||||
"""
|
||||
try:
|
||||
view = SchemaDiffRegistry.get_node_view('schema')
|
||||
server = Server.query.filter_by(id=sid).first()
|
||||
response = view.nodes(gid=server.servergroup_id, sid=sid, did=did)
|
||||
schemas = json.loads(response.data)['data']
|
||||
return schemas
|
||||
except Exception as e:
|
||||
app.logger.exception(e)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def compare_database_objects(**kwargs):
|
||||
"""
|
||||
This function is used to compare the specified schema and their children.
|
||||
|
||||
:param kwargs:
|
||||
:return:
|
||||
"""
|
||||
trans_id = kwargs.get('trans_id')
|
||||
session_obj = kwargs.get('session_obj')
|
||||
source_sid = kwargs.get('source_sid')
|
||||
source_did = kwargs.get('source_did')
|
||||
target_sid = kwargs.get('target_sid')
|
||||
target_did = kwargs.get('target_did')
|
||||
diff_model_obj = kwargs.get('diff_model_obj')
|
||||
total_percent = kwargs.get('total_percent')
|
||||
node_percent = kwargs.get('node_percent')
|
||||
ignore_whitespaces = kwargs.get('ignore_whitespaces')
|
||||
comparison_result = []
|
||||
|
||||
all_registered_nodes = SchemaDiffRegistry.get_registered_nodes(None,
|
||||
'Database')
|
||||
for node_name, node_view in all_registered_nodes.items():
|
||||
view = SchemaDiffRegistry.get_node_view(node_name)
|
||||
if hasattr(view, 'compare'):
|
||||
msg = gettext('Comparing {0}'). \
|
||||
format(gettext(view.blueprint.collection_label))
|
||||
diff_model_obj.set_comparison_info(msg, total_percent)
|
||||
# Update the message and total percentage in session object
|
||||
update_session_diff_transaction(trans_id, session_obj,
|
||||
diff_model_obj)
|
||||
|
||||
res = view.compare(source_sid=source_sid,
|
||||
source_did=source_did,
|
||||
target_sid=target_sid,
|
||||
target_did=target_did,
|
||||
group_name=gettext('Database Objects'),
|
||||
ignore_whitespaces=ignore_whitespaces)
|
||||
|
||||
if res is not None:
|
||||
comparison_result = comparison_result + res
|
||||
total_percent = total_percent + node_percent
|
||||
|
||||
return comparison_result, total_percent
|
||||
|
||||
|
||||
def compare_schema_objects(**kwargs):
|
||||
"""
|
||||
This function is used to compare the specified schema and their children.
|
||||
|
||||
:param kwargs:
|
||||
:return:
|
||||
"""
|
||||
trans_id = kwargs.get('trans_id')
|
||||
session_obj = kwargs.get('session_obj')
|
||||
source_sid = kwargs.get('source_sid')
|
||||
source_did = kwargs.get('source_did')
|
||||
source_scid = kwargs.get('source_scid')
|
||||
target_sid = kwargs.get('target_sid')
|
||||
target_did = kwargs.get('target_did')
|
||||
target_scid = kwargs.get('target_scid')
|
||||
schema_name = kwargs.get('schema_name')
|
||||
diff_model_obj = kwargs.get('diff_model_obj')
|
||||
total_percent = kwargs.get('total_percent')
|
||||
node_percent = kwargs.get('node_percent')
|
||||
ignore_whitespaces = kwargs.get('ignore_whitespaces')
|
||||
comparison_result = []
|
||||
|
||||
all_registered_nodes = SchemaDiffRegistry.get_registered_nodes()
|
||||
for node_name, node_view in all_registered_nodes.items():
|
||||
view = SchemaDiffRegistry.get_node_view(node_name)
|
||||
if hasattr(view, 'compare'):
|
||||
msg = gettext('Comparing {0} of schema \'{1}\''). \
|
||||
format(gettext(view.blueprint.collection_label),
|
||||
gettext(schema_name))
|
||||
diff_model_obj.set_comparison_info(msg, total_percent)
|
||||
# Update the message and total percentage in session object
|
||||
update_session_diff_transaction(trans_id, session_obj,
|
||||
diff_model_obj)
|
||||
|
||||
res = view.compare(source_sid=source_sid,
|
||||
source_did=source_did,
|
||||
source_scid=source_scid,
|
||||
target_sid=target_sid,
|
||||
target_did=target_did,
|
||||
target_scid=target_scid,
|
||||
group_name=gettext(schema_name),
|
||||
ignore_whitespaces=ignore_whitespaces)
|
||||
|
||||
if res is not None:
|
||||
comparison_result = comparison_result + res
|
||||
total_percent = total_percent + node_percent
|
||||
# if total_percent is more then 100 then set it to less then 100
|
||||
if total_percent >= 100:
|
||||
total_percent = 96
|
||||
|
||||
return comparison_result, total_percent
|
||||
|
||||
|
||||
def fetch_compare_schemas(source_sid, source_did, target_sid, target_did):
|
||||
"""
|
||||
This function is used to fetch all the schemas of source and target
|
||||
database and compare them.
|
||||
|
||||
:param source_sid:
|
||||
:param source_did:
|
||||
:param target_sid:
|
||||
:param target_did:
|
||||
:return:
|
||||
"""
|
||||
source_schemas = get_schemas(source_sid, source_did)
|
||||
target_schemas = get_schemas(target_sid, target_did)
|
||||
|
||||
src_schema_dict = {item['label']: item['_id'] for item in source_schemas}
|
||||
tar_schema_dict = {item['label']: item['_id'] for item in target_schemas}
|
||||
|
||||
dict1 = copy.deepcopy(src_schema_dict)
|
||||
dict2 = copy.deepcopy(tar_schema_dict)
|
||||
|
||||
# Find the duplicate keys in both the dictionaries
|
||||
dict1_keys = set(dict1.keys())
|
||||
dict2_keys = set(dict2.keys())
|
||||
intersect_keys = dict1_keys.intersection(dict2_keys)
|
||||
|
||||
# Keys that are available in source and missing in target.
|
||||
source_only = []
|
||||
added = dict1_keys - dict2_keys
|
||||
for item in added:
|
||||
source_only.append({'schema_name': item,
|
||||
'scid': src_schema_dict[item]})
|
||||
|
||||
target_only = []
|
||||
# Keys that are available in target and missing in source.
|
||||
removed = dict2_keys - dict1_keys
|
||||
for item in removed:
|
||||
target_only.append({'schema_name': item,
|
||||
'scid': tar_schema_dict[item]})
|
||||
|
||||
in_both_database = []
|
||||
for item in intersect_keys:
|
||||
in_both_database.append({'schema_name': item,
|
||||
'src_scid': src_schema_dict[item],
|
||||
'tar_scid': tar_schema_dict[item]})
|
||||
|
||||
schema_result = {'source_only': source_only, 'target_only': target_only,
|
||||
'in_both_database': in_both_database}
|
||||
|
||||
return schema_result
|
||||
|
||||
@@ -9,20 +9,17 @@
|
||||
|
||||
"""Schema diff object comparison."""
|
||||
|
||||
import copy
|
||||
|
||||
from flask import render_template
|
||||
from flask_babelex import gettext
|
||||
from pgadmin.utils.driver import get_driver
|
||||
from config import PG_DEFAULT_DRIVER
|
||||
from pgadmin.utils.ajax import internal_server_error
|
||||
from pgadmin.tools.schema_diff.directory_compare import compare_dictionaries
|
||||
from pgadmin.tools.schema_diff.model import SchemaDiffModel
|
||||
|
||||
|
||||
class SchemaDiffObjectCompare:
|
||||
|
||||
keys_to_ignore = ['oid', 'schema']
|
||||
keys_to_ignore = ['oid', 'oid-2']
|
||||
|
||||
@staticmethod
|
||||
def get_schema(sid, did, scid):
|
||||
@@ -57,28 +54,28 @@ class SchemaDiffObjectCompare:
|
||||
:param kwargs:
|
||||
:return:
|
||||
"""
|
||||
|
||||
source_params = {'sid': kwargs.get('source_sid'),
|
||||
'did': kwargs.get('source_did'),
|
||||
'scid': kwargs.get('source_scid')
|
||||
}
|
||||
|
||||
'did': kwargs.get('source_did')}
|
||||
target_params = {'sid': kwargs.get('target_sid'),
|
||||
'did': kwargs.get('target_did'),
|
||||
'scid': kwargs.get('target_scid')
|
||||
}
|
||||
'did': kwargs.get('target_did')}
|
||||
|
||||
group_name = kwargs.get('group_name')
|
||||
ignore_whitespaces = kwargs.get('ignore_whitespaces')
|
||||
status, target_schema = self.get_schema(kwargs.get('target_sid'),
|
||||
kwargs.get('target_did'),
|
||||
kwargs.get('target_scid')
|
||||
)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=target_schema)
|
||||
source = {}
|
||||
target = {}
|
||||
|
||||
source = self.fetch_objects_to_compare(**source_params)
|
||||
if group_name == 'Database Objects':
|
||||
source = self.fetch_objects_to_compare(**source_params)
|
||||
target = self.fetch_objects_to_compare(**target_params)
|
||||
else:
|
||||
source_params['scid'] = kwargs.get('source_scid')
|
||||
target_params['scid'] = kwargs.get('target_scid')
|
||||
|
||||
target = self.fetch_objects_to_compare(**target_params)
|
||||
if 'scid' in source_params and source_params['scid'] is not None:
|
||||
source = self.fetch_objects_to_compare(**source_params)
|
||||
|
||||
if 'scid' in target_params and target_params['scid'] is not None:
|
||||
target = self.fetch_objects_to_compare(**target_params)
|
||||
|
||||
# If both the dict have no items then return None.
|
||||
if not (source or target) or (
|
||||
@@ -88,11 +85,11 @@ class SchemaDiffObjectCompare:
|
||||
return compare_dictionaries(view_object=self,
|
||||
source_params=source_params,
|
||||
target_params=target_params,
|
||||
target_schema=target_schema,
|
||||
source_dict=source,
|
||||
target_dict=target,
|
||||
node=self.node_type,
|
||||
node_label=self.blueprint.collection_label,
|
||||
group_name=group_name,
|
||||
ignore_whitespaces=ignore_whitespaces,
|
||||
ignore_keys=self.keys_to_ignore)
|
||||
|
||||
@@ -105,17 +102,23 @@ class SchemaDiffObjectCompare:
|
||||
source_params = {'gid': 1,
|
||||
'sid': kwargs.get('source_sid'),
|
||||
'did': kwargs.get('source_did'),
|
||||
'scid': kwargs.get('source_scid'),
|
||||
'oid': kwargs.get('source_oid')
|
||||
}
|
||||
|
||||
target_params = {'gid': 1,
|
||||
'sid': kwargs.get('target_sid'),
|
||||
'did': kwargs.get('target_did'),
|
||||
'scid': kwargs.get('target_scid'),
|
||||
'oid': kwargs.get('target_oid')
|
||||
}
|
||||
|
||||
source_scid = kwargs.get('source_scid')
|
||||
if source_scid is not None and source_scid != 0:
|
||||
source_params['scid'] = source_scid
|
||||
|
||||
target_scid = kwargs.get('target_scid')
|
||||
if target_scid is not None and target_scid != 0:
|
||||
target_params['scid'] = target_scid
|
||||
|
||||
source = self.get_sql_from_diff(**source_params)
|
||||
target = self.get_sql_from_diff(**target_params)
|
||||
|
||||
|
||||
@@ -16,7 +16,8 @@ from pgadmin.tools.schema_diff.model import SchemaDiffModel
|
||||
count = 1
|
||||
|
||||
list_keys_array = ['name', 'colname', 'argid', 'token', 'option', 'conname',
|
||||
'member_name', 'label', 'attname']
|
||||
'member_name', 'label', 'attname', 'fdwoption',
|
||||
'fsrvoption', 'umoption']
|
||||
|
||||
|
||||
def compare_dictionaries(**kwargs):
|
||||
@@ -29,7 +30,7 @@ def compare_dictionaries(**kwargs):
|
||||
view_object = kwargs.get('view_object')
|
||||
source_params = kwargs.get('source_params')
|
||||
target_params = kwargs.get('target_params')
|
||||
target_schema = kwargs.get('target_schema')
|
||||
group_name = kwargs.get('group_name')
|
||||
source_dict = kwargs.get('source_dict')
|
||||
target_dict = kwargs.get('target_dict')
|
||||
node = kwargs.get('node')
|
||||
@@ -50,6 +51,7 @@ def compare_dictionaries(**kwargs):
|
||||
|
||||
# Keys that are available in source and missing in target.
|
||||
source_only = []
|
||||
source_dependencies = []
|
||||
added = dict1_keys - dict2_keys
|
||||
global count
|
||||
for item in added:
|
||||
@@ -63,18 +65,25 @@ def compare_dictionaries(**kwargs):
|
||||
temp_src_params['json_resp'] = False
|
||||
source_ddl = \
|
||||
view_object.get_sql_from_table_diff(**temp_src_params)
|
||||
temp_src_params.update({
|
||||
'diff_schema': target_schema
|
||||
})
|
||||
diff_ddl = view_object.get_sql_from_table_diff(**temp_src_params)
|
||||
source_dependencies = \
|
||||
view_object.get_table_submodules_dependencies(
|
||||
**temp_src_params)
|
||||
else:
|
||||
temp_src_params = copy.deepcopy(source_params)
|
||||
temp_src_params['oid'] = source_object_id
|
||||
# Provide Foreign Data Wrapper ID
|
||||
if 'fdwid' in source_dict[item]:
|
||||
temp_src_params['fdwid'] = source_dict[item]['fdwid']
|
||||
# Provide Foreign Server ID
|
||||
if 'fsid' in source_dict[item]:
|
||||
temp_src_params['fsid'] = source_dict[item]['fsid']
|
||||
|
||||
source_ddl = view_object.get_sql_from_diff(**temp_src_params)
|
||||
temp_src_params.update({
|
||||
'diff_schema': target_schema
|
||||
})
|
||||
diff_ddl = view_object.get_sql_from_diff(**temp_src_params)
|
||||
source_dependencies = view_object.get_dependencies(
|
||||
view_object.conn, source_object_id, where=None,
|
||||
show_system_objects=None, is_schema_diff=True)
|
||||
|
||||
source_only.append({
|
||||
'id': count,
|
||||
@@ -85,7 +94,9 @@ def compare_dictionaries(**kwargs):
|
||||
'status': SchemaDiffModel.COMPARISON_STATUS['source_only'],
|
||||
'source_ddl': source_ddl,
|
||||
'target_ddl': '',
|
||||
'diff_ddl': diff_ddl
|
||||
'diff_ddl': diff_ddl,
|
||||
'group_name': group_name,
|
||||
'dependencies': source_dependencies
|
||||
})
|
||||
count += 1
|
||||
|
||||
@@ -110,6 +121,13 @@ def compare_dictionaries(**kwargs):
|
||||
else:
|
||||
temp_tgt_params = copy.deepcopy(target_params)
|
||||
temp_tgt_params['oid'] = target_object_id
|
||||
# Provide Foreign Data Wrapper ID
|
||||
if 'fdwid' in target_dict[item]:
|
||||
temp_tgt_params['fdwid'] = target_dict[item]['fdwid']
|
||||
# Provide Foreign Server ID
|
||||
if 'fsid' in target_dict[item]:
|
||||
temp_tgt_params['fsid'] = target_dict[item]['fsid']
|
||||
|
||||
target_ddl = view_object.get_sql_from_diff(**temp_tgt_params)
|
||||
temp_tgt_params.update(
|
||||
{'drop_sql': True})
|
||||
@@ -124,13 +142,16 @@ def compare_dictionaries(**kwargs):
|
||||
'status': SchemaDiffModel.COMPARISON_STATUS['target_only'],
|
||||
'source_ddl': '',
|
||||
'target_ddl': target_ddl,
|
||||
'diff_ddl': diff_ddl
|
||||
'diff_ddl': diff_ddl,
|
||||
'group_name': group_name,
|
||||
'dependencies': []
|
||||
})
|
||||
count += 1
|
||||
|
||||
# Compare the values of duplicates keys.
|
||||
identical = []
|
||||
different = []
|
||||
diff_dependencies = []
|
||||
for key in intersect_keys:
|
||||
source_object_id = None
|
||||
target_object_id = None
|
||||
@@ -149,7 +170,13 @@ def compare_dictionaries(**kwargs):
|
||||
'oid': source_object_id,
|
||||
'source_oid': source_object_id,
|
||||
'target_oid': target_object_id,
|
||||
'status': SchemaDiffModel.COMPARISON_STATUS['identical']
|
||||
'status': SchemaDiffModel.COMPARISON_STATUS['identical'],
|
||||
'group_name': group_name,
|
||||
'dependencies': [],
|
||||
'source_scid': source_params['scid']
|
||||
if 'scid' in source_params else 0,
|
||||
'target_scid': target_params['scid']
|
||||
if 'scid' in target_params else 0,
|
||||
})
|
||||
else:
|
||||
if node == 'table':
|
||||
@@ -174,12 +201,14 @@ def compare_dictionaries(**kwargs):
|
||||
|
||||
source_ddl = \
|
||||
view_object.get_sql_from_table_diff(**temp_src_params)
|
||||
diff_dependencies = \
|
||||
view_object.get_table_submodules_dependencies(
|
||||
**temp_src_params)
|
||||
target_ddl = \
|
||||
view_object.get_sql_from_table_diff(**temp_tgt_params)
|
||||
diff_ddl = view_object.get_sql_from_submodule_diff(
|
||||
source_params=temp_src_params,
|
||||
target_params=temp_tgt_params,
|
||||
target_schema=target_schema,
|
||||
source=dict1[key], target=dict2[key], diff_dict=diff_dict,
|
||||
ignore_whitespaces=ignore_whitespaces)
|
||||
else:
|
||||
@@ -193,7 +222,19 @@ def compare_dictionaries(**kwargs):
|
||||
|
||||
temp_src_params['oid'] = source_object_id
|
||||
temp_tgt_params['oid'] = target_object_id
|
||||
# Provide Foreign Data Wrapper ID
|
||||
if 'fdwid' in source_dict[key]:
|
||||
temp_src_params['fdwid'] = source_dict[key]['fdwid']
|
||||
temp_tgt_params['fdwid'] = target_dict[key]['fdwid']
|
||||
# Provide Foreign Server ID
|
||||
if 'fsid' in source_dict[key]:
|
||||
temp_src_params['fsid'] = source_dict[key]['fsid']
|
||||
temp_tgt_params['fsid'] = target_dict[key]['fsid']
|
||||
|
||||
source_ddl = view_object.get_sql_from_diff(**temp_src_params)
|
||||
diff_dependencies = view_object.get_dependencies(
|
||||
view_object.conn, source_object_id, where=None,
|
||||
show_system_objects=None, is_schema_diff=True)
|
||||
target_ddl = view_object.get_sql_from_diff(**temp_tgt_params)
|
||||
temp_tgt_params.update(
|
||||
{'data': diff_dict})
|
||||
@@ -210,7 +251,9 @@ def compare_dictionaries(**kwargs):
|
||||
'status': SchemaDiffModel.COMPARISON_STATUS['different'],
|
||||
'source_ddl': source_ddl,
|
||||
'target_ddl': target_ddl,
|
||||
'diff_ddl': diff_ddl
|
||||
'diff_ddl': diff_ddl,
|
||||
'group_name': group_name,
|
||||
'dependencies': diff_dependencies
|
||||
})
|
||||
count += 1
|
||||
|
||||
@@ -498,13 +541,13 @@ def sort_list(source, target):
|
||||
:return:
|
||||
"""
|
||||
# Check the above keys are exist in the dictionary
|
||||
if len(source) > 0 and type(source[0]) == dict:
|
||||
if source is not None and len(source) > 0 and type(source[0]) == dict:
|
||||
tmp_key = is_key_exists(list_keys_array, source[0])
|
||||
if tmp_key is not None:
|
||||
source = sorted(source, key=lambda k: k[tmp_key])
|
||||
|
||||
# Check the above keys are exist in the dictionary
|
||||
if len(target) > 0 and type(target[0]) == dict:
|
||||
if target is not None and len(target) > 0 and type(target[0]) == dict:
|
||||
tmp_key = is_key_exists(list_keys_array, target[0])
|
||||
if tmp_key is not None:
|
||||
target = sorted(target, key=lambda k: k[tmp_key])
|
||||
|
||||
@@ -162,3 +162,7 @@
|
||||
.slick-cell .ml-2 {
|
||||
margin-left: 2rem !important;
|
||||
}
|
||||
|
||||
.slick-cell .ml-3 {
|
||||
margin-left: 3rem !important;
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ let SchemaDiffSelect2Control =
|
||||
controlsClassName: 'pgadmin-controls pg-el-sm-11 pg-el-12',
|
||||
}),
|
||||
className: function() {
|
||||
return 'pgadmin-controls pg-el-sm-4';
|
||||
return 'pgadmin-controls pg-el-sm-6';
|
||||
},
|
||||
events: {
|
||||
'focus select': 'clearInvalid',
|
||||
|
||||
@@ -39,10 +39,8 @@ export default class SchemaDiffUI {
|
||||
this.model = new Backbone.Model({
|
||||
source_sid: undefined,
|
||||
source_did: undefined,
|
||||
source_scid: undefined,
|
||||
target_sid: undefined,
|
||||
target_did: undefined,
|
||||
target_scid: undefined,
|
||||
source_ddl: undefined,
|
||||
target_ddl: undefined,
|
||||
diff_ddl: undefined,
|
||||
@@ -109,7 +107,6 @@ export default class SchemaDiffUI {
|
||||
|
||||
}
|
||||
|
||||
|
||||
raise_error_on_fail(alert_title, xhr) {
|
||||
try {
|
||||
var err = JSON.parse(xhr.responseText);
|
||||
@@ -146,11 +143,9 @@ export default class SchemaDiffUI {
|
||||
url_params = self.model.toJSON();
|
||||
|
||||
if (url_params['source_sid'] == '' || _.isUndefined(url_params['source_sid']) ||
|
||||
url_params['source_did'] == '' || _.isUndefined(url_params['source_did']) ||
|
||||
url_params['source_scid'] == '' || _.isUndefined(url_params['source_scid']) ||
|
||||
url_params['target_sid'] == '' || _.isUndefined(url_params['target_sid']) ||
|
||||
url_params['target_did'] == '' || _.isUndefined(url_params['target_did']) ||
|
||||
url_params['target_scid'] == '' || _.isUndefined(url_params['target_scid'])
|
||||
url_params['source_did'] == '' || _.isUndefined(url_params['source_did']) ||
|
||||
url_params['target_sid'] == '' || _.isUndefined(url_params['target_sid']) ||
|
||||
url_params['target_did'] == '' || _.isUndefined(url_params['target_did'])
|
||||
) {
|
||||
Alertify.alert(gettext('Selection Error'), gettext('Please select source and target.'));
|
||||
return false;
|
||||
@@ -289,18 +284,18 @@ export default class SchemaDiffUI {
|
||||
// Format Schema object title with appropriate icon
|
||||
var formatColumnTitle = function (row, cell, value, columnDef, dataContext) {
|
||||
let icon = 'icon-' + dataContext.type;
|
||||
return '<i class="ml-2 wcTabIcon '+ icon +'"></i><span>' + value + '</span>';
|
||||
return '<i class="ml-3 wcTabIcon '+ icon +'"></i><span>' + value + '</span>';
|
||||
};
|
||||
|
||||
// Grid Columns
|
||||
var grid_width = (self.grid_width - 47) / 2 ;
|
||||
var columns = [
|
||||
checkboxSelector.getColumnDefinition(),
|
||||
{id: 'title', name: gettext('Schema Objects'), field: 'title', minWidth: grid_width, formatter: formatColumnTitle},
|
||||
{id: 'title', name: gettext('Objects'), field: 'title', minWidth: grid_width, formatter: formatColumnTitle},
|
||||
{id: 'status', name: gettext('Comparison Result'), field: 'status', minWidth: grid_width},
|
||||
{id: 'label', name: gettext('Schema Objects'), field: 'label', width: 0, minWidth: 0, maxWidth: 0,
|
||||
{id: 'label', name: gettext('Objects'), field: 'label', width: 0, minWidth: 0, maxWidth: 0,
|
||||
cssClass: 'really-hidden', headerCssClass: 'really-hidden'},
|
||||
{id: 'type', name: gettext('Schema Objects'), field: 'type', width: 0, minWidth: 0, maxWidth: 0,
|
||||
{id: 'type', name: gettext('Objects'), field: 'type', width: 0, minWidth: 0, maxWidth: 0,
|
||||
cssClass: 'really-hidden', headerCssClass: 'really-hidden'},
|
||||
{id: 'id', name: 'id', field: 'id', width: 0, minWidth: 0, maxWidth: 0,
|
||||
cssClass: 'really-hidden', headerCssClass: 'really-hidden' },
|
||||
@@ -316,7 +311,18 @@ export default class SchemaDiffUI {
|
||||
|
||||
// Grouping by Schema Object
|
||||
self.groupBySchemaObject = function() {
|
||||
self.dataView.setGrouping({
|
||||
self.dataView.setGrouping([{
|
||||
getter: 'group_name',
|
||||
formatter: function (g) {
|
||||
let icon = 'icon-schema';
|
||||
if (g.rows[0].group_name == 'Database Objects'){
|
||||
icon = 'icon-coll-database';
|
||||
}
|
||||
return '<i class="wcTabIcon '+ icon +'"></i><span>' + g.rows[0].group_name;
|
||||
},
|
||||
aggregateCollapsed: true,
|
||||
lazyTotalsCalculation: true,
|
||||
}, {
|
||||
getter: 'type',
|
||||
formatter: function (g) {
|
||||
let icon = 'icon-coll-' + g.value;
|
||||
@@ -330,8 +336,9 @@ export default class SchemaDiffUI {
|
||||
return '<i class="wcTabIcon '+ icon +'"></i><span>' + g.rows[0].label + ' - ' + gettext('Identical') + ': <strong>' + identical + '</strong> ' + gettext('Different') + ': <strong>' + different + '</strong> ' + gettext('Source Only') + ': <strong>' + source_only + '</strong> ' + gettext('Target Only') + ': <strong>' + target_only + '</strong></span>';
|
||||
},
|
||||
aggregateCollapsed: true,
|
||||
collapsed: true,
|
||||
lazyTotalsCalculation: true,
|
||||
});
|
||||
}]);
|
||||
};
|
||||
|
||||
var groupItemMetadataProvider = new Slick.Data.GroupItemMetadataProvider({ checkboxSelect: true,
|
||||
@@ -503,6 +510,8 @@ export default class SchemaDiffUI {
|
||||
target_oid = data.target_oid;
|
||||
|
||||
url_params['trans_id'] = self.trans_id;
|
||||
url_params['source_scid'] = data.source_scid;
|
||||
url_params['target_scid'] = data.target_scid;
|
||||
url_params['source_oid'] = source_oid;
|
||||
url_params['target_oid'] = target_oid;
|
||||
url_params['comp_status'] = data.status;
|
||||
@@ -607,37 +616,6 @@ export default class SchemaDiffUI {
|
||||
connect: function() {
|
||||
self.connect_database(this.model.get('source_sid'), arguments[0], arguments[1]);
|
||||
},
|
||||
}, {
|
||||
name: 'source_scid',
|
||||
control: SchemaDiffSelect2Control,
|
||||
group: 'source',
|
||||
deps: ['source_sid', 'source_did'],
|
||||
url: function() {
|
||||
if (this.get('source_sid') && this.get('source_did'))
|
||||
return url_for('schema_diff.schemas', {'sid': this.get('source_sid'), 'did': this.get('source_did')});
|
||||
return false;
|
||||
},
|
||||
select2: {
|
||||
allowClear: true,
|
||||
placeholder: gettext('Select schema...'),
|
||||
},
|
||||
disabled: function(m) {
|
||||
let self_local = this;
|
||||
if (!_.isUndefined(m.get('source_did')) && !_.isNull(m.get('source_did'))
|
||||
&& m.get('source_did') !== '') {
|
||||
setTimeout(function() {
|
||||
if (self_local.options.length > 0) {
|
||||
m.set('source_scid', self_local.options[0].value);
|
||||
}
|
||||
}, 10);
|
||||
return false;
|
||||
}
|
||||
|
||||
setTimeout(function() {
|
||||
m.set('source_scid', undefined);
|
||||
}, 10);
|
||||
return true;
|
||||
},
|
||||
}, {
|
||||
name: 'target_sid', label: false,
|
||||
control: SchemaDiffSelect2Control,
|
||||
@@ -698,37 +676,6 @@ export default class SchemaDiffUI {
|
||||
connect: function() {
|
||||
self.connect_database(this.model.get('target_sid'), arguments[0], arguments[1]);
|
||||
},
|
||||
}, {
|
||||
name: 'target_scid',
|
||||
control: SchemaDiffSelect2Control,
|
||||
group: 'target',
|
||||
deps: ['target_sid', 'target_did'],
|
||||
url: function() {
|
||||
if (this.get('target_sid') && this.get('target_did'))
|
||||
return url_for('schema_diff.schemas', {'sid': this.get('target_sid'), 'did': this.get('target_did')});
|
||||
return false;
|
||||
},
|
||||
select2: {
|
||||
allowClear: true,
|
||||
placeholder: gettext('Select schema...'),
|
||||
},
|
||||
disabled: function(m) {
|
||||
let self_local = this;
|
||||
if (!_.isUndefined(m.get('target_did')) && !_.isNull(m.get('target_did'))
|
||||
&& m.get('target_did') !== '') {
|
||||
setTimeout(function() {
|
||||
if (self_local.options.length > 0) {
|
||||
m.set('target_scid', self_local.options[0].value);
|
||||
}
|
||||
}, 10);
|
||||
return false;
|
||||
}
|
||||
|
||||
setTimeout(function() {
|
||||
m.set('target_scid', undefined);
|
||||
}, 10);
|
||||
return true;
|
||||
},
|
||||
}],
|
||||
});
|
||||
|
||||
@@ -760,7 +707,7 @@ export default class SchemaDiffUI {
|
||||
|
||||
footer_panel.$container.find('#schema-diff-ddl-comp').append(self.footer.render().$el);
|
||||
header_panel.$container.find('#schema-diff-grid').append(`<div class='obj_properties container-fluid'>
|
||||
<div class='pg-panel-message'>` + gettext('Select the server, database and schema for the source and target and click <strong>Compare</strong> to compare them.') + '</div></div>');
|
||||
<div class='pg-panel-message'>` + gettext('Select the server and database for the source and target and click <strong>Compare</strong> to compare them.') + '</div></div>');
|
||||
|
||||
self.grid_width = $('#schema-diff-grid').width();
|
||||
self.grid_height = this.panel_obj.height();
|
||||
|
||||
@@ -23,7 +23,7 @@ from pgadmin.utils.versioned_template_loader import \
|
||||
get_version_mapping_directories
|
||||
|
||||
|
||||
class SchemaDiffTestCase(BaseTestGenerator):
|
||||
class SchemaDiffTestCase():
|
||||
""" This class will test the schema diff. """
|
||||
scenarios = [
|
||||
# Fetching default URL for database node.
|
||||
|
||||
Reference in New Issue
Block a user