1 package DBIx::DBSchema::Column;
4 use vars qw(@ISA $VERSION);
7 use DBIx::DBSchema::_util qw(_load_driver);
16 DBIx::DBSchema::Column - Column objects
20 use DBIx::DBSchema::Column;
22 #named params with a hashref (preferred)
23 $column = new DBIx::DBSchema::Column ( {
24 'name' => 'column_name',
33 $column = new DBIx::DBSchema::Column ( $name, $sql_type, $nullability, $length, $default, $local );
35 $name = $column->name;
36 $column->name( 'name' );
38 $sql_type = $column->type;
39 $column->type( 'sql_type' );
41 $null = $column->null;
42 $column->null( 'NULL' );
43 $column->null( 'NOT NULL' );
46 $length = $column->length;
47 $column->length( '10' );
48 $column->length( '8,2' );
50 $default = $column->default;
51 $column->default( 'Roo' );
53 $sql_line = $column->line;
54 $sql_line = $column->line($datasrc);
56 $sql_add_column = $column->sql_add_column;
57 $sql_add_column = $column->sql_add_column($datasrc);
61 DBIx::DBSchema::Column objects represent columns in tables (see
62 L<DBIx::DBSchema::Table>).
70 =item new [ name [ , type [ , null [ , length [ , default [ , local ] ] ] ] ] ]
72 Creates a new DBIx::DBSchema::Column object. Takes a hashref of named
73 parameters, or a list. B<name> is the name of the column. B<type> is the SQL
74 data type. B<null> is the nullability of the column (intrepreted using Perl's
75 rules for truth, with one exception: `NOT NULL' is false). B<length> is the
76 SQL length of the column. B<default> is the default value of the column.
77 B<local> is reserved for database-specific information.
83 my $class = ref($proto) || $proto;
89 $self = { map { $_ => shift } qw(name type null length default local) };
92 #croak "Illegal name: ". $self->{'name'}
93 # if grep $self->{'name'} eq $_, @reserved_words;
95 $self->{'null'} =~ s/^NOT NULL$//i;
96 $self->{'null'} = 'NULL' if $self->{'null'};
98 bless ($self, $class);
104 Returns or sets the column name.
110 if ( defined($value) ) {
111 #croak "Illegal name: $name" if grep $name eq $_, @reserved_words;
112 $self->{'name'} = $value;
120 Returns or sets the column type.
126 if ( defined($value) ) {
127 $self->{'type'} = $value;
135 Returns or sets the column null flag (the empty string is equivalent to
142 if ( defined($value) ) {
143 $value =~ s/^NOT NULL$//i;
144 $value = 'NULL' if $value;
145 $self->{'null'} = $value;
151 =item length [ LENGTH ]
153 Returns or sets the column length.
159 if ( defined($value) ) {
160 $self->{'length'} = $value;
166 =item default [ LOCAL ]
168 Returns or sets the default value.
174 if ( defined($value) ) {
175 $self->{'default'} = $value;
182 =item local [ LOCAL ]
184 Returns or sets the database-specific field.
190 if ( defined($value) ) {
191 $self->{'local'} = $value;
197 =item table_obj [ TABLE_OBJ ]
199 Returns or sets the table object (see L<DBIx::DBSchema::Table>). Typically
200 set internally when a column object is added to a table object.
206 if ( defined($value) ) {
207 $self->{'table_obj'} = $value;
209 $self->{'table_obj'};
215 Returns the table name, or the empty string if this column has not yet been
222 $self->{'table_obj'} ? $self->{'table_obj'}->name : '';
225 =item line [ DATABASE_HANDLE | DATA_SOURCE [ USERNAME PASSWORD [ ATTR ] ] ]
227 Returns an SQL column definition.
229 The data source can be specified by passing an open DBI database handle, or by
230 passing the DBI data source name, username and password.
232 Although the username and password are optional, it is best to call this method
233 with a database handle or data source including a valid username and password -
234 a DBI connection will be opened and the quoting and type mapping will be more
237 If passed a DBI data source (or handle) such as `DBI:mysql:database' or
238 `DBI:Pg:dbname=database', will use syntax specific to that database engine.
239 Currently supported databases are MySQL and PostgreSQL. Non-standard syntax
240 for other engines (if applicable) may also be supported in the future.
245 my($self,$dbh) = (shift, shift);
248 unless ( ref($dbh) || ! @_ ) {
249 $dbh = DBI->connect( $dbh, @_ ) or die $DBI::errstr;
250 my $gratuitous = $DBI::errstr; #surpress superfluous `used only once' error
253 my $driver = $dbh ? _load_driver($dbh) : '';
256 %typemap = eval "\%DBIx::DBSchema::DBD::${driver}::typemap" if $driver;
257 my $type = defined( $typemap{uc($self->type)} )
258 ? $typemap{uc($self->type)}
261 my $null = $self->null;
264 if ( defined($self->default) && $self->default ne ''
266 # false laziness: nicked from FS::Record::_quote
267 && ( $self->default !~ /^\-?\d+(\.\d+)?$/
268 || $type =~ /(char|binary|blob|text)$/i
271 $default = $dbh->quote($self->default);
273 $default = $self->default;
276 #this should be a callback into the driver
277 if ( $driver eq 'mysql' ) { #yucky mysql hack
278 $null ||= "NOT NULL";
279 $self->local('AUTO_INCREMENT') if uc($self->type) eq 'SERIAL';
280 } elsif ( $driver =~ /^(?:Pg|SQLite)$/ ) { #yucky Pg/SQLite hack
281 $null ||= "NOT NULL";
287 $type. ( ( defined($self->length) && $self->length )
288 ? '('.$self->length.')'
292 ( ( defined($default) && $default ne '' )
293 ? 'DEFAULT '. $default
296 ( ( $driver eq 'mysql' && defined($self->local) )
301 $dbh->disconnect if $created_dbh;
308 Returns a list of SQL statements to add this column.
310 The data source can be specified by passing an open DBI database handle, or by
311 passing the DBI data source name, username and password.
313 Although the username and password are optional, it is best to call this method
314 with a database handle or data source including a valid username and password -
315 a DBI connection will be opened and the quoting and type mapping will be more
318 If passed a DBI data source (or handle) such as `DBI:mysql:database', will use
319 PostgreSQL-specific syntax. Non-standard syntax for other engines (if
320 applicable) may also be supported in the future.
325 my($self, $dbh) = (shift, shift);
327 die "$self: this column is not assigned to a table"
328 unless $self->table_name;
330 #false laziness w/Table::sql_create_driver
332 unless ( ref($dbh) || ! @_ ) {
333 $dbh = DBI->connect( $dbh, @_ ) or die $DBI::errstr;
334 my $gratuitous = $DBI::errstr; #surpress superfluous `used only once' error
338 my $driver = $dbh ? _load_driver($dbh) : '';
345 if ( $driver eq 'Pg' && $self->type eq 'serial' ) {
346 $real_type = 'serial';
349 push @after_add, sub {
350 my($table, $column) = @_;
352 #needs more work for old Pg
355 if ( $dbh->{'pg_server_version'} > 70300 ) {
356 $nextval = "nextval('public.${table}_${column}_seq'::text)";
358 $nextval = "nextval('${table}_${column}_seq'::text)";
362 "ALTER TABLE $table ALTER COLUMN $column SET DEFAULT $nextval",
363 "CREATE SEQUENCE ${table}_${column}_seq",
364 "UPDATE $table SET $column = $nextval WHERE $column IS NULL",
365 #"ALTER TABLE $table ALTER $column SET NOT NULL",
372 my $real_null = undef;
373 if ( $driver eq 'Pg' && ! $self->null ) {
374 $real_null = $self->null;
377 if ( $dbh->{'pg_server_version'} > 70300 ) {
379 push @after_add, sub {
380 my($table, $column) = @_;
381 "ALTER TABLE $table ALTER $column SET NOT NULL";
386 push @after_add, sub {
387 my($table, $column) = @_;
388 "UPDATE pg_attribute SET attnotnull = TRUE ".
389 " WHERE attname = '$column' ".
390 " AND attrelid = ( SELECT oid FROM pg_class WHERE relname = '$table' )";
398 my $table = $self->table_name;
399 my $column = $self->name;
401 push @r, "ALTER TABLE $table ADD COLUMN ". $self->line($dbh);
403 push @r, &{$_}($table, $column) foreach @after_add;
405 push @r, "ALTER TABLE $table ADD PRIMARY KEY ( ".
406 $self->table_obj->primary_key. " )"
407 if $self->name eq $self->table_obj->primary_key;
409 $self->type($real_type) if $real_type;
410 $self->null($real_null) if defined $real_null;
412 $dbh->disconnect if $created_dbh;
422 Ivan Kohler <ivan-dbix-dbschema@420.am>
426 Copyright (c) 2000-2005 Ivan Kohler
428 This program is free software; you can redistribute it and/or modify it under
429 the same terms as Perl itself.
433 line() and sql_add_column() hav database-specific foo that should be abstracted
434 into the DBIx::DBSchema:DBD:: modules.
438 L<DBIx::DBSchema::Table>, L<DBIx::DBSchema>, L<DBIx::DBSchema::DBD>, L<DBI>