Added missing space in error message
[dbsrgits/DBIx-Class-Schema-Loader.git] / lib / DBIx / Class / Schema / Loader.pm
index 75318cf..aa62e41 100644 (file)
@@ -1,9 +1,18 @@
 package DBIx::Class::Schema::Loader;
 
 use strict;
+use warnings;
+use base qw/DBIx::Class::Schema/;
+use base qw/Class::Data::Accessor/;
+use Carp;
 use UNIVERSAL::require;
 
-our $VERSION = '0.01';
+# Always remember to do all digits for the version even if they're 0
+# i.e. first release of 0.XX *must* be 0.XX000. This avoids fBSD ports
+# brain damage and presumably various other packaging systems too
+our $VERSION = '0.02007';
+
+__PACKAGE__->mk_classaccessor('loader');
 
 =head1 NAME
 
@@ -11,51 +20,61 @@ DBIx::Class::Schema::Loader - Dynamic definition of a DBIx::Class::Schema
 
 =head1 SYNOPSIS
 
-  use DBIx::Class::Schema::Loader;
-
-  my $loader = DBIx::Class::Schema::Loader->new(
-    dsn                     => "dbi:mysql:dbname",
-    user                    => "root",
-    password                => "",
-    namespace               => "Data",
+  package My::Schema;
+  use base qw/DBIx::Class::Schema::Loader/;
+
+  sub _monikerize {
+      my $name = shift;
+      $name = join '', map ucfirst, split /[\W_]+/, lc $name;
+      $name;
+  }
+
+  __PACKAGE__->load_from_connection(
+    connect_info            => [ "dbi:mysql:dbname",
+                                 "root",
+                                 "mypassword",
+                                 { AutoCommit => 1 },
+                               ],
     additional_classes      => [qw/DBIx::Class::Foo/],
     additional_base_classes => [qw/My::Stuff/],
     left_base_classes       => [qw/DBIx::Class::Bar/],
+    components              => [qw/ResultSetManager/],
+    resultset_components    => [qw/AlwaysRS/],
     constraint              => '^foo.*',
     relationships           => 1,
     options                 => { AutoCommit => 1 }, 
-    inflect                 => { child => 'children' },
+    inflect_map             => { child => 'children' },
+    moniker_map             => \&_monikerize,
     debug                   => 1,
   );
 
-  my $conn = $loader->connection($dsn, $user, $password); #
-  my $conn = $loader->connection(); # uses same dsn as ->new();
+  # in seperate application code ...
 
-use with mod_perl
+  use My::Schema;
 
-in your startup.pl
+  my $schema1 = My::Schema->connect( $dsn, $user, $password, $attrs);
+  # -or-
+  my $schema1 = "My::Schema";
+  # ^^ defaults to dsn/user/pass from load_from_connection()
 
-  # load all tables
-  use DBIx::Class::Loader;
-  my $loader = DBIx::Class::Loader->new(
-    dsn       => "dbi:mysql:dbname",
-    user      => "root",
-    password  => "",
-    namespace => "Data",
-  );
+  # Get a list of the original (database) names of the tables that
+  #  were loaded
+  my @tables = $schema1->loader->tables;
 
-in your web application.
+  # Get a hashref of table_name => 'TableName' table-to-moniker
+  #   mappings.
+  my $monikers = $schema1->loader->monikers;
 
-  use strict;
+  # Get a hashref of table_name => 'My::Schema::TableName'
+  #   table-to-classname mappings.
+  my $classes = $schema1->loader->classes;
 
-  # you can use Data::Film directly
-  my $conn = $loader->connection();
-  my $film_moniker = $loader->moniker('film');
-  my $a_film = $conn->resultset($film_moniker)->find($id);
+  # Use the schema as per normal for DBIx::Class::Schema
+  my $rs = $schema1->resultset($monikers->{foo_table})->search(...);
 
 =head1 DESCRIPTION
 
-DBIx::Class::Schema::Loader automate the definition of a
+DBIx::Class::Schema::Loader automates the definition of a
 DBIx::Class::Schema by scanning table schemas and setting up
 columns and primary keys.
 
@@ -64,14 +83,28 @@ L<DBIx::Class::Schema::Loader::Generic> for more, and
 L<DBIx::Class::Schema::Loader::Writing> for notes on writing your own
 db-specific subclass for an unsupported db.
 
-L<Class::DBI::Loader>, L<Class::DBI>, and L<DBIx::Class::Loader> are now
-obsolete, use L<DBIx::Class> and this module instead. ;)
+This module requires L<DBIx::Class> 0.05 or later, and obsoletes
+L<DBIx::Class::Loader> for L<DBIx::Class> version 0.05 and later.
 
-=cut
+While on the whole, the bare table definitions are fairly straightforward,
+relationship creation is somewhat heuristic, especially in the choosing
+of relationship types, join types, and relationship names.  The relationships
+generated by this module will probably never be as well-defined as
+hand-generated ones.  Because of this, over time a complex project will
+probably wish to migrate off of L<DBIx::Class::Schema::Loader>.
+
+It is designed more to get you up and running quickly against an existing
+database, or to be effective for simple situations, rather than to be what
+you use in the long term for a complex database/project.
+
+That being said, transitioning your code from a Schema generated by this
+module to one that doesn't use this module should be straightforward and
+painless, so don't shy away from it just for fears of the transition down
+the road.
 
 =head1 METHODS
 
-=head2 new
+=head2 load_from_connection
 
 Example in Synopsis above demonstrates the available arguments.  For
 detailed information on the arguments, see the
@@ -79,29 +112,60 @@ L<DBIx::Class::Schema::Loader::Generic> documentation.
 
 =cut
 
-sub new {
+# XXX this is DBI-specific, as it peers into the dsn to determine
+# the vendor class to use...
+sub load_from_connection {
     my ( $class, %args ) = @_;
 
-    foreach (qw/namespace dsn/) {
-       die qq/Argument $_ is required/ if ! $args{$_};
-    }
+    my $dsn;
 
-    $args{namespace} =~ s/(.*)::$/$1/;
+    if($args{connect_info} && $args{connect_info}->[0]) {
+        $dsn = $args{connect_info}->[0];
+    }
+    elsif($args{dsn}) {
+        warn "dsn argument is deprecated, please use connect_info instead";
+        $dsn = $args{dsn};
+    }
+    else {
+        croak 'connect_info arrayref argument with valid '
+              . 'first element is required';
+    }
 
-    my $dsn = $args{dsn};
     my ($driver) = $dsn =~ m/^dbi:(\w*?)(?:\((.*?)\))?:/i;
     $driver = 'SQLite' if $driver eq 'SQLite2';
     my $impl = "DBIx::Class::Schema::Loader::" . $driver;
 
     $impl->require or
-    die qq/Couldn't require loader class "$impl", "$UNIVERSAL::require::ERROR"/;
+      croak qq/Couldn't require loader class "$impl",/ .
+            qq/"$UNIVERSAL::require::ERROR"/;
 
-    return $impl->new(%args);
+    $args{schema} = $class;
+
+    $class->loader($impl->new(%args));
+    $class->loader->load;
 }
 
+=head2 loader
+
+This is an accessor in the generated Schema class for accessing
+the L<DBIx::Class::Schema::Loader::Generic> -based loader object
+that was used during construction.  See the
+L<DBIx::Class::Schema::Loader::Generic> docs for more information
+on the available loader methods there.
+
+=head1 KNOWN BUGS
+
+Aside from relationship definitions being less than ideal in general,
+this version is known not to handle the case of multiple relationships
+between the same pair of tables.  All of the relationship code will
+be overhauled on the way to 0.03, at which time that bug will be
+addressed.
+
 =head1 AUTHOR
 
-Sebastian Riedel, C<sri@oook.de>
+Brandon Black, C<blblack@gmail.com>
+
+Based on L<DBIx::Class::Loader> by Sebastian Riedel
 
 Based upon the work of IKEBE Tomohiro