line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Fey::Table; |
2
|
|
|
|
|
|
|
BEGIN { |
3
|
1
|
|
|
1
|
|
28453
|
$Fey::Table::VERSION = '0.40'; |
4
|
|
|
|
|
|
|
} |
5
|
|
|
|
|
|
|
|
6
|
1
|
|
|
1
|
|
11
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
45
|
|
7
|
1
|
|
|
1
|
|
5
|
use warnings; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
29
|
|
8
|
1
|
|
|
1
|
|
859
|
use namespace::autoclean; |
|
1
|
|
|
|
|
31793
|
|
|
1
|
|
|
|
|
8
|
|
9
|
|
|
|
|
|
|
|
10
|
1
|
|
|
1
|
|
653
|
use Fey::Column; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
use Fey::Exceptions qw( param_error ); |
12
|
|
|
|
|
|
|
use Fey::NamedObjectSet; |
13
|
|
|
|
|
|
|
use Fey::Schema; |
14
|
|
|
|
|
|
|
use Fey::Table::Alias; |
15
|
|
|
|
|
|
|
use Fey::Types qw( |
16
|
|
|
|
|
|
|
ArrayRef Bool HashRef Str Undef Column ColumnOrName NamedObjectSet Schema |
17
|
|
|
|
|
|
|
); |
18
|
|
|
|
|
|
|
use List::AllUtils qw( any all first_index ); |
19
|
|
|
|
|
|
|
use Scalar::Util qw( blessed weaken ); |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
use Moose; |
22
|
|
|
|
|
|
|
use MooseX::Params::Validate qw( pos_validated_list ); |
23
|
|
|
|
|
|
|
use MooseX::SemiAffordanceAccessor; |
24
|
|
|
|
|
|
|
use MooseX::StrictConstructor; |
25
|
|
|
|
|
|
|
use Moose::Util::TypeConstraints; |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
with 'Fey::Role::TableLike'; |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
with 'Fey::Role::MakesAliasObjects' => { |
30
|
|
|
|
|
|
|
self_param => 'table', |
31
|
|
|
|
|
|
|
alias_class => 'Fey::Table::Alias', |
32
|
|
|
|
|
|
|
}; |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
has 'id' => ( |
35
|
|
|
|
|
|
|
is => 'ro', |
36
|
|
|
|
|
|
|
lazy_build => 1, |
37
|
|
|
|
|
|
|
init_arg => undef, |
38
|
|
|
|
|
|
|
); |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
has 'name' => ( |
41
|
|
|
|
|
|
|
is => 'ro', |
42
|
|
|
|
|
|
|
isa => Str, |
43
|
|
|
|
|
|
|
required => 1, |
44
|
|
|
|
|
|
|
); |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
has 'is_view' => ( |
47
|
|
|
|
|
|
|
is => 'ro', |
48
|
|
|
|
|
|
|
isa => Bool, |
49
|
|
|
|
|
|
|
default => 0, |
50
|
|
|
|
|
|
|
); |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
has '_keys' => ( |
53
|
|
|
|
|
|
|
traits => ['Array'], |
54
|
|
|
|
|
|
|
is => 'bare', |
55
|
|
|
|
|
|
|
isa => ArrayRef[NamedObjectSet], |
56
|
|
|
|
|
|
|
default => sub { [] }, |
57
|
|
|
|
|
|
|
handles => { |
58
|
|
|
|
|
|
|
_keys => 'elements', |
59
|
|
|
|
|
|
|
_add_key => 'push', |
60
|
|
|
|
|
|
|
_delete_key => 'splice', |
61
|
|
|
|
|
|
|
}, |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
); |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
has '_columns' => ( |
66
|
|
|
|
|
|
|
is => 'ro', |
67
|
|
|
|
|
|
|
isa => NamedObjectSet, |
68
|
|
|
|
|
|
|
default => sub { return Fey::NamedObjectSet->new() }, |
69
|
|
|
|
|
|
|
handles => { |
70
|
|
|
|
|
|
|
columns => 'objects', |
71
|
|
|
|
|
|
|
column => 'object', |
72
|
|
|
|
|
|
|
}, |
73
|
|
|
|
|
|
|
); |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
has 'schema' => ( |
76
|
|
|
|
|
|
|
is => 'rw', |
77
|
|
|
|
|
|
|
isa => Undef | Schema, |
78
|
|
|
|
|
|
|
weak_ref => 1, |
79
|
|
|
|
|
|
|
writer => '_set_schema', |
80
|
|
|
|
|
|
|
clearer => '_clear_schema', |
81
|
|
|
|
|
|
|
predicate => 'has_schema', |
82
|
|
|
|
|
|
|
); |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
has 'candidate_keys' => ( |
85
|
|
|
|
|
|
|
is => 'ro', |
86
|
|
|
|
|
|
|
isa => ArrayRef[ArrayRef[Column]], |
87
|
|
|
|
|
|
|
clearer => '_clear_candidate_keys', |
88
|
|
|
|
|
|
|
lazy_build => 1, |
89
|
|
|
|
|
|
|
init_arg => undef, |
90
|
|
|
|
|
|
|
); |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
after '_add_key', '_delete_key' => sub { $_[0]->_clear_candidate_keys() }; |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
has 'primary_key' => ( |
95
|
|
|
|
|
|
|
is => 'ro', |
96
|
|
|
|
|
|
|
isa => ArrayRef[Column], |
97
|
|
|
|
|
|
|
clearer => '_clear_primary_key', |
98
|
|
|
|
|
|
|
lazy_build => 1, |
99
|
|
|
|
|
|
|
init_arg => undef, |
100
|
|
|
|
|
|
|
); |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
after '_clear_candidate_keys' => sub { $_[0]->_clear_primary_key() }; |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
has '_aliased_tables' => ( |
105
|
|
|
|
|
|
|
traits => ['Hash'], |
106
|
|
|
|
|
|
|
is => 'bare', |
107
|
|
|
|
|
|
|
isa => HashRef, |
108
|
|
|
|
|
|
|
lazy => 1, |
109
|
|
|
|
|
|
|
default => sub { {} }, |
110
|
|
|
|
|
|
|
handles => { |
111
|
|
|
|
|
|
|
_aliased_table => 'get', |
112
|
|
|
|
|
|
|
_store_aliased_table => 'set', |
113
|
|
|
|
|
|
|
_has_aliased_table => 'exists', |
114
|
|
|
|
|
|
|
}, |
115
|
|
|
|
|
|
|
); |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
with 'Fey::Role::Named'; |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
sub add_column { |
120
|
|
|
|
|
|
|
my $self = shift; |
121
|
|
|
|
|
|
|
my ($col) = pos_validated_list( \@_, { isa => Column } ); |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
my $name = $col->name(); |
124
|
|
|
|
|
|
|
param_error "The table already has a column named $name." |
125
|
|
|
|
|
|
|
if $self->column($name); |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
$self->_columns()->add($col); |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
$col->_set_table($self); |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
return $self; |
132
|
|
|
|
|
|
|
} |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
sub remove_column { |
135
|
|
|
|
|
|
|
my $self = shift; |
136
|
|
|
|
|
|
|
my ($col) |
137
|
|
|
|
|
|
|
= pos_validated_list( \@_, { isa => ColumnOrName } ); |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
$col = $self->column($col) |
140
|
|
|
|
|
|
|
unless blessed $col; |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
if ( my $schema = $self->schema() ) { |
143
|
|
|
|
|
|
|
for my $fk ( grep { $_->has_column($col) } |
144
|
|
|
|
|
|
|
$schema->foreign_keys_for_table($self) ) { |
145
|
|
|
|
|
|
|
$schema->remove_foreign_key($fk); |
146
|
|
|
|
|
|
|
} |
147
|
|
|
|
|
|
|
} |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
my $name = $col->name(); |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
for my $k ( $self->_keys() ) { |
152
|
|
|
|
|
|
|
$self->remove_candidate_key( $k->objects() ) |
153
|
|
|
|
|
|
|
if $k->object($name); |
154
|
|
|
|
|
|
|
} |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
$self->_columns()->delete($col); |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
$col->_clear_table(); |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
return $self; |
161
|
|
|
|
|
|
|
} |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
sub _build_candidate_keys { |
164
|
|
|
|
|
|
|
my $self = shift; |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
return [ map { [ $_->objects() ] } $self->_keys() ]; |
167
|
|
|
|
|
|
|
} |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
sub _build_primary_key { |
170
|
|
|
|
|
|
|
my $self = shift; |
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
my $keys = $self->candidate_keys(); |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
return $keys->[0] || []; |
175
|
|
|
|
|
|
|
} |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
sub add_candidate_key { |
178
|
|
|
|
|
|
|
my $self = shift; |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
my $count = @_ ? @_ : 1; |
181
|
|
|
|
|
|
|
my (@cols) = pos_validated_list( |
182
|
|
|
|
|
|
|
\@_, |
183
|
|
|
|
|
|
|
( ( { isa => ColumnOrName } ) x $count ), |
184
|
|
|
|
|
|
|
MX_PARAMS_VALIDATE_NO_CACHE => 1, |
185
|
|
|
|
|
|
|
); |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
for my $name ( map { blessed $_ ? $_->name() : $_ } @cols ) { |
188
|
|
|
|
|
|
|
param_error "The column $name is not part of the " |
189
|
|
|
|
|
|
|
. $self->name() |
190
|
|
|
|
|
|
|
. ' table.' |
191
|
|
|
|
|
|
|
unless $self->column($name); |
192
|
|
|
|
|
|
|
} |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
$_ = $self->column($_) for grep { !blessed $_ } @cols; |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
return if $self->has_candidate_key(@cols); |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
$self->_add_key( Fey::NamedObjectSet->new(@cols) ); |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
return; |
201
|
|
|
|
|
|
|
} |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
sub remove_candidate_key { |
204
|
|
|
|
|
|
|
my $self = shift; |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
my $count = @_ ? @_ : 1; |
207
|
|
|
|
|
|
|
my (@cols) = pos_validated_list( |
208
|
|
|
|
|
|
|
\@_, |
209
|
|
|
|
|
|
|
( ( { isa => ColumnOrName } ) x $count ), |
210
|
|
|
|
|
|
|
MX_PARAMS_VALIDATE_NO_CACHE => 1, |
211
|
|
|
|
|
|
|
); |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
for my $name ( map { blessed $_ ? $_->name() : $_ } @cols ) { |
214
|
|
|
|
|
|
|
param_error "The column $name is not part of the " |
215
|
|
|
|
|
|
|
. $self->name() |
216
|
|
|
|
|
|
|
. ' table.' |
217
|
|
|
|
|
|
|
unless $self->column($name); |
218
|
|
|
|
|
|
|
} |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
$_ = $self->column($_) for grep { !blessed $_ } @cols; |
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
my $set = Fey::NamedObjectSet->new(@cols); |
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
my $idx = first_index { $_->is_same_as($set) } $self->_keys(); |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
$self->_delete_key( $idx, 1 ) |
227
|
|
|
|
|
|
|
if $idx >= 0; |
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
return; |
230
|
|
|
|
|
|
|
} |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
sub has_candidate_key { |
233
|
|
|
|
|
|
|
my $self = shift; |
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
my $count = @_ ? @_ : 1; |
236
|
|
|
|
|
|
|
my (@cols) = pos_validated_list( |
237
|
|
|
|
|
|
|
\@_, |
238
|
|
|
|
|
|
|
( ( { isa => ColumnOrName } ) x $count ), |
239
|
|
|
|
|
|
|
MX_PARAMS_VALIDATE_NO_CACHE => 1, |
240
|
|
|
|
|
|
|
); |
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
for my $name ( map { blessed $_ ? $_->name() : $_ } @cols ) { |
243
|
|
|
|
|
|
|
param_error "The column $name is not part of the " |
244
|
|
|
|
|
|
|
. $self->name() |
245
|
|
|
|
|
|
|
. ' table.' |
246
|
|
|
|
|
|
|
unless $self->column($name); |
247
|
|
|
|
|
|
|
} |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
$_ = $self->column($_) for grep { !blessed $_ } @cols; |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
my $set = Fey::NamedObjectSet->new(@cols); |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
return 1 |
254
|
|
|
|
|
|
|
if any { $_->is_same_as($set) } $self->_keys(); |
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
return 0; |
257
|
|
|
|
|
|
|
} |
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
# Caching the objects by name prevents a weird bug where we have two |
260
|
|
|
|
|
|
|
# aliases of the same name, and one disappears because of weak |
261
|
|
|
|
|
|
|
# references, causing weird errors. |
262
|
|
|
|
|
|
|
around 'alias' => sub { |
263
|
|
|
|
|
|
|
my $orig = shift; |
264
|
|
|
|
|
|
|
my $self = shift; |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
# bleh, duplicating code from Aliasable |
267
|
|
|
|
|
|
|
my %p = @_ == 1 ? ( alias_name => $_[0] ) : @_; |
268
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
if ( defined $p{alias_name} ) { |
270
|
|
|
|
|
|
|
return $self->_aliased_table( $p{alias_name} ) |
271
|
|
|
|
|
|
|
if $self->_has_aliased_table( $p{alias_name} ); |
272
|
|
|
|
|
|
|
} |
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
my $alias = $orig->( $self, %p ); |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
$self->_store_aliased_table( $alias->alias_name() => $alias ); |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
return $alias; |
279
|
|
|
|
|
|
|
}; |
280
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
sub is_alias {0} |
282
|
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
sub aliased_column { |
284
|
|
|
|
|
|
|
my $self = shift; |
285
|
|
|
|
|
|
|
my $prefix = shift; |
286
|
|
|
|
|
|
|
my $name = shift; |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
my $col = $self->column($name) |
289
|
|
|
|
|
|
|
or return; |
290
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
return $col->alias( alias_name => $prefix . $col->name() ); |
292
|
|
|
|
|
|
|
} |
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
sub aliased_columns { |
295
|
|
|
|
|
|
|
my $self = shift; |
296
|
|
|
|
|
|
|
my $prefix = shift; |
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
my @names = @_ ? @_ : map { $_->name() } $self->columns(); |
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
return map { $self->aliased_column( $prefix, $_ ) } @names; |
301
|
|
|
|
|
|
|
} |
302
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
sub sql { |
304
|
|
|
|
|
|
|
return $_[1]->quote_identifier( $_[0]->name() ); |
305
|
|
|
|
|
|
|
} |
306
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
sub sql_with_alias { goto &sql } |
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
sub _build_id { $_[0]->name() } |
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
__PACKAGE__->meta()->make_immutable(); |
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
1; |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
# ABSTRACT: Represents a table (or view) |
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
=pod |
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
=head1 NAME |
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
Fey::Table - Represents a table (or view) |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
=head1 VERSION |
326
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
version 0.40 |
328
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
=head1 SYNOPSIS |
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
my $table = Fey::Table->new( name => 'User' ); |
332
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
=head1 DESCRIPTION |
334
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
This class represents a table or view in a schema. From the standpoint |
336
|
|
|
|
|
|
|
of SQL construction in Fey, a table and a view are basically the same |
337
|
|
|
|
|
|
|
thing. |
338
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
=head1 METHODS |
340
|
|
|
|
|
|
|
|
341
|
|
|
|
|
|
|
This class provides the following methods: |
342
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
=head2 Fey::Table->new() |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
my $table = Fey::Table->new( name => 'User' ); |
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
my $table = Fey::Table->new( name => 'ActiveUser', |
348
|
|
|
|
|
|
|
is_view => 1, |
349
|
|
|
|
|
|
|
); |
350
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
This method constructs a new C<Fey::Table> object. It takes the |
352
|
|
|
|
|
|
|
following parameters: |
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
=over 4 |
355
|
|
|
|
|
|
|
|
356
|
|
|
|
|
|
|
=item * name - required |
357
|
|
|
|
|
|
|
|
358
|
|
|
|
|
|
|
The name of the table. |
359
|
|
|
|
|
|
|
|
360
|
|
|
|
|
|
|
=item * is_view - defaults to 0 |
361
|
|
|
|
|
|
|
|
362
|
|
|
|
|
|
|
A boolean indicating whether this table is a view. |
363
|
|
|
|
|
|
|
|
364
|
|
|
|
|
|
|
=back |
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
=head2 $table->name() |
367
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
Returns the name of the table. |
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
=head2 $table->is_view() |
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
Returns a boolean indicating whether the object is a view. |
373
|
|
|
|
|
|
|
|
374
|
|
|
|
|
|
|
=head2 $table->schema() |
375
|
|
|
|
|
|
|
|
376
|
|
|
|
|
|
|
Returns the C<Fey::Schema> object that this table belongs to. This is |
377
|
|
|
|
|
|
|
set when the table is added to a schema via the C<< |
378
|
|
|
|
|
|
|
Fey::Schema->add_table() >> method. |
379
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
=head2 $table->add_column($column) |
381
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
This adds a new column to the schema. The column must be a |
383
|
|
|
|
|
|
|
C<Fey::Column> object. Adding the column to the table sets the table |
384
|
|
|
|
|
|
|
for the column, so that C<< $column->table() >> returns the correct |
385
|
|
|
|
|
|
|
object. |
386
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
If the table already has a column with the same name, an exception is |
388
|
|
|
|
|
|
|
thrown. |
389
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
=head2 $table->remove_column($column) |
391
|
|
|
|
|
|
|
|
392
|
|
|
|
|
|
|
Remove the specified column from the table. If the column was part of |
393
|
|
|
|
|
|
|
any foreign keys, these are removed from the schema. If this column is |
394
|
|
|
|
|
|
|
part of any keys for the table, those keys will be removed. Removing |
395
|
|
|
|
|
|
|
the column unsets the table for the column. |
396
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
The table can be specified either by name or by passing in a |
398
|
|
|
|
|
|
|
C<Fey::Column> object. |
399
|
|
|
|
|
|
|
|
400
|
|
|
|
|
|
|
=head2 $table->column($name) |
401
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
Given a column name, this method returns the matching column object, |
403
|
|
|
|
|
|
|
if one exists. |
404
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
=head2 $table->columns |
406
|
|
|
|
|
|
|
|
407
|
|
|
|
|
|
|
=head2 $table->columns(@names) |
408
|
|
|
|
|
|
|
|
409
|
|
|
|
|
|
|
When this method is called with no arguments, it returns all of the columns in |
410
|
|
|
|
|
|
|
the table. Columns are returned in the order with which they were added to the |
411
|
|
|
|
|
|
|
table. |
412
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
If given a list of names, it returns only the specified columns. If a name is |
414
|
|
|
|
|
|
|
given which doesn't match a column in the table, then it is ignored. |
415
|
|
|
|
|
|
|
|
416
|
|
|
|
|
|
|
=head2 $table->candidate_keys() |
417
|
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
Returns all of the candidate keys for the table as an array |
419
|
|
|
|
|
|
|
reference. Each element of the reference is in turn an array reference |
420
|
|
|
|
|
|
|
containing one or more columns. |
421
|
|
|
|
|
|
|
|
422
|
|
|
|
|
|
|
=head2 $table->has_candidate_key(@columns) |
423
|
|
|
|
|
|
|
|
424
|
|
|
|
|
|
|
This method returns true if the table has the given key. A key is |
425
|
|
|
|
|
|
|
identified as a list of names or C<Fey::Column> objects. |
426
|
|
|
|
|
|
|
|
427
|
|
|
|
|
|
|
=head2 $table->add_candidate_key(@columns) |
428
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
This method adds a new candidate key to the table. The list of columns |
430
|
|
|
|
|
|
|
can contain either names or C<Fey::Column> objects. |
431
|
|
|
|
|
|
|
|
432
|
|
|
|
|
|
|
A candidate key is one or more columns which uniquely identify a row |
433
|
|
|
|
|
|
|
in that table. |
434
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
If a name or column is specified which doesn't belong to the table, an |
436
|
|
|
|
|
|
|
exception will be thrown. |
437
|
|
|
|
|
|
|
|
438
|
|
|
|
|
|
|
=head2 $table->remove_candidate_key(@columns) |
439
|
|
|
|
|
|
|
|
440
|
|
|
|
|
|
|
This method removes a candidate key for the table. The list of columns |
441
|
|
|
|
|
|
|
can contain either names or C<Fey::Column> objects. |
442
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
If a name or column is specified which doesn't belong to the table, an |
444
|
|
|
|
|
|
|
exception will be thrown. |
445
|
|
|
|
|
|
|
|
446
|
|
|
|
|
|
|
=head2 $table->primary_key() |
447
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
This is a convenience method that simply returns the first candidate |
449
|
|
|
|
|
|
|
key added to the table. The key is returned as an array reference of |
450
|
|
|
|
|
|
|
column objects. |
451
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
=head2 $table->alias(%p) |
453
|
|
|
|
|
|
|
|
454
|
|
|
|
|
|
|
=head2 $table->alias($alias_name) |
455
|
|
|
|
|
|
|
|
456
|
|
|
|
|
|
|
This method returns a new C<Fey::Table::Alias> object based on the |
457
|
|
|
|
|
|
|
table. Any parameters passed to this method will be passed through to |
458
|
|
|
|
|
|
|
C<< Fey::Table::Alias->new() >>. |
459
|
|
|
|
|
|
|
|
460
|
|
|
|
|
|
|
As a shortcut, if you pass a single argument to this method, it will |
461
|
|
|
|
|
|
|
be passed as the "alias_name" parameter to C<< |
462
|
|
|
|
|
|
|
Fey::Table::Alias->new() >>. |
463
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
=head2 $table->is_alias() |
465
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
Always returns false. |
467
|
|
|
|
|
|
|
|
468
|
|
|
|
|
|
|
=head2 $table->aliased_column( $prefix, $column_name ) |
469
|
|
|
|
|
|
|
|
470
|
|
|
|
|
|
|
This method returns a new L<Fey::Column::Alias> object. The alias's |
471
|
|
|
|
|
|
|
name is generated by concatenating the specified prefix and the |
472
|
|
|
|
|
|
|
column's real name. |
473
|
|
|
|
|
|
|
|
474
|
|
|
|
|
|
|
=head2 $table->aliased_columns( $prefix, @column_names ) |
475
|
|
|
|
|
|
|
|
476
|
|
|
|
|
|
|
This method returns a list of new L<Fey::Column::Alias> objects. The |
477
|
|
|
|
|
|
|
alias names are generated by concatenating the specified prefix and |
478
|
|
|
|
|
|
|
the column's real name. |
479
|
|
|
|
|
|
|
|
480
|
|
|
|
|
|
|
If you omit the list of column names, it returns aliases for I<all> of the |
481
|
|
|
|
|
|
|
columns in table, in same order as returned by C<< $table->columns() >>. |
482
|
|
|
|
|
|
|
|
483
|
|
|
|
|
|
|
=head2 $table->sql() |
484
|
|
|
|
|
|
|
|
485
|
|
|
|
|
|
|
=head2 $table->sql_with_alias() |
486
|
|
|
|
|
|
|
|
487
|
|
|
|
|
|
|
Returns the appropriate SQL snippet for the table. |
488
|
|
|
|
|
|
|
|
489
|
|
|
|
|
|
|
=head2 $table->id() |
490
|
|
|
|
|
|
|
|
491
|
|
|
|
|
|
|
Returns a unique identifier for the table. |
492
|
|
|
|
|
|
|
|
493
|
|
|
|
|
|
|
=head1 ROLES |
494
|
|
|
|
|
|
|
|
495
|
|
|
|
|
|
|
This class does the L<Fey::Role::TableLike>, L<Fey::Role::MakesAliasObjects>, |
496
|
|
|
|
|
|
|
and L<Fey::Role::Named> roles. |
497
|
|
|
|
|
|
|
|
498
|
|
|
|
|
|
|
=head1 BUGS |
499
|
|
|
|
|
|
|
|
500
|
|
|
|
|
|
|
See L<Fey> for details on how to report bugs. |
501
|
|
|
|
|
|
|
|
502
|
|
|
|
|
|
|
=head1 AUTHOR |
503
|
|
|
|
|
|
|
|
504
|
|
|
|
|
|
|
Dave Rolsky <autarch@urth.org> |
505
|
|
|
|
|
|
|
|
506
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
507
|
|
|
|
|
|
|
|
508
|
|
|
|
|
|
|
This software is Copyright (c) 2011 by Dave Rolsky. |
509
|
|
|
|
|
|
|
|
510
|
|
|
|
|
|
|
This is free software, licensed under: |
511
|
|
|
|
|
|
|
|
512
|
|
|
|
|
|
|
The Artistic License 2.0 (GPL Compatible) |
513
|
|
|
|
|
|
|
|
514
|
|
|
|
|
|
|
=cut |
515
|
|
|
|
|
|
|
|
516
|
|
|
|
|
|
|
|
517
|
|
|
|
|
|
|
__END__ |
518
|
|
|
|
|
|
|
|