package DBIx::DBSchema;
use strict;
-use vars qw(@ISA $VERSION);
+use vars qw(@ISA $VERSION $DEBUG);
#use Exporter;
-use DBI;
use Storable;
-use DBIx::DBSchema::_util qw(_load_driver);
-use DBIx::DBSchema::Table;
+use DBIx::DBSchema::_util qw(_load_driver _dbh);
+use DBIx::DBSchema::Table 0.03;
use DBIx::DBSchema::Column;
use DBIx::DBSchema::ColGroup::Unique;
use DBIx::DBSchema::ColGroup::Index;
#@ISA = qw(Exporter);
@ISA = ();
-$VERSION = "0.28";
+$VERSION = "0.31";
+$DEBUG = 0;
=head1 NAME
=cut
sub new_odbc {
- my($proto, $dbh) = (shift, shift);
- $dbh = DBI->connect( $dbh, @_ ) or die $DBI::errstr unless ref($dbh);
+ my($proto, $dbh) = ( shift, _dbh(@_) );
$proto->new(
map { new_odbc DBIx::DBSchema::Table $dbh, $_ } _tables_from_dbh($dbh)
);
=cut
sub new_native {
- my($proto, $dbh) = (shift, shift);
- $dbh = DBI->connect( $dbh, @_ ) or die $DBI::errstr unless ref($dbh);
+ my($proto, $dbh) = (shift, _dbh(@_) );
$proto->new(
map { new_native DBIx::DBSchema::Table ( $dbh, $_ ) } _tables_from_dbh($dbh)
);
=cut
sub sql {
- my($self, $dbh) = (shift, shift);
- my $created_dbh = 0;
- unless ( ref($dbh) || ! @_ ) {
- $dbh = DBI->connect( $dbh, @_ ) or die $DBI::errstr;
- $created_dbh = 1;
+ my($self, $dbh) = ( shift, _dbh(@_) );
+ map { $self->table($_)->sql_create_table($dbh); } $self->tables;
+}
+
+=item sql_update_schema PROTOTYPE_SCHEMA [ DATABASE_HANDLE | DATA_SOURCE [ USERNAME PASSWORD [ ATTR ] ] ]
+
+Returns a list of SQL statements to update this schema so that it is idential
+to the provided prototype schema, also a DBIx::DBSchema object.
+
+ #Optionally, the data source can be specified by passing an open DBI database
+ #handle, or by passing the DBI data source name, username and password.
+ #
+ #If passed a DBI data source (or handle) such as `DBI:mysql:database' or
+ #`DBI:Pg:dbname=database', will use syntax specific to that database engine.
+ #Currently supported databases are MySQL and PostgreSQL.
+ #
+ #If not passed a data source (or handle), or if there is no driver for the
+ #specified database, will attempt to use generic SQL syntax.
+
+Right now this method knows how to add new tables and alter existing tables.
+It doesn't know how to drop tables yet.
+
+See L<DBIx::DBSchema::Table/sql_alter_table>,
+L<DBIx::DBSchema::Column/sql_add_coumn> and
+L<DBIx::DBSchema::Column/sql_alter_column> for additional specifics and
+limitations.
+
+=cut
+
+#gosh, false laziness w/DBSchema::Table::sql_alter_schema
+
+sub sql_update_schema {
+ my($self, $new, $dbh) = ( shift, shift, _dbh(@_) );
+
+ my @r = ();
+
+ foreach my $table ( $new->tables ) {
+
+ if ( $self->table($table) ) {
+
+ warn "$table exists\n" if $DEBUG > 1;
+
+ push @r,
+ $self->table($table)->sql_alter_table( $new->table($table), $dbh );
+
+ } else {
+
+ warn "table $table does not exist.\n" if $DEBUG;
+
+ push @r,
+ $new->table($table)->sql_create_table( $dbh );
+
+ }
+
}
- my @r = map { $self->table($_)->sql_create_table($dbh); } $self->tables;
- $dbh->disconnect if $created_dbh;
+
+ # should eventually drop tables not in $new
+
+ warn join("\n", @r). "\n"
+ if $DEBUG;
+
@r;
+
+}
+
+=item update_schema PROTOTYPE_SCHEMA, DATABASE_HANDLE | DATA_SOURCE [ USERNAME PASSWORD [ ATTR ] ]
+
+Same as sql_update_schema, except actually runs the SQL commands to update
+the schema. Throws a fatal error if any statement fails.
+
+=cut
+
+sub update_schema {
+ my($self, $new, $dbh) = ( shift, shift, _dbh(@_) );
+
+ foreach my $statement ( $self->sql_update_schema( $new, $dbh ) ) {
+ $dbh->do( $statement )
+ or die "Error: ". $dbh->errstr. "\n executing: $statement";
+ }
+
}
=item pretty_print
=back
-=head1 AUTHOR
+=head1 AUTHORS
Ivan Kohler <ivan-dbix-dbschema@420.am>
Charles Shapiro <charles.shapiro@numethods.com> and Mitchell Friedman
<mitchell.friedman@numethods.com> contributed the start of a Sybase driver.
+Daniel Hanks <hanksdc@about-inc.com> contributed the Oracle driver.
+
+Jesse Vincent contributed the SQLite driver.
+
+=head1 CONTRIBUTIONS
+
+Contributions are welcome! I'm especially keen on any interest in the first
+three items/projects below under BUGS.
+
=head1 COPYRIGHT
-Copyright (c) 2000-2005 Ivan Kohler
+Copyright (c) 2000-2006 Ivan Kohler
Copyright (c) 2000 Mail Abuse Prevention System LLC
All rights reserved.
This program is free software; you can redistribute it and/or modify it under
=head1 BUGS
+Indices are not stored by name. Index representation could use an overhaul.
+
+Multiple primary keys are not yet supported.
+
+Foreign keys and other constraints are not yet supported.
+
+Eventually it would be nice to have additional transformations (deleted,
+modified columns, added/modified/indices (probably need em named first),
+added/deleted tables
+
+Need to port and test with additional databases
+
Each DBIx::DBSchema object should have a name which corresponds to its name
within the SQL database engine (DBI data source).
Perhaps pretty_read should eval column types so that we can use DBI
qw(:sql_types) here instead of externally.
+sql CREATE TABLE output should convert integers
+(i.e. use DBI qw(:sql_types);) to local types using DBI->type_info plus a hash
+to fudge things
+
+sql_update_schema doesn't drop tables yet.
+
=head1 SEE ALSO
L<DBIx::DBSchema::Table>, L<DBIx::DBSchema::ColGroup>,