Commit | Line | Data |
4f4fd192 |
1 | use MooseX::Declare; |
0c4b09d0 |
2 | class SQL::Translator::Object::Table extends SQL::Translator::Object is dirty { |
160f1f55 |
3 | use MooseX::Types::Moose qw(Any Bool HashRef Int Str); |
5f184270 |
4 | use MooseX::MultiMethods; |
a499b4bd |
5 | use SQL::Translator::Types qw(Column Constraint Index Schema Sequence ColumnHash ConstraintHash IndexHash SequenceHash IxHash); |
46ad29bb |
6 | use SQL::Translator::Object::Column; |
e2b6425f |
7 | use SQL::Translator::Object::Constraint; |
a499b4bd |
8 | use Tie::IxHash; |
0c4b09d0 |
9 | clean; |
10 | |
11 | use overload |
12 | '""' => sub { shift->name }, |
13 | 'bool' => sub { $_[0]->name || $_[0] }, |
14 | fallback => 1, |
15 | ; |
16 | |
4f4fd192 |
17 | has 'name' => ( |
18 | is => 'rw', |
19 | isa => Str, |
20 | required => 1 |
21 | ); |
22 | |
23 | has 'columns' => ( |
4f4fd192 |
24 | is => 'rw', |
a499b4bd |
25 | isa => IxHash, #ColumnHash, |
720dcdc3 |
26 | handles => { |
a499b4bd |
27 | exists_column => 'EXISTS', |
28 | column_ids => 'Keys', |
29 | get_columns => 'Values', |
30 | get_column => 'FETCH', |
31 | add_column => 'STORE', |
32 | remove_column => 'DELETE', |
33 | has_columns => 'Length', |
34 | clear_columns => 'CLEAR', |
4f4fd192 |
35 | }, |
a499b4bd |
36 | coerce => 1, |
37 | default => sub { Tie::IxHash->new() } |
4f4fd192 |
38 | ); |
39 | |
40 | has 'indexes' => ( |
4f4fd192 |
41 | is => 'rw', |
a499b4bd |
42 | isa => IxHash, #IndexHash, |
720dcdc3 |
43 | handles => { |
a499b4bd |
44 | exists_index => 'EXISTS', |
45 | index_ids => 'Keys', |
46 | get_indices => 'Values', |
47 | get_index => 'FETCH', |
48 | add_index => 'STORE', |
49 | remove_index => 'DELETE', |
4f4fd192 |
50 | }, |
a499b4bd |
51 | coerce => 1, |
52 | default => sub { Tie::IxHash->new() } |
4f4fd192 |
53 | ); |
54 | |
55 | has 'constraints' => ( |
4f4fd192 |
56 | is => 'rw', |
a499b4bd |
57 | isa => IxHash, #ConstraintHash, |
720dcdc3 |
58 | handles => { |
a499b4bd |
59 | exists_constraint => 'EXISTS', |
60 | constraint_ids => 'Keys', |
61 | get_constraints => 'Values', |
62 | get_constraint => 'FETCH', |
63 | add_constraint => 'STORE', |
64 | remove_constraint => 'DELETE', |
4f4fd192 |
65 | }, |
a499b4bd |
66 | coerce => 1, |
67 | default => sub { Tie::IxHash->new() } |
4f4fd192 |
68 | ); |
69 | |
70 | has 'sequences' => ( |
4f4fd192 |
71 | is => 'rw', |
a499b4bd |
72 | isa => IxHash, #SequenceHash, |
720dcdc3 |
73 | handles => { |
a499b4bd |
74 | exists_sequence => 'EXISTS', |
75 | sequence_ids => 'Keys', |
76 | get_sequences => 'Values', |
77 | get_sequence => 'FETCH', |
78 | add_sequence => 'STORE', |
79 | remove_sequence => 'DELETE', |
4f4fd192 |
80 | }, |
a499b4bd |
81 | coerce => 1, |
82 | default => sub { Tie::IxHash->new() }, |
4f4fd192 |
83 | ); |
f78a484a |
84 | |
2850baeb |
85 | has 'schema' => ( |
4f4fd192 |
86 | is => 'rw', |
2850baeb |
87 | isa => Schema, |
88 | weak_ref => 1, |
4f4fd192 |
89 | ); |
49063029 |
90 | |
2850baeb |
91 | has 'temporary' => ( |
b750d2f1 |
92 | is => 'rw', |
2850baeb |
93 | isa => Bool, |
94 | default => 0 |
b750d2f1 |
95 | ); |
96 | |
160f1f55 |
97 | has '_order' => ( |
98 | is => 'rw', |
99 | isa => Int, |
100 | ); |
101 | |
1f5b9ea4 |
102 | around get_column(Column $column does coerce) { |
103 | $self->$orig($column->name); |
104 | } |
105 | |
de1e817e |
106 | around add_column(Column $column does coerce) { |
107 | die "Can't use column name " . $column->name if $self->exists_column($column->name) || $column->name eq ''; |
e1bef8b9 |
108 | $column->table($self); |
00e28941 |
109 | $self->$orig($column->name, $column); |
110 | return $self->get_column($column->name); |
de1e817e |
111 | } |
e1bef8b9 |
112 | |
78963c00 |
113 | around add_constraint(Constraint $constraint does coerce) { |
4004eb30 |
114 | if ($constraint->type eq 'FOREIGN KEY') { |
115 | my @columns = $constraint->get_columns; |
116 | die "There are no columns associated with this foreign key constraint." unless scalar @columns; |
117 | for my $column (@columns) { |
118 | die "Can't use column " . $column->name . ". It doesn't exist!" unless $self->exists_column($column); |
119 | } |
120 | die "Reference table " . $constraint->reference_table . " does not exist!" unless $self->schema->exists_table($constraint->reference_table); |
121 | } |
f34b818d |
122 | my $name = $constraint->name; |
123 | if ($name eq '') { |
c27fec89 |
124 | my $idx = 0; |
125 | while ($self->exists_constraint('ANON' . $idx)) { $idx++ } |
126 | $name = 'ANON' . $idx; |
f34b818d |
127 | } |
e1bef8b9 |
128 | $constraint->table($self); |
aa20eb7f |
129 | if ($constraint->has_type && $constraint->type eq 'PRIMARY KEY') { |
130 | $self->get_column($_)->is_primary_key(1) for $constraint->column_ids; |
131 | } |
00e28941 |
132 | $self->$orig($name, $constraint); |
133 | return $self->get_constraint($name); |
f34b818d |
134 | } |
e1bef8b9 |
135 | |
706009e5 |
136 | around add_index(Index $index does coerce) { |
c27fec89 |
137 | my $name = $index->name; |
138 | if ($name eq '') { |
139 | my $idx = 0; |
140 | while ($self->exists_index('ANON' . $idx)) { $idx++ } |
141 | $name = 'ANON' . $idx; |
142 | } |
e1bef8b9 |
143 | $index->table($self); |
00e28941 |
144 | $self->$orig($name, $index); |
145 | return $self->get_index($name); |
c27fec89 |
146 | } |
e1bef8b9 |
147 | |
00e28941 |
148 | around add_sequence(Sequence $sequence does coerce) { |
149 | $self->$orig($sequence->name, $sequence); |
150 | return $self->get_sequence($sequence->name); |
151 | } |
51700db2 |
152 | |
e2b6425f |
153 | multi method primary_key { |
154 | my $constraints = $self->constraints; |
c3ec5829 |
155 | for my $key ($constraints->Keys) { |
156 | my $val = $constraints->FETCH($key); |
157 | return $val if $val->type eq 'PRIMARY KEY'; |
e2b6425f |
158 | } |
c3ec5829 |
159 | return; |
e2b6425f |
160 | } |
161 | |
0a7ce17e |
162 | multi method primary_key(Str $column) { |
163 | die "Column $column does not exist!" unless $self->exists_column($column); |
164 | $self->get_column($column)->is_primary_key(1); |
e2b6425f |
165 | |
166 | my $primary_key = $self->primary_key; |
167 | unless (defined $primary_key) { |
a4eab010 |
168 | $primary_key = SQL::Translator::Object::Constraint->new( type => 'PRIMARY KEY' ); |
e2b6425f |
169 | $self->add_constraint($primary_key); |
170 | } |
e1f95352 |
171 | $primary_key->add_column({ name => $column }) unless $primary_key->exists_column($column); |
e2b6425f |
172 | return $primary_key; |
0a7ce17e |
173 | } |
b750d2f1 |
174 | |
160f1f55 |
175 | multi method order(Int $order) { $self->_order($order); } |
176 | multi method order { |
177 | my $order = $self->_order; |
178 | unless (defined $order && $order) { |
179 | my $tables = Tie::IxHash->new( map { $_->name => $_ } $self->schema->get_tables ); |
180 | $order = $tables->Indices($self->name) || 0; $order++; |
181 | $self->_order($order); |
182 | } |
183 | return $order; |
184 | } |
185 | |
5e41f308 |
186 | method is_valid { return $self->has_columns ? 1 : undef } |
079f0c78 |
187 | |
40fb14a9 |
188 | before name($name?) { die "Can't use table name $name, table already exists" if $name && $self->schema->exists_table($name) && $name ne $self->name } |
079f0c78 |
189 | |
bebe11d5 |
190 | around remove_column(Column|Str $column, Int :$cascade = 0) { |
191 | my $name = is_Column($column) ? $column->name : $column; |
192 | die "Can't drop non-existant column " . $name unless $self->exists_column($name); |
193 | $self->$orig($name); |
40fb14a9 |
194 | } |
195 | |
bebe11d5 |
196 | around remove_index(Index|Str $index) { |
197 | my $name = is_Index($index) ? $index->name : $index; |
198 | die "Can't drop non-existant index " . $name unless $self->exists_index($name); |
199 | $self->$orig($name); |
1dde2bfe |
200 | } |
201 | |
bebe11d5 |
202 | around remove_constraint(Constraint|Str $constraint) { |
203 | my $name = is_Constraint($constraint) ? $constraint->name : $constraint; |
204 | die "Can't drop non-existant constraint " . $name unless $self->exists_constraint($name); |
205 | $self->$orig($name); |
1dde2bfe |
206 | } |
46ad29bb |
207 | |
208 | around BUILDARGS(ClassName $self: @args) { |
209 | my $args = $self->$orig(@args); |
210 | |
82e209aa |
211 | my $fields = delete $args->{fields} || []; |
212 | $fields = ref($fields) eq 'ARRAY' ? $fields : [ $fields ]; |
213 | my $ix_hash = Tie::IxHash->new(); |
214 | $ix_hash->STORE($_, SQL::Translator::Object::Column->new( name => $_ )) for @$fields; |
215 | $args->{columns} = $ix_hash; |
46ad29bb |
216 | |
217 | return $args; |
218 | } |
4f4fd192 |
219 | } |