Version.pm 6.51 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# Contributor(s): Tiago R. Mello <timello@async.com.br>
16
#                 Max Kanat-Alexander <mkanat@bugzilla.org>
17 18 19 20 21

use strict;

package Bugzilla::Version;

22 23
use base qw(Bugzilla::Object);

24
use Bugzilla::Install::Util qw(vers_cmp);
25 26 27 28 29 30 31 32 33
use Bugzilla::Util;
use Bugzilla::Error;

################################
#####   Initialization     #####
################################

use constant DEFAULT_VERSION => 'unspecified';

34 35
use constant DB_TABLE => 'versions';

36
use constant DB_COLUMNS => qw(
37 38 39
    id
    value
    product_id
40 41
);

42
use constant NAME_FIELD => 'value';
43 44 45
# This is "id" because it has to be filled in and id is probably the fastest.
# We do a custom sort in new_from_list below.
use constant LIST_ORDER => 'id';
46 47

sub new {
48 49
    my $class = shift;
    my $param = shift;
50 51
    my $dbh = Bugzilla->dbh;

52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
    my $product;
    if (ref $param) {
        $product = $param->{product};
        my $name = $param->{name};
        if (!defined $product) {
            ThrowCodeError('bad_arg',
                {argument => 'product',
                 function => "${class}::new"});
        }
        if (!defined $name) {
            ThrowCodeError('bad_arg',
                {argument => 'name',
                 function => "${class}::new"});
        }

        my $condition = 'product_id = ? AND value = ?';
        my @values = ($product->id, $name);
        $param = { condition => $condition, values => \@values };
70 71
    }

72 73
    unshift @_, $param;
    return $class->SUPER::new(@_);
74 75
}

76 77 78 79 80 81
sub new_from_list {
    my $self = shift;
    my $list = $self->SUPER::new_from_list(@_);
    return [sort { vers_cmp(lc($a->name), lc($b->name)) } @$list];
}

82 83 84 85 86 87 88 89 90 91 92 93 94
sub bug_count {
    my $self = shift;
    my $dbh = Bugzilla->dbh;

    if (!defined $self->{'bug_count'}) {
        $self->{'bug_count'} = $dbh->selectrow_array(qq{
            SELECT COUNT(*) FROM bugs
            WHERE product_id = ? AND version = ?}, undef,
            ($self->product_id, $self->name)) || 0;
    }
    return $self->{'bug_count'};
}

95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
sub remove_from_db {
    my $self = shift;
    my $dbh = Bugzilla->dbh;

    # The version cannot be removed if there are bugs
    # associated with it.
    if ($self->bug_count) {
        ThrowUserError("version_has_bugs", { nb => $self->bug_count });
    }

    $dbh->do(q{DELETE FROM versions WHERE product_id = ? AND value = ?},
              undef, ($self->product_id, $self->name));
}

sub update {
    my $self = shift;
    my ($name, $product) = @_;
    my $dbh = Bugzilla->dbh;

    $name || ThrowUserError('version_not_specified');

    # Remove unprintable characters
    $name = clean_text($name);

    return 0 if ($name eq $self->name);
120
    my $version = new Bugzilla::Version({ product => $product, name => $name });
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141

    if ($version) {
        ThrowUserError('version_already_exists',
                       {'name' => $version->name,
                        'product' => $product->name});
    }

    trick_taint($name);
    $dbh->do("UPDATE bugs SET version = ?
              WHERE version = ? AND product_id = ?", undef,
              ($name, $self->name, $self->product_id));

    $dbh->do("UPDATE versions SET value = ?
              WHERE product_id = ? AND value = ?", undef,
              ($name, $self->product_id, $self->name));

    $self->{'value'} = $name;

    return 1;
}

142 143 144 145
###############################
#####     Accessors        ####
###############################

146
sub name       { return $_[0]->{'value'};      }
147 148 149 150 151 152
sub product_id { return $_[0]->{'product_id'}; }

###############################
#####     Subroutines       ###
###############################

153 154 155 156 157 158 159 160 161 162
sub create {
    my ($name, $product) = @_;
    my $dbh = Bugzilla->dbh;

    # Cleanups and validity checks
    $name || ThrowUserError('version_blank_name');

    # Remove unprintable characters
    $name = clean_text($name);

163
    my $version = new Bugzilla::Version({ product => $product, name => $name });
164 165 166 167 168 169 170 171 172 173 174
    if ($version) {
        ThrowUserError('version_already_exists',
                       {'name' => $version->name,
                        'product' => $product->name});
    }

    # Add the new version
    trick_taint($name);
    $dbh->do(q{INSERT INTO versions (value, product_id)
               VALUES (?, ?)}, undef, ($name, $product->id));

175
    return new Bugzilla::Version($dbh->bz_last_key('versions', 'id'));
176 177
}

178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
1;

__END__

=head1 NAME

Bugzilla::Version - Bugzilla product version class.

=head1 SYNOPSIS

    use Bugzilla::Version;

    my $version = new Bugzilla::Version(1, 'version_value');

    my $product_id = $version->product_id;
    my $value = $version->value;

195 196 197 198
    $version->remove_from_db;

    my $updated = $version->update($version_name, $product);

199 200
    my $version = $hash_ref->{'version_value'};

201 202
    my $version = Bugzilla::Version::create($version_name, $product);

203 204 205 206 207 208 209 210 211 212 213 214 215
=head1 DESCRIPTION

Version.pm represents a Product Version object.

=head1 METHODS

=over

=item C<new($product_id, $value)>

 Description: The constructor is used to load an existing version
              by passing a product id and a version value.

216
 Params:      $product_id - Integer with a product id.
217 218 219 220
              $value - String with a version value.

 Returns:     A Bugzilla::Version object.

221 222 223 224 225 226 227 228
=item C<bug_count()>

 Description: Returns the total of bugs that belong to the version.

 Params:      none.

 Returns:     Integer with the number of bugs.

229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
=item C<remove_from_db()>

 Description: Removes the version from the database.

 Params:      none.

 Retruns:     none.

=item C<update($name, $product)>

 Description: Update the value of the version.

 Params:      $name - String with the new version value.
              $product - Bugzilla::Product object the version belongs to.

 Returns:     An integer - 1 if the version has been updated, else 0.

246 247 248 249 250 251
=back

=head1 SUBROUTINES

=over

252 253 254 255 256 257 258 259 260
=item C<create($version_name, $product)>

 Description: Create a new version for the given product.

 Params:      $version_name - String with a version value.
              $product - A Bugzilla::Product object.

 Returns:     A Bugzilla::Version object.

261 262 263
=back

=cut