package DBIx::Class::Migration::MySQLSandbox; use Moose; use Test::mysqld; use File::Spec::Functions 'catdir', 'catfile', 'splitpath'; use File::Path 'mkpath'; use File::Temp 'tempdir'; use Config::MySQL::Reader; with 'DBIx::Class::Migration::Sandbox'; has test_mysqld => (is=>'ro', lazy_build=>1); sub _generate_schema_path_part { my $schema_class = (my $self = shift)->schema_class; $schema_class =~ s/::/-/g; return lc $schema_class; } sub _generate_sandbox_dir { my $self = shift; return catdir($self->target_dir, $self->_generate_schema_path_part); } sub _generate_unique_socket { my $schema_path_part = (my $self = shift)->_generate_schema_path_part; my $sockdir = catdir( tempdir, $schema_path_part); mkpath($sockdir) unless -d $sockdir; return catfile( $sockdir, 'mysqld.sock'); } sub _build_test_mysqld { my $base_dir = (my $self = shift)->_generate_sandbox_dir; my $auto_start = 2; my $my_cnf = { 'skip-networking' => '', socket => $self->_generate_unique_socket }; if( -d $base_dir) { $auto_start = 1; my $conf = Config::MySQL::Reader->read_file( catfile($base_dir, 'etc', 'my.cnf') ) || die "Can't read my.cnf file"; $my_cnf = { socket => $conf->{mysqld}->{socket} }; if( -e $conf->{mysqld}->{socket}) { $auto_start = 0; } else { my ($volume, $directory, $file) = splitpath($conf->{mysqld}->{socket}); mkpath $directory; } } return Test::mysqld->new( auto_start => $auto_start, base_dir => $base_dir, my_cnf => $my_cnf ); } sub _write_start { my $base_dir = (my $self = shift)->test_mysqld->base_dir; mkpath(my $bin = catdir($base_dir, 'bin')); open( my $fh, '>', catfile($bin, 'start')) || die "Cannot open $bin/start: $!"; my $mysqld = $self->test_mysqld->{mysqld}; my $my_cnf = catfile($base_dir, 'etc', 'my.cnf'); print $fh <test_mysqld->base_dir; mkpath(my $bin = catdir($base_dir, 'bin')); open( my $fh, '>', catfile($bin, 'stop')) || die "Cannot open $bin/stop: $!"; my $PIDFILE = $self->test_mysqld->{my_cnf}->{'pid-file'}; print $fh <test_mysqld->base_dir; mkpath(my $bin = catdir($base_dir, 'bin')); open( my $fh, '>', catfile($bin, 'use')) || die "Cannot open $bin/use: $!"; my $mysqld = $self->test_mysqld->{mysqld}; my $SOCKET = $self->test_mysqld->my_cnf->{socket}; $mysqld =~s/d$//; ## ug. sorry :( print $fh <_generate_sandbox_dir; if( -e catfile($base_dir, 'tmp', 'mysqld.pid')) { return $self->test_mysqld->dsn; } elsif($self->test_mysqld) { $self->_write_start; $self->_write_stop; $self->_write_use; return $self->test_mysqld->dsn; } else { die "can't start a mysql sandbox"; } } __PACKAGE__->meta->make_immutable; =head1 NAME DBIx::Class::Migration::MySQLSandbox - Autocreate a mysql sandbox =head1 SYNOPSIS use DBIx::Class::Migration; my $migration = DBIx::Class::Migration->new( schema_class=>'Local::Schema', db_sandbox_class=>'DBIx::Class::Migration::MySQLSandbox'), $migration->prepare; $migration->install; =head1 DESCRIPTION This automatically creates a mysql sandbox in your C that you can use for initial prototyping, development and demonstration. If you want to use this, you will need to add L to your C or your C file, and get that installed properly. It also requires that you have MySQL installed locally (although MySQL does not need to be running, as long as we can find in $PATH the binary installation). If your copy of MySQL is not installed in a normal location, you might need to locally alter $PATH so that we can find it. For example, on my Mac, C is located at C so I could do something like this: PATH=/usr/local/mysqlbin:$PATH [command] and alter the C<$PATH> for one time running, or I could change the C<$PATH> permanently by editing my C<.bashrc> file (typically located in C<$HOME>). NOTE: You might find installing L to be easier if you edit the C<$PATH> before trying to install it. In addition to the MySQL sandbox, we create three helper scripts C, C and C which can be used to start, stop and open shell level access to you mysql sandbox. These helper scripts will be located in a child directory of your C (which defaults to C under your project root directory). For example: [target_dir]/[schema_class]/bin/[start|stop|use] If your schema class is C you should see helper scripts like /MyApp-Web /lib /MyApp Schema.pm /Schema ... /share /migrations /fixtures /myapp-schema /bin start stop use This give you a system for installing a sandbox locally for development, starting and stopping it for use (for example in a web application like one you might create with L) and for using it by opening a native C shell (such as if you wish to review the database manually, and run native SQL queries). =head1 SEE ALSO L, L, L. =head1 AUTHOR See L for author information =head1 COPYRIGHT & LICENSE See L for copyright and license information =cut