SQLT::Parser::PostgreSQL parses table def with default values
[dbsrgits/SQL-Translator.git] / lib / SQL / Translator / Schema / Object.pm
CommitLineData
b6a880d1 1package SQL::Translator::Schema::Object;
2
b6a880d1 3=pod
4
5=head1 NAME
6
7SQL::Translator::Schema::Object - Base class SQL::Translator Schema objects.
8
9=head1 SYNOPSIS
10
11=head1 DESCSIPTION
12
9371be50 13Base class for Schema objects. Sub classes L<Class::Base> and adds the following
ea93df61 14extra functionality.
b6a880d1 15
16=cut
17
18use strict;
f27f9229 19use warnings;
b6a880d1 20use Class::Base;
9371be50 21use base 'Class::Data::Inheritable';
b6a880d1 22use base 'Class::Base';
7db5f121 23use Class::MakeMethods::Utility::Ref qw( ref_compare );
b6a880d1 24
0c04c5a2 25our $VERSION = '1.59';
11ad2df9 26
da06ac74 27
9371be50 28=head1 Construction
b6a880d1 29
4faaaac6 30Derived classes should declare their attributes using the C<_attributes>
9371be50 31method. They can then inherit the C<init> method from here which will call
32accessors of the same name for any values given in the hash passed to C<new>.
33Note that you will have to impliment the accessors your self and we expect perl
34style methods; call with no args to get and with arg to set.
35
36e.g. If we setup our class as follows;
37
38 package SQL::Translator::Schema::Table;
39 use base qw/SQL::Translator::Schema::Object/;
ea93df61 40
9371be50 41 __PACKAGE__->_attributes( qw/schema name/ );
42
43 sub name { ... }
44 sub schema { ... }
45
46Then we can construct it with
47
ea93df61 48 my $table = SQL::Translator::Schema::Table->new(
9371be50 49 schema => $schema,
50 name => 'foo',
51 );
52
53and init will call C<< $table->name("foo") >> and C<< $table->schema($schema) >>
54to set it up. Any undefined args will be ignored.
55
56Multiple calls to C<_attributes> are cumulative and sub classes will inherit
57their parents attribute names.
58
59This is currently experimental, but will hopefull go on to form an introspection
60API for the Schema objects.
61
62=cut
63
64
65__PACKAGE__->mk_classdata("__attributes");
b1789409 66
67# Define any global attributes here
ea93df61 68__PACKAGE__->__attributes([qw/extra/]);
9371be50 69
70# Set the classes attribute names. Multiple calls are cumulative.
71# We need to be careful to create a new ref so that all classes don't end up
72# with the same ref and hence the same attributes!
73sub _attributes {
74 my $class = shift;
75 if (@_) { $class->__attributes( [ @{$class->__attributes}, @_ ] ); }
76 return @{$class->__attributes};
77}
78
79# Call accessors for any args in hashref passed
80sub init {
81 my ( $self, $config ) = @_;
ea93df61 82
9371be50 83 for my $arg ( $self->_attributes ) {
84 next unless defined $config->{$arg};
ea93df61 85 defined $self->$arg( $config->{$arg} ) or return;
9371be50 86 }
87
88 return $self;
89}
90
b1789409 91sub extra {
92
93=pod
94
95=head1 Global Attributes
96
97The following attributes are defined here, therefore all schema objects will
98have them.
99
100=head2 extra
101
102Get or set the objects "extra" attibutes (e.g., "ZEROFILL" for MySQL fields).
24324d76 103Call with no args to get all the extra data.
104Call with a single name arg to get the value of the named extra attribute,
105returned as a scalar. Call with a hash or hashref to set extra attributes.
106Returns a hash or a hashref.
b1789409 107
108 $field->extra( qualifier => 'ZEROFILL' );
ea93df61 109
24324d76 110 $qualifier = $field->extra('qualifier');
ea93df61 111
24324d76 112 %extra = $field->extra;
113 $extra = $field->extra;
ea93df61 114
b1789409 115=cut
116
117 my $self = shift;
24324d76 118 @_ = %{$_[0]} if ref $_[0] eq "HASH";
119 my $extra = $self->{'extra'} ||= {};
b1789409 120
ea93df61 121 if (@_==1) {
24324d76 122 return exists($extra->{$_[0]}) ? $extra->{$_[0]} : undef ;
b1789409 123 }
24324d76 124 elsif (@_) {
125 my %args = @_;
126 while ( my ( $key, $value ) = each %args ) {
127 $extra->{$key} = $value;
128 }
129 }
ea93df61 130
24324d76 131 return wantarray ? %$extra : $extra;
b1789409 132}
9371be50 133
12018c09 134sub remove_extra {
135
136=head2 remove_extra
137
138L</extra> can only be used to get or set "extra" attributes but not to
139remove some. Call with no args to remove all extra attributes that
140have been set before. Call with a list of key names to remove
141certain extra attributes only.
142
143 # remove all extra attributes
ea93df61 144 $field->remove_extra();
145
12018c09 146 # remove timezone and locale attributes only
147 $field->remove_extra(qw/timezone locale/);
148
149=cut
150
151 my ( $self, @keys ) = @_;
152 unless (@keys) {
153 $self->{'extra'} = {};
154 }
155 else {
156 delete $self->{'extra'}{$_} for @keys;
157 }
158}
a9a72385 159
a9a72385 160sub equals {
161
162=pod
163
164=head2 equals
165
166Determines if this object is the same as another.
167
168 my $isIdentical = $object1->equals( $object2 );
169
170=cut
171
172 my $self = shift;
173 my $other = shift;
ea93df61 174
a9a72385 175 return 0 unless $other;
57059659 176 return 1 if overload::StrVal($self) eq overload::StrVal($other);
a9a72385 177 return 0 unless $other->isa( __PACKAGE__ );
178 return 1;
179}
180
7db5f121 181sub _compare_objects {
ea93df61 182 my $self = shift;
183 my $obj1 = shift;
184 my $obj2 = shift;
185 my $result = (ref_compare($obj1, $obj2) == 0);
186# if ( !$result ) {
187# use Carp qw(cluck);
188# cluck("How did I get here?");
189# use Data::Dumper;
190# $Data::Dumper::Maxdepth = 1;
191# print "obj1: ", Dumper($obj1), "\n";
192# print "obj2: ", Dumper($obj2), "\n";
193# }
194 return $result;
a9a72385 195}
196
9371be50 1971;
b6a880d1 198
199=pod
200
11ad2df9 201=head1 SEE ALSO
202
203=head1 TODO
204
205=head1 BUGS
206
b6a880d1 207=head1 AUTHOR
208
ea93df61 209Ken Youens-Clark E<lt>kclark@cpan.orgE<gt>,
c3b0b535 210Mark Addison E<lt>mark.addison@itn.co.ukE<gt>.
b6a880d1 211
212=cut