4cb733fae7c539ff543fa92175cf57a49d6d5f8f
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / ResultSourceProxy / Table.pm
1 package DBIx::Class::ResultSourceProxy::Table;
2
3 use strict;
4 use warnings;
5
6 use base qw/DBIx::Class::ResultSourceProxy/;
7
8 use DBIx::Class::ResultSource::Table;
9 use Scalar::Util 'blessed';
10 use namespace::clean;
11
12 __PACKAGE__->mk_classaccessor(table_class => 'DBIx::Class::ResultSource::Table');
13 # FIXME: Doesn't actually do anything yet!
14 __PACKAGE__->mk_group_accessors( inherited => 'table_alias' );
15
16 sub _init_result_source_instance {
17     my $class = shift;
18
19     $class->mk_group_accessors( inherited => [ result_source_instance => '_result_source' ] )
20       unless $class->can('result_source_instance');
21
22     # might be pre-made for us courtesy of DBIC::DB::result_source_instance()
23     my $rsrc = $class->result_source_instance;
24
25     return $rsrc
26       if $rsrc and $rsrc->result_class eq $class;
27
28     my $table_class = $class->table_class;
29     $class->ensure_class_loaded($table_class);
30
31     if( $rsrc ) {
32         #
33         # NOTE! - not using clone() here and *NOT* marking source as derived
34         # from the one already existing on the class (if any)
35         #
36         $rsrc = $table_class->new({
37             %$rsrc,
38             result_class => $class,
39             source_name => undef,
40             schema => undef
41         });
42     }
43     else {
44         $rsrc = $table_class->new({
45             name            => undef,
46             result_class    => $class,
47             source_name     => undef,
48         });
49     }
50
51     $class->result_source_instance($rsrc);
52 }
53
54 =head1 NAME
55
56 DBIx::Class::ResultSourceProxy::Table - provides a classdata table
57 object and method proxies
58
59 =head1 SYNOPSIS
60
61   __PACKAGE__->table('cd');
62   __PACKAGE__->add_columns(qw/cdid artist title year/);
63   __PACKAGE__->set_primary_key('cdid');
64
65 =head1 METHODS
66
67 =head2 add_columns
68
69   __PACKAGE__->add_columns(qw/cdid artist title year/);
70
71 Adds columns to the current class and creates accessors for them.
72
73 =cut
74
75 =head2 table
76
77   __PACKAGE__->table('tbl_name');
78
79 Gets or sets the table name.
80
81 =cut
82
83 sub table {
84   return $_[0]->result_source->name unless @_ > 1;
85
86   my ($class, $table) = @_;
87
88   unless (blessed $table && $table->isa($class->table_class)) {
89
90     my $ancestor = $class->can('result_source_instance')
91       ? $class->result_source_instance
92       : undef
93     ;
94
95     # Folks calling ->table on a class *might* expect the name
96     # to shift everywhere, but that can't happen
97     # So what we do is mark the ancestor as "dirty"
98     # even though it will have no "derived" link to the one we
99     # will use afterwards
100     if(
101       defined $ancestor
102         and
103       $ancestor->name ne $table
104         and
105       scalar $ancestor->__derived_instances
106     ) {
107       # Trigger the "descendants are dirty" logic, without giving
108       # it an explicit externally-callable interface
109       # This is ugly as sin, but likely saner in the long run
110       local $ancestor->{__in_rsrc_setter_callstack} = 1
111         unless $ancestor->{__in_rsrc_setter_callstack};
112       my $old_name = $ancestor->name;
113       $ancestor->set_rsrc_instance_specific_attribute( name => "\0" );
114       $ancestor->set_rsrc_instance_specific_attribute( name => $old_name );
115     }
116
117
118     my $table_class = $class->table_class;
119     $class->ensure_class_loaded($table_class);
120
121
122     # NOTE! - not using clone() here and *NOT* marking source as derived
123     # from the one already existing on the class (if any)
124     # This is logically sound as we are operating at class-level, and is
125     # in fact necessary, as otherwise any base-class with a "dummy" table
126     # will be marked as an ancestor of everything
127     $table = $table_class->new({
128         %{ $ancestor || {} },
129         name => $table,
130         result_class => $class,
131     });
132   }
133
134   $class->mk_group_accessors( inherited => [ result_source_instance => '_result_source' ] )
135     unless $class->can('result_source_instance');
136
137   $class->result_source_instance($table)->name;
138 }
139
140 =head2 table_class
141
142   __PACKAGE__->table_class('DBIx::Class::ResultSource::Table');
143
144 Gets or sets the table class used for construction and validation.
145
146 =head2 has_column
147
148   if ($obj->has_column($col)) { ... }
149
150 Returns 1 if the class has a column of this name, 0 otherwise.
151
152 =head2 column_info
153
154   my $info = $obj->column_info($col);
155
156 Returns the column metadata hashref for a column. For a description of
157 the various types of column data in this hashref, see
158 L<DBIx::Class::ResultSource/add_column>
159
160 =head2 columns
161
162   my @column_names = $obj->columns;
163
164 =head1 FURTHER QUESTIONS?
165
166 Check the list of L<additional DBIC resources|DBIx::Class/GETTING HELP/SUPPORT>.
167
168 =head1 COPYRIGHT AND LICENSE
169
170 This module is free software L<copyright|DBIx::Class/COPYRIGHT AND LICENSE>
171 by the L<DBIx::Class (DBIC) authors|DBIx::Class/AUTHORS>. You can
172 redistribute it and/or modify it under the same terms as the
173 L<DBIx::Class library|DBIx::Class/COPYRIGHT AND LICENSE>.
174
175 =cut
176
177 1;
178
179