def _check_objects(server1, server2, db1, db2, db1_conn, db2_conn, options): """Check number of objects server1[in] first server Server instance server2[in] second server Server instance db1[in] first database db2[in] second database db1_conn[in] first Database instance db2_conn[in] second Database instance options[in] options dictionary Returns list of objects in both databases """ differs = False # Check for same number of objects in_both, in_db1, in_db2 = get_common_objects(server1, server2, db1, db2, False, options) in_both.sort() if not options['no_object_check']: server1_str = "server1." + db1 if server1 == server2: server2_str = "server1." + db2 else: server2_str = "server2." + db2 if len(in_db1) or len(in_db2): if options['run_all_tests']: if len(in_db1) > 0: differs = True print_missing_list(in_db1, server1_str, server2_str) print "#" if len(in_db2) > 0: differs = True print_missing_list(in_db2, server2_str, server1_str) print "#" else: differs = True raise UtilError(_ERROR_OBJECT_LIST.format(db1, db2)) # If in verbose mode, show count of object types. if options['verbosity'] > 1: objects = { 'TABLE': 0, 'VIEW': 0, 'TRIGGER': 0, 'PROCEDURE': 0, 'FUNCTION': 0, 'EVENT': 0, } for item in in_both: obj_type = item[0] objects[obj_type] += 1 print "Looking for object types table, view, trigger, procedure," + \ " function, and event." print "Object types found common to both databases:" for obj in objects: print " {0:>12} : {1}".format(obj, objects[obj]) return (in_both, differs)
def database_diff(server1_val, server2_val, db1, db2, options): """Find differences among objects from two databases. This method compares the object definitions among two databases. If any differences are found, the differences are printed in the format chosen and the method returns False. A True result is returned only when all object definitions match. The method will stop and return False on the first difference found unless the option force is set to True (default = False). server1_val[in] a dictionary containing connection information for the first server including: (user, password, host, port, socket) server2_val[in] a dictionary containing connection information for the second server including: (user, password, host, port, socket) db1[in] the first database in the compare db2[in] the second database in the compare options[in] a dictionary containing the options for the operation: (quiet, verbosity, difftype, force) Returns bool True if all object match, False if partial match """ from mysql.utilities.common.dbcompare import get_common_objects from mysql.utilities.common.dbcompare import server_connect force = options.get("force", False) server1, server2 = server_connect(server1_val, server2_val, db1, db2, options) in_both, in_db1, in_db2 = get_common_objects(server1, server2, db1, db2, True, options) in_both.sort() if (len(in_db1) > 0 or len(in_db2) > 0) and not force: return False # Do the diff for the databases themselves result = object_diff(server1, server2, db1, db2, options) if result is not None: success = False if not force: return False # For each that match, do object diff success = True for item in in_both: obj_name1 = quote_with_backticks(item[1][0]) \ if is_quoted_with_backticks(db1) else item[1][0] obj_name2 = quote_with_backticks(item[1][0]) \ if is_quoted_with_backticks(db2) else item[1][0] object1 = "%s.%s" % (db1, obj_name1) object2 = "%s.%s" % (db2, obj_name2) result = object_diff(server1, server2, object1, object2, options) if result is not None: success = False if not force: return False return success
def database_diff(server1_val, server2_val, db1, db2, options): """Find differences among objects from two databases. This method compares the object definitions among two databases. If any differences are found, the differences are printed in the format chosen and the method returns False. A True result is returned only when all object definitions match. The method will stop and return False on the first difference found unless the option force is set to True (default = False). server1_val[in] a dictionary containing connection information for the first server including: (user, password, host, port, socket) server2_val[in] a dictionary containing connection information for the second server including: (user, password, host, port, socket) db1[in] the first database in the compare db2[in] the second database in the compare options[in] a dictionary containing the options for the operation: (quiet, verbosity, difftype, force) Returns bool True if all object match, False if partial match """ from mysql.utilities.common.dbcompare import get_common_objects from mysql.utilities.common.dbcompare import server_connect force = options.get("force", False) server1, server2 = server_connect(server1_val, server2_val, db1, db2, options) in_both, in_db1, in_db2 = get_common_objects(server1, server2, db1, db2, True, options) in_both.sort() if (len(in_db1) > 0 or len(in_db2) > 0) and not force: return False # Do the diff for the databases themselves result = object_diff(server1, server2, db1, db2, options) if result is not None: success = False if not force: return False # For each that match, do object diff success = True for item in in_both: obj_name1 = quote_with_backticks(item[1][0]) \ if is_quoted_with_backticks(db1) else item[1][0] obj_name2 = quote_with_backticks(item[1][0]) \ if is_quoted_with_backticks(db2) else item[1][0] object1 = "%s.%s" % (db1, obj_name1) object2 = "%s.%s" % (db2, obj_name2) result = object_diff(server1, server2, object1, object2, options) if result is not None: success = False if not force: return False return success
def _check_objects(server1, server2, db1, db2, db1_conn, db2_conn, options): """Check number of objects server1[in] first server Server instance server2[in] second server Server instance db1[in] first database db2[in] second database db1_conn[in] first Database instance db2_conn[in] second Database instance options[in] options dictionary Returns list of objects in both databases """ from mysql.utilities.common.dbcompare import get_common_objects from mysql.utilities.common.dbcompare import print_missing_list # Check for same number of objects in_both, in_db1, in_db2 = get_common_objects(server1, server2, db1, db2, False, options) in_both.sort() if not options['no_object_check']: server1_str = "server1." + db1 if server1 == server2: server2_str = "server1." + db2 else: server2_str = "server2." + db2 if len(in_db1) or len(in_db2): if options['run_all_tests']: if len(in_db1) > 0: print_missing_list(in_db1, server1_str, server2_str) print "#" if len(in_db2) > 0: print_missing_list(in_db2, server2_str, server1_str) print "#" else: raise UtilError(_ERROR_OBJECT_LIST.format(db1, db2)) # If in verbose mode, show count of object types. if options['verbosity'] > 1: objects = { 'TABLE' : 0, 'VIEW' : 0, 'TRIGGER' : 0, 'PROCEDURE' : 0, 'FUNCTION' : 0, 'EVENT' : 0, } for item in in_both: obj_type = db1_conn.get_object_type(item[1][0]) objects[obj_type] += 1 print "Looking for object types table, view, trigger, procedure," + \ " function, and event." print "Object types found common to both databases:" for object in objects: print " {0:>12} : {1}".format(object, objects[object]) return in_both
def database_diff(server1_val, server2_val, db1, db2, options): """Find differences among objects from two databases. This method compares the object definitions among two databases. If any differences are found, the differences are printed in the format chosen and the method returns False. A True result is returned only when all object definitions match. The method will stop and return False on the first difference found unless the option force is set to True (default = False). server1_val[in] a dictionary containing connection information for the first server including: (user, password, host, port, socket) server2_val[in] a dictionary containing connection information for the second server including: (user, password, host, port, socket) db1[in] the first database in the compare db2[in] the second database in the compare options[in] a dictionary containing the options for the operation: (quiet, verbosity, difftype, force) Returns bool True if all object match, False if partial match """ force = options.get("force", False) server1, server2 = server_connect(server1_val, server2_val, db1, db2, options) in_both, in_db1, in_db2 = get_common_objects(server1, server2, db1, db2, True, options) in_both.sort() if (len(in_db1) > 0 or len(in_db2) > 0) and not force: return False # Get sql_mode value set on servers server1_sql_mode = server1.select_variable("SQL_MODE") server2_sql_mode = server2.select_variable("SQL_MODE") # Quote database names with backticks. q_db1 = db1 if is_quoted_with_backticks(db1, server1_sql_mode) \ else quote_with_backticks(db1, server1_sql_mode) q_db2 = db2 if is_quoted_with_backticks(db2, server2_sql_mode) \ else quote_with_backticks(db2, server2_sql_mode) # Do the diff for the databases themselves result = object_diff(server1, server2, q_db1, q_db2, options, 'DATABASE') if result is not None: success = False if not force: return False # For each that match, do object diff success = True for item in in_both: # Quote object name with backticks with sql_mode from server1 q_obj_name1 = item[1][0] if \ is_quoted_with_backticks(item[1][0], server1_sql_mode) \ else quote_with_backticks(item[1][0], server1_sql_mode) # Quote object name with backticks with sql_mode from server2 q_obj_name2 = item[1][0] if \ is_quoted_with_backticks(item[1][0], server2_sql_mode) \ else quote_with_backticks(item[1][0], server2_sql_mode) object1 = "{0}.{1}".format(q_db1, q_obj_name1) object2 = "{0}.{1}".format(q_db2, q_obj_name2) result = object_diff(server1, server2, object1, object2, options, item[0]) if result is not None: success = False if not force: return False return success
def object_diff(server1_val, server2_val, object1, object2, options, object_type=None): """diff the definition of two objects Find the difference among two object definitions. server1_val[in] a dictionary containing connection information for the first server including: (user, password, host, port, socket) server2_val[in] a dictionary containing connection information for the second server including: (user, password, host, port, socket) object1[in] the first object in the compare in the form: (db.name) object2[in] the second object in the compare in the form: (db.name) options[in] a dictionary containing the options for the operation: (quiet, verbosity, difftype) object_type[in] type of the objects to be compared (e.g., TABLE, PROCEDURE, etc.). By default None (not defined). Returns None = objects are the same, diff[] = tables differ """ if isinstance(server1_val, dict): # dict or common.server.Server object server1, server2 = server_connect(server1_val, server2_val, object1, object2, options) else: # to save connection server1, server2 = server1_val, server2_val force = options.get("force", None) # compare db's all objects include_create = options.get("include_create", False) # db1.*:db2.* if include_create and object1.endswith('.*') and object2.endswith('.*'): direction = options.get("changes-for", None) reverse = options.get("reverse", False) db_name1, _ = parse_object_name(object1, server1.select_variable("SQL_MODE")) db_name2, _ = parse_object_name(object2, server2.select_variable("SQL_MODE")) in_both, in_db1, in_db2 = get_common_objects(server1, server2, db_name1, db_name2, True, options) # create/alter/drop need all objects compare all_object = set(in_both + in_db1 + in_db2) # call myself recusively to compare all objects for this_obj in all_object: object1 = db_name1 + "." + this_obj[1][0] object2 = db_name2 + "." + this_obj[1][0] # share the same connection in this loop. object_type=None object_diff(server1, server2, object1, object2, options, object_type=None) return [] # Get the object type if unknown considering that objects of different # types can be found with the same name. if not object_type: # Get object types of object1 sql_mode = server1.select_variable("SQL_MODE") db_name, obj_name = parse_object_name(object1, sql_mode) db = Database(server1, db_name, options) obj1_types = db.get_object_type(obj_name) if not obj1_types: if include_create: # if allow generating create object ddl, give 'NULL' object here to tell common.dbcompare.py to handle obj1_types = ['NULL'] else: msg = "The object {0} does not exist.".format(object1) if not force: raise UtilDBError(msg) print("ERROR: {0}".format(msg)) return [] # Get object types of object2 sql_mode = server2.select_variable("SQL_MODE") db_name, obj_name = parse_object_name(object2, sql_mode) db = Database(server2, db_name, options) obj2_types = db.get_object_type(obj_name) if not obj2_types: if include_create: obj2_types = ['NULL'] else: msg = "The object {0} does not exist.".format(object2) if not force: raise UtilDBError(msg) print("ERROR: {0}".format(msg)) return [] # Merge types found for both objects obj_types = set(obj1_types + obj2_types) if obj_types == set(['NULL']): msg = "The object {0} or {1} does not exist in the source side.".format( object1, object2) if not force: raise UtilDBError(msg) print("ERROR: {0}".format(msg)) return [] elif 'NULL' in obj_types: # at least one object exist in db1 and db2 # new db object like TABLE-NULL or NULL-TABLE , 'TABLE' is needed for after use in diff_objects() obj_types = set(['-'.join(obj1_types + obj2_types)]) # Diff objects considering all types found result = [] for obj_type in obj_types: res = diff_objects(server1, server2, object1, object2, options, obj_type) if res: result.append(res) return result if len(result) > 0 else None else: # Diff objects of known type return diff_objects(server1, server2, object1, object2, options, object_type)
def database_diff(server1_val, server2_val, db1, db2, options): """Find differences among objects from two databases. This method compares the object definitions among two databases. If any differences are found, the differences are printed in the format chosen and the method returns False. A True result is returned only when all object definitions match. The method will stop and return False on the first difference found unless the option force is set to True (default = False). server1_val[in] a dictionary containing connection information for the first server including: (user, password, host, port, socket) server2_val[in] a dictionary containing connection information for the second server including: (user, password, host, port, socket) db1[in] the first database in the compare db2[in] the second database in the compare options[in] a dictionary containing the options for the operation: (quiet, verbosity, difftype, force) Returns bool True if all object match, False if partial match """ force = options.get("force", False) server1, server2 = server_connect(server1_val, server2_val, db1, db2, options) in_both, in_db1, in_db2 = get_common_objects(server1, server2, db1, db2, True, options) direction = options.get("changes-for", None) if direction == 'server1' or direction is None: include = [ '{}.{}'.format(db2, tb[1][0]) if tb[0] == 'TABLE' else '' for tb in in_db2 ] server = '{}:{}@{}:{}'.format(server2_val.get('user', 'root'), server2_val.get('passwd', '123456'), server2_val.get('host', 'localhost'), server2_val.get('port', '3306')) db = db2 else: include = [ '{}.{}'.format(db1, tb[1][0]) if tb[0] == 'TABLE' else '' for tb in in_db1 ] server = '{}:{}@{}:{}'.format(server1_val.get('user', 'root'), server1_val.get('passwd', '123456'), server1_val.get('host', 'localhost'), server1_val.get('port', '3306')) db = db1 if include: default = [ '--server={}'.format(server), '--skip-blobs', '--skip-gtid', '--skip-fkey-checks', '--multiprocess=0', '--output-file={}'.format(options.get("output", "")), '--skip=views,triggers,procedures,functions,events,grants,data,create_db' ] for tb in include: default.append('--include={}'.format(tb)) parser = parse_options() if parser: export_db(parser, args=default, values=[db]) in_both.sort() if (len(in_db1) > 0 or len(in_db2) > 0) and not force: return False # Get sql_mode value set on servers server1_sql_mode = server1.select_variable("SQL_MODE") server2_sql_mode = server2.select_variable("SQL_MODE") # Quote database names with backticks. q_db1 = db1 if is_quoted_with_backticks(db1, server1_sql_mode) \ else quote_with_backticks(db1, server1_sql_mode) q_db2 = db2 if is_quoted_with_backticks(db2, server2_sql_mode) \ else quote_with_backticks(db2, server2_sql_mode) # Do the diff for the databases themselves result = object_diff(server1, server2, q_db1, q_db2, options, 'DATABASE') if result is not None: success = False if not force: return False # For each that match, do object diff success = True for item in in_both: # Quote object name with backticks with sql_mode from server1 q_obj_name1 = item[1][0] if \ is_quoted_with_backticks(item[1][0], server1_sql_mode) \ else quote_with_backticks(item[1][0], server1_sql_mode) # Quote object name with backticks with sql_mode from server2 q_obj_name2 = item[1][0] if \ is_quoted_with_backticks(item[1][0], server2_sql_mode) \ else quote_with_backticks(item[1][0], server2_sql_mode) object1 = "{0}.{1}".format(q_db1, q_obj_name1) object2 = "{0}.{1}".format(q_db2, q_obj_name2) result = object_diff(server1, server2, object1, object2, options, item[0]) if result is not None: success = False if not force: return False return success