Commit 946aa227 authored by mkanat%kerio.com's avatar mkanat%kerio.com

Bug 286689: Cross-DB bz_add_index and bz_drop_index (Part of Bug 285111)

Patch By Max Kanat-Alexander <mkanat@kerio.com> r=Tomas.Kopal, a=justdave
parent 7ee3130c
...@@ -392,6 +392,23 @@ sub bz_add_field ($$$) { ...@@ -392,6 +392,23 @@ sub bz_add_field ($$$) {
ADD COLUMN $field $definition"); ADD COLUMN $field $definition");
} }
sub bz_add_index {
my ($self, $table, $name, $definition) = @_;
my $index_exists = $self->bz_index_info($table, $name);
if (!$index_exists) {
my @statements = $self->_bz_real_schema->get_add_index_ddl(
$table, $name, $definition);
print "Adding new index '$name' to the $table table ...\n";
foreach my $sql (@statements) {
$self->do($sql);
}
$self->_bz_real_schema->set_index($table, $name, $definition);
$self->_bz_store_real_schema;
}
}
# XXX - Need to make this cross-db compatible # XXX - Need to make this cross-db compatible
# XXX - This shouldn't print stuff to stdout # XXX - This shouldn't print stuff to stdout
sub bz_change_field_type ($$$) { sub bz_change_field_type ($$$) {
...@@ -430,6 +447,23 @@ sub bz_drop_field ($$) { ...@@ -430,6 +447,23 @@ sub bz_drop_field ($$) {
DROP COLUMN $field"); DROP COLUMN $field");
} }
sub bz_drop_index {
my ($self, $table, $name) = @_;
my $index_exists = $self->bz_index_info($table, $name);
if ($index_exists) {
my @statements = $self->_bz_real_schema->get_drop_index_ddl(
$table, $name);
print "Removing index '$name' from the $table table...\n";
foreach my $sql (@statements) {
$self->do($sql);
}
$self->_bz_real_schema->delete_index($table, $name);
$self->_bz_store_real_schema;
}
}
# XXX - Needs to be made cross-db compatible # XXX - Needs to be made cross-db compatible
sub bz_drop_table_indexes ($) { sub bz_drop_table_indexes ($) {
my ($self, $table) = @_; my ($self, $table) = @_;
...@@ -778,6 +812,8 @@ Bugzilla::DB - Database access routines, using L<DBI> ...@@ -778,6 +812,8 @@ Bugzilla::DB - Database access routines, using L<DBI>
# Schema Modification # Schema Modification
$dbh->bz_add_column($table, $name, \%definition); $dbh->bz_add_column($table, $name, \%definition);
$dbh->bz_add_index($table, $name, $definition);
$dbh->bz_drop_index($table, $name);
# Schema Modification (DEPRECATED) # Schema Modification (DEPRECATED)
$dbh->bz_add_field($table, $column, $definition); $dbh->bz_add_field($table, $column, $definition);
...@@ -1097,6 +1133,26 @@ C<Bugzilla::DB::Schema::ABSTRACT_SCHEMA>. ...@@ -1097,6 +1133,26 @@ C<Bugzilla::DB::Schema::ABSTRACT_SCHEMA>.
\%definition = Abstract column definition for the new column \%definition = Abstract column definition for the new column
Returns: nothing Returns: nothing
=item C<bz_add_index($table, $name, $definition)>
Description: Adds a new index to a table in the database. Prints
out a brief statement that it did so, to stdout.
If the index already exists, we will do nothing.
Params: $table - The table the new index is on.
$name - A name for the new index.
$definition - An abstract index definition.
Either a hashref or an arrayref.
Returns: nothing
=item C<bz_drop_index($table, $name)>
Description: Removes an index from the database. Prints out a brief
statement that it did so, to stdout. If the index
doesn't exist, we do nothing.
Params: $table - The table that the index is on.
$name - The name of the index that you want to drop.
Returns: nothing
=back =back
......
...@@ -1276,18 +1276,8 @@ sub get_table_ddl { ...@@ -1276,18 +1276,8 @@ sub get_table_ddl {
while (@indexes) { while (@indexes) {
my $index_name = shift(@indexes); my $index_name = shift(@indexes);
my $index_info = shift(@indexes); my $index_info = shift(@indexes);
my($index_fields,$index_type); my $index_sql = $self->get_add_index_ddl($table, $index_name,
if (ref($index_info) eq 'HASH') { $index_info);
$index_fields = $index_info->{FIELDS};
$index_type = $index_info->{TYPE};
} else {
$index_fields = $index_info;
$index_type = '';
}
my $index_sql = $self->_get_create_index_ddl($table,
$index_name,
$index_fields,
$index_type);
push(@ddl, $index_sql) if $index_sql; push(@ddl, $index_sql) if $index_sql;
} }
...@@ -1378,6 +1368,40 @@ sub get_add_column_ddl { ...@@ -1378,6 +1368,40 @@ sub get_add_column_ddl {
return ($statement); return ($statement);
} }
sub get_add_index_ddl {
=item C<get_add_index_ddl>
Description: Gets SQL for creating an index.
NOTE: Subclasses should not override this function. Instead,
if they need to specify a custom CREATE INDEX statement,
they should override C<_get_create_index_ddl>
Params: $table - The name of the table the index will be on.
$name - The name of the new index.
$definition - An index definition. Either a hashref
with FIELDS and TYPE or an arrayref
containing a list of columns.
Returns: An array of SQL statements that will create the
requested index.
=cut
my ($self, $table, $name, $definition) = @_;
my ($index_fields, $index_type);
# Index defs can be arrays or hashes
if (ref($definition) eq 'HASH') {
$index_fields = $definition->{FIELDS};
$index_type = $definition->{TYPE};
} else {
$index_fields = $definition;
$index_type = '';
}
return $self->_get_create_index_ddl($table, $name, $index_fields,
$index_type);
}
sub get_alter_column_ddl { sub get_alter_column_ddl {
=item C<get_alter_ddl($table, $column, \%definition)> =item C<get_alter_ddl($table, $column, \%definition)>
...@@ -1468,6 +1492,23 @@ sub get_alter_column_ddl { ...@@ -1468,6 +1492,23 @@ sub get_alter_column_ddl {
return @statements; return @statements;
} }
sub get_drop_index_ddl {
=item C<get_drop_index_ddl($table, $name)>
Description: Generates SQL statements to drop an index.
Params: $table - The table the index is on.
$name - The name of the index being dropped.
Returns: An array of SQL statements.
=cut
my ($self, $table, $name) = @_;
# Although ANSI SQL-92 doesn't specify a method of dropping an index,
# many DBs support this syntax.
return ("DROP INDEX $name");
}
sub get_column_abstract { sub get_column_abstract {
=item C<get_column_abstract($table, $column)> =item C<get_column_abstract($table, $column)>
...@@ -1513,7 +1554,7 @@ sub get_index_abstract { ...@@ -1513,7 +1554,7 @@ sub get_index_abstract {
# table doesn't exist. # table doesn't exist.
if (exists $self->{abstract_schema}->{$table}) { if (exists $self->{abstract_schema}->{$table}) {
my %indexes = (@{ $self->{abstract_schema}{$table}{INDEXES} }); my %indexes = (@{ $self->{abstract_schema}{$table}{INDEXES} });
return dclone($indexes{$index}); return $indexes{$index};
} }
return undef; return undef;
} }
...@@ -1538,23 +1579,81 @@ sub set_column { ...@@ -1538,23 +1579,81 @@ sub set_column {
my ($self, $table, $column, $new_def) = @_; my ($self, $table, $column, $new_def) = @_;
my $abstract_fields = \@{ $self->{abstract_schema}{$table}{FIELDS} }; my $fields = \@{ $self->{abstract_schema}{$table}{FIELDS} };
$self->_set_object($table, $column, $new_def, $fields);
}
sub set_index {
my $field_position = lsearch($abstract_fields, $column) + 1; =item C<set_index($table, $name, $definition)>
# If the column doesn't exist, then add it.
if (!$field_position) { Description: Changes the definition of an index in this Schema object.
push(@$abstract_fields, $column); If the index doesn't exist, it will be added.
push(@$abstract_fields, $new_def); The table that you specify must already exist in the Schema.
NOTE: This does not affect the database on the disk.
Use the C<Bugzilla::DB> "Schema Modification Methods"
if you want to do that.
Params: $table - The table the index is on.
$name - The name of the index.
$definition - A hashref or an arrayref. An index
definition in C<ABSTRACT_SCHEMA> format.
Returns: nothing
=cut
my ($self, $table, $name, $definition) = @_;
my $indexes = \@{ $self->{abstract_schema}{$table}{INDEXES} };
$self->_set_object($table, $name, $definition, $indexes);
}
# A private helper for set_index and set_column.
# This does the actual "work" of those two functions.
# $array_to_change is an arrayref.
sub _set_object {
my ($self, $table, $name, $definition, $array_to_change) = @_;
my $obj_position = lsearch($array_to_change, $name) + 1;
# If the object doesn't exist, then add it.
if (!$obj_position) {
push(@$array_to_change, $name);
push(@$array_to_change, $definition);
} }
# We're modifying an existing column. # We're modifying an existing object in the Schema.
else { else {
splice(@$abstract_fields, $field_position, 1, $new_def); splice(@$array_to_change, $obj_position, 1, $definition);
} }
$self->{schema} = dclone($self->{abstract_schema}); $self->{schema} = dclone($self->{abstract_schema});
$self->_adjust_schema(); $self->_adjust_schema();
} }
=item C<delete_index($table, $name)>
Description: Removes an index definition from this Schema object.
If the index doesn't exist, we will fail.
The table that you specify must exist in the Schema.
NOTE: This does not affect the database on the disk.
Use the C<Bugzilla::DB> "Schema Modification Methods"
if you want to do that.
Params: $table - The table the index is on.
$name - The name of the index that we're removing.
Returns: nothing
=cut
sub delete_index {
my ($self, $table, $name) = @_;
my $indexes = $self->{abstract_schema}{$table}{INDEXES};
my $name_position = lsearch($indexes, $name);
die "Attempted to delete nonexistent index $name on the $table table"
if $name_position == -1;
# Delete the key/value pair from the array.
splice(@$indexes, $name_position, 2);
$self->{schema} = dclone($self->{abstract_schema});
$self->_adjust_schema();
}
sub columns_equal { sub columns_equal {
=item C<columns_equal($col_one, $col_two)> =item C<columns_equal($col_one, $col_two)>
......
...@@ -108,4 +108,9 @@ sub get_alter_column_ddl { ...@@ -108,4 +108,9 @@ sub get_alter_column_ddl {
return (("ALTER TABLE $table CHANGE COLUMN $column $column $new_ddl")); return (("ALTER TABLE $table CHANGE COLUMN $column $column $new_ddl"));
} }
sub get_drop_index_ddl {
my ($self, $table, $name) = @_;
return ("DROP INDEX $name ON $table");
}
1; 1;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment