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