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) && ref($dbh)
265 # false laziness: nicked from FS::Record::_quote
266 && ( $self->default !~ /^\-?\d+(\.\d+)?$/
267 || $type =~ /(char|binary|blob|text)$/i
270 $default = $dbh->quote($self->default);
272 $default = $self->default;
275 #this should be a callback into the driver
276 if ( $driver eq 'mysql' ) { #yucky mysql hack
277 $null ||= "NOT NULL";
278 $self->local('AUTO_INCREMENT') if uc($self->type) eq 'SERIAL';
279 } elsif ( $driver =~ /^(?:Pg|SQLite)$/ ) { #yucky Pg/SQLite hack
280 $null ||= "NOT NULL";
286 $type. ( ( defined($self->length) && $self->length )
287 ? '('.$self->length.')'
291 ( ( defined($default) && $default ne '' )
292 ? 'DEFAULT '. $default
295 ( ( $driver eq 'mysql' && defined($self->local) )
300 $dbh->disconnect if $created_dbh;
307 Returns a list of SQL statements to add this column.
309 The data source can be specified by passing an open DBI database handle, or by
310 passing the DBI data source name, username and password.
312 Although the username and password are optional, it is best to call this method
313 with a database handle or data source including a valid username and password -
314 a DBI connection will be opened and the quoting and type mapping will be more
317 If passed a DBI data source (or handle) such as `DBI:Pg:dbname=database', will
318 use PostgreSQL-specific syntax. Non-standard syntax for other engines (if
319 applicable) may also be supported in the future.
324 my($self, $dbh) = (shift, shift);
326 die "$self: this column is not assigned to a table"
327 unless $self->table_name;
329 #false laziness w/Table::sql_create_driver
331 unless ( ref($dbh) || ! @_ ) {
332 $dbh = DBI->connect( $dbh, @_ ) or die $DBI::errstr;
333 my $gratuitous = $DBI::errstr; #surpress superfluous `used only once' error
337 my $driver = $dbh ? _load_driver($dbh) : '';
344 if ( $driver eq 'Pg' && $self->type eq 'serial' ) {
345 $real_type = 'serial';
348 push @after_add, sub {
349 my($table, $column) = @_;
351 #needs more work for old Pg
354 if ( $dbh->{'pg_server_version'} > 70300 ) {
355 $nextval = "nextval('public.${table}_${column}_seq'::text)";
357 $nextval = "nextval('${table}_${column}_seq'::text)";
361 "ALTER TABLE $table ALTER COLUMN $column SET DEFAULT $nextval",
362 "CREATE SEQUENCE ${table}_${column}_seq",
363 "UPDATE $table SET $column = $nextval WHERE $column IS NULL",
364 #"ALTER TABLE $table ALTER $column SET NOT NULL",
371 my $real_null = undef;
372 if ( $driver eq 'Pg' && ! $self->null ) {
373 $real_null = $self->null;
376 if ( $dbh->{'pg_server_version'} > 70300 ) {
378 push @after_add, sub {
379 my($table, $column) = @_;
380 "ALTER TABLE $table ALTER $column SET NOT NULL";
385 push @after_add, sub {
386 my($table, $column) = @_;
387 "UPDATE pg_attribute SET attnotnull = TRUE ".
388 " WHERE attname = '$column' ".
389 " AND attrelid = ( SELECT oid FROM pg_class WHERE relname = '$table' )";
397 my $table = $self->table_name;
398 my $column = $self->name;
400 push @r, "ALTER TABLE $table ADD COLUMN ". $self->line($dbh);
402 push @r, &{$_}($table, $column) foreach @after_add;
404 push @r, "ALTER TABLE $table ADD PRIMARY KEY ( ".
405 $self->table_obj->primary_key. " )"
406 if $self->name eq $self->table_obj->primary_key;
408 $self->type($real_type) if $real_type;
409 $self->null($real_null) if defined $real_null;
411 $dbh->disconnect if $created_dbh;
421 Ivan Kohler <ivan-dbix-dbschema@420.am>
425 Copyright (c) 2000-2005 Ivan Kohler
427 This program is free software; you can redistribute it and/or modify it under
428 the same terms as Perl itself.
432 line() and sql_add_column() hav database-specific foo that should be abstracted
433 into the DBIx::DBSchema:DBD:: modules.
437 L<DBIx::DBSchema::Table>, L<DBIx::DBSchema>, L<DBIx::DBSchema::DBD>, L<DBI>