⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mysql.pm

📁 bugzilla
💻 PM
📖 第 1 页 / 共 3 页
字号:
                exit;            }            else {                print "         Press Enter to continue or Ctrl-C to exit...";                getc;            }        }        print "Converting table storage format to UTF-8. This may take a",              " while.\n";        foreach my $table ($self->bz_table_list_real) {            my $info_sth = $self->prepare("SHOW FULL COLUMNS FROM $table");            $info_sth->execute();            while (my $column = $info_sth->fetchrow_hashref) {                # Our conversion code doesn't work on enum fields, but they                # all go away later in checksetup anyway.                next if $column->{Type} =~ /enum/i;                # If this particular column isn't stored in utf-8                if ($column->{Collation}                    && $column->{Collation} ne 'NULL'                     && $column->{Collation} !~ /utf8/)                 {                    my $name = $column->{Field};                    # The code below doesn't work on a field with a FULLTEXT                    # index. So we drop it. The upgrade code will re-create                    # it later.                    if ($table eq 'longdescs' && $name eq 'thetext') {                        $self->bz_drop_index('longdescs',                                              'longdescs_thetext_idx');                    }                    if ($table eq 'bugs' && $name eq 'short_desc') {                        $self->bz_drop_index('bugs', 'bugs_short_desc_idx');                    }                    print "Converting $table.$name to be stored as UTF-8...\n";                    my $col_info =                         $self->bz_column_info_real($table, $name);                    # CHANGE COLUMN doesn't take PRIMARY KEY                    delete $col_info->{PRIMARYKEY};                    my $sql_def = $self->_bz_schema->get_type_ddl($col_info);                    # We don't want MySQL to actually try to *convert*                    # from our current charset to UTF-8, we just want to                    # transfer the bytes directly. This is how we do that.                    # The CHARACTER SET part of the definition has to come                    # right after the type, which will always come first.                    my ($binary, $utf8) = ($sql_def, $sql_def);                    my $type = $self->_bz_schema->convert_type($col_info->{TYPE});                    $binary =~ s/(\Q$type\E)/$1 CHARACTER SET binary/;                    $utf8   =~ s/(\Q$type\E)/$1 CHARACTER SET utf8/;                    $self->do("ALTER TABLE $table CHANGE COLUMN $name $name                               $binary");                    $self->do("ALTER TABLE $table CHANGE COLUMN $name $name                               $utf8");                }            }            $self->do("ALTER TABLE $table DEFAULT CHARACTER SET utf8");        } # foreach my $table (@tables)    }    # Sometimes you can have a situation where all the tables are utf8,    # but the database isn't. (This tends to happen when you've done    # a mysqldump.) So we have this change outside of the above block,    # so that it just happens silently if no actual *table* conversion    # needs to happen.    if (Bugzilla->params->{'utf8'} && !$self->bz_db_is_utf8) {        $self->_alter_db_charset_to_utf8();    }}# There is a bug in MySQL 4.1.0 - 4.1.15 that makes certain SELECT# statements fail after a SHOW TABLE STATUS: # http://bugs.mysql.com/bug.php?id=13535# This is a workaround, a dummy SELECT to reset the LAST_INSERT_ID.sub _after_table_status {    my ($self, $tables) = @_;    if (grep($_ eq 'bugs', @$tables)        && $self->bz_column_info_real("bugs", "bug_id"))    {        $self->do('SELECT 1 FROM bugs WHERE bug_id IS NULL');    }}sub _alter_db_charset_to_utf8 {    my $self = shift;    my $db_name = Bugzilla->localconfig->{db_name};    $self->do("ALTER DATABASE $db_name CHARACTER SET utf8"); }sub bz_db_is_utf8 {    my $self = shift;    my $db_collation = $self->selectrow_arrayref(        "SHOW VARIABLES LIKE 'character_set_database'");    # First column holds the variable name, second column holds the value.    return $db_collation->[1] =~ /utf8/ ? 1 : 0;}sub bz_enum_initial_values {    my ($self) = @_;    my %enum_values = %{$self->ENUM_DEFAULTS};    # Get a complete description of the 'bugs' table; with DBD::MySQL    # there isn't a column-by-column way of doing this.  Could use    # $dbh->column_info, but it would go slower and we would have to    # use the undocumented mysql_type_name accessor to get the type    # of each row.    my $sth = $self->prepare("DESCRIBE bugs");    $sth->execute();    # Look for the particular columns we are interested in.    while (my ($thiscol, $thistype) = $sth->fetchrow_array()) {        if (defined $enum_values{$thiscol}) {            # this is a column of interest.            my @value_list;            if ($thistype and ($thistype =~ /^enum\(/)) {                # it has an enum type; get the set of values.                while ($thistype =~ /'([^']*)'(.*)/) {                    push(@value_list, $1);                    $thistype = $2;                }            }            if (@value_list) {                # record the enum values found.                $enum_values{$thiscol} = \@value_list;            }        }    }    return \%enum_values;}###################################################################### MySQL-specific Database-Reading Methods#####################################################################=begin private=head1 MYSQL-SPECIFIC DATABASE-READING METHODSThese methods read information about the database from the disk,instead of from a Schema object. They are only reliable for MySQL (see bug 285111 for the reasons why not all DBs use/have functionslike this), but that's OK because we only need them for backwards-compatibility anyway, for versions of Bugzilla before 2.20.=over 4=item C<bz_column_info_real($table, $column)> Description: Returns an abstract column definition for a column              as it actually exists on disk in the database. Params:      $table - The name of the table the column is on.              $column - The name of the column you want info about. Returns:     An abstract column definition.              If the column does not exist, returns undef.=cutsub bz_column_info_real {    my ($self, $table, $column) = @_;    # DBD::mysql does not support selecting a specific column,    # so we have to get all the columns on the table and find     # the one we want.    my $info_sth = $self->column_info(undef, undef, $table, '%');    # Don't use fetchall_hashref as there's a Win32 DBI bug (292821)    my $col_data;    while ($col_data = $info_sth->fetchrow_hashref) {        last if $col_data->{'COLUMN_NAME'} eq $column;    }    if (!defined $col_data) {        return undef;    }    return $self->_bz_schema->column_info_to_column($col_data);}=item C<bz_index_info_real($table, $index)> Description: Returns information about an index on a table in the database. Params:      $table = name of table containing the index              $index = name of an index Returns:     An abstract index definition, always in hashref format.              If the index does not exist, the function returns undef.=cutsub bz_index_info_real {    my ($self, $table, $index) = @_;    my $sth = $self->prepare("SHOW INDEX FROM $table");    $sth->execute;    my @fields;    my $index_type;    # $raw_def will be an arrayref containing the following information:    # 0 = name of the table that the index is on    # 1 = 0 if unique, 1 if not unique    # 2 = name of the index    # 3 = seq_in_index (The order of the current field in the index).    # 4 = Name of ONE column that the index is on    # 5 = 'Collation' of the index. Usually 'A'.    # 6 = Cardinality. Either a number or undef.    # 7 = sub_part. Usually undef. Sometimes 1.    # 8 = "packed". Usually undef.    # 9 = Null. Sometimes undef, sometimes 'YES'.    # 10 = Index_type. The type of the index. Usually either 'BTREE' or 'FULLTEXT'    # 11 = 'Comment.' Usually undef.    while (my $raw_def = $sth->fetchrow_arrayref) {        if ($raw_def->[2] eq $index) {            push(@fields, $raw_def->[4]);            # No index can be both UNIQUE and FULLTEXT, that's why            # this is written this way.            $index_type = $raw_def->[1] ? '' : 'UNIQUE';            $index_type = $raw_def->[10] eq 'FULLTEXT'                ? 'FULLTEXT' : $index_type;        }    }    my $retval;    if (scalar(@fields)) {        $retval = {FIELDS => \@fields, TYPE => $index_type};    }    return $retval;}=item C<bz_index_list_real($table)> Description: Returns a list of index names on a table in               the database, as it actually exists on disk. Params:      $table - The name of the table you want info about. Returns:     An array of index names.=cutsub bz_index_list_real {    my ($self, $table) = @_;    my $sth = $self->prepare("SHOW INDEX FROM $table");    # Column 3 of a SHOW INDEX statement contains the name of the index.    return @{ $self->selectcol_arrayref($sth, {Columns => [3]}) };}###################################################################### MySQL-Specific "Schema Builder"#####################################################################=back=head1 MYSQL-SPECIFIC "SCHEMA BUILDER"MySQL needs to be able to read in a legacy database (from before Schema existed) and create a Schema object out of it. That's whatthis code does.=end private=cut# This sub itself is actually written generically, but the subroutines# that it depends on are database-specific. In particular, the# bz_column_info_real function would be very difficult to create# properly for any other DB besides MySQL.sub _bz_build_schema_from_disk {    my ($self) = @_;    print "Building Schema object from database...\n";    my $schema = $self->_bz_schema->get_empty_schema();    my @tables = $self->bz_table_list_real();    foreach my $table (@tables) {        $schema->add_table($table);        my @columns = $self->bz_table_columns_real($table);        foreach my $column (@columns) {            my $type_info = $self->bz_column_info_real($table, $column);            $schema->set_column($table, $column, $type_info);        }        my @indexes = $self->bz_index_list_real($table);        foreach my $index (@indexes) {            unless ($index eq 'PRIMARY') {                my $index_info = $self->bz_index_info_real($table, $index);                ($index_info = $index_info->{FIELDS})                     if (!$index_info->{TYPE});                $schema->set_index($table, $index, $index_info);            }        }    }    return $schema;}1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -