Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision ae87c27e

Von Moritz Bunkus vor mehr als 9 Jahren hinzugefügt

  • ID ae87c27e82eaa39a78e2380c9c069abe674ced86
  • Vorgänger 21794e2b
  • Nachfolger 96f8eef0

AttrDuration: Implementation für Spalten, die Dauer in Minuten speichern

Unterschiede anzeigen:

SL/DB/Helper/AttrDuration.pm
3 3
use strict;
4 4

  
5 5
use parent qw(Exporter);
6
our @EXPORT = qw(attr_duration);
6
our @EXPORT = qw(attr_duration attr_duration_minutes);
7 7

  
8 8
use Carp;
9 9

  
......
13 13
  _make($package, $_) for @attributes;
14 14
}
15 15

  
16
sub attr_duration_minutes {
17
  my ($package, @attributes) = @_;
18

  
19
  _make_minutes($package, $_) for @attributes;
20
}
21

  
16 22
sub _make {
17 23
  my ($package, $attribute) = @_;
18 24

  
......
75 81
  };
76 82
}
77 83

  
84
sub _make_minutes {
85
  my ($package, $attribute) = @_;
86

  
87
  no strict 'refs';
88

  
89
  *{ $package . '::' . $attribute . '_as_hours' } = sub {
90
    my ($self, $value) = @_;
91

  
92
    $self->$attribute($value * 60 + ($self->$attribute % 60)) if @_ > 1;
93
    return int(($self->$attribute // 0) / 60);
94
  };
95

  
96
  *{ $package . '::' . $attribute . '_as_minutes' } = sub {
97
    my ($self, $value) = @_;
98

  
99
    $self->$attribute(int($self->$attribute) - (int($self->$attribute) % 60) + ($value // 0)) if @_ > 1;
100
    return ($self->$attribute // 0) % 60;
101
  };
102

  
103
  *{ $package . '::' . $attribute . '_as_duration_string' } = sub {
104
    my ($self, $value) = @_;
105

  
106
    if (@_ > 1) {
107
      if (!defined($value) || ($value eq '')) {
108
        $self->$attribute(undef);
109
      } else {
110
        croak $::locale->text("Invalid duration format") if $value !~ m{^(?:(\d*):)?(\d+)$};
111
        $self->$attribute(($1 // 0) * 60 + ($2 // 0));
112
      }
113
    }
114

  
115
    my $as_hours   = "${attribute}_as_hours";
116
    my $as_minutes = "${attribute}_as_minutes";
117
    return defined($self->$attribute) ? sprintf('%d:%02d', $self->$as_hours, $self->$as_minutes) : undef;
118
  };
119
}
120

  
78 121
1;
79 122
__END__
80 123

  
......
92 135
  # In a Rose model:
93 136
  use SL::DB::Helper::AttrDuration;
94 137
  __PACKAGE__->attr_duration('time_estimation');
138
  __PACKAGE__->attr_duration_minutes('hours');
95 139

  
96 140
  # Read access:
97 141
  print "Minutes: " . $obj->time_estimation_as_minutes . " hours: " . $obj->time_estimation_as_hours . "\n";
......
104 148

  
105 149
=head1 OVERVIEW
106 150

  
107
This is a helper for columns that store a duration as a numeric or
108
floating point number representing a number of hours. So the value
109
1.75 would stand for "1 hour, 45 minutes".
151
This is a helper for columns that store a duration in one of two formats:
110 152

  
111
The helper methods created are:
153
=over 2
154

  
155
=item 1. as a numeric or floating point number representing a number
156
of hours
157

  
158
=item 2. as an integer presenting a number of minutes
159

  
160
=back
161

  
162
In the first case the value 1.75 would stand for "1 hour, 45
163
minutes". In the second case the value 105 represents the same
164
duration.
165

  
166
The helper methods created depend on the mode. Calling
167
C<attr_duration> makes the following methods available:
112 168

  
113 169
=over 4
114 170

  
......
160 216

  
161 217
=back
162 218

  
219
With C<attr_duration_minutes> the following methods are available:
220

  
221
=over 4
222

  
223
=item C<attribute_as_minutes [$new_value]>
224

  
225
Access only the minutes. Return values are in the range [0 - 59].
226

  
227
=item C<attribute_as_hours [$new_value]>
228

  
229
Access only the hours. Returns an integer value.
230

  
231
=item C<attribute_as_duration_string [$new_value]>
232

  
233
Access the full value as a formatted string in the form C<h:mm>,
234
e.g. C<1:30> for the value 90 minutes. Parsing such a string is
235
supported, too.
236

  
237
=back
238

  
163 239
=head1 FUNCTIONS
164 240

  
165 241
=over 4
......
169 245
Package method. Call with the names of attributes for which the helper
170 246
methods should be created.
171 247

  
248
=item C<attr_duration_minutes @attributes>
249

  
250
Package method. Call with the names of attributes for which the helper
251
methods should be created.
252

  
172 253
=back
173 254

  
174 255
=head1 BUGS
t/db_helper/attr_duration.t
4 4

  
5 5
__PACKAGE__->meta->setup(
6 6
  table   => 'dummy',
7
  columns => [ dummy => { type => 'numeric', precision => 2, scale => 12 }, ]
7
  columns => [
8
    dummy => { type => 'numeric', precision => 2, scale => 12 },
9
    inty  => { type => 'integer' },
10
  ]
8 11
);
9 12

  
10 13
use SL::DB::Helper::AttrDuration;
11 14

  
12 15
__PACKAGE__->attr_duration('dummy');
16
__PACKAGE__->attr_duration_minutes('inty');
13 17

  
14 18
package main;
15 19

  
16
use Test::More tests => 91;
20
use Test::More; # tests => 91;
17 21
use Test::Exception;
18 22

  
19 23
use strict;
......
31 35
Support::TestSetup::login();
32 36
my $item;
33 37

  
38
### attr_duration
39

  
34 40
# Wenn das Attribut undef ist:
35 41
is(new_item->dummy,                    undef,  'uninitialized: raw');
36 42
is(new_item->dummy_as_hours,           0,      'uninitialized: as_hours');
......
165 171
lives_ok  { new_item()->dummy_as_man_days_unit('hour')    } 'known unit hour';
166 172
lives_ok  { new_item()->dummy_as_man_days_unit('man_day') } 'known unit man_day';
167 173

  
174
### attr_duration_minutes
175

  
176
# Wenn das Attribut undef ist:
177
is(new_item->inty,                    undef,  'uninitialized: raw');
178
is(new_item->inty_as_hours,           0,      'uninitialized: as_hours');
179
is(new_item->inty_as_minutes,         0,      'uninitialized: as_minutes');
180
is(new_item->inty_as_duration_string, undef,  'uninitialized: as_duration_string');
181

  
182
# Auslesen kleiner 60 Minuten:
183
is(new_item(inty => 37)->inty,                    37,     'initialized < 60: raw');
184
is(new_item(inty => 37)->inty_as_hours,           0,      'initialized < 60: as_hours');
185
is(new_item(inty => 37)->inty_as_minutes,         37,     'initialized < 60: as_minutes');
186
is(new_item(inty => 37)->inty_as_duration_string, '0:37', 'initialized < 60: as_duration_string');
187

  
188
# Auslesen größer 60 Minuten:
189
is(new_item(inty => 145)->inty,                    145,    'initialized > 60: raw');
190
is(new_item(inty => 145)->inty_as_hours,           2,      'initialized > 60: as_hours');
191
is(new_item(inty => 145)->inty_as_minutes,         25,     'initialized > 60: as_minutes');
192
is(new_item(inty => 145)->inty_as_duration_string, '2:25', 'initialized > 60: as_duration_string');
193

  
194
$item = new_item(inty => 145); $item->inty_as_duration_string(undef);
195
is($item->inty,                    undef, 'write as_duration_string undef read raw');
196
is($item->inty_as_minutes,         0,     'write as_duration_string undef read as_minutes');
197
is($item->inty_as_hours,           0,     'write as_duration_string undef read as_hours');
198
is($item->inty_as_duration_string, undef, 'write as_duration_string undef read as_duration_string');
199

  
200
$item = new_item(inty => 145); $item->inty_as_duration_string('');
201
is($item->inty,                    undef, 'write as_duration_string "" read raw');
202
is($item->inty_as_minutes,         0,     'write as_duration_string "" read as_minutes');
203
is($item->inty_as_hours,           0,     'write as_duration_string "" read as_hours');
204
is($item->inty_as_duration_string, undef, 'write as_duration_string "" read as_duration_string');
205

  
206
$item = new_item(inty => 145); $item->inty_as_duration_string("3:21");
207
is($item->inty,                    201,    'write as_duration_string 3:21 read raw');
208
is($item->inty_as_minutes,         21,     'write as_duration_string 3:21 read as_minutes');
209
is($item->inty_as_hours,           3,      'write as_duration_string 3:21 read as_hours');
210
is($item->inty_as_duration_string, "3:21", 'write as_duration_string 3:21 read as_duration_string');
211

  
212
$item = new_item(inty => 145); $item->inty_as_duration_string("03:1");
213
is($item->inty,                    181,    'write as_duration_string 03:1 read raw');
214
is($item->inty_as_minutes,         1,      'write as_duration_string 03:1 read as_minutes');
215
is($item->inty_as_hours,           3,      'write as_duration_string 03:1 read as_hours');
216
is($item->inty_as_duration_string, "3:01", 'write as_duration_string 03:1 read as_duration_string');
217

  
218
# Parametervalidierung
219
throws_ok { new_item()->inty_as_duration_string('invalid') } qr/invalid.*format/i, 'invalid duration format';
220

  
168 221
done_testing();

Auch abrufbar als: Unified diff