use strict;
use vars qw(@ISA $VERSION);
#use Exporter;
-#use Carp qw(verbose);
use DBI;
-use FreezeThaw qw(freeze thaw cmpStr);
+use Storable;
+use DBIx::DBSchema::_util qw(_load_driver);
use DBIx::DBSchema::Table;
use DBIx::DBSchema::Column;
use DBIx::DBSchema::ColGroup::Unique;
#@ISA = qw(Exporter);
@ISA = ();
-$VERSION = "0.13";
+$VERSION = "0.30";
=head1 NAME
it a different process. Most importantly, DBIx::DBSchema can write SQL
CREATE statements statements for different databases from a single source.
-Currently supported databases are MySQL and PostgreSQL. DBIx::DBSchema will
-attempt to use generic SQL syntax for other databases. Assistance adding
-support for other databases is welcomed.
+Currently supported databases are MySQL and PostgreSQL. Sybase support is
+partially implemented. DBIx::DBSchema will attempt to use generic SQL syntax
+for other databases. Assistance adding support for other databases is
+welcomed. See L<DBIx::DBSchema::DBD>, "Driver Writer's Guide and Base Class".
=head1 METHODS
schema that you wish to use with many different database engines. Although
primary key and (unique) index information will only be read from databases
with DBIx::DBSchema::DBD drivers (currently MySQL and PostgreSQL), import of
-column names and attributes *should* work for any database.
+column names and attributes *should* work for any database. Note that this
+method only uses "ODBC" column types; it does not require or use an ODBC
+driver.
=cut
sub load {
my($proto,$file)=@_; #use $proto ?
- open(FILE,"<$file") or die "Can't open $file: $!";
- my($string)=join('',<FILE>); #can $string have newlines? pry not?
- close FILE or die "Can't close $file: $!";
- my($self)=thaw $string;
- #no bless needed?
+
+ my $self;
+
+ #first try Storable
+ eval { $self = Storable::retrieve($file); };
+
+ if ( $@ && $@ =~ /not.*storable/i ) { #then try FreezeThaw
+ eval "use FreezeThaw;";
+ die $@ if $@;
+ open(FILE,"<$file") or die "Can't open $file: $!";
+ my $string = join('',<FILE>);
+ close FILE or die "Can't close $file: $!";
+ ($self) = FreezeThaw::thaw($string);
+ }
+
$self;
+
}
=item save FILENAME
=cut
sub save {
- my($self,$file)=@_;
- my($string)=freeze $self;
- open(FILE,">$file") or die "Can't open $file: $!";
- print FILE $string;
- close FILE or die "Can't close file: $!";
- my($check_self)=thaw $string;
- die "Verify error: Can't freeze and thaw dbdef $self"
- if (cmpStr($self,$check_self));
+ #my($self, $file) = @_;
+ Storable::nstore(@_);
}
=item addtable TABLE_OBJECT
sub sql {
my($self, $dbh) = (shift, shift);
- $dbh = DBI->connect( $dbh, @_ ) or die $DBI::errstr
- unless ref($dbh) || ! @_;
- map { $self->table($_)->sql_create_table($dbh); } $self->tables;
+ my $created_dbh = 0;
+ unless ( ref($dbh) || ! @_ ) {
+ $dbh = DBI->connect( $dbh, @_ ) or die $DBI::errstr;
+ $created_dbh = 1;
+ }
+ my @r = map { $self->table($_)->sql_create_table($dbh); } $self->tables;
+ $dbh->disconnect if $created_dbh;
+ @r;
}
=item pretty_print
). " ],\n"
#" 'index' => [ ". " ],\n"
} $self->tables
- ), "}\n";
+ ). "}\n";
}
=cut
# private subroutines
-sub _load_driver {
- my($dbh) = @_;
- my $driver;
- if ( ref($dbh) ) {
- $driver = $dbh->{Driver}->{Name};
- } else {
- $dbh =~ s/^dbi:(\w*?)(?:\((.*?)\))?://i #nicked from DBI->connect
- or '' =~ /()/; # ensure $1 etc are empty if match fails
- $driver = $1 or die "can't parse data source: $dbh";
- }
-
- #require "DBIx/DBSchema/DBD/$driver.pm";
- #$driver;
- eval 'require "DBIx/DBSchema/DBD/$driver.pm"' and $driver;
-}
-
sub _tables_from_dbh {
my($dbh) = @_;
- my $sth = $dbh->table_info or die $dbh->errstr;
+ my $driver = _load_driver($dbh);
+ my $db_catalog =
+ scalar(eval "DBIx::DBSchema::DBD::$driver->default_db_catalog");
+ my $db_schema =
+ scalar(eval "DBIx::DBSchema::DBD::$driver->default_db_schema");
+ my $sth = $dbh->table_info($db_catalog, $db_schema, '', 'TABLE')
+ or die $dbh->errstr;
#map { $_->{TABLE_NAME} } grep { $_->{TABLE_TYPE} eq 'TABLE' }
# @{ $sth->fetchall_arrayref({ TABLE_NAME=>1, TABLE_TYPE=>1}) };
map { $_->[0] } grep { $_->[1] =~ /^TABLE$/i }
=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 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
+
=head1 SEE ALSO
L<DBIx::DBSchema::Table>, L<DBIx::DBSchema::ColGroup>,
L<DBIx::DBSchema::ColGroup::Unique>, L<DBIx::DBSchema::ColGroup::Index>,
-L<DBIx::DBSchema::Column>, L<DBIx::DBSchema::DBD>, L<DBIx::DBSchema::mysql>,
-L<DBIx::DBSchema::Pg>, L<FS::Record>, L<DBI>
+L<DBIx::DBSchema::Column>, L<DBIx::DBSchema::DBD>,
+L<DBIx::DBSchema::DBD::mysql>, L<DBIx::DBSchema::DBD::Pg>, L<FS::Record>,
+L<DBI>
=cut