| | 48 | |
| | 49 | package Test::GroupBy; |
| | 50 | use base qw( Test::Class MT::Test ); |
| | 51 | use Test::More; |
| | 52 | use POSIX qw(strftime); |
| | 53 | |
| | 54 | sub reset_db : Test(setup) { |
| | 55 | my $self = shift; |
| | 56 | $self->clean_db(); |
| | 57 | |
| | 58 | my @obj_data = ( |
| | 59 | { class => 'Foo', |
| | 60 | id => 1, |
| | 61 | name => 'foo', |
| | 62 | text => 'bar', |
| | 63 | status => 2, }, |
| | 64 | { class => 'Foo', |
| | 65 | id => 2, |
| | 66 | name => 'baz', |
| | 67 | text => 'quux', |
| | 68 | status => 1, }, |
| | 69 | { class => 'Bar', |
| | 70 | id => 1, |
| | 71 | foo_id => 2, |
| | 72 | name => 'bar0', |
| | 73 | status => 0, }, |
| | 74 | { class => 'Bar', |
| | 75 | id => 2, |
| | 76 | foo_id => 2, |
| | 77 | name => 'bar1', |
| | 78 | status => 1, }, |
| | 79 | { class => 'Bar', |
| | 80 | id => 3, |
| | 81 | foo_id => 1, |
| | 82 | name => 'bar2', |
| | 83 | status => 0, }, |
| | 84 | ); |
| | 85 | |
| | 86 | for my $data (@obj_data) { |
| | 87 | my $class = delete $data->{class}; |
| | 88 | my $obj = $class->new; |
| | 89 | $obj->set_values($data); |
| | 90 | $obj->save(); |
| | 91 | } |
| | 92 | } |
| | 93 | |
| | 94 | sub count_group_by : Tests(26) { |
| | 95 | # legacy way of specifying sort direction |
| | 96 | my $cgb_iter = Bar->count_group_by({ |
| | 97 | status => '0', |
| | 98 | }, { |
| | 99 | group => [ 'foo_id' ], |
| | 100 | sort => 'foo_id desc', |
| | 101 | }); |
| | 102 | my ($count, $bfid, $month); |
| | 103 | isa_ok($cgb_iter, 'CODE'); |
| | 104 | ok(($count, $bfid) = $cgb_iter->(), 'set'); |
| | 105 | is($bfid, 2, 'id'); |
| | 106 | is($count, 1, 'count4'); |
| | 107 | ok(($count, $bfid) = $cgb_iter->(), 'set'); |
| | 108 | is($bfid, 1, 'id'); |
| | 109 | is($count, 1, 'count5'); |
| | 110 | ok(!$cgb_iter->(), 'no $iter'); |
| | 111 | |
| | 112 | # new way of specifying sort direction |
| | 113 | my $cgb_iter2 = Bar->count_group_by({ |
| | 114 | status => '0', |
| | 115 | }, { |
| | 116 | group => [ 'foo_id' ], |
| | 117 | sort => 'foo_id', |
| | 118 | direction => 'descend' |
| | 119 | }); |
| | 120 | |
| | 121 | isa_ok($cgb_iter2, 'CODE'); |
| | 122 | ok(($count, $bfid) = $cgb_iter2->(), 'set'); |
| | 123 | is($bfid, 2, 'id'); |
| | 124 | is($count, 1, 'count4'); |
| | 125 | ok(($count, $bfid) = $cgb_iter2->(), 'set'); |
| | 126 | is($bfid, 1, 'id'); |
| | 127 | is($count, 1, 'count5'); |
| | 128 | ok(!$cgb_iter2->(), 'no $iter'); |
| | 129 | |
| | 130 | # legacy way of specifying sort direction |
| | 131 | my $cgb_iter3 = Bar->count_group_by(undef, { |
| | 132 | group => [ 'extract(month from created_on)' ], |
| | 133 | sort => 'extract(month from created_on) desc', |
| | 134 | }); |
| | 135 | isa_ok($cgb_iter3, 'CODE'); |
| | 136 | ok(($count, $month) = $cgb_iter3->(), 'set'); |
| | 137 | is(int($month), int(strftime("%m", localtime)), 'month'); |
| | 138 | is($count, 3, 'count6'); |
| | 139 | ok(!$cgb_iter3->(), 'no $iter'); |
| | 140 | |
| | 141 | # new way of specifying sort direction |
| | 142 | my $cgb_iter4 = Bar->count_group_by(undef, { |
| | 143 | group => [ 'extract(month from created_on)' ], |
| | 144 | sort => [{ column => 'extract(month from created_on)', |
| | 145 | desc => 'desc' }] |
| | 146 | }); |
| | 147 | isa_ok($cgb_iter4, 'CODE'); |
| | 148 | ok(($count, $month) = $cgb_iter4->(), 'set'); |
| | 149 | is(int($month), int(strftime("%m", localtime)), 'month'); |
| | 150 | is($count, 3, 'count6'); |
| | 151 | ok(!$cgb_iter4->(), 'no $iter'); |
| | 152 | } |
| | 153 | |
| | 154 | sub sum_group_by : Tests(7) { |
| | 155 | # Sum status values across groups of ids (that is, a group for each Foo). |
| | 156 | my $sgb = Foo->sum_group_by(undef, { |
| | 157 | sum => 'status', |
| | 158 | group => ['id'], |
| | 159 | direction => 'ascend', |
| | 160 | }); |
| | 161 | |
| | 162 | my ($status, $id) = $sgb->(); |
| | 163 | ok($status && $id, 'sum_group_by results had a first result'); |
| | 164 | is($status, 1, q{sum_group_by result #1's status is 1}); |
| | 165 | is($id, 2, 'sum_group_by result #1 was for Foo #2'); |
| | 166 | |
| | 167 | ($status, $id) = $sgb->(); |
| | 168 | ok($status && $id, 'sum_group_by results had a second result'); |
| | 169 | is($status, 2, q{sum_group_by result #2's status is 2}); |
| | 170 | is($id, 1, 'sum-group_by result #2 was for Foo #1'); |
| | 171 | |
| | 172 | ($status, $id) = $sgb->(); |
| | 173 | ok(!$status, 'sum_group_by only had two results'); |
| | 174 | } |
| | 175 | |
| | 176 | sub clean_db : Test(teardown) { |
| | 177 | for my $class (qw( Foo Bar )) { |
| | 178 | my $driver = $class->dbi_driver; |
| | 179 | my $dbh = $driver->rw_handle; |
| | 180 | my $ddl_class = $driver->dbd->ddl_class; |
| | 181 | |
| | 182 | $dbh->do($ddl_class->drop_table_sql($class)) or die $dbh->errstr; |
| | 183 | $dbh->do($ddl_class->create_table_sql($class)) or die $dbh->errstr; |
| | 184 | $dbh->do($_) or die $dbh->errstr for $ddl_class->index_table_sql($class); |
| | 185 | $ddl_class->create_sequence($class); # may do nothing |
| | 186 | } |
| | 187 | } |
| | 188 | |
| 402 | | |
| 403 | | # legacy way of specifying sort direction |
| 404 | | my $cgb_iter = Bar->count_group_by({ |
| 405 | | status => '0', |
| 406 | | }, { |
| 407 | | group => [ 'foo_id' ], |
| 408 | | sort => 'foo_id desc', |
| 409 | | }); |
| 410 | | my ($count, $bfid, $month); |
| 411 | | isa_ok($cgb_iter, 'CODE'); |
| 412 | | ok(($count, $bfid) = $cgb_iter->(), 'set'); |
| 413 | | is($bfid, $bar[1]->id, 'id'); |
| 414 | | is($count, 1, 'count4'); |
| 415 | | ok(($count, $bfid) = $cgb_iter->(), 'set'); |
| 416 | | is($bfid, $bar[0]->id, 'id'); |
| 417 | | is($count, 1, 'count5'); |
| 418 | | ok(!$cgb_iter->(), 'no $iter'); |
| 419 | | |
| 420 | | # new way of specifying sort direction |
| 421 | | my $cgb_iter2 = Bar->count_group_by({ |
| 422 | | status => '0', |
| 423 | | }, { |
| 424 | | group => [ 'foo_id' ], |
| 425 | | sort => 'foo_id', |
| 426 | | direction => 'descend' |
| 427 | | }); |
| 428 | | |
| 429 | | isa_ok($cgb_iter2, 'CODE'); |
| 430 | | ok(($count, $bfid) = $cgb_iter2->(), 'set'); |
| 431 | | is($bfid, $bar[1]->id, 'id'); |
| 432 | | is($count, 1, 'count4'); |
| 433 | | ok(($count, $bfid) = $cgb_iter2->(), 'set'); |
| 434 | | is($bfid, $bar[0]->id, 'id'); |
| 435 | | is($count, 1, 'count5'); |
| 436 | | ok(!$cgb_iter2->(), 'no $iter'); |
| 437 | | |
| 438 | | # legacy way of specifying sort direction |
| 439 | | my $cgb_iter3 = Bar->count_group_by(undef, { |
| 440 | | group => [ 'extract(month from created_on)' ], |
| 441 | | sort => 'extract(month from created_on) desc', |
| 442 | | }); |
| 443 | | isa_ok($cgb_iter3, 'CODE'); |
| 444 | | ok(($count, $month) = $cgb_iter3->(), 'set'); |
| 445 | | use POSIX qw(strftime); |
| 446 | | is(int($month), int(strftime("%m", localtime)), 'month'); |
| 447 | | is($count, 3, 'count6'); |
| 448 | | ok(!$cgb_iter3->(), 'no $iter'); |
| 449 | | |
| 450 | | # new way of specifying sort direction |
| 451 | | my $cgb_iter4 = Bar->count_group_by(undef, { |
| 452 | | group => [ 'extract(month from created_on)' ], |
| 453 | | sort => [{ column => 'extract(month from created_on)', |
| 454 | | desc => 'desc' }] |
| 455 | | }); |
| 456 | | isa_ok($cgb_iter4, 'CODE'); |
| 457 | | ok(($count, $month) = $cgb_iter4->(), 'set'); |
| 458 | | is(int($month), int(strftime("%m", localtime)), 'month'); |
| 459 | | is($count, 3, 'count6'); |
| 460 | | ok(!$cgb_iter4->(), 'no $iter'); |