📄 db.pm
字号:
EOT $comments->close; rename("$datadir/comments", "$datadir/comments.bak") || warn "Failed to rename: $!"; }}sub _use_ids_for_products_and_components { my $dbh = Bugzilla->dbh; # 2002-08-12 jake@bugzilla.org/bbaetz@student.usyd.edu.au - bug 43600 # Use integer IDs for products and components. if ($dbh->bz_column_info("products", "product")) { print "Updating database to use product IDs.\n"; # First, we need to remove possible NULL entries # NULLs may exist, but won't have been used, since all the uses of them # are in NOT NULL fields in other tables $dbh->do("DELETE FROM products WHERE product IS NULL"); $dbh->do("DELETE FROM components WHERE value IS NULL"); $dbh->bz_add_column("products", "id", {TYPE => 'SMALLSERIAL', NOTNULL => 1, PRIMARYKEY => 1}); $dbh->bz_add_column("components", "product_id", {TYPE => 'INT2', NOTNULL => 1}, 0); $dbh->bz_add_column("versions", "product_id", {TYPE => 'INT2', NOTNULL => 1}, 0); $dbh->bz_add_column("milestones", "product_id", {TYPE => 'INT2', NOTNULL => 1}, 0); $dbh->bz_add_column("bugs", "product_id", {TYPE => 'INT2', NOTNULL => 1}, 0); # The attachstatusdefs table was added in version 2.15, but # removed again in early 2.17. If it exists now, we still need # to perform this change with product_id because the code later on # which converts the attachment statuses to flags depends on it. # But we need to avoid this if the user is upgrading from 2.14 # or earlier (because it won't be there to convert). if ($dbh->bz_table_info("attachstatusdefs")) { $dbh->bz_add_column("attachstatusdefs", "product_id", {TYPE => 'INT2', NOTNULL => 1}, 0); } my %products; my $sth = $dbh->prepare("SELECT id, product FROM products"); $sth->execute; while (my ($product_id, $product) = $sth->fetchrow_array()) { if (exists $products{$product}) { print "Ignoring duplicate product $product\n"; $dbh->do("DELETE FROM products WHERE id = $product_id"); next; } $products{$product} = 1; $dbh->do("UPDATE components SET product_id = $product_id " . "WHERE program = " . $dbh->quote($product)); $dbh->do("UPDATE versions SET product_id = $product_id " . "WHERE program = " . $dbh->quote($product)); $dbh->do("UPDATE milestones SET product_id = $product_id " . "WHERE product = " . $dbh->quote($product)); $dbh->do("UPDATE bugs SET product_id = $product_id " . "WHERE product = " . $dbh->quote($product)); $dbh->do("UPDATE attachstatusdefs SET product_id = $product_id " . "WHERE product = " . $dbh->quote($product)) if $dbh->bz_table_info("attachstatusdefs"); } print "Updating the database to use component IDs.\n"; $dbh->bz_add_column("components", "id", {TYPE => 'SMALLSERIAL', NOTNULL => 1, PRIMARYKEY => 1}); $dbh->bz_add_column("bugs", "component_id", {TYPE => 'INT2', NOTNULL => 1}, 0); my %components; $sth = $dbh->prepare("SELECT id, value, product_id FROM components"); $sth->execute; while (my ($component_id, $component, $product_id) = $sth->fetchrow_array()) { if (exists $components{$component}) { if (exists $components{$component}{$product_id}) { print "Ignoring duplicate component $component for", " product $product_id\n"; $dbh->do("DELETE FROM components WHERE id = $component_id"); next; } } else { $components{$component} = {}; } $components{$component}{$product_id} = 1; $dbh->do("UPDATE bugs SET component_id = $component_id " . "WHERE component = " . $dbh->quote($component) . " AND product_id = $product_id"); } print "Fixing Indexes and Uniqueness.\n"; $dbh->bz_drop_index('milestones', 'milestones_product_idx'); $dbh->bz_add_index('milestones', 'milestones_product_id_idx', {TYPE => 'UNIQUE', FIELDS => [qw(product_id value)]}); $dbh->bz_drop_index('bugs', 'bugs_product_idx'); $dbh->bz_add_index('bugs', 'bugs_product_id_idx', [qw(product_id)]); $dbh->bz_drop_index('bugs', 'bugs_component_idx'); $dbh->bz_add_index('bugs', 'bugs_component_id_idx', [qw(component_id)]); print "Removing, renaming, and retyping old product and", " component fields.\n"; $dbh->bz_drop_column("components", "program"); $dbh->bz_drop_column("versions", "program"); $dbh->bz_drop_column("milestones", "product"); $dbh->bz_drop_column("bugs", "product"); $dbh->bz_drop_column("bugs", "component"); $dbh->bz_drop_column("attachstatusdefs", "product") if $dbh->bz_table_info("attachstatusdefs"); $dbh->bz_rename_column("products", "product", "name"); $dbh->bz_alter_column("products", "name", {TYPE => 'varchar(64)', NOTNULL => 1}); $dbh->bz_rename_column("components", "value", "name"); $dbh->bz_alter_column("components", "name", {TYPE => 'varchar(64)', NOTNULL => 1}); print "Adding indexes for products and components tables.\n"; $dbh->bz_add_index('products', 'products_name_idx', {TYPE => 'UNIQUE', FIELDS => [qw(name)]}); $dbh->bz_add_index('components', 'components_product_id_idx', {TYPE => 'UNIQUE', FIELDS => [qw(product_id name)]}); $dbh->bz_add_index('components', 'components_name_idx', [qw(name)]); }}# Helper for the below function.## _list_bits(arg) returns a list of UNKNOWN<n> if the group# has been deleted for all bits set in arg. When the activity# records are converted from groupset numbers to lists of# group names, _list_bits is used to fill in a list of references# to groupset bits for groups that no longer exist.sub _list_bits { my ($num) = @_; my $dbh = Bugzilla->dbh; my @res; my $curr = 1; while (1) { # Convert a big integer to a list of bits my $sth = $dbh->prepare("SELECT ($num & ~$curr) > 0, ($num & $curr), ($num & ~$curr), $curr << 1"); $sth->execute; my ($more, $thisbit, $remain, $nval) = $sth->fetchrow_array; push @res,"UNKNOWN<$curr>" if ($thisbit); $curr = $nval; $num = $remain; last if !$more; } return @res;}sub _convert_groups_system_from_groupset { my $dbh = Bugzilla->dbh; # 2002-09-22 - bugreport@peshkin.net - bug 157756 # # If the whole groups system is new, but the installation isn't, # convert all the old groupset groups, etc... # # This requires: # 1) define groups ids in group table # 2) populate user_group_map with grants from old groupsets # and blessgroupsets # 3) populate bug_group_map with data converted from old bug groupsets # 4) convert activity logs to use group names instead of numbers # 5) identify the admin from the old all-ones groupset # The groups system needs to be converted if groupset exists if ($dbh->bz_column_info("profiles", "groupset")) { # Some mysql versions will promote any unique key to primary key # so all unique keys are removed first and then added back in $dbh->bz_drop_index('groups', 'groups_bit_idx'); $dbh->bz_drop_index('groups', 'groups_name_idx'); my @primary_key = $dbh->primary_key(undef, undef, 'groups'); if (@primary_key) { $dbh->do("ALTER TABLE groups DROP PRIMARY KEY"); } $dbh->bz_add_column('groups', 'id', {TYPE => 'MEDIUMSERIAL', NOTNULL => 1, PRIMARYKEY => 1}); $dbh->bz_add_index('groups', 'groups_name_idx', {TYPE => 'UNIQUE', FIELDS => [qw(name)]}); # Convert all existing groupset records to map entries before removing # groupset fields or removing "bit" from groups. my $sth = $dbh->prepare("SELECT bit, id FROM groups WHERE bit > 0"); $sth->execute(); while (my ($bit, $gid) = $sth->fetchrow_array) { # Create user_group_map membership grants for old groupsets. # Get each user with the old groupset bit set my $sth2 = $dbh->prepare("SELECT userid FROM profiles WHERE (groupset & $bit) != 0"); $sth2->execute(); while (my ($uid) = $sth2->fetchrow_array) { # Check to see if the user is already a member of the group # and, if not, insert a new record. my $query = "SELECT user_id FROM user_group_map WHERE group_id = $gid AND user_id = $uid AND isbless = 0"; my $sth3 = $dbh->prepare($query); $sth3->execute(); if ( !$sth3->fetchrow_array() ) { $dbh->do("INSERT INTO user_group_map (user_id, group_id, isbless, grant_type) VALUES ($uid, $gid, 0, " . GRANT_DIRECT . ")"); } } # Create user can bless group grants for old groupsets, but only # if we're upgrading from a Bugzilla that had blessing. if($dbh->bz_column_info('profiles', 'blessgroupset')) { # Get each user with the old blessgroupset bit set $sth2 = $dbh->prepare("SELECT userid FROM profiles WHERE (blessgroupset & $bit) != 0"); $sth2->execute(); while (my ($uid) = $sth2->fetchrow_array) { $dbh->do("INSERT INTO user_group_map (user_id, group_id, isbless, grant_type) VALUES ($uid, $gid, 1, " . GRANT_DIRECT . ")"); } } # Create bug_group_map records for old groupsets. # Get each bug with the old group bit set. $sth2 = $dbh->prepare("SELECT bug_id FROM bugs WHERE (groupset & $bit) != 0"); $sth2->execute(); while (my ($bug_id) = $sth2->fetchrow_array) { # Insert the bug, group pair into the bug_group_map. $dbh->do("INSERT INTO bug_group_map (bug_id, group_id) VALUES ($bug_id, $gid)"); } } # Replace old activity log groupset records with lists of names # of groups. $sth = $dbh->prepare("SELECT id FROM fielddefs WHERE name = " . $dbh->quote('bug_group')); $sth->execute(); my ($bgfid) = $sth->fetchrow_array; # Get the field id for the old groupset field $sth = $dbh->prepare("SELECT id FROM fielddefs WHERE name = " . $dbh->quote('groupset')); $sth->execute(); my ($gsid) = $sth->fetchrow_array; # Get all bugs_activity records from groupset changes if ($gsid) { $sth = $dbh->prepare("SELECT bug_id, bug_when, who, added, removed FROM bugs_activity WHERE fieldid = $gsid"); $sth->execute(); while (my ($bug_id, $bug_when, $who, $added, $removed) = $sth->fetchrow_array) { $added ||= 0; $removed ||= 0; # Get names of groups added. my $sth2 = $dbh->prepare("SELECT name FROM groups WHERE (bit & $added) != 0 AND (bit & $removed) = 0"); $sth2->execute(); my @logadd; while (my ($n) = $sth2->fetchrow_array) { push @logadd, $n; } # Get names of groups removed. $sth2 = $dbh->prepare("SELECT name FROM groups WHERE (bit & $removed) != 0 AND (bit & $added) = 0"); $sth2->execute(); my @logrem; while (my ($n) = $sth2->fetchrow_array) { push @logrem, $n; } # Get list of group bits added that correspond to # missing groups. $sth2 = $dbh->prepare("SELECT ($added & ~BIT_OR(bit)) FROM groups"); $sth2->execute(); my ($miss) = $sth2->fetchrow_array; if ($miss) { push @logadd, _list_bits($miss); print "\nWARNING - GROUPSET ACTIVITY ON BUG $bug_id", " CONTAINS DELETED GROUPS\n"; } # Get list of group bits deleted that correspond to # missing groups. $sth2 = $dbh->prepare("SELECT ($removed & ~BIT_OR(bit)) FROM groups"); $sth2->execute(); ($miss) = $sth2->fetchrow_array; if ($miss) { push @logrem, _list_bits($miss); print "\nWARNING - GROUPSET ACTIVITY ON BUG $bug_id", " CONTAINS DELETED GROUPS\n"; } my $logr = ""; my $loga = ""; $logr = join(", ", @logrem) . '?' if @logrem; $l
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -