'Manipulate database object privileges.
:param obj_type: Type of database object to grant/revoke
privileges for.
:param privs: Either a list of privileges to grant/revoke
or None if type is "group".
:param objs: List of database objects to grant/revoke
privileges for.
:param roles: Either a list of role names or "PUBLIC"
for the implicitly defined "PUBLIC" group
:param state: "present" to grant privileges, "absent" to revoke.
:param grant_option: Only for state "present": If True, set
grant/admin option. If False, revoke it.
If None, don\'t change grant option.
:param schema_qualifier: Some object types ("TABLE", "SEQUENCE",
"FUNCTION") must be qualified by schema.
Ignored for other Types.'

def manipulate_privs(self, obj_type, privs, objs, roles, state, grant_option, schema_qualifier=None):

    if (obj_type == 'table'):
        get_status = partial(self.get_table_acls, schema_qualifier)
    elif (obj_type == 'sequence'):
        get_status = partial(self.get_sequence_acls, schema_qualifier)
    elif (obj_type == 'function'):
        get_status = partial(self.get_function_acls, schema_qualifier)
    elif (obj_type == 'schema'):
        get_status = self.get_schema_acls
    elif (obj_type == 'language'):
        get_status = self.get_language_acls
    elif (obj_type == 'tablespace'):
        get_status = self.get_tablespace_acls
    elif (obj_type == 'database'):
        get_status = self.get_database_acls
    elif (obj_type == 'group'):
        get_status = self.get_group_memberships
    else:
        raise Error(('Unsupported    database    object    type    "%s".' % obj_type))
    if (not objs):
        return False
    if (obj_type == 'function'):
        obj_ids = []
        for obj in objs:
            try:
                (f, args) = obj.split('(', 1)
            except:
                raise Error(('Illegal    function    signature:    "%s".' % obj))
            obj_ids.append(('"%s"."%s"(%s' % (schema_qualifier, f, args)))
    elif (obj_type in ['table', 'sequence']):
        obj_ids = [('"%s"."%s"' % (schema_qualifier, o)) for o in objs]
    else:
        obj_ids = [('"%s"' % o) for o in objs]
    if (obj_type == 'group'):
        set_what = ','.join((pg_quote_identifier(i, 'role') for i in obj_ids))
    else:
        if (obj_type != 'function'):
            obj_ids = [pg_quote_identifier(i, 'table') for i in obj_ids]
        set_what = ('%s    ON    %s    %s' % (','.join(privs), obj_type, ','.join(obj_ids)))
    if (roles == 'PUBLIC'):
        for_whom = 'PUBLIC'
    else:
        for_whom = ','.join((pg_quote_identifier(r, 'role') for r in roles))
    status_before = get_status(objs)
    if (state == 'present'):
        if grant_option:
            if (obj_type == 'group'):
                query = 'GRANT    %s    TO    %s    WITH    ADMIN    OPTION'
            else:
                query = 'GRANT    %s    TO    %s    WITH    GRANT    OPTION'
        else:
            query = 'GRANT    %s    TO    %s'
        self.cursor.execute((query % (set_what, for_whom)))
        if (grant_option == False):
            if (obj_type == 'group'):
                query = 'REVOKE    ADMIN    OPTION    FOR    %s    FROM    %s'
            else:
                query = 'REVOKE    GRANT    OPTION    FOR    %s    FROM    %s'
            self.cursor.execute((query % (set_what, for_whom)))
    else:
        query = 'REVOKE    %s    FROM    %s'
        self.cursor.execute((query % (set_what, for_whom)))
    status_after = get_status(objs)
    return (status_before != status_after)
