Ejemplo n.º 1
0
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)
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
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    
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
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)
Ejemplo n.º 7
0
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