Refactored pagination into search method, Sweet syntax is now in Compat
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Table.pm
CommitLineData
ea2e61bf 1package DBIx::Class::Table;
2
3use strict;
4use warnings;
5
223b8fe3 6use DBIx::Class::ResultSet;
2a21de92 7use Data::Page;
95a70f01 8
9use base qw/Class::Data::Inheritable/;
ea2e61bf 10
11__PACKAGE__->mk_classdata('_columns' => {});
12
ea2e61bf 13__PACKAGE__->mk_classdata('_table_name');
14
34d52be2 15__PACKAGE__->mk_classdata('table_alias'); # FIXME: Doesn't actually do anything yet!
16
223b8fe3 17__PACKAGE__->mk_classdata('_resultset_class' => 'DBIx::Class::ResultSet');
95a70f01 18
2a21de92 19__PACKAGE__->mk_classdata('_page_object');
20
223b8fe3 21sub iterator_class { shift->_resultset_class(@_) }
525035fb 22
34d52be2 23=head1 NAME
24
25DBIx::Class::Table - Basic table methods
26
27=head1 SYNOPSIS
28
29=head1 DESCRIPTION
30
31This class is responsible for defining and doing basic operations on
32L<DBIx::Class> objects.
33
34=head1 METHODS
35
36=over 4
37
39fe0e65 38=cut
39
ea2e61bf 40sub _register_columns {
41 my ($class, @cols) = @_;
42 my $names = { %{$class->_columns} };
43 $names->{$_} ||= {} for @cols;
44 $class->_columns($names);
45}
46
47sub _mk_column_accessors {
48 my ($class, @cols) = @_;
510ca912 49 $class->mk_group_accessors('column' => @cols);
ea2e61bf 50}
51
39fe0e65 52=item add_columns
53
54 __PACKAGE__->add_columns(qw/col1 col2 col3/);
55
56Adds columns to the current package, and creates accessors for them
57
58=cut
59
510ca912 60sub add_columns {
8fe001e1 61 my ($class, @cols) = @_;
62 $class->_register_columns(@cols);
63 $class->_mk_column_accessors(@cols);
64}
65
656796f2 66=item search_literal
39fe0e65 67
656796f2 68 my @obj = $class->search_literal($literal_where_cond, @bind);
69 my $cursor = $class->search_literal($literal_where_cond, @bind);
39fe0e65 70
71=cut
72
656796f2 73sub search_literal {
8fe001e1 74 my ($class, $cond, @vals) = @_;
a3018bd3 75 $cond =~ s/^\s*WHERE//i;
8da9889b 76 my $attrs = (ref $vals[$#vals] eq 'HASH' ? { %{ pop(@vals) } } : {});
77 $attrs->{bind} = \@vals;
78 return $class->search(\$cond, $attrs);
510ca912 79}
80
656796f2 81=item count_literal
39fe0e65 82
656796f2 83 my $count = $class->count_literal($literal_where_cond);
39fe0e65 84
85=cut
86
656796f2 87sub count_literal {
7624b19f 88 my $class = shift;
89 return $class->search_literal(@_)->count;
fcbc5f29 90}
91
39fe0e65 92=item count
93
94 my $count = $class->count({ foo => 3 });
95
96=cut
97
06d90c6b 98sub count {
99 my $class = shift;
7624b19f 100 return $class->search(@_)->count;
c1d23573 101}
102
39fe0e65 103=item search
104
105 my @obj = $class->search({ foo => 3 });
106 my $cursor = $class->search({ foo => 3 });
107
108=cut
109
8fe001e1 110sub search {
12bbb339 111 my $class = shift;
8b445e33 112 #warn "@_";
12bbb339 113 my $attrs = { };
114 if (@_ > 1 && ref $_[$#_] eq 'HASH') {
115 $attrs = { %{ pop(@_) } };
116 }
7624b19f 117 $attrs->{where} = (@_ == 1 || ref $_[0] eq "HASH" ? shift: {@_});
2a21de92 118
119 # for pagination, we create the resultset with no limit and slice it later
120 my $page = {};
121 if ( $attrs->{page} ) {
122 map { $page->{$_} = $attrs->{$_} } qw/rows page/;
123 delete $attrs->{$_} for qw/rows offset page/;
124 }
7624b19f 125
126 my $rs = $class->resultset($attrs);
2a21de92 127
128 if ( $page->{page} ) {
129 my $pager = Data::Page->new(
130 $rs->count,
131 $page->{rows} || 10,
132 $page->{page} || 1 );
133 $class->_page_object( $pager );
134 return $rs->slice( $pager->skipped,
135 $pager->skipped + $pager->entries_per_page - 1 );
136 }
137
7624b19f 138 return (wantarray ? $rs->all : $rs);
139}
140
141sub resultset {
142 my $class = shift;
143
144 my $rs_class = $class->_resultset_class;
145 eval "use $rs_class;";
146 my $rs = $rs_class->new($class, @_);
a3018bd3 147}
148
39fe0e65 149=item search_like
150
151Identical to search except defaults to 'LIKE' instead of '=' in condition
152
153=cut
154
a3018bd3 155sub search_like {
156 my $class = shift;
12bbb339 157 my $attrs = { };
158 if (@_ > 1 && ref $_[$#_] eq 'HASH') {
159 $attrs = pop(@_);
160 }
223b8fe3 161 my $query = ref $_[0] eq "HASH" ? { %{shift()} }: {@_};
162 $query->{$_} = { 'like' => $query->{$_} } for keys %$query;
163 return $class->search($query, { %$attrs });
8fe001e1 164}
165
166sub _select_columns {
167 return keys %{$_[0]->_columns};
168}
169
39fe0e65 170=item table
171
172 __PACKAGE__->table('tbl_name');
173
174=cut
175
510ca912 176sub table {
177 shift->_table_name(@_);
178}
179
39fe0e65 180=item find_or_create
181
182 $class->find_or_create({ key => $val, ... });
183
184Searches for a record matching the search condition; if it doesn't find one,
185creates one and returns that instead
186
187=cut
188
95a70f01 189sub find_or_create {
190 my $class = shift;
191 my $hash = ref $_[0] eq "HASH" ? shift: {@_};
1a14aa3f 192 my $exists = $class->find($hash);
95a70f01 193 return defined($exists) ? $exists : $class->create($hash);
194}
195
8b445e33 196sub columns { return keys %{shift->_columns}; }
197
2a21de92 198=item page
199
200 $pager = $class->page;
201
202Returns a Data::Page object for the most recent search that was performed
203using the page parameter.
204
205=cut
206
207sub page { shift->_page_object }
208
ea2e61bf 2091;
34d52be2 210
211=back
212
213=head1 AUTHORS
214
daec44b8 215Matt S. Trout <mst@shadowcatsystems.co.uk>
34d52be2 216
217=head1 LICENSE
218
219You may distribute this code under the same terms as Perl itself.
220
221=cut
222