freeside/install/5.005/DBIx-DBSchema-0.23-5.005kludge Changes,NONE,1.1.2.1 DBSchema.pm,NONE,1.1.2.1 MANIFEST,NONE,1.1.2.1 MANIFEST.SKIP,NONE,1.1.2.1 Makefile.PL,NONE,1.1.2.1 README,NONE,1.1.2.1 TODO,NONE,1.1.2.1

ivan ivan at pouncequick.420.am
Thu Apr 29 02:40:14 PDT 2004


Update of /home/cvs/cvsroot/freeside/install/5.005/DBIx-DBSchema-0.23-5.005kludge
In directory pouncequick:/tmp/cvs-serv11497/DBIx-DBSchema-0.23-5.005kludge

Added Files:
      Tag: FREESIDE_1_4_BRANCH
	Changes DBSchema.pm MANIFEST MANIFEST.SKIP Makefile.PL README 
	TODO 
Log Message:
adding DBD::Pg and DBIx::DBSchema for 5.005 on 1.4 branch too

--- NEW FILE: MANIFEST ---
Changes
MANIFEST
MANIFEST.SKIP
README
TODO
Makefile.PL
DBSchema.pm
t/load.t
t/load-mysql.t
t/load-pg.t
DBSchema/Table.pm
DBSchema/ColGroup.pm
DBSchema/ColGroup/Index.pm
DBSchema/ColGroup/Unique.pm
DBSchema/Column.pm
DBSchema/DBD.pm
DBSchema/DBD/mysql.pm
DBSchema/DBD/Pg.pm
DBSchema/DBD/Sybase.pm

--- NEW FILE: TODO ---
port and test with additional databases

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


--- NEW FILE: Changes ---
Revision history for Perl extension DBIx::DBSchema.

0.23 Mon Feb 16 17:35:54 PST 2004
	- Update Pg dependancy to 1.32
	- Update the simple load test so it skips DBIx::DBSchema::DBD::Pg if
          DBD::Pg 1.32 is not installed.

0.22 Thu Oct 23 15:18:21 PDT 2003
	- Pg reverse-engineering fix: varchar with no limit
	- Pg needs (unreleased) DBD::Pg 1.30 (or deb 1.22-2... interesting)

0.21 Thu Sep 19 05:04:18 PDT 2002
	- Pg reverse-engineering fix: now sets default

0.20 Mon Mar  4 04:58:34 2002
	- documentation updates
	- fix Column->new when using named params
	- fix Pg driver reverse-engineering length of numeric columns:
	  translate 655362 to 10,2, etc.
	- fix Pg driver reverse-engineering of text columns (don't have a
	  length)

0.19 Tue Oct 23 08:49:12 2001
	- documentation for %typemap
	- preliminary Sybase driver from Charles Shapiro
	  <charles.shapiro at numethods.com> and Mitchell J. Friedman
	  <mitchell.friedman at numethods.com>.
	- Fix Column::line to return a scalar as documented, not a list.
	- Should finally eliminate the Use of uninitialized value at
	  ... DBIx/DBSchema/Column.pm line 251

0.18 Fri Aug 10 17:07:28 2001
	- Added Table::delcolumn
	- patch from Charles Shapiro <cshapiro at numethods.com> to add
          `ORDER BY a.attnum' to the SQL in DBIx::DBSchema::DBD::Pg::columns

0.17  Sat Jul  7 17:55:33 2001
	- Rework Table->new interface for named params
	- Fixes for Pg blobs, yay!
	- MySQL doesn't need non-standard index syntax anymore (since 3.22).
	- patch from Mark Ethan Trostler <mark at zzo.com> for generating
	  tables without indices.

0.16  Fri Jan  5 15:55:50 2001
	- Don't overflow index names.

0.15  Fri Nov 24 23:39:16 2000
	- MySQL handling of BOOL type (change to TINYINT)

0.14  Tue Oct 24 14:43:16 2000
        - MySQL handling of SERIAL type (change to INTEGER AUTO_INCREMENT)

0.13  Wed Oct 11 10:47:13 2000
        - fixed up type mapping foo, added default values, added named
          parameters to Column->new, fixed quoting of default values

0.11  Sun Sep 28 02:16:25 2000
        - oops, original verison got 0.10, so this one will get 0.11

0.01  Sun Sep 17 07:57:35 2000
	- original version; created by h2xs 1.19


--- NEW FILE: Makefile.PL ---
use ExtUtils::MakeMaker;
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
# the contents of the Makefile that is written.
WriteMakefile(
    'NAME'	=> 'DBIx::DBSchema',
    'VERSION_FROM' => 'DBSchema.pm', # finds $VERSION
    'PREREQ_PM'    => {
                        'DBI' => 0,
                        'FreezeThaw' => 0,
                      },
);

--- NEW FILE: README ---
DBIx::DBSchema

Copyright (c) 2000-2002 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
the same terms as Perl itself.

This module implements an OO-interface to database schemas.  Using this module,
you can create a database schema with an OO Perl interface.  You can read the
schema from an existing database.  You can save the schema to disk and restore
it from different process.  Most importantly, DBIx::DBSchema can write SQL
CREATE statements for different databases from a single source.

Currently supported databases are MySQL, PostgreSQL and Sybase.
DBIx::DBSchema will attempt to use generic SQL syntax for other databases.
Assistance adding support for other databases is welcomed.  See the
DBIx::DBSchema::DBD manpage, "Driver Writer's Guide and Base Class".

To install:
	perl Makefile.PL
	make
	make test # nothing substantial yet
	make install

Documentation will then be available via `man DBIx::DBSchema' or
`perldoc DBIx::DBSchema'.

Anonymous CVS access is available:
  $ export CVSROOT=":pserver:anonymous at cleanwhisker.420.am:/home/cvs/cvsroot"
  $ cvs login
  (Logging in to anonymous at cleanwhisker.420.am)
  CVS password: anonymous
  $ cvs checkout DBIx-DBSchema
as well as <http://www.420.am/cgi-bin/cvsweb/DBIx-DBSchema>.

A mailing list is available.  Send a blank message to
<ivan-dbix-dbschema-users-subscribe at 420.am>.

Homepage: <http://www.420.am/dbix-dbschema>

$Id: README,v 1.1.2.1 2004/04/29 09:40:08 ivan Exp $

--- NEW FILE: MANIFEST.SKIP ---
CVS/

--- NEW FILE: DBSchema.pm ---
package DBIx::DBSchema;

use strict;
use vars qw(@ISA $VERSION);
#use Exporter;
use Carp qw(confess);
use DBI;
use FreezeThaw qw(freeze thaw cmpStr);
use DBIx::DBSchema::Table;
use DBIx::DBSchema::Column;
use DBIx::DBSchema::ColGroup::Unique;
use DBIx::DBSchema::ColGroup::Index;

#@ISA = qw(Exporter);
@ISA = ();

$VERSION = "0.23";

=head1 NAME

DBIx::DBSchema - Database-independent schema objects

=head1 SYNOPSIS

  use DBIx::DBSchema;

  $schema = new DBIx::DBSchema @dbix_dbschema_table_objects;
  $schema = new_odbc DBIx::DBSchema $dbh;
  $schema = new_odbc DBIx::DBSchema $dsn, $user, $pass;
  $schema = new_native DBIx::DBSchema $dbh;
  $schema = new_native DBIx::DBSchema $dsn, $user, $pass;

  $schema->save("filename");
  $schema = load DBIx::DBSchema "filename";

  $schema->addtable($dbix_dbschema_table_object);

  @table_names = $schema->tables;

  $DBIx_DBSchema_table_object = $schema->table("table_name");

  @sql = $schema->sql($dbh);
  @sql = $schema->sql($dsn, $username, $password);
  @sql = $schema->sql($dsn); #doesn't connect to database - less reliable

  $perl_code = $schema->pretty_print;
  %hash = eval $perl_code;
  use DBI qw(:sql_types); $schema = pretty_read DBIx::DBSchema \%hash;

=head1 DESCRIPTION

DBIx::DBSchema objects are collections of DBIx::DBSchema::Table objects and
represent a database schema.

This module implements an OO-interface to database schemas.  Using this module,
you can create a database schema with an OO Perl interface.  You can read the
schema from an existing database.  You can save the schema to disk and restore
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.  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

=over 4

=item new TABLE_OBJECT, TABLE_OBJECT, ...

Creates a new DBIx::DBSchema object.

=cut

sub new {
  my($proto, @tables) = @_;
  my %tables = map  { $_->name, $_ } @tables; #check for duplicates?

  my $class = ref($proto) || $proto;
  my $self = {
    'tables' => \%tables,
  };

  bless ($self, $class);

}

=item new_odbc DATABASE_HANDLE | DATA_SOURCE USERNAME PASSWORD [ ATTR ]

Creates a new DBIx::DBSchema object from an existing data source, which can be
specified by passing an open DBI database handle, or by passing the DBI data
source name, username, and password.  This uses the experimental DBI type_info
method to create a schema with standard (ODBC) SQL column types that most
closely correspond to any non-portable column types.  Use this to import a
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.  Note that this
method only uses "ODBC" column types; it does not require or use an ODBC
driver.

=cut

sub new_odbc {
  my($proto, $dbh) = (shift, shift);
  $dbh = DBI->connect( $dbh, @_ ) or die $DBI::errstr unless ref($dbh);
  $proto->new(
    map { new_odbc DBIx::DBSchema::Table $dbh, $_ } _tables_from_dbh($dbh)
  );
}

=item new_native DATABASE_HANDLE | DATA_SOURCE USERNAME PASSWORD [ ATTR ]

Creates a new DBIx::DBSchema object from an existing data source, which can be
specified by passing an open DBI database handle, or by passing the DBI data
source name, username and password.  This uses database-native methods to read
the schema, and will preserve any non-portable column types.  The method is
only available if there is a DBIx::DBSchema::DBD for the corresponding database engine (currently, MySQL and PostgreSQL).

=cut

sub new_native {
  my($proto, $dbh) = (shift, shift);
  $dbh = DBI->connect( $dbh, @_ ) or die $DBI::errstr unless ref($dbh);
  $proto->new(
    map { new_native DBIx::DBSchema::Table ( $dbh, $_ ) } _tables_from_dbh($dbh)
  );
}

=item load FILENAME

Loads a DBIx::DBSchema object from a file.

=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?
  $self;
}

=item save FILENAME

Saves a DBIx::DBSchema object to a file.

=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));
}

=item addtable TABLE_OBJECT

Adds the given DBIx::DBSchema::Table object to this DBIx::DBSchema.

=cut

sub addtable {
  my($self,$table)=@_;
  $self->{'tables'}->{$table->name} = $table; #check for dupliates?
}

=item tables 

Returns a list of the names of all tables.

=cut

sub tables {
  my($self)=@_;
  keys %{$self->{'tables'}};
}

=item table TABLENAME

Returns the specified DBIx::DBSchema::Table object.

=cut

sub table {
  my($self,$table)=@_;
  $self->{'tables'}->{$table};
}

=item sql [ DATABASE_HANDLE | DATA_SOURCE [ USERNAME PASSWORD [ ATTR ] ] ]

Returns a list of SQL `CREATE' statements for this schema.

The data source can be specified by passing an open DBI database handle, or by
passing the DBI data source name, username and password.  

Although the username and password are optional, it is best to call this method
with a database handle or data source including a valid username and password -
a DBI connection will be opened and the quoting and type mapping will be more
reliable.

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.

=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 @r = map { $self->table($_)->sql_create_table($dbh); } $self->tables;
  $dbh->disconnect if $created_dbh;
  @r;
}

=item pretty_print

Returns the data in this schema as Perl source, suitable for assigning to a
hash.

=cut

sub pretty_print {
  my($self) = @_;
  join("},\n\n",
    map {
      my $table = $_;
      "'$table' => {\n".
        "  'columns' => [\n".
          join("", map { 
                         #cant because -w complains about , in qw()
                         # (also biiiig problems with empty lengths)
                         #"    qw( $_ ".
                         #$self->table($table)->column($_)->type. " ".
                         #( $self->table($table)->column($_)->null ? 'NULL' : 0 ). " ".
                         #$self->table($table)->column($_)->length. " ),\n"
                         "    '$_', ".
                         "'". $self->table($table)->column($_)->type. "', ".
                         "'". $self->table($table)->column($_)->null. "', ". 
                         "'". $self->table($table)->column($_)->length. "', ".
                         "'". $self->table($table)->column($_)->default. "', ".
                         "'". $self->table($table)->column($_)->local. "',\n"
                       } $self->table($table)->columns
          ).
        "  ],\n".
        "  'primary_key' => '". $self->table($table)->primary_key. "',\n".
        "  'unique' => [ ". join(', ',
          map { "[ '". join("', '", @{$_}). "' ]" }
            @{$self->table($table)->unique->lol_ref}
          ).  " ],\n".
        "  'index' => [ ". join(', ',
          map { "[ '". join("', '", @{$_}). "' ]" }
            @{$self->table($table)->index->lol_ref}
          ). " ],\n"
        #"  'index' => [ ".    " ],\n"
    } $self->tables
  ), "}\n";
}

=cut

=item pretty_read HASHREF

Creates a schema as specified by a data structure such as that created by
B<pretty_print> method.

=cut

sub pretty_read {
  my($proto, $href) = @_;
  my $schema = $proto->new( map {  
    my(@columns);
    while ( @{$href->{$_}{'columns'}} ) {
      push @columns, DBIx::DBSchema::Column->new(
        splice @{$href->{$_}{'columns'}}, 0, 6
      );
    }
    DBIx::DBSchema::Table->new(
      $_,
      $href->{$_}{'primary_key'},
      DBIx::DBSchema::ColGroup::Unique->new($href->{$_}{'unique'}),
      DBIx::DBSchema::ColGroup::Index->new($href->{$_}{'index'}),
      @columns,
    );
  } (keys %{$href}) );
}

# 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 confess "can't parse data source: $dbh";
  }

  #require "DBIx/DBSchema/DBD/$driver.pm";
  #$driver;
  eval 'require "DBIx/DBSchema/DBD/$driver.pm"' and $driver or die $@;
}

sub _tables_from_dbh {
  my($dbh) = @_;
  my $sth = $dbh->table_info 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 }
    @{ $sth->fetchall_arrayref([2,3]) };
}

=back

=head1 AUTHOR

Ivan Kohler <ivan-dbix-dbschema at 420.am>

Charles Shapiro <charles.shapiro at numethods.com> and Mitchell Friedman
<mitchell.friedman at numethods.com> contributed the start of a Sybase driver.

=head1 COPYRIGHT

Copyright (c) 2000 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
the same terms as Perl itself.

=head1 BUGS

Each DBIx::DBSchema object should have a name which corresponds to its name
within the SQL database engine (DBI data source).

pretty_print is actually pretty ugly.

Perhaps pretty_read should eval column types so that we can use DBI
qw(:sql_types) here instead of externally.

=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::DBD::mysql>, L<DBIx::DBSchema::DBD::Pg>, L<FS::Record>,
L<DBI>

=cut

1;





More information about the freeside-commits mailing list