DBIx-Class-Schema-Loader

 view release on metacpan or  search on metacpan

lib/DBIx/Class/Schema/Loader.pm  view on Meta::CPAN

package DBIx::Class::Schema::Loader;

use strict;
use warnings;
use base qw/DBIx::Class::Schema Class::Accessor::Grouped/;
use MRO::Compat;
use mro 'c3';
use Carp::Clan qw/^DBIx::Class/;
use Scalar::Util 'weaken';
use Sub::Util 'set_subname';
use DBIx::Class::Schema::Loader::Utils qw/array_eq sigwarn_silencer/;
use Try::Tiny;
use curry;
use namespace::clean;

# 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.07053';

__PACKAGE__->mk_group_accessors('inherited', qw/
                                _loader_args
                                dump_to_dir
                                _loader_invoked
                                _loader
                                loader_class
                                naming
                                use_namespaces
/);
__PACKAGE__->_loader_args({});

=encoding UTF-8

=head1 NAME

DBIx::Class::Schema::Loader - Create a DBIx::Class::Schema based on a database

=head1 SYNOPSIS

    ### use this module to generate a set of class files

    # in a script
    use DBIx::Class::Schema::Loader qw/ make_schema_at /;
    make_schema_at(
        'My::Schema',
        { debug => 1,
          dump_directory => './lib',
        },
        [ 'dbi:Pg:dbname="foo"', 'myuser', 'mypassword',
           { loader_class => 'MyLoader' } # optionally
        ],
    );

    # from the command line or a shell script with dbicdump (distributed
    # with this module).  Do `perldoc dbicdump` for usage.
    dbicdump -o dump_directory=./lib \
             -o components='["InflateColumn::DateTime"]' \
             -o debug=1 \
             My::Schema \
             'dbi:Pg:dbname=foo' \
             myuser \
             mypassword

    ### or generate and load classes at runtime
    # note: this technique is not recommended
    # for use in production code

    package My::Schema;
    use base qw/DBIx::Class::Schema::Loader/;

lib/DBIx/Class/Schema/Loader.pm  view on Meta::CPAN

        my $class_isa = do {
            no strict 'refs';
            \@{"${class}::ISA"};
        };

        my @component_classes = map {
            /^\+/ ? substr($_, 1, length($_) - 1) : "DBIx::Class::$_"
        } @components;

        $modify_isa++ if not array_eq([ @$class_isa[0..(@components-1)] ], \@component_classes)
    }

    if ($modify_isa) {
        $class->load_components(@components);

        # This hack is necessary because we changed @ISA of $self through
        # ->load_components and we are now in a different place in the mro.
        no warnings 'redefine';

        local *connection = set_subname __PACKAGE__.'::connection' => sub {
            my $self = shift;
            $self->next::method(@_);
        };

        my @linear_isa = @{ mro::get_linear_isa($class) };

        my $next_method;

        foreach my $i (1..$#linear_isa) {
            no strict 'refs';
            $next_method = *{$linear_isa[$i].'::connection'}{CODE};
            last if $next_method;
        }

        $self = $self->$next_method(@_);
    }
    else {
        $self = $self->next::method(@_);
    }

    if(!$class->_loader_invoked) {
        $self->_invoke_loader
    }

    return $self;
}

=head2 clone

See L<DBIx::Class::Schema/clone>.

=cut

sub clone {
    my $self = shift;

    my $clone = $self->next::method(@_);

    if($clone->_loader_args) {
        $clone->_loader_args->{schema} = $clone;
        weaken($clone->_loader_args->{schema});
    }

    $clone;
}

=head2 dump_to_dir

=over 4

=item Argument: $directory

=back

Calling this as a class method on either L<DBIx::Class::Schema::Loader>
or any derived schema class will cause all schemas to dump
manual versions of themselves to the named directory when they are
loaded.  In order to be effective, this must be set before defining a
connection on this schema class or any derived object (as the loading
happens as soon as both a connection and loader_options are set, and
only once per class).

See L<DBIx::Class::Schema::Loader::Base/dump_directory> for more
details on the dumping mechanism.

This can also be set at module import time via the import option
C<dump_to_dir:/foo/bar> to L<DBIx::Class::Schema::Loader>, where
C</foo/bar> is the target directory.

Examples:

    # My::Schema isa DBIx::Class::Schema::Loader, and has connection info
    #   hardcoded in the class itself:
    perl -MDBIx::Class::Schema::Loader=dump_to_dir:/foo/bar -MMy::Schema -e1

    # Same, but no hard-coded connection, so we must provide one:
    perl -MDBIx::Class::Schema::Loader=dump_to_dir:/foo/bar -MMy::Schema -e 'My::Schema->connection("dbi:Pg:dbname=foo", ...)'

    # Or as a class method, as long as you get it done *before* defining a
    #  connection on this schema class or any derived object:
    use My::Schema;
    My::Schema->dump_to_dir('/foo/bar');
    My::Schema->connection(........);

    # Or as a class method on the DBIx::Class::Schema::Loader itself, which affects all
    #   derived schemas
    use My::Schema;
    use My::OtherSchema;
    DBIx::Class::Schema::Loader->dump_to_dir('/foo/bar');
    My::Schema->connection(.......);
    My::OtherSchema->connection(.......);

    # Another alternative to the above:
    use DBIx::Class::Schema::Loader qw| dump_to_dir:/foo/bar |;
    use My::Schema;
    use My::OtherSchema;
    My::Schema->connection(.......);
    My::OtherSchema->connection(.......);

=cut



( run in 1.926 second using v1.01-cache-2.11-cpan-39bf76dae61 )