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; |
4f4fd192 |
5 | use SQL::Translator::Types qw(Column Constraint Index Schema Sequence); |
46ad29bb |
6 | use SQL::Translator::Object::Column; |
e2b6425f |
7 | use SQL::Translator::Object::Constraint; |
0c4b09d0 |
8 | clean; |
9 | |
10 | use overload |
11 | '""' => sub { shift->name }, |
12 | 'bool' => sub { $_[0]->name || $_[0] }, |
13 | fallback => 1, |
14 | ; |
15 | |
4f4fd192 |
16 | has 'name' => ( |
17 | is => 'rw', |
18 | isa => Str, |
19 | required => 1 |
20 | ); |
21 | |
22 | has 'columns' => ( |
720dcdc3 |
23 | traits => ['Hash'], |
4f4fd192 |
24 | is => 'rw', |
25 | isa => HashRef[Column], |
720dcdc3 |
26 | handles => { |
27 | exists_column => 'exists', |
28 | column_ids => 'keys', |
29 | get_columns => 'values', |
30 | get_column => 'get', |
31 | add_column => 'set', |
40fb14a9 |
32 | remove_column => 'delete', |
452c34e6 |
33 | clear_columns => 'clear', |
4f4fd192 |
34 | }, |
35 | default => sub { my %hash = (); tie %hash, 'Tie::IxHash'; return \%hash }, |
36 | ); |
37 | |
38 | has 'indexes' => ( |
720dcdc3 |
39 | traits => ['Hash'], |
4f4fd192 |
40 | is => 'rw', |
41 | isa => HashRef[Index], |
720dcdc3 |
42 | handles => { |
43 | exists_index => 'exists', |
44 | index_ids => 'keys', |
45 | get_indices => 'values', |
46 | get_index => 'get', |
47 | add_index => 'set', |
48020fcf |
48 | remove_index => 'delete', |
4f4fd192 |
49 | }, |
2e7ac234 |
50 | default => sub { my %hash = (); tie %hash, 'Tie::IxHash'; return \%hash }, |
4f4fd192 |
51 | ); |
52 | |
53 | has 'constraints' => ( |
720dcdc3 |
54 | traits => ['Hash'], |
4f4fd192 |
55 | is => 'rw', |
56 | isa => HashRef[Constraint], |
720dcdc3 |
57 | handles => { |
58 | exists_constraint => 'exists', |
59 | constraint_ids => 'keys', |
60 | get_constraints => 'values', |
61 | get_constraint => 'get', |
62 | add_constraint => 'set', |
bebe11d5 |
63 | remove_constraint => 'delete', |
4f4fd192 |
64 | }, |
49063029 |
65 | default => sub { my %hash = (); tie %hash, 'Tie::IxHash'; return \%hash }, |
4f4fd192 |
66 | ); |
67 | |
68 | has 'sequences' => ( |
720dcdc3 |
69 | traits => ['Hash'], |
4f4fd192 |
70 | is => 'rw', |
71 | isa => HashRef[Sequence], |
720dcdc3 |
72 | handles => { |
73 | exists_sequence => 'exists', |
74 | sequence_ids => 'keys', |
75 | get_sequences => 'values', |
76 | get_sequence => 'get', |
77 | add_sequence => 'set', |
f5ced714 |
78 | remove_sequence => 'delete', |
4f4fd192 |
79 | }, |
2e7ac234 |
80 | default => sub { my %hash = (); tie %hash, 'Tie::IxHash'; return \%hash }, |
4f4fd192 |
81 | ); |
f78a484a |
82 | |
2850baeb |
83 | has 'schema' => ( |
4f4fd192 |
84 | is => 'rw', |
2850baeb |
85 | isa => Schema, |
86 | weak_ref => 1, |
4f4fd192 |
87 | ); |
49063029 |
88 | |
2850baeb |
89 | has 'temporary' => ( |
b750d2f1 |
90 | is => 'rw', |
2850baeb |
91 | isa => Bool, |
92 | default => 0 |
b750d2f1 |
93 | ); |
94 | |
160f1f55 |
95 | has '_order' => ( |
96 | is => 'rw', |
97 | isa => Int, |
98 | ); |
99 | |
de1e817e |
100 | around add_column(Column $column does coerce) { |
101 | die "Can't use column name " . $column->name if $self->exists_column($column->name) || $column->name eq ''; |
e1bef8b9 |
102 | $column->table($self); |
de1e817e |
103 | return $self->$orig($column->name, $column); |
104 | } |
e1bef8b9 |
105 | |
78963c00 |
106 | around add_constraint(Constraint $constraint does coerce) { |
f34b818d |
107 | my $name = $constraint->name; |
108 | if ($name eq '') { |
c27fec89 |
109 | my $idx = 0; |
110 | while ($self->exists_constraint('ANON' . $idx)) { $idx++ } |
111 | $name = 'ANON' . $idx; |
f34b818d |
112 | } |
e1bef8b9 |
113 | $constraint->table($self); |
aa20eb7f |
114 | if ($constraint->has_type && $constraint->type eq 'PRIMARY KEY') { |
115 | $self->get_column($_)->is_primary_key(1) for $constraint->column_ids; |
116 | } |
f34b818d |
117 | $self->$orig($name, $constraint) |
118 | } |
e1bef8b9 |
119 | |
706009e5 |
120 | around add_index(Index $index does coerce) { |
c27fec89 |
121 | my $name = $index->name; |
122 | if ($name eq '') { |
123 | my $idx = 0; |
124 | while ($self->exists_index('ANON' . $idx)) { $idx++ } |
125 | $name = 'ANON' . $idx; |
126 | } |
e1bef8b9 |
127 | $index->table($self); |
c27fec89 |
128 | $self->$orig($name, $index) |
129 | } |
e1bef8b9 |
130 | |
78963c00 |
131 | around add_sequence(Sequence $sequence does coerce) { $self->$orig($sequence->name, $sequence) } |
51700db2 |
132 | |
e2b6425f |
133 | multi method primary_key { |
134 | my $constraints = $self->constraints; |
135 | for my $key (keys %$constraints) { |
136 | return $constraints->{$key} if $constraints->{$key}{type} eq 'PRIMARY KEY'; |
137 | } |
138 | return undef; |
139 | } |
140 | |
0a7ce17e |
141 | multi method primary_key(Str $column) { |
142 | die "Column $column does not exist!" unless $self->exists_column($column); |
143 | $self->get_column($column)->is_primary_key(1); |
e2b6425f |
144 | |
145 | my $primary_key = $self->primary_key; |
146 | unless (defined $primary_key) { |
147 | $primary_key = SQL::Translator::Object::Constraint->new({ type => 'PRIMARY KEY' }); |
148 | $self->add_constraint($primary_key); |
149 | } |
eea42e0a |
150 | $primary_key->add_field({ name => $column }) unless $primary_key->exists_column($column); ## FIX ME, change back to add_column once around add_column(coerce .. ) works |
e2b6425f |
151 | return $primary_key; |
0a7ce17e |
152 | } |
b750d2f1 |
153 | |
160f1f55 |
154 | multi method order(Int $order) { $self->_order($order); } |
155 | multi method order { |
156 | my $order = $self->_order; |
157 | unless (defined $order && $order) { |
158 | my $tables = Tie::IxHash->new( map { $_->name => $_ } $self->schema->get_tables ); |
159 | $order = $tables->Indices($self->name) || 0; $order++; |
160 | $self->_order($order); |
161 | } |
162 | return $order; |
163 | } |
164 | |
079f0c78 |
165 | method is_valid { return $self->get_columns ? 1 : undef } |
079f0c78 |
166 | |
40fb14a9 |
167 | 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 |
168 | |
bebe11d5 |
169 | around remove_column(Column|Str $column, Int :$cascade = 0) { |
170 | my $name = is_Column($column) ? $column->name : $column; |
171 | die "Can't drop non-existant column " . $name unless $self->exists_column($name); |
172 | $self->$orig($name); |
40fb14a9 |
173 | } |
174 | |
bebe11d5 |
175 | around remove_index(Index|Str $index) { |
176 | my $name = is_Index($index) ? $index->name : $index; |
177 | die "Can't drop non-existant index " . $name unless $self->exists_index($name); |
178 | $self->$orig($name); |
1dde2bfe |
179 | } |
180 | |
bebe11d5 |
181 | around remove_constraint(Constraint|Str $constraint) { |
182 | my $name = is_Constraint($constraint) ? $constraint->name : $constraint; |
183 | die "Can't drop non-existant constraint " . $name unless $self->exists_constraint($name); |
184 | $self->$orig($name); |
1dde2bfe |
185 | } |
46ad29bb |
186 | |
187 | around BUILDARGS(ClassName $self: @args) { |
188 | my $args = $self->$orig(@args); |
189 | |
190 | my $fields = delete $args->{fields}; |
191 | |
192 | tie %{$args->{columns}}, 'Tie::IxHash'; |
193 | $args->{columns}{$_} = SQL::Translator::Object::Column->new( name => $_ ) for @$fields; |
194 | |
195 | return $args; |
196 | } |
4f4fd192 |
197 | } |